mac80211: move TX info into skb->cb
authorJohannes Berg <johannes@sipsolutions.net>
Thu, 15 May 2008 10:55:29 +0000 (12:55 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 22 May 2008 01:48:11 +0000 (21:48 -0400)
This patch converts mac80211 and all drivers to have transmit
information and status in skb->cb rather than allocating extra
memory for it and copying all the data around. To make it fit,
a union is used where only data that is necessary for all steps
is kept outside of the union.

A number of fixes were done by Ivo, as well as the rt2x00 part
of this patch.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
67 files changed:
drivers/net/wireless/adm8211.c
drivers/net/wireless/adm8211.h
drivers/net/wireless/ath5k/base.c
drivers/net/wireless/ath5k/base.h
drivers/net/wireless/b43/b43.h
drivers/net/wireless/b43/dma.c
drivers/net/wireless/b43/dma.h
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/pio.c
drivers/net/wireless/b43/pio.h
drivers/net/wireless/b43/xmit.c
drivers/net/wireless/b43/xmit.h
drivers/net/wireless/b43legacy/dma.c
drivers/net/wireless/b43legacy/dma.h
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/b43legacy/pio.c
drivers/net/wireless/b43legacy/pio.h
drivers/net/wireless/b43legacy/xmit.c
drivers/net/wireless/b43legacy/xmit.h
drivers/net/wireless/iwlwifi/iwl-3945-rs.c
drivers/net/wireless/iwlwifi/iwl-3945.c
drivers/net/wireless/iwlwifi/iwl-3945.h
drivers/net/wireless/iwlwifi/iwl-4965-rs.c
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-dev.h
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/p54/p54common.h
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2500usb.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00mac.c
drivers/net/wireless/rt2x00/rt2x00pci.c
drivers/net/wireless/rt2x00/rt2x00pci.h
drivers/net/wireless/rt2x00/rt2x00queue.c
drivers/net/wireless/rt2x00/rt2x00queue.h
drivers/net/wireless/rt2x00/rt2x00usb.c
drivers/net/wireless/rt2x00/rt2x00usb.h
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/rtl8180_dev.c
drivers/net/wireless/rtl8187.h
drivers/net/wireless/rtl8187_dev.c
drivers/net/wireless/zd1211rw/zd_mac.c
drivers/net/wireless/zd1211rw/zd_mac.h
drivers/net/wireless/zd1211rw/zd_usb.c
include/net/mac80211.h
net/mac80211/ieee80211_i.h
net/mac80211/main.c
net/mac80211/mlme.c
net/mac80211/rate.h
net/mac80211/rc80211_pid.h
net/mac80211/rc80211_pid_algo.c
net/mac80211/rc80211_pid_debugfs.c
net/mac80211/rx.c
net/mac80211/sta_info.c
net/mac80211/sta_info.h
net/mac80211/tx.c
net/mac80211/util.c
net/mac80211/wep.c
net/mac80211/wme.c
net/mac80211/wpa.c

index 22db664..0ba55ba 100644 (file)
@@ -324,7 +324,7 @@ static void adm8211_interrupt_tci(struct ieee80211_hw *dev)
        for (dirty_tx = priv->dirty_tx; priv->cur_tx - dirty_tx; dirty_tx++) {
                unsigned int entry = dirty_tx % priv->tx_ring_size;
                u32 status = le32_to_cpu(priv->tx_ring[entry].status);
-               struct ieee80211_tx_status tx_status;
+               struct ieee80211_tx_info *txi;
                struct adm8211_tx_ring_info *info;
                struct sk_buff *skb;
 
@@ -334,24 +334,23 @@ static void adm8211_interrupt_tci(struct ieee80211_hw *dev)
 
                info = &priv->tx_buffers[entry];
                skb = info->skb;
+               txi = IEEE80211_SKB_CB(skb);
 
                /* TODO: check TDES0_STATUS_TUF and TDES0_STATUS_TRO */
 
                pci_unmap_single(priv->pdev, info->mapping,
                                 info->skb->len, PCI_DMA_TODEVICE);
 
-               memset(&tx_status, 0, sizeof(tx_status));
+               memset(&txi->status, 0, sizeof(txi->status));
                skb_pull(skb, sizeof(struct adm8211_tx_hdr));
                memcpy(skb_push(skb, info->hdrlen), skb->cb, info->hdrlen);
-               memcpy(&tx_status.control, &info->tx_control,
-                      sizeof(tx_status.control));
-               if (!(tx_status.control.flags & IEEE80211_TXCTL_NO_ACK)) {
+               if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK)) {
                        if (status & TDES0_STATUS_ES)
-                               tx_status.excessive_retries = 1;
+                               txi->status.excessive_retries = 1;
                        else
-                               tx_status.flags |= IEEE80211_TX_STATUS_ACK;
+                               txi->flags |= IEEE80211_TX_STAT_ACK;
                }
-               ieee80211_tx_status_irqsafe(dev, skb, &tx_status);
+               ieee80211_tx_status_irqsafe(dev, skb);
 
                info->skb = NULL;
        }
@@ -1638,7 +1637,6 @@ static void adm8211_calc_durations(int *dur, int *plcp, size_t payload_len, int
 /* Transmit skb w/adm8211_tx_hdr (802.11 header created by hardware) */
 static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb,
                           u16 plcp_signal,
-                          struct ieee80211_tx_control *control,
                           size_t hdrlen)
 {
        struct adm8211_priv *priv = dev->priv;
@@ -1664,7 +1662,6 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb,
 
        priv->tx_buffers[entry].skb = skb;
        priv->tx_buffers[entry].mapping = mapping;
-       memcpy(&priv->tx_buffers[entry].tx_control, control, sizeof(*control));
        priv->tx_buffers[entry].hdrlen = hdrlen;
        priv->tx_ring[entry].buffer1 = cpu_to_le32(mapping);
 
@@ -1685,17 +1682,17 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb,
 }
 
 /* Put adm8211_tx_hdr on skb and transmit */
-static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
-                     struct ieee80211_tx_control *control)
+static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
        struct adm8211_tx_hdr *txhdr;
        u16 fc;
        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);
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_rate *txrate = ieee80211_get_tx_rate(dev, info);
 
-       short_preamble = !!(txrate->flags & IEEE80211_TXCTL_SHORT_PREAMBLE);
+       short_preamble = !!(txrate->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE);
        plcp_signal = txrate->bitrate;
 
        hdr = (struct ieee80211_hdr *)skb->data;
@@ -1730,15 +1727,15 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
        if (short_preamble)
                txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_SHORT_PREAMBLE);
 
-       if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
+       if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
                txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_RTS);
 
        if (fc & IEEE80211_FCTL_PROTECTED)
                txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_WEP_ENGINE);
 
-       txhdr->retry_limit = control->retry_limit;
+       txhdr->retry_limit = info->control.retry_limit;
 
-       adm8211_tx_raw(dev, skb, plcp_signal, control, hdrlen);
+       adm8211_tx_raw(dev, skb, plcp_signal, hdrlen);
 
        return NETDEV_TX_OK;
 }
index 8d7c564..9b190ee 100644 (file)
@@ -443,7 +443,6 @@ struct adm8211_rx_ring_info {
 struct adm8211_tx_ring_info {
        struct sk_buff *skb;
        dma_addr_t mapping;
-       struct ieee80211_tx_control tx_control;
        size_t hdrlen;
 };
 
index 32ee351..7d97934 100644 (file)
@@ -167,8 +167,7 @@ static struct pci_driver ath5k_pci_driver = {
 /*
  * Prototypes - MAC 802.11 stack related functions
  */
-static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
-               struct ieee80211_tx_control *ctl);
+static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
 static int ath5k_reset(struct ieee80211_hw *hw);
 static int ath5k_start(struct ieee80211_hw *hw);
 static void ath5k_stop(struct ieee80211_hw *hw);
@@ -196,8 +195,7 @@ static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
 static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
 static void ath5k_reset_tsf(struct ieee80211_hw *hw);
 static int ath5k_beacon_update(struct ieee80211_hw *hw,
-               struct sk_buff *skb,
-               struct ieee80211_tx_control *ctl);
+               struct sk_buff *skb);
 
 static struct ieee80211_ops ath5k_hw_ops = {
        .tx             = ath5k_tx,
@@ -251,9 +249,7 @@ static void ath5k_desc_free(struct ath5k_softc *sc,
 static int     ath5k_rxbuf_setup(struct ath5k_softc *sc,
                                struct ath5k_buf *bf);
 static int     ath5k_txbuf_setup(struct ath5k_softc *sc,
-                               struct ath5k_buf *bf,
-                               struct ieee80211_tx_control *ctl);
-
+                               struct ath5k_buf *bf);
 static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
                                struct ath5k_buf *bf)
 {
@@ -289,8 +285,7 @@ static void         ath5k_tx_processq(struct ath5k_softc *sc,
 static void    ath5k_tasklet_tx(unsigned long data);
 /* Beacon handling */
 static int     ath5k_beacon_setup(struct ath5k_softc *sc,
-                               struct ath5k_buf *bf,
-                               struct ieee80211_tx_control *ctl);
+                                       struct ath5k_buf *bf);
 static void    ath5k_beacon_send(struct ath5k_softc *sc);
 static void    ath5k_beacon_config(struct ath5k_softc *sc);
 static void    ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
@@ -1295,37 +1290,36 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
 }
 
 static int
-ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
-               struct ieee80211_tx_control *ctl)
+ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
 {
        struct ath5k_hw *ah = sc->ah;
        struct ath5k_txq *txq = sc->txq;
        struct ath5k_desc *ds = bf->desc;
        struct sk_buff *skb = bf->skb;
+       struct ieee80211_tx_info *info = (void*) skb->cb;
        unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID;
        int ret;
 
        flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
-       bf->ctl = *ctl;
+
        /* XXX endianness */
        bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
                        PCI_DMA_TODEVICE);
 
-       if (ctl->flags & IEEE80211_TXCTL_NO_ACK)
+       if (info->flags & IEEE80211_TX_CTL_NO_ACK)
                flags |= AR5K_TXDESC_NOACK;
 
        pktlen = skb->len;
 
-       if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) {
-               keyidx = ctl->hw_key->hw_key_idx;
-               pktlen += ctl->icv_len;
+       if (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)) {
+               keyidx = info->control.hw_key->hw_key_idx;
+               pktlen += info->control.icv_len;
        }
-
        ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
                ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
                (sc->power_level * 2),
-               ieee80211_get_tx_rate(sc->hw, ctl)->hw_value,
-               ctl->retry_limit, keyidx, 0, flags, 0, 0);
+               ieee80211_get_tx_rate(sc->hw, info)->hw_value,
+               info->control.retry_limit, keyidx, 0, flags, 0, 0);
        if (ret)
                goto err_unmap;
 
@@ -1927,11 +1921,11 @@ next:
 static void
 ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
 {
-       struct ieee80211_tx_status txs = {};
        struct ath5k_tx_status ts = {};
        struct ath5k_buf *bf, *bf0;
        struct ath5k_desc *ds;
        struct sk_buff *skb;
+       struct ieee80211_tx_info *info;
        int ret;
 
        spin_lock(&txq->lock);
@@ -1951,24 +1945,25 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
                }
 
                skb = bf->skb;
+               info = (void*) skb->cb;
                bf->skb = NULL;
+
                pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,
                                PCI_DMA_TODEVICE);
 
-               txs.control = bf->ctl;
-               txs.retry_count = ts.ts_shortretry + ts.ts_longretry / 6;
+               info->status.retry_count = ts.ts_shortretry + ts.ts_longretry / 6;
                if (unlikely(ts.ts_status)) {
                        sc->ll_stats.dot11ACKFailureCount++;
                        if (ts.ts_status & AR5K_TXERR_XRETRY)
-                               txs.excessive_retries = 1;
+                               info->status.excessive_retries = 1;
                        else if (ts.ts_status & AR5K_TXERR_FILT)
-                               txs.flags |= IEEE80211_TX_STATUS_TX_FILTERED;
+                               info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
                } else {
-                       txs.flags |= IEEE80211_TX_STATUS_ACK;
-                       txs.ack_signal = ts.ts_rssi;
+                       info->flags |= IEEE80211_TX_STAT_ACK;
+                       info->status.ack_signal = ts.ts_rssi;
                }
 
-               ieee80211_tx_status(sc->hw, skb, &txs);
+               ieee80211_tx_status(sc->hw, skb);
                sc->tx_stats[txq->qnum].count++;
 
                spin_lock(&sc->txbuflock);
@@ -2005,10 +2000,10 @@ ath5k_tasklet_tx(unsigned long data)
  * Setup the beacon frame for transmit.
  */
 static int
-ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
-               struct ieee80211_tx_control *ctl)
+ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
 {
        struct sk_buff *skb = bf->skb;
+       struct  ieee80211_tx_info *info = (void*) skb->cb;
        struct ath5k_hw *ah = sc->ah;
        struct ath5k_desc *ds;
        int ret, antenna = 0;
@@ -2047,7 +2042,7 @@ 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),
-                       ieee80211_get_tx_rate(sc->hw, ctl)->hw_value,
+                       ieee80211_get_tx_rate(sc->hw, info)->hw_value,
                        1, AR5K_TXKEYIX_INVALID,
                        antenna, flags, 0, 0);
        if (ret)
@@ -2626,11 +2621,11 @@ ath5k_led_event(struct ath5k_softc *sc, int event)
 \********************/
 
 static int
-ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
-                       struct ieee80211_tx_control *ctl)
+ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct ath5k_softc *sc = hw->priv;
        struct ath5k_buf *bf;
+       struct ieee80211_tx_info *info = (void*) skb->cb;
        unsigned long flags;
        int hdrlen;
        int pad;
@@ -2656,13 +2651,13 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
                memmove(skb->data, skb->data+pad, hdrlen);
        }
 
-       sc->led_txrate = ieee80211_get_tx_rate(hw, ctl)->hw_value;
+       sc->led_txrate = ieee80211_get_tx_rate(hw, info)->hw_value;
 
        spin_lock_irqsave(&sc->txbuflock, flags);
        if (list_empty(&sc->txbuf)) {
                ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");
                spin_unlock_irqrestore(&sc->txbuflock, flags);
-               ieee80211_stop_queue(hw, ctl->queue);
+               ieee80211_stop_queue(hw, info->queue);
                return -1;
        }
        bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
@@ -2674,7 +2669,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
 
        bf->skb = skb;
 
-       if (ath5k_txbuf_setup(sc, bf, ctl)) {
+       if (ath5k_txbuf_setup(sc, bf)) {
                bf->skb = NULL;
                spin_lock_irqsave(&sc->txbuflock, flags);
                list_add_tail(&bf->list, &sc->txbuf);
@@ -3052,8 +3047,7 @@ ath5k_reset_tsf(struct ieee80211_hw *hw)
 }
 
 static int
-ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
-                       struct ieee80211_tx_control *ctl)
+ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct ath5k_softc *sc = hw->priv;
        int ret;
@@ -3069,7 +3063,7 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
 
        ath5k_txbuf_free(sc, sc->bbuf);
        sc->bbuf->skb = skb;
-       ret = ath5k_beacon_setup(sc, sc->bbuf, ctl);
+       ret = ath5k_beacon_setup(sc, sc->bbuf);
        if (ret)
                sc->bbuf->skb = NULL;
        else
index ecb1749..bb4b26d 100644 (file)
@@ -60,7 +60,6 @@ struct ath5k_buf {
        dma_addr_t              daddr;  /* physical addr of desc */
        struct sk_buff          *skb;   /* skbuff for buf */
        dma_addr_t              skbaddr;/* physical addr of skb data */
-       struct ieee80211_tx_control ctl;
 };
 
 /*
index 0c2bc06..aa49383 100644 (file)
@@ -733,7 +733,6 @@ struct b43_wl {
        /* The beacon we are currently using (AP or IBSS mode).
         * This beacon stuff is protected by the irq_lock. */
        struct sk_buff *current_beacon;
-       struct ieee80211_tx_control beacon_txctl;
        bool beacon0_uploaded;
        bool beacon1_uploaded;
        struct work_struct beacon_update_trigger;
