aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorRon Rindjunsky <ron.rindjunsky@intel.com>2007-12-24 06:36:39 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:00:57 -0500
commit6368e4b18d5c71c73eecd96d568e726b80e5bce1 (patch)
treee12388f4ed3c506e085694a179855302c5fc2674 /net/mac80211/rx.c
parentf704662fb7cd81bfdc441207e788860ae4685e95 (diff)
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>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c86
1 files changed, 50 insertions, 36 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 306e6fc25d8f..a58a94b21401 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -288,11 +288,11 @@ ieee80211_rx_h_parse_qos(struct ieee80211_txrx_data *rx)
288 return TXRX_CONTINUE; 288 return TXRX_CONTINUE;
289} 289}
290 290
291static ieee80211_txrx_result 291
292ieee80211_rx_h_load_stats(struct ieee80211_txrx_data *rx) 292u32 ieee80211_rx_load_stats(struct ieee80211_local *local,
293 struct sk_buff *skb,
294 struct ieee80211_rx_status *status)
293{ 295{
294 struct ieee80211_local *local = rx->local;
295 struct sk_buff *skb = rx->skb;
296 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 296 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
297 u32 load = 0, hdrtime; 297 u32 load = 0, hdrtime;
298 struct ieee80211_rate *rate; 298 struct ieee80211_rate *rate;
@@ -306,7 +306,7 @@ ieee80211_rx_h_load_stats(struct ieee80211_txrx_data *rx)
306 306
307 rate = &mode->rates[0]; 307 rate = &mode->rates[0];
308 for (i = 0; i < mode->num_rates; i++) { 308 for (i = 0; i < mode->num_rates; i++) {
309 if (mode->rates[i].val == rx->u.rx.status->rate) { 309 if (mode->rates[i].val == status->rate) {
310 rate = &mode->rates[i]; 310 rate = &mode->rates[i];
311 break; 311 break;
312 } 312 }
@@ -331,15 +331,13 @@ ieee80211_rx_h_load_stats(struct ieee80211_txrx_data *rx)
331 /* Divide channel_use by 8 to avoid wrapping around the counter */ 331 /* Divide channel_use by 8 to avoid wrapping around the counter */
332 load >>= CHAN_UTIL_SHIFT; 332 load >>= CHAN_UTIL_SHIFT;
333 local->channel_use_raw += load; 333 local->channel_use_raw += load;
334 rx->u.rx.load = load;
335 334
336 return TXRX_CONTINUE; 335 return load;
337} 336}
338 337
339ieee80211_rx_handler ieee80211_rx_pre_handlers[] = 338ieee80211_rx_handler ieee80211_rx_pre_handlers[] =
340{ 339{
341 ieee80211_rx_h_parse_qos, 340 ieee80211_rx_h_parse_qos,
342 ieee80211_rx_h_load_stats,
343 NULL 341 NULL
344}; 342};
345 343
@@ -1613,11 +1611,11 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
1613} 1611}
1614 1612
1615/* 1613/*
1616 * This is the receive path handler. It is called by a low level driver when an 1614 * This is the actual Rx frames handler. as it blongs to Rx path it must
1617 * 802.11 MPDU is received from the hardware. 1615 * be called with rcu_read_lock protection.
1618 */ 1616 */
1619void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, 1617void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, struct sk_buff *skb,
1620 struct ieee80211_rx_status *status) 1618 struct ieee80211_rx_status *status, u32 load)
1621{ 1619{
1622 struct ieee80211_local *local = hw_to_local(hw); 1620 struct ieee80211_local *local = hw_to_local(hw);
1623 struct ieee80211_sub_if_data *sdata; 1621 struct ieee80211_sub_if_data *sdata;
@@ -1625,37 +1623,19 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
1625 struct ieee80211_hdr *hdr; 1623 struct ieee80211_hdr *hdr;
1626 struct ieee80211_txrx_data rx; 1624 struct ieee80211_txrx_data rx;
1627 u16 type; 1625 u16 type;
1628 int prepres; 1626 int prepares;
1629 struct ieee80211_sub_if_data *prev = NULL; 1627 struct ieee80211_sub_if_data *prev = NULL;
1630 struct sk_buff *skb_new; 1628 struct sk_buff *skb_new;
1631 u8 *bssid; 1629 u8 *bssid;
1632 int hdrlen; 1630 int hdrlen;
1633 1631
1634 /*
1635 * key references and virtual interfaces are protected using RCU
1636 * and this requires that we are in a read-side RCU section during
1637 * receive processing
1638 */
1639 rcu_read_lock();
1640
1641 /*
1642 * Frames with failed FCS/PLCP checksum are not returned,
1643 * all other frames are returned without radiotap header
1644 * if it was previously present.
1645 * Also, frames with less than 16 bytes are dropped.
1646 */
1647 skb = ieee80211_rx_monitor(local, skb, status);
1648 if (!skb) {
1649 rcu_read_unlock();
1650 return;
1651 }
1652
1653 hdr = (struct ieee80211_hdr *) skb->data; 1632 hdr = (struct ieee80211_hdr *) skb->data;
1654 memset(&rx, 0, sizeof(rx)); 1633 memset(&rx, 0, sizeof(rx));
1655 rx.skb = skb; 1634 rx.skb = skb;
1656 rx.local = local; 1635 rx.local = local;
1657 1636
1658 rx.u.rx.status = status; 1637 rx.u.rx.status = status;
1638 rx.u.rx.load = load;
1659 rx.fc = le16_to_cpu(hdr->frame_control); 1639 rx.fc = le16_to_cpu(hdr->frame_control);
1660 type = rx.fc & IEEE80211_FCTL_FTYPE; 1640 type = rx.fc & IEEE80211_FCTL_FTYPE;
1661 1641
@@ -1714,11 +1694,11 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
1714 continue; 1694 continue;
1715 1695
1716 rx.flags |= IEEE80211_TXRXD_RXRA_MATCH; 1696 rx.flags |= IEEE80211_TXRXD_RXRA_MATCH;
1717 prepres = prepare_for_handlers(sdata, bssid, &rx, hdr); 1697 prepares = prepare_for_handlers(sdata, bssid, &rx, hdr);
1718 /* prepare_for_handlers can change sta */ 1698 /* prepare_for_handlers can change sta */
1719 sta = rx.sta; 1699 sta = rx.sta;
1720 1700
1721 if (!prepres) 1701 if (!prepares)
1722 continue; 1702 continue;
1723 1703
1724 /* 1704 /*
@@ -1765,11 +1745,45 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
1765 dev_kfree_skb(skb); 1745 dev_kfree_skb(skb);
1766 1746
1767 end: 1747 end:
1768 rcu_read_unlock();
1769
1770 if (sta) 1748 if (sta)
1771 sta_info_put(sta); 1749 sta_info_put(sta);
1772} 1750}
1751
1752/*
1753 * This is the receive path handler. It is called by a low level driver when an
1754 * 802.11 MPDU is received from the hardware.
1755 */
1756void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
1757 struct ieee80211_rx_status *status)
1758{
1759 struct ieee80211_local *local = hw_to_local(hw);
1760 u32 pkt_load;
1761
1762 /*
1763 * key references and virtual interfaces are protected using RCU
1764 * and this requires that we are in a read-side RCU section during
1765 * receive processing
1766 */
1767 rcu_read_lock();
1768
1769 /*
1770 * Frames with failed FCS/PLCP checksum are not returned,
1771 * all other frames are returned without radiotap header
1772 * if it was previously present.
1773 * Also, frames with less than 16 bytes are dropped.
1774 */
1775 skb = ieee80211_rx_monitor(local, skb, status);
1776 if (!skb) {
1777 rcu_read_unlock();
1778 return;
1779 }
1780
1781 pkt_load = ieee80211_rx_load_stats(local, skb, status);
1782
1783 __ieee80211_rx_handle_packet(hw, skb, status, pkt_load);
1784
1785 rcu_read_unlock();
1786}
1773EXPORT_SYMBOL(__ieee80211_rx); 1787EXPORT_SYMBOL(__ieee80211_rx);
1774 1788
1775/* This is a version of the rx handler that can be called from hard irq 1789/* This is a version of the rx handler that can be called from hard irq