forked from Minki/linux
mac80211: restructure __ieee80211_rx
This patch makes a separation between Rx frame pre-handling which stays in __ieee80211_rx and Rx frame handlers, moving to __ieee80211_rx_handle_packet. Although this separation has no affect in regular mode of operation, this kind of mechanism will be used in A-MPDU frames reordering as it allows accumulation of frames during pre-handling, dispatching them to later handling when necessary. Signed-off-by: Ron Rindjunsky <ron.rindjunsky@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
f704662fb7
commit
6368e4b18d
@ -288,11 +288,11 @@ ieee80211_rx_h_parse_qos(struct ieee80211_txrx_data *rx)
|
|||||||
return TXRX_CONTINUE;
|
return TXRX_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ieee80211_txrx_result
|
|
||||||
ieee80211_rx_h_load_stats(struct ieee80211_txrx_data *rx)
|
u32 ieee80211_rx_load_stats(struct ieee80211_local *local,
|
||||||
|
struct sk_buff *skb,
|
||||||
|
struct ieee80211_rx_status *status)
|
||||||
{
|
{
|
||||||
struct ieee80211_local *local = rx->local;
|
|
||||||
struct sk_buff *skb = rx->skb;
|
|
||||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
||||||
u32 load = 0, hdrtime;
|
u32 load = 0, hdrtime;
|
||||||
struct ieee80211_rate *rate;
|
struct ieee80211_rate *rate;
|
||||||
@ -306,7 +306,7 @@ ieee80211_rx_h_load_stats(struct ieee80211_txrx_data *rx)
|
|||||||
|
|
||||||
rate = &mode->rates[0];
|
rate = &mode->rates[0];
|
||||||
for (i = 0; i < mode->num_rates; i++) {
|
for (i = 0; i < mode->num_rates; i++) {
|
||||||
if (mode->rates[i].val == rx->u.rx.status->rate) {
|
if (mode->rates[i].val == status->rate) {
|
||||||
rate = &mode->rates[i];
|
rate = &mode->rates[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -331,15 +331,13 @@ ieee80211_rx_h_load_stats(struct ieee80211_txrx_data *rx)
|
|||||||
/* Divide channel_use by 8 to avoid wrapping around the counter */
|
/* Divide channel_use by 8 to avoid wrapping around the counter */
|
||||||
load >>= CHAN_UTIL_SHIFT;
|
load >>= CHAN_UTIL_SHIFT;
|
||||||
local->channel_use_raw += load;
|
local->channel_use_raw += load;
|
||||||
rx->u.rx.load = load;
|
|
||||||
|
|
||||||
return TXRX_CONTINUE;
|
return load;
|
||||||
}
|
}
|
||||||
|
|
||||||
ieee80211_rx_handler ieee80211_rx_pre_handlers[] =
|
ieee80211_rx_handler ieee80211_rx_pre_handlers[] =
|
||||||
{
|
{
|
||||||
ieee80211_rx_h_parse_qos,
|
ieee80211_rx_h_parse_qos,
|
||||||
ieee80211_rx_h_load_stats,
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1613,11 +1611,11 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the receive path handler. It is called by a low level driver when an
|
* This is the actual Rx frames handler. as it blongs to Rx path it must
|
||||||
* 802.11 MPDU is received from the hardware.
|
* be called with rcu_read_lock protection.
|
||||||
*/
|
*/
|
||||||
void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
|
void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||||
struct ieee80211_rx_status *status)
|
struct ieee80211_rx_status *status, u32 load)
|
||||||
{
|
{
|
||||||
struct ieee80211_local *local = hw_to_local(hw);
|
struct ieee80211_local *local = hw_to_local(hw);
|
||||||
struct ieee80211_sub_if_data *sdata;
|
struct ieee80211_sub_if_data *sdata;
|
||||||
@ -1625,37 +1623,19 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
|
|||||||
struct ieee80211_hdr *hdr;
|
struct ieee80211_hdr *hdr;
|
||||||
struct ieee80211_txrx_data rx;
|
struct ieee80211_txrx_data rx;
|
||||||
u16 type;
|
u16 type;
|
||||||
int prepres;
|
int prepares;
|
||||||
struct ieee80211_sub_if_data *prev = NULL;
|
struct ieee80211_sub_if_data *prev = NULL;
|
||||||
struct sk_buff *skb_new;
|
struct sk_buff *skb_new;
|
||||||
u8 *bssid;
|
u8 *bssid;
|
||||||
int hdrlen;
|
int hdrlen;
|
||||||
|
|
||||||
/*
|
|
||||||
* key references and virtual interfaces are protected using RCU
|
|
||||||
* and this requires that we are in a read-side RCU section during
|
|
||||||
* receive processing
|
|
||||||
*/
|
|
||||||
rcu_read_lock();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Frames with failed FCS/PLCP checksum are not returned,
|
|
||||||
* all other frames are returned without radiotap header
|
|
||||||
* if it was previously present.
|
|
||||||
* Also, frames with less than 16 bytes are dropped.
|
|
||||||
*/
|
|
||||||
skb = ieee80211_rx_monitor(local, skb, status);
|
|
||||||
if (!skb) {
|
|
||||||
rcu_read_unlock();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hdr = (struct ieee80211_hdr *) skb->data;
|
hdr = (struct ieee80211_hdr *) skb->data;
|
||||||
memset(&rx, 0, sizeof(rx));
|
memset(&rx, 0, sizeof(rx));
|
||||||
rx.skb = skb;
|
rx.skb = skb;
|
||||||
rx.local = local;
|
rx.local = local;
|
||||||
|
|
||||||
rx.u.rx.status = status;
|
rx.u.rx.status = status;
|
||||||
|
rx.u.rx.load = load;
|
||||||
rx.fc = le16_to_cpu(hdr->frame_control);
|
rx.fc = le16_to_cpu(hdr->frame_control);
|
||||||
type = rx.fc & IEEE80211_FCTL_FTYPE;
|
type = rx.fc & IEEE80211_FCTL_FTYPE;
|
||||||
|
|
||||||
@ -1714,11 +1694,11 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
rx.flags |= IEEE80211_TXRXD_RXRA_MATCH;
|
rx.flags |= IEEE80211_TXRXD_RXRA_MATCH;
|
||||||
prepres = prepare_for_handlers(sdata, bssid, &rx, hdr);
|
prepares = prepare_for_handlers(sdata, bssid, &rx, hdr);
|
||||||
/* prepare_for_handlers can change sta */
|
/* prepare_for_handlers can change sta */
|
||||||
sta = rx.sta;
|
sta = rx.sta;
|
||||||
|
|
||||||
if (!prepres)
|
if (!prepares)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1765,11 +1745,45 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
|
|||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
if (sta)
|
if (sta)
|
||||||
sta_info_put(sta);
|
sta_info_put(sta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
struct ieee80211_local *local = hw_to_local(hw);
|
||||||
|
u32 pkt_load;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* key references and virtual interfaces are protected using RCU
|
||||||
|
* and this requires that we are in a read-side RCU section during
|
||||||
|
* receive processing
|
||||||
|
*/
|
||||||
|
rcu_read_lock();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Frames with failed FCS/PLCP checksum are not returned,
|
||||||
|
* all other frames are returned without radiotap header
|
||||||
|
* if it was previously present.
|
||||||
|
* Also, frames with less than 16 bytes are dropped.
|
||||||
|
*/
|
||||||
|
skb = ieee80211_rx_monitor(local, skb, status);
|
||||||
|
if (!skb) {
|
||||||
|
rcu_read_unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pkt_load = ieee80211_rx_load_stats(local, skb, status);
|
||||||
|
|
||||||
|
__ieee80211_rx_handle_packet(hw, skb, status, pkt_load);
|
||||||
|
|
||||||
|
rcu_read_unlock();
|
||||||
|
}
|
||||||
EXPORT_SYMBOL(__ieee80211_rx);
|
EXPORT_SYMBOL(__ieee80211_rx);
|
||||||
|
|
||||||
/* This is a version of the rx handler that can be called from hard irq
|
/* This is a version of the rx handler that can be called from hard irq
|
||||||
|
Loading…
Reference in New Issue
Block a user