mac80211: add supported rates change notification in IBSS
authorAntonio Quartulli <ordex@autistici.org>
Sun, 12 Aug 2012 16:24:55 +0000 (18:24 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 20 Aug 2012 11:31:43 +0000 (13:31 +0200)
In IBSS it is possible that the supported rates set for a station changes over
time (e.g. it gets first initialised as an empty set because of no available
information about rates and updated later). In this case the driver has to be
notified about the change in order to update its internal table accordingly (if
needed).

This behaviour is needed by all those drivers that handle rc internally but
leave stations management to mac80211

Reported-by: Gui Iribarren <gui@altermundi.net>
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
[Johannes - add docs, validate IBSS mode only, fix compilation]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/mac80211.h
net/mac80211/driver-ops.h
net/mac80211/ibss.c

index 8114f590f7151b68f01207415be75a30633e8d68..d9cef31f4cbfabd4a5e152d1391ce6af125660b6 100644 (file)
@@ -1897,10 +1897,14 @@ enum ieee80211_frame_release_type {
  * @IEEE80211_RC_BW_CHANGED: The bandwidth that can be used to transmit
  *     to this station changed.
  * @IEEE80211_RC_SMPS_CHANGED: The SMPS state of the station changed.
+ * @IEEE80211_RC_SUPP_RATES_CHANGED: The supported rate set of this peer
+ *     changed (in IBSS mode) due to discovering more information about
+ *     the peer.
  */
 enum ieee80211_rate_control_changed {
        IEEE80211_RC_BW_CHANGED         = BIT(0),
        IEEE80211_RC_SMPS_CHANGED       = BIT(1),
+       IEEE80211_RC_SUPP_RATES_CHANGED = BIT(2),
 };
 
 /**
index a81117a839964510a3d9dad28f163d78f76bebbe..a81154d2729146af6ddb7c308913035d8b9cbb36 100644 (file)
@@ -528,6 +528,9 @@ static inline void drv_sta_rc_update(struct ieee80211_local *local,
        sdata = get_bss_sdata(sdata);
        check_sdata_in_driver(sdata);
 
+       WARN_ON(changed & IEEE80211_RC_SUPP_RATES_CHANGED &&
+               sdata->vif.type != NL80211_IFTYPE_ADHOC);
+
        trace_drv_sta_rc_update(local, sdata, sta, changed);
        if (local->ops->sta_rc_update)
                local->ops->sta_rc_update(&local->hw, &sdata->vif,
index 1ebda2f9e57be7c9b1ff1848e9408134904a3fd8..a9d93285dba75b1a9f6ed78fe804f1d1fc20e178 100644 (file)
@@ -459,8 +459,11 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
                        }
                }
 
-               if (sta && rates_updated)
+               if (sta && rates_updated) {
+                       drv_sta_rc_update(local, sdata, &sta->sta,
+                                         IEEE80211_RC_SUPP_RATES_CHANGED);
                        rate_control_rate_init(sta);
+               }
 
                rcu_read_unlock();
        }