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