/*
 * Copyright (c) 2008-2009 Atheros Communications Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <linux/slab.h>

#include "ath9k.h"

struct ath9k_vif_iter_data {
	const u8 *hw_macaddr;
	u8 mask[ETH_ALEN];
};

static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
{
	struct ath9k_vif_iter_data *iter_data = data;
	int i;

	for (i = 0; i < ETH_ALEN; i++)
		iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]);
}

void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
	struct ath9k_vif_iter_data iter_data;
	int i;

	/*
	 * Use the hardware MAC address as reference, the hardware uses it
	 * together with the BSSID mask when matching addresses.
	 */
	iter_data.hw_macaddr = common->macaddr;
	memset(&iter_data.mask, 0xff, ETH_ALEN);

	if (vif)
		ath9k_vif_iter(&iter_data, vif->addr, vif);

	/* Get list of all active MAC addresses */
	spin_lock_bh(&sc->wiphy_lock);
	ieee80211_iterate_active_interfaces_atomic(sc->hw, ath9k_vif_iter,
						   &iter_data);
	for (i = 0; i < sc->num_sec_wiphy; i++) {
		if (sc->sec_wiphy[i] == NULL)
			continue;
		ieee80211_iterate_active_interfaces_atomic(
			sc->sec_wiphy[i]->hw, ath9k_vif_iter, &iter_data);
	}
	spin_unlock_bh(&sc->wiphy_lock);

	memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);
	ath_hw_setbssidmask(common);
}

int ath9k_wiphy_add(struct ath_softc *sc)
{
	int i, error;
	struct ath_wiphy *aphy;
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
	struct ieee80211_hw *hw;
	u8 addr[ETH_ALEN];

	hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy), &ath9k_ops);
	if (hw == NULL)
		return -ENOMEM;

	spin_lock_bh(&sc->wiphy_lock);
	for (i = 0; i < sc->num_sec_wiphy; i++) {
		if (sc->sec_wiphy[i] == NULL)
			break;
	}

	if (i == sc->num_sec_wiphy) {
		/* No empty slot available; increase array length */
		struct ath_wiphy **n;
		n = krealloc(sc->sec_wiphy,
			     (sc->num_sec_wiphy + 1) *
			     sizeof(struct ath_wiphy *),
			     GFP_ATOMIC);
		if (n == NULL) {
			spin_unlock_bh(&sc->wiphy_lock);
			ieee80211_free_hw(hw);
			return -ENOMEM;
		}
		n[i] = NULL;
		sc->sec_wiphy = n;
		sc->num_sec_wiphy++;
	}

	SET_IEEE80211_DEV(hw, sc->dev);

	aphy = hw->priv;
	aphy->sc = sc;
	aphy->hw = hw;
	sc->sec_wiphy[i] = aphy;
	aphy->last_rssi = ATH_RSSI_DUMMY_MARKER;
	spin_unlock_bh(&sc->wiphy_lock);

	memcpy(addr, common->macaddr, ETH_ALEN);
	addr[0] |= 0x02; /* Locally managed address */
	/*
	 * XOR virtual wiphy index into the least significant bits to generate
	 * a different MAC address for each virtual wiphy.
	 */
	addr[5] ^= i & 0xff;
	addr[4] ^= (i & 0xff00) >> 8;
	addr[3] ^= (i & 0xff0000) >> 16;

	SET_IEEE80211_PERM_ADDR(hw, addr);

	ath9k_set_hw_capab(sc, hw);

	error = ieee80211_register_hw(hw);

	if (error == 0) {
		/* Make sure wiphy scheduler is started (if enabled) */
		ath9k_wiphy_set_scheduler(sc, sc->wiphy_scheduler_int);
	}

	return error;
}

int ath9k_wiphy_del(struct ath_wiphy *aphy)
{
	struct ath_softc *sc = aphy->sc;
	int i;

	spin_lock_bh(&sc->wiphy_lock);
	for (i = 0; i < sc->num_sec_wiphy; i++) {
		if (aphy == sc->sec_wiphy[i]) {
			sc->sec_wiphy[i] = NULL;
			spin_unlock_bh(&sc->wiphy_lock);
			ieee80211_unregister_hw(aphy->hw);
			ieee80211_free_hw(aphy->hw);
			return 0;
		}
	}
	spin_unlock_bh(&sc->wiphy_lock);
	return -ENOENT;
}