index f50e201..aced986 100644 (file)
@@ -1131,10 +1131,10 @@ struct b43_dmaring *parse_cookie(struct b43_wldev *dev, u16 cookie, int *slot)
 }
 
 static int dma_tx_fragment(struct b43_dmaring *ring,
-                          struct sk_buff *skb,
-                          struct ieee80211_tx_control *ctl)
+                          struct sk_buff *skb)
 {
        const struct b43_dma_ops *ops = ring->ops;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        u8 *header;
        int slot, old_top_slot, old_used_slots;
        int err;
@@ -1158,7 +1158,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
        header = &(ring->txhdr_cache[slot * hdrsize]);
        cookie = generate_cookie(ring, slot);
        err = b43_generate_txhdr(ring->dev, header,
-                                skb->data, skb->len, ctl, cookie);
+                                skb->data, skb->len, info, cookie);
        if (unlikely(err)) {
                ring->current_slot = old_top_slot;
                ring->used_slots = old_used_slots;
@@ -1180,7 +1180,6 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
        desc = ops->idx2desc(ring, slot, &meta);
        memset(meta, 0, sizeof(*meta));
 
-       memcpy(&meta->txstat.control, ctl, sizeof(*ctl));
        meta->skb = skb;
        meta->is_last_fragment = 1;
 
@@ -1210,7 +1209,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
 
        ops->fill_descriptor(ring, desc, meta->dmaaddr, skb->len, 0, 1, 1);
 
-       if (ctl->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM) {
+       if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
                /* Tell the firmware about the cookie of the last
                 * mcast frame, so it can clear the more-data bit in it. */
                b43_shm_write16(ring->dev, B43_SHM_SHARED,
@@ -1281,16 +1280,16 @@ static struct b43_dmaring * select_ring_by_priority(struct b43_wldev *dev,
        return ring;
 }
 
-int b43_dma_tx(struct b43_wldev *dev,
-              struct sk_buff *skb, struct ieee80211_tx_control *ctl)
+int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
 {
        struct b43_dmaring *ring;
        struct ieee80211_hdr *hdr;
        int err = 0;
        unsigned long flags;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
        hdr = (struct ieee80211_hdr *)skb->data;
-       if (ctl->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM) {
+       if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
                /* The multicast ring will be sent after the DTIM */
                ring = dev->dma.tx_ring_mcast;
                /* Set the more-data bit. Ucode will clear it on
@@ -1298,7 +1297,7 @@ int b43_dma_tx(struct b43_wldev *dev,
                hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
        } else {
                /* Decide by priority where to put this frame. */
-               ring = select_ring_by_priority(dev, ctl->queue);
+               ring = select_ring_by_priority(dev, info->queue);
        }
 
        spin_lock_irqsave(&ring->lock, flags);
@@ -1316,9 +1315,9 @@ int b43_dma_tx(struct b43_wldev *dev,
        /* Assign the queue number to the ring (if not already done before)
         * so TX status handling can use it. The queue to ring mapping is
         * static, so we don't need to store it per frame. */
-       ring->queue_prio = ctl->queue;
+       ring->queue_prio = info->queue;
 
-       err = dma_tx_fragment(ring, skb, ctl);
+       err = dma_tx_fragment(ring, skb);
        if (unlikely(err == -ENOKEY)) {
                /* Drop this packet, as we don't have the encryption key
                 * anymore and must not transmit it unencrypted. */
@@ -1334,7 +1333,7 @@ int b43_dma_tx(struct b43_wldev *dev,
        if ((free_slots(ring) < SLOTS_PER_PACKET) ||
            should_inject_overflow(ring)) {
                /* This TX ring is full. */
-               ieee80211_stop_queue(dev->wl->hw, ctl->queue);
+               ieee80211_stop_queue(dev->wl->hw, info->queue);
                ring->stopped = 1;
                if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
                        b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index);
@@ -1377,13 +1376,19 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
                                         b43_txhdr_size(dev), 1);
 
                if (meta->is_last_fragment) {
-                       B43_WARN_ON(!meta->skb);
-                       /* Call back to inform the ieee80211 subsystem about the
-                        * status of the transmission.
-                        * Some fields of txstat are already filled in dma_tx().
+                       struct ieee80211_tx_info *info;
+
+                       BUG_ON(!meta->skb);
+
+                       info = IEEE80211_SKB_CB(meta->skb);
+
+                       memset(&info->status, 0, sizeof(info->status));
+
+                       /*
+                        * Call back to inform the ieee80211 subsystem about
+                        * the status of the transmission.
                         */
-                       frame_succeed = b43_fill_txstatus_report(
-                                               &(meta->txstat), status);
+                       frame_succeed = b43_fill_txstatus_report(info, status);
 #ifdef CONFIG_B43_DEBUG
                        if (frame_succeed)
                                ring->nr_succeed_tx_packets++;
@@ -1391,8 +1396,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
                                ring->nr_failed_tx_packets++;
                        ring->nr_total_packet_tries += status->frame_count;
 #endif /* DEBUG */
-                       ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb,
-                                                   &(meta->txstat));
+                       ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb);
+
                        /* skb is freed by ieee80211_tx_status_irqsafe() */
                        meta->skb = NULL;
                } else {
index 20acf88..d1eb5c0 100644 (file)
@@ -181,7 +181,6 @@ struct b43_dmadesc_meta {
        dma_addr_t dmaaddr;
        /* ieee80211 TX status. Only used once per 802.11 frag. */
        bool is_last_fragment;
-       struct ieee80211_tx_status txstat;
 };
 
 struct b43_dmaring;
@@ -285,7 +284,7 @@ void b43_dma_get_tx_stats(struct b43_wldev *dev,
                          struct ieee80211_tx_queue_stats *stats);
 
 int b43_dma_tx(struct b43_wldev *dev,
-              struct sk_buff *skb, struct ieee80211_tx_control *ctl);
+              struct sk_buff *skb);
 void b43_dma_handle_txstatus(struct b43_wldev *dev,
                             const struct b43_txstatus *status);
 
index e428645..3622d76 100644 (file)
@@ -1368,18 +1368,18 @@ static void b43_write_beacon_template(struct b43_wldev *dev,
        unsigned int rate;
        u16 ctl;
        int antenna;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(dev->wl->current_beacon);
 
        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 = ieee80211_get_tx_rate(dev->wl->hw, &dev->wl->beacon_txctl)->hw_value;
+       rate = ieee80211_get_tx_rate(dev->wl->hw, info)->hw_value;
 
        b43_write_template_common(dev, (const u8 *)bcn,
                                  len, ram_offset, shm_size_offset, rate);
 
        /* Write the PHY TX control parameters. */
-       antenna = b43_antenna_from_ieee80211(dev,
-                       dev->wl->beacon_txctl.antenna_sel_tx);
+       antenna = b43_antenna_from_ieee80211(dev, info->antenna_sel_tx);
        antenna = b43_antenna_to_phyctl(antenna);
        ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL);
        /* We can't send beacons with short preamble. Would get PHY errors. */
@@ -1613,8 +1613,7 @@ static void b43_beacon_update_trigger_work(struct work_struct *work)
 
 /* Asynchronously update the packet templates in template RAM.
  * Locking: Requires wl->irq_lock to be locked. */
-static void b43_update_templates(struct b43_wl *wl, struct sk_buff *beacon,
-                                const struct ieee80211_tx_control *txctl)
+static void b43_update_templates(struct b43_wl *wl, struct sk_buff *beacon)
 {
        /* This is the top half of the ansynchronous beacon update.
         * The bottom half is the beacon IRQ.
@@ -1625,7 +1624,6 @@ static void b43_update_templates(struct b43_wl *wl, struct sk_buff *beacon,
        if (wl->current_beacon)
                dev_kfree_skb_any(wl->current_beacon);
        wl->current_beacon = beacon;
-       memcpy(&wl->beacon_txctl, txctl, sizeof(wl->beacon_txctl));
        wl->beacon0_uploaded = 0;
        wl->beacon1_uploaded = 0;
        queue_work(wl->hw->workqueue, &wl->beacon_update_trigger);
@@ -2813,8 +2811,7 @@ static int b43_rng_init(struct b43_wl *wl)
 }
 
 static int b43_op_tx(struct ieee80211_hw *hw,
-                    struct sk_buff *skb,
-                    struct ieee80211_tx_control *ctl)
+                    struct sk_buff *skb)
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
        struct b43_wldev *dev = wl->current_dev;
@@ -2836,9 +2833,9 @@ static int b43_op_tx(struct ieee80211_hw *hw,
        err = -ENODEV;
        if (likely(b43_status(dev) >= B43_STAT_STARTED)) {
                if (b43_using_pio_transfers(dev))
-                       err = b43_pio_tx(dev, skb, ctl);
+                       err = b43_pio_tx(dev, skb);
                else
-                       err = b43_dma_tx(dev, skb, ctl);
+                       err = b43_dma_tx(dev, skb);
        }
 
        read_unlock_irqrestore(&wl->tx_lock, flags);
@@ -3429,10 +3426,8 @@ static int b43_op_config_interface(struct ieee80211_hw *hw,
                if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP)) {
                        B43_WARN_ON(conf->type != IEEE80211_IF_TYPE_AP);
                        b43_set_ssid(dev, conf->ssid, conf->ssid_len);
-                       if (conf->beacon) {
-                               b43_update_templates(wl, conf->beacon,
-                                                    conf->beacon_control);
-                       }
+                       if (conf->beacon)
+                               b43_update_templates(wl, conf->beacon);
                }
                b43_write_mac_bssid_templates(dev);
        }
@@ -4118,31 +4113,29 @@ static int b43_op_beacon_set_tim(struct ieee80211_hw *hw, int aid, int set)
        struct b43_wl *wl = hw_to_b43_wl(hw);
        struct sk_buff *beacon;
        unsigned long flags;
-       struct ieee80211_tx_control txctl;
 
        /* We could modify the existing beacon and set the aid bit in
         * the TIM field, but that would probably require resizing and
         * moving of data within the beacon template.
         * Simply request a new beacon and let mac80211 do the hard work. */
-       beacon = ieee80211_beacon_get(hw, wl->vif, &txctl);
+       beacon = ieee80211_beacon_get(hw, wl->vif);
        if (unlikely(!beacon))
                return -ENOMEM;
        spin_lock_irqsave(&wl->irq_lock, flags);
-       b43_update_templates(wl, beacon, &txctl);
+       b43_update_templates(wl, beacon);
        spin_unlock_irqrestore(&wl->irq_lock, flags);
 
        return 0;
 }
 
 static int b43_op_ibss_beacon_update(struct ieee80211_hw *hw,
-                                    struct sk_buff *beacon,
-                                    struct ieee80211_tx_control *ctl)
+                                    struct sk_buff *beacon)
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
        unsigned long flags;
 
        spin_lock_irqsave(&wl->irq_lock, flags);
-       b43_update_templates(wl, beacon, ctl);
+       b43_update_templates(wl, beacon);
        spin_unlock_irqrestore(&wl->irq_lock, flags);
 
        return 0;
index 08c8a08..284786a 100644 (file)
@@ -446,29 +446,27 @@ static void pio_tx_frame_4byte_queue(struct b43_pio_txpacket *pack,
 }
 
 static int pio_tx_frame(struct b43_pio_txqueue *q,
-                       struct sk_buff *skb,
-                       struct ieee80211_tx_control *ctl)
+                       struct sk_buff *skb)
 {
        struct b43_pio_txpacket *pack;
        struct b43_txhdr txhdr;
        u16 cookie;
        int err;
        unsigned int hdrlen;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
        B43_WARN_ON(list_empty(&q->packets_list));
        pack = list_entry(q->packets_list.next,
                          struct b43_pio_txpacket, list);
-       memset(&pack->txstat, 0, sizeof(pack->txstat));
-       memcpy(&pack->txstat.control, ctl, sizeof(*ctl));
 
        cookie = generate_cookie(q, pack);
        hdrlen = b43_txhdr_size(q->dev);
        err = b43_generate_txhdr(q->dev, (u8 *)&txhdr, skb->data,
-                                skb->len, ctl, cookie);
+                                skb->len, info, cookie);
        if (err)
                return err;
 
-       if (ctl->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM) {
+       if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
                /* Tell the firmware about the cookie of the last
                 * mcast frame, so it can clear the more-data bit in it. */
                b43_shm_write16(q->dev, B43_SHM_SHARED,
@@ -492,17 +490,18 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
        return 0;
 }
 
-int b43_pio_tx(struct b43_wldev *dev,
-              struct sk_buff *skb, struct ieee80211_tx_control *ctl)
+int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
 {
        struct b43_pio_txqueue *q;
        struct ieee80211_hdr *hdr;
        unsigned long flags;
        unsigned int hdrlen, total_len;
        int err = 0;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
        hdr = (struct ieee80211_hdr *)skb->data;
-       if (ctl->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM) {
+
+       if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
                /* The multicast queue will be sent after the DTIM. */
                q = dev->pio.tx_queue_mcast;
                /* Set the frame More-Data bit. Ucode will clear it
@@ -510,7 +509,7 @@ int b43_pio_tx(struct b43_wldev *dev,
                hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
        } else {
                /* Decide by priority where to put this frame. */
-               q = select_queue_by_priority(dev, ctl->queue);
+               q = select_queue_by_priority(dev, info->queue);
        }
 
        spin_lock_irqsave(&q->lock, flags);
@@ -533,7 +532,7 @@ int b43_pio_tx(struct b43_wldev *dev,
        if (total_len > (q->buffer_size - q->buffer_used)) {
                /* Not enough memory on the queue. */
                err = -EBUSY;
-               ieee80211_stop_queue(dev->wl->hw, ctl->queue);
+               ieee80211_stop_queue(dev->wl->hw, info->queue);
                q->stopped = 1;
                goto out_unlock;
        }
@@ -541,9 +540,9 @@ int b43_pio_tx(struct b43_wldev *dev,
        /* Assign the queue number to the ring (if not already done before)
         * so TX status handling can use it. The mac80211-queue to b43-queue
         * mapping is static, so we don't need to store it per frame. */
-       q->queue_prio = ctl->queue;
+       q->queue_prio = info->queue;
 
-       err = pio_tx_frame(q, skb, ctl);
+       err = pio_tx_frame(q, skb);
        if (unlikely(err == -ENOKEY)) {
                /* Drop this packet, as we don't have the encryption key
                 * anymore and must not transmit it unencrypted. */
@@ -561,7 +560,7 @@ int b43_pio_tx(struct b43_wldev *dev,
        if (((q->buffer_size - q->buffer_used) < roundup(2 + 2 + 6, 4)) ||
            (q->free_packet_slots == 0)) {
                /* The queue is full. */
-               ieee80211_stop_queue(dev->wl->hw, ctl->queue);
+               ieee80211_stop_queue(dev->wl->hw, info->queue);
                q->stopped = 1;
        }
 
@@ -578,6 +577,7 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev,
        struct b43_pio_txqueue *q;
        struct b43_pio_txpacket *pack = NULL;
        unsigned int total_len;
+       struct ieee80211_tx_info *info;
 
        q = parse_cookie(dev, status->cookie, &pack);
        if (unlikely(!q))
@@ -586,15 +586,17 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev,
 
        spin_lock(&q->lock); /* IRQs are already disabled. */
 
-       b43_fill_txstatus_report(&(pack->txstat), status);
+       info = (void *)pack->skb;
+       memset(&info->status, 0, sizeof(info->status));
+
+       b43_fill_txstatus_report(info, status);
 
        total_len = pack->skb->len + b43_txhdr_size(dev);
        total_len = roundup(total_len, 4);
        q->buffer_used -= total_len;
        q->free_packet_slots += 1;
 
-       ieee80211_tx_status_irqsafe(dev->wl->hw, pack->skb,
-                                   &(pack->txstat));
+       ieee80211_tx_status_irqsafe(dev->wl->hw, pack->skb);
        pack->skb = NULL;
        list_add(&pack->list, &q->packets_list);
 
index e2ec676..6c174c9 100644 (file)
@@ -62,8 +62,6 @@ struct b43_pio_txpacket {
        struct b43_pio_txqueue *queue;
        /* The TX data packet. */
        struct sk_buff *skb;
-       /* The status meta data. */
-       struct ieee80211_tx_status txstat;
        /* Index in the (struct b43_pio_txqueue)->packets array. */
        u8 index;
 
@@ -167,8 +165,7 @@ int b43_pio_init(struct b43_wldev *dev);
 void b43_pio_stop(struct b43_wldev *dev);
 void b43_pio_free(struct b43_wldev *dev);
 
-int b43_pio_tx(struct b43_wldev *dev,
-              struct sk_buff *skb, struct ieee80211_tx_control *ctl);
+int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb);
 void b43_pio_handle_txstatus(struct b43_wldev *dev,
                             const struct b43_txstatus *status);
 void b43_pio_get_tx_stats(struct b43_wldev *dev,
@@ -193,8 +190,7 @@ static inline void b43_pio_stop(struct b43_wldev *dev)
 {
 }
 static inline int b43_pio_tx(struct b43_wldev *dev,
-                            struct sk_buff *skb,
-                            struct ieee80211_tx_control *ctl)
+                            struct sk_buff *skb)
 {
        return 0;
 }
index 9b682a3..f9e1cff 100644 (file)
@@ -185,14 +185,14 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                       u8 *_txhdr,
                       const unsigned char *fragment_data,
                       unsigned int fragment_len,
-                      const struct ieee80211_tx_control *txctl,
+                      const struct ieee80211_tx_info *info,
                       u16 cookie)
 {
        struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr;
        const struct b43_phy *phy = &dev->phy;
        const struct ieee80211_hdr *wlhdr =
            (const struct ieee80211_hdr *)fragment_data;
-       int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT));
+       int use_encryption = (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT));
        u16 fctl = le16_to_cpu(wlhdr->frame_control);
        struct ieee80211_rate *fbrate;
        u8 rate, rate_fb;
@@ -205,10 +205,10 @@ int b43_generate_txhdr(struct b43_wldev *dev,
 
        memset(txhdr, 0, sizeof(*txhdr));
 
-       txrate = ieee80211_get_tx_rate(dev->wl->hw, txctl);
+       txrate = ieee80211_get_tx_rate(dev->wl->hw, info);
        rate = txrate ? txrate->hw_value : B43_CCK_RATE_1MB;
        rate_ofdm = b43_is_ofdm_rate(rate);
-       fbrate = ieee80211_get_alt_retry_rate(dev->wl->hw, txctl) ? : txrate;
+       fbrate = ieee80211_get_alt_retry_rate(dev->wl->hw, info) ? : txrate;
        rate_fb = fbrate->hw_value;
        rate_fb_ofdm = b43_is_ofdm_rate(rate_fb);
 
@@ -228,15 +228,13 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                 * use the original dur_id field. */
                txhdr->dur_fb = wlhdr->duration_id;
        } else {
-               txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw,
-                                                                txctl->vif,
-                                                                fragment_len,
-                                                                fbrate);
+               txhdr->dur_fb = ieee80211_generic_frame_duration(
+                       dev->wl->hw, info->control.vif, fragment_len, fbrate);
        }
 
        plcp_fragment_len = fragment_len + FCS_LEN;
        if (use_encryption) {
-               u8 key_idx = txctl->hw_key->hw_key_idx;
+               u8 key_idx = info->control.hw_key->hw_key_idx;
                struct b43_key *key;
                int wlhdr_len;
                size_t iv_len;
@@ -254,7 +252,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                }
 
                /* Hardware appends ICV. */
-               plcp_fragment_len += txctl->icv_len;
+               plcp_fragment_len += info->control.icv_len;
 
                key_idx = b43_kidx_to_fw(dev, key_idx);
                mac_ctl |= (key_idx << B43_TXH_MAC_KEYIDX_SHIFT) &
@@ -262,7 +260,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) &
                           B43_TXH_MAC_KEYALG;
                wlhdr_len = ieee80211_get_hdrlen(fctl);
-               iv_len = min((size_t) txctl->iv_len,
+               iv_len = min((size_t) info->control.iv_len,
                             ARRAY_SIZE(txhdr->iv));
                memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
        }
@@ -293,10 +291,10 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                phy_ctl |= B43_TXH_PHY_ENC_OFDM;
        else
                phy_ctl |= B43_TXH_PHY_ENC_CCK;
-       if (txctl->flags & IEEE80211_TXCTL_SHORT_PREAMBLE)
+       if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE)
                phy_ctl |= B43_TXH_PHY_SHORTPRMBL;
 
-       switch (b43_ieee80211_antenna_sanitize(dev, txctl->antenna_sel_tx)) {
+       switch (b43_ieee80211_antenna_sanitize(dev, info->antenna_sel_tx)) {
        case 0: /* Default */
                phy_ctl |= B43_TXH_PHY_ANT01AUTO;
                break;
@@ -317,21 +315,21 @@ int b43_generate_txhdr(struct b43_wldev *dev,
        }
 
        /* MAC control */
-       if (!(txctl->flags & IEEE80211_TXCTL_NO_ACK))
+       if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
                mac_ctl |= B43_TXH_MAC_ACK;
        if (!(((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
              ((fctl & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)))
                mac_ctl |= B43_TXH_MAC_HWSEQ;
-       if (txctl->flags & IEEE80211_TXCTL_FIRST_FRAGMENT)
+       if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
                mac_ctl |= B43_TXH_MAC_STMSDU;
        if (phy->type == B43_PHYTYPE_A)
                mac_ctl |= B43_TXH_MAC_5GHZ;
-       if (txctl->flags & IEEE80211_TXCTL_LONG_RETRY_LIMIT)
+       if (info->flags & IEEE80211_TX_CTL_LONG_RETRY_LIMIT)
                mac_ctl |= B43_TXH_MAC_LONGFRAME;
 
        /* Generate the RTS or CTS-to-self frame */
-       if ((txctl->flags & IEEE80211_TXCTL_USE_RTS_CTS) ||
-           (txctl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) {
+       if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
+           (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) {
                unsigned int len;
                struct ieee80211_hdr *hdr;
                int rts_rate, rts_rate_fb;
@@ -339,14 +337,14 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                struct b43_plcp_hdr6 *plcp;
                struct ieee80211_rate *rts_cts_rate;
 
-               rts_cts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, txctl);
+               rts_cts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info);
 
                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);
 
-               if (txctl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
+               if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
                        struct ieee80211_cts *cts;
 
                        if (b43_is_old_txhdr_format(dev)) {
@@ -356,9 +354,9 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                                cts = (struct ieee80211_cts *)
                                        (txhdr->new_format.rts_frame);
                        }
-                       ieee80211_ctstoself_get(dev->wl->hw, txctl->vif,
+                       ieee80211_ctstoself_get(dev->wl->hw, info->control.vif,
                                                fragment_data, fragment_len,
-                                               txctl, cts);
+                                               info, cts);
                        mac_ctl |= B43_TXH_MAC_SENDCTS;
                        len = sizeof(struct ieee80211_cts);
                } else {
@@ -371,9 +369,9 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                                rts = (struct ieee80211_rts *)
                                        (txhdr->new_format.rts_frame);
                        }
-                       ieee80211_rts_get(dev->wl->hw, txctl->vif,
+                       ieee80211_rts_get(dev->wl->hw, info->control.vif,
                                          fragment_data, fragment_len,
-                                         txctl, rts);
+                                         info, rts);
                        mac_ctl |= B43_TXH_MAC_SENDRTS;
                        len = sizeof(struct ieee80211_rts);
                }
@@ -687,27 +685,27 @@ void b43_handle_txstatus(struct b43_wldev *dev,
 /* Fill out the mac80211 TXstatus report based on the b43-specific
  * txstatus report data. This returns a boolean whether the frame was
  * successfully transmitted. */
-bool b43_fill_txstatus_report(struct ieee80211_tx_status *report,
+bool b43_fill_txstatus_report(struct ieee80211_tx_info *report,
                              const struct b43_txstatus *status)
 {
        bool frame_success = 1;
 
        if (status->acked) {
                /* The frame was ACKed. */
-               report->flags |= IEEE80211_TX_STATUS_ACK;
+               report->flags |= IEEE80211_TX_STAT_ACK;
        } else {
                /* The frame was not ACKed... */
-               if (!(report->control.flags & IEEE80211_TXCTL_NO_ACK)) {
+               if (!(report->flags & IEEE80211_TX_CTL_NO_ACK)) {
                        /* ...but we expected an ACK. */
                        frame_success = 0;
-                       report->excessive_retries = 1;
+                       report->status.excessive_retries = 1;
                }
        }
        if (status->frame_count == 0) {
                /* The frame was not transmitted at all. */
-               report->retry_count = 0;
+               report->status.retry_count = 0;
        } else
-               report->retry_count = status->frame_count - 1;
+               report->status.retry_count = status->frame_count - 1;
 
        return frame_success;
 }
index b05f44e..0215faf 100644 (file)
@@ -178,7 +178,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                       u8 * txhdr,
                       const unsigned char *fragment_data,
                       unsigned int fragment_len,
-                      const struct ieee80211_tx_control *txctl, u16 cookie);
+                      const struct ieee80211_tx_info *txctl, u16 cookie);
 
 /* Transmit Status */
 struct b43_txstatus {
@@ -294,7 +294,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr);
 
 void b43_handle_txstatus(struct b43_wldev *dev,
                         const struct b43_txstatus *status);
-bool b43_fill_txstatus_report(struct ieee80211_tx_status *report,
+bool b43_fill_txstatus_report(struct ieee80211_tx_info *report,
                              const struct b43_txstatus *status);
 
 void b43_tx_suspend(struct b43_wldev *dev);
index d6686f7..c1c501d 100644 (file)
@@ -1205,10 +1205,10 @@ struct b43legacy_dmaring *parse_cookie(struct b43legacy_wldev *dev,
 }
 
 static int dma_tx_fragment(struct b43legacy_dmaring *ring,
-                           struct sk_buff *skb,
-                           struct ieee80211_tx_control *ctl)
+                           struct sk_buff *skb)
 {
        const struct b43legacy_dma_ops *ops = ring->ops;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        u8 *header;
        int slot, old_top_slot, old_used_slots;
        int err;
@@ -1231,7 +1231,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
        header = &(ring->txhdr_cache[slot * sizeof(
                               struct b43legacy_txhdr_fw3)]);
        err = b43legacy_generate_txhdr(ring->dev, header,
-                                skb->data, skb->len, ctl,
+                                skb->data, skb->len, info,
                                 generate_cookie(ring, slot));
        if (unlikely(err)) {
                ring->current_slot = old_top_slot;
@@ -1255,7 +1255,6 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
        desc = ops->idx2desc(ring, slot, &meta);
        memset(meta, 0, sizeof(*meta));
 
-       memcpy(&meta->txstat.control, ctl, sizeof(*ctl));
        meta->skb = skb;
        meta->is_last_fragment = 1;
 
@@ -1323,14 +1322,14 @@ int should_inject_overflow(struct b43legacy_dmaring *ring)
 }
 
 int b43legacy_dma_tx(struct b43legacy_wldev *dev,
-                    struct sk_buff *skb,
-                    struct ieee80211_tx_control *ctl)
+                    struct sk_buff *skb)
 {
        struct b43legacy_dmaring *ring;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        int err = 0;
        unsigned long flags;
 
-       ring = priority_to_txring(dev, ctl->queue);
+       ring = priority_to_txring(dev, info->queue);
        spin_lock_irqsave(&ring->lock, flags);
        B43legacy_WARN_ON(!ring->tx);
        if (unlikely(free_slots(ring) < SLOTS_PER_PACKET)) {
@@ -1343,7 +1342,7 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
         * That would be a mac80211 bug. */
        B43legacy_BUG_ON(ring->stopped);
 
-       err = dma_tx_fragment(ring, skb, ctl);
+       err = dma_tx_fragment(ring, skb);
        if (unlikely(err == -ENOKEY)) {
                /* Drop this packet, as we don't have the encryption key
                 * anymore and must not transmit it unencrypted. */
@@ -1401,26 +1400,29 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
                                         1);
 
                if (meta->is_last_fragment) {
-                       B43legacy_WARN_ON(!meta->skb);
+                       struct ieee80211_tx_info *info;
+                       BUG_ON(!meta->skb);
+                       info = IEEE80211_SKB_CB(meta->skb);
                        /* Call back to inform the ieee80211 subsystem about the
                         * status of the transmission.
                         * Some fields of txstat are already filled in dma_tx().
                         */
+
+                       memset(&info->status, 0, sizeof(info->status));
+
                        if (status->acked) {
-                               meta->txstat.flags |= IEEE80211_TX_STATUS_ACK;
+                               info->flags |= IEEE80211_TX_STAT_ACK;
                        } else {
-                               if (!(meta->txstat.control.flags
-                                     & IEEE80211_TXCTL_NO_ACK))
-                                        meta->txstat.excessive_retries = 1;
+                               if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
+                                        info->status.excessive_retries = 1;
                        }
                        if (status->frame_count == 0) {
                                /* The frame was not transmitted at all. */
-                               meta->txstat.retry_count = 0;
+                               info->status.retry_count = 0;
                        } else
-                               meta->txstat.retry_count = status->frame_count
+                               info->status.retry_count = status->frame_count
                                                           - 1;
-                       ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb,
-                                                   &(meta->txstat));
+                       ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb);
                        /* skb is freed by ieee80211_tx_status_irqsafe() */
                        meta->skb = NULL;
                } else {
index 2dd488c..67537a7 100644 (file)
@@ -195,7 +195,6 @@ struct b43legacy_dmadesc_meta {
        dma_addr_t dmaaddr;
        /* ieee80211 TX status. Only used once per 802.11 frag. */
        bool is_last_fragment;
-       struct ieee80211_tx_status txstat;
 };
 
 struct b43legacy_dmaring;
@@ -297,8 +296,7 @@ void b43legacy_dma_get_tx_stats(struct b43legacy_wldev *dev,
                                struct ieee80211_tx_queue_stats *stats);
 
 int b43legacy_dma_tx(struct b43legacy_wldev *dev,
-                    struct sk_buff *skb,
-                    struct ieee80211_tx_control *ctl);
+                    struct sk_buff *skb);
 void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
                                   const struct b43legacy_txstatus *status);
 
index b05a507..f706ca6 100644 (file)
@@ -2358,8 +2358,7 @@ static int b43legacy_rng_init(struct b43legacy_wl *wl)
 }
 
 static int b43legacy_op_tx(struct ieee80211_hw *hw,
-                          struct sk_buff *skb,
-                          struct ieee80211_tx_control *ctl)
+                          struct sk_buff *skb)
 {
        struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
        struct b43legacy_wldev *dev = wl->current_dev;
@@ -2373,10 +2372,10 @@ static int b43legacy_op_tx(struct ieee80211_hw *hw,
        /* DMA-TX is done without a global lock. */
        if (b43legacy_using_pio(dev)) {
                spin_lock_irqsave(&wl->irq_lock, flags);
-               err = b43legacy_pio_tx(dev, skb, ctl);
+               err = b43legacy_pio_tx(dev, skb);
                spin_unlock_irqrestore(&wl->irq_lock, flags);
        } else
-               err = b43legacy_dma_tx(dev, skb, ctl);
+               err = b43legacy_dma_tx(dev, skb);
 out:
        if (unlikely(err))
                return NETDEV_TX_BUSY;
@@ -3409,7 +3408,7 @@ static int b43legacy_op_beacon_set_tim(struct ieee80211_hw *hw,
         * field, but that would probably require resizing and moving of data
         * within the beacon template. Simply request a new beacon and let
         * mac80211 do the hard work. */
-       beacon = ieee80211_beacon_get(hw, wl->vif, NULL);
+       beacon = ieee80211_beacon_get(hw, wl->vif);
        if (unlikely(!beacon))
                return -ENOMEM;
        spin_lock_irqsave(&wl->irq_lock, flags);
@@ -3420,8 +3419,7 @@ static int b43legacy_op_beacon_set_tim(struct ieee80211_hw *hw,
 }
 
 static int b43legacy_op_ibss_beacon_update(struct ieee80211_hw *hw,
-                                          struct sk_buff *beacon,
-                                          struct ieee80211_tx_control *ctl)
+                                          struct sk_buff *beacon)
 {
        struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
        unsigned long flags;
index 8d3d27d..a86c764 100644 (file)
@@ -196,7 +196,7 @@ static int pio_tx_write_fragment(struct b43legacy_pioqueue *queue,
        B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags != 0);
        err = b43legacy_generate_txhdr(queue->dev,
                                 txhdr, skb->data, skb->len,
-                                &packet->txstat.control,
+                                IEEE80211_SKB_CB(skb),
                                 generate_cookie(queue, packet));
        if (err)
                return err;
@@ -463,8 +463,7 @@ err_destroy0:
 }
 
 int b43legacy_pio_tx(struct b43legacy_wldev *dev,
-                    struct sk_buff *skb,
-                    struct ieee80211_tx_control *ctl)
+                    struct sk_buff *skb)
 {
        struct b43legacy_pioqueue *queue = dev->pio.queue1;
        struct b43legacy_pio_txpacket *packet;
@@ -476,9 +475,6 @@ int b43legacy_pio_tx(struct b43legacy_wldev *dev,
                            list);
        packet->skb = skb;
 
-       memset(&packet->txstat, 0, sizeof(packet->txstat));
-       memcpy(&packet->txstat.control, ctl, sizeof(*ctl));
-
        list_move_tail(&packet->list, &queue->txqueue);
        queue->nr_txfree--;
        queue->nr_tx_packets++;
@@ -494,6 +490,7 @@ void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev,
 {
        struct b43legacy_pioqueue *queue;
        struct b43legacy_pio_txpacket *packet;
+       struct ieee80211_tx_info *info;
 
        queue = parse_cookie(dev, status->cookie, &packet);
        B43legacy_WARN_ON(!queue);
@@ -505,11 +502,13 @@ void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev,
        queue->tx_devq_used -= (packet->skb->len +
                                sizeof(struct b43legacy_txhdr_fw3));
 
+       info = IEEE80211_SKB_CB(packet->skb);
+       memset(&info->status, 0, sizeof(info->status));
+
        if (status->acked)
-               packet->txstat.flags |= IEEE80211_TX_STATUS_ACK;
-       packet->txstat.retry_count = status->frame_count - 1;
-       ieee80211_tx_status_irqsafe(dev->wl->hw, packet->skb,
-                                   &(packet->txstat));
+               info->flags |= IEEE80211_TX_STAT_ACK;
+       info->status.retry_count = status->frame_count - 1;
+       ieee80211_tx_status_irqsafe(dev->wl->hw, packet->skb);
        packet->skb = NULL;
 
        free_txpacket(packet, 1);
index 5bfed0c..49310df 100644 (file)
@@ -41,7 +41,6 @@ struct b43legacy_xmitstatus;
 struct b43legacy_pio_txpacket {
        struct b43legacy_pioqueue *queue;
        struct sk_buff *skb;
-       struct ieee80211_tx_status txstat;
        struct list_head list;
 };
 
@@ -104,8 +103,7 @@ int b43legacy_pio_init(struct b43legacy_wldev *dev);
 void b43legacy_pio_free(struct b43legacy_wldev *dev);
 
 int b43legacy_pio_tx(struct b43legacy_wldev *dev,
-                  struct sk_buff *skb,
-                  struct ieee80211_tx_control *ctl);
+                  struct sk_buff *skb);
 void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev,
                                 const struct b43legacy_txstatus *status);
 void b43legacy_pio_get_tx_stats(struct b43legacy_wldev *dev,
index 55dc251..82dc04d 100644 (file)
@@ -188,11 +188,11 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
                               struct b43legacy_txhdr_fw3 *txhdr,
                               const unsigned char *fragment_data,
                               unsigned int fragment_len,
-                              const struct ieee80211_tx_control *txctl,
+                              const struct ieee80211_tx_info *info,
                               u16 cookie)
 {
        const struct ieee80211_hdr *wlhdr;
-       int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT));
+       int use_encryption = (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT));
        u16 fctl;
        u8 rate;
        struct ieee80211_rate *rate_fb;
@@ -208,11 +208,11 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
 
        memset(txhdr, 0, sizeof(*txhdr));
 
-       tx_rate = ieee80211_get_tx_rate(dev->wl->hw, txctl);
+       tx_rate = ieee80211_get_tx_rate(dev->wl->hw, info);
 
        rate = tx_rate->hw_value;
        rate_ofdm = b43legacy_is_ofdm_rate(rate);
-       rate_fb = ieee80211_get_alt_retry_rate(dev->wl->hw, txctl) ? : tx_rate;
+       rate_fb = ieee80211_get_alt_retry_rate(dev->wl->hw, info) ? : tx_rate;
        rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb->hw_value);
 
        txhdr->mac_frame_ctl = wlhdr->frame_control;
@@ -228,14 +228,14 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
                txhdr->dur_fb = wlhdr->duration_id;
        } else {
                txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw,
-                                                        txctl->vif,
+                                                        info->control.vif,
                                                         fragment_len,
                                                         rate_fb);
        }
 
        plcp_fragment_len = fragment_len + FCS_LEN;
        if (use_encryption) {
-               u8 key_idx = txctl->hw_key->hw_key_idx;
+               u8 key_idx = info->control.hw_key->hw_key_idx;
                struct b43legacy_key *key;
                int wlhdr_len;
                size_t iv_len;
@@ -245,7 +245,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
 
                if (key->enabled) {
                        /* Hardware appends ICV. */
-                       plcp_fragment_len += txctl->icv_len;
+                       plcp_fragment_len += info->control.icv_len;
 
                        key_idx = b43legacy_kidx_to_fw(dev, key_idx);
                        mac_ctl |= (key_idx << B43legacy_TX4_MAC_KEYIDX_SHIFT) &
@@ -254,7 +254,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
                                   B43legacy_TX4_MAC_KEYALG_SHIFT) &
                                   B43legacy_TX4_MAC_KEYALG;
                        wlhdr_len = ieee80211_get_hdrlen(fctl);
-                       iv_len = min((size_t)txctl->iv_len,
+                       iv_len = min((size_t)info->control.iv_len,
                                     ARRAY_SIZE(txhdr->iv));
                        memcpy(txhdr->iv, ((u8 *)wlhdr) + wlhdr_len, iv_len);
                } else {
@@ -278,7 +278,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
                phy_ctl |= B43legacy_TX4_PHY_OFDM;
        if (dev->short_preamble)
                phy_ctl |= B43legacy_TX4_PHY_SHORTPRMBL;
-       switch (txctl->antenna_sel_tx) {
+       switch (info->antenna_sel_tx) {
        case 0:
                phy_ctl |= B43legacy_TX4_PHY_ANTLAST;
                break;
@@ -293,21 +293,21 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
        }
 
        /* MAC control */
-       if (!(txctl->flags & IEEE80211_TXCTL_NO_ACK))
+       if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
                mac_ctl |= B43legacy_TX4_MAC_ACK;
        if (!(((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
              ((fctl & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)))
                mac_ctl |= B43legacy_TX4_MAC_HWSEQ;
-       if (txctl->flags & IEEE80211_TXCTL_FIRST_FRAGMENT)
+       if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
                mac_ctl |= B43legacy_TX4_MAC_STMSDU;
        if (rate_fb_ofdm)
                mac_ctl |= B43legacy_TX4_MAC_FALLBACKOFDM;
-       if (txctl->flags & IEEE80211_TXCTL_LONG_RETRY_LIMIT)
+       if (info->flags & IEEE80211_TX_CTL_LONG_RETRY_LIMIT)
                mac_ctl |= B43legacy_TX4_MAC_LONGFRAME;
 
        /* Generate the RTS or CTS-to-self frame */
-       if ((txctl->flags & IEEE80211_TXCTL_USE_RTS_CTS) ||
-           (txctl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) {
+       if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
+           (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) {
                unsigned int len;
                struct ieee80211_hdr *hdr;
                int rts_rate;
@@ -315,26 +315,26 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
                int rts_rate_ofdm;
                int rts_rate_fb_ofdm;
 
-               rts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, txctl)->hw_value;
+               rts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info)->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);
                if (rts_rate_fb_ofdm)
                        mac_ctl |= B43legacy_TX4_MAC_CTSFALLBACKOFDM;
 
-               if (txctl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
+               if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
                        ieee80211_ctstoself_get(dev->wl->hw,
-                                               txctl->vif,
+                                               info->control.vif,
                                                fragment_data,
-                                               fragment_len, txctl,
+                                               fragment_len, info,
                                                (struct ieee80211_cts *)
                                                (txhdr->rts_frame));
                        mac_ctl |= B43legacy_TX4_MAC_SENDCTS;
                        len = sizeof(struct ieee80211_cts);
                } else {
                        ieee80211_rts_get(dev->wl->hw,
-                                         txctl->vif,
-                                         fragment_data, fragment_len, txctl,
+                                         info->control.vif,
+                                         fragment_data, fragment_len, info,
                                          (struct ieee80211_rts *)
                                          (txhdr->rts_frame));
                        mac_ctl |= B43legacy_TX4_MAC_SENDRTS;
@@ -365,12 +365,12 @@ int b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
                              u8 *txhdr,
                              const unsigned char *fragment_data,
                              unsigned int fragment_len,
-                             const struct ieee80211_tx_control *txctl,
+                             const struct ieee80211_tx_info *info,
                              u16 cookie)
 {
        return generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr,
                           fragment_data, fragment_len,
-                          txctl, cookie);
+                          info, cookie);
 }
 
 static s8 b43legacy_rssi_postprocess(struct b43legacy_wldev *dev,
index bab4792..e56777e 100644 (file)
@@ -80,7 +80,7 @@ int b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
                              u8 *txhdr,
                              const unsigned char *fragment_data,
                              unsigned int fragment_len,
-                             const struct ieee80211_tx_control *txctl,
+                             const struct ieee80211_tx_info *info,
                              u16 cookie);
 
 
index f3ca02f..10c64bd 100644 (file)
@@ -445,8 +445,7 @@ static int rs_adjust_next_rate(struct iwl3945_priv *priv, int rate)
  */
 static void rs_tx_status(void *priv_rate,
                         struct net_device *dev,
-                        struct sk_buff *skb,
-                        struct ieee80211_tx_status *tx_resp)
+                        struct sk_buff *skb)
 {
        u8 retries, current_count;
        int scale_rate_index, first_index, last_index;
@@ -457,14 +456,15 @@ static void rs_tx_status(void *priv_rate,
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct iwl3945_rs_sta *rs_sta;
        struct ieee80211_supported_band *sband;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
        IWL_DEBUG_RATE("enter\n");
 
        sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
 
 
-       retries = tx_resp->retry_count;
-       first_index = sband->bitrates[tx_resp->control.tx_rate_idx].hw_value;
+       retries = info->status.retry_count;
+       first_index = sband->bitrates[info->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;
@@ -525,11 +525,11 @@ static void rs_tx_status(void *priv_rate,
        /* Update the last index window with success/failure based on ACK */
        IWL_DEBUG_RATE("Update rate %d with %s.\n",
                       last_index,
-                      (tx_resp->flags & IEEE80211_TX_STATUS_ACK) ?
+                      (info->flags & IEEE80211_TX_STAT_ACK) ?
                       "success" : "failure");
        iwl3945_collect_tx_data(rs_sta,
                            &rs_sta->win[last_index],
-                           tx_resp->flags & IEEE80211_TX_STATUS_ACK, 1);
+                           info->flags & IEEE80211_TX_STAT_ACK, 1);
 
        /* We updated the rate scale window -- if its been more than
         * flush_time since the last run, schedule the flush
index f8e691f..0ba6889 100644 (file)
@@ -283,8 +283,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv,
                q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
 
                tx_info = &txq->txb[txq->q.read_ptr];
-               ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0],
-                                           &tx_info->status);
+               ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]);
                tx_info->skb[0] = NULL;
                iwl3945_hw_txq_free_tfd(priv, txq);
        }
@@ -306,7 +305,7 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
        int txq_id = SEQ_TO_QUEUE(sequence);
        int index = SEQ_TO_INDEX(sequence);
        struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
-       struct ieee80211_tx_status *tx_status;
+       struct ieee80211_tx_info *info;
        struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
        u32  status = le32_to_cpu(tx_resp->status);
        int rate_idx;
@@ -319,21 +318,22 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
                return;
        }
 
-       tx_status = &(txq->txb[txq->q.read_ptr].status);
+       info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);
+       memset(&info->status, 0, sizeof(info->status));
 
-       tx_status->retry_count = tx_resp->failure_frame;
+       info->status.retry_count = tx_resp->failure_frame;
        /* tx_status->rts_retry_count = tx_resp->failure_rts; */
-       tx_status->flags = ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ?
-                               IEEE80211_TX_STATUS_ACK : 0;
+       info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ?
+                               IEEE80211_TX_STAT_ACK : 0;
 
        IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n",
                        txq_id, iwl3945_get_tx_fail_reason(status), status,
                        tx_resp->rate, tx_resp->failure_frame);
 
        rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate);
-       if (tx_status->control.band == IEEE80211_BAND_5GHZ)
+       if (info->band == IEEE80211_BAND_5GHZ)
                rate_idx -= IWL_FIRST_OFDM_RATE;
-       tx_status->control.tx_rate_idx = rate_idx;
+       info->tx_rate_idx = rate_idx;
        IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
        iwl3945_tx_queue_reclaim(priv, txq_id, index);
 
@@ -960,11 +960,11 @@ u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr)
 */
 void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
                              struct iwl3945_cmd *cmd,
-                             struct ieee80211_tx_control *ctrl,
+                             struct ieee80211_tx_info *info,
                              struct ieee80211_hdr *hdr, int sta_id, int tx_id)
 {
        unsigned long flags;
-       u16 hw_value = ieee80211_get_tx_rate(priv->hw, ctrl)->hw_value;
+       u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value;
        u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1);
        u16 rate_mask;
        int rate;
@@ -977,7 +977,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
        tx_flags = cmd->cmd.tx.tx_flags;
 
        /* We need to figure out how to get the sta->supp_rates while
-        * in this running context; perhaps encoding into ctrl->tx_rate? */
+        * in this running context */
        rate_mask = IWL_RATES_MASK;
 
        spin_lock_irqsave(&priv->sta_lock, flags);
index 9fdc140..835c5b4 100644 (file)
@@ -124,7 +124,6 @@ int iwl3945_x2_queue_used(const struct iwl3945_queue *q, int i);
 
 /* One for each TFD */
 struct iwl3945_tx_info {
-       struct ieee80211_tx_status status;
        struct sk_buff *skb[MAX_NUM_OF_TBS];
 };
 
@@ -645,7 +644,7 @@ extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
 extern int iwl3945_hw_get_rx_read(struct iwl3945_priv *priv);
 extern void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
                                     struct iwl3945_cmd *cmd,
-                                    struct ieee80211_tx_control *ctrl,
+                                    struct ieee80211_tx_info *info,
                                     struct ieee80211_hdr *hdr,
                                     int sta_id, int tx_id);
 extern int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv);
