mac80211: push rx status into skb->cb
authorJohannes Berg <johannes@sipsolutions.net>
Wed, 17 Jun 2009 11:13:00 +0000 (13:13 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 10 Jul 2009 18:57:54 +0000 (14:57 -0400)
Within mac80211, we often need to copy the rx status into
skb->cb. This is wasteful, as drivers could be building it
in there to start with. This patch changes the API so that
drivers are expected to pass the RX status in skb->cb, now
accessible as IEEE80211_SKB_RXCB(skb). It also updates all
drivers to pass the rx status in there, but only by making
them memcpy() it into place before the call to the receive
function (ieee80211_rx(_irqsafe)). Each driver can now be
optimised on its own schedule.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
30 files changed:
drivers/net/wireless/adm8211.c
drivers/net/wireless/at76c50x-usb.c
drivers/net/wireless/ath/ar9170/main.c
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/b43/xmit.c
drivers/net/wireless/b43legacy/xmit.c
drivers/net/wireless/iwlwifi/iwl-3945.c
drivers/net/wireless/iwlwifi/iwl-rx.c
drivers/net/wireless/libertas_tf/main.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mwl8k.c
drivers/net/wireless/p54/p54common.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rtl818x/rtl8180_dev.c
drivers/net/wireless/rtl818x/rtl8187_dev.c
drivers/net/wireless/wl12xx/wl1251_rx.c
drivers/net/wireless/zd1211rw/zd_mac.c
drivers/staging/agnx/xmit.c
drivers/staging/stlc45xx/stlc45xx.c
drivers/staging/winbond/wb35rx.c
include/net/mac80211.h
net/mac80211/ibss.c
net/mac80211/ieee80211_i.h
net/mac80211/main.c
net/mac80211/mesh.c
net/mac80211/mesh.h
net/mac80211/mlme.c
net/mac80211/rx.c
net/mac80211/scan.c

index 2b9e379..ecc9383 100644 (file)
@@ -452,7 +452,8 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev)
                        rx_status.freq = adm8211_channels[priv->channel - 1].center_freq;
                        rx_status.band = IEEE80211_BAND_2GHZ;
 
-                       ieee80211_rx_irqsafe(dev, skb, &rx_status);
+                       memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
+                       ieee80211_rx_irqsafe(dev, skb);
                }
 
                entry = (++priv->cur_rx) % priv->rx_ring_size;
index 4efbdbe..13303fa 100644 (file)
@@ -1568,7 +1568,8 @@ static void at76_rx_tasklet(unsigned long param)
 
        at76_dbg(DBG_MAC80211, "calling ieee80211_rx_irqsafe(): %d/%d",
                 priv->rx_skb->len, priv->rx_skb->data_len);
-       ieee80211_rx_irqsafe(priv->hw, priv->rx_skb, &rx_status);
+       memcpy(IEEE80211_SKB_RXCB(priv->rx_skb), &rx_status, sizeof(rx_status));
+       ieee80211_rx_irqsafe(priv->hw, priv->rx_skb);
 
        /* Use a new skb for the next receive */
        priv->rx_skb = NULL;
index 9d38cf6..51753ed 100644 (file)
@@ -917,8 +917,10 @@ static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
                ar9170_rx_phy_status(ar, phy, &status);
 
        skb = ar9170_rx_copy_data(buf, mpdu_len);
-       if (likely(skb))
-               ieee80211_rx_irqsafe(ar->hw, skb, &status);
+       if (likely(skb)) {
+               memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+               ieee80211_rx_irqsafe(ar->hw, skb);
+       }
 }
 
 void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
index f26a689..c6e7091 100644 (file)
@@ -1905,7 +1905,8 @@ accept:
                if (sc->opmode == NL80211_IFTYPE_ADHOC)
                        ath5k_check_ibss_tsf(sc, skb, &rxs);
 
-               __ieee80211_rx(sc->hw, skb, &rxs);
+               memcpy(IEEE80211_SKB_RXCB(skb), &rxs, sizeof(rxs));
+               ieee80211_rx(sc->hw, skb);
 
                bf->skb = next_skb;
                bf->skbaddr = next_skb_addr;
