18b62915eSRuslan Bukin /*- 2af77cd75SRuslan Bukin * Copyright (c) 2014,2019 Ruslan Bukin <br@bsdpad.com> 38b62915eSRuslan Bukin * All rights reserved. 48b62915eSRuslan Bukin * 58b62915eSRuslan Bukin * This software was developed by SRI International and the University of 68b62915eSRuslan Bukin * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) 78b62915eSRuslan Bukin * ("CTSRD"), as part of the DARPA CRASH research programme. 88b62915eSRuslan Bukin * 98b62915eSRuslan Bukin * Redistribution and use in source and binary forms, with or without 108b62915eSRuslan Bukin * modification, are permitted provided that the following conditions 118b62915eSRuslan Bukin * are met: 128b62915eSRuslan Bukin * 1. Redistributions of source code must retain the above copyright 138b62915eSRuslan Bukin * notice, this list of conditions and the following disclaimer. 148b62915eSRuslan Bukin * 2. Redistributions in binary form must reproduce the above copyright 158b62915eSRuslan Bukin * notice, this list of conditions and the following disclaimer in the 168b62915eSRuslan Bukin * documentation and/or other materials provided with the distribution. 178b62915eSRuslan Bukin * 188b62915eSRuslan Bukin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 198b62915eSRuslan Bukin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 208b62915eSRuslan Bukin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 218b62915eSRuslan Bukin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 228b62915eSRuslan Bukin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 238b62915eSRuslan Bukin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 248b62915eSRuslan Bukin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 258b62915eSRuslan Bukin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 268b62915eSRuslan Bukin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 278b62915eSRuslan Bukin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 288b62915eSRuslan Bukin * SUCH DAMAGE. 298b62915eSRuslan Bukin */ 308b62915eSRuslan Bukin 318b62915eSRuslan Bukin #include <sys/cdefs.h> 328b62915eSRuslan Bukin __FBSDID("$FreeBSD$"); 338b62915eSRuslan Bukin 348b62915eSRuslan Bukin /* 35af77cd75SRuslan Bukin * Micrel KSZ8081/KSZ9021/KSZ9031 Gigabit Ethernet Transceiver 368b62915eSRuslan Bukin */ 378b62915eSRuslan Bukin 388b62915eSRuslan Bukin #include <sys/param.h> 398b62915eSRuslan Bukin #include <sys/systm.h> 408b62915eSRuslan Bukin #include <sys/kernel.h> 418b62915eSRuslan Bukin #include <sys/socket.h> 428b62915eSRuslan Bukin #include <sys/errno.h> 438b62915eSRuslan Bukin #include <sys/module.h> 448b62915eSRuslan Bukin #include <sys/bus.h> 458b62915eSRuslan Bukin #include <sys/malloc.h> 468b62915eSRuslan Bukin 478b62915eSRuslan Bukin #include <machine/bus.h> 488b62915eSRuslan Bukin 498b62915eSRuslan Bukin #include <net/if.h> 508b62915eSRuslan Bukin #include <net/if_media.h> 518b62915eSRuslan Bukin 528b62915eSRuslan Bukin #include <dev/mii/mii.h> 538b62915eSRuslan Bukin #include <dev/mii/miivar.h> 548b62915eSRuslan Bukin #include "miidevs.h" 558b62915eSRuslan Bukin 568b62915eSRuslan Bukin #include "miibus_if.h" 578b62915eSRuslan Bukin 588b62915eSRuslan Bukin #include <dev/fdt/fdt_common.h> 598b62915eSRuslan Bukin #include <dev/ofw/openfirm.h> 608b62915eSRuslan Bukin #include <dev/ofw/ofw_bus.h> 618b62915eSRuslan Bukin #include <dev/ofw/ofw_bus_subr.h> 62af77cd75SRuslan Bukin #include <dev/mii/mii_fdt.h> 638b62915eSRuslan Bukin 648b62915eSRuslan Bukin #define MII_KSZPHY_EXTREG 0x0b 658b62915eSRuslan Bukin #define KSZPHY_EXTREG_WRITE (1 << 15) 668b62915eSRuslan Bukin #define MII_KSZPHY_EXTREG_WRITE 0x0c 678b62915eSRuslan Bukin #define MII_KSZPHY_EXTREG_READ 0x0d 688b62915eSRuslan Bukin #define MII_KSZPHY_CLK_CONTROL_PAD_SKEW 0x104 698b62915eSRuslan Bukin #define MII_KSZPHY_RX_DATA_PAD_SKEW 0x105 708b62915eSRuslan Bukin #define MII_KSZPHY_TX_DATA_PAD_SKEW 0x106 7167a48226SLuiz Otavio O Souza /* KSZ9031 */ 7267a48226SLuiz Otavio O Souza #define MII_KSZ9031_MMD_ACCESS_CTRL 0x0d 7367a48226SLuiz Otavio O Souza #define MII_KSZ9031_MMD_ACCESS_DATA 0x0e 7467a48226SLuiz Otavio O Souza #define MII_KSZ9031_MMD_DATA_NOINC (1 << 14) 7567a48226SLuiz Otavio O Souza #define MII_KSZ9031_CONTROL_PAD_SKEW 0x4 7667a48226SLuiz Otavio O Souza #define MII_KSZ9031_RX_DATA_PAD_SKEW 0x5 7767a48226SLuiz Otavio O Souza #define MII_KSZ9031_TX_DATA_PAD_SKEW 0x6 7867a48226SLuiz Otavio O Souza #define MII_KSZ9031_CLOCK_PAD_SKEW 0x8 798b62915eSRuslan Bukin 80e8b1516aSIan Lepore #define MII_KSZ8081_PHYCTL2 0x1f 81e8b1516aSIan Lepore 8274953fa3SRuslan Bukin #define PS_TO_REG(p) ((p) / 200) 838b62915eSRuslan Bukin 848b62915eSRuslan Bukin static int micphy_probe(device_t); 858b62915eSRuslan Bukin static int micphy_attach(device_t); 86e8b1516aSIan Lepore static void micphy_reset(struct mii_softc *); 878b62915eSRuslan Bukin static int micphy_service(struct mii_softc *, struct mii_data *, int); 888b62915eSRuslan Bukin 898b62915eSRuslan Bukin static device_method_t micphy_methods[] = { 908b62915eSRuslan Bukin /* device interface */ 918b62915eSRuslan Bukin DEVMETHOD(device_probe, micphy_probe), 928b62915eSRuslan Bukin DEVMETHOD(device_attach, micphy_attach), 938b62915eSRuslan Bukin DEVMETHOD(device_detach, mii_phy_detach), 948b62915eSRuslan Bukin DEVMETHOD(device_shutdown, bus_generic_shutdown), 958b62915eSRuslan Bukin DEVMETHOD_END 968b62915eSRuslan Bukin }; 978b62915eSRuslan Bukin 988b62915eSRuslan Bukin static driver_t micphy_driver = { 998b62915eSRuslan Bukin "micphy", 1008b62915eSRuslan Bukin micphy_methods, 1018b62915eSRuslan Bukin sizeof(struct mii_softc) 1028b62915eSRuslan Bukin }; 1038b62915eSRuslan Bukin 104*f438c2ffSJohn Baldwin DRIVER_MODULE(micphy, miibus, micphy_driver, 0, 0); 1058b62915eSRuslan Bukin 1068b62915eSRuslan Bukin static const struct mii_phydesc micphys[] = { 107e8b1516aSIan Lepore MII_PHY_DESC(MICREL, KSZ8081), 1088b62915eSRuslan Bukin MII_PHY_DESC(MICREL, KSZ9021), 10967a48226SLuiz Otavio O Souza MII_PHY_DESC(MICREL, KSZ9031), 1108b62915eSRuslan Bukin MII_PHY_END 1118b62915eSRuslan Bukin }; 1128b62915eSRuslan Bukin 1138b62915eSRuslan Bukin static const struct mii_phy_funcs micphy_funcs = { 1148b62915eSRuslan Bukin micphy_service, 1158b62915eSRuslan Bukin ukphy_status, 116e8b1516aSIan Lepore micphy_reset 1178b62915eSRuslan Bukin }; 1188b62915eSRuslan Bukin 11967a48226SLuiz Otavio O Souza static uint32_t 12067a48226SLuiz Otavio O Souza ksz9031_read(struct mii_softc *sc, uint32_t devaddr, uint32_t reg) 12167a48226SLuiz Otavio O Souza { 12267a48226SLuiz Otavio O Souza /* Set up device address and register. */ 12367a48226SLuiz Otavio O Souza PHY_WRITE(sc, MII_KSZ9031_MMD_ACCESS_CTRL, devaddr); 12467a48226SLuiz Otavio O Souza PHY_WRITE(sc, MII_KSZ9031_MMD_ACCESS_DATA, reg); 12567a48226SLuiz Otavio O Souza 12667a48226SLuiz Otavio O Souza /* Select register data for MMD and read the value. */ 12767a48226SLuiz Otavio O Souza PHY_WRITE(sc, MII_KSZ9031_MMD_ACCESS_CTRL, 12867a48226SLuiz Otavio O Souza MII_KSZ9031_MMD_DATA_NOINC | devaddr); 12967a48226SLuiz Otavio O Souza 13067a48226SLuiz Otavio O Souza return (PHY_READ(sc, MII_KSZ9031_MMD_ACCESS_DATA)); 13167a48226SLuiz Otavio O Souza } 13267a48226SLuiz Otavio O Souza 13374953fa3SRuslan Bukin static void 13467a48226SLuiz Otavio O Souza ksz9031_write(struct mii_softc *sc, uint32_t devaddr, uint32_t reg, 13567a48226SLuiz Otavio O Souza uint32_t val) 13667a48226SLuiz Otavio O Souza { 13767a48226SLuiz Otavio O Souza 13867a48226SLuiz Otavio O Souza /* Set up device address and register. */ 13967a48226SLuiz Otavio O Souza PHY_WRITE(sc, MII_KSZ9031_MMD_ACCESS_CTRL, devaddr); 14067a48226SLuiz Otavio O Souza PHY_WRITE(sc, MII_KSZ9031_MMD_ACCESS_DATA, reg); 14167a48226SLuiz Otavio O Souza 14267a48226SLuiz Otavio O Souza /* Select register data for MMD and write the value. */ 14367a48226SLuiz Otavio O Souza PHY_WRITE(sc, MII_KSZ9031_MMD_ACCESS_CTRL, 14467a48226SLuiz Otavio O Souza MII_KSZ9031_MMD_DATA_NOINC | devaddr); 14567a48226SLuiz Otavio O Souza PHY_WRITE(sc, MII_KSZ9031_MMD_ACCESS_DATA, val); 14667a48226SLuiz Otavio O Souza } 14767a48226SLuiz Otavio O Souza 14867a48226SLuiz Otavio O Souza static uint32_t 14967a48226SLuiz Otavio O Souza ksz9021_read(struct mii_softc *sc, uint32_t reg) 15067a48226SLuiz Otavio O Souza { 15167a48226SLuiz Otavio O Souza 15267a48226SLuiz Otavio O Souza PHY_WRITE(sc, MII_KSZPHY_EXTREG, reg); 15367a48226SLuiz Otavio O Souza 15467a48226SLuiz Otavio O Souza return (PHY_READ(sc, MII_KSZPHY_EXTREG_READ)); 15567a48226SLuiz Otavio O Souza } 15667a48226SLuiz Otavio O Souza 15767a48226SLuiz Otavio O Souza static void 15867a48226SLuiz Otavio O Souza ksz9021_write(struct mii_softc *sc, uint32_t reg, uint32_t val) 1598b62915eSRuslan Bukin { 1608b62915eSRuslan Bukin 1618b62915eSRuslan Bukin PHY_WRITE(sc, MII_KSZPHY_EXTREG, KSZPHY_EXTREG_WRITE | reg); 1628b62915eSRuslan Bukin PHY_WRITE(sc, MII_KSZPHY_EXTREG_WRITE, val); 1638b62915eSRuslan Bukin } 1648b62915eSRuslan Bukin 16567a48226SLuiz Otavio O Souza static void 16667a48226SLuiz Otavio O Souza ksz90x1_load_values(struct mii_softc *sc, phandle_t node, 16767a48226SLuiz Otavio O Souza uint32_t dev, uint32_t reg, char *field1, uint32_t f1mask, int f1off, 16867a48226SLuiz Otavio O Souza char *field2, uint32_t f2mask, int f2off, char *field3, uint32_t f3mask, 16967a48226SLuiz Otavio O Souza int f3off, char *field4, uint32_t f4mask, int f4off) 1708b62915eSRuslan Bukin { 1718b62915eSRuslan Bukin pcell_t dts_value[1]; 1728b62915eSRuslan Bukin int len; 1738b62915eSRuslan Bukin int val; 1748b62915eSRuslan Bukin 17567a48226SLuiz Otavio O Souza if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9031) 17667a48226SLuiz Otavio O Souza val = ksz9031_read(sc, dev, reg); 17767a48226SLuiz Otavio O Souza else 17867a48226SLuiz Otavio O Souza val = ksz9021_read(sc, reg); 1798b62915eSRuslan Bukin 1808b62915eSRuslan Bukin if ((len = OF_getproplen(node, field1)) > 0) { 1818b62915eSRuslan Bukin OF_getencprop(node, field1, dts_value, len); 18267a48226SLuiz Otavio O Souza val &= ~(f1mask << f1off); 18367a48226SLuiz Otavio O Souza val |= (PS_TO_REG(dts_value[0]) & f1mask) << f1off; 1848b62915eSRuslan Bukin } 1858b62915eSRuslan Bukin 18667a48226SLuiz Otavio O Souza if (field2 != NULL && (len = OF_getproplen(node, field2)) > 0) { 1878b62915eSRuslan Bukin OF_getencprop(node, field2, dts_value, len); 18867a48226SLuiz Otavio O Souza val &= ~(f2mask << f2off); 18967a48226SLuiz Otavio O Souza val |= (PS_TO_REG(dts_value[0]) & f2mask) << f2off; 1908b62915eSRuslan Bukin } 1918b62915eSRuslan Bukin 19267a48226SLuiz Otavio O Souza if (field3 != NULL && (len = OF_getproplen(node, field3)) > 0) { 1938b62915eSRuslan Bukin OF_getencprop(node, field3, dts_value, len); 19467a48226SLuiz Otavio O Souza val &= ~(f3mask << f3off); 19567a48226SLuiz Otavio O Souza val |= (PS_TO_REG(dts_value[0]) & f3mask) << f3off; 1968b62915eSRuslan Bukin } 1978b62915eSRuslan Bukin 19867a48226SLuiz Otavio O Souza if (field4 != NULL && (len = OF_getproplen(node, field4)) > 0) { 1998b62915eSRuslan Bukin OF_getencprop(node, field4, dts_value, len); 20067a48226SLuiz Otavio O Souza val &= ~(f4mask << f4off); 20167a48226SLuiz Otavio O Souza val |= (PS_TO_REG(dts_value[0]) & f4mask) << f4off; 2028b62915eSRuslan Bukin } 2038b62915eSRuslan Bukin 20467a48226SLuiz Otavio O Souza if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9031) 20567a48226SLuiz Otavio O Souza ksz9031_write(sc, dev, reg, val); 20667a48226SLuiz Otavio O Souza else 20767a48226SLuiz Otavio O Souza ksz9021_write(sc, reg, val); 20867a48226SLuiz Otavio O Souza } 2098b62915eSRuslan Bukin 21067a48226SLuiz Otavio O Souza static void 21167a48226SLuiz Otavio O Souza ksz9031_load_values(struct mii_softc *sc, phandle_t node) 21267a48226SLuiz Otavio O Souza { 21367a48226SLuiz Otavio O Souza 21467a48226SLuiz Otavio O Souza ksz90x1_load_values(sc, node, 2, MII_KSZ9031_CONTROL_PAD_SKEW, 21567a48226SLuiz Otavio O Souza "txen-skew-ps", 0xf, 0, "rxdv-skew-ps", 0xf, 4, 21667a48226SLuiz Otavio O Souza NULL, 0, 0, NULL, 0, 0); 21767a48226SLuiz Otavio O Souza ksz90x1_load_values(sc, node, 2, MII_KSZ9031_RX_DATA_PAD_SKEW, 21867a48226SLuiz Otavio O Souza "rxd0-skew-ps", 0xf, 0, "rxd1-skew-ps", 0xf, 4, 21967a48226SLuiz Otavio O Souza "rxd2-skew-ps", 0xf, 8, "rxd3-skew-ps", 0xf, 12); 22067a48226SLuiz Otavio O Souza ksz90x1_load_values(sc, node, 2, MII_KSZ9031_TX_DATA_PAD_SKEW, 22167a48226SLuiz Otavio O Souza "txd0-skew-ps", 0xf, 0, "txd1-skew-ps", 0xf, 4, 22267a48226SLuiz Otavio O Souza "txd2-skew-ps", 0xf, 8, "txd3-skew-ps", 0xf, 12); 22367a48226SLuiz Otavio O Souza ksz90x1_load_values(sc, node, 2, MII_KSZ9031_CLOCK_PAD_SKEW, 22467a48226SLuiz Otavio O Souza "rxc-skew-ps", 0x1f, 0, "txc-skew-ps", 0x1f, 5, 22567a48226SLuiz Otavio O Souza NULL, 0, 0, NULL, 0, 0); 22667a48226SLuiz Otavio O Souza } 22767a48226SLuiz Otavio O Souza 22867a48226SLuiz Otavio O Souza static void 22967a48226SLuiz Otavio O Souza ksz9021_load_values(struct mii_softc *sc, phandle_t node) 23067a48226SLuiz Otavio O Souza { 23167a48226SLuiz Otavio O Souza 23267a48226SLuiz Otavio O Souza ksz90x1_load_values(sc, node, 0, MII_KSZPHY_CLK_CONTROL_PAD_SKEW, 23367a48226SLuiz Otavio O Souza "txen-skew-ps", 0xf, 0, "txc-skew-ps", 0xf, 4, 23467a48226SLuiz Otavio O Souza "rxdv-skew-ps", 0xf, 8, "rxc-skew-ps", 0xf, 12); 23567a48226SLuiz Otavio O Souza ksz90x1_load_values(sc, node, 0, MII_KSZPHY_RX_DATA_PAD_SKEW, 23667a48226SLuiz Otavio O Souza "rxd0-skew-ps", 0xf, 0, "rxd1-skew-ps", 0xf, 4, 23767a48226SLuiz Otavio O Souza "rxd2-skew-ps", 0xf, 8, "rxd3-skew-ps", 0xf, 12); 23867a48226SLuiz Otavio O Souza ksz90x1_load_values(sc, node, 0, MII_KSZPHY_TX_DATA_PAD_SKEW, 23967a48226SLuiz Otavio O Souza "txd0-skew-ps", 0xf, 0, "txd1-skew-ps", 0xf, 4, 24067a48226SLuiz Otavio O Souza "txd2-skew-ps", 0xf, 8, "txd3-skew-ps", 0xf, 12); 2418b62915eSRuslan Bukin } 2428b62915eSRuslan Bukin 2438b62915eSRuslan Bukin static int 2448b62915eSRuslan Bukin micphy_probe(device_t dev) 2458b62915eSRuslan Bukin { 2468b62915eSRuslan Bukin 2478b62915eSRuslan Bukin return (mii_phy_dev_probe(dev, micphys, BUS_PROBE_DEFAULT)); 2488b62915eSRuslan Bukin } 2498b62915eSRuslan Bukin 2508b62915eSRuslan Bukin static int 2518b62915eSRuslan Bukin micphy_attach(device_t dev) 2528b62915eSRuslan Bukin { 253af77cd75SRuslan Bukin mii_fdt_phy_config_t *cfg; 2548b62915eSRuslan Bukin struct mii_softc *sc; 2558b62915eSRuslan Bukin phandle_t node; 2568b62915eSRuslan Bukin device_t miibus; 2578b62915eSRuslan Bukin device_t parent; 2588b62915eSRuslan Bukin 2598b62915eSRuslan Bukin sc = device_get_softc(dev); 2608b62915eSRuslan Bukin 2618b62915eSRuslan Bukin mii_phy_dev_attach(dev, MIIF_NOMANPAUSE, &micphy_funcs, 1); 2628b62915eSRuslan Bukin mii_phy_setmedia(sc); 2638b62915eSRuslan Bukin 264e8b1516aSIan Lepore /* Nothing further to configure for 8081 model. */ 265e8b1516aSIan Lepore if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8081) 266e8b1516aSIan Lepore return (0); 267e8b1516aSIan Lepore 2688b62915eSRuslan Bukin miibus = device_get_parent(dev); 2698b62915eSRuslan Bukin parent = device_get_parent(miibus); 2708b62915eSRuslan Bukin 2718b62915eSRuslan Bukin if ((node = ofw_bus_get_node(parent)) == -1) 2728b62915eSRuslan Bukin return (ENXIO); 2738b62915eSRuslan Bukin 274af77cd75SRuslan Bukin cfg = mii_fdt_get_config(dev); 275af77cd75SRuslan Bukin 27667a48226SLuiz Otavio O Souza if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9031) 277af77cd75SRuslan Bukin ksz9031_load_values(sc, cfg->phynode); 27867a48226SLuiz Otavio O Souza else 279af77cd75SRuslan Bukin ksz9021_load_values(sc, cfg->phynode); 2808b62915eSRuslan Bukin 2818b62915eSRuslan Bukin return (0); 2828b62915eSRuslan Bukin } 2838b62915eSRuslan Bukin 284e8b1516aSIan Lepore static void 285e8b1516aSIan Lepore micphy_reset(struct mii_softc *sc) 286e8b1516aSIan Lepore { 287e8b1516aSIan Lepore int reg; 288e8b1516aSIan Lepore 289e8b1516aSIan Lepore /* 290e8b1516aSIan Lepore * The 8081 has no "sticky bits" that survive a soft reset; several bits 291e8b1516aSIan Lepore * in the Phy Control Register 2 must be preserved across the reset. 292e8b1516aSIan Lepore * These bits are set up by the bootloader; they control how the phy 293e8b1516aSIan Lepore * interfaces to the board (such as clock frequency and LED behavior). 294e8b1516aSIan Lepore */ 295e8b1516aSIan Lepore if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8081) 296e8b1516aSIan Lepore reg = PHY_READ(sc, MII_KSZ8081_PHYCTL2); 297e8b1516aSIan Lepore mii_phy_reset(sc); 298e8b1516aSIan Lepore if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8081) 299e8b1516aSIan Lepore PHY_WRITE(sc, MII_KSZ8081_PHYCTL2, reg); 300e8b1516aSIan Lepore } 301e8b1516aSIan Lepore 3028b62915eSRuslan Bukin static int 3038b62915eSRuslan Bukin micphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) 3048b62915eSRuslan Bukin { 3058b62915eSRuslan Bukin 3068b62915eSRuslan Bukin switch (cmd) { 3078b62915eSRuslan Bukin case MII_POLLSTAT: 3088b62915eSRuslan Bukin break; 3098b62915eSRuslan Bukin 3108b62915eSRuslan Bukin case MII_MEDIACHG: 3118b62915eSRuslan Bukin mii_phy_setmedia(sc); 3128b62915eSRuslan Bukin break; 3138b62915eSRuslan Bukin 3148b62915eSRuslan Bukin case MII_TICK: 3158b62915eSRuslan Bukin if (mii_phy_tick(sc) == EJUSTRETURN) 3168b62915eSRuslan Bukin return (0); 3178b62915eSRuslan Bukin break; 3188b62915eSRuslan Bukin } 3198b62915eSRuslan Bukin 3208b62915eSRuslan Bukin /* Update the media status. */ 3218b62915eSRuslan Bukin PHY_STATUS(sc); 3228b62915eSRuslan Bukin 3238b62915eSRuslan Bukin /* Callback if something changed. */ 3248b62915eSRuslan Bukin mii_phy_update(sc, cmd); 3258b62915eSRuslan Bukin return (0); 3268b62915eSRuslan Bukin } 327