eepro100 (Intel 82559 Linux device driver)

Polia, Michael
Mon Aug 9 14:08:13 1999

The version of (Intel 82559 Linux Driver) eepro100.c I am referencing is:
"eepro100.c:v1.08 5/3/99 Donald Becker\n";

I have a question regarding this comment in the file eepro100.c:

Commands may have bits set e.g. CmdSuspend in the command word to either
suspend or stop the transmit/command unit.  This driver always flags the
command with CmdSuspend, erases the CmdSuspend in the previous command, and
then issues a CU_RESUME.
Note: Watch out for the potential race condition here: imagine
	erasing the previous suspend
		the chip processes the previous command
		the chip processes the final command, and suspends
	doing the CU_RESUME
		the chip processes the next-yet-valid post-final-command.
So blindly sending a CU_RESUME is only safe if we do it immediately after
after erasing the previous CmdSuspend, without the possibility of an
intervening delay.  Thus the resume command is always within the
interrupts-disabled region.  This is a timing dependence, but handling this
condition in a timing-independent way would considerably complicate the

I am having some difficulty understanding this race condition. Let me add
some detail
to help analyze this condition:

Imagine an 82559 TxCB transmit ring:
	TxCB0 --> TxCB1(S-bit) --> TxCB2 --> TxCB3
with TxCB0 and TxCB1 containing valid frames to be transmitted and the
TxCB1-S-bit set.
The 82559 device is processing TxCB0 (or previous TxCBs in ring). 
TxCB0 and TxCB1 contain valid frames to be transmitted.

You imply that the problem occurs when the driver TX software loads TxCB2
with the 
next frame to be transmitted:
	1. Driver loads TxCB2 with next frame (TxCB_ring_tail).
	2. Driver sets S-bit in TxCB2 (TxCB_ring_tail).
	3. Driver clears S-bit in TxCB1 (previous_TxCB_ring_tail).
		TxCB0 --> TxCB1 --> TxCB2(S-bit) --> TxCB3

	4. 82558 processes TxCB1 (previous_TxCB_ring_tail).
		TxCB0 --> TxCB1(C-bit, OK-bit) --> TxCB2(S-bit) --> TxCB3

	5. 82559 processes TxCB2 (TxCB_ring_tail).
		TxCB0 --> TxCB1(C-bit, OK-bit) --> TxCB2(S-bit, C-bit,
OK-bit) --> TxCB3

	6. 82559 suspends on S-bit in TxCB2.
	7. Driver increments the ring pointers (previous_TxCB_ring_tail++)
	8. Driver issues CU_RESUME to 82559.
	9. 82559 processes TxCB3 (which contains old or invalid data).

The Intel 82559 Software Developer's Manual (document 687805-00), section
page 95, states that upon issuing a CU_RESUME:
	If the CU is in the SUSPENDED state it goes to the ACTIVE state and
	the beginning of the next CB. Since the 82558 remembers the pointer
to the
	next Action Command, it does not reread the Link Pointer in the
previous CB.
	However, the 82558 will reread the S-bit in the previous CB to
	if the driver has modified it while the 82558 was suspended. If the
S-bit is
	cleared, it will proceed to execute the new CB. If the S-bit is
still set in
	the previous CB, the CU goes back into the SUSPENDED state.

Therefore, for step 9 above, TxCB2 is now the "previous CB". Upon issuing
I would expect the 82559 to reread the S-bit in TxCB2. Since this S-bit is
(still) set,
the 82559 should go back to the SUSPENDED state, not into the ACTIVE state.
So, step 9
above should have the 82559 device remaining in the suspended state.
Therefore, there is not
a race condition.

Is this correct, or am I misinterpreting some aspect of the 82559 device?

Also, regarding the comment:
	Note: In previous generation Intel chips, restarting the command 
	      unit was a notoriously slow process.  
	      This is presumably no longer true.

Is there any info regarding the acceptance time for a command in the 82559

Thank you.

Michael J. Polia                        Sonoma Systems
                                               450 Donald Lynch Blvd
                                               Marlborough, MA 01752
508.481.2215  ext. 256