index 7993a1d..f28b3cc 100644 (file)
@@ -785,8 +785,7 @@ out:
  * mac80211 sends us Tx status
  */
 static void rs_tx_status(void *priv_rate, struct net_device *dev,
-                        struct sk_buff *skb,
-                        struct ieee80211_tx_status *tx_resp)
+                        struct sk_buff *skb)
 {
        int status;
        u8 retries;
@@ -798,6 +797,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
        struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_hw *hw = local_to_hw(local);
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct iwl4965_rate_scale_data *window = NULL;
        struct iwl4965_rate_scale_data *search_win = NULL;
        u32 tx_rate;
@@ -813,11 +813,11 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
                return;
 
        /* This packet was aggregated but doesn't carry rate scale info */
-       if ((tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) &&
-           !(tx_resp->flags & IEEE80211_TX_STATUS_AMPDU))
+       if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
+           !(info->flags & IEEE80211_TX_STAT_AMPDU))
                return;
 
-       retries = tx_resp->retry_count;
+       retries = info->status.retry_count;
 
        if (retries > 15)
                retries = 15;
@@ -862,20 +862,20 @@ 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_idx < 0) ||
+       if ((info->tx_rate_idx < 0) ||
            (tbl_type.is_SGI ^
-               !!(tx_resp->control.flags & IEEE80211_TXCTL_SHORT_GI)) ||
+               !!(info->flags & IEEE80211_TX_CTL_SHORT_GI)) ||
            (tbl_type.is_fat ^
-               !!(tx_resp->control.flags & IEEE80211_TXCTL_40_MHZ_WIDTH)) ||
+               !!(info->flags & IEEE80211_TX_CTL_40_MHZ_WIDTH)) ||
            (tbl_type.is_dup ^
-               !!(tx_resp->control.flags & IEEE80211_TXCTL_DUP_DATA)) ||
-           (tbl_type.ant_type ^ tx_resp->control.antenna_sel_tx) ||
+               !!(info->flags & IEEE80211_TX_CTL_DUP_DATA)) ||
+           (tbl_type.ant_type ^ info->antenna_sel_tx) ||
            (!!(tx_rate & RATE_MCS_HT_MSK) ^
-               !!(tx_resp->control.flags & IEEE80211_TXCTL_OFDM_HT)) ||
+               !!(info->flags & IEEE80211_TX_CTL_OFDM_HT)) ||
            (!!(tx_rate & RATE_MCS_GF_MSK) ^
-               !!(tx_resp->control.flags & IEEE80211_TXCTL_GREEN_FIELD)) ||
+               !!(info->flags & IEEE80211_TX_CTL_GREEN_FIELD)) ||
            (hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate !=
-            hw->wiphy->bands[tx_resp->control.band]->bitrates[tx_resp->control.tx_rate_idx].bitrate)) {
+            hw->wiphy->bands[info->band]->bitrates[info->tx_rate_idx].bitrate)) {
                IWL_DEBUG_RATE("initial rate does not match 0x%x\n", tx_rate);
                goto out;
        }
@@ -929,10 +929,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
        rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index);
 
        /* Update frame history window with "success" if Tx got ACKed ... */
-       if (tx_resp->flags & IEEE80211_TX_STATUS_ACK)
-               status = 1;
-       else
-               status = 0;
+       status = !!(info->flags & IEEE80211_TX_STAT_ACK);
 
        /* If type matches "search" table,
         * add final tx status to "search" history */
@@ -943,10 +940,10 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
                        tpt = search_tbl->expected_tpt[rs_index];
                else
                        tpt = 0;
-               if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU)
+               if (info->flags & IEEE80211_TX_CTL_AMPDU)
                        rs_collect_tx_data(search_win, rs_index, tpt,
-                                          tx_resp->ampdu_ack_len,
-                                          tx_resp->ampdu_ack_map);
+                                          info->status.ampdu_ack_len,
+                                          info->status.ampdu_ack_map);
                else
                        rs_collect_tx_data(search_win, rs_index, tpt,
                                           1, status);
@@ -959,10 +956,10 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
                        tpt = curr_tbl->expected_tpt[rs_index];
                else
                        tpt = 0;
-               if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU)
+               if (info->flags & IEEE80211_TX_CTL_AMPDU)
                        rs_collect_tx_data(window, rs_index, tpt,
-                                          tx_resp->ampdu_ack_len,
-                                          tx_resp->ampdu_ack_map);
+                                          info->status.ampdu_ack_len,
+                                          info->status.ampdu_ack_map);
                else
                        rs_collect_tx_data(window, rs_index, tpt,
                                           1, status);
@@ -971,10 +968,10 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
        /* If not searching for new mode, increment success/failed counter
         * ... these help determine when to start searching again */
        if (lq_sta->stay_in_tbl) {
-               if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) {
-                       lq_sta->total_success += tx_resp->ampdu_ack_map;
+               if (info->flags & IEEE80211_TX_CTL_AMPDU) {
+                       lq_sta->total_success += info->status.ampdu_ack_map;
                        lq_sta->total_failed +=
-                            (tx_resp->ampdu_ack_len - tx_resp->ampdu_ack_map);
+                            (info->status.ampdu_ack_len - info->status.ampdu_ack_map);
                } else {
                        if (status)
                                lq_sta->total_success++;
index fb670b5..ca9ca92 100644 (file)
@@ -357,22 +357,22 @@ int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags)
  * translate ucode response to mac80211 tx status control values
  */
 void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
-                                 struct ieee80211_tx_control *control)
+                                 struct ieee80211_tx_info *control)
 {
        int rate_index;
 
        control->antenna_sel_tx =
                ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);
        if (rate_n_flags & RATE_MCS_HT_MSK)
-               control->flags |= IEEE80211_TXCTL_OFDM_HT;
+               control->flags |= IEEE80211_TX_CTL_OFDM_HT;
        if (rate_n_flags & RATE_MCS_GF_MSK)
-               control->flags |= IEEE80211_TXCTL_GREEN_FIELD;
+               control->flags |= IEEE80211_TX_CTL_GREEN_FIELD;
        if (rate_n_flags & RATE_MCS_FAT_MSK)
-               control->flags |= IEEE80211_TXCTL_40_MHZ_WIDTH;
+               control->flags |= IEEE80211_TX_CTL_40_MHZ_WIDTH;
        if (rate_n_flags & RATE_MCS_DUP_MSK)
-               control->flags |= IEEE80211_TXCTL_DUP_DATA;
+               control->flags |= IEEE80211_TX_CTL_DUP_DATA;
        if (rate_n_flags & RATE_MCS_SGI_MSK)
-               control->flags |= IEEE80211_TXCTL_SHORT_GI;
+               control->flags |= IEEE80211_TX_CTL_SHORT_GI;
        rate_index = iwl4965_hwrate_to_plcp_idx(rate_n_flags);
        if (control->band == IEEE80211_BAND_5GHZ)
                rate_index -= IWL_FIRST_OFDM_RATE;
@@ -3007,7 +3007,7 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv,
        u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
        u64 bitmap;
        int successes = 0;
-       struct ieee80211_tx_status *tx_status;
+       struct ieee80211_tx_info *info;
 
        if (unlikely(!agg->wait_for_ba))  {
                IWL_ERROR("Received BA when not expected\n");
@@ -3045,13 +3045,13 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv,
                        agg->start_idx + i);
        }
 
-       tx_status = &priv->txq[scd_flow].txb[agg->start_idx].status;
-       tx_status->flags = IEEE80211_TX_STATUS_ACK;
-       tx_status->flags |= IEEE80211_TX_STATUS_AMPDU;
-       tx_status->ampdu_ack_map = successes;
-       tx_status->ampdu_ack_len = agg->frame_count;
-       iwl4965_hwrate_to_tx_control(priv, agg->rate_n_flags,
-                                    &tx_status->control);
+       info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb[0]);
+       memset(&info->status, 0, sizeof(info->status));
+       info->flags = IEEE80211_TX_STAT_ACK;
+       info->flags |= IEEE80211_TX_STAT_AMPDU;
+       info->status.ampdu_ack_map = successes;
+       info->status.ampdu_ack_len = agg->frame_count;
+       iwl4965_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
 
        IWL_DEBUG_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap);
 
index a8d062f..ad7422e 100644 (file)
@@ -207,8 +207,7 @@ void iwl_rx_allocate(struct iwl_priv *priv);
 * TX
 ******************************************************/
 int iwl_txq_ctx_reset(struct iwl_priv *priv);
-int iwl_tx_skb(struct iwl_priv *priv,
-               struct sk_buff *skb, struct ieee80211_tx_control *ctl);
+int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
 /* FIXME: remove when free Tx is fully merged into iwlcore */
 int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
 void iwl_hw_txq_ctx_free(struct iwl_priv *priv);
index 820542b..f7fd8ea 100644 (file)
@@ -119,7 +119,6 @@ struct iwl_queue {
 
 /* One for each TFD */
 struct iwl_tx_info {
-       struct ieee80211_tx_status status;
        struct sk_buff *skb[MAX_NUM_OF_TBS];
 };
 
@@ -693,7 +692,7 @@ extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
                                 struct iwl_frame *frame, u8 rate);
 extern void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv,
                                     struct iwl_cmd *cmd,
-                                    struct ieee80211_tx_control *ctrl,
+                                    struct ieee80211_tx_info *info,
                                     struct ieee80211_hdr *hdr,
                                     int sta_id, int tx_id);
 extern int iwl4965_hw_reg_send_txpower(struct iwl_priv *priv);
@@ -749,7 +748,7 @@ extern void iwl4965_update_rate_scaling(struct iwl_priv *priv, u8 mode);
 extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv);
 extern void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv,
                                         u32 rate_n_flags,
-                                        struct ieee80211_tx_control *control);
+                                        struct ieee80211_tx_info *info);
 
 #ifdef CONFIG_IWL4965_HT
 extern void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv,
index 4b5149c..a61293b 100644 (file)
@@ -502,7 +502,7 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
  */
 static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
                                  struct iwl_tx_cmd *tx_cmd,
-                                 struct ieee80211_tx_control *ctrl,
+                                 struct ieee80211_tx_info *info,
                                  struct ieee80211_hdr *hdr,
                                  int is_unicast, u8 std_id)
 {
@@ -510,7 +510,7 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
        __le32 tx_flags = tx_cmd->tx_flags;
 
        tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
-       if (!(ctrl->flags & IEEE80211_TXCTL_NO_ACK)) {
+       if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
                tx_flags |= TX_CMD_FLG_ACK_MSK;
                if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)
                        tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
@@ -538,10 +538,10 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
                tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
        }
 
-       if (ctrl->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
+       if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
                tx_flags |= TX_CMD_FLG_RTS_MSK;
                tx_flags &= ~TX_CMD_FLG_CTS_MSK;
-       } else if (ctrl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
+       } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
                tx_flags &= ~TX_CMD_FLG_RTS_MSK;
                tx_flags |= TX_CMD_FLG_CTS_MSK;
        }
@@ -570,7 +570,7 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
 
 static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
                              struct iwl_tx_cmd *tx_cmd,
-                             struct ieee80211_tx_control *ctrl,
+                             struct ieee80211_tx_info *info,
                              u16 fc, int sta_id,
                              int is_hcca)
 {
@@ -580,7 +580,7 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
        u16 rate_flags = 0;
        int rate_idx;
 
-       rate_idx = min(ieee80211_get_tx_rate(priv->hw, ctrl)->hw_value & 0xffff,
+       rate_idx = min(ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xffff,
                        IWL_RATE_COUNT - 1);
 
        rate_plcp = iwl_rates[rate_idx].plcp;
@@ -637,18 +637,18 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
 }
 
 static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
-                                     struct ieee80211_tx_control *ctl,
+                                     struct ieee80211_tx_info *info,
                                      struct iwl_tx_cmd *tx_cmd,
                                      struct sk_buff *skb_frag,
                                      int sta_id)
 {
-       struct ieee80211_key_conf *keyconf = ctl->hw_key;
+       struct ieee80211_key_conf *keyconf = info->control.hw_key;
 
        switch (keyconf->alg) {
        case ALG_CCMP:
                tx_cmd->sec_ctl = TX_CMD_SEC_CCM;
                memcpy(tx_cmd->key, keyconf->key, keyconf->keylen);
-               if (ctl->flags & IEEE80211_TXCTL_AMPDU)
+               if (info->flags & IEEE80211_TX_CTL_AMPDU)
                        tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK;
                IWL_DEBUG_TX("tx_cmd with aes hwcrypto\n");
                break;
@@ -690,13 +690,13 @@ static void iwl_update_tx_stats(struct iwl_priv *priv, u16 fc, u16 len)
 /*
  * start REPLY_TX command process
  */
-int iwl_tx_skb(struct iwl_priv *priv,
-               struct sk_buff *skb, struct ieee80211_tx_control *ctl)
+int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct iwl_tfd_frame *tfd;
        u32 *control_flags;
-       int txq_id = ctl->queue;
+       int txq_id = info->queue;
        struct iwl_tx_queue *txq = NULL;
        struct iwl_queue *q = NULL;
        dma_addr_t phys_addr;
@@ -726,7 +726,7 @@ int iwl_tx_skb(struct iwl_priv *priv,
                goto drop_unlock;
        }
 
-       if ((ieee80211_get_tx_rate(priv->hw, ctl)->hw_value & 0xFF) ==
+       if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) ==
             IWL_INVALID_RATE) {
                IWL_ERROR("ERROR: No TX rate available.\n");
                goto drop_unlock;
@@ -782,7 +782,7 @@ int iwl_tx_skb(struct iwl_priv *priv,
                seq_number += 0x10;
 #ifdef CONFIG_IWL4965_HT
                /* aggregation is on for this <sta,tid> */
-               if (ctl->flags & IEEE80211_TXCTL_AMPDU)
+               if (info->flags & IEEE80211_TX_CTL_AMPDU)
                        txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
                priv->stations[sta_id].tid[tid].tfds_in_queue++;
 #endif /* CONFIG_IWL4965_HT */
@@ -803,8 +803,6 @@ int iwl_tx_skb(struct iwl_priv *priv,
        /* Set up driver data for this TFD */
        memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
        txq->txb[q->write_ptr].skb[0] = skb;
-       memcpy(&(txq->txb[q->write_ptr].status.control),
-              ctl, sizeof(struct ieee80211_tx_control));
 
        /* Set up first empty entry in queue's array of Tx/cmd buffers */
        out_cmd = &txq->cmd[idx];
@@ -854,8 +852,8 @@ int iwl_tx_skb(struct iwl_priv *priv,
         * first entry */
        iwl_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
 
-       if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT))
-               iwl_tx_cmd_build_hwcrypto(priv, ctl, tx_cmd, skb, sta_id);
+       if (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT))
+               iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
 
        /* Set up TFD's 2nd entry to point directly to remainder of skb,
         * if any (802.11 null frames have no payload). */
@@ -874,10 +872,10 @@ int iwl_tx_skb(struct iwl_priv *priv,
        len = (u16)skb->len;
        tx_cmd->len = cpu_to_le16(len);
        /* TODO need this for burst mode later on */
-       iwl_tx_cmd_build_basic(priv, tx_cmd, ctl, hdr, unicast, sta_id);
+       iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, unicast, sta_id);
 
        /* set is_hcca to 0; it probably will never be implemented */
-       iwl_tx_cmd_build_rate(priv, tx_cmd, ctl, fc, sta_id, 0);
+       iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0);
 
        iwl_update_tx_stats(priv, fc, len);
 
@@ -919,7 +917,7 @@ int iwl_tx_skb(struct iwl_priv *priv,
                        spin_unlock_irqrestore(&priv->lock, flags);
                }
 
-               ieee80211_stop_queue(priv->hw, ctl->queue);
+               ieee80211_stop_queue(priv->hw, info->queue);
        }
 
        return 0;
index a28b4c9..a740a18 100644 (file)
@@ -2376,13 +2376,13 @@ static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode)
 }
 
 static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv,
-                                     struct ieee80211_tx_control *ctl,
+                                     struct ieee80211_tx_info *info,
                                      struct iwl3945_cmd *cmd,
                                      struct sk_buff *skb_frag,
                                      int last_frag)
 {
        struct iwl3945_hw_key *keyinfo =
-           &priv->stations[ctl->hw_key->hw_key_idx].keyinfo;
+           &priv->stations[info->control.hw_key->hw_key_idx].keyinfo;
 
        switch (keyinfo->alg) {
        case ALG_CCMP:
@@ -2405,7 +2405,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv,
 
        case ALG_WEP:
                cmd->cmd.tx.sec_ctl = TX_CMD_SEC_WEP |
-                   (ctl->hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT;
+                   (info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT;
 
                if (keyinfo->keylen == 13)
                        cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128;
@@ -2413,7 +2413,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv,
                memcpy(&cmd->cmd.tx.key[3], keyinfo->key, keyinfo->keylen);
 
                IWL_DEBUG_TX("Configuring packet for WEP encryption "
-                            "with key %d\n", ctl->hw_key->hw_key_idx);
+                            "with key %d\n", info->control.hw_key->hw_key_idx);
                break;
 
        default:
@@ -2427,7 +2427,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv,
  */
 static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
                                  struct iwl3945_cmd *cmd,
-                                 struct ieee80211_tx_control *ctrl,
+                                 struct ieee80211_tx_info *info,
                                  struct ieee80211_hdr *hdr,
                                  int is_unicast, u8 std_id)
 {
@@ -2435,7 +2435,7 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
        __le32 tx_flags = cmd->cmd.tx.tx_flags;
 
        cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
-       if (!(ctrl->flags & IEEE80211_TXCTL_NO_ACK)) {
+       if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
                tx_flags |= TX_CMD_FLG_ACK_MSK;
                if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)
                        tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
@@ -2459,10 +2459,10 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
                tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
        }
 
-       if (ctrl->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
+       if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
                tx_flags |= TX_CMD_FLG_RTS_MSK;
                tx_flags &= ~TX_CMD_FLG_CTS_MSK;
-       } else if (ctrl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
+       } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
                tx_flags &= ~TX_CMD_FLG_RTS_MSK;
                tx_flags |= TX_CMD_FLG_CTS_MSK;
        }
@@ -2546,13 +2546,13 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
 /*
  * start REPLY_TX command process
  */
-static int iwl3945_tx_skb(struct iwl3945_priv *priv,
-                     struct sk_buff *skb, struct ieee80211_tx_control *ctl)
+static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct iwl3945_tfd_frame *tfd;
        u32 *control_flags;
-       int txq_id = ctl->queue;
+       int txq_id = info->queue;
        struct iwl3945_tx_queue *txq = NULL;
        struct iwl3945_queue *q = NULL;
        dma_addr_t phys_addr;
@@ -2581,7 +2581,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
                goto drop_unlock;
        }
 
-       if ((ieee80211_get_tx_rate(priv->hw, ctl)->hw_value & 0xFF) == IWL_INVALID_RATE) {
+       if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) {
                IWL_ERROR("ERROR: No TX rate available.\n");
                goto drop_unlock;
        }
@@ -2650,8 +2650,6 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
        /* Set up driver data for this TFD */
        memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl3945_tx_info));
        txq->txb[q->write_ptr].skb[0] = skb;
-       memcpy(&(txq->txb[q->write_ptr].status.control),
-              ctl, sizeof(struct ieee80211_tx_control));
 
        /* Init first empty entry in queue's array of Tx/cmd buffers */
        out_cmd = &txq->cmd[idx];
@@ -2700,8 +2698,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
         * first entry */
        iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
 
-       if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT))
-               iwl3945_build_tx_cmd_hwcrypto(priv, ctl, out_cmd, skb, 0);
+       if (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT))
+               iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, 0);
 
        /* Set up TFD's 2nd entry to point directly to remainder of skb,
         * if any (802.11 null frames have no payload). */
@@ -2726,10 +2724,10 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
        out_cmd->cmd.tx.len = cpu_to_le16(len);
 
        /* TODO need this for burst mode later on */
-       iwl3945_build_tx_cmd_basic(priv, out_cmd, ctl, hdr, unicast, sta_id);
+       iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, unicast, sta_id);
 
        /* set is_hcca to 0; it probably will never be implemented */
-       iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, ctl, hdr, sta_id, 0);
+       iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0);
 
        out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
        out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
@@ -2767,7 +2765,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
                        spin_unlock_irqrestore(&priv->lock, flags);
                }
 
-               ieee80211_stop_queue(priv->hw, ctl->queue);
+               ieee80211_stop_queue(priv->hw, info->queue);
        }
 
        return 0;
@@ -3230,7 +3228,7 @@ static void iwl3945_bg_beacon_update(struct work_struct *work)
        struct sk_buff *beacon;
 
        /* Pull updated AP beacon from mac80211. will fail if not in AP mode */
-       beacon = ieee80211_beacon_get(priv->hw, priv->vif, NULL);
+       beacon = ieee80211_beacon_get(priv->hw, priv->vif);
 
        if (!beacon) {
                IWL_ERROR("update beacon failed\n");
@@ -6681,8 +6679,7 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw)
        IWL_DEBUG_MAC80211("leave\n");
 }
 
-static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
-                     struct ieee80211_tx_control *ctl)
+static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct iwl3945_priv *priv = hw->priv;
 
@@ -6694,9 +6691,9 @@ 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,
-                    ieee80211_get_tx_rate(hw, ctl)->bitrate);
+                    ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
 
-       if (iwl3945_tx_skb(priv, skb, ctl))
+       if (iwl3945_tx_skb(priv, skb))
                dev_kfree_skb_any(skb);
 
        IWL_DEBUG_MAC80211("leave\n");
@@ -7333,8 +7330,7 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
 
 }
 
-static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
-                                struct ieee80211_tx_control *control)
+static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct iwl3945_priv *priv = hw->priv;
        unsigned long flags;
index 1fad622..07c52b6 100644 (file)
@@ -1606,17 +1606,7 @@ static int iwl4965_get_measurement(struct iwl_priv *priv,
 static void iwl4965_txstatus_to_ieee(struct iwl_priv *priv,
                                     struct iwl_tx_info *tx_sta)
 {
-
-       tx_sta->status.ack_signal = 0;
-       tx_sta->status.excessive_retries = 0;
-
-       if (in_interrupt())
-               ieee80211_tx_status_irqsafe(priv->hw,
-                                           tx_sta->skb[0], &(tx_sta->status));
-       else
-               ieee80211_tx_status(priv->hw,
-                                   tx_sta->skb[0], &(tx_sta->status));
-
+       ieee80211_tx_status_irqsafe(priv->hw, tx_sta->skb[0]);
        tx_sta->skb[0] = NULL;
 }
 
@@ -1710,7 +1700,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
 {
        u16 status;
        struct agg_tx_status *frame_status = &tx_resp->status;
-       struct ieee80211_tx_status *tx_status = NULL;
+       struct ieee80211_tx_info *info = NULL;
        struct ieee80211_hdr *hdr = NULL;
        int i, sh;
        int txq_id, idx;
@@ -1736,14 +1726,14 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
                IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
                                   agg->frame_count, agg->start_idx, idx);
 
-               tx_status = &(priv->txq[txq_id].txb[idx].status);
-               tx_status->retry_count = tx_resp->failure_frame;
-               tx_status->control.flags &= ~IEEE80211_TXCTL_AMPDU;
-               tx_status->flags = iwl4965_is_tx_success(status)?
-                       IEEE80211_TX_STATUS_ACK : 0;
+               info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
+               info->status.retry_count = tx_resp->failure_frame;
+               info->flags &= ~IEEE80211_TX_CTL_AMPDU;
+               info->flags |= iwl4965_is_tx_success(status)?
+                       IEEE80211_TX_STAT_ACK : 0;
                iwl4965_hwrate_to_tx_control(priv,
                                             le32_to_cpu(tx_resp->rate_n_flags),
-                                            &tx_status->control);
+                                            info);
                /* FIXME: code repetition end */
 
                IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",
