mac80211: use rate index in TX control
authorJohannes Berg <johannes@sipsolutions.net>
Thu, 15 May 2008 10:55:27 +0000 (12:55 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 22 May 2008 01:48:09 +0000 (21:48 -0400)
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>
25 files changed:
drivers/net/wireless/adm8211.c
drivers/net/wireless/ath5k/base.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/xmit.c
drivers/net/wireless/b43legacy/xmit.c
drivers/net/wireless/iwlwifi/iwl-3945-rs.c
drivers/net/wireless/iwlwifi/iwl-3945.c
drivers/net/wireless/iwlwifi/iwl-4965-rs.c
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/iwlwifi/iwl4965-base.c
drivers/net/wireless/p54/p54common.c
drivers/net/wireless/rt2x00/rt2x00queue.c
drivers/net/wireless/rtl8180_dev.c
drivers/net/wireless/rtl8187_dev.c
drivers/net/wireless/zd1211rw/zd_mac.c
include/net/mac80211.h
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c
net/mac80211/rate.c
net/mac80211/rate.h
net/mac80211/rc80211_pid_algo.c
net/mac80211/tx.c
net/mac80211/util.c

index 79dfca546c895416a5b71d934a45a8bd81c3183b..22db664a58d910bb8fea1fab3cea75fba3deff69 100644 (file)
@@ -1693,10 +1693,10 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
        size_t payload_len, hdrlen;
        int plcp, dur, len, plcp_signal, short_preamble;
        struct ieee80211_hdr *hdr;
+       struct ieee80211_rate *txrate = ieee80211_get_tx_rate(dev, control);
 
-       short_preamble = !!(control->tx_rate->flags &
-                                       IEEE80211_TXCTL_SHORT_PREAMBLE);
-       plcp_signal = control->tx_rate->bitrate;
+       short_preamble = !!(txrate->flags & IEEE80211_TXCTL_SHORT_PREAMBLE);
+       plcp_signal = txrate->bitrate;
 
        hdr = (struct ieee80211_hdr *)skb->data;
        fc = le16_to_cpu(hdr->frame_control) & ~IEEE80211_FCTL_PROTECTED;
index 3f16ad66bdb51478de991d73e18a8ac44194b9fe..32ee351a76509398c6c3c1e166fa6ed4e53abdea 100644 (file)
@@ -1323,7 +1323,8 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
 
        ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
                ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
-               (sc->power_level * 2), ctl->tx_rate->hw_value,
+               (sc->power_level * 2),
+               ieee80211_get_tx_rate(sc->hw, ctl)->hw_value,
                ctl->retry_limit, keyidx, 0, flags, 0, 0);
        if (ret)
                goto err_unmap;
@@ -2046,7 +2047,8 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
        ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
                        ieee80211_get_hdrlen_from_skb(skb),
                        AR5K_PKT_TYPE_BEACON, (sc->power_level * 2),
-                       ctl->tx_rate->hw_value, 1, AR5K_TXKEYIX_INVALID,
+                       ieee80211_get_tx_rate(sc->hw, ctl)->hw_value,
+                       1, AR5K_TXKEYIX_INVALID,
                        antenna, flags, 0, 0);
        if (ret)
                goto err_unmap;
@@ -2654,7 +2656,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
                memmove(skb->data, skb->data+pad, hdrlen);
        }
 
-       sc->led_txrate = ctl->tx_rate->hw_value;
+       sc->led_txrate = ieee80211_get_tx_rate(hw, ctl)->hw_value;
 
        spin_lock_irqsave(&sc->txbuflock, flags);
        if (list_empty(&sc->txbuf)) {
index 9445a604a96663a32b819fecb114032afb09367a..e428645352b459d853d7218b55b2d57426affd06 100644 (file)
@@ -1372,7 +1372,7 @@ static void b43_write_beacon_template(struct b43_wldev *dev,
        bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data);
        len = min((size_t) dev->wl->current_beacon->len,
                  0x200 - sizeof(struct b43_plcp_hdr6));
-       rate = dev->wl->beacon_txctl.tx_rate->hw_value;
+       rate = ieee80211_get_tx_rate(dev->wl->hw, &dev->wl->beacon_txctl)->hw_value;
 
        b43_write_template_common(dev, (const u8 *)bcn,
                                  len, ram_offset, shm_size_offset, rate);
index afce9338d83a2b305b403ed5362ac1e8ce950f29..9b682a3cf5e469882c08241e7ce3407cc99c8da4 100644 (file)
@@ -201,13 +201,14 @@ int b43_generate_txhdr(struct b43_wldev *dev,
        u32 mac_ctl = 0;
        u16 phy_ctl = 0;
        u8 extra_ft = 0;
+       struct ieee80211_rate *txrate;
 
        memset(txhdr, 0, sizeof(*txhdr));
 
-       WARN_ON(!txctl->tx_rate);
-       rate = txctl->tx_rate ? txctl->tx_rate->hw_value : B43_CCK_RATE_1MB;
+       txrate = ieee80211_get_tx_rate(dev->wl->hw, txctl);
+       rate = txrate ? txrate->hw_value : B43_CCK_RATE_1MB;
        rate_ofdm = b43_is_ofdm_rate(rate);
-       fbrate = txctl->alt_retry_rate ? : txctl->tx_rate;
+       fbrate = ieee80211_get_alt_retry_rate(dev->wl->hw, txctl) ? : txrate;
        rate_fb = fbrate->hw_value;
        rate_fb_ofdm = b43_is_ofdm_rate(rate_fb);
 
@@ -336,9 +337,11 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                int rts_rate, rts_rate_fb;
                int rts_rate_ofdm, rts_rate_fb_ofdm;
                struct b43_plcp_hdr6 *plcp;
+               struct ieee80211_rate *rts_cts_rate;
 
-               WARN_ON(!txctl->rts_cts_rate);
-               rts_rate = txctl->rts_cts_rate ? txctl->rts_cts_rate->hw_value : B43_CCK_RATE_1MB;
+               rts_cts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, txctl);
+
+               rts_rate = rts_cts_rate ? rts_cts_rate->hw_value : B43_CCK_RATE_1MB;
                rts_rate_ofdm = b43_is_ofdm_rate(rts_rate);
                rts_rate_fb = b43_calc_fallback_rate(rts_rate);
                rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb);
