diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index af352c05c983..46705ae7a847 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -954,4 +954,10 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx, struct ieee80211_hdr *hdr); +#ifdef CONFIG_MAC80211_DEBUG +#define debug_noinline noinline +#else +#define debug_noinline +#endif + #endif /* IEEE80211_I_H */ diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 8f1c574bc8fb..7b930d3c2fba 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -220,7 +220,7 @@ static int inline is_ieee80211_device(struct net_device *dev, /* tx handlers */ -static ieee80211_tx_result +static ieee80211_tx_result debug_noinline ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG @@ -274,7 +274,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) return TX_CONTINUE; } -static ieee80211_tx_result +static ieee80211_tx_result debug_noinline ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; @@ -432,7 +432,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) return TX_CONTINUE; } -static ieee80211_tx_result +static ieee80211_tx_result debug_noinline ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) { if (unlikely(tx->flags & IEEE80211_TX_PS_BUFFERED)) @@ -444,7 +444,7 @@ ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) return ieee80211_tx_h_multicast_ps_buf(tx); } -static ieee80211_tx_result +static ieee80211_tx_result debug_noinline ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) { struct ieee80211_key *key; @@ -493,7 +493,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) return TX_CONTINUE; } -static ieee80211_tx_result +static ieee80211_tx_result debug_noinline ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) { struct rate_selection rsel; @@ -537,7 +537,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) return TX_CONTINUE; } -static ieee80211_tx_result +static ieee80211_tx_result debug_noinline ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; @@ -632,7 +632,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) return TX_CONTINUE; } -static ieee80211_tx_result +static ieee80211_tx_result debug_noinline ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; @@ -724,7 +724,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) return TX_DROP; } -static ieee80211_tx_result +static ieee80211_tx_result debug_noinline ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) { if (!tx->key) @@ -744,7 +744,7 @@ ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) return TX_DROP; } -static ieee80211_tx_result +static ieee80211_tx_result debug_noinline ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; @@ -774,7 +774,7 @@ ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx) return TX_CONTINUE; } -static ieee80211_tx_result +static ieee80211_tx_result debug_noinline ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) { int i; @@ -795,24 +795,6 @@ ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) } -typedef ieee80211_tx_result (*ieee80211_tx_handler)(struct ieee80211_tx_data *); -static ieee80211_tx_handler ieee80211_tx_handlers[] = -{ - ieee80211_tx_h_check_assoc, - ieee80211_tx_h_sequence, - ieee80211_tx_h_ps_buf, - ieee80211_tx_h_select_key, - ieee80211_tx_h_michael_mic_add, - ieee80211_tx_h_rate_ctrl, - ieee80211_tx_h_misc, - ieee80211_tx_h_fragment, - /* handlers after fragment must be aware of tx info fragmentation! */ - ieee80211_tx_h_encrypt, - ieee80211_tx_h_calculate_duration, - ieee80211_tx_h_stats, - NULL -}; - /* actual transmit path */ /* @@ -1111,16 +1093,29 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, static int invoke_tx_handlers(struct ieee80211_tx_data *tx) { struct sk_buff *skb = tx->skb; - ieee80211_tx_handler *handler; ieee80211_tx_result res = TX_DROP; int i; - for (handler = ieee80211_tx_handlers; *handler != NULL; handler++) { - res = (*handler)(tx); - if (res != TX_CONTINUE) - break; - } +#define CALL_TXH(txh) \ + res = txh(tx); \ + if (res != TX_CONTINUE) \ + goto txh_done; + CALL_TXH(ieee80211_tx_h_check_assoc) + CALL_TXH(ieee80211_tx_h_sequence) + CALL_TXH(ieee80211_tx_h_ps_buf) + CALL_TXH(ieee80211_tx_h_select_key) + CALL_TXH(ieee80211_tx_h_michael_mic_add) + CALL_TXH(ieee80211_tx_h_rate_ctrl) + CALL_TXH(ieee80211_tx_h_misc) + CALL_TXH(ieee80211_tx_h_fragment) + /* handlers after fragment must be aware of tx info fragmentation! */ + CALL_TXH(ieee80211_tx_h_encrypt) + CALL_TXH(ieee80211_tx_h_calculate_duration) + CALL_TXH(ieee80211_tx_h_stats) +#undef CALL_TXH + + txh_done: if (unlikely(res == TX_DROP)) { I802_DEBUG_INC(tx->local->tx_handlers_drop); dev_kfree_skb(skb);