diff mbox

[RFC] mac80211: support rate and retry settings in injected frames

Message ID 1267588562.30055.12.camel@mj (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Pavel Roskin March 3, 2010, 3:56 a.m. UTC
None
diff mbox

Patch

diff --git a/Documentation/networking/mac80211-injection.txt b/Documentation/networking/mac80211-injection.txt
index b30e81a..80a3860 100644
--- a/Documentation/networking/mac80211-injection.txt
+++ b/Documentation/networking/mac80211-injection.txt
@@ -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.
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 80eb7cc..f296b6e 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -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),
 };
 
 /**
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index cbe53ed..986ee52 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -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))