[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <773DB8A82AB6A046AE0195C68612A319017BCF36@sbs2003.acksys.local>
Date: Thu, 5 Jun 2014 10:54:25 +0200
From: "Cedric Debarge" <cedric.debarge@...sys.fr>
To: <netdev@...r.kernel.org>
Subject: [RFC]mac80211: Add radiotap field in parser
Add the radiotap field IEEE80211_RADIOTAP_RATE and
IEEE80211_RADIOTAP_MCS radiotap parser.
These additions are compatible with the radiotap definition
(http://www.radiotap.org/Radiotap)
Previous attempts were made on this mailing list using a new flag in
ieee80211_tx_info. But since this field is now full, I choose to use a bit field
in the rate control part of the ieee80211_tx_info.
signed-off-by: Cédric Debarge <cedric.debarge@...sys.fr>
---
include/net/mac80211.h | 1 +
net/mac80211/tx.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 70 insertions(+), 3 deletions(-)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 421b6ec..3ed63d8 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -721,6 +721,7 @@ struct ieee80211_tx_info {
u8 use_cts_prot:1;
u8 short_preamble:1;
u8 skip_table:1;
+ u8 tx_ctl_rc_bypass:1;
/* 2 bytes free */
};
/* only needed before rate control */
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 5214686..7aff9b5 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -657,6 +657,9 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
struct ieee80211_sta_rates *ratetbl = NULL;
bool assoc = false;
+ if (info->control.tx_ctl_rc_bypass)
+ return TX_CONTINUE;
+
memset(&txrc, 0, sizeof(txrc));
sband = tx->local->hw.wiphy->bands[info->band];
@@ -1530,19 +1533,30 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
ieee80211_tx(sdata, skb, false, band);
}
-static bool ieee80211_parse_tx_radiotap(struct sk_buff *skb)
+static bool ieee80211_parse_tx_radiotap(struct sk_buff *skb,
+ struct ieee80211_local *local)
{
struct ieee80211_radiotap_iterator iterator;
struct ieee80211_radiotap_header *rthdr =
(struct ieee80211_radiotap_header *) skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_channel *chan = local->monitor_chandef.chan;
+ struct ieee80211_supported_band *sband =
+ local->hw.wiphy->bands[chan->band];
+ u16 txflags;
+ s8 rate_idx;
+ u16 bit_rate;
+ int i;
+ unsigned char known;
+ unsigned char flags;
int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len,
NULL);
- u16 txflags;
info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
IEEE80211_TX_CTL_DONTFRAG;
+ info->control.tx_ctl_rc_bypass = 0;
+
/*
* for every radiotap entry that is present
* (ieee80211_radiotap_iterator_next returns -ENOENT when no more
@@ -1589,6 +1603,58 @@ static bool ieee80211_parse_tx_radiotap(struct sk_buff *skb)
info->flags |= IEEE80211_TX_CTL_NO_ACK;
break;
+ case IEEE80211_RADIOTAP_RATE:
+ rate_idx = -1;
+ /* convert legacy rate; NB: .5 Mb/s -> 100 kb/s */
+ bit_rate = *iterator.this_arg * 5;
+ for (i = 0; i < sband->n_bitrates; i++){
+ if (sband->bitrates[i].bitrate == bit_rate) {
+ rate_idx = i;
+ break;
+ }
+ }
+ /* Rate not available - rejecting */
+ if (rate_idx < 0)
+ return false;
+
+ info->control.tx_ctl_rc_bypass = 1;
+ info->control.rates[0].idx = rate_idx;
+ info->control.rates[0].count = 1;
+ break;
+
+ case IEEE80211_RADIOTAP_MCS:
+ known = iterator.this_arg[0];
+ flags = iterator.this_arg[1];
+ rate_idx = iterator.this_arg[2];
+
+ /* 11n not supported - rejecting */
+ if(!sband->ht_cap.ht_supported) {
+ return false;
+ }
+
+ /* set mcs */
+ if(known & IEEE80211_RADIOTAP_MCS_HAVE_MCS) {
+ info->control.rates[0].idx = rate_idx;
+ info->control.rates[0].flags |=
+ IEEE80211_TX_RC_MCS;
+ }
+
+ /* set GI */
+ if ((known & IEEE80211_RADIOTAP_MCS_HAVE_GI) &&
+ (flags & IEEE80211_RADIOTAP_MCS_SGI))
+ info->control.rates[0].flags |=
+ IEEE80211_TX_RC_SHORT_GI;
+
+ /* set bandwith */
+ if ((known & IEEE80211_RADIOTAP_MCS_HAVE_BW) &&
+ (flags & IEEE80211_RADIOTAP_MCS_BW_40))
+ info->control.rates[0].flags |=
+ IEEE80211_TX_RC_40_MHZ_WIDTH;
+
+ info->control.rates[0].count = 1;
+ info->control.tx_ctl_rc_bypass = 1;
+ break;
+
/*
* Please update the file
* Documentation/networking/mac80211-injection.txt
@@ -1684,7 +1750,7 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
IEEE80211_TX_CTL_INJECTED;
/* process and remove the injection radiotap header */
- if (!ieee80211_parse_tx_radiotap(skb))
+ if (!ieee80211_parse_tx_radiotap(skb, local))
goto fail;
rcu_read_lock();
--
1.7.9.5
Cédric DEBARGE
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists