eepro100 (Intel 82559 Linux device driver)
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
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
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
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
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
next Action Command, it does not reread the Link Pointer in the
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
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
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
Michael J. Polia Sonoma Systems
450 Donald Lynch Blvd
Marlborough, MA 01752
508.481.2215 ext. 256