static int ath9k_send_nullfunc(struct ath_wiphy *aphy,
			       struct ieee80211_vif *vif, const u8 *bssid,
			       int ps)
{
	struct ath_softc *sc = aphy->sc;
	struct ath_tx_control txctl;
	struct sk_buff *skb;
	struct ieee80211_hdr *hdr;
	__le16 fc;
	struct ieee80211_tx_info *info;

	skb = dev_alloc_skb(24);
	if (skb == NULL)
		return -ENOMEM;
	hdr = (struct ieee80211_hdr *) skb_put(skb, 24);
	memset(hdr, 0, 24);
	fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
			 IEEE80211_FCTL_TODS);
	if (ps)
		fc |= cpu_to_le16(IEEE80211_FCTL_PM);
	hdr->frame_control = fc;
	memcpy(hdr->addr1, bssid, ETH_ALEN);
	memcpy(hdr->addr2, aphy->hw->wiphy->perm_addr, ETH_ALEN);
	memcpy(hdr->addr3, bssid, ETH_ALEN);

	info = IEEE80211_SKB_CB(skb);
	memset(info, 0, sizeof(*info));
	info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS;
	info->control.vif = vif;
	info->control.rates[0].idx = 0;
	info->control.rates[0].count = 4;
	info->control.rates[1].idx = -1;

	memset(&txctl, 0, sizeof(struct ath_tx_control));
	txctl.txq = sc->tx.txq_map[WME_AC_VO];
	txctl.frame_type = ps ? ATH9K_IFT_PAUSE : ATH9K_IFT_UNPAUSE;

	if (ath_tx_start(aphy->hw, skb, &txctl) != 0)
		goto exit;

	return 0;
exit:
	dev_kfree_skb_any(skb);
	return -1;
}

static bool __ath9k_wiphy_pausing(struct ath_softc *sc)
{
	int i;
	if (sc->pri_wiphy->state == ATH_WIPHY_PAUSING)
		return true;
	for (i = 0; i < sc->num_sec_wiphy; i++) {
		if (sc->sec_wiphy[i] &&
		    sc->sec_wiphy[i]->state == ATH_WIPHY_PAUSING)
			return true;
	}
	return false;
}

static bool ath9k_wiphy_pausing(struct ath_softc *sc)
{
	bool ret;
	spin_lock_bh(&sc->wiphy_lock);
	ret = __ath9k_wiphy_pausing(sc);
	spin_unlock_bh(&sc->wiphy_lock);
	return ret;
}

static bool __ath9k_wiphy_scanning(struct ath_softc *sc)
{
	int i;
	if (sc->pri_wiphy->state == ATH_WIPHY_SCAN)
		return true;
	for (i = 0; i < sc->num_sec_wiphy; i++) {
		if (sc->sec_wiphy[i] &&
		    sc->sec_wiphy[i]->state == ATH_WIPHY_SCAN)
			return true;
	}
	return false;
}

bool ath9k_wiphy_scanning(struct ath_softc *sc)
{
	bool ret;
	spin_lock_bh(&sc->wiphy_lock);
	ret = __ath9k_wiphy_scanning(sc);
	spin_unlock_bh(&sc->wiphy_lock);
	return ret;
}

static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy);

/* caller must hold wiphy_lock */
static void __ath9k_wiphy_unpause_ch(struct ath_wiphy *aphy)
{
	if (aphy == NULL)
		return;
	if (aphy->chan_idx != aphy->sc->chan_idx)
		return; /* wiphy not on the selected channel */
	__ath9k_wiphy_unpause(aphy);
}

static void ath9k_wiphy_unpause_channel(struct ath_softc *sc)
{
	int i;
	spin_lock_bh(&sc->wiphy_lock);
	__ath9k_wiphy_unpause_ch(sc->pri_wiphy);
	for (i = 0; i < sc->num_sec_wiphy; i++)
		__ath9k_wiphy_unpause_ch(sc->sec_wiphy[i]);
	spin_unlock_bh(&sc->wiphy_lock);
}

void ath9k_wiphy_chan_work(struct work_struct *work)
{
	struct ath_softc *sc = container_of(work, struct ath_softc, chan_work);
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
	struct ath_wiphy *aphy = sc->next_wiphy;

	if (aphy == NULL)
		return;

	/*
	 * All pending interfaces paused; ready to change
	 * channels.
	 */

	/* Change channels */
	mutex_lock(&sc->mutex);
	/* XXX: remove me eventually */
	ath9k_update_ichannel(sc, aphy->hw,
			      &sc->sc_ah->channels[sc->chan_idx]);

	/* sync hw configuration for hw code */
	common->hw = aphy->hw;

	if (ath_set_channel(sc, aphy->hw,
			    &sc->sc_ah->channels[sc->chan_idx]) < 0) {
		printk(KERN_DEBUG "ath9k: Failed to set channel for new "
		       "virtual wiphy\n");
		mutex_unlock(&sc->mutex);
		return;
	}
	mutex_unlock(&sc->mutex);

	ath9k_wiphy_unpause_channel(sc);
}

