Commit Graph

414 Commits

Author SHA1 Message Date
Adrian Chadd
ba5c15d9ba Migrate most of the beacon handling functions out to if_ath_beacon.c.
This is also in preparation for supporting AR9300 and later NICs.
2012-05-20 04:14:29 +00:00
Adrian Chadd
a35dae8d87 Migrate the TDMA management functions out of if_ath.c into if_ath_tdma.c.
There's some TX path TDMA code in if_ath_tx.c which should be migrated
out, but first I should likely try and verify/fix/repair the TDMA support
in 9.x and -HEAD.
2012-05-20 02:49:42 +00:00
Adrian Chadd
e60c4fc2c9 Migrate the bulk of the RX routines out from if_ath.c to if_ath_rx.[ch].
* migrate the rx processing out into if_ath_rx.c
* migrate the TSF functions into if_ath_tsf.h, as inlines

This is in prepration for supporting the EDMA RX routines, required to
support the AR93xx series NICs.

TODO:

* ath_start() shouldn't be private, but it's called as part of
  the RX path. I should likely migrate ath_rx_tasklet() back into
  if_ath.c and then return this to be 'static'.  The RX code really
  shouldn't need to see TX routines (and vice versa.)

* ath_beacon_* should be in if_ath_beacon.[ch].

* ath_tdma_* should be in if_ath_tdma.[ch] ...
2012-05-20 02:05:10 +00:00
Adrian Chadd
78de21c070 Re-enable this particular DELAY() for now, at least until the
TX and RX PCU stop/drain routines have been thoroughly debugged.

It's also very likely that I should add hooks back up to the
interface glue (if_ath_pci / if_ath_ahb) to do any relevant
bus flushes that are required.  A WMAC DDR flush may be required
for the AR9130 SoC.
2012-05-07 18:30:22 +00:00
Adrian Chadd
9406c902cd Add a comment about this DELAY(), I'm not sure whether it's supposed
to be for a DDR/FIFO flush or something else.
2012-04-28 05:00:47 +00:00
Adrian Chadd
f846cf42ab Run the fatal proc as a proc, rather than where it currently is.
Otherwise the reset path will sleep, which it can't do in this context.
2012-04-17 06:02:41 +00:00
Adrian Chadd
53e98d5a48 Fix the default, non-superg compile.
Pointy-hat-to:	adrian
2012-04-11 02:34:32 +00:00
Adrian Chadd
43faa6b266 Fix compilation with IEEE80211_ENABLE_SUPERG defined.
PR:		kern/164951
2012-04-10 19:47:44 +00:00
Adrian Chadd
41b6b5074c Blank the aggregate stats whenever the zero ioctl is called. 2012-04-10 07:27:42 +00:00
Adrian Chadd
9467e3f3fc Squirrel away SYNC interrupt debugging if it's enabled in the HAL.
Bus errors will show up as various SYNC interrupts which will be passed
back up to ath_intr().
2012-04-10 07:23:37 +00:00
Adrian Chadd
eddd7521f1 Revert this for now - it may work for -8 and -9 and -HEAD, but not
"-HEAD driver + net80211 on -9 kernel."

I'll figure this out at some later stage.
2012-04-10 07:16:28 +00:00
Adrian Chadd
fdd72b4a32 * Since the API changed along the -CURRENT path (december 2011),
add a FreeBSD_version check.  It should work fine for compiling
  on -HEAD, 9.x and 8.x.

* Conditionally compile the 11n options only when 11n is enabled.

The above changes allow the ath(4) driver to compile and run on
8.1-RELEASE (Hi old PC-BSD!) but with the 11n stuff disabled.

I've done a test against the net80211 and tools in 8.1-RELEASE.
The NIC used in testing is the AR2427 in an EEEPC.

