2003-06-23 17:01:19 +00:00
|
|
|
/*-
|
2009-01-08 17:12:47 +00:00
|
|
|
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
|
2003-06-23 17:01:19 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer,
|
|
|
|
* without modification.
|
|
|
|
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
|
|
|
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
|
|
|
|
* redistribution must be conditioned upon including a substantially
|
|
|
|
* similar Disclaimer requirement for further binary redistribution.
|
|
|
|
*
|
|
|
|
* NO WARRANTY
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
|
|
|
|
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
|
|
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
|
|
|
|
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
|
|
|
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|
|
|
* THE POSSIBILITY OF SUCH DAMAGES.
|
|
|
|
*
|
|
|
|
* $FreeBSD$
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Defintions for the Atheros Wireless LAN controller driver.
|
|
|
|
*/
|
|
|
|
#ifndef _DEV_ATH_ATHVAR_H
|
|
|
|
#define _DEV_ATH_ATHVAR_H
|
|
|
|
|
2012-10-15 00:07:18 +00:00
|
|
|
#include <machine/atomic.h>
|
|
|
|
|
2008-12-01 16:53:01 +00:00
|
|
|
#include <dev/ath/ath_hal/ah.h>
|
|
|
|
#include <dev/ath/ath_hal/ah_desc.h>
|
2003-09-05 22:22:49 +00:00
|
|
|
#include <net80211/ieee80211_radiotap.h>
|
2003-06-23 17:01:19 +00:00
|
|
|
#include <dev/ath/if_athioctl.h>
|
2004-12-08 17:34:36 +00:00
|
|
|
#include <dev/ath/if_athrate.h>
|
2012-11-08 18:11:31 +00:00
|
|
|
#ifdef ATH_DEBUG_ALQ
|
|
|
|
#include <dev/ath/if_ath_alq.h>
|
|
|
|
#endif
|
2003-06-23 17:01:19 +00:00
|
|
|
|
|
|
|
#define ATH_TIMEOUT 1000
|
|
|
|
|
2012-06-13 06:57:55 +00:00
|
|
|
/*
|
|
|
|
* There is a separate TX ath_buf pool for management frames.
|
|
|
|
* This ensures that management frames such as probe responses
|
|
|
|
* and BAR frames can be transmitted during periods of high
|
|
|
|
* TX activity.
|
|
|
|
*/
|
|
|
|
#define ATH_MGMT_TXBUF 32
|
|
|
|
|
2011-03-26 11:58:29 +00:00
|
|
|
/*
|
|
|
|
* 802.11n requires more TX and RX buffers to do AMPDU.
|
|
|
|
*/
|
2011-03-27 08:47:55 +00:00
|
|
|
#ifdef ATH_ENABLE_11N
|
2012-05-22 19:50:21 +00:00
|
|
|
#define ATH_TXBUF 512
|
2011-03-26 11:58:29 +00:00
|
|
|
#define ATH_RXBUF 512
|
|
|
|
#endif
|
|
|
|
|
2006-02-09 21:03:25 +00:00
|
|
|
#ifndef ATH_RXBUF
|
2003-06-23 17:01:19 +00:00
|
|
|
#define ATH_RXBUF 40 /* number of RX buffers */
|
2006-02-09 21:03:25 +00:00
|
|
|
#endif
|
|
|
|
#ifndef ATH_TXBUF
|
Update 802.11 wireless support:
o major overhaul of the way channels are handled: channels are now
fully enumerated and uniquely identify the operating characteristics;
these changes are visible to user applications which require changes
o make scanning support independent of the state machine to enable
background scanning and roaming
o move scanning support into loadable modules based on the operating
mode to enable different policies and reduce the memory footprint
on systems w/ constrained resources
o add background scanning in station mode (no support for adhoc/ibss
mode yet)
o significantly speedup sta mode scanning with a variety of techniques
o add roaming support when background scanning is supported; for now
we use a simple algorithm to trigger a roam: we threshold the rssi
and tx rate, if either drops too low we try to roam to a new ap
o add tx fragmentation support
o add first cut at 802.11n support: this code works with forthcoming
drivers but is incomplete; it's included now to establish a baseline
for other drivers to be developed and for user applications
o adjust max_linkhdr et. al. to reflect 802.11 requirements; this eliminates
prepending mbufs for traffic generated locally
o add support for Atheros protocol extensions; mainly the fast frames
encapsulation (note this can be used with any card that can tx+rx
large frames correctly)
o add sta support for ap's that beacon both WPA1+2 support
o change all data types from bsd-style to posix-style
o propagate noise floor data from drivers to net80211 and on to user apps
o correct various issues in the sta mode state machine related to handling
authentication and association failures
o enable the addition of sta mode power save support for drivers that need
net80211 support (not in this commit)
o remove old WI compatibility ioctls (wicontrol is officially dead)
o change the data structures returned for get sta info and get scan
results so future additions will not break user apps
o fixed tx rate is now maintained internally as an ieee rate and not an
index into the rate set; this needs to be extended to deal with
multi-mode operation
o add extended channel specifications to radiotap to enable 11n sniffing
Drivers:
o ath: add support for bg scanning, tx fragmentation, fast frames,
dynamic turbo (lightly tested), 11n (sniffing only and needs
new hal)
o awi: compile tested only
o ndis: lightly tested
o ipw: lightly tested
o iwi: add support for bg scanning (well tested but may have some
rough edges)
o ral, ural, rum: add suppoort for bg scanning, calibrate rssi data
o wi: lightly tested
This work is based on contributions by Atheros, kmacy, sephe, thompsa,
mlaier, kevlo, and others. Much of the scanning work was supported by
Atheros. The 11n work was supported by Marvell.
2007-06-11 03:36:55 +00:00
|
|
|
#define ATH_TXBUF 200 /* number of TX buffers */
|
2006-02-09 21:03:25 +00:00
|
|
|
#endif
|
2008-04-20 20:35:46 +00:00
|
|
|
#define ATH_BCBUF 4 /* number of beacon buffers */
|
|
|
|
|
2005-01-18 19:42:17 +00:00
|
|
|
#define ATH_TXDESC 10 /* number of descriptors per buffer */
|
2004-12-08 17:34:36 +00:00
|
|
|
#define ATH_TXMAXTRY 11 /* max number of transmit attempts */
|
2006-02-09 20:57:48 +00:00
|
|
|
#define ATH_TXMGTTRY 4 /* xmit attempts for mgt/ctl frames */
|
2004-12-08 17:34:36 +00:00
|
|
|
#define ATH_TXINTR_PERIOD 5 /* max number of batched tx descriptors */
|
2003-06-23 17:01:19 +00:00
|
|
|
|
2011-09-28 02:54:42 +00:00
|
|
|
#define ATH_BEACON_AIFS_DEFAULT 1 /* default aifs for ap beacon q */
|
2005-06-07 00:12:40 +00:00
|
|
|
#define ATH_BEACON_CWMIN_DEFAULT 0 /* default cwmin for ap beacon q */
|
|
|
|
#define ATH_BEACON_CWMAX_DEFAULT 0 /* default cwmax for ap beacon q */
|
|
|
|
|
2005-06-06 16:39:21 +00:00
|
|
|
/*
|
|
|
|
* The key cache is used for h/w cipher state and also for
|
|
|
|
* tracking station state such as the current tx antenna.
|
|
|
|
* We also setup a mapping table between key cache slot indices
|
|
|
|
* and station state to short-circuit node lookups on rx.
|
|
|
|
* Different parts have different size key caches. We handle
|
|
|
|
* up to ATH_KEYMAX entries (could dynamically allocate state).
|
|
|
|
*/
|
|
|
|
#define ATH_KEYMAX 128 /* max key cache size we handle */
|
|
|
|
#define ATH_KEYBYTES (ATH_KEYMAX/NBBY) /* storage space in bytes */
|
|
|
|
|
Update 802.11 wireless support:
o major overhaul of the way channels are handled: channels are now
fully enumerated and uniquely identify the operating characteristics;
these changes are visible to user applications which require changes
o make scanning support independent of the state machine to enable
background scanning and roaming
o move scanning support into loadable modules based on the operating
mode to enable different policies and reduce the memory footprint
on systems w/ constrained resources
o add background scanning in station mode (no support for adhoc/ibss
mode yet)
o significantly speedup sta mode scanning with a variety of techniques
o add roaming support when background scanning is supported; for now
we use a simple algorithm to trigger a roam: we threshold the rssi
and tx rate, if either drops too low we try to roam to a new ap
o add tx fragmentation support
o add first cut at 802.11n support: this code works with forthcoming
drivers but is incomplete; it's included now to establish a baseline
for other drivers to be developed and for user applications
o adjust max_linkhdr et. al. to reflect 802.11 requirements; this eliminates
prepending mbufs for traffic generated locally
o add support for Atheros protocol extensions; mainly the fast frames
encapsulation (note this can be used with any card that can tx+rx
large frames correctly)
o add sta support for ap's that beacon both WPA1+2 support
o change all data types from bsd-style to posix-style
o propagate noise floor data from drivers to net80211 and on to user apps
o correct various issues in the sta mode state machine related to handling
authentication and association failures
o enable the addition of sta mode power save support for drivers that need
net80211 support (not in this commit)
o remove old WI compatibility ioctls (wicontrol is officially dead)
o change the data structures returned for get sta info and get scan
results so future additions will not break user apps
o fixed tx rate is now maintained internally as an ieee rate and not an
index into the rate set; this needs to be extended to deal with
multi-mode operation
o add extended channel specifications to radiotap to enable 11n sniffing
Drivers:
o ath: add support for bg scanning, tx fragmentation, fast frames,
dynamic turbo (lightly tested), 11n (sniffing only and needs
new hal)
o awi: compile tested only
o ndis: lightly tested
o ipw: lightly tested
o iwi: add support for bg scanning (well tested but may have some
rough edges)
o ral, ural, rum: add suppoort for bg scanning, calibrate rssi data
o wi: lightly tested
This work is based on contributions by Atheros, kmacy, sephe, thompsa,
mlaier, kevlo, and others. Much of the scanning work was supported by
Atheros. The 11n work was supported by Marvell.
2007-06-11 03:36:55 +00:00
|
|
|
struct taskqueue;
|
|
|
|
struct kthread;
|
|
|
|
struct ath_buf;
|
|
|
|
|
2011-11-08 02:12:11 +00:00
|
|
|
#define ATH_TID_MAX_BUFS (2 * IEEE80211_AGGR_BAWMAX)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Per-TID state
|
|
|
|
*
|
|
|
|
* Note that TID 16 (WME_NUM_TID+1) is for handling non-QoS frames.
|
|
|
|
*/
|
|
|
|
struct ath_tid {
|
2012-10-07 23:45:19 +00:00
|
|
|
TAILQ_HEAD(,ath_buf) tid_q; /* pending buffers */
|
2011-11-08 02:12:11 +00:00
|
|
|
struct ath_node *an; /* pointer to parent */
|
|
|
|
int tid; /* tid */
|
|
|
|
int ac; /* which AC gets this trafic */
|
|
|
|
int hwq_depth; /* how many buffers are on HW */
|
Delete the per-TXQ locks and replace them with a single TX lock.
I couldn't think of a way to maintain the hardware TXQ locks _and_ layer
on top of that per-TXQ software queuing and any other kind of fine-grained
locks (eg per-TID, or per-node locks.)
So for now, to facilitate some further code refactoring and development
as part of the final push to get software queue ps-poll and u-apsd handling
into this driver, just do away with them entirely.
I may eventually bring them back at some point, when it looks slightly more
architectually cleaner to do so. But as it stands at the present, it's
not really buying us much:
* in order to properly serialise things and not get bitten by scheduling
and locking interactions with things higher up in the stack, we need to
wrap the whole TX path in a long held lock. Otherwise we can end up
being pre-empted during frame handling, resulting in some out of order
frame handling between sequence number allocation and encryption handling
(ie, the seqno and the CCMP IV get out of sequence);
* .. so whilst that's the case, holding the lock for that long means that
we're acquiring and releasing the TXQ lock _inside_ that context;
* And we also acquire it per-frame during frame completion, but we currently
can't hold the lock for the duration of the TX completion as we need
to call net80211 layer things with the locks _unheld_ to avoid LOR.
* .. the other places were grab that lock are reset/flush, which don't happen
often.
My eventual aim is to change the TX path so all rejected frame transmissions
and all frame completions result in any ieee80211_free_node() calls to occur
outside of the TX lock; then I can cut back on the amount of locking that
goes on here.
There may be some LORs that occur when ieee80211_free_node() is called when
the TX queue path fails; I'll begin to address these in follow-up commits.
2012-12-02 06:24:08 +00:00
|
|
|
u_int axq_depth; /* SW queue depth */
|
2011-11-08 02:12:11 +00:00
|
|
|
|
2012-09-17 01:21:55 +00:00
|
|
|
struct {
|
2012-10-07 23:45:19 +00:00
|
|
|
TAILQ_HEAD(,ath_buf) tid_q; /* filtered queue */
|
2012-09-17 01:21:55 +00:00
|
|
|
u_int axq_depth; /* SW queue depth */
|
|
|
|
} filtq;
|
|
|
|
|
2011-11-08 02:12:11 +00:00
|
|
|
/*
|
|
|
|
* Entry on the ath_txq; when there's traffic
|
|
|
|
* to send
|
|
|
|
*/
|
|
|
|
TAILQ_ENTRY(ath_tid) axq_qelem;
|
|
|
|
int sched;
|
|
|
|
int paused; /* >0 if the TID has been paused */
|
2012-09-17 01:21:55 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* These are flags - perhaps later collapse
|
|
|
|
* down to a single uint32_t ?
|
|
|
|
*/
|
2012-05-22 06:31:03 +00:00
|
|
|
int addba_tx_pending; /* TX ADDBA pending */
|
Implement BAR TX.
A BAR frame must be transmitted when an frame in an A-MPDU session fails
to transmit - it's retried too often, or it can't be cloned for
re-transmission. The BAR frame tells the remote side to advance the
left edge of the block-ack window (BAW) to a new value.
In order to do this:
* TX for that particular node/TID must be paused;
* The existing frames in the hardware queue needs to be completed, whether
they're TXed successfully or otherwise;
* The new left edge of the BAW is then communicated to the remote side
via a BAR frame;
* Once the BAR frame has been sucessfully TXed, aggregation can resume;
* If the BAR frame can't be successfully TXed, the aggregation session
is torn down.
This is a first pass that implements the above. What needs to be done/
tested:
* What happens during say, a channel reset / stuck beacon _and_ BAR
TX. It _should_ be correctly buffered and retried once the
reset has completed. But if a bgscan occurs (and they shouldn't,
grr) the BAR frame will be forcibly failed and the aggregation session
will be torn down.
Yes, another reason to disable bgscan until I've figured this out.
* There's way too much locking going on here. I'm going to do a couple
of further passes of sanitising and refactoring so the (re) locking
isn't so heavy. Right now I'm going for correctness, not speed.
* The BAR TX can fail if the hardware TX queue is full. Since there's
no "free" space kept for management frames, a full TX queue (from eg
an iperf test) can race with your ability to allocate ath_buf/mbufs
and cause issues. I'll knock this on the head with a subsequent
commit.
* I need to do some _much_ more thorough testing in hostap mode to ensure
that many concurrent traffic streams to different end nodes are correctly
handled. I'll find and squish whichever bugs show up here.
But, this is an important step to being able to flip on 802.11n by default.
The last issue (besides bug fixes, of course) is HT frame protection and
I'll address that in a subsequent commit.
2012-04-04 23:45:15 +00:00
|
|
|
int bar_wait; /* waiting for BAR */
|
|
|
|
int bar_tx; /* BAR TXed */
|
2012-09-17 01:21:55 +00:00
|
|
|
int isfiltered; /* is this node currently filtered */
|
2011-11-08 02:12:11 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Is the TID being cleaned up after a transition
|
|
|
|
* from aggregation to non-aggregation?
|
|
|
|
* When this is set to 1, this TID will be paused
|
|
|
|
* and no further traffic will be queued until all
|
|
|
|
* the hardware packets pending for this TID have been
|
|
|
|
* TXed/completed; at which point (non-aggregation)
|
|
|
|
* traffic will resume being TXed.
|
|
|
|
*/
|
|
|
|
int cleanup_inprogress;
|
|
|
|
/*
|
|
|
|
* How many hardware-queued packets are
|
|
|
|
* waiting to be cleaned up.
|
|
|
|
* This is only valid if cleanup_inprogress is 1.
|
|
|
|
*/
|
|
|
|
int incomp;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The following implements a ring representing
|
|
|
|
* the frames in the current BAW.
|
|
|
|
* To avoid copying the array content each time
|
|
|
|
* the BAW is moved, the baw_head/baw_tail point
|
|
|
|
* to the current BAW begin/end; when the BAW is
|
|
|
|
* shifted the head/tail of the array are also
|
|
|
|
* appropriately shifted.
|
|
|
|
*/
|
|
|
|
/* active tx buffers, beginning at current BAW */
|
|
|
|
struct ath_buf *tx_buf[ATH_TID_MAX_BUFS];
|
|
|
|
/* where the baw head is in the array */
|
|
|
|
int baw_head;
|
|
|
|
/* where the BAW tail is in the array */
|
|
|
|
int baw_tail;
|
|
|
|
};
|
|
|
|
|
2004-12-08 17:34:36 +00:00
|
|
|
/* driver-specific node state */
|
2003-06-23 17:01:19 +00:00
|
|
|
struct ath_node {
|
2003-08-19 22:17:04 +00:00
|
|
|
struct ieee80211_node an_node; /* base class */
|
2008-04-20 20:35:46 +00:00
|
|
|
u_int8_t an_mgmtrix; /* min h/w rate index */
|
|
|
|
u_int8_t an_mcastrix; /* mcast h/w rate index */
|
2012-10-03 23:23:45 +00:00
|
|
|
uint32_t an_is_powersave; /* node is sleeping */
|
2012-10-28 21:13:12 +00:00
|
|
|
uint32_t an_stack_psq; /* net80211 psq isn't empty */
|
|
|
|
uint32_t an_tim_set; /* TIM has been set */
|
Update 802.11 wireless support:
o major overhaul of the way channels are handled: channels are now
fully enumerated and uniquely identify the operating characteristics;
these changes are visible to user applications which require changes
o make scanning support independent of the state machine to enable
background scanning and roaming
o move scanning support into loadable modules based on the operating
mode to enable different policies and reduce the memory footprint
on systems w/ constrained resources
o add background scanning in station mode (no support for adhoc/ibss
mode yet)
o significantly speedup sta mode scanning with a variety of techniques
o add roaming support when background scanning is supported; for now
we use a simple algorithm to trigger a roam: we threshold the rssi
and tx rate, if either drops too low we try to roam to a new ap
o add tx fragmentation support
o add first cut at 802.11n support: this code works with forthcoming
drivers but is incomplete; it's included now to establish a baseline
for other drivers to be developed and for user applications
o adjust max_linkhdr et. al. to reflect 802.11 requirements; this eliminates
prepending mbufs for traffic generated locally
o add support for Atheros protocol extensions; mainly the fast frames
encapsulation (note this can be used with any card that can tx+rx
large frames correctly)
o add sta support for ap's that beacon both WPA1+2 support
o change all data types from bsd-style to posix-style
o propagate noise floor data from drivers to net80211 and on to user apps
o correct various issues in the sta mode state machine related to handling
authentication and association failures
o enable the addition of sta mode power save support for drivers that need
net80211 support (not in this commit)
o remove old WI compatibility ioctls (wicontrol is officially dead)
o change the data structures returned for get sta info and get scan
results so future additions will not break user apps
o fixed tx rate is now maintained internally as an ieee rate and not an
index into the rate set; this needs to be extended to deal with
multi-mode operation
o add extended channel specifications to radiotap to enable 11n sniffing
Drivers:
o ath: add support for bg scanning, tx fragmentation, fast frames,
dynamic turbo (lightly tested), 11n (sniffing only and needs
new hal)
o awi: compile tested only
o ndis: lightly tested
o ipw: lightly tested
o iwi: add support for bg scanning (well tested but may have some
rough edges)
o ral, ural, rum: add suppoort for bg scanning, calibrate rssi data
o wi: lightly tested
This work is based on contributions by Atheros, kmacy, sephe, thompsa,
mlaier, kevlo, and others. Much of the scanning work was supported by
Atheros. The 11n work was supported by Marvell.
2007-06-11 03:36:55 +00:00
|
|
|
struct ath_buf *an_ff_buf[WME_NUM_AC]; /* ff staging area */
|
2011-11-08 02:12:11 +00:00
|
|
|
struct ath_tid an_tid[IEEE80211_TID_SIZE]; /* per-TID state */
|
|
|
|
char an_name[32]; /* eg "wlan0_a1" */
|
2013-05-13 18:57:18 +00:00
|
|
|
struct mtx an_mtx; /* protecting the rate control state */
|
2012-10-15 00:07:18 +00:00
|
|
|
uint32_t an_swq_depth; /* how many SWQ packets for this
|
|
|
|
node */
|
2013-01-21 04:06:04 +00:00
|
|
|
int clrdmask; /* has clrdmask been set */
|
Implement my first cut at "correct" node power-save and
PS-POLL support.
This implements PS-POLL awareness i nthe
* Implement frame "leaking", which allows for a software queue
to be scheduled even though it's asleep
* Track whether a frame has been leaked or not
* Leak out a single non-AMPDU frame when transmitting aggregates
* Queue BAR frames if the node is asleep
* Direct-dispatch the rest of control and management frames.
This allows for things like re-association to occur (which involves
sending probe req/resp as well as assoc request/response) when
the node is asleep and then tries reassociating.
* Limit how many frames can set in the software node queue whilst
the node is asleep. net80211 is already buffering frames for us
so this is mostly just paranoia.
* Add a PS-POLL method which leaks out a frame if there's something
in the software queue, else it calls net80211's ps-poll routine.
Since the ath PS-POLL routine marks the node as having a single frame
to leak, either a software queued frame would leak, OR the next queued
frame would leak. The next queued frame could be something from the
net80211 power save queue, OR it could be a NULL frame from net80211.
TODO:
* Don't transmit further BAR frames (eg via a timeout) if the node is
currently asleep. Otherwise we may end up exhausting management frames
due to the lots of queued BAR frames.
I may just undo this bit later on and direct-dispatch BAR frames
even if the node is asleep.
* It would be nice to burst out a single A-MPDU frame if both ends
support this. I may end adding a FreeBSD IE soon to negotiate
this power save behaviour.
* I should make STAs timeout of power save mode if they've been in power
save for more than a handful of seconds. This way cards that get
"stuck" in power save mode don't stay there for the "inactivity" timeout
in net80211.
* Move the queue depth check into the driver layer (ath_start / ath_transmit)
rather than doing it in the TX path.
* There could be some naughty corner cases with ps-poll leaking.
Specifically, if net80211 generates a NULL data frame whilst another
transmitter sends a normal data frame out net80211 output / transmit,
we need to ensure that the NULL data frame goes out first.
This is one of those things that should occur inside the VAP/ic TX lock.
Grr, more investigations to do..
Tested:
* STA: AR5416, AR9280
* AP: AR5416, AR9280, AR9160
2013-05-15 18:33:05 +00:00
|
|
|
uint32_t an_leak_count; /* How many frames to leak during pause */
|
2004-12-08 17:34:36 +00:00
|
|
|
/* variable-length rate control state follows */
|
2003-06-23 17:01:19 +00:00
|
|
|
};
|
2004-12-08 17:34:36 +00:00
|
|
|
#define ATH_NODE(ni) ((struct ath_node *)(ni))
|
|
|
|
#define ATH_NODE_CONST(ni) ((const struct ath_node *)(ni))
|
|
|
|
|
|
|
|
#define ATH_RSSI_LPF_LEN 10
|
|
|
|
#define ATH_RSSI_DUMMY_MARKER 0x127
|
|
|
|
#define ATH_EP_MUL(x, mul) ((x) * (mul))
|
|
|
|
#define ATH_RSSI_IN(x) (ATH_EP_MUL((x), HAL_RSSI_EP_MULTIPLIER))
|
|
|
|
#define ATH_LPF_RSSI(x, y, len) \
|
|
|
|
((x != ATH_RSSI_DUMMY_MARKER) ? (((x) * ((len) - 1) + (y)) / (len)) : (y))
|
|
|
|
#define ATH_RSSI_LPF(x, y) do { \
|
|
|
|
if ((y) >= -20) \
|
|
|
|
x = ATH_LPF_RSSI((x), ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN); \
|
|
|
|
} while (0)
|
2008-10-27 17:51:24 +00:00
|
|
|
#define ATH_EP_RND(x,mul) \
|
|
|
|
((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
|
|
|
|
#define ATH_RSSI(x) ATH_EP_RND(x, HAL_RSSI_EP_MULTIPLIER)
|
2003-06-23 17:01:19 +00:00
|
|
|
|
2012-06-13 06:57:55 +00:00
|
|
|
typedef enum {
|
|
|
|
ATH_BUFTYPE_NORMAL = 0,
|
|
|
|
ATH_BUFTYPE_MGMT = 1,
|
|
|
|
} ath_buf_type_t;
|
|
|
|
|
2003-06-23 17:01:19 +00:00
|
|
|
struct ath_buf {
|
2011-11-08 17:08:12 +00:00
|
|
|
TAILQ_ENTRY(ath_buf) bf_list;
|
2011-11-08 02:12:11 +00:00
|
|
|
struct ath_buf * bf_next; /* next buffer in the aggregate */
|
2003-06-23 17:01:19 +00:00
|
|
|
int bf_nseg;
|
2012-07-14 02:52:48 +00:00
|
|
|
HAL_STATUS bf_rxstatus;
|
2009-01-08 17:12:47 +00:00
|
|
|
uint16_t bf_flags; /* status flags (below) */
|
2012-08-15 06:48:34 +00:00
|
|
|
uint16_t bf_descid; /* 16 bit descriptor ID */
|
2003-06-23 17:01:19 +00:00
|
|
|
struct ath_desc *bf_desc; /* virtual addr of desc */
|
2006-12-13 19:34:35 +00:00
|
|
|
struct ath_desc_status bf_status; /* tx/rx status */
|
2003-06-23 17:01:19 +00:00
|
|
|
bus_addr_t bf_daddr; /* physical addr of desc */
|
2004-12-08 17:34:36 +00:00
|
|
|
bus_dmamap_t bf_dmamap; /* DMA map for mbuf chain */
|
2003-06-23 17:01:19 +00:00
|
|
|
struct mbuf *bf_m; /* mbuf for buf */
|
|
|
|
struct ieee80211_node *bf_node; /* pointer to the node */
|
2011-11-08 02:12:11 +00:00
|
|
|
struct ath_desc *bf_lastds; /* last descriptor for comp status */
|
|
|
|
struct ath_buf *bf_last; /* last buffer in aggregate, or self for non-aggregate */
|
2003-06-23 17:01:19 +00:00
|
|
|
bus_size_t bf_mapsize;
|
2005-01-18 19:42:17 +00:00
|
|
|
#define ATH_MAX_SCATTER ATH_TXDESC /* max(tx,rx,beacon) desc's */
|
2003-06-23 17:01:19 +00:00
|
|
|
bus_dma_segment_t bf_segs[ATH_MAX_SCATTER];
|
Migrate ath(4) to now use if_transmit instead of the legacy if_start
and if queue mechanism; also fix up (non-11n) TX fragment handling.
This may result in a bit of a performance drop for now but I plan on
debugging and resolving this at a later stage.
Whilst here, fix the transmit path so fragment transmission works.
The TX fragmentation handling is a bit more special. In order to
correctly transmit TX fragments, there's a bunch of corner cases that
need to be handled:
* They must be transmitted back to back, in the same order..
* .. ie, you need to hold the TX lock whilst transmitting this
set of fragments rather than interleaving it with other MSDUs
destined to other nodes;
* The length of the next fragment is required when transmitting, in
order to correctly set the NAV field in the current frame to the
length of the next frame; which requires ..
* .. that we know the transmit duration of the next frame, which ..
* .. requires us to set the rate of all fragments to the same length,
or make the decision up-front, etc.
To facilitate this, I've added a new ath_buf field to describe the
length of the next fragment. This avoids having to keep the mbuf
chain together. This used to work before my 11n TX path work because
the ath_tx_start() routine would be handed a single mbuf with m_nextpkt
pointing to the next frame, and that would be maintained all the way
up to when the duration calculation was done. This doesn't hold
true any longer - the actual queuing may occur at any point in the
future (think ath_node TID software queuing) so this information
needs to be maintained.
Right now this does work for non-11n frames but it doesn't at all
enforce the same rate control decision for all frames in the fragment.
I plan on fixing this in a followup commit.
RTS/CTS has the same issue, I'll look at fixing this in a subsequent
commit.
Finaly, 11n fragment support requires the driver to have fully
decided what the rate scenario setup is - including 20/40MHz,
short/long GI, STBC, LDPC, number of streams, etc. Right now that
decision is (currently) made _after_ the NAV field value is updated.
I'll fix all of this in subsequent commits.
Tested:
* AR5416, STA, transmitting 11abg fragments
* AR5416, STA, 11n fragments work but the NAV field is incorrect for
the reasons above.
TODO:
* It would be nice to be able to queue mbufs per-node and per-TID so
we can only queue ath_buf entries when it's time to assemble frames
to send to the hardware.
But honestly, we should just do that level of software queue management
in net80211 rather than ath(4), so I'm going to leave this alone for now.
* More thorough AP, mesh and adhoc testing.
* Ensure that net80211 doesn't hand us fragmented frames when A-MPDU has
been negotiated, as we can't do software retransmission of fragments.
* .. set CLRDMASK when transmitting fragments, just to ensure.
2013-05-26 22:23:39 +00:00
|
|
|
uint32_t bf_nextfraglen; /* length of next fragment */
|
2011-11-08 02:12:11 +00:00
|
|
|
|
|
|
|
/* Completion function to call on TX complete (fail or not) */
|
|
|
|
/*
|
|
|
|
* "fail" here is set to 1 if the queue entries were removed
|
|
|
|
* through a call to ath_tx_draintxq().
|
|
|
|
*/
|
|
|
|
void(* bf_comp) (struct ath_softc *sc, struct ath_buf *bf, int fail);
|
|
|
|
|
|
|
|
/* This state is kept to support software retries and aggregation */
|
|
|
|
struct {
|
2012-06-14 04:24:13 +00:00
|
|
|
uint16_t bfs_seqno; /* sequence number of this packet */
|
2011-11-08 02:12:11 +00:00
|
|
|
uint16_t bfs_ndelim; /* number of delims for padding */
|
|
|
|
|
2012-06-14 04:24:13 +00:00
|
|
|
uint8_t bfs_retries; /* retry count */
|
|
|
|
uint8_t bfs_tid; /* packet TID (or TID_MAX for no QoS) */
|
|
|
|
uint8_t bfs_nframes; /* number of frames in aggregate */
|
|
|
|
uint8_t bfs_pri; /* packet AC priority */
|
2012-12-11 04:19:51 +00:00
|
|
|
uint8_t bfs_tx_queue; /* destination hardware TX queue */
|
2012-06-14 04:24:13 +00:00
|
|
|
|
2012-04-10 19:25:43 +00:00
|
|
|
u_int32_t bfs_aggr:1, /* part of aggregate? */
|
|
|
|
bfs_aggrburst:1, /* part of aggregate burst? */
|
|
|
|
bfs_isretried:1, /* retried frame? */
|
|
|
|
bfs_dobaw:1, /* actually check against BAW? */
|
|
|
|
bfs_addedbaw:1, /* has been added to the BAW */
|
|
|
|
bfs_shpream:1, /* use short preamble */
|
|
|
|
bfs_istxfrag:1, /* is fragmented */
|
|
|
|
bfs_ismrr:1, /* do multi-rate TX retry */
|
|
|
|
bfs_doprot:1, /* do RTS/CTS based protection */
|
2012-06-11 06:59:28 +00:00
|
|
|
bfs_doratelookup:1; /* do rate lookup before each TX */
|
2012-04-10 19:25:43 +00:00
|
|
|
|
2011-11-08 02:12:11 +00:00
|
|
|
/*
|
|
|
|
* These fields are passed into the
|
|
|
|
* descriptor setup functions.
|
|
|
|
*/
|
2012-06-16 04:41:35 +00:00
|
|
|
|
|
|
|
/* Make this an 8 bit value? */
|
2011-11-08 02:12:11 +00:00
|
|
|
HAL_PKT_TYPE bfs_atype; /* packet type */
|
2012-06-16 04:41:35 +00:00
|
|
|
|
|
|
|
uint32_t bfs_pktlen; /* length of this packet */
|
|
|
|
|
|
|
|
uint16_t bfs_hdrlen; /* length of this packet header */
|
2011-11-08 02:12:11 +00:00
|
|
|
uint16_t bfs_al; /* length of aggregate */
|
2012-06-16 04:41:35 +00:00
|
|
|
|
|
|
|
uint16_t bfs_txflags; /* HAL (tx) descriptor flags */
|
|
|
|
uint8_t bfs_txrate0; /* first TX rate */
|
|
|
|
uint8_t bfs_try0; /* first try count */
|
|
|
|
|
|
|
|
uint16_t bfs_txpower; /* tx power */
|
2011-11-08 02:12:11 +00:00
|
|
|
uint8_t bfs_ctsrate0; /* Non-zero - use this as ctsrate */
|
2012-06-16 04:41:35 +00:00
|
|
|
uint8_t bfs_ctsrate; /* CTS rate */
|
|
|
|
|
|
|
|
/* 16 bit? */
|
|
|
|
int32_t bfs_keyix; /* crypto key index */
|
|
|
|
int32_t bfs_txantenna; /* TX antenna config */
|
|
|
|
|
|
|
|
/* Make this an 8 bit value? */
|
2011-11-08 02:12:11 +00:00
|
|
|
enum ieee80211_protmode bfs_protmode;
|
2012-06-16 04:41:35 +00:00
|
|
|
|
|
|
|
/* 16 bit? */
|
|
|
|
uint32_t bfs_ctsduration; /* CTS duration (pre-11n NICs) */
|
2011-11-08 02:12:11 +00:00
|
|
|
struct ath_rc_series bfs_rc[ATH_RC_NUM]; /* non-11n TX series */
|
|
|
|
} bf_state;
|
2003-06-23 17:01:19 +00:00
|
|
|
};
|
2011-11-08 17:08:12 +00:00
|
|
|
typedef TAILQ_HEAD(ath_bufhead_s, ath_buf) ath_bufhead;
|
2004-12-08 17:34:36 +00:00
|
|
|
|
2012-06-13 06:57:55 +00:00
|
|
|
#define ATH_BUF_MGMT 0x00000001 /* (tx) desc is a mgmt desc */
|
2009-01-08 17:12:47 +00:00
|
|
|
#define ATH_BUF_BUSY 0x00000002 /* (tx) desc owned by h/w */
|
2013-03-26 19:46:51 +00:00
|
|
|
#define ATH_BUF_FIFOEND 0x00000004
|
|
|
|
#define ATH_BUF_FIFOPTR 0x00000008
|
|
|
|
|
|
|
|
#define ATH_BUF_FLAGS_CLONE (ATH_BUF_MGMT)
|
2009-01-08 17:12:47 +00:00
|
|
|
|
2004-12-08 17:34:36 +00:00
|
|
|
/*
|
|
|
|
* DMA state for tx/rx descriptors.
|
|
|
|
*/
|
|
|
|
struct ath_descdma {
|
|
|
|
const char* dd_name;
|
|
|
|
struct ath_desc *dd_desc; /* descriptors */
|
2012-07-23 02:26:33 +00:00
|
|
|
int dd_descsize; /* size of single descriptor */
|
2004-12-08 17:34:36 +00:00
|
|
|
bus_addr_t dd_desc_paddr; /* physical addr of dd_desc */
|
2006-05-05 03:21:13 +00:00
|
|
|
bus_size_t dd_desc_len; /* size of dd_desc */
|
2004-12-08 17:34:36 +00:00
|
|
|
bus_dma_segment_t dd_dseg;
|
|
|
|
bus_dma_tag_t dd_dmat; /* bus DMA tag */
|
|
|
|
bus_dmamap_t dd_dmamap; /* DMA map for descriptors */
|
|
|
|
struct ath_buf *dd_bufptr; /* associated buffers */
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Data transmit queue state. One of these exists for each
|
|
|
|
* hardware transmit queue. Packets sent to us from above
|
|
|
|
* are assigned to queues based on their priority. Not all
|
|
|
|
* devices support a complete set of hardware transmit queues.
|
|
|
|
* For those devices the array sc_ac2q will map multiple
|
|
|
|
* priorities to fewer hardware queues (typically all to one
|
|
|
|
* hardware queue).
|
|
|
|
*/
|
|
|
|
struct ath_txq {
|
2011-11-08 02:12:11 +00:00
|
|
|
struct ath_softc *axq_softc; /* Needed for scheduling */
|
2004-12-08 17:34:36 +00:00
|
|
|
u_int axq_qnum; /* hardware q number */
|
2008-04-20 20:35:46 +00:00
|
|
|
#define ATH_TXQ_SWQ (HAL_NUM_TX_QUEUES+1) /* qnum for s/w only queue */
|
2009-03-30 21:53:27 +00:00
|
|
|
u_int axq_ac; /* WME AC */
|
2009-01-08 17:12:47 +00:00
|
|
|
u_int axq_flags;
|
Be (very) careful about how to add more TX DMA work.
The list-based DMA engine has the following behaviour:
* When the DMA engine is in the init state, you can write the first
descriptor address to the QCU TxDP register and it will work.
* Then when it hits the end of the list (ie, it either hits a NULL
link pointer, OR it hits a descriptor with VEOL set) the QCU
stops, and the TxDP points to the last descriptor that was transmitted.
* Then when you want to transmit a new frame, you can then either:
+ write the head of the new list into TxDP, or
+ you write the head of the new list into the link pointer of the
last completed descriptor (ie, where TxDP points), then kick
TxE to restart transmission on that QCU>
* The hardware then will re-read the descriptor to pick up the link
pointer and then jump to that.
Now, the quirks:
* If you write a TxDP when there's been no previous TxDP (ie, it's 0),
it works.
* If you write a TxDP in any other instance, the TxDP write may actually
fail. Thus, when you start transmission, it will re-read the last
transmitted descriptor to get the link pointer, NOT just start a new
transmission.
So the correct thing to do here is:
* ALWAYS use the holding descriptor (ie, the last transmitted descriptor
that we've kept safe) and use the link pointer in _THAT_ to transmit
the next frame.
* NEVER write to the TxDP after you've done the initial write.
* .. also, don't do this whilst you're also resetting the NIC.
With this in mind, the following patch does basically the above.
* Since this encapsulates Sam's issues with the QCU behaviour w/ TDMA,
kill the TDMA special case and replace it with the above.
* Add a new TXQ flag - PUTRUNNING - which indicates that we've started
DMA.
* Clear that flag when DMA has been shutdown.
* Ensure that we're not restarting DMA with PUTRUNNING enabled.
* Fix the link pointer logic during TXQ drain - we should always ensure
the link pointer does point to something if there's a list of frames.
Having it be NULL as an indication that DMA has finished or during
a reset causes trouble.
Now, given all of this, i want to nuke axq_link from orbit. There's now HAL
methods to get and set the link pointer of a descriptor, so what we
should do instead is to update the right link pointer.
* If there's a holding descriptor and an empty TXQ list, set the
link pointer of said holding descriptor to the new frame.
* If there's a non-empty TXQ list, set the link pointer of the
last descriptor in the list to the new frame.
* Nuke axq_link from orbit.
Note:
* The AR9380 doesn't need this. FIFO TX writes are atomic. As long as
we don't append to a list of frames that we've already passed to the
hardware, all of the above doesn't apply. The holding descriptor stuff
is still needed to ensure the hardware can re-read a completed
descriptor to move onto the next one, but we restart DMA by pushing in
a new FIFO entry into the TX QCU. That doesn't require any real
gymnastics.
Tested:
* AR5210, AR5211, AR5212, AR5416, AR9380 - STA mode.
2013-05-18 18:27:53 +00:00
|
|
|
//#define ATH_TXQ_PUTPENDING 0x0001 /* ath_hal_puttxbuf pending */
|
|
|
|
#define ATH_TXQ_PUTRUNNING 0x0002 /* ath_hal_puttxbuf has been called */
|
2006-02-27 17:20:23 +00:00
|
|
|
u_int axq_depth; /* queue depth (stat only) */
|
2011-11-08 02:12:11 +00:00
|
|
|
u_int axq_aggr_depth; /* how many aggregates are queued */
|
2004-12-08 17:34:36 +00:00
|
|
|
u_int axq_intrcnt; /* interrupt count */
|
|
|
|
u_int32_t *axq_link; /* link ptr in last TX desc */
|
2011-11-08 17:08:12 +00:00
|
|
|
TAILQ_HEAD(axq_q_s, ath_buf) axq_q; /* transmit queue */
|
Overhaul the TXQ locking (again!) as part of some beacon/cabq timing
related issues.
Moving the TX locking under one lock made things easier to progress on
but it had one important side-effect - it increased the latency when
handling CABQ setup when sending beacons.
This commit introduces a bunch of new changes and a few unrelated changs
that are just easier to lump in here.
The aim is to have the CABQ locking separate from other locking.
The CABQ transmit path in the beacon process thus doesn't have to grab
the general TX lock, reducing lock contention/latency and making it
more likely that we'll make the beacon TX timing.
The second half of this commit is the CABQ related setup changes needed
for sane looking EDMA CABQ support. Right now the EDMA TX code naively
assumes that only one frame (MPDU or A-MPDU) is being pushed into each
FIFO slot. For the CABQ this isn't true - a whole list of frames is
being pushed in - and thus CABQ handling breaks very quickly.
The aim here is to setup the CABQ list and then push _that list_ to
the hardware for transmission. I can then extend the EDMA TX code
to stamp that list as being "one" FIFO entry (likely by tagging the
last buffer in that list as "FIFO END") so the EDMA TX completion code
correctly tracks things.
Major:
* Migrate the per-TXQ add/removal locking back to per-TXQ, rather than
a single lock.
* Leave the software queue side of things under the ATH_TX_LOCK lock,
(continuing) to serialise things as they are.
* Add a new function which is called whenever there's a beacon miss,
to print out some debugging. This is primarily designed to help
me figure out if the beacon miss events are due to a noisy environment,
issues with the PHY/MAC, or other.
* Move the CABQ setup/enable to occur _after_ all the VAPs have been
looked at. This means that for multiple VAPS in bursted mode, the
CABQ gets primed once all VAPs are checked, rather than being primed
on the first VAP and then having frames appended after this.
Minor:
* Add a (disabled) twiddle to let me enable/disable cabq traffic.
It's primarily there to let me easily debug what's going on with beacon
and CABQ setup/traffic; there's some DMA engine hangs which I'm finally
trying to trace down.
* Clear bf_next when flushing frames; it should quieten some warnings
that show up when a node goes away.
Tested:
* AR9280, STA/hostap, up to 4 vaps (staggered)
* AR5416, STA/hostap, up to 4 vaps (staggered)
TODO:
* (Lots) more AR9380 and later testing, as I may have missed something here.
* Leverage this to fix CABQ hanling for AR9380 and later chips.
* Force bursted beaconing on the chips that default to staggered beacons and
ensure the CABQ stuff is all sane (eg, the MORE bits that aren't being
correctly set when chaining descriptors.)
2013-03-24 00:03:12 +00:00
|
|
|
struct mtx axq_lock; /* lock on q and link */
|
|
|
|
|
2013-03-26 19:46:51 +00:00
|
|
|
/*
|
|
|
|
* This is the FIFO staging buffer when doing EDMA.
|
|
|
|
*
|
|
|
|
* For legacy chips, we just push the head pointer to
|
|
|
|
* the hardware and we ignore this list.
|
|
|
|
*
|
|
|
|
* For EDMA, the staging buffer is treated as normal;
|
|
|
|
* when it's time to push a list of frames to the hardware
|
|
|
|
* we move that list here and we stamp buffers with
|
|
|
|
* flags to identify the beginning/end of that particular
|
|
|
|
* FIFO entry.
|
|
|
|
*/
|
|
|
|
struct {
|
|
|
|
TAILQ_HEAD(axq_q_f_s, ath_buf) axq_q;
|
|
|
|
u_int axq_depth;
|
|
|
|
} fifo;
|
|
|
|
u_int axq_fifo_depth; /* depth of FIFO frames */
|
|
|
|
|
2013-03-15 02:52:37 +00:00
|
|
|
/*
|
|
|
|
* XXX the holdingbf field is protected by the TXBUF lock
|
Overhaul the TXQ locking (again!) as part of some beacon/cabq timing
related issues.
Moving the TX locking under one lock made things easier to progress on
but it had one important side-effect - it increased the latency when
handling CABQ setup when sending beacons.
This commit introduces a bunch of new changes and a few unrelated changs
that are just easier to lump in here.
The aim is to have the CABQ locking separate from other locking.
The CABQ transmit path in the beacon process thus doesn't have to grab
the general TX lock, reducing lock contention/latency and making it
more likely that we'll make the beacon TX timing.
The second half of this commit is the CABQ related setup changes needed
for sane looking EDMA CABQ support. Right now the EDMA TX code naively
assumes that only one frame (MPDU or A-MPDU) is being pushed into each
FIFO slot. For the CABQ this isn't true - a whole list of frames is
being pushed in - and thus CABQ handling breaks very quickly.
The aim here is to setup the CABQ list and then push _that list_ to
the hardware for transmission. I can then extend the EDMA TX code
to stamp that list as being "one" FIFO entry (likely by tagging the
last buffer in that list as "FIFO END") so the EDMA TX completion code
correctly tracks things.
Major:
* Migrate the per-TXQ add/removal locking back to per-TXQ, rather than
a single lock.
* Leave the software queue side of things under the ATH_TX_LOCK lock,
(continuing) to serialise things as they are.
* Add a new function which is called whenever there's a beacon miss,
to print out some debugging. This is primarily designed to help
me figure out if the beacon miss events are due to a noisy environment,
issues with the PHY/MAC, or other.
* Move the CABQ setup/enable to occur _after_ all the VAPs have been
looked at. This means that for multiple VAPS in bursted mode, the
CABQ gets primed once all VAPs are checked, rather than being primed
on the first VAP and then having frames appended after this.
Minor:
* Add a (disabled) twiddle to let me enable/disable cabq traffic.
It's primarily there to let me easily debug what's going on with beacon
and CABQ setup/traffic; there's some DMA engine hangs which I'm finally
trying to trace down.
* Clear bf_next when flushing frames; it should quieten some warnings
that show up when a node goes away.
Tested:
* AR9280, STA/hostap, up to 4 vaps (staggered)
* AR5416, STA/hostap, up to 4 vaps (staggered)
TODO:
* (Lots) more AR9380 and later testing, as I may have missed something here.
* Leverage this to fix CABQ hanling for AR9380 and later chips.
* Force bursted beaconing on the chips that default to staggered beacons and
ensure the CABQ stuff is all sane (eg, the MORE bits that aren't being
correctly set when chaining descriptors.)
2013-03-24 00:03:12 +00:00
|
|
|
* for now, NOT the TXQ lock.
|
2013-03-15 02:52:37 +00:00
|
|
|
*
|
|
|
|
* Architecturally, it would likely be better to move
|
|
|
|
* the holdingbf field to a separate array in ath_softc
|
|
|
|
* just to highlight that it's not protected by the normal
|
|
|
|
* TX path lock.
|
|
|
|
*/
|
Implement "holding buffers" per TX queue rather than globally.
When working on TDMA, Sam Leffler found that the MAC DMA hardware
would re-read the last TX descriptor when getting ready to transmit
the next one. Thus the whole ATH_BUF_BUSY came into existance -
the descriptor must be left alone (very specifically the link pointer
must be maintained) until the hardware has moved onto the next frame.
He saw this in TDMA because the MAC would be frequently stopping during
active transmit (ie, when it wasn't its turn to transmit.)
Fast-forward to today. It turns out that this is a problem not with
a single MAC DMA instance, but with each QCU (from 0->9). They each
maintain separate descriptor pointers and will re-read the last
descriptor when starting to transmit the next.
So when your AP is busy transmitting from multiple TX queues, you'll
(more) frequently see one QCU stopped, waiting for a higher-priority QCU
to finsh transmitting, before it'll go ahead and continue. If you mess
up the descriptor (ie by freeing it) then you're short of luck.
Thanks to rpaulo for sticking with me whilst I diagnosed this issue
that he was quite reliably triggering in his environment.
This is a reimplementation; it doesn't have anything in common with
the ath9k or the Qualcomm Atheros reference driver.
Now - it in theory doesn't apply on the EDMA chips, as long as you
push one complete frame into the FIFO at a time. But the MAC can DMA
from a list of frames pushed into the hardware queue (ie, you concat
'n' frames together with link pointers, and then push the head pointer
into the TXQ FIFO.) Since that's likely how I'm going to implement
CABQ handling in hostap mode, it's likely that I will end up teaching
the EDMA TX completion code about busy buffers, just to be "sure"
this doesn't creep up.
Tested - iperf ap->sta and sta->ap (with both sides running this code):
* AR5416 STA
* AR9160/AR9220 hostap
To validate that it doesn't break the EDMA (FIFO) chips:
* AR9380, AR9485, AR9462 STA
Using iperf with the -S <tos byte decimal value> to set the TCP client
side DSCP bits, mapping to different TIDs and thus different TX queues.
TODO:
* Make this work on the EDMA chips, if we end up pushing lists of frames
to the hardware (eg how we eventually will handle cabq in hostap/ibss
mode.)
2013-03-14 06:20:02 +00:00
|
|
|
struct ath_buf *axq_holdingbf; /* holding TX buffer */
|
2006-02-09 21:09:26 +00:00
|
|
|
char axq_name[12]; /* e.g. "ath0_txq4" */
|
2011-11-08 17:08:12 +00:00
|
|
|
|
2011-11-08 02:12:11 +00:00
|
|
|
/* Per-TID traffic queue for software -> hardware TX */
|
Overhaul the TXQ locking (again!) as part of some beacon/cabq timing
related issues.
Moving the TX locking under one lock made things easier to progress on
but it had one important side-effect - it increased the latency when
handling CABQ setup when sending beacons.
This commit introduces a bunch of new changes and a few unrelated changs
that are just easier to lump in here.
The aim is to have the CABQ locking separate from other locking.
The CABQ transmit path in the beacon process thus doesn't have to grab
the general TX lock, reducing lock contention/latency and making it
more likely that we'll make the beacon TX timing.
The second half of this commit is the CABQ related setup changes needed
for sane looking EDMA CABQ support. Right now the EDMA TX code naively
assumes that only one frame (MPDU or A-MPDU) is being pushed into each
FIFO slot. For the CABQ this isn't true - a whole list of frames is
being pushed in - and thus CABQ handling breaks very quickly.
The aim here is to setup the CABQ list and then push _that list_ to
the hardware for transmission. I can then extend the EDMA TX code
to stamp that list as being "one" FIFO entry (likely by tagging the
last buffer in that list as "FIFO END") so the EDMA TX completion code
correctly tracks things.
Major:
* Migrate the per-TXQ add/removal locking back to per-TXQ, rather than
a single lock.
* Leave the software queue side of things under the ATH_TX_LOCK lock,
(continuing) to serialise things as they are.
* Add a new function which is called whenever there's a beacon miss,
to print out some debugging. This is primarily designed to help
me figure out if the beacon miss events are due to a noisy environment,
issues with the PHY/MAC, or other.
* Move the CABQ setup/enable to occur _after_ all the VAPs have been
looked at. This means that for multiple VAPS in bursted mode, the
CABQ gets primed once all VAPs are checked, rather than being primed
on the first VAP and then having frames appended after this.
Minor:
* Add a (disabled) twiddle to let me enable/disable cabq traffic.
It's primarily there to let me easily debug what's going on with beacon
and CABQ setup/traffic; there's some DMA engine hangs which I'm finally
trying to trace down.
* Clear bf_next when flushing frames; it should quieten some warnings
that show up when a node goes away.
Tested:
* AR9280, STA/hostap, up to 4 vaps (staggered)
* AR5416, STA/hostap, up to 4 vaps (staggered)
TODO:
* (Lots) more AR9380 and later testing, as I may have missed something here.
* Leverage this to fix CABQ hanling for AR9380 and later chips.
* Force bursted beaconing on the chips that default to staggered beacons and
ensure the CABQ stuff is all sane (eg, the MORE bits that aren't being
correctly set when chaining descriptors.)
2013-03-24 00:03:12 +00:00
|
|
|
/*
|
|
|
|
* This is protected by the general TX path lock, not (for now)
|
|
|
|
* by the TXQ lock.
|
|
|
|
*/
|
2011-11-08 02:12:11 +00:00
|
|
|
TAILQ_HEAD(axq_t_s,ath_tid) axq_tidq;
|
2004-12-08 17:34:36 +00:00
|
|
|
};
|
|
|
|
|
Overhaul the TXQ locking (again!) as part of some beacon/cabq timing
related issues.
Moving the TX locking under one lock made things easier to progress on
but it had one important side-effect - it increased the latency when
handling CABQ setup when sending beacons.
This commit introduces a bunch of new changes and a few unrelated changs
that are just easier to lump in here.
The aim is to have the CABQ locking separate from other locking.
The CABQ transmit path in the beacon process thus doesn't have to grab
the general TX lock, reducing lock contention/latency and making it
more likely that we'll make the beacon TX timing.
The second half of this commit is the CABQ related setup changes needed
for sane looking EDMA CABQ support. Right now the EDMA TX code naively
assumes that only one frame (MPDU or A-MPDU) is being pushed into each
FIFO slot. For the CABQ this isn't true - a whole list of frames is
being pushed in - and thus CABQ handling breaks very quickly.
The aim here is to setup the CABQ list and then push _that list_ to
the hardware for transmission. I can then extend the EDMA TX code
to stamp that list as being "one" FIFO entry (likely by tagging the
last buffer in that list as "FIFO END") so the EDMA TX completion code
correctly tracks things.
Major:
* Migrate the per-TXQ add/removal locking back to per-TXQ, rather than
a single lock.
* Leave the software queue side of things under the ATH_TX_LOCK lock,
(continuing) to serialise things as they are.
* Add a new function which is called whenever there's a beacon miss,
to print out some debugging. This is primarily designed to help
me figure out if the beacon miss events are due to a noisy environment,
issues with the PHY/MAC, or other.
* Move the CABQ setup/enable to occur _after_ all the VAPs have been
looked at. This means that for multiple VAPS in bursted mode, the
CABQ gets primed once all VAPs are checked, rather than being primed
on the first VAP and then having frames appended after this.
Minor:
* Add a (disabled) twiddle to let me enable/disable cabq traffic.
It's primarily there to let me easily debug what's going on with beacon
and CABQ setup/traffic; there's some DMA engine hangs which I'm finally
trying to trace down.
* Clear bf_next when flushing frames; it should quieten some warnings
that show up when a node goes away.
Tested:
* AR9280, STA/hostap, up to 4 vaps (staggered)
* AR5416, STA/hostap, up to 4 vaps (staggered)
TODO:
* (Lots) more AR9380 and later testing, as I may have missed something here.
* Leverage this to fix CABQ hanling for AR9380 and later chips.
* Force bursted beaconing on the chips that default to staggered beacons and
ensure the CABQ stuff is all sane (eg, the MORE bits that aren't being
correctly set when chaining descriptors.)
2013-03-24 00:03:12 +00:00
|
|
|
#define ATH_TXQ_LOCK_INIT(_sc, _tq) do { \
|
|
|
|
snprintf((_tq)->axq_name, sizeof((_tq)->axq_name), "%s_txq%u", \
|
|
|
|
device_get_nameunit((_sc)->sc_dev), (_tq)->axq_qnum); \
|
|
|
|
mtx_init(&(_tq)->axq_lock, (_tq)->axq_name, NULL, MTX_DEF); \
|
|
|
|
} while (0)
|
|
|
|
#define ATH_TXQ_LOCK_DESTROY(_tq) mtx_destroy(&(_tq)->axq_lock)
|
|
|
|
#define ATH_TXQ_LOCK(_tq) mtx_lock(&(_tq)->axq_lock)
|
|
|
|
#define ATH_TXQ_UNLOCK(_tq) mtx_unlock(&(_tq)->axq_lock)
|
|
|
|
#define ATH_TXQ_LOCK_ASSERT(_tq) mtx_assert(&(_tq)->axq_lock, MA_OWNED)
|
2013-05-08 21:23:51 +00:00
|
|
|
#define ATH_TXQ_UNLOCK_ASSERT(_tq) mtx_assert(&(_tq)->axq_lock, \
|
|
|
|
MA_NOTOWNED)
|
Overhaul the TXQ locking (again!) as part of some beacon/cabq timing
related issues.
Moving the TX locking under one lock made things easier to progress on
but it had one important side-effect - it increased the latency when
handling CABQ setup when sending beacons.
This commit introduces a bunch of new changes and a few unrelated changs
that are just easier to lump in here.
The aim is to have the CABQ locking separate from other locking.
The CABQ transmit path in the beacon process thus doesn't have to grab
the general TX lock, reducing lock contention/latency and making it
more likely that we'll make the beacon TX timing.
The second half of this commit is the CABQ related setup changes needed
for sane looking EDMA CABQ support. Right now the EDMA TX code naively
assumes that only one frame (MPDU or A-MPDU) is being pushed into each
FIFO slot. For the CABQ this isn't true - a whole list of frames is
being pushed in - and thus CABQ handling breaks very quickly.
The aim here is to setup the CABQ list and then push _that list_ to
the hardware for transmission. I can then extend the EDMA TX code
to stamp that list as being "one" FIFO entry (likely by tagging the
last buffer in that list as "FIFO END") so the EDMA TX completion code
correctly tracks things.
Major:
* Migrate the per-TXQ add/removal locking back to per-TXQ, rather than
a single lock.
* Leave the software queue side of things under the ATH_TX_LOCK lock,
(continuing) to serialise things as they are.
* Add a new function which is called whenever there's a beacon miss,
to print out some debugging. This is primarily designed to help
me figure out if the beacon miss events are due to a noisy environment,
issues with the PHY/MAC, or other.
* Move the CABQ setup/enable to occur _after_ all the VAPs have been
looked at. This means that for multiple VAPS in bursted mode, the
CABQ gets primed once all VAPs are checked, rather than being primed
on the first VAP and then having frames appended after this.
Minor:
* Add a (disabled) twiddle to let me enable/disable cabq traffic.
It's primarily there to let me easily debug what's going on with beacon
and CABQ setup/traffic; there's some DMA engine hangs which I'm finally
trying to trace down.
* Clear bf_next when flushing frames; it should quieten some warnings
that show up when a node goes away.
Tested:
* AR9280, STA/hostap, up to 4 vaps (staggered)
* AR5416, STA/hostap, up to 4 vaps (staggered)
TODO:
* (Lots) more AR9380 and later testing, as I may have missed something here.
* Leverage this to fix CABQ hanling for AR9380 and later chips.
* Force bursted beaconing on the chips that default to staggered beacons and
ensure the CABQ stuff is all sane (eg, the MORE bits that aren't being
correctly set when chaining descriptors.)
2013-03-24 00:03:12 +00:00
|
|
|
|
|
|
|
|
2011-11-08 02:12:11 +00:00
|
|
|
#define ATH_NODE_LOCK(_an) mtx_lock(&(_an)->an_mtx)
|
|
|
|
#define ATH_NODE_UNLOCK(_an) mtx_unlock(&(_an)->an_mtx)
|
|
|
|
#define ATH_NODE_LOCK_ASSERT(_an) mtx_assert(&(_an)->an_mtx, MA_OWNED)
|
2012-10-03 23:23:45 +00:00
|
|
|
#define ATH_NODE_UNLOCK_ASSERT(_an) mtx_assert(&(_an)->an_mtx, \
|
|
|
|
MA_NOTOWNED)
|
2011-11-08 02:12:11 +00:00
|
|
|
|
2012-10-07 23:45:19 +00:00
|
|
|
/*
|
|
|
|
* These are for the hardware queue.
|
|
|
|
*/
|
2011-11-08 17:08:12 +00:00
|
|
|
#define ATH_TXQ_INSERT_HEAD(_tq, _elm, _field) do { \
|
|
|
|
TAILQ_INSERT_HEAD(&(_tq)->axq_q, (_elm), _field); \
|
|
|
|
(_tq)->axq_depth++; \
|
|
|
|
} while (0)
|
2004-12-08 17:34:36 +00:00
|
|
|
#define ATH_TXQ_INSERT_TAIL(_tq, _elm, _field) do { \
|
2011-11-08 17:08:12 +00:00
|
|
|
TAILQ_INSERT_TAIL(&(_tq)->axq_q, (_elm), _field); \
|
2004-12-08 17:34:36 +00:00
|
|
|
(_tq)->axq_depth++; \
|
|
|
|
} while (0)
|
2011-11-08 17:08:12 +00:00
|
|
|
#define ATH_TXQ_REMOVE(_tq, _elm, _field) do { \
|
|
|
|
TAILQ_REMOVE(&(_tq)->axq_q, _elm, _field); \
|
2004-12-08 17:34:36 +00:00
|
|
|
(_tq)->axq_depth--; \
|
|
|
|
} while (0)
|
2012-08-11 22:20:28 +00:00
|
|
|
#define ATH_TXQ_FIRST(_tq) TAILQ_FIRST(&(_tq)->axq_q)
|
2011-11-08 17:08:12 +00:00
|
|
|
#define ATH_TXQ_LAST(_tq, _field) TAILQ_LAST(&(_tq)->axq_q, _field)
|
2008-04-20 20:35:46 +00:00
|
|
|
|
2012-10-07 23:45:19 +00:00
|
|
|
/*
|
2012-10-14 23:52:30 +00:00
|
|
|
* These are for the TID software queue.
|
2012-10-07 23:45:19 +00:00
|
|
|
*/
|
|
|
|
#define ATH_TID_INSERT_HEAD(_tq, _elm, _field) do { \
|
|
|
|
TAILQ_INSERT_HEAD(&(_tq)->tid_q, (_elm), _field); \
|
|
|
|
(_tq)->axq_depth++; \
|
2013-05-13 19:03:12 +00:00
|
|
|
(_tq)->an->an_swq_depth++; \
|
2012-10-07 23:45:19 +00:00
|
|
|
} while (0)
|
|
|
|
#define ATH_TID_INSERT_TAIL(_tq, _elm, _field) do { \
|
|
|
|
TAILQ_INSERT_TAIL(&(_tq)->tid_q, (_elm), _field); \
|
|
|
|
(_tq)->axq_depth++; \
|
2013-05-13 19:03:12 +00:00
|
|
|
(_tq)->an->an_swq_depth++; \
|
2012-10-07 23:45:19 +00:00
|
|
|
} while (0)
|
|
|
|
#define ATH_TID_REMOVE(_tq, _elm, _field) do { \
|
|
|
|
TAILQ_REMOVE(&(_tq)->tid_q, _elm, _field); \
|
|
|
|
(_tq)->axq_depth--; \
|
2013-05-13 19:03:12 +00:00
|
|
|
(_tq)->an->an_swq_depth--; \
|
2012-10-07 23:45:19 +00:00
|
|
|
} while (0)
|
|
|
|
#define ATH_TID_FIRST(_tq) TAILQ_FIRST(&(_tq)->tid_q)
|
|
|
|
#define ATH_TID_LAST(_tq, _field) TAILQ_LAST(&(_tq)->tid_q, _field)
|
|
|
|
|
2012-10-14 23:52:30 +00:00
|
|
|
/*
|
|
|
|
* These are for the TID filtered frame queue
|
|
|
|
*/
|
|
|
|
#define ATH_TID_FILT_INSERT_HEAD(_tq, _elm, _field) do { \
|
|
|
|
TAILQ_INSERT_HEAD(&(_tq)->filtq.tid_q, (_elm), _field); \
|
|
|
|
(_tq)->axq_depth++; \
|
2013-05-13 19:03:12 +00:00
|
|
|
(_tq)->an->an_swq_depth++; \
|
2012-10-14 23:52:30 +00:00
|
|
|
} while (0)
|
|
|
|
#define ATH_TID_FILT_INSERT_TAIL(_tq, _elm, _field) do { \
|
|
|
|
TAILQ_INSERT_TAIL(&(_tq)->filtq.tid_q, (_elm), _field); \
|
|
|
|
(_tq)->axq_depth++; \
|
2013-05-13 19:03:12 +00:00
|
|
|
(_tq)->an->an_swq_depth++; \
|
2012-10-14 23:52:30 +00:00
|
|
|
} while (0)
|
|
|
|
#define ATH_TID_FILT_REMOVE(_tq, _elm, _field) do { \
|
|
|
|
TAILQ_REMOVE(&(_tq)->filtq.tid_q, _elm, _field); \
|
|
|
|
(_tq)->axq_depth--; \
|
2013-05-13 19:03:12 +00:00
|
|
|
(_tq)->an->an_swq_depth--; \
|
2012-10-14 23:52:30 +00:00
|
|
|
} while (0)
|
|
|
|
#define ATH_TID_FILT_FIRST(_tq) TAILQ_FIRST(&(_tq)->filtq.tid_q)
|
|
|
|
#define ATH_TID_FILT_LAST(_tq, _field) TAILQ_LAST(&(_tq)->filtq.tid_q,_field)
|
|
|
|
|
2008-04-20 20:35:46 +00:00
|
|
|
struct ath_vap {
|
|
|
|
struct ieee80211vap av_vap; /* base class */
|
|
|
|
int av_bslot; /* beacon slot index */
|
|
|
|
struct ath_buf *av_bcbuf; /* beacon buffer */
|
|
|
|
struct ieee80211_beacon_offsets av_boff;/* dynamic update state */
|
|
|
|
struct ath_txq av_mcastq; /* buffered mcast s/w queue */
|
|
|
|
|
|
|
|
void (*av_recv_mgmt)(struct ieee80211_node *,
|
2009-05-20 20:00:40 +00:00
|
|
|
struct mbuf *, int, int, int);
|
2008-04-20 20:35:46 +00:00
|
|
|
int (*av_newstate)(struct ieee80211vap *,
|
|
|
|
enum ieee80211_state, int);
|
|
|
|
void (*av_bmiss)(struct ieee80211vap *);
|
2012-10-03 23:23:45 +00:00
|
|
|
void (*av_node_ps)(struct ieee80211_node *, int);
|
2012-10-28 21:13:12 +00:00
|
|
|
int (*av_set_tim)(struct ieee80211_node *, int);
|
Implement my first cut at "correct" node power-save and
PS-POLL support.
This implements PS-POLL awareness i nthe
* Implement frame "leaking", which allows for a software queue
to be scheduled even though it's asleep
* Track whether a frame has been leaked or not
* Leak out a single non-AMPDU frame when transmitting aggregates
* Queue BAR frames if the node is asleep
* Direct-dispatch the rest of control and management frames.
This allows for things like re-association to occur (which involves
sending probe req/resp as well as assoc request/response) when
the node is asleep and then tries reassociating.
* Limit how many frames can set in the software node queue whilst
the node is asleep. net80211 is already buffering frames for us
so this is mostly just paranoia.
* Add a PS-POLL method which leaks out a frame if there's something
in the software queue, else it calls net80211's ps-poll routine.
Since the ath PS-POLL routine marks the node as having a single frame
to leak, either a software queued frame would leak, OR the next queued
frame would leak. The next queued frame could be something from the
net80211 power save queue, OR it could be a NULL frame from net80211.
TODO:
* Don't transmit further BAR frames (eg via a timeout) if the node is
currently asleep. Otherwise we may end up exhausting management frames
due to the lots of queued BAR frames.
I may just undo this bit later on and direct-dispatch BAR frames
even if the node is asleep.
* It would be nice to burst out a single A-MPDU frame if both ends
support this. I may end adding a FreeBSD IE soon to negotiate
this power save behaviour.
* I should make STAs timeout of power save mode if they've been in power
save for more than a handful of seconds. This way cards that get
"stuck" in power save mode don't stay there for the "inactivity" timeout
in net80211.
* Move the queue depth check into the driver layer (ath_start / ath_transmit)
rather than doing it in the TX path.
* There could be some naughty corner cases with ps-poll leaking.
Specifically, if net80211 generates a NULL data frame whilst another
transmitter sends a normal data frame out net80211 output / transmit,
we need to ensure that the NULL data frame goes out first.
This is one of those things that should occur inside the VAP/ic TX lock.
Grr, more investigations to do..
Tested:
* STA: AR5416, AR9280
* AP: AR5416, AR9280, AR9160
2013-05-15 18:33:05 +00:00
|
|
|
void (*av_recv_pspoll)(struct ieee80211_node *,
|
|
|
|
struct mbuf *);
|
2008-04-20 20:35:46 +00:00
|
|
|
};
|
|
|
|
#define ATH_VAP(vap) ((struct ath_vap *)(vap))
|
2003-06-23 17:01:19 +00:00
|
|
|
|
2006-02-09 21:48:51 +00:00
|
|
|
struct taskqueue;
|
2006-02-09 21:28:11 +00:00
|
|
|
struct ath_tx99;
|
|
|
|
|
2011-11-08 02:12:11 +00:00
|
|
|
/*
|
|
|
|
* Whether to reset the TX/RX queue with or without
|
|
|
|
* a queue flush.
|
|
|
|
*/
|
|
|
|
typedef enum {
|
|
|
|
ATH_RESET_DEFAULT = 0,
|
|
|
|
ATH_RESET_NOLOSS = 1,
|
|
|
|
ATH_RESET_FULL = 2,
|
|
|
|
} ATH_RESET_TYPE;
|
|
|
|
|
2012-07-03 06:59:12 +00:00
|
|
|
struct ath_rx_methods {
|
2013-03-19 19:32:28 +00:00
|
|
|
void (*recv_sched_queue)(struct ath_softc *sc,
|
|
|
|
HAL_RX_QUEUE q, int dosched);
|
|
|
|
void (*recv_sched)(struct ath_softc *sc, int dosched);
|
2012-07-03 06:59:12 +00:00
|
|
|
void (*recv_stop)(struct ath_softc *sc, int dodelay);
|
|
|
|
int (*recv_start)(struct ath_softc *sc);
|
|
|
|
void (*recv_flush)(struct ath_softc *sc);
|
|
|
|
void (*recv_tasklet)(void *arg, int npending);
|
|
|
|
int (*recv_rxbuf_init)(struct ath_softc *sc,
|
|
|
|
struct ath_buf *bf);
|
2012-07-09 08:37:59 +00:00
|
|
|
int (*recv_setup)(struct ath_softc *sc);
|
|
|
|
int (*recv_teardown)(struct ath_softc *sc);
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Represent the current state of the RX FIFO.
|
|
|
|
*/
|
|
|
|
struct ath_rx_edma {
|
|
|
|
struct ath_buf **m_fifo;
|
|
|
|
int m_fifolen;
|
|
|
|
int m_fifo_head;
|
|
|
|
int m_fifo_tail;
|
|
|
|
int m_fifo_depth;
|
|
|
|
struct mbuf *m_rxpending;
|
2012-07-03 06:59:12 +00:00
|
|
|
};
|
|
|
|
|
2012-07-28 04:42:05 +00:00
|
|
|
struct ath_tx_edma_fifo {
|
|
|
|
struct ath_buf **m_fifo;
|
|
|
|
int m_fifolen;
|
|
|
|
int m_fifo_head;
|
|
|
|
int m_fifo_tail;
|
|
|
|
int m_fifo_depth;
|
|
|
|
};
|
|
|
|
|
2012-07-23 03:52:18 +00:00
|
|
|
struct ath_tx_methods {
|
|
|
|
int (*xmit_setup)(struct ath_softc *sc);
|
|
|
|
int (*xmit_teardown)(struct ath_softc *sc);
|
2012-07-31 03:09:48 +00:00
|
|
|
void (*xmit_attach_comp_func)(struct ath_softc *sc);
|
|
|
|
|
|
|
|
void (*xmit_dma_restart)(struct ath_softc *sc,
|
|
|
|
struct ath_txq *txq);
|
|
|
|
void (*xmit_handoff)(struct ath_softc *sc,
|
|
|
|
struct ath_txq *txq, struct ath_buf *bf);
|
2012-08-12 00:37:29 +00:00
|
|
|
void (*xmit_drain)(struct ath_softc *sc,
|
|
|
|
ATH_RESET_TYPE reset_type);
|
2012-07-23 03:52:18 +00:00
|
|
|
};
|
|
|
|
|
2003-06-23 17:01:19 +00:00
|
|
|
struct ath_softc {
|
2005-06-10 16:49:24 +00:00
|
|
|
struct ifnet *sc_ifp; /* interface common */
|
2004-12-08 17:34:36 +00:00
|
|
|
struct ath_stats sc_stats; /* interface statistics */
|
2011-11-08 02:12:11 +00:00
|
|
|
struct ath_tx_aggr_stats sc_aggr_stats;
|
2012-04-10 07:23:37 +00:00
|
|
|
struct ath_intr_stats sc_intr_stats;
|
2012-05-15 23:39:37 +00:00
|
|
|
uint64_t sc_debug;
|
2012-09-24 20:35:56 +00:00
|
|
|
uint64_t sc_ktrdebug;
|
2008-04-20 20:35:46 +00:00
|
|
|
int sc_nvaps; /* # vaps */
|
|
|
|
int sc_nstavaps; /* # station vaps */
|
2009-07-21 19:01:04 +00:00
|
|
|
int sc_nmeshvaps; /* # mbss vaps */
|
2008-04-20 20:35:46 +00:00
|
|
|
u_int8_t sc_hwbssidmask[IEEE80211_ADDR_LEN];
|
|
|
|
u_int8_t sc_nbssid0; /* # vap's using base mac */
|
|
|
|
uint32_t sc_bssidmask; /* bssid mask */
|
|
|
|
|
2012-07-03 06:59:12 +00:00
|
|
|
struct ath_rx_methods sc_rx;
|
2012-07-19 03:18:15 +00:00
|
|
|
struct ath_rx_edma sc_rxedma[HAL_NUM_RX_QUEUES]; /* HP/LP queues */
|
2013-04-16 20:21:02 +00:00
|
|
|
ath_bufhead sc_rx_rxlist[HAL_NUM_RX_QUEUES]; /* deferred RX completion */
|
2012-07-23 03:52:18 +00:00
|
|
|
struct ath_tx_methods sc_tx;
|
2012-07-28 04:42:05 +00:00
|
|
|
struct ath_tx_edma_fifo sc_txedma[HAL_NUM_TX_QUEUES];
|
2012-07-23 03:52:18 +00:00
|
|
|
|
Implement frame (data) transmission using if_transmit(), rather than
if_start().
This removes the overlapping data path TX from occuring, which
solves quite a number of the potential TX queue races in ath(4).
It doesn't fix the net80211 layer TX queue races and it doesn't
fix the raw TX path yet, but it's an important step towards this.
This hasn't dropped the TX performance in my testing; primarily
because now the TX path can quickly queue frames and continue
along processing.
This involves a few rather deep changes:
* Use the ath_buf as a queue placeholder for now, as we need to be
able to support queuing a list of mbufs (ie, when transmitting
fragments) and m_nextpkt can't be used here (because it's what is
joining the fragments together)
* if_transmit() now simply allocates the ath_buf and queues it to
a driver TX staging queue.
* TX is now moved into a taskqueue function.
* The TX taskqueue function now dequeues and transmits frames.
* Fragments are handled correctly here - as the current API passes
the fragment list as one mbuf list (joined with m_nextpkt) through
to the driver if_transmit().
* For the couple of places where ath_start() may be called (mostly
from net80211 when starting the VAP up again), just reimplement
it using the new enqueue and taskqueue methods.
What I don't like (about this work and the TX code in general):
* I'm using the same lock for the staging TX queue management and the
actual TX. This isn't required; I'm just being slack.
* I haven't yet moved TX to a separate taskqueue (but the taskqueue is
created); it's easy enough to do this later if necessary. I just need
to make sure it's a higher priority queue, so TX has the same
behaviour as it used to (where it would preempt existing RX..)
* I need to re-review the TX path a little more and make sure that
ieee80211_node_*() functions aren't called within the TX lock.
When queueing, I should just push failed frames into a queue and
when I'm wrapping up the TX code, unlock the TX lock and
call ieee80211_node_free() on each.
* It would be nice if I could hold the TX lock for the entire
TX and TX completion, rather than this release/re-acquire behaviour.
But that requires that I shuffle around the TX completion code
to handle actual ath_buf free and net80211 callback/free outside
of the TX lock. That's one of my next projects.
* the ic_raw_xmit() path doesn't use this yet - so it still has
sequencing problems with parallel, overlapping calls to the
data path. I'll fix this later.
Tested:
* Hostap - AR9280, AR9220
* STA - AR5212, AR9280, AR5416
2013-01-15 18:01:23 +00:00
|
|
|
/*
|
|
|
|
* This is (currently) protected by the TX queue lock;
|
|
|
|
* it should migrate to a separate lock later
|
|
|
|
* so as to minimise contention.
|
|
|
|
*/
|
|
|
|
ath_bufhead sc_txbuf_list;
|
|
|
|
|
2012-07-09 08:37:59 +00:00
|
|
|
int sc_rx_statuslen;
|
|
|
|
int sc_tx_desclen;
|
|
|
|
int sc_tx_statuslen;
|
|
|
|
int sc_tx_nmaps; /* Number of TX maps */
|
|
|
|
int sc_edma_bufsize;
|
2012-07-03 06:59:12 +00:00
|
|
|
|
2011-11-08 02:12:11 +00:00
|
|
|
void (*sc_node_cleanup)(struct ieee80211_node *);
|
2004-12-08 17:34:36 +00:00
|
|
|
void (*sc_node_free)(struct ieee80211_node *);
|
2003-06-23 17:01:19 +00:00
|
|
|
device_t sc_dev;
|
2006-06-05 17:51:20 +00:00
|
|
|
HAL_BUS_TAG sc_st; /* bus space tag */
|
|
|
|
HAL_BUS_HANDLE sc_sh; /* bus space handle */
|
2003-06-23 17:01:19 +00:00
|
|
|
bus_dma_tag_t sc_dmat; /* bus DMA tag */
|
|
|
|
struct mtx sc_mtx; /* master lock (recursive) */
|
2011-11-08 02:12:11 +00:00
|
|
|
struct mtx sc_pcu_mtx; /* PCU access mutex */
|
|
|
|
char sc_pcu_mtx_name[32];
|
2012-07-14 02:22:17 +00:00
|
|
|
struct mtx sc_rx_mtx; /* RX access mutex */
|
|
|
|
char sc_rx_mtx_name[32];
|
2013-02-07 07:50:16 +00:00
|
|
|
struct mtx sc_tx_mtx; /* TX handling/comp mutex */
|
2012-10-31 06:27:58 +00:00
|
|
|
char sc_tx_mtx_name[32];
|
2013-02-07 07:50:16 +00:00
|
|
|
struct mtx sc_tx_ic_mtx; /* TX queue mutex */
|
|
|
|
char sc_tx_ic_mtx_name[32];
|
2006-02-09 21:48:51 +00:00
|
|
|
struct taskqueue *sc_tq; /* private task queue */
|
2003-06-23 17:01:19 +00:00
|
|
|
struct ath_hal *sc_ah; /* Atheros HAL */
|
2004-12-08 17:34:36 +00:00
|
|
|
struct ath_ratectrl *sc_rc; /* tx rate control support */
|
2006-02-09 21:28:11 +00:00
|
|
|
struct ath_tx99 *sc_tx99; /* tx99 adjunct state */
|
2004-12-08 17:34:36 +00:00
|
|
|
void (*sc_setdefantenna)(struct ath_softc *, u_int);
|
2012-11-03 22:12:35 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* First set of flags.
|
|
|
|
*/
|
|
|
|
uint32_t sc_invalid : 1,/* disable hardware accesses */
|
2008-04-20 20:35:46 +00:00
|
|
|
sc_mrretry : 1,/* multi-rate retry support */
|
2012-07-31 23:54:15 +00:00
|
|
|
sc_mrrprot : 1,/* MRR + protection support */
|
2008-04-20 20:35:46 +00:00
|
|
|
sc_softled : 1,/* enable LED gpio status */
|
Flesh out configurable hardware based LED blinking.
The hardware (MAC) LED blinking involves a few things:
* Selecting which GPIO pins map to the MAC "power" and "network" lines;
* Configuring the MAC LED state (associated, scanning, idle);
* Configuring the MAC LED blinking type and speed.
The AR5416 HAL configures the normal blinking setup - ie, blink rate based
on TX/RX throughput. The default AR5212 HAL doesn't program in any
specific blinking type, but the default of 0 is the same.
This code introduces a few things:
* The hardware led override is configured via sysctl 'hardled';
* The MAC network and power LED GPIO lines can be set, or left at -1
if needed. This is intended to allow only one of the hardware MUX
entries to be configured (eg for PCIe cards which only have one LED
exposed.)
TODO:
* For AR2417, the software LED blinking involves software blinking the
Network LED. For the AR5416 and later, this can just be configured
as a GPIO output line. I'll chase that up with a subsequent commit.
* Add another software LED blink for "Link", separate from "activity",
which blinks based on the association state. This would make my
D-Link DWA-552 have consistent and useful LED behaviour (as they're
marked "Link" and "Activity."
* Don't expose the hardware LED override unless it's an AR5416 or later,
as the previous generation hardware doesn't have this multiplexing
setup.
2011-12-26 07:47:05 +00:00
|
|
|
sc_hardled : 1,/* enable MAC LED status */
|
2008-04-20 20:35:46 +00:00
|
|
|
sc_splitmic : 1,/* split TKIP MIC keys */
|
|
|
|
sc_needmib : 1,/* enable MIB stats intr */
|
|
|
|
sc_diversity: 1,/* enable rx diversity */
|
|
|
|
sc_hasveol : 1,/* tx VEOL support */
|
|
|
|
sc_ledstate : 1,/* LED on/off state */
|
|
|
|
sc_blinking : 1,/* LED blink operation active */
|
|
|
|
sc_mcastkey : 1,/* mcast key cache search */
|
|
|
|
sc_scanning : 1,/* scanning active */
|
2006-02-09 22:21:53 +00:00
|
|
|
sc_syncbeacon:1,/* sync/resync beacon timers */
|
2008-04-20 20:35:46 +00:00
|
|
|
sc_hasclrkey: 1,/* CLR key supported */
|
2006-12-27 19:07:09 +00:00
|
|
|
sc_xchanmode: 1,/* extended channel mode */
|
Update 802.11 wireless support:
o major overhaul of the way channels are handled: channels are now
fully enumerated and uniquely identify the operating characteristics;
these changes are visible to user applications which require changes
o make scanning support independent of the state machine to enable
background scanning and roaming
o move scanning support into loadable modules based on the operating
mode to enable different policies and reduce the memory footprint
on systems w/ constrained resources
o add background scanning in station mode (no support for adhoc/ibss
mode yet)
o significantly speedup sta mode scanning with a variety of techniques
o add roaming support when background scanning is supported; for now
we use a simple algorithm to trigger a roam: we threshold the rssi
and tx rate, if either drops too low we try to roam to a new ap
o add tx fragmentation support
o add first cut at 802.11n support: this code works with forthcoming
drivers but is incomplete; it's included now to establish a baseline
for other drivers to be developed and for user applications
o adjust max_linkhdr et. al. to reflect 802.11 requirements; this eliminates
prepending mbufs for traffic generated locally
o add support for Atheros protocol extensions; mainly the fast frames
encapsulation (note this can be used with any card that can tx+rx
large frames correctly)
o add sta support for ap's that beacon both WPA1+2 support
o change all data types from bsd-style to posix-style
o propagate noise floor data from drivers to net80211 and on to user apps
o correct various issues in the sta mode state machine related to handling
authentication and association failures
o enable the addition of sta mode power save support for drivers that need
net80211 support (not in this commit)
o remove old WI compatibility ioctls (wicontrol is officially dead)
o change the data structures returned for get sta info and get scan
results so future additions will not break user apps
o fixed tx rate is now maintained internally as an ieee rate and not an
index into the rate set; this needs to be extended to deal with
multi-mode operation
o add extended channel specifications to radiotap to enable 11n sniffing
Drivers:
o ath: add support for bg scanning, tx fragmentation, fast frames,
dynamic turbo (lightly tested), 11n (sniffing only and needs
new hal)
o awi: compile tested only
o ndis: lightly tested
o ipw: lightly tested
o iwi: add support for bg scanning (well tested but may have some
rough edges)
o ral, ural, rum: add suppoort for bg scanning, calibrate rssi data
o wi: lightly tested
This work is based on contributions by Atheros, kmacy, sephe, thompsa,
mlaier, kevlo, and others. Much of the scanning work was supported by
Atheros. The 11n work was supported by Marvell.
2007-06-11 03:36:55 +00:00
|
|
|
sc_outdoor : 1,/* outdoor operation */
|
2008-04-20 20:35:46 +00:00
|
|
|
sc_dturbo : 1,/* dynamic turbo in use */
|
|
|
|
sc_hasbmask : 1,/* bssid mask support */
|
Implementation of the upcoming Wireless Mesh standard, 802.11s, on the
net80211 wireless stack. This work is based on the March 2009 D3.0 draft
standard. This standard is expected to become final next year.
This includes two main net80211 modules, ieee80211_mesh.c
which deals with peer link management, link metric calculation,
routing table control and mesh configuration and ieee80211_hwmp.c
which deals with the actually routing process on the mesh network.
HWMP is the mandatory routing protocol on by the mesh standard, but
others, such as RA-OLSR, can be implemented.
Authentication and encryption are not implemented.
There are several scripts under tools/tools/net80211/scripts that can be
used to test different mesh network topologies and they also teach you
how to setup a mesh vap (for the impatient: ifconfig wlan0 create
wlandev ... wlanmode mesh).
A new build option is available: IEEE80211_SUPPORT_MESH and it's enabled
by default on GENERIC kernels for i386, amd64, sparc64 and pc98.
Drivers that support mesh networks right now are: ath, ral and mwl.
More information at: http://wiki.freebsd.org/WifiMesh
Please note that this work is experimental. Also, please note that
bridging a mesh vap with another network interface is not yet supported.
Many thanks to the FreeBSD Foundation for sponsoring this project and to
Sam Leffler for his support.
Also, I would like to thank Gateworks Corporation for sending me a
Cambria board which was used during the development of this project.
Reviewed by: sam
Approved by: re (kensmith)
Obtained from: projects/mesh11s
2009-07-11 15:02:45 +00:00
|
|
|
sc_hasbmatch: 1,/* bssid match disable support*/
|
2008-04-20 20:35:46 +00:00
|
|
|
sc_hastsfadd: 1,/* tsf adjust support */
|
|
|
|
sc_beacons : 1,/* beacons running */
|
|
|
|
sc_swbmiss : 1,/* sta mode using sw bmiss */
|
|
|
|
sc_stagbeacons:1,/* use staggered beacons */
|
2008-05-29 00:10:48 +00:00
|
|
|
sc_wmetkipmic:1,/* can do WME+TKIP MIC */
|
2008-12-07 19:26:34 +00:00
|
|
|
sc_resume_up: 1,/* on resume, start all vaps */
|
2009-01-08 17:12:47 +00:00
|
|
|
sc_tdma : 1,/* TDMA in use */
|
2009-03-05 00:15:43 +00:00
|
|
|
sc_setcca : 1,/* set/clr CCA with TDMA */
|
2011-04-04 14:52:31 +00:00
|
|
|
sc_resetcal : 1,/* reset cal state next trip */
|
Fix a corner case in RXEOL handling which was likely introduced by yours
truly.
Before 802.11n, the RX descriptor list would employ the "self-linked tail
descriptor" trick which linked the last descriptor back to itself.
This way, the RX engine would never hit the "end" of the list and stop
processing RX (and assert RXEOL) as it never hit a descriptor whose next
pointer was 0. It would just keep overwriting the last descriptor until
the software freed up some more RX descriptors and chained them onto the
end.
For 802.11n, this needs to stop as a self-linked RX descriptor tickles the
block-ack logic into ACK'ing whatever frames are received into that
self-linked descriptor - so in very busy periods, you could end up with
A-MPDU traffic that is ACKed but never received by the 802.11 stack.
This would cause some confusion as the ADDBA windows would suddenly
be out of sync.
So when that occured here, the last descriptor would be hit and the PCU
logic would stop. It would only start again when the RX descriptor list
was updated and the PCU RX engine was re-tickled. That wasn't being done,
so RXEOL would be continuously asserted and no RX would continue.
This patch introduces a new flag - sc->sc_kickpcu - which when set,
signals the RX task to kick the PCU after its processed whatever packets
it can. This way completed packets aren't discarded.
In case some other task gets called which resets the hardware, don't
update sc->sc_imask - instead, just update the hardware interrupt mask
directly and let either ath_rx_proc() or ath_reset() restore the imask
to its former setting.
Note: this bug was only triggered when doing a whole lot of frame snooping
with serial console IO in the RX task. This would defer interrupt processing
enough to cause an RX descriptor overflow. It doesn't happen in normal
conditions.
Approved by: re (kib, blanket)
2011-08-02 02:46:03 +00:00
|
|
|
sc_rxslink : 1,/* do self-linked final descriptor */
|
2012-07-09 08:37:59 +00:00
|
|
|
sc_rxtsf32 : 1,/* RX dec TSF is 32 bits */
|
Bring over some initial power save management support, reset path
fixes and beacon programming / debugging into the ath(4) driver.
The basic power save tracking:
* Add some new code to track the current desired powersave state; and
* Add some reference count tracking so we know when the NIC is awake; then
* Add code in all the points where we're about to touch the hardware and
push it to force-wake.
Then, how things are moved into power save:
* Only move into network-sleep during a RUN->SLEEP transition;
* Force wake the hardware up everywhere that we're about to touch
the hardware.
The net80211 stack takes care of doing RUN<->SLEEP<->(other) state
transitions so we don't have to do it in the driver.
Next, when to wake things up:
* In short - everywhere we touch the hardware.
* The hardware will take care of staying awake if things are queued
in the transmit queue(s); it'll then transit down to sleep if
there's nothing left. This way we don't have to track the
software / hardware transmit queue(s) and keep the hardware
awake for those.
Then, some transmit path fixes that aren't related but useful:
* Force EAPOL frames to go out at the lowest rate. This improves
reliability during the encryption handshake after 802.11
negotiation.
Next, some reset path fixes!
* Fix the overlap between reset and transmit pause so we don't
transmit frames during a reset.
* Some noisy environments will end up taking a lot longer to reset
than normal, so extend the reset period and drop the raise the
reset interval to be more realistic and give the hardware some
time to finish calibration.
* Skip calibration during the reset path. Tsk!
Then, beacon fixes in station mode!
* Add a _lot_ more debugging in the station beacon reset path.
This is all quite fluid right now.
* Modify the STA beacon programming code to try and take
the TU gap between desired TSF and the target TU into
account. (Lifted from QCA.)
Tested:
* AR5210
* AR5211
* AR5212
* AR5413
* AR5416
* AR9280
* AR9285
TODO:
* More AP, IBSS, mesh, TDMA testing
* Thorough AR9380 and later testing!
* AR9160 and AR9287 testing
Obtained from: QCA
2014-04-30 02:19:41 +00:00
|
|
|
sc_isedma : 1,/* supports EDMA */
|
|
|
|
sc_do_mybeacon : 1; /* supports mybeacon */
|
2012-11-03 22:12:35 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Second set of flags.
|
|
|
|
*/
|
2013-02-27 00:25:44 +00:00
|
|
|
u_int32_t sc_use_ent : 1,
|
|
|
|
sc_rx_stbc : 1,
|
Enable the use of TDMA on an 802.11n channel (with aggregation disabled,
of course.)
There's a few things that needed to happen:
* In case someone decides to set the beacon transmission rate to be
at an MCS rate, use the MCS-aware version of the duration calculation
to figure out how long the received beacon frame was.
* If TxOP enforcing is available on the hardware and we're doing TDMA,
enable it after a reset and set the TDMA guard interval to zero.
This seems to behave fine.
TODO:
* Although I haven't yet seen packet loss, the PHY errors that would be
triggered (specifically Transmit-Override-Receive) aren't enabled
by the 11n HAL. I'll have to do some work to enable these PHY errors
for debugging.
What broke:
* My recent changes to the TX queue handling has resulted in the driver
not keeping the hardware queue properly filled when doing non-aggregate
traffic. I have a patch to commit soon which fixes this situation
(albeit by reminding me about how my ath driver locking isn't working
out, sigh.)
So if you want to test this without updating to the next set of patches
that I commit, just bump the sysctl dev.ath.X.hwq_limit from 2 to 32.
Tested:
* AR5416 <-> AR5416, with ampdu disabled, HT40, 5GHz, MCS12+Short-GI.
I saw 30mbit/sec in both directions using a bidirectional UDP test.
2013-05-21 18:02:54 +00:00
|
|
|
sc_tx_stbc : 1,
|
2013-06-05 00:45:19 +00:00
|
|
|
sc_hasenforcetxop : 1, /* support enforce TxOP */
|
2013-06-12 14:52:57 +00:00
|
|
|
sc_hasdivcomb : 1, /* RX diversity combining */
|
2013-06-05 00:45:19 +00:00
|
|
|
sc_rx_lnamixer : 1; /* RX using LNA mixing */
|
Overhaul the TXQ locking (again!) as part of some beacon/cabq timing
related issues.
Moving the TX locking under one lock made things easier to progress on
but it had one important side-effect - it increased the latency when
handling CABQ setup when sending beacons.
This commit introduces a bunch of new changes and a few unrelated changs
that are just easier to lump in here.
The aim is to have the CABQ locking separate from other locking.
The CABQ transmit path in the beacon process thus doesn't have to grab
the general TX lock, reducing lock contention/latency and making it
more likely that we'll make the beacon TX timing.
The second half of this commit is the CABQ related setup changes needed
for sane looking EDMA CABQ support. Right now the EDMA TX code naively
assumes that only one frame (MPDU or A-MPDU) is being pushed into each
FIFO slot. For the CABQ this isn't true - a whole list of frames is
being pushed in - and thus CABQ handling breaks very quickly.
The aim here is to setup the CABQ list and then push _that list_ to
the hardware for transmission. I can then extend the EDMA TX code
to stamp that list as being "one" FIFO entry (likely by tagging the
last buffer in that list as "FIFO END") so the EDMA TX completion code
correctly tracks things.
Major:
* Migrate the per-TXQ add/removal locking back to per-TXQ, rather than
a single lock.
* Leave the software queue side of things under the ATH_TX_LOCK lock,
(continuing) to serialise things as they are.
* Add a new function which is called whenever there's a beacon miss,
to print out some debugging. This is primarily designed to help
me figure out if the beacon miss events are due to a noisy environment,
issues with the PHY/MAC, or other.
* Move the CABQ setup/enable to occur _after_ all the VAPs have been
looked at. This means that for multiple VAPS in bursted mode, the
CABQ gets primed once all VAPs are checked, rather than being primed
on the first VAP and then having frames appended after this.
Minor:
* Add a (disabled) twiddle to let me enable/disable cabq traffic.
It's primarily there to let me easily debug what's going on with beacon
and CABQ setup/traffic; there's some DMA engine hangs which I'm finally
trying to trace down.
* Clear bf_next when flushing frames; it should quieten some warnings
that show up when a node goes away.
Tested:
* AR9280, STA/hostap, up to 4 vaps (staggered)
* AR5416, STA/hostap, up to 4 vaps (staggered)
TODO:
* (Lots) more AR9380 and later testing, as I may have missed something here.
* Leverage this to fix CABQ hanling for AR9380 and later chips.
* Force bursted beaconing on the chips that default to staggered beacons and
ensure the CABQ stuff is all sane (eg, the MORE bits that aren't being
correctly set when chaining descriptors.)
2013-03-24 00:03:12 +00:00
|
|
|
|
|
|
|
int sc_cabq_enable; /* Enable cabq transmission */
|
|
|
|
|
2012-11-03 22:12:35 +00:00
|
|
|
/*
|
|
|
|
* Enterprise mode configuration for AR9380 and later chipsets.
|
|
|
|
*/
|
|
|
|
uint32_t sc_ent_cfg;
|
|
|
|
|
2008-05-03 21:52:05 +00:00
|
|
|
uint32_t sc_eerd; /* regdomain from EEPROM */
|
|
|
|
uint32_t sc_eecc; /* country code from EEPROM */
|
2003-06-23 17:01:19 +00:00
|
|
|
/* rate tables */
|
2009-02-19 05:22:40 +00:00
|
|
|
const HAL_RATE_TABLE *sc_rates[IEEE80211_MODE_MAX];
|
2003-06-23 17:01:19 +00:00
|
|
|
const HAL_RATE_TABLE *sc_currates; /* current rate table */
|
|
|
|
enum ieee80211_phymode sc_curmode; /* current phy mode */
|
2006-02-09 21:42:53 +00:00
|
|
|
HAL_OPMODE sc_opmode; /* current operating mode */
|
2004-12-08 17:34:36 +00:00
|
|
|
u_int16_t sc_curtxpow; /* current tx power limit */
|
Update 802.11 wireless support:
o major overhaul of the way channels are handled: channels are now
fully enumerated and uniquely identify the operating characteristics;
these changes are visible to user applications which require changes
o make scanning support independent of the state machine to enable
background scanning and roaming
o move scanning support into loadable modules based on the operating
mode to enable different policies and reduce the memory footprint
on systems w/ constrained resources
o add background scanning in station mode (no support for adhoc/ibss
mode yet)
o significantly speedup sta mode scanning with a variety of techniques
o add roaming support when background scanning is supported; for now
we use a simple algorithm to trigger a roam: we threshold the rssi
and tx rate, if either drops too low we try to roam to a new ap
o add tx fragmentation support
o add first cut at 802.11n support: this code works with forthcoming
drivers but is incomplete; it's included now to establish a baseline
for other drivers to be developed and for user applications
o adjust max_linkhdr et. al. to reflect 802.11 requirements; this eliminates
prepending mbufs for traffic generated locally
o add support for Atheros protocol extensions; mainly the fast frames
encapsulation (note this can be used with any card that can tx+rx
large frames correctly)
o add sta support for ap's that beacon both WPA1+2 support
o change all data types from bsd-style to posix-style
o propagate noise floor data from drivers to net80211 and on to user apps
o correct various issues in the sta mode state machine related to handling
authentication and association failures
o enable the addition of sta mode power save support for drivers that need
net80211 support (not in this commit)
o remove old WI compatibility ioctls (wicontrol is officially dead)
o change the data structures returned for get sta info and get scan
results so future additions will not break user apps
o fixed tx rate is now maintained internally as an ieee rate and not an
index into the rate set; this needs to be extended to deal with
multi-mode operation
o add extended channel specifications to radiotap to enable 11n sniffing
Drivers:
o ath: add support for bg scanning, tx fragmentation, fast frames,
dynamic turbo (lightly tested), 11n (sniffing only and needs
new hal)
o awi: compile tested only
o ndis: lightly tested
o ipw: lightly tested
o iwi: add support for bg scanning (well tested but may have some
rough edges)
o ral, ural, rum: add suppoort for bg scanning, calibrate rssi data
o wi: lightly tested
This work is based on contributions by Atheros, kmacy, sephe, thompsa,
mlaier, kevlo, and others. Much of the scanning work was supported by
Atheros. The 11n work was supported by Marvell.
2007-06-11 03:36:55 +00:00
|
|
|
u_int16_t sc_curaid; /* current association id */
|
2009-01-28 18:00:22 +00:00
|
|
|
struct ieee80211_channel *sc_curchan; /* current installed channel */
|
Update 802.11 wireless support:
o major overhaul of the way channels are handled: channels are now
fully enumerated and uniquely identify the operating characteristics;
these changes are visible to user applications which require changes
o make scanning support independent of the state machine to enable
background scanning and roaming
o move scanning support into loadable modules based on the operating
mode to enable different policies and reduce the memory footprint
on systems w/ constrained resources
o add background scanning in station mode (no support for adhoc/ibss
mode yet)
o significantly speedup sta mode scanning with a variety of techniques
o add roaming support when background scanning is supported; for now
we use a simple algorithm to trigger a roam: we threshold the rssi
and tx rate, if either drops too low we try to roam to a new ap
o add tx fragmentation support
o add first cut at 802.11n support: this code works with forthcoming
drivers but is incomplete; it's included now to establish a baseline
for other drivers to be developed and for user applications
o adjust max_linkhdr et. al. to reflect 802.11 requirements; this eliminates
prepending mbufs for traffic generated locally
o add support for Atheros protocol extensions; mainly the fast frames
encapsulation (note this can be used with any card that can tx+rx
large frames correctly)
o add sta support for ap's that beacon both WPA1+2 support
o change all data types from bsd-style to posix-style
o propagate noise floor data from drivers to net80211 and on to user apps
o correct various issues in the sta mode state machine related to handling
authentication and association failures
o enable the addition of sta mode power save support for drivers that need
net80211 support (not in this commit)
o remove old WI compatibility ioctls (wicontrol is officially dead)
o change the data structures returned for get sta info and get scan
results so future additions will not break user apps
o fixed tx rate is now maintained internally as an ieee rate and not an
index into the rate set; this needs to be extended to deal with
multi-mode operation
o add extended channel specifications to radiotap to enable 11n sniffing
Drivers:
o ath: add support for bg scanning, tx fragmentation, fast frames,
dynamic turbo (lightly tested), 11n (sniffing only and needs
new hal)
o awi: compile tested only
o ndis: lightly tested
o ipw: lightly tested
o iwi: add support for bg scanning (well tested but may have some
rough edges)
o ral, ural, rum: add suppoort for bg scanning, calibrate rssi data
o wi: lightly tested
This work is based on contributions by Atheros, kmacy, sephe, thompsa,
mlaier, kevlo, and others. Much of the scanning work was supported by
Atheros. The 11n work was supported by Marvell.
2007-06-11 03:36:55 +00:00
|
|
|
u_int8_t sc_curbssid[IEEE80211_ADDR_LEN];
|
2003-06-23 17:01:19 +00:00
|
|
|
u_int8_t sc_rixmap[256]; /* IEEE to h/w rate table ix */
|
2005-01-18 19:03:04 +00:00
|
|
|
struct {
|
|
|
|
u_int8_t ieeerate; /* IEEE rate */
|
2005-01-24 20:31:24 +00:00
|
|
|
u_int8_t rxflags; /* radiotap rx flags */
|
|
|
|
u_int8_t txflags; /* radiotap tx flags */
|
2005-01-18 19:03:04 +00:00
|
|
|
u_int16_t ledon; /* softled on time */
|
|
|
|
u_int16_t ledoff; /* softled off time */
|
|
|
|
} sc_hwmap[32]; /* h/w rate ix mappings */
|
2004-12-08 17:34:36 +00:00
|
|
|
u_int8_t sc_protrix; /* protection rate index */
|
Update 802.11 wireless support:
o major overhaul of the way channels are handled: channels are now
fully enumerated and uniquely identify the operating characteristics;
these changes are visible to user applications which require changes
o make scanning support independent of the state machine to enable
background scanning and roaming
o move scanning support into loadable modules based on the operating
mode to enable different policies and reduce the memory footprint
on systems w/ constrained resources
o add background scanning in station mode (no support for adhoc/ibss
mode yet)
o significantly speedup sta mode scanning with a variety of techniques
o add roaming support when background scanning is supported; for now
we use a simple algorithm to trigger a roam: we threshold the rssi
and tx rate, if either drops too low we try to roam to a new ap
o add tx fragmentation support
o add first cut at 802.11n support: this code works with forthcoming
drivers but is incomplete; it's included now to establish a baseline
for other drivers to be developed and for user applications
o adjust max_linkhdr et. al. to reflect 802.11 requirements; this eliminates
prepending mbufs for traffic generated locally
o add support for Atheros protocol extensions; mainly the fast frames
encapsulation (note this can be used with any card that can tx+rx
large frames correctly)
o add sta support for ap's that beacon both WPA1+2 support
o change all data types from bsd-style to posix-style
o propagate noise floor data from drivers to net80211 and on to user apps
o correct various issues in the sta mode state machine related to handling
authentication and association failures
o enable the addition of sta mode power save support for drivers that need
net80211 support (not in this commit)
o remove old WI compatibility ioctls (wicontrol is officially dead)
o change the data structures returned for get sta info and get scan
results so future additions will not break user apps
o fixed tx rate is now maintained internally as an ieee rate and not an
index into the rate set; this needs to be extended to deal with
multi-mode operation
o add extended channel specifications to radiotap to enable 11n sniffing
Drivers:
o ath: add support for bg scanning, tx fragmentation, fast frames,
dynamic turbo (lightly tested), 11n (sniffing only and needs
new hal)
o awi: compile tested only
o ndis: lightly tested
o ipw: lightly tested
o iwi: add support for bg scanning (well tested but may have some
rough edges)
o ral, ural, rum: add suppoort for bg scanning, calibrate rssi data
o wi: lightly tested
This work is based on contributions by Atheros, kmacy, sephe, thompsa,
mlaier, kevlo, and others. Much of the scanning work was supported by
Atheros. The 11n work was supported by Marvell.
2007-06-11 03:36:55 +00:00
|
|
|
u_int8_t sc_lastdatarix; /* last data frame rate index */
|
2006-02-09 21:15:36 +00:00
|
|
|
u_int sc_mcastrate; /* ieee rate for mcastrateix */
|
Update 802.11 wireless support:
o major overhaul of the way channels are handled: channels are now
fully enumerated and uniquely identify the operating characteristics;
these changes are visible to user applications which require changes
o make scanning support independent of the state machine to enable
background scanning and roaming
o move scanning support into loadable modules based on the operating
mode to enable different policies and reduce the memory footprint
on systems w/ constrained resources
o add background scanning in station mode (no support for adhoc/ibss
mode yet)
o significantly speedup sta mode scanning with a variety of techniques
o add roaming support when background scanning is supported; for now
we use a simple algorithm to trigger a roam: we threshold the rssi
and tx rate, if either drops too low we try to roam to a new ap
o add tx fragmentation support
o add first cut at 802.11n support: this code works with forthcoming
drivers but is incomplete; it's included now to establish a baseline
for other drivers to be developed and for user applications
o adjust max_linkhdr et. al. to reflect 802.11 requirements; this eliminates
prepending mbufs for traffic generated locally
o add support for Atheros protocol extensions; mainly the fast frames
encapsulation (note this can be used with any card that can tx+rx
large frames correctly)
o add sta support for ap's that beacon both WPA1+2 support
o change all data types from bsd-style to posix-style
o propagate noise floor data from drivers to net80211 and on to user apps
o correct various issues in the sta mode state machine related to handling
authentication and association failures
o enable the addition of sta mode power save support for drivers that need
net80211 support (not in this commit)
o remove old WI compatibility ioctls (wicontrol is officially dead)
o change the data structures returned for get sta info and get scan
results so future additions will not break user apps
o fixed tx rate is now maintained internally as an ieee rate and not an
index into the rate set; this needs to be extended to deal with
multi-mode operation
o add extended channel specifications to radiotap to enable 11n sniffing
Drivers:
o ath: add support for bg scanning, tx fragmentation, fast frames,
dynamic turbo (lightly tested), 11n (sniffing only and needs
new hal)
o awi: compile tested only
o ndis: lightly tested
o ipw: lightly tested
o iwi: add support for bg scanning (well tested but may have some
rough edges)
o ral, ural, rum: add suppoort for bg scanning, calibrate rssi data
o wi: lightly tested
This work is based on contributions by Atheros, kmacy, sephe, thompsa,
mlaier, kevlo, and others. Much of the scanning work was supported by
Atheros. The 11n work was supported by Marvell.
2007-06-11 03:36:55 +00:00
|
|
|
u_int sc_fftxqmin; /* min frames before staging */
|
|
|
|
u_int sc_fftxqmax; /* max frames before drop */
|
2004-12-08 17:34:36 +00:00
|
|
|
u_int sc_txantenna; /* tx antenna (fixed or auto) */
|
2011-11-08 18:10:04 +00:00
|
|
|
|
2003-06-23 17:01:19 +00:00
|
|
|
HAL_INT sc_imask; /* interrupt mask copy */
|
Flesh out some slightly dirty reset/channel change serialisation code
for the ath(4) driver.
Currently, there's nothing stopping reset, channel change and general
TX/RX from overlapping with each other. This wasn't a big deal with
pre-11n traffic as it just results in some dropped frames.
It's possible this may have also caused some inconsistencies and
badly-setup hardware.
Since locks can't be held across all of this (the Linux solution)
due to LORs with the network stack locks, some state counter
variables are used to track what parts of the code the driver is
currently in.
When the hardware is being reset, it disables the taskqueue and
waits for pending interrupts, tx, rx and tx completion before
it begins the reset or channel change.
TX and RX both abort if called during an active reset or channel
change.
Finally, the reset path now doesn't flush frames if ATH_RESET_NOLOSS
is set. Instead, completed TX and RX frames are passed back up to
net80211 before the reset occurs.
This is not without problems:
* Raw frame xmit are just dropped, rather than placed on a queue.
The net80211 stack should be the one which queues these frames
rather than the driver.
* It's all very messy. It'd be better if these hardware operations
were serialised on some kind of work queue, rather than hoping
they can be run in parallel.
* The taskqueue block/unblock may occur in parallel with the
newstate() function - which shuts down the taskqueue and restarts
it once the new state is known. It's likely these operations should
be refcounted so the taskqueue is restored once no other areas
in the code wish to suspend operations.
* .. interrupt disable/enable should likely be refcounted as well.
With this work, the driver does not drop frames during stuck beacon
or fatal errors and thus 11n traffic continues to run correctly.
Default and full resets however do still drop frames and it's possible
this may occur, causing traffic loss and session stalls.
Sponsored by: Hobnob, Inc.
2011-11-18 05:06:30 +00:00
|
|
|
|
2011-11-08 18:10:04 +00:00
|
|
|
/*
|
|
|
|
* These are modified in the interrupt handler as well as
|
|
|
|
* the task queues and other contexts. Thus these must be
|
|
|
|
* protected by a mutex, or they could clash.
|
|
|
|
*
|
|
|
|
* For now, access to these is behind the ATH_LOCK,
|
|
|
|
* just to save time.
|
|
|
|
*/
|
|
|
|
uint32_t sc_txq_active; /* bitmap of active TXQs */
|
|
|
|
uint32_t sc_kickpcu; /* whether to kick the PCU */
|
Flesh out some slightly dirty reset/channel change serialisation code
for the ath(4) driver.
Currently, there's nothing stopping reset, channel change and general
TX/RX from overlapping with each other. This wasn't a big deal with
pre-11n traffic as it just results in some dropped frames.
It's possible this may have also caused some inconsistencies and
badly-setup hardware.
Since locks can't be held across all of this (the Linux solution)
due to LORs with the network stack locks, some state counter
variables are used to track what parts of the code the driver is
currently in.
When the hardware is being reset, it disables the taskqueue and
waits for pending interrupts, tx, rx and tx completion before
it begins the reset or channel change.
TX and RX both abort if called during an active reset or channel
change.
Finally, the reset path now doesn't flush frames if ATH_RESET_NOLOSS
is set. Instead, completed TX and RX frames are passed back up to
net80211 before the reset occurs.
This is not without problems:
* Raw frame xmit are just dropped, rather than placed on a queue.
The net80211 stack should be the one which queues these frames
rather than the driver.
* It's all very messy. It'd be better if these hardware operations
were serialised on some kind of work queue, rather than hoping
they can be run in parallel.
* The taskqueue block/unblock may occur in parallel with the
newstate() function - which shuts down the taskqueue and restarts
it once the new state is known. It's likely these operations should
be refcounted so the taskqueue is restored once no other areas
in the code wish to suspend operations.
* .. interrupt disable/enable should likely be refcounted as well.
With this work, the driver does not drop frames during stuck beacon
or fatal errors and thus 11n traffic continues to run correctly.
Default and full resets however do still drop frames and it's possible
this may occur, causing traffic loss and session stalls.
Sponsored by: Hobnob, Inc.
2011-11-18 05:06:30 +00:00
|
|
|
uint32_t sc_rxproc_cnt; /* In RX processing */
|
|
|
|
uint32_t sc_txproc_cnt; /* In TX processing */
|
|
|
|
uint32_t sc_txstart_cnt; /* In TX output (raw/start) */
|
|
|
|
uint32_t sc_inreset_cnt; /* In active reset/chanchange */
|
|
|
|
uint32_t sc_txrx_cnt; /* refcount on stop/start'ing TX */
|
|
|
|
uint32_t sc_intr_cnt; /* refcount on interrupt handling */
|
2011-11-08 18:10:04 +00:00
|
|
|
|
2004-12-08 17:34:36 +00:00
|
|
|
u_int sc_keymax; /* size of key cache */
|
2005-06-06 16:39:21 +00:00
|
|
|
u_int8_t sc_keymap[ATH_KEYBYTES];/* key use bit map */
|
2004-12-08 17:34:36 +00:00
|
|
|
|
Flesh out configurable hardware based LED blinking.
The hardware (MAC) LED blinking involves a few things:
* Selecting which GPIO pins map to the MAC "power" and "network" lines;
* Configuring the MAC LED state (associated, scanning, idle);
* Configuring the MAC LED blinking type and speed.
The AR5416 HAL configures the normal blinking setup - ie, blink rate based
on TX/RX throughput. The default AR5212 HAL doesn't program in any
specific blinking type, but the default of 0 is the same.
This code introduces a few things:
* The hardware led override is configured via sysctl 'hardled';
* The MAC network and power LED GPIO lines can be set, or left at -1
if needed. This is intended to allow only one of the hardware MUX
entries to be configured (eg for PCIe cards which only have one LED
exposed.)
TODO:
* For AR2417, the software LED blinking involves software blinking the
Network LED. For the AR5416 and later, this can just be configured
as a GPIO output line. I'll chase that up with a subsequent commit.
* Add another software LED blink for "Link", separate from "activity",
which blinks based on the association state. This would make my
D-Link DWA-552 have consistent and useful LED behaviour (as they're
marked "Link" and "Activity."
* Don't expose the hardware LED override unless it's an AR5416 or later,
as the previous generation hardware doesn't have this multiplexing
setup.
2011-12-26 07:47:05 +00:00
|
|
|
/*
|
|
|
|
* Software based LED blinking
|
|
|
|
*/
|
2005-01-18 19:03:04 +00:00
|
|
|
u_int sc_ledpin; /* GPIO pin for driving LED */
|
|
|
|
u_int sc_ledon; /* pin setting for LED on */
|
|
|
|
u_int sc_ledidle; /* idle polling interval */
|
|
|
|
int sc_ledevent; /* time of last LED event */
|
2008-10-27 18:22:44 +00:00
|
|
|
u_int8_t sc_txrix; /* current tx rate for LED */
|
2005-01-18 19:03:04 +00:00
|
|
|
u_int16_t sc_ledoff; /* off time for current blink */
|
|
|
|
struct callout sc_ledtimer; /* led off timer */
|
2003-06-23 17:01:19 +00:00
|
|
|
|
Flesh out configurable hardware based LED blinking.
The hardware (MAC) LED blinking involves a few things:
* Selecting which GPIO pins map to the MAC "power" and "network" lines;
* Configuring the MAC LED state (associated, scanning, idle);
* Configuring the MAC LED blinking type and speed.
The AR5416 HAL configures the normal blinking setup - ie, blink rate based
on TX/RX throughput. The default AR5212 HAL doesn't program in any
specific blinking type, but the default of 0 is the same.
This code introduces a few things:
* The hardware led override is configured via sysctl 'hardled';
* The MAC network and power LED GPIO lines can be set, or left at -1
if needed. This is intended to allow only one of the hardware MUX
entries to be configured (eg for PCIe cards which only have one LED
exposed.)
TODO:
* For AR2417, the software LED blinking involves software blinking the
Network LED. For the AR5416 and later, this can just be configured
as a GPIO output line. I'll chase that up with a subsequent commit.
* Add another software LED blink for "Link", separate from "activity",
which blinks based on the association state. This would make my
D-Link DWA-552 have consistent and useful LED behaviour (as they're
marked "Link" and "Activity."
* Don't expose the hardware LED override unless it's an AR5416 or later,
as the previous generation hardware doesn't have this multiplexing
setup.
2011-12-26 07:47:05 +00:00
|
|
|
/*
|
|
|
|
* Hardware based LED blinking
|
|
|
|
*/
|
|
|
|
int sc_led_pwr_pin; /* MAC power LED GPIO pin */
|
|
|
|
int sc_led_net_pin; /* MAC network LED GPIO pin */
|
|
|
|
|
2006-02-10 19:07:08 +00:00
|
|
|
u_int sc_rfsilentpin; /* GPIO pin for rfkill int */
|
|
|
|
u_int sc_rfsilentpol; /* pin setting for rfkill on */
|
|
|
|
|
2008-04-20 20:35:46 +00:00
|
|
|
struct ath_descdma sc_rxdma; /* RX descriptors */
|
2004-12-08 17:34:36 +00:00
|
|
|
ath_bufhead sc_rxbuf; /* receive buffer */
|
2003-06-23 17:01:19 +00:00
|
|
|
u_int32_t *sc_rxlink; /* link ptr in last RX desc */
|
|
|
|
struct task sc_rxtask; /* rx int processing */
|
2004-12-08 17:34:36 +00:00
|
|
|
u_int8_t sc_defant; /* current default antenna */
|
|
|
|
u_int8_t sc_rxotherant; /* rx's on non-default antenna*/
|
2006-02-09 22:03:26 +00:00
|
|
|
u_int64_t sc_lastrx; /* tsf at last rx'd frame */
|
2009-05-20 20:00:40 +00:00
|
|
|
struct ath_rx_status *sc_lastrs; /* h/w status of last rx */
|
|
|
|
struct ath_rx_radiotap_header sc_rx_th;
|
|
|
|
int sc_rx_th_len;
|
|
|
|
u_int sc_monpass; /* frames to pass in mon.mode */
|
2003-06-23 17:01:19 +00:00
|
|
|
|
2004-12-08 17:34:36 +00:00
|
|
|
struct ath_descdma sc_txdma; /* TX descriptors */
|
2012-08-15 06:48:34 +00:00
|
|
|
uint16_t sc_txbuf_descid;
|
2004-12-08 17:34:36 +00:00
|
|
|
ath_bufhead sc_txbuf; /* transmit buffer */
|
2012-06-14 00:51:53 +00:00
|
|
|
int sc_txbuf_cnt; /* how many buffers avail */
|
2012-06-13 06:57:55 +00:00
|
|
|
struct ath_descdma sc_txdma_mgmt; /* mgmt TX descriptors */
|
|
|
|
ath_bufhead sc_txbuf_mgmt; /* mgmt transmit buffer */
|
2012-07-27 10:41:54 +00:00
|
|
|
struct ath_descdma sc_txsdma; /* EDMA TX status desc's */
|
2003-06-23 17:01:19 +00:00
|
|
|
struct mtx sc_txbuflock; /* txbuf lock */
|
2006-02-09 21:09:26 +00:00
|
|
|
char sc_txname[12]; /* e.g. "ath0_buf" */
|
2004-12-08 17:34:36 +00:00
|
|
|
u_int sc_txqsetup; /* h/w queues setup */
|
|
|
|
u_int sc_txintrperiod;/* tx interrupt batching */
|
|
|
|
struct ath_txq sc_txq[HAL_NUM_TX_QUEUES];
|
|
|
|
struct ath_txq *sc_ac2q[5]; /* WME AC -> h/w q map */
|
2003-06-23 17:01:19 +00:00
|
|
|
struct task sc_txtask; /* tx int processing */
|
2012-03-29 17:39:18 +00:00
|
|
|
struct task sc_txqtask; /* tx proc processing */
|
2012-07-23 02:49:25 +00:00
|
|
|
|
|
|
|
struct ath_descdma sc_txcompdma; /* TX EDMA completion */
|
|
|
|
struct mtx sc_txcomplock; /* TX EDMA completion lock */
|
|
|
|
char sc_txcompname[12]; /* eg ath0_txcomp */
|
|
|
|
|
2009-03-09 23:10:19 +00:00
|
|
|
int sc_wd_timer; /* count down for wd timer */
|
|
|
|
struct callout sc_wd_ch; /* tx watchdog timer */
|
2009-05-20 20:00:40 +00:00
|
|
|
struct ath_tx_radiotap_header sc_tx_th;
|
|
|
|
int sc_tx_th_len;
|
2003-06-23 17:01:19 +00:00
|
|
|
|
2004-12-08 17:34:36 +00:00
|
|
|
struct ath_descdma sc_bdma; /* beacon descriptors */
|
|
|
|
ath_bufhead sc_bbuf; /* beacon buffers */
|
2003-06-23 17:01:19 +00:00
|
|
|
u_int sc_bhalq; /* HAL q for outgoing beacons */
|
2004-12-08 17:34:36 +00:00
|
|
|
u_int sc_bmisscount; /* missed beacon transmits */
|
|
|
|
u_int32_t sc_ant_tx[8]; /* recent tx frames/antenna */
|
|
|
|
struct ath_txq *sc_cabq; /* tx q for cab frames */
|
2003-06-23 17:01:19 +00:00
|
|
|
struct task sc_bmisstask; /* bmiss int processing */
|
2004-12-08 17:34:36 +00:00
|
|
|
struct task sc_bstucktask; /* stuck beacon processing */
|
2012-02-25 19:12:54 +00:00
|
|
|
struct task sc_resettask; /* interface reset task */
|
2012-04-17 06:02:41 +00:00
|
|
|
struct task sc_fataltask; /* fatal task */
|
2004-12-08 17:34:36 +00:00
|
|
|
enum {
|
|
|
|
OK, /* no change needed */
|
|
|
|
UPDATE, /* update pending */
|
|
|
|
COMMIT /* beacon sent, commit change */
|
|
|
|
} sc_updateslot; /* slot time update fsm */
|
2008-04-20 20:35:46 +00:00
|
|
|
int sc_slotupdate; /* slot to advance fsm */
|
|
|
|
struct ieee80211vap *sc_bslot[ATH_BCBUF];
|
|
|
|
int sc_nbcnvaps; /* # vaps with beacons */
|
2003-06-23 17:01:19 +00:00
|
|
|
|
|
|
|
struct callout sc_cal_ch; /* callout handle for cals */
|
2008-12-07 19:26:34 +00:00
|
|
|
int sc_lastlongcal; /* last long cal completed */
|
|
|
|
int sc_lastcalreset;/* last cal reset done */
|
2011-01-21 05:21:00 +00:00
|
|
|
int sc_lastani; /* last ANI poll */
|
|
|
|
int sc_lastshortcal; /* last short calibration */
|
|
|
|
HAL_BOOL sc_doresetcal; /* Yes, we're doing a reset cal atm */
|
2006-02-09 21:23:44 +00:00
|
|
|
HAL_NODE_STATS sc_halstats; /* station-mode rssi stats */
|
2009-01-08 17:12:47 +00:00
|
|
|
u_int sc_tdmadbaprep; /* TDMA DBA prep time */
|
|
|
|
u_int sc_tdmaswbaprep;/* TDMA SWBA prep time */
|
|
|
|
u_int sc_tdmaswba; /* TDMA SWBA counter */
|
|
|
|
u_int32_t sc_tdmabintval; /* TDMA beacon interval (TU) */
|
|
|
|
u_int32_t sc_tdmaguard; /* TDMA guard time (usec) */
|
|
|
|
u_int sc_tdmaslotlen; /* TDMA slot length (usec) */
|
|
|
|
u_int32_t sc_avgtsfdeltap;/* TDMA slot adjust (+) */
|
|
|
|
u_int32_t sc_avgtsfdeltam;/* TDMA slot adjust (-) */
|
2011-01-20 07:56:09 +00:00
|
|
|
uint16_t *sc_eepromdata; /* Local eeprom data, if AR9100 */
|
2013-04-19 06:59:10 +00:00
|
|
|
uint32_t sc_txchainmask; /* hardware TX chainmask */
|
|
|
|
uint32_t sc_rxchainmask; /* hardware RX chainmask */
|
|
|
|
uint32_t sc_cur_txchainmask; /* currently configured TX chainmask */
|
|
|
|
uint32_t sc_cur_rxchainmask; /* currently configured RX chainmask */
|
|
|
|
uint32_t sc_rts_aggr_limit; /* TX limit on RTS aggregates */
|
2013-02-21 06:18:40 +00:00
|
|
|
int sc_aggr_limit; /* TX limit on all aggregates */
|
2013-02-21 06:38:49 +00:00
|
|
|
int sc_delim_min_pad; /* Minimum delimiter count */
|
2011-06-01 20:09:49 +00:00
|
|
|
|
2012-03-10 04:14:04 +00:00
|
|
|
/* Queue limits */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* To avoid queue starvation in congested conditions,
|
|
|
|
* these parameters tune the maximum number of frames
|
|
|
|
* queued to the data/mcastq before they're dropped.
|
|
|
|
*
|
|
|
|
* This is to prevent:
|
|
|
|
* + a single destination overwhelming everything, including
|
|
|
|
* management/multicast frames;
|
|
|
|
* + multicast frames overwhelming everything (when the
|
|
|
|
* air is sufficiently busy that cabq can't drain.)
|
Implement my first cut at "correct" node power-save and
PS-POLL support.
This implements PS-POLL awareness i nthe
* Implement frame "leaking", which allows for a software queue
to be scheduled even though it's asleep
* Track whether a frame has been leaked or not
* Leak out a single non-AMPDU frame when transmitting aggregates
* Queue BAR frames if the node is asleep
* Direct-dispatch the rest of control and management frames.
This allows for things like re-association to occur (which involves
sending probe req/resp as well as assoc request/response) when
the node is asleep and then tries reassociating.
* Limit how many frames can set in the software node queue whilst
the node is asleep. net80211 is already buffering frames for us
so this is mostly just paranoia.
* Add a PS-POLL method which leaks out a frame if there's something
in the software queue, else it calls net80211's ps-poll routine.
Since the ath PS-POLL routine marks the node as having a single frame
to leak, either a software queued frame would leak, OR the next queued
frame would leak. The next queued frame could be something from the
net80211 power save queue, OR it could be a NULL frame from net80211.
TODO:
* Don't transmit further BAR frames (eg via a timeout) if the node is
currently asleep. Otherwise we may end up exhausting management frames
due to the lots of queued BAR frames.
I may just undo this bit later on and direct-dispatch BAR frames
even if the node is asleep.
* It would be nice to burst out a single A-MPDU frame if both ends
support this. I may end adding a FreeBSD IE soon to negotiate
this power save behaviour.
* I should make STAs timeout of power save mode if they've been in power
save for more than a handful of seconds. This way cards that get
"stuck" in power save mode don't stay there for the "inactivity" timeout
in net80211.
* Move the queue depth check into the driver layer (ath_start / ath_transmit)
rather than doing it in the TX path.
* There could be some naughty corner cases with ps-poll leaking.
Specifically, if net80211 generates a NULL data frame whilst another
transmitter sends a normal data frame out net80211 output / transmit,
we need to ensure that the NULL data frame goes out first.
This is one of those things that should occur inside the VAP/ic TX lock.
Grr, more investigations to do..
Tested:
* STA: AR5416, AR9280
* AP: AR5416, AR9280, AR9160
2013-05-15 18:33:05 +00:00
|
|
|
* + A node in powersave shouldn't be allowed to exhaust
|
|
|
|
* all available mbufs;
|
2012-03-10 04:14:04 +00:00
|
|
|
*
|
|
|
|
* These implement:
|
|
|
|
* + data_minfree is the maximum number of free buffers
|
|
|
|
* overall to successfully allow a data frame.
|
|
|
|
*
|
2012-03-10 19:58:23 +00:00
|
|
|
* + mcastq_maxdepth is the maximum depth allowed of the cabq.
|
2012-03-10 04:14:04 +00:00
|
|
|
*/
|
2013-05-07 07:52:18 +00:00
|
|
|
int sc_txq_node_maxdepth;
|
2012-03-10 04:14:04 +00:00
|
|
|
int sc_txq_data_minfree;
|
|
|
|
int sc_txq_mcastq_maxdepth;
|
Implement my first cut at "correct" node power-save and
PS-POLL support.
This implements PS-POLL awareness i nthe
* Implement frame "leaking", which allows for a software queue
to be scheduled even though it's asleep
* Track whether a frame has been leaked or not
* Leak out a single non-AMPDU frame when transmitting aggregates
* Queue BAR frames if the node is asleep
* Direct-dispatch the rest of control and management frames.
This allows for things like re-association to occur (which involves
sending probe req/resp as well as assoc request/response) when
the node is asleep and then tries reassociating.
* Limit how many frames can set in the software node queue whilst
the node is asleep. net80211 is already buffering frames for us
so this is mostly just paranoia.
* Add a PS-POLL method which leaks out a frame if there's something
in the software queue, else it calls net80211's ps-poll routine.
Since the ath PS-POLL routine marks the node as having a single frame
to leak, either a software queued frame would leak, OR the next queued
frame would leak. The next queued frame could be something from the
net80211 power save queue, OR it could be a NULL frame from net80211.
TODO:
* Don't transmit further BAR frames (eg via a timeout) if the node is
currently asleep. Otherwise we may end up exhausting management frames
due to the lots of queued BAR frames.
I may just undo this bit later on and direct-dispatch BAR frames
even if the node is asleep.
* It would be nice to burst out a single A-MPDU frame if both ends
support this. I may end adding a FreeBSD IE soon to negotiate
this power save behaviour.
* I should make STAs timeout of power save mode if they've been in power
save for more than a handful of seconds. This way cards that get
"stuck" in power save mode don't stay there for the "inactivity" timeout
in net80211.
* Move the queue depth check into the driver layer (ath_start / ath_transmit)
rather than doing it in the TX path.
* There could be some naughty corner cases with ps-poll leaking.
Specifically, if net80211 generates a NULL data frame whilst another
transmitter sends a normal data frame out net80211 output / transmit,
we need to ensure that the NULL data frame goes out first.
This is one of those things that should occur inside the VAP/ic TX lock.
Grr, more investigations to do..
Tested:
* STA: AR5416, AR9280
* AP: AR5416, AR9280, AR9160
2013-05-15 18:33:05 +00:00
|
|
|
int sc_txq_node_psq_maxdepth;
|
2012-03-10 04:14:04 +00:00
|
|
|
|
2011-11-08 02:12:11 +00:00
|
|
|
/*
|
2013-05-21 18:13:57 +00:00
|
|
|
* Software queue twiddles
|
2011-11-08 02:12:11 +00:00
|
|
|
*
|
2013-05-21 18:13:57 +00:00
|
|
|
* hwq_limit_nonaggr:
|
|
|
|
* when to begin limiting non-aggregate frames to the
|
|
|
|
* hardware queue, regardless of the TID.
|
|
|
|
* hwq_limit_aggr:
|
|
|
|
* when to begin limiting A-MPDU frames to the
|
|
|
|
* hardware queue, regardless of the TID.
|
2011-11-08 02:12:11 +00:00
|
|
|
* tid_hwq_lo: how low the per-TID hwq count has to be before the
|
|
|
|
* TID will be scheduled again
|
|
|
|
* tid_hwq_hi: how many frames to queue to the HWQ before the TID
|
|
|
|
* stops being scheduled.
|
|
|
|
*/
|
2013-05-21 18:13:57 +00:00
|
|
|
int sc_hwq_limit_nonaggr;
|
|
|
|
int sc_hwq_limit_aggr;
|
2011-11-08 02:12:11 +00:00
|
|
|
int sc_tid_hwq_lo;
|
|
|
|
int sc_tid_hwq_hi;
|
|
|
|
|
2011-06-01 20:09:49 +00:00
|
|
|
/* DFS related state */
|
|
|
|
void *sc_dfs; /* Used by an optional DFS module */
|
2011-06-04 04:14:59 +00:00
|
|
|
int sc_dodfs; /* Whether to enable DFS rx filter bits */
|
2011-06-01 20:09:49 +00:00
|
|
|
struct task sc_dfstask; /* DFS processing task */
|
2011-11-08 02:12:11 +00:00
|
|
|
|
2013-01-02 03:59:02 +00:00
|
|
|
/* Spectral related state */
|
|
|
|
void *sc_spectral;
|
|
|
|
int sc_dospectral;
|
|
|
|
|
2013-06-12 14:52:57 +00:00
|
|
|
/* LNA diversity related state */
|
|
|
|
void *sc_lna_div;
|
|
|
|
int sc_dolnadiv;
|
|
|
|
|
2012-11-08 18:11:31 +00:00
|
|
|
/* ALQ */
|
2012-11-10 08:34:40 +00:00
|
|
|
#ifdef ATH_DEBUG_ALQ
|
2012-11-08 18:11:31 +00:00
|
|
|
struct if_ath_alq sc_alq;
|
|
|
|
#endif
|
|
|
|
|
2011-11-08 02:12:11 +00:00
|
|
|
/* TX AMPDU handling */
|
|
|
|
int (*sc_addba_request)(struct ieee80211_node *,
|
|
|
|
struct ieee80211_tx_ampdu *, int, int, int);
|
|
|
|
int (*sc_addba_response)(struct ieee80211_node *,
|
|
|
|
struct ieee80211_tx_ampdu *, int, int, int);
|
|
|
|
void (*sc_addba_stop)(struct ieee80211_node *,
|
|
|
|
struct ieee80211_tx_ampdu *);
|
|
|
|
void (*sc_addba_response_timeout)
|
|
|
|
(struct ieee80211_node *,
|
|
|
|
struct ieee80211_tx_ampdu *);
|
|
|
|
void (*sc_bar_response)(struct ieee80211_node *ni,
|
|
|
|
struct ieee80211_tx_ampdu *tap,
|
|
|
|
int status);
|
Bring over some initial power save management support, reset path
fixes and beacon programming / debugging into the ath(4) driver.
The basic power save tracking:
* Add some new code to track the current desired powersave state; and
* Add some reference count tracking so we know when the NIC is awake; then
* Add code in all the points where we're about to touch the hardware and
push it to force-wake.
Then, how things are moved into power save:
* Only move into network-sleep during a RUN->SLEEP transition;
* Force wake the hardware up everywhere that we're about to touch
the hardware.
The net80211 stack takes care of doing RUN<->SLEEP<->(other) state
transitions so we don't have to do it in the driver.
Next, when to wake things up:
* In short - everywhere we touch the hardware.
* The hardware will take care of staying awake if things are queued
in the transmit queue(s); it'll then transit down to sleep if
there's nothing left. This way we don't have to track the
software / hardware transmit queue(s) and keep the hardware
awake for those.
Then, some transmit path fixes that aren't related but useful:
* Force EAPOL frames to go out at the lowest rate. This improves
reliability during the encryption handshake after 802.11
negotiation.
Next, some reset path fixes!
* Fix the overlap between reset and transmit pause so we don't
transmit frames during a reset.
* Some noisy environments will end up taking a lot longer to reset
than normal, so extend the reset period and drop the raise the
reset interval to be more realistic and give the hardware some
time to finish calibration.
* Skip calibration during the reset path. Tsk!
Then, beacon fixes in station mode!
* Add a _lot_ more debugging in the station beacon reset path.
This is all quite fluid right now.
* Modify the STA beacon programming code to try and take
the TU gap between desired TSF and the target TU into
account. (Lifted from QCA.)
Tested:
* AR5210
* AR5211
* AR5212
* AR5413
* AR5416
* AR9280
* AR9285
TODO:
* More AP, IBSS, mesh, TDMA testing
* Thorough AR9380 and later testing!
* AR9160 and AR9287 testing
Obtained from: QCA
2014-04-30 02:19:41 +00:00
|
|
|
|
|
|
|
/*
|
2014-05-02 00:48:09 +00:00
|
|
|
* Powersave state tracking.
|
|
|
|
*
|
|
|
|
* target/cur powerstate is the chip power state.
|
|
|
|
* target selfgen state is the self-generated frames
|
|
|
|
* state. The chip can be awake but transmitted frames
|
|
|
|
* can have the PWRMGT bit set to 1 so the destination
|
|
|
|
* thinks the node is asleep.
|
Bring over some initial power save management support, reset path
fixes and beacon programming / debugging into the ath(4) driver.
The basic power save tracking:
* Add some new code to track the current desired powersave state; and
* Add some reference count tracking so we know when the NIC is awake; then
* Add code in all the points where we're about to touch the hardware and
push it to force-wake.
Then, how things are moved into power save:
* Only move into network-sleep during a RUN->SLEEP transition;
* Force wake the hardware up everywhere that we're about to touch
the hardware.
The net80211 stack takes care of doing RUN<->SLEEP<->(other) state
transitions so we don't have to do it in the driver.
Next, when to wake things up:
* In short - everywhere we touch the hardware.
* The hardware will take care of staying awake if things are queued
in the transmit queue(s); it'll then transit down to sleep if
there's nothing left. This way we don't have to track the
software / hardware transmit queue(s) and keep the hardware
awake for those.
Then, some transmit path fixes that aren't related but useful:
* Force EAPOL frames to go out at the lowest rate. This improves
reliability during the encryption handshake after 802.11
negotiation.
Next, some reset path fixes!
* Fix the overlap between reset and transmit pause so we don't
transmit frames during a reset.
* Some noisy environments will end up taking a lot longer to reset
than normal, so extend the reset period and drop the raise the
reset interval to be more realistic and give the hardware some
time to finish calibration.
* Skip calibration during the reset path. Tsk!
Then, beacon fixes in station mode!
* Add a _lot_ more debugging in the station beacon reset path.
This is all quite fluid right now.
* Modify the STA beacon programming code to try and take
the TU gap between desired TSF and the target TU into
account. (Lifted from QCA.)
Tested:
* AR5210
* AR5211
* AR5212
* AR5413
* AR5416
* AR9280
* AR9285
TODO:
* More AP, IBSS, mesh, TDMA testing
* Thorough AR9380 and later testing!
* AR9160 and AR9287 testing
Obtained from: QCA
2014-04-30 02:19:41 +00:00
|
|
|
*/
|
|
|
|
HAL_POWER_MODE sc_target_powerstate;
|
2014-05-02 00:48:09 +00:00
|
|
|
HAL_POWER_MODE sc_target_selfgen_state;
|
|
|
|
|
Bring over some initial power save management support, reset path
fixes and beacon programming / debugging into the ath(4) driver.
The basic power save tracking:
* Add some new code to track the current desired powersave state; and
* Add some reference count tracking so we know when the NIC is awake; then
* Add code in all the points where we're about to touch the hardware and
push it to force-wake.
Then, how things are moved into power save:
* Only move into network-sleep during a RUN->SLEEP transition;
* Force wake the hardware up everywhere that we're about to touch
the hardware.
The net80211 stack takes care of doing RUN<->SLEEP<->(other) state
transitions so we don't have to do it in the driver.
Next, when to wake things up:
* In short - everywhere we touch the hardware.
* The hardware will take care of staying awake if things are queued
in the transmit queue(s); it'll then transit down to sleep if
there's nothing left. This way we don't have to track the
software / hardware transmit queue(s) and keep the hardware
awake for those.
Then, some transmit path fixes that aren't related but useful:
* Force EAPOL frames to go out at the lowest rate. This improves
reliability during the encryption handshake after 802.11
negotiation.
Next, some reset path fixes!
* Fix the overlap between reset and transmit pause so we don't
transmit frames during a reset.
* Some noisy environments will end up taking a lot longer to reset
than normal, so extend the reset period and drop the raise the
reset interval to be more realistic and give the hardware some
time to finish calibration.
* Skip calibration during the reset path. Tsk!
Then, beacon fixes in station mode!
* Add a _lot_ more debugging in the station beacon reset path.
This is all quite fluid right now.
* Modify the STA beacon programming code to try and take
the TU gap between desired TSF and the target TU into
account. (Lifted from QCA.)
Tested:
* AR5210
* AR5211
* AR5212
* AR5413
* AR5416
* AR9280
* AR9285
TODO:
* More AP, IBSS, mesh, TDMA testing
* Thorough AR9380 and later testing!
* AR9160 and AR9287 testing
Obtained from: QCA
2014-04-30 02:19:41 +00:00
|
|
|
HAL_POWER_MODE sc_cur_powerstate;
|
2014-05-02 00:48:09 +00:00
|
|
|
|
Bring over some initial power save management support, reset path
fixes and beacon programming / debugging into the ath(4) driver.
The basic power save tracking:
* Add some new code to track the current desired powersave state; and
* Add some reference count tracking so we know when the NIC is awake; then
* Add code in all the points where we're about to touch the hardware and
push it to force-wake.
Then, how things are moved into power save:
* Only move into network-sleep during a RUN->SLEEP transition;
* Force wake the hardware up everywhere that we're about to touch
the hardware.
The net80211 stack takes care of doing RUN<->SLEEP<->(other) state
transitions so we don't have to do it in the driver.
Next, when to wake things up:
* In short - everywhere we touch the hardware.
* The hardware will take care of staying awake if things are queued
in the transmit queue(s); it'll then transit down to sleep if
there's nothing left. This way we don't have to track the
software / hardware transmit queue(s) and keep the hardware
awake for those.
Then, some transmit path fixes that aren't related but useful:
* Force EAPOL frames to go out at the lowest rate. This improves
reliability during the encryption handshake after 802.11
negotiation.
Next, some reset path fixes!
* Fix the overlap between reset and transmit pause so we don't
transmit frames during a reset.
* Some noisy environments will end up taking a lot longer to reset
than normal, so extend the reset period and drop the raise the
reset interval to be more realistic and give the hardware some
time to finish calibration.
* Skip calibration during the reset path. Tsk!
Then, beacon fixes in station mode!
* Add a _lot_ more debugging in the station beacon reset path.
This is all quite fluid right now.
* Modify the STA beacon programming code to try and take
the TU gap between desired TSF and the target TU into
account. (Lifted from QCA.)
Tested:
* AR5210
* AR5211
* AR5212
* AR5413
* AR5416
* AR9280
* AR9285
TODO:
* More AP, IBSS, mesh, TDMA testing
* Thorough AR9380 and later testing!
* AR9160 and AR9287 testing
Obtained from: QCA
2014-04-30 02:19:41 +00:00
|
|
|
int sc_powersave_refcnt;
|
2003-06-23 17:01:19 +00:00
|
|
|
};
|
|
|
|
|
2003-10-14 22:51:45 +00:00
|
|
|
#define ATH_LOCK_INIT(_sc) \
|
|
|
|
mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
|
2007-03-05 21:56:33 +00:00
|
|
|
NULL, MTX_DEF | MTX_RECURSE)
|
2003-10-14 22:51:45 +00:00
|
|
|
#define ATH_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx)
|
|
|
|
#define ATH_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
|
|
|
|
#define ATH_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
|
|
|
|
#define ATH_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
|
Flesh out some slightly dirty reset/channel change serialisation code
for the ath(4) driver.
Currently, there's nothing stopping reset, channel change and general
TX/RX from overlapping with each other. This wasn't a big deal with
pre-11n traffic as it just results in some dropped frames.
It's possible this may have also caused some inconsistencies and
badly-setup hardware.
Since locks can't be held across all of this (the Linux solution)
due to LORs with the network stack locks, some state counter
variables are used to track what parts of the code the driver is
currently in.
When the hardware is being reset, it disables the taskqueue and
waits for pending interrupts, tx, rx and tx completion before
it begins the reset or channel change.
TX and RX both abort if called during an active reset or channel
change.
Finally, the reset path now doesn't flush frames if ATH_RESET_NOLOSS
is set. Instead, completed TX and RX frames are passed back up to
net80211 before the reset occurs.
This is not without problems:
* Raw frame xmit are just dropped, rather than placed on a queue.
The net80211 stack should be the one which queues these frames
rather than the driver.
* It's all very messy. It'd be better if these hardware operations
were serialised on some kind of work queue, rather than hoping
they can be run in parallel.
* The taskqueue block/unblock may occur in parallel with the
newstate() function - which shuts down the taskqueue and restarts
it once the new state is known. It's likely these operations should
be refcounted so the taskqueue is restored once no other areas
in the code wish to suspend operations.
* .. interrupt disable/enable should likely be refcounted as well.
With this work, the driver does not drop frames during stuck beacon
or fatal errors and thus 11n traffic continues to run correctly.
Default and full resets however do still drop frames and it's possible
this may occur, causing traffic loss and session stalls.
Sponsored by: Hobnob, Inc.
2011-11-18 05:06:30 +00:00
|
|
|
#define ATH_UNLOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_NOTOWNED)
|
2003-10-14 22:51:45 +00:00
|
|
|
|
2012-10-31 06:27:58 +00:00
|
|
|
/*
|
2013-02-07 07:50:16 +00:00
|
|
|
* The TX lock is non-reentrant and serialises the TX frame send
|
|
|
|
* and completion operations.
|
2012-10-31 06:27:58 +00:00
|
|
|
*/
|
|
|
|
#define ATH_TX_LOCK_INIT(_sc) do {\
|
|
|
|
snprintf((_sc)->sc_tx_mtx_name, \
|
|
|
|
sizeof((_sc)->sc_tx_mtx_name), \
|
|
|
|
"%s TX lock", \
|
|
|
|
device_get_nameunit((_sc)->sc_dev)); \
|
|
|
|
mtx_init(&(_sc)->sc_tx_mtx, (_sc)->sc_tx_mtx_name, \
|
|
|
|
NULL, MTX_DEF); \
|
|
|
|
} while (0)
|
|
|
|
#define ATH_TX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_tx_mtx)
|
|
|
|
#define ATH_TX_LOCK(_sc) mtx_lock(&(_sc)->sc_tx_mtx)
|
|
|
|
#define ATH_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_tx_mtx)
|
|
|
|
#define ATH_TX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_tx_mtx, \
|
|
|
|
MA_OWNED)
|
|
|
|
#define ATH_TX_UNLOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_tx_mtx, \
|
|
|
|
MA_NOTOWNED)
|
Pull out the if_transmit() work and revert back to ath_start().
My changed had some rather significant behavioural changes to throughput.
The two issues I noticed:
* With if_start and the ifnet mbuf queue, any temporary latency
would get eaten up by some mbufs being queued. With ath_transmit()
queuing things to ath_buf's, I'd only get 512 TX buffers before I
couldn't queue any further frames.
* There's also some non-zero latency involved with TX being pushed
into a taskqueue via direct dispatch. Any time the scheduler didn't
immediately schedule the ath TX task would cause extra latency.
Various 1ge/10ge drivers implement both direct dispatch (if the TX
lock can be acquired) and deferred task transmission (if the TX lock
can't be acquired), with frames being pushed into a drbd queue.
I'll have to do this at some point, but until I figure out how to
deal with 802.11 fragments, I'll have to wait a while longer.
So what I saw:
* lots of extra latency, specially under load - if the taskqueue
wasn't immediately scheduled, things went pear shaped;
* any extra latency would result in TX ath_buf's taking their sweet time
being replenished, so any further calls to ath_transmit() would drop
mbufs.
* .. yes, there's no explicit backpressure here - things are just dropped.
Eek.
With this, the general performance has gone up, but those subtle if_start()
related race conditions are back. For some reason, this is doubly-obvious
with the AR5416 NIC and I don't quite understand why yet.
There's an unrelated issue with AR5416 performance in STA mode (it's
fine in AP mode when bridging frames, weirdly..) that requires a little
further investigation. Specifically - it works fine on a Lenovo T40
(single core CPU) running a March 2012 9-STABLE kernel, but a Lenovo T60
(dual core) running an early November 2012 kernel behaves very poorly.
The same hardware with an AR9160 or AR9280 behaves perfectly.
2013-02-13 05:32:19 +00:00
|
|
|
#define ATH_TX_TRYLOCK(_sc) (mtx_owned(&(_sc)->sc_tx_mtx) != 0 && \
|
|
|
|
mtx_trylock(&(_sc)->sc_tx_mtx))
|
2012-10-31 06:27:58 +00:00
|
|
|
|
2013-02-07 07:50:16 +00:00
|
|
|
/*
|
|
|
|
* The IC TX lock is non-reentrant and serialises packet queuing from
|
|
|
|
* the upper layers.
|
|
|
|
*/
|
|
|
|
#define ATH_TX_IC_LOCK_INIT(_sc) do {\
|
|
|
|
snprintf((_sc)->sc_tx_ic_mtx_name, \
|
|
|
|
sizeof((_sc)->sc_tx_ic_mtx_name), \
|
|
|
|
"%s IC TX lock", \
|
|
|
|
device_get_nameunit((_sc)->sc_dev)); \
|
|
|
|
mtx_init(&(_sc)->sc_tx_ic_mtx, (_sc)->sc_tx_ic_mtx_name, \
|
|
|
|
NULL, MTX_DEF); \
|
|
|
|
} while (0)
|
|
|
|
#define ATH_TX_IC_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_tx_ic_mtx)
|
|
|
|
#define ATH_TX_IC_LOCK(_sc) mtx_lock(&(_sc)->sc_tx_ic_mtx)
|
|
|
|
#define ATH_TX_IC_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_tx_ic_mtx)
|
|
|
|
#define ATH_TX_IC_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_tx_ic_mtx, \
|
|
|
|
MA_OWNED)
|
|
|
|
#define ATH_TX_IC_UNLOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_tx_ic_mtx, \
|
|
|
|
MA_NOTOWNED)
|
|
|
|
|
2011-11-08 02:12:11 +00:00
|
|
|
/*
|
|
|
|
* The PCU lock is non-recursive and should be treated as a spinlock.
|
|
|
|
* Although currently the interrupt code is run in netisr context and
|
|
|
|
* doesn't require this, this may change in the future.
|
|
|
|
* Please keep this in mind when protecting certain code paths
|
|
|
|
* with the PCU lock.
|
|
|
|
*
|
|
|
|
* The PCU lock is used to serialise access to the PCU so things such
|
|
|
|
* as TX, RX, state change (eg channel change), channel reset and updates
|
|
|
|
* from interrupt context (eg kickpcu, txqactive bits) do not clash.
|
|
|
|
*
|
|
|
|
* Although the current single-thread taskqueue mechanism protects the
|
|
|
|
* majority of these situations by simply serialising them, there are
|
|
|
|
* a few others which occur at the same time. These include the TX path
|
|
|
|
* (which only acquires ATH_LOCK when recycling buffers to the free list),
|
|
|
|
* ath_set_channel, the channel scanning API and perhaps quite a bit more.
|
|
|
|
*/
|
|
|
|
#define ATH_PCU_LOCK_INIT(_sc) do {\
|
|
|
|
snprintf((_sc)->sc_pcu_mtx_name, \
|
|
|
|
sizeof((_sc)->sc_pcu_mtx_name), \
|
|
|
|
"%s PCU lock", \
|
|
|
|
device_get_nameunit((_sc)->sc_dev)); \
|
|
|
|
mtx_init(&(_sc)->sc_pcu_mtx, (_sc)->sc_pcu_mtx_name, \
|
|
|
|
NULL, MTX_DEF); \
|
|
|
|
} while (0)
|
|
|
|
#define ATH_PCU_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_pcu_mtx)
|
|
|
|
#define ATH_PCU_LOCK(_sc) mtx_lock(&(_sc)->sc_pcu_mtx)
|
|
|
|
#define ATH_PCU_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_pcu_mtx)
|
|
|
|
#define ATH_PCU_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_pcu_mtx, \
|
|
|
|
MA_OWNED)
|
Flesh out some slightly dirty reset/channel change serialisation code
for the ath(4) driver.
Currently, there's nothing stopping reset, channel change and general
TX/RX from overlapping with each other. This wasn't a big deal with
pre-11n traffic as it just results in some dropped frames.
It's possible this may have also caused some inconsistencies and
badly-setup hardware.
Since locks can't be held across all of this (the Linux solution)
due to LORs with the network stack locks, some state counter
variables are used to track what parts of the code the driver is
currently in.
When the hardware is being reset, it disables the taskqueue and
waits for pending interrupts, tx, rx and tx completion before
it begins the reset or channel change.
TX and RX both abort if called during an active reset or channel
change.
Finally, the reset path now doesn't flush frames if ATH_RESET_NOLOSS
is set. Instead, completed TX and RX frames are passed back up to
net80211 before the reset occurs.
This is not without problems:
* Raw frame xmit are just dropped, rather than placed on a queue.
The net80211 stack should be the one which queues these frames
rather than the driver.
* It's all very messy. It'd be better if these hardware operations
were serialised on some kind of work queue, rather than hoping
they can be run in parallel.
* The taskqueue block/unblock may occur in parallel with the
newstate() function - which shuts down the taskqueue and restarts
it once the new state is known. It's likely these operations should
be refcounted so the taskqueue is restored once no other areas
in the code wish to suspend operations.
* .. interrupt disable/enable should likely be refcounted as well.
With this work, the driver does not drop frames during stuck beacon
or fatal errors and thus 11n traffic continues to run correctly.
Default and full resets however do still drop frames and it's possible
this may occur, causing traffic loss and session stalls.
Sponsored by: Hobnob, Inc.
2011-11-18 05:06:30 +00:00
|
|
|
#define ATH_PCU_UNLOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_pcu_mtx, \
|
|
|
|
MA_NOTOWNED)
|
2011-11-08 02:12:11 +00:00
|
|
|
|
2012-07-14 02:22:17 +00:00
|
|
|
/*
|
|
|
|
* The RX lock is primarily a(nother) workaround to ensure that the
|
|
|
|
* RX FIFO/list isn't modified by various execution paths.
|
|
|
|
* Even though RX occurs in a single context (the ath taskqueue), the
|
|
|
|
* RX path can be executed via various reset/channel change paths.
|
|
|
|
*/
|
|
|
|
#define ATH_RX_LOCK_INIT(_sc) do {\
|
|
|
|
snprintf((_sc)->sc_rx_mtx_name, \
|
|
|
|
sizeof((_sc)->sc_rx_mtx_name), \
|
|
|
|
"%s RX lock", \
|
|
|
|
device_get_nameunit((_sc)->sc_dev)); \
|
|
|
|
mtx_init(&(_sc)->sc_rx_mtx, (_sc)->sc_rx_mtx_name, \
|
|
|
|
NULL, MTX_DEF); \
|
|
|
|
} while (0)
|
|
|
|
#define ATH_RX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_rx_mtx)
|
|
|
|
#define ATH_RX_LOCK(_sc) mtx_lock(&(_sc)->sc_rx_mtx)
|
|
|
|
#define ATH_RX_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_rx_mtx)
|
|
|
|
#define ATH_RX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_rx_mtx, \
|
|
|
|
MA_OWNED)
|
|
|
|
#define ATH_RX_UNLOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_rx_mtx, \
|
|
|
|
MA_NOTOWNED)
|
|
|
|
|
2004-12-08 17:34:36 +00:00
|
|
|
#define ATH_TXQ_SETUP(sc, i) ((sc)->sc_txqsetup & (1<<i))
|
|
|
|
|
2006-02-09 21:09:26 +00:00
|
|
|
#define ATH_TXBUF_LOCK_INIT(_sc) do { \
|
|
|
|
snprintf((_sc)->sc_txname, sizeof((_sc)->sc_txname), "%s_buf", \
|
|
|
|
device_get_nameunit((_sc)->sc_dev)); \
|
2007-03-05 21:56:33 +00:00
|
|
|
mtx_init(&(_sc)->sc_txbuflock, (_sc)->sc_txname, NULL, MTX_DEF); \
|
2006-02-09 21:09:26 +00:00
|
|
|
} while (0)
|
2003-10-14 22:51:45 +00:00
|
|
|
#define ATH_TXBUF_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_txbuflock)
|
|
|
|
#define ATH_TXBUF_LOCK(_sc) mtx_lock(&(_sc)->sc_txbuflock)
|
|
|
|
#define ATH_TXBUF_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_txbuflock)
|
|
|
|
#define ATH_TXBUF_LOCK_ASSERT(_sc) \
|
|
|
|
mtx_assert(&(_sc)->sc_txbuflock, MA_OWNED)
|
2013-05-08 21:23:51 +00:00
|
|
|
#define ATH_TXBUF_UNLOCK_ASSERT(_sc) \
|
|
|
|
mtx_assert(&(_sc)->sc_txbuflock, MA_NOTOWNED)
|
2003-10-14 22:51:45 +00:00
|
|
|
|
2012-07-23 02:49:25 +00:00
|
|
|
#define ATH_TXSTATUS_LOCK_INIT(_sc) do { \
|
|
|
|
snprintf((_sc)->sc_txcompname, sizeof((_sc)->sc_txcompname), \
|
|
|
|
"%s_buf", \
|
|
|
|
device_get_nameunit((_sc)->sc_dev)); \
|
|
|
|
mtx_init(&(_sc)->sc_txcomplock, (_sc)->sc_txcompname, NULL, \
|
|
|
|
MTX_DEF); \
|
|
|
|
} while (0)
|
|
|
|
#define ATH_TXSTATUS_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_txcomplock)
|
|
|
|
#define ATH_TXSTATUS_LOCK(_sc) mtx_lock(&(_sc)->sc_txcomplock)
|
|
|
|
#define ATH_TXSTATUS_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_txcomplock)
|
|
|
|
#define ATH_TXSTATUS_LOCK_ASSERT(_sc) \
|
|
|
|
mtx_assert(&(_sc)->sc_txcomplock, MA_OWNED)
|
|
|
|
|
2003-06-23 17:01:19 +00:00
|
|
|
int ath_attach(u_int16_t, struct ath_softc *);
|
|
|
|
int ath_detach(struct ath_softc *);
|
|
|
|
void ath_resume(struct ath_softc *);
|
|
|
|
void ath_suspend(struct ath_softc *);
|
|
|
|
void ath_shutdown(struct ath_softc *);
|
|
|
|
void ath_intr(void *);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* HAL definitions to comply with local coding convention.
|
|
|
|
*/
|
2004-12-08 17:34:36 +00:00
|
|
|
#define ath_hal_detach(_ah) \
|
|
|
|
((*(_ah)->ah_detach)((_ah)))
|
2003-06-23 17:01:19 +00:00
|
|
|
#define ath_hal_reset(_ah, _opmode, _chan, _outdoor, _pstatus) \
|
|
|
|
((*(_ah)->ah_reset)((_ah), (_opmode), (_chan), (_outdoor), (_pstatus)))
|
2009-01-08 17:12:47 +00:00
|
|
|
#define ath_hal_macversion(_ah) \
|
|
|
|
(((_ah)->ah_macVersion << 4) | ((_ah)->ah_macRev))
|
2003-06-23 17:01:19 +00:00
|
|
|
#define ath_hal_getratetable(_ah, _mode) \
|
|
|
|
((*(_ah)->ah_getRateTable)((_ah), (_mode)))
|
|
|
|
#define ath_hal_getmac(_ah, _mac) \
|
|
|
|
((*(_ah)->ah_getMacAddress)((_ah), (_mac)))
|
2004-12-08 17:34:36 +00:00
|
|
|
#define ath_hal_setmac(_ah, _mac) \
|
|
|
|
((*(_ah)->ah_setMacAddress)((_ah), (_mac)))
|
2008-04-20 20:35:46 +00:00
|
|
|
#define ath_hal_getbssidmask(_ah, _mask) \
|
|
|
|
((*(_ah)->ah_getBssIdMask)((_ah), (_mask)))
|
|
|
|
#define ath_hal_setbssidmask(_ah, _mask) \
|
|
|
|
((*(_ah)->ah_setBssIdMask)((_ah), (_mask)))
|
2003-06-23 17:01:19 +00:00
|
|
|
#define ath_hal_intrset(_ah, _mask) \
|
|
|
|
((*(_ah)->ah_setInterrupts)((_ah), (_mask)))
|
|
|
|
#define ath_hal_intrget(_ah) \
|
|
|
|
((*(_ah)->ah_getInterrupts)((_ah)))
|
|
|
|
#define ath_hal_intrpend(_ah) \
|
|
|
|
((*(_ah)->ah_isInterruptPending)((_ah)))
|
|
|
|
#define ath_hal_getisr(_ah, _pmask) \
|
|
|
|
((*(_ah)->ah_getPendingInterrupts)((_ah), (_pmask)))
|
|
|
|
#define ath_hal_updatetxtriglevel(_ah, _inc) \
|
|
|
|
((*(_ah)->ah_updateTxTrigLevel)((_ah), (_inc)))
|
2006-02-10 19:07:08 +00:00
|
|
|
#define ath_hal_setpower(_ah, _mode) \
|
|
|
|
((*(_ah)->ah_setPowerMode)((_ah), (_mode), AH_TRUE))
|
Bring over some initial power save management support, reset path
fixes and beacon programming / debugging into the ath(4) driver.
The basic power save tracking:
* Add some new code to track the current desired powersave state; and
* Add some reference count tracking so we know when the NIC is awake; then
* Add code in all the points where we're about to touch the hardware and
push it to force-wake.
Then, how things are moved into power save:
* Only move into network-sleep during a RUN->SLEEP transition;
* Force wake the hardware up everywhere that we're about to touch
the hardware.
The net80211 stack takes care of doing RUN<->SLEEP<->(other) state
transitions so we don't have to do it in the driver.
Next, when to wake things up:
* In short - everywhere we touch the hardware.
* The hardware will take care of staying awake if things are queued
in the transmit queue(s); it'll then transit down to sleep if
there's nothing left. This way we don't have to track the
software / hardware transmit queue(s) and keep the hardware
awake for those.
Then, some transmit path fixes that aren't related but useful:
* Force EAPOL frames to go out at the lowest rate. This improves
reliability during the encryption handshake after 802.11
negotiation.
Next, some reset path fixes!
* Fix the overlap between reset and transmit pause so we don't
transmit frames during a reset.
* Some noisy environments will end up taking a lot longer to reset
than normal, so extend the reset period and drop the raise the
reset interval to be more realistic and give the hardware some
time to finish calibration.
* Skip calibration during the reset path. Tsk!
Then, beacon fixes in station mode!
* Add a _lot_ more debugging in the station beacon reset path.
This is all quite fluid right now.
* Modify the STA beacon programming code to try and take
the TU gap between desired TSF and the target TU into
account. (Lifted from QCA.)
Tested:
* AR5210
* AR5211
* AR5212
* AR5413
* AR5416
* AR9280
* AR9285
TODO:
* More AP, IBSS, mesh, TDMA testing
* Thorough AR9380 and later testing!
* AR9160 and AR9287 testing
Obtained from: QCA
2014-04-30 02:19:41 +00:00
|
|
|
#define ath_hal_setselfgenpower(_ah, _mode) \
|
|
|
|
((*(_ah)->ah_setPowerMode)((_ah), (_mode), AH_FALSE))
|
2004-12-08 17:34:36 +00:00
|
|
|
#define ath_hal_keycachesize(_ah) \
|
|
|
|
((*(_ah)->ah_getKeyCacheSize)((_ah)))
|
2003-06-23 17:01:19 +00:00
|
|
|
#define ath_hal_keyreset(_ah, _ix) \
|
|
|
|
((*(_ah)->ah_resetKeyCacheEntry)((_ah), (_ix)))
|
2004-12-08 17:34:36 +00:00
|
|
|
#define ath_hal_keyset(_ah, _ix, _pk, _mac) \
|
|
|
|
((*(_ah)->ah_setKeyCacheEntry)((_ah), (_ix), (_pk), (_mac), AH_FALSE))
|
2003-06-23 17:01:19 +00:00
|
|
|
#define ath_hal_keyisvalid(_ah, _ix) \
|
|
|
|
(((*(_ah)->ah_isKeyCacheEntryValid)((_ah), (_ix))))
|
|
|
|
#define ath_hal_keysetmac(_ah, _ix, _mac) \
|
|
|
|
((*(_ah)->ah_setKeyCacheEntryMac)((_ah), (_ix), (_mac)))
|
|
|
|
#define ath_hal_getrxfilter(_ah) \
|
|
|
|
((*(_ah)->ah_getRxFilter)((_ah)))
|
|
|
|
#define ath_hal_setrxfilter(_ah, _filter) \
|
|
|
|
((*(_ah)->ah_setRxFilter)((_ah), (_filter)))
|
|
|
|
#define ath_hal_setmcastfilter(_ah, _mfilt0, _mfilt1) \
|
|
|
|
((*(_ah)->ah_setMulticastFilter)((_ah), (_mfilt0), (_mfilt1)))
|
|
|
|
#define ath_hal_waitforbeacon(_ah, _bf) \
|
|
|
|
((*(_ah)->ah_waitForBeaconDone)((_ah), (_bf)->bf_daddr))
|
2012-07-09 07:19:11 +00:00
|
|
|
#define ath_hal_putrxbuf(_ah, _bufaddr, _rxq) \
|
|
|
|
((*(_ah)->ah_setRxDP)((_ah), (_bufaddr), (_rxq)))
|
2009-01-08 17:12:47 +00:00
|
|
|
/* NB: common across all chips */
|
|
|
|
#define AR_TSF_L32 0x804c /* MAC local clock lower 32 bits */
|
2003-06-23 17:01:19 +00:00
|
|
|
#define ath_hal_gettsf32(_ah) \
|
2009-01-08 17:12:47 +00:00
|
|
|
OS_REG_READ(_ah, AR_TSF_L32)
|
2003-06-23 17:01:19 +00:00
|
|
|
#define ath_hal_gettsf64(_ah) \
|
|
|
|
((*(_ah)->ah_getTsf64)((_ah)))
|
2012-11-23 05:33:01 +00:00
|
|
|
#define ath_hal_settsf64(_ah, _val) \
|
|
|
|
((*(_ah)->ah_setTsf64)((_ah), (_val)))
|
2003-06-23 17:01:19 +00:00
|
|
|
#define ath_hal_resettsf(_ah) \
|
|
|
|
((*(_ah)->ah_resetTsf)((_ah)))
|
|
|
|
#define ath_hal_rxena(_ah) \
|
|
|
|
((*(_ah)->ah_enableReceive)((_ah)))
|
|
|
|
#define ath_hal_puttxbuf(_ah, _q, _bufaddr) \
|
|
|
|
((*(_ah)->ah_setTxDP)((_ah), (_q), (_bufaddr)))
|
|
|
|
#define ath_hal_gettxbuf(_ah, _q) \
|
|
|
|
((*(_ah)->ah_getTxDP)((_ah), (_q)))
|
2004-12-08 17:34:36 +00:00
|
|
|
#define ath_hal_numtxpending(_ah, _q) \
|
|
|
|
((*(_ah)->ah_numTxPending)((_ah), (_q)))
|
2012-07-09 07:19:11 +00:00
|
|
|
#define ath_hal_getrxbuf(_ah, _rxq) \
|
|
|
|
((*(_ah)->ah_getRxDP)((_ah), (_rxq)))
|
2003-06-23 17:01:19 +00:00
|
|
|
#define ath_hal_txstart(_ah, _q) \
|
|
|
|
((*(_ah)->ah_startTxDma)((_ah), (_q)))
|
|
|
|
#define ath_hal_setchannel(_ah, _chan) \
|
|
|
|
((*(_ah)->ah_setChannel)((_ah), (_chan)))
|
2006-02-10 19:07:08 +00:00
|
|
|
#define ath_hal_calibrate(_ah, _chan, _iqcal) \
|
|
|
|
((*(_ah)->ah_perCalibration)((_ah), (_chan), (_iqcal)))
|
2008-12-07 19:26:34 +00:00
|
|
|
#define ath_hal_calibrateN(_ah, _chan, _lcal, _isdone) \
|
|
|
|
((*(_ah)->ah_perCalibrationN)((_ah), (_chan), 0x1, (_lcal), (_isdone)))
|
|
|
|
#define ath_hal_calreset(_ah, _chan) \
|
|
|
|
((*(_ah)->ah_resetCalValid)((_ah), (_chan)))
|
2003-06-23 17:01:19 +00:00
|
|
|
#define ath_hal_setledstate(_ah, _state) \
|
|
|
|
((*(_ah)->ah_setLedState)((_ah), (_state)))
|
2004-12-08 17:34:36 +00:00
|
|
|
#define ath_hal_beaconinit(_ah, _nextb, _bperiod) \
|
|
|
|
((*(_ah)->ah_beaconInit)((_ah), (_nextb), (_bperiod)))
|
2003-06-23 17:01:19 +00:00
|
|
|
#define ath_hal_beaconreset(_ah) \
|
|
|
|
((*(_ah)->ah_resetStationBeaconTimers)((_ah)))
|
2009-01-08 17:12:47 +00:00
|
|
|
#define ath_hal_beaconsettimers(_ah, _bt) \
|
|
|
|
((*(_ah)->ah_setBeaconTimers)((_ah), (_bt)))
|
2004-12-08 17:34:36 +00:00
|
|
|
#define ath_hal_beacontimers(_ah, _bs) \
|
|
|
|
((*(_ah)->ah_setStationBeaconTimers)((_ah), (_bs)))
|
2011-09-08 01:23:05 +00:00
|
|
|
#define ath_hal_getnexttbtt(_ah) \
|
|
|
|
((*(_ah)->ah_getNextTBTT)((_ah)))
|
2003-06-23 17:01:19 +00:00
|
|
|
#define ath_hal_setassocid(_ah, _bss, _associd) \
|
2004-12-08 17:34:36 +00:00
|
|
|
((*(_ah)->ah_writeAssocid)((_ah), (_bss), (_associd)))
|
|
|
|
#define ath_hal_phydisable(_ah) \
|
|
|
|
((*(_ah)->ah_phyDisable)((_ah)))
|
|
|
|
#define ath_hal_setopmode(_ah) \
|
|
|
|
((*(_ah)->ah_setPCUConfig)((_ah)))
|
2003-06-23 17:01:19 +00:00
|
|
|
#define ath_hal_stoptxdma(_ah, _qnum) \
|
|
|
|
((*(_ah)->ah_stopTxDma)((_ah), (_qnum)))
|
|
|
|
#define ath_hal_stoppcurecv(_ah) \
|
|
|
|
((*(_ah)->ah_stopPcuReceive)((_ah)))
|
|
|
|
#define ath_hal_startpcurecv(_ah) \
|
|
|
|
((*(_ah)->ah_startPcuReceive)((_ah)))
|
|
|
|
#define ath_hal_stopdmarecv(_ah) \
|
|
|
|
((*(_ah)->ah_stopDmaReceive)((_ah)))
|
2004-12-08 17:34:36 +00:00
|
|
|
#define ath_hal_getdiagstate(_ah, _id, _indata, _insize, _outdata, _outsize) \
|
|
|
|
((*(_ah)->ah_getDiagState)((_ah), (_id), \
|
|
|
|
(_indata), (_insize), (_outdata), (_outsize)))
|
2006-02-15 18:23:03 +00:00
|
|
|
#define ath_hal_getfatalstate(_ah, _outdata, _outsize) \
|
Update 802.11 wireless support:
o major overhaul of the way channels are handled: channels are now
fully enumerated and uniquely identify the operating characteristics;
these changes are visible to user applications which require changes
o make scanning support independent of the state machine to enable
background scanning and roaming
o move scanning support into loadable modules based on the operating
mode to enable different policies and reduce the memory footprint
on systems w/ constrained resources
o add background scanning in station mode (no support for adhoc/ibss
mode yet)
o significantly speedup sta mode scanning with a variety of techniques
o add roaming support when background scanning is supported; for now
we use a simple algorithm to trigger a roam: we threshold the rssi
and tx rate, if either drops too low we try to roam to a new ap
o add tx fragmentation support
o add first cut at 802.11n support: this code works with forthcoming
drivers but is incomplete; it's included now to establish a baseline
for other drivers to be developed and for user applications
o adjust max_linkhdr et. al. to reflect 802.11 requirements; this eliminates
prepending mbufs for traffic generated locally
o add support for Atheros protocol extensions; mainly the fast frames
encapsulation (note this can be used with any card that can tx+rx
large frames correctly)
o add sta support for ap's that beacon both WPA1+2 support
o change all data types from bsd-style to posix-style
o propagate noise floor data from drivers to net80211 and on to user apps
o correct various issues in the sta mode state machine related to handling
authentication and association failures
o enable the addition of sta mode power save support for drivers that need
net80211 support (not in this commit)
o remove old WI compatibility ioctls (wicontrol is officially dead)
o change the data structures returned for get sta info and get scan
results so future additions will not break user apps
o fixed tx rate is now maintained internally as an ieee rate and not an
index into the rate set; this needs to be extended to deal with
multi-mode operation
o add extended channel specifications to radiotap to enable 11n sniffing
Drivers:
o ath: add support for bg scanning, tx fragmentation, fast frames,
dynamic turbo (lightly tested), 11n (sniffing only and needs
new hal)
o awi: compile tested only
o ndis: lightly tested
o ipw: lightly tested
o iwi: add support for bg scanning (well tested but may have some
rough edges)
o ral, ural, rum: add suppoort for bg scanning, calibrate rssi data
o wi: lightly tested
This work is based on contributions by Atheros, kmacy, sephe, thompsa,
mlaier, kevlo, and others. Much of the scanning work was supported by
Atheros. The 11n work was supported by Marvell.
2007-06-11 03:36:55 +00:00
|
|
|
ath_hal_getdiagstate(_ah, 29, NULL, 0, (_outdata), _outsize)
|
2003-06-23 17:01:19 +00:00
|
|
|
#define ath_hal_setuptxqueue(_ah, _type, _irq) \
|
|
|
|
((*(_ah)->ah_setupTxQueue)((_ah), (_type), (_irq)))
|
|
|
|
#define ath_hal_resettxqueue(_ah, _q) \
|
|
|
|
((*(_ah)->ah_resetTxQueue)((_ah), (_q)))
|
|
|
|
#define ath_hal_releasetxqueue(_ah, _q) \
|
|
|
|
((*(_ah)->ah_releaseTxQueue)((_ah), (_q)))
|
2004-12-08 17:34:36 +00:00
|
|
|
#define ath_hal_gettxqueueprops(_ah, _q, _qi) \
|
|
|
|
((*(_ah)->ah_getTxQueueProps)((_ah), (_q), (_qi)))
|
|
|
|
#define ath_hal_settxqueueprops(_ah, _q, _qi) \
|
|
|
|
((*(_ah)->ah_setTxQueueProps)((_ah), (_q), (_qi)))
|
2009-01-08 17:12:47 +00:00
|
|
|
/* NB: common across all chips */
|
|
|
|
#define AR_Q_TXE 0x0840 /* MAC Transmit Queue enable */
|
|
|
|
#define ath_hal_txqenabled(_ah, _qnum) \
|
|
|
|
(OS_REG_READ(_ah, AR_Q_TXE) & (1<<(_qnum)))
|
2003-06-23 17:01:19 +00:00
|
|
|
#define ath_hal_getrfgain(_ah) \
|
|
|
|
((*(_ah)->ah_getRfGain)((_ah)))
|
2004-12-08 17:34:36 +00:00
|
|
|
#define ath_hal_getdefantenna(_ah) \
|
|
|
|
((*(_ah)->ah_getDefAntenna)((_ah)))
|
|
|
|
#define ath_hal_setdefantenna(_ah, _ant) \
|
|
|
|
((*(_ah)->ah_setDefAntenna)((_ah), (_ant)))
|
2006-02-10 19:07:08 +00:00
|
|
|
#define ath_hal_rxmonitor(_ah, _arg, _chan) \
|
|
|
|
((*(_ah)->ah_rxMonitor)((_ah), (_arg), (_chan)))
|
2011-01-21 05:21:00 +00:00
|
|
|
#define ath_hal_ani_poll(_ah, _chan) \
|
|
|
|
((*(_ah)->ah_aniPoll)((_ah), (_chan)))
|
2004-12-08 17:34:36 +00:00
|
|
|
#define ath_hal_mibevent(_ah, _stats) \
|
|
|
|
((*(_ah)->ah_procMibEvent)((_ah), (_stats)))
|
|
|
|
#define ath_hal_setslottime(_ah, _us) \
|
|
|
|
((*(_ah)->ah_setSlotTime)((_ah), (_us)))
|
|
|
|
#define ath_hal_getslottime(_ah) \
|
|
|
|
((*(_ah)->ah_getSlotTime)((_ah)))
|
|
|
|
#define ath_hal_setacktimeout(_ah, _us) \
|
|
|
|
((*(_ah)->ah_setAckTimeout)((_ah), (_us)))
|
|
|
|
#define ath_hal_getacktimeout(_ah) \
|
|
|
|
((*(_ah)->ah_getAckTimeout)((_ah)))
|
|
|
|
#define ath_hal_setctstimeout(_ah, _us) \
|
|
|
|
((*(_ah)->ah_setCTSTimeout)((_ah), (_us)))
|
|
|
|
#define ath_hal_getctstimeout(_ah) \
|
|
|
|
((*(_ah)->ah_getCTSTimeout)((_ah)))
|
|
|
|
#define ath_hal_getcapability(_ah, _cap, _param, _result) \
|
|
|
|
((*(_ah)->ah_getCapability)((_ah), (_cap), (_param), (_result)))
|
|
|
|
#define ath_hal_setcapability(_ah, _cap, _param, _v, _status) \
|
|
|
|
((*(_ah)->ah_setCapability)((_ah), (_cap), (_param), (_v), (_status)))
|
|
|
|
#define ath_hal_ciphersupported(_ah, _cipher) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_CIPHER, _cipher, NULL) == HAL_OK)
|
|
|
|
#define ath_hal_getregdomain(_ah, _prd) \
|
2006-02-10 19:07:08 +00:00
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_REG_DMN, 0, (_prd)) == HAL_OK)
|
2008-10-27 18:30:33 +00:00
|
|
|
#define ath_hal_setregdomain(_ah, _rd) \
|
|
|
|
ath_hal_setcapability(_ah, HAL_CAP_REG_DMN, 0, _rd, NULL)
|
2004-12-08 17:34:36 +00:00
|
|
|
#define ath_hal_getcountrycode(_ah, _pcc) \
|
|
|
|
(*(_pcc) = (_ah)->ah_countryCode)
|
2008-04-20 20:35:46 +00:00
|
|
|
#define ath_hal_gettkipmic(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_TKIP_MIC, 1, NULL) == HAL_OK)
|
|
|
|
#define ath_hal_settkipmic(_ah, _v) \
|
|
|
|
ath_hal_setcapability(_ah, HAL_CAP_TKIP_MIC, 1, _v, NULL)
|
2006-09-18 16:26:19 +00:00
|
|
|
#define ath_hal_hastkipsplit(_ah) \
|
2004-12-08 17:34:36 +00:00
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_TKIP_SPLIT, 0, NULL) == HAL_OK)
|
2006-09-18 16:26:19 +00:00
|
|
|
#define ath_hal_gettkipsplit(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_TKIP_SPLIT, 1, NULL) == HAL_OK)
|
|
|
|
#define ath_hal_settkipsplit(_ah, _v) \
|
|
|
|
ath_hal_setcapability(_ah, HAL_CAP_TKIP_SPLIT, 1, _v, NULL)
|
2008-04-20 20:35:46 +00:00
|
|
|
#define ath_hal_haswmetkipmic(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_WME_TKIPMIC, 0, NULL) == HAL_OK)
|
2004-12-08 17:34:36 +00:00
|
|
|
#define ath_hal_hwphycounters(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_PHYCOUNTERS, 0, NULL) == HAL_OK)
|
|
|
|
#define ath_hal_hasdiversity(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_DIVERSITY, 0, NULL) == HAL_OK)
|
|
|
|
#define ath_hal_getdiversity(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_DIVERSITY, 1, NULL) == HAL_OK)
|
|
|
|
#define ath_hal_setdiversity(_ah, _v) \
|
|
|
|
ath_hal_setcapability(_ah, HAL_CAP_DIVERSITY, 1, _v, NULL)
|
2007-02-24 23:12:58 +00:00
|
|
|
#define ath_hal_getantennaswitch(_ah) \
|
|
|
|
((*(_ah)->ah_getAntennaSwitch)((_ah)))
|
|
|
|
#define ath_hal_setantennaswitch(_ah, _v) \
|
|
|
|
((*(_ah)->ah_setAntennaSwitch)((_ah), (_v)))
|
2004-12-08 17:34:36 +00:00
|
|
|
#define ath_hal_getdiag(_ah, _pv) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_DIAG, 0, _pv) == HAL_OK)
|
|
|
|
#define ath_hal_setdiag(_ah, _v) \
|
|
|
|
ath_hal_setcapability(_ah, HAL_CAP_DIAG, 0, _v, NULL)
|
|
|
|
#define ath_hal_getnumtxqueues(_ah, _pv) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_NUM_TXQUEUES, 0, _pv) == HAL_OK)
|
|
|
|
#define ath_hal_hasveol(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_VEOL, 0, NULL) == HAL_OK)
|
|
|
|
#define ath_hal_hastxpowlimit(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_TXPOW, 0, NULL) == HAL_OK)
|
|
|
|
#define ath_hal_settxpowlimit(_ah, _pow) \
|
|
|
|
((*(_ah)->ah_setTxPowerLimit)((_ah), (_pow)))
|
|
|
|
#define ath_hal_gettxpowlimit(_ah, _ppow) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_TXPOW, 1, _ppow) == HAL_OK)
|
|
|
|
#define ath_hal_getmaxtxpow(_ah, _ppow) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_TXPOW, 2, _ppow) == HAL_OK)
|
|
|
|
#define ath_hal_gettpscale(_ah, _scale) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_TXPOW, 3, _scale) == HAL_OK)
|
|
|
|
#define ath_hal_settpscale(_ah, _v) \
|
|
|
|
ath_hal_setcapability(_ah, HAL_CAP_TXPOW, 3, _v, NULL)
|
|
|
|
#define ath_hal_hastpc(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_TPC, 0, NULL) == HAL_OK)
|
|
|
|
#define ath_hal_gettpc(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_TPC, 1, NULL) == HAL_OK)
|
|
|
|
#define ath_hal_settpc(_ah, _v) \
|
|
|
|
ath_hal_setcapability(_ah, HAL_CAP_TPC, 1, _v, NULL)
|
|
|
|
#define ath_hal_hasbursting(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_BURST, 0, NULL) == HAL_OK)
|
2010-02-08 20:23:20 +00:00
|
|
|
#define ath_hal_setmcastkeysearch(_ah, _v) \
|
|
|
|
ath_hal_setcapability(_ah, HAL_CAP_MCAST_KEYSRCH, 0, _v, NULL)
|
2005-06-06 16:39:21 +00:00
|
|
|
#define ath_hal_hasmcastkeysearch(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_MCAST_KEYSRCH, 0, NULL) == HAL_OK)
|
|
|
|
#define ath_hal_getmcastkeysearch(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_MCAST_KEYSRCH, 1, NULL) == HAL_OK)
|
Update 802.11 wireless support:
o major overhaul of the way channels are handled: channels are now
fully enumerated and uniquely identify the operating characteristics;
these changes are visible to user applications which require changes
o make scanning support independent of the state machine to enable
background scanning and roaming
o move scanning support into loadable modules based on the operating
mode to enable different policies and reduce the memory footprint
on systems w/ constrained resources
o add background scanning in station mode (no support for adhoc/ibss
mode yet)
o significantly speedup sta mode scanning with a variety of techniques
o add roaming support when background scanning is supported; for now
we use a simple algorithm to trigger a roam: we threshold the rssi
and tx rate, if either drops too low we try to roam to a new ap
o add tx fragmentation support
o add first cut at 802.11n support: this code works with forthcoming
drivers but is incomplete; it's included now to establish a baseline
for other drivers to be developed and for user applications
o adjust max_linkhdr et. al. to reflect 802.11 requirements; this eliminates
prepending mbufs for traffic generated locally
o add support for Atheros protocol extensions; mainly the fast frames
encapsulation (note this can be used with any card that can tx+rx
large frames correctly)
o add sta support for ap's that beacon both WPA1+2 support
o change all data types from bsd-style to posix-style
o propagate noise floor data from drivers to net80211 and on to user apps
o correct various issues in the sta mode state machine related to handling
authentication and association failures
o enable the addition of sta mode power save support for drivers that need
net80211 support (not in this commit)
o remove old WI compatibility ioctls (wicontrol is officially dead)
o change the data structures returned for get sta info and get scan
results so future additions will not break user apps
o fixed tx rate is now maintained internally as an ieee rate and not an
index into the rate set; this needs to be extended to deal with
multi-mode operation
o add extended channel specifications to radiotap to enable 11n sniffing
Drivers:
o ath: add support for bg scanning, tx fragmentation, fast frames,
dynamic turbo (lightly tested), 11n (sniffing only and needs
new hal)
o awi: compile tested only
o ndis: lightly tested
o ipw: lightly tested
o iwi: add support for bg scanning (well tested but may have some
rough edges)
o ral, ural, rum: add suppoort for bg scanning, calibrate rssi data
o wi: lightly tested
This work is based on contributions by Atheros, kmacy, sephe, thompsa,
mlaier, kevlo, and others. Much of the scanning work was supported by
Atheros. The 11n work was supported by Marvell.
2007-06-11 03:36:55 +00:00
|
|
|
#define ath_hal_hasfastframes(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_FASTFRAME, 0, NULL) == HAL_OK)
|
2008-04-20 20:35:46 +00:00
|
|
|
#define ath_hal_hasbssidmask(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_BSSIDMASK, 0, NULL) == HAL_OK)
|
2009-06-27 20:06:56 +00:00
|
|
|
#define ath_hal_hasbssidmatch(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_BSSIDMATCH, 0, NULL) == HAL_OK)
|
2008-04-20 20:35:46 +00:00
|
|
|
#define ath_hal_hastsfadjust(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_TSF_ADJUST, 0, NULL) == HAL_OK)
|
|
|
|
#define ath_hal_gettsfadjust(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_TSF_ADJUST, 1, NULL) == HAL_OK)
|
|
|
|
#define ath_hal_settsfadjust(_ah, _onoff) \
|
|
|
|
ath_hal_setcapability(_ah, HAL_CAP_TSF_ADJUST, 1, _onoff, NULL)
|
2006-02-10 19:07:08 +00:00
|
|
|
#define ath_hal_hasrfsilent(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_RFSILENT, 0, NULL) == HAL_OK)
|
|
|
|
#define ath_hal_getrfkill(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_RFSILENT, 1, NULL) == HAL_OK)
|
|
|
|
#define ath_hal_setrfkill(_ah, _onoff) \
|
|
|
|
ath_hal_setcapability(_ah, HAL_CAP_RFSILENT, 1, _onoff, NULL)
|
|
|
|
#define ath_hal_getrfsilent(_ah, _prfsilent) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_RFSILENT, 2, _prfsilent) == HAL_OK)
|
|
|
|
#define ath_hal_setrfsilent(_ah, _rfsilent) \
|
|
|
|
ath_hal_setcapability(_ah, HAL_CAP_RFSILENT, 2, _rfsilent, NULL)
|
|
|
|
#define ath_hal_gettpack(_ah, _ptpack) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_TPC_ACK, 0, _ptpack) == HAL_OK)
|
|
|
|
#define ath_hal_settpack(_ah, _tpack) \
|
|
|
|
ath_hal_setcapability(_ah, HAL_CAP_TPC_ACK, 0, _tpack, NULL)
|
|
|
|
#define ath_hal_gettpcts(_ah, _ptpcts) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_TPC_CTS, 0, _ptpcts) == HAL_OK)
|
|
|
|
#define ath_hal_settpcts(_ah, _tpcts) \
|
|
|
|
ath_hal_setcapability(_ah, HAL_CAP_TPC_CTS, 0, _tpcts, NULL)
|
2008-10-27 17:22:46 +00:00
|
|
|
#define ath_hal_hasintmit(_ah) \
|
2012-01-24 06:12:48 +00:00
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_INTMIT, \
|
|
|
|
HAL_CAP_INTMIT_PRESENT, NULL) == HAL_OK)
|
2008-10-27 17:22:46 +00:00
|
|
|
#define ath_hal_getintmit(_ah) \
|
2012-01-24 06:12:48 +00:00
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_INTMIT, \
|
|
|
|
HAL_CAP_INTMIT_ENABLE, NULL) == HAL_OK)
|
2008-10-27 17:22:46 +00:00
|
|
|
#define ath_hal_setintmit(_ah, _v) \
|
2012-01-24 06:12:48 +00:00
|
|
|
ath_hal_setcapability(_ah, HAL_CAP_INTMIT, \
|
|
|
|
HAL_CAP_INTMIT_ENABLE, _v, NULL)
|
Bring over some initial power save management support, reset path
fixes and beacon programming / debugging into the ath(4) driver.
The basic power save tracking:
* Add some new code to track the current desired powersave state; and
* Add some reference count tracking so we know when the NIC is awake; then
* Add code in all the points where we're about to touch the hardware and
push it to force-wake.
Then, how things are moved into power save:
* Only move into network-sleep during a RUN->SLEEP transition;
* Force wake the hardware up everywhere that we're about to touch
the hardware.
The net80211 stack takes care of doing RUN<->SLEEP<->(other) state
transitions so we don't have to do it in the driver.
Next, when to wake things up:
* In short - everywhere we touch the hardware.
* The hardware will take care of staying awake if things are queued
in the transmit queue(s); it'll then transit down to sleep if
there's nothing left. This way we don't have to track the
software / hardware transmit queue(s) and keep the hardware
awake for those.
Then, some transmit path fixes that aren't related but useful:
* Force EAPOL frames to go out at the lowest rate. This improves
reliability during the encryption handshake after 802.11
negotiation.
Next, some reset path fixes!
* Fix the overlap between reset and transmit pause so we don't
transmit frames during a reset.
* Some noisy environments will end up taking a lot longer to reset
than normal, so extend the reset period and drop the raise the
reset interval to be more realistic and give the hardware some
time to finish calibration.
* Skip calibration during the reset path. Tsk!
Then, beacon fixes in station mode!
* Add a _lot_ more debugging in the station beacon reset path.
This is all quite fluid right now.
* Modify the STA beacon programming code to try and take
the TU gap between desired TSF and the target TU into
account. (Lifted from QCA.)
Tested:
* AR5210
* AR5211
* AR5212
* AR5413
* AR5416
* AR9280
* AR9285
TODO:
* More AP, IBSS, mesh, TDMA testing
* Thorough AR9380 and later testing!
* AR9160 and AR9287 testing
Obtained from: QCA
2014-04-30 02:19:41 +00:00
|
|
|
#define ath_hal_hasmybeacon(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_DO_MYBEACON, 1, NULL) == HAL_OK)
|
2012-07-09 07:31:26 +00:00
|
|
|
|
Enable the use of TDMA on an 802.11n channel (with aggregation disabled,
of course.)
There's a few things that needed to happen:
* In case someone decides to set the beacon transmission rate to be
at an MCS rate, use the MCS-aware version of the duration calculation
to figure out how long the received beacon frame was.
* If TxOP enforcing is available on the hardware and we're doing TDMA,
enable it after a reset and set the TDMA guard interval to zero.
This seems to behave fine.
TODO:
* Although I haven't yet seen packet loss, the PHY errors that would be
triggered (specifically Transmit-Override-Receive) aren't enabled
by the 11n HAL. I'll have to do some work to enable these PHY errors
for debugging.
What broke:
* My recent changes to the TX queue handling has resulted in the driver
not keeping the hardware queue properly filled when doing non-aggregate
traffic. I have a patch to commit soon which fixes this situation
(albeit by reminding me about how my ath driver locking isn't working
out, sigh.)
So if you want to test this without updating to the next set of patches
that I commit, just bump the sysctl dev.ath.X.hwq_limit from 2 to 32.
Tested:
* AR5416 <-> AR5416, with ampdu disabled, HT40, 5GHz, MCS12+Short-GI.
I saw 30mbit/sec in both directions using a bidirectional UDP test.
2013-05-21 18:02:54 +00:00
|
|
|
#define ath_hal_hasenforcetxop(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_ENFORCE_TXOP, 0, NULL) == HAL_OK)
|
|
|
|
#define ath_hal_getenforcetxop(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_ENFORCE_TXOP, 1, NULL) == HAL_OK)
|
|
|
|
#define ath_hal_setenforcetxop(_ah, _v) \
|
|
|
|
ath_hal_setcapability(_ah, HAL_CAP_ENFORCE_TXOP, 1, _v, NULL)
|
|
|
|
|
2013-06-05 00:45:19 +00:00
|
|
|
#define ath_hal_hasrxlnamixer(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_RX_LNA_MIXING, 0, NULL) == HAL_OK)
|
Enable the use of TDMA on an 802.11n channel (with aggregation disabled,
of course.)
There's a few things that needed to happen:
* In case someone decides to set the beacon transmission rate to be
at an MCS rate, use the MCS-aware version of the duration calculation
to figure out how long the received beacon frame was.
* If TxOP enforcing is available on the hardware and we're doing TDMA,
enable it after a reset and set the TDMA guard interval to zero.
This seems to behave fine.
TODO:
* Although I haven't yet seen packet loss, the PHY errors that would be
triggered (specifically Transmit-Override-Receive) aren't enabled
by the 11n HAL. I'll have to do some work to enable these PHY errors
for debugging.
What broke:
* My recent changes to the TX queue handling has resulted in the driver
not keeping the hardware queue properly filled when doing non-aggregate
traffic. I have a patch to commit soon which fixes this situation
(albeit by reminding me about how my ath driver locking isn't working
out, sigh.)
So if you want to test this without updating to the next set of patches
that I commit, just bump the sysctl dev.ath.X.hwq_limit from 2 to 32.
Tested:
* AR5416 <-> AR5416, with ampdu disabled, HT40, 5GHz, MCS12+Short-GI.
I saw 30mbit/sec in both directions using a bidirectional UDP test.
2013-05-21 18:02:54 +00:00
|
|
|
|
2013-06-12 14:52:57 +00:00
|
|
|
#define ath_hal_hasdivantcomb(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_ANT_DIV_COMB, 0, NULL) == HAL_OK)
|
|
|
|
|
2012-07-09 07:31:26 +00:00
|
|
|
/* EDMA definitions */
|
2012-07-02 06:02:12 +00:00
|
|
|
#define ath_hal_hasedma(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_ENHANCED_DMA_SUPPORT, \
|
|
|
|
0, NULL) == HAL_OK)
|
2012-07-09 07:31:26 +00:00
|
|
|
#define ath_hal_getrxfifodepth(_ah, _qtype, _req) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_RXFIFODEPTH, _qtype, _req) \
|
|
|
|
== HAL_OK)
|
|
|
|
#define ath_hal_getntxmaps(_ah, _req) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_NUM_TXMAPS, 0, _req) \
|
|
|
|
== HAL_OK)
|
|
|
|
#define ath_hal_gettxdesclen(_ah, _req) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_TXDESCLEN, 0, _req) \
|
|
|
|
== HAL_OK)
|
|
|
|
#define ath_hal_gettxstatuslen(_ah, _req) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_TXSTATUSLEN, 0, _req) \
|
|
|
|
== HAL_OK)
|
|
|
|
#define ath_hal_getrxstatuslen(_ah, _req) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_RXSTATUSLEN, 0, _req) \
|
|
|
|
== HAL_OK)
|
|
|
|
#define ath_hal_setrxbufsize(_ah, _req) \
|
|
|
|
(ath_hal_setcapability(_ah, HAL_CAP_RXBUFSIZE, 0, _req, NULL) \
|
|
|
|
== HAL_OK)
|
|
|
|
|
2006-01-09 17:13:20 +00:00
|
|
|
#define ath_hal_getchannoise(_ah, _c) \
|
|
|
|
((*(_ah)->ah_getChanNoise)((_ah), (_c)))
|
2012-07-09 07:31:26 +00:00
|
|
|
|
|
|
|
/* 802.11n HAL methods */
|
2011-02-01 04:39:15 +00:00
|
|
|
#define ath_hal_getrxchainmask(_ah, _prxchainmask) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_RX_CHAINMASK, 0, _prxchainmask))
|
|
|
|
#define ath_hal_gettxchainmask(_ah, _ptxchainmask) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_TX_CHAINMASK, 0, _ptxchainmask))
|
2012-02-10 10:01:09 +00:00
|
|
|
#define ath_hal_setrxchainmask(_ah, _rx) \
|
|
|
|
(ath_hal_setcapability(_ah, HAL_CAP_RX_CHAINMASK, 1, _rx, NULL))
|
|
|
|
#define ath_hal_settxchainmask(_ah, _tx) \
|
|
|
|
(ath_hal_setcapability(_ah, HAL_CAP_TX_CHAINMASK, 1, _tx, NULL))
|
2011-02-09 16:37:29 +00:00
|
|
|
#define ath_hal_split4ktrans(_ah) \
|
2012-01-24 06:12:48 +00:00
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_SPLIT_4KB_TRANS, \
|
|
|
|
0, NULL) == HAL_OK)
|
2011-04-04 14:52:31 +00:00
|
|
|
#define ath_hal_self_linked_final_rxdesc(_ah) \
|
2012-01-24 06:12:48 +00:00
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_RXDESC_SELFLINK, \
|
|
|
|
0, NULL) == HAL_OK)
|
2011-04-18 12:15:43 +00:00
|
|
|
#define ath_hal_gtxto_supported(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_GTXTO, 0, NULL) == HAL_OK)
|
2011-09-08 01:23:05 +00:00
|
|
|
#define ath_hal_has_long_rxdesc_tsf(_ah) \
|
2012-01-24 06:12:48 +00:00
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_LONG_RXDESC_TSF, \
|
|
|
|
0, NULL) == HAL_OK)
|
2003-06-23 17:01:19 +00:00
|
|
|
#define ath_hal_setuprxdesc(_ah, _ds, _size, _intreq) \
|
|
|
|
((*(_ah)->ah_setupRxDesc)((_ah), (_ds), (_size), (_intreq)))
|
2006-12-13 19:34:35 +00:00
|
|
|
#define ath_hal_rxprocdesc(_ah, _ds, _dspa, _dsnext, _rs) \
|
|
|
|
((*(_ah)->ah_procRxDesc)((_ah), (_ds), (_dspa), (_dsnext), 0, (_rs)))
|
2003-06-23 17:01:19 +00:00
|
|
|
#define ath_hal_setuptxdesc(_ah, _ds, _plen, _hlen, _atype, _txpow, \
|
|
|
|
_txr0, _txtr0, _keyix, _ant, _flags, \
|
|
|
|
_rtsrate, _rtsdura) \
|
|
|
|
((*(_ah)->ah_setupTxDesc)((_ah), (_ds), (_plen), (_hlen), (_atype), \
|
|
|
|
(_txpow), (_txr0), (_txtr0), (_keyix), (_ant), \
|
2006-02-10 19:07:08 +00:00
|
|
|
(_flags), (_rtsrate), (_rtsdura), 0, 0, 0))
|
2004-12-08 17:34:36 +00:00
|
|
|
#define ath_hal_setupxtxdesc(_ah, _ds, \
|
2003-06-23 17:01:19 +00:00
|
|
|
_txr1, _txtr1, _txr2, _txtr2, _txr3, _txtr3) \
|
2004-12-08 17:34:36 +00:00
|
|
|
((*(_ah)->ah_setupXTxDesc)((_ah), (_ds), \
|
2003-06-23 17:01:19 +00:00
|
|
|
(_txr1), (_txtr1), (_txr2), (_txtr2), (_txr3), (_txtr3)))
|
2012-08-05 10:12:27 +00:00
|
|
|
#define ath_hal_filltxdesc(_ah, _ds, _b, _l, _did, _qid, _first, _last, _ds0) \
|
|
|
|
((*(_ah)->ah_fillTxDesc)((_ah), (_ds), (_b), (_l), (_did), (_qid), \
|
|
|
|
(_first), (_last), (_ds0)))
|
2006-12-13 19:34:35 +00:00
|
|
|
#define ath_hal_txprocdesc(_ah, _ds, _ts) \
|
|
|
|
((*(_ah)->ah_procTxDesc)((_ah), (_ds), (_ts)))
|
2006-02-10 19:07:08 +00:00
|
|
|
#define ath_hal_gettxintrtxqs(_ah, _txqs) \
|
|
|
|
((*(_ah)->ah_getTxIntrQueue)((_ah), (_txqs)))
|
2011-01-20 08:15:46 +00:00
|
|
|
#define ath_hal_gettxcompletionrates(_ah, _ds, _rates, _tries) \
|
|
|
|
((*(_ah)->ah_getTxCompletionRates)((_ah), (_ds), (_rates), (_tries)))
|
2012-07-19 02:25:14 +00:00
|
|
|
#define ath_hal_settxdesclink(_ah, _ds, _link) \
|
|
|
|
((*(_ah)->ah_setTxDescLink)((_ah), (_ds), (_link)))
|
|
|
|
#define ath_hal_gettxdesclink(_ah, _ds, _link) \
|
|
|
|
((*(_ah)->ah_getTxDescLink)((_ah), (_ds), (_link)))
|
|
|
|
#define ath_hal_gettxdesclinkptr(_ah, _ds, _linkptr) \
|
|
|
|
((*(_ah)->ah_getTxDescLinkPtr)((_ah), (_ds), (_linkptr)))
|
2012-07-24 01:18:19 +00:00
|
|
|
#define ath_hal_setuptxstatusring(_ah, _tsstart, _tspstart, _size) \
|
|
|
|
((*(_ah)->ah_setupTxStatusRing)((_ah), (_tsstart), (_tspstart), \
|
|
|
|
(_size)))
|
2012-11-03 04:56:08 +00:00
|
|
|
#define ath_hal_gettxrawtxdesc(_ah, _txstatus) \
|
|
|
|
((*(_ah)->ah_getTxRawTxDesc)((_ah), (_txstatus)))
|
2004-12-08 17:34:36 +00:00
|
|
|
|
2011-01-29 12:16:26 +00:00
|
|
|
#define ath_hal_setupfirsttxdesc(_ah, _ds, _aggrlen, _flags, _txpower, \
|
|
|
|
_txr0, _txtr0, _antm, _rcr, _rcd) \
|
|
|
|
((*(_ah)->ah_setupFirstTxDesc)((_ah), (_ds), (_aggrlen), (_flags), \
|
|
|
|
(_txpower), (_txr0), (_txtr0), (_antm), (_rcr), (_rcd)))
|
2012-08-05 11:24:21 +00:00
|
|
|
#define ath_hal_chaintxdesc(_ah, _ds, _bl, _sl, _pktlen, _hdrlen, _type, \
|
|
|
|
_keyix, _cipher, _delims, _first, _last, _lastaggr) \
|
|
|
|
((*(_ah)->ah_chainTxDesc)((_ah), (_ds), (_bl), (_sl), \
|
|
|
|
(_pktlen), (_hdrlen), (_type), (_keyix), (_cipher), (_delims), \
|
2012-04-04 21:49:49 +00:00
|
|
|
(_first), (_last), (_lastaggr)))
|
2011-01-29 12:16:26 +00:00
|
|
|
#define ath_hal_setuplasttxdesc(_ah, _ds, _ds0) \
|
|
|
|
((*(_ah)->ah_setupLastTxDesc)((_ah), (_ds), (_ds0)))
|
2011-11-08 02:12:11 +00:00
|
|
|
|
2011-01-29 12:30:13 +00:00
|
|
|
#define ath_hal_set11nratescenario(_ah, _ds, _dur, _rt, _series, _ns, _flags) \
|
2011-01-29 12:16:26 +00:00
|
|
|
((*(_ah)->ah_set11nRateScenario)((_ah), (_ds), (_dur), (_rt), \
|
2011-01-29 12:30:13 +00:00
|
|
|
(_series), (_ns), (_flags)))
|
2011-11-08 02:12:11 +00:00
|
|
|
|
|
|
|
#define ath_hal_set11n_aggr_first(_ah, _ds, _len, _num) \
|
2012-11-03 04:56:08 +00:00
|
|
|
((*(_ah)->ah_set11nAggrFirst)((_ah), (_ds), (_len), (_num)))
|
|
|
|
#define ath_hal_set11n_aggr_middle(_ah, _ds, _num) \
|
2011-11-08 02:12:11 +00:00
|
|
|
((*(_ah)->ah_set11nAggrMiddle)((_ah), (_ds), (_num)))
|
|
|
|
#define ath_hal_set11n_aggr_last(_ah, _ds) \
|
|
|
|
((*(_ah)->ah_set11nAggrLast)((_ah), (_ds)))
|
|
|
|
|
2011-01-29 12:16:26 +00:00
|
|
|
#define ath_hal_set11nburstduration(_ah, _ds, _dur) \
|
|
|
|
((*(_ah)->ah_set11nBurstDuration)((_ah), (_ds), (_dur)))
|
2011-11-08 02:12:11 +00:00
|
|
|
#define ath_hal_clr11n_aggr(_ah, _ds) \
|
|
|
|
((*(_ah)->ah_clr11nAggr)((_ah), (_ds)))
|
2013-03-04 07:40:49 +00:00
|
|
|
#define ath_hal_set11n_virtmorefrag(_ah, _ds, _v) \
|
|
|
|
((*(_ah)->ah_set11nVirtMoreFrag)((_ah), (_ds), (_v)))
|
2011-01-29 12:16:26 +00:00
|
|
|
|
2012-01-24 06:12:48 +00:00
|
|
|
#define ath_hal_gpioCfgOutput(_ah, _gpio, _type) \
|
|
|
|
((*(_ah)->ah_gpioCfgOutput)((_ah), (_gpio), (_type)))
|
|
|
|
#define ath_hal_gpioset(_ah, _gpio, _b) \
|
|
|
|
((*(_ah)->ah_gpioSet)((_ah), (_gpio), (_b)))
|
|
|
|
#define ath_hal_gpioget(_ah, _gpio) \
|
|
|
|
((*(_ah)->ah_gpioGet)((_ah), (_gpio)))
|
|
|
|
#define ath_hal_gpiosetintr(_ah, _gpio, _b) \
|
|
|
|
((*(_ah)->ah_gpioSetIntr)((_ah), (_gpio), (_b)))
|
|
|
|
|
2012-05-25 02:07:59 +00:00
|
|
|
/*
|
|
|
|
* PCIe suspend/resume/poweron/poweroff related macros
|
|
|
|
*/
|
2012-05-25 05:01:27 +00:00
|
|
|
#define ath_hal_enablepcie(_ah, _restore, _poweroff) \
|
|
|
|
((*(_ah)->ah_configPCIE)((_ah), (_restore), (_poweroff)))
|
2012-05-25 02:07:59 +00:00
|
|
|
#define ath_hal_disablepcie(_ah) \
|
|
|
|
((*(_ah)->ah_disablePCIE)((_ah)))
|
|
|
|
|
2011-06-01 20:09:49 +00:00
|
|
|
/*
|
|
|
|
* This is badly-named; you need to set the correct parameters
|
|
|
|
* to begin to receive useful radar events; and even then
|
|
|
|
* it doesn't "enable" DFS. See the ath_dfs/null/ module for
|
|
|
|
* more information.
|
|
|
|
*/
|
|
|
|
#define ath_hal_enabledfs(_ah, _param) \
|
|
|
|
((*(_ah)->ah_enableDfs)((_ah), (_param)))
|
|
|
|
#define ath_hal_getdfsthresh(_ah, _param) \
|
|
|
|
((*(_ah)->ah_getDfsThresh)((_ah), (_param)))
|
2012-08-24 17:37:12 +00:00
|
|
|
#define ath_hal_getdfsdefaultthresh(_ah, _param) \
|
|
|
|
((*(_ah)->ah_getDfsDefaultThresh)((_ah), (_param)))
|
2011-06-07 09:03:28 +00:00
|
|
|
#define ath_hal_procradarevent(_ah, _rxs, _fulltsf, _buf, _event) \
|
2012-01-24 06:12:48 +00:00
|
|
|
((*(_ah)->ah_procRadarEvent)((_ah), (_rxs), (_fulltsf), \
|
|
|
|
(_buf), (_event)))
|
2011-08-08 15:41:03 +00:00
|
|
|
#define ath_hal_is_fast_clock_enabled(_ah) \
|
2011-08-08 19:03:26 +00:00
|
|
|
((*(_ah)->ah_isFastClockEnabled)((_ah)))
|
2012-01-24 06:12:48 +00:00
|
|
|
#define ath_hal_radar_wait(_ah, _chan) \
|
2006-02-10 19:07:08 +00:00
|
|
|
((*(_ah)->ah_radarWait)((_ah), (_chan)))
|
2012-05-01 14:48:51 +00:00
|
|
|
#define ath_hal_get_mib_cycle_counts(_ah, _sample) \
|
|
|
|
((*(_ah)->ah_getMibCycleCounts)((_ah), (_sample)))
|
2012-01-24 06:12:48 +00:00
|
|
|
#define ath_hal_get_chan_ext_busy(_ah) \
|
2012-01-24 06:07:05 +00:00
|
|
|
((*(_ah)->ah_get11nExtBusy)((_ah)))
|
2013-02-25 22:42:43 +00:00
|
|
|
#define ath_hal_setchainmasks(_ah, _txchainmask, _rxchainmask) \
|
|
|
|
((*(_ah)->ah_setChainMasks)((_ah), (_txchainmask), (_rxchainmask)))
|
2003-06-23 17:01:19 +00:00
|
|
|
|
2013-01-03 19:03:03 +00:00
|
|
|
#define ath_hal_spectral_supported(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_SPECTRAL_SCAN, 0, NULL) == HAL_OK)
|
2013-01-02 01:40:23 +00:00
|
|
|
#define ath_hal_spectral_get_config(_ah, _p) \
|
|
|
|
((*(_ah)->ah_spectralGetConfig)((_ah), (_p)))
|
|
|
|
#define ath_hal_spectral_configure(_ah, _p) \
|
|
|
|
((*(_ah)->ah_spectralConfigure)((_ah), (_p)))
|
|
|
|
#define ath_hal_spectral_start(_ah) \
|
|
|
|
((*(_ah)->ah_spectralStart)((_ah)))
|
|
|
|
#define ath_hal_spectral_stop(_ah) \
|
|
|
|
((*(_ah)->ah_spectralStop)((_ah)))
|
|
|
|
|
2013-06-07 05:18:07 +00:00
|
|
|
#define ath_hal_btcoex_supported(_ah) \
|
|
|
|
(ath_hal_getcapability(_ah, HAL_CAP_BT_COEX, 0, NULL) == HAL_OK)
|
|
|
|
#define ath_hal_btcoex_set_info(_ah, _info) \
|
|
|
|
((*(_ah)->ah_btCoexSetInfo)((_ah), (_info)))
|
|
|
|
#define ath_hal_btcoex_set_config(_ah, _cfg) \
|
|
|
|
((*(_ah)->ah_btCoexSetConfig)((_ah), (_cfg)))
|
|
|
|
#define ath_hal_btcoex_set_qcu_thresh(_ah, _qcuid) \
|
|
|
|
((*(_ah)->ah_btCoexSetQcuThresh)((_ah), (_qcuid)))
|
|
|
|
#define ath_hal_btcoex_set_weights(_ah, _weight) \
|
|
|
|
((*(_ah)->ah_btCoexSetWeights)((_ah), (_weight)))
|
|
|
|
#define ath_hal_btcoex_set_weights(_ah, _weight) \
|
|
|
|
((*(_ah)->ah_btCoexSetWeights)((_ah), (_weight)))
|
|
|
|
#define ath_hal_btcoex_set_bmiss_thresh(_ah, _thr) \
|
|
|
|
((*(_ah)->ah_btCoexSetBmissThresh)((_ah), (_thr)))
|
|
|
|
#define ath_hal_btcoex_set_parameter(_ah, _attrib, _val) \
|
|
|
|
((*(_ah)->ah_btCoexSetParameter)((_ah), (_attrib), (_val)))
|
|
|
|
#define ath_hal_btcoex_enable(_ah) \
|
|
|
|
((*(_ah)->ah_btCoexEnable)((_ah)))
|
|
|
|
#define ath_hal_btcoex_disable(_ah) \
|
|
|
|
((*(_ah)->ah_btCoexDisable)((_ah)))
|
|
|
|
|
2013-06-12 14:52:57 +00:00
|
|
|
#define ath_hal_div_comb_conf_get(_ah, _conf) \
|
|
|
|
((*(_ah)->ah_divLnaConfGet)((_ah), (_conf)))
|
|
|
|
#define ath_hal_div_comb_conf_set(_ah, _conf) \
|
|
|
|
((*(_ah)->ah_divLnaConfSet)((_ah), (_conf)))
|
|
|
|
|
2003-06-23 17:01:19 +00:00
|
|
|
#endif /* _DEV_ATH_ATHVAR_H */
|