/* * Copyright (c) 2004-2008 Reyk Floeter <[email protected]> * Copyright (c) 2006-2008 Nick Kossifidis <[email protected]> * * 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) … #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) { … } /** * 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) { … } /** * 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) { … } /** * 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) { … } /** * 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) { … } /** * 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) { … } /*******************************\ * 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) { … } /** * 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) { … } /**************************\ * 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) { … } /** * 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) { … }