/*
 * ath9k version of ieee80211_tx_status() for TX frames that are generated
 * internally in the driver.
 */
void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, int ftype)
{
	struct ath_wiphy *aphy = hw->priv;
	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);

	if (ftype == ATH9K_IFT_PAUSE && aphy->state == ATH_WIPHY_PAUSING) {
		if (!(tx_info->flags & IEEE80211_TX_STAT_ACK)) {
			printk(KERN_DEBUG "ath9k: %s: no ACK for pause "
			       "frame\n", wiphy_name(hw->wiphy));
			/*
			 * The AP did not reply; ignore this to allow us to
			 * continue.
			 */
		}
		aphy->state = ATH_WIPHY_PAUSED;
		if (!ath9k_wiphy_pausing(aphy->sc)) {
			/*
			 * Drop from tasklet to work to allow mutex for channel
			 * change.
			 */
			ieee80211_queue_work(aphy->sc->hw,
				   &aphy->sc->chan_work);
		}
	}

	dev_kfree_skb(skb);
}

static void ath9k_mark_paused(struct ath_wiphy *aphy)
{
	struct ath_softc *sc = aphy->sc;
	aphy->state = ATH_WIPHY_PAUSED;
	if (!__ath9k_wiphy_pausing(sc))
		ieee80211_queue_work(sc->hw, &sc->chan_work);
}

static void ath9k_pause_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
{
	struct ath_wiphy *aphy = data;
	struct ath_vif *avp = (void *) vif->drv_priv;

	switch (vif->type) {
	case NL80211_IFTYPE_STATION:
		if (!vif->bss_conf.assoc) {
			ath9k_mark_paused(aphy);
			break;
		}
		/* TODO: could avoid this if already in PS mode */
		if (ath9k_send_nullfunc(aphy, vif, avp->bssid, 1)) {
			printk(KERN_DEBUG "%s: failed to send PS nullfunc\n",
			       __func__);
			ath9k_mark_paused(aphy);
		}
		break;
	case NL80211_IFTYPE_AP:
		/* Beacon transmission is paused by aphy->state change */
		ath9k_mark_paused(aphy);
		break;
	default:
		break;
	}
}

/* caller must hold wiphy_lock */
static int __ath9k_wiphy_pause(struct ath_wiphy *aphy)
{
	ieee80211_stop_queues(aphy->hw);
	aphy->state = ATH_WIPHY_PAUSING;
	/*
	 * TODO: handle PAUSING->PAUSED for the case where there are multiple
	 * active vifs (now we do it on the first vif getting ready; should be
	 * on the last)
	 */
	ieee80211_iterate_active_interfaces_atomic(aphy->hw, ath9k_pause_iter,
						   aphy);
	return 0;
}

int ath9k_wiphy_pause(struct ath_wiphy *aphy)
{
	int ret;
	spin_lock_bh(&aphy->sc->wiphy_lock);
	ret = __ath9k_wiphy_pause(aphy);
	spin_unlock_bh(&aphy->sc->wiphy_lock);
	return ret;
}

static void ath9k_unpause_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
{
	struct ath_wiphy *aphy = data;
	struct ath_vif *avp = (void *) vif->drv_priv;

	switch (vif->type) {
	case NL80211_IFTYPE_STATION:
		if (!vif->bss_conf.assoc)
			break;
		ath9k_send_nullfunc(aphy, vif, avp->bssid, 0);
		break;
	case NL80211_IFTYPE_AP:
		/* Beacon transmission is re-enabled by aphy->state change */
		break;
	default:
		break;
	}
}

/* caller must hold wiphy_lock */
static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy)
{
	ieee80211_iterate_active_interfaces_atomic(aphy->hw,
						   ath9k_unpause_iter, aphy);
	aphy->state = ATH_WIPHY_ACTIVE;
	ieee80211_wake_queues(aphy->hw);
	return 0;
}

int ath9k_wiphy_unpause(struct ath_wiphy *aphy)
{
	int ret;
	spin_lock_bh(&aphy->sc->wiphy_lock);
	ret = __ath9k_wiphy_unpause(aphy);
	spin_unlock_bh(&aphy->sc->wiphy_lock);
	return ret;
}

static void __ath9k_wiphy_mark_all_paused(struct ath_softc *sc)
{
	int i;
	if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE)
		sc->pri_wiphy->state = ATH_WIPHY_PAUSED;
	for (i = 0; i < sc->num_sec_wiphy; i++) {
		if (sc->sec_wiphy[i] &&
		    sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE)
			sc->sec_wiphy[i]->state = ATH_WIPHY_PAUSED;
	}
}

