2011-12-09 22:31:35

by Paul Stewart

[permalink] [raw]
Subject: [PATCH] cfg80211: Return beacon loss count in station

If station info contains a beacon loss count, return
it to userspace.

Signed-off-by: Paul Stewart <[email protected]>
---
include/linux/nl80211.h | 2 ++
include/net/cfg80211.h | 7 ++++++-
net/mac80211/cfg.c | 4 +++-
net/mac80211/mlme.c | 8 ++++++++
net/mac80211/sta_info.h | 2 ++
net/wireless/nl80211.c | 3 +++
6 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index a187606..3c88e7a 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1651,6 +1651,7 @@ enum nl80211_sta_bss_param {
* containing info as possible, see &enum nl80211_sta_bss_param
* @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected
* @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update.
+ * @NL80211_STA_INFO_BEACON_LOSS: count of times beacon loss was detected (u32)
* @__NL80211_STA_INFO_AFTER_LAST: internal
* @NL80211_STA_INFO_MAX: highest possible station info attribute
*/
@@ -1673,6 +1674,7 @@ enum nl80211_sta_info {
NL80211_STA_INFO_BSS_PARAM,
NL80211_STA_INFO_CONNECTED_TIME,
NL80211_STA_INFO_STA_FLAGS,
+ NL80211_STA_INFO_BEACON_LOSS,

/* keep last */
__NL80211_STA_INFO_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 3de1c39..0144de8 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -505,6 +505,7 @@ struct station_parameters {
* @STATION_INFO_CONNECTED_TIME: @connected_time filled
* @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled
* @STATION_INFO_STA_FLAGS: @sta_flags filled
+ * @STATION_INFO_BEACON_LOSS_COUNT: @beacon_loss_count filled
*/
enum station_info_flags {
STATION_INFO_INACTIVE_TIME = 1<<0,
@@ -525,7 +526,8 @@ enum station_info_flags {
STATION_INFO_BSS_PARAM = 1<<15,
STATION_INFO_CONNECTED_TIME = 1<<16,
STATION_INFO_ASSOC_REQ_IES = 1<<17,
- STATION_INFO_STA_FLAGS = 1<<18
+ STATION_INFO_STA_FLAGS = 1<<18,
+ STATION_INFO_BEACON_LOSS_COUNT = 1<<19
};

/**
@@ -623,6 +625,7 @@ struct sta_bss_parameters {
* the cfg80211_new_sta() calls to notify user space of the IEs.
* @assoc_req_ies_len: Length of assoc_req_ies buffer in octets.
* @sta_flags: station flags mask & values
+ * @beacon_loss_count: Number of times beacon loss event has triggered.
*/
struct station_info {
u32 filled;
@@ -650,6 +653,8 @@ struct station_info {
const u8 *assoc_req_ies;
size_t assoc_req_ies_len;

+ u32 beacon_loss_count;
+
/*
* Note: Add a new enum station_info_flags value for each new field and
* use it to check which fields are initialized.
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 393b2a4..4b9c8ce 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -355,7 +355,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
STATION_INFO_RX_DROP_MISC |
STATION_INFO_BSS_PARAM |
STATION_INFO_CONNECTED_TIME |
- STATION_INFO_STA_FLAGS;
+ STATION_INFO_STA_FLAGS |
+ STATION_INFO_BEACON_LOSS_COUNT;

do_posix_clock_monotonic_gettime(&uptime);
sinfo->connected_time = uptime.tv_sec - sta->last_connected;
@@ -368,6 +369,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
sinfo->tx_retries = sta->tx_retry_count;
sinfo->tx_failed = sta->tx_retry_failed;
sinfo->rx_dropped_misc = sta->rx_dropped;
+ sinfo->beacon_loss_count = sta->beacon_loss_count;

if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
(sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 09019d1..b9f6fe3 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1381,6 +1381,14 @@ void ieee80211_beacon_connection_loss_work(struct work_struct *work)
struct ieee80211_sub_if_data *sdata =
container_of(work, struct ieee80211_sub_if_data,
u.mgd.beacon_connection_loss_work);
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+ struct sta_info *sta;
+
+ if (ifmgd->associated) {
+ sta = sta_info_get(sdata, ifmgd->bssid);
+ if (sta)
+ sta->beacon_loss_count++;
+ }

if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
__ieee80211_connection_loss(sdata);
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 1a14fab..75dfc10 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -262,6 +262,7 @@ struct sta_ampdu_mlme {
* @dummy: indicate a dummy station created for receiving
* EAP frames before association
* @sta: station information we share with the driver
+ * @beacon_loss_count: number of times beacon loss has triggered
*/
struct sta_info {
/* General information, mostly static */
@@ -352,6 +353,7 @@ struct sta_info {
#endif

unsigned int lost_packets;
+ unsigned int beacon_loss_count;

/* should be right in front of sta to be in the same cache line */
bool dummy;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index ba43966..a39d1b3 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2390,6 +2390,9 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
if (sinfo->filled & STATION_INFO_TX_FAILED)
NLA_PUT_U32(msg, NL80211_STA_INFO_TX_FAILED,
sinfo->tx_failed);
+ if (sinfo->filled & STATION_INFO_BEACON_LOSS_COUNT)
+ NLA_PUT_U32(msg, NL80211_STA_INFO_BEACON_LOSS,
+ sinfo->beacon_loss_count);
if (sinfo->filled & STATION_INFO_BSS_PARAM) {
bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM);
if (!bss_param)
--
1.7.3.1



2011-12-12 14:38:04

by Paul Stewart

[permalink] [raw]
Subject: Re: [PATCH] cfg80211: Return beacon loss count in station

On Mon, Dec 12, 2011 at 1:06 AM, Johannes Berg
<[email protected]> wrote:
> On Fri, 2011-12-09 at 11:01 -0800, Paul Stewart wrote:
>> If station info contains a beacon loss count, return
>> it to userspace.
>
>
>> + * @NL80211_STA_INFO_BEACON_LOSS: count of times beacon loss was detected (u32)
>
> Hmm, this is very vague. Are you sure it does what you think it does?
> Some drivers like wl12xx might not trigger the beacon loss function for
> every beacon, instead aggregating things. I implemented this in iwlwifi
> once and it would only tell mac80211 roughly every 20 beacons about
> missed ones...
>
> This should at least be documented, but I fear it makes the value rather
> useless in the general case.

I actually differ on that. I completely agree that this is not a
count of how many beacons were lost, but it does represent an
important statistic worth measuring, which is how often the system
enters a state where it is trying to recover from beacon loss. You
can't get this information anywhere else (unless you turn on
MAC80211_VERBOSE_DEBUG and go trawling through the logs) and my aim is
to collect swaths of this information to get qualitative information
about the occurrence count of this situation for a large population of
users. It seems like the cleanest way to get at it, regardless of the
somewhat device-specific interpretation (which one can always account
for).

> johannes
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to [email protected]
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html

2011-12-12 09:06:28

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH] cfg80211: Return beacon loss count in station

On Fri, 2011-12-09 at 11:01 -0800, Paul Stewart wrote:
> If station info contains a beacon loss count, return
> it to userspace.


> + * @NL80211_STA_INFO_BEACON_LOSS: count of times beacon loss was detected (u32)

Hmm, this is very vague. Are you sure it does what you think it does?
Some drivers like wl12xx might not trigger the beacon loss function for
every beacon, instead aggregating things. I implemented this in iwlwifi
once and it would only tell mac80211 roughly every 20 beacons about
missed ones...

This should at least be documented, but I fear it makes the value rather
useless in the general case.

johannes