diff options
author | Ron Rindjunsky <ron.rindjunsky@intel.com> | 2007-12-24 06:36:39 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:00:57 -0500 |
commit | 6368e4b18d5c71c73eecd96d568e726b80e5bce1 (patch) | |
tree | e12388f4ed3c506e085694a179855302c5fc2674 | |
parent | f704662fb7cd81bfdc441207e788860ae4685e95 (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>
-rw-r--r-- | net/mac80211/rx.c | 86 |
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 | ||
291 | static ieee80211_txrx_result | 291 | |
292 | ieee80211_rx_h_load_stats(struct ieee80211_txrx_data *rx) | 292 | u32 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 | ||
339 | ieee80211_rx_handler ieee80211_rx_pre_handlers[] = | 338 | ieee80211_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 | */ |
1619 | void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | 1617 | void __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 | */ | ||
1756 | void __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 | } | ||
1773 | EXPORT_SYMBOL(__ieee80211_rx); | 1787 | EXPORT_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 |