/*
 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
 *
 * Permission to use, copy, modify, and 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.
 *
 */

/********************************************\
Queue Control Unit, DCF Control Unit Functions
\********************************************/

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include "ath5k.h"
#include "reg.h"
#include "debug.h"
#include <linux/log2.h>

/**
 * DOC: Queue Control Unit (QCU)/DCF Control Unit (DCU) functions
 *
 * Here we setup parameters for the 12 available TX queues. Note that
 * on the various registers we can usually only map the first 10 of them so
 * basically we have 10 queues to play with. Each queue has a matching
 * QCU that controls when the queue will get triggered and multiple QCUs
 * can be mapped to a single DCU that controls the various DFS parameters
 * for the various queues. In our setup we have a 1:1 mapping between QCUs
 * and DCUs allowing us to have different DFS settings for each queue.
 *
 * When a frame goes into a TX queue, QCU decides when it'll trigger a
 * transmission based on various criteria (such as how many data we have inside
 * it's buffer or -if it's a beacon queue- if it's time to fire up the queue
 * based on TSF etc), DCU adds backoff, IFSes etc and then a scheduler
 * (arbitrator) decides the priority of each QCU based on it's configuration
 * (e.g. beacons are always transmitted when they leave DCU bypassing all other
 * frames from other queues waiting to be transmitted). After a frame leaves
 * the DCU it goes to PCU for further processing and then to PHY for
 * the actual transmission.
 */


/******************\
* Helper functions *
\******************/

/**
 * ath5k_hw_num_tx_pending() - Get number of pending frames for a  given queue
 * @ah: The &struct ath5k_hw
 * @queue: One of enum ath5k_tx_queue_id
 */
u32
ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
{
	u32 pending;
	AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);

	/* Return if queue is declared inactive */
	if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
		return false;

	/* XXX: How about AR5K_CFG_TXCNT ? */
	if (ah->ah_version == AR5K_AR5210)
		return false;

	pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue));
	pending &= AR5K_QCU_STS_FRMPENDCNT;

	/* It's possible to have no frames pending even if TXE
	 * is set. To indicate that q has not stopped return
	 * true */
	if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
		return true;

	return pending;
}

/**
 * ath5k_hw_release_tx_queue() - Set a transmit queue inactive
 * @ah: The &struct ath5k_hw
 * @queue: One of enum ath5k_tx_queue_id
 */
void
ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
{
	if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
		return;

	/* This queue will be skipped in further operations */
	ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
	/*For SIMR setup*/
	AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
}

/**
 * ath5k_cw_validate() - Make sure the given cw is valid
 * @cw_req: The contention window value to check
 *
 * Make sure cw is a power of 2 minus 1 and smaller than 1024
 */
static u16
ath5k_cw_validate(u16 cw_req)
{
	cw_req = min(cw_req, (u16)1023);

	/* Check if cw_req + 1 a power of 2 */
	if (is_power_of_2(cw_req + 1))
		return cw_req;

	/* Check if cw_req is a power of 2 */
	if (is_power_of_2(cw_req))
		return cw_req - 1;

	/* If none of the above is correct
	 * find the closest power of 2 */
	cw_req = (u16) roundup_pow_of_two(cw_req) - 1;

	return cw_req;
}

/**
 * ath5k_hw_get_tx_queueprops() - Get properties for a transmit queue
 * @ah: The &struct ath5k_hw
 * @queue: One of enum ath5k_tx_queue_id
 * @queue_info: The &struct ath5k_txq_info to fill
 */
int
ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
		struct ath5k_txq_info *queue_info)
{
	memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
	return 0;
}

/**
 * ath5k_hw_set_tx_queueprops() - Set properties for a transmit queue
 * @ah: The &struct ath5k_hw
 * @queue: One of enum ath5k_tx_queue_id
 * @qinfo: The &struct ath5k_txq_info to use
 *
 * Returns 0 on success or -EIO if queue is inactive
 */
