RFC Patch: Add signal strength to nl80211station info
Subsystems (2)
Hello,
I have just written a prototype of a patch that adds signal strength information to the nl80211 station info. This allows user space programs to keep track of the signal strength of each other station in communication range (in adhoc mode) without using radiotap headers (which consume lots of cpu power on embedded systems).
I have tested the patch with a modified iw command on ath5k. I'm still looking for a way to add the datarate of unicast for each of the stations in range, but would like to hear comments about the patch.
-------------------------------------------
include/linux/nl80211.h +4 -1
@@ -413,7 +413,10 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , - +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_NOISE , +NL80211_STA_INFO_QUAL , +/* keep last */ __NL80211_STA_INFO_AFTER_LAST,NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST -1
include/net/cfg80211.h +4 -0
@@ -175,6 +175,9 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , +STATION_INFO_NOISE =1 <<7 , + STATION_INFO_QUAL = 1<<8, };/**
@@ -195,6 +198,7 @@ struct station_info {u32 inactive_time;u32 rx_bytes;u32 tx_bytes; +u32 signal,noise,qual;u16 llid;u16 plid;u8 plink_state;
net/mac80211/cfg.c +8 -2
@@ -310,12 +310,18 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) sinfo->filled =STATION_INFO_INACTIVE_TIME |STATION_INFO_RX_BYTES | -STATION_INFO_TX_BYTES ; +STATION_INFO_TX_BYTES | +STATION_INFO_SIGNAL | +STATION_INFO_NOISE | +STATION_INFO_QUAL ; sinfo->inactive_time =jiffies_to_msecs (jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes; sinfo->tx_bytes = sta->tx_bytes; - + sinfo->signal = sta->last_signal; + sinfo->qual = sta->last_qual; + sinfo->noise = sta->last_noise; +if (ieee80211_vif_is_mesh (&sdata->vif)) {#ifdef CONFIG_MAC80211_MESH sinfo->filled |= STATION_INFO_LLID |
net/wireless/nl80211.c +9 -0
@@ -1057,6 +1057,15 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,if (sinfo->filled &STATION_INFO_PLINK_STATE )NLA_PUT_U8 (msg,NL80211_STA_INFO_PLINK_STATE , sinfo->plink_state); +if (sinfo->filled &STATION_INFO_SIGNAL ) +NLA_PUT_U32 (msg,NL80211_STA_INFO_SIGNAL , + sinfo->signal); +if (sinfo->filled &STATION_INFO_NOISE ) +NLA_PUT_U32 (msg,NL80211_STA_INFO_NOISE , + sinfo->noise); +if (sinfo->filled &STATION_INFO_QUAL ) +NLA_PUT_U32 (msg,NL80211_STA_INFO_QUAL , + sinfo->qual);nla_nest_end (msg, sinfoattr);
include/linux/nl80211.h +4 -1
@@ -413,7 +413,10 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , - +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_NOISE , +NL80211_STA_INFO_QUAL , +/* keep last */ __NL80211_STA_INFO_AFTER_LAST,NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST -1
include/net/cfg80211.h +4 -0
@@ -175,6 +175,9 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , +STATION_INFO_NOISE =1 <<7 , + STATION_INFO_QUAL = 1<<8, };/**
@@ -195,6 +198,7 @@ struct station_info {u32 inactive_time;u32 rx_bytes;u32 tx_bytes; +u32 signal,noise,qual;u16 llid;u16 plid;u8 plink_state;
net/mac80211/cfg.c +8 -2
@@ -310,12 +310,18 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) sinfo->filled =STATION_INFO_INACTIVE_TIME |STATION_INFO_RX_BYTES | -STATION_INFO_TX_BYTES ; +STATION_INFO_TX_BYTES | +STATION_INFO_SIGNAL | +STATION_INFO_NOISE | +STATION_INFO_QUAL ; sinfo->inactive_time =jiffies_to_msecs (jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes; sinfo->tx_bytes = sta->tx_bytes; - + sinfo->signal = sta->last_signal; + sinfo->qual = sta->last_qual; + sinfo->noise = sta->last_noise; +if (ieee80211_vif_is_mesh (&sdata->vif)) {#ifdef CONFIG_MAC80211_MESH sinfo->filled |= STATION_INFO_LLID |
net/wireless/nl80211.c +9 -0
@@ -1057,6 +1057,15 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,if (sinfo->filled &STATION_INFO_PLINK_STATE )NLA_PUT_U8 (msg,NL80211_STA_INFO_PLINK_STATE , sinfo->plink_state); +if (sinfo->filled &STATION_INFO_SIGNAL ) +NLA_PUT_U32 (msg,NL80211_STA_INFO_SIGNAL , + sinfo->signal); +if (sinfo->filled &STATION_INFO_NOISE ) +NLA_PUT_U32 (msg,NL80211_STA_INFO_NOISE , + sinfo->noise); +if (sinfo->filled &STATION_INFO_QUAL ) +NLA_PUT_U32 (msg,NL80211_STA_INFO_QUAL , + sinfo->qual);nla_nest_end (msg, sinfoattr);
Johannes Berg
maintainerinclude/linux/nl80211.h enum nl80211_sta_info { · line 418
Quoted 3 lines · Henning Rogge
include/linux/nl80211.h +3
-0+NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_NOISE , + NL80211_STA_INFO_QUAL,
Sorry, no, this WEXT junk is just too undefined to put it into nl80211.
johannes
Quoted 6 lines · On Tuesday 25 November 2008 21:47:17 Johannes Berg wrote:
include/linux/nl80211.h enum nl80211_sta_info { · line 418
Quoted 3 lines · Henning Rogge
include/linux/nl80211.h +3
-0+NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_NOISE , + NL80211_STA_INFO_QUAL,Sorry, no, this WEXT junk is just too undefined to put it into nl80211.
It was an experiment... the question is, what kind of information about signal strength or SNR would be good enough to make it available to userspace.
At the moment there is no way to get this information without a huge overhead of cpu power (raw sockets + monitor mode + radiotap)
Henning
Hi Johannes,
Quoted 5 lines
include/linux/nl80211.h enum nl80211_sta_info { · line 418
Quoted 3 lines
include/linux/nl80211.h +3
-0+NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_NOISE , + NL80211_STA_INFO_QUAL,Sorry, no, this WEXT junk is just too undefined to put it into nl80211.
I know that WEXT were pretty bad in describing what to expect from these values and every driver did whatever it thought it would be best. Can we not just try to define how these values should be filled in and then either mark drivers as broken or try to fix them? Just an idea.
Regards
Marcel
Johannes Berg
maintainerQuoted 9 lines · Marcel Holtmann
Hi Johannes,
Quoted 6 lines
include/linux/nl80211.h enum nl80211_sta_info { · line 418
Quoted 3 lines
include/linux/nl80211.h +3
-0+NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_NOISE , + NL80211_STA_INFO_QUAL,Sorry, no, this WEXT junk is just too undefined to put it into nl80211.
Quoted 5 lines
I know that WEXT were pretty bad in describing what to expect from these values and every driver did whatever it thought it would be best. Can we not just try to define how these values should be filled in and then either mark drivers as broken or try to fix them? Just an idea.
But it doesn't even physically make sense. The noise is not per station but rather per channel, if you know it at all. The "quality" is simply not defined, and would usually be "signal", unless you're doing something else to estimate "quality", like taking into account retransmissions, ... And then signal/noise should be in dBm.
johannes
Quoted 9 lines · On Wednesday 26 November 2008 06:21:40 Marcel Holtmann wrote:
Hi Johannes,
Quoted 6 lines
include/linux/nl80211.h enum nl80211_sta_info { · line 418
Quoted 3 lines
include/linux/nl80211.h +3
-0+NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_NOISE , + NL80211_STA_INFO_QUAL,Sorry, no, this WEXT junk is just too undefined to put it into nl80211.
Quoted 5 lines
I know that WEXT were pretty bad in describing what to expect from these values and every driver did whatever it thought it would be best. Can we not just try to define how these values should be filled in and then either mark drivers as broken or try to fix them? Just an idea.
That would be a great thing... it's not that I really need the noise level (or the quality value), I was just testing how easy I can push values through nl80211 into userspace. The layer 1/2 data I'm looking for is signalstrength and transmission rate for each adhoc communication partner. And I still think the mac80211 stack is missing some easy way to get them at the moment.
Henning
Re: RFC Patch v2: Add signal strength to nl80211station info
In reply to Marcel HoltmannQuoted 5 lines · On Wednesday 26 November 2008 06:21:40 Marcel Holtmann wrote:
I know that WEXT were pretty bad in describing what to expect from these values and every driver did whatever it thought it would be best. Can we not just try to define how these values should be filled in and then either mark drivers as broken or try to fix them? Just an idea.
I just created a second patch for station info.
Changes since v1:
- removed noise and quality from station info in NL80211
- added bandwith to station info in NL80211
- changed name of patch file to nl80211ext_v2.patch
The problem of a well defined signal strength value is still not addressed, but I have not enough knowledge about the driver specific implementations to make a good suggestion I think.
Henning
---------------------------------------------------
include/linux/nl80211.h +2 -0
@@ -413,6 +413,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_BANDWITH ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +4 -0
@@ -175,6 +175,8 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , + STATION_INFO_BANDWITH = 1<<7, };/**
@@ -198,6 +200,8 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +u16 bandwith; };/**
net/mac80211/cfg.c +0 -0
@@ -307,14 +307,24 @@ static int ieee80211_config_default_key(struct wiphy
*wiphy,
static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) {
struct ieee80211_sub_if_data *sdata = sta->sdata;
+ struct ieee80211_supported_band *sband;
sinfo->filled = STATION_INFO_INACTIVE_TIME |
STATION_INFO_RX_BYTES |
- STATION_INFO_TX_BYTES;
+ STATION_INFO_TX_BYTES |
+ STATION_INFO_SIGNAL |
+ STATION_INFO_BANDWITH;
sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes;
sinfo->tx_bytes = sta->tx_bytes;
+ sinfo->signal = sta->last_signal;
+
+ sband = sta->local->hw.wiphy->bands[sta->local->hw.conf.channel->band];
+ if (!(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS))
+ sinfo->bandwith = sband->bitrates[sta->last_tx_rate.idx].bitrate;
+ else
+ sinfo->bandwith = 0;
if (ieee80211_vif_is_mesh(&sdata->vif)) {
#ifdef CONFIG_MAC80211_MESH
net/wireless/nl80211.c +0 -0
@@ -1057,6 +1057,12 @@ static int nl80211_send_station(struct sk_buff *msg,
u32 pid, u32 seq,
if (sinfo->filled & STATION_INFO_PLINK_STATE)
NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
sinfo->plink_state);
+ if (sinfo->filled & STATION_INFO_SIGNAL)
+ NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
+ sinfo->signal);
+ if (sinfo->filled & STATION_INFO_BANDWITH)
+ NLA_PUT_U16(msg, NL80211_STA_INFO_BANDWITH,
+ sinfo->bandwith);
nla_nest_end(msg, sinfoattr);
include/linux/nl80211.h +2 -0
@@ -413,6 +413,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_BANDWITH ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +4 -0
@@ -175,6 +175,8 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , + STATION_INFO_BANDWITH = 1<<7, };/**
@@ -198,6 +200,8 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +u16 bandwith; };/**
net/mac80211/cfg.c +11 -1
@@ -307,14 +307,24 @@ static int ieee80211_config_default_key(struct wiphy *wiphy,static void sta_set_sinfo (struct sta_info *sta,struct station_info *sinfo) {struct ieee80211_sub_if_data *sdata = sta->sdata; +struct ieee80211_supported_band *sband; sinfo->filled =STATION_INFO_INACTIVE_TIME |STATION_INFO_RX_BYTES | -STATION_INFO_TX_BYTES ; +STATION_INFO_TX_BYTES | +STATION_INFO_SIGNAL | +STATION_INFO_BANDWITH ; sinfo->inactive_time =jiffies_to_msecs (jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes; sinfo->tx_bytes = sta->tx_bytes; + sinfo->signal = sta->last_signal; + + sband = sta->local->hw.wiphy->bands[sta->local->hw.conf.channel->band]; +if (!(sta->last_tx_rate.flags &IEEE80211_TX_RC_MCS )) + sinfo->bandwith = sband->bitrates[sta->last_tx_rate.idx].bitrate; +else + sinfo->bandwith =0 ;if (ieee80211_vif_is_mesh (&sdata->vif)) {#ifdef CONFIG_MAC80211_MESH
net/wireless/nl80211.c +6 -0
@@ -1057,6 +1057,12 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,if (sinfo->filled &STATION_INFO_PLINK_STATE )NLA_PUT_U8 (msg,NL80211_STA_INFO_PLINK_STATE , sinfo->plink_state); +if (sinfo->filled &STATION_INFO_SIGNAL ) +NLA_PUT_U8 (msg,NL80211_STA_INFO_SIGNAL , + sinfo->signal); +if (sinfo->filled &STATION_INFO_BANDWITH ) +NLA_PUT_U16 (msg,NL80211_STA_INFO_BANDWITH , + sinfo->bandwith);nla_nest_end (msg, sinfoattr);
Johannes Berg
maintainerRe: RFC Patch v2: Add signal strength to nl80211station info
include/linux/nl80211.h enum nl80211_sta_info { · line 417
Quoted 10 lines · Henning Rogge
include/linux/nl80211.h +2
-0@@ -413,6 +413,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , + NL80211_STA_INFO_BANDWITH,
Even if you corrected the spelling to "bandwidth" you'd (a) be missing documentation and (b) be using an entirely wrong term for what you're doing.
johannes
Re: RFC Patch v2: Add signal strength to nl80211station info
Am Monday 01 December 2008 12:17:36 schrieb Johannes Berg:
Quoted 3 lines
Even if you corrected the spelling to "bandwidth" you'd (a) be missing documentation and (b) be using an entirely wrong term for what you're doing.
Changes since v1:
- removed noise and quality from station info in NL80211
- added bandwith to station info in NL80211
- changed name of patch file to nl80211ext_v2.patch
Changes since v2:
- added kernel comment lines for new fields/enums
- changed name of "bandwith" field to tx_bitrate
Henning Rogge
*************************************************
Diplom Informatiker Henning Rogge
Forschungsgesellschaft für
Angewandte Naturwissenschaften e. V. (FGAN)
Neuenahrer Str. 20, 53343 Wachtberg, Germany
Tel.: 0049 (0)228 9435-961
Fax: 0049 (0)228 9435-685
E-Mail: [email protected]
Web: www.fgan.de
************************************************
Sitz der Gesellschaft: Bonn
Registergericht: Amtsgericht Bonn VR 2530
Vorstand: Dr. rer. nat. Ralf Dornhaus (Vors.), Prof. Dr. Joachim Ender (Stellv.)
---------------------------------------------------
include/linux/nl80211.h +1 -0
@@ -404,6 +404,8 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received package (u8,
dBm)
+ * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate (u16, 100 kbit/s) */
enum nl80211_sta_info {
__NL80211_STA_INFO_INVALID,
@@ -413,6 +415,8 @@ enum nl80211_sta_info {
NL80211_STA_INFO_LLID,
NL80211_STA_INFO_PLID,
NL80211_STA_INFO_PLINK_STATE,
+ NL80211_STA_INFO_SIGNAL,
+ NL80211_STA_INFO_TX_BITRATE,
/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +8 -0
@@ -167,6 +167,8 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate filled */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -175,6 +177,8 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , + STATION_INFO_TX_BITRATE = 1<<7, };/**
@@ -189,6 +193,8 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received package in dBm +* @tx_bitrate: current unicast tx rate in 100 kbit/sec */ struct station_info {u32 filled;
@@ -198,6 +204,8 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +u16 tx_bitrate; };/**
net/mac80211/cfg.c +0 -0
@@ -307,14 +307,24 @@ static int ieee80211_config_default_key(struct wiphy
*wiphy,
static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) {
struct ieee80211_sub_if_data *sdata = sta->sdata;
+ struct ieee80211_supported_band *sband;
sinfo->filled = STATION_INFO_INACTIVE_TIME |
STATION_INFO_RX_BYTES |
- STATION_INFO_TX_BYTES;
+ STATION_INFO_TX_BYTES |
+ STATION_INFO_SIGNAL |
+ STATION_INFO_TX_BITRATE;
sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes;
sinfo->tx_bytes = sta->tx_bytes;
+ sinfo->signal = sta->last_signal;
+
+ sband = sta->local->hw.wiphy->bands[sta->local->hw.conf.channel->band];
+ if (!(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS))
+ sinfo->tx_bitrate = sband->bitrates[sta->last_tx_rate.idx].bitrate;
+ else
+ sinfo->tx_bitrate = 0;
if (ieee80211_vif_is_mesh(&sdata->vif)) {
#ifdef CONFIG_MAC80211_MESH
net/wireless/nl80211.c +0 -0
@@ -1057,6 +1057,12 @@ static int nl80211_send_station(struct sk_buff *msg,
u32 pid, u32 seq,
if (sinfo->filled & STATION_INFO_PLINK_STATE)
NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
sinfo->plink_state);
+ if (sinfo->filled & STATION_INFO_SIGNAL)
+ NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
+ sinfo->signal);
+ if (sinfo->filled & STATION_INFO_TX_BITRATE)
+ NLA_PUT_U16(msg, NL80211_STA_INFO_TX_BITRATE,
+ sinfo->tx_bitrate);
nla_nest_end(msg, sinfoattr);
include/linux/nl80211.h +4 -0
@@ -404,6 +404,8 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received package (u8, dBm) +* @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate (u16, 100 kbit/s) */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID,
@@ -413,6 +415,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_TX_BITRATE ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +8 -0
@@ -167,6 +167,8 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate filled */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -175,6 +177,8 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , + STATION_INFO_TX_BITRATE = 1<<7, };/**
@@ -189,6 +193,8 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received package in dBm +* @tx_bitrate: current unicast tx rate in 100 kbit/sec */ struct station_info {u32 filled;
@@ -198,6 +204,8 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +u16 tx_bitrate; };/**
net/mac80211/cfg.c +11 -1
@@ -307,14 +307,24 @@ static int ieee80211_config_default_key(struct wiphy *wiphy,static void sta_set_sinfo (struct sta_info *sta,struct station_info *sinfo) {struct ieee80211_sub_if_data *sdata = sta->sdata; +struct ieee80211_supported_band *sband; sinfo->filled =STATION_INFO_INACTIVE_TIME |STATION_INFO_RX_BYTES | -STATION_INFO_TX_BYTES ; +STATION_INFO_TX_BYTES | +STATION_INFO_SIGNAL | +STATION_INFO_TX_BITRATE ; sinfo->inactive_time =jiffies_to_msecs (jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes; sinfo->tx_bytes = sta->tx_bytes; + sinfo->signal = sta->last_signal; + + sband = sta->local->hw.wiphy->bands[sta->local->hw.conf.channel->band]; +if (!(sta->last_tx_rate.flags &IEEE80211_TX_RC_MCS )) + sinfo->tx_bitrate = sband->bitrates[sta->last_tx_rate.idx].bitrate; +else + sinfo->tx_bitrate =0 ;if (ieee80211_vif_is_mesh (&sdata->vif)) {#ifdef CONFIG_MAC80211_MESH
net/wireless/nl80211.c +6 -0
@@ -1057,6 +1057,12 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,if (sinfo->filled &STATION_INFO_PLINK_STATE )NLA_PUT_U8 (msg,NL80211_STA_INFO_PLINK_STATE , sinfo->plink_state); +if (sinfo->filled &STATION_INFO_SIGNAL ) +NLA_PUT_U8 (msg,NL80211_STA_INFO_SIGNAL , + sinfo->signal); +if (sinfo->filled &STATION_INFO_TX_BITRATE ) +NLA_PUT_U16 (msg,NL80211_STA_INFO_TX_BITRATE , + sinfo->tx_bitrate);nla_nest_end (msg, sinfoattr);
Re: RFC Patch v2: Add signal strength to nl80211station info
Quoted 2 lines · Henning Rogge
Am Monday 01 December 2008 12:17:36 schrieb Johannes Berg:
Quoted 1 line
Even if you corrected the spelling to "bandwidth" you'd (a) be miss=
ing
Quoted 1 line
Quoted 1 line
documentation and (b) be using an entirely wrong term for what you'=
re
Quoted 18 lines
Quoted 1 line
doing.
=20
Changes since v1:
- removed noise and quality from station info in NL80211
- added bandwith to station info in NL80211
- changed name of patch file to nl80211ext_v2.patch =20
Changes since v2:
- added kernel comment lines for new fields/enums
- changed name of "bandwith" field totx_bitrate=20
Henning Rogge
=20
*************************************************
Diplom Informatiker Henning Rogge Forschungsgesellschaft f=FCr
Angewandte Naturwissenschaften e. V. (FGAN)=20 Neuenahrer Str. 20, 53343 Wachtberg, Germany
Quoted 8 lines
Tel.: 0049 (0)228 9435-961
Fax: 0049 (0)228 9435-685
E-Mail: [email protected]
Web: www.fgan.de
************************************************
Sitz der Gesellschaft: Bonn
Registergericht: Amtsgericht Bonn VR 2530
Vorstand: Dr. rer. nat. Ralf Dornhaus (Vors.), Prof. Dr. Joachim Ende=
r=20
include/linux/nl80211.h enum nl80211_sta_flags { · line 404
Quoted 10 lines
(Stellv.)
=20
---------------------------------------------------
=20include/linux/nl80211.h +0
-0@@ -404,6 +404,8 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this=
station)
include/linux/nl80211.h enum nl80211_sta_flags {
Quoted 3 lines
include/linux/nl80211.h +1
-0* @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received packag=
e (u8,=20
include/linux/nl80211.h enum nl80211_sta_flags { · line 409
Quoted 2 lines
include/linux/nl80211.h +1
-0dBm) + * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate (u16, 100 k=
bit/s)
net/mac80211/cfg.c static int ieee80211_config_default_key(struct =
Quoted 57 lines
include/linux/nl80211.h +0
-0*/ enum nl80211_sta_info {include/linux/nl80211.h +2
-0__NL80211_STA_INFO_INVALID,@@ -413,6 +415,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , + NL80211_STA_INFO_TX_BITRATE,=20
include/linux/nl80211.h +0
-0/* keep last */ __NL80211_STA_INFO_AFTER_LAST,include/net/cfg80211.h +4
-0@@ -167,6 +167,8 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate filled */ enum station_info_flags { STATION_INFO_INACTIVE_TIME =3D 1<<0,@@ -175,6 +177,8 @@ enum station_info_flags { STATION_INFO_LLID =3D 1<<3, STATION_INFO_PLID =3D 1<<4, STATION_INFO_PLINK_STATE =3D 1<<5, + STATION_INFO_SIGNAL =3D 1<<6, + STATION_INFO_TX_BITRATE =3D 1<<7, };=20
/**include/net/cfg80211.h +4
-0@@ -189,6 +193,8 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received package in dBm +* @tx_bitrate: current unicast tx rate in 100 kbit/sec */ struct station_info {u32 filled;@@ -198,6 +204,8 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +u16 tx_bitrate; };=20
/**net/mac80211/cfg.c +0
-0@@ -307,14 +307,24 @@ static int ieee80211_config_default_key(struct =
wiphy=20
net/mac80211/cfg.c static int ieee80211_config_default_key(struct = · line 308
Quoted 2 lines
net/mac80211/cfg.c +0
-0*wiphy, static void sta_set_sinfo(struct sta_info *sta, struct station_info =
*sinfo)
Quoted 11 lines
net/mac80211/cfg.c +1
-0{ struct ieee80211_sub_if_data *sdata =3D sta->sdata; +struct ieee80211_supported_band *sband;=20
net/mac80211/cfg.c +3
-1sinfo->filled =3D STATION_INFO_INACTIVE_TIME |STATION_INFO_RX_BYTES | -STATION_INFO_TX_BYTES ; +STATION_INFO_TX_BYTES | +STATION_INFO_SIGNAL | +STATION_INFO_TX_BITRATE ;=20
net/mac80211/cfg.c
Quoted 6 lines
net/mac80211/cfg.c +3
-0sinfo->inactive_time =3D jiffies_to_msecs(jiffies - sta->last_rx); sinfo->rx_bytes =3D sta->rx_bytes; sinfo->tx_bytes =3D sta->tx_bytes; + sinfo->signal =3D sta->last_signal; + + sband =3D sta->local->hw.wiphy->bands[sta->local->hw.conf.channel->=
band];
net/mac80211/cfg.c
Quoted 2 lines
net/mac80211/cfg.c +2
-0+if (!(sta->last_tx_rate.flags &IEEE80211_TX_RC_MCS )) + sinfo->tx_bitrate =3D sband->bitrates[sta->last_tx_rate.idx].bitr=
ate;
net/mac80211/cfg.c
Quoted 2 lines
net/mac80211/cfg.c +2
-0+else + sinfo->tx_bitrate =3D 0;
It would be nice to get this figured out before adding it. We got rando= m
complaints from users claiming 802.11n wasn't working before because iwconfig didn't report a good rate. Users will trust it so I'd rather see this go in with MCS rate figured out as part of the API to avoid such reports. Would it be possible for you to work on that?
This might come in handy:
http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11=
n#MCSRates
What you need then is the guard interval, the MCS rate index and the number of streams being used for communication.=20
Luis
--
To unsubscribe from this list: send the line "unsubscribe linux-wireles= s" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: RFC Patch v2: Add signal strength to nl80211station info
T24gTW9uLCBEZWMgMSwgMjAwOCBhdCA5OjM5IEFNLCBMdWlzIFIuIFJvZHJpZ3Vlego8bHJvZHJp Z3VlekBhdGhlcm9zLmNvbT4gd3JvdGU6Cj4gT24gTW9uLCBEZWMgMDEsIDIwMDggYXQgMDU6MjI6 MjNBTSAtMDgwMCwgSGVubmluZyBSb2dnZSB3cm90ZToKPj4gQW0gTW9uZGF5IDAxIERlY2VtYmVy IDIwMDggMTI6MTc6MzYgc2NocmllYiBKb2hhbm5lcyBCZXJnOgo+PiA+IEV2ZW4gaWYgeW91IGNv cnJlY3RlZCB0aGUgc3BlbGxpbmcgdG8gImJhbmR3aWR0aCIgeW91J2QgKGEpIGJlIG1pc3NpbmcK Pj4gPiBkb2N1bWVudGF0aW9uIGFuZCAoYikgYmUgdXNpbmcgYW4gZW50aXJlbHkgd3JvbmcgdGVy bSBmb3Igd2hhdCB5b3UncmUKPj4gPiBkb2luZy4KPj4KPj4gQ2hhbmdlcyBzaW5jZSB2MToKPj4g LSByZW1vdmVkIG5vaXNlIGFuZCBxdWFsaXR5IGZyb20gc3RhdGlvbiBpbmZvIGluIE5MODAyMTEK Pj4gLSBhZGRlZCBiYW5kd2l0aCB0byBzdGF0aW9uIGluZm8gaW4gTkw4MDIxMQo+PiAtIGNoYW5n ZWQgbmFtZSBvZiBwYXRjaCBmaWxlIHRvIG5sODAyMTFleHRfdjIucGF0Y2gKPj4KPj4gQ2hhbmdl cyBzaW5jZSB2MjoKPj4gLSBhZGRlZCBrZXJuZWwgY29tbWVudCBsaW5lcyBmb3IgbmV3IGZpZWxk cy9lbnVtcwo+PiAtIGNoYW5nZWQgbmFtZSBvZiAiYmFuZHdpdGgiIGZpZWxkIHRvIHR4X2JpdHJh dGUKPj4KPj4gSGVubmluZyBSb2dnZQo+Pgo+PiAqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqCj4+IERpcGxvbSBJbmZvcm1hdGlrZXIgSGVubmluZyBSb2dn ZQo+PiBGb3JzY2h1bmdzZ2VzZWxsc2NoYWZ0IGbDvHIKPj4gQW5nZXdhbmR0ZSBOYXR1cndpc3Nl bnNjaGFmdGVuIGUuIFYuIChGR0FOKQo+PiBOZXVlbmFocmVyIFN0ci4gMjAsIDUzMzQzIFdhY2h0 YmVyZywgR2VybWFueQo+PiBUZWwuOiAwMDQ5ICgwKTIyOCA5NDM1LTk2MQo+PiBGYXg6IDAwNDkg KDApMjI4IDk0MzUtNjg1Cj4+IEUtTWFpbDogcm9nZ2VAZmdhbi5kZQo+PiBXZWI6IHd3dy5mZ2Fu LmRlCj4+ICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgo+ PiBTaXR6IGRlciBHZXNlbGxzY2hhZnQ6IEJvbm4KPj4gUmVnaXN0ZXJnZXJpY2h0OiBBbXRzZ2Vy aWNodCBCb25uIFZSIDI1MzAKPj4gVm9yc3RhbmQ6IERyLiByZXIuIG5hdC4gUmFsZiBEb3JuaGF1 cyAoVm9ycy4pLCBQcm9mLiBEci4gSm9hY2hpbSBFbmRlcgo+PiAoU3RlbGx2LikKPj4KPj4gLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCj4+Cj4+IGRp ZmYgLS1naXQgYS9pbmNsdWRlL2xpbnV4L25sODAyMTEuaCBiL2luY2x1ZGUvbGludXgvbmw4MDIx MS5oCj4+IGluZGV4IGUwOGM4YmMuLjAzMGZlZWQgMTAwNjQ0Cj4+IC0tLSBhL2luY2x1ZGUvbGlu dXgvbmw4MDIxMS5oCj4+ICsrKyBiL2luY2x1ZGUvbGludXgvbmw4MDIxMS5oCj4+IEBAIC00MDQs NiArNDA0LDggQEAgZW51bSBubDgwMjExX3N0YV9mbGFncyB7Cj4+ICAgKiBATkw4MDIxMV9TVEFf SU5GT19UWF9CWVRFUzogdG90YWwgdHJhbnNtaXR0ZWQgYnl0ZXMgKHUzMiwgdG8gdGhpcyBzdGF0 aW9uKQo+PiAgICogQF9fTkw4MDIxMV9TVEFfSU5GT19BRlRFUl9MQVNUOiBpbnRlcm5hbAo+PiAg ICogQE5MODAyMTFfU1RBX0lORk9fTUFYOiBoaWdoZXN0IHBvc3NpYmxlIHN0YXRpb24gaW5mbyBh dHRyaWJ1dGUKPj4gKyAqIEBOTDgwMjExX1NUQV9JTkZPX1NJR05BTDogc2lnbmFsIHN0cmVuZ3Ro IG9mIGxhc3QgcmVjZWl2ZWQgcGFja2FnZSAodTgsCj4+IGRCbSkKPj4gKyAqIEBOTDgwMjExX1NU QV9JTkZPX1RYX0JJVFJBVEU6IGN1cnJlbnQgdW5pY2FzdCB0eCByYXRlICh1MTYsIDEwMCBrYml0 L3MpCj4+ICAgKi8KPj4gIGVudW0gbmw4MDIxMV9zdGFfaW5mbyB7Cj4+ICAgICAgIF9fTkw4MDIx MV9TVEFfSU5GT19JTlZBTElELAo+PiBAQCAtNDEzLDYgKzQxNSw4IEBAIGVudW0gbmw4MDIxMV9z dGFfaW5mbyB7Cj4+ICAgICAgIE5MODAyMTFfU1RBX0lORk9fTExJRCwKPj4gICAgICAgTkw4MDIx MV9TVEFfSU5GT19QTElELAo+PiAgICAgICBOTDgwMjExX1NUQV9JTkZPX1BMSU5LX1NUQVRFLAo+ PiArICAgICBOTDgwMjExX1NUQV9JTkZPX1NJR05BTCwKPj4gKyAgICAgTkw4MDIxMV9TVEFfSU5G T19UWF9CSVRSQVRFLAo+Pgo+PiAgICAgICAvKiBrZWVwIGxhc3QgKi8KPj4gICAgICAgX19OTDgw MjExX1NUQV9JTkZPX0FGVEVSX0xBU1QsCj4+IGRpZmYgLS1naXQgYS9pbmNsdWRlL25ldC9jZmc4 MDIxMS5oIGIvaW5jbHVkZS9uZXQvY2ZnODAyMTEuaAo+PiBpbmRleCAxZDU3ODM1Li5mZDk5NjRj IDEwMDY0NAo+PiAtLS0gYS9pbmNsdWRlL25ldC9jZmc4MDIxMS5oCj4+ICsrKyBiL2luY2x1ZGUv bmV0L2NmZzgwMjExLmgKPj4gQEAgLTE2Nyw2ICsxNjcsOCBAQCBzdHJ1Y3Qgc3RhdGlvbl9wYXJh bWV0ZXJzIHsKPj4gICAqIEBTVEFUSU9OX0lORk9fTExJRDogQGxsaWQgZmlsbGVkCj4+ICAgKiBA U1RBVElPTl9JTkZPX1BMSUQ6IEBwbGlkIGZpbGxlZAo+PiAgICogQFNUQVRJT05fSU5GT19QTElO S19TVEFURTogQHBsaW5rX3N0YXRlIGZpbGxlZAo+PiArICogQFNUQVRJT05fSU5GT19TSUdOQUw6 IEBzaWduYWwgZmlsbGVkCj4+ICsgKiBAU1RBVElPTl9JTkZPX1RYX0JJVFJBVEU6IEB0eF9iaXRy YXRlIGZpbGxlZAo+PiAgICovCj4+ICBlbnVtIHN0YXRpb25faW5mb19mbGFncyB7Cj4+ICAgICAg IFNUQVRJT05fSU5GT19JTkFDVElWRV9USU1FICAgICAgPSAxPDwwLAo+PiBAQCAtMTc1LDYgKzE3 Nyw4IEBAIGVudW0gc3RhdGlvbl9pbmZvX2ZsYWdzIHsKPj4gICAgICAgU1RBVElPTl9JTkZPX0xM SUQgICAgICAgICAgICAgICA9IDE8PDMsCj4+ICAgICAgIFNUQVRJT05fSU5GT19QTElEICAgICAg ICAgICAgICAgPSAxPDw0LAo+PiAgICAgICBTVEFUSU9OX0lORk9fUExJTktfU1RBVEUgICAgICAg ID0gMTw8NSwKPj4gKyAgICAgU1RBVElPTl9JTkZPX1NJR05BTCAgICAgICAgICAgICA9IDE8PDYs Cj4+ICsgICAgIFNUQVRJT05fSU5GT19UWF9CSVRSQVRFICAgICAgICAgPSAxPDw3LAo+PiAgfTsK Pj4KPj4gIC8qKgo+PiBAQCAtMTg5LDYgKzE5Myw4IEBAIGVudW0gc3RhdGlvbl9pbmZvX2ZsYWdz IHsKPj4gICAqIEBsbGlkOiBtZXNoIGxvY2FsIGxpbmsgaWQKPj4gICAqIEBwbGlkOiBtZXNoIHBl ZXIgbGluayBpZAo+PiAgICogQHBsaW5rX3N0YXRlOiBtZXNoIHBlZXIgbGluayBzdGF0ZQo+PiAr ICogQHNpZ25hbDogc2lnbmFsIHN0cmVuZ3RoIG9mIGxhc3QgcmVjZWl2ZWQgcGFja2FnZSBpbiBk Qm0KPj4gKyAqIEB0eF9iaXRyYXRlOiBjdXJyZW50IHVuaWNhc3QgdHggcmF0ZSBpbiAxMDAga2Jp dC9zZWMKPj4gICAqLwo+PiAgc3RydWN0IHN0YXRpb25faW5mbyB7Cj4+ICAgICAgIHUzMiBmaWxs ZWQ7Cj4+IEBAIC0xOTgsNiArMjA0LDggQEAgc3RydWN0IHN0YXRpb25faW5mbyB7Cj4+ICAgICAg IHUxNiBsbGlkOwo+PiAgICAgICB1MTYgcGxpZDsKPj4gICAgICAgdTggcGxpbmtfc3RhdGU7Cj4+ ICsgICAgIHU4IHNpZ25hbDsKPj4gKyAgICAgdTE2IHR4X2JpdHJhdGU7Cj4+ICB9Owo+Pgo+PiAg LyoqCj4+IGRpZmYgLS1naXQgYS9uZXQvbWFjODAyMTEvY2ZnLmMgYi9uZXQvbWFjODAyMTEvY2Zn LmMKPj4gaW5kZXggMTY0MjNmOS4uZjZlZDViNSAxMDA2NDQKPj4gLS0tIGEvbmV0L21hYzgwMjEx L2NmZy5jCj4+ICsrKyBiL25ldC9tYWM4MDIxMS9jZmcuYwo+PiBAQCAtMzA3LDE0ICszMDcsMjQg QEAgc3RhdGljIGludCBpZWVlODAyMTFfY29uZmlnX2RlZmF1bHRfa2V5KHN0cnVjdCB3aXBoeQo+ PiAqd2lwaHksCj4+ICBzdGF0aWMgdm9pZCBzdGFfc2V0X3NpbmZvKHN0cnVjdCBzdGFfaW5mbyAq c3RhLCBzdHJ1Y3Qgc3RhdGlvbl9pbmZvICpzaW5mbykKPj4gIHsKPj4gICAgICAgc3RydWN0IGll ZWU4MDIxMV9zdWJfaWZfZGF0YSAqc2RhdGEgPSBzdGEtPnNkYXRhOwo+PiArICBzdHJ1Y3QgaWVl ZTgwMjExX3N1cHBvcnRlZF9iYW5kICpzYmFuZDsKPj4KPj4gICAgICAgc2luZm8tPmZpbGxlZCA9 IFNUQVRJT05fSU5GT19JTkFDVElWRV9USU1FIHwKPj4gICAgICAgICAgICAgICAgICAgICAgIFNU QVRJT05fSU5GT19SWF9CWVRFUyB8Cj4+IC0gICAgICAgICAgICAgICAgICAgICBTVEFUSU9OX0lO Rk9fVFhfQllURVM7Cj4+ICsgICAgICAgICAgICAgICAgICAgICBTVEFUSU9OX0lORk9fVFhfQllU RVMgfAo+PiArICAgICAgICAgICAgICAgICAgICAgU1RBVElPTl9JTkZPX1NJR05BTCB8Cj4+ICsg ICAgICAgICAgICAgICAgICAgICBTVEFUSU9OX0lORk9fVFhfQklUUkFURTsKPj4KPj4gICAgICAg c2luZm8tPmluYWN0aXZlX3RpbWUgPSBqaWZmaWVzX3RvX21zZWNzKGppZmZpZXMgLSBzdGEtPmxh c3RfcngpOwo+PiAgICAgICBzaW5mby0+cnhfYnl0ZXMgPSBzdGEtPnJ4X2J5dGVzOwo+PiAgICAg ICBzaW5mby0+dHhfYnl0ZXMgPSBzdGEtPnR4X2J5dGVzOwo+PiArICAgICBzaW5mby0+c2lnbmFs ID0gc3RhLT5sYXN0X3NpZ25hbDsKPj4gKwo+PiArICAgICBzYmFuZCA9IHN0YS0+bG9jYWwtPmh3 LndpcGh5LT5iYW5kc1tzdGEtPmxvY2FsLT5ody5jb25mLmNoYW5uZWwtPmJhbmRdOwo+PiArICAg ICBpZiAoIShzdGEtPmxhc3RfdHhfcmF0ZS5mbGFncyAmIElFRUU4MDIxMV9UWF9SQ19NQ1MpKQo+ PiArICAgICAgIHNpbmZvLT50eF9iaXRyYXRlID0gc2JhbmQtPmJpdHJhdGVzW3N0YS0+bGFzdF90 eF9yYXRlLmlkeF0uYml0cmF0ZTsKPj4gKyAgICAgZWxzZQo+PiArICAgICAgIHNpbmZvLT50eF9i aXRyYXRlID0gMDsKPgo+IEl0IHdvdWxkIGJlIG5pY2UgdG8gZ2V0IHRoaXMgZmlndXJlZCBvdXQg YmVmb3JlIGFkZGluZyBpdC4gV2UgZ290IHJhbmRvbQo+IGNvbXBsYWludHMgZnJvbSB1c2VycyBj bGFpbWluZyA4MDIuMTFuIHdhc24ndCB3b3JraW5nIGJlZm9yZSBiZWNhdXNlCj4gaXdjb25maWcg ZGlkbid0IHJlcG9ydCBhIGdvb2QgcmF0ZS4gVXNlcnMgd2lsbCB0cnVzdCBpdCBzbyBJJ2QgcmF0 aGVyCj4gc2VlIHRoaXMgZ28gaW4gd2l0aCBNQ1MgcmF0ZSBmaWd1cmVkIG91dCBhcyBwYXJ0IG9m IHRoZSBBUEkgdG8gYXZvaWQKPiBzdWNoIHJlcG9ydHMuIFdvdWxkIGl0IGJlIHBvc3NpYmxlIGZv ciB5b3UgdG8gd29yayBvbiB0aGF0Pwo+Cj4gVGhpcyBtaWdodCBjb21lIGluIGhhbmR5Ogo+Cj4g aHR0cDovL3dpcmVsZXNzLmtlcm5lbC5vcmcvZW4vZGV2ZWxvcGVycy9Eb2N1bWVudGF0aW9uL2ll ZWU4MDIxMS84MDIuMTFuI01DU1JhdGVzCj4KPiBXaGF0IHlvdSBuZWVkIHRoZW4gaXMgdGhlIGd1 YXJkIGludGVydmFsLCB0aGUgTUNTIHJhdGUgaW5kZXggYW5kIHRoZQo+IG51bWJlciBvZiBzdHJl YW1zIGJlaW5nIHVzZWQgZm9yIGNvbW11bmljYXRpb24uCgpBbHNvIGhvdyBhYm91dCB3ZSBhZGQg YSBsYXN0IFRYIHJhdGUgYW5kIGxhc3QgUlggcmF0ZSBzbyB3ZSBnZXQgYm90aD8KCiBMdWlzCg==
Re: RFC Patch v2: Add signal strength to nl80211station info
In reply to Luis R. RodriguezQuoted 10 lines · On Monday 01 December 2008 18:39:48 Luis R. Rodriguez wrote:
It would be nice to get this figured out before adding it. We got random complaints from users claiming 802.11n wasn't working before because iwconfig didn't report a good rate. Users will trust it so I'd rather see this go in with MCS rate figured out as part of the API to avoid such reports. Would it be possible for you to work on that?
This might come in handy:
http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n#MC
SRates
I will look at it... thank you for the link.
Quoted 4 lines
What you need then is the guard interval, the MCS rate index and the number of streams being used for communication.
Also how about we add a last TX rate and last RX rate so we get both?
Sounds like a good idea... have to look at the code of mac80211 a little bit more (I just copied the TX-rate thing from the wext code), but I really like the idea.
Henning
RFC Patch v2: Add signal strength to nl80211station info
In reply to Luis R. RodriguezAm Monday 01 December 2008 18:39:48 schrieb Luis R. Rodriguez:
Quoted 11 lines
It would be nice to get this figured out before adding it. We got random complaints from users claiming 802.11n wasn't working before because iwconfig didn't report a good rate. Users will trust it so I'd rather see this go in with MCS rate figured out as part of the API to avoid such reports. Would it be possible for you to work on that?
This might come in handy:
http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n#MC
SRates
Quoted 6 lines
What you need then is the guard interval, the MCS rate index and the number of streams being used for communication.
Also how about we add a last TX rate and last RX rate so we get both?
Luis
Changes since v1:
- removed noise and quality from station info in NL80211
- added bandwith to station info in NL80211
- changed name of patch file to nl80211ext_v2.patch
Changes since v2:
- added kernel comment lines for new fields/enums
- changed name of "bandwith" field to tx_bitrate
Changes since v3:
- added rx_bitrate to station info and sta_info
- remember bitrate of last received unicast packet to this station
- decode 802.11n MCS index for nl80211
(maybe this should be ported to WEXT too ?)
The last part is untested because I own only one 802.11n capable wlan device, so I cannot create an adhoc network with 802.11n, but I hope I got the code right. The four data arrays and sta_get_80211n_bitrate() should be maybe moved to another file, but I'm not sure where to put it.
I have attached a patched station.c for the iw command, so the changes can be tested with "iw dev wlan0 station dump":
root@.....:~/iw.new# ./iw dev wlan0 station dump
Station xx:xx:xx:xx:xx:xx (on wlan0)
inactive time: 228 ms
rx bytes: 4247
tx bytes: 932
signal: -68 dBm
rx-bitrate: 12.0 MBit/s
tx-bitrate: 6.0 MBit/s Henning
*************************************************
Diplom Informatiker Henning Rogge
Forschungsgesellschaft für
Angewandte Naturwissenschaften e. V. (FGAN)
Neuenahrer Str. 20, 53343 Wachtberg, Germany
Tel.: 0049 (0)228 9435-961
Fax: 0049 (0)228 9435-685
E-Mail: [email protected]
Web: www.fgan.de
************************************************
Sitz der Gesellschaft: Bonn
Registergericht: Amtsgericht Bonn VR 2530
Vorstand: Dr. rer. nat. Ralf Dornhaus (Vors.), Prof. Dr. Joachim Ender (Stellv.)
--------------------------------------------------------
include/linux/nl80211.h +1 -0
@@ -404,6 +404,10 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received package (u8,
dBm)
+ * @NL80211_STA_INFO_RX_BITRATE: bitrate of last received unicast packet
+ * (u16, 100 kbit/s)
+ * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate (u16, 100 kbit/s) */
enum nl80211_sta_info {
__NL80211_STA_INFO_INVALID,
@@ -413,6 +417,9 @@ enum nl80211_sta_info {
NL80211_STA_INFO_LLID,
NL80211_STA_INFO_PLID,
NL80211_STA_INFO_PLINK_STATE,
+ NL80211_STA_INFO_SIGNAL,
+ NL80211_STA_INFO_RX_BITRATE,
+ NL80211_STA_INFO_TX_BITRATE,
/* keep last */
__NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +12 -0
@@ -167,6 +167,9 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_RX_BITRATE: @rx_bitrate filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate filled */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -175,6 +178,9 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , +STATION_INFO_RX_BITRATE =1 <<7 , + STATION_INFO_TX_BITRATE = 1<<8, };/**
@@ -189,6 +195,9 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received package in dBm +* @rx_bitrate: bitrate of last received unicast packet in 100 kbit/sec +* @tx_bitrate: current unicast tx rate in 100 kbit/sec */ struct station_info {u32 filled;
@@ -198,6 +207,9 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +u16 rx_bitrate; +u16 tx_bitrate; };/**
net/mac80211/cfg.c +1 -0
@@ -17,6 +17,41 @@#include "rate.h" #include "mesh.h" +/* bitrate of 802.11n ht20 connections with 800ns guard interval in 100kbit/s
*/
+const u16 ieee80211n_ht20_gi800[] = {
+ 65, 130, 195, 260, 390, 520, 585, 650, + 130, 260, 390, 520, 780, 1040, 1170, 1300, + 195, 390, 585, 780, 1170, 1560, 1755, 1950, + 260, 520, 780, 1040, 1560, 2080, 2340, 2600
+};
+
+/* bitrate of 802.11n ht20 connections with 400ns guard interval
+ * in 100kbit/s per spatial stream */
+const u16 ieee80211n_ht20_gi400[] = {
+ 72, 144, 217, 289, 433, 578, 650, 722, + 144, 289, 433, 578, 867, 1156, 1300, 1440, + 217, 433, 650, 867, 1300, 1733, 1950, 2167, + 289, 578, 867, 1157, 1733, 2311, 2600, 2889
+};
+
+/* bitrate of 802.11n ht40 connections with 800ns guard interval
+ * in 100kbit/s per spatial stream */
+const u16 ieee80211n_ht40_gi800[] = {
+ 135, 270, 405, 540, 810, 1080, 1215, 1350, + 270, 540, 810, 1080, 1620, 2160, 2430, 2700, + 405, 810, 1215, 1620, 2430, 3240, 3645, 4050, + 540, 1080, 1620, 2160, 3240, 4320, 4860, 5400
+};
+
+/* bitrate of 802.11n ht40 connections with 400ns guard interval
+ * in 100kbit/s per spatial stream */
+const u16 ieee80211n_ht40_gi400[] = {
+ 150, 300, 450, 600, 900, 1200, 1350, 1500, + 300, 600, 900, 1200, 1800, 2400, 2700, 3000, + 450, 900, 1350, 1800, 2700, 3600, 4050, 4500, + 600, 1200, 1800, 2400, 3600, 4800, 5400, 6000
+};
+
static bool nl80211_type_check(enum nl80211_iftype type)
{
switch (type) {
@@ -304,18 +339,50 @@ static int ieee80211_config_default_key(struct wiphy *wiphy,
return 0;
}
+static u16 sta_get_80211n_bitrate(struct ieee80211_tx_rate *rate) {
+ if (!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) {
+ if (!(rate->flags & IEEE80211_TX_RC_SHORT_GI))
+ return ieee80211n_ht20_gi800[rate->idx];
+
+ return ieee80211n_ht20_gi400[rate->idx];
+ }
+ else {
+ if (!(rate->flags & IEEE80211_TX_RC_SHORT_GI))
+ return ieee80211n_ht40_gi800[rate->idx];
+
+ return ieee80211n_ht40_gi400[rate->idx];
+ }
+}
+
static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) {
struct ieee80211_sub_if_data *sdata = sta->sdata;
sinfo->filled = STATION_INFO_INACTIVE_TIME |
STATION_INFO_RX_BYTES |
- STATION_INFO_TX_BYTES;
+ STATION_INFO_TX_BYTES |
+ STATION_INFO_RX_BITRATE |
+ STATION_INFO_TX_BITRATE;
sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes;
sinfo->tx_bytes = sta->tx_bytes;
+ if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
+ sinfo->filled |= STATION_INFO_SIGNAL;
+ sinfo->signal = sta->last_signal;
+ }
+
+ sinfo->rx_bitrate = sta->last_rxrate_unicast;
+
+ if (!(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) {
+ struct ieee80211_supported_band *sband; + sband = sta->local->hw.wiphy->bands[sta->local->hw.conf.channel->band]; + sinfo->tx_bitrate = sband->bitrates[sta->last_tx_rate.idx].bitrate;
+ }
+ else
+ sinfo->tx_bitrate = sta_get_80211n_bitrate(&sta->last_tx_rate);
+
if (ieee80211_vif_is_mesh(&sdata->vif)) {
#ifdef CONFIG_MAC80211_MESH
sinfo->filled |= STATION_INFO_LLID |
net/mac80211/rx.c +8 -1
@@ -720,8 +720,15 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)if (rx->sdata->vif.type ==NL80211_IFTYPE_ADHOC ) {u8 *bssid =ieee80211_get_bssid (hdr, rx->skb->len,NL80211_IFTYPE_ADHOC ); -if (compare_ether_addr (bssid, rx->sdata->u.sta.bssid) ==0 ) +if (compare_ether_addr (bssid, rx->sdata->u.sta.bssid) ==0 ) { sta->last_rx = jiffies; + +/* only update last_rxrate_unicast when we receive a +* unicast packet for this station */ +if (compare_ether_addr (hdr->addr1, sta->sta.addr)) { + sta->last_rxrate_unicast = rx->rate->bitrate; + } + } }else if (!is_multicast_ether_addr (hdr->addr1) || rx->sdata->vif.type ==NL80211_IFTYPE_STATION ) {
net/mac80211/sta_info.h +1 -0
@@ -254,6 +254,7 @@ struct sta_info {int last_signal;int last_qual;int last_noise; +u16 last_rxrate_unicast;__le16 last_seq_ctrl[NUM_RX_DATA_QUEUES ];/* Updated from TX status path only, no locking requirements */
net/wireless/nl80211.c +0 -0
@@ -1057,6 +1057,15 @@ static int nl80211_send_station(struct sk_buff *msg,
u32 pid, u32 seq,
if (sinfo->filled & STATION_INFO_PLINK_STATE)
NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
sinfo->plink_state);
+ if (sinfo->filled & STATION_INFO_SIGNAL)
+ NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
+ sinfo->signal);
+ if (sinfo->filled & STATION_INFO_RX_BITRATE)
+ NLA_PUT_U16(msg, NL80211_STA_INFO_RX_BITRATE,
+ sinfo->rx_bitrate);
+ if (sinfo->filled & STATION_INFO_TX_BITRATE)
+ NLA_PUT_U16(msg, NL80211_STA_INFO_TX_BITRATE,
+ sinfo->tx_bitrate);
nla_nest_end(msg, sinfoattr);
include/linux/nl80211.h +7 -0
@@ -404,6 +404,10 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received package (u8, dBm) +* @NL80211_STA_INFO_RX_BITRATE: bitrate of last received unicast packet +* (u16, 100 kbit/s) +* @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate (u16, 100 kbit/s) */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID,
@@ -413,6 +417,9 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_RX_BITRATE , +NL80211_STA_INFO_TX_BITRATE ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +12 -0
@@ -167,6 +167,9 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_RX_BITRATE: @rx_bitrate filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate filled */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -175,6 +178,9 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , +STATION_INFO_RX_BITRATE =1 <<7 , + STATION_INFO_TX_BITRATE = 1<<8, };/**
@@ -189,6 +195,9 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received package in dBm +* @rx_bitrate: bitrate of last received unicast packet in 100 kbit/sec +* @tx_bitrate: current unicast tx rate in 100 kbit/sec */ struct station_info {u32 filled;
@@ -198,6 +207,9 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +u16 rx_bitrate; +u16 tx_bitrate; };/**
net/mac80211/cfg.c +68 -1
92 lines not on this page · raw message
net/mac80211/rx.c +8 -1
@@ -720,8 +720,15 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)if (rx->sdata->vif.type ==NL80211_IFTYPE_ADHOC ) {u8 *bssid =ieee80211_get_bssid (hdr, rx->skb->len,NL80211_IFTYPE_ADHOC ); -if (compare_ether_addr (bssid, rx->sdata->u.sta.bssid) ==0 ) +if (compare_ether_addr (bssid, rx->sdata->u.sta.bssid) ==0 ) { sta->last_rx = jiffies; + +/* only update last_rxrate_unicast when we receive a +* unicast packet for this station */ +if (compare_ether_addr (hdr->addr1, sta->sta.addr)) { + sta->last_rxrate_unicast = rx->rate->bitrate; + } + } }else if (!is_multicast_ether_addr (hdr->addr1) || rx->sdata->vif.type ==NL80211_IFTYPE_STATION ) {
net/mac80211/sta_info.h +1 -0
@@ -254,6 +254,7 @@ struct sta_info {int last_signal;int last_qual;int last_noise; +u16 last_rxrate_unicast;__le16 last_seq_ctrl[NUM_RX_DATA_QUEUES ];/* Updated from TX status path only, no locking requirements */
net/wireless/nl80211.c +9 -0
@@ -1057,6 +1057,15 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,if (sinfo->filled &STATION_INFO_PLINK_STATE )NLA_PUT_U8 (msg,NL80211_STA_INFO_PLINK_STATE , sinfo->plink_state); +if (sinfo->filled &STATION_INFO_SIGNAL ) +NLA_PUT_U8 (msg,NL80211_STA_INFO_SIGNAL , + sinfo->signal); +if (sinfo->filled &STATION_INFO_RX_BITRATE ) +NLA_PUT_U16 (msg,NL80211_STA_INFO_RX_BITRATE , + sinfo->rx_bitrate); +if (sinfo->filled &STATION_INFO_TX_BITRATE ) +NLA_PUT_U16 (msg,NL80211_STA_INFO_TX_BITRATE , + sinfo->tx_bitrate);nla_nest_end (msg, sinfoattr);
#include <net/if.h>
#include <errno.h>
#include <string.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/family.h>
#include <netlink/genl/ctrl.h>
#include <netlink/msg.h>
#include <netlink/attr.h>
#include "nl80211.h"
#include "iw.h"
enum plink_state {
LISTEN,
OPN_SNT,
OPN_RCVD,
CNF_RCVD,
ESTAB,
HOLDING,
BLOCKED
};
enum plink_actions {
PLINK_ACTION_UNDEFINED,
PLINK_ACTION_OPEN,
PLINK_ACTION_BLOCK,
};
static int print_sta_handler(struct nl_msg *msg, void *arg)
{
struct nlattr *tb[NL80211_ATTR_MAX + 1];
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
char mac_addr[20], state_name[10], dev[20];
static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
[NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
[NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 },
[NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
[NL80211_STA_INFO_LLID] = { .type = NLA_U16 },
[NL80211_STA_INFO_PLID] = { .type = NLA_U16 },
[NL80211_STA_INFO_PLINK_STATE] = { .type = NLA_U8 },
[NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
[NL80211_STA_INFO_RX_BITRATE] = { .type = NLA_U16 },
[NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_U16 },
};
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
/*
* TODO: validate the interface and mac address!
* Otherwise, there's a race condition as soon as
* the kernel starts sending station notifications.
*/
if (!tb[NL80211_ATTR_STA_INFO]) {
fprintf(stderr, "sta stats missing!");
return NL_SKIP;
}
if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
tb[NL80211_ATTR_STA_INFO],
stats_policy)) {
fprintf(stderr, "failed to parse nested attributes!");
return NL_SKIP;
}
mac_addr_n2a(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
printf("Station %s (on %s)", mac_addr, dev);
if (sinfo[NL80211_STA_INFO_INACTIVE_TIME])
printf("\n\tinactive time:\t%d ms",
nla_get_u32(sinfo[NL80211_STA_INFO_INACTIVE_TIME]));
if (sinfo[NL80211_STA_INFO_RX_BYTES])
printf("\n\trx bytes:\t%d",
nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES]));
if (sinfo[NL80211_STA_INFO_TX_BYTES])
printf("\n\ttx bytes:\t%d",
nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES]));
if (sinfo[NL80211_STA_INFO_SIGNAL])
printf("\n\tsignal: \t%d dBm",
(int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]));
if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
int bitrate = nla_get_u16(sinfo[NL80211_STA_INFO_RX_BITRATE]);
printf("\n\trx-bitrate:\t%d.%01d MBit/s", bitrate/10, bitrate % 10);
}
if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
int bitrate = nla_get_u16(sinfo[NL80211_STA_INFO_TX_BITRATE]);
printf("\n\ttx-bitrate:\t%d.%01d MBit/s", bitrate/10, bitrate % 10);
}
if (sinfo[NL80211_STA_INFO_LLID])
printf("\n\tmesh llid:\t%d",
nla_get_u16(sinfo[NL80211_STA_INFO_LLID]));
if (sinfo[NL80211_STA_INFO_PLID])
printf("\n\tmesh plid:\t%d",
nla_get_u16(sinfo[NL80211_STA_INFO_PLID]));
if (sinfo[NL80211_STA_INFO_PLINK_STATE]) {
switch (nla_get_u16(sinfo[NL80211_STA_INFO_PLINK_STATE])) {
case LISTEN:
strcpy(state_name, "LISTEN");
break;
case OPN_SNT:
strcpy(state_name, "OPN_SNT");
break;
case OPN_RCVD:
strcpy(state_name, "OPN_RCVD");
break;
case CNF_RCVD:
strcpy(state_name, "CNF_RCVD");
break;
case ESTAB:
strcpy(state_name, "ESTAB");
break;
case HOLDING:
strcpy(state_name, "HOLDING");
break;
case BLOCKED:
strcpy(state_name, "BLOCKED");
break;
default:
strcpy(state_name, "UNKNOWN");
break;
}
printf("\n\tmesh plink:\t%s", state_name);
}
printf("\n");
return NL_SKIP;
}static int handle_station_get(struct nl_cb *cb,
struct nl_msg *msg, int argc, char **argv)
{
unsigned char mac_addr[ETH_ALEN];
if (argc < 1)
return 1;
if (mac_addr_a2n(mac_addr, argv[0])) {
fprintf(stderr, "invalid mac address\n");
return 2;
}
argc--;
argv++;
if (argc)
return 1;
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_sta_handler, NULL);
return 0;
nla_put_failure:
return -ENOBUFS;
}
COMMAND(station, get, "<MAC address>",
NL80211_CMD_GET_STATION, 0, CIB_NETDEV, handle_station_get);
COMMAND(station, del, "<MAC address>",
NL80211_CMD_DEL_STATION, 0, CIB_NETDEV, handle_station_get);static int handle_station_set(struct nl_cb *cb,
struct nl_msg *msg, int argc, char **argv)
{
unsigned char plink_action;
unsigned char mac_addr[ETH_ALEN];
if (argc < 3)
return 1;
if (mac_addr_a2n(mac_addr, argv[0])) {
fprintf(stderr, "invalid mac address\n");
return 2;
}
argc--;
argv++;
if (strcmp("plink_action", argv[0]) != 0)
return 1;
argc--;
argv++;
if (strcmp("open", argv[0]) == 0)
plink_action = PLINK_ACTION_OPEN;
else if (strcmp("block", argv[0]) == 0)
plink_action = PLINK_ACTION_BLOCK;
else {
fprintf(stderr, "plink action not supported\n");
return 2;
}
argc--;
argv++;
if (argc)
return 1;
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
NLA_PUT_U8(msg, NL80211_ATTR_STA_PLINK_ACTION, plink_action);
return 0;
nla_put_failure:
return -ENOBUFS;
}
COMMAND(station, set, "<MAC address> plink_action <open|block>",
NL80211_CMD_SET_STATION, 0, CIB_NETDEV, handle_station_set);static int handle_station_dump(struct nl_cb *cb,
struct nl_msg *msg, int argc, char **argv)
{
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_sta_handler, NULL);
return 0;
}
COMMAND(station, dump, NULL,
NL80211_CMD_GET_STATION, NLM_F_DUMP, CIB_NETDEV, handle_station_dump);Re: RFC Patch v2: Add signal strength to nl80211station info
include/linux/nl80211.h enum nl80211_sta_flags { · line 408
Quoted 10 lines · Henning Rogge
include/linux/nl80211.h +1
-0@@ -404,6 +404,10 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received package (u8, dBm)
Shouldn't this be s8?
include/net/cfg80211.h struct station_parameters { · line 170
Quoted 9 lines
include/net/cfg80211.h +1
-0@@ -167,6 +167,9 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled
Can you extend this to indicate drivers which enable this must pass the singal in dBm (IEEE80211_HW_SIGNAL_DBM for mac80211 drivers) as that is what cfg80211 expects?
This is important as mac80211 drivers not using IEEE80211_HW_SIGNAL_DBM will luck out of getting signal reports. This means these drivers won't get signal reports right now:
adm8211.c:1865: dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;rtl818x/rtl8187_dev.c:1416: dev->flags |= IEEE80211_HW_SIGNAL_UNSPEC;rtl818x/rtl8180_dev.c:900: IEEE80211_HW_SIGNAL_UNSPEC;zd1211rw/zd_mac.c:972: IEEE80211_HW_SIGNAL_DB;
I guess this is the iffy part... I'll see if zd1211rw can somehow use dBm though.
Quoted 34 lines
net/mac80211/cfg.c +25
-0@@ -17,6 +17,41 @@#include "rate.h" #include "mesh.h" +/* bitrate of 802.11n ht20 connections with 800ns guard interval in 100kbit/s */ +const u16 ieee80211n_ht20_gi800[] = { +65 ,130 ,195 ,260 ,390 ,520 ,585 ,650 , +130 ,260 ,390 ,520 ,780 ,1040 ,1170 ,1300 , +195 ,390 ,585 ,780 ,1170 ,1560 ,1755 ,1950 , +260 ,520 ,780 ,1040 ,1560 ,2080 ,2340 ,2600 +}; + +/* bitrate of 802.11n ht20 connections with 400ns guard interval +* in 100kbit/s per spatial stream */ +const u16 ieee80211n_ht20_gi400[] = { +72 ,144 ,217 ,289 ,433 ,578 ,650 ,722 , +144 ,289 ,433 ,578 ,867 ,1156 ,1300 ,1440 , +217 ,433 ,650 ,867 ,1300 ,1733 ,1950 ,2167 , +289 ,578 ,867 ,1157 ,1733 ,2311 ,2600 ,2889 +}; + +/* bitrate of 802.11n ht40 connections with 800ns guard interval +* in 100kbit/s per spatial stream */ +const u16 ieee80211n_ht40_gi800[] = { +135 ,270 ,405 ,540 ,810 ,1080 ,1215 ,1350 , +270 ,540 ,810 ,1080 ,1620 ,2160 ,2430 ,2700 , +405 ,810 ,1215 ,1620 ,2430 ,3240 ,3645 ,4050 , +540 ,1080 ,1620 ,2160 ,3240 ,4320 ,4860 ,5400 +};
net/mac80211/cfg.c line 55
Quoted 10 lines
net/mac80211/cfg.c +10
-0+ +/* bitrate of 802.11n ht40 connections with 400ns guard interval +* in 100kbit/s per spatial stream */ +const u16 ieee80211n_ht40_gi400[] = { +150 ,300 ,450 ,600 ,900 ,1200 ,1350 ,1500 , +300 ,600 ,900 ,1200 ,1800 ,2400 ,2700 ,3000 , +450 ,900 ,1350 ,1800 ,2700 ,3600 ,4050 ,4500 , +600 ,1200 ,1800 ,2400 ,3600 ,4800 ,5400 ,6000 +}; +
Awesome stuff, now come to think of it, perhaps its best we let userspace do the calculation and we just give it the last RX/TX guard interval and the MCS index? Technically speaking it seems we don't have duplicate rates though so a reverse map is possible but it seems useful to just provide the information directly.
Any thoughts?
Luis
Re: RFC Patch v2: Add signal strength to nl80211station info
Quoted 7 lines
Quoted 6 lines
(quoted diff) +0
-0@@ -404,6 +404,10 @@ enum nl80211_sta_flags { * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to thisstation) * @__NL80211_STA_INFO_AFTER_LAST: internal
* @NL80211_STA_INFO_MAX: highest possible station info attribute
+ * @NL80211_STA_INFO_SIGNAL: signal strength of last received package (u8, dBm)Shouldn't this be s8?
I did not find macros for nl80211 to add signed values... so its just "say it's signed, but use the unsigned macro" ? If yes I will change the documentation.
Quoted 5 lines
Quoted 5 lines
include/net/cfg80211.h +0
-0@@ -167,6 +167,9 @@ struct station_parameters {
Quoted 8 lines
include/net/cfg80211.h struct station_parameters { · line 170
Quoted 4 lines
include/net/cfg80211.h +1
-0* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled Can you extend this to indicate drivers which enable this must pass the singal in dBm (
IEEE80211_HW_SIGNAL_DBMfor mac80211 drivers) as that is what cfg80211 expects?
The flag is only set if the driver sets the IEEE80211_HW_SIGNAL_DBM flag. cfg.c:
+ if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { + sinfo->filled |= STATION_INFO_SIGNAL;
+ sinfo->signal = sta->last_signal;
+ }
But it might be better to explain this in the documentation.
Quoted 3 lines
This is important as mac80211 drivers not using
IEEE80211_HW_SIGNAL_DBMwill luck out of getting signal reports. This means these drivers won't get signal reports right now:
I know... (did search for the HW_SIGNAL flags in the drivers)
Quoted 2 lines
I guess this is the iffy part... I'll see if zd1211rw can somehow use dBm though.
That would be good I think.
Quoted 5 lines
Awesome stuff, now come to think of it, perhaps its best we let userspace do the calculation and we just give it the last RX/TX guard interval and the MCS index? Technically speaking it seems we don't have duplicate rates though so a reverse map is possible but it seems useful to just provide the information directly.
the problem of this approach would be that every userspace calculation would
have to do this calculation on it's own. Whats about transmitting "basic datarate", "number of spatial streams" and "flags" (short/long GI, 20/40 Mhz width) to userspace ? This way it would be just a multiplication to get the total bandwith, but it still can easily be reverse mapped into MCS with some arithmetics.
Henning
Re: RFC Patch v2: Add signal strength to nl80211station info
Quoted 2 lines · Henning Rogge
Quoted 2 lines
Review enum nl80211_sta_flags { · line 404
Quoted 2 lines
(quoted diff) +0
-0@@ -404,6 +404,10 @@ enum nl80211_sta_flags { * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to =
this
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
station) * @__NL80211_STA_INFO_AFTER_LAST: internal
* @NL80211_STA_INFO_MAX: highest possible station info attribut=
e
Quoted 1 line
Quoted 1 line
Quoted 1 line
+ * @NL80211_STA_INFO_SIGNAL: signal strength of last received pa=
ckage
Quoted 3 lines
Quoted 2 lines
Quoted 1 line
(u8, dBm)
Shouldn't this be s8?
I did not find macros for nl80211 to add signed values... so its just=
"say=20
Quoted 2 lines
it's signed, but use the unsigned macro" ? If yes I will change the=20 documentation.
Ah no, nevermind me, netlink doesn't have singed values.
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
include/net/cfg80211.h +0
-0
Quoted 8 lines
Quoted 8 lines
include/net/cfg80211.h struct station_parameters { · line 170
Quoted 5 lines
include/net/cfg80211.h +1
-0@@ -167,6 +167,9 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled Can you extend this to indicate drivers which enable this must pass the singal in dBm (
IEEE80211_HW_SIGNAL_DBMfor mac80211 driver=
s)
Quoted 2 lines
Quoted 1 line
as that is what cfg80211 expects?
The flag is only set if the driver sets the
IEEE80211_HW_SIGNAL_DBMf=
lag.
Quoted 2 lines
cfg.c:
+=A0=A0=A0=A0=A0=A0=A0if (sta->local->hw.flags& IEEE80211_HW_SIGNAL_=
DBM) {
Quoted 5 lines
+=A0=A0=A0=A0=A0=A0=A0 =A0sinfo->filled |=3D STATION_INFO_SIGNAL; +=A0=A0=A0=A0=A0=A0=A0 =A0sinfo->signal =3D sta->last_signal; +=A0=A0=A0=A0=A0=A0=A0}=20
But it might be better to explain this in the documentation.
Right.
Quoted 1 line
Quoted 1 line
This is important as mac80211 drivers not using IEEE80211_HW_SIGNAL=
_DBM
Quoted 1 line
Quoted 1 line
will luck out of getting signal reports. This means these drivers w=
on't
Quoted 4 lines
Quoted 1 line
get signal reports right now:
I know... (did search for the
HW_SIGNALflags in the drivers) =20Quoted 1 line
I guess this is the iffy part... I'll see if zd1211rw can somehow u=
se
Quoted 9 lines
Quoted 1 line
dBm though.
That would be good I think.
=20Quoted 5 lines
Awesome stuff, now come to think of it, perhaps its best we let userspace do the calculation and we just give it the last RX/TX guard interval and the MCS index? Technically speaking it seems we don't have duplicate rates though so a reverse map is possible but it seems useful to just provide the information directly.
the problem of this approach would be that every userspace calculati=
on would=20
Quoted 1 line
have to do this calculation on it's own.
True..
Quoted 2 lines
Whats about transmitting "basic=20
datarate"
What's that?
Quoted 1 line
, "number of spatial streams"
No need for this one, the HT mode (ht20 or ht40) and MCS index would give us that.
Quoted 1 line
and "flags" (short/long GI, 20/40 Mhz width) to userspace ?
Well... see below.
Quoted 2 lines
This way it would be just a multiplication to get the=20 total bandwith, but it still can easily be reverse mapped into MCS wi=
th some=20
Quoted 1 line
arithmetics.
I believe to get the throughput you need a lot more info than this, hen= ce
why the table is so big and why you have array index for each MCS index for each HT mode and guard interval.
So... what if we pass the throughput as you have it but also pass the other stuff (flags, and MCS index) just so all userspace apps that want to get last TX/RX guard interval, HT20/HT40, and MCS index doesn't have to have a funky reverse map to get the flags and MCS index= ?
Luis
--
To unsubscribe from this list: send the line "unsubscribe linux-wireles= s" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: RFC Patch v2: Add signal strength to nl80211station info
Am Wednesday 03 December 2008 02:44:30 schrieb Luis R. Rodriguez:
Quoted 4 lines
So... what if we pass the throughput as you have it but also pass the other stuff (flags, and MCS index) just so all userspace apps that want to get last TX/RX guard interval, HT20/HT40, and MCS index doesn't have to have a funky reverse map to get the flags and MCS index?
Changes since v1:
- removed noise and quality from station info in NL80211
- added bandwith to station info in NL80211
- changed name of patch file to nl80211ext_v2.patch
Changes since v2:
- added kernel comment lines for new fields/enums
- changed name of "bandwith" field to tx_bitrate
Changes since v3:
- added rx_bitrate to station info and sta_info
- remember bitrate of last received unicast packet to this station
- decode 802.11n MCS index for nl80211
(maybe this should be ported to WEXT too ?)
Changes since v4:
- added tx_bitrate_flags adn tx_bitrate_mcs field to station info
- added flags for 40Mhz and small guard interval to NL80211 station info
- added mcs field to NL80211 station info
The IEEE80211_TX_RC_40_MHZ_WIDTH flag in nl80211 should work for 802.11g "turbomodes" and 802.11n, the IEEE80211_TX_RC_SHORT_GI is only available if the NL80211_STA_INFO_TX_BITRATE_MCS index is set too. All three fields will be only available if the STATION_INFO_TX_BITRATE field is set. (see station.c)
The whole 802.11n stuff is only compile-tested, but the code works on an atheros 802.11g card.
What do you think about the idea to export the 802.11n transmission rate through the old WExt interface, so iwconfig will show the correct rate too ? But for this the "mcs to bitrate" tables would have to be moved to some other file, so wext.c can access them too (which one ?).
Henning Rogge
*************************************************
Diplom Informatiker Henning Rogge
Forschungsgesellschaft für
Angewandte Naturwissenschaften e. V. (FGAN)
Neuenahrer Str. 20, 53343 Wachtberg, Germany
Tel.: 0049 (0)228 9435-961
Fax: 0049 (0)228 9435-685
E-Mail: [email protected]
Web: www.fgan.de
************************************************
Sitz der Gesellschaft: Bonn
Registergericht: Amtsgericht Bonn VR 2530
Vorstand: Dr. rer. nat. Ralf Dornhaus (Vors.), Prof. Dr. Joachim Ender (Stellv.)
-------------------------------------------------------
include/linux/nl80211.h +1 -0
@@ -404,6 +404,14 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received package (u8,
dBm)
+ * @NL80211_STA_INFO_RX_BITRATE: bitrate of last received unicast packet
+ * (u16, 100 kbit/s)
+ * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate (u16, 100 kbit/s)
+ * @NL80211_STA_INFO_TX_BITRATE_40_MHZ: dual channel transmission (flag)
+ * @NL80211_STA_INFO_TX_BITRATE_MCS: 802.11n MCS index of tx rate (u8)
+ * @NL80211_STA_INFO_TX_BITRATE_SHORT_GI: 802.11n with 400ns GI, 800ns
+ * otherwise, should be ignored if TX_BITRATE_MCS is not set (flag) */
enum nl80211_sta_info {
__NL80211_STA_INFO_INVALID,
@@ -413,6 +421,12 @@ enum nl80211_sta_info {
NL80211_STA_INFO_LLID,
NL80211_STA_INFO_PLID,
NL80211_STA_INFO_PLINK_STATE,
+ NL80211_STA_INFO_SIGNAL,
+ NL80211_STA_INFO_RX_BITRATE,
+ NL80211_STA_INFO_TX_BITRATE,
+ NL80211_STA_INFO_TX_BITRATE_40_MHZ,
+ NL80211_STA_INFO_TX_BITRATE_MCS,
+ NL80211_STA_INFO_TX_BITRATE_SHORT_GI,
/* keep last */
__NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +22 -0
@@ -160,6 +160,8 @@ struct station_parameters {* * Used by the driver to indicate which info in &struct station_info * it has filled in during get_station() or dump_station(). +* Signal strength is only available if driver supports dBm signal +* strength. * * @STATION_INFO_INACTIVE_TIME: @inactive_time filled * @STATION_INFO_RX_BYTES: @rx_bytes filled
@@ -167,6 +169,10 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_RX_BITRATE: @rx_bitrate filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled +* (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -175,6 +181,9 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , +STATION_INFO_RX_BITRATE =1 <<7 , + STATION_INFO_TX_BITRATE = 1<<8, };/**
@@ -189,6 +198,15 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received package in dBm +* @rx_bitrate: bitrate of last received unicast packet in 100 kbit/sec +* @tx_bitrate: current unicast bitrate to this station in 100 kbit/sec +* @tx_bitrate_flags: a binary field with a combination of flags +* IEEE80211_TX_RC_MCS: bitrate_mcs field contains the 802.11n MCS number +* IEEE80211_TX_RC_40_MHZ_WIDTH: 40 Mhz wide channel, 20 Mhz if not set +* IEEE80211_TX_RC_SHORT_GI: 400ns guard interval, 800ns if not set +* @tx_bitrate_mcs: if IEEE80211_TX_RC_MCS is set this is the MCS index +* of a 802.11n transmission, if not it is set to zero */ struct station_info {u32 filled;
@@ -198,6 +216,10 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +u16 rx_bitrate; +u16 tx_bitrate; +u8 tx_bitrate_flags, tx_bitrate_mcs; };/**
net/mac80211/cfg.c +1 -0
@@ -17,6 +17,41 @@#include "rate.h" #include "mesh.h" +/* bitrate of 802.11n ht20 connections with 800ns guard interval in 100kbit/s
*/
+const u16 ieee80211n_ht20_gi800[] = {
+ 65, 130, 195, 260, 390, 520, 585, 650, + 130, 260, 390, 520, 780, 1040, 1170, 1300, + 195, 390, 585, 780, 1170, 1560, 1755, 1950, + 260, 520, 780, 1040, 1560, 2080, 2340, 2600
+};
+
+/* bitrate of 802.11n ht20 connections with 400ns guard interval
+ * in 100kbit/s per spatial stream */
+const u16 ieee80211n_ht20_gi400[] = {
+ 72, 144, 217, 289, 433, 578, 650, 722, + 144, 289, 433, 578, 867, 1156, 1300, 1440, + 217, 433, 650, 867, 1300, 1733, 1950, 2167, + 289, 578, 867, 1157, 1733, 2311, 2600, 2889
+};
+
+/* bitrate of 802.11n ht40 connections with 800ns guard interval
+ * in 100kbit/s per spatial stream */
+const u16 ieee80211n_ht40_gi800[] = {
+ 135, 270, 405, 540, 810, 1080, 1215, 1350, + 270, 540, 810, 1080, 1620, 2160, 2430, 2700, + 405, 810, 1215, 1620, 2430, 3240, 3645, 4050, + 540, 1080, 1620, 2160, 3240, 4320, 4860, 5400
+};
+
+/* bitrate of 802.11n ht40 connections with 400ns guard interval
+ * in 100kbit/s per spatial stream */
+const u16 ieee80211n_ht40_gi400[] = {
+ 150, 300, 450, 600, 900, 1200, 1350, 1500, + 300, 600, 900, 1200, 1800, 2400, 2700, 3000, + 450, 900, 1350, 1800, 2700, 3600, 4050, 4500, + 600, 1200, 1800, 2400, 3600, 4800, 5400, 6000
+};
+
static bool nl80211_type_check(enum nl80211_iftype type)
{
switch (type) {
@@ -304,18 +339,58 @@ static int ieee80211_config_default_key(struct wiphy *wiphy,
return 0;
}
+static u16 sta_get_80211n_bitrate(struct ieee80211_tx_rate *rate) {
+ if (!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) {
+ if (!(rate->flags & IEEE80211_TX_RC_SHORT_GI))
+ return ieee80211n_ht20_gi800[rate->idx];
+
+ return ieee80211n_ht20_gi400[rate->idx];
+ }
+ else {
+ if (!(rate->flags & IEEE80211_TX_RC_SHORT_GI))
+ return ieee80211n_ht40_gi800[rate->idx];
+
+ return ieee80211n_ht40_gi400[rate->idx];
+ }
+}
+
static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) {
struct ieee80211_sub_if_data *sdata = sta->sdata;
sinfo->filled = STATION_INFO_INACTIVE_TIME |
STATION_INFO_RX_BYTES |
- STATION_INFO_TX_BYTES;
+ STATION_INFO_TX_BYTES |
+ STATION_INFO_RX_BITRATE |
+ STATION_INFO_TX_BITRATE;
sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes;
sinfo->tx_bytes = sta->tx_bytes;
+ if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
+ sinfo->filled |= STATION_INFO_SIGNAL;
+ sinfo->signal = sta->last_signal;
+ }
+
+ sinfo->rx_bitrate = sta->last_rxrate_unicast;
+
+ sinfo->tx_bitrate_flags = sta->last_tx_rate.flags &
+ (IEEE80211_TX_RC_MCS |
+ IEEE80211_TX_RC_40_MHZ_WIDTH |
+ IEEE80211_TX_RC_SHORT_GI);
+
+ if (!(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) {
+ struct ieee80211_supported_band *sband;
+ sband = sta->local->hw.wiphy->bands[sta->local->hw.conf.channel->band];
+ sinfo->tx_bitrate = sband->bitrates[sta->last_tx_rate.idx].bitrate;
+ sinfo->tx_bitrate_mcs = 0;
+ }
+ else {
+ sinfo->tx_bitrate = sta_get_80211n_bitrate(&sta->last_tx_rate);
+ sinfo->tx_bitrate_mcs = sta->last_tx_rate.idx;
+ }
+
if (ieee80211_vif_is_mesh(&sdata->vif)) {
#ifdef CONFIG_MAC80211_MESH
sinfo->filled |= STATION_INFO_LLID |
net/mac80211/rx.c +8 -1
@@ -720,8 +720,15 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)if (rx->sdata->vif.type ==NL80211_IFTYPE_ADHOC ) {u8 *bssid =ieee80211_get_bssid (hdr, rx->skb->len,NL80211_IFTYPE_ADHOC ); -if (compare_ether_addr (bssid, rx->sdata->u.sta.bssid) ==0 ) +if (compare_ether_addr (bssid, rx->sdata->u.sta.bssid) ==0 ) { sta->last_rx = jiffies; + +/* only update last_rxrate_unicast when we receive a +* unicast packet for this station */ +if (compare_ether_addr (hdr->addr1, sta->sta.addr)) { + sta->last_rxrate_unicast = rx->rate->bitrate; + } + } }else if (!is_multicast_ether_addr (hdr->addr1) || rx->sdata->vif.type ==NL80211_IFTYPE_STATION ) {
net/mac80211/sta_info.h +1 -0
@@ -254,6 +254,7 @@ struct sta_info {int last_signal;int last_qual;int last_noise; +u16 last_rxrate_unicast;__le16 last_seq_ctrl[NUM_RX_DATA_QUEUES ];/* Updated from TX status path only, no locking requirements */
net/wireless/nl80211.c +1 -0
@@ -16,6 +16,7 @@#include <linux/netlink.h> #include <net/genetlink.h> #include <net/cfg80211.h> +#include <net/mac80211.h> #include "core.h" #include "nl80211.h" #include "reg.h"
@@ -1057,7 +1058,24 @@ static int nl80211_send_station(struct sk_buff *msg,
u32 pid, u32 seq,
if (sinfo->filled & STATION_INFO_PLINK_STATE)
NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
sinfo->plink_state);
-
+ if (sinfo->filled & STATION_INFO_SIGNAL)
+ NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
+ sinfo->signal);
+ if (sinfo->filled & STATION_INFO_RX_BITRATE)
+ NLA_PUT_U16(msg, NL80211_STA_INFO_RX_BITRATE,
+ sinfo->rx_bitrate);
+ if (sinfo->filled & STATION_INFO_TX_BITRATE) {
+ NLA_PUT_U16(msg, NL80211_STA_INFO_TX_BITRATE,
+ sinfo->tx_bitrate);
+
+ if (sinfo->tx_bitrate_flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ NLA_PUT_FLAG(msg, NL80211_STA_INFO_TX_BITRATE_40_MHZ);
+ if (sinfo->tx_bitrate_flags & IEEE80211_TX_RC_SHORT_GI)
+ NLA_PUT_FLAG(msg, NL80211_STA_INFO_TX_BITRATE_SHORT_GI);
+ if (sinfo->tx_bitrate_flags & IEEE80211_TX_RC_MCS)
+ NLA_PUT_U16(msg, NL80211_STA_INFO_TX_BITRATE_MCS,
+ sinfo->tx_bitrate_mcs);
+ }
nla_nest_end(msg, sinfoattr);
return genlmsg_end(msg, hdr);
#include <net/if.h>
#include <errno.h>
#include <string.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/family.h>
#include <netlink/genl/ctrl.h>
#include <netlink/msg.h>
#include <netlink/attr.h>
#include "nl80211.h"
#include "iw.h"
enum plink_state {
LISTEN,
OPN_SNT,
OPN_RCVD,
CNF_RCVD,
ESTAB,
HOLDING,
BLOCKED
};
enum plink_actions {
PLINK_ACTION_UNDEFINED,
PLINK_ACTION_OPEN,
PLINK_ACTION_BLOCK,
};
static int print_sta_handler(struct nl_msg *msg, void *arg)
{
struct nlattr *tb[NL80211_ATTR_MAX + 1];
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
char mac_addr[20], state_name[10], dev[20];
static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
[NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
[NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 },
[NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
[NL80211_STA_INFO_LLID] = { .type = NLA_U16 },
[NL80211_STA_INFO_PLID] = { .type = NLA_U16 },
[NL80211_STA_INFO_PLINK_STATE] = { .type = NLA_U8 },
[NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
[NL80211_STA_INFO_RX_BITRATE] = { .type = NLA_U16 },
[NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_U16 },
[NL80211_STA_INFO_TX_BITRATE_40_MHZ] = { .type = NLA_FLAG },
[NL80211_STA_INFO_TX_BITRATE_SHORT_GI] = { .type = NLA_FLAG },
[NL80211_STA_INFO_TX_BITRATE_MCS] = { .type = NLA_U8 },
};
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
/*
* TODO: validate the interface and mac address!
* Otherwise, there's a race condition as soon as
* the kernel starts sending station notifications.
*/
if (!tb[NL80211_ATTR_STA_INFO]) {
fprintf(stderr, "sta stats missing!");
return NL_SKIP;
}
if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
tb[NL80211_ATTR_STA_INFO],
stats_policy)) {
fprintf(stderr, "failed to parse nested attributes!");
return NL_SKIP;
}
mac_addr_n2a(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
printf("Station %s (on %s)", mac_addr, dev);
if (sinfo[NL80211_STA_INFO_INACTIVE_TIME])
printf("\n\tinactive time:\t%d ms",
nla_get_u32(sinfo[NL80211_STA_INFO_INACTIVE_TIME]));
if (sinfo[NL80211_STA_INFO_RX_BYTES])
printf("\n\trx bytes:\t%d",
nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES]));
if (sinfo[NL80211_STA_INFO_TX_BYTES])
printf("\n\ttx bytes:\t%d",
nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES]));
if (sinfo[NL80211_STA_INFO_SIGNAL])
printf("\n\tsignal: \t%d dBm",
(int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]));
if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
int bitrate = nla_get_u16(sinfo[NL80211_STA_INFO_RX_BITRATE]);
printf("\n\trx-bitrate:\t%d.%01d MBit/s", bitrate/10, bitrate % 10);
}
if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
int bitrate = 0;
int mcs = -1;
int short_gi = 0;
bitrate = nla_get_u16(sinfo[NL80211_STA_INFO_TX_BITRATE]);
if (sinfo[NL80211_STA_INFO_TX_BITRATE_MCS])
mcs = nla_get_u8(sinfo[NL80211_STA_INFO_TX_BITRATE_MCS]);
if (sinfo[NL80211_STA_INFO_TX_BITRATE_SHORT_GI])
short_gi = 1;
printf("\n\ttx-bitrate:\t%d.%01d MBit/s", bitrate/10, bitrate % 10);
if (sinfo[NL80211_STA_INFO_TX_BITRATE_40_MHZ])
printf(" 40Mhz");
if (mcs != -1) {
printf(" (MCS %d%s)", mcs, short_gi ? ", short guard interval" : "");
}
}
if (sinfo[NL80211_STA_INFO_LLID])
printf("\n\tmesh llid:\t%d",
nla_get_u16(sinfo[NL80211_STA_INFO_LLID]));
if (sinfo[NL80211_STA_INFO_PLID])
printf("\n\tmesh plid:\t%d",
nla_get_u16(sinfo[NL80211_STA_INFO_PLID]));
if (sinfo[NL80211_STA_INFO_PLINK_STATE]) {
switch (nla_get_u16(sinfo[NL80211_STA_INFO_PLINK_STATE])) {
case LISTEN:
strcpy(state_name, "LISTEN");
break;
case OPN_SNT:
strcpy(state_name, "OPN_SNT");
break;
case OPN_RCVD:
strcpy(state_name, "OPN_RCVD");
break;
case CNF_RCVD:
strcpy(state_name, "CNF_RCVD");
break;
case ESTAB:
strcpy(state_name, "ESTAB");
break;
case HOLDING:
strcpy(state_name, "HOLDING");
break;
case BLOCKED:
strcpy(state_name, "BLOCKED");
break;
default:
strcpy(state_name, "UNKNOWN");
break;
}
printf("\n\tmesh plink:\t%s", state_name);
}
printf("\n");
return NL_SKIP;
}static int handle_station_get(struct nl_cb *cb,
struct nl_msg *msg, int argc, char **argv)
{
unsigned char mac_addr[ETH_ALEN];
if (argc < 1)
return 1;
if (mac_addr_a2n(mac_addr, argv[0])) {
fprintf(stderr, "invalid mac address\n");
return 2;
}
argc--;
argv++;
if (argc)
return 1;
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_sta_handler, NULL);
return 0;
nla_put_failure:
return -ENOBUFS;
}
COMMAND(station, get, "<MAC address>",
NL80211_CMD_GET_STATION, 0, CIB_NETDEV, handle_station_get);
COMMAND(station, del, "<MAC address>",
NL80211_CMD_DEL_STATION, 0, CIB_NETDEV, handle_station_get);static int handle_station_set(struct nl_cb *cb,
struct nl_msg *msg, int argc, char **argv)
{
unsigned char plink_action;
unsigned char mac_addr[ETH_ALEN];
if (argc < 3)
return 1;
if (mac_addr_a2n(mac_addr, argv[0])) {
fprintf(stderr, "invalid mac address\n");
return 2;
}
argc--;
argv++;
if (strcmp("plink_action", argv[0]) != 0)
return 1;
argc--;
argv++;
if (strcmp("open", argv[0]) == 0)
plink_action = PLINK_ACTION_OPEN;
else if (strcmp("block", argv[0]) == 0)
plink_action = PLINK_ACTION_BLOCK;
else {
fprintf(stderr, "plink action not supported\n");
return 2;
}
argc--;
argv++;
if (argc)
return 1;
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
NLA_PUT_U8(msg, NL80211_ATTR_STA_PLINK_ACTION, plink_action);
return 0;
nla_put_failure:
return -ENOBUFS;
}
COMMAND(station, set, "<MAC address> plink_action <open|block>",
NL80211_CMD_SET_STATION, 0, CIB_NETDEV, handle_station_set);static int handle_station_dump(struct nl_cb *cb,
struct nl_msg *msg, int argc, char **argv)
{
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_sta_handler, NULL);
return 0;
}
COMMAND(station, dump, NULL,
NL80211_CMD_GET_STATION, NLM_F_DUMP, CIB_NETDEV, handle_station_dump);include/linux/nl80211.h +14 -0
@@ -404,6 +404,14 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received package (u8, dBm) +* @NL80211_STA_INFO_RX_BITRATE: bitrate of last received unicast packet +* (u16, 100 kbit/s) +* @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate (u16, 100 kbit/s) +* @NL80211_STA_INFO_TX_BITRATE_40_MHZ: dual channel transmission (flag) +* @NL80211_STA_INFO_TX_BITRATE_MCS: 802.11n MCS index of tx rate (u8) +* @NL80211_STA_INFO_TX_BITRATE_SHORT_GI: 802.11n with 400ns GI, 800ns +* otherwise, should be ignored if TX_BITRATE_MCS is not set (flag) */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID,
@@ -413,6 +421,12 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_RX_BITRATE , +NL80211_STA_INFO_TX_BITRATE , +NL80211_STA_INFO_TX_BITRATE_40_MHZ , +NL80211_STA_INFO_TX_BITRATE_MCS , +NL80211_STA_INFO_TX_BITRATE_SHORT_GI ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +22 -0
@@ -160,6 +160,8 @@ struct station_parameters {* * Used by the driver to indicate which info in &struct station_info * it has filled in during get_station() or dump_station(). +* Signal strength is only available if driver supports dBm signal +* strength. * * @STATION_INFO_INACTIVE_TIME: @inactive_time filled * @STATION_INFO_RX_BYTES: @rx_bytes filled
@@ -167,6 +169,10 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_RX_BITRATE: @rx_bitrate filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled +* (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -175,6 +181,9 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , +STATION_INFO_RX_BITRATE =1 <<7 , + STATION_INFO_TX_BITRATE = 1<<8, };/**
@@ -189,6 +198,15 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received package in dBm +* @rx_bitrate: bitrate of last received unicast packet in 100 kbit/sec +* @tx_bitrate: current unicast bitrate to this station in 100 kbit/sec +* @tx_bitrate_flags: a binary field with a combination of flags +* IEEE80211_TX_RC_MCS: bitrate_mcs field contains the 802.11n MCS number +* IEEE80211_TX_RC_40_MHZ_WIDTH: 40 Mhz wide channel, 20 Mhz if not set +* IEEE80211_TX_RC_SHORT_GI: 400ns guard interval, 800ns if not set +* @tx_bitrate_mcs: if IEEE80211_TX_RC_MCS is set this is the MCS index +* of a 802.11n transmission, if not it is set to zero */ struct station_info {u32 filled;
@@ -198,6 +216,10 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +u16 rx_bitrate; +u16 tx_bitrate; +u8 tx_bitrate_flags, tx_bitrate_mcs; };/**
net/mac80211/cfg.c +76 -1
100 lines not on this page · raw message
net/mac80211/rx.c +8 -1
@@ -720,8 +720,15 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)if (rx->sdata->vif.type ==NL80211_IFTYPE_ADHOC ) {u8 *bssid =ieee80211_get_bssid (hdr, rx->skb->len,NL80211_IFTYPE_ADHOC ); -if (compare_ether_addr (bssid, rx->sdata->u.sta.bssid) ==0 ) +if (compare_ether_addr (bssid, rx->sdata->u.sta.bssid) ==0 ) { sta->last_rx = jiffies; + +/* only update last_rxrate_unicast when we receive a +* unicast packet for this station */ +if (compare_ether_addr (hdr->addr1, sta->sta.addr)) { + sta->last_rxrate_unicast = rx->rate->bitrate; + } + } }else if (!is_multicast_ether_addr (hdr->addr1) || rx->sdata->vif.type ==NL80211_IFTYPE_STATION ) {
net/mac80211/sta_info.h +1 -0
@@ -254,6 +254,7 @@ struct sta_info {int last_signal;int last_qual;int last_noise; +u16 last_rxrate_unicast;__le16 last_seq_ctrl[NUM_RX_DATA_QUEUES ];/* Updated from TX status path only, no locking requirements */
net/wireless/nl80211.c +19 -1
@@ -16,6 +16,7 @@#include <linux/netlink.h> #include <net/genetlink.h> #include <net/cfg80211.h> +#include <net/mac80211.h> #include "core.h" #include "nl80211.h" #include "reg.h"
@@ -1057,7 +1058,24 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,if (sinfo->filled &STATION_INFO_PLINK_STATE )NLA_PUT_U8 (msg,NL80211_STA_INFO_PLINK_STATE , sinfo->plink_state); - +if (sinfo->filled &STATION_INFO_SIGNAL ) +NLA_PUT_U8 (msg,NL80211_STA_INFO_SIGNAL , + sinfo->signal); +if (sinfo->filled &STATION_INFO_RX_BITRATE ) +NLA_PUT_U16 (msg,NL80211_STA_INFO_RX_BITRATE , + sinfo->rx_bitrate); +if (sinfo->filled &STATION_INFO_TX_BITRATE ) { +NLA_PUT_U16 (msg,NL80211_STA_INFO_TX_BITRATE , + sinfo->tx_bitrate); + +if (sinfo->tx_bitrate_flags &IEEE80211_TX_RC_40_MHZ_WIDTH ) +NLA_PUT_FLAG (msg,NL80211_STA_INFO_TX_BITRATE_40_MHZ ); +if (sinfo->tx_bitrate_flags &IEEE80211_TX_RC_SHORT_GI ) +NLA_PUT_FLAG (msg,NL80211_STA_INFO_TX_BITRATE_SHORT_GI ); +if (sinfo->tx_bitrate_flags &IEEE80211_TX_RC_MCS ) +NLA_PUT_U16 (msg,NL80211_STA_INFO_TX_BITRATE_MCS , + sinfo->tx_bitrate_mcs); + }nla_nest_end (msg, sinfoattr);return genlmsg_end (msg, hdr);
Johannes Berg
maintainerRe: RFC Patch v2: Add signal strength to nl80211station info
Quoted 4 lines · Henning Rogge
What do you think about the idea to export the 802.11n transmission rate through the old WExt interface, so iwconfig will show the correct rate too ? But for this the "mcs to bitrate" tables would have to be moved to some other file, so
wext.ccan access them too (which one ?).
No, that can't possibly work right, sorry.
Quoted 2 lines
+ * @NL80211_STA_INFO_SIGNAL: signal strength of last received package (u8, dBm)
s8? should be signed, no?
Quoted 2 lines
+ * @NL80211_STA_INFO_RX_BITRATE: bitrate of last received unicast packet
+ * (u16, 100 kbit/s)
I don't really like this. I know we cannot report the real information yet because we don't even have the driver/mac80211 api but let's add rx rate reporting when we have the HT information too.
Quoted 5 lines
+ * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate (u16, 100 kbit/s)
+ * @NL80211_STA_INFO_TX_BITRATE_40_MHZ: dual channel transmission (flag)
+ * @NL80211_STA_INFO_TX_BITRATE_MCS: 802.11n MCS index of tx rate (u8)
+ * @NL80211_STA_INFO_TX_BITRATE_SHORT_GI: 802.11n with 400ns GI, 800ns
+ * otherwise, should be ignored ifTX_BITRATE_MCSis not set (flag)
I'm not sure I like the bitrate being used as prefix and final name, can we have maybe TXRATE_ as prefix and use TXRATE_RATE, TXRATE_40, ...?
Quoted 25 lines
+/* bitrate of 802.11n ht20 connections with 800ns guard interval in 100kbit/s */
net/mac80211/cfg.c +23
-0+const u16 ieee80211n_ht20_gi800[] = { +65 ,130 ,195 ,260 ,390 ,520 ,585 ,650 , +130 ,260 ,390 ,520 ,780 ,1040 ,1170 ,1300 , +195 ,390 ,585 ,780 ,1170 ,1560 ,1755 ,1950 , +260 ,520 ,780 ,1040 ,1560 ,2080 ,2340 ,2600 +}; + +/* bitrate of 802.11n ht20 connections with 400ns guard interval +* in 100kbit/s per spatial stream */ +const u16 ieee80211n_ht20_gi400[] = { +72 ,144 ,217 ,289 ,433 ,578 ,650 ,722 , +144 ,289 ,433 ,578 ,867 ,1156 ,1300 ,1440 , +217 ,433 ,650 ,867 ,1300 ,1733 ,1950 ,2167 , +289 ,578 ,867 ,1157 ,1733 ,2311 ,2600 ,2889 +}; + +/* bitrate of 802.11n ht40 connections with 800ns guard interval +* in 100kbit/s per spatial stream */ +const u16 ieee80211n_ht40_gi800[] = { +135 ,270 ,405 ,540 ,810 ,1080 ,1215 ,1350 , +270 ,540 ,810 ,1080 ,1620 ,2160 ,2430 ,2700 , +405 ,810 ,1215 ,1620 ,2430 ,3240 ,3645 ,4050 , +540 ,1080 ,1620 ,2160 ,3240 ,4320 ,4860 ,5400
net/mac80211/cfg.c line 53
Quoted 10 lines
net/mac80211/cfg.c +10
-0+}; + +/* bitrate of 802.11n ht40 connections with 400ns guard interval +* in 100kbit/s per spatial stream */ +const u16 ieee80211n_ht40_gi400[] = { +150 ,300 ,450 ,600 ,900 ,1200 ,1350 ,1500 , +300 ,600 ,900 ,1200 ,1800 ,2400 ,2700 ,3000 , +450 ,900 ,1350 ,1800 ,2700 ,3600 ,4050 ,4500 , +600 ,1200 ,1800 ,2400 ,3600 ,4800 ,5400 ,6000 +};
I definitely don't like this, ick, please put that into userspace.
net/mac80211/cfg.c static int ieee80211_config_default_key(struct wiphy *wiphy, · line 374
Quoted 4 lines
net/mac80211/cfg.c +4
-0+if (sta->local->hw.flags &IEEE80211_HW_SIGNAL_DBM ) { + sinfo->filled |=STATION_INFO_SIGNAL ; + sinfo->signal = sta->last_signal; + }
Good plan to report only when dBm are available, I like that.
net/mac80211/cfg.c static int ieee80211_config_default_key(struct wiphy *wiphy, · line 381
Quoted 6 lines
net/mac80211/cfg.c +6
-0+ sinfo->rx_bitrate = sta->last_rxrate_unicast; + + sinfo->tx_bitrate_flags = sta->last_tx_rate.flags & + (IEEE80211_TX_RC_MCS | +IEEE80211_TX_RC_40_MHZ_WIDTH | +IEEE80211_TX_RC_SHORT_GI );
That looks very odd. Are you sure it's using the same rate flags? And if it is, that's wrong, because cfg80211 must not rely on mac80211 flags.
net/mac80211/cfg.c static int ieee80211_config_default_key(struct wiphy *wiphy, · line 387
Quoted 5 lines
net/mac80211/cfg.c +5
-0+if (!(sta->last_tx_rate.flags &IEEE80211_TX_RC_MCS )) { +struct ieee80211_supported_band *sband; + sband = sta->local->hw.wiphy->bands[sta->local->hw.conf.channel->band]; + sinfo->tx_bitrate = sband->bitrates[sta->last_tx_rate.idx].bitrate; + sinfo->tx_bitrate_mcs =0 ;
I don't think you should initialise mcs here.
Some places also need work on the coding style.
johannes
Re: RFC Patch v2: Add signal strength to nl80211station info
Am Thursday 04 December 2008 09:47:52 schrieb Johannes Berg:
Quoted 7 lines · Henning Rogge
Quoted 4 lines
What do you think about the idea to export the 802.11n transmission rate through the old WExt interface, so iwconfig will show the correct rate too ? But for this the "mcs to bitrate" tables would have to be moved to some other file, so
wext.ccan access them too (which one ?).No, that can't possibly work right, sorry.
I think it would work for reading the bitrate with WExt, but not for setting the bitrate.
Quoted 4 lines
Quoted 2 lines
+ * @NL80211_STA_INFO_SIGNAL: signal strength of last received package (u8, dBm)
s8? should be signed, no?
Yes, it should be signed, but nl80211 does not support signed values. Shall I document it as signed but use the unsigned macros to transmit it through nl80211 to userspace (not sure about it) ?
Quoted 6 lines
Quoted 2 lines
+ * @NL80211_STA_INFO_RX_BITRATE: bitrate of last received unicast packet
+ * (u16, 100 kbit/s)I don't really like this. I know we cannot report the real information yet because we don't even have the driver/mac80211 api but let's add rx rate reporting when we have the HT information too.
I'm not sure I understand your problem.
We have the mcs number from the driver, we have the the 20/40 Mhz flag and we have to 400/800ns guard interval flag. That should be everything we need.
Quoted 9 lines
Quoted 6 lines
+ * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate (u16, 100 kbit/s) + * @NL80211_STA_INFO_TX_BITRATE_40_MHZ: dual channel transmission (flag) + * @NL80211_STA_INFO_TX_BITRATE_MCS: 802.11n MCS index of tx rate (u8) + * @NL80211_STA_INFO_TX_BITRATE_SHORT_GI: 802.11n with 400ns GI, 800ns + * otherwise, should be ignored if
TX_BITRATE_MCSis not set (flag)I'm not sure I like the bitrate being used as prefix and final name, can we have maybe
TXRATE_as prefix and useTXRATE_RATE,TXRATE_40, ...?
Like this ?
NL80211_STA_INFO_TXRATE_RATENL80211_STA_INFO_TXRATE_40_MHZNL80211_STA_INFO_TXRATE_MCSNL80211_STA_INFO_TXRATE_SHORT_GI
Quoted 29 lines
Quoted 29 lines
+/* bitrate of 802.11n ht20 connections with 800ns guard interval in 100kbit/s */
net/mac80211/cfg.c +27
-0+const u16 ieee80211n_ht20_gi800[] = { +65 ,130 ,195 ,260 ,390 ,520 ,585 ,650 , +130 ,260 ,390 ,520 ,780 ,1040 ,1170 ,1300 , +195 ,390 ,585 ,780 ,1170 ,1560 ,1755 ,1950 , +260 ,520 ,780 ,1040 ,1560 ,2080 ,2340 ,2600 +}; + +/* bitrate of 802.11n ht20 connections with 400ns guard interval +* in 100kbit/s per spatial stream */ +const u16 ieee80211n_ht20_gi400[] = { +72 ,144 ,217 ,289 ,433 ,578 ,650 ,722 , +144 ,289 ,433 ,578 ,867 ,1156 ,1300 ,1440 , +217 ,433 ,650 ,867 ,1300 ,1733 ,1950 ,2167 , +289 ,578 ,867 ,1157 ,1733 ,2311 ,2600 ,2889 +}; + +/* bitrate of 802.11n ht40 connections with 800ns guard interval +* in 100kbit/s per spatial stream */ +const u16 ieee80211n_ht40_gi800[] = { +135 ,270 ,405 ,540 ,810 ,1080 ,1215 ,1350 , +270 ,540 ,810 ,1080 ,1620 ,2160 ,2430 ,2700 , +405 ,810 ,1215 ,1620 ,2430 ,3240 ,3645 ,4050 , +540 ,1080 ,1620 ,2160 ,3240 ,4320 ,4860 ,5400 +}; + +/* bitrate of 802.11n ht40 connections with 400ns guard interval +* in 100kbit/s per spatial stream */
Quoted 8 lines
net/mac80211/cfg.c line 53
Quoted 6 lines
net/mac80211/cfg.c +6
-0+const u16 ieee80211n_ht40_gi400[] = { +150 ,300 ,450 ,600 ,900 ,1200 ,1350 ,1500 , +300 ,600 ,900 ,1200 ,1800 ,2400 ,2700 ,3000 , +450 ,900 ,1350 ,1800 ,2700 ,3600 ,4050 ,4500 , +600 ,1200 ,1800 ,2400 ,3600 ,4800 ,5400 ,6000 +};I definitely don't like this, ick, please put that into userspace.
Is there some kind of userspace library I could put this function into ? Every userspace programm using nl80211 will need this translation function, so it would be bad to put it into the iw command.
Quoted 9 lines
net/mac80211/cfg.c static int ieee80211_config_default_key(struct wiphy *wiphy, · line 381
Quoted 6 lines
net/mac80211/cfg.c +6
-0+ sinfo->rx_bitrate = sta->last_rxrate_unicast; + + sinfo->tx_bitrate_flags = sta->last_tx_rate.flags & + (IEEE80211_TX_RC_MCS | +IEEE80211_TX_RC_40_MHZ_WIDTH | +IEEE80211_TX_RC_SHORT_GI );That looks very odd. Are you sure it's using the same rate flags? And if it is, that's wrong, because cfg80211 must not rely on mac80211 flags.
I just store them in the flags field and translate them into NL80211 flags later. They never leave the kernel.
But I can add a new enum for this. Maybe this way ?
enum station_info_txrate_flags {
STATION_INFO_TXFLAGS_MCS,
STATION_INFO_TXFLAGS_40_MHZ,
STATION_INFO_TXFLAGS_SHORT_GI
};
Quoted 7 lines
net/mac80211/cfg.c static int ieee80211_config_default_key(struct wiphy *wiphy, · line 387
Quoted 6 lines
net/mac80211/cfg.c +3
-0+if (!(sta->last_tx_rate.flags &IEEE80211_TX_RC_MCS )) { +struct ieee80211_supported_band *sband; + sband =sta->local->hw.wiphy->bands[sta->local->hw.conf.channel->band];
net/mac80211/cfg.c +2
-0+ sinfo->tx_bitrate = sband->bitrates[sta->last_tx_rate.idx].bitrate; + sinfo->tx_bitrate_mcs =0 ;I don't think you should initialise mcs here.
I didn't liked to keep it uninitialized, but I can just delete the line.
Quoted 1 line
Some places also need work on the coding style.
Maybe you can give me an example, I'm still trying to learn the coding style for this group.
Henning
*************************************************
Diplom Informatiker Henning Rogge
Forschungsgesellschaft für
Angewandte Naturwissenschaften e. V. (FGAN)
Neuenahrer Str. 20, 53343 Wachtberg, Germany
Tel.: 0049 (0)228 9435-961
Fax: 0049 (0)228 9435-685
E-Mail: [email protected]
Web: www.fgan.de
************************************************
Sitz der Gesellschaft: Bonn
Registergericht: Amtsgericht Bonn VR 2530
Vorstand: Dr. rer. nat. Ralf Dornhaus (Vors.), Prof. Dr. Joachim Ender (Stellv.)
Johannes Berg
maintainerRe: RFC Patch v2: Add signal strength to nl80211station info
Quoted 6 lines
Quoted 3 lines
No, that can't possibly work right, sorry.
I think it would work for reading the bitrate with WExt, but not for setting the bitrate.
Yes, that might work, but would be quite inconsistent, IMHO.
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
+ * @NL80211_STA_INFO_SIGNAL: signal strength of last received package (u8, dBm)
s8? should be signed, no?
Yes, it should be signed, but nl80211 does not support signed values. Shall I
document it as signed but use the unsigned macros to transmit it through nl80211 to userspace (not sure about it) ?
Yes, please document as signed.
Quoted 11 lines
Quoted 1 line
Quoted 1 line
+ * @NL80211_STA_INFO_RX_BITRATE: bitrate of last received unicast
packet
Quoted 5 lines
Quoted 1 line
+ * (u16, 100 kbit/s)
I don't really like this. I know we cannot report the real information yet because we don't even have the driver/mac80211 api but let's add rx rate reporting when we have the HT information too.
I'm not sure I understand your problem.
We have the mcs number from the driver, we have the the 20/40 Mhz flag
and
Quoted 2 lines
we
have to 400/800ns guard interval flag. That should be everything we need.
I don't think we have MCS number, where did you see it? And we don't have the 20/40, GI etc. either, afaict. Remember this is RX.
Quoted 9 lines
Quoted 4 lines
Quoted 4 lines
+ * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate (u16, 100 kbit/s) + * @NL80211_STA_INFO_TX_BITRATE_40_MHZ: dual channel transmission (flag) + * @NL80211_STA_INFO_TX_BITRATE_MCS: 802.11n MCS index of tx rate (u8) + * @NL80211_STA_INFO_TX_BITRATE_SHORT_GI:
802.11n
Quoted 1 line
Quoted 1 line
with 400ns GI, 800ns + * otherwise, should be ignored if
TX_BITRATE_MCSQuoted 2 lines
Quoted 1 line
is not set (flag)
Quoted 8 lines
Quoted 2 lines
I'm not sure I like the bitrate being used as prefix and final name, can we have maybe
TXRATE_as prefix and useTXRATE_RATE,TXRATE_40, ...?Like this ?
NL80211_STA_INFO_TXRATE_RATENL80211_STA_INFO_TXRATE_40_MHZNL80211_STA_INFO_TXRATE_MCSNL80211_STA_INFO_TXRATE_SHORT_GI
Yeah, much better.
Quoted 4 lines
Quoted 1 line
I definitely don't like this, ick, please put that into userspace.
Is there some kind of userspace library I could put this function into ? Every userspace programm using nl80211 will need this translation function, so it would be bad to put it into the iw command.
Why would that be bad? Most programs using nl80211 won't care, and this is fixed information, not something that changes.
Quoted 10 lines
Quoted 9 lines
net/mac80211/cfg.c static int ieee80211_config_default_key(struct wiphy *wiphy, · line 381
Quoted 6 lines
net/mac80211/cfg.c +6
-0+ sinfo->rx_bitrate = sta->last_rxrate_unicast; + + sinfo->tx_bitrate_flags = sta->last_tx_rate.flags & + (IEEE80211_TX_RC_MCS | +IEEE80211_TX_RC_40_MHZ_WIDTH | +IEEE80211_TX_RC_SHORT_GI );That looks very odd. Are you sure it's using the same rate flags? And if it is, that's wrong, because cfg80211 must not rely on mac80211 flags.
I just store them in the flags field and translate them into NL80211
flags
Quoted 10 lines
later. They never leave the kernel.
But I can add a new enum for this. Maybe this way ?
enum
station_info_txrate_flags{
STATION_INFO_TXFLAGS_MCS,
STATION_INFO_TXFLAGS_40_MHZ,
STATION_INFO_TXFLAGS_SHORT_GI
};
Yes, that would be better, and that needs to be defined in cfg80211.
Quoted 9 lines
Quoted 7 lines
net/mac80211/cfg.c static int ieee80211_config_default_key(struct wiphy *wiphy, · line 387
Quoted 6 lines
net/mac80211/cfg.c +3
-0+if (!(sta->last_tx_rate.flags &IEEE80211_TX_RC_MCS )) { +struct ieee80211_supported_band *sband; + sband =sta->local->hw.wiphy->bands[sta->local->hw.conf.channel->band];
net/mac80211/cfg.c +2
-0+ sinfo->tx_bitrate = sband->bitrates[sta->last_tx_rate.idx].bitrate; + sinfo->tx_bitrate_mcs =0 ;I don't think you should initialise mcs here.
I didn't liked to keep it uninitialized, but I can just delete the line.
But it won't be used anyway, so imho it's easier to understand if you remove it.
Quoted 4 lines
Quoted 1 line
Some places also need work on the coding style.
Maybe you can give me an example, I'm still trying to learn the coding style for this group.
You can find stuff on that in the Documentation/ directory.
johannes
PS: Sent from new webmail, apologies for the previous johannes@localhost, let me know if this is ok!
Johannes Berg
maintainerRe: RFC Patch v2: Add signal strength to nl80211station info
In reply to Henning RoggeQuoted 3 lines · Henning Rogge
Changes since v3:
- addedrx_bitrateto station info andsta_info
- remember bitrate of last received unicast packet to this station
Please remove the RX bitrate for now, the drivers are not currently reporting HT information appropriately.
Quoted 2 lines
- decode 802.11n MCS index for nl80211
(maybe this should be ported to WEXT too ?)
I don't like all the tables in the kernel, please move those to userspace. If we used more accurate values (these rates are fractional) then we also don't need the values for the number of streams since those are perfect multiples (1x, 2x, 3x, 4x for up to 4 streams).
Quoted 7 lines
Changes since v4:
- addedtx_bitrate_flagsadntx_bitrate_mcsfield to station info
- added flags for 40Mhz and small guard interval to NL80211 station info
- added mcs field to NL80211 station infoThe
IEEE80211_TX_RC_40_MHZ_WIDTHflag in nl80211 should work for 802.11g "turbomodes"
I don't think we should ever go there. But that's just me maybe.
Quoted 13 lines
+ * @NL80211_STA_INFO_SIGNAL: signal strength of last received package (u8, dBm)
+ * @NL80211_STA_INFO_RX_BITRATE: bitrate of last received unicast packet
+ * (u16, 100 kbit/s)
+ * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate (u16, 100 kbit/s)
+ * @NL80211_STA_INFO_TX_BITRATE_40_MHZ: dual channel transmission (flag)
+ * @NL80211_STA_INFO_TX_BITRATE_MCS: 802.11n MCS index of tx rate (u8)
+ * @NL80211_STA_INFO_TX_BITRATE_SHORT_GI: 802.11n with 400ns GI, 800ns
+ * otherwise, should be ignored ifTX_BITRATE_MCSis not set (flag) */
enumnl80211_sta_info{include/linux/nl80211.h +0
-0__NL80211_STA_INFO_INVALID,
include/linux/nl80211.h enum nl80211_sta_info { · line 429
Quoted 9 lines
include/linux/nl80211.h +6
-0@@ -413,6 +421,12 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_RX_BITRATE , +NL80211_STA_INFO_TX_BITRATE , +NL80211_STA_INFO_TX_BITRATE_40_MHZ , +NL80211_STA_INFO_TX_BITRATE_MCS , + NL80211_STA_INFO_TX_BITRATE_SHORT_GI,
Just had another idea. Since we'll end up duplicating these for TX and RX (ultimately we'll need RX_BITRATE_40_MHZ/MCS/SGI etc too) we should actually do this differently:
1) define NL80211_STA_INFO_RATE,
2) define NL80211_RATE_INFO_BITRATE/40/MCS/SGI
and then nest the bitrate information into the STA_INFO_RATE, just like station flags are nested etc. That way the RATE_INFO things could also be used elsewhere.
include/net/cfg80211.h struct station_parameters { · line 164
Quoted 4 lines
include/net/cfg80211.h +2
-0* Used by the driver to indicate which info in &struct station_info * it has filled in during get_station() or dump_station(). +* Signal strength is only available if driver supports dBm signal +* strength.
That comment is wrong here since cfg80211 drivers are expected to fill this correctly. This comment is about _mac80211_ drivers and thus inappropriate in cfg80211.h.
Quoted 1 line
+ * @signal: signal strength of last received package in dBm
packet, or better yet PPDU
Quoted 6 lines
+ * @rx_bitrate: bitrate of last received unicast packet in 100 kbit/sec
+ * @tx_bitrate: current unicast bitrate to this station in 100 kbit/sec
+ * @tx_bitrate_flags: a binary field with a combination of flags+ * IEEE80211_TX_RC_MCS: bitrate_mcs field contains the 802.11n MCS number + * IEEE80211_TX_RC_40_MHZ_WIDTH: 40 Mhz wide channel, 20 Mhz if not set + * IEEE80211_TX_RC_SHORT_GI: 400ns guard interval, 800ns if not set
make those tx/rx independent too please, maybe even introduce a new struct here so that it gets
station_info.tx_rate.flags and eventually .rx_rate.flags too
johannes
Re: RFC Patch v2: Add signal strength to nl80211station info
Quoted 8 lines · Johannes Berg
Quoted 3 lines · Henning Rogge
Changes since v3:
- addedrx_bitrateto station info andsta_info
- remember bitrate of last received unicast packet to this stationPlease remove the RX bitrate for now, the drivers are not currently reporting HT information appropriately.
It seems that's the case for ath9k, at least Jouni had pointed out to me.
Quoted 5 lines
Quoted 2 lines
- decode 802.11n MCS index for nl80211
(maybe this should be ported to WEXT too ?)I don't like all the tables in the kernel, please move those to userspace. If we used more accurate values (these rates are fractional)
So the rate stuff in the 11n wiki page is rounded up, so yeah it would technically be a bit off so its technically better to let us figure it out in userspace.. sorry about that Henning... And Johannes also pointed out to me we actually do have duplicate rates, I failed to catch them.
Quoted 2 lines
then we also don't need the values for the number of streams since those are perfect multiples (1x, 2x, 3x, 4x for up to 4 streams).
Well if you have the MCS index and HT mode you get the # of streams. Not sure I understood the perfect multiple stuff.
Quoted 9 lines
Quoted 7 lines
Changes since v4:
- addedtx_bitrate_flagsadntx_bitrate_mcsfield to station info
- added flags for 40Mhz and small guard interval to NL80211 station info
- added mcs field to NL80211 station infoThe
IEEE80211_TX_RC_40_MHZ_WIDTHflag in nl80211 should work for 802.11g "turbomodes"I don't think we should ever go there. But that's just me maybe.
I don't think we want to support this either and I doubt bug reports for it would get attention from us.
Quoted 27 lines
Quoted 13 lines
+ * @NL80211_STA_INFO_SIGNAL: signal strength of last received package (u8, dBm)
+ * @NL80211_STA_INFO_RX_BITRATE: bitrate of last received unicast packet
+ * (u16, 100 kbit/s)
+ * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate (u16, 100 kbit/s)
+ * @NL80211_STA_INFO_TX_BITRATE_40_MHZ: dual channel transmission (flag)
+ * @NL80211_STA_INFO_TX_BITRATE_MCS: 802.11n MCS index of tx rate (u8)
+ * @NL80211_STA_INFO_TX_BITRATE_SHORT_GI: 802.11n with 400ns GI, 800ns
+ * otherwise, should be ignored ifTX_BITRATE_MCSis not set (flag) */
enumnl80211_sta_info{include/linux/nl80211.h +0
-0__NL80211_STA_INFO_INVALID,include/linux/nl80211.h enum nl80211_sta_info { · line 429
Quoted 9 lines
include/linux/nl80211.h +6
-0@@ -413,6 +421,12 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_RX_BITRATE , +NL80211_STA_INFO_TX_BITRATE , +NL80211_STA_INFO_TX_BITRATE_40_MHZ , +NL80211_STA_INFO_TX_BITRATE_MCS , + NL80211_STA_INFO_TX_BITRATE_SHORT_GI,Just had another idea. Since we'll end up duplicating these for TX and RX (ultimately we'll need RX_BITRATE_40_MHZ/MCS/SGI etc too) we should actually do this differently:
Quoted 6 lines
1) define
NL80211_STA_INFO_RATE,
2) define NL80211_RATE_INFO_BITRATE/40/MCS/SGIand then nest the bitrate information into the
STA_INFO_RATE, just like station flags are nested etc. That way theRATE_INFOthings could also be used elsewhere.
So we'll have to add an enum then too to distinguish which rate this is for.
Quoted 8 lines
include/net/cfg80211.h struct station_parameters { · line 164
Quoted 4 lines
include/net/cfg80211.h +2
-0* Used by the driver to indicate which info in &struct station_info * it has filled in during get_station() or dump_station(). +* Signal strength is only available if driver supports dBm signal +* strength. That comment is wrong here since cfg80211 drivers are expected to fill this correctly. This comment is about _mac80211_ drivers and thus inappropriate in
cfg80211.h.
adm8211 is a cfg80211 driver and does not report dBm. So it seems we currently allow cfg80211 drivers to *not* fill this in properly. The RTL drivers are some others ones as well as zd1211rw but it seems we'll be able to correct zd1211rw.
Luis
Johannes Berg
maintainerRe: RFC Patch v2: Add signal strength to nl80211station info
Quoted 4 lines · Luis R. Rodriguez
Quoted 2 lines
Please remove the RX bitrate for now, the drivers are not currently reporting HT information appropriately.
It seems that's the case for ath9k, at least Jouni had pointed out to me.
They cannot, we don't even have that in the API.
Quoted 5 lines
Quoted 2 lines
then we also don't need the values for the number of streams since those are perfect multiples (1x, 2x, 3x, 4x for up to 4 streams).
Well if you have the MCS index and HT mode you get the # of streams. Not sure I understood the perfect multiple stuff.
Right, but you don't need to store a bitrate for MCS 0, 8, 16 and 24, the latter three can just use the first multiplied by 2, 3 and 4 respectively.
Quoted 7 lines
Quoted 7 lines
Just had another idea. Since we'll end up duplicating these for TX and RX (ultimately we'll need RX_BITRATE_40_MHZ/MCS/SGI etc too) we should actually do this differently:
1) define
NL80211_STA_INFO_RATE,
2) define NL80211_RATE_INFO_BITRATE/40/MCS/SGI
Quoted 6 lines
Quoted 3 lines
and then nest the bitrate information into the
STA_INFO_RATE, just like station flags are nested etc. That way theRATE_INFOthings could also be used elsewhere.So we'll have to add an enum then too to distinguish which rate this is for.
No, we know that based on what "container" attribute it's contained in, in netlink.
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
* Used by the driver to indicate which info in &struct
station_info
* it has filled in duringget_station()ordump_station().
+ * Signal strength is only available if driver supports dBm signal
+ * strength.
Quoted 8 lines
Quoted 3 lines
That comment is wrong here since cfg80211 drivers are expected to fill this correctly. This comment is about _mac80211_ drivers and thus inappropriate in
cfg80211.h.adm8211 is a cfg80211 driver and does not report dBm. So it seems we currently allow cfg80211 drivers to *not* fill this in properly. The RTL drivers are some others ones as well as zd1211rw but it seems we'll be able to correct zd1211rw.
adm8211 is a mac80211 driver, and mac80211 doesn't fill this information because of that, I think that's an important distinction. If you feel this needs to be noted explicitly (it should be obvious since cfg80211 defines it in dBm and the driver cannot give such values) then please add it to the documentation about the signal HW flags.
johannes
Re: RFC Patch v2: Add signal strength to nl80211station info
Am Thursday 04 December 2008 22:20:35 schrieb Johannes Berg:
Quoted 4 lines · Luis R. Rodriguez
Quoted 1 line
It seems that's the case for ath9k, at least Jouni had pointed out to me.
They cannot, we don't even have that in the API.
Ath9k has it's ***_ratetable which contains a line of data for each transmission range. 20/40Mhz and guard interval is already contained in this table (encoded in "phy" variable). Just the MCS number is missing.
And I think the intel driver has the necessary data too. If I understand the iwl5000 driver, it pushes the rate index (even for 802.11n) through ieee80211_rx_status into mac80211.
Quoted 9 lines
Quoted 5 lines
Quoted 2 lines
then we also don't need the values for the number of streams since those are perfect multiples (1x, 2x, 3x, 4x for up to 4 streams).
Well if you have the MCS index and HT mode you get the # of streams. Not sure I understood the perfect multiple stuff.
Right, but you don't need to store a bitrate for MCS 0, 8, 16 and 24, the latter three can just use the first multiplied by 2, 3 and 4 respectively.
When I looked at the table in the wiki I noticed it cannot be created just by a little bit arithmetric ? Maybe someone can look at the 802.11 draft if we don't need the tables at all but just use a formula ? If yes we could remove them from kernelspace and just add a macro for calculating the rate into a userspace-accessable header file.
Quoted 11 lines
Quoted 11 lines
Quoted 10 lines
Just had another idea. Since we'll end up duplicating these for TX and RX (ultimately we'll need RX_BITRATE_40_MHZ/MCS/SGI etc too) we should actually do this differently:
1) define
NL80211_STA_INFO_RATE,
2) define NL80211_RATE_INFO_BITRATE/40/MCS/SGIand then nest the bitrate information into the
STA_INFO_RATE, just like station flags are nested etc. That way theRATE_INFOthings could also be used elsewhere.
Quoted 5 lines
Quoted 2 lines
So we'll have to add an enum then too to distinguish which rate this is for.
No, we know that based on what "container" attribute it's contained in, in netlink.
So it's possible to define a substructure in the station info in nl80211 ? Sounds like a nice way to construct the tx/rx rate.
I will see if I get a "v6" patch ready during the weekend.
Henning
*************************************************
Diplom Informatiker Henning Rogge
Forschungsgesellschaft für
Angewandte Naturwissenschaften e. V. (FGAN)
Neuenahrer Str. 20, 53343 Wachtberg, Germany
Tel.: 0049 (0)228 9435-961
Fax: 0049 (0)228 9435-685
E-Mail: [email protected]
Web: www.fgan.de
************************************************
Sitz der Gesellschaft: Bonn
Registergericht: Amtsgericht Bonn VR 2530
Vorstand: Dr. rer. nat. Ralf Dornhaus (Vors.), Prof. Dr. Joachim Ender (Stellv.)
Johannes Berg
maintainerRe: RFC Patch v2: Add signal strength to nl80211station info
Quoted 8 lines · Henning Rogge
Am Thursday 04 December 2008 22:20:35 schrieb Johannes Berg:
Quoted 4 lines · Luis R. Rodriguez
Quoted 1 line
It seems that's the case for ath9k, at least Jouni had pointed out to me.
They cannot, we don't even have that in the API.
Ath9k has it's ***_ratetable which contains a line of data for each transmission range. 20/40Mhz and guard interval is already contained in this table (encoded in "phy" variable). Just the MCS number is missing.
Well, yes, but it's not done uniformly across drivers.
Quoted 3 lines
And I think the intel driver has the necessary data too. If I understand the iwl5000 driver, it pushes the rate index (even for 802.11n) through
ieee80211_rx_statusinto mac80211.
Sort of, yes, but again, in a much different way. We really have to rename struct ieee80211_tx_rate to struct ieee80211_txrx_rate and embed it into struct ieee80211_rx_status for doing this properly.
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
Quoted 2 lines
then we also don't need the values for the number of streams since those are perfect multiples (1x, 2x, 3x, 4x for up to 4 streams).
Well if you have the MCS index and HT mode you get the # of streams. Not sure I understood the perfect multiple stuff.
Quoted 8 lines
Quoted 3 lines
Right, but you don't need to store a bitrate for MCS 0, 8, 16 and 24, the latter three can just use the first multiplied by 2, 3 and 4 respectively.
When I looked at the table in the wiki I noticed it cannot be created just by a little bit arithmetric ? Maybe someone can look at the 802.11 draft if we don't need the tables at all but just use a formula ? If yes we could remove them from kernelspace and just add a macro for calculating the rate into a userspace-accessable header file.
I checked for a bit, but it's not trivial. Cf.
http://www.dsprelated.com/showmessage/92947/1.php
Quoted 11 lines
Quoted 9 lines
Quoted 6 lines
Quoted 3 lines
and then nest the bitrate information into the
STA_INFO_RATE, just like station flags are nested etc. That way theRATE_INFOthings could also be used elsewhere.So we'll have to add an enum then too to distinguish which rate this is for.
No, we know that based on what "container" attribute it's contained in, in netlink.
So it's possible to define a substructure in the station info in nl80211 ? Sounds like a nice way to construct the tx/rx rate.
Yes, you do that by nesting. nl80211 already does that for phy info and many other things, you should be able to figure it out, just look for nla_nest_start/nla_nest_end.
Quoted 1 line
I will see if I get a "v6" patch ready during the weekend.
Thanks!
johannes
Re: RFC Patch v2: Add signal strength to nl80211station info
Am Friday 05 December 2008 10:45:10 schrieb Johannes Berg:
Quoted 6 lines
Quoted 3 lines
Ath9k has it's ***_ratetable which contains a line of data for each transmission range. 20/40Mhz and guard interval is already contained in this table (encoded in "phy" variable). Just the MCS number is missing.
Well, yes, but it's not done uniformly across drivers.
Quoted 7 lines
Quoted 3 lines
And I think the intel driver has the necessary data too. If I understand the iwl5000 driver, it pushes the rate index (even for 802.11n) through
ieee80211_rx_statusinto mac80211.Sort of, yes, but again, in a much different way. We really have to rename struct
ieee80211_tx_rateto structieee80211_txrx_rateand embed it into structieee80211_rx_statusfor doing this properly.
How many 802.11n capable drivers exist in mac80211 at the moment ?
Henning
*************************************************
Diplom Informatiker Henning Rogge
Forschungsgesellschaft für
Angewandte Naturwissenschaften e. V. (FGAN)
Neuenahrer Str. 20, 53343 Wachtberg, Germany
Tel.: 0049 (0)228 9435-961
Fax: 0049 (0)228 9435-685
E-Mail: [email protected]
Web: www.fgan.de
************************************************
Sitz der Gesellschaft: Bonn
Registergericht: Amtsgericht Bonn VR 2530
Vorstand: Dr. rer. nat. Ralf Dornhaus (Vors.), Prof. Dr. Joachim Ender (Stellv.)
Johannes Berg
maintainerRe: RFC Patch v2: Add signal strength to nl80211station info
Quoted 11 lines · Henning Rogge
Am Friday 05 December 2008 10:45:10 schrieb Johannes Berg:
Quoted 10 lines
Quoted 3 lines
Ath9k has it's ***_ratetable which contains a line of data for each transmission range. 20/40Mhz and guard interval is already contained in this table (encoded in "phy" variable). Just the MCS number is missing.
Well, yes, but it's not done uniformly across drivers.
Quoted 3 lines
And I think the intel driver has the necessary data too. If I understand the iwl5000 driver, it pushes the rate index (even for 802.11n) through
ieee80211_rx_statusinto mac80211.
Quoted 5 lines
Quoted 3 lines
Sort of, yes, but again, in a much different way. We really have to rename struct
ieee80211_tx_rateto structieee80211_txrx_rateand embed it into structieee80211_rx_statusfor doing this properly.How many 802.11n capable drivers exist in mac80211 at the moment ?
Only those two, really, but more are in development, for example ar9170 and rt2800.
johannes
Re: RFC Patch v2: Add signal strength to nl80211station info
I just did a few calculations about the tx/rx rates in 802.11n and I think I can replace all of them with simple integer arithmetics. Only the 20Mhz rates with short guard interval are a little bit off (I think I miss two of them by 0.1 MBit/s and one of them by 0.2 MBit/s)...
do you think that's accurate enough ?
Henning
Johannes Berg
maintainerRe: RFC Patch v2: Add signal strength to nl80211station info
Quoted 6 lines · Henning Rogge
I just did a few calculations about the tx/rx rates in 802.11n and I think I can replace all of them with simple integer arithmetics. Only the 20Mhz rates with short guard interval are a little bit off (I think I miss two of them by 0.1 MBit/s and one of them by 0.2 MBit/s)...
do you think that's accurate enough ?
Yes, well, depending on which values you used you might have run into the fact that the values from the tables were already rounded.
johannes
Re: RFC Patch v2: Add signal strength to nl80211station info
Quoted 2 lines · On Saturday 06 December 2008 10:15:20 Johannes Berg wrote:
Yes, well, depending on which values you used you might have run into the fact that the values from the tables were already rounded.
Both errors happen for 20 Mhz channels... one of them is definitely a typo in the wiki.
I get 144.4 MBit/s (wiki says 144.0) for MCS 15 (long GI)
and 115.6 MBit/s (wiki says 173.3, which is a typo !) for MCS 27(short GI).
in pseudocode:
-----------------
int modulation = mcs & 7;
int streams = mcs / 8;
int bitrate = (flags & 40MHZ) ? 13500000 : 6500000;
if (modulation < 4)
bitrate *= (modulation + 1);
else if (modulation == 4)
bitrate *= (modulation + 2);
else
bitrate *= (modulation + 3);bitrate *= streams;
if (flags & SHORT_GI)
bitrate = (bitrate * 10) / 9;
return (bitrate + 50000) / 100000; // do NOT just round down
Henning
Re: RFC Patch v2: Add signal strength to nl80211station info
In reply to Johannes BergOkay, here is v6 of my patch... feel free to rip it apart. ;)
Changes since v1:
- removed noise and quality from station info in NL80211
- added bandwith to station info in NL80211
- changed name of patch file to nl80211ext_v2.patch
Changes since v2:
- added kernel comment lines for new fields/enums
- changed name of "bandwith" field to tx_bitrate
Changes since v3:
- added rx_bitrate to station info and sta_info
- remember bitrate of last received unicast packet to this station
- decode 802.11n MCS index for nl80211
(maybe this should be ported to WEXT too ?)
Changes since v4:
- added tx_bitrate_flags adn tx_bitrate_mcs field to station info
- added flags for 40Mhz and small guard interval to NL80211 station info
- added mcs field to NL80211 station info
Changes since v5:
- remove rx_bitrate from patch until we get a sane way to learn the details of received 802.11n packages
-replace 802.11n bitrate arrays with calculation based on basic rates
- pushed txrate nl80211 stationinfo into nested attribute
- created station_info_rate_flags enum to save bitrate flags in station_info
- cleanup of kerneldoc
TODO:
- push magic numbers of sta_get_80211n_bitrate (65/135) into constants
- coding style cleanup
Henning
include/linux/nl80211.h +29 -0
@@ -425,6 +425,30 @@ enum nl80211_sta_flags { };/** +* enum nl80211_sta_info_rate - station information about bitrate +* +* These attribute types are used with %NL80211_STA_INFO_TXRATE +* when getting information about the bitrate of a station. +* +* @__NL80211_STA_INFO_RATE_INVALID: attribute number 0 is reserved +* @NL80211_STA_INFO_RATE_TOTAL: total bitrate (u16, 100kbit/s) +* @NL80211_STA_INFO_RATE_MCS: mcs index for 802.11n (u8) +* @NL80211_STA_INFO_RATE_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate +* @NL80211_STA_INFO_RATE_SHORT_GI: 400ns guard interval +*/ +enum nl80211_sta_info_rate { + __NL80211_STA_INFO_RATE_INVALID, +NL80211_STA_INFO_RATE_TOTAL , +NL80211_STA_INFO_RATE_MCS , +NL80211_STA_INFO_RATE_40_MHZ_WIDTH , +NL80211_STA_INFO_RATE_SHORT_GI , + +/* keep last */ + __NL80211_STA_INFO_RATE_AFTER_LAST, +NL80211_STA_INFO_RATE_MAX = __NL80211_STA_INFO_RATE_AFTER_LAST -1 +}; + +/** * enum nl80211_sta_info - station information * * These attribute types are used with %NL80211_ATTR_STA_INFO
@@ -436,6 +460,9 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received package (u8, dBm) +* @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute +* containing info as possible, see &enum nl80211_sta_info_txrate. */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID,
@@ -445,6 +472,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_TX_BITRATE ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +32 -0
@@ -169,6 +169,10 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_RX_BITRATE: @rx_bitrate filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled +* (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -177,6 +181,25 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , +STATION_INFO_RX_BITRATE =1 <<7 , + STATION_INFO_TX_BITRATE = 1<<8, +}; + +/** +* enum station_info_rate_flags - station transmission rate flags +* +* Used by the driver to indicate the specific rate transmission +* type for 802.11n transmissions. +* +* @STATION_INFO_BITRATE_MCS: @tx_bitrate_mcs filled +* @STATION_INFO_BITRATE_40_MHZ_WIDTH: 40 Mhz width transmission +* @STATION_INFO_BITRATE_SHORT_GI: 400ns guard interval +*/ +enum station_info_rate_flags { +STATION_INFO_BITRATE_MCS =1 <<0 , +STATION_INFO_BITRATE_40_MHZ_WIDTH =1 <<1 , +STATION_INFO_BITRATE_SHORT_GI =1 <<2 , };/**
@@ -191,6 +214,11 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received package in dBm +* @txrate_total: current unicast bitrate to this station in 100 kbit/sec +* @txrate_flags: bitflag of flags from &enum station_info_bitrate_flags +* @txrate_mcs: MCS index of a 802.11n transmission, see +* &enum station_info_bitrate_flags */ struct station_info {u32 filled;
@@ -200,6 +228,10 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +u16 txrate_total; +u8 txrate_flags; +u8 txrate_mcs; };/**
net/mac80211/cfg.c +48 -1
66 lines not on this page · raw message
net/mac80211/rx.c +2 -1
@@ -727,8 +727,9 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)if (rx->sdata->vif.type ==NL80211_IFTYPE_ADHOC ) {u8 *bssid =ieee80211_get_bssid (hdr, rx->skb->len,NL80211_IFTYPE_ADHOC ); -if (compare_ether_addr (bssid, rx->sdata->u.sta.bssid) ==0 ) +if (compare_ether_addr (bssid, rx->sdata->u.sta.bssid) ==0 ) { sta->last_rx = jiffies; + } }else if (!is_multicast_ether_addr (hdr->addr1) || rx->sdata->vif.type ==NL80211_IFTYPE_STATION ) {
net/wireless/nl80211.c +22 -1
@@ -16,6 +16,7 @@#include <linux/netlink.h> #include <net/genetlink.h> #include <net/cfg80211.h> +#include <net/mac80211.h> #include "core.h" #include "nl80211.h" #include "reg.h"
@@ -1084,7 +1085,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, u8 *mac_addr, struct station_info *sinfo) { void *hdr; -struct nlattr *sinfoattr; +struct nlattr *sinfoattr, *txrate; hdr =nl80211hdr_put (msg, pid, seq, flags,NL80211_CMD_NEW_STATION );if (!hdr)
@@ -1114,7 +1115,27 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,if (sinfo->filled &STATION_INFO_PLINK_STATE )NLA_PUT_U8 (msg,NL80211_STA_INFO_PLINK_STATE , sinfo->plink_state); +if (sinfo->filled &STATION_INFO_SIGNAL ) +NLA_PUT_U8 (msg,NL80211_STA_INFO_SIGNAL , + sinfo->signal); +if (sinfo->filled &STATION_INFO_TX_BITRATE ) { + txrate =nla_nest_start (msg,NL80211_STA_INFO_TX_BITRATE ); +if (!txrate) + goto nla_put_failure; + +NLA_PUT_U16 (msg,NL80211_STA_INFO_RATE_TOTAL , + sinfo->txrate_total); +if (sinfo->txrate_flags &STATION_INFO_BITRATE_MCS ) +NLA_PUT_U16 (msg,NL80211_STA_INFO_RATE_MCS , + sinfo->txrate_mcs); +if (sinfo->txrate_flags &STATION_INFO_BITRATE_40_MHZ_WIDTH ) +NLA_PUT_FLAG (msg,NL80211_STA_INFO_RATE_40_MHZ_WIDTH ); +if (sinfo->txrate_flags &STATION_INFO_BITRATE_SHORT_GI ) +NLA_PUT_FLAG (msg,NL80211_STA_INFO_RATE_SHORT_GI ); + +nla_nest_end (msg, txrate); + }nla_nest_end (msg, sinfoattr);return genlmsg_end (msg, hdr);
Re: RFC Patch v2: Add signal strength to nl80211station info
Okay, here is v6 of my patch... feel free to rip it apart. ;) (forgot to put the patch inline too... sorry)
Changes since v1:
- removed noise and quality from station info in NL80211
- added bandwith to station info in NL80211
- changed name of patch file to nl80211ext_v2.patch
Changes since v2:
- added kernel comment lines for new fields/enums
- changed name of "bandwith" field to tx_bitrate
Changes since v3:
- added rx_bitrate to station info and sta_info
- remember bitrate of last received unicast packet to this station
- decode 802.11n MCS index for nl80211
(maybe this should be ported to WEXT too ?)
Changes since v4:
- added tx_bitrate_flags adn tx_bitrate_mcs field to station info
- added flags for 40Mhz and small guard interval to NL80211 station info
- added mcs field to NL80211 station info
Changes since v5:
- remove rx_bitrate from patch until we get a sane way to learn the details of received 802.11n packages
-replace 802.11n bitrate arrays with calculation based on basic rates
- pushed txrate nl80211 stationinfo into nested attribute
- created station_info_rate_flags enum to save bitrate flags in station_info - cleanup of kerneldoc
TODO:
- push magic numbers of sta_get_80211n_bitrate (65/135) into constants
- coding style cleanup
Henning
-----------------------
include/linux/nl80211.h +25 -0
@@ -425,6 +425,30 @@ enum nl80211_sta_flags { };/** +* enum nl80211_sta_info_rate - station information about bitrate +* +* These attribute types are used with %NL80211_STA_INFO_TXRATE +* when getting information about the bitrate of a station. +* +* @__NL80211_STA_INFO_RATE_INVALID: attribute number 0 is reserved +* @NL80211_STA_INFO_RATE_TOTAL: total bitrate (u16, 100kbit/s) +* @NL80211_STA_INFO_RATE_MCS: mcs index for 802.11n (u8) +* @NL80211_STA_INFO_RATE_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate +* @NL80211_STA_INFO_RATE_SHORT_GI: 400ns guard interval +*/ +enum nl80211_sta_info_rate { + __NL80211_STA_INFO_RATE_INVALID, +NL80211_STA_INFO_RATE_TOTAL , +NL80211_STA_INFO_RATE_MCS , +NL80211_STA_INFO_RATE_40_MHZ_WIDTH , +NL80211_STA_INFO_RATE_SHORT_GI , + +/* keep last */ + __NL80211_STA_INFO_RATE_AFTER_LAST, +NL80211_STA_INFO_RATE_MAX = __NL80211_STA_INFO_RATE_AFTER_LAST -1 +}; + +/** * enum nl80211_sta_info - station information * * These attribute types are used with %NL80211_ATTR_STA_INFO
@@ -436,6 +460,9 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received package (u8,
dBm)
+ * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute
+ * containing info as possible, see &enum nl80211_sta_info_txrate. */
enum nl80211_sta_info {
__NL80211_STA_INFO_INVALID,
@@ -445,6 +472,8 @@ enum nl80211_sta_info {
NL80211_STA_INFO_LLID,
NL80211_STA_INFO_PLID,
NL80211_STA_INFO_PLINK_STATE,
+ NL80211_STA_INFO_SIGNAL,
+ NL80211_STA_INFO_TX_BITRATE,
/* keep last */
__NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +32 -0
@@ -169,6 +169,10 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_RX_BITRATE: @rx_bitrate filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled +* (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -177,6 +181,25 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , +STATION_INFO_RX_BITRATE =1 <<7 , + STATION_INFO_TX_BITRATE = 1<<8, +}; + +/** +* enum station_info_rate_flags - station transmission rate flags +* +* Used by the driver to indicate the specific rate transmission +* type for 802.11n transmissions. +* +* @STATION_INFO_BITRATE_MCS: @tx_bitrate_mcs filled +* @STATION_INFO_BITRATE_40_MHZ_WIDTH: 40 Mhz width transmission +* @STATION_INFO_BITRATE_SHORT_GI: 400ns guard interval +*/ +enum station_info_rate_flags { +STATION_INFO_BITRATE_MCS =1 <<0 , +STATION_INFO_BITRATE_40_MHZ_WIDTH =1 <<1 , +STATION_INFO_BITRATE_SHORT_GI =1 <<2 , };/**
@@ -191,6 +214,11 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received package in dBm +* @txrate_total: current unicast bitrate to this station in 100 kbit/sec +* @txrate_flags: bitflag of flags from &enum station_info_bitrate_flags +* @txrate_mcs: MCS index of a 802.11n transmission, see +* &enum station_info_bitrate_flags */ struct station_info {u32 filled;
@@ -200,6 +228,10 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +u16 txrate_total; +u8 txrate_flags; +u8 txrate_mcs; };/**
net/mac80211/cfg.c +0 -0
@@ -304,18 +304,65 @@ static int ieee80211_config_default_key(struct wiphy
*wiphy,
return 0;
}
+static u16 sta_get_80211n_bitrate(struct ieee80211_tx_rate *rate) +{
+ int modulation = rate->idx & 7;
+ int streams = rate->idx >> 3;
+
+ int bitrate = (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? 13500000 :
6500000;
+
+ if (modulation < 4)
+ bitrate *= (modulation + 1);
+ else if (modulation == 4)
+ bitrate *= (modulation + 2);
+ else
+ bitrate *= (modulation + 3);
+
+ bitrate *= streams;
+
+ if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
+ bitrate = (bitrate * 10) / 9;
+
+ return (bitrate + 50000) / 100000; // do NOT just round down
+}
+
static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) {
struct ieee80211_sub_if_data *sdata = sta->sdata;
sinfo->filled = STATION_INFO_INACTIVE_TIME |
STATION_INFO_RX_BYTES |
- STATION_INFO_TX_BYTES;
+ STATION_INFO_TX_BYTES |
+ STATION_INFO_RX_BITRATE |
+ STATION_INFO_TX_BITRATE;
sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes;
sinfo->tx_bytes = sta->tx_bytes;
+ if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
+ sinfo->filled |= STATION_INFO_SIGNAL;
+ sinfo->signal = sta->last_signal;
+ }
+
+ sinfo->txrate_flags = 0;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
+ sinfo->txrate_flags |= STATION_INFO_BITRATE_MCS;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ sinfo->txrate_flags |= STATION_INFO_BITRATE_40_MHZ_WIDTH;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI)
+ sinfo->txrate_flags |= STATION_INFO_BITRATE_SHORT_GI;
+
+ if (!(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) {
+ struct ieee80211_supported_band *sband;
+ sband = sta->local->hw.wiphy->bands[sta->local->hw.conf.channel->band];
+ sinfo->txrate_total = sband->bitrates[sta->last_tx_rate.idx].bitrate;
+ }
+ else {
+ sinfo->txrate_total = sta_get_80211n_bitrate(&sta->last_tx_rate);
+ sinfo->txrate_mcs = sta->last_tx_rate.idx;
+ }
+
if (ieee80211_vif_is_mesh(&sdata->vif)) {
#ifdef CONFIG_MAC80211_MESH
sinfo->filled |= STATION_INFO_LLID |
net/mac80211/rx.c +2 -1
@@ -727,8 +727,9 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)if (rx->sdata->vif.type ==NL80211_IFTYPE_ADHOC ) {u8 *bssid =ieee80211_get_bssid (hdr, rx->skb->len,NL80211_IFTYPE_ADHOC ); -if (compare_ether_addr (bssid, rx->sdata->u.sta.bssid) ==0 ) +if (compare_ether_addr (bssid, rx->sdata->u.sta.bssid) ==0 ) { sta->last_rx = jiffies; + } }else if (!is_multicast_ether_addr (hdr->addr1) || rx->sdata->vif.type ==NL80211_IFTYPE_STATION ) {
net/wireless/nl80211.c +1 -0
@@ -16,6 +16,7 @@#include <linux/netlink.h> #include <net/genetlink.h> #include <net/cfg80211.h> +#include <net/mac80211.h> #include "core.h" #include "nl80211.h" #include "reg.h"
@@ -1084,7 +1085,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32
pid, u32 seq,
u8 *mac_addr, struct station_info *sinfo)
{
void *hdr;
- struct nlattr *sinfoattr;
+ struct nlattr *sinfoattr, *txrate;
hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION); if (!hdr)
@@ -1114,7 +1115,27 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
if (sinfo->filled & STATION_INFO_PLINK_STATE)
NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
sinfo->plink_state);
+ if (sinfo->filled & STATION_INFO_SIGNAL)
+ NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
+ sinfo->signal);
+ if (sinfo->filled & STATION_INFO_TX_BITRATE) {
+ txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE);
+ if (!txrate)
+ goto nla_put_failure;
+
+ NLA_PUT_U16(msg, NL80211_STA_INFO_RATE_TOTAL,
+ sinfo->txrate_total);
+ if (sinfo->txrate_flags & STATION_INFO_BITRATE_MCS)
+ NLA_PUT_U16(msg, NL80211_STA_INFO_RATE_MCS,
+ sinfo->txrate_mcs);
+ if (sinfo->txrate_flags & STATION_INFO_BITRATE_40_MHZ_WIDTH)
+ NLA_PUT_FLAG(msg, NL80211_STA_INFO_RATE_40_MHZ_WIDTH);
+ if (sinfo->txrate_flags & STATION_INFO_BITRATE_SHORT_GI)
+ NLA_PUT_FLAG(msg, NL80211_STA_INFO_RATE_SHORT_GI);
+
+ nla_nest_end(msg, txrate);
+ }
nla_nest_end(msg, sinfoattr);
return genlmsg_end(msg, hdr);
include/linux/nl80211.h +29 -0
@@ -425,6 +425,30 @@ enum nl80211_sta_flags { };/** +* enum nl80211_sta_info_rate - station information about bitrate +* +* These attribute types are used with %NL80211_STA_INFO_TXRATE +* when getting information about the bitrate of a station. +* +* @__NL80211_STA_INFO_RATE_INVALID: attribute number 0 is reserved +* @NL80211_STA_INFO_RATE_TOTAL: total bitrate (u16, 100kbit/s) +* @NL80211_STA_INFO_RATE_MCS: mcs index for 802.11n (u8) +* @NL80211_STA_INFO_RATE_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate +* @NL80211_STA_INFO_RATE_SHORT_GI: 400ns guard interval +*/ +enum nl80211_sta_info_rate { + __NL80211_STA_INFO_RATE_INVALID, +NL80211_STA_INFO_RATE_TOTAL , +NL80211_STA_INFO_RATE_MCS , +NL80211_STA_INFO_RATE_40_MHZ_WIDTH , +NL80211_STA_INFO_RATE_SHORT_GI , + +/* keep last */ + __NL80211_STA_INFO_RATE_AFTER_LAST, +NL80211_STA_INFO_RATE_MAX = __NL80211_STA_INFO_RATE_AFTER_LAST -1 +}; + +/** * enum nl80211_sta_info - station information * * These attribute types are used with %NL80211_ATTR_STA_INFO
@@ -436,6 +460,9 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received package (u8, dBm) +* @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute +* containing info as possible, see &enum nl80211_sta_info_txrate. */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID,
@@ -445,6 +472,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_TX_BITRATE ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +32 -0
@@ -169,6 +169,10 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_RX_BITRATE: @rx_bitrate filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled +* (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -177,6 +181,25 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , +STATION_INFO_RX_BITRATE =1 <<7 , + STATION_INFO_TX_BITRATE = 1<<8, +}; + +/** +* enum station_info_rate_flags - station transmission rate flags +* +* Used by the driver to indicate the specific rate transmission +* type for 802.11n transmissions. +* +* @STATION_INFO_BITRATE_MCS: @tx_bitrate_mcs filled +* @STATION_INFO_BITRATE_40_MHZ_WIDTH: 40 Mhz width transmission +* @STATION_INFO_BITRATE_SHORT_GI: 400ns guard interval +*/ +enum station_info_rate_flags { +STATION_INFO_BITRATE_MCS =1 <<0 , +STATION_INFO_BITRATE_40_MHZ_WIDTH =1 <<1 , +STATION_INFO_BITRATE_SHORT_GI =1 <<2 , };/**
@@ -191,6 +214,11 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received package in dBm +* @txrate_total: current unicast bitrate to this station in 100 kbit/sec +* @txrate_flags: bitflag of flags from &enum station_info_bitrate_flags +* @txrate_mcs: MCS index of a 802.11n transmission, see +* &enum station_info_bitrate_flags */ struct station_info {u32 filled;
@@ -200,6 +228,10 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +u16 txrate_total; +u8 txrate_flags; +u8 txrate_mcs; };/**
net/mac80211/cfg.c +48 -1
66 lines not on this page · raw message
net/mac80211/rx.c +2 -1
@@ -727,8 +727,9 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)if (rx->sdata->vif.type ==NL80211_IFTYPE_ADHOC ) {u8 *bssid =ieee80211_get_bssid (hdr, rx->skb->len,NL80211_IFTYPE_ADHOC ); -if (compare_ether_addr (bssid, rx->sdata->u.sta.bssid) ==0 ) +if (compare_ether_addr (bssid, rx->sdata->u.sta.bssid) ==0 ) { sta->last_rx = jiffies; + } }else if (!is_multicast_ether_addr (hdr->addr1) || rx->sdata->vif.type ==NL80211_IFTYPE_STATION ) {
net/wireless/nl80211.c +22 -1
@@ -16,6 +16,7 @@#include <linux/netlink.h> #include <net/genetlink.h> #include <net/cfg80211.h> +#include <net/mac80211.h> #include "core.h" #include "nl80211.h" #include "reg.h"
@@ -1084,7 +1085,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, u8 *mac_addr, struct station_info *sinfo) { void *hdr; -struct nlattr *sinfoattr; +struct nlattr *sinfoattr, *txrate; hdr =nl80211hdr_put (msg, pid, seq, flags,NL80211_CMD_NEW_STATION );if (!hdr)
@@ -1114,7 +1115,27 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,if (sinfo->filled &STATION_INFO_PLINK_STATE )NLA_PUT_U8 (msg,NL80211_STA_INFO_PLINK_STATE , sinfo->plink_state); +if (sinfo->filled &STATION_INFO_SIGNAL ) +NLA_PUT_U8 (msg,NL80211_STA_INFO_SIGNAL , + sinfo->signal); +if (sinfo->filled &STATION_INFO_TX_BITRATE ) { + txrate =nla_nest_start (msg,NL80211_STA_INFO_TX_BITRATE ); +if (!txrate) + goto nla_put_failure; + +NLA_PUT_U16 (msg,NL80211_STA_INFO_RATE_TOTAL , + sinfo->txrate_total); +if (sinfo->txrate_flags &STATION_INFO_BITRATE_MCS ) +NLA_PUT_U16 (msg,NL80211_STA_INFO_RATE_MCS , + sinfo->txrate_mcs); +if (sinfo->txrate_flags &STATION_INFO_BITRATE_40_MHZ_WIDTH ) +NLA_PUT_FLAG (msg,NL80211_STA_INFO_RATE_40_MHZ_WIDTH ); +if (sinfo->txrate_flags &STATION_INFO_BITRATE_SHORT_GI ) +NLA_PUT_FLAG (msg,NL80211_STA_INFO_RATE_SHORT_GI ); + +nla_nest_end (msg, txrate); + }nla_nest_end (msg, sinfoattr);return genlmsg_end (msg, hdr);
Johannes Berg
maintainerRe: RFC Patch v2: Add signal strength to nl80211station info
In reply to Henning RoggeQuoted 1 line · Henning Rogge
Okay, here is v6 of my patch... feel free to rip it apart. ;)
Heh. Please inline patches, makes it much easier.
Quoted 13 lines
/**
+ * enumnl80211_sta_info_rate- station information about bitrate
+ *
+ * These attribute types are used with %NL80211_STA_INFO_TXRATE
+ * when getting information about the bitrate of a station.
+ *
+ * @__NL80211_STA_INFO_RATE_INVALID: attribute number 0 is reserved
+ * @NL80211_STA_INFO_RATE_TOTAL: total bitrate (u16, 100kbit/s)
+ * @NL80211_STA_INFO_RATE_MCS: mcs index for 802.11n (u8)
+ * @NL80211_STA_INFO_RATE_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate
+ * @NL80211_STA_INFO_RATE_SHORT_GI: 400ns guard interval
+ */include/linux/nl80211.h +1
-0+enum nl80211_sta_info_rate {
include/linux/nl80211.h enum nl80211_sta_flags { · line 449
Quoted 10 lines
include/linux/nl80211.h +10
-0+ __NL80211_STA_INFO_RATE_INVALID, +NL80211_STA_INFO_RATE_TOTAL , +NL80211_STA_INFO_RATE_MCS , +NL80211_STA_INFO_RATE_40_MHZ_WIDTH , +NL80211_STA_INFO_RATE_SHORT_GI , + +/* keep last */ + __NL80211_STA_INFO_RATE_AFTER_LAST, + NL80211_STA_INFO_RATE_MAX = __NL80211_STA_INFO_RATE_AFTER_LAST - 1 +};
I'd drop the _STA_ part from these and do RATE_INFO_... since we may end up using these for other things potentially. Not sure we will, but who knows. I could imagine using it to fix a transmit rate, for example, and then it wouldn't necessarily be per station.
Quoted 1 line
+ * @NL80211_STA_INFO_SIGNAL: signal strength of last received package (u8, dBm)
packet, or, more accurately, PPDU I guess
Quoted 2 lines
+ * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute
+ * containing info as possible, see &enumnl80211_sta_info_txrate.
Please indent with a tab here
include/net/cfg80211.h enum station_info_flags { · line 185
Quoted 12 lines
+ * @STATION_INFO_RX_BITRATE: @rx_bitrate filled
+ * @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled
+ * (tx_bitrate,tx_bitrate_flagsandtx_bitrate_mcs) */
enumstation_info_flags{
STATION_INFO_INACTIVE_TIME= 1<<0,include/net/cfg80211.h +2
-0@@ -177,6 +181,25 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , + STATION_INFO_RX_BITRATE = 1<<7,
RX bitrate?
Quoted 5 lines
include/net/cfg80211.h +5
-0+/** +* enum station_info_rate_flags - station transmission rate flags +* +* Used by the driver to indicate the specific rate transmission +* type for 802.11n transmissions.
include/net/cfg80211.h enum station_info_flags { · line 203
Quoted 10 lines
include/net/cfg80211.h +9
-0+* +* @STATION_INFO_BITRATE_MCS: @tx_bitrate_mcs filled +* @STATION_INFO_BITRATE_40_MHZ_WIDTH: 40 Mhz width transmission +* @STATION_INFO_BITRATE_SHORT_GI: 400ns guard interval +*/ +enum station_info_rate_flags { +STATION_INFO_BITRATE_MCS =1 <<0 , +STATION_INFO_BITRATE_40_MHZ_WIDTH =1 <<1 , +STATION_INFO_BITRATE_SHORT_GI =1 <<2 , };
Same here as the first comment, this is rate specific, so I'd call these BITRATE_* or something like that.
Quoted 14 lines
include/net/cfg80211.h +5
-0/** @@ -191,6 +214,11 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received package in dBm +* @txrate_total: current unicast bitrate to this station in 100 kbit/sec +* @txrate_flags: bitflag of flags from &enum station_info_bitrate_flags +* @txrate_mcs: MCS index of a 802.11n transmission, see +* &enum station_info_bitrate_flags */ struct station_info {u32 filled;
include/net/cfg80211.h struct station_info { · line 234
Quoted 7 lines
include/net/cfg80211.h +4
-0@@ -200,6 +228,10 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +u16 txrate_total; +u8 txrate_flags; +u8 txrate_mcs;
can you please move the rate parts into a new struct, so we can use tx.flags, tx.mcs etc. and later just need to add a second instance of the struct for rx
Quoted 11 lines
net/mac80211/cfg.c +11
-0+static u16 sta_get_80211n_bitrate (struct ieee80211_tx_rate *rate) +{ +int modulation = rate->idx &7 ; +int streams = rate->idx >>3 ; + +int bitrate = (rate->flags &IEEE80211_TX_RC_40_MHZ_WIDTH ) ?13500000 :6500000 ; + +if (modulation <4 ) + bitrate *= (modulation +1 ); +else if (modulation ==4 ) + bitrate *= (modulation +2 );
net/mac80211/cfg.c static int ieee80211_config_default_key(struct wiphy *wiphy, · line 327
Quoted 10 lines
net/mac80211/cfg.c +10
-0+else + bitrate *= (modulation +3 ); + + bitrate *= streams; + +if (rate->flags &IEEE80211_TX_RC_SHORT_GI ) + bitrate = (bitrate *10 ) /9 ; + +return (bitrate +50000 ) /100000 ;// do NOT just round down +}
Don't use // comments please, see Documentation/CodingStyle.
Also, if we really really need this information (I still don't see why the kernel has to calculate it) then it should be in cfg80211 not mac80211 so other drivers could potentially make use of it. Personally, I'd just leave it out though.
net/mac80211/cfg.c static int ieee80211_config_default_key(struct wiphy *wiphy, · line 337
Quoted 6 lines
sinfo->filled = STATION_INFO_INACTIVE_TIME | STATION_INFO_RX_BYTES |net/mac80211/cfg.c +3
-1-STATION_INFO_TX_BYTES ; +STATION_INFO_TX_BYTES | +STATION_INFO_RX_BITRATE | +STATION_INFO_TX_BITRATE ;
RX?
net/mac80211/rx.c ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) · line 735
Quoted 13 lines
net/mac80211/rx.c +2
-1@@ -727,8 +727,9 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)if (rx->sdata->vif.type ==NL80211_IFTYPE_ADHOC ) {u8 *bssid =ieee80211_get_bssid (hdr, rx->skb->len,NL80211_IFTYPE_ADHOC ); -if (compare_ether_addr (bssid, rx->sdata->u.sta.bssid) ==0 ) +if (compare_ether_addr (bssid, rx->sdata->u.sta.bssid) ==0 ) { sta->last_rx = jiffies; + } }else if (!is_multicast_ether_addr (hdr->addr1) || rx->sdata->vif.type ==NL80211_IFTYPE_STATION ) {
That looks unintended
net/wireless/nl80211.c line 19
Quoted 9 lines
net/wireless/nl80211.c +1
-0@@ -16,6 +16,7 @@#include <linux/netlink.h> #include <net/genetlink.h> #include <net/cfg80211.h> +#include <net/mac80211.h>
Ahem. Please observe the layering, cfg80211 and nl80211 are strictly below mac80211.
I'd rename _TOTAL to _LEGACY and remove the calculation for MCS rates, that way it's obviously clear what you're getting in userland.
johannes
Re: RFC Patch v2: Add signal strength to nl80211station info
Quoted 3 lines · On Saturday 06 December 2008 15:51:20 Johannes Berg wrote:
Quoted 1 line
Okay, here is v6 of my patch... feel free to rip it apart. ;)
Heh. Please inline patches, makes it much easier.
Resend it inlined... but you were a little bit too fast... ;)
Quoted 4 lines
I'd drop the _STA_ part from these and do
RATE_INFO_... since we may end up using these for other things potentially. Not sure we will, but who knows. I could imagine using it to fix a transmit rate, for example, and then it wouldn't necessarily be per station.
Okay, will be done in v7
Quoted 4 lines
Quoted 2 lines
+ * @NL80211_STA_INFO_SIGNAL: signal strength of last received package (u8, dBm)
packet, or, more accurately, PPDU I guess
ok.
Quoted 6 lines
Quoted 3 lines
+ * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute + * containing info as possible, see &enum
nl80211_sta_info_txrate.Please indent with a tab here
Quoted 14 lines
include/net/cfg80211.h enum station_info_flags { · line 185
Quoted 12 lines
+ * @STATION_INFO_RX_BITRATE: @rx_bitrate filled
+ * @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled
+ * (tx_bitrate,tx_bitrate_flagsandtx_bitrate_mcs) */
enumstation_info_flags{
STATION_INFO_INACTIVE_TIME= 1<<0,include/net/cfg80211.h +2
-0@@ -177,6 +181,25 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , + STATION_INFO_RX_BITRATE = 1<<7,RX bitrate?
Okay, it seems I missed one place to remove the RX one... thought I had got all of them.
Quoted 10 lines
Quoted 10 lines
include/net/cfg80211.h +10
-0+/** +* enum station_info_rate_flags - station transmission rate flags +* +* Used by the driver to indicate the specific rate transmission +* type for 802.11n transmissions. +* +* @STATION_INFO_BITRATE_MCS: @tx_bitrate_mcs filled +* @STATION_INFO_BITRATE_40_MHZ_WIDTH: 40 Mhz width transmission +* @STATION_INFO_BITRATE_SHORT_GI: 400ns guard interval +*/
Quoted 8 lines
include/net/cfg80211.h enum station_info_flags { · line 203
Quoted 5 lines
include/net/cfg80211.h +4
-0+enum station_info_rate_flags { +STATION_INFO_BITRATE_MCS =1 <<0 , +STATION_INFO_BITRATE_40_MHZ_WIDTH =1 <<1 , +STATION_INFO_BITRATE_SHORT_GI =1 <<2 , };Same here as the first comment, this is rate specific, so I'd call these BITRATE_* or something like that.
okay.
Quoted 18 lines
Quoted 18 lines
include/net/cfg80211.h +2
-0/** @@ -191,6 +214,11 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received package in dBm +* @txrate_total: current unicast bitrate to this station in 100 kbit/sec + * @txrate_flags: bitflag of flags from &enum
station_info_bitrate_flags+ * @txrate_mcs: MCS index of a 802.11n transmission, see
+ * &enumstation_info_bitrate_flags
*/struct station_info { u32 filled;include/net/cfg80211.h +0
-0@@ -200,6 +228,10 @@ struct station_info {u16 llid;u16 plid;u8 plink_state;
Quoted 8 lines
include/net/cfg80211.h struct station_info { · line 234
Quoted 4 lines
include/net/cfg80211.h +4
-0+u8 signal; +u16 txrate_total; +u8 txrate_flags; +u8 txrate_mcs;can you please move the rate parts into a new struct, so we can use tx.flags, tx.mcs etc. and later just need to add a second instance of the struct for rx
struct bitrate_info ?
or maybe
struct cfg80211_bitrate_info ?
Quoted 15 lines
Quoted 15 lines
net/mac80211/cfg.c +6
-0+static u16 sta_get_80211n_bitrate (struct ieee80211_tx_rate *rate) +{ +int modulation = rate->idx &7 ; +int streams = rate->idx >>3 ; + + int bitrate = (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ?13500000 : 6500000; +
net/mac80211/cfg.c +8
-0+if (modulation <4 ) + bitrate *= (modulation +1 ); +else if (modulation ==4 ) + bitrate *= (modulation +2 ); +else + bitrate *= (modulation +3 ); + + bitrate *= streams;
Quoted 8 lines
net/mac80211/cfg.c static int ieee80211_config_default_key(struct wiphy *wiphy, · line 327
Quoted 6 lines
net/mac80211/cfg.c +6
-0+ +if (rate->flags &IEEE80211_TX_RC_SHORT_GI ) + bitrate = (bitrate *10 ) /9 ; + +return (bitrate +50000 ) /100000 ;// do NOT just round down +}Don't use // comments please, see
Documentation/CodingStyle.
Copypasta error from the "pseudocode", sorry.
Quoted 4 lines
Also, if we really really need this information (I still don't see why the kernel has to calculate it) then it should be in cfg80211 not mac80211 so other drivers could potentially make use of it. Personally, I'd just leave it out though.
Hmm... is "cfg.c" not part of cfg80211 ?
Quoted 8 lines
net/mac80211/cfg.c static int ieee80211_config_default_key(struct wiphy *wiphy, · line 337
Quoted 6 lines
sinfo->filled = STATION_INFO_INACTIVE_TIME | STATION_INFO_RX_BYTES |net/mac80211/cfg.c +3
-1-STATION_INFO_TX_BYTES ; +STATION_INFO_TX_BYTES | +STATION_INFO_RX_BITRATE | +STATION_INFO_TX_BITRATE ;RX?
Another one... I think I will have to post a v7 patch this weekend...
Quoted 7 lines
Quoted 7 lines
net/mac80211/rx.c +0
-1@@ -727,8 +727,9 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) if (rx->sdata->vif.type == NL80211_IFTYPE_ADHOC) {u8 *bssid =ieee80211_get_bssid (hdr, rx->skb->len,NL80211_IFTYPE_ADHOC ); - if (compare_ether_addr(bssid, rx->sdata->u.sta.bssid) ==
Quoted 8 lines
net/mac80211/rx.c ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) · line 735
Quoted 6 lines
net/mac80211/rx.c +1
-00) + if (compare_ether_addr(bssid, rx->sdata->u.sta.bssid) == 0) { sta->last_rx = jiffies; + } }else if (!is_multicast_ether_addr (hdr->addr1) || rx->sdata->vif.type ==NL80211_IFTYPE_STATION ) {That looks unintended
Yes.. I removed the "else" part for the rx_rate, but left the {} there.
Quoted 14 lines
net/wireless/nl80211.c line 19
Quoted 9 lines
net/wireless/nl80211.c +1
-0@@ -16,6 +16,7 @@#include <linux/netlink.h> #include <net/genetlink.h> #include <net/cfg80211.h> +#include <net/mac80211.h> Ahem. Please observe the layering, cfg80211 and nl80211 are strictly below mac80211.
Quoted 2 lines
I'd rename
_TOTALto_LEGACYand remove the calculation for MCS rates, that way it's obviously clear what you're getting in userland.
We need the "total bitrate" for 802.11abg rates. They have no mcs rates. The "legacy index" for non 802.11n bitrates points to a hw specific "band" array, so I don't think we can export it to userspace as an index.
Henning
Re: RFC Patch v2: Add signal strength to nl80211station info
Quoted 2 lines · On Saturday 06 December 2008 16:03:16 Henning Rogge wrote:
Quoted 2 lines
I'd rename
_TOTALto_LEGACYand remove the calculation for MCS rates, that way it's obviously clear what you're getting in userland.
Okay, after reading your mail a second time I understood you...
I think with removing the total bitrate for 802.11n we will just make the userspace interface more complex. You will have to look at four different things (flags, MCS, guard interval, legacy) just to get the bitrate, which will be the typical information the user wants to know. Is there anything nl80211 will gain if we don't put this value inside for all 802.11 ? We cannot drop it because of 802.11abg, so why not fill it with useful data ?
Henning
Johannes Berg
maintainerRe: RFC Patch v2: Add signal strength to nl80211station info
In reply to Henning RoggeQuoted 7 lines · Henning Rogge
Quoted 3 lines
can you please move the rate parts into a new struct, so we can use tx.flags, tx.mcs etc. and later just need to add a second instance of the struct for rx
struct
bitrate_info?
or maybe
structcfg80211_bitrate_info?
Either one is fine I guess.
Quoted 6 lines
Quoted 4 lines
Also, if we really really need this information (I still don't see why the kernel has to calculate it) then it should be in cfg80211 not mac80211 so other drivers could potentially make use of it. Personally, I'd just leave it out though.
Hmm... is "
cfg.c" not part of cfg80211 ?
No, cfg.c is part of mac80211, it's mac80211's code to interact with cfg80211, it won't be called for non-mac80211 drivers.
Quoted 3 lines
We need the "total bitrate" for 802.11abg rates. They have no mcs rates. The "legacy index" for non 802.11n bitrates points to a hw specific "band" array, so I don't think we can export it to userspace as an index.
But we can name it _legacy and put the bitrate there in units of 100kbps, and leave it out for MCS rates then.
johannes
Johannes Berg
maintainerRe: RFC Patch v2: Add signal strength to nl80211station info
In reply to Henning RoggeQuoted 11 lines · Henning Rogge
Quoted 2 lines · On Saturday 06 December 2008 16:03:16 Henning Rogge wrote:
Quoted 2 lines
I'd rename
_TOTALto_LEGACYand remove the calculation for MCS rates, that way it's obviously clear what you're getting in userland.Okay, after reading your mail a second time I understood you...
I think with removing the total bitrate for 802.11n we will just make the userspace interface more complex. You will have to look at four different things (flags, MCS, guard interval, legacy) just to get the bitrate, which will be the typical information the user wants to know. Is there anything nl80211 will gain if we don't put this value inside for all 802.11 ? We cannot drop it because of 802.11abg, so why not fill it with useful data ?
For one, I'm a bit concerned that the calculation is fairly complex, and may not always be necessary; especially divisions can be expensive on some CPUs.
Also, there are duplicate numbers possible, so just the pure bitrate will _not_ actually be "the typical information" because it's not specific enough, when debugging, for example, you will probably need to know whether it's short-gi or not.
johannes
Re: RFC Patch v2: Add signal strength to nl80211station info
Quoted 3 lines · On Saturday 06 December 2008 16:59:32 Johannes Berg wrote:
For one, I'm a bit concerned that the calculation is fairly complex, and may not always be necessary; especially divisions can be expensive on some CPUs.
What if I push the calculation into nl80211.c, so it will be only called when the a userspace process requests the station info ? This would mean the calculation is not done at all until someone needs the rate info.
Quoted 4 lines
Also, there are duplicate numbers possible, so just the pure bitrate will _not_ actually be "the typical information" because it's not specific enough, when debugging, for example, you will probably need to know whether it's short-gi or not.
Don't you think the normal nl80211 use will just be a display of "how fast are we doing at the moment" ? Most applications don't even need to set a rate, they just want to show the user some feedback.
Henning
Re: RFC Patch v2: Add signal strength to nl80211station info
In reply to Johannes BergQuoted 13 lines · Johannes Berg
Quoted 11 lines · Henning Rogge
Quoted 2 lines · On Saturday 06 December 2008 16:03:16 Henning Rogge wrote:
Quoted 2 lines
I'd rename
_TOTALto_LEGACYand remove the calculation for MCS rates, that way it's obviously clear what you're getting in userland.Okay, after reading your mail a second time I understood you...
I think with removing the total bitrate for 802.11n we will just make the userspace interface more complex. You will have to look at four different things (flags, MCS, guard interval, legacy) just to get the bitrate, which will be the typical information the user wants to know. Is there anything nl80211 will gain if we don't put this value inside for all 802.11 ? We cannot drop it because of 802.11abg, so why not fill it with useful data ?
Quoted 8 lines
For one, I'm a bit concerned that the calculation is fairly complex, and may not always be necessary; especially divisions can be expensive on some CPUs.
Also, there are duplicate numbers possible, so just the pure bitrate will _not_ actually be "the typical information" because it's not specific enough, when debugging, for example, you will probably need to know whether it's short-gi or not.
Aren't we providing that *as well*?
Luis
Re: RFC Patch v2: Add signal strength to nl80211station info
Quoted 1 line · On Saturday 06 December 2008 21:46:13 Luis R. Rodriguez wrote:
On Sat, Dec 6, 2008 at 7:59 AM, Johannes Berg <[email protected]>
Quoted 6 lines · wrote:
Quoted 4 lines
Also, there are duplicate numbers possible, so just the pure bitrate will _not_ actually be "the typical information" because it's not specific enough, when debugging, for example, you will probably need to know whether it's short-gi or not.
Aren't we providing that *as well*?
I think the suggestion is to remove the total/legacy bitrate for 802.11n completely from the nl80211 station_info. Which I still think is not a good idea. This way we force any application displaying the bitrate to check for several cases, know about the 802.11n table, ...
I think it's funny that we have the "total bitrate" information available on driver level but translate it into the mcs index with the help of tables... and assume that userspace knows about the tables.
But here is the next version of my patch, this one without the "total bandwith" for 802.11n... I can easily put it back later.
Changes since v1:
- removed noise and quality from station info in NL80211
- added bandwith to station info in NL80211
- changed name of patch file to nl80211ext_v2.patch
Changes since v2:
- added kernel comment lines for new fields/enums
- changed name of "bandwith" field to tx_bitrate
Changes since v3:
- added rx_bitrate to station info and sta_info
- remember bitrate of last received unicast packet to this station
- decode 802.11n MCS index for nl80211
(maybe this should be ported to WEXT too ?)
Changes since v4:
- added tx_bitrate_flags adn tx_bitrate_mcs field to station info
- added flags for 40Mhz and small guard interval to NL80211 station info
- added mcs field to NL80211 station info
Changes since v5:
- remove rx_bitrate from patch until we get a sane way to learn the details of received 802.11n packages
-replace 802.11n bitrate arrays with calculation based on basic rates
- pushed txrate nl80211 stationinfo into nested attribute
- created station_info_rate_flags enum to save bitrate flags in station_info
- cleanup of kerneldoc
Changes since v6:
- removed mcs index to bitrate conversion
- push station info bitrate into substructure
- renamed "total" bitrate into "legacy"
- some code cleanup
Henning
-------------------
include/linux/nl80211.h +29 -0
@@ -425,6 +425,30 @@ enum nl80211_sta_flags { };/** +* enum nl80211_sta_info_rate - station information about bitrate +* +* These attribute types are used with %NL80211_STA_INFO_TXRATE +* when getting information about the bitrate of a station. +* +* @__NL80211_STA_INFO_RATE_INVALID: attribute number 0 is reserved +* @NL80211_STA_INFO_RATE_LEGACY: bitrate for 802.11abg (u16, 100kbit/s) +* @NL80211_STA_INFO_RATE_MCS: mcs index for 802.11n (u8) +* @NL80211_STA_INFO_RATE_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate +* @NL80211_STA_INFO_RATE_SHORT_GI: 400ns guard interval +*/ +enum nl80211_sta_info_rate { + __NL80211_STA_INFO_RATE_INVALID, +NL80211_STA_INFO_RATE_LEGACY , +NL80211_STA_INFO_RATE_MCS , +NL80211_STA_INFO_RATE_40_MHZ_WIDTH , +NL80211_STA_INFO_RATE_SHORT_GI , + +/* keep last */ + __NL80211_STA_INFO_RATE_AFTER_LAST, +NL80211_STA_INFO_RATE_MAX = __NL80211_STA_INFO_RATE_AFTER_LAST -1 +}; + +/** * enum nl80211_sta_info - station information * * These attribute types are used with %NL80211_ATTR_STA_INFO
@@ -436,6 +460,9 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) +* @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute +* containing info as possible, see &enum nl80211_sta_info_txrate. */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID,
@@ -445,6 +472,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_TX_BITRATE ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +40 -0
@@ -169,6 +169,9 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled +* (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -177,6 +180,39 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , + STATION_INFO_TX_BITRATE = 1<<7, +}; + +/** +* enum station_info_rate_flags - bitrate info flags +* +* Used by the driver to indicate the specific rate transmission +* type for 802.11n transmissions. +* +* @RATE_INFO_FLAGS_MCS: @tx_bitrate_mcs filled +* @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 Mhz width transmission +* @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval +*/ +enum rate_info_flags { +RATE_INFO_FLAGS_MCS =1 <<0 , +RATE_INFO_FLAGS_40_MHZ_WIDTH =1 <<1 , +RATE_INFO_FLAGS_SHORT_GI =1 <<2 , +}; + +/** +* struct rate_info - bitrate information +* +* Information about a receiving or transmitting bitrate +* +* @flags: bitflag of flags from &enum rate_info_flags +* @mcs: mcs index if struct describes a 802.11n bitrate +* @legacy: bitrate in 100kbit/s for 802.11abg +*/ +struct rate_info { +u8 flags; +u8 mcs; +u16 legacy; };/**
@@ -191,6 +227,8 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received package in dBm +* @txrate: current unicast bitrate to this station */ struct station_info {u32 filled;
@@ -200,6 +238,8 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +struct rate_info txrate; };/**
net/mac80211/cfg.c +0 -0
@@ -310,12 +310,35 @@ static void sta_set_sinfo(struct sta_info *sta, struct
station_info *sinfo)
sinfo->filled = STATION_INFO_INACTIVE_TIME |
STATION_INFO_RX_BYTES |
- STATION_INFO_TX_BYTES;
+ STATION_INFO_TX_BYTES |
+ STATION_INFO_TX_BITRATE;
sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes;
sinfo->tx_bytes = sta->tx_bytes;
+ if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
+ sinfo->filled |= STATION_INFO_SIGNAL;
+ sinfo->signal = sta->last_signal;
+ }
+
+ sinfo->txrate.flags = 0;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI)
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+
+ if (!(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) {
+ struct ieee80211_supported_band *sband;
+ sband = sta->local->hw.wiphy->bands[sta->local->hw.conf.channel->band];
+ sinfo->txrate.legacy = sband->bitrates[sta->last_tx_rate.idx].bitrate;
+ }
+ else {
+ sinfo->txrate.mcs = sta->last_tx_rate.idx;
+ }
+
if (ieee80211_vif_is_mesh(&sdata->vif)) {
#ifdef CONFIG_MAC80211_MESH
sinfo->filled |= STATION_INFO_LLID |
net/wireless/nl80211.c +1 -0
@@ -14,6 +14,7 @@#include <linux/nl80211.h> #include <linux/rtnetlink.h> #include <linux/netlink.h> +#include <net/mac80211.h> #include <net/genetlink.h> #include <net/cfg80211.h> #include "core.h"
@@ -1084,7 +1085,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32
pid, u32 seq,
u8 *mac_addr, struct station_info *sinfo)
{
void *hdr;
- struct nlattr *sinfoattr;
+ struct nlattr *sinfoattr, *txrate;
hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION); if (!hdr)
@@ -1114,7 +1115,28 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
if (sinfo->filled & STATION_INFO_PLINK_STATE)
NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
sinfo->plink_state);
+ if (sinfo->filled & STATION_INFO_SIGNAL)
+ NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
+ sinfo->signal);
+ if (sinfo->filled & STATION_INFO_TX_BITRATE) {
+ txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE);
+ if (!txrate)
+ goto nla_put_failure;
+
+ if (!(sinfo->txrate.flags & RATE_INFO_FLAGS_MCS))
+ NLA_PUT_U16(msg, NL80211_STA_INFO_RATE_LEGACY,
+ sinfo->txrate.legacy);
+ else
+ NLA_PUT_U16(msg, NL80211_STA_INFO_RATE_MCS,
+ sinfo->txrate.mcs);
+ if (sinfo->txrate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
+ NLA_PUT_FLAG(msg, NL80211_STA_INFO_RATE_40_MHZ_WIDTH);
+ if (sinfo->txrate.flags & RATE_INFO_FLAGS_SHORT_GI)
+ NLA_PUT_FLAG(msg, NL80211_STA_INFO_RATE_SHORT_GI);
+
+ nla_nest_end(msg, txrate);
+ }
nla_nest_end(msg, sinfoattr);
return genlmsg_end(msg, hdr);
include/linux/nl80211.h +29 -0
@@ -425,6 +425,30 @@ enum nl80211_sta_flags { };/** +* enum nl80211_sta_info_rate - station information about bitrate +* +* These attribute types are used with %NL80211_STA_INFO_TXRATE +* when getting information about the bitrate of a station. +* +* @__NL80211_STA_INFO_RATE_INVALID: attribute number 0 is reserved +* @NL80211_STA_INFO_RATE_LEGACY: bitrate for 802.11abg (u16, 100kbit/s) +* @NL80211_STA_INFO_RATE_MCS: mcs index for 802.11n (u8) +* @NL80211_STA_INFO_RATE_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate +* @NL80211_STA_INFO_RATE_SHORT_GI: 400ns guard interval +*/ +enum nl80211_sta_info_rate { + __NL80211_STA_INFO_RATE_INVALID, +NL80211_STA_INFO_RATE_LEGACY , +NL80211_STA_INFO_RATE_MCS , +NL80211_STA_INFO_RATE_40_MHZ_WIDTH , +NL80211_STA_INFO_RATE_SHORT_GI , + +/* keep last */ + __NL80211_STA_INFO_RATE_AFTER_LAST, +NL80211_STA_INFO_RATE_MAX = __NL80211_STA_INFO_RATE_AFTER_LAST -1 +}; + +/** * enum nl80211_sta_info - station information * * These attribute types are used with %NL80211_ATTR_STA_INFO
@@ -436,6 +460,9 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) +* @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute +* containing info as possible, see &enum nl80211_sta_info_txrate. */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID,
@@ -445,6 +472,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_TX_BITRATE ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +40 -0
@@ -169,6 +169,9 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled +* (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -177,6 +180,39 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , + STATION_INFO_TX_BITRATE = 1<<7, +}; + +/** +* enum station_info_rate_flags - bitrate info flags +* +* Used by the driver to indicate the specific rate transmission +* type for 802.11n transmissions. +* +* @RATE_INFO_FLAGS_MCS: @tx_bitrate_mcs filled +* @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 Mhz width transmission +* @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval +*/ +enum rate_info_flags { +RATE_INFO_FLAGS_MCS =1 <<0 , +RATE_INFO_FLAGS_40_MHZ_WIDTH =1 <<1 , +RATE_INFO_FLAGS_SHORT_GI =1 <<2 , +}; + +/** +* struct rate_info - bitrate information +* +* Information about a receiving or transmitting bitrate +* +* @flags: bitflag of flags from &enum rate_info_flags +* @mcs: mcs index if struct describes a 802.11n bitrate +* @legacy: bitrate in 100kbit/s for 802.11abg +*/ +struct rate_info { +u8 flags; +u8 mcs; +u16 legacy; };/**
@@ -191,6 +227,8 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received package in dBm +* @txrate: current unicast bitrate to this station */ struct station_info {u32 filled;
@@ -200,6 +238,8 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +struct rate_info txrate; };/**
net/mac80211/cfg.c +24 -1
@@ -310,12 +310,35 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) sinfo->filled =STATION_INFO_INACTIVE_TIME |STATION_INFO_RX_BYTES | -STATION_INFO_TX_BYTES ; +STATION_INFO_TX_BYTES | +STATION_INFO_TX_BITRATE ; sinfo->inactive_time =jiffies_to_msecs (jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes; sinfo->tx_bytes = sta->tx_bytes; +if (sta->local->hw.flags &IEEE80211_HW_SIGNAL_DBM ) { + sinfo->filled |=STATION_INFO_SIGNAL ; + sinfo->signal = sta->last_signal; + } + + sinfo->txrate.flags =0 ; +if (sta->last_tx_rate.flags &IEEE80211_TX_RC_MCS ) + sinfo->txrate.flags |=RATE_INFO_FLAGS_MCS ; +if (sta->last_tx_rate.flags &IEEE80211_TX_RC_40_MHZ_WIDTH ) + sinfo->txrate.flags |=RATE_INFO_FLAGS_40_MHZ_WIDTH ; +if (sta->last_tx_rate.flags &IEEE80211_TX_RC_SHORT_GI ) + sinfo->txrate.flags |=RATE_INFO_FLAGS_SHORT_GI ; + +if (!(sta->last_tx_rate.flags &IEEE80211_TX_RC_MCS )) { +struct ieee80211_supported_band *sband; + sband = sta->local->hw.wiphy->bands[sta->local->hw.conf.channel->band]; + sinfo->txrate.legacy = sband->bitrates[sta->last_tx_rate.idx].bitrate; + } +else { + sinfo->txrate.mcs = sta->last_tx_rate.idx; + } +if (ieee80211_vif_is_mesh (&sdata->vif)) {#ifdef CONFIG_MAC80211_MESH sinfo->filled |= STATION_INFO_LLID |
net/wireless/nl80211.c +23 -1
@@ -14,6 +14,7 @@#include <linux/nl80211.h> #include <linux/rtnetlink.h> #include <linux/netlink.h> +#include <net/mac80211.h> #include <net/genetlink.h> #include <net/cfg80211.h> #include "core.h"
@@ -1084,7 +1085,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, u8 *mac_addr, struct station_info *sinfo) { void *hdr; -struct nlattr *sinfoattr; +struct nlattr *sinfoattr, *txrate; hdr =nl80211hdr_put (msg, pid, seq, flags,NL80211_CMD_NEW_STATION );if (!hdr)
@@ -1114,7 +1115,28 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,if (sinfo->filled &STATION_INFO_PLINK_STATE )NLA_PUT_U8 (msg,NL80211_STA_INFO_PLINK_STATE , sinfo->plink_state); +if (sinfo->filled &STATION_INFO_SIGNAL ) +NLA_PUT_U8 (msg,NL80211_STA_INFO_SIGNAL , + sinfo->signal); +if (sinfo->filled &STATION_INFO_TX_BITRATE ) { + txrate =nla_nest_start (msg,NL80211_STA_INFO_TX_BITRATE ); +if (!txrate) + goto nla_put_failure; + +if (!(sinfo->txrate.flags &RATE_INFO_FLAGS_MCS )) +NLA_PUT_U16 (msg,NL80211_STA_INFO_RATE_LEGACY , + sinfo->txrate.legacy); +else +NLA_PUT_U16 (msg,NL80211_STA_INFO_RATE_MCS , + sinfo->txrate.mcs); +if (sinfo->txrate.flags &RATE_INFO_FLAGS_40_MHZ_WIDTH ) +NLA_PUT_FLAG (msg,NL80211_STA_INFO_RATE_40_MHZ_WIDTH ); +if (sinfo->txrate.flags &RATE_INFO_FLAGS_SHORT_GI ) +NLA_PUT_FLAG (msg,NL80211_STA_INFO_RATE_SHORT_GI ); + +nla_nest_end (msg, txrate); + }nla_nest_end (msg, sinfoattr);return genlmsg_end (msg, hdr);
Johannes Berg
maintainerRe: RFC Patch v2: Add signal strength to nl80211station info
Quoted 7 lines · Henning Rogge
I think the suggestion is to remove the total/legacy bitrate for 802.11n completely from the nl80211
station_info. Which I still think is not a good idea. This way we force any application displaying the bitrate to check for several cases, know about the 802.11n table, ...
I think it's funny that we have the "total bitrate" information available on driver level but translate it into the mcs index with the help of tables... and assume that userspace knows about the tables.
Alright, whatever, put it in, but please do the calculation in cfg80211 (nl80211.c). Should rename it to _TOTAL again then, though, I guess.
Quoted 13 lines
/**
+ * enumnl80211_sta_info_rate- station information about bitrate
+ *
+ * These attribute types are used with %NL80211_STA_INFO_TXRATE
+ * when getting information about the bitrate of a station.
+ *
+ * @__NL80211_STA_INFO_RATE_INVALID: attribute number 0 is reserved
+ * @NL80211_STA_INFO_RATE_LEGACY: bitrate for 802.11abg (u16, 100kbit/s)
+ * @NL80211_STA_INFO_RATE_MCS: mcs index for 802.11n (u8)
+ * @NL80211_STA_INFO_RATE_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate
+ * @NL80211_STA_INFO_RATE_SHORT_GI: 400ns guard interval
+ */include/linux/nl80211.h +1
-0+enum nl80211_sta_info_rate {
include/linux/nl80211.h enum nl80211_sta_flags { · line 449
Quoted 10 lines
include/linux/nl80211.h +10
-0+ __NL80211_STA_INFO_RATE_INVALID, +NL80211_STA_INFO_RATE_LEGACY , +NL80211_STA_INFO_RATE_MCS , +NL80211_STA_INFO_RATE_40_MHZ_WIDTH , +NL80211_STA_INFO_RATE_SHORT_GI , + +/* keep last */ + __NL80211_STA_INFO_RATE_AFTER_LAST, + NL80211_STA_INFO_RATE_MAX = __NL80211_STA_INFO_RATE_AFTER_LAST - 1 +};
Can you rename those too to NL80211_RATE_INFO_*? That way we can use them for other things later.
But this looks good to me now.
johannes
PATCH 1/2 Add signal strength and bandwith to nl80211station info
This patch adds information about signal strength and unicast transmission bitrate to the nl80211 station info.
----------------------
include/linux/nl80211.h +29 -0
@@ -425,6 +425,30 @@ enum nl80211_sta_flags { };/** +* enum nl80211_rate_info - bitrate information +* +* These attribute types are used with %NL80211_STA_INFO_TXRATE +* when getting information about the bitrate of a station. +* +* @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved +* @NL80211_RATE_INFO_LEGACY: bitrate for 802.11abg (u16, 100kbit/s) +* @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) +* @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate +* @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval +*/ +enum nl80211_rate_info { + __NL80211_RATE_INFO_INVALID, +NL80211_RATE_INFO_LEGACY , +NL80211_RATE_INFO_MCS , +NL80211_RATE_INFO_40_MHZ_WIDTH , +NL80211_RATE_INFO_SHORT_GI , + +/* keep last */ + __NL80211_RATE_INFO_AFTER_LAST, +NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST -1 +}; + +/** * enum nl80211_sta_info - station information * * These attribute types are used with %NL80211_ATTR_STA_INFO
@@ -436,6 +460,9 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) +* @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute +* containing info as possible, see &enum nl80211_sta_info_txrate. */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID,
@@ -445,6 +472,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_TX_BITRATE ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +40 -0
@@ -169,6 +169,9 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled +* (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -177,6 +180,39 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , + STATION_INFO_TX_BITRATE = 1<<7, +}; + +/** +* enum station_info_rate_flags - bitrate info flags +* +* Used by the driver to indicate the specific rate transmission +* type for 802.11n transmissions. +* +* @RATE_INFO_FLAGS_MCS: @tx_bitrate_mcs filled +* @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 Mhz width transmission +* @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval +*/ +enum rate_info_flags { +RATE_INFO_FLAGS_MCS =1 <<0 , +RATE_INFO_FLAGS_40_MHZ_WIDTH =1 <<1 , +RATE_INFO_FLAGS_SHORT_GI =1 <<2 , +}; + +/** +* struct rate_info - bitrate information +* +* Information about a receiving or transmitting bitrate +* +* @flags: bitflag of flags from &enum rate_info_flags +* @mcs: mcs index if struct describes a 802.11n bitrate +* @legacy: bitrate in 100kbit/s for 802.11abg +*/ +struct rate_info { +u8 flags; +u8 mcs; +u16 legacy; };/**
@@ -191,6 +227,8 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received package in dBm +* @txrate: current unicast bitrate to this station */ struct station_info {u32 filled;
@@ -200,6 +238,8 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +struct rate_info txrate; };/**
net/mac80211/cfg.c +0 -0
@@ -310,12 +310,35 @@ static void sta_set_sinfo(struct sta_info *sta, struct
station_info *sinfo)
sinfo->filled = STATION_INFO_INACTIVE_TIME |
STATION_INFO_RX_BYTES |
- STATION_INFO_TX_BYTES;
+ STATION_INFO_TX_BYTES |
+ STATION_INFO_TX_BITRATE;
sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes;
sinfo->tx_bytes = sta->tx_bytes;
+ if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
+ sinfo->filled |= STATION_INFO_SIGNAL;
+ sinfo->signal = sta->last_signal;
+ }
+
+ sinfo->txrate.flags = 0;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI)
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+
+ if (!(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) {
+ struct ieee80211_supported_band *sband;
+ sband = sta->local->hw.wiphy->bands[sta->local->hw.conf.channel->band];
+ sinfo->txrate.legacy = sband->bitrates[sta->last_tx_rate.idx].bitrate;
+ }
+ else {
+ sinfo->txrate.mcs = sta->last_tx_rate.idx;
+ }
+
if (ieee80211_vif_is_mesh(&sdata->vif)) {
#ifdef CONFIG_MAC80211_MESH
sinfo->filled |= STATION_INFO_LLID |
net/wireless/nl80211.c +1 -0
@@ -14,6 +14,7 @@#include <linux/nl80211.h> #include <linux/rtnetlink.h> #include <linux/netlink.h> +#include <net/mac80211.h> #include <net/genetlink.h> #include <net/cfg80211.h> #include "core.h"
@@ -1084,7 +1085,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32
pid, u32 seq,
u8 *mac_addr, struct station_info *sinfo)
{
void *hdr;
- struct nlattr *sinfoattr;
+ struct nlattr *sinfoattr, *txrate;
hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION); if (!hdr)
@@ -1114,7 +1115,28 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
if (sinfo->filled & STATION_INFO_PLINK_STATE)
NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
sinfo->plink_state);
+ if (sinfo->filled & STATION_INFO_SIGNAL)
+ NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
+ sinfo->signal);
+ if (sinfo->filled & STATION_INFO_TX_BITRATE) {
+ txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE);
+ if (!txrate)
+ goto nla_put_failure;
+
+ if (!(sinfo->txrate.flags & RATE_INFO_FLAGS_MCS))
+ NLA_PUT_U16(msg, NL80211_RATE_INFO_LEGACY,
+ sinfo->txrate.legacy);
+ else
+ NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS,
+ sinfo->txrate.mcs);
+ if (sinfo->txrate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
+ NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
+ if (sinfo->txrate.flags & RATE_INFO_FLAGS_SHORT_GI)
+ NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI);
+
+ nla_nest_end(msg, txrate);
+ }
nla_nest_end(msg, sinfoattr);
return genlmsg_end(msg, hdr);
include/linux/nl80211.h +29 -0
@@ -425,6 +425,30 @@ enum nl80211_sta_flags { };/** +* enum nl80211_rate_info - bitrate information +* +* These attribute types are used with %NL80211_STA_INFO_TXRATE +* when getting information about the bitrate of a station. +* +* @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved +* @NL80211_RATE_INFO_LEGACY: bitrate for 802.11abg (u16, 100kbit/s) +* @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) +* @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate +* @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval +*/ +enum nl80211_rate_info { + __NL80211_RATE_INFO_INVALID, +NL80211_RATE_INFO_LEGACY , +NL80211_RATE_INFO_MCS , +NL80211_RATE_INFO_40_MHZ_WIDTH , +NL80211_RATE_INFO_SHORT_GI , + +/* keep last */ + __NL80211_RATE_INFO_AFTER_LAST, +NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST -1 +}; + +/** * enum nl80211_sta_info - station information * * These attribute types are used with %NL80211_ATTR_STA_INFO
@@ -436,6 +460,9 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) +* @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute +* containing info as possible, see &enum nl80211_sta_info_txrate. */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID,
@@ -445,6 +472,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_TX_BITRATE ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +40 -0
@@ -169,6 +169,9 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled +* (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -177,6 +180,39 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , + STATION_INFO_TX_BITRATE = 1<<7, +}; + +/** +* enum station_info_rate_flags - bitrate info flags +* +* Used by the driver to indicate the specific rate transmission +* type for 802.11n transmissions. +* +* @RATE_INFO_FLAGS_MCS: @tx_bitrate_mcs filled +* @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 Mhz width transmission +* @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval +*/ +enum rate_info_flags { +RATE_INFO_FLAGS_MCS =1 <<0 , +RATE_INFO_FLAGS_40_MHZ_WIDTH =1 <<1 , +RATE_INFO_FLAGS_SHORT_GI =1 <<2 , +}; + +/** +* struct rate_info - bitrate information +* +* Information about a receiving or transmitting bitrate +* +* @flags: bitflag of flags from &enum rate_info_flags +* @mcs: mcs index if struct describes a 802.11n bitrate +* @legacy: bitrate in 100kbit/s for 802.11abg +*/ +struct rate_info { +u8 flags; +u8 mcs; +u16 legacy; };/**
@@ -191,6 +227,8 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received package in dBm +* @txrate: current unicast bitrate to this station */ struct station_info {u32 filled;
@@ -200,6 +238,8 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +struct rate_info txrate; };/**
net/mac80211/cfg.c +24 -1
@@ -310,12 +310,35 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) sinfo->filled =STATION_INFO_INACTIVE_TIME |STATION_INFO_RX_BYTES | -STATION_INFO_TX_BYTES ; +STATION_INFO_TX_BYTES | +STATION_INFO_TX_BITRATE ; sinfo->inactive_time =jiffies_to_msecs (jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes; sinfo->tx_bytes = sta->tx_bytes; +if (sta->local->hw.flags &IEEE80211_HW_SIGNAL_DBM ) { + sinfo->filled |=STATION_INFO_SIGNAL ; + sinfo->signal = sta->last_signal; + } + + sinfo->txrate.flags =0 ; +if (sta->last_tx_rate.flags &IEEE80211_TX_RC_MCS ) + sinfo->txrate.flags |=RATE_INFO_FLAGS_MCS ; +if (sta->last_tx_rate.flags &IEEE80211_TX_RC_40_MHZ_WIDTH ) + sinfo->txrate.flags |=RATE_INFO_FLAGS_40_MHZ_WIDTH ; +if (sta->last_tx_rate.flags &IEEE80211_TX_RC_SHORT_GI ) + sinfo->txrate.flags |=RATE_INFO_FLAGS_SHORT_GI ; + +if (!(sta->last_tx_rate.flags &IEEE80211_TX_RC_MCS )) { +struct ieee80211_supported_band *sband; + sband = sta->local->hw.wiphy->bands[sta->local->hw.conf.channel->band]; + sinfo->txrate.legacy = sband->bitrates[sta->last_tx_rate.idx].bitrate; + } +else { + sinfo->txrate.mcs = sta->last_tx_rate.idx; + } +if (ieee80211_vif_is_mesh (&sdata->vif)) {#ifdef CONFIG_MAC80211_MESH sinfo->filled |= STATION_INFO_LLID |
net/wireless/nl80211.c +23 -1
@@ -14,6 +14,7 @@#include <linux/nl80211.h> #include <linux/rtnetlink.h> #include <linux/netlink.h> +#include <net/mac80211.h> #include <net/genetlink.h> #include <net/cfg80211.h> #include "core.h"
@@ -1084,7 +1085,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, u8 *mac_addr, struct station_info *sinfo) { void *hdr; -struct nlattr *sinfoattr; +struct nlattr *sinfoattr, *txrate; hdr =nl80211hdr_put (msg, pid, seq, flags,NL80211_CMD_NEW_STATION );if (!hdr)
@@ -1114,7 +1115,28 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,if (sinfo->filled &STATION_INFO_PLINK_STATE )NLA_PUT_U8 (msg,NL80211_STA_INFO_PLINK_STATE , sinfo->plink_state); +if (sinfo->filled &STATION_INFO_SIGNAL ) +NLA_PUT_U8 (msg,NL80211_STA_INFO_SIGNAL , + sinfo->signal); +if (sinfo->filled &STATION_INFO_TX_BITRATE ) { + txrate =nla_nest_start (msg,NL80211_STA_INFO_TX_BITRATE ); +if (!txrate) + goto nla_put_failure; + +if (!(sinfo->txrate.flags &RATE_INFO_FLAGS_MCS )) +NLA_PUT_U16 (msg,NL80211_RATE_INFO_LEGACY , + sinfo->txrate.legacy); +else +NLA_PUT_U8 (msg,NL80211_RATE_INFO_MCS , + sinfo->txrate.mcs); +if (sinfo->txrate.flags &RATE_INFO_FLAGS_40_MHZ_WIDTH ) +NLA_PUT_FLAG (msg,NL80211_RATE_INFO_40_MHZ_WIDTH ); +if (sinfo->txrate.flags &RATE_INFO_FLAGS_SHORT_GI ) +NLA_PUT_FLAG (msg,NL80211_RATE_INFO_SHORT_GI ); + +nla_nest_end (msg, txrate); + }nla_nest_end (msg, sinfoattr);return genlmsg_end (msg, hdr);
PATCH 2/2 Add signal strength and bandwith to nl80211station info
In reply to Johannes BergThis patch adds the total transmission bitrate for adhoc station even for 802.11n transmissions. It must be applied after the first patch of this series.
-------------------------
include/linux/nl80211.h +2 -2
@@ -431,14 +431,14 @@ enum nl80211_sta_flags {* when getting information about the bitrate of a station. * * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved -* @NL80211_RATE_INFO_LEGACY: bitrate for 802.11abg (u16, 100kbit/s) +* @NL80211_RATE_INFO_TOTAL: total bitrate (u16, 100kbit/s) * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval */ enum nl80211_rate_info { __NL80211_RATE_INFO_INVALID, -NL80211_RATE_INFO_LEGACY , +NL80211_RATE_INFO_TOTAL ,NL80211_RATE_INFO_MCS ,NL80211_RATE_INFO_40_MHZ_WIDTH ,NL80211_RATE_INFO_SHORT_GI ,
net/wireless/nl80211.c +0 -0
@@ -1080,6 +1080,35 @@ static int parse_station_flags(struct nlattr *nla, u32
*staflags)
return 0;
}
+static u16 nl80211_calculate_bitrate(struct rate_info *rate)
+{
+ int modulation, streams, bitrate;
+
+ if (!(rate->flags & RATE_INFO_FLAGS_MCS))
+ return rate->legacy;
+
+ modulation = rate->mcs & 7;
+ streams = rate->mcs >> 3;
+
+ bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ?
+ 13500000 : 6500000;
+
+ if (modulation < 4)
+ bitrate *= (modulation + 1);
+ else if (modulation == 4)
+ bitrate *= (modulation + 2);
+ else
+ bitrate *= (modulation + 3);
+
+ bitrate *= streams;
+
+ if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
+ bitrate = (bitrate * 10) / 9;
+
+ /* do NOT round down here */
+ return (bitrate + 50000) / 100000;
+}
+
static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
int flags, struct net_device *dev, u8 *mac_addr, struct station_info *sinfo)
@@ -1123,13 +1152,12 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
if (!txrate)
goto nla_put_failure;
-
- if (!(sinfo->txrate.flags & RATE_INFO_FLAGS_MCS))
- NLA_PUT_U16(msg, NL80211_RATE_INFO_LEGACY,
- sinfo->txrate.legacy);
- else
+ NLA_PUT_U16(msg, NL80211_RATE_INFO_TOTAL,
+ nl80211_calculate_bitrate(&sinfo->txrate));
+ if (sinfo->txrate.flags & RATE_INFO_FLAGS_MCS)
NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS,
sinfo->txrate.mcs);
+
if (sinfo->txrate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
if (sinfo->txrate.flags & RATE_INFO_FLAGS_SHORT_GI)
include/linux/nl80211.h +2 -2
@@ -431,14 +431,14 @@ enum nl80211_sta_flags {* when getting information about the bitrate of a station. * * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved -* @NL80211_RATE_INFO_LEGACY: bitrate for 802.11abg (u16, 100kbit/s) +* @NL80211_RATE_INFO_TOTAL: total bitrate (u16, 100kbit/s) * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval */ enum nl80211_rate_info { __NL80211_RATE_INFO_INVALID, -NL80211_RATE_INFO_LEGACY , +NL80211_RATE_INFO_TOTAL ,NL80211_RATE_INFO_MCS ,NL80211_RATE_INFO_40_MHZ_WIDTH ,NL80211_RATE_INFO_SHORT_GI ,
net/wireless/nl80211.c +33 -5
@@ -1080,6 +1080,35 @@ static int parse_station_flags(struct nlattr *nla, u32 *staflags)return 0 ; } +static u16 nl80211_calculate_bitrate (struct rate_info *rate) +{ +int modulation, streams, bitrate; + +if (!(rate->flags &RATE_INFO_FLAGS_MCS )) +return rate->legacy; + + modulation = rate->mcs &7 ; + streams = rate->mcs >>3 ; + + bitrate = (rate->flags &RATE_INFO_FLAGS_40_MHZ_WIDTH ) ? +13500000 :6500000 ; + +if (modulation <4 ) + bitrate *= (modulation +1 ); +else if (modulation ==4 ) + bitrate *= (modulation +2 ); +else + bitrate *= (modulation +3 ); + + bitrate *= streams; + +if (rate->flags &RATE_INFO_FLAGS_SHORT_GI ) + bitrate = (bitrate *10 ) /9 ; + +/* do NOT round down here */ +return (bitrate +50000 ) /100000 ; +} +static int nl80211_send_station (struct sk_buff *msg,u32 pid,u32 seq,int flags,struct net_device *dev,u8 *mac_addr,struct station_info *sinfo)
@@ -1123,13 +1152,12 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,if (!txrate) goto nla_put_failure; - -if (!(sinfo->txrate.flags &RATE_INFO_FLAGS_MCS )) -NLA_PUT_U16 (msg,NL80211_RATE_INFO_LEGACY , - sinfo->txrate.legacy); -else +NLA_PUT_U16 (msg,NL80211_RATE_INFO_TOTAL , +nl80211_calculate_bitrate (&sinfo->txrate)); +if (sinfo->txrate.flags &RATE_INFO_FLAGS_MCS )NLA_PUT_U8 (msg,NL80211_RATE_INFO_MCS , sinfo->txrate.mcs); +if (sinfo->txrate.flags &RATE_INFO_FLAGS_40_MHZ_WIDTH )NLA_PUT_FLAG (msg,NL80211_RATE_INFO_40_MHZ_WIDTH );if (sinfo->txrate.flags &RATE_INFO_FLAGS_SHORT_GI )
cover Add signal strength and bandwith to nl80211station info
In reply to Johannes BergQuoted 4 lines · On Sunday 07 December 2008 18:39:38 Johannes Berg wrote:
Can you rename those too to NL80211_RATE_INFO_*? That way we can use them for other things later.
But this looks good to me now.
I have splitted the patch into two parts so a better review is possible without deciding if we put the total bandwith into nl80211 or not.
Changes since v1:
- removed noise and quality from station info in NL80211
- added bandwith to station info in NL80211
- changed name of patch file to nl80211ext_v2.patch
Changes since v2:
- added kernel comment lines for new fields/enums
- changed name of "bandwith" field to tx_bitrate
Changes since v3:
- added rx_bitrate to station info and sta_info
- remember bitrate of last received unicast packet to this station
- decode 802.11n MCS index for nl80211
(maybe this should be ported to WEXT too ?)
Changes since v4:
- added tx_bitrate_flags adn tx_bitrate_mcs field to station info
- added flags for 40Mhz and small guard interval to NL80211 station info
- added mcs field to NL80211 station info
Changes since v5:
- remove rx_bitrate from patch until we get a sane way to learn the details of
received 802.11n packages
-replace 802.11n bitrate arrays with calculation based on basic rates
- pushed txrate nl80211 stationinfo into nested attribute
- created station_info_rate_flags enum to save bitrate flags in station_info
- cleanup of kerneldoc
Changes since v6:
- removed mcs index to bitrate conversion
- push station info bitrate into substructure
- renamed "total" bitrate into "legacy"
- some code cleanup
Changes since v7:
- corrected a small type in nl80211 mcs representation
- splitted patch into two parts
TODO:
- tests with real 802.11n hardware
- more tests with 802.11abg hardware
Henning
Johannes Berg
maintainerRe: [PATCH 1/2] Add signal strength and bandwith to nl80211station info
In reply to Henning RoggeQuoted 1 line · Henning Rogge
+ * @NL80211_RATE_INFO_LEGACY: bitrate for 802.11abg (u16, 100kbit/s)
Your other patch named this _TOTAL, can you rename it to _BITRATE instead?
net/mac80211/cfg.c static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) · line 340
Quoted 8 lines
net/mac80211/cfg.c +8
-0+if (!(sta->last_tx_rate.flags &IEEE80211_TX_RC_MCS )) { +struct ieee80211_supported_band *sband; + sband = sta->local->hw.wiphy->bands[sta->local->hw.conf.channel->band]; + sinfo->txrate.legacy = sband->bitrates[sta->last_tx_rate.idx].bitrate; + } +else { + sinfo->txrate.mcs = sta->last_tx_rate.idx; + }
Put the else on the same line as the closing brace, please.
net/wireless/nl80211.c line 20
Quoted 10 lines
net/wireless/nl80211.c +1
-0@@ -14,6 +14,7 @@#include <linux/nl80211.h> #include <linux/rtnetlink.h> #include <linux/netlink.h> +#include <net/mac80211.h> #include <net/genetlink.h> #include <net/cfg80211.h> #include "core.h"
That has to go.
And on your second patch:
net/wireless/nl80211.c
Quoted 9 lines
net/wireless/nl80211.c +9
-0+static u16 nl80211_calculate_bitrate (struct rate_info *rate) +{ +int modulation, streams, bitrate; + +if (!(rate->flags &RATE_INFO_FLAGS_MCS )) +return rate->legacy; + + modulation = rate->mcs &7 ; + streams = rate->mcs >>3 ;
I don't think this gives correct results for MCS rates 32 through 76, does it? It should at least not calculate anything then. If we did it in userspace then programs could also actually calculate the correct rate as a float, rather than this approximation. Not that it'll matter, I guess. Doesn't anybody know how to do the actual calculation?
johannes
Re: [PATCH 1/2] Add signal strength and bandwith to nl80211station info
Quoted 16 lines · On Monday 08 December 2008 20:43:35 you wrote:
And on your second patch:
Review
Quoted 9 lines
(quoted diff) +9
-0+static u16 nl80211_calculate_bitrate(struct rate_info *rate) +{ + int modulation, streams, bitrate; + + if (!(rate->flags & RATE_INFO_FLAGS_MCS)) + return rate->legacy; + + modulation = rate->mcs & 7; + streams = rate->mcs >> 3;I don't think this gives correct results for MCS rates 32 through 76, does it? It should at least not calculate anything then. If we did it in userspace then programs could also actually calculate the correct rate as a float, rather than this approximation. Not that it'll matter, I guess. Doesn't anybody know how to do the actual calculation?
It had a small type (corrected in the new patches), but I think the values are good. I have attached a test programm to this mail that outputs the bandwith values calculated by the function.
Henning
#include <stdio.h>
#define RATE_INFO_FLAGS_MCS 1
#define RATE_INFO_FLAGS_40_MHZ_WIDTH 2
#define RATE_INFO_FLAGS_SHORT_GI 4
struct rate_info {
int flags, mcs, legacy;
};int nl80211_calculate_bitrate(struct rate_info *rate)
{
int modulation, streams, bitrate;
if (!(rate->flags & RATE_INFO_FLAGS_MCS))
return rate->legacy;
modulation = rate->mcs & 7;
streams = (rate->mcs >> 3) + 1;
bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ?
13500000 : 6500000;
if (modulation < 4)
bitrate *= (modulation + 1);
else if (modulation == 4)
bitrate *= (modulation + 2);
else
bitrate *= (modulation + 3);
bitrate *= streams;
if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
bitrate = (bitrate / 9) * 10;
/* do NOT round down here */
return (bitrate + 50000) / 100000;
}int main(int argc, char **argv) {
struct rate_info ri;
int mcs;
printf("20 Mhz wide channels\n");
for (mcs = 0; mcs < 72; mcs++) {
int r1, r2;
ri.mcs = mcs;
ri.flags = RATE_INFO_FLAGS_MCS;
r1 = nl80211_calculate_bitrate(&ri);
ri.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_SHORT_GI;
r2 = nl80211_calculate_bitrate(&ri);
printf("mcs %d: long gi %4d / short gi %4d\n", mcs, r1, r2);
}
printf("\n");
printf("40 Mhz wide channels\n");
for (mcs = 0; mcs < 72; mcs++) {
int r1, r2;
ri.mcs = mcs;
ri.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_40_MHZ_WIDTH;
r1 = nl80211_calculate_bitrate(&ri);
ri.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_SHORT_GI | RATE_INFO_FLAGS_40_MHZ_WIDTH;
r2 = nl80211_calculate_bitrate(&ri);
printf("mcs %d: long gi %4d / short gi %4d\n", mcs, r1, r2);
}}
PATCH v2 1/2 Add signal strength and bandwith to nl80211station info
In reply to Johannes BergThis patch adds information about signal strength and unicast transmission bitrate to the nl80211 station info.
------------------------------------
include/linux/nl80211.h +29 -0
@@ -425,6 +425,30 @@ enum nl80211_sta_flags { };/** +* enum nl80211_rate_info - bitrate information +* +* These attribute types are used with %NL80211_STA_INFO_TXRATE +* when getting information about the bitrate of a station. +* +* @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved +* @NL80211_RATE_INFO_LEGACY: bitrate for 802.11abg (u16, 100kbit/s) +* @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) +* @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate +* @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval +*/ +enum nl80211_rate_info { + __NL80211_RATE_INFO_INVALID, +NL80211_RATE_INFO_LEGACY , +NL80211_RATE_INFO_MCS , +NL80211_RATE_INFO_40_MHZ_WIDTH , +NL80211_RATE_INFO_SHORT_GI , + +/* keep last */ + __NL80211_RATE_INFO_AFTER_LAST, +NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST -1 +}; + +/** * enum nl80211_sta_info - station information * * These attribute types are used with %NL80211_ATTR_STA_INFO
@@ -436,6 +460,9 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) +* @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute +* containing info as possible, see &enum nl80211_sta_info_txrate. */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID,
@@ -445,6 +472,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_TX_BITRATE ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +40 -0
@@ -169,6 +169,9 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled +* (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -177,6 +180,39 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , + STATION_INFO_TX_BITRATE = 1<<7, +}; + +/** +* enum station_info_rate_flags - bitrate info flags +* +* Used by the driver to indicate the specific rate transmission +* type for 802.11n transmissions. +* +* @RATE_INFO_FLAGS_MCS: @tx_bitrate_mcs filled +* @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 Mhz width transmission +* @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval +*/ +enum rate_info_flags { +RATE_INFO_FLAGS_MCS =1 <<0 , +RATE_INFO_FLAGS_40_MHZ_WIDTH =1 <<1 , +RATE_INFO_FLAGS_SHORT_GI =1 <<2 , +}; + +/** +* struct rate_info - bitrate information +* +* Information about a receiving or transmitting bitrate +* +* @flags: bitflag of flags from &enum rate_info_flags +* @mcs: mcs index if struct describes a 802.11n bitrate +* @legacy: bitrate in 100kbit/s for 802.11abg +*/ +struct rate_info { +u8 flags; +u8 mcs; +u16 legacy; };/**
@@ -191,6 +227,8 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received package in dBm +* @txrate: current unicast bitrate to this station */ struct station_info {u32 filled;
@@ -200,6 +238,8 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +struct rate_info txrate; };/**
net/mac80211/cfg.c +0 -0
@@ -310,12 +310,35 @@ static void sta_set_sinfo(struct sta_info *sta, struct
station_info *sinfo)
sinfo->filled = STATION_INFO_INACTIVE_TIME |
STATION_INFO_RX_BYTES |
- STATION_INFO_TX_BYTES;
+ STATION_INFO_TX_BYTES |
+ STATION_INFO_TX_BITRATE;
sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes;
sinfo->tx_bytes = sta->tx_bytes;
+ if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
+ sinfo->filled |= STATION_INFO_SIGNAL;
+ sinfo->signal = sta->last_signal;
+ }
+
+ sinfo->txrate.flags = 0;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI)
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+
+ if (!(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) {
+ struct ieee80211_supported_band *sband;
+ sband = sta->local->hw.wiphy->bands[
+ sta->local->hw.conf.channel->band];
+ sinfo->txrate.legacy =
+ sband->bitrates[sta->last_tx_rate.idx].bitrate;
+ } else
+ sinfo->txrate.mcs = sta->last_tx_rate.idx;
+
if (ieee80211_vif_is_mesh(&sdata->vif)) {
#ifdef CONFIG_MAC80211_MESH
sinfo->filled |= STATION_INFO_LLID |
net/wireless/nl80211.c +0 -0
@@ -1084,7 +1084,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32
pid, u32 seq,
u8 *mac_addr, struct station_info *sinfo)
{
void *hdr;
- struct nlattr *sinfoattr;
+ struct nlattr *sinfoattr, *txrate;
hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION); if (!hdr)
@@ -1114,7 +1114,28 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
if (sinfo->filled & STATION_INFO_PLINK_STATE)
NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
sinfo->plink_state);
+ if (sinfo->filled & STATION_INFO_SIGNAL)
+ NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
+ sinfo->signal);
+ if (sinfo->filled & STATION_INFO_TX_BITRATE) {
+ txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE);
+ if (!txrate)
+ goto nla_put_failure;
+
+ if (!(sinfo->txrate.flags & RATE_INFO_FLAGS_MCS))
+ NLA_PUT_U16(msg, NL80211_RATE_INFO_LEGACY,
+ sinfo->txrate.legacy);
+ else
+ NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS,
+ sinfo->txrate.mcs);
+ if (sinfo->txrate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
+ NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
+ if (sinfo->txrate.flags & RATE_INFO_FLAGS_SHORT_GI)
+ NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI);
+
+ nla_nest_end(msg, txrate);
+ }
nla_nest_end(msg, sinfoattr);
return genlmsg_end(msg, hdr);
include/linux/nl80211.h +29 -0
@@ -425,6 +425,30 @@ enum nl80211_sta_flags { };/** +* enum nl80211_rate_info - bitrate information +* +* These attribute types are used with %NL80211_STA_INFO_TXRATE +* when getting information about the bitrate of a station. +* +* @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved +* @NL80211_RATE_INFO_LEGACY: bitrate for 802.11abg (u16, 100kbit/s) +* @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) +* @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate +* @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval +*/ +enum nl80211_rate_info { + __NL80211_RATE_INFO_INVALID, +NL80211_RATE_INFO_LEGACY , +NL80211_RATE_INFO_MCS , +NL80211_RATE_INFO_40_MHZ_WIDTH , +NL80211_RATE_INFO_SHORT_GI , + +/* keep last */ + __NL80211_RATE_INFO_AFTER_LAST, +NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST -1 +}; + +/** * enum nl80211_sta_info - station information * * These attribute types are used with %NL80211_ATTR_STA_INFO
@@ -436,6 +460,9 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) +* @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute +* containing info as possible, see &enum nl80211_sta_info_txrate. */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID,
@@ -445,6 +472,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_TX_BITRATE ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +40 -0
@@ -169,6 +169,9 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled +* (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -177,6 +180,39 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , + STATION_INFO_TX_BITRATE = 1<<7, +}; + +/** +* enum station_info_rate_flags - bitrate info flags +* +* Used by the driver to indicate the specific rate transmission +* type for 802.11n transmissions. +* +* @RATE_INFO_FLAGS_MCS: @tx_bitrate_mcs filled +* @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 Mhz width transmission +* @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval +*/ +enum rate_info_flags { +RATE_INFO_FLAGS_MCS =1 <<0 , +RATE_INFO_FLAGS_40_MHZ_WIDTH =1 <<1 , +RATE_INFO_FLAGS_SHORT_GI =1 <<2 , +}; + +/** +* struct rate_info - bitrate information +* +* Information about a receiving or transmitting bitrate +* +* @flags: bitflag of flags from &enum rate_info_flags +* @mcs: mcs index if struct describes a 802.11n bitrate +* @legacy: bitrate in 100kbit/s for 802.11abg +*/ +struct rate_info { +u8 flags; +u8 mcs; +u16 legacy; };/**
@@ -191,6 +227,8 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received package in dBm +* @txrate: current unicast bitrate to this station */ struct station_info {u32 filled;
@@ -200,6 +238,8 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +struct rate_info txrate; };/**
net/mac80211/cfg.c +24 -1
@@ -310,12 +310,35 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) sinfo->filled =STATION_INFO_INACTIVE_TIME |STATION_INFO_RX_BYTES | -STATION_INFO_TX_BYTES ; +STATION_INFO_TX_BYTES | +STATION_INFO_TX_BITRATE ; sinfo->inactive_time =jiffies_to_msecs (jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes; sinfo->tx_bytes = sta->tx_bytes; +if (sta->local->hw.flags &IEEE80211_HW_SIGNAL_DBM ) { + sinfo->filled |=STATION_INFO_SIGNAL ; + sinfo->signal = sta->last_signal; + } + + sinfo->txrate.flags =0 ; +if (sta->last_tx_rate.flags &IEEE80211_TX_RC_MCS ) + sinfo->txrate.flags |=RATE_INFO_FLAGS_MCS ; +if (sta->last_tx_rate.flags &IEEE80211_TX_RC_40_MHZ_WIDTH ) + sinfo->txrate.flags |=RATE_INFO_FLAGS_40_MHZ_WIDTH ; +if (sta->last_tx_rate.flags &IEEE80211_TX_RC_SHORT_GI ) + sinfo->txrate.flags |=RATE_INFO_FLAGS_SHORT_GI ; + +if (!(sta->last_tx_rate.flags &IEEE80211_TX_RC_MCS )) { +struct ieee80211_supported_band *sband; + sband = sta->local->hw.wiphy->bands[ + sta->local->hw.conf.channel->band]; + sinfo->txrate.legacy = + sband->bitrates[sta->last_tx_rate.idx].bitrate; + }else + sinfo->txrate.mcs = sta->last_tx_rate.idx; +if (ieee80211_vif_is_mesh (&sdata->vif)) {#ifdef CONFIG_MAC80211_MESH sinfo->filled |= STATION_INFO_LLID |
net/wireless/nl80211.c +22 -1
@@ -1084,7 +1084,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, u8 *mac_addr, struct station_info *sinfo) { void *hdr; -struct nlattr *sinfoattr; +struct nlattr *sinfoattr, *txrate; hdr =nl80211hdr_put (msg, pid, seq, flags,NL80211_CMD_NEW_STATION );if (!hdr)
@@ -1114,7 +1114,28 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,if (sinfo->filled &STATION_INFO_PLINK_STATE )NLA_PUT_U8 (msg,NL80211_STA_INFO_PLINK_STATE , sinfo->plink_state); +if (sinfo->filled &STATION_INFO_SIGNAL ) +NLA_PUT_U8 (msg,NL80211_STA_INFO_SIGNAL , + sinfo->signal); +if (sinfo->filled &STATION_INFO_TX_BITRATE ) { + txrate =nla_nest_start (msg,NL80211_STA_INFO_TX_BITRATE ); +if (!txrate) + goto nla_put_failure; + +if (!(sinfo->txrate.flags &RATE_INFO_FLAGS_MCS )) +NLA_PUT_U16 (msg,NL80211_RATE_INFO_LEGACY , + sinfo->txrate.legacy); +else +NLA_PUT_U8 (msg,NL80211_RATE_INFO_MCS , + sinfo->txrate.mcs); +if (sinfo->txrate.flags &RATE_INFO_FLAGS_40_MHZ_WIDTH ) +NLA_PUT_FLAG (msg,NL80211_RATE_INFO_40_MHZ_WIDTH ); +if (sinfo->txrate.flags &RATE_INFO_FLAGS_SHORT_GI ) +NLA_PUT_FLAG (msg,NL80211_RATE_INFO_SHORT_GI ); + +nla_nest_end (msg, txrate); + }nla_nest_end (msg, sinfoattr);return genlmsg_end (msg, hdr);
PATCH v2 2/2 Add signal strength and bandwith to nl80211station info
In reply to Johannes BergThis patch adds the total transmission bitrate for adhoc station even for 802.11n transmissions. It must be applied after the first patch of this series.
--------------------------
include/linux/nl80211.h +2 -2
@@ -431,14 +431,14 @@ enum nl80211_sta_flags {* when getting information about the bitrate of a station. * * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved -* @NL80211_RATE_INFO_LEGACY: bitrate for 802.11abg (u16, 100kbit/s) +* @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval */ enum nl80211_rate_info { __NL80211_RATE_INFO_INVALID, -NL80211_RATE_INFO_LEGACY , +NL80211_RATE_INFO_BITRATE ,NL80211_RATE_INFO_MCS ,NL80211_RATE_INFO_40_MHZ_WIDTH ,NL80211_RATE_INFO_SHORT_GI ,
net/wireless/nl80211.c +0 -0
@@ -1079,6 +1079,35 @@ static int parse_station_flags(struct nlattr *nla, u32
*staflags)
return 0;
}
+static u16 nl80211_calculate_bitrate(struct rate_info *rate)
+{
+ int modulation, streams, bitrate;
+
+ if (!(rate->flags & RATE_INFO_FLAGS_MCS))
+ return rate->legacy;
+
+ modulation = rate->mcs & 7;
+ streams = (rate->mcs >> 3) + 1;
+
+ bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ?
+ 13500000 : 6500000;
+
+ if (modulation < 4)
+ bitrate *= (modulation + 1);
+ else if (modulation == 4)
+ bitrate *= (modulation + 2);
+ else
+ bitrate *= (modulation + 3);
+
+ bitrate *= streams;
+
+ if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
+ bitrate = (bitrate / 9) * 10;
+
+ /* do NOT round down here */
+ return (bitrate + 50000) / 100000;
+}
+
static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
int flags, struct net_device *dev, u8 *mac_addr, struct station_info *sinfo)
@@ -1122,13 +1151,12 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
if (!txrate)
goto nla_put_failure;
-
- if (!(sinfo->txrate.flags & RATE_INFO_FLAGS_MCS))
- NLA_PUT_U16(msg, NL80211_RATE_INFO_LEGACY,
- sinfo->txrate.legacy);
- else
+ NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE,
+ nl80211_calculate_bitrate(&sinfo->txrate));
+ if (sinfo->txrate.flags & RATE_INFO_FLAGS_MCS)
NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS,
sinfo->txrate.mcs);
+
if (sinfo->txrate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
if (sinfo->txrate.flags & RATE_INFO_FLAGS_SHORT_GI)
include/linux/nl80211.h +2 -2
@@ -431,14 +431,14 @@ enum nl80211_sta_flags {* when getting information about the bitrate of a station. * * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved -* @NL80211_RATE_INFO_LEGACY: bitrate for 802.11abg (u16, 100kbit/s) +* @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval */ enum nl80211_rate_info { __NL80211_RATE_INFO_INVALID, -NL80211_RATE_INFO_LEGACY , +NL80211_RATE_INFO_BITRATE ,NL80211_RATE_INFO_MCS ,NL80211_RATE_INFO_40_MHZ_WIDTH ,NL80211_RATE_INFO_SHORT_GI ,
net/wireless/nl80211.c +33 -5
@@ -1079,6 +1079,35 @@ static int parse_station_flags(struct nlattr *nla, u32 *staflags)return 0 ; } +static u16 nl80211_calculate_bitrate (struct rate_info *rate) +{ +int modulation, streams, bitrate; + +if (!(rate->flags &RATE_INFO_FLAGS_MCS )) +return rate->legacy; + + modulation = rate->mcs &7 ; + streams = (rate->mcs >>3 ) +1 ; + + bitrate = (rate->flags &RATE_INFO_FLAGS_40_MHZ_WIDTH ) ? +13500000 :6500000 ; + +if (modulation <4 ) + bitrate *= (modulation +1 ); +else if (modulation ==4 ) + bitrate *= (modulation +2 ); +else + bitrate *= (modulation +3 ); + + bitrate *= streams; + +if (rate->flags &RATE_INFO_FLAGS_SHORT_GI ) + bitrate = (bitrate /9 ) *10 ; + +/* do NOT round down here */ +return (bitrate +50000 ) /100000 ; +} +static int nl80211_send_station (struct sk_buff *msg,u32 pid,u32 seq,int flags,struct net_device *dev,u8 *mac_addr,struct station_info *sinfo)
@@ -1122,13 +1151,12 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,if (!txrate) goto nla_put_failure; - -if (!(sinfo->txrate.flags &RATE_INFO_FLAGS_MCS )) -NLA_PUT_U16 (msg,NL80211_RATE_INFO_LEGACY , - sinfo->txrate.legacy); -else +NLA_PUT_U16 (msg,NL80211_RATE_INFO_BITRATE , +nl80211_calculate_bitrate (&sinfo->txrate)); +if (sinfo->txrate.flags &RATE_INFO_FLAGS_MCS )NLA_PUT_U8 (msg,NL80211_RATE_INFO_MCS , sinfo->txrate.mcs); +if (sinfo->txrate.flags &RATE_INFO_FLAGS_40_MHZ_WIDTH )NLA_PUT_FLAG (msg,NL80211_RATE_INFO_40_MHZ_WIDTH );if (sinfo->txrate.flags &RATE_INFO_FLAGS_SHORT_GI )
Johannes Berg
maintainerRe: [PATCH 1/2] Add signal strength and bandwith to nl80211station info
In reply to Henning RoggeQuoted 18 lines · Henning Rogge
Quoted 16 lines · On Monday 08 December 2008 20:43:35 you wrote:
And on your second patch:
Review
Quoted 9 lines
(quoted diff) +9
-0+static u16 nl80211_calculate_bitrate(struct rate_info *rate) +{ + int modulation, streams, bitrate; + + if (!(rate->flags & RATE_INFO_FLAGS_MCS)) + return rate->legacy; + + modulation = rate->mcs & 7; + streams = rate->mcs >> 3;I don't think this gives correct results for MCS rates 32 through 76, does it? It should at least not calculate anything then. If we did it in userspace then programs could also actually calculate the correct rate as a float, rather than this approximation. Not that it'll matter, I guess. Doesn't anybody know how to do the actual calculation?
Quoted 3 lines
It had a small type (corrected in the new patches), but I think the values are good. I have attached a test programm to this mail that outputs the bandwith values calculated by the function.
No, that's the thing, for 32 through 76 the calculated values are totally wrong, that isn't a logical extension of the scheme, MCS 73 for 20 MHz for example is:
four streams, using 64-qam, 64-qam, 16-qam, qpsk with a coding rate of 3/4 for a net bitrate of 195.0 MBits
johannes
Johannes Berg
maintainerRe: [Patch 2/2 v2] Add signal strength and bandwith to nl80211station info
In reply to Henning Roggenet/wireless/nl80211.c static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, · line 1155
Quoted 6 lines · Henning Rogge
net/wireless/nl80211.c +2
-4-if (!(sinfo->txrate.flags &RATE_INFO_FLAGS_MCS )) -NLA_PUT_U16 (msg,NL80211_RATE_INFO_LEGACY , - sinfo->txrate.legacy); -else +NLA_PUT_U16 (msg,NL80211_RATE_INFO_BITRATE , +nl80211_calculate_bitrate (&sinfo->txrate));
If you do:
if (sinfo->txrate.flags & RATE_INFO_FLAGS_MCS) {
if (sinfo->txrate.mcs < 32)
NLA_PUT_U16(msg, ..., calculate());
} else
NLA_PUT_U16(msg, ..., legacy);and add a big comment to the calculate function that it only works for MCS < 32, I'm fine with it.
johannes
Re: [PATCH 1/2] Add signal strength and bandwith to nl80211station info
In reply to Johannes BergAm Tuesday 09 December 2008 22:16:12 schrieb Johannes Berg:
Quoted 6 lines
No, that's the thing, for 32 through 76 the calculated values are totally wrong, that isn't a logical extension of the scheme, MCS 73 for 20 MHz for example is:
four streams, using 64-qam, 64-qam, 16-qam, qpsk with a coding rate of 3/4 for a net bitrate of 195.0 MBits
Maybe you can just post the whole mcs 32-76 table, so I can look at it. I can only work with the values in the wiki, and at the moment the calculation matchs them very well.
Henning
*************************************************
Diplom Informatiker Henning Rogge
Forschungsgesellschaft für
Angewandte Naturwissenschaften e. V. (FGAN)
Neuenahrer Str. 20, 53343 Wachtberg, Germany
Tel.: 0049 (0)228 9435-961
Fax: 0049 (0)228 9435-685
E-Mail: [email protected]
Web: www.fgan.de
************************************************
Sitz der Gesellschaft: Bonn
Registergericht: Amtsgericht Bonn VR 2530
Vorstand: Dr. rer. nat. Ralf Dornhaus (Vors.), Prof. Dr. Joachim Ender (Stellv.)
Johannes Berg
maintainerRe: [PATCH 1/2] Add signal strength and bandwith to nl80211station info
Quoted 11 lines · Henning Rogge
Am Tuesday 09 December 2008 22:16:12 schrieb Johannes Berg:
Quoted 6 lines
No, that's the thing, for 32 through 76 the calculated values are totally wrong, that isn't a logical extension of the scheme, MCS 73 for 20 MHz for example is:
four streams, using 64-qam, 64-qam, 16-qam, qpsk with a coding rate of 3/4 for a net bitrate of 195.0 MBits
Maybe you can just post the whole mcs 32-76 table, so I can look at it. I can only work with the values in the wiki, and at the moment the calculation matchs them very well.
Uh huh, it's a huge table, and very irregular. Not very inclined to copy that right now. What's wrong with deferring it until somebody actually implements these rates?
johannes
Re: [PATCH 1/2] Add signal strength and bandwith to nl80211station info
Quoted 3 lines · On Wednesday 10 December 2008 10:05:50 Johannes Berg wrote:
Uh huh, it's a huge table, and very irregular. Not very inclined to copy that right now. What's wrong with deferring it until somebody actually implements these rates?
Okay... I will try to implement a complete version of the function when I get access to the table... here is a modified patch with two warnings about the missing datarates. It will return 0 for mcs >= 32.
Just a question, did someone with 802.11n hardware test this patches ? I hope I will have some hardware myself at the end of the year, but at the moment it's untested.
Henning
--------------------------
include/linux/nl80211.h +2 -2
@@ -431,14 +431,14 @@ enum nl80211_sta_flags {* when getting information about the bitrate of a station. * * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved -* @NL80211_RATE_INFO_LEGACY: bitrate for 802.11abg (u16, 100kbit/s) +* @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval */ enum nl80211_rate_info { __NL80211_RATE_INFO_INVALID, -NL80211_RATE_INFO_LEGACY , +NL80211_RATE_INFO_BITRATE ,NL80211_RATE_INFO_MCS ,NL80211_RATE_INFO_40_MHZ_WIDTH ,NL80211_RATE_INFO_SHORT_GI ,
net/wireless/nl80211.c +0 -0
@@ -1079,6 +1079,39 @@ static int parse_station_flags(struct nlattr *nla, u32
*staflags)
return 0;
}
+static u16 nl80211_calculate_bitrate(struct rate_info *rate)
+{
+ int modulation, streams, bitrate;
+
+ if (!(rate->flags & RATE_INFO_FLAGS_MCS))
+ return rate->legacy;
+
+ /* the formula below does only work for MCS values smaller than 32 */
+ if (rate->mcs >= 32)
+ return 0;
+
+ modulation = rate->mcs & 7;
+ streams = (rate->mcs >> 3) + 1;
+
+ bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ?
+ 13500000 : 6500000;
+
+ if (modulation < 4)
+ bitrate *= (modulation + 1);
+ else if (modulation == 4)
+ bitrate *= (modulation + 2);
+ else
+ bitrate *= (modulation + 3);
+
+ bitrate *= streams;
+
+ if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
+ bitrate = (bitrate / 9) * 10;
+
+ /* do NOT round down here */
+ return (bitrate + 50000) / 100000;
+}
+
static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
int flags, struct net_device *dev, u8 *mac_addr, struct station_info *sinfo)
@@ -1122,13 +1155,13 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
if (!txrate)
goto nla_put_failure;
-
- if (!(sinfo->txrate.flags & RATE_INFO_FLAGS_MCS))
- NLA_PUT_U16(msg, NL80211_RATE_INFO_LEGACY,
- sinfo->txrate.legacy);
- else
+ /* nl80211_calculate_bitrate will return 0 for mcs >= 32 */
+ NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE,
+ nl80211_calculate_bitrate(&sinfo->txrate));
+ if (sinfo->txrate.flags & RATE_INFO_FLAGS_MCS)
NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS,
sinfo->txrate.mcs);
+
if (sinfo->txrate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
if (sinfo->txrate.flags & RATE_INFO_FLAGS_SHORT_GI)
include/linux/nl80211.h +2 -2
@@ -431,14 +431,14 @@ enum nl80211_sta_flags {* when getting information about the bitrate of a station. * * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved -* @NL80211_RATE_INFO_LEGACY: bitrate for 802.11abg (u16, 100kbit/s) +* @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval */ enum nl80211_rate_info { __NL80211_RATE_INFO_INVALID, -NL80211_RATE_INFO_LEGACY , +NL80211_RATE_INFO_BITRATE ,NL80211_RATE_INFO_MCS ,NL80211_RATE_INFO_40_MHZ_WIDTH ,NL80211_RATE_INFO_SHORT_GI ,
net/wireless/nl80211.c +38 -5
57 lines not on this page · raw message
Johannes Berg
maintainerRe: [PATCH 1/2] Add signal strength and bandwith to nl80211station info
Quoted 8 lines · Henning Rogge
Quoted 3 lines · On Wednesday 10 December 2008 10:05:50 Johannes Berg wrote:
Uh huh, it's a huge table, and very irregular. Not very inclined to copy that right now. What's wrong with deferring it until somebody actually implements these rates?
Okay... I will try to implement a complete version of the function when I get access to the table... here is a modified patch with two warnings about the missing datarates. It will return 0 for mcs >= 32.
Can you do what I asked for instead and not include the attribute when it has a bogus value?
Thanks,
Johannes
Re: [PATCH 1/2] Add signal strength and bandwith to nl80211station info
Quoted 3 lines · On Wednesday 10 December 2008 21:45:37 Johannes Berg wrote:
On Wed, 2008-12-10 at 18:40 +0100, Henning Rogge wrote:
Can you do what I asked for instead and not include the attribute when it has a bogus value?
I agree, that was a stupid thing...
Henning
-------------------------------
include/linux/nl80211.h +2 -2
@@ -431,14 +431,14 @@ enum nl80211_sta_flags {* when getting information about the bitrate of a station. * * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved -* @NL80211_RATE_INFO_LEGACY: bitrate for 802.11abg (u16, 100kbit/s) +* @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval */ enum nl80211_rate_info { __NL80211_RATE_INFO_INVALID, -NL80211_RATE_INFO_LEGACY , +NL80211_RATE_INFO_BITRATE ,NL80211_RATE_INFO_MCS ,NL80211_RATE_INFO_40_MHZ_WIDTH ,NL80211_RATE_INFO_SHORT_GI ,
net/wireless/nl80211.c +0 -0
@@ -1079,12 +1079,46 @@ static int parse_station_flags(struct nlattr *nla, u32
*staflags)
return 0;
}
+static u16 nl80211_calculate_bitrate(struct rate_info *rate) +{
+ int modulation, streams, bitrate;
+
+ if (!(rate->flags & RATE_INFO_FLAGS_MCS))
+ return rate->legacy;
+
+ /* the formula below does only work for MCS values smaller than 32 */
+ if (rate->mcs >= 32)
+ return 0;
+
+ modulation = rate->mcs & 7;
+ streams = (rate->mcs >> 3) + 1;
+
+ bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ?
+ 13500000 : 6500000;
+
+ if (modulation < 4)
+ bitrate *= (modulation + 1);
+ else if (modulation == 4)
+ bitrate *= (modulation + 2);
+ else
+ bitrate *= (modulation + 3);
+
+ bitrate *= streams;
+
+ if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
+ bitrate = (bitrate / 9) * 10;
+
+ /* do NOT round down here */
+ return (bitrate + 50000) / 100000;
+}
+
static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
int flags, struct net_device *dev, u8 *mac_addr, struct station_info *sinfo)
{
void *hdr;
struct nlattr *sinfoattr, *txrate;
+ u16 bitrate;
hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION); if (!hdr)
@@ -1122,11 +1156,12 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
if (!txrate)
goto nla_put_failure;
+ /* nl80211_calculate_bitrate will return 0 for mcs >= 32 */
+ bitrate = nl80211_calculate_bitrate(&sinfo->txrate);
+ if (bitrate > 0)
+ NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
- if (!(sinfo->txrate.flags & RATE_INFO_FLAGS_MCS))
- NLA_PUT_U16(msg, NL80211_RATE_INFO_LEGACY,
- sinfo->txrate.legacy);
- else
+ if (sinfo->txrate.flags & RATE_INFO_FLAGS_MCS)
NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS,
sinfo->txrate.mcs);
if (sinfo->txrate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
include/linux/nl80211.h +2 -2
@@ -431,14 +431,14 @@ enum nl80211_sta_flags {* when getting information about the bitrate of a station. * * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved -* @NL80211_RATE_INFO_LEGACY: bitrate for 802.11abg (u16, 100kbit/s) +* @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval */ enum nl80211_rate_info { __NL80211_RATE_INFO_INVALID, -NL80211_RATE_INFO_LEGACY , +NL80211_RATE_INFO_BITRATE ,NL80211_RATE_INFO_MCS ,NL80211_RATE_INFO_40_MHZ_WIDTH ,NL80211_RATE_INFO_SHORT_GI ,
net/wireless/nl80211.c +39 -4
62 lines not on this page · raw message
Johannes Berg
maintainerRe: [PATCH 1/2] Add signal strength and bandwith to nl80211station info
Quoted 5 lines · Henning Rogge
Quoted 3 lines · On Wednesday 10 December 2008 21:45:37 Johannes Berg wrote:
On Wed, 2008-12-10 at 18:40 +0100, Henning Rogge wrote:
Can you do what I asked for instead and not include the attribute when it has a bogus value?I agree, that was a stupid thing...
Now merge it all into one patch, and I think we're good :)
Quoted 94 lines
Henning
-------------------------------include/linux/nl80211.h +2
-2@@ -431,14 +431,14 @@ enum nl80211_sta_flags {* when getting information about the bitrate of a station. * * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved -* @NL80211_RATE_INFO_LEGACY: bitrate for 802.11abg (u16, 100kbit/s) +* @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval */ enum nl80211_rate_info { __NL80211_RATE_INFO_INVALID, -NL80211_RATE_INFO_LEGACY , +NL80211_RATE_INFO_BITRATE ,NL80211_RATE_INFO_MCS ,NL80211_RATE_INFO_40_MHZ_WIDTH ,NL80211_RATE_INFO_SHORT_GI ,net/wireless/nl80211.c +34
-0@@ -1079,12 +1079,46 @@ static int parse_station_flags(struct nlattr *nla, u32 *staflags)return 0 ; } +static u16 nl80211_calculate_bitrate (struct rate_info *rate) +{ +int modulation, streams, bitrate; + +if (!(rate->flags &RATE_INFO_FLAGS_MCS )) +return rate->legacy; + +/* the formula below does only work for MCS values smaller than 32 */ +if (rate->mcs >=32 ) +return 0 ; + + modulation = rate->mcs &7 ; + streams = (rate->mcs >>3 ) +1 ; + + bitrate = (rate->flags &RATE_INFO_FLAGS_40_MHZ_WIDTH ) ? +13500000 :6500000 ; + +if (modulation <4 ) + bitrate *= (modulation +1 ); +else if (modulation ==4 ) + bitrate *= (modulation +2 ); +else + bitrate *= (modulation +3 ); + + bitrate *= streams; + +if (rate->flags &RATE_INFO_FLAGS_SHORT_GI ) + bitrate = (bitrate /9 ) *10 ; + +/* do NOT round down here */ +return (bitrate +50000 ) /100000 ; +} +static int nl80211_send_station (struct sk_buff *msg,u32 pid,u32 seq,int flags,struct net_device *dev,u8 *mac_addr,struct station_info *sinfo) {void *hdr;struct nlattr *sinfoattr, *txrate; +u16 bitrate; hdr =nl80211hdr_put (msg, pid, seq, flags,NL80211_CMD_NEW_STATION );net/wireless/nl80211.c +5
-4if (!hdr)@@ -1122,11 +1156,12 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, if (!txrate) goto nla_put_failure; +/* nl80211_calculate_bitrate will return 0 for mcs >= 32 */ + bitrate =nl80211_calculate_bitrate (&sinfo->txrate); +if (bitrate >0 ) +NLA_PUT_U16 (msg,NL80211_RATE_INFO_BITRATE , bitrate); -if (!(sinfo->txrate.flags &RATE_INFO_FLAGS_MCS )) -NLA_PUT_U16 (msg,NL80211_RATE_INFO_LEGACY , - sinfo->txrate.legacy); -else +if (sinfo->txrate.flags &RATE_INFO_FLAGS_MCS )NLA_PUT_U8 (msg,NL80211_RATE_INFO_MCS , sinfo->txrate.mcs);if (
sinfo->txrate.flags&RATE_INFO_FLAGS_40_MHZ_WIDTH)
PATCH 1/1 nl80211: Add signal strength and bandwith to nl80211station info
This patch adds signal strength and transmission bitrate to the station_info of nl80211.
---
include/linux/nl80211.h +29 -0
@@ -425,6 +425,30 @@ enum nl80211_sta_flags { };/** +* enum nl80211_rate_info - bitrate information +* +* These attribute types are used with %NL80211_STA_INFO_TXRATE +* when getting information about the bitrate of a station. +* +* @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved +* @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) +* @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) +* @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate +* @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval +*/ +enum nl80211_rate_info { + __NL80211_RATE_INFO_INVALID, +NL80211_RATE_INFO_BITRATE , +NL80211_RATE_INFO_MCS , +NL80211_RATE_INFO_40_MHZ_WIDTH , +NL80211_RATE_INFO_SHORT_GI , + +/* keep last */ + __NL80211_RATE_INFO_AFTER_LAST, +NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST -1 +}; + +/** * enum nl80211_sta_info - station information * * These attribute types are used with %NL80211_ATTR_STA_INFO
@@ -436,6 +460,9 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) +* @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute +* containing info as possible, see &enum nl80211_sta_info_txrate. */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID,
@@ -445,6 +472,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_TX_BITRATE ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +40 -0
@@ -169,6 +169,9 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled +* (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -177,6 +180,39 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , + STATION_INFO_TX_BITRATE = 1<<7, +}; + +/** +* enum station_info_rate_flags - bitrate info flags +* +* Used by the driver to indicate the specific rate transmission +* type for 802.11n transmissions. +* +* @RATE_INFO_FLAGS_MCS: @tx_bitrate_mcs filled +* @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 Mhz width transmission +* @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval +*/ +enum rate_info_flags { +RATE_INFO_FLAGS_MCS =1 <<0 , +RATE_INFO_FLAGS_40_MHZ_WIDTH =1 <<1 , +RATE_INFO_FLAGS_SHORT_GI =1 <<2 , +}; + +/** +* struct rate_info - bitrate information +* +* Information about a receiving or transmitting bitrate +* +* @flags: bitflag of flags from &enum rate_info_flags +* @mcs: mcs index if struct describes a 802.11n bitrate +* @legacy: bitrate in 100kbit/s for 802.11abg +*/ +struct rate_info { +u8 flags; +u8 mcs; +u16 legacy; };/**
@@ -191,6 +227,8 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received package in dBm +* @txrate: current unicast bitrate to this station */ struct station_info {u32 filled;
@@ -200,6 +238,8 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +struct rate_info txrate; };/**
net/mac80211/cfg.c +0 -0
@@ -310,12 +310,35 @@ static void sta_set_sinfo(struct sta_info *sta, struct
station_info *sinfo)
sinfo->filled = STATION_INFO_INACTIVE_TIME |
STATION_INFO_RX_BYTES |
- STATION_INFO_TX_BYTES;
+ STATION_INFO_TX_BYTES |
+ STATION_INFO_TX_BITRATE;
sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes;
sinfo->tx_bytes = sta->tx_bytes;
+ if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
+ sinfo->filled |= STATION_INFO_SIGNAL;
+ sinfo->signal = sta->last_signal;
+ }
+
+ sinfo->txrate.flags = 0;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI)
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+
+ if (!(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) {
+ struct ieee80211_supported_band *sband;
+ sband = sta->local->hw.wiphy->bands[
+ sta->local->hw.conf.channel->band];
+ sinfo->txrate.legacy =
+ sband->bitrates[sta->last_tx_rate.idx].bitrate;
+ } else
+ sinfo->txrate.mcs = sta->last_tx_rate.idx;
+
if (ieee80211_vif_is_mesh(&sdata->vif)) {
#ifdef CONFIG_MAC80211_MESH
sinfo->filled |= STATION_INFO_LLID |
net/wireless/nl80211.c +0 -0
@@ -1091,12 +1091,46 @@ static int parse_station_flags(struct nlattr *nla, u32
*staflags)
return 0;
}
+static u16 nl80211_calculate_bitrate(struct rate_info *rate) +{
+ int modulation, streams, bitrate;
+
+ if (!(rate->flags & RATE_INFO_FLAGS_MCS))
+ return rate->legacy;
+
+ /* the formula below does only work for MCS values smaller than 32 */
+ if (rate->mcs >= 32)
+ return 0;
+
+ modulation = rate->mcs & 7;
+ streams = (rate->mcs >> 3) + 1;
+
+ bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ?
+ 13500000 : 6500000;
+
+ if (modulation < 4)
+ bitrate *= (modulation + 1);
+ else if (modulation == 4)
+ bitrate *= (modulation + 2);
+ else
+ bitrate *= (modulation + 3);
+
+ bitrate *= streams;
+
+ if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
+ bitrate = (bitrate / 9) * 10;
+
+ /* do NOT round down here */
+ return (bitrate + 50000) / 100000;
+}
+
static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
int flags, struct net_device *dev, u8 *mac_addr, struct station_info *sinfo)
{
void *hdr;
- struct nlattr *sinfoattr;
+ struct nlattr *sinfoattr, *txrate;
+ u16 bitrate;
hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION); if (!hdr)
@@ -1126,7 +1160,29 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
if (sinfo->filled & STATION_INFO_PLINK_STATE)
NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
sinfo->plink_state);
+ if (sinfo->filled & STATION_INFO_SIGNAL)
+ NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
+ sinfo->signal);
+ if (sinfo->filled & STATION_INFO_TX_BITRATE) {
+ txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE);
+ if (!txrate)
+ goto nla_put_failure;
+
+ /* nl80211_calculate_bitrate will return 0 for mcs >= 32 */
+ bitrate = nl80211_calculate_bitrate(&sinfo->txrate);
+ if (bitrate > 0)
+ NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
+ if (sinfo->txrate.flags & RATE_INFO_FLAGS_MCS)
+ NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS,
+ sinfo->txrate.mcs);
+ if (sinfo->txrate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
+ NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
+ if (sinfo->txrate.flags & RATE_INFO_FLAGS_SHORT_GI)
+ NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI);
+
+ nla_nest_end(msg, txrate);
+ }
nla_nest_end(msg, sinfoattr);
return genlmsg_end(msg, hdr);
This patch adds signal strength and transmission bitrate to the station_info of nl80211.
---
include/linux/nl80211.h +29 -0
@@ -425,6 +425,30 @@ enum nl80211_sta_flags { };/** +* enum nl80211_rate_info - bitrate information +* +* These attribute types are used with %NL80211_STA_INFO_TXRATE +* when getting information about the bitrate of a station. +* +* @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved +* @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) +* @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) +* @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate +* @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval +*/ +enum nl80211_rate_info { + __NL80211_RATE_INFO_INVALID, +NL80211_RATE_INFO_BITRATE , +NL80211_RATE_INFO_MCS , +NL80211_RATE_INFO_40_MHZ_WIDTH , +NL80211_RATE_INFO_SHORT_GI , + +/* keep last */ + __NL80211_RATE_INFO_AFTER_LAST, +NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST -1 +}; + +/** * enum nl80211_sta_info - station information * * These attribute types are used with %NL80211_ATTR_STA_INFO
@@ -436,6 +460,9 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) +* @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute +* containing info as possible, see &enum nl80211_sta_info_txrate. */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID,
@@ -445,6 +472,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_TX_BITRATE ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +40 -0
@@ -169,6 +169,9 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled +* (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -177,6 +180,39 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , + STATION_INFO_TX_BITRATE = 1<<7, +}; + +/** +* enum station_info_rate_flags - bitrate info flags +* +* Used by the driver to indicate the specific rate transmission +* type for 802.11n transmissions. +* +* @RATE_INFO_FLAGS_MCS: @tx_bitrate_mcs filled +* @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 Mhz width transmission +* @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval +*/ +enum rate_info_flags { +RATE_INFO_FLAGS_MCS =1 <<0 , +RATE_INFO_FLAGS_40_MHZ_WIDTH =1 <<1 , +RATE_INFO_FLAGS_SHORT_GI =1 <<2 , +}; + +/** +* struct rate_info - bitrate information +* +* Information about a receiving or transmitting bitrate +* +* @flags: bitflag of flags from &enum rate_info_flags +* @mcs: mcs index if struct describes a 802.11n bitrate +* @legacy: bitrate in 100kbit/s for 802.11abg +*/ +struct rate_info { +u8 flags; +u8 mcs; +u16 legacy; };/**
@@ -191,6 +227,8 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received package in dBm +* @txrate: current unicast bitrate to this station */ struct station_info {u32 filled;
@@ -200,6 +238,8 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal; +struct rate_info txrate; };/**
net/mac80211/cfg.c +24 -1
@@ -310,12 +310,35 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) sinfo->filled =STATION_INFO_INACTIVE_TIME |STATION_INFO_RX_BYTES | -STATION_INFO_TX_BYTES ; +STATION_INFO_TX_BYTES | +STATION_INFO_TX_BITRATE ; sinfo->inactive_time =jiffies_to_msecs (jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes; sinfo->tx_bytes = sta->tx_bytes; +if (sta->local->hw.flags &IEEE80211_HW_SIGNAL_DBM ) { + sinfo->filled |=STATION_INFO_SIGNAL ; + sinfo->signal = sta->last_signal; + } + + sinfo->txrate.flags =0 ; +if (sta->last_tx_rate.flags &IEEE80211_TX_RC_MCS ) + sinfo->txrate.flags |=RATE_INFO_FLAGS_MCS ; +if (sta->last_tx_rate.flags &IEEE80211_TX_RC_40_MHZ_WIDTH ) + sinfo->txrate.flags |=RATE_INFO_FLAGS_40_MHZ_WIDTH ; +if (sta->last_tx_rate.flags &IEEE80211_TX_RC_SHORT_GI ) + sinfo->txrate.flags |=RATE_INFO_FLAGS_SHORT_GI ; + +if (!(sta->last_tx_rate.flags &IEEE80211_TX_RC_MCS )) { +struct ieee80211_supported_band *sband; + sband = sta->local->hw.wiphy->bands[ + sta->local->hw.conf.channel->band]; + sinfo->txrate.legacy = + sband->bitrates[sta->last_tx_rate.idx].bitrate; + }else + sinfo->txrate.mcs = sta->last_tx_rate.idx; +if (ieee80211_vif_is_mesh (&sdata->vif)) {#ifdef CONFIG_MAC80211_MESH sinfo->filled |= STATION_INFO_LLID |
net/wireless/nl80211.c +57 -1
76 lines not on this page · raw message
Johannes Berg
maintainerRe: [Patch] nl80211: Add signal strength and bandwith to nl80211station info
Quoted 2 lines · Henning Rogge
This patch adds signal strength and transmission bitrate to the
station_infoof nl80211.
Ok, this looks good, except a few minor things:
Quoted 1 line
+ * @signal: signal strength of last received package in dBm
I still want to change the docs to read "packet" here ;)
include/net/cfg80211.h struct station_info { · line 241
Quoted 9 lines
+ * @txrate: current unicast bitrate to this station */
structstation_info{include/net/cfg80211.h +1
-0u32 filled;@@ -200,6 +238,8 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +u8 signal;
and I think a u8 isn't the right type. It should be s8.
Can you also send me the corresponding iw patch?
johannes
Re: [Patch] nl80211: Add signal strength and bandwith to nl80211station info
Quoted 5 lines · On Thursday 11 December 2008 18:24:08 Johannes Berg wrote:
Ok, this looks good, except a few minor things:
Quoted 1 line
+ * @signal: signal strength of last received package in dBm
I still want to change the docs to read "packet" here ;)
Quoted 11 lines
Review struct station_info { · line 241
Quoted 9 lines
+ * @txrate: current unicast bitrate to this station */
structstation_info{(quoted diff) +1
-0u32 filled;@@ -200,6 +238,8 @@ struct station_info { u16 llid; u16 plid; u8 plink_state; + u8 signal;and I think a u8 isn't the right type. It should be s8.
Okay... I have included a casting to s8 into cfg.c so everyone is warned... the original signal field in the sta_info struct is an int, but this structure is used by the drivers so I don't want to touch it.
Quoted 1 line
Can you also send me the corresponding iw patch?
Have to write a modified one, I will post it later this evening I think.
Henning
----------------------------------------
This patch adds signal strength and transmission bitrate to the station_info of nl80211.
---
include/linux/nl80211.h +29 -0
@@ -425,6 +425,30 @@ enum nl80211_sta_flags { };/** +* enum nl80211_rate_info - bitrate information +* +* These attribute types are used with %NL80211_STA_INFO_TXRATE +* when getting information about the bitrate of a station. +* +* @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved +* @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) +* @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) +* @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate +* @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval +*/ +enum nl80211_rate_info { + __NL80211_RATE_INFO_INVALID, +NL80211_RATE_INFO_BITRATE , +NL80211_RATE_INFO_MCS , +NL80211_RATE_INFO_40_MHZ_WIDTH , +NL80211_RATE_INFO_SHORT_GI , + +/* keep last */ + __NL80211_RATE_INFO_AFTER_LAST, +NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST -1 +}; + +/** * enum nl80211_sta_info - station information * * These attribute types are used with %NL80211_ATTR_STA_INFO
@@ -436,6 +460,9 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) +* @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute +* containing info as possible, see &enum nl80211_sta_info_txrate. */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID,
@@ -445,6 +472,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_TX_BITRATE ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +40 -0
@@ -169,6 +169,9 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled +* (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -177,6 +180,39 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , + STATION_INFO_TX_BITRATE = 1<<7, +}; + +/** +* enum station_info_rate_flags - bitrate info flags +* +* Used by the driver to indicate the specific rate transmission +* type for 802.11n transmissions. +* +* @RATE_INFO_FLAGS_MCS: @tx_bitrate_mcs filled +* @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 Mhz width transmission +* @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval +*/ +enum rate_info_flags { +RATE_INFO_FLAGS_MCS =1 <<0 , +RATE_INFO_FLAGS_40_MHZ_WIDTH =1 <<1 , +RATE_INFO_FLAGS_SHORT_GI =1 <<2 , +}; + +/** +* struct rate_info - bitrate information +* +* Information about a receiving or transmitting bitrate +* +* @flags: bitflag of flags from &enum rate_info_flags +* @mcs: mcs index if struct describes a 802.11n bitrate +* @legacy: bitrate in 100kbit/s for 802.11abg +*/ +struct rate_info { +u8 flags; +u8 mcs; +u16 legacy; };/**
@@ -191,6 +227,8 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received packet in dBm +* @txrate: current unicast bitrate to this station */ struct station_info {u32 filled;
@@ -200,6 +238,8 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +s8 signal; +struct rate_info txrate; };/**
net/mac80211/cfg.c +0 -0
@@ -310,12 +310,35 @@ static void sta_set_sinfo(struct sta_info *sta, struct
station_info *sinfo)
sinfo->filled = STATION_INFO_INACTIVE_TIME |
STATION_INFO_RX_BYTES |
- STATION_INFO_TX_BYTES;
+ STATION_INFO_TX_BYTES |
+ STATION_INFO_TX_BITRATE;
sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes;
sinfo->tx_bytes = sta->tx_bytes;
+ if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
+ sinfo->filled |= STATION_INFO_SIGNAL;
+ sinfo->signal = (s8)sta->last_signal;
+ }
+
+ sinfo->txrate.flags = 0;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI)
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+
+ if (!(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) {
+ struct ieee80211_supported_band *sband;
+ sband = sta->local->hw.wiphy->bands[
+ sta->local->hw.conf.channel->band];
+ sinfo->txrate.legacy =
+ sband->bitrates[sta->last_tx_rate.idx].bitrate;
+ } else
+ sinfo->txrate.mcs = sta->last_tx_rate.idx;
+
if (ieee80211_vif_is_mesh(&sdata->vif)) {
#ifdef CONFIG_MAC80211_MESH
sinfo->filled |= STATION_INFO_LLID |
net/wireless/nl80211.c +0 -0
@@ -1091,12 +1091,46 @@ static int parse_station_flags(struct nlattr *nla, u32
*staflags)
return 0;
}
+static u16 nl80211_calculate_bitrate(struct rate_info *rate) +{
+ int modulation, streams, bitrate;
+
+ if (!(rate->flags & RATE_INFO_FLAGS_MCS))
+ return rate->legacy;
+
+ /* the formula below does only work for MCS values smaller than 32 */
+ if (rate->mcs >= 32)
+ return 0;
+
+ modulation = rate->mcs & 7;
+ streams = (rate->mcs >> 3) + 1;
+
+ bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ?
+ 13500000 : 6500000;
+
+ if (modulation < 4)
+ bitrate *= (modulation + 1);
+ else if (modulation == 4)
+ bitrate *= (modulation + 2);
+ else
+ bitrate *= (modulation + 3);
+
+ bitrate *= streams;
+
+ if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
+ bitrate = (bitrate / 9) * 10;
+
+ /* do NOT round down here */
+ return (bitrate + 50000) / 100000;
+}
+
static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
int flags, struct net_device *dev, u8 *mac_addr, struct station_info *sinfo)
{
void *hdr;
- struct nlattr *sinfoattr;
+ struct nlattr *sinfoattr, *txrate;
+ u16 bitrate;
hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION); if (!hdr)
@@ -1126,7 +1160,29 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
if (sinfo->filled & STATION_INFO_PLINK_STATE)
NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
sinfo->plink_state);
+ if (sinfo->filled & STATION_INFO_SIGNAL)
+ NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
+ sinfo->signal);
+ if (sinfo->filled & STATION_INFO_TX_BITRATE) {
+ txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE);
+ if (!txrate)
+ goto nla_put_failure;
+
+ /* nl80211_calculate_bitrate will return 0 for mcs >= 32 */
+ bitrate = nl80211_calculate_bitrate(&sinfo->txrate);
+ if (bitrate > 0)
+ NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
+ if (sinfo->txrate.flags & RATE_INFO_FLAGS_MCS)
+ NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS,
+ sinfo->txrate.mcs);
+ if (sinfo->txrate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
+ NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
+ if (sinfo->txrate.flags & RATE_INFO_FLAGS_SHORT_GI)
+ NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI);
+
+ nla_nest_end(msg, txrate);
+ }
nla_nest_end(msg, sinfoattr);
return genlmsg_end(msg, hdr);
This patch adds signal strength and transmission bitrate to the station_info of nl80211.
---
include/linux/nl80211.h +29 -0
@@ -425,6 +425,30 @@ enum nl80211_sta_flags { };/** +* enum nl80211_rate_info - bitrate information +* +* These attribute types are used with %NL80211_STA_INFO_TXRATE +* when getting information about the bitrate of a station. +* +* @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved +* @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) +* @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) +* @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate +* @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval +*/ +enum nl80211_rate_info { + __NL80211_RATE_INFO_INVALID, +NL80211_RATE_INFO_BITRATE , +NL80211_RATE_INFO_MCS , +NL80211_RATE_INFO_40_MHZ_WIDTH , +NL80211_RATE_INFO_SHORT_GI , + +/* keep last */ + __NL80211_RATE_INFO_AFTER_LAST, +NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST -1 +}; + +/** * enum nl80211_sta_info - station information * * These attribute types are used with %NL80211_ATTR_STA_INFO
@@ -436,6 +460,9 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) +* @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute +* containing info as possible, see &enum nl80211_sta_info_txrate. */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID,
@@ -445,6 +472,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_TX_BITRATE ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +40 -0
@@ -169,6 +169,9 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled +* (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -177,6 +180,39 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , + STATION_INFO_TX_BITRATE = 1<<7, +}; + +/** +* enum station_info_rate_flags - bitrate info flags +* +* Used by the driver to indicate the specific rate transmission +* type for 802.11n transmissions. +* +* @RATE_INFO_FLAGS_MCS: @tx_bitrate_mcs filled +* @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 Mhz width transmission +* @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval +*/ +enum rate_info_flags { +RATE_INFO_FLAGS_MCS =1 <<0 , +RATE_INFO_FLAGS_40_MHZ_WIDTH =1 <<1 , +RATE_INFO_FLAGS_SHORT_GI =1 <<2 , +}; + +/** +* struct rate_info - bitrate information +* +* Information about a receiving or transmitting bitrate +* +* @flags: bitflag of flags from &enum rate_info_flags +* @mcs: mcs index if struct describes a 802.11n bitrate +* @legacy: bitrate in 100kbit/s for 802.11abg +*/ +struct rate_info { +u8 flags; +u8 mcs; +u16 legacy; };/**
@@ -191,6 +227,8 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received packet in dBm +* @txrate: current unicast bitrate to this station */ struct station_info {u32 filled;
@@ -200,6 +238,8 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +s8 signal; +struct rate_info txrate; };/**
net/mac80211/cfg.c +24 -1
@@ -310,12 +310,35 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) sinfo->filled =STATION_INFO_INACTIVE_TIME |STATION_INFO_RX_BYTES | -STATION_INFO_TX_BYTES ; +STATION_INFO_TX_BYTES | +STATION_INFO_TX_BITRATE ; sinfo->inactive_time =jiffies_to_msecs (jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes; sinfo->tx_bytes = sta->tx_bytes; +if (sta->local->hw.flags &IEEE80211_HW_SIGNAL_DBM ) { + sinfo->filled |=STATION_INFO_SIGNAL ; + sinfo->signal = (s8 )sta->last_signal; + } + + sinfo->txrate.flags =0 ; +if (sta->last_tx_rate.flags &IEEE80211_TX_RC_MCS ) + sinfo->txrate.flags |=RATE_INFO_FLAGS_MCS ; +if (sta->last_tx_rate.flags &IEEE80211_TX_RC_40_MHZ_WIDTH ) + sinfo->txrate.flags |=RATE_INFO_FLAGS_40_MHZ_WIDTH ; +if (sta->last_tx_rate.flags &IEEE80211_TX_RC_SHORT_GI ) + sinfo->txrate.flags |=RATE_INFO_FLAGS_SHORT_GI ; + +if (!(sta->last_tx_rate.flags &IEEE80211_TX_RC_MCS )) { +struct ieee80211_supported_band *sband; + sband = sta->local->hw.wiphy->bands[ + sta->local->hw.conf.channel->band]; + sinfo->txrate.legacy = + sband->bitrates[sta->last_tx_rate.idx].bitrate; + }else + sinfo->txrate.mcs = sta->last_tx_rate.idx; +if (ieee80211_vif_is_mesh (&sdata->vif)) {#ifdef CONFIG_MAC80211_MESH sinfo->filled |= STATION_INFO_LLID |
net/wireless/nl80211.c +57 -1
76 lines not on this page · raw message
Re: [Patch] nl80211: Add signal strength and bandwith to nl80211station info
Quoted 3 lines · Henning Rogge
Okay... I have included a casting to s8 into
cfg.cso everyone is warned... the original signal field in thesta_infostruct is an int, but this structure is used by the drivers so I don't want to touch it.
Right, not sure what happens when it's not in dBm anyway.
Quoted 2 lines
Quoted 1 line
Can you also send me the corresponding iw patch?
Have to write a modified one, I will post it later this evening I think.
Ok. I noticed a few more things, sorry:
Quoted 10 lines
+ * enum
nl80211_rate_info- bitrate information
+ *
+ * These attribute types are used with %NL80211_STA_INFO_TXRATE
+ * when getting information about the bitrate of a station.
+ *
+ * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved
+ * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s)
+ * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8)
+ * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate
+ * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval
This needs documentation for __...after_last and ..._max too, I think, or kernel-doc will complain, and then I get email on the next daily git update and complain ;)
Other than that,
so feel free to add that into the patch when you resend.
johannes
Re: [Patch] nl80211: Add signal strength and bandwith to nl80211station info
Quoted 7 lines · On Thursday 11 December 2008 19:14:47 you wrote:
Quoted 3 lines
Okay... I have included a casting to s8 into
cfg.cso everyone is warned... the original signal field in thesta_infostruct is an int, but this structure is used by the drivers so I don't want to touch it.Right, not sure what happens when it's not in dBm anyway.
Ok. I noticed a few more things, sorry:
no problem... I want to get the bugs out of the patch, not to get it "in" as soon as possible.
Quoted 11 lines
Quoted 10 lines
+ * enum
nl80211_rate_info- bitrate information
+ *
+ * These attribute types are used with %NL80211_STA_INFO_TXRATE
+ * when getting information about the bitrate of a station.
+ *
+ * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved
+ * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s)
+ * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8)
+ * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate
+ * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval
Quoted 3 lines
This needs documentation for __...after_last and ..._max too, I think, or kernel-doc will complain, and then I get email on the next daily git update and complain ;)
Is there a script to check for mistakes like this ? I used checkpatch.pl and it did not complain...
Quoted 5 lines
Other than that,
Acked-by Johannes Berg <[email protected]>so feel free to add that into the patch when you resend.
I will... together with the iw patch.
Henning
Johannes Berg
maintainerRe: [Patch] nl80211: Add signal strength and bandwith to nl80211station info
Quoted 5 lines · Henning Rogge
Quoted 3 lines
This needs documentation for __...after_last and ..._max too, I think, or kernel-doc will complain, and then I get email on the next daily git update and complain ;)
Is there a script to check for mistakes like this ? I used checkpatch.pl and it did not complain...
well, apply the patch and do
make htmldocs DOCBOOKS=mac80211.xml
Actually, hmm, I think, that won't help, because these files aren't included yet. Heh.
johannes
Re: [Patch] nl80211: Add signal strength and bandwith to nl80211station info
I noticed the MAX/AFTER_LAST comments are missing for most nl80211 enums. ;)
But I get this output on my local (2 card) ad-hoc network:
# ./iw dev wlan0 station dump
Station 00:1b:fc:91:7d:d2 (on wlan0)
inactive time: 52 ms
rx bytes: 207220
tx bytes: 1396
signal: -66 dBm
tx bitrate: 18.0 MBit/sPatch for iw attached (based on git tree an hour ago). Of course the 802.11n output part is only compile tested. Most of the patch is to put the new copy of nl80211.h into iw (why does iw carry a copy of this file ?)
Henning
------------
nl80211.h +29 -0
@@ -425,6 +425,30 @@ enum nl80211_sta_flags { };/** +* enum nl80211_rate_info - bitrate information +* +* These attribute types are used with %NL80211_STA_INFO_TXRATE +* when getting information about the bitrate of a station. +* +* @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved +* @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) +* @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) +* @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate +* @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval +*/ +enum nl80211_rate_info { + __NL80211_RATE_INFO_INVALID, +NL80211_RATE_INFO_BITRATE , +NL80211_RATE_INFO_MCS , +NL80211_RATE_INFO_40_MHZ_WIDTH , +NL80211_RATE_INFO_SHORT_GI , + +/* keep last */ + __NL80211_RATE_INFO_AFTER_LAST, +NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST -1 +}; + +/** * enum nl80211_sta_info - station information * * These attribute types are used with %NL80211_ATTR_STA_INFO
@@ -436,6 +460,9 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) +* @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute +* containing info as possible, see &enum nl80211_sta_info_txrate. */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID,
@@ -445,6 +472,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_TX_BITRATE ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
station.c +38 -2
@@ -27,22 +27,31 @@ enum plink_actions { PLINK_ACTION_BLOCK, }; -static int print_sta_handler (struct nl_msg *msg,void *arg) {struct nlattr *tb[NL80211_ATTR_MAX +1 ];struct genlmsghdr *gnlh =nlmsg_data (nlmsg_hdr (msg));struct nlattr *sinfo[NL80211_STA_INFO_MAX +1 ]; +struct nlattr *rinfo[NL80211_RATE_INFO_MAX +1 ];char mac_addr[20 ], state_name[10 ], dev[20 ];static struct nla_policy stats_policy[NL80211_STA_INFO_MAX +1 ] = { [NL80211_STA_INFO_INACTIVE_TIME ] = { .type =NLA_U32 }, [NL80211_STA_INFO_RX_BYTES ] = { .type =NLA_U32 }, [NL80211_STA_INFO_TX_BYTES ] = { .type =NLA_U32 }, + [NL80211_STA_INFO_SIGNAL ] = { .type =NLA_U8 }, + [NL80211_STA_INFO_TX_BITRATE ] = { .type =NLA_NESTED }, [NL80211_STA_INFO_LLID ] = { .type =NLA_U16 }, [NL80211_STA_INFO_PLID ] = { .type =NLA_U16 }, [NL80211_STA_INFO_PLINK_STATE ] = { .type =NLA_U8 }, }; +static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX +1 ] = { + [NL80211_RATE_INFO_BITRATE ] = { .type =NLA_U16 }, + [NL80211_RATE_INFO_MCS ] = { .type =NLA_U8 }, + [NL80211_RATE_INFO_40_MHZ_WIDTH ] = { .type =NLA_FLAG }, + [NL80211_RATE_INFO_SHORT_GI ] = { .type =NLA_FLAG }, + }; +nla_parse (tb,NL80211_ATTR_MAX ,genlmsg_attrdata (gnlh,0 ),genlmsg_attrlen (gnlh,0 ),NULL );
@@ -62,7 +71,7 @@ static int print_sta_handler(struct nl_msg *msg, void *arg)fprintf (stderr,"failed to parse nested attributes!" );return NL_SKIP ; } - +mac_addr_n2a (mac_addr,nla_data (tb[NL80211_ATTR_MAC ]));if_indextoname (nla_get_u32 (tb[NL80211_ATTR_IFINDEX ]), dev);printf ("Station %s (on %s)" , mac_addr, dev);
@@ -76,6 +85,33 @@ static int print_sta_handler(struct nl_msg *msg, void *arg)if (sinfo[NL80211_STA_INFO_TX_BYTES ])printf ("\n\ttx bytes:\t%d" ,nla_get_u32 (sinfo[NL80211_STA_INFO_TX_BYTES ])); +if (sinfo[NL80211_STA_INFO_SIGNAL ]) +printf ("\n\tsignal: \t%d dBm" , + (int8_t )nla_get_u8 (sinfo[NL80211_STA_INFO_SIGNAL ])); + +if (sinfo[NL80211_STA_INFO_TX_BITRATE ]) { +if (nla_parse_nested (rinfo,NL80211_RATE_INFO_MAX , + sinfo[NL80211_STA_INFO_TX_BITRATE ], + rate_policy)) { +fprintf (stderr,"failed to parse nested rate attributes!" ); + }else { +printf ("\n\ttx bitrate:\t" ); +if (rinfo[NL80211_RATE_INFO_BITRATE ]) { +int rate =nla_get_u16 (rinfo[NL80211_RATE_INFO_BITRATE ]); +printf ("%d.%d MBit/s" , rate /10 , rate %10 ); + } +else +printf ("?" ); + +if (rinfo[NL80211_RATE_INFO_MCS ]) +printf (" msc:%d" , +nla_get_u8 (rinfo[NL80211_RATE_INFO_MCS ])); +if (rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH ]) +printf (" 40Mhz" ); +if (rinfo[NL80211_RATE_INFO_SHORT_GI ]) +printf (" short-guard-interval" ); + } + }if (sinfo[NL80211_STA_INFO_LLID ])printf ("\n\tmesh llid:\t%d" ,nla_get_u16 (sinfo[NL80211_STA_INFO_LLID ]));
nl80211.h +29 -0
@@ -425,6 +425,30 @@ enum nl80211_sta_flags { };/** +* enum nl80211_rate_info - bitrate information +* +* These attribute types are used with %NL80211_STA_INFO_TXRATE +* when getting information about the bitrate of a station. +* +* @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved +* @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) +* @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) +* @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate +* @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval +*/ +enum nl80211_rate_info { + __NL80211_RATE_INFO_INVALID, +NL80211_RATE_INFO_BITRATE , +NL80211_RATE_INFO_MCS , +NL80211_RATE_INFO_40_MHZ_WIDTH , +NL80211_RATE_INFO_SHORT_GI , + +/* keep last */ + __NL80211_RATE_INFO_AFTER_LAST, +NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST -1 +}; + +/** * enum nl80211_sta_info - station information * * These attribute types are used with %NL80211_ATTR_STA_INFO
@@ -436,6 +460,9 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) +* @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute +* containing info as possible, see &enum nl80211_sta_info_txrate. */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID,
@@ -445,6 +472,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_TX_BITRATE ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
station.c +38 -2
@@ -27,22 +27,31 @@ enum plink_actions { PLINK_ACTION_BLOCK, }; -static int print_sta_handler (struct nl_msg *msg,void *arg) {struct nlattr *tb[NL80211_ATTR_MAX +1 ];struct genlmsghdr *gnlh =nlmsg_data (nlmsg_hdr (msg));struct nlattr *sinfo[NL80211_STA_INFO_MAX +1 ]; +struct nlattr *rinfo[NL80211_RATE_INFO_MAX +1 ];char mac_addr[20 ], state_name[10 ], dev[20 ];static struct nla_policy stats_policy[NL80211_STA_INFO_MAX +1 ] = { [NL80211_STA_INFO_INACTIVE_TIME ] = { .type =NLA_U32 }, [NL80211_STA_INFO_RX_BYTES ] = { .type =NLA_U32 }, [NL80211_STA_INFO_TX_BYTES ] = { .type =NLA_U32 }, + [NL80211_STA_INFO_SIGNAL ] = { .type =NLA_U8 }, + [NL80211_STA_INFO_TX_BITRATE ] = { .type =NLA_NESTED }, [NL80211_STA_INFO_LLID ] = { .type =NLA_U16 }, [NL80211_STA_INFO_PLID ] = { .type =NLA_U16 }, [NL80211_STA_INFO_PLINK_STATE ] = { .type =NLA_U8 }, }; +static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX +1 ] = { + [NL80211_RATE_INFO_BITRATE ] = { .type =NLA_U16 }, + [NL80211_RATE_INFO_MCS ] = { .type =NLA_U8 }, + [NL80211_RATE_INFO_40_MHZ_WIDTH ] = { .type =NLA_FLAG }, + [NL80211_RATE_INFO_SHORT_GI ] = { .type =NLA_FLAG }, + }; +nla_parse (tb,NL80211_ATTR_MAX ,genlmsg_attrdata (gnlh,0 ),genlmsg_attrlen (gnlh,0 ),NULL );
@@ -62,7 +71,7 @@ static int print_sta_handler(struct nl_msg *msg, void *arg)fprintf (stderr,"failed to parse nested attributes!" );return NL_SKIP ; } - +mac_addr_n2a (mac_addr,nla_data (tb[NL80211_ATTR_MAC ]));if_indextoname (nla_get_u32 (tb[NL80211_ATTR_IFINDEX ]), dev);printf ("Station %s (on %s)" , mac_addr, dev);
@@ -76,6 +85,33 @@ static int print_sta_handler(struct nl_msg *msg, void *arg)if (sinfo[NL80211_STA_INFO_TX_BYTES ])printf ("\n\ttx bytes:\t%d" ,nla_get_u32 (sinfo[NL80211_STA_INFO_TX_BYTES ])); +if (sinfo[NL80211_STA_INFO_SIGNAL ]) +printf ("\n\tsignal: \t%d dBm" , + (int8_t )nla_get_u8 (sinfo[NL80211_STA_INFO_SIGNAL ])); + +if (sinfo[NL80211_STA_INFO_TX_BITRATE ]) { +if (nla_parse_nested (rinfo,NL80211_RATE_INFO_MAX , + sinfo[NL80211_STA_INFO_TX_BITRATE ], + rate_policy)) { +fprintf (stderr,"failed to parse nested rate attributes!" ); + }else { +printf ("\n\ttx bitrate:\t" ); +if (rinfo[NL80211_RATE_INFO_BITRATE ]) { +int rate =nla_get_u16 (rinfo[NL80211_RATE_INFO_BITRATE ]); +printf ("%d.%d MBit/s" , rate /10 , rate %10 ); + } +else +printf ("?" ); + +if (rinfo[NL80211_RATE_INFO_MCS ]) +printf (" msc:%d" , +nla_get_u8 (rinfo[NL80211_RATE_INFO_MCS ])); +if (rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH ]) +printf (" 40Mhz" ); +if (rinfo[NL80211_RATE_INFO_SHORT_GI ]) +printf (" short-guard-interval" ); + } + }if (sinfo[NL80211_STA_INFO_LLID ])printf ("\n\tmesh llid:\t%d" ,nla_get_u16 (sinfo[NL80211_STA_INFO_LLID ]));
Re: [Patch] nl80211: Add signal strength and bandwith to nl80211station info
In reply to Johannes BergThis patch adds signal strength and transmission bitrate to the station_info of nl80211.
---
include/linux/nl80211.h +31 -0
@@ -425,6 +425,32 @@ enum nl80211_sta_flags { };/** +* enum nl80211_rate_info - bitrate information +* +* These attribute types are used with %NL80211_STA_INFO_TXRATE +* when getting information about the bitrate of a station. +* +* @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved +* @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) +* @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) +* @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate +* @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval +* @NL80211_RATE_INFO_MAX: highest rate_info number currently defined +* @__NL80211_RATE_INFO_AFTER_LAST: internal use +*/ +enum nl80211_rate_info { + __NL80211_RATE_INFO_INVALID, +NL80211_RATE_INFO_BITRATE , +NL80211_RATE_INFO_MCS , +NL80211_RATE_INFO_40_MHZ_WIDTH , +NL80211_RATE_INFO_SHORT_GI , + +/* keep last */ + __NL80211_RATE_INFO_AFTER_LAST, +NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST -1 +}; + +/** * enum nl80211_sta_info - station information * * These attribute types are used with %NL80211_ATTR_STA_INFO
@@ -436,6 +462,9 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) +* @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute +* containing info as possible, see &enum nl80211_sta_info_txrate. */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID,
@@ -445,6 +474,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_TX_BITRATE ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +40 -0
@@ -169,6 +169,9 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled +* (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -177,6 +180,39 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , + STATION_INFO_TX_BITRATE = 1<<7, +}; + +/** +* enum station_info_rate_flags - bitrate info flags +* +* Used by the driver to indicate the specific rate transmission +* type for 802.11n transmissions. +* +* @RATE_INFO_FLAGS_MCS: @tx_bitrate_mcs filled +* @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 Mhz width transmission +* @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval +*/ +enum rate_info_flags { +RATE_INFO_FLAGS_MCS =1 <<0 , +RATE_INFO_FLAGS_40_MHZ_WIDTH =1 <<1 , +RATE_INFO_FLAGS_SHORT_GI =1 <<2 , +}; + +/** +* struct rate_info - bitrate information +* +* Information about a receiving or transmitting bitrate +* +* @flags: bitflag of flags from &enum rate_info_flags +* @mcs: mcs index if struct describes a 802.11n bitrate +* @legacy: bitrate in 100kbit/s for 802.11abg +*/ +struct rate_info { +u8 flags; +u8 mcs; +u16 legacy; };/**
@@ -191,6 +227,8 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received packet in dBm +* @txrate: current unicast bitrate to this station */ struct station_info {u32 filled;
@@ -200,6 +238,8 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +s8 signal; +struct rate_info txrate; };/**
net/mac80211/cfg.c +0 -0
@@ -310,12 +310,35 @@ static void sta_set_sinfo(struct sta_info *sta, struct
station_info *sinfo)
sinfo->filled = STATION_INFO_INACTIVE_TIME |
STATION_INFO_RX_BYTES |
- STATION_INFO_TX_BYTES;
+ STATION_INFO_TX_BYTES |
+ STATION_INFO_TX_BITRATE;
sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes;
sinfo->tx_bytes = sta->tx_bytes;
+ if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
+ sinfo->filled |= STATION_INFO_SIGNAL;
+ sinfo->signal = (s8)sta->last_signal;
+ }
+
+ sinfo->txrate.flags = 0;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+ if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI)
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+
+ if (!(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) {
+ struct ieee80211_supported_band *sband;
+ sband = sta->local->hw.wiphy->bands[
+ sta->local->hw.conf.channel->band];
+ sinfo->txrate.legacy =
+ sband->bitrates[sta->last_tx_rate.idx].bitrate;
+ } else
+ sinfo->txrate.mcs = sta->last_tx_rate.idx;
+
if (ieee80211_vif_is_mesh(&sdata->vif)) {
#ifdef CONFIG_MAC80211_MESH
sinfo->filled |= STATION_INFO_LLID |
net/wireless/nl80211.c +0 -0
@@ -1091,12 +1091,46 @@ static int parse_station_flags(struct nlattr *nla, u32
*staflags)
return 0;
}
+static u16 nl80211_calculate_bitrate(struct rate_info *rate) +{
+ int modulation, streams, bitrate;
+
+ if (!(rate->flags & RATE_INFO_FLAGS_MCS))
+ return rate->legacy;
+
+ /* the formula below does only work for MCS values smaller than 32 */
+ if (rate->mcs >= 32)
+ return 0;
+
+ modulation = rate->mcs & 7;
+ streams = (rate->mcs >> 3) + 1;
+
+ bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ?
+ 13500000 : 6500000;
+
+ if (modulation < 4)
+ bitrate *= (modulation + 1);
+ else if (modulation == 4)
+ bitrate *= (modulation + 2);
+ else
+ bitrate *= (modulation + 3);
+
+ bitrate *= streams;
+
+ if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
+ bitrate = (bitrate / 9) * 10;
+
+ /* do NOT round down here */
+ return (bitrate + 50000) / 100000;
+}
+
static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
int flags, struct net_device *dev, u8 *mac_addr, struct station_info *sinfo)
{
void *hdr;
- struct nlattr *sinfoattr;
+ struct nlattr *sinfoattr, *txrate;
+ u16 bitrate;
hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION); if (!hdr)
@@ -1126,7 +1160,29 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
if (sinfo->filled & STATION_INFO_PLINK_STATE)
NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
sinfo->plink_state);
+ if (sinfo->filled & STATION_INFO_SIGNAL)
+ NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
+ sinfo->signal);
+ if (sinfo->filled & STATION_INFO_TX_BITRATE) {
+ txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE);
+ if (!txrate)
+ goto nla_put_failure;
+
+ /* nl80211_calculate_bitrate will return 0 for mcs >= 32 */
+ bitrate = nl80211_calculate_bitrate(&sinfo->txrate);
+ if (bitrate > 0)
+ NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
+ if (sinfo->txrate.flags & RATE_INFO_FLAGS_MCS)
+ NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS,
+ sinfo->txrate.mcs);
+ if (sinfo->txrate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
+ NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
+ if (sinfo->txrate.flags & RATE_INFO_FLAGS_SHORT_GI)
+ NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI);
+
+ nla_nest_end(msg, txrate);
+ }
nla_nest_end(msg, sinfoattr);
return genlmsg_end(msg, hdr);
This patch adds signal strength and transmission bitrate to the station_info of nl80211.
---
include/linux/nl80211.h +31 -0
@@ -425,6 +425,32 @@ enum nl80211_sta_flags { };/** +* enum nl80211_rate_info - bitrate information +* +* These attribute types are used with %NL80211_STA_INFO_TXRATE +* when getting information about the bitrate of a station. +* +* @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved +* @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) +* @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) +* @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate +* @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval +* @NL80211_RATE_INFO_MAX: highest rate_info number currently defined +* @__NL80211_RATE_INFO_AFTER_LAST: internal use +*/ +enum nl80211_rate_info { + __NL80211_RATE_INFO_INVALID, +NL80211_RATE_INFO_BITRATE , +NL80211_RATE_INFO_MCS , +NL80211_RATE_INFO_40_MHZ_WIDTH , +NL80211_RATE_INFO_SHORT_GI , + +/* keep last */ + __NL80211_RATE_INFO_AFTER_LAST, +NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST -1 +}; + +/** * enum nl80211_sta_info - station information * * These attribute types are used with %NL80211_ATTR_STA_INFO
@@ -436,6 +462,9 @@ enum nl80211_sta_flags {* @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute +* @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) +* @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute +* containing info as possible, see &enum nl80211_sta_info_txrate. */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID,
@@ -445,6 +474,8 @@ enum nl80211_sta_info {NL80211_STA_INFO_LLID ,NL80211_STA_INFO_PLID ,NL80211_STA_INFO_PLINK_STATE , +NL80211_STA_INFO_SIGNAL , +NL80211_STA_INFO_TX_BITRATE ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
include/net/cfg80211.h +40 -0
@@ -169,6 +169,9 @@ struct station_parameters {* @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled +* @STATION_INFO_SIGNAL: @signal filled +* @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled +* (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) */ enum station_info_flags {STATION_INFO_INACTIVE_TIME =1 <<0 ,
@@ -177,6 +180,39 @@ enum station_info_flags {STATION_INFO_LLID =1 <<3 ,STATION_INFO_PLID =1 <<4 ,STATION_INFO_PLINK_STATE =1 <<5 , +STATION_INFO_SIGNAL =1 <<6 , + STATION_INFO_TX_BITRATE = 1<<7, +}; + +/** +* enum station_info_rate_flags - bitrate info flags +* +* Used by the driver to indicate the specific rate transmission +* type for 802.11n transmissions. +* +* @RATE_INFO_FLAGS_MCS: @tx_bitrate_mcs filled +* @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 Mhz width transmission +* @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval +*/ +enum rate_info_flags { +RATE_INFO_FLAGS_MCS =1 <<0 , +RATE_INFO_FLAGS_40_MHZ_WIDTH =1 <<1 , +RATE_INFO_FLAGS_SHORT_GI =1 <<2 , +}; + +/** +* struct rate_info - bitrate information +* +* Information about a receiving or transmitting bitrate +* +* @flags: bitflag of flags from &enum rate_info_flags +* @mcs: mcs index if struct describes a 802.11n bitrate +* @legacy: bitrate in 100kbit/s for 802.11abg +*/ +struct rate_info { +u8 flags; +u8 mcs; +u16 legacy; };/**
@@ -191,6 +227,8 @@ enum station_info_flags {* @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state +* @signal: signal strength of last received packet in dBm +* @txrate: current unicast bitrate to this station */ struct station_info {u32 filled;
@@ -200,6 +238,8 @@ struct station_info {u16 llid;u16 plid;u8 plink_state; +s8 signal; +struct rate_info txrate; };/**
net/mac80211/cfg.c +24 -1
@@ -310,12 +310,35 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) sinfo->filled =STATION_INFO_INACTIVE_TIME |STATION_INFO_RX_BYTES | -STATION_INFO_TX_BYTES ; +STATION_INFO_TX_BYTES | +STATION_INFO_TX_BITRATE ; sinfo->inactive_time =jiffies_to_msecs (jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes; sinfo->tx_bytes = sta->tx_bytes; +if (sta->local->hw.flags &IEEE80211_HW_SIGNAL_DBM ) { + sinfo->filled |=STATION_INFO_SIGNAL ; + sinfo->signal = (s8 )sta->last_signal; + } + + sinfo->txrate.flags =0 ; +if (sta->last_tx_rate.flags &IEEE80211_TX_RC_MCS ) + sinfo->txrate.flags |=RATE_INFO_FLAGS_MCS ; +if (sta->last_tx_rate.flags &IEEE80211_TX_RC_40_MHZ_WIDTH ) + sinfo->txrate.flags |=RATE_INFO_FLAGS_40_MHZ_WIDTH ; +if (sta->last_tx_rate.flags &IEEE80211_TX_RC_SHORT_GI ) + sinfo->txrate.flags |=RATE_INFO_FLAGS_SHORT_GI ; + +if (!(sta->last_tx_rate.flags &IEEE80211_TX_RC_MCS )) { +struct ieee80211_supported_band *sband; + sband = sta->local->hw.wiphy->bands[ + sta->local->hw.conf.channel->band]; + sinfo->txrate.legacy = + sband->bitrates[sta->last_tx_rate.idx].bitrate; + }else + sinfo->txrate.mcs = sta->last_tx_rate.idx; +if (ieee80211_vif_is_mesh (&sdata->vif)) {#ifdef CONFIG_MAC80211_MESH sinfo->filled |= STATION_INFO_LLID |
net/wireless/nl80211.c +57 -1
76 lines not on this page · raw message
Johannes Berg
maintainerRe: [Patch] nl80211: Add signal strength and bandwith to nl80211station info
Quoted 5 lines · Henning Rogge
This patch adds signal strength and transmission bitrate to the
station_infoof nl80211.Signed-off-by Henning Rogge <[email protected]>Acked-by Johannes Berg <[email protected]>
You should probably send this with just [PATCH v14] (no Re:), CC John and not attach the file but make sure the inline version is ok (if possible)
johannes
Johannes Berg
maintainerRe: [Patch] nl80211: Add signal strength and bandwith to nl80211station info
In reply to Henning RoggeQuoted 1 line · Henning Rogge
I noticed the MAX/AFTER_LAST comments are missing for most nl80211 enums. ;)
Hah
Quoted 9 lines
But I get this output on my local (2 card) ad-hoc network:
# ./iw dev wlan0 station dump Station 00:1b:fc:91:7d:d2 (on wlan0) inactive time: 52 ms rx bytes: 207220 tx bytes: 1396 signal: -66 dBm tx bitrate: 18.0 MBit/s
Quoted 3 lines
Patch for iw attached (based on git tree an hour ago). Of course the 802.11n output part is only compile tested. Most of the patch is to put the new copy of
nl80211.hinto iw (why does iw carry a copy of this file ?)
Because it's easier to build that way if you don't have a current tree.
I'll take the patch once the other one gets into the kernel tree.
johannes