@@ -1830,7 +1820,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
        int txq_id = SEQ_TO_QUEUE(sequence);
        int index = SEQ_TO_INDEX(sequence);
        struct iwl_tx_queue *txq = &priv->txq[txq_id];
-       struct ieee80211_tx_status *tx_status;
+       struct ieee80211_tx_info *info;
        struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
        u32  status = le32_to_cpu(tx_resp->status);
 #ifdef CONFIG_IWL4965_HT
@@ -1848,6 +1838,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
                return;
        }
 
+       info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);
+       memset(&info->status, 0, sizeof(info->status));
+
 #ifdef CONFIG_IWL4965_HT
        hdr = iwl4965_tx_queue_get_hdr(priv, txq_id, index);
        fc = le16_to_cpu(hdr->frame_control);
@@ -1902,13 +1895,12 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
                }
        } else {
 #endif /* CONFIG_IWL4965_HT */
-       tx_status = &(txq->txb[txq->q.read_ptr].status);
 
-       tx_status->retry_count = tx_resp->failure_frame;
-       tx_status->flags =
-           iwl4965_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0;
+       info->status.retry_count = tx_resp->failure_frame;
+       info->flags |=
+           iwl4965_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0;
        iwl4965_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),
-                                    &tx_status->control);
+                                    info);
 
        IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x "
                     "retries %d\n", txq_id, iwl4965_get_tx_fail_reason(status),
@@ -2053,7 +2045,7 @@ static void iwl4965_bg_beacon_update(struct work_struct *work)
        struct sk_buff *beacon;
 
        /* Pull updated AP beacon from mac80211. will fail if not in AP mode */
-       beacon = ieee80211_beacon_get(priv->hw, priv->vif, NULL);
+       beacon = ieee80211_beacon_get(priv->hw, priv->vif);
 
        if (!beacon) {
                IWL_ERROR("update beacon failed\n");
@@ -4268,8 +4260,7 @@ static void iwl4965_mac_stop(struct ieee80211_hw *hw)
        IWL_DEBUG_MAC80211("leave\n");
 }
 
-static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
-                     struct ieee80211_tx_control *ctl)
+static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct iwl_priv *priv = hw->priv;
 
@@ -4281,9 +4272,9 @@ 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,
-                    ieee80211_get_tx_rate(hw, ctl)->bitrate);
+                    ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
 
-       if (iwl_tx_skb(priv, skb, ctl))
+       if (iwl_tx_skb(priv, skb))
                dev_kfree_skb_any(skb);
 
        IWL_DEBUG_MAC80211("leave\n");
@@ -5065,8 +5056,7 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
        IWL_DEBUG_MAC80211("leave\n");
 }
 
-static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
-                                struct ieee80211_tx_control *control)
+static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct iwl_priv *priv = hw->priv;
        unsigned long flags;
index 3ca9386..8508579 100644 (file)
@@ -394,7 +394,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
        while (entry != (struct sk_buff *)&priv->tx_queue) {
                range = (struct memrecord *)&entry->cb;
                if (range->start_addr == addr) {
-                       struct ieee80211_tx_status status;
+                       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry);
                        struct p54_control_hdr *entry_hdr;
                        struct p54_tx_control_allocdata *entry_data;
                        int pad = 0;
@@ -406,30 +406,23 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
 
                        last_addr = range->end_addr;
                        __skb_unlink(entry, &priv->tx_queue);
-                       if (!range->control) {
-                               kfree_skb(entry);
-                               break;
-                       }
-                       memset(&status, 0, sizeof(status));
-                       memcpy(&status.control, range->control,
-                              sizeof(status.control));
-                       kfree(range->control);
-                       priv->tx_stats[status.control.queue].len--;
+                       memset(&info->status, 0, sizeof(info->status));
+                       priv->tx_stats[info->queue].len--;
                        entry_hdr = (struct p54_control_hdr *) entry->data;
                        entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data;
                        if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0)
                                pad = entry_data->align[0];
 
-                       if (!(status.control.flags & IEEE80211_TXCTL_NO_ACK)) {
+                       if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
                                if (!(payload->status & 0x01))
-                                       status.flags |= IEEE80211_TX_STATUS_ACK;
+                                       info->flags |= IEEE80211_TX_STAT_ACK;
                                else
-                                       status.excessive_retries = 1;
+                                       info->status.excessive_retries = 1;
                        }
-                       status.retry_count = payload->retries - 1;
-                       status.ack_signal = le16_to_cpu(payload->ack_rssi);
+                       info->status.retry_count = payload->retries - 1;
+                       info->status.ack_signal = le16_to_cpu(payload->ack_rssi);
                        skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data));
-                       ieee80211_tx_status_irqsafe(dev, entry, &status);
+                       ieee80211_tx_status_irqsafe(dev, entry);
                        break;
                } else
                        last_addr = range->end_addr;
@@ -494,13 +487,11 @@ EXPORT_SYMBOL_GPL(p54_rx);
  * allocated areas.
  */
 static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
-                              struct p54_control_hdr *data, u32 len,
-                              struct ieee80211_tx_control *control)
+                              struct p54_control_hdr *data, u32 len)
 {
        struct p54_common *priv = dev->priv;
        struct sk_buff *entry = priv->tx_queue.next;
        struct sk_buff *target_skb = NULL;
-       struct memrecord *range;
        u32 last_addr = priv->rx_start;
        u32 largest_hole = 0;
        u32 target_addr = priv->rx_start;
@@ -512,7 +503,8 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
        left = skb_queue_len(&priv->tx_queue);
        while (left--) {
                u32 hole_size;
-               range = (struct memrecord *)&entry->cb;
+               struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry);
+               struct memrecord *range = (void *)info->driver_data;
                hole_size = range->start_addr - last_addr;
                if (!target_skb && hole_size >= len) {
                        target_skb = entry->prev;
@@ -527,17 +519,18 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
                target_skb = priv->tx_queue.prev;
                largest_hole = max(largest_hole, priv->rx_end - last_addr - len);
                if (!skb_queue_empty(&priv->tx_queue)) {
-                       range = (struct memrecord *)&target_skb->cb;
+                       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(target_skb);
+                       struct memrecord *range = (void *)info->driver_data;
                        target_addr = range->end_addr;
                }
        } else
                largest_hole = max(largest_hole, priv->rx_end - last_addr);
 
        if (skb) {
-               range = (struct memrecord *)&skb->cb;
+               struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+               struct memrecord *range = (void *)info->driver_data;
                range->start_addr = target_addr;
                range->end_addr = target_addr + len;
-               range->control = control;
                __skb_queue_after(&priv->tx_queue, target_skb, skb);
                if (largest_hole < IEEE80211_MAX_RTS_THRESHOLD + 0x170 +
                                   sizeof(struct p54_control_hdr))
@@ -548,32 +541,27 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
        data->req_id = cpu_to_le32(target_addr + 0x70);
 }
 
-static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
-                 struct ieee80211_tx_control *control)
+static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ieee80211_tx_queue_stats *current_queue;
        struct p54_common *priv = dev->priv;
        struct p54_control_hdr *hdr;
        struct p54_tx_control_allocdata *txhdr;
-       struct ieee80211_tx_control *control_copy;
        size_t padding, len;
        u8 rate;
 
-       current_queue = &priv->tx_stats[control->queue];
+       current_queue = &priv->tx_stats[info->queue];
        if (unlikely(current_queue->len > current_queue->limit))
                return NETDEV_TX_BUSY;
        current_queue->len++;
        current_queue->count++;
        if (current_queue->len == current_queue->limit)
-               ieee80211_stop_queue(dev, control->queue);
+               ieee80211_stop_queue(dev, info->queue);
 
        padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3;
        len = skb->len;
 
-       control_copy = kmalloc(sizeof(*control), GFP_ATOMIC);
-       if (control_copy)
-               memcpy(control_copy, control, sizeof(*control));
-
        txhdr = (struct p54_tx_control_allocdata *)
                        skb_push(skb, sizeof(*txhdr) + padding);
        hdr = (struct p54_control_hdr *) skb_push(skb, sizeof(*hdr));
@@ -583,35 +571,37 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
        else
                hdr->magic1 = cpu_to_le16(0x0010);
        hdr->len = cpu_to_le16(len);
-       hdr->type = (control->flags & IEEE80211_TXCTL_NO_ACK) ? 0 : cpu_to_le16(1);
-       hdr->retry1 = hdr->retry2 = control->retry_limit;
-       p54_assign_address(dev, skb, hdr, skb->len, control_copy);
+       hdr->type = (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 0 : cpu_to_le16(1);
+       hdr->retry1 = hdr->retry2 = info->control.retry_limit;
 
        memset(txhdr->wep_key, 0x0, 16);
        txhdr->padding = 0;
        txhdr->padding2 = 0;
 
        /* TODO: add support for alternate retry TX rates */
-       rate = ieee80211_get_tx_rate(dev, control)->hw_value;
-       if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE)
+       rate = ieee80211_get_tx_rate(dev, info)->hw_value;
+       if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE)
                rate |= 0x10;
-       if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
+       if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
                rate |= 0x40;
-       else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
+       else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
                rate |= 0x20;
        memset(txhdr->rateset, rate, 8);
        txhdr->wep_key_present = 0;
        txhdr->wep_key_len = 0;
-       txhdr->frame_type = cpu_to_le32(control->queue + 4);
+       txhdr->frame_type = cpu_to_le32(info->queue + 4);
        txhdr->magic4 = 0;
-       txhdr->antenna = (control->antenna_sel_tx == 0) ?
-               2 : control->antenna_sel_tx - 1;
+       txhdr->antenna = (info->antenna_sel_tx == 0) ?
+               2 : info->antenna_sel_tx - 1;
        txhdr->output_power = 0x7f; // HW Maximum
-       txhdr->magic5 = (control->flags & IEEE80211_TXCTL_NO_ACK) ?
+       txhdr->magic5 = (info->flags & IEEE80211_TX_CTL_NO_ACK) ?
                0 : ((rate > 0x3) ? cpu_to_le32(0x33) : cpu_to_le32(0x23));
        if (padding)
                txhdr->align[0] = padding;
 
+       /* modifies skb->cb and with it info, so must be last! */
+       p54_assign_address(dev, skb, hdr, skb->len);
+
        priv->tx(dev, hdr, skb->len, 0);
        return 0;
 }
@@ -634,7 +624,7 @@ static int p54_set_filter(struct ieee80211_hw *dev, u16 filter_type,
        filter = (struct p54_tx_control_filter *) hdr->data;
        hdr->magic1 = cpu_to_le16(0x8001);
        hdr->len = cpu_to_le16(sizeof(*filter));
-       p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*filter), NULL);
+       p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*filter));
        hdr->type = cpu_to_le16(P54_CONTROL_TYPE_FILTER_SET);
 
        filter->filter_type = cpu_to_le16(filter_type);
@@ -678,7 +668,7 @@ static int p54_set_freq(struct ieee80211_hw *dev, __le16 freq)
        hdr->magic1 = cpu_to_le16(0x8001);
        hdr->len = cpu_to_le16(sizeof(*chan));
        hdr->type = cpu_to_le16(P54_CONTROL_TYPE_CHANNEL_CHANGE);
-       p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + payload_len, NULL);
+       p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + payload_len);
 
        chan->magic1 = cpu_to_le16(0x1);
        chan->magic2 = cpu_to_le16(0x0);
@@ -751,7 +741,7 @@ static int p54_set_leds(struct ieee80211_hw *dev, int mode, int link, int act)
        hdr->magic1 = cpu_to_le16(0x8001);
        hdr->len = cpu_to_le16(sizeof(*led));
        hdr->type = cpu_to_le16(P54_CONTROL_TYPE_LED);
-       p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*led), NULL);
+       p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*led));
 
        led = (struct p54_tx_control_led *) hdr->data;
        led->mode = cpu_to_le16(mode);
@@ -801,7 +791,7 @@ static void p54_set_vdcf(struct ieee80211_hw *dev)
 
        hdr = (void *)priv->cached_vdcf + priv->tx_hdr_len;
 
-       p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*vdcf), NULL);
+       p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*vdcf));
 
        vdcf = (struct p54_tx_control_vdcf *) hdr->data;
 
@@ -837,12 +827,8 @@ static void p54_stop(struct ieee80211_hw *dev)
 {
        struct p54_common *priv = dev->priv;
        struct sk_buff *skb;
-       while ((skb = skb_dequeue(&priv->tx_queue))) {
-               struct memrecord *range = (struct memrecord *)&skb->cb;
-               if (range->control)
-                       kfree(range->control);
+       while ((skb = skb_dequeue(&priv->tx_queue)))
                kfree_skb(skb);
-       }
        priv->stop(dev);
        priv->mode = IEEE80211_IF_TYPE_INVALID;
 }
index c15b56e..2245fcc 100644 (file)
@@ -152,7 +152,6 @@ struct pda_pa_curve_data {
 struct memrecord {
        u32 start_addr;
        u32 end_addr;
-       struct ieee80211_tx_control *control;
 };
 
 struct p54_eeprom_lm86 {
index 4fcba9b..900140d 100644 (file)
@@ -1484,11 +1484,11 @@ static u64 rt2400pci_get_tsf(struct ieee80211_hw *hw)
        return tsf;
 }
 
-static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
-                                  struct ieee80211_tx_control *control)
+static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
-       struct rt2x00_intf *intf = vif_to_intf(control->vif);
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
        struct queue_entry_priv_pci *entry_priv;
        struct skb_frame_desc *skbdesc;
        struct txentry_desc txdesc;
@@ -1504,7 +1504,7 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
         * for our information.
         */
        intf->beacon->skb = skb;
-       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc, control);
+       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc);
 
        /*
         * Fill in skb descriptor
index 06e87cd..6733509 100644 (file)
@@ -1799,11 +1799,11 @@ static u64 rt2500pci_get_tsf(struct ieee80211_hw *hw)
        return tsf;
 }
 
-static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
-                                  struct ieee80211_tx_control *control)
+static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
-       struct rt2x00_intf *intf = vif_to_intf(control->vif);
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
        struct queue_entry_priv_pci *entry_priv;
        struct skb_frame_desc *skbdesc;
        struct txentry_desc txdesc;
@@ -1820,7 +1820,7 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
         * for our information.
         */
        intf->beacon->skb = skb;
-       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc, control);
+       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc);
 
        /*
         * Fill in skb descriptor
index 4122c5e..cca1504 100644 (file)
@@ -1666,13 +1666,12 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 /*
  * IEEE80211 stack callback functions.
  */
-static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
-                                  struct sk_buff *skb,
-                                  struct ieee80211_tx_control *control)
+static int rt2500usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
        struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev);
-       struct rt2x00_intf *intf = vif_to_intf(control->vif);
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
        struct queue_entry_priv_usb_bcn *bcn_priv;
        struct skb_frame_desc *skbdesc;
        struct txentry_desc txdesc;
@@ -1691,7 +1690,7 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
         * for our information.
         */
        intf->beacon->skb = skb;
-       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc, control);
+       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc);
 
        /*
         * Add the descriptor in front of the skb.
index 1900d4c..5c7220e 100644 (file)
@@ -542,8 +542,7 @@ struct rt2x00lib_ops {
                               struct sk_buff *skb,
                               struct txentry_desc *txdesc);
        int (*write_tx_data) (struct rt2x00_dev *rt2x00dev,
-                             struct data_queue *queue, struct sk_buff *skb,
-                             struct ieee80211_tx_control *control);
+                             struct data_queue *queue, struct sk_buff *skb);
        int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev,
                                struct sk_buff *skb);
        void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev,
@@ -930,7 +929,6 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate)
  * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input
  * @entry: The entry which will be used to transfer the TX frame.
  * @txdesc: rt2x00 TX descriptor which will be initialized by this function.
- * @control: mac80211 TX control structure from where we read the information.
  *
  * This function will initialize the &struct txentry_desc based on information
  * from mac80211. This descriptor can then be used by rt2x00lib and the drivers
@@ -943,8 +941,7 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate)
  * the &struct txentry_desc structure.
  */
 void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
-                                     struct txentry_desc *txdesc,
-                                     struct ieee80211_tx_control *control);
+                                     struct txentry_desc *txdesc);
 
 /**
  * rt2x00queue_write_tx_descriptor - Write TX descriptor to hardware
@@ -1001,8 +998,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
 /*
  * mac80211 handlers.
  */
-int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
-                struct ieee80211_tx_control *control);
+int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
 int rt2x00mac_start(struct ieee80211_hw *hw);
 void rt2x00mac_stop(struct ieee80211_hw *hw);
 int rt2x00mac_add_interface(struct ieee80211_hw *hw,
index d341764..69e2336 100644 (file)
@@ -415,7 +415,6 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
        struct rt2x00_dev *rt2x00dev = data;
        struct rt2x00_intf *intf = vif_to_intf(vif);
        struct sk_buff *skb;
-       struct ieee80211_tx_control control;
        struct ieee80211_bss_conf conf;
        int delayed_flags;
 
@@ -433,9 +432,9 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
        spin_unlock(&intf->lock);
 
        if (delayed_flags & DELAYED_UPDATE_BEACON) {
-               skb = ieee80211_beacon_get(rt2x00dev->hw, vif, &control);
-               if (skb && rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw,
-                                                            skb, &control))
+               skb = ieee80211_beacon_get(rt2x00dev->hw, vif);
+               if (skb &&
+                   rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, skb))
                        dev_kfree_skb(skb);
        }
 
@@ -494,8 +493,13 @@ void rt2x00lib_txdone(struct queue_entry *entry,
                      struct txdone_entry_desc *txdesc)
 {
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
-       struct skb_frame_desc *skbdesc;
-       struct ieee80211_tx_status tx_status;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
+
+       /*
+        * Send frame to debugfs immediately, after this call is completed
+        * we are going to overwrite the skb->cb array.
+        */
+       rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry->skb);
 
        /*
         * Update TX statistics.
@@ -508,21 +512,20 @@ void rt2x00lib_txdone(struct queue_entry *entry,
        /*
         * Initialize TX status
         */
-       tx_status.flags = 0;
-       tx_status.ack_signal = 0;
-       tx_status.excessive_retries =
+       memset(&tx_info->status, 0, sizeof(tx_info->status));
+       tx_info->status.ack_signal = 0;
+       tx_info->status.excessive_retries =
            test_bit(TXDONE_EXCESSIVE_RETRY, &txdesc->flags);
-       tx_status.retry_count = txdesc->retry;
-       memcpy(&tx_status.control, txdesc->control, sizeof(*txdesc->control));
+       tx_info->status.retry_count = txdesc->retry;
 
-       if (!(tx_status.control.flags & IEEE80211_TXCTL_NO_ACK)) {
+       if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
                if (test_bit(TXDONE_SUCCESS, &txdesc->flags))
-                       tx_status.flags |= IEEE80211_TX_STATUS_ACK;
+                       tx_info->flags |= IEEE80211_TX_STAT_ACK;
                else if (test_bit(TXDONE_FAILURE, &txdesc->flags))
                        rt2x00dev->low_level_stats.dot11ACKFailureCount++;
        }
 
-       if (tx_status.control.flags & IEEE80211_TXCTL_USE_RTS_CTS) {
+       if (tx_info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
                if (test_bit(TXDONE_SUCCESS, &txdesc->flags))
                        rt2x00dev->low_level_stats.dot11RTSSuccessCount++;
                else if (test_bit(TXDONE_FAILURE, &txdesc->flags))
@@ -530,19 +533,13 @@ void rt2x00lib_txdone(struct queue_entry *entry,
        }
 
        /*
-        * Send the tx_status to debugfs. Only send the status report
-        * to mac80211 when the frame originated from there. If this was
-        * a extra frame coming through a mac80211 library call (RTS/CTS)
-        * then we should not send the status report back.
-        * If send to mac80211, mac80211 will clean up the skb structure,
-        * otherwise we have to do it ourself.
+        * Only send the status report to mac80211 when TX status was
+        * requested by it. If this was a extra frame coming through
+        * a mac80211 library call (RTS/CTS) then we should not send the
+        * status report back.
         */
-       rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry->skb);
-
-       skbdesc = get_skb_frame_desc(entry->skb);
-       if (!(skbdesc->flags & FRAME_DESC_DRIVER_GENERATED))
-               ieee80211_tx_status_irqsafe(rt2x00dev->hw,
-                                           entry->skb, &tx_status);
+       if (tx_info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)
+               ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb);
        else
                dev_kfree_skb_irq(entry->skb);
        entry->skb = NULL;
index c5cedb2..b5379b0 100644 (file)
 
 static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
                                struct data_queue *queue,
-                               struct sk_buff *frag_skb,
-                               struct ieee80211_tx_control *control)
+                               struct sk_buff *frag_skb)
 {
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(frag_skb);
        struct skb_frame_desc *skbdesc;
+       struct ieee80211_tx_info *rts_info;
        struct sk_buff *skb;
        int size;
 
-       if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
+       if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
                size = sizeof(struct ieee80211_cts);
        else
                size = sizeof(struct ieee80211_rts);
@@ -52,13 +53,33 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
        skb_reserve(skb, rt2x00dev->hw->extra_tx_headroom);
        skb_put(skb, size);
 
-       if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
-               ieee80211_ctstoself_get(rt2x00dev->hw, control->vif,
-                                       frag_skb->data, frag_skb->len, control,
+       /*
+        * Copy TX information over from original frame to
+        * RTS/CTS frame. Note that we set the no encryption flag
+        * since we don't want this frame to be encrypted.
+        * RTS frames should be acked, while CTS-to-self frames
+        * should not. The ready for TX flag is cleared to prevent
+        * it being automatically send when the descriptor is
+        * written to the hardware.
+        */
+       memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb));
+       rts_info = IEEE80211_SKB_CB(skb);
+       rts_info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
+       rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT;
+       rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS;
+
+       if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
+               rts_info->flags |= IEEE80211_TX_CTL_NO_ACK;
+       else
+               rts_info->flags &= ~IEEE80211_TX_CTL_NO_ACK;
+
+       if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
+               ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif,
+                                       frag_skb->data, size, tx_info,
                                        (struct ieee80211_cts *)(skb->data));
        else
-               ieee80211_rts_get(rt2x00dev->hw, control->vif,
-                                 frag_skb->data, frag_skb->len, control,
+               ieee80211_rts_get(rt2x00dev->hw, tx_info->control.vif,
+                                 frag_skb->data, size, tx_info,
                                  (struct ieee80211_rts *)(skb->data));
 
        /*
@@ -68,7 +89,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
        memset(skbdesc, 0, sizeof(*skbdesc));
        skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
 
-       if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb, control)) {
+       if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb)) {
                WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n");
                return NETDEV_TX_BUSY;
        }
@@ -76,14 +97,13 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
        return NETDEV_TX_OK;
 }
 
-int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
-                struct ieee80211_tx_control *control)
+int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
        struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;
-       enum data_queue_qid qid = mac80211_queue_to_qid(control->queue);
+       enum data_queue_qid qid = mac80211_queue_to_qid(tx_info->queue);
        struct data_queue *queue;
-       struct skb_frame_desc *skbdesc;
        u16 frame_control;
 
        /*
@@ -100,7 +120,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
        /*
         * Determine which queue to put packet on.
         */
-       if (control->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM &&
+       if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM &&
            test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags))
                queue = rt2x00queue_get_queue(rt2x00dev, QID_ATIM);
        else
@@ -125,33 +145,27 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
         */
        frame_control = le16_to_cpu(ieee80211hdr->frame_control);
        if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) &&
-           (control->flags & (IEEE80211_TXCTL_USE_RTS_CTS |
-                              IEEE80211_TXCTL_USE_CTS_PROTECT)) &&
+           (tx_info->flags & (IEEE80211_TX_CTL_USE_RTS_CTS |
+                              IEEE80211_TX_CTL_USE_CTS_PROTECT)) &&
            !rt2x00dev->ops->hw->set_rts_threshold) {
                if (rt2x00queue_available(queue) <= 1) {
-                       ieee80211_stop_queue(rt2x00dev->hw, control->queue);
+                       ieee80211_stop_queue(rt2x00dev->hw, tx_info->queue);
                        return NETDEV_TX_BUSY;
                }
 
-               if (rt2x00mac_tx_rts_cts(rt2x00dev, queue, skb, control)) {
-                       ieee80211_stop_queue(rt2x00dev->hw, control->queue);
+               if (rt2x00mac_tx_rts_cts(rt2x00dev, queue, skb)) {
+                       ieee80211_stop_queue(rt2x00dev->hw, tx_info->queue);
                        return NETDEV_TX_BUSY;
                }
        }
 
-       /*
-        * Initialize skb descriptor
-        */
-       skbdesc = get_skb_frame_desc(skb);
-       memset(skbdesc, 0, sizeof(*skbdesc));
-
-       if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb, control)) {
-               ieee80211_stop_queue(rt2x00dev->hw, control->queue);
+       if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb)) {
+               ieee80211_stop_queue(rt2x00dev->hw, tx_info->queue);
                return NETDEV_TX_BUSY;
        }
 
        if (rt2x00queue_full(queue))
-               ieee80211_stop_queue(rt2x00dev->hw, control->queue);
+               ieee80211_stop_queue(rt2x00dev->hw, tx_info->queue);
 
        if (rt2x00dev->ops->lib->kick_tx_queue)
                rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, qid);
@@ -380,9 +394,7 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw,
        if (conf->type != IEEE80211_IF_TYPE_AP || !conf->beacon)
                return 0;
 
-       status = rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw,
-                                                  conf->beacon,
-                                                  conf->beacon_control);
+       status = rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, conf->beacon);
        if (status)
                dev_kfree_skb(conf->beacon);
 
index fa7de41..70a3d13 100644 (file)
@@ -35,8 +35,7 @@
  * TX data handlers.
  */
 int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
-                           struct data_queue *queue, struct sk_buff *skb,
-                           struct ieee80211_tx_control *control)
+                           struct data_queue *queue, struct sk_buff *skb)
 {
        struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
        struct queue_entry_priv_pci *entry_priv = entry->priv_data;
@@ -64,19 +63,19 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
         * for our information.
         */
        entry->skb = skb;
-       rt2x00queue_create_tx_descriptor(entry, &txdesc, control);
+       rt2x00queue_create_tx_descriptor(entry, &txdesc);
 
        /*
         * Fill in skb descriptor
         */
        skbdesc = get_skb_frame_desc(skb);
+       memset(skbdesc, 0, sizeof(*skbdesc));
        skbdesc->data = skb->data;
        skbdesc->data_len = skb->len;
        skbdesc->desc = entry_priv->desc;
        skbdesc->desc_len = queue->desc_size;
        skbdesc->entry = entry;
 
-       memcpy(&entry_priv->control, control, sizeof(entry_priv->control));
        memcpy(entry_priv->data, skb->data, skb->len);
 
        rt2x00queue_write_tx_descriptor(entry, &txdesc);
@@ -164,9 +163,9 @@ void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry,
                      struct txdone_entry_desc *txdesc)
 {
        struct queue_entry_priv_pci *entry_priv = entry->priv_data;
+       enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
        u32 word;
 
-       txdesc->control = &entry_priv->control;
        rt2x00lib_txdone(entry, txdesc);
 
        /*
@@ -187,7 +186,7 @@ void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry,
         * is reenabled when the txdone handler has finished.
         */
        if (!rt2x00queue_full(entry->queue))
-               ieee80211_wake_queue(rt2x00dev->hw, entry_priv->control.queue);
+               ieee80211_wake_queue(rt2x00dev->hw, qid);
 
 }
 EXPORT_SYMBOL_GPL(rt2x00pci_txdone);
index 557d15a..37c851e 100644 (file)
@@ -91,8 +91,7 @@ rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
  * TX data handlers.
  */
 int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
