]> www.infradead.org Git - users/hch/block.git/commitdiff
staging: wfx: fix the cache of rate policies on interface reset
authorJérôme Pouiller <jerome.pouiller@silabs.com>
Tue, 17 Dec 2019 16:14:27 +0000 (16:14 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Dec 2019 14:49:14 +0000 (15:49 +0100)
Device and driver maintain a cache of rate policies (aka.
tx_retry_policy in hardware API).

When hif_reset() is sent to hardware, device resets its cache of rate
policies. In order to keep driver in sync, it is necessary to do the
same on driver.

Note, when driver tries to use a rate policy that has not been defined
on device, data is sent at 1Mbps. So, this patch should fix abnormal
throughput observed sometime after a reset of the interface.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20191217161318.31402-2-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/wfx/data_tx.c
drivers/staging/wfx/data_tx.h
drivers/staging/wfx/sta.c

index df2640a79f02f5c50e0824cd1192fc862a206b00..bc769d1b6bc5a1d3ee88d12b70d2318e5959264e 100644 (file)
@@ -249,7 +249,7 @@ static int wfx_tx_policy_upload(struct wfx_vif *wvif)
        return 0;
 }
 
-static void wfx_tx_policy_upload_work(struct work_struct *work)
+void wfx_tx_policy_upload_work(struct work_struct *work)
 {
        struct wfx_vif *wvif =
                container_of(work, struct wfx_vif, tx_policy_upload_work);
@@ -270,7 +270,6 @@ void wfx_tx_policy_init(struct wfx_vif *wvif)
        spin_lock_init(&cache->lock);
        INIT_LIST_HEAD(&cache->used);
        INIT_LIST_HEAD(&cache->free);
-       INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work);
 
        for (i = 0; i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES; ++i)
                list_add(&cache->cache[i].link, &cache->free);
index 29faa5640516d1020c728d056a3b8fafd4d2c709..a0f9ae69baf58aeb20de1d2c41215071176cc404 100644 (file)
@@ -61,6 +61,7 @@ struct wfx_tx_priv {
 } __packed;
 
 void wfx_tx_policy_init(struct wfx_vif *wvif);
+void wfx_tx_policy_upload_work(struct work_struct *work);
 
 void wfx_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
            struct sk_buff *skb);
index 29848a202ab4e16ccff65afb48ea88623214756b..471dd15b227fe7a9b3107ff6b3102ed4e0d16869 100644 (file)
@@ -592,6 +592,7 @@ static void wfx_do_unjoin(struct wfx_vif *wvif)
        wfx_tx_flush(wvif->wdev);
        hif_keep_alive_period(wvif, 0);
        hif_reset(wvif, false);
+       wfx_tx_policy_init(wvif);
        hif_set_output_power(wvif, wvif->wdev->output_power * 10);
        wvif->dtim_period = 0;
        hif_set_macaddr(wvif, wvif->vif->addr);
@@ -880,8 +881,10 @@ static int wfx_update_beaconing(struct wfx_vif *wvif)
                if (wvif->state != WFX_STATE_AP ||
                    wvif->beacon_int != conf->beacon_int) {
                        wfx_tx_lock_flush(wvif->wdev);
-                       if (wvif->state != WFX_STATE_PASSIVE)
+                       if (wvif->state != WFX_STATE_PASSIVE) {
                                hif_reset(wvif, false);
+                               wfx_tx_policy_init(wvif);
+                       }
                        wvif->state = WFX_STATE_PASSIVE;
                        wfx_start_ap(wvif);
                        wfx_tx_unlock(wvif->wdev);
@@ -1567,6 +1570,7 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
        INIT_WORK(&wvif->set_cts_work, wfx_set_cts_work);
        INIT_WORK(&wvif->unjoin_work, wfx_unjoin_work);
 
+       INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work);
        mutex_unlock(&wdev->conf_mutex);
 
        hif_set_macaddr(wvif, vif->addr);