int
ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
				const struct ath5k_txq_info *qinfo)
{
	struct ath5k_txq_info *qi;

	AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);

	qi = &ah->ah_txq[queue];

	if (qi->tqi_type == AR5K_TX_QUEUE_INACTIVE)
		return -EIO;

	/* copy and validate values */
	qi->tqi_type = qinfo->tqi_type;
	qi->tqi_subtype = qinfo->tqi_subtype;
	qi->tqi_flags = qinfo->tqi_flags;
	/*
	 * According to the docs: Although the AIFS field is 8 bit wide,
	 * the maximum supported value is 0xFC. Setting it higher than that
	 * will cause the DCU to hang.
	 */
	qi->tqi_aifs = min(qinfo->tqi_aifs, (u8)0xFC);
	qi->tqi_cw_min = ath5k_cw_validate(qinfo->tqi_cw_min);
	qi->tqi_cw_max = ath5k_cw_validate(qinfo->tqi_cw_max);
	qi->tqi_cbr_period = qinfo->tqi_cbr_period;
	qi->tqi_cbr_overflow_limit = qinfo->tqi_cbr_overflow_limit;
	qi->tqi_burst_time = qinfo->tqi_burst_time;
	qi->tqi_ready_time = qinfo->tqi_ready_time;

	/*XXX: Is this supported on 5210 ?*/
	/*XXX: Is this correct for AR5K_WME_AC_VI,VO ???*/
	if ((qinfo->tqi_type == AR5K_TX_QUEUE_DATA &&
		((qinfo->tqi_subtype == AR5K_WME_AC_VI) ||
		 (qinfo->tqi_subtype == AR5K_WME_AC_VO))) ||
	     qinfo->tqi_type == AR5K_TX_QUEUE_UAPSD)
		qi->tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;

	return 0;
}

/**
 * ath5k_hw_setup_tx_queue() - Initialize a transmit queue
 * @ah: The &struct ath5k_hw
 * @queue_type: One of enum ath5k_tx_queue
 * @queue_info: The &struct ath5k_txq_info to use
 *
 * Returns 0 on success, -EINVAL on invalid arguments
 */
int
ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
		struct ath5k_txq_info *queue_info)
{
	unsigned int queue;
	int ret;

	/*
	 * Get queue by type
	 */
	/* 5210 only has 2 queues */
	if (ah->ah_capabilities.cap_queues.q_tx_num == 2) {
		switch (queue_type) {
		case AR5K_TX_QUEUE_DATA:
			queue = AR5K_TX_QUEUE_ID_NOQCU_DATA;
			break;
		case AR5K_TX_QUEUE_BEACON:
		case AR5K_TX_QUEUE_CAB:
			queue = AR5K_TX_QUEUE_ID_NOQCU_BEACON;
			break;
		default:
			return -EINVAL;
		}
	} else {
		switch (queue_type) {
		case AR5K_TX_QUEUE_DATA:
			queue = queue_info->tqi_subtype;
			break;
		case AR5K_TX_QUEUE_UAPSD:
			queue = AR5K_TX_QUEUE_ID_UAPSD;
			break;
		case AR5K_TX_QUEUE_BEACON:
			queue = AR5K_TX_QUEUE_ID_BEACON;
			break;
		case AR5K_TX_QUEUE_CAB:
			queue = AR5K_TX_QUEUE_ID_CAB;
			break;
		default:
			return -EINVAL;
		}
	}

	/*
	 * Setup internal queue structure
	 */
	memset(&ah->ah_txq[queue], 0, sizeof(struct ath5k_txq_info));
	ah->ah_txq[queue].tqi_type = queue_type;

	if (queue_info != NULL) {
		queue_info->tqi_type = queue_type;
		ret = ath5k_hw_set_tx_queueprops(ah, queue, queue_info);
		if (ret)
			return ret;
	}

	/*
	 * We use ah_txq_status to hold a temp value for
	 * the Secondary interrupt mask registers on 5211+
	 * check out ath5k_hw_reset_tx_queue
	 */
	AR5K_Q_ENABLE_BITS(ah->ah_txq_status, queue);

	return queue;
}


/*******************************\
* Single QCU/DCU initialization *
\*******************************/

/**
 * ath5k_hw_set_tx_retry_limits() - Set tx retry limits on DCU
 * @ah: The &struct ath5k_hw
 * @queue: One of enum ath5k_tx_queue_id
 *
 * This function is used when initializing a queue, to set
 * retry limits based on ah->ah_retry_* and the chipset used.
 */
