Home | History | Annotate | Line # | Download | only in mii
ikphy.c revision 1.19
      1  1.19   thorpej /*	$NetBSD: ikphy.c,v 1.19 2020/03/15 23:04:50 thorpej 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.19   thorpej __KERNEL_RCSID(0, "$NetBSD: ikphy.c,v 1.19 2020/03/15 23:04:50 thorpej 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.14  christos 	MII_PHY_DESC(xxMARVELL, I82563),
     96  1.14  christos 	MII_PHY_END,
     97   1.1    bouyer };
     98   1.1    bouyer 
     99   1.1    bouyer static int
    100   1.7   xtraeme ikphymatch(device_t parent, cfdata_t match, void *aux)
    101   1.1    bouyer {
    102   1.1    bouyer 	struct mii_attach_args *ma = aux;
    103   1.1    bouyer 
    104   1.1    bouyer 	if (mii_phy_match(ma, ikphys) != NULL)
    105  1.15   msaitoh 		return 10;
    106   1.1    bouyer 
    107  1.15   msaitoh 	return 0;
    108   1.1    bouyer }
    109   1.1    bouyer 
    110   1.1    bouyer static void
    111   1.7   xtraeme ikphyattach(device_t parent, device_t self, void *aux)
    112   1.1    bouyer {
    113   1.1    bouyer 	struct mii_softc *sc = device_private(self);
    114   1.1    bouyer 	struct mii_attach_args *ma = aux;
    115   1.1    bouyer 	struct mii_data *mii = ma->mii_data;
    116   1.1    bouyer 	const struct mii_phydesc *mpd;
    117   1.1    bouyer 
    118   1.1    bouyer 	mpd = mii_phy_match(ma, ikphys);
    119   1.1    bouyer 	aprint_naive(": Media interface\n");
    120   1.1    bouyer 	aprint_normal(": %s, rev. %d\n", mpd->mpd_name, MII_REV(ma->mii_id2));
    121   1.1    bouyer 
    122   1.7   xtraeme 	sc->mii_dev = self;
    123   1.1    bouyer 	sc->mii_inst = mii->mii_instance;
    124   1.1    bouyer 	sc->mii_phy = ma->mii_phyno;
    125  1.12   msaitoh 	sc->mii_mpd_oui = MII_OUI(ma->mii_id1, ma->mii_id2);
    126  1.12   msaitoh 	sc->mii_mpd_model = MII_MODEL(ma->mii_id2);
    127  1.12   msaitoh 	sc->mii_mpd_rev = MII_REV(ma->mii_id2);
    128   1.1    bouyer 	sc->mii_funcs = &ikphy_funcs;
    129   1.1    bouyer 	sc->mii_pdata = mii;
    130   1.1    bouyer 	sc->mii_flags = ma->mii_flags;
    131   1.1    bouyer 
    132  1.19   thorpej 	mii_lock(mii);
    133  1.19   thorpej 
    134   1.1    bouyer 	PHY_RESET(sc);
    135   1.1    bouyer 
    136  1.13   msaitoh 	PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
    137  1.13   msaitoh 	sc->mii_capabilities &= ma->mii_capmask;
    138   1.1    bouyer 	if (sc->mii_capabilities & BMSR_EXTSTAT)
    139  1.13   msaitoh 		PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities);
    140  1.18   msaitoh 
    141  1.19   thorpej 	mii_unlock(mii);
    142  1.19   thorpej 
    143  1.18   msaitoh 	mii_phy_add_media(sc);
    144   1.1    bouyer }
    145   1.1    bouyer 
    146   1.1    bouyer static int
    147   1.1    bouyer ikphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
    148   1.1    bouyer {
    149   1.1    bouyer 	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
    150  1.13   msaitoh 	uint16_t reg;
    151   1.1    bouyer 
    152  1.19   thorpej 	KASSERT(mii_locked(mii));
    153  1.19   thorpej 
    154   1.1    bouyer 	switch (cmd) {
    155   1.1    bouyer 	case MII_POLLSTAT:
    156  1.15   msaitoh 		/* If we're not polling our PHY instance, just return. */
    157   1.1    bouyer 		if (IFM_INST(ife->ifm_media) != sc->mii_inst)
    158  1.15   msaitoh 			return 0;
    159   1.1    bouyer 		break;
    160   1.1    bouyer 
    161   1.1    bouyer 	case MII_MEDIACHG:
    162   1.1    bouyer 		/*
    163   1.1    bouyer 		 * If the media indicates a different PHY instance,
    164   1.1    bouyer 		 * isolate ourselves.
    165   1.1    bouyer 		 */
    166   1.1    bouyer 		if (IFM_INST(ife->ifm_media) != sc->mii_inst) {
    167  1.13   msaitoh 			PHY_READ(sc, MII_BMCR, &reg);
    168   1.1    bouyer 			PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
    169  1.15   msaitoh 			return 0;
    170   1.1    bouyer 		}
    171   1.1    bouyer 
    172  1.15   msaitoh 		/* If the interface is not up, don't do anything. */
    173   1.1    bouyer 		if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
    174   1.1    bouyer 			break;
    175   1.1    bouyer 
    176   1.1    bouyer 		ikphy_setmedia(sc);
    177   1.1    bouyer 		break;
    178   1.1    bouyer 
    179   1.1    bouyer 	case MII_TICK:
    180  1.15   msaitoh 		/* If we're not currently selected, just return. */
    181   1.1    bouyer 		if (IFM_INST(ife->ifm_media) != sc->mii_inst)
    182  1.15   msaitoh 			return 0;
    183   1.1    bouyer 
    184   1.1    bouyer 		if (mii_phy_tick(sc) == EJUSTRETURN)
    185  1.15   msaitoh 			return 0;
    186   1.1    bouyer 		break;
    187   1.1    bouyer 
    188   1.1    bouyer 	case MII_DOWN:
    189   1.1    bouyer 		mii_phy_down(sc);
    190  1.15   msaitoh 		return 0;
    191   1.1    bouyer 	}
    192   1.1    bouyer 
    193   1.1    bouyer 	/* Update the media status. */
    194   1.1    bouyer 	mii_phy_status(sc);
    195   1.1    bouyer 
    196   1.1    bouyer 	/* Callback if something changed. */
    197   1.1    bouyer 	mii_phy_update(sc, cmd);
    198  1.15   msaitoh 	return 0;
    199   1.1    bouyer }
    200   1.1    bouyer 
    201   1.1    bouyer static void
    202   1.1    bouyer ikphy_setmedia(struct mii_softc *sc)
    203   1.1    bouyer {
    204   1.1    bouyer 	uint16_t phy_data;
    205   1.1    bouyer 	struct mii_data *mii = sc->mii_pdata;
    206   1.1    bouyer 	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
    207   1.1    bouyer 
    208  1.19   thorpej 	KASSERT(mii_locked(mii));
    209  1.19   thorpej 
    210   1.1    bouyer 	/* Enable CRS on TX for half-duplex operation. */
    211  1.13   msaitoh 	PHY_READ(sc, GG82563_PHY_MAC_SPEC_CTRL, &phy_data);
    212   1.1    bouyer 	phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
    213   1.1    bouyer 	/* Use 25MHz for both link down and 1000BASE-T for Tx clock */
    214   1.1    bouyer 	phy_data |= GG82563_MSCR_TX_CLK_1000MBPS_25MHZ;
    215   1.1    bouyer 	PHY_WRITE(sc, GG82563_PHY_MAC_SPEC_CTRL, phy_data);
    216   1.1    bouyer 
    217  1.16   msaitoh 	/* Set mdi/mid-x options */
    218  1.13   msaitoh 	PHY_READ(sc, GG82563_PHY_SPEC_CTRL, &phy_data);
    219   1.1    bouyer 	phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK;
    220   1.1    bouyer 	if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO)
    221   1.1    bouyer 		phy_data |= GG82563_PSCR_CROSSOVER_MODE_AUTO;
    222   1.1    bouyer 	else
    223   1.1    bouyer 		phy_data |= GG82563_PSCR_CROSSOVER_MODE_MDI;
    224  1.16   msaitoh 	/* Set polarity correction */
    225   1.1    bouyer 	phy_data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE;
    226   1.1    bouyer 	PHY_WRITE(sc, GG82563_PHY_SPEC_CTRL, phy_data);
    227   1.1    bouyer 
    228   1.1    bouyer 	/* SW Reset the PHY so all changes take effect */
    229   1.1    bouyer 	PHY_RESET(sc);
    230   1.1    bouyer 
    231  1.16   msaitoh 	/* For the i80003 */
    232  1.13   msaitoh 	PHY_READ(sc, GG82563_PHY_SPEC_CTRL_2, &phy_data);
    233   1.1    bouyer 	phy_data &= ~GG82563_PSCR2_REVERSE_AUTO_NEG;
    234   1.1    bouyer 	PHY_WRITE(sc, GG82563_PHY_SPEC_CTRL_2, phy_data);
    235   1.1    bouyer 
    236   1.1    bouyer 	/* Enable Electrical Idle on the PHY */
    237  1.13   msaitoh 	PHY_READ(sc, GG82563_PHY_PWR_MGMT_CTRL, &phy_data);
    238   1.1    bouyer 	phy_data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE;
    239   1.1    bouyer 	PHY_WRITE(sc, GG82563_PHY_PWR_MGMT_CTRL, phy_data);
    240   1.1    bouyer 
    241  1.13   msaitoh 	PHY_READ(sc, GG82563_PHY_KMRN_MODE_CTRL, &phy_data);
    242   1.1    bouyer 	phy_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
    243   1.1    bouyer 	PHY_WRITE(sc, GG82563_PHY_KMRN_MODE_CTRL, phy_data);
    244   1.1    bouyer 
    245   1.1    bouyer 	/*
    246   1.1    bouyer 	 * Workaround: Disable padding in Kumeran interface in the MAC
    247   1.1    bouyer 	 * and in the PHY to avoid CRC errors.
    248   1.1    bouyer 	 */
    249  1.13   msaitoh 	PHY_READ(sc, GG82563_PHY_INBAND_CTRL, &phy_data);
    250   1.1    bouyer 	phy_data |= GG82563_ICR_DIS_PADDING;
    251   1.1    bouyer 	PHY_WRITE(sc, GG82563_PHY_INBAND_CTRL, phy_data);
    252   1.1    bouyer 
    253   1.1    bouyer 	mii_phy_setmedia(sc);
    254   1.1    bouyer 	if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) {
    255   1.1    bouyer 		/*
    256  1.15   msaitoh 		 * When not in auto mode, we need to restart nego
    257   1.1    bouyer 		 * anyway, or a switch from a fixed mode to another
    258   1.1    bouyer 		 * fixed mode may not be seen by the switch.
    259   1.1    bouyer 		 */
    260  1.13   msaitoh 		PHY_READ(sc, MII_BMCR, &phy_data);
    261  1.13   msaitoh 		PHY_WRITE(sc, MII_BMCR, phy_data | BMCR_STARTNEG);
    262   1.1    bouyer 	}
    263  1.13   msaitoh 	PHY_READ(sc, GG82563_PHY_MAC_SPEC_CTRL, &phy_data);
    264   1.1    bouyer 	phy_data &= ~GG82563_MSCR_TX_CLK_MASK;
    265  1.16   msaitoh 	switch (IFM_SUBTYPE(ife->ifm_media)) {
    266   1.1    bouyer 	case IFM_10_T:
    267   1.1    bouyer 		phy_data |= GG82563_MSCR_TX_CLK_10MBPS_2_5MHZ;
    268   1.1    bouyer 		break;
    269   1.1    bouyer 	case IFM_100_TX:
    270   1.1    bouyer 		phy_data |= GG82563_MSCR_TX_CLK_100MBPS_25MHZ;
    271   1.1    bouyer 		break;
    272   1.1    bouyer 	case IFM_1000_T:
    273   1.1    bouyer 		phy_data |= GG82563_MSCR_TX_CLK_1000MBPS_25MHZ;
    274   1.1    bouyer 		break;
    275   1.1    bouyer 	}
    276   1.1    bouyer 	phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
    277   1.1    bouyer 	PHY_WRITE(sc, GG82563_PHY_MAC_SPEC_CTRL, phy_data);
    278   1.1    bouyer }
    279   1.1    bouyer 
    280   1.1    bouyer static void
    281   1.1    bouyer ikphy_status(struct mii_softc *sc)
    282   1.1    bouyer {
    283   1.1    bouyer 	struct mii_data *mii = sc->mii_pdata;
    284   1.1    bouyer 	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
    285  1.13   msaitoh 	uint16_t pssr, bmcr, gtsr, kmrn;
    286   1.1    bouyer 
    287  1.19   thorpej 	KASSERT(mii_locked(mii));
    288  1.19   thorpej 
    289   1.1    bouyer 	mii->mii_media_status = IFM_AVALID;
    290   1.1    bouyer 	mii->mii_media_active = IFM_ETHER;
    291   1.1    bouyer 
    292  1.13   msaitoh 	PHY_READ(sc, GG82563_PHY_SPEC_STATUS, &pssr);
    293   1.1    bouyer 
    294   1.1    bouyer 	if (pssr & GG82563_PSSR_LINK)
    295   1.1    bouyer 		mii->mii_media_status |= IFM_ACTIVE;
    296   1.1    bouyer 
    297  1.13   msaitoh 	PHY_READ(sc, MII_BMCR, &bmcr);
    298   1.1    bouyer 	if (bmcr & BMCR_ISO) {
    299   1.1    bouyer 		mii->mii_media_active |= IFM_NONE;
    300   1.1    bouyer 		mii->mii_media_status = 0;
    301   1.1    bouyer 		return;
    302   1.1    bouyer 	}
    303   1.1    bouyer 
    304   1.1    bouyer 	if (bmcr & BMCR_LOOP)
    305   1.1    bouyer 		mii->mii_media_active |= IFM_LOOP;
    306   1.1    bouyer 
    307   1.1    bouyer 	if (bmcr & BMCR_AUTOEN) {
    308   1.1    bouyer 		/*
    309  1.17   msaitoh 		 * The media status bits are only valid if autonegotiation
    310   1.1    bouyer 		 * has completed (or it's disabled).
    311   1.1    bouyer 		 */
    312   1.1    bouyer 		if ((pssr & GG82563_PSSR_SPEED_DUPLEX_RESOLVED) == 0) {
    313   1.1    bouyer 			/* Erg, still trying, I guess... */
    314   1.1    bouyer 			mii->mii_media_active |= IFM_NONE;
    315   1.1    bouyer 			return;
    316   1.1    bouyer 		}
    317   1.1    bouyer 
    318   1.1    bouyer 		switch (pssr & GG82563_PSSR_SPEED_MASK) {
    319   1.1    bouyer 		case GG82563_PSSR_SPEED_1000MBPS:
    320   1.1    bouyer 			mii->mii_media_active |= IFM_1000_T;
    321  1.13   msaitoh 			PHY_READ(sc, MII_100T2SR, &gtsr);
    322   1.1    bouyer 			if (gtsr & GTSR_MS_RES)
    323   1.1    bouyer 				mii->mii_media_active |= IFM_ETH_MASTER;
    324   1.1    bouyer 			break;
    325   1.1    bouyer 
    326   1.1    bouyer 		case GG82563_PSSR_SPEED_100MBPS:
    327   1.1    bouyer 			mii->mii_media_active |= IFM_100_TX;
    328   1.1    bouyer 			break;
    329   1.1    bouyer 
    330   1.1    bouyer 		case GG82563_PSSR_SPEED_10MBPS:
    331   1.1    bouyer 			mii->mii_media_active |= IFM_10_T;
    332   1.1    bouyer 			break;
    333   1.1    bouyer 
    334   1.1    bouyer 		default:
    335   1.1    bouyer 			mii->mii_media_active |= IFM_NONE;
    336   1.1    bouyer 			mii->mii_media_status = 0;
    337   1.1    bouyer 			return;
    338   1.1    bouyer 		}
    339   1.1    bouyer 
    340   1.1    bouyer 		if (pssr & GG82563_PSSR_DUPLEX)
    341   1.1    bouyer 			mii->mii_media_active |=
    342   1.1    bouyer 			    IFM_FDX | mii_phy_flowstatus(sc);
    343  1.10   msaitoh 		else
    344  1.10   msaitoh 			mii->mii_media_active |= IFM_HDX;
    345   1.1    bouyer 	} else
    346   1.1    bouyer 		mii->mii_media_active = ife->ifm_media;
    347  1.13   msaitoh 	PHY_READ(sc, GG82563_PHY_KMRN_MODE_CTRL, &kmrn);
    348   1.1    bouyer 	if (mii->mii_media_active & IFM_FDX)
    349   1.1    bouyer 		kmrn &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
    350   1.1    bouyer 	else
    351   1.1    bouyer 		kmrn |= GG82563_KMCR_PASS_FALSE_CARRIER;
    352   1.1    bouyer 	PHY_WRITE(sc, GG82563_PHY_KMRN_MODE_CTRL, kmrn);
    353   1.1    bouyer }
    354