stack.
There are unfortunately quite a few odd cases in BAR TX and BAR TX
retransmission that I haven't yet fully diagnosed. So for now, add
this work-around so the resume() function isn't called too often,
decrementing pause to -1 (and causing things to stay paused.)
a 4kb buffer if a request uses a buffer size of 0. (The Linux ioctl path
already did this.)
PR: kern/155658
Submitted by: Andreas Longwitz
MFC after: 1 week
#defines. This also has the advantage that it makes the names more
compact, iand also allows us to correct the non-uniform naming of
the PCIM_LINK_* defines, making them all consistent amongst themselves.
This is a mostly mechanical rename:
s/PCIR_EXPRESS_/PCIER_/g
s/PCIM_EXP_/PCIEM_/g
s/PCIM_LINK_/PCIEM_LINK_/g
When this is MFC'd, #defines will be added for the old names to assist
out-of-tree drivers.
Discussed with: jhb
MFC after: 1 week
is done.
The aggregate path was definitely accessing 'ts' before it was actually
being assigned.
This had the side effect of over-filtering frames, since occasionally that
bit would be '1'.
Whilst here, do the same thing in the non-aggregate completion function -
as calling the filter function may also invalidate bf.
Pointy hat to: adrian, for not noticing this over many, many code reviews.
This fixes issue in nvmecontrol(8), where clang throws a cast-align
warning when casting a __packed structure pointer to a uint32_t
pointer as part of printing raw hex output.
Reported by: dhw
The hardware can optionally "filter" frames if successive transmissions
to a given node (ie, "entry in the keycache") fail. That way the hardware
can implement a kind of early abort of all the other frames queued to
that destination, rather than simply trying to TX each frame to that
destination (and failing.)
The background:
* If a frame comes back as being filtered, the hardware didn't try to
TX it (or it was outside the TX burst opportunity.) So, take it as a hint
that some (but not all, see below) frames to the destination may be
filtered.
* If the CLRDMASK bit is set in a TX descriptor, the "filter to this
destination" bit in the keycache entry is cleared and TX to that host
will be unconditionally retried.
* Right now everything has the CLRDMASK bit set, so filtered frames
tend to be aggregates and frames that fall outside of the WME burst
window. It was a bit worse in the past as I had messed up the TX
flags and CLRDMASK wasn't being set on aggregate frames.
The annoying bits:
* It's easy (ish) to do for aggregate session frames - firstly, they
can be retried in any order as long as they're within the BAW, and
there's already a bunch of infrastructure tracking how many frames
the TID has queued to the hardware (tid->hwq_depth.) However, for
frames that bypassed the software queue, hwq_depth doesn't get
incremented. I'll fix that in a subsequent commit.
* For non-aggregate session frames, the only retries that can occur
are ones for sequence numbers that hvaen't successfully been TXed yet.
Since there's no re-ordering going on in non-aggregate sessions, if any
subsequent seqno frames make it out, any filtered frames before that
seqno need to be dropped.
Hence why this initially is just for aggregate session frames.
* Since there may be intermediary frames to the destination that
have CLRDMASK set - for example, any directly dispatched management
frames to that destination - it's possible that there will be some
filtered frames followed up by some non filtered frames. Thus,
it can't be assumed that once you see a filtered frame for the given
destination node, all subsequent frames for all TIDs will be filtered.
Ok, with that in mind:
* Create a per-TID filtered frame queue for frames that the hardware
returns as filtered.
* Track filtered frames per-tid, rather than per-node. It just makes
the locking much easier.
* When a filtered frame appears in the completion function, the node
transitions to "filtered", and all subsequent completed error frames
(filtered or otherwise) are put on the filtered frame queue. The TID
is paused once (during the transition from non-filtered to filtered).
* If a filtered frame retry count exceeds SWMAX_RETRIES, a BAR should be
sent.
* Once all the frames queued to the hardware for the given filtered frame
TID, transition back from filtered frame to non-filtered frame, which
means pre-pending all the filtered frames onto the head of the software
queue, clearing the filtered frame state and unpausing the TID.
Things get quite hairy around handling completion (aggr, non-aggr, norm,
direct-dispatched frames to a hardware queue); whether it's an "error",
"cleanup" or "BAR" state as well as filtered, which order to do things
in (eg do filtered BEFORE checking for BAR, as the filter completion
may be needed to actually transmit a BAR frame.)
This work has definitely reminded me that I have to tidy up all the locking
and remove some of the ridiculous lock/unlock/lock/unlock going on in the
completion functions.
It's also reminded me that I should really split out TID versus hardware TXQ
locking, even if the underlying locking is still the destination hardware TXQ.
Finally, this is all pre-requisite for working on AP mode power save support
(PS-POLL, uAPSD) as well as improving performance to misbehaving nodes (as
they can transition into filter mode, stopping any TX until everything has
caught up.)
Finally (ish) - this should also be done for non-aggregate sessions as
there are still plenty of laptops and mobile devices that don't speak
802.11n but do wish for stable, useful power save AP support where packets
aren't simply dropped. This requires software retransmission for
non-aggregate sessions to be implemented, which includes the caveats I've
mentioned above.
Finally finally - this doesn't yet do anything about the CLRDMASK bit in the
TX descriptor. That's still unconditionally set to 1. I'll debug the
current work (mostly ensuring I haven't busted up the hairy transitions
between BAR, filtered, error (all frames in an aggregate failing) and
cleanup (when transitioning from aggregation -> non-aggregation.))
Finally finally finally - this is all original work by yours truely, rather
than ported from the Atheros internal driver codebase or Linux ath9k.
Tested:
* AR9280, AR5416 in STA mode
* AR9280, AR9130 in hostap mode
* Lots and lots of iperf testing in very marginal and non-marginal conditions,
complete with inducing filtered frames + BAR TX conditions.
support to FreeBSD. A full description of the overall functionality
being added is below. nvmexpress.org defines NVM Express as "an optimized
register interface, command set and feature set fo PCI Express (PCIe)-based
Solid-State Drives (SSDs)."
This commit adds nvme(4) and nvd(4) driver source code and Makefiles
to the tree.
Full NVMe functionality description:
Add nvme(4) and nvd(4) drivers and nvmecontrol(8) for NVM Express (NVMe)
device support.
There will continue to be ongoing work on NVM Express support, but there
is more than enough to allow for evaluation of pre-production NVM Express
devices as well as soliciting feedback. Questions and feedback are welcome.
nvme(4) implements NVMe hardware abstraction and is a provider of NVMe
namespaces. The closest equivalent of an NVMe namespace is a SCSI LUN.
nvd(4) is an NVMe consumer, surfacing NVMe namespaces as GEOM disks.
nvmecontrol(8) is used for NVMe configuration and management.
The following are currently supported:
nvme(4)
- full mandatory NVM command set support
- per-CPU IO queues (enabled by default but configurable)
- per-queue sysctls for statistics and full command/completion queue
dumps for debugging
- registration API for NVMe namespace consumers
- I/O error handling (except for timeoutsee below)
- compilation switches for support back to stable-7
nvd(4)
- BIO_DELETE and BIO_FLUSH (if supported by controller)
- proper BIO_ORDERED handling
nvmecontrol(8)
- devlist: list NVMe controllers and their namespaces
- identify: display controller or namespace identify data in
human-readable or hex format
- perftest: quick and dirty performance test to measure raw
performance of NVMe device without userspace/physio/GEOM
overhead
The following are still work in progress and will be completed over the
next 3-6 months in rough priority order:
- complete man pages
- firmware download and activation
- asynchronous error requests
- command timeout error handling
- controller resets
- nvmecontrol(8) log page retrieval
This has been primarily tested on amd64, with light testing on i386. I
would be happy to provide assistance to anyone interested in porting
this to other architectures, but am not currently planning to do this
work myself. Big-endian and dmamap sync for command/completion queues
are the main areas that would need to be addressed.
The nvme(4) driver currently has references to Chatham, which is an
Intel-developed prototype board which is not fully spec compliant.
These references will all be removed over time.
Sponsored by: Intel
Contributions from: Joe Golio/EMC <joseph dot golio at emc dot com>
- Use callout(9) rather than timeout(9).
- Add a mutex as an I/O lock that protects the adapter and is used
for the I/O path.
- Add an sx lock as a configuration lock that protects the relationship
of configured volumes.
- Freeze the request queue when a DMA load is deferred with EINPROGRESS
and unfreeze the queue when the DMA callback is invoked.
- Explicitly poll the hardware while waiting to submit a command to
allow completed commands to free up slots in the command ring.
- Remove driver-wide 'initted' variable from mlx_*_fw_handshake() routines.
That state should be per-controller instead. Add it as an argument
since the first caller knows when it is the first caller.
- Remove explicit bus_space tag/handle and use bus_*() rather than
bus_space_*().
- Move duplicated PCI device ID probing into a mlx_pci_match() routine.
- Don't check for PCIM_CMD_MEMEN (the PCI bus will enable that when
allocating the resource) and use pci_enable_busmaster() rather than
manipulating the register directly.
Tested by: no one despite multiple requests (hope it works)
These are intended for software TX filtering support, where the NIC
decides there has been too many successive failues to a destination
and will filter it.
Although the filtering is done per-destination (via the keycache),
the state and queue is kept per-TID for now. It simplifies the overall
architecture design and locking.
Whilst here, add ATH_TID_UNLOCK_ASSERT().
* Don't treat high percentage failures as "sucessive failures" - high
MCS rates are very picky and will quite happily "fade" from low
to high failure % and back again within a few seconds. If they really
don't work, the aggregate will just plain fail.
* Only sample MCS rates +/- 3 from the current MCS. Sample will back off
quite quickly, so there's no need to sample _all_ MCS rates between
a high MCS rate and MCS0; there may be a lot of them.
* Modify the smoothing rate to be 75% rather than 95% - it's more adaptive
but it comes with a cost of being slightly less stable at times.
A per-node, hysterisis behaviour would be nicer.
(download microcode with offsets, save, and activate).
SATI translation layer was incorrectly using allocation length instead
of blocks, and was constructing the ATA command incorrectly.
Also change #define to specify that the 512 block size here is
specific for DOWNLOAD_MICROCODE, and does not relate to the device's
logical block size.
Submitted by: scottl (with small modifications)
MFC after: 3 days
trap checks (eg. printtrap()).
Generally this check is not needed anymore, as there is not a legitimate
case where curthread != NULL, after pcpu 0 area has been properly
initialized.
Reviewed by: bde, jhb
MFC after: 1 week
- Add constants for the rest of the fields in the PCI-express device
capability and control registers.
- Tweak some of the recently added PCI-e capability constants (always
use hex for offsets in config space, and include a shortened
version of the relevant register in the name of field constants).
MFC after: 1 week
I'm not sure where in the deep, distant past I found the AR_PHY_MODE
registers for half/quarter rate mode, but unfortunately that doesn't
seem to work "right" for non-AR9280 chips.
Specifically:
* don't touch AR_PHY_MODE
* set the PLL bits when configuring half/quarter rate
I've verified this on the AR9280 (5ghz fast clock) and the AR5416.
The AR9280 works in both half/quarter rate; the AR5416 unfortunately
only currently works at half rate. It fails to calibrate on quarter rate.
No, this isn't HT/5 and HT/10 support. This is the 11a half/quarter
rate support primarily used by the 4.9GHz and GSM band regulatory
domains.
This is definitely a work in progress.
TODO:
* everything in the last commit;
* lots more interoperability testing with the AR5212 half/quarter rate
support for the relevant chips;
* Do some interop testing on half/quarter rate support between _all_
the 11n chips - AR5416, AR9160, AR9280 (and AR9285/AR9287 when 2GHz
half/quarter rate support is coded up.)
used when running the chips in half/quarter rate.
This sets up some default parameters which are then overridden by the
driver (which manually configures things like slot timing at interface
start time.)
Although this is a copy-and-modify from the AR5212 HAL, I did peek
at the reference HAL and the ath9k driver to see what they did.
Ath9k in particular doesn't hard-code this - instead, their version
of ar5416InitUserSettings() does all of the relevant math.
TODO:
* do the math, not hard code things!
* fix the mac clock calculation for the AR9287; since it runs the
MAC clock at a higher rate, requiring all the duration calculations
to change;
* Do a whole lot more validation for half/quarter rates.
Obtained from: Qualcomm Atheros, Linux ath9k