void
ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah,
				  unsigned int queue)
{
	/* Single data queue on AR5210 */
	if (ah->ah_version == AR5K_AR5210) {
		struct ath5k_txq_info *tq = &ah->ah_txq[queue];

		if (queue > 0)
			return;

		ath5k_hw_reg_write(ah,
			(tq->tqi_cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
			| AR5K_REG_SM(ah->ah_retry_long,
				      AR5K_NODCU_RETRY_LMT_SLG_RETRY)
			| AR5K_REG_SM(ah->ah_retry_short,
				      AR5K_NODCU_RETRY_LMT_SSH_RETRY)
			| AR5K_REG_SM(ah->ah_retry_long,
				      AR5K_NODCU_RETRY_LMT_LG_RETRY)
			| AR5K_REG_SM(ah->ah_retry_short,
				      AR5K_NODCU_RETRY_LMT_SH_RETRY),
			AR5K_NODCU_RETRY_LMT);
	/* DCU on AR5211+ */
	} else {
		ath5k_hw_reg_write(ah,
			AR5K_REG_SM(ah->ah_retry_long,
				    AR5K_DCU_RETRY_LMT_RTS)
			| AR5K_REG_SM(ah->ah_retry_long,
				      AR5K_DCU_RETRY_LMT_STA_RTS)
			| AR5K_REG_SM(max(ah->ah_retry_long, ah->ah_retry_short),
				      AR5K_DCU_RETRY_LMT_STA_DATA),
			AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
	}
}

/**
 * ath5k_hw_reset_tx_queue() - Initialize a single hw queue
 * @ah: The &struct ath5k_hw
 * @queue: One of enum ath5k_tx_queue_id
 *
 * Set DCF properties for the given transmit queue on DCU
 * and configures all queue-specific parameters.
 */
int
ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
{
	struct ath5k_txq_info *tq = &ah->ah_txq[queue];

	AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);

	tq = &ah->ah_txq[queue];

	/* Skip if queue inactive or if we are on AR5210
	 * that doesn't have QCU/DCU */
	if ((ah->ah_version == AR5K_AR5210) ||
	(tq->tqi_type == AR5K_TX_QUEUE_INACTIVE))
		return 0;

	/*
	 * Set contention window (cw_min/cw_max)
	 * and arbitrated interframe space (aifs)...
	 */
	ath5k_hw_reg_write(ah,
		AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
		AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
		AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS),
		AR5K_QUEUE_DFS_LOCAL_IFS(queue));

	/*
	 * Set tx retry limits for this queue
	 */
	ath5k_hw_set_tx_retry_limits(ah, queue);


	/*
	 * Set misc registers
	 */

	/* Enable DCU to wait for next fragment from QCU */
	AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
				AR5K_DCU_MISC_FRAG_WAIT);

	/* On Maui and Spirit use the global seqnum on DCU */
	if (ah->ah_mac_version < AR5K_SREV_AR5211)
		AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
					AR5K_DCU_MISC_SEQNUM_CTL);

	/* Constant bit rate period */
	if (tq->tqi_cbr_period) {
		ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
					AR5K_QCU_CBRCFG_INTVAL) |
					AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
					AR5K_QCU_CBRCFG_ORN_THRES),
					AR5K_QUEUE_CBRCFG(queue));

		AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
					AR5K_QCU_MISC_FRSHED_CBR);

		if (tq->tqi_cbr_overflow_limit)
			AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
					AR5K_QCU_MISC_CBR_THRES_ENABLE);
	}

	/* Ready time interval */
	if (tq->tqi_ready_time && (tq->tqi_type != AR5K_TX_QUEUE_CAB))
		ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
					AR5K_QCU_RDYTIMECFG_INTVAL) |
					AR5K_QCU_RDYTIMECFG_ENABLE,
					AR5K_QUEUE_RDYTIMECFG(queue));

	if (tq->tqi_burst_time) {
		ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
					AR5K_DCU_CHAN_TIME_DUR) |
					AR5K_DCU_CHAN_TIME_ENABLE,
					AR5K_QUEUE_DFS_CHANNEL_TIME(queue));

		if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
			AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
					AR5K_QCU_MISC_RDY_VEOL_POLICY);
	}

	/* Enable/disable Post frame backoff */
	if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
		ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
					AR5K_QUEUE_DFS_MISC(queue));

	/* Enable/disable fragmentation burst backoff */
	if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
		ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
					AR5K_QUEUE_DFS_MISC(queue));

	/*
	 * Set registers by queue type
	 */
	switch (tq->tqi_type) {
	case AR5K_TX_QUEUE_BEACON:
		AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
				AR5K_QCU_MISC_FRSHED_DBA_GT |
				AR5K_QCU_MISC_CBREXP_BCN_DIS |
				AR5K_QCU_MISC_BCN_ENABLE);

		AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
				(AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
				AR5K_DCU_MISC_ARBLOCK_CTL_S) |
				AR5K_DCU_MISC_ARBLOCK_IGNORE |
				AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
				AR5K_DCU_MISC_BCN_ENABLE);
		break;

	case AR5K_TX_QUEUE_CAB:
		/* XXX: use BCN_SENT_GT, if we can figure out how */
		AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
					AR5K_QCU_MISC_FRSHED_DBA_GT |
					AR5K_QCU_MISC_CBREXP_DIS |
					AR5K_QCU_MISC_CBREXP_BCN_DIS);

		ath5k_hw_reg_write(ah, ((tq->tqi_ready_time -
					(AR5K_TUNE_SW_BEACON_RESP -
					AR5K_TUNE_DMA_BEACON_RESP) -
				AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
					AR5K_QCU_RDYTIMECFG_ENABLE,
					AR5K_QUEUE_RDYTIMECFG(queue));

		AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
					(AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
					AR5K_DCU_MISC_ARBLOCK_CTL_S));
		break;

	case AR5K_TX_QUEUE_UAPSD:
		AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
					AR5K_QCU_MISC_CBREXP_DIS);
		break;

	case AR5K_TX_QUEUE_DATA:
	default:
			break;
	}

	/* TODO: Handle frame compression */

	/*
	 * Enable interrupts for this tx queue
	 * in the secondary interrupt mask registers
	 */
	if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
		AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);

	if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
		AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);

	if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
		AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);

	if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
		AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);

	if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
		AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);

	if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)
		AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);

	if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)
		AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);

	if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)
		AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);

	if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)
		AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);

	/* Update secondary interrupt mask registers */

	/* Filter out inactive queues */
	ah->ah_txq_imr_txok &= ah->ah_txq_status;
	ah->ah_txq_imr_txerr &= ah->ah_txq_status;
	ah->ah_txq_imr_txurn &= ah->ah_txq_status;
	ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
	ah->ah_txq_imr_txeol &= ah->ah_txq_status;
	ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;
	ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;
	ah->ah_txq_imr_qtrig &= ah->ah_txq_status;
	ah->ah_txq_imr_nofrm &= ah->ah_txq_status;

	ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
					AR5K_SIMR0_QCU_TXOK) |
					AR5K_REG_SM(ah->ah_txq_imr_txdesc,
					AR5K_SIMR0_QCU_TXDESC),
					AR5K_SIMR0);

	ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
					AR5K_SIMR1_QCU_TXERR) |
					AR5K_REG_SM(ah->ah_txq_imr_txeol,
					AR5K_SIMR1_QCU_TXEOL),
					AR5K_SIMR1);

	/* Update SIMR2 but don't overwrite rest simr2 settings */
	AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);
	AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,
				AR5K_REG_SM(ah->ah_txq_imr_txurn,
				AR5K_SIMR2_QCU_TXURN));

	ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,
				AR5K_SIMR3_QCBRORN) |
				AR5K_REG_SM(ah->ah_txq_imr_cbrurn,
				AR5K_SIMR3_QCBRURN),
				AR5K_SIMR3);

	ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,
				AR5K_SIMR4_QTRIG), AR5K_SIMR4);

	/* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */
	ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,
				AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);

	/* No queue has TXNOFRM enabled, disable the interrupt
	 * by setting AR5K_TXNOFRM to zero */
	if (ah->ah_txq_imr_nofrm == 0)
		ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);

	/* Set QCU mask for this DCU to save power */
	AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);

	return 0;
}


