Commit f1d58c25 authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

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: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 18ad01c4
......@@ -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;
......
......@@ -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;
......
......@@ -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)
......
......@@ -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;
......
......@@ -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);
}
}
......
......@@ -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:
......
......@@ -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:
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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);
......
......@@ -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++;
}
......
......@@ -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));
......
......@@ -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.
......
......@@ -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;
......
......@@ -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)) {
......
......@@ -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)
......
......@@ -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;
}
......
......@@ -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++);
......
......@@ -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;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment