There are two possible causes which will make vr(4) stall:
in vr_start(), if vr_encap() fails:
1) vr_start() will set IFF_OACTIVE. If the packet causing vr_encap() to fail
is the only packet pending to be downloaded to device, vr(4) will stall,
since:
* No more packets can be transfered, because IFF_OACTIVE is turned on
* Except for vr_{init, stop}(), vr_txeoc() is the only function that can
turn off IFF_OACTIVE. It is triggered by "frame download completing"
interrupt. But this kind of interrupt will not be generated here, since
there are no other packets pending to be downloaded.
2) vr_start() will skip TX head and tail pointer updating, which leaks all
previous successfully encapsulated TX chains.
Following fixes are applied:
- Allocate chunk of memory in vr_attch() to reduce the failure chance of
vr_encap(). This will also reduce the load of mbuf allocation system
- Use indexes instead of pointers for TX chain processing. This can save us
some spaces in every vr_chain
- Update Tx head and tail indexes when there are successfully encapsultaed
packets pending to be downloaded to device, even if vr_encap() fails for
some packets
- Cache TX buffer and next TX descriptor's physical address in vr_chain, since
these addresses are fixed during the life time of vr(4)
Other stuffs:
- Use M_ZERO flag in memory allocation instead of calling bzero() later
- Remove (char *) cast in bzero()
- Minor style changes
Reported-by: corecode
With-helps-form: joerg
Reviewed-by: joerg, submit@