Since this driver internally stores the supported rate set for each station in
order to perform rate control, this callback is needed to update the internal
table as soon as the rate set changes in the mac80211 station configuration.

Reported-by: Guido Iribarren <[email protected]>
Tested-by: Guido Iribarren <[email protected]>
Signed-off-by: Antonio Quartulli <[email protected]>
---
 drivers/net/wireless/ath/ath9k/htc_drv_main.c |   24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c 
b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index c785129..6f5c134 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -676,21 +676,24 @@ static void ath9k_htc_init_rate(struct ath9k_htc_priv 
*priv,
 }
 
 static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv,
+                                 struct ieee80211_sta *sta,
                                  struct ieee80211_vif *vif,
                                  struct ieee80211_bss_conf *bss_conf)
 {
        struct ath_common *common = ath9k_hw_common(priv->ah);
        struct ath9k_htc_target_rate trate;
-       struct ieee80211_sta *sta;
        int ret;
 
        memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
 
        rcu_read_lock();
-       sta = ieee80211_find_sta(vif, bss_conf->bssid);
+       /* if no sta was passed, look for the AP */
        if (!sta) {
-               rcu_read_unlock();
-               return;
+               sta = ieee80211_find_sta(vif, bss_conf->bssid);
+               if (!sta) {
+                       rcu_read_unlock();
+                       return;
+               }
        }
        ath9k_htc_setup_rate(priv, sta, &trate);
        rcu_read_unlock();
@@ -702,6 +705,16 @@ static void ath9k_htc_update_rate(struct ath9k_htc_priv 
*priv,
                        bss_conf->bssid, be32_to_cpu(trate.capflags));
 }
 
+static void ath9k_htc_sta_update_rates(struct ieee80211_hw *hw,
+                                      struct ieee80211_sta *sta,
+                                      struct ieee80211_vif *vif,
+                                      struct ieee80211_bss_conf *info)
+{
+       struct ath9k_htc_priv *priv = hw->priv;
+
+       ath9k_htc_update_rate(priv, sta, vif, info);
+}
+
 static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv,
                                  struct ieee80211_vif *vif,
                                  struct ieee80211_sta *sta,
@@ -1550,7 +1563,7 @@ static void ath9k_htc_bss_info_changed(struct 
ieee80211_hw *hw,
        }
 
        if (changed & BSS_CHANGED_HT)
-               ath9k_htc_update_rate(priv, vif, bss_conf);
+               ath9k_htc_update_rate(priv, NULL, vif, bss_conf);
 
        ath9k_htc_ps_restore(priv);
        mutex_unlock(&priv->mutex);
@@ -1759,6 +1772,7 @@ struct ieee80211_ops ath9k_htc_ops = {
        .sta_remove         = ath9k_htc_sta_remove,
        .conf_tx            = ath9k_htc_conf_tx,
        .bss_info_changed   = ath9k_htc_bss_info_changed,
+       .sta_update_rates   = ath9k_htc_sta_update_rates,
        .set_key            = ath9k_htc_set_key,
        .get_tsf            = ath9k_htc_get_tsf,
        .set_tsf            = ath9k_htc_set_tsf,
-- 
1.7.9.4

_______________________________________________
ath9k-devel mailing list
[email protected]
https://lists.ath9k.org/mailman/listinfo/ath9k-devel

Reply via email to