Just to be clear - this change is to allow the -HEAD ath/hal/rate
code to run on 9.x _and_ 8.x with no source changes. However,
when running on earlier kernels, it should only be used for legacy
mode. (Don't define ATH_ENABLE_11N.)
2012-04-10 06:25:11 +00:00
Adrian Chadd
ce656facf3 Store away the RTS aggregate limit from the HAL.
This will be used by some upcoming code to ensure that aggregates
are enforced to be a certain size.  The AR5416 has a limitation on
RTS protected aggregates (8KiB).
2012-04-07 02:51:53 +00:00
Adrian Chadd
875a9451d9 Remove duplicate txflags field from ath_buf.
rename bf_state.bfs_flags to bf_state.bfs_txflags, as that is what
it effectively is.
2012-04-07 02:01:26 +00:00
Adrian Chadd
d6b2002327 Disable the HWQ contents upon a TX queue reset, rather than a TX queue flush.
This is designed to assist in figuring out what the hardware state is
when something like a queue hang has occured.
2012-04-04 22:24:11 +00:00
Adrian Chadd
b5a9dfd57c oops, add a missing lock. 2012-03-29 21:54:19 +00:00
Adrian Chadd
03e9308f0a Defer the rescheduling of TID -> TXQ frames in some instances.
Right now ath_txq_sched() is mainly called from the TX ath_tx_processq()
routine, which is (mostly) done as part of the taskqueue.  It shouldn't
be called outside the taskqueue.

But now that I'm about to flip back on BAR TX, I'm going to start
stressing the ath_tx_tid_pause() and ath_tx_tid_resume() paths.
What I don't want to have happen is a reschedule of the TID traffic
_during_ the completion of TX frames.

Ideally I'd like to have a way to flag back up to the processing code
that the current hardware queue should be rechecked for software TID
queue frames.  But for now, this should suffice for the BAR TX case.

I may eventually delete this code once I've brought some further
sanity to the general TX queue/completion path.
2012-03-29 17:39:18 +00:00
Adrian Chadd
e7200579b8 Add the new channel width change field to the ath(4) driver.
This is not entirely correct as it simply resets the channel, flushing
whatever is in the TX/RX queue.  This can and will break aggregation
BAW tracking.  But the alternative (HT40 frames being sent with the hardware
in HT20 mode) is even worse.

There's still a small window between the htinfo being received (and the ni_chw
field being updated) which could cause problems.  I'll look at fleshing this
out in follow-up commits.

PR:		kern/166286
2012-03-25 03:14:31 +00:00
Adrian Chadd
a66d508971 Fix a couple of debugging outputs.
* printf -> device_printf
* print the buffer pointer and sequence number for any buffer that wasn't
  correctly tidied up before it was freed.  This is to aid in some
  current SMP TX debugging stalls.

PR:		kern/166190
2012-03-16 23:24:27 +00:00
Adrian Chadd
58816f3f1b Add a dependency on ALQ if IEEE80211_ALQ and/or AH_DEBUG_ALQ is included. 2012-03-16 23:12:40 +00:00
Adrian Chadd
e4e7938ae5 Stick the if_drv_flags access (check and modify) behind the ifq lock.
Although access to the flags to check/set OACTIVE is racy due to how
the default if_start() function works, this should remove any races
with read/modify/write between threads.
2012-03-10 20:09:02 +00:00
Adrian Chadd
9c85ff9164 Don't flood the cabq/mcastq with frames.
In a very noisy 2.4GHz environment (with HT/40 enabled, making it worse)
I saw the following occur:

* the air was considered "busy" a lot of the time;
* the cabq time is quite short due to staggered beacons being enabled;
* it just wasn't able to keep up TX'ing CABQ frames;
* .. and the cabq would swallow up all the TX ath_buf's.

This patch introduces a twiddle which allows the maximum cabq depth to be
set, forcing further frames to be dropped.

It defaults to the TX buffer count at the moment, so the default behaviour
isn't changed.

I've also started fleshing out a similar setup for the data path, so
it doesn't swallow up all the available TX buffers and preventing management
frames (such as ADDBA) out.

PR:		kern/165895
2012-03-10 04:14:04 +00:00
Adrian Chadd
91d92caece Should the mcast queue be locked here? In case more multicast traffic
comes along?

