It allows application driver get initial link state without racing with
hardware interrupts, thanks to the context rmlock held here.
MFC after: 1 week
Sponsored by: iXsystems, Inc.
Those events may be reported as soon as callback is registered, if the link
is enabled by hardware or some other application.
While there, clean link_is_up variable on link down event.
MFC after: 1 week
This driver supports both NTB-to-NTB and NTB-to-Root Port modes (though
the second with predictable complications on hot-plug and reboot events).
I tested it with PEX 8717 and PEX 8733 chips, but expect it should work
with many other compatible ones too. It supports up to two NT bridges
per chip, each of which can have up to 2 64-bit or 4 32-bit memory windows,
6 or 12 scratchpad registers and 16 doorbells. There are also 4 DMA engines
in those chips, but they are not yet supported.
While there, rename Intel NTB driver from generic ntb_hw(4) to more specific
ntb_hw_intel(4), so now it is on par with this new ntb_hw_plx(4) driver and
alike to Linux naming.
MFC after: 2 weeks
Sponsored by: iXsystems, Inc.
This fixes interrupt storms on hardware using legacy level-triggered
interrupts, since doorbell processing could take time after interrupt
handler completion, that triggered extra interrupts in a loop.
MFC after: 2 weeks
Sponsored by: iXsystems, Inc.
Since the doorbell bit is already set when interrupt handler is called,
the event was not propagated to upper layer. It was working normally
because present code was not using masking actively, but that is going
to change.
MFC after: 2 weeks
Sponsored by: iXsystems, Inc.
I believe it never worked correctly for more the one queue even in Linux.
This fixes case when one of consumer drivers is not loaded on one side,
but its queues still announced as ready if something else brought link up.
While there, remove some pointless NULL checks.
New design allows to attach multiple consumers to ntb_transport(4) instance.
Previous design obtained from Linux theoretically allowed that, but was not
practically usable (Linux also has only one consumer driver now).
New design allows hardware resources to be split between several consumers.
For example, one BAR can be dedicated for remote memory access, while other
resources can be used for packet transport for virtual Ethernet interface.
And even without resource split, this code allows to specify which consumer
driver should attach the hardware.
From some points this makes the code even closer to Linux one, even though
Linux does not provide the described flexibility.
Calling it earlier increases the window when MSIX info may change.
This change does not solve the problem completely, but seems logical.
Complete solution should probably include link reset in case of MSIX
remap to trigger new negotiation, but we have no way to get notified
about that now.
I don't know what errata is mentioned there, I was unable to find it, but
setting limit before the base simply does not work at all. According to
specification attempt to set limit out of the present window range resets
it to zero, effectively disabling it. And that is what I see in practice.
Fixing this properly disables access for remote side to our memory until
respective xlat is negotiated and set. As I see, Linux does the same.
At that point link is quite likely not established yet, so messing with
scratch registers is premature there. Original commit message mentioned
code diff reduction from Linux, but this line is not present in Linux now.
For some reason hack with sending MSI-X interrupts by writing to remote
LAPIC memory works only for 32-bit BARs, that are available only if split
BARs mode is enabled in BIOS. If it is not, complain loudly and fall back
to less efficient workaround.
For compatibility reasons make driver not report any checksum offload by
default, since there is indeed none. But if administrator knows that
interface is used only for local traffic, he can enable fake checksum
offload manually on both sides to save some CPU cycles, since the data
are already protected by CRC32 of PCIe link.
Sponsored by: iXsystems, Inc.
This allows at least first three doorbells to work very close to normal
hardware, properly signaling events to upper layers without spurious or
lost events. Doorbells above the first three may still report spurious
events due to lack of reliable information, but they are rarely used.
It is odd idea to serialize different MSI-X vectors. Use of rmlocks
here allows them to execute in parallel, but still protects ctx.
If upper layers require any additional serialization -- they can
do it by themselves.
This follows NTB subsystem modularization in Linux, tuning it to FreeBSD
native NewBus interfaces. This change allows to support different types
of hardware with different drivers, support multiple NTB instances in a
system, ntb_transport module use for needs other then if_ntb, etc.
Sponsored by: iXsystems, Inc.
Since SBARxSZ register can be write-once, it can be unusable for disabling
the SBAR. For such case also set SBARxBASE to zero to not intersect with
config BAR.
This allows IPv6 link local addresses (and other IPv6 functionality) to work.
PR: 210355
Submitted by: Steve Wahl and David Bright (both at Dell Inc.)
Reviewed by: cem, mav
Tested by: mav (on Intel hardware)
Approved by: re (kib)
MFC after: 5 days
Sponsored by: Dell Inc.
Differential Revision: https://reviews.freebsd.org/D6885
BAR size to 1MB. According to Xeon v3 specifications and my tests, that
size register is write-once and so not writeable after BIOS written it.
Instead of that, make the code work with BAR of any sufficient size,
properly calculating offset within its base. It also simplifies the code.
Discussed with: cem
MFC after: 2 weeks
Sponsored by: iXsystems, Inc.
NTB_MSIX_RECEIVED status, before making upper layers overwrite it.
This is not completely perfect, but now it works better then before.
MFC after: 2 weeks
Sponsored by: iXsystems, Inc.
This patch comes from Dave Jiang's Linux tree, davejiang/ntb. It hasn't
been accepted into Linus' tree, so I do not have an authoritative SHA1
to point at. Original commit log:
=====================================================================
A hardware errata causes the NTB to hang when heavy bi-directional
traffic in addition to the usage of BAR0/1 (where the registers reside,
including the doorbell registers to trigger interrupts).
This workaround is only available on Haswell and Broadwell platform.
The workaround is to enable split BAR in the BIOS to allow the 64bit
BAR4 to be split into two 32bit BAR4 and BAR5. The BAR4 shall be pointed
to LAPIC region of the remote host. We will bypass the db mechanism and
directly trigger the MSIX interrupts. The offsets and vectors are
exchanged during transport scratch pad negotiation. The scratch pads are
now overloaded in order to allow the exchange of the information. This
gets around using the doorbell and prevents the lockup with additional
pcode changes in BIOS.
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
=====================================================================
Notable changes in the FreeBSD version of this patch:
* The MSIX BAR is configurable, like hw.ntb.b2b_mw_idx (msix_mw_idx).
The Linux version of the patch only uses BAR4.
* MSIX negotiation aborts if the link goes down.
Obtained from: Linux (Dual BSD/GPL driver)
Sponsored by: EMC / Isilon Storage Division
Replace the hw.ntb.enable_writecombine tunable with
hw.ntb.default_mw_pat. It can be set with several specific numerical
values to select a caching type. Any bogus value is treated as
Uncacheable (UC).
The ntb_mw_set_wc() KPI has removed the restriction that the selected
mode must be one of UC, WC, or WB.
Sponsored by: EMC / Isilon Storage Division
Note that the MW allocation still must be BAR *aligned*. So, this only
loosens the constraints on MW allocation slightly. BAR-aligned does not
play well with large (GB+) BAR sizes.
Going forward, if anyone cares about if_ntb on very large BARs, I
suggest they add functionality to allocate a smaller window than the BAR
size, and set the BAR range to cover a window much larger than the
allocated window. This will require negotiating a window offset and
limit for protocol traffic. None of this is implemented in this
revision.
Sponsored by: EMC / Isilon Storage Division
And expose vm_memattr_t of current mapping to consumers (as well as the
ability to change it to one of UC, WB, WC).
After short discussion with: jhb (but no review)
Sponsored by: EMC / Isilon Storage Division
Adds a new tunable, ntb.hw.b2b_mw_idx, which specifies the offset (from the
total number of memory windows) to use for register access on hardware with
the SDOORBELL_LOCKUP errata. The default is -1, i.e., the last memory
window.
We map BARs before the b2b_mw_idx is selected, so map them all as memory
windows initially. The register memory window should not be write-combined,
so we explicitly disable WC on the selected MW later.
This introduces a layer of abstraction between consumer memory window
indices, which exclude any exclusive errata-workaround BARs, and internal
memory window indices, which include such BARs. An internal routine,
ntb_user_mw_to_idx(), converts the former to the latter. Public APIs have
been updated to use this instead of assuming the exclusive workaround BAR is
the last available MW.
Sponsored by: EMC / Isilon Storage Division
Lower the payload data (IP) portion of the MTU from 0x10000 to
IP_MAXPACKET (0xFFFF) to avoid panicing the IP stack.
Sponsored by: EMC / Isilon Storage Division
This feature is disabled by default. To enable it, tune
hw.if_ntb.enable_xeon_watchdog to non-zero.
If enabled, writes an unused NTB register every second to demonstrate to
a hardware watchdog that the NTB device is still alive. Most machines
with NTB will not need this -- you know who you are.
Sponsored by: EMC / Isilon Storage Division
Discard the unused rx_free_q. Instead, reuse inputed packets by putting
them back on the *pend* queue after reinitialization.
If tx or rx handlers are unavailable, free mbufs rather than leaking
them.
With this change, if_ntb can receive more than 100
(NTB_QP_DEF_NUM_ENTRIES) packets.
Sponsored by: EMC / Isilon Storage Division
32-bit BARs can only address memory mapped in the low 32 bits of
physical RAM. Expose this as a 'plimit' out parameter from
ntb_mw_get_range().
Fix if_ntb to allocate memory within this limit.
Sponsored by: EMC / Isilon Storage Division
Sometimes they'll read spurious values (observed: 0xc on Broadwell-DE),
failing link negotiation.
Discussed with: Dave Jiang, Allen Hubbe
Sponsored by: EMC / Isilon Storage Division
The tunable 'hw.ntb.enable_writecombine' may be set to zero to
administratively disable write combining the mapped NTB region.
Sponsored by: EMC / Isilon Storage Division
Use bus_space_write instead of (non-volatile) C pointer writes via an
iowrite32() shim in the same places as the Dual BSD/GPL Linux driver.
Update some types to fixed 32-bit sizes.
Sponsored by: EMC / Isilon Storage Division
There is no need for the upstream and downstream addresses to be
different for the NTB configs. Go to using a single set of address. It
is still possible to configure them differently using module parameter
override however (CEM: tunable).
Authored by: Dave Jiang <dave.jiang@intel.com>
Reviewed by: Allen Hubbe <Allen.Hubbe@emc.com>
Reviewed by: Jon Mason <jdmason@kudzu.us>
Obtained from: Linux (Dual BSD/GPL driver)
Sponsored by: EMC / Isilon Storage Division
Order of operations issue with the QP Num and MW count, which would
result in the receive buffer pointer being invalid if there are more
than 1 MW. Corrected with parenthesis to enforce the proper order of
operations.
Reported by: John I. Kading <John.Kading@gd-ms.com>
Reported by: Conrad Meyer <cem@FreeBSD.org>
Authored by: Jon Mason <jdmason@kudzu.us>
Obtained from: Linux (Dual BSD/GPL driver)
Sponsored by: EMC / Isilon Storage Division
Because it can sleep drainking link work callout(s). Linux (dual
BSD/GPL driver) does something very similar.
At the same time, switch the NTB CTX lock to a non-spin mutex, because
the taskqueue_swi lock can't be taken after a spin mutex.
Suggested by: Witness
Sponsored by: EMC / Isilon Storage Division
In ntb_poll_link, we are intentionally writing the link bit, which is
absent from db_valid_mask. Don't panic on a kassert when we do so.
The Linux version of this (dual BSD/GPL) driver has the db_valid_mask
assertions in callers of db_iowrite() rather than db_iowrite() itself;
it skips the assertions in the equivalent of ntb_poll_link(). Rather
than duplicating the assertions in every caller, add a db_iowrite_raw()
that doesn't check and use it from ntb_poll_link().
Suggested by: kassert_panic
Sponsored by: EMC / Isilon Storage Division
AMD64 pmap assumes ranges will be in the DMAP, which isn't necessarily
true for NTB memory windows (especially 64-bit BARs).
Suggested by: pmap_change_attr_locked -> kassert_panic
Sponsored by: EMC / Isilon Storage Division
This should export all of the same information as the Linux ntb_hw_intel
debugfs info file, but with a bit more structure, in the sysctl tree
rooted at 'dev.ntb_hw.<N>.debug_info'.
Raw registers are marked as OPAQUE because reading them on some hardware
revisions may cause a hard lockup (NTB errata). They can be read with
'sysctl -x dev.ntb_hw.<N>.debug_info.registers'. On Xeon platforms,
some additional registers are available under 'registers.xeon_stats' and
'registers.xeon_hw_err'. They are exported as big-endian values so that
the 'sysctl -x' output is legible.
Shrink the feature mask to 32 bits so we can use the %b formatter in
'debug_info.features'.
Sponsored by: EMC / Isilon Storage Division
Add ntb_q_idx_t so it is more clear which struct members are of the same
type (some bogus uint64_ts snuck in that should have been unsigned int).
Add tx_err_no_buf and s/ENOMEM/EBUSY/ in tx_enqueue to match Linux.
Sponsored by: EMC / Isilon Storage Division
A plain 32 bit integer will overflow for values over 4GiB.
Change the plain integer size to the appropriate size type in
ntb_set_mw. Change the type of the size parameter and two local
variables used for size.
Even if there is no overflow, a size of zero is invalid here.
Authored by: Allen Hubbe
Reported by: Juyoung Jung
Obtained from: Linux (Dual BSD/GPL driver)
Sponsored by: EMC / Isilon Storage Division
It was possible for a synchronous update of the RX index in the error
case to get ahead of the asynchronous RX index update in the normal
case. Change the RX processing to preserve an RX completion order.
There were two error cases. First, if a buffer is not present to
receive data, there would be no queue entry to preserve the RX
completion order. Instead of dropping the RX frame, leave the RX frame
in the ring. Schedule RX processing when RX entries are enqueued, in
case there are RX frames waiting in the ring to be received.
Second, if a buffer is too small to receive data, drop the frame in the
ring, mark the RX entry as done, and indicate the error in the RX entry
length. Check for a negative length in the receive callback in
ntb_netdev, and count occurrences as rx_length_errors.
Authored by: Allen Hubbe
Obtained from: Linux (Dual BSD/GPL driver)
Sponsored by: EMC / Isilon Storage Division
Mechanically replace "SOC" with "ATOM" to match Linux. No functional
change. Original Linux commit log follows:
Instead of using the platform code names, use the correct platform names
to identify the respective Intel NTB hardware.
Authored by: Dave Jiang
Obtained from: Linux (Dual BSD/GPL driver)
Sponsored by: EMC / Isilon Storage Division
Prints driver name to indicate what is being loaded.
Authored by: Dave Jiang
Obtained from: Linux (Dual BSD/GPL driver)
Sponsored by: EMC / Isilon Storage Division
Benchmarking showed a significant performance increase with the MTU size
to 64k instead of 16k. Change the driver default to 64k.
Authored by: Dave Jiang
Obtained from: Linux (Dual BSD/GPL driver)
Sponsored by: EMC / Isilon Storage Division
Throw away the result of the peer SPAD read. The peer will write our
local SPAD and we need to keep the locally read SPAD value to check if
the remote side is up.
Sponsored by: EMC / Isilon Storage Division
Add module parameters for the addresses to be used in B2B topology.
Authored by: Allen Hubbe
Obtained from: Linux (Dual BSD/GPL driver)
Sponsored by: EMC / Isilon Storage Division
Reset the link stats when the link goes down. In particular, the TX and
RX index and count must be reset, or else the TX side will be sending
packets to the RX side where the RX side is not expecting them. Reset
all the stats, to be consistent.
Authored by: Allen Hubbe
Obtained from: Linux (Dual BSD/GPL driver)
Sponsored by: EMC / Isilon Storage Division
We skip actually bringing up Rootport/Transparent configurations, so
most of this doesn't apply. Original Linux commit log:
Link training should be enabled in the driver probe for root port mode.
We should not have to wait for transport to be loaded for this to
happen. Otherwise the ntb device will not show up on the transparent
bridge side of the link.
Authored by: Dave Jiang
Obtained from: Linux (Dual BSD/GPL driver)
Sponsored by: EMC / Isilon Storage Division