/* caller must hold wiphy_lock */
static void __ath9k_wiphy_pause_all(struct ath_softc *sc)
{
	int i;
	if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE)
		__ath9k_wiphy_pause(sc->pri_wiphy);
	for (i = 0; i < sc->num_sec_wiphy; i++) {
		if (sc->sec_wiphy[i] &&
		    sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE)
			__ath9k_wiphy_pause(sc->sec_wiphy[i]);
	}
}

int ath9k_wiphy_select(struct ath_wiphy *aphy)
{
	struct ath_softc *sc = aphy->sc;
	bool now;

	spin_lock_bh(&sc->wiphy_lock);
	if (__ath9k_wiphy_scanning(sc)) {
		/*
		 * For now, we are using mac80211 sw scan and it expects to
		 * have full control over channel changes, so avoid wiphy
		 * scheduling during a scan. This could be optimized if the
		 * scanning control were moved into the driver.
		 */
		spin_unlock_bh(&sc->wiphy_lock);
		return -EBUSY;
	}
	if (__ath9k_wiphy_pausing(sc)) {
		if (sc->wiphy_select_failures == 0)
			sc->wiphy_select_first_fail = jiffies;
		sc->wiphy_select_failures++;
		if (time_after(jiffies, sc->wiphy_select_first_fail + HZ / 2))
		{
			printk(KERN_DEBUG "ath9k: Previous wiphy select timed "
			       "out; disable/enable hw to recover\n");
			__ath9k_wiphy_mark_all_paused(sc);
			/*
			 * TODO: this workaround to fix hardware is unlikely to
			 * be specific to virtual wiphy changes. It can happen
			 * on normal channel change, too, and as such, this
			 * should really be made more generic. For example,
			 * tricker radio disable/enable on GTT interrupt burst
			 * (say, 10 GTT interrupts received without any TX
			 * frame being completed)
			 */
			spin_unlock_bh(&sc->wiphy_lock);
			ath_radio_disable(sc, aphy->hw);
			ath_radio_enable(sc, aphy->hw);
			/* Only the primary wiphy hw is used for queuing work */
			ieee80211_queue_work(aphy->sc->hw,
				   &aphy->sc->chan_work);
			return -EBUSY; /* previous select still in progress */
		}
		spin_unlock_bh(&sc->wiphy_lock);
		return -EBUSY; /* previous select still in progress */
	}
	sc->wiphy_select_failures = 0;

	/* Store the new channel */
	sc->chan_idx = aphy->chan_idx;
	sc->chan_is_ht = aphy->chan_is_ht;
	sc->next_wiphy = aphy;

	__ath9k_wiphy_pause_all(sc);
	now = !__ath9k_wiphy_pausing(aphy->sc);
	spin_unlock_bh(&sc->wiphy_lock);

	if (now) {
		/* Ready to request channel change immediately */
		ieee80211_queue_work(aphy->sc->hw, &aphy->sc->chan_work);
	}

	/*
	 * wiphys will be unpaused in ath9k_tx_status() once channel has been
	 * changed if any wiphy needs time to become paused.
	 */

	return 0;
}

bool ath9k_wiphy_started(struct ath_softc *sc)
{
	int i;
	spin_lock_bh(&sc->wiphy_lock);
	if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) {
		spin_unlock_bh(&sc->wiphy_lock);
		return true;
	}
	for (i = 0; i < sc->num_sec_wiphy; i++) {
		if (sc->sec_wiphy[i] &&
		    sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE) {
			spin_unlock_bh(&sc->wiphy_lock);
			return true;
		}
	}
	spin_unlock_bh(&sc->wiphy_lock);
	return false;
}

static void ath9k_wiphy_pause_chan(struct ath_wiphy *aphy,
				   struct ath_wiphy *selected)
{
	if (selected->state == ATH_WIPHY_SCAN) {
		if (aphy == selected)
			return;
		/*
		 * Pause all other wiphys for the duration of the scan even if
		 * they are on the current channel now.
		 */
	} else if (aphy->chan_idx == selected->chan_idx)
		return;
	aphy->state = ATH_WIPHY_PAUSED;
	ieee80211_stop_queues(aphy->hw);
}

void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
				  struct ath_wiphy *selected)
{
	int i;
	spin_lock_bh(&sc->wiphy_lock);
	if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE)
		ath9k_wiphy_pause_chan(sc->pri_wiphy, selected);
	for (i = 0; i < sc->num_sec_wiphy; i++) {
		if (sc->sec_wiphy[i] &&
		    sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE)
			ath9k_wiphy_pause_chan(sc->sec_wiphy[i], selected);
	}
	spin_unlock_bh(&sc->wiphy_lock);
}