This commit was brought to you via an Atheros AR5210, associated to an 3x3
HT40 11na access point.  Yes, this driver still works with it.
2012-03-09 22:41:09 +00:00
Adrian Chadd
e86fd7a715 Insert extra paranoia into the ath(4) driver.
This function must be called with both the source and destination TXQs
locked or things will get hairy.

I added this as part of some debugging in a PR but it turned out to not
be the cause.  I still think it's -correct- so, here it is.
2012-03-09 08:36:30 +00:00
Adrian Chadd
a887b1e359 Wrap another ATH_LOCK around the scanning flag.
PR:		kern/163318
2012-03-02 03:11:53 +00:00
Adrian Chadd
c98cefc5db Wrap the scan code state change stuff behind ATH_LOCK and the PCU fiddling
behind the PCU lock.

sc_scanning is being checked without ATH_LOCK behind held and could
in theory run from multiple threads.
2012-03-02 02:57:10 +00:00
Adrian Chadd
d52f713265 Attempt to further fix some of the concurrency/reset issues that occur.
* ath_reset() is being called in softclock context, which may have the
  thing sleep on a lock.  To avoid this, since we really _shouldn't_
  be sleeping on any locks, break out the no-loss reset path into a tasklet
  and call that from:

  + ath_calibrate()
  + ath_watchdog()

  This has the added advantage that it'll end up also doing the frame
  RX cleanup from within the taskqueue context, rather than the softclock
  context.

* Shuffle around the taskqueue_block() call to be before we grab the lock
  and disable interrupts.

  The trouble here is that taskqueue_block() doesn't block currently
  queued (but not yet running) tasks so calling it doesn't guarantee
  no further tasks (that weren't running on _A_ CPU at the time of this
  call) will complete.  Calling taskqueue_drain() on these tasks won't
  work because if any _other_ thread calls taskqueue_enqueue() for whatever
  reason, everything gets very angry and stops working.

  This slightly changes the race condition enough to let ath_rx_tasklet()
  run before we try disabling it, and thus quietens the warnings a bit.

  The (more) true solution will be doing something like the following:

  * having a taskqueue_blocked mask in ath_softc;
  * having an interrupt_blocked mask in ath_softc;
  * only calling taskqueue_drain() on each individual task _after_ the
    lock has been acquired - that way no further tasklet scheduling
    is going to occur.
  * Then once the tasks have been blocked _and_ the interrupt has been
    disabled, call taskqueue_drain() on each, ensuring that anything
    that _was_ scheduled or running is removed.

  The trouble is if something calls taskqueue_enqueue() on a task
  after taskqueue_blocked() has been called but BEFORE taskqueue_drain()
  has been called, ta_pending will be set to 1 and taskqueue_drain()
  will sit there stuck in msleep() until you hard-kill the machine.

PR: kern/165382
PR: kern/165220
2012-02-25 19:12:54 +00:00
Adrian Chadd
398bca2e5e Use the passed-in channel rather than ic->ic_curchan.
I'm not sure _why_ the ic is NULL here, but I've seen it occasionally do
this after I've been tinkering with things for a while.  It ends up
crashing in a call to ath_chan_set() via the net80211 scan code and scan
task.
2012-02-23 08:32:54 +00:00
Adrian Chadd
107fdf9681 Try to ensure that ieee80211_newstate() and the vap_newstate methods
hold the lock.

This is part of my series of work to try and capture when net80211
locking isn't.

ObNote: it'd be nice to be able to mark a lock as "assert if the lock
is dropped", so I could capture functions which decide that dropping
and reacquiring the lock is a good idea (without re-checking the
sanity of the state protected by the lock.)
2012-02-18 09:18:06 +00:00
Adrian Chadd
e78719adf9 Enforce some consistent ordering and handling of interrupt disable/enable
with RX/TX halting.

* Always disable/enable interrupts during a channel change, just to simply
  things.

* Ensure that the ath taskqueue has completed and is paused before
  continuing.

This dramatically reduces the instances of overlapping RX and reset
conditions.

