aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-06-30 09:10:45 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-07-02 15:48:33 -0400
commit49461622edf74cd1e1a1056cee3ca8dd90cd9556 (patch)
tree201add958aa18af22b88b6ddfb93df841213b1fb
parentd9e8a70fa20dc3eaa00859a6eac0adfaef910c77 (diff)
mac80211: get rid of function pointers in RX path
This changes the RX path to no longer use function pointers for RX handlers but rather invoke them directly. If debugging is enabled, mark the RX handlers noinline because otherwise they all get inlined into ieee80211_invoke_rx_handlers() which makes it harder to see where a bug is. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/mac80211/rx.c97
1 files changed, 44 insertions, 53 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 8962d1355f04..289112777e90 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -386,7 +386,7 @@ static void ieee80211_verify_ip_alignment(struct ieee80211_rx_data *rx)
386 386
387/* rx handlers */ 387/* rx handlers */
388 388
389static ieee80211_rx_result 389static ieee80211_rx_result debug_noinline
390ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) 390ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
391{ 391{
392 struct ieee80211_local *local = rx->local; 392 struct ieee80211_local *local = rx->local;
@@ -463,7 +463,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
463} 463}
464 464
465 465
466static ieee80211_rx_result 466static ieee80211_rx_result debug_noinline
467ieee80211_rx_h_check(struct ieee80211_rx_data *rx) 467ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
468{ 468{
469 struct ieee80211_hdr *hdr; 469 struct ieee80211_hdr *hdr;
@@ -522,7 +522,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
522} 522}
523 523
524 524
525static ieee80211_rx_result 525static ieee80211_rx_result debug_noinline
526ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) 526ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
527{ 527{
528 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; 528 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
@@ -710,7 +710,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
710 return sent; 710 return sent;
711} 711}
712 712
713static ieee80211_rx_result 713static ieee80211_rx_result debug_noinline
714ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) 714ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
715{ 715{
716 struct sta_info *sta = rx->sta; 716 struct sta_info *sta = rx->sta;
@@ -858,7 +858,7 @@ ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata,
858 return NULL; 858 return NULL;
859} 859}
860 860
861static ieee80211_rx_result 861static ieee80211_rx_result debug_noinline
862ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) 862ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
863{ 863{
864 struct ieee80211_hdr *hdr; 864 struct ieee80211_hdr *hdr;
@@ -974,7 +974,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
974 return RX_CONTINUE; 974 return RX_CONTINUE;
975} 975}
976 976
977static ieee80211_rx_result 977static ieee80211_rx_result debug_noinline
978ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) 978ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
979{ 979{
980 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); 980 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
@@ -1049,7 +1049,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
1049 return RX_QUEUED; 1049 return RX_QUEUED;
1050} 1050}
1051 1051
1052static ieee80211_rx_result 1052static ieee80211_rx_result debug_noinline
1053ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx) 1053ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx)
1054{ 1054{
1055 u16 fc = rx->fc; 1055 u16 fc = rx->fc;
@@ -1367,7 +1367,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
1367 } 1367 }
1368} 1368}
1369 1369
1370static ieee80211_rx_result 1370static ieee80211_rx_result debug_noinline
1371ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) 1371ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
1372{ 1372{
1373 struct net_device *dev = rx->dev; 1373 struct net_device *dev = rx->dev;
@@ -1484,7 +1484,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
1484 return RX_QUEUED; 1484 return RX_QUEUED;
1485} 1485}
1486 1486
1487static ieee80211_rx_result 1487static ieee80211_rx_result debug_noinline
1488ieee80211_rx_h_data(struct ieee80211_rx_data *rx) 1488ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
1489{ 1489{
1490 struct net_device *dev = rx->dev; 1490 struct net_device *dev = rx->dev;
@@ -1515,7 +1515,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
1515 return RX_QUEUED; 1515 return RX_QUEUED;
1516} 1516}
1517 1517
1518static ieee80211_rx_result 1518static ieee80211_rx_result debug_noinline
1519ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) 1519ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx)
1520{ 1520{
1521 struct ieee80211_local *local = rx->local; 1521 struct ieee80211_local *local = rx->local;
@@ -1559,7 +1559,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx)
1559 return RX_CONTINUE; 1559 return RX_CONTINUE;
1560} 1560}
1561 1561
1562static ieee80211_rx_result 1562static ieee80211_rx_result debug_noinline
1563ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) 1563ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
1564{ 1564{
1565 struct ieee80211_sub_if_data *sdata; 1565 struct ieee80211_sub_if_data *sdata;
@@ -1732,66 +1732,57 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx)
1732 dev_kfree_skb(skb); 1732 dev_kfree_skb(skb);
1733} 1733}
1734 1734
1735typedef ieee80211_rx_result (*ieee80211_rx_handler)(struct ieee80211_rx_data *);
1736static ieee80211_rx_handler ieee80211_rx_handlers[] =
1737{
1738 ieee80211_rx_h_passive_scan,
1739 ieee80211_rx_h_check,
1740 ieee80211_rx_h_decrypt,
1741 ieee80211_rx_h_sta_process,
1742 ieee80211_rx_h_defragment,
1743 ieee80211_rx_h_ps_poll,
1744 ieee80211_rx_h_michael_mic_verify,
1745 /* this must be after decryption - so header is counted in MPDU mic
1746 * must be before pae and data, so QOS_DATA format frames
1747 * are not passed to user space by these functions
1748 */
1749 ieee80211_rx_h_remove_qos_control,
1750 ieee80211_rx_h_amsdu,
1751 ieee80211_rx_h_data,
1752 ieee80211_rx_h_ctrl,
1753 ieee80211_rx_h_mgmt,
1754 NULL
1755};
1756 1735
1757static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, 1736static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
1758 struct ieee80211_rx_data *rx, 1737 struct ieee80211_rx_data *rx,
1759 struct sk_buff *skb) 1738 struct sk_buff *skb)
1760{ 1739{
1761 ieee80211_rx_handler *handler;
1762 ieee80211_rx_result res = RX_DROP_MONITOR; 1740 ieee80211_rx_result res = RX_DROP_MONITOR;
1763 1741
1764 rx->skb = skb; 1742 rx->skb = skb;
1765 rx->sdata = sdata; 1743 rx->sdata = sdata;
1766 rx->dev = sdata->dev; 1744 rx->dev = sdata->dev;
1767 1745
1768 for (handler = ieee80211_rx_handlers; *handler != NULL; handler++) { 1746#define CALL_RXH(rxh) \
1769 res = (*handler)(rx); 1747 res = rxh(rx); \
1770 1748 if (res != RX_CONTINUE) \
1771 switch (res) { 1749 goto rxh_done;
1772 case RX_CONTINUE: 1750
1773 continue; 1751 CALL_RXH(ieee80211_rx_h_passive_scan)
1774 case RX_DROP_UNUSABLE: 1752 CALL_RXH(ieee80211_rx_h_check)
1775 case RX_DROP_MONITOR: 1753 CALL_RXH(ieee80211_rx_h_decrypt)
1776 I802_DEBUG_INC(sdata->local->rx_handlers_drop); 1754 CALL_RXH(ieee80211_rx_h_sta_process)
1777 if (rx->sta) 1755 CALL_RXH(ieee80211_rx_h_defragment)
1778 rx->sta->rx_dropped++; 1756 CALL_RXH(ieee80211_rx_h_ps_poll)
1779 break; 1757 CALL_RXH(ieee80211_rx_h_michael_mic_verify)
1780 case RX_QUEUED: 1758 /* must be after MMIC verify so header is counted in MPDU mic */
1781 I802_DEBUG_INC(sdata->local->rx_handlers_queued); 1759 CALL_RXH(ieee80211_rx_h_remove_qos_control)
1782 break; 1760 CALL_RXH(ieee80211_rx_h_amsdu)
1783 } 1761 CALL_RXH(ieee80211_rx_h_data)
1784 break; 1762 CALL_RXH(ieee80211_rx_h_ctrl)
1785 } 1763 CALL_RXH(ieee80211_rx_h_mgmt)
1786 1764
1765#undef CALL_RXH
1766
1767 rxh_done:
1787 switch (res) { 1768 switch (res) {
1788 case RX_CONTINUE:
1789 case RX_DROP_MONITOR: 1769 case RX_DROP_MONITOR:
1770 I802_DEBUG_INC(sdata->local->rx_handlers_drop);
1771 if (rx->sta)
1772 rx->sta->rx_dropped++;
1773 /* fall through */
1774 case RX_CONTINUE:
1790 ieee80211_rx_cooked_monitor(rx); 1775 ieee80211_rx_cooked_monitor(rx);
1791 break; 1776 break;
1792 case RX_DROP_UNUSABLE: 1777 case RX_DROP_UNUSABLE:
1778 I802_DEBUG_INC(sdata->local->rx_handlers_drop);
1779 if (rx->sta)
1780 rx->sta->rx_dropped++;
1793 dev_kfree_skb(rx->skb); 1781 dev_kfree_skb(rx->skb);
1794 break; 1782 break;
1783 case RX_QUEUED:
1784 I802_DEBUG_INC(sdata->local->rx_handlers_queued);
1785 break;
1795 } 1786 }
1796} 1787}
1797 1788