/**************************\
* Global QCU/DCU functions *
\**************************/

/**
 * ath5k_hw_set_ifs_intervals()  - Set global inter-frame spaces on DCU
 * @ah: The &struct ath5k_hw
 * @slot_time: Slot time in us
 *
 * Sets the global IFS intervals on DCU (also works on AR5210) for
 * the given slot time and the current bwmode.
 */
int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
{
	struct ieee80211_channel *channel = ah->ah_current_channel;
	enum nl80211_band band;
	struct ieee80211_supported_band *sband;
	struct ieee80211_rate *rate;
	u32 ack_tx_time, eifs, eifs_clock, sifs, sifs_clock;
	u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time);
	u32 rate_flags, i;

	if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX)
		return -EINVAL;

	sifs = ath5k_hw_get_default_sifs(ah);
	sifs_clock = ath5k_hw_htoclock(ah, sifs - 2);

	/* EIFS
	 * Txtime of ack at lowest rate + SIFS + DIFS
	 * (DIFS = SIFS + 2 * Slot time)
	 *
	 * Note: HAL has some predefined values for EIFS
	 * Turbo:   (37 + 2 * 6)
	 * Default: (74 + 2 * 9)
	 * Half:    (149 + 2 * 13)
	 * Quarter: (298 + 2 * 21)
	 *
	 * (74 + 2 * 6) for AR5210 default and turbo !
	 *
	 * According to the formula we have
	 * ack_tx_time = 25 for turbo and
	 * ack_tx_time = 42.5 * clock multiplier
	 * for default/half/quarter.
	 *
	 * This can't be right, 42 is what we would get
	 * from ath5k_hw_get_frame_dur_for_bwmode or
	 * ieee80211_generic_frame_duration for zero frame
	 * length and without SIFS !
	 *
	 * Also we have different lowest rate for 802.11a
	 */
	if (channel->band == NL80211_BAND_5GHZ)
		band = NL80211_BAND_5GHZ;
	else
		band = NL80211_BAND_2GHZ;

	switch (ah->ah_bwmode) {
	case AR5K_BWMODE_5MHZ:
		rate_flags = IEEE80211_RATE_SUPPORTS_5MHZ;
		break;
	case AR5K_BWMODE_10MHZ:
		rate_flags = IEEE80211_RATE_SUPPORTS_10MHZ;
		break;
	default:
		rate_flags = 0;
		break;
	}
	sband = &ah->sbands[band];
	rate = NULL;
	for (i = 0; i < sband->n_bitrates; i++) {
		if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
			continue;
		rate = &sband->bitrates[i];
		break;
	}
	if (WARN_ON(!rate))
		return -EINVAL;

	ack_tx_time = ath5k_hw_get_frame_duration(ah, band, 10, rate, false);

	/* ack_tx_time includes an SIFS already */
	eifs = ack_tx_time + sifs + 2 * slot_time;
	eifs_clock = ath5k_hw_htoclock(ah, eifs);

	/* Set IFS settings on AR5210 */
	if (ah->ah_version == AR5K_AR5210) {
		u32 pifs, pifs_clock, difs, difs_clock;

		/* Set slot time */
		ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME);

		/* Set EIFS */
		eifs_clock = AR5K_REG_SM(eifs_clock, AR5K_IFS1_EIFS);

		/* PIFS = Slot time + SIFS */
		pifs = slot_time + sifs;
		pifs_clock = ath5k_hw_htoclock(ah, pifs);
		pifs_clock = AR5K_REG_SM(pifs_clock, AR5K_IFS1_PIFS);

		/* DIFS = SIFS + 2 * Slot time */
		difs = sifs + 2 * slot_time;
		difs_clock = ath5k_hw_htoclock(ah, difs);

		/* Set SIFS/DIFS */
		ath5k_hw_reg_write(ah, (difs_clock <<
				AR5K_IFS0_DIFS_S) | sifs_clock,
				AR5K_IFS0);

		/* Set PIFS/EIFS and preserve AR5K_INIT_CARR_SENSE_EN */
		ath5k_hw_reg_write(ah, pifs_clock | eifs_clock |
				(AR5K_INIT_CARR_SENSE_EN << AR5K_IFS1_CS_EN_S),
				AR5K_IFS1);

		return 0;
	}

	/* Set IFS slot time */
	ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT);

	/* Set EIFS interval */
	ath5k_hw_reg_write(ah, eifs_clock, AR5K_DCU_GBL_IFS_EIFS);

	/* Set SIFS interval in usecs */
	AR5K_REG_WRITE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,
				AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC,
				sifs);

	/* Set SIFS interval in clock cycles */
	ath5k_hw_reg_write(ah, sifs_clock, AR5K_DCU_GBL_IFS_SIFS);

	return 0;
}