index bed9e041d6c5518b48ce8e90673ee8d6b09c5f2b..55dc251bf5101fcfb4efac421bfc43f95e3bfe73 100644 (file)
@@ -201,15 +201,18 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
        unsigned int plcp_fragment_len;
        u32 mac_ctl = 0;
        u16 phy_ctl = 0;
+       struct ieee80211_rate *tx_rate;
 
        wlhdr = (const struct ieee80211_hdr *)fragment_data;
        fctl = le16_to_cpu(wlhdr->frame_control);
 
        memset(txhdr, 0, sizeof(*txhdr));
 
-       rate = txctl->tx_rate->hw_value;
+       tx_rate = ieee80211_get_tx_rate(dev->wl->hw, txctl);
+
+       rate = tx_rate->hw_value;
        rate_ofdm = b43legacy_is_ofdm_rate(rate);
-       rate_fb = txctl->alt_retry_rate ? : txctl->tx_rate;
+       rate_fb = ieee80211_get_alt_retry_rate(dev->wl->hw, txctl) ? : tx_rate;
        rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb->hw_value);
 
        txhdr->mac_frame_ctl = wlhdr->frame_control;
@@ -312,7 +315,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
                int rts_rate_ofdm;
                int rts_rate_fb_ofdm;
 
-               rts_rate = txctl->rts_cts_rate->hw_value;
+               rts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, txctl)->hw_value;
                rts_rate_ofdm = b43legacy_is_ofdm_rate(rts_rate);
                rts_rate_fb = b43legacy_calc_fallback_rate(rts_rate);
                rts_rate_fb_ofdm = b43legacy_is_ofdm_rate(rts_rate_fb);
index e51eeeff6992bc8af8a0ea04fdc24401b3f47b17..f3ca02fe9619b914cee198bf5d721816fe30d317 100644 (file)
@@ -464,7 +464,7 @@ static void rs_tx_status(void *priv_rate,
 
 
        retries = tx_resp->retry_count;
-       first_index = tx_resp->control.tx_rate->hw_value;
+       first_index = sband->bitrates[tx_resp->control.tx_rate_idx].hw_value;
        if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) {
                IWL_DEBUG_RATE("leave: Rate out of bounds: %d\n", first_index);
                return;
@@ -669,7 +669,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
            is_multicast_ether_addr(hdr->addr1) ||
            !sta || !sta->rate_ctrl_priv) {
                IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
-               sel->rate = rate_lowest(local, sband, sta);
+               sel->rate_idx = rate_lowest_index(local, sband, sta);
                rcu_read_unlock();
                return;
        }
@@ -813,7 +813,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
 
        IWL_DEBUG_RATE("leave: %d\n", index);
 
-       sel->rate = &sband->bitrates[sta->txrate_idx];
+       sel->rate_idx = sta->txrate_idx;
 }
 
 static struct rate_control_ops rs_ops = {
index ad4e7b74ca244ca75aa7c703e63968cf7dad36bb..f8e691f88ab37969ff00b8b5632475b3bbcdfe24 100644 (file)
@@ -331,7 +331,9 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
                        tx_resp->rate, tx_resp->failure_frame);
 
        rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate);
-       tx_status->control.tx_rate = &priv->ieee_rates[rate_idx];
+       if (tx_status->control.band == IEEE80211_BAND_5GHZ)
+               rate_idx -= IWL_FIRST_OFDM_RATE;
+       tx_status->control.tx_rate_idx = rate_idx;
        IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
        iwl3945_tx_queue_reclaim(priv, txq_id, index);
 
@@ -962,7 +964,8 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
                              struct ieee80211_hdr *hdr, int sta_id, int tx_id)
 {
        unsigned long flags;
-       u16 rate_index = min(ctrl->tx_rate->hw_value & 0xffff, IWL_RATE_COUNT - 1);
+       u16 hw_value = ieee80211_get_tx_rate(priv->hw, ctrl)->hw_value;
+       u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1);
        u16 rate_mask;
        int rate;
        u8 rts_retry_limit;
index 2adc2281c77c75571a3bbe183a0835ac8fa97729..7993a1d8302530f714bd5df36ce71c05b2fe1aae 100644 (file)
@@ -862,7 +862,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
        if (priv->band == IEEE80211_BAND_5GHZ)
                rs_index -= IWL_FIRST_OFDM_RATE;
 
-       if ((tx_resp->control.tx_rate == NULL) ||
+       if ((tx_resp->control.tx_rate_idx < 0) ||
            (tbl_type.is_SGI ^
                !!(tx_resp->control.flags & IEEE80211_TXCTL_SHORT_GI)) ||
            (tbl_type.is_fat ^
@@ -875,7 +875,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
            (!!(tx_rate & RATE_MCS_GF_MSK) ^
                !!(tx_resp->control.flags & IEEE80211_TXCTL_GREEN_FIELD)) ||
            (hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate !=
-               tx_resp->control.tx_rate->bitrate)) {
+            hw->wiphy->bands[tx_resp->control.band]->bitrates[tx_resp->control.tx_rate_idx].bitrate)) {
                IWL_DEBUG_RATE("initial rate does not match 0x%x\n", tx_rate);
                goto out;
        }
@@ -2154,7 +2154,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
        fc = le16_to_cpu(hdr->frame_control);
        if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
            !sta || !sta->rate_ctrl_priv) {
-               sel->rate = rate_lowest(local, sband, sta);
+               sel->rate_idx = rate_lowest_index(local, sband, sta);
                goto out;
        }
 
