Remove spaces in 3rd PCI_ROM field.
Debugged-by: Marty Connor <mdc@etherboot.org>
Reported-by: Giandomenico De Tullio <ghisha@email.it>
Signed-off-by: Michael Brown <mcb30@etherboot.org>
The iBFT is Ethernet-centric in providing only six bytes for a MAC
address. This is most probably an indirect consequence of a similar
design flaw in the Windows NDIS stack. (The WinOF IPoIB stack
performs all sorts of contortions in order to pretend to the NDIS
layer that it is dealing with six-byte MAC addresses.)
There is no sensible way in which to extend the iBFT without breaking
compatibility with programs that expect to parse it. Add the notion
of an "Ethernet-compatible" MAC address to our link layer abstraction,
so that link layers can provide their own workarounds for this
limitation.
Recent gcc versions generate more warnings when compiling util/zbin.c
on a 64-bit system:
util/zbin.c: In function `read_file':
util/zbin.c:85: warning: format `%d' expects type `int', but
argument 3 has type `size_t'
util/zbin.c:91: warning: format `%d' expects type `int', but
argument 3 has type `size_t'
util/zbin.c: In function `read_zinfo_file':
util/zbin.c:119: warning: format `%d' expects type `int', but
argument 4 has type `size_t'
util/zbin.c: In function `alloc_output_file':
util/zbin.c:134: warning: format `%d' expects type `int', but
argument 3 has type `size_t'
util/zbin.c: In function `process_zinfo_add':
util/zbin.c:244: warning: format `%d' expects type `int', but
argument 3 has type `size_t'
util/zbin.c:266: warning: format `%d' expects type `int', but
argument 7 has type `size_t'
util/zbin.c:286: warning: format `%#x' expects type `unsigned int',
but argument 7 has type `size_t'
util/zbin.c: In function `write_output_file':
util/zbin.c:348: warning: format `%d' expects type `int', but
argument 3 has type `size_t'
This patch eliminates these warnings.
Signed-off-by: Marty Connor <mdc@etherboot.org>
gcc 3.3.3 gave the following error when compiling sis190.c
drivers/net/sis190.c: In function 'sis190_get_mac_addr_from_apc':
drivers/net/sis190.c:966: warning: 'isa_bridge' might be used
uninitialized in this function
make: *** [bin/sis190.o] Error 1
This patch allows error-free compilation.
Signed-off-by: Marty Connor <mdc@etherboot.org>
Recent gcc versions generate warnings when compiling util/zbin.c
( tested with gcc-4.3.3 ):
util/zbin.c: In function ‘process_zinfo_pack’:
util/zbin.c:200: warning: format ‘%#zx’ expects type ‘size_t’, but argument 6
has type ‘long unsigned int’
util/zbin.c: In function ‘process_zinfo_add’:
util/zbin.c:257: warning: format ‘%#lx’ expects type ‘long unsigned int’, but
argument 4 has type ‘int’
util/zbin.c:266: warning: format ‘%#lx’ expects type ‘long unsigned int’, but
argument 4 has type ‘int’
util/zbin.c:266: warning: format ‘%d’ expects type ‘int’, but argument 8 has
type ‘long unsigned int’
util/zbin.c:286: warning: format ‘%#lx’ expects type ‘long unsigned int’, but
argument 6 has type ‘int’
util/zbin.c:286: warning: format ‘%#lx’ expects type ‘long unsigned int’, but
argument 7 has type ‘size_t’
This patch eliminates these warnings.
Tested with gcc-4.3.3 on Ubuntu 9.04 and gcc-4.1.2 on Debian Etch.
Signed-off-by: Marty Connor <mdc@etherboot.org>
Some BIOSes set the PCI cacheline size to zero for the card; the ath5k
driver fixes it to a reasonable in PCI config space, but failed to
correct the internal value it had already read. This resulted in
divide-by-zero errors when cacheline-aligning various data structures.
Fix by setting the internal cachelsz to a sane value at the same time
as we write that value to PCI config space.
Signed-off-by: Marty Connor <mdc@etherboot.org>
This adds basic rfkill support for enabling the wireless card on certain
laptops, and changes miscellaneous other details that may help in obscure
cases.
Also change the error handling to not report CRC errors, which due to the
basic facts of wireless may happen even more frequently than valid packets.
Signed-off-by: Marty Connor <mdc@etherboot.org>
Add the 82576 to the e1000 driver.
- Examining the Linux 2.6.30-rc4 igb driver, which supports this card and;
- Information available in the Intel® 82576 Gigabit Ethernet
Controller Datasheet v2.1, which is available from Intel's web site.
I only have a dual-ported card with Copper PHY, so any code paths relating
to Fibre haven't been tested. Also, I have only tested using auto-negotiation
of speed and duplex, and no flow control. Other code paths relating to
those settings also have not been exercised.
Signed-off-by: Simon Horman <horms@verge.net.au>
Sponsored-by: Thomas Miletich <thomas.miletich@gmail.com>
Modified-by: Thomas Miletich <thomas.miletich@gmail.com>
Modified-by: Marty Connor <mdc@etherboot.org>
Signed-off-by: Marty Connor <mdc@etherboot.org>
Enable interrupts in sis900_irq(). Doing so allows some programs using
gPXE's UNDI interface to work properly, including Symantec Ghost.
Tested-by: Hubert Mercier <hubert.mercier@unilim.fr>
Signed-off-by: Marty Connor <mdc@etherboot.org>
The mtools version check does not handle GNU mtools 4.0.10. This commit
makes the pattern more general so it matches older mtools as well as the
newer "mtools (GNU mtools) 4.0.10" string.
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
Signed-off-by: Marty Connor <mdc@etherboot.org>
A jump instruction starts at the third byte of an option ROM image, and
it is required that the bytes in the whole image add up to zero. To
achieve this, a checksum byte is usually placed after the jump. The jump
can be either a short jump (2 bytes, EB xx) or a near jump (3 bytes,
E9 xx xx). gPXE's romprefix.S uses a near jump, but modrom.pl assumed
a short jump, and clobbered the high byte of the offset. This caused
modrom-modified gPXE ROM images to crash the system during POST.
Fix by making modrom.pl place the checksum at byte 6, like makerom.pl does.
Signed-off-by: Marty Connor <mdc@etherboot.org>
Debug builds for filenames with hyphens such as:
$ make bin/via-rhine.dsk DEBUG=via-rhine
fail with:
[BUILD] bin/via-rhine.dbg1.o
<command-line>: error: missing whitespace after the macro name
make: *** [bin/via-rhine.dbg1.o] Error 1
This is because "-" is not a legal character in C identifiers, and
gcc rejects "-Ddebug_via-rhine=1" as an argument.
Signed-off-by: Daniel Verkamp <daniel@drv.nu>
Signed-off-by: Joshua Oreman <oremanj@rwcr.net>
Signed-off-by: Marty Connor <mdc@etherboot.org>
Both methods disabled packet tx and rx just to have it enabled again
by calling a3c90x_reset().
Fixed by disabling tx and rx after the call to a3c90x_reset().
Tested by booting Ubuntu intrepid(8.10) directly from gPXE and pxelinux.
Tested on 3c905, 3c905B, 3c905C.
Signed-off-by: Marty Connor <mdc@etherboot.org>
Some systems will retry their boot sequence in the event of a boot
failure. On these systems, the second and subsequent boot attempts
will fail to initialise the Hermon HCA.
Fix by resetting the HCA during probe(). This incurs a one-second
cost, but there seems to be no viable alternative.
Originally-fixed-by: Itay Gazit <itaygazit@gmail.com>
Some devices can only be reset via a mechanism that also resets the
card's PCI core, thus necessitating a backup and restore of all or
part of the PCI configuration space across a reset.
802.11 multicast hashing is the same as standard Ethernet hashing, so
just expose and use eth_mc_hash().
Signed-off-by: Joshua Oreman <oremanj@rwcr.net>
The recent change to process_add() to detect duplicate process
additions relies on the fact that all processes will be initialized
using process_init_stopped() before being passed to that function.
The autoassociation process was not initialized in this fashion, so
process_add() erroneously detected it as a duplicate.
Fix by using process_init_stopped() to initialize the autoassociation
process instead of setting the step member directly.
Signed-off-by: Michael Brown <mcb30@etherboot.org>
For IPoIB, the chaddr field is too small (16 bytes) to contain the
20-byte IPoIB link-layer address. RFC4390 mandates that we should
pass an empty chaddr field and rely on the DHCP client identifier
instead. This has many problems, not least of which is that a client
identifier containing an IPoIB link-layer address is not very useful
from the point of view of creating DHCP reservations, since the QPN
component is assigned at runtime and may vary between boots.
Leave the DHCP client identifier as-is, to avoid breaking existing
setups as far as possible, but expose the real hardware address (the
port GUID) via the DHCP chaddr field, using the broadcast flag to
instruct the DHCP server not to use this chaddr value as a link-layer
address.
This makes it possible (at least with ISC dhcpd) to create DHCP
reservations using host declarations such as:
host duckling {
fixed-address 10.252.252.99;
hardware unknown-32 00:02:c9:02:00:25:a1:b5;
}
IPoIB has a 20-byte link-layer address, of which only eight bytes
represent anything relating to a "hardware address".
The PXE and EFI SNP APIs expect the permanent address to be the same
size as the link-layer address, so fill in the "permanent address"
field with the initial link layer address (as generated by
register_netdev() based upon the real hardware address).
The hardware address is an intrinsic property of the hardware, while
the link-layer address can be changed at runtime. This separation is
exposed via APIs such as PXE and EFI, but is currently elided by gPXE.
Expose the hardware and link-layer addresses as separate properties
within a net device. Drivers should now fill in hw_addr, which will
be used to initialise ll_addr at the time of calling
register_netdev().
The option ROM header contains a one-byte field indicating the number
of 512-byte sectors in the ROM image. Currently it is linked to
contain the number of uncompressed sectors, with an instruction to the
compressor to correct it. This causes link failure when the
uncompressed size of the ROM image is over 128k.
Fix by replacing the SUBx compressor fixup with an ADDx fixup that
adds the total compressed output length, scaled as requested, to an
addend stored in the field where the final length value will be
placed. This is similar to the behavior of ELF relocations, and
ensures that an overflow error will not be generated unless the
compressed size is still too large for the field.
This also allows us to do away with the _filesz_pgh and _filesz_sect
calculations exported by the linker script.
Output tested bitwise identical to the old SUBx mechanism on hd, dsk,
lkrn, and rom prefixes, on both 32-bit and 64-bit processors.
Modified-by: Michael Brown <mcb30@etherboot.org>
Signed-off-by: Michael Brown <mcb30@etherboot.org>
The SRP Boot Firmware Table serves a similar role to the iSCSI and AoE
Boot Firmware Tables; it provides information required by the loaded
OS in order to establish a connection back to the SRP boot device.
There is diagnostic value in being able to disambiguate between the
various reasons why an IB CM has rejected a connection attempt. In
particular, reason 8 "invalid service ID" can be used to identify an
incorrect SRP service_id root-path component, and reason 28 "consumer
reject" corresponds to a genuine SRP login rejection IU, which can be
passed up to the SRP layer.
For rejection reasons other than "consumer reject", we should not pass
through the private data, since it is most likely generated by the CM
without any protocol-specific knowledge.
With iSCSI, connection attempts are expensive; it may take many
seconds to determine that a connection will fail. SRP connection
attempts are much less expensive, so we may as well avoid the
"optimisation" of declaring a state of permanent failure after a
certain number of attempts. This allows a gPXE SRP initiator to
resume operations after an arbitrary amount of SRP target downtime.
Generate errors within individual MAD transaction consumers such as
ib_pathrec.c and ib_mcast.c, rather than within ib_mi.c. This allows
for more meaningful error messages to eventually be displayed to the
user.
SRP is the SCSI RDMA Protocol. It allows for a method of SAN booting
whereby the target is responsible for reading and writing data using
Remote DMA directly to the initiator's memory. The software initiator
merely sends and receives SCSI commands; it never has to touch the
actual data.
The minimal-surprise behaviour, when no explicit SRP initiator device
is specified, will probably be to use the most recently opened
Infiniband device. This matches our behaviour with using the most
recently opened net device for PXE, iSCSI, AoE, NBI, etc.
SRP over Infiniband uses a protocol whereby data is sent via a
combination of the CM private data fields and the RC queue pair
itself. This seems sufficiently generic that it's worth having
available as a separate protocol.
The ACK timeout determines how long we take to notice a failed
Reliable Connection. Reducing it from the arbitrary value of 19 down
to 14 reduces the individual ACK timeout from around 2.1s to 67ms;
this in turn reduces the time to tear down and re-establish a broken
SRP session from around 30s to around 1s.
The Infiniband Communication Manager will refuse to establish a
connection if it believes the connection is already established.
There is no immediately obvious way to ask it to tear down the
existing connection and replace it; to issue a DREP we would need to
know the local and remote communication IDs used for the previous
connection setup.
We can work around this by randomising the high-order bits of the
queue pair number; these have no significance to the hardware, but are
sufficient to convince the IB CM that this is a different connection.
We will terminate our transaction as soon as we receive the first CM
REP, since that provides all the state that we need. However, the
peer may resend the REP if it didn't see our RTU, and if we don't
respond with another RTU we risk being disconnected. (This protocol
appears not to handle retries gracefully.)
Fix by adding a management agent that will listen for these duplicate
REPs and send back an RTU.
When a probe found no results, the list head of beacons would not be
freed, leaking 16 bytes of memory per probe.
Signed-off-by: Michael Brown <mcb30@etherboot.org>
Previously the maximum packet length was computed using an erroneous
understanding of the role of the MIC field in TKIP-encrypted packets.
The field is actually considered to be part of the MSDU (encrypted and
fragmented data), not the MPDU (container for each encrypted
fragment). As such its size does not contribute to cryptographic
overhead outside the data field's size limitations. The net result is
that the previous maximum packet length value was 4 bytes too long;
fix it to the correct value of 2352.
Signed-off-by: Michael Brown <mcb30@etherboot.org>
Some cards (such as ath5k) always need to tune to a particular channel
when they are reset; the reset may happen upon open(), which is before
the channels array would be set up (in prepare_probe()). Avoid tuning
the card to an inconsistent state by copying the hardware
supported-channels array to the 802.11 device's allowable-channels
array even before channels are "properly" set up.
Signed-off-by: Michael Brown <mcb30@etherboot.org>
The prior net80211 model of physical-layer behavior for drivers was
overly simplistic and limited the drivers that could be written. To
be more flexible, split the driver-provided list of supported rates by
band, and add a means for specifying a list of supported channels.
Allow drivers to specify a hardware channel value that will be tied to
uses of the channel.
Expose net80211_duration() to drivers, and make the rate it uses in
its computations configurable, so that it can be used in calculating
durations that must be set in hardware for ACK and CTS packets. Add
net80211_cts_duration() for the common case of calculating the
duration for a CTS packet.
Signed-off-by: Michael Brown <mcb30@etherboot.org>
If isolinux.bin is not installed in the expected location the error
message shown is slightly misleading.
Signed-off-by: Vibi Sreenivasan <vibi_sreenivasan@cms.com>
Signed-off-by: Michael Brown <mcb30@etherboot.org>
A management interface is the component through which both local and
remote management agents are accessed.
This new implementation of a management interface allows for the user
to react to timed-out transactions, and also allows for cancellation
of in-progress transactions.
Some BIOSes support the BIOS Boot Specification (BBS) but fail to set
%es:%di correctly when calling the option ROM initialisation entry
point. This causes gPXE to identify the BIOS as non-PnP (and so
non-BBS), leaving the user unable to control the boot order.
Fix by scanning for the $PnP signature ourselves, rather than relying
on the BIOS having passed in %es:%di correctly.
Tested-by: Helmut Adrigan <helmut.adrigan@chello.at>
The IBA specification refers to management "interfaces" and "agents".
The interface is the component that connects to the queue pair and
sends and receives MADs; the agent is the component that constructs
the reply to the MAD.
Rename the IB_{QPN,QKEY,QPT} constants as a first step towards making
this separation in gPXE.
The function __intel_new_proc_init() (called implicitly when building
using icc) is marked with __attribute__((cdecl)). This breaks
building on x86_64, where cdecl is meaningless.
Fix by replacing with the existing __libgcc macro, which is already
defined to be "__attribute__((cdecl))" for i386 builds and empty for
x86_64 builds.
The MIT and ISC licenses are legally equivalent to the bsd2 license,
but with slightly different verbiage.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Michael Brown <mcb30@etherboot.org>
pxe_api.h is just a description of API functions, it's actively
undesirable to have more implementations than necessary. Allowing it
under the MIT license lets the Syslinux libraries use it.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Michael Brown <mcb30@etherboot.org>
In several places, we currently use size_t to represent a difference
between TCP sequence numbers. This can cause compiler warnings
relating to printf format specifiers, since the result of
(uint32_t+size_t) may be an unsigned long on some compilers.
Fix by using uint32_t for all variables that represent a difference
between TCP sequence numbers.
Tested-by: Joshua Oreman <oremanj@xenon.get-linux.org>
The geniso, genliso and gensdsk scripts contain hard-coded temporary
directory names, and so could potentially collide with each other when
run as part of a concurrent build (e.g. "make -j 4").
Fix by using mktemp to generate suitable temporary directory names.
We add a syslinux floppy disk type using parts of the genliso script.
This floppy image cat be dd'ed to a physical floppy or used in
instances where a virtual floppy with an mountable DOS filesystem is
useful.
We also modify the genliso script to only generate .liso images
rather than creating images depending on how it is called.
Signed-off-by: Michael Brown <mcb30@etherboot.org>
This is required for all modern 802.11 devices, and allows drivers
to be written for them with minimally more effort than is required
for a wired NIC.
Signed-off-by: Michael Brown <mcb30@etherboot.org>
Modified-by: Michael Brown <mcb30@etherboot.org>
The Linux IB Communication Manager will always send MADs to QP1,
rather than back to the originating QP. On Hermon, QP1 is by default
handled by the embedded firmware. We can change this, but the cost is
that we have to handle both QP0 and QP1 (i.e. we have to provide SMA
as well as GMA service in software), and we have to use MLX queues
rather than standard UD queues (i.e. we have to construct the UD
datagrams by hand).
There doesn't seem to be any viable way around this situation, ugly
though it is.
Queue pairs are now assumed to be created in the INIT state, with a
call to ib_modify_qp() required to bring the queue pair to the RTS
state.
ib_modify_qp() no longer takes a modification list; callers should
modify the relevant queue pair parameters (e.g. qkey) directly and
then call ib_modify_qp() to synchronise the changes to the hardware.
The packet sequence number is now a property of the queue pair, rather
than of the device.
Each queue pair may have an associated address vector. For RC queue
pairs, this is the address vector that will be programmed in to the
hardware as the remote address. For UD queue pairs, it will be used
as the default address vector if none is supplied to ib_post_send().
Now that MAD handlers no longer return a status code, we can allow
them to return a pointer to a MAD structure if and only if they want
to send a response. This provides a more natural and flexible
approach than using a "response method" field within the handler's
descriptor.
MAD handlers have to set the status fields within the MAD itself
anyway, in order to provide a meaningful response MAD; the additional
gPXE return status code is just noise.
Note that we probably don't need to ever explicitly set the status to
IB_MGMT_STATUS_OK, since it should already have this value from the
request. (By not explicitly setting the status in this way, we can
safely have ib_sma_set_xxx() call ib_sma_get_xxx() in order to
generate the GetResponse MAD without worrying that ib_sma_get_xxx()
will clear any error status set by ib_sma_set_xxx().)
Most IB hardware seems not to allow allocation of the genuine QPNs 0
and 1, so allow for the externally-visible QPN (as constructed and
parsed by ib_packet, where used) to differ from the real
hardware-allocated QPN.
The queue key is stored as a property of the queue pair, and so can
optionally be added by the Infiniband core at the time of calling
ib_post_send(), rather than always having to be specified by the
caller.
This allows IPoIB to avoid explicitly keeping track of the data queue
key.
Now that path record lookups are handled entirely via
ib_resolve_path(), the only role of the IPoIB peer cache is as a
lookup table for MAC addresses. Update the code structure and
comments to reflect this.
The IPoIB broadcast MAC address varies according to the partition key.
Now that the broadcast MAC address is a property of the network device
rather than of the link layer, we can expose this real MAC address
directly.
The broadcast LID is now identified via a path record lookup; this is
marginally inefficient (since it was present in the MCMemberRecord
GetResponse), but avoids the need to special-case broadcasts when
constructing the address vector in ipoib_transmit().
Generalise the subnet management agent into a general management agent
capable of sending and responding to MADs, including support for
retransmissions as necessary.
Currently, all Infiniband users must create a process for polling
their completion queues (or rely on a regular hook such as
netdev_poll() in ipoib.c).
Move instead to a model whereby the Infiniband core maintains a single
process calling ib_poll_eq(), and polling the event queue triggers
polls of the applicable completion queues. (At present, the
Infiniband core simply polls all of the device's completion queues.)
Polling a completion queue will now implicitly refill all attached
receive work queues; this is analogous to the way that netdev_poll()
implicitly refills the RX ring.
Infiniband users no longer need to create a process just to poll their
completion queues and refill their receive rings.
IPoIB and the SMA have separate constants for the packet size to be
used to I/O buffer allocations. Merge these into the single
IB_MAX_PAYLOAD_SIZE constant.
(Various other points in the Infiniband stack have hard-coded
assumptions of a 2048-byte payload; we don't currently support
variable MTUs.)
IPoIB has a link-layer broadcast address that varies according to the
partition key. We currently go through several contortions to pretend
that the link-layer address is a fixed constant; by making the
broadcast address a property of the network device rather than the
link-layer protocol it will be possible to simplify IPoIB's broadcast
handling.
Move the icky call to step() from aoe.c to ata.c; this takes it at
least one step further away from where it really doesn't belong.
Unfortunately, AoE has the ugly aoe_discover() mechanism which means
that we still have a step() loop in aoe.c for now; this needs to be
replaced at some future point.
Objects typically call xfer_close() as part of their response to a
close() message. If the initiating object has already nullified the
xfer interface then this isn't a problem, but it can lead to
unexpected behaviour when the initiating object is aiming to reuse the
connection and so does not nullify the interface.
Fix by always temporarily nullifying the interface during xfer_close()
(as was already being done by xfer_vreopen() in order to work around
this specific problem).
Reported-by: infernix <infernix@infernix.net>
Tested-by: infernix <infernix@infernix.net>
These commands can be used to activate or deactivate the PXE API (on a
specifiable network interface).
This is currently of limited use, since most image formats will call
shutdown() before booting the image, meaning that the underlying net
device gets shut down during remove_devices() anyway.
ifcommon_exec() was long-ago marked as __attribute__((regparm(2))) in
order to minimise the size of functions that call into it. Since
then, gPXE has added -mregparm=3 as a general compilation option, and
this "optimisation" is now counter-productive.
Change (and simplify) the prototype to minimise code size given the
current compilation conditions.
pxe_init_structures() fills in the fields of the !PXE and PXENV+
structures that aren't known until gPXE starts up. Once gPXE is
started, these values will never change.
Make pxe_init_structures() an initialisation function so that PXE
users don't have to worry about calling it.
It is possible that the UNDI ISR may be triggered before netdev_tx()
returns control to pxenv_undi_transmit(). This means that
pxenv_undi_isr() may see a zero undi_tx_count, and so not check for TX
completions. This is not a significant problem, since it will check
for TX completions on the next call to pxenv_undi_isr() anyway; it
just means that the NBP will see a spurious IRQ that was apparently
caused by nothing.
Fix by updating the undi_tx_count before calling netdev_tx(), so that
pxenv_undi_isr() can decrement it and report the TX completion.
Symantec Ghost requires working multicast support. gPXE configures
all (sufficiently supported) network adapters into "receive all
multicasts" mode, which means that PXENV_UNDI_SET_MCAST_ADDRESS is
actually a no-op, but the current implementation returns
PXENV_STATUS_UNSUPPORTED instead.
Fix by making PXENV_UNDI_SET_MCAST_ADDRESS return success. For good
measure, also implement PXENV_UNDI_GET_MCAST_ADDRESS, since the
relevant functionality is now exposed by the net device core.
Note that this will silently fail if the gPXE driver for the NIC being
used fails to configure the NIC in "receive all multicasts" mode.
The PXE debugging messages have remained pretty much unaltered since
Etherboot 5.4, and are now difficult to read in comparison to most of
the rest of gPXE.
Bring the pxe_undi debug messages up to normal gPXE standards.
This keeps code size down, since the wireless interface management
commands have the same command-line interface and overall structure as
the wired commands.
Signed-off-by: Michael Brown <mcb30@etherboot.org>
With the addition of link status codes, we can now display a detailed
error indication if iflinkwait() fails.
Putting the error output in iflinkwait avoids code duplication, and
gains symmetry with the other interface management routines; ifopen()
already prints an error directly if it cannot open its interface.
Modified-by: Michael Brown <mcb30@etherboot.org>
Signed-off-by: Michael Brown <mcb30@etherboot.org>
Expand the NETDEV_LINK_UP bit into a link_rc status code field,
allowing specific reasons for link failure to be reported via
"ifstat".
Originally-authored-by: Joshua Oreman <oremanj@rwcr.net>
The Symantec UNDI DOS driver fails when run on top of gPXE because we
return our interface type as "gPXE" rather than one of the predefined
NDIS interface type strings.
Fix by returning the standard "DIX+802.3" string; this isn't
necessarily always accurate, but it's highly unlikely that anything
trying to use the UNDI API would understand our IPoIB link-layer
pseudo-header anyway.
The Intel DOS UNDI driver fails when run on top of gPXE because we do
not fill in the ServiceFlags field in PXENV_UNDI_GET_IFACE_INFO.
Fix by filling in the ServiceFlags field with reasonable values
indicating our approximate feature capabilities.
The 3Com DOS UNDI driver fails when run on top of gPXE for two
reasons: firstly because PXENV_UNDI_SET_PACKET_FILTER is unsupported,
and secondly because gPXE enters the NBP without enabling interrupts
on the NIC, and the 3Com driver never calls PXENV_UNDI_OPEN.
Fix by always returning success from PXENV_UNDI_SET_PACKET_FILTER
(which is no worse than the current situation, since we already ignore
the receive packet filter in PXENV_UNDI_OPEN), and by forcibly
enabling interrupts on the NIC within PXENV_UNDI_TRANSMIT. The latter
is something of a hack, but avoids the need to implement a complete
base-code ISR that we would otherwise need if we were to enter the NBP
with interrupts enabled.
Commit 558c1a4 ("[tcp] Improve robustness in the presence of duplicated
received packets") introduced a regression in that an old duplicate
ACK received while in the ESTABLISHED state would pass through normal
ACK processing, including updating tcp->snd_seq.
Fix by ensuring that ACK processing ignores all duplicate ACKs.
All TCP errors or unusual events should now generate a debugging
message at DBGLVL_LOG, with enough information (SEQ and ACK numbers)
to be able to identify the corresponding packet (or missing packet) in
a network trace from the remote end.
This makes it possible to leave TCP debugging enabled in order to see
interesting TCP events, without flooding the console with at least one
message per packet.
This resolves potential difficulties occurring when more than one script
is used. Total cost: 88 bytes uncompressed.
Signed-off-by: Michael Brown <mcb30@etherboot.org>
In order to construct outgoing link-layer frames or parse incoming
ones properly, some protocols (such as 802.11) need more state than is
available in the existing variables passed to the link-layer protocol
handlers. To remedy this, add struct net_device *netdev as the first
argument to each of these functions, so that more information can be
fetched from the link layer-private part of the network device.
Updated all three call sites (netdevice.c, efi_snp.c, pxe_undi.c) and
both implementations (ethernet.c, ipoib.c) of ll_protocol to use the
new argument.
Signed-off-by: Michael Brown <mcb30@etherboot.org>
The 93C66 is identical to the 93C56 in programming interface and
addressing, but twice as large in data storage (4096 bits). It's
used in some RTL8185 wireless cards.
Signed-off-by: Michael Brown <mcb30@etherboot.org>
gPXE responds to duplicated ACKs with an immediate retransmission,
which can lead to a sorceror's apprentice syndrome. It also responds
to out-of-range (or old duplicate) ACKs with a RST, which can cause
valid connections to be dropped.
Fix the sorceror's apprentice syndrome by leaving the retransmission
timer running (and so inhibiting the immediate retransmission) when we
receive a potential duplicate ACK. This seems to match the behaviour
of Linux observed via wireshark traces.
Fix the RST issue by sending RST only on out-of-range ACKs that occur
before the connection is fully established, as per RFC 793.
These problems were exposed during development of the 802.11 wireless
link layer; the 802.11 protocol has a failure mode that can easily
cause duplicated packets. The fixes were tested in a controlled way
by faking large numbers of duplicated packets in the rtl8139 driver.
Originally-fixed-by: Joshua Oreman <oremanj@rwcr.net>
setting_cmp() compares by option tag and then by name. Empty names
will always match, which gives us a false positive.
Fix by explicitly checking for empty names.
Modified-by: Michael Brown <mcb30@etherboot.org>
Signed-off-by: Michael Brown <mcb30@etherboot.org>
MAX_LL_HEADER_LEN is erroneously set to 6 rather than 14, resulting
in possible data corruption whenever we send an ARP packet.
Fix value and add a comment explaining why MAX_LL_ADDR_LEN is greater
than MAX_LL_HEADER_LEN.
Reported-by: Joshua Oreman <oremanj@rwcr.net>
Windows text editors such as Notepad tend to use CRLF line endings,
which breaks gPXE's signature detection for script images. Since
scripts are usually very small, they end up falling back to being
detected as valid PXE executable images (since there are no signature
checks for PXE executables). Executing text files as x86 machine code
tends not to work well.
Fix by allowing for any isspace() character to terminate the "#!gpxe"
signature, and by ensuring that CR characters get stripped during
command line parsing.
Suggested-by: Shao Miller <Shao.Miller@yrdsb.edu.on.ca>