index cece1c4..c00b905 100644 (file)
@@ -619,13 +619,18 @@ static void ath_rx_send_to_mac80211(struct ath_softc *sc, struct sk_buff *skb,
                        if (aphy == NULL)
                                continue;
                        nskb = skb_copy(skb, GFP_ATOMIC);
-                       if (nskb)
-                               __ieee80211_rx(aphy->hw, nskb, rx_status);
+                       if (nskb) {
+                               memcpy(IEEE80211_SKB_RXCB(nskb), rx_status,
+                                       sizeof(*rx_status));
+                               ieee80211_rx(aphy->hw, nskb);
+                       }
                }
-               __ieee80211_rx(sc->hw, skb, rx_status);
+               memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
+               ieee80211_rx(sc->hw, skb);
        } else {
                /* Deliver unicast frames based on receiver address */
-               __ieee80211_rx(ath_get_virt_hw(sc, hdr), skb, rx_status);
+               memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
+               ieee80211_rx(ath_get_virt_hw(sc, hdr), skb);
        }
 }
 
index 55f36a7..5b85e7d 100644 (file)
@@ -670,7 +670,8 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
                goto drop;
        }
 
-       ieee80211_rx_irqsafe(dev->wl->hw, skb, &status);
+       memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+       ieee80211_rx_irqsafe(dev->wl->hw, skb);
 
        return;
 drop:
index b8e39dd..f79cee8 100644 (file)
@@ -591,7 +591,8 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
        }
 
        dev->stats.last_rx = jiffies;
-       ieee80211_rx_irqsafe(dev->wl->hw, skb, &status);
+       memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+       ieee80211_rx_irqsafe(dev->wl->hw, skb);
 
        return;
 drop:
index 46288e7..777c095 100644 (file)
@@ -577,7 +577,8 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
        if (ieee80211_is_data(hdr->frame_control))
                priv->rxtxpackets += len;
 #endif
-       ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats);
+       memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats));
+       ieee80211_rx_irqsafe(priv->hw, rxb->skb);
        rxb->skb = NULL;
 }
 
index 2b8d40b..2160795 100644 (file)
@@ -932,7 +932,8 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
                return;
 
        iwl_update_rx_stats(priv, le16_to_cpu(hdr->frame_control), len);
-       ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats);
+       memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats));
+       ieee80211_rx_irqsafe(priv->hw, rxb->skb);
        priv->alloc_rxb_skb--;
        rxb->skb = NULL;
 }
index 10a99e2..4872345 100644 (file)
@@ -503,7 +503,8 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb)
                skb_reserve(skb, 2);
        }
 
-       ieee80211_rx_irqsafe(priv->hw, skb, &stats);
+       memcpy(IEEE80211_SKB_RXCB(skb), &stats, sizeof(stats));
+       ieee80211_rx_irqsafe(priv->hw, skb);
        return 0;
 }
 EXPORT_SYMBOL_GPL(lbtf_rx);
index c47ef48..b1e4bae 100644 (file)
@@ -430,7 +430,8 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
                if (memcmp(hdr->addr1, data2->hw->wiphy->perm_addr,
                           ETH_ALEN) == 0)
                        ack = true;
-               ieee80211_rx_irqsafe(data2->hw, nskb, &rx_status);
+               memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status));
+               ieee80211_rx_irqsafe(data2->hw, nskb);
        }
        spin_unlock(&hwsim_radio_lock);
 
index a263d5c..b9eded8 100644 (file)
@@ -1047,7 +1047,8 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
                status.flag = 0;
                status.band = IEEE80211_BAND_2GHZ;
                status.freq = ieee80211_channel_to_frequency(rx_desc->channel);
-               ieee80211_rx_irqsafe(hw, skb, &status);
+               memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+               ieee80211_rx_irqsafe(hw, skb);
 
                processed++;
        }
index 22ca122..1b15f9e 100644 (file)
@@ -794,7 +794,8 @@ static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
        skb_pull(skb, header_len);
        skb_trim(skb, le16_to_cpu(hdr->len));
 
-       ieee80211_rx_irqsafe(dev, skb, &rx_status);
+       memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
+       ieee80211_rx_irqsafe(dev, skb);
 
        queue_delayed_work(dev->workqueue, &priv->work,
                           msecs_to_jiffies(P54_STATISTICS_UPDATE));