PR:	kern/165220
2012-02-17 03:46:38 +00:00
Adrian Chadd
21008bf10d Begin breaking out the txrx stop code into a locked and unlocked variant.
PR:	kern/165220
2012-02-17 03:23:01 +00:00
Adrian Chadd
807675317e Attempt to address some potential vap->iv_bss race conditions.
There are unfortunately a number of situations where vap->iv_bss is changed
or freed by some code in net80211.  Because multiple threads can concurrently
be doing work (and the vap->iv_bss access isn't at all done behind any kind
of lock), it's quite possible that:

* a change will occur in one thread - eg, by a call through
  ieee80211_sta_join1();
* a state change occurs in another thread - eg an RX is scheduled
  in the ath tasklet and it calls ieee80211_input_mimo_all(), which
  does dereference vap->iv_bss;
* these two executing concurrently, causing things to explode.

Another instance is ath_beacon_alloc() which takes an ieee80211_node *.
It's called with the vap->iv_bss node from ath_newstate(). If the node has
changed in the meantime (say it's been freed elsewhere) the reference
that it grabbed _before_ refcounting it may be stale.

I would _prefer_ that these sorts of things were serialised somewhere but
that may be a bit much to ask.  Instead, the best we can (currently) hope
is that the underlying bss node is still (somewhat) valid.

There is a related PR (kern/164382) described by the first case above.
That should be fixed by properly serialising the RX path and reset path
so an RX can't occur at the same time as the vap free/shutdown path.

This is inspired by some related fixes in r212127.

PR: kern/165060
2012-02-13 00:28:41 +00:00
Adrian Chadd
dc8552d525 .. oops, use the right chainmask. 2012-02-10 10:09:16 +00:00
Adrian Chadd
a865860d09 Add in a new driver feature to allow the TX and RX chainmask to be
overridden at attach time.

Some 802.11n NICs may only have one physical antenna connected.
The radios will be very upset if you try enabling radios which aren't
connected to antennas.

This allows hints to override the TX and RX chainmask.

These hints are:

hint.ath.X.rx_chainmask
hint.ath.X.tx_chainmask

They can be set at either boot time or in kenv before the module is loaded.

This and the previous HAL commit were sponsored in late 2011 by Hobnob, Inc.

Sponsored by:	Hobnob, Inc.
2012-02-10 10:01:09 +00:00
Adrian Chadd
54517070b5 Correctly fetch the TX/RX stream count from the HAL.
Pointy hat to: me
2012-01-31 22:27:35 +00:00
Adrian Chadd
06fc4a109d Two changes from my DFS work:
* Grab the net80211com lock when calling ieee80211_dfs_notify_radar().
* Use the tsf extend function to turn the 64 bit base TSF into a per-
  frame 64 bit TSF.  This will improve radiotap logging (which will
  now have a (more) correct per-frame TSF, rather then the single TSF64
  value read at the beginning of ath_rx_proc().
2012-01-28 21:37:33 +00:00
Adrian Chadd
7ebd03d755 Add some node debugging which has helped me track down which particular
concurrent vap->iv_bss free issues have been occuring.
2012-01-26 07:03:30 +00:00
Adrian Chadd
fad901eb2b Re-enable the PHY radar error frames if sc_dodfs is set.
This was messing up a local port of the atheros reference radar detection
code; I'll fix the port instead.
2012-01-11 00:18:33 +00:00
Adrian Chadd
3440495a52 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
Adrian Chadd
a497cd8806 Setup the initial LED state on attach and resume.
Some of the NICs I have here power up with the LEDs blinking, which is
incorrect. The blinking should only occur when the NIC is attempting
to associate.

* On powerup, set the state to HAL_LED_INIT, which turns on the "Power" MAC
  LED but leaves the "Network" MAC LED the way it is.

* On resume, also init it to HAL_LED_INIT unless in station mode, where
  it's forced to HAL_LED_RUN. Hopefully the net80211 state machine will
  call newstate() at some point, which will refiddle the LEDs.

I've tested this on a handful of 11n and pre-11n NICs. The blinking
behaviour is slightly more sensible now.
2011-12-26 06:25:12 +00:00
Adrian Chadd
6558ffd99a Refactor out the software LED config code into a common function, called
ath_led_config().

The eventual aim is to have both software and hardware based LED
configuration done here.
2011-12-26 05:46:22 +00:00
Adrian Chadd
c65ee21d46 First pass of LED related code changes.
Migrate the LED code out of if_ath.c and into if_ath_led.c.
These routines are _all_ software based LED blinking.
2011-12-26 05:37:09 +00:00
Adrian Chadd
7e97436b0e Do a quick style(9) pass of some of the code introduced with 802.11n
support.
2011-12-26 05:26:35 +00:00
Adrian Chadd
ee3219757a Rework this ugly mess that tries to handle reset serialisation.
Some users were reporting concurrent resets _were_ occuring - ie,
either two ath_reset()s ran at the same time (likely one on each CPU)
or ath_reset() versus ath_chan_change().

Instead, this now tries to grab the serialisation semaphore and will
pause() for a while if it fails. It will always eventually succeed though
and will log an error if it hits the recursion situation.

All of this stuff needs to die a horrible death at some point and be
replaced with a properly serialising method of programming this stuff
(eg using the net80211 taskqueue for all of this stuff.) The trouble
is figuring out how to handle the concurrent ioctl() based things without
introducing more LORs (which is another reason why I haven't just wrapped
all of this stuff in large, long-lived locks, a-la what Linux can get
away with.)

MFC after:	Absolutely, positively never.
2011-12-23 03:59:49 +00:00
Adrian Chadd
6e0f116875 Make some more of the 11n specific code conditional.
This doesn't fix compilation w/out AH_SUPPORT_AR5416 as all of the software
aggregation support in if_ath_tx.c and 11n code in if_ath_tx_ht.c touches
the 11n specific fields. I'll work on that later.
2011-12-23 02:40:35 +00:00
Adrian Chadd
197d53c565 Add a temporary debugging statement in order to try and identify what's
going on with the occasional garbage rs_antenna field reported by AR9285
users.

I've discovered that the 11n NICs only fill out the entire RX status
descriptor on the final descriptor in an aggregate. Some of the fields
(notably RSSI) are complete nonsense for A-MPDU subframes. This may
be another example of this.

The driver doesn't currently toss out statistics for non-final aggregate
frames. It's likely that this should be done.

If any users hit this particular debugging message they should report it
immediately to freebsd-wireless@freebsd.org - please ensure you have
ATH_DEBUG enabled so it prints out the full receive descriptor.

PR:		kern/163312
2011-12-23 02:21:22 +00:00
Bernhard Schmidt
fcd9500f91 Fix some net80211 enum nits:
- ic_vap_create() uses an ieee80211_opmode argument
- ieee80211_rate2media() takes an ieee80211_phymode argument
- ieee80211_plcp2rate() takes an ieee80211_phytype argument
- cast to enum ieee80211_protmode and ieee80211_roamingmode to silence
  compiler warnings

Submitted by:	arundel@
2011-12-17 10:23:17 +00:00
Adrian Chadd
46a924c4c8 Print out the radio RF version at startup, so I can better see which
RF frontend versions people have when they submit problem reports.

Sponsored by:	Hobnob, Inc.
2011-12-15 00:55:27 +00:00
Adrian Chadd
0fbe75a1c9 Re-lock the ath lock after ath_reset() has been called.
The calibrate callout is done with the sc lock held.

This only showed up when using an older NIC (AR5212) whose
radio/phy requires the rfgain adjustment.

Pointy-hat-to:	adrian
Sponsored by:	Hobnob, Inc.
2011-11-23 07:12:26 +00:00
Adrian Chadd
a2d8240de5 Use the correct lock when calling msleep().
This fixes panics that users have been seeing when operating in station mode,
where the interface undergoes a lot more resets then in hostap mode (ie whilst
doing channel scanning.)

Reported by:	arundel, wblock@wonkity.com
Sponsored by:	Hobnob, Inc.
2011-11-21 22:57:28 +00:00