mac80211: notify drivers on sta rate table changes
authorJohannes Berg <johannes.berg@intel.com>
Tue, 18 Nov 2014 23:10:42 +0000 (00:10 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 19 Nov 2014 18:15:50 +0000 (19:15 +0100)
This allows drivers with a firmware or chip-based rate lookup table to
use the most recent default rate selection without having to get it from
per-packet data or explicit ieee80211_get_tx_rate calls

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/mac80211.h
net/mac80211/driver-ops.h
net/mac80211/rate.c
net/mac80211/trace.h

index 7b889e3..cff3a26 100644 (file)
@@ -2695,6 +2695,9 @@ enum ieee80211_reconfig_type {
  *     uses hardware rate control (%IEEE80211_HW_HAS_RATE_CONTROL) since
  *     otherwise the rate control algorithm is notified directly.
  *     Must be atomic.
+ * @sta_rate_tbl_update: Notifies the driver that the rate table changed. This
+ *     is only used if the configured rate control algorithm actually uses
+ *     the new rate table API, and is therefore optional. Must be atomic.
  *
  * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
  *     bursting) for a hardware TX queue.
@@ -3056,6 +3059,9 @@ struct ieee80211_ops {
                              struct ieee80211_vif *vif,
                              struct ieee80211_sta *sta,
                              u32 changed);
+       void (*sta_rate_tbl_update)(struct ieee80211_hw *hw,
+                                   struct ieee80211_vif *vif,
+                                   struct ieee80211_sta *sta);
        int (*conf_tx)(struct ieee80211_hw *hw,
                       struct ieee80211_vif *vif, u16 ac,
                       const struct ieee80211_tx_queue_params *params);
index 5f5fc3f..2ebc9ea 100644 (file)
@@ -624,6 +624,21 @@ static inline void drv_sta_rc_update(struct ieee80211_local *local,
        trace_drv_return_void(local);
 }
 
+static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local,
+                                          struct ieee80211_sub_if_data *sdata,
+                                          struct ieee80211_sta *sta)
+{
+       sdata = get_bss_sdata(sdata);
+       if (!check_sdata_in_driver(sdata))
+               return;
+
+       trace_drv_sta_rate_tbl_update(local, sdata, sta);
+       if (local->ops->sta_rate_tbl_update)
+               local->ops->sta_rate_tbl_update(&local->hw, &sdata->vif, sta);
+
+       trace_drv_return_void(local);
+}
+
 static inline int drv_conf_tx(struct ieee80211_local *local,
                              struct ieee80211_sub_if_data *sdata, u16 ac,
                              const struct ieee80211_tx_queue_params *params)
index f6fea67..08ab7d6 100644 (file)
@@ -696,6 +696,7 @@ int rate_control_set_rates(struct ieee80211_hw *hw,
                           struct ieee80211_sta *pubsta,
                           struct ieee80211_sta_rates *rates)
 {
+       struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
        struct ieee80211_sta_rates *old;
 
        /*
@@ -709,6 +710,8 @@ int rate_control_set_rates(struct ieee80211_hw *hw,
        if (old)
                kfree_rcu(old, rcu_head);
 
+       drv_sta_rate_tbl_update(hw_to_local(hw), sta->sdata, pubsta);
+
        return 0;
 }
 EXPORT_SYMBOL(rate_control_set_rates);
index eb91505..85ccfbe 100644 (file)
@@ -846,6 +846,13 @@ DEFINE_EVENT(sta_event, drv_sta_pre_rcu_remove,
        TP_ARGS(local, sdata, sta)
 );
 
+DEFINE_EVENT(sta_event, drv_sta_rate_tbl_update,
+       TP_PROTO(struct ieee80211_local *local,
+                struct ieee80211_sub_if_data *sdata,
+                struct ieee80211_sta *sta),
+       TP_ARGS(local, sdata, sta)
+);
+
 TRACE_EVENT(drv_conf_tx,
        TP_PROTO(struct ieee80211_local *local,
                 struct ieee80211_sub_if_data *sdata,