Only port state change events are currently mapped to our event queue,
since those are the only events we are prepared to handle. This
ignores a potentially useful source of diagnostic information in the
case of unexpected failures.
Fix by mapping all events to the event queue; a build with debugging
enabled will therefore at least dump the raw content of the unexpected
events.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Only port state change events are currently mapped to our event queue,
since those are the only events we are prepared to handle. This
ignores a potentially useful source of diagnostic information in the
case of unexpected failures.
Fix by mapping all events to the event queue; a build with debugging
enabled will therefore at least dump the raw content of the unexpected
events.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[infiniband] Add node GUID as distinct from the first port GUID
iPXE currently uses the first port's port GUID as the node GUID,
rather than using the (possibly distinct) real node GUID. This can
confuse opensm during the handover to a loaded OS: it thinks the port
already belongs to a different node and so discards our port
information with a warning message about duplicate ports. Everything
is picked up correctly on the second subnet sweep, after opensm has
established that the "old" node no longer exists, but this can delay
link-up unnecessarily by several seconds.
Fix by using the real node GUID.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
No event is generated upon reaching INIT, so we must poll separately
for link state changes while we remain DOWN.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
No event is generated upon reaching INIT, so we must poll separately
for link state changes while we remain DOWN.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[infiniband] Always call ib_link_state_changed() in ib_smc_update()
ib_smc_update() potentially updates the Infiniband port state, and so
should almost always be followed by a call to ib_link_state_changed().
The one exception is the call made to ib_smc_update() before the
device is registered.
Fix by removing explicit calls to ib_link_state_changed() from drivers
using ib_smc_update(), including a call to ib_link_state_changed()
within ib_smc_update(), and creating a separate ib_smc_init() for use
prior to device registration.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[scsi] Include sense key within error number reported to user
The sense key gives a first idea of what the problem might be, and so
is potentially useful in diagnosing problems in a non-debug build.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[fcoe] Disambiguate the various error cases and add a CRC failure message
It seems as though several drivers neglect to strip the Ethernet CRC,
which will cause the FCoE footer to be misplaced and result
(coincidentally) in an "invalid CRC" error from FCoE.
Add a human-visible message indicating this, to aid in diagnosis.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[netdevice] Report network-layer errors via network device statistics
Errors generated by the network layer in response to received packets
are liable to be lost, since nothing systematically records these
errors and often the packets do not propagate far enough through the
stack to impact upon user-visible processes.
Improve this situation by recording network-layer errors in the
network device statistics.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The Fibre Channel Protocol provides a mechanism for transporting SCSI
commands via a Fibre Channel fabric.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add support for Fibre Channel ports, peers, and upper-layer protocols,
and for Fibre Channel extended link services.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[block] Replace gPXE block-device API with an iPXE asynchronous interface
The block device interface used in gPXE predates the invention of even
the old gPXE data-transfer interface, let alone the current iPXE
generic asynchronous interface mechanism. Bring this old code up to
date, with the following benefits:
o Block device commands can be cancelled by the requestor. The INT 13
layer uses this to provide a global timeout on all INT 13 calls,
with the result that an unexpected passive failure mode (such as
an iSCSI target ACKing the request but never sending a response)
will lead to a timeout that gets reported back to the INT 13 user,
rather than simply freezing the system.
o INT 13,00 (reset drive) is now able to reset the underlying block
device. INT 13 users, such as DOS, that use INT 13,00 as a method
for error recovery now have a chance of recovering.
o All block device commands are tagged, with a numerical tag that
will show up in debugging output and in packet captures; this will
allow easier interpretation of bug reports that include both
sources of information.
o The extremely ugly hacks used to generate the boot firmware tables
have been eradicated and replaced with a generic acpi_describe()
method (exploiting the ability of iPXE interfaces to pass through
methods to an underlying interface). The ACPI tables are now
built in a shared data block within .bss16, rather than each
requiring dedicated space in .data16.
o The architecture-independent concept of a SAN device has been
exposed to the iPXE core through the sanboot API, which provides
calls to hook, unhook, boot, and describe SAN devices. This
allows for much more flexible usage patterns (such as hooking an
empty SAN device and then running an OS installer via TFTP).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[hermon] Use correct alignment for doorbell records
Doorbell records are currently embedded within the completion queue
and receive work queue strucures, which are allocated using zalloc()
and so have an alignment guarantee of only sizeof(void*), i.e. four
bytes. This is sufficient for the receive work queue, but not for the
completion queue, which requires an alignment guarantee of eight
bytes.
Though not guaranteed, it so happens that zalloc() will always return
a pointer that is exactly four bytes above a sixteen-byte boundary.
The completion queue doorbell record is therefore always misaligned,
and the value passed to the hardware via SW2HW_CQ is actually always
pointing to the page_offset value within the MTT descriptor (which
directly precedes the inline doorbell record). Provided that the page
offset is greater than 0x100, this looks to the hardware like an
update_ci value of greater than 0x010000 (taking into account
endianness differences), and so the hardware will happily deliver more
than 0x010000 completions before stopping. Hence this problem is
rarely observable.
Fix by allocating the doorbell records separately and using the
correct alignment constraints.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[hermon] Set event queue number for completion queues
Give completion queues a chance to deliver exception events by
programming in the number of our event queue (currently used only for
port state changes).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Improve the utility of debugging messages by including the relevant
port number, queue number (QPN, CQN, EQN), work queue entry (WQE)
number, and physical addresses wherever applicable.
Add hermon_dump_cqctx() for dumping a completion queue context, and
hermon_fill_nop_send_wqe() for inserting NOPs into send work queues.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[build] Remove unnecessary constraint on DBG_ENABLE()/DBG_DISABLE()
DBG_ENABLE() and DBG_DISABLE() are currently constrained to enabling
and disabling only debug levels that are compiled in for the current
object. For example, a DBG_ENABLE(DBGLVL_EXTRA) in foo.c will not be
able to affect output from other objects at DBGLVL_EXTRA unless foo.c
is itself compiled with DBGLVL_EXTRA enabled.
Partially fix by removing this unnecessary constraint. (Note that it
is still necessary for at least one debug level to be compiled in for
the object invoking DBG_ENABLE()/DBG_DISABLE().)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[rtl8139] Check for oversized packets when transmitting
An attempt to transmit a packet of 8192 bytes or larger will collide
with the status bits in the TX descriptor. This gives the appearance
of the network card's transmit data path having just suddenly stopped
responding; iPXE is waiting for the card to report a TX completion
but, because of the status bit collision, the card thinks that the
descriptor has not yet been written.
Fix by explicitly checking for oversized packets in rtl_transmit().
Discovered during Fibre Channel over Ethernet testing, and debugged by
using gdb to examine the state of the emulated rtl8139 card in qemu.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
xfer_window_changed() can be used to notify peers that an interface is
now ready to accept data. This can potentially be used to eliminate
the need for wasteful processes that simply poll xfer_window() until
the window becomes non-zero.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[infiniband] Add the concept of an Infiniband upper-layer driver
Replace the explicit calls from the Infiniband core to the IPoIB layer
with the general concept of an Infiniband upper-layer driver
(analogous to a PCI driver) which can create arbitrary devices on top
of Infiniband devices.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[netdevice] Add the concept of a network upper-layer driver
Add the concept of a network upper-layer driver, which can create
arbitrary devices on top of network devices.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The rtl8139 driver includes the Ethernet CRC within the received
packet. All current protocols ignore trailing garbage, but FCoE
requires the frame length to be correct (since the FCoE footer
position is calculated from the end of the packet), so fix the driver
to strip out the CRC.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[retry] Hold reference while timer is running and during expiry callback
Guarantee that a retry timer cannot go out of scope while the timer is
running, and provide a guarantee to the expiry callback that the timer
will remain in scope during the entire callback (similar to the
guarantee provided to interface methods).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[xfer] Generalise metadata "whence" field to "flags" field
iPXE has never supported SEEK_END; the usage of "whence" offers only
the options of SEEK_SET and SEEK_CUR and so is effectively a boolean
flag. Further flags will be required to support additional metadata
required by the Fibre Channel network model, so repurpose the "whence"
field as a generic "flags" field.
xfer_seek() has always been used with SEEK_SET, so remove the "whence"
field altogether from its argument list.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[build] Fix misaligned table entries when using gcc 4.5
Declarations without the accompanying __table_entry cause misalignment
of the table entries when using gcc 4.5. Fix by adding the
appropriate __table_entry macro or (where possible) by removing
unnecessary forward declarations.
Signed-off-by: Piotr Jaroszyński <p.jaroszynski@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[compiler] Prevent empty weak function stubs from being removed
Even with the noinline specifier added by commit 1a260f8, gcc may skip
calls to non-inlinable functions that it knows have no side
effects. This caused the get_cached_dhcpack() call in start_dhcp(),
the weak stub of which has no code in its body, to be removed,
preventing cached DHCP from working.
Fix by adding a __keepme macro to compiler.h expanding to asm(""), as
recommended by gcc's info page, and using it in the weak stub for
get_cached_dhcpack().
Reported-by: Aaron Brooks <aaron@brooks1.net>
Tested-by: Aaron Brooks <aaron@brooks1.net>
Signed-off-by: Joshua Oreman <oremanj@rwcr.net>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add the tap driver that can be used like:
$ ./ipxe.linux --net tap,if=tap0,mac=00:0c:29:c5:39:a1
The if setting is mandatory.
Signed-off-by: Piotr Jaroszyński <p.jaroszynski@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Support qemu-like arguments for network setup:
--net driver_name[,setting=value]*
and global settings:
--settings setting=value[,setting=value]*
Signed-off-by: Piotr Jaroszyński <p.jaroszynski@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add the base to build linux drivers and the linux UI code on. UI
fills device requests, which are later walked over by the linux
root_driver and delegated to specific linux drivers.
Signed-off-by: Piotr Jaroszyński <p.jaroszynski@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
There exists an smbios userspace library so implementing this is
probably possible, but doesn't seem really important to have in
userspace. Hence provide a dummy implementation returning an error.
Signed-off-by: Piotr Jaroszyński <p.jaroszynski@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add user access API for linux.
On linux userspace virtual == user == phys addresses. Physical
addresses also being the same is wrong, but there is no general way of
converting userspace addresses to physical as what appears to be
contiguous in userspace is physically fragmented. Currently only the
DMA memory is special-cased, but its conversion to bus addresses is
done in phys_to_bus. This is known to break virtio as it is passing
phys addresses to the virtual device.
Signed-off-by: Piotr Jaroszyński <p.jaroszynski@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>