@@ -2184,11 +2184,13 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
 
 done:
        if ((i < 0) || (i > IWL_RATE_COUNT)) {
-               sel->rate = rate_lowest(local, sband, sta);
+               sel->rate_idx = rate_lowest_index(local, sband, sta);
                goto out;
        }
 
-       sel->rate = &priv->ieee_rates[i];
+       if (sband->band == IEEE80211_BAND_5GHZ)
+               i -= IWL_FIRST_OFDM_RATE;
+       sel->rate_idx = i;
 out:
        rcu_read_unlock();
 }
index f848a5b0f62279430e614f93238d7405b5af512d..fb670b5cfebbea6c80a358e1649f129a53c1aa83 100644 (file)
@@ -373,14 +373,10 @@ void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
                control->flags |= IEEE80211_TXCTL_DUP_DATA;
        if (rate_n_flags & RATE_MCS_SGI_MSK)
                control->flags |= IEEE80211_TXCTL_SHORT_GI;
-       /* since iwl4965_hwrate_to_plcp_idx is band indifferent, we always use
-        * IEEE80211_BAND_2GHZ band as it contains all the rates */
        rate_index = iwl4965_hwrate_to_plcp_idx(rate_n_flags);
-       if (rate_index == -1)
-               control->tx_rate = NULL;
-       else
-               control->tx_rate =
-                       &priv->bands[IEEE80211_BAND_2GHZ].bitrates[rate_index];
+       if (control->band == IEEE80211_BAND_5GHZ)
+               rate_index -= IWL_FIRST_OFDM_RATE;
+       control->tx_rate_idx = rate_index;
 }
 
 int iwl4965_hw_rxq_stop(struct iwl_priv *priv)
index f32cddabdf64c3a64ac3e07f0157c8e9c59c44d5..4b5149c8c32ebfbc0011fa7c952d2b5a9bee1ccc 100644 (file)
@@ -578,7 +578,10 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
        u8 data_retry_limit = 0;
        u8 rate_plcp;
        u16 rate_flags = 0;
-       int rate_idx = min(ctrl->tx_rate->hw_value & 0xffff, IWL_RATE_COUNT - 1);
+       int rate_idx;
+
+       rate_idx = min(ieee80211_get_tx_rate(priv->hw, ctrl)->hw_value & 0xffff,
+                       IWL_RATE_COUNT - 1);
 
        rate_plcp = iwl_rates[rate_idx].plcp;
 
@@ -723,7 +726,8 @@ int iwl_tx_skb(struct iwl_priv *priv,
                goto drop_unlock;
        }
 
-       if ((ctl->tx_rate->hw_value & 0xFF) == IWL_INVALID_RATE) {
+       if ((ieee80211_get_tx_rate(priv->hw, ctl)->hw_value & 0xFF) ==
+            IWL_INVALID_RATE) {
                IWL_ERROR("ERROR: No TX rate available.\n");
                goto drop_unlock;
        }
index 54cde8a7b5fabe6e5a7330c28f7639d5cf7ebdef..a28b4c9f6524834509896ff24339d469a5bbd249 100644 (file)
@@ -2581,7 +2581,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
                goto drop_unlock;
        }
 
-       if ((ctl->tx_rate->hw_value & 0xFF) == IWL_INVALID_RATE) {
+       if ((ieee80211_get_tx_rate(priv->hw, ctl)->hw_value & 0xFF) == IWL_INVALID_RATE) {
                IWL_ERROR("ERROR: No TX rate available.\n");
                goto drop_unlock;
        }
@@ -6694,7 +6694,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
        }
 
        IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
-                    ctl->tx_rate->bitrate);
+                    ieee80211_get_tx_rate(hw, ctl)->bitrate);
 
        if (iwl3945_tx_skb(priv, skb, ctl))
                dev_kfree_skb_any(skb);
index db4f606bad500f8253c349bfdd6f1374544dc0bd..1fad6227aa51da217cf85a487472972010bba6f6 100644 (file)
@@ -4281,7 +4281,7 @@ static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
        }
 
        IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
-                    ctl->tx_rate->bitrate);
+                    ieee80211_get_tx_rate(hw, ctl)->bitrate);
 
        if (iwl_tx_skb(priv, skb, ctl))
                dev_kfree_skb_any(skb);
index 3d35fe6a8f5f743a7a701ee785e0765c6026e813..3ca9386561ffdd64fea99a76ccbdcebf8f78fb33 100644 (file)
@@ -592,7 +592,7 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
        txhdr->padding2 = 0;
 
        /* TODO: add support for alternate retry TX rates */
-       rate = control->tx_rate->hw_value;
+       rate = ieee80211_get_tx_rate(dev, control)->hw_value;
        if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE)
                rate |= 0x10;
        if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
index 19c10629c767513ca510e66c82732ce5e91584da..5cf4c2f5926049e9613c449b0dbb6d19b51fa555 100644 (file)
@@ -33,8 +33,10 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
                                      struct txentry_desc *txdesc,
                                      struct ieee80211_tx_control *control)
 {
+       struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
-       struct ieee80211_rate *rate = control->tx_rate;
+       struct ieee80211_rate *rate =
+           ieee80211_get_tx_rate(rt2x00dev->hw, control);
        const struct rt2x00_rate *hwrate;
        unsigned int data_length;
        unsigned int duration;
@@ -77,8 +79,9 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
                        __set_bit(ENTRY_TXD_CTS_FRAME, &txdesc->flags);
                        __clear_bit(ENTRY_TXD_ACK, &txdesc->flags);
                }
