Commit 6c4a5f24 authored by Christian Lamparter's avatar Christian Lamparter Committed by John W. Linville
Browse files

carl9170: split up carl9170_handle_mpdu

carl9170_handle_mpdu is the final part of the
rx path of the driver. It splits the raw data
streams from the device into skb packets and
passes them on to mac80211. As a result of
continuous updates, it grew over the years when
new code was added by the following commits:
	- report A-MPDU status
	- fix HT peer BA session corruption
	- A-MPDU frame type filter
	- ...

This patch splits the routine into two stages.
The first stage only deals with the details
about extracting and verifying the data from
the incoming stream. Whereas the second stage
packs it into skbs and passes it on to mac80211.
Reported-by: default avatarJavier Lopez <>
Signed-off-by: default avatarChristian Lamparter <>
Signed-off-by: default avatarJohn W. Linville <>
parent f3b369e4
......@@ -660,6 +660,35 @@ static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms,
return false;
static int carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len,
struct ieee80211_rx_status *status)
struct sk_buff *skb;
/* (driver) frame trap handler
* Because power-saving mode handing has to be implemented by
* the driver/firmware. We have to check each incoming beacon
* from the associated AP, if there's new data for us (either
* broadcast/multicast or unicast) we have to react quickly.
* So, if you have you want to add additional frame trap
* handlers, this would be the perfect place!
carl9170_ps_beacon(ar, buf, len);
carl9170_ba_check(ar, buf, len);
skb = carl9170_rx_copy_data(buf, len);
if (!skb)
return -ENOMEM;
memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
ieee80211_rx(ar->hw, skb);
return 0;
* If the frame alignment is right (or the kernel has
......@@ -669,14 +698,12 @@ static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms,
* mode, and we need to observe the proper ordering,
* this is non-trivial.
static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
static void carl9170_rx_untie_data(struct ar9170 *ar, u8 *buf, int len)
struct ar9170_rx_head *head;
struct ar9170_rx_macstatus *mac;
struct ar9170_rx_phystatus *phy = NULL;
struct ieee80211_rx_status status;
struct sk_buff *skb;
int mpdu_len;
u8 mac_status;
......@@ -788,18 +815,10 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
if (phy)
carl9170_rx_phy_status(ar, phy, &status);
carl9170_ps_beacon(ar, buf, mpdu_len);
carl9170_ba_check(ar, buf, mpdu_len);
skb = carl9170_rx_copy_data(buf, mpdu_len);
if (!skb)
if (carl9170_handle_mpdu(ar, buf, mpdu_len, &status))
goto drop;
memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
ieee80211_rx(ar->hw, skb);
......@@ -851,7 +870,7 @@ static void __carl9170_rx(struct ar9170 *ar, u8 *buf, unsigned int len)
if (i == 12)
carl9170_rx_untie_cmds(ar, buf, len);
carl9170_handle_mpdu(ar, buf, len);
carl9170_rx_untie_data(ar, buf, len);
static void carl9170_rx_stream(struct ar9170 *ar, void *buf, unsigned int len)
Supports Markdown
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