void ath9k_wiphy_work(struct work_struct *work)
{
	struct ath_softc *sc = container_of(work, struct ath_softc,
					    wiphy_work.work);
	struct ath_wiphy *aphy = NULL;
	bool first = true;

	spin_lock_bh(&sc->wiphy_lock);

	if (sc->wiphy_scheduler_int == 0) {
		/* wiphy scheduler is disabled */
		spin_unlock_bh(&sc->wiphy_lock);
		return;
	}

try_again:
	sc->wiphy_scheduler_index++;
	while (sc->wiphy_scheduler_index <= sc->num_sec_wiphy) {
		aphy = sc->sec_wiphy[sc->wiphy_scheduler_index - 1];
		if (aphy && aphy->state != ATH_WIPHY_INACTIVE)
			break;

		sc->wiphy_scheduler_index++;
		aphy = NULL;
	}
	if (aphy == NULL) {
		sc->wiphy_scheduler_index = 0;
		if (sc->pri_wiphy->state == ATH_WIPHY_INACTIVE) {
			if (first) {
				first = false;
				goto try_again;
			}
			/* No wiphy is ready to be scheduled */
		} else
			aphy = sc->pri_wiphy;
	}

	spin_unlock_bh(&sc->wiphy_lock);

	if (aphy &&
	    aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN &&
	    ath9k_wiphy_select(aphy)) {
		printk(KERN_DEBUG "ath9k: Failed to schedule virtual wiphy "
		       "change\n");
	}

	ieee80211_queue_delayed_work(sc->hw,
				     &sc->wiphy_work,
				     sc->wiphy_scheduler_int);
}

void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int)
{
	cancel_delayed_work_sync(&sc->wiphy_work);
	sc->wiphy_scheduler_int = msecs_to_jiffies(msec_int);
	if (sc->wiphy_scheduler_int)
		ieee80211_queue_delayed_work(sc->hw, &sc->wiphy_work,
					     sc->wiphy_scheduler_int);
}

/* caller must hold wiphy_lock */
bool ath9k_all_wiphys_idle(struct ath_softc *sc)
{
	unsigned int i;
	if (!sc->pri_wiphy->idle)
		return false;
	for (i = 0; i < sc->num_sec_wiphy; i++) {
		struct ath_wiphy *aphy = sc->sec_wiphy[i];
		if (!aphy)
			continue;
		if (!aphy->idle)
			return false;
	}
	return true;
}

/* caller must hold wiphy_lock */
void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle)
{
	struct ath_softc *sc = aphy->sc;

	aphy->idle = idle;
	ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
		"Marking %s as %sidle\n",
		wiphy_name(aphy->hw->wiphy), idle ? "" : "not-");
}
/* Only bother starting a queue on an active virtual wiphy */
bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue)
{
	struct ieee80211_hw *hw = sc->pri_wiphy->hw;
	unsigned int i;
	bool txq_started = false;

	spin_lock_bh(&sc->wiphy_lock);

	/* Start the primary wiphy */
	if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) {
		ieee80211_wake_queue(hw, skb_queue);
		txq_started = true;
		goto unlock;
	}

	/* Now start the secondary wiphy queues */
	for (i = 0; i < sc->num_sec_wiphy; i++) {
		struct ath_wiphy *aphy = sc->sec_wiphy[i];
		if (!aphy)
			continue;
		if (aphy->state != ATH_WIPHY_ACTIVE)
			continue;

		hw = aphy->hw;
		ieee80211_wake_queue(hw, skb_queue);
		txq_started = true;
		break;
	}

unlock:
	spin_unlock_bh(&sc->wiphy_lock);
	return txq_started;
}

/* Go ahead and propagate information to all virtual wiphys, it won't hurt */
void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue)
{
	struct ieee80211_hw *hw = sc->pri_wiphy->hw;
	unsigned int i;

	spin_lock_bh(&sc->wiphy_lock);

	/* Stop the primary wiphy */
	ieee80211_stop_queue(hw, skb_queue);

	/* Now stop the secondary wiphy queues */
	for (i = 0; i < sc->num_sec_wiphy; i++) {
		struct ath_wiphy *aphy = sc->sec_wiphy[i];
		if (!aphy)
			continue;
		hw = aphy->hw;
		ieee80211_stop_queue(hw, skb_queue);
	}
	spin_unlock_bh(&sc->wiphy_lock);
}
