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