-                           struct data_queue *queue, struct sk_buff *skb,
-                           struct ieee80211_tx_control *control);
+                           struct data_queue *queue, struct sk_buff *skb);
 
 /**
  * struct queue_entry_priv_pci: Per entry PCI specific information
@@ -101,7 +100,6 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
  * @desc_dma: DMA pointer to &desc.
  * @data: Pointer to device's entry memory.
  * @data_dma: DMA pointer to &data.
- * @control: mac80211 control structure used to transmit data.
  */
 struct queue_entry_priv_pci {
        __le32 *desc;
@@ -109,8 +107,6 @@ struct queue_entry_priv_pci {
 
        void *data;
        dma_addr_t data_dma;
-
-       struct ieee80211_tx_control control;
 };
 
 /**
index 5cf4c2f..e69ef4b 100644 (file)
 #include "rt2x00lib.h"
 
 void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
-                                     struct txentry_desc *txdesc,
-                                     struct ieee80211_tx_control *control)
+                                     struct txentry_desc *txdesc)
 {
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
        struct ieee80211_rate *rate =
-           ieee80211_get_tx_rate(rt2x00dev->hw, control);
+           ieee80211_get_tx_rate(rt2x00dev->hw, tx_info);
        const struct rt2x00_rate *hwrate;
        unsigned int data_length;
        unsigned int duration;
@@ -64,7 +64,7 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
        /*
         * Check whether this frame is to be acked.
         */
-       if (!(control->flags & IEEE80211_TXCTL_NO_ACK))
+       if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK))
                __set_bit(ENTRY_TXD_ACK, &txdesc->flags);
 
        /*
@@ -72,23 +72,20 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
         */
        if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) {
                __set_bit(ENTRY_TXD_BURST, &txdesc->flags);
-               if (is_rts_frame(frame_control)) {
+               if (is_rts_frame(frame_control))
                        __set_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags);
-                       __set_bit(ENTRY_TXD_ACK, &txdesc->flags);
-               } else {
+               else
                        __set_bit(ENTRY_TXD_CTS_FRAME, &txdesc->flags);
-                       __clear_bit(ENTRY_TXD_ACK, &txdesc->flags);
-               }
-               if (control->rts_cts_rate_idx >= 0)
+               if (tx_info->control.rts_cts_rate_idx >= 0)
                        rate =
-                           ieee80211_get_rts_cts_rate(rt2x00dev->hw, control);
+                           ieee80211_get_rts_cts_rate(rt2x00dev->hw, tx_info);
        }
 
        /*
         * Determine retry information.
         */
-       txdesc->retry_limit = control->retry_limit;
-       if (control->flags & IEEE80211_TXCTL_LONG_RETRY_LIMIT)
+       txdesc->retry_limit = tx_info->control.retry_limit;
+       if (tx_info->flags & IEEE80211_TX_CTL_LONG_RETRY_LIMIT)
                __set_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags);
 
        /*
@@ -113,7 +110,7 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
         */
        if (test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) {
                txdesc->ifs = IFS_SIFS;
-       } else if (control->flags & IEEE80211_TXCTL_FIRST_FRAGMENT) {
+       } else if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) {
                __set_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags);
                txdesc->ifs = IFS_BACKOFF;
        } else {
@@ -179,8 +176,10 @@ void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
 
        /*
         * We are done writing the frame to the queue entry,
-        * if this entry is a RTS of CTS-to-self frame we are done,
-        * otherwise we need to kick the queue.
+        * also kick the queue in case the correct flags are set,
+        * note that this will automatically filter beacons and
+        * RTS/CTS frames since those frames don't have this flag
+        * set.
         */
        if (rt2x00dev->ops->lib->kick_tx_queue &&
            !(skbdesc->flags & FRAME_DESC_DRIVER_GENERATED))
index c6edc52..f263fe4 100644 (file)
@@ -105,8 +105,8 @@ enum skb_frame_desc_flags {
 /**
  * struct skb_frame_desc: Descriptor information for the skb buffer
  *
- * This structure is placed over the skb->cb array, this means that
- * this structure should not exceed the size of that array (48 bytes).
+ * This structure is placed over the driver_data array, this means that
+ * this structure should not exceed the size of that array (40 bytes).
  *
  * @flags: Frame flags, see &enum skb_frame_desc_flags.
  * @data: Pointer to data part of frame (Start of ieee80211 header).
@@ -129,10 +129,15 @@ struct skb_frame_desc {
        struct queue_entry *entry;
 };
 
+/**
+ * get_skb_frame_desc - Obtain the rt2x00 frame descriptor from a sk_buff.
+ * @skb: &struct sk_buff from where we obtain the &struct skb_frame_desc
+ */
 static inline struct skb_frame_desc* get_skb_frame_desc(struct sk_buff *skb)
 {
-       BUILD_BUG_ON(sizeof(struct skb_frame_desc) > sizeof(skb->cb));
-       return (struct skb_frame_desc *)&skb->cb[0];
+       BUILD_BUG_ON(sizeof(struct skb_frame_desc) >
+                    IEEE80211_TX_INFO_DRIVER_DATA_SIZE);
+       return (struct skb_frame_desc *)&IEEE80211_SKB_CB(skb)->driver_data;
 }
 
 /**
@@ -189,12 +194,10 @@ enum txdone_entry_desc_flags {
  * Summary of information that has been read from the TX frame descriptor
  * after the device is done with transmission.
  *
- * @control: Control structure which was used to transmit the frame.
  * @flags: TX done flags (See &enum txdone_entry_desc_flags).
  * @retry: Retry count.
  */
 struct txdone_entry_desc {
-       struct ieee80211_tx_control *control;
        unsigned long flags;
        int retry;
 };
index dcee1b4..52d12fd 100644 (file)
@@ -129,9 +129,9 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
 {
        struct queue_entry *entry = (struct queue_entry *)urb->context;
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
-       struct queue_entry_priv_usb *entry_priv = entry->priv_data;
        struct txdone_entry_desc txdesc;
        __le32 *txd = (__le32 *)entry->skb->data;
+       enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
        u32 word;
 
        if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
@@ -159,7 +159,6 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
        else
                __set_bit(TXDONE_FAILURE, &txdesc.flags);
        txdesc.retry = 0;
-       txdesc.control = &entry_priv->control;
 
        rt2x00lib_txdone(entry, &txdesc);
 
@@ -175,12 +174,11 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
         * is reenabled when the txdone handler has finished.
         */
        if (!rt2x00queue_full(entry->queue))
-               ieee80211_wake_queue(rt2x00dev->hw, entry_priv->control.queue);
+               ieee80211_wake_queue(rt2x00dev->hw, qid);
 }
 
 int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
-                           struct data_queue *queue, struct sk_buff *skb,
-                           struct ieee80211_tx_control *control)
+                           struct data_queue *queue, struct sk_buff *skb)
 {
        struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev);
        struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
@@ -206,7 +204,7 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
         * for our information.
         */
        entry->skb = skb;
-       rt2x00queue_create_tx_descriptor(entry, &txdesc, control);
+       rt2x00queue_create_tx_descriptor(entry, &txdesc);
 
        /*
         * Add the descriptor in front of the skb.
@@ -218,13 +216,13 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
         * Fill in skb descriptor
         */
        skbdesc = get_skb_frame_desc(skb);
+       memset(skbdesc, 0, sizeof(*skbdesc));
        skbdesc->data = skb->data + queue->desc_size;
        skbdesc->data_len = skb->len - queue->desc_size;
        skbdesc->desc = skb->data;
        skbdesc->desc_len = queue->desc_size;
        skbdesc->entry = entry;
 
-       memcpy(&entry_priv->control, control, sizeof(entry_priv->control));
        rt2x00queue_write_tx_descriptor(entry, &txdesc);
 
        /*
index 15b404a..26f53f8 100644 (file)
@@ -216,19 +216,15 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev);
  * TX data handlers.
  */
 int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
-                           struct data_queue *queue, struct sk_buff *skb,
-                           struct ieee80211_tx_control *control);
+                           struct data_queue *queue, struct sk_buff *skb);
 
 /**
  * struct queue_entry_priv_usb: Per entry USB specific information
  *
  * @urb: Urb structure used for device communication.
- * @control: mac80211 control structure used to transmit data.
  */
 struct queue_entry_priv_usb {
        struct urb *urb;
-
-       struct ieee80211_tx_control control;
 };
 
 /**
@@ -239,15 +235,12 @@ struct queue_entry_priv_usb {
  * with beacons.
  *
  * @urb: Urb structure used for device communication.
- * @control: mac80211 control structure used to transmit data.
  * @guardian_data: Set to 0, used for sending the guardian data.
  * @guardian_urb: Urb structure used to send the guardian data.
  */
 struct queue_entry_priv_usb_bcn {
        struct urb *urb;
 
-       struct ieee80211_tx_control control;
-
        unsigned int guardian_data;
        struct urb *guardian_urb;
 };
index 7598b6e..e13ed5c 100644 (file)
@@ -2357,11 +2357,11 @@ static u64 rt61pci_get_tsf(struct ieee80211_hw *hw)
        return tsf;
 }
 
-static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
-                                struct ieee80211_tx_control *control)
+static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
-       struct rt2x00_intf *intf = vif_to_intf(control->vif);
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
        struct queue_entry_priv_pci *entry_priv;
        struct skb_frame_desc *skbdesc;
        struct txentry_desc txdesc;
@@ -2377,7 +2377,7 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
         * for our information.
         */
        intf->beacon->skb = skb;
-       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc, control);
+       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc);
 
        entry_priv = intf->beacon->priv_data;
        memset(entry_priv->desc, 0, intf->beacon->queue->desc_size);
index e55bcbd..26c2e0a 100644 (file)
@@ -1948,11 +1948,11 @@ static u64 rt73usb_get_tsf(struct ieee80211_hw *hw)
 #define rt73usb_get_tsf        NULL
 #endif
 
-static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
-                                struct ieee80211_tx_control *control)
+static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
-       struct rt2x00_intf *intf = vif_to_intf(control->vif);
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
        struct skb_frame_desc *skbdesc;
        struct txentry_desc txdesc;
        unsigned int beacon_base;
@@ -1967,7 +1967,7 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
         * for our information.
         */
        intf->beacon->skb = skb;
-       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc, control);
+       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc);
 
        /*
         * Add the descriptor in front of the skb.
index 6263209..4427bc9 100644 (file)
@@ -170,34 +170,29 @@ static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio)
        while (skb_queue_len(&ring->queue)) {
                struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
                struct sk_buff *skb;
-               struct ieee80211_tx_status status;
-               struct ieee80211_tx_control *control;
+               struct ieee80211_tx_info *info;
                u32 flags = le32_to_cpu(entry->flags);
 
                if (flags & RTL8180_TX_DESC_FLAG_OWN)
                        return;
 
-               memset(&status, 0, sizeof(status));
-
                ring->idx = (ring->idx + 1) % ring->entries;
                skb = __skb_dequeue(&ring->queue);
                pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
                                 skb->len, PCI_DMA_TODEVICE);
 
-               control = *((struct ieee80211_tx_control **)skb->cb);
-               if (control)
-                       memcpy(&status.control, control, sizeof(*control));
-               kfree(control);
+               info = IEEE80211_SKB_CB(skb);
+               memset(&info->status, 0, sizeof(info->status));
 
-               if (!(status.control.flags & IEEE80211_TXCTL_NO_ACK)) {
+               if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
                        if (flags & RTL8180_TX_DESC_FLAG_TX_OK)
-                               status.flags = IEEE80211_TX_STATUS_ACK;
+                               info->flags |= IEEE80211_TX_STAT_ACK;
                        else
-                               status.excessive_retries = 1;
+                               info->status.excessive_retries = 1;
                }
-               status.retry_count = flags & 0xFF;
+               info->status.retry_count = flags & 0xFF;
 
-               ieee80211_tx_status_irqsafe(dev, skb, &status);
+               ieee80211_tx_status_irqsafe(dev, skb);
                if (ring->entries - skb_queue_len(&ring->queue) == 2)
                        ieee80211_wake_queue(dev, prio);
        }
@@ -238,9 +233,9 @@ static irqreturn_t rtl8180_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
-                     struct ieee80211_tx_control *control)
+static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct rtl8180_priv *priv = dev->priv;
        struct rtl8180_tx_ring *ring;
        struct rtl8180_tx_desc *entry;
@@ -251,7 +246,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
        u16 plcp_len = 0;
        __le16 rts_duration = 0;
 
-       prio = control->queue;
+       prio = info->queue;
        ring = &priv->tx_ring[prio];
 
        mapping = pci_map_single(priv->pdev, skb->data,
@@ -259,35 +254,32 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
 
        tx_flags = RTL8180_TX_DESC_FLAG_OWN | RTL8180_TX_DESC_FLAG_FS |
                   RTL8180_TX_DESC_FLAG_LS |
-                  (ieee80211_get_tx_rate(dev, control)->hw_value << 24) |
+                  (ieee80211_get_tx_rate(dev, info)->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) {
+       if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
                tx_flags |= RTL8180_TX_DESC_FLAG_RTS;
-               tx_flags |= ieee80211_get_rts_cts_rate(dev, control)->hw_value << 19;
-       } else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
+               tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
+       } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
                tx_flags |= RTL8180_TX_DESC_FLAG_CTS;
-               tx_flags |= ieee80211_get_rts_cts_rate(dev, control)->hw_value << 19;
+               tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
        }
 
-       *((struct ieee80211_tx_control **) skb->cb) =
-               kmemdup(control, sizeof(*control), GFP_ATOMIC);
-
-       if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
+       if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
                rts_duration = ieee80211_rts_duration(dev, priv->vif, skb->len,
-                                                     control);
+                                                     info);
 
        if (!priv->r8185) {
                unsigned int remainder;
 
                plcp_len = DIV_ROUND_UP(16 * (skb->len + 4),
-                               (ieee80211_get_tx_rate(dev, control)->bitrate * 2) / 10);
+                               (ieee80211_get_tx_rate(dev, info)->bitrate * 2) / 10);
                remainder = (16 * (skb->len + 4)) %
-                           ((ieee80211_get_tx_rate(dev, control)->bitrate * 2) / 10);
+                           ((ieee80211_get_tx_rate(dev, info)->bitrate * 2) / 10);
                if (remainder > 0 && remainder <= 6)
                        plcp_len |= 1 << 15;
        }
@@ -300,13 +292,13 @@ 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_idx >= 0 ?
-               ieee80211_get_alt_retry_rate(dev, control)->bitrate << 4 : 0;
-       entry->retry_limit = control->retry_limit;
+       entry->flags2 = info->control.alt_retry_rate_idx >= 0 ?
+               ieee80211_get_alt_retry_rate(dev, info)->bitrate << 4 : 0;
+       entry->retry_limit = info->control.retry_limit;
        entry->flags = cpu_to_le32(tx_flags);
        __skb_queue_tail(&ring->queue, skb);
        if (ring->entries - skb_queue_len(&ring->queue) < 2)
-               ieee80211_stop_queue(dev, control->queue);
+               ieee80211_stop_queue(dev, info->queue);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4)));
@@ -522,7 +514,6 @@ static void rtl8180_free_tx_ring(struct ieee80211_hw *dev, unsigned int prio)
 
                pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
                                 skb->len, PCI_DMA_TODEVICE);
-               kfree(*((struct ieee80211_tx_control **) skb->cb));
                kfree_skb(skb);
                ring->idx = (ring->idx + 1) % ring->entries;
        }
index 076d88b..a0cfb66 100644 (file)
@@ -44,12 +44,6 @@ struct rtl8187_rx_hdr {
        __le64 mac_time;
 } __attribute__((packed));
 
-struct rtl8187_tx_info {
-       struct ieee80211_tx_control *control;
-       struct urb *urb;
-       struct ieee80211_hw *dev;
-};
-
 struct rtl8187_tx_hdr {
        __le32 flags;
 #define RTL8187_TX_FLAG_NO_ENCRYPT     (1 << 15)
index 86a09b4..b581ef8 100644 (file)
@@ -145,27 +145,22 @@ void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
 
 static void rtl8187_tx_cb(struct urb *urb)
 {
-       struct ieee80211_tx_status status;
        struct sk_buff *skb = (struct sk_buff *)urb->context;
-       struct rtl8187_tx_info *info = (struct rtl8187_tx_info *)skb->cb;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_hw *hw = info->driver_data[0];
 
-       memset(&status, 0, sizeof(status));
-
-       usb_free_urb(info->urb);
-       if (info->control)
-               memcpy(&status.control, info->control, sizeof(status.control));
-       kfree(info->control);
+       usb_free_urb(info->driver_data[1]);
        skb_pull(skb, sizeof(struct rtl8187_tx_hdr));
-       status.flags |= IEEE80211_TX_STATUS_ACK;
-       ieee80211_tx_status_irqsafe(info->dev, skb, &status);
+       memset(&info->status, 0, sizeof(info->status));
+       info->flags |= IEEE80211_TX_STAT_ACK;
+       ieee80211_tx_status_irqsafe(hw, skb);
 }
 
-static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
-                     struct ieee80211_tx_control *control)
+static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
        struct rtl8187_priv *priv = dev->priv;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct rtl8187_tx_hdr *hdr;
-       struct rtl8187_tx_info *info;
        struct urb *urb;
        __le16 rts_dur = 0;
        u32 flags;
@@ -179,29 +174,27 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
        flags = skb->len;
        flags |= RTL8187_TX_FLAG_NO_ENCRYPT;
 
-       flags |= ieee80211_get_tx_rate(dev, control)->hw_value << 24;
+       flags |= ieee80211_get_tx_rate(dev, info)->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) {
+       if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
                flags |= RTL8187_TX_FLAG_RTS;
-               flags |= ieee80211_get_rts_cts_rate(dev, control)->hw_value << 19;
+               flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
                rts_dur = ieee80211_rts_duration(dev, priv->vif,
-                                                skb->len, control);
-       } else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
+                                                skb->len, info);
+       } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
                flags |= RTL8187_TX_FLAG_CTS;
-               flags |= ieee80211_get_rts_cts_rate(dev, control)->hw_value << 19;
+               flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
        }
 
        hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
        hdr->flags = cpu_to_le32(flags);
        hdr->len = 0;
        hdr->rts_duration = rts_dur;
-       hdr->retry = cpu_to_le32(control->retry_limit << 8);
+       hdr->retry = cpu_to_le32(info->control.retry_limit << 8);
 
-       info = (struct rtl8187_tx_info *)skb->cb;
-       info->control = kmemdup(control, sizeof(*control), GFP_ATOMIC);
-       info->urb = urb;
-       info->dev = dev;
+       info->driver_data[0] = dev;
+       info->driver_data[1] = urb;
        usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, 2),
                          hdr, skb->len, rtl8187_tx_cb, skb);
        usb_submit_urb(urb, GFP_ATOMIC);
index 99c508c..edb1aef 100644 (file)
@@ -224,36 +224,6 @@ out:
        return r;
 }
 
-/**
- * clear_tx_skb_control_block - clears the control block of tx skbuffs
- * @skb: a &struct sk_buff pointer
- *
- * This clears the control block of skbuff buffers, which were transmitted to
- * the device. Notify that the function is not thread-safe, so prevent
- * multiple calls.
- */
-static void clear_tx_skb_control_block(struct sk_buff *skb)
-{
-       struct zd_tx_skb_control_block *cb =
-               (struct zd_tx_skb_control_block *)skb->cb;
-
-       kfree(cb->control);
-       cb->control = NULL;
-}
-
-/**
- * kfree_tx_skb - frees a tx skbuff
- * @skb: a &struct sk_buff pointer
- *
- * Frees the tx skbuff. Frees also the allocated control structure in the
- * control block if necessary.
- */
-static void kfree_tx_skb(struct sk_buff *skb)
-{
-       clear_tx_skb_control_block(skb);
-       dev_kfree_skb_any(skb);
-}
-
 static void zd_op_stop(struct ieee80211_hw *hw)
 {
        struct zd_mac *mac = zd_hw_mac(hw);
@@ -276,40 +246,15 @@ static void zd_op_stop(struct ieee80211_hw *hw)
 
 
        while ((skb = skb_dequeue(ack_wait_queue)))
-               kfree_tx_skb(skb);
-}
-
-/**
- * init_tx_skb_control_block - initializes skb control block
- * @skb: a &sk_buff pointer
- * @dev: pointer to the mac80221 device
- * @control: mac80211 tx control applying for the frame in @skb
- *
- * Initializes the control block of the skbuff to be transmitted.
- */
-static int init_tx_skb_control_block(struct sk_buff *skb,
-                                    struct ieee80211_hw *hw,
-                                    struct ieee80211_tx_control *control)
-{
-       struct zd_tx_skb_control_block *cb =
-               (struct zd_tx_skb_control_block *)skb->cb;
-
-       ZD_ASSERT(sizeof(*cb) <= sizeof(skb->cb));
-       memset(cb, 0, sizeof(*cb));
-       cb->hw= hw;
-       cb->control = kmalloc(sizeof(*control), GFP_ATOMIC);
-       if (cb->control == NULL)
-               return -ENOMEM;
-       memcpy(cb->control, control, sizeof(*control));
-
-       return 0;
+               dev_kfree_skb_any(skb);
 }
 
 /**
  * tx_status - reports tx status of a packet if required
  * @hw - a &struct ieee80211_hw pointer
  * @skb - a sk-buffer
- * @status - the tx status of the packet without control information
+ * @flags: extra flags to set in the TX status info
+ * @ackssi: ACK signal strength
  * @success - True for successfull transmission of the frame
  *
  * This information calls ieee80211_tx_status_irqsafe() if required by the
@@ -319,18 +264,17 @@ static int init_tx_skb_control_block(struct sk_buff *skb,
  * If no status information has been requested, the skb is freed.
  */
 static void tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
-                     struct ieee80211_tx_status *status,
-                     bool success)
+                     u32 flags, int ackssi, bool success)
 {
-       struct zd_tx_skb_control_block *cb = (struct zd_tx_skb_control_block *)
-               skb->cb;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+       memset(&info->status, 0, sizeof(info->status));
 
-       ZD_ASSERT(cb->control != NULL);
-       memcpy(&status->control, cb->control, sizeof(status->control));
        if (!success)
-               status->excessive_retries = 1;
-       clear_tx_skb_control_block(skb);
-       ieee80211_tx_status_irqsafe(hw, skb, status);
+               info->status.excessive_retries = 1;
+       info->flags |= flags;
+       info->status.ack_signal = ackssi;
+       ieee80211_tx_status_irqsafe(hw, skb);
 }
 
 /**
@@ -345,15 +289,12 @@ void zd_mac_tx_failed(struct ieee80211_hw *hw)
 {
        struct sk_buff_head *q = &zd_hw_mac(hw)->ack_wait_queue;
        struct sk_buff *skb;
-       struct ieee80211_tx_status status;
 
        skb = skb_dequeue(q);
        if (skb == NULL)
                return;
 
-       memset(&status, 0, sizeof(status));
-
-       tx_status(hw, skb, &status, 0);
+       tx_status(hw, skb, 0, 0, 0);
 }
 
 /**
@@ -368,28 +309,20 @@ void zd_mac_tx_failed(struct ieee80211_hw *hw)
  */
 void zd_mac_tx_to_dev(struct sk_buff *skb, int error)
 {
-       struct zd_tx_skb_control_block *cb =
-               (struct zd_tx_skb_control_block *)skb->cb;
-       struct ieee80211_hw *hw = cb->hw;
-
-       if (likely(cb->control)) {
-               skb_pull(skb, sizeof(struct zd_ctrlset));
-               if (unlikely(error ||
-                   (cb->control->flags & IEEE80211_TXCTL_NO_ACK)))
-               {
-                       struct ieee80211_tx_status status;
-                       memset(&status, 0, sizeof(status));
-                       tx_status(hw, skb, &status, !error);
-               } else {
-                       struct sk_buff_head *q =
-                               &zd_hw_mac(hw)->ack_wait_queue;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_hw *hw = info->driver_data[0];
 
-                       skb_queue_tail(q, skb);
-                       while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS)
-                               zd_mac_tx_failed(hw);
-               }
+       skb_pull(skb, sizeof(struct zd_ctrlset));
+       if (unlikely(error ||
+           (info->flags & IEEE80211_TX_CTL_NO_ACK))) {
+               tx_status(hw, skb, 0, 0, !error);
        } else {
-               kfree_tx_skb(skb);
+               struct sk_buff_head *q =
+                       &zd_hw_mac(hw)->ack_wait_queue;
+
+               skb_queue_tail(q, skb);
+               while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS)
+                       zd_mac_tx_failed(hw);
        }
 }
 
@@ -454,7 +387,7 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
        cs->control = 0;
 
        /* First fragment */
-       if (flags & IEEE80211_TXCTL_FIRST_FRAGMENT)
+       if (flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
                cs->control |= ZD_CS_NEED_RANDOM_BACKOFF;
 
        /* Multicast */
@@ -466,10 +399,10 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
            (IEEE80211_FTYPE_CTL|IEEE80211_STYPE_PSPOLL))
                cs->control |= ZD_CS_PS_POLL_FRAME;
 
-       if (flags & IEEE80211_TXCTL_USE_RTS_CTS)
+       if (flags & IEEE80211_TX_CTL_USE_RTS_CTS)
                cs->control |= ZD_CS_RTS;
 
-       if (flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
+       if (flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
                cs->control |= ZD_CS_SELF_CTS;
 
        /* FIXME: Management frame? */
@@ -516,8 +449,7 @@ void zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon)
 }
 
 static int fill_ctrlset(struct zd_mac *mac,
-                       struct sk_buff *skb,
-                       struct ieee80211_tx_control *control)
+                       struct sk_buff *skb)
 {
        int r;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
@@ -526,18 +458,19 @@ static int fill_ctrlset(struct zd_mac *mac,
        struct ieee80211_rate *txrate;
        struct zd_ctrlset *cs = (struct zd_ctrlset *)
                skb_push(skb, sizeof(struct zd_ctrlset));
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
        ZD_ASSERT(frag_len <= 0xffff);
 
-       txrate = ieee80211_get_tx_rate(mac->hw, control);
+       txrate = ieee80211_get_tx_rate(mac->hw, info);
 
        cs->modulation = txrate->hw_value;
-       if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE)
+       if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE)
                cs->modulation = txrate->hw_value_short;
 
        cs->tx_length = cpu_to_le16(frag_len);
 
-       cs_set_control(mac, cs, hdr, control->flags);
+       cs_set_control(mac, cs, hdr, info->flags);
 
        packet_length = frag_len + sizeof(struct zd_ctrlset) + 10;
        ZD_ASSERT(packet_length <= 0xffff);
@@ -582,24 +515,21 @@ static int fill_ctrlset(struct zd_mac *mac,
  * control block of the skbuff will be initialized. If necessary the incoming
  * mac80211 queues will be stopped.
  */
-static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
-                    struct ieee80211_tx_control *control)
+static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct zd_mac *mac = zd_hw_mac(hw);
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        int r;
 
-       r = fill_ctrlset(mac, skb, control);
+       r = fill_ctrlset(mac, skb);
        if (r)
                return r;
 
-       r = init_tx_skb_control_block(skb, hw, control);
-       if (r)
-               return r;
+       info->driver_data[0] = hw;
+
        r = zd_usb_tx(&mac->chip.usb, skb);
-       if (r) {
-               clear_tx_skb_control_block(skb);
+       if (r)
                return r;
-       }
        return 0;
 }
 
@@ -637,13 +567,8 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr,
                tx_hdr = (struct ieee80211_hdr *)skb->data;
                if (likely(!compare_ether_addr(tx_hdr->addr2, rx_hdr->addr1)))
                {
-                       struct ieee80211_tx_status status;
-
-                       memset(&status, 0, sizeof(status));
-                       status.flags = IEEE80211_TX_STATUS_ACK;
-                       status.ack_signal = stats->signal;
                        __skb_unlink(skb, q);
-                       tx_status(hw, skb, &status, 1);
+                       tx_status(hw, skb, IEEE80211_TX_STAT_ACK, stats->signal, 1);
                        goto out;
                }
        }
