Skip to content

Commit

Permalink
mwl8k: Handle watchdog event with highest prioriry
Browse files Browse the repository at this point in the history
Currently, command path waits till all the tx host queues
are empty. Whenever watchdog event is raised, firmware
expects driver to destroy ampdu queues immediately.

This requires corresponding commands i.e.
mwl8k_cmd_get_watchdog_bitmap and mwl8k_destroy_ba to be
sent without waiting for the tx queues to be completely
empty.

Use "watchdog_event_pending" to ensure the above mentioned
two commands are sent down immediately.

Signed-off-by: Nishant Sarmukadam <nishants@marvell.com>
Signed-off-by: Yogesh Ashok Powar <yogeshp@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Yogesh Ashok Powar authored and John W. Linville committed Jan 7, 2013
1 parent cfacba1 commit c27a54d
Showing 1 changed file with 19 additions and 0 deletions.
19 changes: 19 additions & 0 deletions drivers/net/wireless/mwl8k.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ struct mwl8k_priv {
int fw_mutex_depth;
struct completion *hostcmd_wait;

atomic_t watchdog_event_pending;

/* lock held over TX and TX reap */
spinlock_t tx_lock;

Expand Down Expand Up @@ -1527,6 +1529,9 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
return -EBUSY;
}

if (atomic_read(&priv->watchdog_event_pending))
return 0;

/*
* The TX queues are stopped at this point, so this test
* doesn't need to take ->tx_lock.
Expand All @@ -1548,6 +1553,14 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
spin_unlock_bh(&priv->tx_lock);
timeout = wait_for_completion_timeout(&tx_wait,
msecs_to_jiffies(MWL8K_TX_WAIT_TIMEOUT_MS));

if (atomic_read(&priv->watchdog_event_pending)) {
spin_lock_bh(&priv->tx_lock);
priv->tx_wait = NULL;
spin_unlock_bh(&priv->tx_lock);
return 0;
}

spin_lock_bh(&priv->tx_lock);

if (timeout) {
Expand Down Expand Up @@ -3645,6 +3658,7 @@ static void mwl8k_watchdog_ba_events(struct work_struct *work)

spin_unlock(&priv->stream_lock);
done:
atomic_dec(&priv->watchdog_event_pending);
status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
iowrite32((status | MWL8K_A2H_INT_BA_WATCHDOG),
priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
Expand Down Expand Up @@ -4346,6 +4360,10 @@ static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
}

if (status & MWL8K_A2H_INT_BA_WATCHDOG) {
iowrite32(~MWL8K_A2H_INT_BA_WATCHDOG,
priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);

atomic_inc(&priv->watchdog_event_pending);
status &= ~MWL8K_A2H_INT_BA_WATCHDOG;
ieee80211_queue_work(hw, &priv->watchdog_ba_handle);
}
Expand Down Expand Up @@ -5520,6 +5538,7 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw)
priv->sniffer_enabled = false;
priv->wmm_enabled = false;
priv->pending_tx_pkts = 0;
atomic_set(&priv->watchdog_event_pending, 0);

rc = mwl8k_rxq_init(hw, 0);
if (rc)
Expand Down

0 comments on commit c27a54d

Please sign in to comment.