mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-04 09:09:56 +00:00
Fix a bug brought to light by the people working on SMPng. I don't quite
understand exactly what it is about SMPng that tickles this bug. What I do know is that the foo_init() routine in most drivers is often called twice when an interface is brought up. One time is due to the ifconfig(8) command calling the SIOCSIFFLAGS ioctl to set the IFF_UP flag, and another is probably due to the kernel calling ifp->if_init at some point. In any case, the SMPng changes seem to affect the timing of these two events in such a way that there is a significant delay before any packets are sent onto the wire after the interface is first brought up. This manifested itself locally as an SMPng test machine which failed to obtain an address via DHCP when booting up. It looks like the second call to fxp_init() is happening faster now than it did before, and I think it catches the chip while it's in the process of dealing with the configuration command from the first call. Whatever the case, a FXP_CSR_SCB_CNA interrupt event is now generated shortly after the second fxp_init() call. (This interrupt is apparently never generated by a non-SMPng kernel, so nobody noticed.) There are two problems with this: first, fxp_intr() does not handle the FXP_CSR_SCB_CNA interrupt event (it never tests for it or does anything to deal with it), and second, the meaning of FXP_CSR_SCB_CNA is not documented in the driver. (Apparently it means "command unit not active.") Bad coder. No biscuit. The fix is to have the FXP_CSR_SCB_CNA interrupt handled just like the FXP_SCB_STATACK_CXTNO interrupt. This prevents the state machine for the configuration/RX filter programming stuff from getting wedged for several seconds and preventing packet transmission. Noticed by: jhb
This commit is contained in:
parent
30a77b76ff
commit
069363018f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=64547
@ -1120,8 +1120,18 @@ fxp_intr(arg)
|
||||
|
||||
/*
|
||||
* Free any finished transmit mbuf chains.
|
||||
*
|
||||
* Handle the CNA event likt a CXTNO event. It used to
|
||||
* be that this event (control unit not ready) was not
|
||||
* encountered, but it is now with the SMPng modifications.
|
||||
* The exact sequence of events that occur when the interface
|
||||
* is brought up are different now, and if this event
|
||||
* goes unhandled, the configuration/rxfilter setup sequence
|
||||
* can stall for several seconds. The result is that no
|
||||
* packets go out onto the wire for about 5 to 10 seconds
|
||||
* after the interface is ifconfig'ed for the first time.
|
||||
*/
|
||||
if (statack & FXP_SCB_STATACK_CXTNO) {
|
||||
if (statack & (FXP_SCB_STATACK_CXTNO | FXP_SCB_STATACK_CNA)) {
|
||||
struct fxp_cb_tx *txp;
|
||||
|
||||
for (txp = sc->cbl_first; sc->tx_queued &&
|
||||
|
@ -1120,8 +1120,18 @@ fxp_intr(arg)
|
||||
|
||||
/*
|
||||
* Free any finished transmit mbuf chains.
|
||||
*
|
||||
* Handle the CNA event likt a CXTNO event. It used to
|
||||
* be that this event (control unit not ready) was not
|
||||
* encountered, but it is now with the SMPng modifications.
|
||||
* The exact sequence of events that occur when the interface
|
||||
* is brought up are different now, and if this event
|
||||
* goes unhandled, the configuration/rxfilter setup sequence
|
||||
* can stall for several seconds. The result is that no
|
||||
* packets go out onto the wire for about 5 to 10 seconds
|
||||
* after the interface is ifconfig'ed for the first time.
|
||||
*/
|
||||
if (statack & FXP_SCB_STATACK_CXTNO) {
|
||||
if (statack & (FXP_SCB_STATACK_CXTNO | FXP_SCB_STATACK_CNA)) {
|
||||
struct fxp_cb_tx *txp;
|
||||
|
||||
for (txp = sc->cbl_first; sc->tx_queued &&
|
||||
|
Loading…
Reference in New Issue
Block a user