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:
Ron Rindjunsky 2007-12-24 13:36:39 +02:00 committed by David S. Miller
parent f704662fb7
commit 6368e4b18d

View File

@ -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