summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2014-11-19 02:10:42 +0300
committerJohannes Berg <johannes.berg@intel.com>2014-11-19 21:15:50 +0300
commitf815e2b3c0126c26911cac72b837f03a31c0c2ed (patch)
treea0ffb718bd301afbbee9d106f87e7b886dbc52f0
parent8f894be2df9ad43d17763bc0201f7f303a91f091 (diff)
downloadlinux-f815e2b3c0126c26911cac72b837f03a31c0c2ed.tar.xz
mac80211: notify drivers on sta rate table changes
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>
-rw-r--r--include/net/mac80211.h6
-rw-r--r--net/mac80211/driver-ops.h15
-rw-r--r--net/mac80211/rate.c3
-rw-r--r--net/mac80211/trace.h7
4 files changed, 31 insertions, 0 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 7b889e3a2647..cff3a26a9dae 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -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);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 5f5fc3f3ee7c..2ebc9ead9695 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -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)
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index f6fea67fcc5b..08ab7d6d1517 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -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);
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index eb91505eb43e..85ccfbe863db 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -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,