/**
 * ath5k_hw_init_queues() - Initialize tx queues
 * @ah: The &struct ath5k_hw
 *
 * Initializes all tx queues based on information on
 * ah->ah_txq* set by the driver
 */
int
ath5k_hw_init_queues(struct ath5k_hw *ah)
{
	int i, ret;

	/* TODO: HW Compression support for data queues */
	/* TODO: Burst prefetch for data queues */

	/*
	 * Reset queues and start beacon timers at the end of the reset routine
	 * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping
	 * Note: If we want we can assign multiple qcus on one dcu.
	 */
	if (ah->ah_version != AR5K_AR5210)
		for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
			ret = ath5k_hw_reset_tx_queue(ah, i);
			if (ret) {
				ATH5K_ERR(ah,
					"failed to reset TX queue #%d\n", i);
				return ret;
			}
		}
	else
		/* No QCU/DCU on AR5210, just set tx
		 * retry limits. We set IFS parameters
		 * on ath5k_hw_set_ifs_intervals */
		ath5k_hw_set_tx_retry_limits(ah, 0);

	/* Set the turbo flag when operating on 40MHz */
	if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
		AR5K_REG_ENABLE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,
				AR5K_DCU_GBL_IFS_MISC_TURBO_MODE);

	/* If we didn't set IFS timings through
	 * ath5k_hw_set_coverage_class make sure
	 * we set them here */
	if (!ah->ah_coverage_class) {
		unsigned int slot_time = ath5k_hw_get_default_slottime(ah);
		ath5k_hw_set_ifs_intervals(ah, slot_time);
	}

	return 0;
}
