Commit f815e2b3 authored by Johannes Berg's avatar Johannes Berg

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: default avatarFelix Fietkau <nbd@openwrt.org>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 8f894be2
...@@ -2695,6 +2695,9 @@ enum ieee80211_reconfig_type { ...@@ -2695,6 +2695,9 @@ enum ieee80211_reconfig_type {
* uses hardware rate control (%IEEE80211_HW_HAS_RATE_CONTROL) since * uses hardware rate control (%IEEE80211_HW_HAS_RATE_CONTROL) since
* otherwise the rate control algorithm is notified directly. * otherwise the rate control algorithm is notified directly.
* Must be atomic. * 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), * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
* bursting) for a hardware TX queue. * bursting) for a hardware TX queue.
...@@ -3056,6 +3059,9 @@ struct ieee80211_ops { ...@@ -3056,6 +3059,9 @@ struct ieee80211_ops {
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct ieee80211_sta *sta,
u32 changed); 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, int (*conf_tx)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, u16 ac, struct ieee80211_vif *vif, u16 ac,
const struct ieee80211_tx_queue_params *params); const struct ieee80211_tx_queue_params *params);
......
...@@ -624,6 +624,21 @@ static inline void drv_sta_rc_update(struct ieee80211_local *local, ...@@ -624,6 +624,21 @@ static inline void drv_sta_rc_update(struct ieee80211_local *local,
trace_drv_return_void(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, static inline int drv_conf_tx(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata, u16 ac, struct ieee80211_sub_if_data *sdata, u16 ac,
const struct ieee80211_tx_queue_params *params) const struct ieee80211_tx_queue_params *params)
......
...@@ -696,6 +696,7 @@ int rate_control_set_rates(struct ieee80211_hw *hw, ...@@ -696,6 +696,7 @@ int rate_control_set_rates(struct ieee80211_hw *hw,
struct ieee80211_sta *pubsta, struct ieee80211_sta *pubsta,
struct ieee80211_sta_rates *rates) struct ieee80211_sta_rates *rates)
{ {
struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
struct ieee80211_sta_rates *old; struct ieee80211_sta_rates *old;
/* /*
...@@ -709,6 +710,8 @@ int rate_control_set_rates(struct ieee80211_hw *hw, ...@@ -709,6 +710,8 @@ int rate_control_set_rates(struct ieee80211_hw *hw,
if (old) if (old)
kfree_rcu(old, rcu_head); kfree_rcu(old, rcu_head);
drv_sta_rate_tbl_update(hw_to_local(hw), sta->sdata, pubsta);
return 0; return 0;
} }
EXPORT_SYMBOL(rate_control_set_rates); EXPORT_SYMBOL(rate_control_set_rates);
......
...@@ -846,6 +846,13 @@ DEFINE_EVENT(sta_event, drv_sta_pre_rcu_remove, ...@@ -846,6 +846,13 @@ DEFINE_EVENT(sta_event, drv_sta_pre_rcu_remove,
TP_ARGS(local, sdata, sta) 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, TRACE_EVENT(drv_conf_tx,
TP_PROTO(struct ieee80211_local *local, TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata, struct ieee80211_sub_if_data *sdata,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment