Commit Graph

19 Commits

Author SHA1 Message Date
adrian
c74ad1c589 Remove unnecessary debugging printf()s. 2012-08-06 22:54:10 +00:00
adrian
142df5fc8e Modify ath_descdma_setup() to take a descriptor size parameter.
The AR9300 and later descriptors are 128 bytes, however I'd like to make
sure that isn't used for earlier chips.

* Populate the TX descriptor length field in the softc with
  sizeof(ath_desc)

* Use this field when allocating the TX descriptors

* Pre-AR93xx TX/RX descriptors will use the ath_desc size; newer ones will
  query the HAL for these sizes.
2012-07-23 23:40:13 +00:00
adrian
c486d0bf45 Handle RX Keymiss events.
The AR9003 series NICs implement a separate RX error to signal that a
Keycache miss occured.  The earlier NICs would not set the key index
valid bit.

I'll dig into the difference between "no key index bit set" and "keycache
miss".
2012-07-15 20:51:41 +00:00
adrian
b89b88c83b Migrate the ATH_KTR_* fields out to if_ath_debug.h . 2012-07-10 06:11:39 +00:00
adrian
5dbf12e2ad Convert sc_rxpending to a per-EDMA queue, and use that for the legacy code.
Prepare ath_rx_pkt() to handle multiple RX queues, and default the legacy
RX queue to use the HP queue.
2012-07-10 00:02:19 +00:00
adrian
2977d109d8 Further preparations for the RX EDMA support.
Break out the DMA descriptor setup/teardown code into a method.
The EDMA RX code doesn't allocate descriptors, just ath_buf entries.
2012-07-09 08:37:59 +00:00
adrian
de86634e9a Extend the RX HAL API to include the RX queue identifier.
The AR93xx and later chips support two RX FIFO queues - a high and low
priority queue.

For legacy chips, just assume the queues are high priority.

This is inspired by the reference driver but is a reimplementation of
the API and code.
2012-07-09 07:19:11 +00:00
adrian
8af1316f3a Begin abstracting out the RX path in preparation for RX EDMA support.
The RX EDMA support requires a modified approach to the RX descriptor
handling.

Specifically:

* There's now two RX queues - high and low priority;
* The RX queues are implemented as FIFOs; they're now an array of pointers
  to buffers;
* .. and the RX buffer and descriptor are in the same "buffer", rather than
  being separate.

So to that end, this commit abstracts out most of the RX related functions
from the bulk of the driver.  Notably, the RX DMA/buffer allocation isn't
updated, primarily because I haven't yet fleshed out what it should look
like.

Whilst I'm here, create a set of matching but mostly unimplemented EDMA
stubs.

Tested:

  * AR9280, station mode

TODO:

  * Thorough AP and other mode testing for non-EDMA chips;
  * Figure out how to allocate RX buffers suitable for RX EDMA, including
    correctly setting the mbuf length to compensate for the RX descriptor
    and completion status area.
2012-07-03 06:59:12 +00:00
adrian
c5fe4faa45 Change the ath_dfs_process_phy_err() method to take an mbuf rather than
a buffer pointer.

For large radar pulses, the AR9130 and later will return a series of
FFT results for software processing.  These can overflow a single 2KB
buffer on longer pulses.  This would result in undefined buffer behaviour.
2012-06-24 08:09:06 +00:00
adrian
a5794ac4d0 Introduce an optional ath(4) radiotap vendor extension.
This includes a few new fields in each RXed frame:

* per chain RX RSSI (ctl and ext);
* current RX chainmask;
* EVM information;
* PHY error code;
* basic RX status bits (CRC error, PHY error, etc).

This is primarily to allow me to do some userland PHY error processing
for radar and spectral scan data.  However since EVM and per-chain RSSI
is provided, others may find it useful for a variety of tasks.