index 57813e7..41e3379 100644 (file)
@@ -449,7 +449,8 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
         * mac80211 will clean up the skb structure.
         */
        rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb);
-       ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status);
+       memcpy(IEEE80211_SKB_RXCB(entry->skb), rx_status, sizeof(*rx_status));
+       ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb);
 
        /*
         * Replace the skb with the freshly allocated one.
index 7e65d7c..47521c5 100644 (file)
@@ -143,7 +143,8 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
                        if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
                                rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
 
-                       ieee80211_rx_irqsafe(dev, skb, &rx_status);
+                       memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
+                       ieee80211_rx_irqsafe(dev, skb);
 
                        skb = new_skb;
                        priv->rx_buf[priv->rx_idx] = skb;
index 294250e..c9b9dbe 100644 (file)
@@ -380,7 +380,8 @@ static void rtl8187_rx_cb(struct urb *urb)
        rx_status.flag |= RX_FLAG_TSFT;
        if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
                rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
-       ieee80211_rx_irqsafe(dev, skb, &rx_status);
+       memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
+       ieee80211_rx_irqsafe(dev, skb);
 
        skb = dev_alloc_skb(RTL8187_MAX_RX);
        if (unlikely(!skb)) {
index 48fa39e..0dbb483 100644 (file)
@@ -151,7 +151,8 @@ static void wl1251_rx_body(struct wl1251 *wl,
        wl1251_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
                     beacon ? "beacon" : "");
 
-       ieee80211_rx(wl->hw, skb, &status);
+       memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+       ieee80211_rx(wl->hw, skb);
 }
 
 static void wl1251_rx_ack(struct wl1251 *wl)
index 40b07b9..9600b72 100644 (file)
@@ -711,7 +711,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length)
 
        memcpy(skb_put(skb, length), buffer, length);
 
-       ieee80211_rx_irqsafe(hw, skb, &stats);
+       memcpy(IEEE80211_SKB_RXCB(skb), &stats, sizeof(stats));
+       ieee80211_rx_irqsafe(hw, skb);
        return 0;
 }
 
index 0e03408..42db410 100644 (file)
@@ -384,7 +384,8 @@ void handle_rx_irq(struct agnx_priv *priv)
 /*                     dump_ieee80211_hdr((struct ieee80211_hdr *)skb->data, "RX G"); */
                } else
                        agnx_bug("Unknown packets type");
-               ieee80211_rx_irqsafe(priv->hw, skb, &status);
+               memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+               ieee80211_rx_irqsafe(priv->hw, skb);
                rx_desc_reinit(priv, i);
 
        } while (priv->rx.idx++);
index cfdaac9..52744fa 100644 (file)
@@ -1429,7 +1429,8 @@ static int stlc45xx_rx_data(struct stlc45xx *stlc, struct sk_buff *skb)
        stlc45xx_debug(DEBUG_RX, "rx data 0x%p %d B", skb->data, skb->len);
        stlc45xx_dump(DEBUG_RX_CONTENT, skb->data, skb->len);
 
-       ieee80211_rx(stlc->hw, skb, &status);
+       memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+       ieee80211_rx(stlc->hw, skb);
 
        return 0;
 }
index 3e8cf08..b905e7b 100644 (file)
@@ -40,7 +40,8 @@ static void packet_came(struct ieee80211_hw *hw, char *pRxBufferAddress, int Pac
        rx_status.phymode = MODE_IEEE80211B;
 */
 
-       ieee80211_rx_irqsafe(hw, skb, &rx_status);
+       memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
+       ieee80211_rx_irqsafe(hw, skb);
 }
 
 static void Wb35Rx_adjust(PDESCRIPTOR pRxDes)
index c061044..fe80771 100644 (file)
@@ -397,6 +397,11 @@ static inline struct ieee80211_tx_info *IEEE80211_SKB_CB(struct sk_buff *skb)
        return (struct ieee80211_tx_info *)skb->cb;
 }
 
