Avoid unnecessary controller reinitialization by checking driver
running state. fxp(4) requires controller reinitialization for the following cases. o RX lockup condition on i82557 o promiscuous mode change o multicast filter change o WOL configuration o TSO/VLAN hardware tagging/checksum offloading configuration o MAC reprogramming after speed/duplex/flow-control resolution o Any events that result in MAC reprogramming(link UP/DOWN, remote link partner's restart of auto-negotiation etc) o Microcode loading/unloading Apart from above cases which come from hardware limitation, upper stack also blindly reinitializes controller whenever an IP address is assigned. After r194573, fxp(4) no longer needs to reinitialize the controller to program multicast filter after upping the interface. So keeping track of driver running state should remove all unnecessary controller reinitializations. This change will also address endless controller reinitialization triggered by dhclient(8). Tested by: hrs, Alban Hertroys <haramrae@gmail.com>
This commit is contained in:
parent
4e8602cd39
commit
015913b383
@ -1075,7 +1075,8 @@ fxp_suspend(device_t dev)
|
||||
pmstat |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE;
|
||||
sc->flags |= FXP_FLAG_WOL;
|
||||
/* Reconfigure hardware to accept magic frames. */
|
||||
fxp_init_body(sc, 1);
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
fxp_init_body(sc, 0);
|
||||
}
|
||||
pci_write_config(sc->dev, pmc + PCIR_POWER_STATUS, pmstat, 2);
|
||||
}
|
||||
@ -2141,8 +2142,10 @@ fxp_tick(void *xsc)
|
||||
*/
|
||||
if (sc->rx_idle_secs > FXP_MAX_RX_IDLE) {
|
||||
sc->rx_idle_secs = 0;
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
fxp_init_body(sc, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
/*
|
||||
@ -2240,6 +2243,7 @@ fxp_watchdog(struct fxp_softc *sc)
|
||||
device_printf(sc->dev, "device timeout\n");
|
||||
sc->ifp->if_oerrors++;
|
||||
|
||||
sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
fxp_init_body(sc, 1);
|
||||
}
|
||||
|
||||
@ -2274,6 +2278,10 @@ fxp_init_body(struct fxp_softc *sc, int setmedia)
|
||||
int i, prm;
|
||||
|
||||
FXP_LOCK_ASSERT(sc, MA_OWNED);
|
||||
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Cancel any pending I/O
|
||||
*/
|
||||
@ -2813,6 +2821,7 @@ fxp_miibus_statchg(device_t dev)
|
||||
*/
|
||||
if (sc->revision == FXP_REV_82557)
|
||||
return;
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
fxp_init_body(sc, 0);
|
||||
}
|
||||
|
||||
@ -2836,9 +2845,10 @@ fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
if (ifp->if_flags & IFF_UP) {
|
||||
if (((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) &&
|
||||
((ifp->if_flags ^ sc->if_flags) &
|
||||
(IFF_PROMISC | IFF_ALLMULTI | IFF_LINK0)) != 0)
|
||||
(IFF_PROMISC | IFF_ALLMULTI | IFF_LINK0)) != 0) {
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
fxp_init_body(sc, 0);
|
||||
else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
|
||||
} else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
|
||||
fxp_init_body(sc, 1);
|
||||
} else {
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
|
||||
@ -2851,8 +2861,10 @@ fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
case SIOCADDMULTI:
|
||||
case SIOCDELMULTI:
|
||||
FXP_LOCK(sc);
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
fxp_init_body(sc, 0);
|
||||
}
|
||||
FXP_UNLOCK(sc);
|
||||
break;
|
||||
|
||||
@ -2942,8 +2954,10 @@ fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
~(IFCAP_VLAN_HWTSO | IFCAP_VLAN_HWCSUM);
|
||||
reinit++;
|
||||
}
|
||||
if (reinit > 0 && ifp->if_flags & IFF_UP)
|
||||
if (reinit > 0 && (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
fxp_init_body(sc, 0);
|
||||
}
|
||||
FXP_UNLOCK(sc);
|
||||
VLAN_CAPABILITIES(ifp);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user