mac80211: track AP's beacon rate and give it to the driver
authorAlexander Bondar <alexander.bondar@intel.com>
Sun, 19 May 2013 11:23:57 +0000 (14:23 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 13 Jun 2013 09:58:47 +0000 (11:58 +0200)
Track the AP's beacon rate in the scan BSS data and in the
interface configuration to let the drivers know which rate
the AP is using. This information may be used by drivers,
in our case to let the firmware optimise beacon RX.

Signed-off-by: Alexander Bondar <alexander.bondar@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/mac80211.h
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c
net/mac80211/scan.c

index a405a7a9775cb0ad96f10cc0b683ac739de363cc..5b7a3dadaddec1b7cabb919a1cf9919b90ff638d 100644 (file)
@@ -305,6 +305,7 @@ enum ieee80211_rssi_event {
  * @basic_rates: bitmap of basic rates, each bit stands for an
  *     index into the rate table configured by the driver in
  *     the current band.
+ * @beacon_rate: associated AP's beacon TX rate
  * @mcast_rate: per-band multicast rate index + 1 (0: disabled)
  * @bssid: The BSSID for this BSS
  * @enable_beacon: whether beaconing should be enabled or not
@@ -352,6 +353,7 @@ struct ieee80211_bss_conf {
        u32 sync_device_ts;
        u8 sync_dtim_count;
        u32 basic_rates;
+       struct ieee80211_rate *beacon_rate;
        int mcast_rate[IEEE80211_NUM_BANDS];
        u16 ht_operation_mode;
        s32 cqm_rssi_thold;
index 7a6f1a0207ec1dfc6fab981e8d23efd9f867b5b5..a4dfb0be53d73404451eabf2761987300e49003c 100644 (file)
@@ -94,6 +94,7 @@ struct ieee80211_bss {
 #define IEEE80211_MAX_SUPP_RATES 32
        u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
        size_t supp_rates_len;
+       struct ieee80211_rate *beacon_rate;
 
        /*
         * During association, we save an ERP value from a probe response so
index ad9bb9e10cbb04947cb3bcac1aa4c9674d2a186b..87f2d4df31f8ab470bbd9c2de6e8c94bb2e0eb86 100644 (file)
@@ -1779,8 +1779,10 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
                 * probably just won't work at all.
                 */
                bss_conf->dtim_period = sdata->u.mgd.dtim_period ?: 1;
+               bss_conf->beacon_rate = bss->beacon_rate;
                bss_info_changed |= BSS_CHANGED_BEACON_INFO;
        } else {
+               bss_conf->beacon_rate = NULL;
                bss_conf->dtim_period = 0;
        }
 
@@ -1903,6 +1905,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
        del_timer_sync(&sdata->u.mgd.chswitch_timer);
 
        sdata->vif.bss_conf.dtim_period = 0;
+       sdata->vif.bss_conf.beacon_rate = NULL;
+
        ifmgd->have_beacon = false;
 
        ifmgd->flags = 0;
@@ -2754,8 +2758,10 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
 
        bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
                                        channel);
-       if (bss)
+       if (bss) {
                ieee80211_rx_bss_put(local, bss);
+               sdata->vif.bss_conf.beacon_rate = bss->beacon_rate;
+       }
 
        if (!sdata->u.mgd.associated ||
            !ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid))
index 99b103921a4befecdaa8d95a1391d3f040479fb1..1b122a79b0d8369a4118a6f238dc6d69db9e072c 100644 (file)
@@ -140,6 +140,15 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
                        bss->valid_data |= IEEE80211_BSS_VALID_WMM;
        }
 
+       if (beacon) {
+               struct ieee80211_supported_band *sband =
+                       local->hw.wiphy->bands[rx_status->band];
+               if (!(rx_status->flag & RX_FLAG_HT) &&
+                   !(rx_status->flag & RX_FLAG_VHT))
+                       bss->beacon_rate =
+                               &sband->bitrates[rx_status->rate_idx];
+       }
+
        return bss;
 }