+static inline struct ieee80211_rx_status *IEEE80211_SKB_RXCB(struct sk_buff *skb)
+{
+       return (struct ieee80211_rx_status *)skb->cb;
+}
+
 /**
  * ieee80211_tx_info_clear_status - clear TX status
  *
@@ -478,7 +483,7 @@ enum mac80211_rx_flags {
  *
  * The low-level driver should provide this information (the subset
  * supported by hardware) to the 802.11 code with each received
- * frame.
+ * frame, in the skb's control buffer (cb).
  *
  * @mactime: value in microseconds of the 64-bit Time Synchronization Function
  *     (TSF) timer when the first data symbol (MPDU) arrived at the hardware.
@@ -1606,9 +1611,11 @@ void ieee80211_free_hw(struct ieee80211_hw *hw);
  */
 void ieee80211_restart_hw(struct ieee80211_hw *hw);
 
-/* trick to avoid symbol clashes with the ieee80211 subsystem */
-void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
-                   struct ieee80211_rx_status *status);
+/*
+ * trick to avoid symbol clashes with the ieee80211 subsystem,
+ * use the inline below instead
+ */
+void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb);
 
 /**
  * ieee80211_rx - receive frame
@@ -1624,13 +1631,10 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
  *
  * @hw: the hardware this frame came in on
  * @skb: the buffer to receive, owned by mac80211 after this call
- * @status: status of this frame; the status pointer need not be valid
- *     after this function returns
  */
-static inline void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
-                               struct ieee80211_rx_status *status)
+static inline void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
-       __ieee80211_rx(hw, skb, status);
+       __ieee80211_rx(hw, skb);
 }
 
 /**
@@ -1644,13 +1648,8 @@ static inline void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
  *
  * @hw: the hardware this frame came in on
  * @skb: the buffer to receive, owned by mac80211 after this call
- * @status: status of 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_rx_irqsafe(struct ieee80211_hw *hw,
-                         struct sk_buff *skb,
-                         struct ieee80211_rx_status *status);
+void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb);
 
 /**
  * ieee80211_tx_status - transmit status callback
index 0b30277..15d5a53 100644 (file)
@@ -705,7 +705,7 @@ static void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_mgmt *mgmt;
        u16 fc;
 
-       rx_status = (struct ieee80211_rx_status *) skb->cb;
+       rx_status = IEEE80211_SKB_RXCB(skb);
        mgmt = (struct ieee80211_mgmt *) skb->data;
        fc = le16_to_cpu(mgmt->frame_control);
 
@@ -836,8 +836,7 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
 }
 
 ieee80211_rx_result
-ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
-                      struct ieee80211_rx_status *rx_status)
+ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_mgmt *mgmt;
@@ -852,7 +851,6 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
        switch (fc & IEEE80211_FCTL_STYPE) {
        case IEEE80211_STYPE_PROBE_RESP:
        case IEEE80211_STYPE_BEACON:
-               memcpy(skb->cb, rx_status, sizeof(*rx_status));
        case IEEE80211_STYPE_PROBE_REQ:
        case IEEE80211_STYPE_AUTH:
                skb_queue_tail(&sdata->u.ibss.skb_queue, skb);
index 68eb505..c65c65a 100644 (file)
@@ -943,8 +943,7 @@ extern const struct iw_handler_def ieee80211_iw_handler_def;
 /* STA code */
 void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata);
 ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
-                                         struct sk_buff *skb,
-                                         struct ieee80211_rx_status *rx_status);
+                                         struct sk_buff *skb);
 int ieee80211_sta_commit(struct ieee80211_sub_if_data *sdata);
 int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len);
 int ieee80211_sta_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len);
@@ -967,8 +966,7 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata);
 void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
 void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata);
 ieee80211_rx_result
-ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
-                      struct ieee80211_rx_status *rx_status);
+ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
 struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
                                        u8 *bssid, u8 *addr, u32 supp_rates);
 int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
@@ -988,9 +986,7 @@ int ieee80211_scan_results(struct ieee80211_local *local,
                           char *buf, size_t len);
 void ieee80211_scan_cancel(struct ieee80211_local *local);
 ieee80211_rx_result
-ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata,
-                 struct sk_buff *skb,
-                 struct ieee80211_rx_status *rx_status);
+ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
 int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata,
                               const char *ie, size_t len);
 
