diff --git a/sys/dev/ed/if_ed.c b/sys/dev/ed/if_ed.c index b6b517c9d28b..f9a32bf57111 100644 --- a/sys/dev/ed/if_ed.c +++ b/sys/dev/ed/if_ed.c @@ -1739,3 +1739,38 @@ ed_shmem_write_mbufs(struct ed_softc *sc, struct mbuf *m, bus_size_t dst) } return (len); } + +/* + * Generic ifmedia support. By default, the DP8390-based cards don't know + * what their network attachment really is, or even if it is valid (except + * upon successful transmission of a packet). To play nicer with dhclient, as + * well as to fit in with a framework where some cards can provde more + * detailed information, make sure that we use this as a fallback. + */ +static int +ed_gen_ifmedia_ioctl(struct ed_softc *sc, struct ifreq *ifr, u_long command) +{ + return (ifmedia_ioctl(sc->ifp, ifr, &sc->ifmedia, command)); +} + +static int +ed_gen_ifmedia_upd(struct ifnet *ifp) +{ + return 0; +} + +static void +ed_gen_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) +{ + ifmr->ifm_active = IFM_ETHER | IFM_AUTO; + ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE; +} + +void +ed_gen_ifmedia_init(struct ed_softc *sc) +{ + sc->sc_media_ioctl = &ed_gen_ifmedia_ioctl; + ifmedia_init(&sc->ifmedia, 0, ed_gen_ifmedia_upd, ed_gen_ifmedia_sts); + ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_AUTO, 0, 0); + ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_AUTO); +} diff --git a/sys/dev/ed/if_ed_cbus.c b/sys/dev/ed/if_ed_cbus.c index dc4fabb68859..bcc0d85b7cf5 100644 --- a/sys/dev/ed/if_ed_cbus.c +++ b/sys/dev/ed/if_ed_cbus.c @@ -248,7 +248,8 @@ ed_cbus_attach(dev) ed_release_resources(dev); return (error); } - + if (sc->sc_media_ioctl == NULL) + ed_gen_ifmedia_init(sc); return ed_attach(dev); } diff --git a/sys/dev/ed/if_ed_isa.c b/sys/dev/ed/if_ed_isa.c index 7d30614963f6..1beac2720bd3 100644 --- a/sys/dev/ed/if_ed_isa.c +++ b/sys/dev/ed/if_ed_isa.c @@ -175,7 +175,8 @@ ed_isa_attach(device_t dev) ed_release_resources(dev); return (error); } - + if (sc->sc_media_ioctl == NULL) + ed_gen_ifmedia_init(sc); return ed_attach(dev); } diff --git a/sys/dev/ed/if_ed_pci.c b/sys/dev/ed/if_ed_pci.c index a2831b8f6497..1b2e17d8a6ab 100644 --- a/sys/dev/ed/if_ed_pci.c +++ b/sys/dev/ed/if_ed_pci.c @@ -91,11 +91,9 @@ ed_pci_attach(device_t dev) int error = ENXIO; /* - * If this card claims to be a RTL8029, probe it as such. - * However, allow that probe to fail. Some versions of qemu - * claim to be a 8029 in the PCI register, but it doesn't - * implement the 8029 specific registers. In that case, fall - * back to a normal NE2000. + * Probe RTL8029 cards, but allow failure and try as a generic + * ne-2000. QEMU 0.9 and earlier use the RTL8029 PCI ID, but + * are areally just generic ne-2000 cards. */ if (pci_get_devid(dev) == ED_RTL8029_PCI_ID) error = ed_probe_RTL80x9(dev, PCIR_BAR(0), flags); @@ -118,7 +116,8 @@ ed_pci_attach(device_t dev) ed_release_resources(dev); return (error); } - + if (sc->sc_media_ioctl == NULL) + ed_gen_ifmedia_init(sc); error = ed_attach(dev); if (error) ed_release_resources(dev); diff --git a/sys/dev/ed/if_edvar.h b/sys/dev/ed/if_edvar.h index 30610abc5f1b..27dd6694d9ae 100644 --- a/sys/dev/ed/if_edvar.h +++ b/sys/dev/ed/if_edvar.h @@ -226,6 +226,8 @@ u_short ed_pio_write_mbufs(struct ed_softc *, struct mbuf *, bus_size_t); void ed_disable_16bit_access(struct ed_softc *); void ed_enable_16bit_access(struct ed_softc *); +void ed_gen_ifmedia_init(struct ed_softc *); + driver_intr_t edintr; extern devclass_t ed_devclass;