cfg80211: Return beacon loss count in station
authorPaul Stewart <pstew@chromium.org>
Fri, 9 Dec 2011 19:01:49 +0000 (11:01 -0800)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 19 Dec 2011 19:34:13 +0000 (14:34 -0500)
If station info contains a beacon loss count, return
it to userspace.

Signed-off-by: Paul Stewart <pstew@chromium.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
include/linux/nl80211.h
include/net/cfg80211.h
net/mac80211/cfg.c
net/mac80211/mlme.c
net/mac80211/sta_info.h
net/wireless/nl80211.c

index f795cb7dccdda2011b62b1ea63f5d0d5ccc87143..0f5ff37398206d0cb30f866244879be020b99ed5 100644 (file)
@@ -1655,6 +1655,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
  */
@@ -1677,6 +1678,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,
index 9f85fca0b676606e0f04c4baa3a80bf6888778c4..15f4be7d768e48e740b5b58f39ba76813e79e2f6 100644 (file)
@@ -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.
index 66ad9d9af87f8f8d13ef199fe8b366207194f9ed..850bb96bd6805204685083dde687b8097bd19b0f 100644 (file)
@@ -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)) {
index a984f1f60ddbc7ab0370ce3665415260f2a7ef2e..57989a046fcace8570efa32612d09d5e9d345cc7 100644 (file)
@@ -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);
index dee284290464aaad208350882bd337bbe05b6e66..6f77f12dc3fc313410964a91f318e48f1319d86c 100644 (file)
@@ -275,6 +275,7 @@ struct sta_ampdu_mlme {
  *     EAP frames before association
  * @sta: station information we share with the driver
  * @sta_state: duplicates information about station state (for debug)
+ * @beacon_loss_count: number of times beacon loss has triggered
  */
 struct sta_info {
        /* General information, mostly static */
@@ -367,6 +368,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;
index b07c4fc4ae223363659592f91a9b6ff37ac42862..b3d3cf8931cb9a3c055df2e497943ec2500cfc51 100644 (file)
@@ -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)