index 092a017..5b69f5f 100644 (file)
@@ -330,19 +330,16 @@ 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_ra_tid *ra_tid;
 
        while ((skb = skb_dequeue(&local->skb_queue)) ||
               (skb = skb_dequeue(&local->skb_queue_unreliable))) {
                switch (skb->pkt_type) {
                case IEEE80211_RX_MSG:
-                       /* status is in skb->cb */
-                       memcpy(&rx_status, skb->cb, sizeof(rx_status));
                        /* Clear skb->pkt_type in order to not confuse kernel
                         * netstack. */
                        skb->pkt_type = 0;
-                       __ieee80211_rx(local_to_hw(local), skb, &rx_status);
+                       ieee80211_rx(local_to_hw(local), skb);
                        break;
                case IEEE80211_TX_STATUS_MSG:
                        skb->pkt_type = 0;
index 11cf45b..542ea02 100644 (file)
@@ -568,7 +568,7 @@ static void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
 
        ifmsh = &sdata->u.mesh;
 
-       rx_status = (struct ieee80211_rx_status *) skb->cb;
+       rx_status = IEEE80211_SKB_RXCB(skb);
        mgmt = (struct ieee80211_mgmt *) skb->data;
        stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
 
@@ -671,8 +671,7 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
 }
 
 ieee80211_rx_result
-ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
-                      struct ieee80211_rx_status *rx_status)
+ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
@@ -689,7 +688,6 @@ ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
        case IEEE80211_STYPE_PROBE_RESP:
        case IEEE80211_STYPE_BEACON:
        case IEEE80211_STYPE_ACTION:
-               memcpy(skb->cb, rx_status, sizeof(*rx_status));
                skb_queue_tail(&ifmsh->skb_queue, skb);
                queue_work(local->hw.workqueue, &ifmsh->work);
                return RX_QUEUED;
index c7d7281..2a2ed18 100644 (file)
@@ -208,8 +208,7 @@ void ieee80211s_init(void);
 void ieee80211s_stop(void);
 void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata);
 ieee80211_rx_result
-ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
-                      struct ieee80211_rx_status *rx_status);
+ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
 void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata);
 void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata);
 
index aca22b0..5e25d32 100644 (file)
@@ -2063,8 +2063,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
 }
 
 ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
-                                         struct sk_buff *skb,
-                                         struct ieee80211_rx_status *rx_status)
+                                         struct sk_buff *skb)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_mgmt *mgmt;
@@ -2080,7 +2079,6 @@ ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
        case IEEE80211_STYPE_PROBE_REQ:
        case IEEE80211_STYPE_PROBE_RESP:
        case IEEE80211_STYPE_BEACON:
-               memcpy(skb->cb, rx_status, sizeof(*rx_status));
        case IEEE80211_STYPE_AUTH:
        case IEEE80211_STYPE_ASSOC_RESP:
        case IEEE80211_STYPE_REASSOC_RESP:
index de5bba7..0563b69 100644 (file)
@@ -30,7 +30,6 @@
 static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
                                           struct tid_ampdu_rx *tid_agg_rx,
                                           struct sk_buff *skb,
-                                          struct ieee80211_rx_status *status,
                                           u16 mpdu_seq_num,
                                           int bar_req);
 /*
@@ -59,11 +58,11 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
        return skb;
 }
 
-static inline int should_drop_frame(struct ieee80211_rx_status *status,
-                                   struct sk_buff *skb,
+static inline int should_drop_frame(struct sk_buff *skb,
                                    int present_fcs_len,
                                    int radiotap_len)
 {
+       struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 
        if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC))
@@ -111,10 +110,10 @@ ieee80211_rx_radiotap_len(struct ieee80211_local *local,
 static void
 ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
                                 struct sk_buff *skb,
-                                struct ieee80211_rx_status *status,
                                 struct ieee80211_rate *rate,
                                 int rtap_len)
 {
+       struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
        struct ieee80211_radiotap_header *rthdr;
        unsigned char *pos;
 
@@ -220,9 +219,9 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
  */
 static struct sk_buff *
 ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
-                    struct ieee80211_rx_status *status,
                     struct ieee80211_rate *rate)
 {
+       struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb);
        struct ieee80211_sub_if_data *sdata;
        int needed_headroom = 0;
        struct sk_buff *skb, *skb2;