@@ -947,8 +872,7 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
 }
 
 static int zd_op_beacon_update(struct ieee80211_hw *hw,
-                              struct sk_buff *skb,
-                              struct ieee80211_tx_control *ctl)
+                              struct sk_buff *skb)
 {
        struct zd_mac *mac = zd_hw_mac(hw);
        zd_mac_config_beacon(hw, skb);
index 7117024..18c1d56 100644 (file)
@@ -149,22 +149,6 @@ struct housekeeping {
        struct delayed_work link_led_work;
 };
 
-/**
- * struct zd_tx_skb_control_block - control block for tx skbuffs
- * @control: &struct ieee80211_tx_control pointer
- * @context: context pointer
- *
- * This structure is used to fill the cb field in an &sk_buff to transmit.
- * The control field is NULL, if there is no requirement from the mac80211
- * stack to report about the packet ACK. This is the case if the flag
- * IEEE80211_TXCTL_NO_ACK is not set in &struct ieee80211_tx_control.
- */
-struct zd_tx_skb_control_block {
-       struct ieee80211_tx_control *control;
-       struct ieee80211_hw *hw;
-       void *context;
-};
-
 #define ZD_MAC_STATS_BUFFER_SIZE 16
 
 #define ZD_MAC_MAX_ACK_WAITERS 10
index 12e24f0..c8a0b34 100644 (file)
@@ -869,7 +869,7 @@ static void tx_urb_complete(struct urb *urb)
 {
        int r;
        struct sk_buff *skb;
-       struct zd_tx_skb_control_block *cb;
+       struct ieee80211_tx_info *info;
        struct zd_usb *usb;
 
        switch (urb->status) {
@@ -893,8 +893,8 @@ free_urb:
         * grab 'usb' pointer before handing off the skb (since
         * it might be freed by zd_mac_tx_to_dev or mac80211)
         */
-       cb = (struct zd_tx_skb_control_block *)skb->cb;
-       usb = &zd_hw_mac(cb->hw)->chip.usb;
+       info = IEEE80211_SKB_CB(skb);
+       usb = &zd_hw_mac(info->driver_data[0])->chip.usb;
        zd_mac_tx_to_dev(skb, urb->status);
        free_tx_urb(usb, urb);
        tx_dec_submitted_urbs(usb);
index 0df91be..54960b8 100644 (file)
@@ -201,101 +201,127 @@ struct ieee80211_bss_conf {
 };
 
 /**
- * enum mac80211_tx_control_flags - flags to describe Tx configuration for
- *                                 the Tx frame
- *
- * These flags are used with the @flags member of &ieee80211_tx_control
- *
- * @IEEE80211_TXCTL_REQ_TX_STATUS: request TX status callback for this frame.
- * @IEEE80211_TXCTL_DO_NOT_ENCRYPT: send this frame without encryption;
- *                                 e.g., for EAPOL frame
- * @IEEE80211_TXCTL_USE_RTS_CTS: use RTS-CTS before sending frame
- * @IEEE80211_TXCTL_USE_CTS_PROTECT: use CTS protection for the frame (e.g.,
- *                                  for combined 802.11g / 802.11b networks)
- * @IEEE80211_TXCTL_NO_ACK: tell the low level not to wait for an ack
- * @IEEE80211_TXCTL_RATE_CTRL_PROBE
- * @EEE80211_TXCTL_CLEAR_PS_FILT: clear powersave filter
- *                                 for destination station
- * @IEEE80211_TXCTL_REQUEUE:
- * @IEEE80211_TXCTL_FIRST_FRAGMENT: this is a first fragment of the frame
- * @IEEE80211_TXCTL_LONG_RETRY_LIMIT: this frame should be send using the
- *                                   through set_retry_limit configured long
- *                                   retry value
- * @IEEE80211_TXCTL_EAPOL_FRAME: internal to mac80211
- * @IEEE80211_TXCTL_SEND_AFTER_DTIM: send this frame after DTIM beacon
- * @IEEE80211_TXCTL_AMPDU: this frame should be sent as part of an A-MPDU
- * @IEEE80211_TXCTL_OFDM_HT: this frame can be sent in HT OFDM rates. number
- *                          of streams when this flag is on can be extracted
- *                          from antenna_sel_tx, so if 1 antenna is marked
- *                          use SISO, 2 antennas marked use MIMO, n antennas
- *                          marked use MIMO_n.
- * @IEEE80211_TXCTL_GREEN_FIELD: use green field protection for this frame
- * @IEEE80211_TXCTL_40_MHZ_WIDTH: send this frame using 40 Mhz channel width
- * @IEEE80211_TXCTL_DUP_DATA: duplicate data frame on both 20 Mhz channels
- * @IEEE80211_TXCTL_SHORT_GI: send this frame using short guard interval
+ * enum mac80211_tx_flags - flags to transmission information/status
+ *
+ * These flags are used with the @flags member of &ieee80211_tx_info
+ *
+ * @IEEE80211_TX_CTL_REQ_TX_STATUS: request TX status callback for this frame.
+ * @IEEE80211_TX_CTL_DO_NOT_ENCRYPT: send this frame without encryption;
+ *     e.g., for EAPOL frame
+ * @IEEE80211_TX_CTL_USE_RTS_CTS: use RTS-CTS before sending frame
+ * @IEEE80211_TX_CTL_USE_CTS_PROTECT: use CTS protection for the frame (e.g.,
+ *     for combined 802.11g / 802.11b networks)
+ * @IEEE80211_TX_CTL_NO_ACK: tell the low level not to wait for an ack
+ * @IEEE80211_TX_CTL_RATE_CTRL_PROBE
+ * @IEEE80211_TX_CTL_CLEAR_PS_FILT: clear powersave filter for destination
+ *     station
+ * @IEEE80211_TX_CTL_REQUEUE:
+ * @IEEE80211_TX_CTL_FIRST_FRAGMENT: this is a first fragment of the frame
+ * @IEEE80211_TX_CTL_LONG_RETRY_LIMIT: this frame should be send using the
+ *     through set_retry_limit configured long retry value
+ * @IEEE80211_TX_CTL_EAPOL_FRAME: internal to mac80211
+ * @IEEE80211_TX_CTL_SEND_AFTER_DTIM: send this frame after DTIM beacon
+ * @IEEE80211_TX_CTL_AMPDU: this frame should be sent as part of an A-MPDU
+ * @IEEE80211_TX_CTL_OFDM_HT: this frame can be sent in HT OFDM rates. number
+ *     of streams when this flag is on can be extracted from antenna_sel_tx,
+ *     so if 1 antenna is marked use SISO, 2 antennas marked use MIMO, n
+ *     antennas marked use MIMO_n.
+ * @IEEE80211_TX_CTL_GREEN_FIELD: use green field protection for this frame
+ * @IEEE80211_TX_CTL_40_MHZ_WIDTH: send this frame using 40 Mhz channel width
+ * @IEEE80211_TX_CTL_DUP_DATA: duplicate data frame on both 20 Mhz channels
+ * @IEEE80211_TX_CTL_SHORT_GI: send this frame using short guard interval
+ * @IEEE80211_TX_STAT_TX_FILTERED: The frame was not transmitted
+ *     because the destination STA was in powersave mode.
+ * @IEEE80211_TX_STAT_ACK: Frame was acknowledged
+ * @IEEE80211_TX_STAT_AMPDU: The frame was aggregated, so status
+ *     is for the whole aggregation.
  */
 enum mac80211_tx_control_flags {
-       IEEE80211_TXCTL_REQ_TX_STATUS           = (1<<0),
-       IEEE80211_TXCTL_DO_NOT_ENCRYPT          = (1<<1),
-       IEEE80211_TXCTL_USE_RTS_CTS             = (1<<2),
-       IEEE80211_TXCTL_USE_CTS_PROTECT         = (1<<3),
-       IEEE80211_TXCTL_NO_ACK                  = (1<<4),
-       IEEE80211_TXCTL_RATE_CTRL_PROBE         = (1<<5),
-       IEEE80211_TXCTL_CLEAR_PS_FILT           = (1<<6),
-       IEEE80211_TXCTL_REQUEUE                 = (1<<7),
-       IEEE80211_TXCTL_FIRST_FRAGMENT          = (1<<8),
-       IEEE80211_TXCTL_SHORT_PREAMBLE          = (1<<9),
-       IEEE80211_TXCTL_LONG_RETRY_LIMIT        = (1<<10),
-       IEEE80211_TXCTL_EAPOL_FRAME             = (1<<11),
-       IEEE80211_TXCTL_SEND_AFTER_DTIM         = (1<<12),
-       IEEE80211_TXCTL_AMPDU                   = (1<<13),
-       IEEE80211_TXCTL_OFDM_HT                 = (1<<14),
-       IEEE80211_TXCTL_GREEN_FIELD             = (1<<15),
-       IEEE80211_TXCTL_40_MHZ_WIDTH            = (1<<16),
-       IEEE80211_TXCTL_DUP_DATA                = (1<<17),
-       IEEE80211_TXCTL_SHORT_GI                = (1<<18),
+       IEEE80211_TX_CTL_REQ_TX_STATUS          = BIT(0),
+       IEEE80211_TX_CTL_DO_NOT_ENCRYPT         = BIT(1),
+       IEEE80211_TX_CTL_USE_RTS_CTS            = BIT(2),
+       IEEE80211_TX_CTL_USE_CTS_PROTECT        = BIT(3),
+       IEEE80211_TX_CTL_NO_ACK                 = BIT(4),
+       IEEE80211_TX_CTL_RATE_CTRL_PROBE        = BIT(5),
+       IEEE80211_TX_CTL_CLEAR_PS_FILT          = BIT(6),
+       IEEE80211_TX_CTL_REQUEUE                = BIT(7),
+       IEEE80211_TX_CTL_FIRST_FRAGMENT         = BIT(8),
+       IEEE80211_TX_CTL_SHORT_PREAMBLE         = BIT(9),
+       IEEE80211_TX_CTL_LONG_RETRY_LIMIT       = BIT(10),
+       IEEE80211_TX_CTL_EAPOL_FRAME            = BIT(11),
+       IEEE80211_TX_CTL_SEND_AFTER_DTIM        = BIT(12),
+       IEEE80211_TX_CTL_AMPDU                  = BIT(13),
+       IEEE80211_TX_CTL_OFDM_HT                = BIT(14),
+       IEEE80211_TX_CTL_GREEN_FIELD            = BIT(15),
+       IEEE80211_TX_CTL_40_MHZ_WIDTH           = BIT(16),
+       IEEE80211_TX_CTL_DUP_DATA               = BIT(17),
+       IEEE80211_TX_CTL_SHORT_GI               = BIT(18),
+       IEEE80211_TX_CTL_INJECTED               = BIT(19),
+       IEEE80211_TX_STAT_TX_FILTERED           = BIT(20),
+       IEEE80211_TX_STAT_ACK                   = BIT(21),
+       IEEE80211_TX_STAT_AMPDU                 = BIT(22),
 };
 
-/* Transmit control fields. This data structure is passed to low-level driver
- * with each TX frame. The low-level driver is responsible for configuring
- * the hardware to use given values (depending on what is supported).
- *
- * NOTE: Be careful with using the pointers outside of the ieee80211_ops->tx()
- * context (i.e. when defering the work to a workqueue).
- * The vif pointer is valid until the it has been removed with the
- * 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.
- */
-struct ieee80211_tx_control {
-       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 */
-
-       s8 retry_limit;         /* 1 = only first attempt, 2 = one retry, ..
-                                * This could be used when set_retry_limit
-                                * is not implemented by the driver */
 
-       struct ieee80211_vif *vif;
-
-       /* Key used for hardware encryption
-        * NULL if IEEE80211_TXCTL_DO_NOT_ENCRYPT is set */
-       struct ieee80211_key_conf *hw_key;
+#define IEEE80211_TX_INFO_DRIVER_DATA_SIZE \
+       (sizeof(((struct sk_buff *)0)->cb) - 8)
+#define IEEE80211_TX_INFO_DRIVER_DATA_PTRS \
+       (IEEE80211_TX_INFO_DRIVER_DATA_SIZE / sizeof(void *))
 
-       enum ieee80211_band band;
+/**
+ * struct ieee80211_tx_info - skb transmit information
+ *
+ * This structure is placed in skb->cb for three uses:
+ *  (1) mac80211 TX control - mac80211 tells the driver what to do
+ *  (2) driver internal use (if applicable)
+ *  (3) TX status information - driver tells mac80211 what happened
+ *
+ * @flags: transmit info flags, defined above
+ * @retry_count: number of retries
+ * @excessive_retries: set to 1 if the frame was retried many times
+ *     but not acknowledged
+ * @ampdu_ack_len: number of aggregated frames.
+ *     relevant only if IEEE80211_TX_STATUS_AMPDU was set.
+ * @ampdu_ack_map: block ack bit map for the aggregation.
+ *     relevant only if IEEE80211_TX_STATUS_AMPDU was set.
+ * @ack_signal: signal strength of the ACK frame
+ */
+struct ieee80211_tx_info {
+       /* common information */
+       u32 flags;
+       u8 band;
+       s8 tx_rate_idx;
+       u8 antenna_sel_tx;
 
-       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 */
-       u8 iv_len;              /* length of the IV field in octets */
-       u16 queue;              /* hardware queue to use for this frame;
-                                * 0 = highest, hw->queues-1 = lowest */
-       u16 aid;                /* Station AID */
-       int type;       /* internal */
+       u8 queue; /* use skb_queue_mapping soon */
+
+       union {
+               struct {
+                       struct ieee80211_vif *vif;
+                       struct ieee80211_key_conf *hw_key;
+                       unsigned long jiffies;
+                       int ifindex;
+                       u16 aid;
+                       s8 rts_cts_rate_idx, alt_retry_rate_idx;
+                       u8 retry_limit;
+                       u8 icv_len;
+                       u8 iv_len;
+               } control;
+               struct {
+                       u64 ampdu_ack_map;
+                       int ack_signal;
+                       u8 retry_count;
+                       bool excessive_retries;
+                       u8 ampdu_ack_len;
+               } status;
+               void *driver_data[IEEE80211_TX_INFO_DRIVER_DATA_PTRS];
+       };
 };
 
+static inline struct ieee80211_tx_info *IEEE80211_SKB_CB(struct sk_buff *skb)
+{
+       return (struct ieee80211_tx_info *)skb->cb;
+}
 
 
 /**
@@ -362,52 +388,6 @@ struct ieee80211_rx_status {
        int flag;
 };
 
-/**
- * enum ieee80211_tx_status_flags - transmit status flags
- *
- * Status flags to indicate various transmit conditions.
- *
- * @IEEE80211_TX_STATUS_TX_FILTERED: The frame was not transmitted
- *     because the destination STA was in powersave mode.
- * @IEEE80211_TX_STATUS_ACK: Frame was acknowledged
- * @IEEE80211_TX_STATUS_AMPDU: The frame was aggregated, so status
- *     is for the whole aggregation.
- */
-enum ieee80211_tx_status_flags {
-       IEEE80211_TX_STATUS_TX_FILTERED = 1<<0,
-       IEEE80211_TX_STATUS_ACK         = 1<<1,
-       IEEE80211_TX_STATUS_AMPDU       = 1<<2,
-};
-
-/**
- * struct ieee80211_tx_status - transmit status
- *
- * As much information as possible should be provided for each transmitted
- * frame with ieee80211_tx_status().
- *
- * @control: a copy of the &struct ieee80211_tx_control passed to the driver
- *     in the tx() callback.
- * @flags: transmit status flags, defined above
- * @retry_count: number of retries
- * @excessive_retries: set to 1 if the frame was retried many times
- *     but not acknowledged
- * @ampdu_ack_len: number of aggregated frames.
- *     relevant only if IEEE80211_TX_STATUS_AMPDU was set.
- * @ampdu_ack_map: block ack bit map for the aggregation.
- *     relevant only if IEEE80211_TX_STATUS_AMPDU was set.
- * @ack_signal: signal strength of the ACK frame either in dBm, dB or unspec
- *     depending on hardware capabilites flags @IEEE80211_HW_SIGNAL_*
- */
-struct ieee80211_tx_status {
-       struct ieee80211_tx_control control;
-       u8 flags;
-       u8 retry_count;
-       bool excessive_retries;
-       u8 ampdu_ack_len;
-       u64 ampdu_ack_map;
-       int ack_signal;
-};
-
 /**
  * enum ieee80211_conf_flags - configuration flags
  *
@@ -563,7 +543,6 @@ struct ieee80211_if_conf {
        u8 *ssid;
        size_t ssid_len;
        struct sk_buff *beacon;
-       struct ieee80211_tx_control *beacon_control;
 };
 
 /**
@@ -825,7 +804,7 @@ static inline void SET_IEEE80211_PERM_ADDR(struct ieee80211_hw *hw, u8 *addr)
 
 static inline struct ieee80211_rate *
 ieee80211_get_tx_rate(const struct ieee80211_hw *hw,
-                     const struct ieee80211_tx_control *c)
+                     const struct ieee80211_tx_info *c)
 {
        if (WARN_ON(c->tx_rate_idx < 0))
                return NULL;
@@ -834,20 +813,20 @@ ieee80211_get_tx_rate(const struct ieee80211_hw *hw,
 
 static inline struct ieee80211_rate *
 ieee80211_get_rts_cts_rate(const struct ieee80211_hw *hw,
-                          const struct ieee80211_tx_control *c)
+                          const struct ieee80211_tx_info *c)
 {
-       if (c->rts_cts_rate_idx < 0)
+       if (c->control.rts_cts_rate_idx < 0)
                return NULL;
-       return &hw->wiphy->bands[c->band]->bitrates[c->rts_cts_rate_idx];
+       return &hw->wiphy->bands[c->band]->bitrates[c->control.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)
+                            const struct ieee80211_tx_info *c)
 {
-       if (c->alt_retry_rate_idx < 0)
+       if (c->control.alt_retry_rate_idx < 0)
                return NULL;
-       return &hw->wiphy->bands[c->band]->bitrates[c->alt_retry_rate_idx];
+       return &hw->wiphy->bands[c->band]->bitrates[c->control.alt_retry_rate_idx];
 }
 
 /**
@@ -1142,8 +1121,7 @@ enum ieee80211_ampdu_mlme_action {
  *     that TX/RX_STOP can pass NULL for this parameter.
  */
 struct ieee80211_ops {
-       int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb,
-                 struct ieee80211_tx_control *control);
+       int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
        int (*start)(struct ieee80211_hw *hw);
        void (*stop)(struct ieee80211_hw *hw);
        int (*add_interface)(struct ieee80211_hw *hw,
@@ -1187,8 +1165,7 @@ struct ieee80211_ops {
        u64 (*get_tsf)(struct ieee80211_hw *hw);
        void (*reset_tsf)(struct ieee80211_hw *hw);
        int (*beacon_update)(struct ieee80211_hw *hw,
-                            struct sk_buff *skb,
-                            struct ieee80211_tx_control *control);
+                            struct sk_buff *skb);
        int (*tx_last_beacon)(struct ieee80211_hw *hw);
        int (*ampdu_action)(struct ieee80211_hw *hw,
                            enum ieee80211_ampdu_mlme_action action,
@@ -1384,13 +1361,9 @@ void ieee80211_rx_irqsafe(struct ieee80211_hw *hw,
  *
  * @hw: the hardware the frame was transmitted by
  * @skb: the frame that was transmitted, owned by mac80211 after this call
- * @status: status information for this frame; the status pointer need not
- *     be valid after this function returns and is not freed by mac80211,
- *     it is recommended that it points to a stack area
  */
 void ieee80211_tx_status(struct ieee80211_hw *hw,
-                        struct sk_buff *skb,
-                        struct ieee80211_tx_status *status);
+                        struct sk_buff *skb);
 
 /**
  * ieee80211_tx_status_irqsafe - irq-safe transmit status callback
@@ -1403,13 +1376,9 @@ void ieee80211_tx_status(struct ieee80211_hw *hw,
  *
  * @hw: the hardware the frame was transmitted by
  * @skb: the frame that was transmitted, owned by mac80211 after this call
- * @status: status information for this frame; the status pointer need not
- *     be valid after this function returns and is not freed by mac80211,
- *     it is recommended that it points to a stack area
  */
 void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
-                                struct sk_buff *skb,
-                                struct ieee80211_tx_status *status);
+                                struct sk_buff *skb);
 
 /**
  * ieee80211_beacon_get - beacon generation function
@@ -1425,8 +1394,7 @@ void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
  * is responsible of freeing it.
  */
 struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
-                                    struct ieee80211_vif *vif,
-                                    struct ieee80211_tx_control *control);
+                                    struct ieee80211_vif *vif);
 
 /**
  * ieee80211_rts_get - RTS frame generation function
@@ -1434,7 +1402,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
  * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
  * @frame: pointer to the frame that is going to be protected by the RTS.
  * @frame_len: the frame length (in octets).
- * @frame_txctl: &struct ieee80211_tx_control of the frame.
+ * @frame_txctl: &struct ieee80211_tx_info of the frame.
  * @rts: The buffer where to store the RTS frame.
  *
  * If the RTS frames are generated by the host system (i.e., not in
@@ -1444,7 +1412,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
  */
 void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                       const void *frame, size_t frame_len,
-                      const struct ieee80211_tx_control *frame_txctl,
+                      const struct ieee80211_tx_info *frame_txctl,
                       struct ieee80211_rts *rts);
 
 /**
@@ -1452,7 +1420,7 @@ void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  * @hw: pointer obtained from ieee80211_alloc_hw().
  * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
  * @frame_len: the length of the frame that is going to be protected by the RTS.
- * @frame_txctl: &struct ieee80211_tx_control of the frame.
+ * @frame_txctl: &struct ieee80211_tx_info of the frame.
  *
  * If the RTS is generated in firmware, but the host system must provide
  * the duration field, the low-level driver uses this function to receive
@@ -1460,7 +1428,7 @@ void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  */
 __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
                              struct ieee80211_vif *vif, size_t frame_len,
-                             const struct ieee80211_tx_control *frame_txctl);
+                             const struct ieee80211_tx_info *frame_txctl);
 
 /**
  * ieee80211_ctstoself_get - CTS-to-self frame generation function
@@ -1468,7 +1436,7 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
  * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
  * @frame: pointer to the frame that is going to be protected by the CTS-to-self.
  * @frame_len: the frame length (in octets).
- * @frame_txctl: &struct ieee80211_tx_control of the frame.
+ * @frame_txctl: &struct ieee80211_tx_info of the frame.
  * @cts: The buffer where to store the CTS-to-self frame.
  *
  * If the CTS-to-self frames are generated by the host system (i.e., not in
@@ -1479,7 +1447,7 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
 void ieee80211_ctstoself_get(struct ieee80211_hw *hw,
                             struct ieee80211_vif *vif,
                             const void *frame, size_t frame_len,
-                            const struct ieee80211_tx_control *frame_txctl,
+                            const struct ieee80211_tx_info *frame_txctl,
                             struct ieee80211_cts *cts);
 
 /**
@@ -1487,7 +1455,7 @@ void ieee80211_ctstoself_get(struct ieee80211_hw *hw,
  * @hw: pointer obtained from ieee80211_alloc_hw().
  * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
  * @frame_len: the length of the frame that is going to be protected by the CTS-to-self.
- * @frame_txctl: &struct ieee80211_tx_control of the frame.
+ * @frame_txctl: &struct ieee80211_tx_info of the frame.
  *
  * If the CTS-to-self is generated in firmware, but the host system must provide
  * the duration field, the low-level driver uses this function to receive
@@ -1496,7 +1464,7 @@ void ieee80211_ctstoself_get(struct ieee80211_hw *hw,
 __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
                                    struct ieee80211_vif *vif,
                                    size_t frame_len,
-                                   const struct ieee80211_tx_control *frame_txctl);
+                                   const struct ieee80211_tx_info *frame_txctl);
 
 /**
  * ieee80211_generic_frame_duration - Calculate the duration field for a frame
@@ -1535,8 +1503,7 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
  * use common code for all beacons.
  */
 struct sk_buff *
-ieee80211_get_buffered_bc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                         struct ieee80211_tx_control *control);
+ieee80211_get_buffered_bc(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
 
 /**
  * ieee80211_get_hdrlen_from_skb - get header length from data
index a4cccd1..79a65b3 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright 2002-2005, Instant802 Networks, Inc.
  * Copyright 2005, Devicescape Software, Inc.
  * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
+ * Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -147,7 +148,6 @@ typedef unsigned __bitwise__ ieee80211_tx_result;
 #define IEEE80211_TX_UNICAST           BIT(1)
 #define IEEE80211_TX_PS_BUFFERED       BIT(2)
 #define IEEE80211_TX_PROBE_LAST_FRAG   BIT(3)
-#define IEEE80211_TX_INJECTED          BIT(4)
 
 struct ieee80211_tx_data {
        struct sk_buff *skb;
@@ -157,7 +157,6 @@ struct ieee80211_tx_data {
        struct sta_info *sta;
        struct ieee80211_key *key;
 
-       struct ieee80211_tx_control *control;
        struct ieee80211_channel *channel;
        s8 rate_idx;
        /* use this rate (if set) for last fragment; rate can
@@ -207,22 +206,7 @@ struct ieee80211_rx_data {
        u16 tkip_iv16;
 };
 
-/* flags used in struct ieee80211_tx_packet_data.flags */
-#define IEEE80211_TXPD_REQ_TX_STATUS   BIT(0)
-#define IEEE80211_TXPD_DO_NOT_ENCRYPT  BIT(1)
-#define IEEE80211_TXPD_REQUEUE         BIT(2)
-#define IEEE80211_TXPD_EAPOL_FRAME     BIT(3)
-#define IEEE80211_TXPD_AMPDU           BIT(4)
-/* Stored in sk_buff->cb */
-struct ieee80211_tx_packet_data {
-       int ifindex;
-       unsigned long jiffies;
-       unsigned int flags;
-       u8 queue;
-};
-
 struct ieee80211_tx_stored_packet {
-       struct ieee80211_tx_control control;
        struct sk_buff *skb;
        struct sk_buff **extra_frag;
        s8 last_frag_rate_idx;
index 9761d9b..8f1ff7e 100644 (file)
@@ -971,8 +971,7 @@ void ieee80211_if_setup(struct net_device *dev)
 /* everything else */
 
 static int __ieee80211_if_config(struct net_device *dev,
-                                struct sk_buff *beacon,
-                                struct ieee80211_tx_control *control)
+                                struct sk_buff *beacon)
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
@@ -990,13 +989,11 @@ static int __ieee80211_if_config(struct net_device *dev,
                conf.ssid_len = sdata->u.sta.ssid_len;
        } else if (ieee80211_vif_is_mesh(&sdata->vif)) {
                conf.beacon = beacon;
-               conf.beacon_control = control;
                ieee80211_start_mesh(dev);
        } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) {
                conf.ssid = sdata->u.ap.ssid;
                conf.ssid_len = sdata->u.ap.ssid_len;
                conf.beacon = beacon;
-               conf.beacon_control = control;
        }
        return local->ops->config_interface(local_to_hw(local),
                                            &sdata->vif, &conf);
@@ -1009,23 +1006,21 @@ int ieee80211_if_config(struct net_device *dev)
        if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT &&
            (local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE))
                return ieee80211_if_config_beacon(dev);
-       return __ieee80211_if_config(dev, NULL, NULL);
+       return __ieee80211_if_config(dev, NULL);
 }
 
 int ieee80211_if_config_beacon(struct net_device *dev)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct ieee80211_tx_control control;
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct sk_buff *skb;
 
        if (!(local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE))
                return 0;
-       skb = ieee80211_beacon_get(local_to_hw(local), &sdata->vif,
-                                  &control);
+       skb = ieee80211_beacon_get(local_to_hw(local), &sdata->vif);
        if (!skb)
                return -ENOMEM;
-       return __ieee80211_if_config(dev, skb, &control);
+       return __ieee80211_if_config(dev, skb);
 }
 
 int ieee80211_hw_config(struct ieee80211_local *local)
@@ -1180,38 +1175,20 @@ void ieee80211_reset_erp_info(struct net_device *dev)
 }
 
 void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
