From 1cac1dbfab7edc277f6a724adc52e65e2aea550a Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 7 Apr 2009 05:41:38 +0000 Subject: [PATCH] Provide a generic ifmedia set of routines as a fallback. The DP8390-based cards have no generic way of reporting status of the link or setting the media type. Some specific versions of these cards do, however, allow for this, and we already support some of them. Make the 'ed' experience more uniform by providing "autoselect" as the meida and status "active" always. This won't affect the chips that provide more specific details. --- sys/dev/ed/if_ed.c | 35 +++++++++++++++++++++++++++++++++++ sys/dev/ed/if_ed_cbus.c | 3 ++- sys/dev/ed/if_ed_isa.c | 3 ++- sys/dev/ed/if_ed_pci.c | 11 +++++------ sys/dev/ed/if_edvar.h | 2 ++ 5 files changed, 46 insertions(+), 8 deletions(-) diff --git a/sys/dev/ed/if_ed.c b/sys/dev/ed/if_ed.c index b6b517c9d28..f9a32bf5711 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 dc4fabb6885..bcc0d85b7cf 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 7d30614963f..1beac2720bd 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 a2831b8f649..1b2e17d8a6a 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 30610abc5f1..27dd6694d9a 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; -- 2.45.2