A zero divisor will currently lead to a 16-bit integer overflow when
calculating the transmit padding, and a potential division by zero if
assertions are enabled.
Avoid these problems by treating a divisor value of zero as equivalent
to a divisor value of one (i.e. no alignment requirements).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The current error handling mechanism defers the endpoint reset until
the next use of the endpoint, on the basis that errors are detected
during completions and completion handling should not recursively call
usb_poll().
In the case of usb_control(), we are already at the level that calls
usb_poll() and can therefore safely perform the endpoint reset
immediately. This has no impact on functionality, but does make
debugging traces easier to read since the reset will appear
immediately after the causative error.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We currently use a heuristic to determine whether or not to request
cable detection in PXE_OPCODE_INITIALIZE, based on the need to work
around a known Emulex driver bug (see commit c0b61ba "[efi] Work
around bugs in Emulex NII driver") and the need to accommodate links
that are legitimately slow to come up (see commit 6324227 "[efi] Skip
cable detection at initialisation where possible").
This heuristic appears to fail with newer Emulex drivers. Attempt to
support all known drivers (past and present) by first attempting
initialisation with cable detection, then falling back to attempting
initialisation without cable detection.
Reported-by: Kwang Woo Lee <kwleeyh@gmail.com>
Tested-by: Kwang Woo Lee <kwleeyh@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
A failure in device registration (e.g. due to a device with malformed
descriptors) will currently result in the port being disabled as part
of the error path. This in turn causes the hardware to detect the
device as newly connected, leading to an endless loop of failed device
registrations.
Fix by leaving the port enabled in the case of a registration failure.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When connected to a USB3 port, the AX88179 seems to have an
approximately 50% chance of producing a USB transaction error on each
of its three endpoints after being closed and reopened. The root
cause is unclear, but rewriting the USB device configuration value
seems to clear whatever internal error state has accumulated.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Experimentation shows that the existing 20ms delay is insufficient,
and often results in device detection being deferred until after iPXE
has completed startup.
Fix by increasing the delay to 100ms.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The driver-private data for root hubs is already set immediately after
allocating the USB bus. There seems to be no reason to set it again
when opening the root hub.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The "disabled" port states for USB2 and USB3 are not directly
equivalent. In particular, a disabled USB3 port will not detect new
device connections. The result is that a USB3 device disconnected
from and reconnected to an xHCI root hub port will end up reconnecting
as a USB2 device.
Fix by setting the link state to RxDetect after disabling the port, as
is already done during initialisation.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The USB3 specification removes PORT_ENABLE from the list of features
that may be cleared via a CLEAR_FEATURE request. Experimentation
shows that omitting the attempt to clear PORT_ENABLE seems to result
in the correct hotplug behaviour.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Resetting the host endpoint may immediately restart any pending
transfers for that endpoint. If the device endpoint halt has not yet
been cleared, then this will probably result in a second failed
transfer.
This second failure may be detected within usb_endpoint_reset() while
waiting for usb_clear_feature() to complete. The endpoint will
subsequently be removed from the list of halted endpoints, causing the
second failure to be effectively ignored and leaving the host endpoint
in a permanently halted state.
Fix by deferring the host endpoint reset until after the device
endpoint is ready to accept new transfers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The ASIX USB NICs are capable of autodetecting the Ethernet link speed
and reporting it via PLSR but will not automatically update the
relevant GM and PS bits in MSR. The result is that a non-gigabit link
will fail to send or receive any packets.
The interrupt endpoint used to report link state includes the values
of the PHY BMSR and LPA registers. These are not sufficient to
differentiate between 100Mbps and 1000Mbps, since the LPA_NPAGE bit
does not necessarily indicate that the link partner is advertising
1000Mbps.
Extend axge_check_link() to write the MSR value based on the link
speed read from PLSR, and simplify the interrupt endpoint handler to
merely trigger a call to axge_check_link().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
GCC 10 emits warnings for implicit conversions of enumerated types.
The flexboot_nodnic code defines nodnic_queue_pair_type with values
identical to those of ib_queue_pair_type, and implicitly casts between
them. Add an explicit cast to fix the warning.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
GCC 10 produces a spurious warning about an out-of-bounds array access
for the unsized raw dword array in union intelvf_msg.
Avoid the warning by embedding the zero-length array within a struct.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some devices (observed with a Getac RX10 tablet and docking station
containing an embedded AX88179 USB NIC) seem to be capable of
detecting link state only during the call to Initialize(), and will
occasionally erroneously report that the link is down for the first
few such calls.
Work around these devices by retrying the Initialize() call multiple
times, terminating early if a link is detected. The eventual absence
of a link is treated as a non-fatal error, since it is entirely
possible that the link really is down.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
According to UEFI specification 2.8 p 24.1 we must set the
EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit in the "Disable" mask, when
"ResetMCastFilter" is TRUE.
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
Split-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Currently, if the SNP driver for whatever reason fails to enable
receive filters for multicast frames, it falls back to enabling just
unicast and broadcast filters. This breaks some IPv6 functionality as
the network card does not respond to neighbour solicitation requests.
Some cards refuse to enable EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST, but
do support enabling EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST,
so try it before falling back to just unicast+broadcast.
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
Split-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
On devices with no EEPROM or OTP, the MAC_CR register defaults to not
using automatic link speed detection, with the result that no packets
are successfully sent or received.
Fix by always enabling automatic speed and duplex detection, since
iPXE provides no mechanism for manual configuration of either link
speed or duplex.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
On at least some platforms (observed with a Raspberry Pi), any attempt
to perform USB transfers via EFI_USB_IO_PROTOCOL during EFI shutdown
will lock up the system. This is quite probably due to the already
documented failure of all EFI timers when ExitBootServices() is
called: see e.g. commit 5cf5ffea2 "[efi] Work around temporal anomaly
encountered during ExitBootServices()".
Work around this problem by refusing to poll endpoints if shutdown is
in progress, and by immediately failing any attempts to enqueue new
transfers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The USB core reuses the I/O buffer space occupied by the USB setup
packet to hold the completion status for message transfers, assuming
that the message() method will always strip the setup packet before
returning. This assumption is correct for all of the hardware
controller drivers (XHCI, EHCI, and UHCI), since these drivers are
able to enqueue the transfer as a separate action from waiting for the
transfer to complete.
The EFI_USB_IO_PROTOCOL does not allow us to separate actions in this
way: there is only a single blocking method that both enqueues and
waits for completion. Our usbio driver therefore currently defers
stripping the setup packet until the control endpoint is polled.
This causes a bug if a message transfer is enqueued but never polled
and is subsequently cancelled, since the cancellation will be reported
with the I/O buffer still containing the setup packet. This breaks
the assumption that the setup packet has been stripped, and triggers
an assertion failure in usb_control_complete().
Fix by always stripping the setup packet in usbio_endpoint_message(),
and adjusting usbio_control_poll() to match.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The physical function defaults to operating in "PXE mode" after a
power-on reset. In this mode, receive descriptors are fetched and
written back as single descriptors. In normal (non-PXE mode)
operation, receive descriptors are fetched and written back only as
complete cachelines unless an interrupt is raised.
There is no way to return to PXE mode from non-PXE mode, and there is
no way for the virtual function driver to operate in PXE mode.
Choose to operate in non-PXE mode. This requires us to trick the
hardware into believing that it is raising an interrupt, so that it
will not defer writing back receive descriptors until a complete
cacheline (i.e. four packets) have been consumed. We do so by
configuring the hardware to use MSI-X with a dummy target location in
place of the usual APIC register.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The virtual function driver will use the same transmit and receive
descriptor ring structures, but will not itself construct and program
the ring context. Split out ring creation and destruction from the
programming of the ring context, to allow code to be shared between
physical and virtual function drivers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The virtual function transmit and receive ring tail register offsets
do not match those of the physical function. Allow the tail register
offsets to be specified separately.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The physical function driver does not allow the virtual function to
request the use of 16-byte receive descriptors. Switch to using
32-byte receive descriptors.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide a weak stub function for handling the "send to VF" event used
for communications between the physical and virtual function drivers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The "send to PF" and "send to VF" admin queue descriptors (ab)use the
cookie field to hold the extended opcode and return code values.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
A virtual function reset is triggered via an admin queue command and
will reset the admin queue configuration registers. Allow the admin
queues to be reinitialised after such a reset, without requiring the
overhead (and potential failure paths) of freeing and reallocating the
queues.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We currently use a single data buffer shared between all admin queue
descriptors. This works for the physical function driver since we
have at most one command in progress and only a single event (which
does not use a data buffer).
The communication path between the physical and virtual function
drivers uses the event data buffer, and there is no way to prevent a
solicited event (i.e. a response to a request) from being overwritten
by an unsolicited event (e.g. a link status change).
Provide individual data buffers for each admin event queue descriptor
(and for each admin command queue descriptor, for the sake of
consistency).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The register map for the virtual functions appears to have been
constructed using a random number generator.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The physical function driver does not allow the virtual function to
request that VLAN tags are left unstripped. Extract and use the VLAN
tag from the receive descriptor if present.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The Hermon driver uses vlan_find() to identify the appropriate VLAN
device for packets that are received with the VLAN tag already
stripped out by the hardware. Generalise this capability and expose
it for use by other network card drivers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The Intel 40 Gigabit Ethernet virtual functions support only MSI-X
interrupts, and will write back completed interrupt descriptors only
when the device attempts to raise an interrupt (or when a complete
cacheline of receive descriptors has been completed).
We cannot actually use MSI-X interrupts within iPXE, since we never
have ownership of the APIC. However, an MSI-X interrupt is
fundamentally just a DMA write of a single dword to an arbitrary
address. We can therefore configure the device to "raise" an
interrupt by writing a meaningless value to an otherwise unused memory
location: this is sufficient to trigger the receive descriptor
writeback logic.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The first adapters in this family are X2522-10, X2522-25, X2541 and
X2542.
These no longer use PCI BAR 0 for I/O, but use that for memory. In
other words, BAR 2 on SFN8xxx adapters now becomes BAR 0.
Signed-off-by: Michael Brown <mcb30@ipxe.org>