Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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;
+2 −1
Original line number Diff line number Diff line
@@ -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;
+4 −2
Original line number Diff line number Diff line
@@ -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)
+2 −1
Original line number Diff line number Diff line
@@ -1905,7 +1905,8 @@ ath5k_tasklet_rx(unsigned long data)
		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;
+9 −4
Original line number Diff line number Diff line
@@ -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);
	}
}

Loading