aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-06-17 07:13:00 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-10 14:57:54 -0400
commitf1d58c2521eb160178b2151d6326d8dc5d7c8560 (patch)
treeaf373bb1a5fbb6bc9436d29095133992d33d6598
parent18ad01c43918751cc22f8ee28f6b38b8954a55b2 (diff)
mac80211: push rx status into skb->cb
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>
-rw-r--r--drivers/net/wireless/adm8211.c3
-rw-r--r--drivers/net/wireless/at76c50x-usb.c3
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c6
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c13
-rw-r--r--drivers/net/wireless/b43/xmit.c3
-rw-r--r--drivers/net/wireless/b43legacy/xmit.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c3
-rw-r--r--drivers/net/wireless/libertas_tf/main.c3
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c3
-rw-r--r--drivers/net/wireless/mwl8k.c3
-rw-r--r--drivers/net/wireless/p54/p54common.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c3
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_dev.c3
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c3
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_rx.c3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c3
-rw-r--r--drivers/staging/agnx/xmit.c3
-rw-r--r--drivers/staging/stlc45xx/stlc45xx.c3
-rw-r--r--drivers/staging/winbond/wb35rx.c3
-rw-r--r--include/net/mac80211.h29
-rw-r--r--net/mac80211/ibss.c6
-rw-r--r--net/mac80211/ieee80211_i.h10
-rw-r--r--net/mac80211/main.c5
-rw-r--r--net/mac80211/mesh.c6
-rw-r--r--net/mac80211/mesh.h3
-rw-r--r--net/mac80211/mlme.c4
-rw-r--r--net/mac80211/rx.c71
-rw-r--r--net/mac80211/scan.c4
30 files changed, 108 insertions, 106 deletions
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index 2b9e379994a1..ecc93834533f 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -452,7 +452,8 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev)
452 rx_status.freq = adm8211_channels[priv->channel - 1].center_freq; 452 rx_status.freq = adm8211_channels[priv->channel - 1].center_freq;
453 rx_status.band = IEEE80211_BAND_2GHZ; 453 rx_status.band = IEEE80211_BAND_2GHZ;
454 454
455 ieee80211_rx_irqsafe(dev, skb, &rx_status); 455 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
456 ieee80211_rx_irqsafe(dev, skb);
456 } 457 }
457 458
458 entry = (++priv->cur_rx) % priv->rx_ring_size; 459 entry = (++priv->cur_rx) % priv->rx_ring_size;
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 4efbdbe6d6bf..13303fa34734 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1568,7 +1568,8 @@ static void at76_rx_tasklet(unsigned long param)
1568 1568
1569 at76_dbg(DBG_MAC80211, "calling ieee80211_rx_irqsafe(): %d/%d", 1569 at76_dbg(DBG_MAC80211, "calling ieee80211_rx_irqsafe(): %d/%d",
1570 priv->rx_skb->len, priv->rx_skb->data_len); 1570 priv->rx_skb->len, priv->rx_skb->data_len);
1571 ieee80211_rx_irqsafe(priv->hw, priv->rx_skb, &rx_status); 1571 memcpy(IEEE80211_SKB_RXCB(priv->rx_skb), &rx_status, sizeof(rx_status));
1572 ieee80211_rx_irqsafe(priv->hw, priv->rx_skb);
1572 1573
1573 /* Use a new skb for the next receive */ 1574 /* Use a new skb for the next receive */
1574 priv->rx_skb = NULL; 1575 priv->rx_skb = NULL;
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index 9d38cf60a0db..51753ed1b8ba 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -917,8 +917,10 @@ static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
917 ar9170_rx_phy_status(ar, phy, &status); 917 ar9170_rx_phy_status(ar, phy, &status);
918 918
919 skb = ar9170_rx_copy_data(buf, mpdu_len); 919 skb = ar9170_rx_copy_data(buf, mpdu_len);
920 if (likely(skb)) 920 if (likely(skb)) {
921 ieee80211_rx_irqsafe(ar->hw, skb, &status); 921 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
922 ieee80211_rx_irqsafe(ar->hw, skb);
923 }
922} 924}
923 925
924void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) 926void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index f26a68960622..c6e70919435c 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1905,7 +1905,8 @@ accept:
1905 if (sc->opmode == NL80211_IFTYPE_ADHOC) 1905 if (sc->opmode == NL80211_IFTYPE_ADHOC)
1906 ath5k_check_ibss_tsf(sc, skb, &rxs); 1906 ath5k_check_ibss_tsf(sc, skb, &rxs);
1907 1907
1908 __ieee80211_rx(sc->hw, skb, &rxs); 1908 memcpy(IEEE80211_SKB_RXCB(skb), &rxs, sizeof(rxs));
1909 ieee80211_rx(sc->hw, skb);
1909 1910
1910 bf->skb = next_skb; 1911 bf->skb = next_skb;
1911 bf->skbaddr = next_skb_addr; 1912 bf->skbaddr = next_skb_addr;
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index cece1c4c6bda..c00b9051bb53 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -619,13 +619,18 @@ static void ath_rx_send_to_mac80211(struct ath_softc *sc, struct sk_buff *skb,
619 if (aphy == NULL) 619 if (aphy == NULL)
620 continue; 620 continue;
621 nskb = skb_copy(skb, GFP_ATOMIC); 621 nskb = skb_copy(skb, GFP_ATOMIC);
622 if (nskb) 622 if (nskb) {
623 __ieee80211_rx(aphy->hw, nskb, rx_status); 623 memcpy(IEEE80211_SKB_RXCB(nskb), rx_status,
624 sizeof(*rx_status));
625 ieee80211_rx(aphy->hw, nskb);
626 }
624 } 627 }
625 __ieee80211_rx(sc->hw, skb, rx_status); 628 memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
629 ieee80211_rx(sc->hw, skb);
626 } else { 630 } else {
627 /* Deliver unicast frames based on receiver address */ 631 /* Deliver unicast frames based on receiver address */
628 __ieee80211_rx(ath_get_virt_hw(sc, hdr), skb, rx_status); 632 memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
633 ieee80211_rx(ath_get_virt_hw(sc, hdr), skb);
629 } 634 }
630} 635}
631 636
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 55f36a7254d9..5b85e7d73592 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -670,7 +670,8 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
670 goto drop; 670 goto drop;
671 } 671 }
672 672
673 ieee80211_rx_irqsafe(dev->wl->hw, skb, &status); 673 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
674 ieee80211_rx_irqsafe(dev->wl->hw, skb);
674 675
675 return; 676 return;
676drop: 677drop:
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c
index b8e39dd06e99..f79cee82601b 100644
--- a/drivers/net/wireless/b43legacy/xmit.c
+++ b/drivers/net/wireless/b43legacy/xmit.c
@@ -591,7 +591,8 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
591 } 591 }
592 592
593 dev->stats.last_rx = jiffies; 593 dev->stats.last_rx = jiffies;
594 ieee80211_rx_irqsafe(dev->wl->hw, skb, &status); 594 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
595 ieee80211_rx_irqsafe(dev->wl->hw, skb);
595 596
596 return; 597 return;
597drop: 598drop:
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 46288e724889..777c09534cec 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -577,7 +577,8 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
577 if (ieee80211_is_data(hdr->frame_control)) 577 if (ieee80211_is_data(hdr->frame_control))
578 priv->rxtxpackets += len; 578 priv->rxtxpackets += len;
579#endif 579#endif
580 ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats); 580 memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats));
581 ieee80211_rx_irqsafe(priv->hw, rxb->skb);
581 rxb->skb = NULL; 582 rxb->skb = NULL;
582} 583}
583 584
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 2b8d40b37a1c..2160795ed015 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -932,7 +932,8 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
932 return; 932 return;
933 933
934 iwl_update_rx_stats(priv, le16_to_cpu(hdr->frame_control), len); 934 iwl_update_rx_stats(priv, le16_to_cpu(hdr->frame_control), len);
935 ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats); 935 memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats));
936 ieee80211_rx_irqsafe(priv->hw, rxb->skb);
936 priv->alloc_rxb_skb--; 937 priv->alloc_rxb_skb--;
937 rxb->skb = NULL; 938 rxb->skb = NULL;
938} 939}
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c
index 10a99e26d392..4872345a2f61 100644
--- a/drivers/net/wireless/libertas_tf/main.c
+++ b/drivers/net/wireless/libertas_tf/main.c
@@ -503,7 +503,8 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb)
503 skb_reserve(skb, 2); 503 skb_reserve(skb, 2);
504 } 504 }
505 505
506 ieee80211_rx_irqsafe(priv->hw, skb, &stats); 506 memcpy(IEEE80211_SKB_RXCB(skb), &stats, sizeof(stats));
507 ieee80211_rx_irqsafe(priv->hw, skb);
507 return 0; 508 return 0;
508} 509}
509EXPORT_SYMBOL_GPL(lbtf_rx); 510EXPORT_SYMBOL_GPL(lbtf_rx);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index c47ef48f31c5..b1e4baec29f4 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -430,7 +430,8 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
430 if (memcmp(hdr->addr1, data2->hw->wiphy->perm_addr, 430 if (memcmp(hdr->addr1, data2->hw->wiphy->perm_addr,
431 ETH_ALEN) == 0) 431 ETH_ALEN) == 0)
432 ack = true; 432 ack = true;
433 ieee80211_rx_irqsafe(data2->hw, nskb, &rx_status); 433 memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status));
434 ieee80211_rx_irqsafe(data2->hw, nskb);
434 } 435 }
435 spin_unlock(&hwsim_radio_lock); 436 spin_unlock(&hwsim_radio_lock);
436 437
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index a263d5c84c08..b9eded88c322 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -1047,7 +1047,8 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
1047 status.flag = 0; 1047 status.flag = 0;
1048 status.band = IEEE80211_BAND_2GHZ; 1048 status.band = IEEE80211_BAND_2GHZ;
1049 status.freq = ieee80211_channel_to_frequency(rx_desc->channel); 1049 status.freq = ieee80211_channel_to_frequency(rx_desc->channel);
1050 ieee80211_rx_irqsafe(hw, skb, &status); 1050 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
1051 ieee80211_rx_irqsafe(hw, skb);
1051 1052
1052 processed++; 1053 processed++;
1053 } 1054 }
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 22ca122bd798..1b15f9e0b861 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -794,7 +794,8 @@ static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
794 skb_pull(skb, header_len); 794 skb_pull(skb, header_len);
795 skb_trim(skb, le16_to_cpu(hdr->len)); 795 skb_trim(skb, le16_to_cpu(hdr->len));
796 796
797 ieee80211_rx_irqsafe(dev, skb, &rx_status); 797 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
798 ieee80211_rx_irqsafe(dev, skb);
798 799
799 queue_delayed_work(dev->workqueue, &priv->work, 800 queue_delayed_work(dev->workqueue, &priv->work,
800 msecs_to_jiffies(P54_STATISTICS_UPDATE)); 801 msecs_to_jiffies(P54_STATISTICS_UPDATE));
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 57813e72c808..41e33798adb5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -449,7 +449,8 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
449 * mac80211 will clean up the skb structure. 449 * mac80211 will clean up the skb structure.
450 */ 450 */
451 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); 451 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb);
452 ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status); 452 memcpy(IEEE80211_SKB_RXCB(entry->skb), rx_status, sizeof(*rx_status));
453 ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb);
453 454
454 /* 455 /*
455 * Replace the skb with the freshly allocated one. 456 * Replace the skb with the freshly allocated one.
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index 7e65d7c31802..47521c5b6f91 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -143,7 +143,8 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
143 if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) 143 if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
144 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; 144 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
145 145
146 ieee80211_rx_irqsafe(dev, skb, &rx_status); 146 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
147 ieee80211_rx_irqsafe(dev, skb);
147 148
148 skb = new_skb; 149 skb = new_skb;
149 priv->rx_buf[priv->rx_idx] = skb; 150 priv->rx_buf[priv->rx_idx] = skb;
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index 294250e294dd..c9b9dbe584c6 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -380,7 +380,8 @@ static void rtl8187_rx_cb(struct urb *urb)
380 rx_status.flag |= RX_FLAG_TSFT; 380 rx_status.flag |= RX_FLAG_TSFT;
381 if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) 381 if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
382 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; 382 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
383 ieee80211_rx_irqsafe(dev, skb, &rx_status); 383 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
384 ieee80211_rx_irqsafe(dev, skb);
384 385
385 skb = dev_alloc_skb(RTL8187_MAX_RX); 386 skb = dev_alloc_skb(RTL8187_MAX_RX);
386 if (unlikely(!skb)) { 387 if (unlikely(!skb)) {
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl12xx/wl1251_rx.c
index 48fa39ea17ed..0dbb483a0973 100644
--- a/drivers/net/wireless/wl12xx/wl1251_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_rx.c
@@ -151,7 +151,8 @@ static void wl1251_rx_body(struct wl1251 *wl,
151 wl1251_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len, 151 wl1251_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
152 beacon ? "beacon" : ""); 152 beacon ? "beacon" : "");
153 153
154 ieee80211_rx(wl->hw, skb, &status); 154 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
155 ieee80211_rx(wl->hw, skb);
155} 156}
156 157
157static void wl1251_rx_ack(struct wl1251 *wl) 158static void wl1251_rx_ack(struct wl1251 *wl)
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 40b07b988224..9600b72495da 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -711,7 +711,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length)
711 711
712 memcpy(skb_put(skb, length), buffer, length); 712 memcpy(skb_put(skb, length), buffer, length);
713 713
714 ieee80211_rx_irqsafe(hw, skb, &stats); 714 memcpy(IEEE80211_SKB_RXCB(skb), &stats, sizeof(stats));
715 ieee80211_rx_irqsafe(hw, skb);
715 return 0; 716 return 0;
716} 717}
717 718
diff --git a/drivers/staging/agnx/xmit.c b/drivers/staging/agnx/xmit.c
index 0e034081f3a5..42db41070cf0 100644
--- a/drivers/staging/agnx/xmit.c
+++ b/drivers/staging/agnx/xmit.c
@@ -384,7 +384,8 @@ void handle_rx_irq(struct agnx_priv *priv)
384/* dump_ieee80211_hdr((struct ieee80211_hdr *)skb->data, "RX G"); */ 384/* dump_ieee80211_hdr((struct ieee80211_hdr *)skb->data, "RX G"); */
385 } else 385 } else
386 agnx_bug("Unknown packets type"); 386 agnx_bug("Unknown packets type");
387 ieee80211_rx_irqsafe(priv->hw, skb, &status); 387 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
388 ieee80211_rx_irqsafe(priv->hw, skb);
388 rx_desc_reinit(priv, i); 389 rx_desc_reinit(priv, i);
389 390
390 } while (priv->rx.idx++); 391 } while (priv->rx.idx++);
diff --git a/drivers/staging/stlc45xx/stlc45xx.c b/drivers/staging/stlc45xx/stlc45xx.c
index cfdaac9b747e..52744faedbff 100644
--- a/drivers/staging/stlc45xx/stlc45xx.c
+++ b/drivers/staging/stlc45xx/stlc45xx.c
@@ -1429,7 +1429,8 @@ static int stlc45xx_rx_data(struct stlc45xx *stlc, struct sk_buff *skb)
1429 stlc45xx_debug(DEBUG_RX, "rx data 0x%p %d B", skb->data, skb->len); 1429 stlc45xx_debug(DEBUG_RX, "rx data 0x%p %d B", skb->data, skb->len);
1430 stlc45xx_dump(DEBUG_RX_CONTENT, skb->data, skb->len); 1430 stlc45xx_dump(DEBUG_RX_CONTENT, skb->data, skb->len);
1431 1431
1432 ieee80211_rx(stlc->hw, skb, &status); 1432 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
1433 ieee80211_rx(stlc->hw, skb);
1433 1434
1434 return 0; 1435 return 0;
1435} 1436}
diff --git a/drivers/staging/winbond/wb35rx.c b/drivers/staging/winbond/wb35rx.c
index 3e8cf08b87e6..b905e7b43a19 100644
--- a/drivers/staging/winbond/wb35rx.c
+++ b/drivers/staging/winbond/wb35rx.c
@@ -40,7 +40,8 @@ static void packet_came(struct ieee80211_hw *hw, char *pRxBufferAddress, int Pac
40 rx_status.phymode = MODE_IEEE80211B; 40 rx_status.phymode = MODE_IEEE80211B;
41*/ 41*/
42 42
43 ieee80211_rx_irqsafe(hw, skb, &rx_status); 43 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
44 ieee80211_rx_irqsafe(hw, skb);
44} 45}
45 46
46static void Wb35Rx_adjust(PDESCRIPTOR pRxDes) 47static void Wb35Rx_adjust(PDESCRIPTOR pRxDes)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index c06104476973..fe80771d95f1 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -397,6 +397,11 @@ static inline struct ieee80211_tx_info *IEEE80211_SKB_CB(struct sk_buff *skb)
397 return (struct ieee80211_tx_info *)skb->cb; 397 return (struct ieee80211_tx_info *)skb->cb;
398} 398}
399 399
400static inline struct ieee80211_rx_status *IEEE80211_SKB_RXCB(struct sk_buff *skb)
401{
402 return (struct ieee80211_rx_status *)skb->cb;
403}
404
400/** 405/**
401 * ieee80211_tx_info_clear_status - clear TX status 406 * ieee80211_tx_info_clear_status - clear TX status
402 * 407 *
@@ -478,7 +483,7 @@ enum mac80211_rx_flags {
478 * 483 *
479 * The low-level driver should provide this information (the subset 484 * The low-level driver should provide this information (the subset
480 * supported by hardware) to the 802.11 code with each received 485 * supported by hardware) to the 802.11 code with each received
481 * frame. 486 * frame, in the skb's control buffer (cb).
482 * 487 *
483 * @mactime: value in microseconds of the 64-bit Time Synchronization Function 488 * @mactime: value in microseconds of the 64-bit Time Synchronization Function
484 * (TSF) timer when the first data symbol (MPDU) arrived at the hardware. 489 * (TSF) timer when the first data symbol (MPDU) arrived at the hardware.
@@ -1606,9 +1611,11 @@ void ieee80211_free_hw(struct ieee80211_hw *hw);
1606 */ 1611 */
1607void ieee80211_restart_hw(struct ieee80211_hw *hw); 1612void ieee80211_restart_hw(struct ieee80211_hw *hw);
1608 1613
1609/* trick to avoid symbol clashes with the ieee80211 subsystem */ 1614/*
1610void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, 1615 * trick to avoid symbol clashes with the ieee80211 subsystem,
1611 struct ieee80211_rx_status *status); 1616 * use the inline below instead
1617 */
1618void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb);
1612 1619
1613/** 1620/**
1614 * ieee80211_rx - receive frame 1621 * ieee80211_rx - receive frame
@@ -1624,13 +1631,10 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
1624 * 1631 *
1625 * @hw: the hardware this frame came in on 1632 * @hw: the hardware this frame came in on
1626 * @skb: the buffer to receive, owned by mac80211 after this call 1633 * @skb: the buffer to receive, owned by mac80211 after this call
1627 * @status: status of this frame; the status pointer need not be valid
1628 * after this function returns
1629 */ 1634 */
1630static inline void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, 1635static inline void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
1631 struct ieee80211_rx_status *status)
1632{ 1636{
1633 __ieee80211_rx(hw, skb, status); 1637 __ieee80211_rx(hw, skb);
1634} 1638}
1635 1639
1636/** 1640/**
@@ -1644,13 +1648,8 @@ static inline void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
1644 * 1648 *
1645 * @hw: the hardware this frame came in on 1649 * @hw: the hardware this frame came in on
1646 * @skb: the buffer to receive, owned by mac80211 after this call 1650 * @skb: the buffer to receive, owned by mac80211 after this call
1647 * @status: status of this frame; the status pointer need not be valid
1648 * after this function returns and is not freed by mac80211,
1649 * it is recommended that it points to a stack area
1650 */ 1651 */
1651void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, 1652void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb);
1652 struct sk_buff *skb,
1653 struct ieee80211_rx_status *status);
1654 1653
1655/** 1654/**
1656 * ieee80211_tx_status - transmit status callback 1655 * ieee80211_tx_status - transmit status callback
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 0b30277eb366..15d5a53b59a8 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -705,7 +705,7 @@ static void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
705 struct ieee80211_mgmt *mgmt; 705 struct ieee80211_mgmt *mgmt;
706 u16 fc; 706 u16 fc;
707 707
708 rx_status = (struct ieee80211_rx_status *) skb->cb; 708 rx_status = IEEE80211_SKB_RXCB(skb);
709 mgmt = (struct ieee80211_mgmt *) skb->data; 709 mgmt = (struct ieee80211_mgmt *) skb->data;
710 fc = le16_to_cpu(mgmt->frame_control); 710 fc = le16_to_cpu(mgmt->frame_control);
711 711
@@ -836,8 +836,7 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
836} 836}
837 837
838ieee80211_rx_result 838ieee80211_rx_result
839ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, 839ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
840 struct ieee80211_rx_status *rx_status)
841{ 840{
842 struct ieee80211_local *local = sdata->local; 841 struct ieee80211_local *local = sdata->local;
843 struct ieee80211_mgmt *mgmt; 842 struct ieee80211_mgmt *mgmt;
@@ -852,7 +851,6 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
852 switch (fc & IEEE80211_FCTL_STYPE) { 851 switch (fc & IEEE80211_FCTL_STYPE) {
853 case IEEE80211_STYPE_PROBE_RESP: 852 case IEEE80211_STYPE_PROBE_RESP:
854 case IEEE80211_STYPE_BEACON: 853 case IEEE80211_STYPE_BEACON:
855 memcpy(skb->cb, rx_status, sizeof(*rx_status));
856 case IEEE80211_STYPE_PROBE_REQ: 854 case IEEE80211_STYPE_PROBE_REQ:
857 case IEEE80211_STYPE_AUTH: 855 case IEEE80211_STYPE_AUTH:
858 skb_queue_tail(&sdata->u.ibss.skb_queue, skb); 856 skb_queue_tail(&sdata->u.ibss.skb_queue, skb);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 68eb5052179a..c65c65a9e697 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -943,8 +943,7 @@ extern const struct iw_handler_def ieee80211_iw_handler_def;
943/* STA code */ 943/* STA code */
944void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata); 944void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata);
945ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, 945ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
946 struct sk_buff *skb, 946 struct sk_buff *skb);
947 struct ieee80211_rx_status *rx_status);
948int ieee80211_sta_commit(struct ieee80211_sub_if_data *sdata); 947int ieee80211_sta_commit(struct ieee80211_sub_if_data *sdata);
949int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len); 948int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len);
950int ieee80211_sta_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len); 949int 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);
967void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); 966void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
968void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata); 967void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata);
969ieee80211_rx_result 968ieee80211_rx_result
970ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, 969ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
971 struct ieee80211_rx_status *rx_status);
972struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, 970struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
973 u8 *bssid, u8 *addr, u32 supp_rates); 971 u8 *bssid, u8 *addr, u32 supp_rates);
974int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, 972int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
@@ -988,9 +986,7 @@ int ieee80211_scan_results(struct ieee80211_local *local,
988 char *buf, size_t len); 986 char *buf, size_t len);
989void ieee80211_scan_cancel(struct ieee80211_local *local); 987void ieee80211_scan_cancel(struct ieee80211_local *local);
990ieee80211_rx_result 988ieee80211_rx_result
991ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, 989ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
992 struct sk_buff *skb,
993 struct ieee80211_rx_status *rx_status);
994int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata, 990int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata,
995 const char *ie, size_t len); 991 const char *ie, size_t len);
996 992
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 092a017b237e..5b69f5f07299 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -330,19 +330,16 @@ static void ieee80211_tasklet_handler(unsigned long data)
330{ 330{
331 struct ieee80211_local *local = (struct ieee80211_local *) data; 331 struct ieee80211_local *local = (struct ieee80211_local *) data;
332 struct sk_buff *skb; 332 struct sk_buff *skb;
333 struct ieee80211_rx_status rx_status;
334 struct ieee80211_ra_tid *ra_tid; 333 struct ieee80211_ra_tid *ra_tid;
335 334
336 while ((skb = skb_dequeue(&local->skb_queue)) || 335 while ((skb = skb_dequeue(&local->skb_queue)) ||
337 (skb = skb_dequeue(&local->skb_queue_unreliable))) { 336 (skb = skb_dequeue(&local->skb_queue_unreliable))) {
338 switch (skb->pkt_type) { 337 switch (skb->pkt_type) {
339 case IEEE80211_RX_MSG: 338 case IEEE80211_RX_MSG:
340 /* status is in skb->cb */
341 memcpy(&rx_status, skb->cb, sizeof(rx_status));
342 /* Clear skb->pkt_type in order to not confuse kernel 339 /* Clear skb->pkt_type in order to not confuse kernel
343 * netstack. */ 340 * netstack. */
344 skb->pkt_type = 0; 341 skb->pkt_type = 0;
345 __ieee80211_rx(local_to_hw(local), skb, &rx_status); 342 ieee80211_rx(local_to_hw(local), skb);
346 break; 343 break;
347 case IEEE80211_TX_STATUS_MSG: 344 case IEEE80211_TX_STATUS_MSG:
348 skb->pkt_type = 0; 345 skb->pkt_type = 0;
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 11cf45bce38a..542ea025494e 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -568,7 +568,7 @@ static void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
568 568
569 ifmsh = &sdata->u.mesh; 569 ifmsh = &sdata->u.mesh;
570 570
571 rx_status = (struct ieee80211_rx_status *) skb->cb; 571 rx_status = IEEE80211_SKB_RXCB(skb);
572 mgmt = (struct ieee80211_mgmt *) skb->data; 572 mgmt = (struct ieee80211_mgmt *) skb->data;
573 stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; 573 stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
574 574
@@ -671,8 +671,7 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
671} 671}
672 672
673ieee80211_rx_result 673ieee80211_rx_result
674ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, 674ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
675 struct ieee80211_rx_status *rx_status)
676{ 675{
677 struct ieee80211_local *local = sdata->local; 676 struct ieee80211_local *local = sdata->local;
678 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 677 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,
689 case IEEE80211_STYPE_PROBE_RESP: 688 case IEEE80211_STYPE_PROBE_RESP:
690 case IEEE80211_STYPE_BEACON: 689 case IEEE80211_STYPE_BEACON:
691 case IEEE80211_STYPE_ACTION: 690 case IEEE80211_STYPE_ACTION:
692 memcpy(skb->cb, rx_status, sizeof(*rx_status));
693 skb_queue_tail(&ifmsh->skb_queue, skb); 691 skb_queue_tail(&ifmsh->skb_queue, skb);
694 queue_work(local->hw.workqueue, &ifmsh->work); 692 queue_work(local->hw.workqueue, &ifmsh->work);
695 return RX_QUEUED; 693 return RX_QUEUED;
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index c7d72819cdd2..2a2ed182cb7e 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -208,8 +208,7 @@ void ieee80211s_init(void);
208void ieee80211s_stop(void); 208void ieee80211s_stop(void);
209void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); 209void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata);
210ieee80211_rx_result 210ieee80211_rx_result
211ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, 211ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
212 struct ieee80211_rx_status *rx_status);
213void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); 212void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata);
214void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata); 213void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata);
215 214
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index aca22b00b6a3..5e25d320deae 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2063,8 +2063,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2063} 2063}
2064 2064
2065ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, 2065ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
2066 struct sk_buff *skb, 2066 struct sk_buff *skb)
2067 struct ieee80211_rx_status *rx_status)
2068{ 2067{
2069 struct ieee80211_local *local = sdata->local; 2068 struct ieee80211_local *local = sdata->local;
2070 struct ieee80211_mgmt *mgmt; 2069 struct ieee80211_mgmt *mgmt;
@@ -2080,7 +2079,6 @@ ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
2080 case IEEE80211_STYPE_PROBE_REQ: 2079 case IEEE80211_STYPE_PROBE_REQ:
2081 case IEEE80211_STYPE_PROBE_RESP: 2080 case IEEE80211_STYPE_PROBE_RESP:
2082 case IEEE80211_STYPE_BEACON: 2081 case IEEE80211_STYPE_BEACON:
2083 memcpy(skb->cb, rx_status, sizeof(*rx_status));
2084 case IEEE80211_STYPE_AUTH: 2082 case IEEE80211_STYPE_AUTH:
2085 case IEEE80211_STYPE_ASSOC_RESP: 2083 case IEEE80211_STYPE_ASSOC_RESP:
2086 case IEEE80211_STYPE_REASSOC_RESP: 2084 case IEEE80211_STYPE_REASSOC_RESP:
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index de5bba7f910a..0563b6969a21 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -30,7 +30,6 @@
30static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, 30static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
31 struct tid_ampdu_rx *tid_agg_rx, 31 struct tid_ampdu_rx *tid_agg_rx,
32 struct sk_buff *skb, 32 struct sk_buff *skb,
33 struct ieee80211_rx_status *status,
34 u16 mpdu_seq_num, 33 u16 mpdu_seq_num,
35 int bar_req); 34 int bar_req);
36/* 35/*
@@ -59,11 +58,11 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
59 return skb; 58 return skb;
60} 59}
61 60
62static inline int should_drop_frame(struct ieee80211_rx_status *status, 61static inline int should_drop_frame(struct sk_buff *skb,
63 struct sk_buff *skb,
64 int present_fcs_len, 62 int present_fcs_len,
65 int radiotap_len) 63 int radiotap_len)
66{ 64{
65 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
67 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 66 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
68 67
69 if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) 68 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,
111static void 110static void
112ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, 111ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
113 struct sk_buff *skb, 112 struct sk_buff *skb,
114 struct ieee80211_rx_status *status,
115 struct ieee80211_rate *rate, 113 struct ieee80211_rate *rate,
116 int rtap_len) 114 int rtap_len)
117{ 115{
116 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
118 struct ieee80211_radiotap_header *rthdr; 117 struct ieee80211_radiotap_header *rthdr;
119 unsigned char *pos; 118 unsigned char *pos;
120 119
@@ -220,9 +219,9 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
220 */ 219 */
221static struct sk_buff * 220static struct sk_buff *
222ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, 221ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
223 struct ieee80211_rx_status *status,
224 struct ieee80211_rate *rate) 222 struct ieee80211_rate *rate)
225{ 223{
224 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb);
226 struct ieee80211_sub_if_data *sdata; 225 struct ieee80211_sub_if_data *sdata;
227 int needed_headroom = 0; 226 int needed_headroom = 0;
228 struct sk_buff *skb, *skb2; 227 struct sk_buff *skb, *skb2;
@@ -248,8 +247,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
248 present_fcs_len = FCS_LEN; 247 present_fcs_len = FCS_LEN;
249 248
250 if (!local->monitors) { 249 if (!local->monitors) {
251 if (should_drop_frame(status, origskb, present_fcs_len, 250 if (should_drop_frame(origskb, present_fcs_len, rtap_len)) {
252 rtap_len)) {
253 dev_kfree_skb(origskb); 251 dev_kfree_skb(origskb);
254 return NULL; 252 return NULL;
255 } 253 }
@@ -257,7 +255,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
257 return remove_monitor_info(local, origskb, rtap_len); 255 return remove_monitor_info(local, origskb, rtap_len);
258 } 256 }
259 257
260 if (should_drop_frame(status, origskb, present_fcs_len, rtap_len)) { 258 if (should_drop_frame(origskb, present_fcs_len, rtap_len)) {
261 /* only need to expand headroom if necessary */ 259 /* only need to expand headroom if necessary */
262 skb = origskb; 260 skb = origskb;
263 origskb = NULL; 261 origskb = NULL;
@@ -289,7 +287,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
289 287
290 /* if necessary, prepend radiotap information */ 288 /* if necessary, prepend radiotap information */
291 if (!(status->flag & RX_FLAG_RADIOTAP)) 289 if (!(status->flag & RX_FLAG_RADIOTAP))
292 ieee80211_add_rx_radiotap_header(local, skb, status, rate, 290 ieee80211_add_rx_radiotap_header(local, skb, rate,
293 needed_headroom); 291 needed_headroom);
294 292
295 skb_reset_mac_header(skb); 293 skb_reset_mac_header(skb);
@@ -421,12 +419,11 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
421 struct sk_buff *skb = rx->skb; 419 struct sk_buff *skb = rx->skb;
422 420
423 if (unlikely(local->hw_scanning)) 421 if (unlikely(local->hw_scanning))
424 return ieee80211_scan_rx(rx->sdata, skb, rx->status); 422 return ieee80211_scan_rx(rx->sdata, skb);
425 423
426 if (unlikely(local->sw_scanning)) { 424 if (unlikely(local->sw_scanning)) {
427 /* drop all the other packets during a software scan anyway */ 425 /* drop all the other packets during a software scan anyway */
428 if (ieee80211_scan_rx(rx->sdata, skb, rx->status) 426 if (ieee80211_scan_rx(rx->sdata, skb) != RX_QUEUED)
429 != RX_QUEUED)
430 dev_kfree_skb(skb); 427 dev_kfree_skb(skb);
431 return RX_QUEUED; 428 return RX_QUEUED;
432 } 429 }
@@ -1620,7 +1617,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx)
1620 /* manage reordering buffer according to requested */ 1617 /* manage reordering buffer according to requested */
1621 /* sequence number */ 1618 /* sequence number */
1622 rcu_read_lock(); 1619 rcu_read_lock();
1623 ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, NULL, NULL, 1620 ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, NULL,
1624 start_seq_num, 1); 1621 start_seq_num, 1);
1625 rcu_read_unlock(); 1622 rcu_read_unlock();
1626 return RX_DROP_UNUSABLE; 1623 return RX_DROP_UNUSABLE;
@@ -1817,13 +1814,13 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
1817 return RX_DROP_MONITOR; 1814 return RX_DROP_MONITOR;
1818 1815
1819 if (ieee80211_vif_is_mesh(&sdata->vif)) 1816 if (ieee80211_vif_is_mesh(&sdata->vif))
1820 return ieee80211_mesh_rx_mgmt(sdata, rx->skb, rx->status); 1817 return ieee80211_mesh_rx_mgmt(sdata, rx->skb);
1821 1818
1822 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 1819 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
1823 return ieee80211_ibss_rx_mgmt(sdata, rx->skb, rx->status); 1820 return ieee80211_ibss_rx_mgmt(sdata, rx->skb);
1824 1821
1825 if (sdata->vif.type == NL80211_IFTYPE_STATION) 1822 if (sdata->vif.type == NL80211_IFTYPE_STATION)
1826 return ieee80211_sta_rx_mgmt(sdata, rx->skb, rx->status); 1823 return ieee80211_sta_rx_mgmt(sdata, rx->skb);
1827 1824
1828 return RX_DROP_MONITOR; 1825 return RX_DROP_MONITOR;
1829} 1826}
@@ -2114,9 +2111,9 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
2114 */ 2111 */
2115static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, 2112static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2116 struct sk_buff *skb, 2113 struct sk_buff *skb,
2117 struct ieee80211_rx_status *status,
2118 struct ieee80211_rate *rate) 2114 struct ieee80211_rate *rate)
2119{ 2115{
2116 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
2120 struct ieee80211_local *local = hw_to_local(hw); 2117 struct ieee80211_local *local = hw_to_local(hw);
2121 struct ieee80211_sub_if_data *sdata; 2118 struct ieee80211_sub_if_data *sdata;
2122 struct ieee80211_hdr *hdr; 2119 struct ieee80211_hdr *hdr;
@@ -2227,20 +2224,21 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
2227{ 2224{
2228 struct ieee80211_supported_band *sband; 2225 struct ieee80211_supported_band *sband;
2229 struct ieee80211_rate *rate; 2226 struct ieee80211_rate *rate;
2230 struct ieee80211_rx_status status; 2227 struct sk_buff *skb = tid_agg_rx->reorder_buf[index];
2228 struct ieee80211_rx_status *status;
2231 2229
2232 if (!tid_agg_rx->reorder_buf[index]) 2230 if (!skb)
2233 goto no_frame; 2231 goto no_frame;
2234 2232
2233 status = IEEE80211_SKB_RXCB(skb);
2234
2235 /* release the reordered frames to stack */ 2235 /* release the reordered frames to stack */
2236 memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, sizeof(status)); 2236 sband = hw->wiphy->bands[status->band];
2237 sband = hw->wiphy->bands[status.band]; 2237 if (status->flag & RX_FLAG_HT)
2238 if (status.flag & RX_FLAG_HT)
2239 rate = sband->bitrates; /* TODO: HT rates */ 2238 rate = sband->bitrates; /* TODO: HT rates */
2240 else 2239 else
2241 rate = &sband->bitrates[status.rate_idx]; 2240 rate = &sband->bitrates[status->rate_idx];
2242 __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], 2241 __ieee80211_rx_handle_packet(hw, skb, rate);
2243 &status, rate);
2244 tid_agg_rx->stored_mpdu_num--; 2242 tid_agg_rx->stored_mpdu_num--;
2245 tid_agg_rx->reorder_buf[index] = NULL; 2243 tid_agg_rx->reorder_buf[index] = NULL;
2246 2244
@@ -2265,7 +2263,6 @@ no_frame:
2265static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, 2263static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
2266 struct tid_ampdu_rx *tid_agg_rx, 2264 struct tid_ampdu_rx *tid_agg_rx,
2267 struct sk_buff *skb, 2265 struct sk_buff *skb,
2268 struct ieee80211_rx_status *rxstatus,
2269 u16 mpdu_seq_num, 2266 u16 mpdu_seq_num,
2270 int bar_req) 2267 int bar_req)
2271{ 2268{
@@ -2324,8 +2321,6 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
2324 /* put the frame in the reordering buffer */ 2321 /* put the frame in the reordering buffer */
2325 tid_agg_rx->reorder_buf[index] = skb; 2322 tid_agg_rx->reorder_buf[index] = skb;
2326 tid_agg_rx->reorder_time[index] = jiffies; 2323 tid_agg_rx->reorder_time[index] = jiffies;
2327 memcpy(tid_agg_rx->reorder_buf[index]->cb, rxstatus,
2328 sizeof(*rxstatus));
2329 tid_agg_rx->stored_mpdu_num++; 2324 tid_agg_rx->stored_mpdu_num++;
2330 /* release the buffer until next missing frame */ 2325 /* release the buffer until next missing frame */
2331 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) 2326 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,
2374} 2369}
2375 2370
2376static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, 2371static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
2377 struct sk_buff *skb, 2372 struct sk_buff *skb)
2378 struct ieee80211_rx_status *status)
2379{ 2373{
2380 struct ieee80211_hw *hw = &local->hw; 2374 struct ieee80211_hw *hw = &local->hw;
2381 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 2375 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
@@ -2424,7 +2418,7 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
2424 2418
2425 /* according to mpdu sequence number deal with reordering buffer */ 2419 /* according to mpdu sequence number deal with reordering buffer */
2426 mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4; 2420 mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4;
2427 ret = ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, status, 2421 ret = ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb,
2428 mpdu_seq_num, 0); 2422 mpdu_seq_num, 0);
2429 end_reorder: 2423 end_reorder:
2430 return ret; 2424 return ret;
@@ -2434,12 +2428,12 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
2434 * This is the receive path handler. It is called by a low level driver when an 2428 * This is the receive path handler. It is called by a low level driver when an
2435 * 802.11 MPDU is received from the hardware. 2429 * 802.11 MPDU is received from the hardware.
2436 */ 2430 */
2437void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, 2431void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
2438 struct ieee80211_rx_status *status)
2439{ 2432{
2440 struct ieee80211_local *local = hw_to_local(hw); 2433 struct ieee80211_local *local = hw_to_local(hw);
2441 struct ieee80211_rate *rate = NULL; 2434 struct ieee80211_rate *rate = NULL;
2442 struct ieee80211_supported_band *sband; 2435 struct ieee80211_supported_band *sband;
2436 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
2443 2437
2444 if (status->band < 0 || 2438 if (status->band < 0 ||
2445 status->band >= IEEE80211_NUM_BANDS) { 2439 status->band >= IEEE80211_NUM_BANDS) {
@@ -2482,7 +2476,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
2482 * if it was previously present. 2476 * if it was previously present.
2483 * Also, frames with less than 16 bytes are dropped. 2477 * Also, frames with less than 16 bytes are dropped.
2484 */ 2478 */
2485 skb = ieee80211_rx_monitor(local, skb, status, rate); 2479 skb = ieee80211_rx_monitor(local, skb, rate);
2486 if (!skb) { 2480 if (!skb) {
2487 rcu_read_unlock(); 2481 rcu_read_unlock();
2488 return; 2482 return;
@@ -2500,8 +2494,8 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
2500 * frames from other than operational channel), but that should not 2494 * frames from other than operational channel), but that should not
2501 * happen in normal networks. 2495 * happen in normal networks.
2502 */ 2496 */
2503 if (!ieee80211_rx_reorder_ampdu(local, skb, status)) 2497 if (!ieee80211_rx_reorder_ampdu(local, skb))
2504 __ieee80211_rx_handle_packet(hw, skb, status, rate); 2498 __ieee80211_rx_handle_packet(hw, skb, rate);
2505 2499
2506 rcu_read_unlock(); 2500 rcu_read_unlock();
2507} 2501}
@@ -2509,16 +2503,13 @@ EXPORT_SYMBOL(__ieee80211_rx);
2509 2503
2510/* This is a version of the rx handler that can be called from hard irq 2504/* This is a version of the rx handler that can be called from hard irq
2511 * context. Post the skb on the queue and schedule the tasklet */ 2505 * context. Post the skb on the queue and schedule the tasklet */
2512void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb, 2506void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb)
2513 struct ieee80211_rx_status *status)
2514{ 2507{
2515 struct ieee80211_local *local = hw_to_local(hw); 2508 struct ieee80211_local *local = hw_to_local(hw);
2516 2509
2517 BUILD_BUG_ON(sizeof(struct ieee80211_rx_status) > sizeof(skb->cb)); 2510 BUILD_BUG_ON(sizeof(struct ieee80211_rx_status) > sizeof(skb->cb));
2518 2511
2519 skb->dev = local->mdev; 2512 skb->dev = local->mdev;
2520 /* copy status into skb->cb for use by tasklet */
2521 memcpy(skb->cb, status, sizeof(*status));
2522 skb->pkt_type = IEEE80211_RX_MSG; 2513 skb->pkt_type = IEEE80211_RX_MSG;
2523 skb_queue_tail(&local->skb_queue, skb); 2514 skb_queue_tail(&local->skb_queue, skb);
2524 tasklet_schedule(&local->tasklet); 2515 tasklet_schedule(&local->tasklet);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 2a8d09ad17ff..8b2416c77a6e 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -135,9 +135,9 @@ void ieee80211_rx_bss_remove(struct ieee80211_sub_if_data *sdata, u8 *bssid,
135} 135}
136 136
137ieee80211_rx_result 137ieee80211_rx_result
138ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, 138ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
139 struct ieee80211_rx_status *rx_status)
140{ 139{
140 struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
141 struct ieee80211_mgmt *mgmt; 141 struct ieee80211_mgmt *mgmt;
142 struct ieee80211_bss *bss; 142 struct ieee80211_bss *bss;
143 u8 *elements; 143 u8 *elements;