The default is to not compile in the radiotap vendor extensions, primarily
because tcpdump doesn't seem to handle the particular vendor extension
layout I'm using, and I'd rather not break existing code out there that
may be (badly) parsing the radiotap data.

Instead, add the option 'ATH_ENABLE_RADIOTAP_VENDOR_EXT' to your kernel
configuration file to enable these options.
2012-06-24 07:01:49 +00:00
adrian
f4c9781794 .. and this wasn't supposed to be in the previous commit either. 2012-06-16 22:28:36 +00:00
adrian
e781c0c0fc oops, remove this, it wasn't supposed to be committed. 2012-06-16 22:26:45 +00:00
adrian
6dd8c2eb6c Create a function - ath_tx_kick() - which is called where ath_start() is
called to "kick" along TX.

For now, schedule a taskqueue call.

Later on I may go back to the direct call of ath_rx_tasklet() - but for
now, this will do.

I've tested UDP and TCP TX. UDP TX still achieves 240MBit, but TCP
TX gets stuck at around 100MBit or so, instead of the 150MBit it should
be at.  I'll re-test with no ACPI/power/sleep states enabled at startup
and see what effect it has.

This is in preparation for supporting an if_transmit() path, which will
turn ath_tx_kick() into a NUL operation (as there won't be an ifnet
queue to service.)

Tested:
	* AR9280 STA

TODO:
	* test on AR5416, AR9160, AR928x STA/AP modes

PR:		kern/168649
2012-06-05 03:14:49 +00:00
adrian
673d798918 Migrate the TX path to a taskqueue for now, until a better way of
implementing parallel TX and TX/RX completion can be done without
simply abusing long-held locks.

Right now, multiple concurrent ath_start() entries can result in
frames being dequeued out of order.  Well, they're dequeued in order
fine, but if there's any preemption or race between CPUs between:

* removing the frame from the ifnet, and
* calling and runningath_tx_start(), until the frame is placed on a
  software or hardware TXQ

Then although dequeueing the frame is in-order, queueing it to the hardware
may be out of order.

This is solved in a lot of other drivers by just holding a TX lock over
a rather long period of time.  This lets them continue to direct dispatch
without races between dequeue and hardware queue.

Note to observers: if_transmit() doesn't necessarily solve this.
It removes the ifnet from the main path, but the same issue exists if
there's some intermediary queue (eg a bufring, which as an aside also
may pull in ifnet when you're using ALTQ.)

So, until I can sit down and code up a much better way of doing parallel
TX, I'm going to leave the TX path using a deferred taskqueue task.
What I will likely head towards is doing a direct dispatch to hardware
or software via if_transmit(), but it'll require some driver changes to
allow queues to be made without using the really large ath_buf / ath_desc
entries.

TODO:

* Look at how feasible it'll be to just do direct dispatch to
  ath_tx_start() from if_transmit(), avoiding doing _any_ intermediary
  serialisation into a global queue.  This may break ALTQ for example,
  so I have to be delicate.

* It's quite likely that I should break up ath_tx_start() so it
  deposits frames onto the software queues first, and then only fill
  in the 802.11 fields when it's being queued to the hardware.
  That will make the if_transmit() -> software queue path very
  quick and lightweight.

* This has some very bad behaviour when using ACPI and Cx states.
  I'll do some subsequent analysis using KTR and schedgraph and file
  a follow-up PR or two.

PR:		kern/168649
2012-06-04 22:01:12 +00:00
adrian
83179ad85b Re-add 'ic' and properly wrap it in the SUPERG macro. 2012-05-21 17:51:26 +00:00
bschmidt
2a516c354f Remove unused variable. 2012-05-20 09:46:48 +00:00
adrian
e1654c32a7 Migrate the per-frame code out from ath_rx_proc() to ath_rx_pkt().
This will (eventually) be used by the EDMA RX path used by the
AR93xx and later NICs.
2012-05-20 06:35:22 +00:00
adrian
91668b1b5a 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
677f51d0dd 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