diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1998-09-22 18:58:06 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1998-09-22 18:58:06 +0000 |
commit | 3e95c62a8d107490bc393fb74fa9b7b4dbafc25e (patch) | |
tree | de85f2e454d9e104d880e1b3e24e8272b8719e04 /sys/dev/pci/if_fxp.c | |
parent | fc68c3bd07f476bc5450c0a55ccff79519f6b2d5 (diff) |
media support
Diffstat (limited to 'sys/dev/pci/if_fxp.c')
-rw-r--r-- | sys/dev/pci/if_fxp.c | 178 |
1 files changed, 93 insertions, 85 deletions
diff --git a/sys/dev/pci/if_fxp.c b/sys/dev/pci/if_fxp.c index be631480a92..38dc986e461 100644 --- a/sys/dev/pci/if_fxp.c +++ b/sys/dev/pci/if_fxp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_fxp.c,v 1.16 1998/08/28 22:28:51 downsj Exp $ */ +/* $OpenBSD: if_fxp.c,v 1.17 1998/09/22 18:58:03 deraadt Exp $ */ /* $NetBSD: if_fxp.c,v 1.2 1997/06/05 02:01:55 thorpej Exp $ */ /* @@ -49,6 +49,7 @@ #include <net/if.h> #include <net/if_dl.h> +#include <net/if_media.h> #include <net/if_types.h> #ifdef INET @@ -94,6 +95,8 @@ #include <machine/bus.h> #include <machine/intr.h> +#include <dev/mii/miivar.h> + #include <dev/pci/if_fxpreg.h> #include <dev/pci/if_fxpvar.h> @@ -185,7 +188,19 @@ static u_char fxp_cb_config_template[] = { 0x5 /* 21 */ }; +/* Supported media types. */ +struct fxp_supported_media { + const int fsm_phy; /* PHY type */ + const int *fsm_media; /* the media array */ + const int fsm_nmedia; /* the number of supported media */ + const int fsm_defmedia; /* default media for this PHY */ +}; + +static int fxp_mediachange __P((struct ifnet *)); +static void fxp_mediastatus __P((struct ifnet *, struct ifmediareq *)); +#if 0 static const char *fxp_phyname __P((int)); +#endif static inline void fxp_scb_wait __P((struct fxp_softc *)); static FXP_INTR_TYPE fxp_intr __P((void *)); static void fxp_start __P((struct ifnet *)); @@ -195,8 +210,9 @@ static void fxp_init __P((void *)); static void fxp_stop __P((struct fxp_softc *)); static void fxp_watchdog __P((struct ifnet *)); static int fxp_add_rfabuf __P((struct fxp_softc *, struct mbuf *)); -static int fxp_mdi_read __P((struct fxp_softc *, int, int)); -static void fxp_mdi_write __P((struct fxp_softc *, int, int, int)); +static int fxp_mdi_read __P((struct device *, int, int)); +static void fxp_mdi_write __P((struct device *, int, int, int)); +static void fxp_statchg __P((struct device *)); static void fxp_read_eeprom __P((struct fxp_softc *, u_int16_t *, int, int)); static int fxp_attach_common __P((struct fxp_softc *, u_int8_t *)); @@ -384,7 +400,6 @@ fxp_attach(parent, self, aux) return; } - printf(": %s\n", intrstr); #ifdef __OpenBSD__ ifp = &sc->arpcom.ac_if; @@ -399,10 +414,31 @@ fxp_attach(parent, self, aux) ifp->if_start = fxp_start; ifp->if_watchdog = fxp_watchdog; + printf(": %s, address %s\n", intrstr, + ether_sprintf(sc->arpcom.ac_enaddr)); + + /* + * Initialize our media structures and probe the MII. + */ + sc->sc_mii.mii_ifp = ifp; + sc->sc_mii.mii_readreg = fxp_mdi_read; + sc->sc_mii.mii_writereg = fxp_mdi_write; + sc->sc_mii.mii_statchg = fxp_statchg; + ifmedia_init(&sc->sc_mii.mii_media, 0, fxp_mediachange, + fxp_mediastatus); + mii_phy_probe(self, &sc->sc_mii, 0xffffffff); + if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { + ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL); + ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE); + } else + ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO); + +#if 0 printf(FXP_FORMAT ": %s (%s) address %s\n", FXP_ARGS(sc), fxp_phyname(sc->phy_primary_device), sc->phy_10Mbps_only ? "10Mbps" : "10/100Mbps", ether_sprintf(sc->arpcom.ac_enaddr)); +#endif /* * Attach the interface. @@ -436,6 +472,7 @@ fxp_attach(parent, self, aux) shutdownhook_establish(fxp_shutdown, sc); } +#if 0 static const char * fxp_phyname(device) int device; @@ -449,6 +486,7 @@ fxp_phyname(device) return(phynames[0]); return(phynames[device]); } +#endif /* * Device shutdown routine. Called at system shutdown after sync. The @@ -1237,7 +1275,7 @@ fxp_init(xsc) struct fxp_cb_config *cbp; struct fxp_cb_ias *cb_ias; struct fxp_cb_tx *txp; - int i, s, prm, oldmdi; + int i, s, prm; s = splimp(); /* @@ -1377,80 +1415,10 @@ fxp_init(xsc) vtophys(sc->rfa_headm->m_ext.ext_buf) + RFA_ALIGNMENT_FUDGE); CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_RU_START); - oldmdi = sc->phy_settings; - /* - * Toggle a few bits in the PHY. + * Set current media. */ - switch (sc->phy_primary_device) { - case FXP_PHY_DP83840: - case FXP_PHY_DP83840A: - fxp_mdi_write(sc, sc->phy_primary_addr, FXP_DP83840_PCR, - fxp_mdi_read(sc, sc->phy_primary_addr, FXP_DP83840_PCR) | - FXP_DP83840_PCR_LED4_MODE | /* LED4 always indicates duplex */ - FXP_DP83840_PCR_F_CONNECT | /* force link disconnect bypass */ - FXP_DP83840_PCR_BIT10); /* XXX I have no idea */ - /* fallthrough */ - case FXP_PHY_82553A: - case FXP_PHY_82553C: - case FXP_PHY_82555: - case FXP_PHY_82555B: - /* - * If link0 is set, disable auto-negotiation and then: - * If link1 is unset = 10Mbps - * If link1 is set = 100Mbps - * If link2 is unset = half duplex - * If link2 is set = full duplex - * XXX THIS IS BEGGING FOR IF_MEDIA! - */ - if (ifp->if_flags & IFF_LINK0) { - int flags; - - flags = (ifp->if_flags & IFF_LINK1) ? - FXP_PHY_BMCR_SPEED_100M : 0; - flags |= (ifp->if_flags & IFF_LINK2) ? - FXP_PHY_BMCR_FULLDUPLEX : 0; - fxp_mdi_write(sc, sc->phy_primary_addr, - FXP_PHY_BMCR, - (fxp_mdi_read(sc, sc->phy_primary_addr, - FXP_PHY_BMCR) & - ~(FXP_PHY_BMCR_AUTOEN | - FXP_PHY_BMCR_SPEED_100M | - FXP_PHY_BMCR_FULLDUPLEX)) | flags); - } else { - fxp_mdi_write(sc, sc->phy_primary_addr, - FXP_PHY_BMCR, - (fxp_mdi_read(sc, sc->phy_primary_addr, - FXP_PHY_BMCR) | - FXP_PHY_BMCR_AUTOEN)); - } - - sc->phy_settings = fxp_mdi_read(sc, sc->phy_primary_addr, - FXP_PHY_BMCR); - break; - /* - * The Seeq 80c24 doesn't have a PHY programming interface, so do - * nothing. - */ - case FXP_PHY_80C24: - break; - default: - printf(FXP_FORMAT - ": warning: unsupported PHY, type = %d, addr = %d\n", - FXP_ARGS(sc), sc->phy_primary_device, - sc->phy_primary_addr); - } - - if (oldmdi != sc->phy_settings) { - printf(FXP_FORMAT ": %s %s%s port\n", - FXP_ARGS(sc), - (sc->phy_settings & FXP_PHY_BMCR_AUTOEN) ? - "autosensing" : "enabling", - (sc->phy_settings & FXP_PHY_BMCR_FULLDUPLEX) ? - "full duplex " : "", - (sc->phy_settings & FXP_PHY_BMCR_SPEED_100M) ? - "100baseTX" : "10baseT"); - } + mii_mediachg(&sc->sc_mii); ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; @@ -1463,6 +1431,34 @@ fxp_init(xsc) } /* + * Change media according to request. + */ +int +fxp_mediachange(ifp) + struct ifnet *ifp; +{ + + if (ifp->if_flags & IFF_UP) + fxp_init(ifp->if_softc); + return (0); +} + +/* + * Notify the world which media we're using. + */ +void +fxp_mediastatus(ifp, ifmr) + struct ifnet *ifp; + struct ifmediareq *ifmr; +{ + struct fxp_softc *sc = ifp->if_softc; + + mii_pollstat(&sc->sc_mii); + ifmr->ifm_status = sc->sc_mii.mii_media_status; + ifmr->ifm_active = sc->sc_mii.mii_media_active; +} + +/* * Add a buffer to the end of the RFA buffer list. * Return 0 if successful, 1 for failure. A failure results in * adding the 'oldm' (if non-NULL) on to the end of the list - @@ -1548,11 +1544,12 @@ fxp_add_rfabuf(sc, oldm) } volatile int -fxp_mdi_read(sc, phy, reg) - struct fxp_softc *sc; +fxp_mdi_read(self, phy, reg) + struct device *self; int phy; int reg; { + struct fxp_softc *sc = (struct fxp_softc *)self; int count = 10000; int value; @@ -1570,13 +1567,22 @@ fxp_mdi_read(sc, phy, reg) return (value & 0xffff); } +static void +fxp_statchg(self) + struct device *self; +{ + + /* XXX Update ifp->if_baudrate */ +} + void -fxp_mdi_write(sc, phy, reg, value) - struct fxp_softc *sc; +fxp_mdi_write(self, phy, reg, value) + struct device *self; int phy; int reg; int value; { + struct fxp_softc *sc = (struct fxp_softc *)self; int count = 10000; CSR_WRITE_4(sc, FXP_CSR_MDICONTROL, @@ -1599,6 +1605,7 @@ fxp_ioctl(ifp, command, data) caddr_t data; { struct fxp_softc *sc = ifp->if_softc; + struct ifreq *ifr = (struct ifreq *)data; int s, error = 0; s = splimp(); @@ -1634,9 +1641,6 @@ fxp_ioctl(ifp, command, data) case SIOCDELMULTI: sc->all_mcasts = (ifp->if_flags & IFF_ALLMULTI) ? 1 : 0; #if defined(__NetBSD__) || defined(__OpenBSD__) - { - struct ifreq *ifr = (struct ifreq *) data; - #if defined(__OpenBSD__) error = (command == SIOCADDMULTI) ? ether_addmulti(ifr, &sc->arpcom) : @@ -1662,7 +1666,6 @@ fxp_ioctl(ifp, command, data) fxp_init(sc); error = 0; } - } #else /* __FreeBSD__ */ /* * Multicast list has changed; set the hardware filter @@ -1673,6 +1676,11 @@ fxp_ioctl(ifp, command, data) #endif /* __NetBSD__ || __OpenBSD__ */ break; + case SIOCSIFMEDIA: + case SIOCGIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, command); + break; + default: error = EINVAL; } |