Some hubs (e.g. the Avocent Corp. Virtual Hub on a Lenovo x3550
Integrated Management Module) have been observed to require more than
the standard 200ms for ports to stabilise, with the result that
devices appear to disconnect and immediately reconnect during the
initial bus enumeration.
Work around this problem by allowing specific hubs an extra 500ms of
settling time.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Record the speed of a USB device based on the port's speed at the time
that the device was enabled. This allows us to remember the device's
speed even after the device has been disconnected (and so the port's
current speed has changed).
In particular, this allows us to correctly identify the transaction
translator for a low-speed or full-speed device after the device has
been disconnected.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The usb_message() and usb_stream() functions currently check for
port->speed==USB_SPEED_NONE to determine whether or not a device has
been unplugged. This test will give a false negative result if a new
device has been plugged in before the hotplug mechanism has finished
handling the removal of the old device.
Fix by checking instead the port->disconnected flag, which is now
cleared only after completing the removal of the old device.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Tested using QEMU and usbredir to expose the LAN9512 chip present on a
Raspberry Pi.
There is a known issue with the LAN9512: an extra two bytes are
appended to every transmitted packet. These two bytes comprise:
{ 0x00, 0x08 } if packet length == 0 (mod 8)
{ CRC[0], 0x00 } if packet length == 7 (mod 8)
{ CRC[0], CRC[1] } otherwise
The extra bytes are appended whether the Ethernet CRC is generated
manually or added automatically by the hardware. The issue occurs
with the Linux kernel driver as well as the iPXE driver. It appears
to be an undocumented hardware errata.
TCP/IP traffic is not affected, since the IP header length field
causes the extraneous bytes to be discarded by the receiver. However,
protocols that rely on the length of the Ethernet frame (such as FCoE
or iPXE's "lotest" protocol) will be unusable on this hardware.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
On some models (notably ICH), the PHY reset mechanism appears to be
broken. In particular, the PHY_CTRL register will be correctly loaded
from NVM but the values will not be propagated to the "OEM bits" PHY
register. This typically has the effect of dropping the link speed to
10Mbps.
Since the original version of this driver in commit 945e428 ("[intel]
Replace driver for Intel Gigabit NICs"), we have always worked around
this problem by skipping the PHY reset if the link is already up.
Enhance this workaround by explicitly checking for known-broken PCI
IDs.
Reported-by: Robin Smidsrød <robin@smidsrod.no>
Tested-by: Robin Smidsrød <robin@smidsrod.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Make the class ID a property of the USB driver (rather than a property
of the USB device ID), and allow USB drivers to specify a wildcard ID
for any of the three component IDs (class, subclass, or protocol).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Generate a score for each possible USB device configuration based on
the available driver support, and select the configuration with the
highest score. This will allow us to prefer ECM over RNDIS (for
devices which support both) and will allow us to meaningfully select a
configuration even when we have drivers available for all functions
(e.g. when exposing unused functions via EFI_USB_IO_PROTOCOL).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The decision on whether or not a zero-length packet needs to be
transmitted is independent of the host controller and belongs in the
USB core.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow iPXE to coexist with other USB device drivers, by attaching to
the EFI_USB_IO_PROTOCOL instances provided by the UEFI platform
firmware.
The EFI_USB_IO_PROTOCOL is an unsurprisingly badly designed
abstraction of a USB device. The poor design choices intrinsic in the
UEFI specification prevent efficient operation as a network device,
with the result that devices operated using the EFI_USB_IO_PROTOCOL
operate approximately two orders of magnitude slower than devices
operated using our native EHCI or xHCI host controller drivers.
Since the performance is so abysmally slow, and since the underlying
problems are due to fundamental architectural mistakes in the UEFI
specification, support for the EFI_USB_IO_PROTOCOL host controller
driver is left as disabled by default. Users are advised to use the
native iPXE host controller drivers instead.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The raw EFI_HANDLE value is almost never useful to know, and simply
adds noise to the already verbose debug messages. Improve the
legibility of debug messages by using only the name generated by
efi_handle_name().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The Infiniband link status change callback ipoib_link_state_changed()
may be called while the IPoIB device is closed, in which case there
will not be an IPoIB queue pair to be joined to the IPv4 broadcast
group. This leads to NULL pointer dereferences in ib_mcast_attach()
and ib_mcast_detach().
Fix by not attempting to join (or leave) the broadcast group unless we
actually have an IPoIB queue pair.
Signed-off-by: Wissam Shoukair <wissams@mellanox.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Multicast MAC addresses will never have REMAC cache entries, and the
corresponding multicast IPoIB MAC address cannot be obtained simply by
issuing an ARP request.
For the trivial volume of multicast packets that we expect to send in
any realistic scenario, the simplest solution is to send them as
broadcasts instead.
Reported-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The only way to map an eIPoIB MAC address (REMAC) to an IPoIB MAC
address is to intercept an incoming ARP request or reply.
If we do not have an REMAC cache entry for a particular destination
MAC address, then we cannot transmit the packet. This can arise in at
least two situations:
- An external program (e.g. a PXE NBP using the UNDI API) may attempt
to transmit to a destination MAC address that has been obtained by
some method other than ARP.
- Memory pressure may have caused REMAC cache entries to be
discarded. This is fairly likely on a busy network, since REMAC
cache entries are created for all received (broadcast) ARP
requests. (We can't sensibly avoid creating these cache entries,
since they are required in order to send an ARP reply, and when we
are being used via the UNDI API we may have no knowledge of which
IP addresses are "ours".)
Attempt to ameliorate the situation by generating a semi-spurious ARP
request whenever we find a missing REMAC cache entry. This will
hopefully trigger an ARP reply, which would then provide us with the
information required to populate the REMAC cache.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
As with the neighbour cache, discarding an REMAC cache entry is
potentially very disruptive.
Originally-fixed-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some Intel Skylake platforms (observed on a prototype Lenovo ThinkPad)
report the list of available USB3 protocol speed ID values as {1,2,3}
but then report a port's speed using ID value 4.
The value 4 happens to be the default value for SuperSpeed (when no
protocol speed ID value list is explicitly defined), and the hardware
seems to function correctly if we simply ignore its protocol speed ID
table and assume that it uses the default values.
Fix by adding a "broken PSI values" quirk for this controller.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
gcc 4.8.2 fails to report this erroneous comparison unless assertions
are enabled.
Reported-by: Mary-Ann Johnson <MaryAnn.Johnson@displaylink.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The xHCI slot ID is one-based, not zero-based. Fix the length of the
xhci->slot[] array to account for this, and add assertions to check
that the hardware returns a valid slot ID in response to the Enable
Slot command.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When jumbo frames are enabled, the Linux ixgbe physical function
driver will disable the virtual function's receive datapath by
default, and will enable it only if the virtual function negotiates
API version 1.1 (or higher) and explicitly selects an MTU.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Virtual functions use a mailbox to communicate with the physical
function driver: this covers functionality such as obtaining the MAC
address.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Intel virtual function NICs almost work with the use of "legacy"
transmit and receive descriptors (which are backwards compatible right
back to the original Intel Gigabit NICs).
Unfortunately the "TX switching" feature (which allows for VM<->VM
traffic to be looped back within the NIC itself) does not work when a
legacy TX descriptor is used: the packet is instead sent onto the
wire.
Fix by allowing for the use of an "advanced" TX descriptor (containing
exactly the same information as is found in the "legacy" descriptor).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The recorded disconnections (in port->disconnected) will currently be
left uncleared if usb_attached() returns an error (e.g. because there
are no drivers for a particular USB device). This is incorrect
behaviour: the disconnection has been handled and the record should be
cleared until the next physical disconnection is detected (via the CSC
bit).
The problem is masked for EHCI, UHCI, and USB hubs, since these will
report a changed port (via usb_port_changed()) only when the
underlying hardware reports a change. xHCI will call
usb_port_changed() in response to any port status event, at which
point the stale value of port->disconnected will be erroneously acted
upon. This can lead to an endless loop of repeatedly enumerating the
same device when a driverless device is attached to an xHCI root hub
port.
Fix by unconditionally clearing port->disconnected in usb_hotplugged().
Reported-by: Robin Smidsrød <robin@smidsrod.no>
Tested-by: Robin Smidsrød <robin@smidsrod.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The action of registering a new hub can itself happen in only two
ways: either a new USB hub has been created (in which case we are
already inside a call to usb_hotplug()), or a new root hub has been
created.
In the former case, we do not need to issue a further call to
usb_hotplug(), since the hub's ports will all be marked as changed and
so will be handled after the return from register_usb_hub() anyway.
Calling usb_hotplug() within register_usb_hub() leads to a confusing
order of events, such as:
- root hub port 1 detects a change
- root hub port 2 detects a change
- usb_hotplug() is called
- root hub port 1 finds a USB hub
- usb_hotplug() is called
- this inner call to usb_hotplug() handles root hub port 2
Fix by calling usb_hotplug() only from usb_step() and from
register_usb_bus(). This avoids recursive calls to usb_hotplug() and
ensures that devices are enumerated in the order of detection.
Tested-by: Robin Smidsrød <robin@smidsrod.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When USB network card drivers are used, the BIOS' legacy USB
capability is necessarily disabled since there is no way to share the
host controller between the BIOS and iPXE. This currently results in
USB keyboards becoming non-functional in USB-enabled builds of iPXE.
Fix by adding basic support for USB keyboards, enabled by default in
iPXE builds which include USB support.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When an EHCI hotplug action results in the controller disowning the
port, it will result in a hotplug action on the corresponding UHCI or
OHCI controller. Allow such hotplug actions to be carried out as part
of the same call to usb_step() or usb_register_bus(), by maintaining a
single central list of changed ports.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The USB core will currently fail to detect disconnections if a new
device has attached by the time the port is examined in
usb_hotplug().
Fix by recording the fact that a disconnection has taken place
whenever the "connection status changed" (CSC) bit is observed to be
set. (Whether the change represents a disconnection or a
reconnection, it indicates that the port has experienced some time of
being disconnected.)
Note that the time at which a disconnection can be detected varies by
hub type. In particular: root hubs can observe the CSC bit when
polling, and so will record the disconnection before calling
usb_port_changed(), but USB hubs read the port status (and hence the
CSC bit) only during the call to hub_speed(), long after the call to
usb_port_changed().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Rename PCI_CLASS() (which constructs a struct pci_class_id) to
PCI_CLASS_ID(), and provide PCI_CLASS() as a macro which constructs
the 24-bit scalar value of a PCI class code.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The USB API currently assumes that host controllers will have
immediate data buffer space available in which to store the setup
packet. This is true for xHCI, partially true for EHCI (which happens
to have 12 bytes of padding in each transfer descriptor due to
alignment requirements), and not true at all for UHCI.
Include the setup packet within the I/O buffer passed to the host
controller's message() method, thereby eliminating the requirement for
host controllers to provide immediate data buffers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The current API for Base16 (and Base64) encoding requires the caller
to always provide sufficient buffer space. This prevents the use of
the generic encoding/decoding functionality in some situations, such
as in formatting the hex setting types.
Implement a generic hex_encode() (based on the existing
format_hex_setting()), implement base16_encode() and base16_decode()
in terms of the more generic hex_encode() and hex_decode(), and update
all callers to provide the additional buffer length parameter.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This changed in Linux kernel the same way in commit 7067e701
("ath9k_hw: remove confusing logic inversion in an ANI variable") by
Felix Fietkau.
Additionally this fixes "error: logical not is only applied to the
left hand side of comparison" with GCC 5.1.0.
Signed-off-by: Christian Hesse <mail@eworm.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
I218-LM (rev 3) is found in Lenovo Thinkpad X250. The remaining
device IDs are from linux/drivers/net/ethernet/intel/e1000e/hw.h
Signed-off-by: Christian Hesse <mail@eworm.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
On some RTL8169 onboard NICs (observed with a Lenovo ThinkPad 11e),
the EEPROM is not merely not present: any attempt to read from the
non-existent EEPROM will crash and reboot the system.
The equivalent code to read from the EEPROM was removed from the Linux
r8169 driver in 2009 with a comment suggesting that it was similarly
found to be unreliable on some systems.
Fix by accessing the EEPROM only on RTL8139 NICs, and assuming that
the MAC address will always be correctly preset on RTL8169 NICs.
Reported-by: Evan Prohaska <eprohaska@edkey.org>
Tested-by: Evan Prohaska <eprohaska@edkey.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The emulated Intel 82545em in some versions of VMware (observed with
ESXi v5.1) seems to sometimes fail to set the RXT0 bit in the
interrupt cause register (ICR), causing iPXE to stop receiving
packets. Work around this problem (for the 82545em only) by always
polling the receive queue regardless of the state of the ICR.
Reported-by: Slava Bendersky <volga629@networklab.ca>
Tested-by: Slava Bendersky <volga629@networklab.ca>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
At least one NII implementation (in a Microsoft Surface tablet) seems
to fail to report the absence (sic) of TX completions properly. Work
around this by checking for TX completions only when we expect to see
one.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some NII implementations will fail the GET_STATUS operation if we
request the media status. Fix by doing so only if GET_INIT_INFO
reported that media status is supported.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
In theory USB3 ports do not require a reset to enable the port.
Experimentation shows that this is sometimes required, particularly
when rerouting ports from EHCI to xHCI and switching speeds.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
xHCI provides a somewhat convoluted mechanism for specifying details
of a transaction translator. Hubs must be marked as such in the
device slot context. The only opportunity to do so is as part of a
Configure Endpoint command, which can be executed only when opening
the hub's interrupt endpoint.
We add a mechanism for host controllers to intercept the opening of
hub devices, providing xHCI with an opportunity to update the internal
device slot structure for the corresponding USB device to indicate
that the device is a hub. We then include the hub-specific details in
the input context whenever any Configure Endpoint command is issued.
When a device is opened, we record the device slot and port for its
transaction translator (if any), and supply these as part of the
Address Device command.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Support low-speed and full-speed devices attached to a USB2 hub. Such
devices use a transaction translator (TT) within the USB2 hub, which
asynchronously initiates transactions on the lower-speed bus and
returns the result via a split completion on the high-speed bus.
We make the simplifying assumption that there will never be more than
sixteen active interrupt endpoints behind a single transaction
translator; this assumption allows us to schedule all periodic start
splits in microframe 0 and all periodic split completions in
microframes 2 and 3. (We do not handle isochronous endpoints.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The current endpoint reset logic defers the reset until the caller
attempts to enqueue a new transfer to that endpoint. This is
insufficient when dealing with endpoints behind a transaction
translator, since the transaction translator is a resource shared
between multiple endpoints.
We cannot reset the endpoint as part of the completion handling, since
that would introduce recursive calls to usb_poll(). Instead, we
add the endpoint to a list of halted endpoints, and perform the reset
on the next call to usb_step().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The endpoint may already have enqueued TRBs at the time that
xhci_endpoint_reset() is called. Ring the doorbell to resume
processing these TRBs immediately, rather than waiting until the next
call to xhci_endpoint_message() or xhci_endpoint_stream().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Several of the USB timeouts were chosen on the principle of "pick an
arbitrary but ridiculously large value, just to be safe". It turns
out that some of the timeouts permitted by the USB specification are
even larger: for example, control transactions are allowed to take up
to five seconds to complete.
Fix up these USB timeout values to match those found in the USB2
specification.
Debugged-by: Robin Smidsrød <robin@smidsrod.no>
Tested-by: Robin Smidsrød <robin@smidsrod.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
xHCI (and EHCI) nominally provide a mechanism for releasing ownership
of the host controller back to the BIOS, which can then potentially
restore legacy USB keyboard functionality.
This is a rarely used code path, since most operating systems claim
ownership and never attempt to later return to the BIOS. On some
systems (observed with a Lenovo X1 Carbon), this code path leads to
obscure and interesting bugs: if the xHCI and EHCI controllers are
both claimed and later released back to the BIOS, then a subsequent
call to INT 16,0305 to set the keyboard repeat rate to a non-default
value will lock the system.
Obscure though this sequence of operations may sound, it is exactly
what happens when using iPXE to boot a Linux kernel via a USB network
card. There is old and probably unwanted code in Linux's
arch/x86/boot/main.c which sets the keyboard repeat rate (with the
accompanying comment "Set keyboard repeat rate (why?)"). When booting
Linux via a USB network card on a Lenovo X1 Carbon, the system
therefore locks up immediately after jumping to the kernel's entry
point.
Work around this problem by preventing the release of ownership back
to the BIOS if it is known that we are shutting down to boot an OS.
This should allow legacy USB keyboard functionality to be restored if
the user chooses to exit iPXE, while avoiding the rarely used code
paths (and corresponding BIOS bugs) if the user chooses instead to
boot an OS.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
If the BIOS fails to gracefully release ownership of the xHCI
controller, we can forcibly claim it by disabling all SMIs via the
USB legacy support control/status register.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
RX FIFO overflow is almost inevitable since the (usable) USB2 bus
bandwidth is approximately one quarter of the Ethernet bandwidth.
Avoid flooding the console with RX FIFO overflow messages in a
standard debug build.
With TCP SACK implemented, the RX FIFO overflow no longer causes a
catastrophic drop in throughput. Experimentation shows that HTTP
downloads now progress at a fairly smooth 250Mbps, which is around the
maximum speed attainable for a USB2 NIC.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This driver is functional but any downloads via a TCP-based protocol
tend to perform poorly. The 1Gbps Ethernet line rate is substantially
higher than the 480Mbps (in practice around 280Mbps) provided by USB2,
and the device has only 32kB of internal buffer memory. Our 256kB TCP
receive window therefore rapidly overflows the RX FIFO, leading to
multiple dropped packets (usually within the same TCP window) and
hence a low overall throughput.
Reducing the TCP window size so that the RX FIFO does not overflow
greatly increases throughput, but is not a general-purpose solution.
Further investigation is required to determine how other OSes
(e.g. Linux) cope with this scenario. It is possible that
implementing TCP SACK would provide some benefit.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Most devices expose at least the link up/down status via a bit in a
MAC register, since the MAC generally already needs to know whether or
not the link is up. Some devices (e.g. the SMSC75xx USB NIC) expose
this information to software only via the MII registers.
Provide a generic mii_check_link() implementation to check the BMSR
and report the link status via netdev_link_{up,down}().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE already sends RX notifications to the backend when needed, but
does not set the "feature-rx-notify" flag. As of XenServer 6.5, this
flag is mandatory and omitting it will cause the backend to fail.
Fix by setting the "feature-rx-notify" flag, to inform the backend
that we will send notifications.
Reported-by: Shalom Bhooshi <shalom.bhooshi@citrix.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Restore the original values of XUSB2PR and USB3PSSEN, in case we are
booting an OS with no support for xHCI.
Suggested-by: Dan Ellis <Dan.Ellis@displaylink.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Intel PCH controllers default to routing USB2 ports to EHCI rather
than xHCI, and default to disabling SuperSpeed connections.
Manipulate the PCI configuration space registers as necessary to
reroute ports and enable SuperSpeed.
Originally-fixed-by: Dan Ellis <Dan.Ellis@displaylink.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Relicense files with kind permission from
Stefan Hajnoczi <stefanha@redhat.com>
alongside the contributors who have already granted such relicensing
permission.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
At some point in the past few years, binutils became more aggressive
at removing unused symbols. To function as a symbol requirement, a
relocation record must now be in a section marked with @progbits and
must not be in a section which gets discarded during the link (either
via --gc-sections or via /DISCARD/).
Update REQUIRE_SYMBOL() to generate relocation records meeting these
criteria. To minimise the impact upon the final binary size, we use
existing symbols (specified via the REQUIRING_SYMBOL() macro) as the
relocation targets where possible. We use R_386_NONE or R_X86_64_NONE
relocation types to prevent any actual unwanted relocation taking
place. Where no suitable symbol exists for REQUIRING_SYMBOL() (such
as in config.c), the macro PROVIDE_REQUIRING_SYMBOL() can be used to
generate a one-byte-long symbol to act as the relocation target.
If there are versions of binutils for which this approach fails, then
the fallback will probably involve killing off REQUEST_SYMBOL(),
redefining REQUIRE_SYMBOL() to use the current definition of
REQUEST_SYMBOL(), and postprocessing the linked ELF file with
something along the lines of "nm -u | wc -l" to check that there are
no undefined symbols remaining.
Signed-off-by: Michael Brown <mcb30@ipxe.org>