freebsd-nq/sys/dev/fxp
Andrew Gallatin 0617522889 Fix an alpha-only race which causes the transmit side of the chip to
lock up under moderate to heavy load.

The status & command fields share a 32-bit longword.  The programming
API of the eepro apparently requires that you update the command field
of a transmit slot that you've already given to the card.  This means
the card could be updating the status field of the same longword at
the same time. Since alphas can only operate on 32-bit chunks of
memory, both the status & command fields are loaded from memory &
operated on in registers when the following line of C is executed:

                sc->cbl_last->cb_command &= ~FXP_CB_COMMAND_S;

The race is caused by the card DMA'ing up the status at just the wrong
time -- after it has been loaded into a register & before it has been
written back.  The old value of the status is written back, clobbering
the status the card just DMA'ed up. The fact that the card has sent
this frame is missed & the transmit engine appears to hang.

Luckily, as numerous people on the freebsd-alpha list pointed out, the
load-locked/store-conditional instructions used by the atomic
functions work with respect changes in memory due to I/O devices.  We
now use them to safely update the command field.

Tested by: Bernd Walter <ticso@mail.cicely.de>
2000-07-19 14:33:52 +00:00
..
if_fxp.c Fix an alpha-only race which causes the transmit side of the chip to 2000-07-19 14:33:52 +00:00
if_fxpreg.h Added support for the i82559ER (10/100Mbps NIC for embedded applications). 2000-06-18 10:26:09 +00:00
if_fxpvar.h Added support for cards and on-motherboard NICs that use an SEEPROM 2000-03-28 04:41:42 +00:00