Currently we didn't check if there are still pending frames Signed-off-by: Christian Lamparter <chunkeey@xxxxxx> --- diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index a66aa7d..8c8f45b 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c @@ -1299,6 +1299,37 @@ static void ar9170_op_remove_interface(struct ieee80211_hw *hw, mutex_unlock(&ar->mutex); } +static int ar9170_stop_and_flush_queues(struct ar9170 *ar) +{ + int err; + + ieee80211_stop_queues(ar->hw); + + err = ar->flush(ar); + if (err) { + printk(KERN_ERR "%s: device is not responding (%d)!\n", + wiphy_name(ar->hw->wiphy), err); + + /* FIXME: purge tx_status queues and reset */ + } + + return err; +} + +static void ar9170_wake_queues(struct ar9170 *ar) +{ + unsigned long flags; + unsigned int i; + + spin_lock_irqsave(&ar->tx_stats_lock, flags); + for (i = 0; i < __AR9170_NUM_TXQ; i++) { + if ((ar->tx_stats[i].len < ar->tx_stats[i].limit) && + (ieee80211_queue_stopped(ar->hw, i))) + ieee80211_wake_queue(ar->hw, i); + } + spin_unlock_irqrestore(&ar->tx_stats_lock, flags); +} + static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed) { struct ar9170 *ar = hw->priv; @@ -1344,6 +1375,9 @@ static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed) } if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { + err = ar9170_stop_and_flush_queues(ar); + if (err) + goto out; /* adjust slot time for 5 GHz */ err = ar9170_set_slot_time(ar); @@ -1359,10 +1393,12 @@ static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed) nl80211_to_ar9170(hw->conf.channel_type)); if (err) goto out; + } out: mutex_unlock(&ar->mutex); + ar9170_wake_queues(ar); return err; } -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html