Home | History | Annotate | Line # | Download | only in mii
ikphy.c revision 1.7
      1  1.7   xtraeme /*	$NetBSD: ikphy.c,v 1.7 2008/05/04 17:06:09 xtraeme Exp $	*/
      2  1.1    bouyer 
      3  1.1    bouyer /*******************************************************************************
      4  1.1    bouyer Copyright (c) 2001-2005, Intel Corporation
      5  1.1    bouyer All rights reserved.
      6  1.1    bouyer 
      7  1.1    bouyer Redistribution and use in source and binary forms, with or without
      8  1.1    bouyer modification, are permitted provided that the following conditions are met:
      9  1.1    bouyer 
     10  1.1    bouyer  1. Redistributions of source code must retain the above copyright notice,
     11  1.1    bouyer     this list of conditions and the following disclaimer.
     12  1.1    bouyer 
     13  1.1    bouyer  2. Redistributions in binary form must reproduce the above copyright
     14  1.1    bouyer     notice, this list of conditions and the following disclaimer in the
     15  1.1    bouyer     documentation and/or other materials provided with the distribution.
     16  1.1    bouyer 
     17  1.1    bouyer  3. Neither the name of the Intel Corporation nor the names of its
     18  1.1    bouyer     contributors may be used to endorse or promote products derived from
     19  1.1    bouyer     this software without specific prior written permission.
     20  1.1    bouyer 
     21  1.1    bouyer THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     22  1.1    bouyer AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  1.1    bouyer IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  1.1    bouyer ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     25  1.1    bouyer LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     26  1.1    bouyer CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     27  1.1    bouyer SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     28  1.1    bouyer INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     29  1.1    bouyer CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     30  1.1    bouyer ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     31  1.1    bouyer POSSIBILITY OF SUCH DAMAGE.
     32  1.1    bouyer *******************************************************************************/
     33  1.1    bouyer /*
     34  1.1    bouyer  * Copyright (c) 2006 Manuel Bouyer.  All rights reserved.
     35  1.1    bouyer  *
     36  1.1    bouyer  * Redistribution and use in source and binary forms, with or without
     37  1.1    bouyer  * modification, are permitted provided that the following conditions
     38  1.1    bouyer  * are met:
     39  1.1    bouyer  * 1. Redistributions of source code must retain the above copyright
     40  1.1    bouyer  *    notice, this list of conditions and the following disclaimer.
     41  1.1    bouyer  * 2. Redistributions in binary form must reproduce the above copyright
     42  1.1    bouyer  *    notice, this list of conditions and the following disclaimer in the
     43  1.1    bouyer  *    documentation and/or other materials provided with the distribution.
     44  1.1    bouyer  * 3. All advertising materials mentioning features or use of this software
     45  1.1    bouyer  *    must display the following acknowledgement:
     46  1.1    bouyer  *	This product includes software developed by Manuel Bouyer.
     47  1.1    bouyer  * 4. The name of the author may not be used to endorse or promote products
     48  1.1    bouyer  *    derived from this software without specific prior written permission.
     49  1.1    bouyer  *
     50  1.1    bouyer  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     51  1.1    bouyer  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     52  1.1    bouyer  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     53  1.1    bouyer  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     54  1.1    bouyer  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     55  1.1    bouyer  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     56  1.1    bouyer  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     57  1.1    bouyer  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     58  1.1    bouyer  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     59  1.1    bouyer  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     60  1.1    bouyer  */
     61  1.1    bouyer 
     62  1.1    bouyer /*
     63  1.1    bouyer  * driver for Intel's i82563 ethernet 10/100/1000 PHY
     64  1.1    bouyer  */
     65  1.1    bouyer 
     66  1.1    bouyer #include <sys/cdefs.h>
     67  1.7   xtraeme __KERNEL_RCSID(0, "$NetBSD: ikphy.c,v 1.7 2008/05/04 17:06:09 xtraeme Exp $");
     68  1.1    bouyer 
     69  1.1    bouyer #include <sys/param.h>
     70  1.1    bouyer #include <sys/systm.h>
     71  1.1    bouyer #include <sys/kernel.h>
     72  1.1    bouyer #include <sys/device.h>
     73  1.1    bouyer #include <sys/socket.h>
     74  1.1    bouyer #include <sys/errno.h>
     75  1.1    bouyer 
     76  1.1    bouyer #include <net/if.h>
     77  1.1    bouyer #include <net/if_media.h>
     78  1.1    bouyer 
     79  1.1    bouyer #include <dev/mii/mii.h>
     80  1.1    bouyer #include <dev/mii/miivar.h>
     81  1.1    bouyer #include <dev/mii/miidevs.h>
     82  1.1    bouyer 
     83  1.1    bouyer #include <dev/mii/ikphyreg.h>
     84  1.1    bouyer 
     85  1.7   xtraeme static int	ikphymatch(device_t, cfdata_t, void *);
     86  1.7   xtraeme static void	ikphyattach(device_t, device_t, void *);
     87  1.1    bouyer 
     88  1.7   xtraeme CFATTACH_DECL_NEW(ikphy, sizeof(struct mii_softc),
     89  1.1    bouyer     ikphymatch, ikphyattach, mii_phy_detach, mii_phy_activate);
     90  1.1    bouyer 
     91  1.1    bouyer static int	ikphy_service(struct mii_softc *, struct mii_data *, int);
     92  1.1    bouyer static void	ikphy_status(struct mii_softc *);
     93  1.1    bouyer static void	ikphy_setmedia(struct mii_softc *);
     94  1.1    bouyer 
     95  1.1    bouyer static const struct mii_phy_funcs ikphy_funcs = {
     96  1.1    bouyer 	ikphy_service, ikphy_status, mii_phy_reset,
     97  1.1    bouyer };
     98  1.1    bouyer 
     99  1.1    bouyer static const struct mii_phydesc ikphys[] = {
    100  1.1    bouyer 	{ MII_OUI_xxMARVELL,		MII_MODEL_xxMARVELL_I82563,
    101  1.1    bouyer 	  MII_STR_xxMARVELL_I82563 },
    102  1.1    bouyer 
    103  1.1    bouyer 	{ 0,				0,
    104  1.1    bouyer 	  NULL },
    105  1.1    bouyer };
    106  1.1    bouyer 
    107  1.1    bouyer static int
    108  1.7   xtraeme ikphymatch(device_t parent, cfdata_t match, void *aux)
    109  1.1    bouyer {
    110  1.1    bouyer 	struct mii_attach_args *ma = aux;
    111  1.1    bouyer 
    112  1.1    bouyer 	if (mii_phy_match(ma, ikphys) != NULL)
    113  1.1    bouyer 		return (10);
    114  1.1    bouyer 
    115  1.1    bouyer 	return (0);
    116  1.1    bouyer }
    117  1.1    bouyer 
    118  1.1    bouyer static void
    119  1.7   xtraeme ikphyattach(device_t parent, device_t self, void *aux)
    120  1.1    bouyer {
    121  1.1    bouyer 	struct mii_softc *sc = device_private(self);
    122  1.1    bouyer 	struct mii_attach_args *ma = aux;
    123  1.1    bouyer 	struct mii_data *mii = ma->mii_data;
    124  1.1    bouyer 	const struct mii_phydesc *mpd;
    125  1.1    bouyer 
    126  1.1    bouyer 	mpd = mii_phy_match(ma, ikphys);
    127  1.1    bouyer 	aprint_naive(": Media interface\n");
    128  1.1    bouyer 	aprint_normal(": %s, rev. %d\n", mpd->mpd_name, MII_REV(ma->mii_id2));
    129  1.1    bouyer 
    130  1.7   xtraeme 	sc->mii_dev = self;
    131  1.1    bouyer 	sc->mii_inst = mii->mii_instance;
    132  1.1    bouyer 	sc->mii_phy = ma->mii_phyno;
    133  1.1    bouyer 	sc->mii_funcs = &ikphy_funcs;
    134  1.1    bouyer 	sc->mii_pdata = mii;
    135  1.1    bouyer 	sc->mii_flags = ma->mii_flags;
    136  1.3  christos 	sc->mii_anegticks = MII_ANEGTICKS;
    137  1.1    bouyer 
    138  1.1    bouyer 	PHY_RESET(sc);
    139  1.1    bouyer 
    140  1.1    bouyer 	sc->mii_capabilities =
    141  1.1    bouyer 	    PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
    142  1.1    bouyer 	if (sc->mii_capabilities & BMSR_EXTSTAT)
    143  1.1    bouyer 	    sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
    144  1.7   xtraeme 	aprint_normal_dev(self, "");
    145  1.1    bouyer 	if ((sc->mii_capabilities & BMSR_MEDIAMASK) == 0 &&
    146  1.1    bouyer 	    (sc->mii_extcapabilities & EXTSR_MEDIAMASK) == 0)
    147  1.1    bouyer 		aprint_error("no media present");
    148  1.1    bouyer 	else
    149  1.1    bouyer 		mii_phy_add_media(sc);
    150  1.1    bouyer 	aprint_normal("\n");
    151  1.4  jmcneill 
    152  1.4  jmcneill 	if (!pmf_device_register(self, NULL, mii_phy_resume))
    153  1.4  jmcneill 		aprint_error_dev(self, "couldn't establish power handler\n");
    154  1.1    bouyer }
    155  1.1    bouyer 
    156  1.1    bouyer static int
    157  1.1    bouyer ikphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
    158  1.1    bouyer {
    159  1.1    bouyer 	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
    160  1.1    bouyer 	int reg;
    161  1.1    bouyer 
    162  1.1    bouyer 	switch (cmd) {
    163  1.1    bouyer 	case MII_POLLSTAT:
    164  1.1    bouyer 		/*
    165  1.1    bouyer 		 * If we're not polling our PHY instance, just return.
    166  1.1    bouyer 		 */
    167  1.1    bouyer 		if (IFM_INST(ife->ifm_media) != sc->mii_inst)
    168  1.1    bouyer 			return (0);
    169  1.1    bouyer 		break;
    170  1.1    bouyer 
    171  1.1    bouyer 	case MII_MEDIACHG:
    172  1.1    bouyer 		/*
    173  1.1    bouyer 		 * If the media indicates a different PHY instance,
    174  1.1    bouyer 		 * isolate ourselves.
    175  1.1    bouyer 		 */
    176  1.1    bouyer 		if (IFM_INST(ife->ifm_media) != sc->mii_inst) {
    177  1.1    bouyer 			reg = PHY_READ(sc, MII_BMCR);
    178  1.1    bouyer 			PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
    179  1.1    bouyer 			return (0);
    180  1.1    bouyer 		}
    181  1.1    bouyer 
    182  1.1    bouyer 		/*
    183  1.1    bouyer 		 * If the interface is not up, don't do anything.
    184  1.1    bouyer 		 */
    185  1.1    bouyer 		if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
    186  1.1    bouyer 			break;
    187  1.1    bouyer 
    188  1.1    bouyer 		ikphy_setmedia(sc);
    189  1.1    bouyer 		break;
    190  1.1    bouyer 
    191  1.1    bouyer 	case MII_TICK:
    192  1.1    bouyer 		/*
    193  1.1    bouyer 		 * If we're not currently selected, just return.
    194  1.1    bouyer 		 */
    195  1.1    bouyer 		if (IFM_INST(ife->ifm_media) != sc->mii_inst)
    196  1.1    bouyer 			return (0);
    197  1.1    bouyer 
    198  1.1    bouyer 		if (mii_phy_tick(sc) == EJUSTRETURN)
    199  1.1    bouyer 			return (0);
    200  1.1    bouyer 		break;
    201  1.1    bouyer 
    202  1.1    bouyer 	case MII_DOWN:
    203  1.1    bouyer 		mii_phy_down(sc);
    204  1.1    bouyer 		return (0);
    205  1.1    bouyer 	}
    206  1.1    bouyer 
    207  1.1    bouyer 	/* Update the media status. */
    208  1.1    bouyer 	mii_phy_status(sc);
    209  1.1    bouyer 
    210  1.1    bouyer 	/* Callback if something changed. */
    211  1.1    bouyer 	mii_phy_update(sc, cmd);
    212  1.1    bouyer 	return (0);
    213  1.1    bouyer }
    214  1.1    bouyer 
    215  1.1    bouyer static void
    216  1.1    bouyer ikphy_setmedia(struct mii_softc *sc)
    217  1.1    bouyer {
    218  1.1    bouyer 	uint16_t phy_data;
    219  1.1    bouyer 	struct mii_data *mii = sc->mii_pdata;
    220  1.1    bouyer 	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
    221  1.1    bouyer 
    222  1.1    bouyer 	/* Enable CRS on TX for half-duplex operation. */
    223  1.1    bouyer 	phy_data = PHY_READ(sc, GG82563_PHY_MAC_SPEC_CTRL);
    224  1.1    bouyer 	phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
    225  1.1    bouyer 	/* Use 25MHz for both link down and 1000BASE-T for Tx clock */
    226  1.1    bouyer 	phy_data |= GG82563_MSCR_TX_CLK_1000MBPS_25MHZ;
    227  1.1    bouyer 	PHY_WRITE(sc, GG82563_PHY_MAC_SPEC_CTRL, phy_data);
    228  1.1    bouyer 
    229  1.1    bouyer 	/* set mdi/mid-x options */
    230  1.1    bouyer 	phy_data = PHY_READ(sc, GG82563_PHY_SPEC_CTRL);
    231  1.1    bouyer 	phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK;
    232  1.1    bouyer 	if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO)
    233  1.1    bouyer 		phy_data |= GG82563_PSCR_CROSSOVER_MODE_AUTO;
    234  1.1    bouyer 	else
    235  1.1    bouyer 		phy_data |= GG82563_PSCR_CROSSOVER_MODE_MDI;
    236  1.1    bouyer 	/* set polarity correction */
    237  1.1    bouyer 	phy_data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE;
    238  1.1    bouyer 	PHY_WRITE(sc, GG82563_PHY_SPEC_CTRL, phy_data);
    239  1.1    bouyer 
    240  1.1    bouyer 	/* SW Reset the PHY so all changes take effect */
    241  1.1    bouyer 	PHY_RESET(sc);
    242  1.1    bouyer 
    243  1.1    bouyer 	/* for the i80003 */
    244  1.1    bouyer 	phy_data = PHY_READ(sc, GG82563_PHY_SPEC_CTRL_2);
    245  1.1    bouyer 	phy_data &= ~GG82563_PSCR2_REVERSE_AUTO_NEG;
    246  1.1    bouyer 	PHY_WRITE(sc, GG82563_PHY_SPEC_CTRL_2, phy_data);
    247  1.1    bouyer 
    248  1.1    bouyer 	/* Enable Electrical Idle on the PHY */
    249  1.1    bouyer 	phy_data = PHY_READ(sc, GG82563_PHY_PWR_MGMT_CTRL);
    250  1.1    bouyer 	phy_data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE;
    251  1.1    bouyer 	PHY_WRITE(sc, GG82563_PHY_PWR_MGMT_CTRL, phy_data);
    252  1.1    bouyer 
    253  1.1    bouyer 	phy_data = PHY_READ(sc, GG82563_PHY_KMRN_MODE_CTRL);
    254  1.1    bouyer 	phy_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
    255  1.1    bouyer 	PHY_WRITE(sc, GG82563_PHY_KMRN_MODE_CTRL, phy_data);
    256  1.1    bouyer 
    257  1.1    bouyer 	/*
    258  1.1    bouyer 	 * Workaround: Disable padding in Kumeran interface in the MAC
    259  1.1    bouyer 	 * and in the PHY to avoid CRC errors.
    260  1.1    bouyer 	 */
    261  1.1    bouyer 	phy_data = PHY_READ(sc, GG82563_PHY_INBAND_CTRL);
    262  1.1    bouyer 	phy_data |= GG82563_ICR_DIS_PADDING;
    263  1.1    bouyer 	PHY_WRITE(sc, GG82563_PHY_INBAND_CTRL, phy_data);
    264  1.1    bouyer 
    265  1.1    bouyer 	mii_phy_setmedia(sc);
    266  1.1    bouyer 	if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) {
    267  1.1    bouyer 		/*
    268  1.1    bouyer 		 * when not in auto mode, we need to restart nego
    269  1.1    bouyer 		 * anyway, or a switch from a fixed mode to another
    270  1.1    bouyer 		 * fixed mode may not be seen by the switch.
    271  1.1    bouyer 		 */
    272  1.1    bouyer 		PHY_WRITE(sc, MII_BMCR,
    273  1.1    bouyer 		    PHY_READ(sc, MII_BMCR) | BMCR_STARTNEG);
    274  1.1    bouyer 	}
    275  1.1    bouyer 	phy_data = PHY_READ(sc, GG82563_PHY_MAC_SPEC_CTRL);
    276  1.1    bouyer 	phy_data &= ~GG82563_MSCR_TX_CLK_MASK;
    277  1.1    bouyer 	switch(IFM_SUBTYPE(ife->ifm_media)) {
    278  1.1    bouyer 	case IFM_10_T:
    279  1.1    bouyer 		phy_data |= GG82563_MSCR_TX_CLK_10MBPS_2_5MHZ;
    280  1.1    bouyer 		break;
    281  1.1    bouyer 	case IFM_100_TX:
    282  1.1    bouyer 		phy_data |= GG82563_MSCR_TX_CLK_100MBPS_25MHZ;
    283  1.1    bouyer 		break;
    284  1.1    bouyer 	case IFM_1000_T:
    285  1.1    bouyer 		phy_data |= GG82563_MSCR_TX_CLK_1000MBPS_25MHZ;
    286  1.1    bouyer 		break;
    287  1.1    bouyer 	}
    288  1.1    bouyer 	phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
    289  1.1    bouyer 	PHY_WRITE(sc, GG82563_PHY_MAC_SPEC_CTRL, phy_data);
    290  1.1    bouyer }
    291  1.1    bouyer 
    292  1.1    bouyer static void
    293  1.1    bouyer ikphy_status(struct mii_softc *sc)
    294  1.1    bouyer {
    295  1.1    bouyer 	struct mii_data *mii = sc->mii_pdata;
    296  1.1    bouyer 	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
    297  1.1    bouyer 	int pssr, bmcr, gtsr, kmrn;
    298  1.1    bouyer 
    299  1.1    bouyer 	mii->mii_media_status = IFM_AVALID;
    300  1.1    bouyer 	mii->mii_media_active = IFM_ETHER;
    301  1.1    bouyer 
    302  1.1    bouyer 	pssr = PHY_READ(sc, GG82563_PHY_SPEC_STATUS);
    303  1.1    bouyer 
    304  1.1    bouyer 	if (pssr & GG82563_PSSR_LINK)
    305  1.1    bouyer 		mii->mii_media_status |= IFM_ACTIVE;
    306  1.1    bouyer 
    307  1.1    bouyer 	bmcr = PHY_READ(sc, MII_BMCR);
    308  1.1    bouyer 	if (bmcr & BMCR_ISO) {
    309  1.1    bouyer 		mii->mii_media_active |= IFM_NONE;
    310  1.1    bouyer 		mii->mii_media_status = 0;
    311  1.1    bouyer 		return;
    312  1.1    bouyer 	}
    313  1.1    bouyer 
    314  1.1    bouyer 	if (bmcr & BMCR_LOOP)
    315  1.1    bouyer 		mii->mii_media_active |= IFM_LOOP;
    316  1.1    bouyer 
    317  1.1    bouyer 	if (bmcr & BMCR_AUTOEN) {
    318  1.1    bouyer 		/*
    319  1.1    bouyer 		 * The media status bits are only valid of autonegotiation
    320  1.1    bouyer 		 * has completed (or it's disabled).
    321  1.1    bouyer 		 */
    322  1.1    bouyer 		if ((pssr & GG82563_PSSR_SPEED_DUPLEX_RESOLVED) == 0) {
    323  1.1    bouyer 			/* Erg, still trying, I guess... */
    324  1.1    bouyer 			mii->mii_media_active |= IFM_NONE;
    325  1.1    bouyer 			return;
    326  1.1    bouyer 		}
    327  1.1    bouyer 
    328  1.1    bouyer 		switch (pssr & GG82563_PSSR_SPEED_MASK) {
    329  1.1    bouyer 		case GG82563_PSSR_SPEED_1000MBPS:
    330  1.1    bouyer 			mii->mii_media_active |= IFM_1000_T;
    331  1.1    bouyer 			gtsr = PHY_READ(sc, MII_100T2SR);
    332  1.1    bouyer 			if (gtsr & GTSR_MS_RES)
    333  1.1    bouyer 				mii->mii_media_active |= IFM_ETH_MASTER;
    334  1.1    bouyer 			break;
    335  1.1    bouyer 
    336  1.1    bouyer 		case GG82563_PSSR_SPEED_100MBPS:
    337  1.1    bouyer 			mii->mii_media_active |= IFM_100_TX;
    338  1.1    bouyer 			break;
    339  1.1    bouyer 
    340  1.1    bouyer 		case GG82563_PSSR_SPEED_10MBPS:
    341  1.1    bouyer 			mii->mii_media_active |= IFM_10_T;
    342  1.1    bouyer 			break;
    343  1.1    bouyer 
    344  1.1    bouyer 		default:
    345  1.1    bouyer 			mii->mii_media_active |= IFM_NONE;
    346  1.1    bouyer 			mii->mii_media_status = 0;
    347  1.1    bouyer 			return;
    348  1.1    bouyer 		}
    349  1.1    bouyer 
    350  1.1    bouyer 		if (pssr & GG82563_PSSR_DUPLEX)
    351  1.1    bouyer 			mii->mii_media_active |=
    352  1.1    bouyer 			    IFM_FDX | mii_phy_flowstatus(sc);
    353  1.1    bouyer 	} else
    354  1.1    bouyer 		mii->mii_media_active = ife->ifm_media;
    355  1.1    bouyer 	kmrn = PHY_READ(sc, GG82563_PHY_KMRN_MODE_CTRL);
    356  1.1    bouyer 	if (mii->mii_media_active & IFM_FDX)
    357  1.1    bouyer 		kmrn &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
    358  1.1    bouyer 	else
    359  1.1    bouyer 		kmrn |= GG82563_KMCR_PASS_FALSE_CARRIER;
    360  1.1    bouyer 	PHY_WRITE(sc, GG82563_PHY_KMRN_MODE_CTRL, kmrn);
    361  1.1    bouyer }
    362