Subject: port-i386/522: Several bugs in IE ethernet driver
To: None <gnats-admin@sun-lamp.cs.berkeley.edu>
From: None <r-boni@uiuc.edu>
List: netbsd-bugs
Date: 10/17/1994 14:20:04
>Number: 522
>Category: port-i386
>Synopsis: if_ie sets promisc mode in wrong place, fouls up TDR commands
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: gnats-admin (GNATS administrator)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Oct 17 14:20:03 1994
>Originator: Rafal Boni
>Organization:
Procrastination, Inc.: We'll get to you tomorrow!
>Release: 1.0_Beta, Supped Oct 17th, ~ 3PM Central
>Environment:
System: NetBSD colt-73.slip.uiuc.edu 1.0_BETA NetBSD 1.0_BETA (RAFAL) #9: Fri Oct 14 17:26:08 CDT 1994 rafal@ruger-47.slip.uiuc.edu:/usr/src/sys/arch/i386/compile/RAFAL i386
2 i386 boxes with EtherLink/16 cards.
>Description:
[There's two mostly independent probs. here...]
1) the if_ie driver sets the promisc flag AFTER the card is re-
configured, so PROMISC. mode does not get set in the right place,
AND/OR can linger on after it should have been turned off.
2) The if_ie driver also mucks about with stuff in the TDR code, so
that a failed TDR command will be reported as an OPEN!
>How-To-Repeat:
[Match up these statements with prob. descriptions above...]
1) Run tcpdump and watch machine come to it's knees as the if_ie driver
leaves the card in promisc. mode but thinks it isn't... Hence ALL
packets off the wire are passed up to the higher-level protocol
machinery
2) Dunno... I seem to encounter this pretty much at random, sometimes
on bootup, other times it's caused by the card's re-initing itself.
>Fix:
[NOTE: this patch also cleans out 3-4 lines of dead/pointless code...]
*** if_ie.c.orig Mon Oct 17 15:48:10 1994
--- if_ie.c Mon Oct 17 15:51:47 1994
***************
*** 728,738 ****
mc_setup(sc, (caddr_t)sc->xmit_cbuffs[0]);
sc->want_mcsetup = 0;
}
- /* Wish I knew why this seems to be necessary... */
- sc->xmit_cmds[0]->ie_xmit_status |= IE_STAT_COMPL;
-
iestart(&sc->sc_arpcom.ac_if);
}
/*
--- 728,735 ----
***************
*** 1569,1592 ****
cmd->com.ie_cmd_status = 0;
cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
cmd->com.ie_cmd_link = 0xffff;
- cmd->ie_tdr_time = 0;
sc->scb->ie_command_list = MK_16(MEM, cmd);
cmd->ie_tdr_time = 0;
! if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL))
! result = 0x2000;
else
result = cmd->ie_tdr_time;
ie_ack(sc, IE_ST_WHENCE);
if (result & IE_TDR_SUCCESS)
return;
! if (result & IE_TDR_XCVR) {
printf("%s: transceiver problem\n", sc->sc_dev.dv_xname);
} else if (result & IE_TDR_OPEN) {
printf("%s: TDR detected an open %d clocks away\n",
sc->sc_dev.dv_xname, result & IE_TDR_TIME);
--- 1566,1591 ----
cmd->com.ie_cmd_status = 0;
cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
cmd->com.ie_cmd_link = 0xffff;
sc->scb->ie_command_list = MK_16(MEM, cmd);
cmd->ie_tdr_time = 0;
! if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
! !(cmd->com.ie_cmd_status & IE_STAT_OK))
! result = 0x10000;
else
result = cmd->ie_tdr_time;
ie_ack(sc, IE_ST_WHENCE);
if (result & IE_TDR_SUCCESS)
return;
! if (result & 0x10000) {
! printf("%s: TDR command failed\n", sc->sc_dev.dv_xname);
! } else if (result & IE_TDR_XCVR) {
printf("%s: transceiver problem\n", sc->sc_dev.dv_xname);
} else if (result & IE_TDR_OPEN) {
printf("%s: TDR detected an open %d clocks away\n",
sc->sc_dev.dv_xname, result & IE_TDR_TIME);
***************
*** 1806,1818 ****
ptr += IE_TBUF_SIZE;
ptr = Align(ptr);
}
- /*
- * This must be coordinated with iestart() and ietint().
- */
- sc->xmit_cmds[0]->ie_xmit_status = IE_STAT_COMPL;
-
sc->sc_arpcom.ac_if.if_flags |= IFF_RUNNING; /* tell higher levels that we are here */
start_receiver(sc);
return 0;
}
--- 1805,1812 ----
***************
*** 1881,1888 ****
--- 1875,1884 ----
}
break;
case SIOCSIFFLAGS:
+ sc->promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
+
if ((ifp->if_flags & IFF_UP) == 0 &&
(ifp->if_flags & IFF_RUNNING) != 0) {
/*
* If interface is marked down and it is running, then
***************
*** 1904,1912 ****
*/
iestop(sc);
ieinit(sc);
}
- sc->promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
#ifdef IEDEBUG
if (ifp->if_flags & IFF_DEBUG)
sc->sc_debug = IED_ALL;
else
--- 1900,1907 ----
>Audit-Trail:
>Unformatted: