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 2b9e379994a180294690d0f06735f864a27e045f..ecc93834533fa15aab8f2a694cd662634ade46f2 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 4efbdbe6d6bf511c75816350aabc038a239830cd..13303fa3473416e4a14d6a215bef81d68ec58a81 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 9d38cf60a0db2bd8ee1197d99ea6854769aa7357..51753ed1b8ba9bf05a627b28e4215fd8953cdfcb 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 f26a6896062262b0ffd20a05ac1b468cfd4f6ff8..c6e70919435cd93487c44ec8b054fc5a9ea6539d 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 cece1c4c6bda5db0b151c2a1cd745ba4feab83a3..c00b9051bb5349fe0eaa4a1627c6f601aac39db4 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 55f36a7254d98515b7d61b22152fe10c4a567255..5b85e7d73592761afe3871a0be6aafc3f9cec187 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 b8e39dd06e99d580829cc26b8c8513272d9a409d..f79cee82601b397242c633d93be959968518958e 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 46288e724889b05e8e17cb506daf4b4ffad4774a..777c09534cecd18eab190c2a05b71ed351672c93 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 2b8d40b37a1c9e1be70e0989b4fc2820faf9290e..2160795ed0154efeb5e5d9eec2f88407233f4e2b 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 10a99e26d392ea4e67e5fe82396a86e748e1046e..4872345a2f619a9cf2efff3e5771e4740a083a95 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 c47ef48f31c54bf531d7cd7b8c1430e8b382f98f..b1e4baec29f445400243824777c774b758a7caad 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 a263d5c84c0874857b8ee02243cff89bc9e8eee6..b9eded88c32230b45b6a21e7c2a6109df358efc0 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 22ca122bd798c7d37ae3a7da4476b64dbacde233..1b15f9e0b861b8c060b4443b97890be47ca0c13f 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 57813e72c80875feda793d915c4709f05753b359..41e33798adb5e37484a6d1b637156ac6d914d38b 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 7e65d7c31802097ff7194430589e6b10e0705e46..47521c5b6f91060e9d669cb4d84a574a1a5aae96 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 294250e294dd548bb295c620e6d52c799f03021f..c9b9dbe584c630c0ce508deb79d321abb1dd4808 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 48fa39ea17edebcc5a82a7e9e1ab8ac50df0c3d9..0dbb483a0973d888938a69a6f41aba26dafc7849 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 40b07b988224a4eee002a91c970fe1b5500f8ce2..9600b72495daf95fb2430a056254ee6b2ecb5dc1 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 0e034081f3a5021725facfa41fa0e15bb8ec2d8f..42db41070cf0dc486d324275d3847f0a228891ca 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 cfdaac9b747edbc15cc3c0c0746772815b6ddd9c..52744faedbff0a622fd22a3e93eb82f69b503083 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 3e8cf08b87e6c7a26bdf6d55002c59f11a367b9a..b905e7b43a19877e576415de8c02ed01ea13a0f6 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 c061044769737f72a54bb1afe8e70c6d77ca38a7..fe80771d95f1fd81628bccf1fcf164bde027d9af 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 0b30277eb3667bbc113cc89802609959f8d1faae..15d5a53b59a815f78a036828e992b2ca8a4ccd9d 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 68eb5052179a54b306b8a53e425dd8242536eb3c..c65c65a9e697463fe95fd6a7c2af64e292f83ec3 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 092a017b237e35faa10ef4c72a5f0e21b64c33b6..5b69f5f07299486fef620c445fe8b5e86b637145 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 11cf45bce38a36cf17c4592b5b0991a489a28c5e..542ea025494ee909b4cdd515152837665d6926e6 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 c7d72819cdd2bdb448d9c323fbf52c22ae5cc47a..2a2ed182cb7ea219a2cd3e57708163b4c28b4c59 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 aca22b00b6a327873ee5ffc5a443ae541fdab5ed..5e25d320deaec524f58d63755cfb32fc321f1b6f 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 de5bba7f910ae876637c3002544a6963eebccdfd..0563b6969a213ed21fa9bedf01c885497ee1d933 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 2a8d09ad17ff8829cc777143d0cff77dff6052c3..8b2416c77a6e3fda2977b9db1e94c4e95780f4ed 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;