From e039fa4a4195ac4ee895e6f3d1334beed63256fe Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 15 May 2008 12:55:29 +0200 Subject: mac80211: move TX info into skb->cb 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 Signed-off-by: Johannes Berg Acked-by: David S. Miller Signed-off-by: John W. Linville --- drivers/net/wireless/b43legacy/dma.c | 36 ++++++++++++++-------------- drivers/net/wireless/b43legacy/dma.h | 4 +--- drivers/net/wireless/b43legacy/main.c | 12 ++++------ drivers/net/wireless/b43legacy/pio.c | 19 +++++++-------- drivers/net/wireless/b43legacy/pio.h | 4 +--- drivers/net/wireless/b43legacy/xmit.c | 44 +++++++++++++++++------------------ drivers/net/wireless/b43legacy/xmit.h | 2 +- 7 files changed, 58 insertions(+), 63 deletions(-) (limited to 'drivers/net/wireless/b43legacy') diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index d6686f7..c1c501d 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c @@ -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 { diff --git a/drivers/net/wireless/b43legacy/dma.h b/drivers/net/wireless/b43legacy/dma.h index 2dd488c..67537a7 100644 --- a/drivers/net/wireless/b43legacy/dma.h +++ b/drivers/net/wireless/b43legacy/dma.h @@ -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); diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index b05a507..f706ca6 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -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; diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c index 8d3d27d..a86c764 100644 --- a/drivers/net/wireless/b43legacy/pio.c +++ b/drivers/net/wireless/b43legacy/pio.c @@ -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); diff --git a/drivers/net/wireless/b43legacy/pio.h b/drivers/net/wireless/b43legacy/pio.h index 5bfed0c..49310df 100644 --- a/drivers/net/wireless/b43legacy/pio.h +++ b/drivers/net/wireless/b43legacy/pio.h @@ -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, diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index 55dc251..82dc04d 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c @@ -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, diff --git a/drivers/net/wireless/b43legacy/xmit.h b/drivers/net/wireless/b43legacy/xmit.h index bab4792..e56777e0f 100644 --- a/drivers/net/wireless/b43legacy/xmit.h +++ b/drivers/net/wireless/b43legacy/xmit.h @@ -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); -- cgit v1.1