wfb-ng/patches/mac80211-radiotap-bitrate_mcs_rtscts.linux-4.4.patch
2017-04-24 23:20:59 +03:00

155 lines
4.6 KiB
Diff

diff -Naur 1/include/net/mac80211.h 2/include/net/mac80211.h
--- 1/include/net/mac80211.h 2016-02-25 21:01:36.000000000 +0100
+++ 2/include/net/mac80211.h 2016-04-07 09:05:21.474203687 +0200
@@ -867,7 +867,16 @@
/* 2 bytes free */
};
/* only needed before rate control */
- unsigned long jiffies;
+ struct {
+ /* same position as rates[0] */
+ struct ieee80211_tx_rate prerate;
+ u8 use_preset_rate:1;
+ u8 use_legacy_rate:1;
+ /* only used for legacy bitrates */
+ u16 bitrate;
+ /* 2 bytes free */
+ unsigned long jiffies;
+ };
};
/* NB: vif can be NULL for injected frames */
struct ieee80211_vif *vif;
diff -Naur 1/net/mac80211/tx.c 2/net/mac80211/tx.c
--- 1/net/mac80211/tx.c 2016-02-25 21:01:36.000000000 +0100
+++ 2/net/mac80211/tx.c 2016-04-07 09:05:21.478203760 +0200
@@ -786,6 +786,52 @@
}
static ieee80211_tx_result debug_noinline
+ieee80211_tx_h_rate_preset(struct ieee80211_tx_data *tx)
+{
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
+ struct ieee80211_supported_band *sband;
+ u16 bitrate;
+ u8 use_legacy_rate;
+ s8 idx;
+ int i;
+
+ sband = tx->local->hw.wiphy->bands[info->band];
+
+ bitrate = info->control.bitrate;
+ use_legacy_rate = info->control.use_legacy_rate;
+
+ /*
+ * WARNING: This overwrites some data that may be needed in the
+ * following procedure. So everything that is needed and shares memory
+ * with info->control.rates[] needs to be copied beforehand.
+ */
+ for (i = 1; i < IEEE80211_TX_MAX_RATES; i++)
+ info->control.rates[i].idx = -1;
+
+ if (!use_legacy_rate) {
+ if (info->control.rates[0].idx < 0)
+ return TX_DROP;
+ return TX_CONTINUE;
+ }
+
+ idx = -1;
+ for (i = 0; i < sband->n_bitrates; i++) {
+ if (sband->bitrates[i].bitrate > bitrate)
+ continue;
+ if (idx >= 0 &&
+ sband->bitrates[i].bitrate < sband->bitrates[idx].bitrate)
+ continue;
+ idx = i;
+ }
+ if (unlikely(idx < 0))
+ return TX_DROP;
+
+ info->control.rates[0].idx = idx;
+
+ return TX_CONTINUE;
+}
+
+static ieee80211_tx_result debug_noinline
ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
@@ -1476,8 +1522,12 @@
CALL_TXH(ieee80211_tx_h_ps_buf);
CALL_TXH(ieee80211_tx_h_check_control_port_protocol);
CALL_TXH(ieee80211_tx_h_select_key);
- if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL))
- CALL_TXH(ieee80211_tx_h_rate_ctrl);
+ if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL)) {
+ if (unlikely(info->control.use_preset_rate))
+ CALL_TXH(ieee80211_tx_h_rate_preset);
+ else
+ CALL_TXH(ieee80211_tx_h_rate_ctrl);
+ }
if (unlikely(info->flags & IEEE80211_TX_INTFL_RETRANSMISSION)) {
__skb_queue_tail(&tx->skbs, tx->skb);
@@ -1674,9 +1724,14 @@
int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len,
NULL);
u16 txflags;
+ u8 known, flags, mcs;
info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
IEEE80211_TX_CTL_DONTFRAG;
+ info->control.prerate.count = 1;
+ info->control.prerate.flags = 0;
+ info->control.use_preset_rate = 0;
+ info->control.use_legacy_rate = 0;
/*
* for every radiotap entry that is present
@@ -1722,6 +1777,46 @@
txflags = get_unaligned_le16(iterator.this_arg);
if (txflags & IEEE80211_RADIOTAP_F_TX_NOACK)
info->flags |= IEEE80211_TX_CTL_NO_ACK;
+ if (txflags & IEEE80211_RADIOTAP_F_TX_CTS)
+ info->control.prerate.flags |=
+ IEEE80211_TX_RC_USE_CTS_PROTECT;
+ if (txflags & IEEE80211_RADIOTAP_F_TX_RTS)
+ info->control.prerate.flags |=
+ IEEE80211_TX_RC_USE_RTS_CTS;
+ break;
+
+ case IEEE80211_RADIOTAP_RATE:
+ info->control.bitrate = *iterator.this_arg * 5;
+ info->control.use_legacy_rate = 1;
+ info->control.use_preset_rate = 1;
+ break;
+
+ case IEEE80211_RADIOTAP_MCS:
+ known = *iterator.this_arg;
+ flags = *(iterator.this_arg + 1);
+ mcs = *(iterator.this_arg + 2);
+ if (known & IEEE80211_RADIOTAP_MCS_HAVE_MCS) {
+ info->control.prerate.idx = mcs;
+ info->control.prerate.flags |=
+ IEEE80211_TX_RC_MCS;
+ info->control.use_preset_rate = 1;
+ }
+ if (known & IEEE80211_RADIOTAP_MCS_HAVE_BW) {
+ if ((flags & IEEE80211_RADIOTAP_MCS_BW_MASK)
+ == IEEE80211_RADIOTAP_MCS_BW_40)
+ info->control.prerate.flags |=
+ IEEE80211_TX_RC_40_MHZ_WIDTH;
+ }
+ if (known & IEEE80211_RADIOTAP_MCS_HAVE_GI) {
+ if (flags & IEEE80211_RADIOTAP_MCS_SGI)
+ info->control.prerate.flags |=
+ IEEE80211_TX_RC_SHORT_GI;
+ }
+ if (known & IEEE80211_RADIOTAP_MCS_HAVE_FMT) {
+ if (flags & IEEE80211_RADIOTAP_MCS_FMT_GF)
+ info->control.prerate.flags |=
+ IEEE80211_TX_RC_GREEN_FIELD;
+ }
break;
/*