@@ -248,8 +247,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
                present_fcs_len = FCS_LEN;
 
        if (!local->monitors) {
-               if (should_drop_frame(status, origskb, present_fcs_len,
-                                     rtap_len)) {
+               if (should_drop_frame(origskb, present_fcs_len, rtap_len)) {
                        dev_kfree_skb(origskb);
                        return NULL;
                }
@@ -257,7 +255,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
                return remove_monitor_info(local, origskb, rtap_len);
        }
 
-       if (should_drop_frame(status, origskb, present_fcs_len, rtap_len)) {
+       if (should_drop_frame(origskb, present_fcs_len, rtap_len)) {
                /* only need to expand headroom if necessary */
                skb = origskb;
                origskb = NULL;
@@ -289,7 +287,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
 
        /* if necessary, prepend radiotap information */
        if (!(status->flag & RX_FLAG_RADIOTAP))
-               ieee80211_add_rx_radiotap_header(local, skb, status, rate,
+               ieee80211_add_rx_radiotap_header(local, skb, rate,
                                                 needed_headroom);
 
        skb_reset_mac_header(skb);
@@ -421,12 +419,11 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
        struct sk_buff *skb = rx->skb;
 
        if (unlikely(local->hw_scanning))
-               return ieee80211_scan_rx(rx->sdata, skb, rx->status);
+               return ieee80211_scan_rx(rx->sdata, skb);
 
        if (unlikely(local->sw_scanning)) {
                /* drop all the other packets during a software scan anyway */
-               if (ieee80211_scan_rx(rx->sdata, skb, rx->status)
-                   != RX_QUEUED)
+               if (ieee80211_scan_rx(rx->sdata, skb) != RX_QUEUED)
                        dev_kfree_skb(skb);
                return RX_QUEUED;
        }
@@ -1620,7 +1617,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx)
                /* manage reordering buffer according to requested */
                /* sequence number */
                rcu_read_lock();
-               ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, NULL, NULL,
+               ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, NULL,
                                                 start_seq_num, 1);
                rcu_read_unlock();
                return RX_DROP_UNUSABLE;
@@ -1817,13 +1814,13 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
                return RX_DROP_MONITOR;
 
        if (ieee80211_vif_is_mesh(&sdata->vif))
-               return ieee80211_mesh_rx_mgmt(sdata, rx->skb, rx->status);
+               return ieee80211_mesh_rx_mgmt(sdata, rx->skb);
 
        if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-               return ieee80211_ibss_rx_mgmt(sdata, rx->skb, rx->status);
+               return ieee80211_ibss_rx_mgmt(sdata, rx->skb);
 
        if (sdata->vif.type == NL80211_IFTYPE_STATION)
-               return ieee80211_sta_rx_mgmt(sdata, rx->skb, rx->status);
+               return ieee80211_sta_rx_mgmt(sdata, rx->skb);
 
        return RX_DROP_MONITOR;
 }
@@ -2114,9 +2111,9 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
  */
 static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
                                         struct sk_buff *skb,
-                                        struct ieee80211_rx_status *status,
                                         struct ieee80211_rate *rate)
 {
+       struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
        struct ieee80211_local *local = hw_to_local(hw);
        struct ieee80211_sub_if_data *sdata;
        struct ieee80211_hdr *hdr;
@@ -2227,20 +2224,21 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
 {
        struct ieee80211_supported_band *sband;
        struct ieee80211_rate *rate;
-       struct ieee80211_rx_status status;
+       struct sk_buff *skb = tid_agg_rx->reorder_buf[index];
+       struct ieee80211_rx_status *status;
 
-       if (!tid_agg_rx->reorder_buf[index])
+       if (!skb)
                goto no_frame;
 
+       status = IEEE80211_SKB_RXCB(skb);
+
        /* release the reordered frames to stack */
-       memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, sizeof(status));
-       sband = hw->wiphy->bands[status.band];
-       if (status.flag & RX_FLAG_HT)
+       sband = hw->wiphy->bands[status->band];
+       if (status->flag & RX_FLAG_HT)
                rate = sband->bitrates; /* TODO: HT rates */
        else
-               rate = &sband->bitrates[status.rate_idx];
-       __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index],
-                                    &status, rate);
+               rate = &sband->bitrates[status->rate_idx];
+       __ieee80211_rx_handle_packet(hw, skb, rate);
        tid_agg_rx->stored_mpdu_num--;
        tid_agg_rx->reorder_buf[index] = NULL;
 
