summaryrefslogtreecommitdiffstats
path: root/sys/dev/ath/if_ath.c
Commit message (Collapse)AuthorAgeFilesLines
...
* Migrate the ATH_KTR_* fields out to if_ath_debug.h .adrian2012-07-101-3/+0
|
* Further preparations for the RX EDMA support.adrian2012-07-091-19/+25
| | | | | Break out the DMA descriptor setup/teardown code into a method. The EDMA RX code doesn't allocate descriptors, just ath_buf entries.
* Begin abstracting out the RX path in preparation for RX EDMA support.adrian2012-07-031-3/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Shuffle these initialisations to where they should be.adrian2012-06-241-7/+7
|
* Introduce an optional ath(4) radiotap vendor extension.adrian2012-06-241-0/+15
| | | | | | | | | | | | | | | | | | | | | | 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.
* After some discussion with bschmidt@, it's likely better to just goadrian2012-06-171-37/+4
| | | | | | | through ieee80211_suspend_all() and ieee80211_resume_all(). All the other wireless drivers are doing that particular dance. PR: kern/169084
* oops, remove this, it wasn't supposed to be committed.adrian2012-06-161-3/+0
|
* Fix build.kib2012-06-161-1/+1
|
* Shuffle some more fields in ath_buf so it's not too big.adrian2012-06-161-0/+3
| | | | | | This shaves off 20 bytes - from 288 bytes to 268 bytes. However, it's still too big.
* Convert ath(4) to just use ieee80211_suspend_all() and ieee80211_resume_all().adrian2012-06-151-0/+16
| | | | | | | | | | | | The existing code tries to use the beacon miss timer to signal that the AP has gone away. Unfortunately this doesn't seem to be behaving itself. I'll try to investigate why this is for the sake of completeness. The result is the STA will stay "associated" to the AP it was associated with when it suspended. It never receives a bmiss notification so it never tries reassociating. PR: kern/169084
* Disable BGSCAN for 802.11n for now. Until scanning during traffic isadrian2012-06-141-6/+2
| | | | | | | | fixed for 802.11n TX, this needs to be disabled or users wlil see randomly hanging aggregation sessions. Whilst I'm here, remove the warning about 802.11n being full of dragons. It's nowhere near that scary now.
* Implement a global (all non-mgmt traffic) TX ath_buf limitation whenadrian2012-06-141-3/+48
| | | | | | | | | | | | | | | | | ath_start() is called. This (defaults to 10 frames) gives for a little headway in the TX ath_buf allocation, so buffer cloning is still possible. This requires a lot omre experimenting and tuning. It also doesn't stop a node/TID from consuming all of the available ath_buf's, especially when the node is going through high packet loss or only talking at a low TX rate. It also doesn't stop a paused TID from taking all of the ath_bufs. I'll look at fixing that up in subsequent commits. PR: kern/168170
* Implement a separate, smaller pool of ath_buf entries for use by managementadrian2012-06-131-13/+69
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | traffic. * Create sc_mgmt_txbuf and sc_mgmt_txdesc, initialise/free them appropriately. * Create an enum to represent buffer types in the API. * Extend ath_getbuf() and _ath_getbuf_locked() to take the above enum. * Right now anything sent via ic_raw_xmit() allocates via ATH_BUFTYPE_MGMT. This may not be very useful. * Add ATH_BUF_MGMT flag (ath_buf.bf_flags) which indicates the current buffer is a mgmt buffer and should go back onto the mgmt free list. * Extend 'txagg' to include debugging output for both normal and mgmt txbufs. * When checking/clearing ATH_BUF_BUSY, do it on both TX pools. Tested: * STA mode, with heavy UDP injection via iperf. This filled the TX queue however BARs were still going out successfully. TODO: * Initialise the mgmt buffers with ATH_BUF_MGMT and then ensure the right type is being allocated and freed on the appropriate list. That'd save a write operation (to bf->bf_flags) on each buffer alloc/free. * Test on AP mode, ensure that BAR TX and probe responses go out nicely when the main TX queue is filled (eg with paused traffic to a TID, awaiting a BAR to complete.) PR: kern/168170
* Replace the direct sc_txbuf manipulation with a pair of functions.adrian2012-06-131-3/+21
| | | | | | | This is preparation work for having a separate ath_buf queue for management traffic. PR: kern/168170
* Add a new ioctl for ath(4) which returns the aggregate statistics.adrian2012-06-101-0/+3
|
* Mostly revert previous commit(s). After doing a bunch of local testing,adrian2012-06-051-11/+0
| | | | | | | | | | | it turns out that it negatively affects performance. I'm stil investigating exactly why deferring the IO causes such negative TCP performance but doesn't affect UDP preformance. Leave the ath_tx_kick() change in there however; it's going to be useful to have that there for if_transmit() work. PR: kern/168649
* Create a function - ath_tx_kick() - which is called where ath_start() isadrian2012-06-051-7/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | 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
* Migrate the TX path to a taskqueue for now, until a better way ofadrian2012-06-041-3/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* oops - ath_hal_disablepcie is actually destined for another purpose,adrian2012-05-251-3/+9
| | | | | | | not to disable the PCIe PHY in prepration for reset. Extend the enablepci method to have a "poweroff" flag, which if equal to true means the hardware is about to go to sleep.
* Prepare for improved (read: pcie) suspend/resume support.adrian2012-05-251-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Flesh out the pcie disable method for 11n chips, as they were defaulting to the AR5212 (empty) PCIe disable method. * Add accessor macros for the HAL PCIe enable/disable calls. * Call disable on ath_suspend() * Call enable on ath_resume() NOTE: * This has nothing to do with the NIC sleep/run state - the NIC still will stay in network-run state rather than supporting network-sleep state. This is preparation work for supporting correct suspend/resume WARs for the 11n PCIe NICs. TODO: * It may be feasible at this point to keep the chip powered down during initial probe/attach and only power it up upon the first configure/reset pass. This however would require correct (for values of "correct") tracking of the NIC power configuration state from the driver and that just isn't attempted at the moment. Tested: * AR9280 on my Lenovo T60, but with no suspend/resume pass (yet).
* Migrate most of the beacon handling functions out to if_ath_beacon.c.adrian2012-05-201-746/+2
| | | | This is also in preparation for supporting AR9300 and later NICs.
* Migrate the TDMA management functions out of if_ath.c into if_ath_tdma.c.adrian2012-05-201-367/+8
| | | | | | 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.
* Migrate the bulk of the RX routines out from if_ath.c to if_ath_rx.[ch].adrian2012-05-201-911/+6
| | | | | | | | | | | | | | | | | | | * 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] ...
* Re-enable this particular DELAY() for now, at least until theadrian2012-05-071-0/+2
| | | | | | | | | 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.
* Add a comment about this DELAY(), I'm not sure whether it's supposedadrian2012-04-281-0/+4
| | | | to be for a DDR/FIFO flush or something else.
* Run the fatal proc as a proc, rather than where it currently is.adrian2012-04-171-1/+2
| | | | Otherwise the reset path will sleep, which it can't do in this context.
* Fix the default, non-superg compile.adrian2012-04-111-0/+2
| | | | Pointy-hat-to: adrian
* Fix compilation with IEEE80211_ENABLE_SUPERG defined.adrian2012-04-101-0/+1
| | | | PR: kern/164951
* Blank the aggregate stats whenever the zero ioctl is called.adrian2012-04-101-0/+2
|
* Squirrel away SYNC interrupt debugging if it's enabled in the HAL.adrian2012-04-101-1/+13
| | | | | Bus errors will show up as various SYNC interrupts which will be passed back up to ath_intr().
* Revert this for now - it may work for -8 and -9 and -HEAD, but notadrian2012-04-101-14/+0
| | | | | | "-HEAD driver + net80211 on -9 kernel." I'll figure this out at some later stage.
* * Since the API changed along the -CURRENT path (december 2011),adrian2012-04-101-2/+22
| | | | | | | | | | | | | | | | | | 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.)
* Store away the RTS aggregate limit from the HAL.adrian2012-04-071-0/+7
| | | | | | 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).
* Remove duplicate txflags field from ath_buf.adrian2012-04-071-5/+4
| | | | | rename bf_state.bfs_flags to bf_state.bfs_txflags, as that is what it effectively is.
* Disable the HWQ contents upon a TX queue reset, rather than a TX queue flush.adrian2012-04-041-0/+4
| | | | | This is designed to assist in figuring out what the hardware state is when something like a queue hang has occured.
* oops, add a missing lock.adrian2012-03-291-1/+4
|
* Defer the rescheduling of TID -> TXQ frames in some instances.adrian2012-03-291-0/+34
| | | | | | | | | | | | | | | | | | 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.
* Add the new channel width change field to the ath(4) driver.adrian2012-03-251-0/+27
| | | | | | | | | | | | | 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
* Fix a couple of debugging outputs.adrian2012-03-161-4/+13
| | | | | | | | | * 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
* Add a dependency on ALQ if IEEE80211_ALQ and/or AH_DEBUG_ALQ is included.adrian2012-03-161-0/+6
|
* Stick the if_drv_flags access (check and modify) behind the ifq lock.adrian2012-03-101-9/+18
| | | | | | 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.
* Don't flood the cabq/mcastq with frames.adrian2012-03-101-0/+13
| | | | | | | | | | | | | | | | | | | | | | 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
* Should the mcast queue be locked here? In case more multicast trafficadrian2012-03-091-0/+2
| | | | | | | 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.
* Insert extra paranoia into the ath(4) driver.adrian2012-03-091-0/+4
| | | | | | | | 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.
* Wrap another ATH_LOCK around the scanning flag.adrian2012-03-021-0/+2
| | | | PR: kern/163318
* Wrap the scan code state change stuff behind ATH_LOCK and the PCU fiddlingadrian2012-03-021-0/+10
| | | | | | | behind the PCU lock. sc_scanning is being checked without ATH_LOCK behind held and could in theory run from multiple threads.
* Attempt to further fix some of the concurrency/reset issues that occur.adrian2012-02-251-16/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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
* Use the passed-in channel rather than ic->ic_curchan.adrian2012-02-231-1/+1
| | | | | | | 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.
* Try to ensure that ieee80211_newstate() and the vap_newstate methodsadrian2012-02-181-0/+15
| | | | | | | | | | | | 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.)
* Enforce some consistent ordering and handling of interrupt disable/enableadrian2012-02-171-12/+8
| | | | | | | | | | | | | | | 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
OpenPOWER on IntegriCloud