mac80211: reconfigure tx on device reconfiguration
Eliad Peller [Thu, 14 Jul 2011 17:29:42 +0000 (20:29 +0300)]
Add tx_conf array to save the current tx queues
configuration, and reconfig it on resume (ieee80211_reconfig).

On resume, the driver is being reconfigured. Without
reconfiguring the tx queues as well, the driver might
configure the device to use wrong ac params (e.g. ps-poll
instead of uapsd).

Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

net/mac80211/cfg.c
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c
net/mac80211/util.c

index bfc36e9..3d1b091 100644 (file)
@@ -1255,6 +1255,10 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
         */
        p.uapsd = false;
 
+       if (params->queue >= local->hw.queues)
+               return -EINVAL;
+
+       local->tx_conf[params->queue] = p;
        if (drv_conf_tx(local, params->queue, &p)) {
                wiphy_debug(local->hw.wiphy,
                            "failed to set TX queue parameters for queue %d\n",
index dda0d1a..1b845bb 100644 (file)
@@ -746,6 +746,7 @@ struct ieee80211_local {
        struct workqueue_struct *workqueue;
 
        unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES];
+       struct ieee80211_tx_queue_params tx_conf[IEEE80211_MAX_QUEUES];
        /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */
        spinlock_t queue_stop_reason_lock;
 
index c99237c..71e20a7 100644 (file)
@@ -917,6 +917,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
                            params.aifs, params.cw_min, params.cw_max,
                            params.txop, params.uapsd);
 #endif
+               local->tx_conf[queue] = params;
                if (drv_conf_tx(local, queue, &params))
                        wiphy_debug(local->hw.wiphy,
                                    "failed to set TX queue parameters for queue %d\n",
index 8c2df33..ca440bc 100644 (file)
@@ -799,6 +799,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
 
                qparam.uapsd = false;
 
+               local->tx_conf[queue] = qparam;
                drv_conf_tx(local, queue, &qparam);
        }
 
@@ -1134,7 +1135,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
        struct ieee80211_hw *hw = &local->hw;
        struct ieee80211_sub_if_data *sdata;
        struct sta_info *sta;
-       int res;
+       int res, i;
 
 #ifdef CONFIG_PM
        if (local->suspended)
@@ -1211,6 +1212,10 @@ int ieee80211_reconfig(struct ieee80211_local *local)
        }
        mutex_unlock(&local->sta_mtx);
 
+       /* reconfigure tx conf */
+       for (i = 0; i < hw->queues; i++)
+               drv_conf_tx(local, i, &local->tx_conf[i]);
+
        /* reconfigure hardware */
        ieee80211_hw_config(local, ~0);