@@ -2265,7 +2263,6 @@ no_frame:
 static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
                                           struct tid_ampdu_rx *tid_agg_rx,
                                           struct sk_buff *skb,
-                                          struct ieee80211_rx_status *rxstatus,
                                           u16 mpdu_seq_num,
                                           int bar_req)
 {
@@ -2324,8 +2321,6 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
        /* put the frame in the reordering buffer */
        tid_agg_rx->reorder_buf[index] = skb;
        tid_agg_rx->reorder_time[index] = jiffies;
-       memcpy(tid_agg_rx->reorder_buf[index]->cb, rxstatus,
-              sizeof(*rxstatus));
        tid_agg_rx->stored_mpdu_num++;
        /* release the buffer until next missing frame */
        index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn)
@@ -2374,8 +2369,7 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
 }
 
 static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
-                                    struct sk_buff *skb,
-                                    struct ieee80211_rx_status *status)
+                                    struct sk_buff *skb)
 {
        struct ieee80211_hw *hw = &local->hw;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
@@ -2424,7 +2418,7 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
 
        /* according to mpdu sequence number deal with reordering buffer */
        mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4;
-       ret = ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, status,
+       ret = ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb,
                                                mpdu_seq_num, 0);
  end_reorder:
        return ret;
@@ -2434,12 +2428,12 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
  * This is the receive path handler. It is called by a low level driver when an
  * 802.11 MPDU is received from the hardware.
  */
-void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
-                   struct ieee80211_rx_status *status)
+void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct ieee80211_local *local = hw_to_local(hw);
        struct ieee80211_rate *rate = NULL;
        struct ieee80211_supported_band *sband;
+       struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
 
        if (status->band < 0 ||
            status->band >= IEEE80211_NUM_BANDS) {
@@ -2482,7 +2476,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
         * if it was previously present.
         * Also, frames with less than 16 bytes are dropped.
         */
-       skb = ieee80211_rx_monitor(local, skb, status, rate);
+       skb = ieee80211_rx_monitor(local, skb, rate);
        if (!skb) {
                rcu_read_unlock();
                return;
@@ -2500,8 +2494,8 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
         * frames from other than operational channel), but that should not
         * happen in normal networks.
         */
-       if (!ieee80211_rx_reorder_ampdu(local, skb, status))
-               __ieee80211_rx_handle_packet(hw, skb, status, rate);
+       if (!ieee80211_rx_reorder_ampdu(local, skb))
+               __ieee80211_rx_handle_packet(hw, skb, rate);
 
        rcu_read_unlock();
 }
@@ -2509,16 +2503,13 @@ EXPORT_SYMBOL(__ieee80211_rx);
 
 /* This is a version of the rx handler that can be called from hard irq
  * context. Post the skb on the queue and schedule the tasklet */
-void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb,
-                         struct ieee80211_rx_status *status)
+void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct ieee80211_local *local = hw_to_local(hw);
 
        BUILD_BUG_ON(sizeof(struct ieee80211_rx_status) > sizeof(skb->cb));
 
        skb->dev = local->mdev;
-       /* copy status into skb->cb for use by tasklet */
-       memcpy(skb->cb, status, sizeof(*status));
        skb->pkt_type = IEEE80211_RX_MSG;
        skb_queue_tail(&local->skb_queue, skb);
        tasklet_schedule(&local->tasklet);
index 2a8d09a..8b2416c 100644 (file)
@@ -135,9 +135,9 @@ void ieee80211_rx_bss_remove(struct ieee80211_sub_if_data *sdata, u8 *bssid,
 }
 
 ieee80211_rx_result
-ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
-                 struct ieee80211_rx_status *rx_status)
+ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
 {
+       struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
        struct ieee80211_mgmt *mgmt;
        struct ieee80211_bss *bss;
        u8 *elements;