diff options
author | Ajay Singh <ajay.kathat@microchip.com> | 2020-01-23 12:50:49 +0000 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-01-23 19:16:12 +0100 |
commit | bd4217cb9d54171a109fe63d0ac801cc7a18edb9 (patch) | |
tree | f8eb70961540787bc1dd2de808f7d08437e9a1e1 /drivers/staging/wilc1000 | |
parent | 7a80aa23d0f0f52478339840577137f556bf9121 (diff) |
staging: wilc1000: avoid mutex unlock without lock in wilc_wlan_handle_txq()
In wilc_wlan_handle_txq(), mutex unlock was called without acquiring
it. Also error code for full VMM condition was incorrect as discussed in
[1]. Now used a proper code to indicate VMM is full, for which transfer
to VMM is required again. 'wilc_wlan_handle_txq()' should be called
again if the VMM space was full earlier or otherwise based on
'txq_event' signal.
1. https://lore.kernel.org/driverdev-devel/20191113183322.a54mh2w6dulklgsd@kili.mountain/
Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
Link: https://lore.kernel.org/r/20200123182129.4053-2-ajay.kathat@microchip.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/wilc1000')
-rw-r--r-- | drivers/staging/wilc1000/netdev.c | 2 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wlan.c | 15 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wlan.h | 1 |
3 files changed, 12 insertions, 6 deletions
diff --git a/drivers/staging/wilc1000/netdev.c b/drivers/staging/wilc1000/netdev.c index 0f48e74aa3ea..fce5bf2d82fa 100644 --- a/drivers/staging/wilc1000/netdev.c +++ b/drivers/staging/wilc1000/netdev.c @@ -174,7 +174,7 @@ static int wilc_txq_task(void *vp) } srcu_read_unlock(&wl->srcu, srcu_idx); } - } while (ret == -ENOBUFS && !wl->close); + } while (ret == WILC_VMM_ENTRY_FULL_RETRY && !wl->close); } return 0; } diff --git a/drivers/staging/wilc1000/wlan.c b/drivers/staging/wilc1000/wlan.c index b904eda42806..601e4d1345d2 100644 --- a/drivers/staging/wilc1000/wlan.c +++ b/drivers/staging/wilc1000/wlan.c @@ -489,12 +489,12 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count) struct wilc_vif *vif; if (wilc->quit) - goto out; + goto out_update_cnt; mutex_lock(&wilc->txq_add_to_head_cs); tqe = wilc_wlan_txq_get_first(wilc); if (!tqe) - goto out; + goto out_unlock; dev = tqe->vif->ndev; wilc_wlan_txq_filter_dup_tcp_ack(dev); i = 0; @@ -526,7 +526,7 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count) } if (i == 0) - goto out; + goto out_unlock; vmm_table[i] = 0x0; acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP); @@ -595,7 +595,11 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count) goto out_release_bus; if (entries == 0) { - ret = -ENOBUFS; + /* + * No VMM space available in firmware so retry to transmit + * the packet from tx queue. + */ + ret = WILC_VMM_ENTRY_FULL_RETRY; goto out_release_bus; } @@ -662,9 +666,10 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count) out_release_bus: release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); -out: +out_unlock: mutex_unlock(&wilc->txq_add_to_head_cs); +out_update_cnt: *txq_count = wilc->txq_entries; return ret; } diff --git a/drivers/staging/wilc1000/wlan.h b/drivers/staging/wilc1000/wlan.h index 44ae6ed6882c..8c4634262adb 100644 --- a/drivers/staging/wilc1000/wlan.h +++ b/drivers/staging/wilc1000/wlan.h @@ -198,6 +198,7 @@ #define IS_MGMT_STATUS_SUCCES 0x040 #define WILC_WID_TYPE GENMASK(15, 12) +#define WILC_VMM_ENTRY_FULL_RETRY 1 /******************************************** * * Tx/Rx Queue Structure |