-                                struct sk_buff *skb,
-                                struct ieee80211_tx_status *status)
+                                struct sk_buff *skb)
 {
        struct ieee80211_local *local = hw_to_local(hw);
-       struct ieee80211_tx_status *saved;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        int tmp;
 
        skb->dev = local->mdev;
-       saved = kmalloc(sizeof(struct ieee80211_tx_status), GFP_ATOMIC);
-       if (unlikely(!saved)) {
-               if (net_ratelimit())
-                       printk(KERN_WARNING "%s: Not enough memory, "
-                              "dropping tx status", skb->dev->name);
-               /* should be dev_kfree_skb_irq, but due to this function being
-                * named _irqsafe instead of just _irq we can't be sure that
-                * people won't call it from non-irq contexts */
-               dev_kfree_skb_any(skb);
-               return;
-       }
-       memcpy(saved, status, sizeof(struct ieee80211_tx_status));
-       /* copy pointer to saved status into skb->cb for use by tasklet */
-       memcpy(skb->cb, &saved, sizeof(saved));
-
        skb->pkt_type = IEEE80211_TX_STATUS_MSG;
-       skb_queue_tail(status->control.flags & IEEE80211_TXCTL_REQ_TX_STATUS ?
+       skb_queue_tail(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS ?
                       &local->skb_queue : &local->skb_queue_unreliable, skb);
        tmp = skb_queue_len(&local->skb_queue) +
                skb_queue_len(&local->skb_queue_unreliable);
        while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT &&
               (skb = skb_dequeue(&local->skb_queue_unreliable))) {
-               memcpy(&saved, skb->cb, sizeof(saved));
-               kfree(saved);
                dev_kfree_skb_irq(skb);
                tmp--;
                I802_DEBUG_INC(local->tx_status_drop);
@@ -1225,7 +1202,6 @@ static void ieee80211_tasklet_handler(unsigned long data)
        struct ieee80211_local *local = (struct ieee80211_local *) data;
        struct sk_buff *skb;
        struct ieee80211_rx_status rx_status;
-       struct ieee80211_tx_status *tx_status;
        struct ieee80211_ra_tid *ra_tid;
 
        while ((skb = skb_dequeue(&local->skb_queue)) ||
@@ -1240,12 +1216,8 @@ static void ieee80211_tasklet_handler(unsigned long data)
                        __ieee80211_rx(local_to_hw(local), skb, &rx_status);
                        break;
                case IEEE80211_TX_STATUS_MSG:
-                       /* get pointer to saved status out of skb->cb */
-                       memcpy(&tx_status, skb->cb, sizeof(tx_status));
                        skb->pkt_type = 0;
-                       ieee80211_tx_status(local_to_hw(local),
-                                           skb, tx_status);
-                       kfree(tx_status);
+                       ieee80211_tx_status(local_to_hw(local), skb);
                        break;
                case IEEE80211_DELBA_MSG:
                        ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
@@ -1274,24 +1246,15 @@ static void ieee80211_tasklet_handler(unsigned long data)
  * Also, tx_packet_data in cb is restored from tx_control. */
 static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
                                      struct ieee80211_key *key,
-                                     struct sk_buff *skb,
-                                     struct ieee80211_tx_control *control)
+                                     struct sk_buff *skb)
 {
        int hdrlen, iv_len, mic_len;
-       struct ieee80211_tx_packet_data *pkt_data;
-
-       pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
-       pkt_data->ifindex = vif_to_sdata(control->vif)->dev->ifindex;
-       pkt_data->flags = 0;
-       if (control->flags & IEEE80211_TXCTL_REQ_TX_STATUS)
-               pkt_data->flags |= IEEE80211_TXPD_REQ_TX_STATUS;
-       if (control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)
-               pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT;
-       if (control->flags & IEEE80211_TXCTL_REQUEUE)
-               pkt_data->flags |= IEEE80211_TXPD_REQUEUE;
-       if (control->flags & IEEE80211_TXCTL_EAPOL_FRAME)
-               pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME;
-       pkt_data->queue = control->queue;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+       info->flags &=  IEEE80211_TX_CTL_REQ_TX_STATUS |
+                       IEEE80211_TX_CTL_DO_NOT_ENCRYPT |
+                       IEEE80211_TX_CTL_REQUEUE |
+                       IEEE80211_TX_CTL_EAPOL_FRAME;
 
        hdrlen = ieee80211_get_hdrlen_from_skb(skb);
 
@@ -1338,9 +1301,10 @@ no_key:
 
 static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
                                            struct sta_info *sta,
-                                           struct sk_buff *skb,
-                                           struct ieee80211_tx_status *status)
+                                           struct sk_buff *skb)
 {
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
        sta->tx_filtered_count++;
 
        /*
@@ -1382,18 +1346,16 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
         */
        if (test_sta_flags(sta, WLAN_STA_PS) &&
            skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) {
-               ieee80211_remove_tx_extra(local, sta->key, skb,
-                                         &status->control);
+               ieee80211_remove_tx_extra(local, sta->key, skb);
                skb_queue_tail(&sta->tx_filtered, skb);
                return;
        }
 
        if (!test_sta_flags(sta, WLAN_STA_PS) &&
-           !(status->control.flags & IEEE80211_TXCTL_REQUEUE)) {
+           !(info->flags & IEEE80211_TX_CTL_REQUEUE)) {
                /* Software retry the packet once */
-               status->control.flags |= IEEE80211_TXCTL_REQUEUE;
-               ieee80211_remove_tx_extra(local, sta->key, skb,
-                                         &status->control);
+               info->flags |= IEEE80211_TX_CTL_REQUEUE;
+               ieee80211_remove_tx_extra(local, sta->key, skb);
                dev_queue_xmit(skb);
                return;
        }
@@ -1407,28 +1369,20 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
        dev_kfree_skb(skb);
 }
 
-void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
-                        struct ieee80211_tx_status *status)
+void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct sk_buff *skb2;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
        struct ieee80211_local *local = hw_to_local(hw);
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        u16 frag, type;
        struct ieee80211_tx_status_rtap_hdr *rthdr;
        struct ieee80211_sub_if_data *sdata;
        struct net_device *prev_dev = NULL;
 
-       if (!status) {
-               printk(KERN_ERR
-                      "%s: ieee80211_tx_status called with NULL status\n",
-                      wiphy_name(local->hw.wiphy));
-               dev_kfree_skb(skb);
-               return;
-       }
-
        rcu_read_lock();
 
-       if (status->excessive_retries) {
+       if (info->status.excessive_retries) {
                struct sta_info *sta;
                sta = sta_info_get(local, hdr->addr1);
                if (sta) {
@@ -1437,27 +1391,23 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
                                 * The STA is in power save mode, so assume
                                 * that this TX packet failed because of that.
                                 */
-                               status->excessive_retries = 0;
-                               status->flags |= IEEE80211_TX_STATUS_TX_FILTERED;
-                               ieee80211_handle_filtered_frame(local, sta,
-                                                               skb, status);
+                               ieee80211_handle_filtered_frame(local, sta, skb);
                                rcu_read_unlock();
                                return;
                        }
                }
        }
 
-       if (status->flags & IEEE80211_TX_STATUS_TX_FILTERED) {
+       if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
                struct sta_info *sta;
                sta = sta_info_get(local, hdr->addr1);
                if (sta) {
-                       ieee80211_handle_filtered_frame(local, sta, skb,
-                                                       status);
+                       ieee80211_handle_filtered_frame(local, sta, skb);
                        rcu_read_unlock();
                        return;
                }
        } else
-               rate_control_tx_status(local->mdev, skb, status);
+               rate_control_tx_status(local->mdev, skb);
 
        rcu_read_unlock();
 
@@ -1471,14 +1421,14 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
        frag = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG;
        type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE;
 
-       if (status->flags & IEEE80211_TX_STATUS_ACK) {
+       if (info->flags & IEEE80211_TX_STAT_ACK) {
                if (frag == 0) {
                        local->dot11TransmittedFrameCount++;
                        if (is_multicast_ether_addr(hdr->addr1))
                                local->dot11MulticastTransmittedFrameCount++;
-                       if (status->retry_count > 0)
+                       if (info->status.retry_count > 0)
                                local->dot11RetryCount++;
-                       if (status->retry_count > 1)
+                       if (info->status.retry_count > 1)
                                local->dot11MultipleRetryCount++;
                }
 
@@ -1524,17 +1474,17 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
                cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) |
                            (1 << IEEE80211_RADIOTAP_DATA_RETRIES));
 
-       if (!(status->flags & IEEE80211_TX_STATUS_ACK) &&
+       if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
            !is_multicast_ether_addr(hdr->addr1))
                rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL);
 
-       if ((status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) &&
-           (status->control.flags & IEEE80211_TXCTL_USE_CTS_PROTECT))
+       if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) &&
+           (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT))
                rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS);
-       else if (status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS)
+       else if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
                rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS);
 
-       rthdr->data_retries = status->retry_count;
+       rthdr->data_retries = info->status.retry_count;
 
        /* XXX: is this sufficient for BPF? */
        skb_set_mac_header(skb, 0);
@@ -1895,7 +1845,9 @@ static int __init ieee80211_init(void)
        struct sk_buff *skb;
        int ret;
 
-       BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb));
+       BUILD_BUG_ON(sizeof(struct ieee80211_tx_info) > sizeof(skb->cb));
+       BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) +
+                    IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb));
 
        ret = rc80211_pid_init();
        if (ret)
index 6041493..9a26437 100644 (file)
@@ -578,7 +578,7 @@ void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb,
                      int encrypt)
 {
        struct ieee80211_sub_if_data *sdata;
-       struct ieee80211_tx_packet_data *pkt_data;
+       struct ieee80211_tx_info *info;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        skb->dev = sdata->local->mdev;
@@ -586,11 +586,11 @@ void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb,
        skb_set_network_header(skb, 0);
        skb_set_transport_header(skb, 0);
 
-       pkt_data = (struct ieee80211_tx_packet_data *) skb->cb;
-       memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
-       pkt_data->ifindex = sdata->dev->ifindex;
+       info = IEEE80211_SKB_CB(skb);
+       memset(info, 0, sizeof(struct ieee80211_tx_info));
+       info->control.ifindex = sdata->dev->ifindex;
        if (!encrypt)
-               pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT;
+               info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
 
        dev_queue_xmit(skb);
 }
@@ -2314,7 +2314,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
        int res, rates, i, j;
        struct sk_buff *skb;
        struct ieee80211_mgmt *mgmt;
-       struct ieee80211_tx_control control;
+       struct ieee80211_tx_info *control;
        struct rate_selection ratesel;
        u8 *pos;
        struct ieee80211_sub_if_data *sdata;
@@ -2404,21 +2404,22 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
                        memcpy(pos, &bss->supp_rates[8], rates);
                }
 
-               memset(&control, 0, sizeof(control));
+               control = IEEE80211_SKB_CB(skb);
+
                rate_control_get_rate(dev, sband, skb, &ratesel);
                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_idx = ratesel.rate_idx;
+               control->control.vif = &sdata->vif;
+               control->tx_rate_idx = ratesel.rate_idx;
                if (sdata->bss_conf.use_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;
-               control.retry_limit = 1;
+                       control->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE;
+               control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
+               control->flags |= IEEE80211_TX_CTL_NO_ACK;
+               control->control.retry_limit = 1;
 
                ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC);
                if (ifsta->probe_resp) {
@@ -2433,8 +2434,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
                }
 
                if (local->ops->beacon_update &&
-                   local->ops->beacon_update(local_to_hw(local),
-                                            skb, &control) == 0) {
+                   local->ops->beacon_update(local_to_hw(local), skb) == 0) {
                        printk(KERN_DEBUG "%s: Configured IBSS beacon "
                               "template\n", dev->name);
                        skb = NULL;
index a29148d..0ed9c8a 100644 (file)
@@ -34,8 +34,7 @@ struct rate_control_ops {
        struct module *module;
        const char *name;
        void (*tx_status)(void *priv, struct net_device *dev,
-                         struct sk_buff *skb,
-                         struct ieee80211_tx_status *status);
+                         struct sk_buff *skb);
        void (*get_rate)(void *priv, struct net_device *dev,
                         struct ieee80211_supported_band *band,
                         struct sk_buff *skb,
@@ -77,13 +76,12 @@ struct rate_control_ref *rate_control_get(struct rate_control_ref *ref);
 void rate_control_put(struct rate_control_ref *ref);
 
 static inline void rate_control_tx_status(struct net_device *dev,
-                                         struct sk_buff *skb,
-                                         struct ieee80211_tx_status *status)
+                                         struct sk_buff *skb)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct rate_control_ref *ref = local->rate_ctrl;
 
-       ref->ops->tx_status(ref->priv, dev, skb, status);
+       ref->ops->tx_status(ref->priv, dev, skb);
 }
 
 
index 04afc13..2078803 100644 (file)
@@ -61,7 +61,7 @@ enum rc_pid_event_type {
 union rc_pid_event_data {
        /* RC_PID_EVENT_TX_STATUS */
        struct {
-               struct ieee80211_tx_status tx_status;
+               struct ieee80211_tx_info tx_status;
        };
        /* RC_PID_EVENT_TYPE_RATE_CHANGE */
        /* RC_PID_EVENT_TYPE_TX_RATE */
@@ -158,7 +158,7 @@ struct rc_pid_debugfs_entries {
 };
 
 void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf,
-                                            struct ieee80211_tx_status *stat);
+                                     struct ieee80211_tx_info *stat);
 
 void rate_control_pid_event_rate_change(struct rc_pid_event_buffer *buf,
                                               int index, int rate);
index 14cde36..e894541 100644 (file)
@@ -237,8 +237,7 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
 }
 
 static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
-                                      struct sk_buff *skb,
-                                      struct ieee80211_tx_status *status)
+                                      struct sk_buff *skb)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
@@ -248,6 +247,7 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
        struct rc_pid_sta_info *spinfo;
        unsigned long period;
        struct ieee80211_supported_band *sband;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
        rcu_read_lock();
 
@@ -266,28 +266,28 @@ 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_idx != sta->txrate_idx)
+       if (info->tx_rate_idx != sta->txrate_idx)
                goto unlock;
 
        spinfo = sta->rate_ctrl_priv;
        spinfo->tx_num_xmit++;
 
 #ifdef CONFIG_MAC80211_DEBUGFS
-       rate_control_pid_event_tx_status(&spinfo->events, status);
+       rate_control_pid_event_tx_status(&spinfo->events, info);
 #endif
 
        /* We count frames that totally failed to be transmitted as two bad
         * frames, those that made it out but had some retries as one good and
         * one bad frame. */
-       if (status->excessive_retries) {
+       if (info->status.excessive_retries) {
                spinfo->tx_num_failed += 2;
                spinfo->tx_num_xmit++;
-       } else if (status->retry_count) {
+       } else if (info->status.retry_count) {
                spinfo->tx_num_failed++;
                spinfo->tx_num_xmit++;
        }
 
-       if (status->excessive_retries) {
+       if (info->status.excessive_retries) {
                sta->tx_retry_failed++;
                sta->tx_num_consecutive_failures++;
                sta->tx_num_mpdu_fail++;
@@ -295,8 +295,8 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
                sta->tx_num_consecutive_failures = 0;
                sta->tx_num_mpdu_ok++;
        }
-       sta->tx_retry_count += status->retry_count;
-       sta->tx_num_mpdu_fail += status->retry_count;
+       sta->tx_retry_count += info->status.retry_count;
+       sta->tx_num_mpdu_fail += info->status.retry_count;
 
        /* Update PID controller state. */
        period = (HZ * pinfo->sampling_period + 500) / 1000;
index ff5c380..8121d3b 100644 (file)
@@ -39,11 +39,11 @@ static void rate_control_pid_event(struct rc_pid_event_buffer *buf,
 }
 
 void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf,
-                                            struct ieee80211_tx_status *stat)
+                                     struct ieee80211_tx_info *stat)
 {
        union rc_pid_event_data evd;
 
-       memcpy(&evd.tx_status, stat, sizeof(struct ieee80211_tx_status));
+       memcpy(&evd.tx_status, stat, sizeof(struct ieee80211_tx_info));
        rate_control_pid_event(buf, RC_PID_EVENT_TYPE_TX_STATUS, &evd);
 }
 
@@ -167,8 +167,8 @@ static ssize_t rate_control_pid_events_read(struct file *file, char __user *buf,
        switch (ev->type) {
        case RC_PID_EVENT_TYPE_TX_STATUS:
                p += snprintf(pb + p, length - p, "tx_status %u %u",
-                             ev->data.tx_status.excessive_retries,
-                             ev->data.tx_status.retry_count);
+                             ev->data.tx_status.status.excessive_retries,
+                             ev->data.tx_status.status.retry_count);
                break;
        case RC_PID_EVENT_TYPE_RATE_CHANGE:
                p += snprintf(pb + p, length - p, "rate_change %d %d",
index fa68305..cf0de3b 100644 (file)
@@ -714,7 +714,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
        struct sk_buff *skb;
        int sent = 0;
        struct ieee80211_sub_if_data *sdata;
-       struct ieee80211_tx_packet_data *pkt_data;
+       struct ieee80211_tx_info *info;
        DECLARE_MAC_BUF(mac);
 
        sdata = sta->sdata;
@@ -734,13 +734,13 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
 
        /* Send all buffered frames to the station */
        while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) {
-               pkt_data = (struct ieee80211_tx_packet_data *) skb->cb;
+               info = IEEE80211_SKB_CB(skb);
                sent++;
-               pkt_data->flags |= IEEE80211_TXPD_REQUEUE;
+               info->flags |= IEEE80211_TX_CTL_REQUEUE;
                dev_queue_xmit(skb);
        }
        while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) {
-               pkt_data = (struct ieee80211_tx_packet_data *) skb->cb;
+               info = IEEE80211_SKB_CB(skb);
                local->total_ps_buffered--;
                sent++;
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
@@ -748,7 +748,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
                       "since STA not sleeping anymore\n", dev->name,
                       print_mac(mac, sta->addr), sta->aid);
 #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
-               pkt_data->flags |= IEEE80211_TXPD_REQUEUE;
+               info->flags |= IEEE80211_TX_CTL_REQUEUE;
                dev_queue_xmit(skb);
        }
 
index baf5e47..ef31493 100644 (file)
@@ -511,20 +511,20 @@ static inline int sta_info_buffer_expired(struct ieee80211_local *local,
                                          struct sta_info *sta,
                                          struct sk_buff *skb)
 {
-       struct ieee80211_tx_packet_data *pkt_data;
+       struct ieee80211_tx_info *info;
        int timeout;
 
        if (!skb)
                return 0;
 
-       pkt_data = (struct ieee80211_tx_packet_data *) skb->cb;
+       info = IEEE80211_SKB_CB(skb);
 
        /* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */
        timeout = (sta->listen_interval * local->hw.conf.beacon_int * 32 /
                   15625) * HZ;
        if (timeout < STA_TX_BUFFER_EXPIRE)
                timeout = STA_TX_BUFFER_EXPIRE;
-       return time_after(jiffies, pkt_data->jiffies + timeout);
+       return time_after(jiffies, info->control.jiffies + timeout);
 }
 
 
index e89cc16..f592290 100644 (file)
@@ -32,7 +32,7 @@
  * @WLAN_STA_WDS: Station is one of our WDS peers.
  * @WLAN_STA_PSPOLL: Station has just PS-polled us.
  * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
- *     IEEE80211_TXCTL_CLEAR_PS_FILT control flag) when the next
+ *     IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
  *     frame to this station is transmitted.
  */
 enum ieee80211_sta_info_flags {
index 666158f..ac9a4af 100644 (file)
@@ -238,12 +238,12 @@ static ieee80211_tx_result
 ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
 {
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-       struct sk_buff *skb = tx->skb;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
 #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
        u32 sta_flags;
 
-       if (unlikely(tx->flags & IEEE80211_TX_INJECTED))
+       if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED))
                return TX_CONTINUE;
 
        if (unlikely(tx->local->sta_sw_scanning) &&
@@ -348,6 +348,8 @@ static void purge_old_ps_buffers(struct ieee80211_local *local)
 static ieee80211_tx_result
 ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
 {
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
+
        /*
         * broadcast/multicast frame
         *
@@ -383,7 +385,7 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
        }
 
        /* buffered in hardware */
-       tx->control->flags |= IEEE80211_TXCTL_SEND_AFTER_DTIM;
+       info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM;
 
        return TX_CONTINUE;
 }
@@ -392,6 +394,7 @@ static ieee80211_tx_result
 ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
 {
        struct sta_info *sta = tx->sta;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
        u32 staflags;
        DECLARE_MAC_BUF(mac);
 
@@ -404,7 +407,6 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
 
        if (unlikely((staflags & WLAN_STA_PS) &&
                     !(staflags & WLAN_STA_PSPOLL))) {
-               struct ieee80211_tx_packet_data *pkt_data;
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
                printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries "
                       "before %d)\n",
@@ -428,8 +430,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
                if (skb_queue_empty(&sta->ps_tx_buf))
                        sta_info_set_tim_bit(sta);
 
-               pkt_data = (struct ieee80211_tx_packet_data *)tx->skb->cb;
-               pkt_data->jiffies = jiffies;
+               info->control.jiffies = jiffies;
                skb_queue_tail(&sta->ps_tx_buf, tx->skb);
                return TX_QUEUED;
        }
@@ -461,17 +462,18 @@ static ieee80211_tx_result
 ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
 {
        struct ieee80211_key *key;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
        u16 fc = tx->fc;
 
-       if (unlikely(tx->control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT))
+       if (unlikely(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT))
                tx->key = NULL;
        else if (tx->sta && (key = rcu_dereference(tx->sta->key)))
                tx->key = key;
        else if ((key = rcu_dereference(tx->sdata->default_key)))
                tx->key = key;
        else if (tx->sdata->drop_unencrypted &&
-                !(tx->control->flags & IEEE80211_TXCTL_EAPOL_FRAME) &&
-                !(tx->flags & IEEE80211_TX_INJECTED)) {
+                !(info->flags & IEEE80211_TX_CTL_EAPOL_FRAME) &&
+                !(info->flags & IEEE80211_TX_CTL_INJECTED)) {
                I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted);
                return TX_DROP;
        } else
@@ -500,7 +502,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
        }
 
        if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
-               tx->control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
+               info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
 
        return TX_CONTINUE;
 }
@@ -510,6 +512,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
 {
        struct rate_selection rsel;
        struct ieee80211_supported_band *sband;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
 
        sband = tx->local->hw.wiphy->bands[tx->channel->band];
 
@@ -517,18 +520,17 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
                rate_control_get_rate(tx->dev, sband, tx->skb, &rsel);
                tx->rate_idx = rsel.rate_idx;
                if (unlikely(rsel.probe_idx >= 0)) {
-                       tx->control->flags |=
-                               IEEE80211_TXCTL_RATE_CTRL_PROBE;
+                       info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
                        tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG;
-                       tx->control->alt_retry_rate_idx = tx->rate_idx;
+                       info->control.alt_retry_rate_idx = tx->rate_idx;
                        tx->rate_idx = rsel.probe_idx;
                } else
-                       tx->control->alt_retry_rate_idx = -1;
+                       info->control.alt_retry_rate_idx = -1;
 
                if (unlikely(tx->rate_idx < 0))
                        return TX_DROP;
        } else
-               tx->control->alt_retry_rate_idx = -1;
+               info->control.alt_retry_rate_idx = -1;
 
        if (tx->sdata->bss_conf.use_cts_prot &&
            (tx->flags & IEEE80211_TX_FRAGMENTED) && (rsel.nonerp_idx >= 0)) {
@@ -538,13 +540,13 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
                else
                        tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG;
                tx->rate_idx = rsel.nonerp_idx;
-               tx->control->tx_rate_idx = rsel.nonerp_idx;
-               tx->control->flags &= ~IEEE80211_TXCTL_RATE_CTRL_PROBE;
+               info->tx_rate_idx = rsel.nonerp_idx;
+               info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE;
        } else {
                tx->last_frag_rate_idx = tx->rate_idx;
-               tx->control->tx_rate_idx = tx->rate_idx;
+               info->tx_rate_idx = tx->rate_idx;
        }
-       tx->control->tx_rate_idx = tx->rate_idx;
+       info->tx_rate_idx = tx->rate_idx;
 
        return TX_CONTINUE;
 }
@@ -555,28 +557,32 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
        u16 fc = le16_to_cpu(hdr->frame_control);
        u16 dur;
-       struct ieee80211_tx_control *control = tx->control;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
        struct ieee80211_supported_band *sband;
 
        sband = tx->local->hw.wiphy->bands[tx->channel->band];
 
-       if (!control->retry_limit) {
+       if (tx->sta)
+               info->control.aid = tx->sta->aid;
+
+       if (!info->control.retry_limit) {
                if (!is_multicast_ether_addr(hdr->addr1)) {
-                       if (tx->skb->len + FCS_LEN > tx->local->rts_threshold
+                       int len = min_t(int, tx->skb->len + FCS_LEN,
+                                       tx->local->fragmentation_threshold);
+                       if (len > tx->local->rts_threshold
                            && tx->local->rts_threshold <
-                                       IEEE80211_MAX_RTS_THRESHOLD) {
-                               control->flags |=
-                                       IEEE80211_TXCTL_USE_RTS_CTS;
-                               control->flags |=
-                                       IEEE80211_TXCTL_LONG_RETRY_LIMIT;
-                               control->retry_limit =
+                                               IEEE80211_MAX_RTS_THRESHOLD) {
+                               info->flags |= IEEE80211_TX_CTL_USE_RTS_CTS;
+                               info->flags |=
+                                       IEEE80211_TX_CTL_LONG_RETRY_LIMIT;
+                               info->control.retry_limit =
                                        tx->local->long_retry_limit;
                        } else {
-                               control->retry_limit =
+                               info->control.retry_limit =
                                        tx->local->short_retry_limit;
                        }
                } else {
-                       control->retry_limit = 1;
+                       info->control.retry_limit = 1;
                }
        }
 
@@ -585,7 +591,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
                 * frames.
                 * TODO: The last fragment could still use multiple retry
                 * rates. */
-               control->alt_retry_rate_idx = -1;
+               info->control.alt_retry_rate_idx = -1;
        }
 
        /* Use CTS protection for unicast frames sent using extended rates if
@@ -595,8 +601,8 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
            (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))
-               control->flags |= IEEE80211_TXCTL_USE_CTS_PROTECT;
+           !(info->flags & IEEE80211_TX_CTL_USE_RTS_CTS))
+               info->flags |= IEEE80211_TX_CTL_USE_CTS_PROTECT;
 
        /* Transmit data frames using short preambles if the driver supports
         * short preambles at the selected rate and short preambles are
@@ -605,7 +611,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
            (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;
+               info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE;
        }
 
        /* Setup duration field for the first fragment of the frame. Duration
@@ -616,8 +622,8 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
                                 tx->extra_frag[0]->len : 0);
        hdr->duration_id = cpu_to_le16(dur);
 
-       if ((control->flags & IEEE80211_TXCTL_USE_RTS_CTS) ||
-           (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) {
+       if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
+           (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) {
                struct ieee80211_supported_band *sband;
                struct ieee80211_rate *rate;
                s8 baserate = -1;
@@ -626,7 +632,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
                sband = tx->local->hw.wiphy->bands[tx->channel->band];
 
                /* Do not use multiple retry rates when using RTS/CTS */
-               control->alt_retry_rate_idx = -1;
+               info->control.alt_retry_rate_idx = -1;
 
                /* Use min(data rate, max base rate) as CTS/RTS rate */
                rate = &sband->bitrates[tx->rate_idx];
@@ -642,13 +648,13 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
                }
 
                if (baserate >= 0)
-                       control->rts_cts_rate_idx = baserate;
+                       info->control.rts_cts_rate_idx = baserate;
                else
-                       control->rts_cts_rate_idx = 0;
+                       info->control.rts_cts_rate_idx = 0;
        }
 
        if (tx->sta)
-               control->aid = tx->sta->aid;
+               info->control.aid = tx->sta->aid;
 
        return TX_CONTINUE;
 }
@@ -762,6 +768,7 @@ ieee80211_tx_h_stats(struct ieee80211_tx_data *tx)
        u32 load = 0, hdrtime;
        struct ieee80211_rate *rate;
        struct ieee80211_supported_band *sband;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
        sband = tx->local->hw.wiphy->bands[tx->channel->band];
        rate = &sband->bitrates[tx->rate_idx];
@@ -786,9 +793,9 @@ ieee80211_tx_h_stats(struct ieee80211_tx_data *tx)
        if (!is_multicast_ether_addr(hdr->addr1))
                load += hdrtime;
 
-       if (tx->control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
+       if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
                load += 2 * hdrtime;
-       else if (tx->control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
+       else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
                load += hdrtime;
 
        /* TODO: optimise again */
@@ -839,6 +846,7 @@ static ieee80211_tx_handler ieee80211_tx_handlers[] =
        ieee80211_tx_h_rate_ctrl,
        ieee80211_tx_h_misc,
        ieee80211_tx_h_fragment,
+       /* handlers after fragment must be aware of tx info fragmentation! */
        ieee80211_tx_h_encrypt,
        ieee80211_tx_h_stats,
        NULL
@@ -867,12 +875,12 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
                (struct ieee80211_radiotap_header *) skb->data;
        struct ieee80211_supported_band *sband;
        int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len);
-       struct ieee80211_tx_control *control = tx->control;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
        sband = tx->local->hw.wiphy->bands[tx->channel->band];
 
-       control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
-       tx->flags |= IEEE80211_TX_INJECTED;
+       info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
+       info->flags |= IEEE80211_TX_CTL_INJECTED;
        tx->flags &= ~IEEE80211_TX_FRAGMENTED;
 
        /*
@@ -920,7 +928,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
                         * radiotap uses 0 for 1st ant, mac80211 is 1 for
                         * 1st ant
                         */
-                       control->antenna_sel_tx = (*iterator.this_arg) + 1;
+                       info->antenna_sel_tx = (*iterator.this_arg) + 1;
                        break;
 
 #if 0
@@ -944,8 +952,8 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
                                skb_trim(skb, skb->len - FCS_LEN);
                        }
                        if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP)
