staging: wfx: send rate policies one by one
authorJérôme Pouiller <jerome.pouiller@silabs.com>
Wed, 15 Jan 2020 13:54:07 +0000 (13:54 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 16 Jan 2020 19:59:45 +0000 (20:59 +0100)
Rate policies (aka. tx_rate_retry_policy in hardware API) are sent to
device asynchronously from tx requests. So, the device maintains a list
of active rate policies and the tx requests only reference an existent
rate policy.

The device API allows to send multiple rate policies at once. However,
this property is very rarely used. We prefer to send rate policies one
by one and simplify the architecture.

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

index b2a325c47b2daf05b5e164b7ae9576513af94e3b..fb51c5910ace1e5ec054bab521cac6f9b4bbe3fd 100644 (file)
@@ -217,37 +217,34 @@ static void wfx_tx_policy_put(struct wfx_vif *wvif, int idx)
 
 static int wfx_tx_policy_upload(struct wfx_vif *wvif)
 {
-       int i;
-       struct tx_policy_cache *cache = &wvif->tx_policy_cache;
        struct hif_mib_set_tx_rate_retry_policy *arg =
-               kzalloc(struct_size(arg,
-                                   tx_rate_retry_policy,
-                                   HIF_MIB_NUM_TX_RATE_RETRY_POLICIES),
-                       GFP_KERNEL);
-       struct hif_mib_tx_rate_retry_policy *dst;
+               kzalloc(struct_size(arg, tx_rate_retry_policy, 1), GFP_KERNEL);
+       struct tx_policy *policies = wvif->tx_policy_cache.cache;
+       int i;
 
-       spin_lock_bh(&cache->lock);
-       /* Upload only modified entries. */
-       for (i = 0; i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES; ++i) {
-               struct tx_policy *src = &cache->cache[i];
-
-               if (!src->uploaded && memzcmp(src->rates, sizeof(src->rates))) {
-                       dst = arg->tx_rate_retry_policy +
-                               arg->num_tx_rate_policies;
-
-                       dst->policy_index = i;
-                       dst->short_retry_count = 255;
-                       dst->long_retry_count = 255;
-                       dst->first_rate_sel = 1;
-                       dst->terminate = 1;
-                       dst->count_init = 1;
-                       memcpy(&dst->rates, src->rates, sizeof(src->rates));
-                       src->uploaded = true;
-                       arg->num_tx_rate_policies++;
+       do {
+               spin_lock_bh(&wvif->tx_policy_cache.lock);
+               for (i = 0; i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES; ++i)
+                       if (!policies[i].uploaded &&
+                           memzcmp(policies[i].rates, sizeof(policies[i].rates)))
+                               break;
+               if (i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES) {
+                       policies[i].uploaded = 1;
+                       arg->num_tx_rate_policies = 1;
+                       arg->tx_rate_retry_policy[0].policy_index = i;
+                       arg->tx_rate_retry_policy[0].short_retry_count = 255;
+                       arg->tx_rate_retry_policy[0].long_retry_count = 255;
+                       arg->tx_rate_retry_policy[0].first_rate_sel = 1;
+                       arg->tx_rate_retry_policy[0].terminate = 1;
+                       arg->tx_rate_retry_policy[0].count_init = 1;
+                       memcpy(&arg->tx_rate_retry_policy[0].rates,
+                              policies[i].rates, sizeof(policies[i].rates));
+                       spin_unlock_bh(&wvif->tx_policy_cache.lock);
+                       hif_set_tx_rate_retry_policy(wvif, arg);
+               } else {
+                       spin_unlock_bh(&wvif->tx_policy_cache.lock);
                }
-       }
-       spin_unlock_bh(&cache->lock);
-       hif_set_tx_rate_retry_policy(wvif, arg);
+       } while (i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES);
        kfree(arg);
        return 0;
 }