@@ -23,6 +23,13 @@ radiotap headers and used to control injection:
IEEE80211_RADIOTAP_F_FRAG: frame will be fragmented if longer than the
current fragmentation threshold.
+ * IEEE80211_RADIOTAP_RATE: Transmit rate will be set to the requested value if
+ it's available. Rate control will not be used for
+ the frame.
+
+ * IEEE80211_RADIOTAP_DATA_RETRIES: Retry count will be set to the requested
+ value. This parameter can only be used in
+ conjunction with IEEE80211_RADIOTAP_RATE.
The injection code can also skip all other currently defined radiotap fields
facilitating replay of captured radiotap headers directly.
@@ -267,6 +267,7 @@ struct ieee80211_bss_conf {
* @IEEE80211_TX_INTFL_NL80211_FRAME_TX: Frame was requested through nl80211
* MLME command (internal to mac80211 to figure out whether to send TX
* status to user space)
+ * @IEEE80211_TX_CTL_RC_BYPASS: Don't use rate control on the frame.
*/
enum mac80211_tx_control_flags {
IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
@@ -290,6 +291,7 @@ enum mac80211_tx_control_flags {
IEEE80211_TX_INTFL_RETRANSMISSION = BIT(19),
IEEE80211_TX_INTFL_HAS_RADIOTAP = BIT(20),
IEEE80211_TX_INTFL_NL80211_FRAME_TX = BIT(21),
+ IEEE80211_TX_CTL_RC_BYPASS = BIT(22),
};
/**
@@ -1058,6 +1058,39 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
tx->flags |= IEEE80211_TX_FRAGMENTED;
break;
+ case IEEE80211_RADIOTAP_RATE: {
+ int i, idx = -1;
+ int rate = *iterator.this_arg * 5;
+
+ for (i = 0; i < sband->n_bitrates; i++)
+ if (sband->bitrates[i].bitrate == rate) {
+ idx = i;
+ break;
+ }
+
+ /* Rate not available - rejecting */
+ if (idx < 0)
+ return false;
+
+ info->flags |= IEEE80211_TX_CTL_RC_BYPASS;
+ info->control.rates[0].idx = idx;
+ info->control.rates[0].count = 1;
+ for (i = 1; i < IEEE80211_TX_MAX_RATES; i++)
+ info->control.rates[i].idx = -1;
+ break;
+ }
+
+ case IEEE80211_RADIOTAP_DATA_RETRIES:
+ /*
+ * Only allow setting the number of retries in
+ * conjunction with the rates, when the rate control
+ * is bypassed.
+ */
+ if (info->flags & IEEE80211_TX_CTL_RC_BYPASS)
+ info->control.rates[0].count =
+ *iterator.this_arg;
+ break;
+
/*
* Please update the file
* Documentation/networking/mac80211-injection.txt
@@ -1305,7 +1338,8 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
CALL_TXH(ieee80211_tx_h_ps_buf);
CALL_TXH(ieee80211_tx_h_select_key);
CALL_TXH(ieee80211_tx_h_sta);
- if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL))
+ if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) &&
+ !(info->flags & IEEE80211_TX_CTL_RC_BYPASS))
CALL_TXH(ieee80211_tx_h_rate_ctrl);
if (unlikely(info->flags & IEEE80211_TX_INTFL_RETRANSMISSION))