interrupts are enabled and the NIC is awake (think: loading a module)
then there's a not-quite-zero window where we'll get an interrupt
for the device before the attach method is called to finish setting
up the hardware.
Since I grab locks in ath_intr() to check various things, the locks
need to be ready much earlier.
doesn't get truncated to 32 bits.
Without this, 3x3 NICs transmitting at an MCS rate whose rix (rate
index) in the rate table is > 31 end up returning errors, as the
sample rate code doesn't think the rate is set in the rate table.
Tested:
* AR9380, STA, speaking 3x3 to an AP
in prep for the next NF calibration pass.
Totally missing braces. Damn you C.
Submitted by: Sascha Wildner <swildner@dragonflybsd.org>
MFC after: 1 week
MCI bluetooth coexistence method for WB222.
The rest of MCI requires a bunch more work, including adding a DMA buffer
for the MCI hardware to bounce messages in/out of and handling MCI
interrupts. But the more important part here is telling the HAL
the btcoex is enabled and MCI is in use so it configures the correct
initial bluetooth parameters in the wireless NIC and configures
things like bluetooth traffic weights and such.
So, this at least gets the HAL to do some of the right things in
configuring the inital bluetooth coexistence stuff, but doesn't
actually do full btcoex. That'll take.. some effort.
Tested:
* AR9462 (WB222), STA mode
AR5416 and later NICs have more than 8 (Well, more than 6) GPIO pins.
So to support rfkill on these NICs we need to bump this up or the
rfkill GPIO pin may get reset to the wrong value.
Noticed by: Anthony Jenkins <scoobi_doo@yahoo.com>
ath kernel module:
sys/dev/ath/ath_hal/ar5212/ar5212_reset.c:2642:7: error: taking the absolute value of unsigned type 'unsigned int' has no effect [-Werror,-Wabsolute-value]
if (abs(lp[0] * EEP_SCALE - target) < EEP_DELTA) {
^
sys/dev/ath/ah_osdep.h:74:18: note: expanded from macro 'abs'
#define abs(_a) __builtin_abs(_a)
^
sys/dev/ath/ath_hal/ar5212/ar5212_reset.c:2642:7: note: remove the call to '__builtin_abs' since unsigned values cannot be negative
sys/dev/ath/ah_osdep.h:74:18: note: expanded from macro 'abs'
#define abs(_a) __builtin_abs(_a)
^
1 error generated.
This warning occurs because both lp[0] and target are unsigned, so the
subtraction expression is also unsigned, and calling abs() is a no-op.
However, the intention was to look at the absolute difference between
the two unsigned quantities. Introduce a small static function to
clarify what we're doing, and call that instead.
Reviewed by: adrian
MFC after: 3 days
Differential Revision: https://reviews.freebsd.org/D1212
I did this wrong - I should've included a state flag for each callout
to see if it was supposed to run or not. I didn't do that.
Instead, just use mutexes anyway.
Suggested by: jhb
These variants have a few differences from the default AR9485 NIC,
namely:
* a non-default antenna switch config;
* slightly different RX gain table setup;
* an external XLNA hooked up to a GPIO pin;
* (and not yet done) RSSI threshold differences when
doing slow diversity.
To make this possible:
* Add the PCI device list from Linux ath9k, complete with vendor and
sub-vendor IDs for various things to be enabled;
* .. and until FreeBSD learns about a PCI device list like this,
write a search function inspired by the USB device enumeration code;
* add HAL_OPS_CONFIG to the HAL attach methods; the HAL can use this
to initialise its local driver parameters upon attach;
* copy these parameters over in the AR9300 HAL;
* don't default to override the antenna switch - only do it for
the chips that require it;
* I brought over ar9300_attenuation_apply() from ath9k which is cleaner
and easier to read for this particular NIC.
This is a work in progress. I'm worried that there's some post-AR9380
NIC out there which doesn't work without the antenna override set as
I currently haven't implemented bluetooth coexistence for the AR9380
and later HAL. But I'd rather have this code in the tree and fix it
up before 11.0-RELEASE happens versus having a set of newer NICs
in laptops be effectively RX deaf.
Tested:
* AR9380 (STA)
* AR9485 CUS198 (STA)
Obtained from: Qualcomm Atheros, Linux ath9k
The original code was .. well, slightly more than incorrect.
It showed up as stalled RX queues if the NIC needed to be frequently
reinitialised (eg during scans.)
This is inspired by work done by Matt Dillon over at the DragonflyBSD
project.
So:
* track when EDMA RX has been stopped and when the MAC has been reset;
* re-initialise the ring only after a reset;
* track whether RX has been stopped/started - just for debugging now;
* don't bother with the RX EOL stuff for EDMA - we don't need the
interrupt at all. We also don't need to disable/enable the interrupt
or start DMA - once new frames are pushed into the ring via the
normal RX path, it'll just restart RX DMA on its own.
Tested:
* AR9380, STA mode
* AR9380, AP mode
* AR9485, STA mode
* AR9462, STA mode
to get upset.
The Qualcomm Atheros reference design code goes through significant
hacks to shut down RX before TX. It doesn't even try do do it in the
driver - it actually makes the DMA stop routines in the HAL shut down
RX before shutting down TX.
So, to make this work for chips that aren't the AR9380 and later, do
it in the driver. Shuffle the TX stop/drain HAL calls to be called
*after* the RX stop HAL call.
Tested:
* AR5413 (STA)
* AR5212 (STA)
* AR5416 (STA)
* AR9380 (STA)
* AR9331 (AP)
* AR9341 (AP)
TODO:
* test ar92xx series NIC and the AR5210/AR5211, in case there's something
even odder about those.
The AR9380 and later chips have a 128KiB register window, so the register
read diag api needs changing.
The tools are about to be updated as well. No, they're not backwards
compatible.
This includes:
o All directories named *ia64*
o All files named *ia64*
o All ia64-specific code guarded by __ia64__
o All ia64-specific makefile logic
o Mention of ia64 in comments and documentation
This excludes:
o Everything under contrib/
o Everything under crypto/
o sys/xen/interface
o sys/sys/elf_common.h
Discussed at: BSDcan
These changes prevent sysctl(8) from returning proper output,
such as:
1) no output from sysctl(8)
2) erroneously returning ENOMEM with tools like truss(1)
or uname(1)
truss: can not get etype: Cannot allocate memory
there is an environment variable which shall initialize the SYSCTL
during early boot. This works for all SYSCTL types both statically and
dynamically created ones, except for the SYSCTL NODE type and SYSCTLs
which belong to VNETs. A new flag, CTLFLAG_NOFETCH, has been added to
be used in the case a tunable sysctl has a custom initialisation
function allowing the sysctl to still be marked as a tunable. The
kernel SYSCTL API is mostly the same, with a few exceptions for some
special operations like iterating childrens of a static/extern SYSCTL
node. This operation should probably be made into a factored out
common macro, hence some device drivers use this. The reason for
changing the SYSCTL API was the need for a SYSCTL parent OID pointer
and not only the SYSCTL parent OID list pointer in order to quickly
generate the sysctl path. The motivation behind this patch is to avoid
parameter loading cludges inside the OFED driver subsystem. Instead of
adding special code to the OFED driver subsystem to post-load tunables
into dynamically created sysctls, we generalize this in the kernel.
Other changes:
- Corrected a possibly incorrect sysctl name from "hw.cbb.intr_mask"
to "hw.pcic.intr_mask".
- Removed redundant TUNABLE statements throughout the kernel.
- Some minor code rewrites in connection to removing not needed
TUNABLE statements.
- Added a missing SYSCTL_DECL().
- Wrapped two very long lines.
- Avoid malloc()/free() inside sysctl string handling, in case it is
called to initialize a sysctl from a tunable, hence malloc()/free() is
not ready when sysctls from the sysctl dataset are registered.
- Bumped FreeBSD version to indicate SYSCTL API change.
MFC after: 2 weeks
Sponsored by: Mellanox Technologies
used.
It turns out that the RX DMA engine does the same last-descriptor-link-
pointer-re-reading trick that the TX DMA engine. That is, the hardware
re-reads the link pointer before it moves onto the next descriptor.
Thus we can't free a descriptor before we move on; it's possible the
hardware will need to re-read the link pointer before we overwrite
it with a new one.
Tested:
* AR5416, STA mode
TODO:
* more thorough AP and STA mode testing!
* test on other pre-AR9380 NICs, just to be sure.
* Break out the RX descriptor grabbing bits from the RX completion
bits, like what is done in the RX EDMA code, so ..
* .. the RX lock can be held during ath_rx_proc(), but not across
packet input.
call, which assumes the hardware is awake.
Turn ath_update_mcast() into a routine that's only called from the
net80211 layer - and it forces the hardware awake first.
This fixes a LOR from the EDMA RX path which calls ath_mode_init()
with the RX lock held - the driver lock can't also be grabbed.
This path assumes that the ath_mode_init() callers all wake up
the NIC first.
Tested:
* AR9485, STA mode, powersave
This seems to probe/attach as an AR9485 and thus nothing else besides
adding the device id seems to be required.
ath0: <Atheros AR1111> mem 0xf4800000-0xf487ffff irq 19 at device 0.0 on pci5
ath0: [HT] enabling HT modes
ath0: [HT] enabling short-GI in 20MHz mode
ath0: [HT] 1 stream STBC receive enabled
ath0: [HT] 1 RX streams; 1 TX streams
ath0: AR9485 mac 576.1 RF5110 phy 1926.8
ath0: 2GHz radio: 0x0000; 5GHz radio: 0x0000
The NIC I have here is a 1 antenna, 2GHz only device.
Thankyou to Jim Thompson <jim@netgate.com> for the AR1111 NIC.
Tested:
* AR1111 (pretending not to be an AR9485, but failing miserably);
STA mode with powersave.
Relnotes: yes
Sponsored by: Netgate
The hardware can generate its own frames (eg RTS/CTS exchanges, other
kinds of 802.11 management stuff, especially when it comes to 802.11n)
and these also have PWRMGT flags. So if the VAP is asleep but the
NIC is in force-awake for some reason, ensure that the self-generated
frames have PWRMGT set to 1.
Now, this (like basically everything to do with powersave) is still
racy - the only way to guarantee that it's all actually consistent
is to pause transmit and let it finish before transitioning the VAP
to sleep, but this at least gets the basic method of tracking and
updating the state debugged.
Tested:
* AR5416, STA mode
* AR9380, STA mode
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
Some code will appear soon that is actually setting the chip powerstate
separate from the self-generated frames power state.
* Allow the AR5416 family chips to actually have the power state changed
from the self generated state change.
Tested (STA mode):
* AR5210
* AR5211
* AR5412
* AR5413
* AR5416
* AR9285
the MYBEACON RX filter (only receive beacons which match the BSSID)
or all beacons on the current channel.
* Add the relevant RX filter entry for MYBEACON.
Tested:
* AR5416, STA
* AR9285, STA
TODO:
* once the code is in -HEAD, just make sure that the code which uses it
correctly sets BEACON for pre-AR5416 chips.
Obtained from: QCA, Linux ath9k
the QCA HAL.
This fires off an interrupt if the TSF from the AP / IBSS peer is
wildly out of range. I'll add some code to the ath(4) driver soon
which makes use of this.
TODO:
* verify this didn't break TDMA!
to the hardware.
The QCA HAL has a comment noting that if this isn't done, modifications
to AR_IMR_S2 before AR_IMR is flushed may produce spurious interrupts.
Obtained from: QCA
concurrent updates from any completing transmits in other threads.
This was exposed when doing power save work - net80211 is constantly
doing reassociations and it's causing the rate control state to get
blanked out. This could cause the rate control code to assert.
This should be MFCed to stable/10 as it's a stability fix.
Tested:
* AR5416, STA
MFC after: 7 days
The existing cleanup code was based on the Atheros reference driver
from way back and stuff that was in Linux ath9k. It turned out to be ..
rather silly.
Specifically:
* The whole method of determining whether there's hardware-queued frames
was fragile and the BAW would never quite work right afterwards.
* The cleanup path wouldn't correctly pull apart aggregate frames in the
queue, so frames would not be freed and the BAW wouldn't be correctly
updated.
So to implement this:
* Pull the aggregate frames apart correctly and handle each separately;
* Make the atid->incomp counter just track the number of hardware queued
frames rather than try to figure it out from the BAW;
* Modify the aggregate completion path to handle it as a single frame
(atid->incomp tracks the one frame now, not the subframes) and
remove the frames from the BAW before completing them as normal frames;
* Make sure bf->bf_next is NULled out correctly;
* Make both aggregate session and non-aggregate path frames now be
handled via the incompletion path.
TODO:
* kill atid->incomp; the driver tracks the hardware queued frames
for each TID and so we can just use that.
This is a stability fix that should be merged back to stable/10.
Tested:
* AR5416, STA
MFC after: 7 days
MAC
* Now that the paused < 0 bugs have been identified, make the DPRINTF()
a device_printf() again. Anything else that shows up here needs to be
fixed immediately.
Tested:
* AR5416, STA mode
MFC after: 7 days
During power save testing I noticed that the cleanup code is being
called during a RUN->RUN state transition. It's because the net80211
stack is treating that (for reasons I don't quitey know yet) as a
reassociation and this calls the node cleanup code. The reason it's
seeing a RUN->RUN transition is because during active power save
stuff it's possible that the RUN->SLEEP and SLEEP->RUN transitions
happen so quickly that the deferred net80211 vap state code
"loses" a transition, namely the intermediary SLEEP transition.
So, this was causing the node reassociation code to sometimes be called
twice in quick succession and this would result in ath_tx_tid_cleanup()
to be called again. The code calling it would always call pause, and
then only call resume if the TID didn't have "cleanup_inprogress" set.
Unfortunately it didn't check if it was already set on entry, so it
would pause but not call resume. Thus, paused would be called more
than once (once before each entry into ath-tx_tid_cleanup()) but resume
would only be called once when the cleanup state was finished.
This doesn't entirely fix all of the issues seen in the cleanup path
but it's a necessary first step.
Since this is a stability fix, it should be merged to stable/10 at some
point.
Tested:
* AR5416, STA mode
MFC after: 7 days
tracked BAW actually is.
The net80211 code that completes a BAR will set tid->txa_start (the
BAW start) to whatever value was called when sending the BAR.
Now, in case there's bugs in my driver code that cause the BAW
to slip along, we should make sure that the new BAW we start
at is actually what we currently have it at, not what we've sent.
This totally breaks the specification and so this stays a printf().
If it happens then I need to know and fix it.
Whilst here, add some debugging updates:
* add TID logging to places where it's useful;
* use SEQNO().