Home | History | Annotate | Line # | Download | only in mii
igphy.c revision 1.3.2.3
      1  1.3.2.3  skrll /*	$NetBSD: igphy.c,v 1.3.2.3 2004/08/25 06:58:05 skrll Exp $	*/
      2  1.3.2.2  skrll 
      3  1.3.2.2  skrll /*
      4  1.3.2.2  skrll  * The Intel copyright applies to the analog register setup, and the
      5  1.3.2.2  skrll  * (currently disabled) SmartSpeed workaround code.
      6  1.3.2.2  skrll  */
      7  1.3.2.2  skrll 
      8  1.3.2.2  skrll /*******************************************************************************
      9  1.3.2.2  skrll 
     10  1.3.2.2  skrll   Copyright (c) 2001-2003, Intel Corporation
     11  1.3.2.2  skrll   All rights reserved.
     12  1.3.2.2  skrll 
     13  1.3.2.2  skrll   Redistribution and use in source and binary forms, with or without
     14  1.3.2.2  skrll   modification, are permitted provided that the following conditions are met:
     15  1.3.2.2  skrll 
     16  1.3.2.2  skrll    1. Redistributions of source code must retain the above copyright notice,
     17  1.3.2.2  skrll       this list of conditions and the following disclaimer.
     18  1.3.2.2  skrll 
     19  1.3.2.2  skrll    2. Redistributions in binary form must reproduce the above copyright
     20  1.3.2.2  skrll       notice, this list of conditions and the following disclaimer in the
     21  1.3.2.2  skrll       documentation and/or other materials provided with the distribution.
     22  1.3.2.2  skrll 
     23  1.3.2.2  skrll    3. Neither the name of the Intel Corporation nor the names of its
     24  1.3.2.2  skrll       contributors may be used to endorse or promote products derived from
     25  1.3.2.2  skrll       this software without specific prior written permission.
     26  1.3.2.2  skrll 
     27  1.3.2.2  skrll   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     28  1.3.2.2  skrll   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     29  1.3.2.2  skrll   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     30  1.3.2.2  skrll   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     31  1.3.2.2  skrll   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32  1.3.2.2  skrll   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33  1.3.2.2  skrll   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     34  1.3.2.2  skrll   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     35  1.3.2.2  skrll   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     36  1.3.2.2  skrll   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     37  1.3.2.2  skrll   POSSIBILITY OF SUCH DAMAGE.
     38  1.3.2.2  skrll 
     39  1.3.2.2  skrll *******************************************************************************/
     40  1.3.2.2  skrll 
     41  1.3.2.2  skrll 
     42  1.3.2.2  skrll /*-
     43  1.3.2.2  skrll  * Copyright (c) 1998, 1999, 2000, 2003 The NetBSD Foundation, Inc.
     44  1.3.2.2  skrll  * All rights reserved.
     45  1.3.2.2  skrll  *
     46  1.3.2.2  skrll  * This code is derived from software contributed to The NetBSD Foundation
     47  1.3.2.2  skrll  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
     48  1.3.2.2  skrll  * NASA Ames Research Center, and by Frank van der Linden.
     49  1.3.2.2  skrll  *
     50  1.3.2.2  skrll  * Redistribution and use in source and binary forms, with or without
     51  1.3.2.2  skrll  * modification, are permitted provided that the following conditions
     52  1.3.2.2  skrll  * are met:
     53  1.3.2.2  skrll  * 1. Redistributions of source code must retain the above copyright
     54  1.3.2.2  skrll  *    notice, this list of conditions and the following disclaimer.
     55  1.3.2.2  skrll  * 2. Redistributions in binary form must reproduce the above copyright
     56  1.3.2.2  skrll  *    notice, this list of conditions and the following disclaimer in the
     57  1.3.2.2  skrll  *    documentation and/or other materials provided with the distribution.
     58  1.3.2.2  skrll  * 3. All advertising materials mentioning features or use of this software
     59  1.3.2.2  skrll  *    must display the following acknowledgement:
     60  1.3.2.2  skrll  *	This product includes software developed by the NetBSD
     61  1.3.2.2  skrll  *	Foundation, Inc. and its contributors.
     62  1.3.2.2  skrll  * 4. Neither the name of The NetBSD Foundation nor the names of its
     63  1.3.2.2  skrll  *    contributors may be used to endorse or promote products derived
     64  1.3.2.2  skrll  *    from this software without specific prior written permission.
     65  1.3.2.2  skrll  *
     66  1.3.2.2  skrll  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     67  1.3.2.2  skrll  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     68  1.3.2.2  skrll  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     69  1.3.2.2  skrll  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     70  1.3.2.2  skrll  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     71  1.3.2.2  skrll  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     72  1.3.2.2  skrll  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     73  1.3.2.2  skrll  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     74  1.3.2.2  skrll  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     75  1.3.2.2  skrll  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     76  1.3.2.2  skrll  * POSSIBILITY OF SUCH DAMAGE.
     77  1.3.2.2  skrll  */
     78  1.3.2.2  skrll 
     79  1.3.2.2  skrll #include <sys/cdefs.h>
     80  1.3.2.3  skrll __KERNEL_RCSID(0, "$NetBSD: igphy.c,v 1.3.2.3 2004/08/25 06:58:05 skrll Exp $");
     81  1.3.2.2  skrll 
     82  1.3.2.2  skrll #include "opt_mii.h"
     83  1.3.2.2  skrll 
     84  1.3.2.2  skrll #include <sys/param.h>
     85  1.3.2.2  skrll #include <sys/systm.h>
     86  1.3.2.2  skrll #include <sys/kernel.h>
     87  1.3.2.2  skrll #include <sys/device.h>
     88  1.3.2.2  skrll #include <sys/socket.h>
     89  1.3.2.2  skrll #include <sys/errno.h>
     90  1.3.2.2  skrll 
     91  1.3.2.2  skrll #include <net/if.h>
     92  1.3.2.2  skrll #include <net/if_media.h>
     93  1.3.2.2  skrll 
     94  1.3.2.2  skrll #include <dev/mii/mii.h>
     95  1.3.2.2  skrll #include <dev/mii/miivar.h>
     96  1.3.2.2  skrll #include <dev/mii/miidevs.h>
     97  1.3.2.2  skrll 
     98  1.3.2.2  skrll #include <dev/mii/igphyreg.h>
     99  1.3.2.2  skrll 
    100  1.3.2.2  skrll static void igphy_reset(struct mii_softc *);
    101  1.3.2.2  skrll static void igphy_load_dspcode(struct mii_softc *);
    102  1.3.2.2  skrll #if 0
    103  1.3.2.2  skrll static void igphy_smartspeed_workaround(struct mii_softc *sc);
    104  1.3.2.2  skrll #endif
    105  1.3.2.2  skrll 
    106  1.3.2.3  skrll static int	igphymatch(struct device *, struct cfdata *, void *);
    107  1.3.2.3  skrll static void	igphyattach(struct device *, struct device *, void *);
    108  1.3.2.2  skrll 
    109  1.3.2.2  skrll CFATTACH_DECL(igphy, sizeof(struct mii_softc),
    110  1.3.2.2  skrll     igphymatch, igphyattach, mii_phy_detach, mii_phy_activate);
    111  1.3.2.2  skrll 
    112  1.3.2.3  skrll static int	igphy_service(struct mii_softc *, struct mii_data *, int);
    113  1.3.2.3  skrll static void	igphy_status(struct mii_softc *);
    114  1.3.2.2  skrll 
    115  1.3.2.3  skrll static const struct mii_phy_funcs igphy_funcs = {
    116  1.3.2.2  skrll 	igphy_service, igphy_status, igphy_reset,
    117  1.3.2.2  skrll };
    118  1.3.2.2  skrll 
    119  1.3.2.3  skrll static const struct mii_phydesc igphys[] = {
    120  1.3.2.2  skrll 	{ MII_OUI_yyINTEL,		MII_MODEL_yyINTEL_IGP01E1000,
    121  1.3.2.2  skrll 	  MII_STR_yyINTEL_IGP01E1000 },
    122  1.3.2.2  skrll 
    123  1.3.2.2  skrll 	{0,				0,
    124  1.3.2.2  skrll 	 NULL },
    125  1.3.2.2  skrll };
    126  1.3.2.2  skrll 
    127  1.3.2.3  skrll static int
    128  1.3.2.2  skrll igphymatch(struct device *parent, struct cfdata *match, void *aux)
    129  1.3.2.2  skrll {
    130  1.3.2.2  skrll 	struct mii_attach_args *ma = aux;
    131  1.3.2.2  skrll 
    132  1.3.2.2  skrll 	if (mii_phy_match(ma, igphys) != NULL)
    133  1.3.2.2  skrll 		return 10;
    134  1.3.2.2  skrll 
    135  1.3.2.2  skrll 	return 0;
    136  1.3.2.2  skrll }
    137  1.3.2.2  skrll 
    138  1.3.2.3  skrll static void
    139  1.3.2.2  skrll igphyattach(struct device *parent, struct device *self, void *aux)
    140  1.3.2.2  skrll {
    141  1.3.2.2  skrll 	struct mii_softc *sc = (struct mii_softc *)self;
    142  1.3.2.2  skrll 	struct mii_attach_args *ma = aux;
    143  1.3.2.2  skrll 	struct mii_data *mii = ma->mii_data;
    144  1.3.2.2  skrll 	const struct mii_phydesc *mpd;
    145  1.3.2.2  skrll 
    146  1.3.2.2  skrll 	mpd = mii_phy_match(ma, igphys);
    147  1.3.2.2  skrll 	aprint_naive(": Media interface\n");
    148  1.3.2.2  skrll 	aprint_normal(": %s, rev. %d\n", mpd->mpd_name, MII_REV(ma->mii_id2));
    149  1.3.2.2  skrll 
    150  1.3.2.2  skrll 	sc->mii_inst = mii->mii_instance;
    151  1.3.2.2  skrll 	sc->mii_phy = ma->mii_phyno;
    152  1.3.2.2  skrll 	sc->mii_funcs = &igphy_funcs;
    153  1.3.2.2  skrll 	sc->mii_pdata = mii;
    154  1.3.2.2  skrll 	sc->mii_flags = ma->mii_flags;
    155  1.3.2.2  skrll 	sc->mii_anegticks = 10;
    156  1.3.2.2  skrll 
    157  1.3.2.2  skrll 	PHY_RESET(sc);
    158  1.3.2.2  skrll 
    159  1.3.2.2  skrll 	sc->mii_capabilities =
    160  1.3.2.2  skrll 	    PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
    161  1.3.2.2  skrll 	if (sc->mii_capabilities & BMSR_EXTSTAT)
    162  1.3.2.2  skrll 		sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
    163  1.3.2.2  skrll 	aprint_normal("%s: ", sc->mii_dev.dv_xname);
    164  1.3.2.2  skrll 	if ((sc->mii_capabilities & BMSR_MEDIAMASK) == 0 &&
    165  1.3.2.2  skrll 	    (sc->mii_extcapabilities & EXTSR_MEDIAMASK) == 0)
    166  1.3.2.2  skrll 		aprint_error("no media present");
    167  1.3.2.2  skrll 	else
    168  1.3.2.2  skrll 		mii_phy_add_media(sc);
    169  1.3.2.2  skrll 	aprint_normal("\n");
    170  1.3.2.2  skrll }
    171  1.3.2.2  skrll 
    172  1.3.2.2  skrll static void
    173  1.3.2.2  skrll igphy_load_dspcode(struct mii_softc *sc)
    174  1.3.2.2  skrll {
    175  1.3.2.2  skrll 	static const struct {
    176  1.3.2.2  skrll 		int reg;
    177  1.3.2.2  skrll 		uint16_t val;
    178  1.3.2.2  skrll 	} dspcode[] = {
    179  1.3.2.2  skrll 		{ 0x1f95, 0x0001 },
    180  1.3.2.2  skrll 		{ 0x1f71, 0xbd21 },
    181  1.3.2.2  skrll 		{ 0x1f79, 0x0018 },
    182  1.3.2.2  skrll 		{ 0x1f30, 0x1600 },
    183  1.3.2.2  skrll 		{ 0x1f31, 0x0014 },
    184  1.3.2.2  skrll 		{ 0x1f32, 0x161c },
    185  1.3.2.2  skrll 		{ 0x1f94, 0x0003 },
    186  1.3.2.2  skrll 		{ 0x1f96, 0x003f },
    187  1.3.2.2  skrll 		{ 0x2010, 0x0008 },
    188  1.3.2.2  skrll 		{ 0, 0 },
    189  1.3.2.2  skrll 	};
    190  1.3.2.2  skrll 	int i;
    191  1.3.2.2  skrll 
    192  1.3.2.2  skrll 	delay(10);
    193  1.3.2.2  skrll 
    194  1.3.2.2  skrll 	PHY_WRITE(sc, MII_IGPHY_PAGE_SELECT, 0x0000);
    195  1.3.2.2  skrll 	PHY_WRITE(sc, 0x0000, 0x0140);
    196  1.3.2.2  skrll 
    197  1.3.2.2  skrll 	delay(5);
    198  1.3.2.2  skrll 
    199  1.3.2.2  skrll 	for (i = 0; dspcode[i].reg != 0; i++)
    200  1.3.2.2  skrll 		IGPHY_WRITE(sc, dspcode[i].reg, dspcode[i].val);
    201  1.3.2.2  skrll 
    202  1.3.2.2  skrll 	PHY_WRITE(sc, MII_IGPHY_PAGE_SELECT,0x0000);
    203  1.3.2.2  skrll 	PHY_WRITE(sc, 0x0000, 0x3300);
    204  1.3.2.2  skrll }
    205  1.3.2.2  skrll 
    206  1.3.2.2  skrll static void
    207  1.3.2.2  skrll igphy_reset(struct mii_softc *sc)
    208  1.3.2.2  skrll {
    209  1.3.2.2  skrll 	uint16_t fused, fine, coarse;
    210  1.3.2.2  skrll 
    211  1.3.2.2  skrll 	mii_phy_reset(sc);
    212  1.3.2.2  skrll 	igphy_load_dspcode(sc);
    213  1.3.2.2  skrll 
    214  1.3.2.2  skrll 	fused = IGPHY_READ(sc, MII_IGPHY_ANALOG_SPARE_FUSE_STATUS);
    215  1.3.2.2  skrll 	if ((fused & ANALOG_SPARE_FUSE_ENABLED) == 0) {
    216  1.3.2.2  skrll 		fused = IGPHY_READ(sc, MII_IGPHY_ANALOG_FUSE_STATUS);
    217  1.3.2.2  skrll 
    218  1.3.2.2  skrll 		fine = fused & ANALOG_FUSE_FINE_MASK;
    219  1.3.2.2  skrll 		coarse = fused & ANALOG_FUSE_COARSE_MASK;
    220  1.3.2.2  skrll 
    221  1.3.2.2  skrll 		if (coarse > ANALOG_FUSE_COARSE_THRESH) {
    222  1.3.2.2  skrll 			coarse -= ANALOG_FUSE_COARSE_10;
    223  1.3.2.2  skrll 			fine -= ANALOG_FUSE_FINE_1;
    224  1.3.2.2  skrll 		} else if (coarse == ANALOG_FUSE_COARSE_THRESH)
    225  1.3.2.2  skrll 			fine -= ANALOG_FUSE_FINE_10;
    226  1.3.2.2  skrll 
    227  1.3.2.2  skrll 		fused = (fused & ANALOG_FUSE_POLY_MASK) |
    228  1.3.2.2  skrll 			(fine & ANALOG_FUSE_FINE_MASK) |
    229  1.3.2.2  skrll 			(coarse & ANALOG_FUSE_COARSE_MASK);
    230  1.3.2.2  skrll 
    231  1.3.2.2  skrll 		IGPHY_WRITE(sc, MII_IGPHY_ANALOG_FUSE_CONTROL, fused);
    232  1.3.2.2  skrll 		IGPHY_WRITE(sc, MII_IGPHY_ANALOG_FUSE_BYPASS,
    233  1.3.2.2  skrll 		    ANALOG_FUSE_ENABLE_SW_CONTROL);
    234  1.3.2.2  skrll 	}
    235  1.3.2.2  skrll 	PHY_WRITE(sc, MII_IGPHY_PAGE_SELECT,0x0000);
    236  1.3.2.2  skrll }
    237  1.3.2.2  skrll 
    238  1.3.2.2  skrll 
    239  1.3.2.3  skrll static int
    240  1.3.2.2  skrll igphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
    241  1.3.2.2  skrll {
    242  1.3.2.2  skrll 	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
    243  1.3.2.2  skrll 	uint16_t reg;
    244  1.3.2.2  skrll 
    245  1.3.2.2  skrll 	switch (cmd) {
    246  1.3.2.2  skrll 	case MII_POLLSTAT:
    247  1.3.2.2  skrll 		/*
    248  1.3.2.2  skrll 		 * If we're not polling our PHY instance, just return.
    249  1.3.2.2  skrll 		 */
    250  1.3.2.2  skrll 		if (IFM_INST(ife->ifm_media) != sc->mii_inst)
    251  1.3.2.2  skrll 			return (0);
    252  1.3.2.2  skrll 		break;
    253  1.3.2.2  skrll 
    254  1.3.2.2  skrll 	case MII_MEDIACHG:
    255  1.3.2.2  skrll 		/*
    256  1.3.2.2  skrll 		 * If the media indicates a different PHY instance,
    257  1.3.2.2  skrll 		 * isolate ourselves.
    258  1.3.2.2  skrll 		 */
    259  1.3.2.2  skrll 		if (IFM_INST(ife->ifm_media) != sc->mii_inst) {
    260  1.3.2.2  skrll 			reg = PHY_READ(sc, MII_BMCR);
    261  1.3.2.2  skrll 			PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
    262  1.3.2.2  skrll 			return (0);
    263  1.3.2.2  skrll 		}
    264  1.3.2.2  skrll 
    265  1.3.2.2  skrll 		/*
    266  1.3.2.2  skrll 		 * If the interface is not up, don't do anything.
    267  1.3.2.2  skrll 		 */
    268  1.3.2.2  skrll 		if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
    269  1.3.2.2  skrll 			break;
    270  1.3.2.2  skrll 
    271  1.3.2.2  skrll 		mii_phy_setmedia(sc);
    272  1.3.2.2  skrll 		break;
    273  1.3.2.2  skrll 
    274  1.3.2.2  skrll 	case MII_TICK:
    275  1.3.2.2  skrll 		/*
    276  1.3.2.2  skrll 		 * If we're not currently selected, just return.
    277  1.3.2.2  skrll 		 */
    278  1.3.2.2  skrll 		if (IFM_INST(ife->ifm_media) != sc->mii_inst)
    279  1.3.2.2  skrll 			return (0);
    280  1.3.2.2  skrll 
    281  1.3.2.2  skrll #if 0
    282  1.3.2.2  skrll 		igphy_smartspeed_workaround(sc);
    283  1.3.2.2  skrll #endif
    284  1.3.2.2  skrll 
    285  1.3.2.2  skrll 		if (mii_phy_tick(sc) == EJUSTRETURN)
    286  1.3.2.2  skrll 			return (0);
    287  1.3.2.2  skrll 		break;
    288  1.3.2.2  skrll 
    289  1.3.2.2  skrll 	case MII_DOWN:
    290  1.3.2.2  skrll 		mii_phy_down(sc);
    291  1.3.2.2  skrll 		return (0);
    292  1.3.2.2  skrll 	}
    293  1.3.2.2  skrll 
    294  1.3.2.2  skrll 	/* Update the media status. */
    295  1.3.2.2  skrll 	mii_phy_status(sc);
    296  1.3.2.2  skrll 
    297  1.3.2.2  skrll 	/* Callback if something changed. */
    298  1.3.2.2  skrll 	mii_phy_update(sc, cmd);
    299  1.3.2.2  skrll 	return (0);
    300  1.3.2.2  skrll }
    301  1.3.2.2  skrll 
    302  1.3.2.2  skrll 
    303  1.3.2.3  skrll static void
    304  1.3.2.2  skrll igphy_status(struct mii_softc *sc)
    305  1.3.2.2  skrll {
    306  1.3.2.2  skrll 	struct mii_data *mii = sc->mii_pdata;
    307  1.3.2.2  skrll 	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
    308  1.3.2.2  skrll 	uint16_t bmcr, pssr, gtsr, bmsr;
    309  1.3.2.2  skrll 
    310  1.3.2.2  skrll 	mii->mii_media_status = IFM_AVALID;
    311  1.3.2.2  skrll 	mii->mii_media_active = IFM_ETHER;
    312  1.3.2.2  skrll 
    313  1.3.2.2  skrll 	pssr = PHY_READ(sc, MII_IGPHY_PORT_STATUS);
    314  1.3.2.2  skrll 
    315  1.3.2.2  skrll 	if (pssr & PSSR_LINK_UP)
    316  1.3.2.2  skrll 		mii->mii_media_status |= IFM_ACTIVE;
    317  1.3.2.2  skrll 
    318  1.3.2.2  skrll 	bmcr = PHY_READ(sc, MII_BMCR);
    319  1.3.2.2  skrll 	if (bmcr & BMCR_ISO) {
    320  1.3.2.2  skrll 		mii->mii_media_active |= IFM_NONE;
    321  1.3.2.2  skrll 		mii->mii_media_status = 0;
    322  1.3.2.2  skrll 		return;
    323  1.3.2.2  skrll 	}
    324  1.3.2.2  skrll 
    325  1.3.2.2  skrll 	if (bmcr & BMCR_LOOP)
    326  1.3.2.2  skrll 		mii->mii_media_active |= IFM_LOOP;
    327  1.3.2.2  skrll 
    328  1.3.2.2  skrll 	bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
    329  1.3.2.2  skrll 
    330  1.3.2.2  skrll 	/*
    331  1.3.2.2  skrll 	 * XXX can't check if the info is valid, no
    332  1.3.2.2  skrll 	 * 'negotiation done' bit?
    333  1.3.2.2  skrll 	 */
    334  1.3.2.2  skrll 	if (bmcr & BMCR_AUTOEN) {
    335  1.3.2.2  skrll 		if ((bmsr & BMSR_ACOMP) == 0) {
    336  1.3.2.2  skrll 			mii->mii_media_active |= IFM_NONE;
    337  1.3.2.2  skrll 			return;
    338  1.3.2.2  skrll 		}
    339  1.3.2.2  skrll 		switch (pssr & PSSR_SPEED_MASK) {
    340  1.3.2.2  skrll 		case PSSR_SPEED_1000MBPS:
    341  1.3.2.2  skrll 			mii->mii_media_active |= IFM_1000_T;
    342  1.3.2.2  skrll 			gtsr = PHY_READ(sc, MII_100T2SR);
    343  1.3.2.2  skrll 			if (gtsr & GTSR_MS_RES)
    344  1.3.2.2  skrll 				mii->mii_media_active |= IFM_ETH_MASTER;
    345  1.3.2.2  skrll 			break;
    346  1.3.2.2  skrll 
    347  1.3.2.2  skrll 		case PSSR_SPEED_100MBPS:
    348  1.3.2.2  skrll 			mii->mii_media_active |= IFM_100_TX;
    349  1.3.2.2  skrll 			break;
    350  1.3.2.2  skrll 
    351  1.3.2.2  skrll 		case PSSR_SPEED_10MBPS:
    352  1.3.2.2  skrll 			mii->mii_media_active |= IFM_10_T;
    353  1.3.2.2  skrll 			break;
    354  1.3.2.2  skrll 
    355  1.3.2.2  skrll 		default:
    356  1.3.2.2  skrll 			mii->mii_media_active |= IFM_NONE;
    357  1.3.2.2  skrll 			mii->mii_media_status = 0;
    358  1.3.2.2  skrll 			return;
    359  1.3.2.2  skrll 		}
    360  1.3.2.2  skrll 
    361  1.3.2.2  skrll 		if (pssr & PSSR_FULL_DUPLEX)
    362  1.3.2.2  skrll 			mii->mii_media_active |=
    363  1.3.2.2  skrll 			    IFM_FDX | mii_phy_flowstatus(sc);
    364  1.3.2.2  skrll 	} else
    365  1.3.2.2  skrll 		mii->mii_media_active = ife->ifm_media;
    366  1.3.2.2  skrll }
    367  1.3.2.2  skrll 
    368  1.3.2.2  skrll #if 0
    369  1.3.2.2  skrll static void
    370  1.3.2.2  skrll igphy_smartspeed_workaround(struct mii_softc *sc)
    371  1.3.2.2  skrll {
    372  1.3.2.2  skrll 	uint16_t reg, gtsr, gctr;
    373  1.3.2.2  skrll 
    374  1.3.2.2  skrll 	reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
    375  1.3.2.2  skrll 	if (!(reg & BMSR_LINK)) {
    376  1.3.2.2  skrll 		switch (sc->mii_ticks) {
    377  1.3.2.2  skrll 		case 0:
    378  1.3.2.2  skrll 			gtsr = PHY_READ(sc, MII_100T2SR);
    379  1.3.2.2  skrll 			if (!(gtsr & GTSR_MAN_MS_FLT))
    380  1.3.2.2  skrll 				break;
    381  1.3.2.2  skrll 			gtsr = PHY_READ(sc, MII_100T2SR);
    382  1.3.2.2  skrll 			if (gtsr & GTSR_MAN_MS_FLT) {
    383  1.3.2.2  skrll 				gtcr = PHY_READ(sc, MII_100T2CR);
    384  1.3.2.2  skrll 				if (gtcr & GTCR_MAN_MS) {
    385  1.3.2.2  skrll 					gtcr &= ~GTCR_MAN_MS;
    386  1.3.2.2  skrll 					PHY_WRITE(sc, MII_100T2CR,
    387  1.3.2.2  skrll 					    gtcr);
    388  1.3.2.2  skrll 				}
    389  1.3.2.2  skrll 				mii_phy_auto(sc, 0);
    390  1.3.2.2  skrll 				sc->mii_ticks++;
    391  1.3.2.2  skrll 			}
    392  1.3.2.2  skrll 			break;
    393  1.3.2.2  skrll 		case IGPHY_TICK_DOWNSHIFT:
    394  1.3.2.2  skrll 			gtcr = PHY_READ(sc, MII_100T2CR);
    395  1.3.2.2  skrll 			gtcr |= GTCR_MAN_MS;
    396  1.3.2.2  skrll 			PHY_WRITE(sc, MII_100T2CR, gtcr);
    397  1.3.2.2  skrll 			mii_phy_auto(sc, 0);
    398  1.3.2.2  skrll 			break;
    399  1.3.2.2  skrll 		default:
    400  1.3.2.2  skrll 			break;
    401  1.3.2.2  skrll 		}
    402  1.3.2.2  skrll 	}
    403  1.3.2.2  skrll }
    404  1.3.2.2  skrll #endif
    405