@@ -1670,7 +1670,6 @@ static void wlan_init_locks(struct wilc *wl)
mutex_init(&wl->vif_mutex);
mutex_init(&wl->deinit_lock);
- spin_lock_init(&wl->txq_spinlock);
mutex_init(&wl->txq_add_to_head_cs);
mutex_init(&wl->tx_q_limit_lock);
@@ -863,6 +863,7 @@ void wilc_netdev_cleanup(struct wilc *wilc)
srcu_idx = srcu_read_lock(&wilc->srcu);
list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
+ mutex_destroy(&vif->ack_filter_lock);
if (vif->ndev)
unregister_netdev(vif->ndev);
}
@@ -929,6 +930,7 @@ struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
vif->wilc = wl;
vif->ndev = ndev;
ndev->ml_priv = vif;
+ mutex_init(&vif->ack_filter_lock);
ndev->netdev_ops = &wilc_netdev_ops;
@@ -190,6 +190,8 @@ struct wilc_vif {
struct timer_list during_ip_timer;
struct timer_list periodic_rssi;
struct rf_info periodic_stat;
+ /* protect ack_filter */
+ struct mutex ack_filter_lock;
struct tcp_ack_filter ack_filter;
bool connecting;
struct wilc_priv priv;
@@ -226,9 +228,6 @@ struct wilc {
/* protect head of transmit queue */
struct mutex txq_add_to_head_cs;
- /* protect txq_entry_t transmit queue */
- spinlock_t txq_spinlock;
-
/* protect rxq_entry_t receiver queue */
struct mutex rxq_cs;
@@ -124,15 +124,13 @@ static inline void tcp_process(struct net_device *dev, struct sk_buff *tqe)
void *buffer = tqe->data;
const struct ethhdr *eth_hdr_ptr = buffer;
int i;
- unsigned long flags;
struct wilc_vif *vif = netdev_priv(dev);
- struct wilc *wilc = vif->wilc;
struct tcp_ack_filter *f = &vif->ack_filter;
const struct iphdr *ip_hdr_ptr;
const struct tcphdr *tcp_hdr_ptr;
u32 ihl, total_length, data_offset;
- spin_lock_irqsave(&wilc->txq_spinlock, flags);
+ mutex_lock(&vif->ack_filter_lock);
if (eth_hdr_ptr->h_proto != htons(ETH_P_IP))
goto out;
@@ -168,7 +166,7 @@ static inline void tcp_process(struct net_device *dev, struct sk_buff *tqe)
}
out:
- spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
+ mutex_unlock(&vif->ack_filter_lock);
}
static void wilc_wlan_tx_packet_done(struct sk_buff *tqe, int status)
@@ -201,12 +199,10 @@ static void wilc_wlan_txq_drop_net_pkt(struct sk_buff *tqe)
static void wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
{
struct wilc_vif *vif = netdev_priv(dev);
- struct wilc *wilc = vif->wilc;
struct tcp_ack_filter *f = &vif->ack_filter;
u32 i = 0;
- unsigned long flags;
- spin_lock_irqsave(&wilc->txq_spinlock, flags);
+ mutex_lock(&vif->ack_filter_lock);
for (i = f->pending_base;
i < (f->pending_base + f->pending_acks_idx); i++) {
u32 index;
@@ -238,7 +234,7 @@ static void wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
else
f->pending_base = 0;
- spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
+ mutex_unlock(&vif->ack_filter_lock);
}
void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value)
The only purpose left for txq_spinlock is to protect the ack_filter. The ack_filter is only updated by the tx queue writers and the tx queue consumer, so interrupts don't have to be disabled and sleeping is OK. In other words, we can use a mutex instead of a spinlock. Signed-off-by: David Mosberger-Tang <davidm@egauge.net> --- drivers/net/wireless/microchip/wilc1000/cfg80211.c | 1 - drivers/net/wireless/microchip/wilc1000/netdev.c | 2 ++ drivers/net/wireless/microchip/wilc1000/netdev.h | 5 ++--- drivers/net/wireless/microchip/wilc1000/wlan.c | 12 ++++-------- 4 files changed, 8 insertions(+), 12 deletions(-)