-                               control->flags &=
-                                       ~IEEE80211_TXCTL_DO_NOT_ENCRYPT;
+                               info->flags &=
+                                       ~IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
                        if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG)
                                tx->flags |= IEEE80211_TX_FRAGMENTED;
                        break;
@@ -980,12 +988,12 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
 static ieee80211_tx_result
 __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
                       struct sk_buff *skb,
-                      struct net_device *dev,
-                      struct ieee80211_tx_control *control)
+                      struct net_device *dev)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_hdr *hdr;
        struct ieee80211_sub_if_data *sdata;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
        int hdrlen;
 
@@ -994,7 +1002,7 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
        tx->dev = dev; /* use original interface */
        tx->local = local;
        tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       tx->control = control;
+       tx->channel = local->hw.conf.channel;
        /*
         * Set this flag (used below to indicate "automatic fragmentation"),
         * it will be cleared/left by radiotap as desired.
@@ -1021,10 +1029,10 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
 
        if (is_multicast_ether_addr(hdr->addr1)) {
                tx->flags &= ~IEEE80211_TX_UNICAST;
-               control->flags |= IEEE80211_TXCTL_NO_ACK;
+               info->flags |= IEEE80211_TX_CTL_NO_ACK;
        } else {
                tx->flags |= IEEE80211_TX_UNICAST;
-               control->flags &= ~IEEE80211_TXCTL_NO_ACK;
+               info->flags &= ~IEEE80211_TX_CTL_NO_ACK;
        }
 
        if (tx->flags & IEEE80211_TX_FRAGMENTED) {
@@ -1037,16 +1045,16 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
        }
 
        if (!tx->sta)
-               control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT;
+               info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
        else if (test_and_clear_sta_flags(tx->sta, WLAN_STA_CLEAR_PS_FILT))
-               control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT;
+               info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
 
        hdrlen = ieee80211_get_hdrlen(tx->fc);
        if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) {
                u8 *pos = &skb->data[hdrlen + sizeof(rfc1042_header)];
                tx->ethertype = (pos[0] << 8) | pos[1];
        }
-       control->flags |= IEEE80211_TXCTL_FIRST_FRAGMENT;
+       info->flags |= IEEE80211_TX_CTL_FIRST_FRAGMENT;
 
        return TX_CONTINUE;
 }
@@ -1056,14 +1064,12 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
  */
 static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
                                struct sk_buff *skb,
-                               struct net_device *mdev,
-                               struct ieee80211_tx_control *control)
+                               struct net_device *mdev)
 {
-       struct ieee80211_tx_packet_data *pkt_data;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct net_device *dev;
 
-       pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
-       dev = dev_get_by_index(&init_net, pkt_data->ifindex);
+       dev = dev_get_by_index(&init_net, info->control.ifindex);
        if (unlikely(dev && !is_ieee80211_device(dev, mdev))) {
                dev_put(dev);
                dev = NULL;
@@ -1071,7 +1077,7 @@ static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
        if (unlikely(!dev))
                return -ENODEV;
        /* initialises tx with control */
-       __ieee80211_tx_prepare(tx, skb, dev, control);
+       __ieee80211_tx_prepare(tx, skb, dev);
        dev_put(dev);
        return 0;
 }
@@ -1079,7 +1085,7 @@ static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
 static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
                          struct ieee80211_tx_data *tx)
 {
-       struct ieee80211_tx_control *control = tx->control;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        int ret, i;
 
        if (!ieee80211_qdisc_installed(local->mdev) &&
@@ -1090,39 +1096,39 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
        if (skb) {
                ieee80211_dump_frame(wiphy_name(local->hw.wiphy),
                                     "TX to low-level driver", skb);
-               ret = local->ops->tx(local_to_hw(local), skb, control);
+               ret = local->ops->tx(local_to_hw(local), skb);
                if (ret)
                        return IEEE80211_TX_AGAIN;
                local->mdev->trans_start = jiffies;
                ieee80211_led_tx(local, 1);
        }
        if (tx->extra_frag) {
-               control->flags &= ~(IEEE80211_TXCTL_USE_RTS_CTS |
-                                   IEEE80211_TXCTL_USE_CTS_PROTECT |
-                                   IEEE80211_TXCTL_CLEAR_PS_FILT |
-                                   IEEE80211_TXCTL_FIRST_FRAGMENT);
                for (i = 0; i < tx->num_extra_frag; i++) {
                        if (!tx->extra_frag[i])
                                continue;
-                       if (__ieee80211_queue_stopped(local, control->queue))
+                       info = IEEE80211_SKB_CB(tx->extra_frag[i]);
+                       info->flags &= ~(IEEE80211_TX_CTL_USE_RTS_CTS |
+                                        IEEE80211_TX_CTL_USE_CTS_PROTECT |
+                                        IEEE80211_TX_CTL_CLEAR_PS_FILT |
+                                        IEEE80211_TX_CTL_FIRST_FRAGMENT);
+                       if (__ieee80211_queue_stopped(local, info->queue))
                                return IEEE80211_TX_FRAG_AGAIN;
                        if (i == tx->num_extra_frag) {
-                               control->tx_rate_idx = tx->last_frag_rate_idx;
+                               info->tx_rate_idx = tx->last_frag_rate_idx;
 
                                if (tx->flags & IEEE80211_TX_PROBE_LAST_FRAG)
-                                       control->flags |=
-                                               IEEE80211_TXCTL_RATE_CTRL_PROBE;
+                                       info->flags |=
+                                               IEEE80211_TX_CTL_RATE_CTRL_PROBE;
                                else
-                                       control->flags &=
-                                               ~IEEE80211_TXCTL_RATE_CTRL_PROBE;
+                                       info->flags &=
+                                               ~IEEE80211_TX_CTL_RATE_CTRL_PROBE;
                        }
 
                        ieee80211_dump_frame(wiphy_name(local->hw.wiphy),
                                             "TX to low-level driver",
                                             tx->extra_frag[i]);
                        ret = local->ops->tx(local_to_hw(local),
-                                           tx->extra_frag[i],
-                                           control);
+                                           tx->extra_frag[i]);
                        if (ret)
                                return IEEE80211_TX_FRAG_AGAIN;
                        local->mdev->trans_start = jiffies;
@@ -1135,17 +1141,18 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
        return IEEE80211_TX_OK;
 }
 
-static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
-                       struct ieee80211_tx_control *control)
+static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct sta_info *sta;
        ieee80211_tx_handler *handler;
        struct ieee80211_tx_data tx;
        ieee80211_tx_result res = TX_DROP, res_prepare;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        int ret, i;
+       int queue = info->queue;
 
-       WARN_ON(__ieee80211_queue_pending(local, control->queue));
+       WARN_ON(__ieee80211_queue_pending(local, queue));
 
        if (unlikely(skb->len < 10)) {
                dev_kfree_skb(skb);
@@ -1155,7 +1162,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
        rcu_read_lock();
 
        /* initialises tx */
-       res_prepare = __ieee80211_tx_prepare(&tx, skb, dev, control);
+       res_prepare = __ieee80211_tx_prepare(&tx, skb, dev);
 
        if (res_prepare == TX_DROP) {
                dev_kfree_skb(skb);
@@ -1165,7 +1172,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;
+       info->band = tx.channel->band;
 
        for (handler = ieee80211_tx_handlers; *handler != NULL;
             handler++) {
@@ -1174,7 +1181,8 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
                        break;
        }
 
-       skb = tx.skb; /* handlers are allowed to change skb */
+       if (WARN_ON(tx.skb != skb))
+               goto drop;
 
        if (unlikely(res == TX_DROP)) {
                I802_DEBUG_INC(local->tx_handlers_drop);
@@ -1209,12 +1217,12 @@ retry:
        ret = __ieee80211_tx(local, skb, &tx);
        if (ret) {
                struct ieee80211_tx_stored_packet *store =
-                       &local->pending_packet[control->queue];
+                       &local->pending_packet[info->queue];
 
                if (ret == IEEE80211_TX_FRAG_AGAIN)
                        skb = NULL;
                set_bit(IEEE80211_LINK_STATE_PENDING,
-                       &local->state[control->queue]);
+                       &local->state[queue]);
                smp_mb();
                /* When the driver gets out of buffers during sending of
                 * fragments and calls ieee80211_stop_queue, there is
@@ -1225,13 +1233,11 @@ retry:
                 * called with IEEE80211_LINK_STATE_PENDING. Prevent this by
                 * continuing transmitting here when that situation is
                 * possible to have happened. */
-               if (!__ieee80211_queue_stopped(local, control->queue)) {
+               if (!__ieee80211_queue_stopped(local, queue)) {
                        clear_bit(IEEE80211_LINK_STATE_PENDING,
-                                 &local->state[control->queue]);
+                                 &local->state[queue]);
                        goto retry;
                }
-               memcpy(&store->control, control,
-                      sizeof(struct ieee80211_tx_control));
                store->skb = skb;
                store->extra_frag = tx.extra_frag;
                store->num_extra_frag = tx.num_extra_frag;
@@ -1258,21 +1264,14 @@ retry:
 int ieee80211_master_start_xmit(struct sk_buff *skb,
                                struct net_device *dev)
 {
-       struct ieee80211_tx_control control;
-       struct ieee80211_tx_packet_data *pkt_data;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct net_device *odev = NULL;
        struct ieee80211_sub_if_data *osdata;
        int headroom;
        int ret;
 
-       /*
-        * copy control out of the skb so other people can use skb->cb
-        */
-       pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
-       memset(&control, 0, sizeof(struct ieee80211_tx_control));
-
-       if (pkt_data->ifindex)
-               odev = dev_get_by_index(&init_net, pkt_data->ifindex);
+       if (info->control.ifindex)
+               odev = dev_get_by_index(&init_net, info->control.ifindex);
        if (unlikely(odev && !is_ieee80211_device(odev, dev))) {
                dev_put(odev);
                odev = NULL;
@@ -1285,6 +1284,7 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
                dev_kfree_skb(skb);
                return 0;
        }
+
        osdata = IEEE80211_DEV_TO_SUB_IF(odev);
 
        headroom = osdata->local->tx_headroom + IEEE80211_ENCRYPT_HEADROOM;
@@ -1296,21 +1296,8 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
                }
        }
 
-       control.vif = &osdata->vif;
-       control.type = osdata->vif.type;
-       if (pkt_data->flags & IEEE80211_TXPD_REQ_TX_STATUS)
-               control.flags |= IEEE80211_TXCTL_REQ_TX_STATUS;
-       if (pkt_data->flags & IEEE80211_TXPD_DO_NOT_ENCRYPT)
-               control.flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
-       if (pkt_data->flags & IEEE80211_TXPD_REQUEUE)
-               control.flags |= IEEE80211_TXCTL_REQUEUE;
-       if (pkt_data->flags & IEEE80211_TXPD_EAPOL_FRAME)
-               control.flags |= IEEE80211_TXCTL_EAPOL_FRAME;
-       if (pkt_data->flags & IEEE80211_TXPD_AMPDU)
-               control.flags |= IEEE80211_TXCTL_AMPDU;
-       control.queue = pkt_data->queue;
-
-       ret = ieee80211_tx(odev, skb, &control);
+       info->control.vif = &osdata->vif;
+       ret = ieee80211_tx(odev, skb);
        dev_put(odev);
 
        return ret;
@@ -1320,7 +1307,7 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb,
                                 struct net_device *dev)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct ieee80211_tx_packet_data *pkt_data;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ieee80211_radiotap_header *prthdr =
                (struct ieee80211_radiotap_header *)skb->data;
        u16 len_rthdr;
@@ -1342,14 +1329,12 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb,
 
        skb->dev = local->mdev;
 
-       pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
-       memset(pkt_data, 0, sizeof(*pkt_data));
        /* needed because we set skb device to master */
-       pkt_data->ifindex = dev->ifindex;
+       info->control.ifindex = dev->ifindex;
 
-       pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT;
+       info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
        /* Interfaces should always request a status report */
-       pkt_data->flags |= IEEE80211_TXPD_REQ_TX_STATUS;
+       info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
 
        /*
         * fix up the pointers accounting for the radiotap
@@ -1393,7 +1378,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
                               struct net_device *dev)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct ieee80211_tx_packet_data *pkt_data;
+       struct ieee80211_tx_info *info;
        struct ieee80211_sub_if_data *sdata;
        int ret = 1, head_need;
        u16 ethertype, hdrlen,  meshhdrlen = 0, fc;
@@ -1625,14 +1610,14 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
        nh_pos += hdrlen;
        h_pos += hdrlen;
 
-       pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
-       memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
-       pkt_data->ifindex = dev->ifindex;
+       info = IEEE80211_SKB_CB(skb);
+       memset(info, 0, sizeof(*info));
+       info->control.ifindex = dev->ifindex;
        if (ethertype == ETH_P_PAE)
-               pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME;
+               info->flags |= IEEE80211_TX_CTL_EAPOL_FRAME;
 
        /* Interfaces should always request a status report */
-       pkt_data->flags |= IEEE80211_TXPD_REQ_TX_STATUS;
+       info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
 
        skb->dev = local->mdev;
        dev->stats.tx_packets++;
@@ -1693,7 +1678,6 @@ void ieee80211_tx_pending(unsigned long data)
                        continue;
                }
                store = &local->pending_packet[i];
-               tx.control = &store->control;
                tx.extra_frag = store->extra_frag;
                tx.num_extra_frag = store->num_extra_frag;
                tx.last_frag_rate_idx = store->last_frag_rate_idx;
@@ -1786,11 +1770,11 @@ static void ieee80211_beacon_add_tim(struct ieee80211_local *local,
 }
 
 struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
-                                    struct ieee80211_vif *vif,
-                                    struct ieee80211_tx_control *control)
+                                    struct ieee80211_vif *vif)
 {
        struct ieee80211_local *local = hw_to_local(hw);
        struct sk_buff *skb;
+       struct ieee80211_tx_info *info;
        struct net_device *bdev;
        struct ieee80211_sub_if_data *sdata = NULL;
        struct ieee80211_if_ap *ap = NULL;
@@ -1896,31 +1880,32 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
                goto out;
        }
 
-       if (control) {
-               control->band = band;
-               rate_control_get_rate(local->mdev, sband, skb, &rsel);
-               if (unlikely(rsel.rate_idx < 0)) {
-                       if (net_ratelimit()) {
-                               printk(KERN_DEBUG "%s: ieee80211_beacon_get: "
-                                      "no rate found\n",
-                                      wiphy_name(local->hw.wiphy));
-                       }
-                       dev_kfree_skb(skb);
-                       skb = NULL;
-                       goto out;
-               }
+       info = IEEE80211_SKB_CB(skb);
+
+       info->band = band;
+       rate_control_get_rate(local->mdev, sband, skb, &rsel);
 
-               control->vif = vif;
-               control->tx_rate_idx = rsel.rate_idx;
-               if (sdata->bss_conf.use_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;
-               control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
-               control->retry_limit = 1;
-               control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT;
+       if (unlikely(rsel.rate_idx < 0)) {
+               if (net_ratelimit()) {
+                       printk(KERN_DEBUG "%s: ieee80211_beacon_get: "
+                              "no rate found\n",
+                              wiphy_name(local->hw.wiphy));
+               }
+               dev_kfree_skb(skb);
+               skb = NULL;
+               goto out;
        }
+
+       info->control.vif = vif;
+       info->tx_rate_idx = rsel.rate_idx;
+       if (sdata->bss_conf.use_short_preamble &&
+           sband->bitrates[rsel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE)
+               info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE;
+       info->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
+       info->flags |= IEEE80211_TX_CTL_NO_ACK;
+       info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
+       info->control.retry_limit = 1;
+       info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
        (*num_beacons)++;
 out:
        rcu_read_unlock();
@@ -1930,7 +1915,7 @@ EXPORT_SYMBOL(ieee80211_beacon_get);
 
 void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                       const void *frame, size_t frame_len,
-                      const struct ieee80211_tx_control *frame_txctl,
+                      const struct ieee80211_tx_info *frame_txctl,
                       struct ieee80211_rts *rts)
 {
        const struct ieee80211_hdr *hdr = frame;
@@ -1947,7 +1932,7 @@ EXPORT_SYMBOL(ieee80211_rts_get);
 
 void ieee80211_ctstoself_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                             const void *frame, size_t frame_len,
-                            const struct ieee80211_tx_control *frame_txctl,
+                            const struct ieee80211_tx_info *frame_txctl,
                             struct ieee80211_cts *cts)
 {
        const struct ieee80211_hdr *hdr = frame;
@@ -1963,8 +1948,7 @@ EXPORT_SYMBOL(ieee80211_ctstoself_get);
 
 struct sk_buff *
 ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
-                         struct ieee80211_vif *vif,
-                         struct ieee80211_tx_control *control)
+                         struct ieee80211_vif *vif)
 {
        struct ieee80211_local *local = hw_to_local(hw);
        struct sk_buff *skb;
@@ -1976,6 +1960,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
        struct ieee80211_sub_if_data *sdata;
        struct ieee80211_if_ap *bss = NULL;
        struct beacon_data *beacon;
+       struct ieee80211_tx_info *info;
 
        sdata = vif_to_sdata(vif);
        bdev = sdata->dev;
@@ -1995,7 +1980,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
 
        if (bss->dtim_count != 0)
                return NULL; /* send buffered bc/mc only after DTIM beacon */
-       memset(control, 0, sizeof(*control));
+
        while (1) {
                skb = skb_dequeue(&bss->ps_bc_buf);
                if (!skb)
@@ -2012,21 +1997,26 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
                                cpu_to_le16(IEEE80211_FCTL_MOREDATA);
                }
 
-               if (!ieee80211_tx_prepare(&tx, skb, local->mdev, control))
+               if (!ieee80211_tx_prepare(&tx, skb, local->mdev))
                        break;
                dev_kfree_skb_any(skb);
        }
+
+       info = IEEE80211_SKB_CB(skb);
+
        sta = tx.sta;
        tx.flags |= IEEE80211_TX_PS_BUFFERED;
        tx.channel = local->hw.conf.channel;
-       control->band = tx.channel->band;
+       info->band = tx.channel->band;
 
        for (handler = ieee80211_tx_handlers; *handler != NULL; handler++) {
                res = (*handler)(&tx);
                if (res == TX_DROP || res == TX_QUEUED)
                        break;
        }
-       skb = tx.skb; /* handlers are allowed to change skb */
+
+       if (WARN_ON(tx.skb != skb))
+               return NULL;
 
        if (res == TX_DROP) {
                I802_DEBUG_INC(local->tx_handlers_drop);
index 65a34fd..d9109de 100644 (file)
@@ -258,7 +258,7 @@ EXPORT_SYMBOL(ieee80211_generic_frame_duration);
 
 __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
                              struct ieee80211_vif *vif, size_t frame_len,
-                             const struct ieee80211_tx_control *frame_txctl)
+                             const struct ieee80211_tx_info *frame_txctl)
 {
        struct ieee80211_local *local = hw_to_local(hw);
        struct ieee80211_rate *rate;
@@ -272,7 +272,7 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
 
        short_preamble = sdata->bss_conf.use_short_preamble;
 
-       rate = &sband->bitrates[frame_txctl->rts_cts_rate_idx];
+       rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];
 
        erp = 0;
        if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
@@ -295,7 +295,7 @@ EXPORT_SYMBOL(ieee80211_rts_duration);
 __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
                                    struct ieee80211_vif *vif,
                                    size_t frame_len,
-                                   const struct ieee80211_tx_control *frame_txctl)
+                                   const struct ieee80211_tx_info *frame_txctl)
 {
        struct ieee80211_local *local = hw_to_local(hw);
        struct ieee80211_rate *rate;
@@ -309,7 +309,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
 
        short_preamble = sdata->bss_conf.use_short_preamble;
 
-       rate = &sband->bitrates[frame_txctl->rts_cts_rate_idx];
+       rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];
        erp = 0;
        if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
                erp = rate->flags & IEEE80211_RATE_ERP_G;
@@ -317,7 +317,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
        /* Data frame duration */
        dur = ieee80211_frame_duration(local, frame_len, rate->bitrate,
                                       erp, short_preamble);
-       if (!(frame_txctl->flags & IEEE80211_TXCTL_NO_ACK)) {
+       if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) {
                /* ACK duration */
                dur += ieee80211_frame_duration(local, 10, rate->bitrate,
                                                erp, short_preamble);
index 3cbae42..1e7f03d 100644 (file)
@@ -333,11 +333,16 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx)
 
 static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
 {
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+       info->control.iv_len = WEP_IV_LEN;
+       info->control.icv_len = WEP_ICV_LEN;
+
        if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
+               info->control.hw_key = &tx->key->conf;
                if (ieee80211_wep_encrypt(tx->local, skb, tx->key))
                        return -1;
        } else {
-               tx->control->hw_key = &tx->key->conf;
                if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) {
                        if (!ieee80211_wep_add_iv(tx->local, skb, tx->key))
                                return -1;
@@ -349,8 +354,6 @@ static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
 ieee80211_tx_result
 ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx)
 {
-       tx->control->iv_len = WEP_IV_LEN;
-       tx->control->icv_len = WEP_ICV_LEN;
        ieee80211_tx_set_protected(tx);
 
        if (wep_encrypt_skb(tx, tx->skb) < 0) {
index c87baf4..477690f 100644 (file)
@@ -149,8 +149,7 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
        struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
        struct ieee80211_hw *hw = &local->hw;
        struct ieee80211_sched_data *q = qdisc_priv(qd);
-       struct ieee80211_tx_packet_data *pkt_data =
-               (struct ieee80211_tx_packet_data *) skb->cb;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
        unsigned short fc = le16_to_cpu(hdr->frame_control);
        struct Qdisc *qdisc;
@@ -158,8 +157,8 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
        int err, queue;
        u8 tid;
 
-       if (pkt_data->flags & IEEE80211_TXPD_REQUEUE) {
-               queue = pkt_data->queue;
+       if (info->flags & IEEE80211_TX_CTL_REQUEUE) {
+               queue = info->queue;
                rcu_read_lock();
                sta = sta_info_get(local, hdr->addr1);
                tid = skb->priority & QOS_CONTROL_TAG1D_MASK;
@@ -168,9 +167,9 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
                        if ((ampdu_queue < QD_NUM(hw)) &&
                            test_bit(ampdu_queue, q->qdisc_pool)) {
                                queue = ampdu_queue;
-                               pkt_data->flags |= IEEE80211_TXPD_AMPDU;
+                               info->flags |= IEEE80211_TX_CTL_AMPDU;
                        } else {
-                               pkt_data->flags &= ~IEEE80211_TXPD_AMPDU;
+                               info->flags &= ~IEEE80211_TX_CTL_AMPDU;
                        }
                }
                rcu_read_unlock();
@@ -206,9 +205,9 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
                        if ((ampdu_queue < QD_NUM(hw)) &&
                            test_bit(ampdu_queue, q->qdisc_pool)) {
                                queue = ampdu_queue;
-                               pkt_data->flags |= IEEE80211_TXPD_AMPDU;
+                               info->flags |= IEEE80211_TX_CTL_AMPDU;
                        } else {
-                               pkt_data->flags &= ~IEEE80211_TXPD_AMPDU;
+                               info->flags &= ~IEEE80211_TX_CTL_AMPDU;
                        }
                }
 
@@ -220,7 +219,7 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
                        err = NET_XMIT_DROP;
        } else {
                tid = skb->priority & QOS_CONTROL_TAG1D_MASK;
-               pkt_data->queue = (unsigned int) queue;
+               info->queue = (unsigned int) queue;
                qdisc = q->queues[queue];
                err = qdisc->enqueue(skb, qdisc);
                if (err == NET_XMIT_SUCCESS) {
@@ -241,13 +240,12 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
 static int wme_qdiscop_requeue(struct sk_buff *skb, struct Qdisc* qd)
 {
        struct ieee80211_sched_data *q = qdisc_priv(qd);
-       struct ieee80211_tx_packet_data *pkt_data =
-               (struct ieee80211_tx_packet_data *) skb->cb;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct Qdisc *qdisc;
        int err;
 
        /* we recorded which queue to use earlier! */
-       qdisc = q->queues[pkt_data->queue];
+       qdisc = q->queues[info->queue];
 
        if ((err = qdisc->ops->requeue(skb, qdisc)) == 0) {
                qd->q.qlen++;
index d730449..d6635f6 100644 (file)
@@ -183,15 +183,25 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
 }
 
 
-static int tkip_encrypt_skb(struct ieee80211_tx_data *tx,
-                           struct sk_buff *skb, int test)
+static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
        struct ieee80211_key *key = tx->key;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        int hdrlen, len, tailneed;
        u16 fc;
        u8 *pos;
 
+       info->control.icv_len = TKIP_ICV_LEN;
+       info->control.iv_len = TKIP_IV_LEN;
+
+       if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
+           !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
+               /* hwaccel - with no need for preallocated room for IV/ICV */
+               info->control.hw_key = &tx->key->conf;
+               return TX_CONTINUE;
+       }
+
        fc = le16_to_cpu(hdr->frame_control);
        hdrlen = ieee80211_get_hdrlen(fc);
        len = skb->len - hdrlen;
@@ -228,7 +238,7 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx,
                                            0x7f),
                                      (u8) key->u.tkip.tx.iv16);
 
-               tx->control->hw_key = &tx->key->conf;
+               info->control.hw_key = &tx->key->conf;
                return 0;
        }
 
@@ -246,28 +256,16 @@ ieee80211_tx_result
 ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx)
 {
        struct sk_buff *skb = tx->skb;
-       int wpa_test = 0, test = 0;
 
-       tx->control->icv_len = TKIP_ICV_LEN;
-       tx->control->iv_len = TKIP_IV_LEN;
        ieee80211_tx_set_protected(tx);
 
-       if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
-           !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
-           !wpa_test) {
-               /* hwaccel - with no need for preallocated room for IV/ICV */
-               tx->control->hw_key = &tx->key->conf;
-               return TX_CONTINUE;
-       }
-
-       if (tkip_encrypt_skb(tx, skb, test) < 0)
+       if (tkip_encrypt_skb(tx, skb) < 0)
                return TX_DROP;
 
        if (tx->extra_frag) {
                int i;
                for (i = 0; i < tx->num_extra_frag; i++) {
-                       if (tkip_encrypt_skb(tx, tx->extra_frag[i], test)
-                           < 0)
+                       if (tkip_encrypt_skb(tx, tx->extra_frag[i]) < 0)
                                return TX_DROP;
                }
        }
@@ -429,16 +427,27 @@ static inline int ccmp_hdr2pn(u8 *pn, u8 *hdr)
 }
 
 
-static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx,
-                           struct sk_buff *skb, int test)
+static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
        struct ieee80211_key *key = tx->key;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        int hdrlen, len, tailneed;
        u16 fc;
        u8 *pos, *pn, *b_0, *aad, *scratch;
        int i;
 
+       info->control.icv_len = CCMP_MIC_LEN;
+       info->control.iv_len = CCMP_HDR_LEN;
+
+       if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
+           !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
+               /* hwaccel - with no need for preallocated room for CCMP "
+                * header or MIC fields */
+               info->control.hw_key = &tx->key->conf;
+               return TX_CONTINUE;
+       }
+
        scratch = key->u.ccmp.tx_crypto_buf;
        b_0 = scratch + 3 * AES_BLOCK_LEN;
        aad = scratch + 4 * AES_BLOCK_LEN;
@@ -478,7 +487,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx,
 
        if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
                /* hwaccel - with preallocated room for CCMP header */
-               tx->control->hw_key = &tx->key->conf;
+               info->control.hw_key = &tx->key->conf;
                return 0;
        }
 
@@ -495,28 +504,16 @@ ieee80211_tx_result
 ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx)
 {
        struct sk_buff *skb = tx->skb;
-       int test = 0;
 
-       tx->control->icv_len = CCMP_MIC_LEN;
-       tx->control->iv_len = CCMP_HDR_LEN;
        ieee80211_tx_set_protected(tx);
 
-       if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
-           !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
-               /* hwaccel - with no need for preallocated room for CCMP "
-                * header or MIC fields */
-               tx->control->hw_key = &tx->key->conf;
-               return TX_CONTINUE;
-       }
-
-       if (ccmp_encrypt_skb(tx, skb, test) < 0)
+       if (ccmp_encrypt_skb(tx, skb) < 0)
                return TX_DROP;
 
        if (tx->extra_frag) {
                int i;
                for (i = 0; i < tx->num_extra_frag; i++) {
-                       if (ccmp_encrypt_skb(tx, tx->extra_frag[i], test)
-                           < 0)
+                       if (ccmp_encrypt_skb(tx, tx->extra_frag[i]) < 0)
                                return TX_DROP;
                }
        }