-               if (control->rts_cts_rate)
-                       rate = control->rts_cts_rate;
+               if (control->rts_cts_rate_idx >= 0)
+                       rate =
+                           ieee80211_get_rts_cts_rate(rt2x00dev->hw, control);
        }
 
        /*
index c220998cee65b46fd844cead4153023223fd95dc..6263209b889e3ac1021305527fcb3cce7ca31bd6 100644 (file)
@@ -257,24 +257,21 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
        mapping = pci_map_single(priv->pdev, skb->data,
                                 skb->len, PCI_DMA_TODEVICE);
 
-       BUG_ON(!control->tx_rate);
-
        tx_flags = RTL8180_TX_DESC_FLAG_OWN | RTL8180_TX_DESC_FLAG_FS |
                   RTL8180_TX_DESC_FLAG_LS |
-                  (control->tx_rate->hw_value << 24) | skb->len;
+                  (ieee80211_get_tx_rate(dev, control)->hw_value << 24) |
+                  skb->len;
 
        if (priv->r8185)
                tx_flags |= RTL8180_TX_DESC_FLAG_DMA |
                            RTL8180_TX_DESC_FLAG_NO_ENC;
 
        if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
-               BUG_ON(!control->rts_cts_rate);
                tx_flags |= RTL8180_TX_DESC_FLAG_RTS;
-               tx_flags |= control->rts_cts_rate->hw_value << 19;
+               tx_flags |= ieee80211_get_rts_cts_rate(dev, control)->hw_value << 19;
        } else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
-               BUG_ON(!control->rts_cts_rate);
                tx_flags |= RTL8180_TX_DESC_FLAG_CTS;
-               tx_flags |= control->rts_cts_rate->hw_value << 19;
+               tx_flags |= ieee80211_get_rts_cts_rate(dev, control)->hw_value << 19;
        }
 
        *((struct ieee80211_tx_control **) skb->cb) =
@@ -288,9 +285,9 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
                unsigned int remainder;
 
                plcp_len = DIV_ROUND_UP(16 * (skb->len + 4),
-                                       (control->tx_rate->bitrate * 2) / 10);
+                               (ieee80211_get_tx_rate(dev, control)->bitrate * 2) / 10);
                remainder = (16 * (skb->len + 4)) %
-                           ((control->tx_rate->bitrate * 2) / 10);
+                           ((ieee80211_get_tx_rate(dev, control)->bitrate * 2) / 10);
                if (remainder > 0 && remainder <= 6)
                        plcp_len |= 1 << 15;
        }
@@ -303,8 +300,8 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
        entry->plcp_len = cpu_to_le16(plcp_len);
        entry->tx_buf = cpu_to_le32(mapping);
        entry->frame_len = cpu_to_le32(skb->len);
-       entry->flags2 = control->alt_retry_rate != NULL ?
-                       control->alt_retry_rate->bitrate << 4 : 0;
+       entry->flags2 = control->alt_retry_rate_idx >= 0 ?
+               ieee80211_get_alt_retry_rate(dev, control)->bitrate << 4 : 0;
        entry->retry_limit = control->retry_limit;
        entry->flags = cpu_to_le32(tx_flags);
        __skb_queue_tail(&ring->queue, skb);
index e14c84248686ca4581fc9c6c76f1aef8ec9cbee9..86a09b49681ccc3adb6ead86d7c197ed24d8452e 100644 (file)
@@ -179,21 +179,17 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
        flags = skb->len;
        flags |= RTL8187_TX_FLAG_NO_ENCRYPT;
 
-       BUG_ON(!control->tx_rate);
-
-       flags |= control->tx_rate->hw_value << 24;
+       flags |= ieee80211_get_tx_rate(dev, control)->hw_value << 24;
        if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb->data))
                flags |= RTL8187_TX_FLAG_MORE_FRAG;
        if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
-               BUG_ON(!control->rts_cts_rate);
                flags |= RTL8187_TX_FLAG_RTS;
-               flags |= control->rts_cts_rate->hw_value << 19;
+               flags |= ieee80211_get_rts_cts_rate(dev, control)->hw_value << 19;
                rts_dur = ieee80211_rts_duration(dev, priv->vif,
                                                 skb->len, control);
        } else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
-               BUG_ON(!control->rts_cts_rate);
                flags |= RTL8187_TX_FLAG_CTS;
-               flags |= control->rts_cts_rate->hw_value << 19;
+               flags |= ieee80211_get_rts_cts_rate(dev, control)->hw_value << 19;
        }
 
        hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
index 0c736735e2173daee686f55d66ff7dca717128df..99c508c09e5ba791c3dabc262fe6a9bb95e41b10 100644 (file)
@@ -523,14 +523,17 @@ static int fill_ctrlset(struct zd_mac *mac,
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
        unsigned int frag_len = skb->len + FCS_LEN;
        unsigned int packet_length;
+       struct ieee80211_rate *txrate;
        struct zd_ctrlset *cs = (struct zd_ctrlset *)
                skb_push(skb, sizeof(struct zd_ctrlset));
 
        ZD_ASSERT(frag_len <= 0xffff);
 
-       cs->modulation = control->tx_rate->hw_value;
+       txrate = ieee80211_get_tx_rate(mac->hw, control);
+
+       cs->modulation = txrate->hw_value;
        if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE)
-               cs->modulation = control->tx_rate->hw_value_short;
+               cs->modulation = txrate->hw_value_short;
 
        cs->tx_length = cpu_to_le16(frag_len);
 
index f00fc76a7344a56b92cf8127bdb9d119cb6caca4..0df91bea6c1f9d22301d1284bf1a6a6c5ca77676 100644 (file)
@@ -266,27 +266,26 @@ enum mac80211_tx_control_flags {
  * ieee80211_ops->remove_interface() callback funtion.
  * The hw_key pointer is valid until it has been removed with the
  * ieee80211_ops->set_key() callback function.
- * The tx_rate and alt_retry_rate pointers are valid until the phy is
- * deregistered.
  */
 struct ieee80211_tx_control {
-       struct ieee80211_vif *vif;
-       struct ieee80211_rate *tx_rate;
+       u32 flags;              /* tx control flags defined above */
+
+       s8 tx_rate_idx,         /* Transmit rate (indexes registered rates) */
+          rts_cts_rate_idx,    /* Transmit rate for RTS/CTS frame */
+          alt_retry_rate_idx;  /* retry rate for the last retries */
 
-       /* Transmit rate for RTS/CTS frame */
-       struct ieee80211_rate *rts_cts_rate;
+       s8 retry_limit;         /* 1 = only first attempt, 2 = one retry, ..
+                                * This could be used when set_retry_limit
+                                * is not implemented by the driver */
 
-       /* retry rate for the last retries */
-       struct ieee80211_rate *alt_retry_rate;
+       struct ieee80211_vif *vif;
 
        /* Key used for hardware encryption
         * NULL if IEEE80211_TXCTL_DO_NOT_ENCRYPT is set */
        struct ieee80211_key_conf *hw_key;
 
-       u32 flags;              /* tx control flags defined above */
-       u8 retry_limit;         /* 1 = only first attempt, 2 = one retry, ..
-                                * This could be used when set_retry_limit
-                                * is not implemented by the driver */
+       enum ieee80211_band band;
+
        u8 antenna_sel_tx;      /* 0 = default/diversity, otherwise bit
                                 * position represents antenna number used */
        u8 icv_len;             /* length of the ICV/MIC field in octets */
@@ -298,6 +297,7 @@ struct ieee80211_tx_control {
 };
 
 
+
 /**
  * enum mac80211_rx_flags - receive flags
  *
@@ -823,6 +823,33 @@ static inline void SET_IEEE80211_PERM_ADDR(struct ieee80211_hw *hw, u8 *addr)
        memcpy(hw->wiphy->perm_addr, addr, ETH_ALEN);
 }
 
+static inline struct ieee80211_rate *
+ieee80211_get_tx_rate(const struct ieee80211_hw *hw,
+                     const struct ieee80211_tx_control *c)
+{
+       if (WARN_ON(c->tx_rate_idx < 0))
+               return NULL;
+       return &hw->wiphy->bands[c->band]->bitrates[c->tx_rate_idx];
+}
+
+static inline struct ieee80211_rate *
+ieee80211_get_rts_cts_rate(const struct ieee80211_hw *hw,
+                          const struct ieee80211_tx_control *c)
+{
+       if (c->rts_cts_rate_idx < 0)
+               return NULL;
+       return &hw->wiphy->bands[c->band]->bitrates[c->rts_cts_rate_idx];
+}
+
+static inline struct ieee80211_rate *
+ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
+                            const struct ieee80211_tx_control *c)
+{
+       if (c->alt_retry_rate_idx < 0)
+               return NULL;
+       return &hw->wiphy->bands[c->band]->bitrates[c->alt_retry_rate_idx];
+}
+
 /**
  * DOC: Hardware crypto acceleration
  *
index ed0d9b35ae6f6d161922f0ddb2df83a192bdbc3b..a4cccd1b7d539f8a21c169e3a116395fbe050a52 100644 (file)
@@ -159,11 +159,11 @@ struct ieee80211_tx_data {
 
        struct ieee80211_tx_control *control;
        struct ieee80211_channel *channel;
-       struct ieee80211_rate *rate;
+       s8 rate_idx;
        /* use this rate (if set) for last fragment; rate can
         * be set to lower rate for the first fragments, e.g.,
         * when using CTS protection with IEEE 802.11g. */
-       struct ieee80211_rate *last_frag_rate;
+       s8 last_frag_rate_idx;
 
        /* Extra fragments (in addition to the first fragment
         * in skb) */
@@ -225,9 +225,9 @@ struct ieee80211_tx_stored_packet {
        struct ieee80211_tx_control control;
        struct sk_buff *skb;
        struct sk_buff **extra_frag;
-       struct ieee80211_rate *last_frag_rate;
+       s8 last_frag_rate_idx;
        int num_extra_frag;
-       unsigned int last_frag_rate_ctrl_probe;
+       bool last_frag_rate_ctrl_probe;
 };
 
 struct beacon_data {
index 7877d3b3f4cbf57ca7cb9e4c86abf4d7f55933e0..604149369dc9c82d7f286cf873f9cd7f1e4f3a5b 100644 (file)
@@ -2406,15 +2406,15 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
 
                memset(&control, 0, sizeof(control));
                rate_control_get_rate(dev, sband, skb, &ratesel);
-               if (!ratesel.rate) {
+               if (ratesel.rate_idx < 0) {
                        printk(KERN_DEBUG "%s: Failed to determine TX rate "
                               "for IBSS beacon\n", dev->name);
                        break;
                }
                control.vif = &sdata->vif;
-               control.tx_rate = ratesel.rate;
+               control.tx_rate_idx = ratesel.rate_idx;
                if (sdata->bss_conf.use_short_preamble &&
-                   ratesel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)
+                   sband->bitrates[ratesel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE)
                        control.flags |= IEEE80211_TXCTL_SHORT_PREAMBLE;
                control.antenna_sel_tx = local->hw.conf.antenna_sel_tx;
                control.flags |= IEEE80211_TXCTL_NO_ACK;
index 841df93807fc86fa0178cf282f4d9ce11b1c7317..0388c090dfe9bb5c1d3437c1137a2abed2ca17bf 100644 (file)
@@ -176,20 +176,24 @@ void rate_control_get_rate(struct net_device *dev,
        rcu_read_lock();
        sta = sta_info_get(local, hdr->addr1);
 
-       memset(sel, 0, sizeof(struct rate_selection));
+       sel->rate_idx = -1;
+       sel->nonerp_idx = -1;
+       sel->probe_idx = -1;
 
        ref->ops->get_rate(ref->priv, dev, sband, skb, sel);
 
+       BUG_ON(sel->rate_idx < 0);
+
        /* Select a non-ERP backup rate. */
-       if (!sel->nonerp) {
+       if (sel->nonerp_idx < 0) {
                for (i = 0; i < sband->n_bitrates; i++) {
                        struct ieee80211_rate *rate = &sband->bitrates[i];
-                       if (sel->rate->bitrate < rate->bitrate)
+                       if (sband->bitrates[sel->rate_idx].bitrate < rate->bitrate)
                                break;
 
                        if (rate_supported(sta, sband->band, i) &&
                            !(rate->flags & IEEE80211_RATE_ERP_G))
-                               sel->nonerp = rate;
+                               sel->nonerp_idx = i;
                }
        }
 
index 5b45f33cb7663364f537d1316478d3b39835a446..a29148dcca99e41ed1913b138f23648ed778cd30 100644 (file)
 #include "ieee80211_i.h"
 #include "sta_info.h"
 
-/* TODO: kdoc */
+/**
+ * struct rate_selection - rate selection for rate control algos
+ * @rate: selected transmission rate index
+ * @nonerp: Non-ERP rate to use instead if ERP cannot be used
+ * @probe: rate for probing (or -1)
+ *
+ */
 struct rate_selection {
-       /* Selected transmission rate */
-       struct ieee80211_rate *rate;
-       /* Non-ERP rate to use if mac80211 decides it cannot use an ERP rate */
-       struct ieee80211_rate *nonerp;
-       /* probe with this rate, or NULL for no probing */
-       struct ieee80211_rate *probe;
+       s8 rate_idx, nonerp_idx, probe_idx;
 };
 
 struct rate_control_ops {
@@ -138,7 +139,7 @@ static inline int rate_supported(struct sta_info *sta,
        return (sta == NULL || sta->supp_rates[band] & BIT(index));
 }
 
-static inline int
+static inline s8
 rate_lowest_index(struct ieee80211_local *local,
                  struct ieee80211_supported_band *sband,
                  struct sta_info *sta)
@@ -155,14 +156,6 @@ rate_lowest_index(struct ieee80211_local *local,
        return 0;
 }
 
-static inline struct ieee80211_rate *
-rate_lowest(struct ieee80211_local *local,
-           struct ieee80211_supported_band *sband,
-           struct sta_info *sta)
-{
-       return &sband->bitrates[rate_lowest_index(local, sband, sta)];
-}
-
 
 /* functions for rate control related to a device */
 int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
index a849b745bdb56b6f83b19a98e73f069f42341621..14cde36f50701eb37e1565e60eb05d9f9696d2a1 100644 (file)
@@ -266,7 +266,7 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
 
        /* Ignore all frames that were sent with a different rate than the rate
         * we currently advise mac80211 to use. */
-       if (status->control.tx_rate != &sband->bitrates[sta->txrate_idx])
+       if (status->control.tx_rate_idx != sta->txrate_idx)
                goto unlock;
 
        spinfo = sta->rate_ctrl_priv;
@@ -330,7 +330,7 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev,
        fc = le16_to_cpu(hdr->frame_control);
        if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
            is_multicast_ether_addr(hdr->addr1) || !sta) {
-               sel->rate = rate_lowest(local, sband, sta);
+               sel->rate_idx = rate_lowest_index(local, sband, sta);
                rcu_read_unlock();
                return;
        }
@@ -349,7 +349,7 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev,
 
        rcu_read_unlock();
 
-       sel->rate = &sband->bitrates[rateidx];
+       sel->rate_idx = rateidx;
 
 #ifdef CONFIG_MAC80211_DEBUGFS
        rate_control_pid_event_tx_rate(
index aecec2a72b086b117a3b9d357beef904d7b157eb..99c3860bc0e2f42a21e5d051afecf31d54ed8caa 100644 (file)
@@ -91,11 +91,12 @@ static u16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
                              int next_frag_len)
 {
        int rate, mrate, erp, dur, i;
-       struct ieee80211_rate *txrate = tx->rate;
+       struct ieee80211_rate *txrate;
        struct ieee80211_local *local = tx->local;
        struct ieee80211_supported_band *sband;
 
-       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+       sband = local->hw.wiphy->bands[tx->channel->band];
+       txrate = &sband->bitrates[tx->rate_idx];
 
        erp = 0;
        if (tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
@@ -610,40 +611,40 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
        struct rate_selection rsel;
        struct ieee80211_supported_band *sband;
 
-       sband = tx->local->hw.wiphy->bands[tx->local->hw.conf.channel->band];
+       sband = tx->local->hw.wiphy->bands[tx->channel->band];
 
-       if (likely(!tx->rate)) {
+       if (likely(tx->rate_idx < 0)) {
                rate_control_get_rate(tx->dev, sband, tx->skb, &rsel);
-               tx->rate = rsel.rate;
-               if (unlikely(rsel.probe)) {
+               tx->rate_idx = rsel.rate_idx;
+               if (unlikely(rsel.probe_idx >= 0)) {
                        tx->control->flags |=
                                IEEE80211_TXCTL_RATE_CTRL_PROBE;
                        tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG;
-                       tx->control->alt_retry_rate = tx->rate;
-                       tx->rate = rsel.probe;
+                       tx->control->alt_retry_rate_idx = tx->rate_idx;
+                       tx->rate_idx = rsel.probe_idx;
                } else
-                       tx->control->alt_retry_rate = NULL;
+                       tx->control->alt_retry_rate_idx = -1;
 
-               if (!tx->rate)
+               if (unlikely(tx->rate_idx < 0))
                        return TX_DROP;
        } else
-               tx->control->alt_retry_rate = NULL;
+               tx->control->alt_retry_rate_idx = -1;
 
        if (tx->sdata->bss_conf.use_cts_prot &&
-           (tx->flags & IEEE80211_TX_FRAGMENTED) && rsel.nonerp) {
-               tx->last_frag_rate = tx->rate;
-               if (rsel.probe)
+           (tx->flags & IEEE80211_TX_FRAGMENTED) && (rsel.nonerp_idx >= 0)) {
+               tx->last_frag_rate_idx = tx->rate_idx;
+               if (rsel.probe_idx >= 0)
                        tx->flags &= ~IEEE80211_TX_PROBE_LAST_FRAG;
                else
                        tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG;
-               tx->rate = rsel.nonerp;
-               tx->control->tx_rate = rsel.nonerp;
+               tx->rate_idx = rsel.nonerp_idx;
+               tx->control->tx_rate_idx = rsel.nonerp_idx;
                tx->control->flags &= ~IEEE80211_TXCTL_RATE_CTRL_PROBE;
        } else {
-               tx->last_frag_rate = tx->rate;
-               tx->control->tx_rate = tx->rate;
+               tx->last_frag_rate_idx = tx->rate_idx;
+               tx->control->tx_rate_idx = tx->rate_idx;
        }
-       tx->control->tx_rate = tx->rate;
+       tx->control->tx_rate_idx = tx->rate_idx;
 
        return TX_CONTINUE;
 }
@@ -655,6 +656,9 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
        u16 fc = le16_to_cpu(hdr->frame_control);
        u16 dur;
        struct ieee80211_tx_control *control = tx->control;
+       struct ieee80211_supported_band *sband;
+
+       sband = tx->local->hw.wiphy->bands[tx->channel->band];
 
        if (!control->retry_limit) {
                if (!is_multicast_ether_addr(hdr->addr1)) {
@@ -681,14 +685,14 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
                 * frames.
                 * TODO: The last fragment could still use multiple retry
                 * rates. */
-               control->alt_retry_rate = NULL;
+               control->alt_retry_rate_idx = -1;
        }
 
        /* Use CTS protection for unicast frames sent using extended rates if
         * there are associated non-ERP stations and RTS/CTS is not configured
         * for the frame. */
        if ((tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) &&
-           (tx->rate->flags & IEEE80211_RATE_ERP_G) &&
+           (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_ERP_G) &&
            (tx->flags & IEEE80211_TX_UNICAST) &&
            tx->sdata->bss_conf.use_cts_prot &&
            !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS))
@@ -698,7 +702,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
         * short preambles at the selected rate and short preambles are
         * available on the network at the current point in time. */
        if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
-           (tx->rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
+           (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
            tx->sdata->bss_conf.use_short_preamble &&
            (!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) {
                tx->control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE;
@@ -715,32 +719,32 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
        if ((control->flags & IEEE80211_TXCTL_USE_RTS_CTS) ||
            (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) {
                struct ieee80211_supported_band *sband;
-               struct ieee80211_rate *rate, *baserate;
+               struct ieee80211_rate *rate;
+               s8 baserate = -1;
                int idx;
 
-               sband = tx->local->hw.wiphy->bands[
-                               tx->local->hw.conf.channel->band];
+               sband = tx->local->hw.wiphy->bands[tx->channel->band];
 
                /* Do not use multiple retry rates when using RTS/CTS */
-               control->alt_retry_rate = NULL;
+               control->alt_retry_rate_idx = -1;
 
                /* Use min(data rate, max base rate) as CTS/RTS rate */
-               rate = tx->rate;
-               baserate = NULL;
+               rate = &sband->bitrates[tx->rate_idx];
 
                for (idx = 0; idx < sband->n_bitrates; idx++) {
                        if (sband->bitrates[idx].bitrate > rate->bitrate)
                                continue;
                        if (tx->sdata->basic_rates & BIT(idx) &&
-                           (!baserate ||
-                            (baserate->bitrate < sband->bitrates[idx].bitrate)))
-                               baserate = &sband->bitrates[idx];
+                           (baserate < 0 ||
+                            (sband->bitrates[baserate].bitrate
+                             < sband->bitrates[idx].bitrate)))
+                               baserate = idx;
                }
 
-               if (baserate)
-                       control->rts_cts_rate = baserate;
+               if (baserate >= 0)
+                       control->rts_cts_rate_idx = baserate;
                else
-                       control->rts_cts_rate = &sband->bitrates[0];
+                       control->rts_cts_rate_idx = 0;
        }
 
        if (tx->sta) {
@@ -768,7 +772,11 @@ ieee80211_tx_h_load_stats(struct ieee80211_tx_data *tx)
        struct sk_buff *skb = tx->skb;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
        u32 load = 0, hdrtime;
-       struct ieee80211_rate *rate = tx->rate;
+       struct ieee80211_rate *rate;
+       struct ieee80211_supported_band *sband;
+
+       sband = tx->local->hw.wiphy->bands[tx->channel->band];
+       rate = &sband->bitrates[tx->rate_idx];
 
        /* TODO: this could be part of tx_status handling, so that the number
         * 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)
                for (i = 0; i < tx->num_extra_frag; i++) {
                        load += 2 * hdrtime;
                        load += tx->extra_frag[i]->len *
-                               tx->rate->bitrate;
+                               rate->bitrate;
                }
        }
 
@@ -859,7 +867,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
        int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len);
        struct ieee80211_tx_control *control = tx->control;
 
-       sband = tx->local->hw.wiphy->bands[tx->local->hw.conf.channel->band];
+       sband = tx->local->hw.wiphy->bands[tx->channel->band];
 
        control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
        tx->flags |= IEEE80211_TX_INJECTED;
@@ -899,7 +907,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
                                r = &sband->bitrates[i];
 
                                if (r->bitrate == target_rate) {
-                                       tx->rate = r;
+                                       tx->rate_idx = i;
                                        break;
                                }
                        }
@@ -1097,7 +1105,7 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
                        if (__ieee80211_queue_stopped(local, control->queue))
                                return IEEE80211_TX_FRAG_AGAIN;
                        if (i == tx->num_extra_frag) {
-                               control->tx_rate = tx->last_frag_rate;
+                               control->tx_rate_idx = tx->last_frag_rate_idx;
 
                                if (tx->flags & IEEE80211_TX_PROBE_LAST_FRAG)
                                        control->flags |=
@@ -1155,6 +1163,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
 
        sta = tx.sta;
        tx.channel = local->hw.conf.channel;
+       control->band = tx.channel->band;
 
        for (handler = ieee80211_tx_handlers; *handler != NULL;
             handler++) {
@@ -1187,7 +1196,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
                                next_len = tx.extra_frag[i + 1]->len;
                        } else {
                                next_len = 0;
-                               tx.rate = tx.last_frag_rate;
+                               tx.rate_idx = tx.last_frag_rate_idx;
                        }
                        dur = ieee80211_duration(&tx, 0, next_len);
                        hdr->duration_id = cpu_to_le16(dur);
@@ -1224,7 +1233,7 @@ retry:
                store->skb = skb;
                store->extra_frag = tx.extra_frag;
                store->num_extra_frag = tx.num_extra_frag;
-               store->last_frag_rate = tx.last_frag_rate;
+               store->last_frag_rate_idx = tx.last_frag_rate_idx;
                store->last_frag_rate_ctrl_probe =
                        !!(tx.flags & IEEE80211_TX_PROBE_LAST_FRAG);
        }
@@ -1685,7 +1694,7 @@ void ieee80211_tx_pending(unsigned long data)
                tx.control = &store->control;
                tx.extra_frag = store->extra_frag;
                tx.num_extra_frag = store->num_extra_frag;
-               tx.last_frag_rate = store->last_frag_rate;
+               tx.last_frag_rate_idx = store->last_frag_rate_idx;
                tx.flags = 0;
                if (store->last_frag_rate_ctrl_probe)
                        tx.flags |= IEEE80211_TX_PROBE_LAST_FRAG;
@@ -1789,9 +1798,10 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
        struct ieee80211_mgmt *mgmt;
        int *num_beacons;
        bool err = true;
+       enum ieee80211_band band = local->hw.conf.channel->band;
        u8 *pos;
 
-       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+       sband = local->hw.wiphy->bands[band];
 
        rcu_read_lock();
 
@@ -1885,8 +1895,9 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
        }
 
        if (control) {
+               control->band = band;
                rate_control_get_rate(local->mdev, sband, skb, &rsel);
-               if (!rsel.rate) {
+               if (unlikely(rsel.rate_idx < 0)) {
                        if (net_ratelimit()) {
                                printk(KERN_DEBUG "%s: ieee80211_beacon_get: "
                                       "no rate found\n",
@@ -1898,9 +1909,9 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
                }
 
                control->vif = vif;
-               control->tx_rate = rsel.rate;
+               control->tx_rate_idx = rsel.rate_idx;
                if (sdata->bss_conf.use_short_preamble &&
-                   rsel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)
+                   sband->bitrates[rsel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE)
                        control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE;
                control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
                control->flags |= IEEE80211_TXCTL_NO_ACK;
@@ -2006,6 +2017,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
        sta = tx.sta;
        tx.flags |= IEEE80211_TX_PS_BUFFERED;
        tx.channel = local->hw.conf.channel;
+       control->band = tx.channel->band;
 
        for (handler = ieee80211_tx_handlers; *handler != NULL; handler++) {
                res = (*handler)(&tx);
index 800c15aff6e7bc8bca62c70e217ce7fe2f8462d7..65a34fddeb00e099dadec4b3a5249ba03fec9106 100644 (file)
@@ -266,10 +266,13 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
        bool short_preamble;
        int erp;
        u16 dur;
+       struct ieee80211_supported_band *sband;
+
+       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
 
        short_preamble = sdata->bss_conf.use_short_preamble;
 
-       rate = frame_txctl->rts_cts_rate;
+       rate = &sband->bitrates[frame_txctl->rts_cts_rate_idx];
 
        erp = 0;
        if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
@@ -300,10 +303,13 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
        bool short_preamble;
        int erp;
        u16 dur;
+       struct ieee80211_supported_band *sband;
+
+       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
 
        short_preamble = sdata->bss_conf.use_short_preamble;
 
-       rate = frame_txctl->rts_cts_rate;
+       rate = &sband->bitrates[frame_txctl->rts_cts_rate_idx];
        erp = 0;
        if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
                erp = rate->flags & IEEE80211_RATE_ERP_G;