The function NICReturnRFD(Adapter, pMpRfd)
pulls a HW RFD corresponding to pMpRfd from the linked list and adds
it to the tail. While sofware links will be ok, the HW RFDs link will
be broken because,
pHwRfd->RfdCbHeader.CbStatus = 0;
pHwRfd->RfdActualCount = 0;
pHwRfd->RfdCbHeader.CbCommand = (RFD_EL_BIT);
pHwRfd->RfdCbHeader.CbLinkPointer = DRIVER_NULL;
// Link it onto the end of the chain dynamically
pHwRfd = pLastMpRfd->HwRfd;
pHwRfd->RfdCbHeader.CbLinkPointer = pMpRfd->HwRfdPhys;
pHwRfd->RfdCbHeader.CbCommand = 0;
WILL only fix the CURRENT and NEXT links and NOT the PREVIOUS HW RFD
There should be a way to fix the previous HW RFD link pointer also.
something like pPREV_RFD->RfdCbHeader.CbLinkPointer = PENULTIMATE_TAIL-
This code luckily works as long as pMpRfd in NICReturnRFD(Adapter,
pMpRfd) is the HEAD ENTRY. In MpHandleRecvInterrupt ( ... ) it was a
lucky case and in MPReturnNetBufferLists(...) and a couple of other
places it looks like a BUG.
Can some one clarify?
I have attempted a pictorial description of the bug
hw_rfd1 -> hw_rfd2 -> hw_rfd3
will become 2 sets
hw_rfd1 -> hw_rfd2 AND a *** hw_rfd3 -> hw_rfd2 !! because of bad