1 1.15 jmcneill /* $NetBSD: micphy.c,v 1.15 2022/10/31 22:45:13 jmcneill Exp $ */ 2 1.1 ozaki 3 1.1 ozaki /*- 4 1.1 ozaki * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. 5 1.1 ozaki * All rights reserved. 6 1.1 ozaki * 7 1.1 ozaki * This code is derived from software contributed to The NetBSD Foundation 8 1.1 ozaki * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 1.1 ozaki * NASA Ames Research Center, and by Frank van der Linden. 10 1.1 ozaki * 11 1.1 ozaki * Redistribution and use in source and binary forms, with or without 12 1.1 ozaki * modification, are permitted provided that the following conditions 13 1.1 ozaki * are met: 14 1.1 ozaki * 1. Redistributions of source code must retain the above copyright 15 1.1 ozaki * notice, this list of conditions and the following disclaimer. 16 1.1 ozaki * 2. Redistributions in binary form must reproduce the above copyright 17 1.1 ozaki * notice, this list of conditions and the following disclaimer in the 18 1.1 ozaki * documentation and/or other materials provided with the distribution. 19 1.1 ozaki * 20 1.1 ozaki * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 1.1 ozaki * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.1 ozaki * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 1.1 ozaki * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 1.1 ozaki * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 1.1 ozaki * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 1.1 ozaki * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 1.1 ozaki * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 1.1 ozaki * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 1.1 ozaki * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 1.1 ozaki * POSSIBILITY OF SUCH DAMAGE. 31 1.1 ozaki */ 32 1.1 ozaki 33 1.1 ozaki /* 34 1.1 ozaki * Copyright (c) 1997 Manuel Bouyer. All rights reserved. 35 1.1 ozaki * 36 1.1 ozaki * Redistribution and use in source and binary forms, with or without 37 1.1 ozaki * modification, are permitted provided that the following conditions 38 1.1 ozaki * are met: 39 1.1 ozaki * 1. Redistributions of source code must retain the above copyright 40 1.1 ozaki * notice, this list of conditions and the following disclaimer. 41 1.1 ozaki * 2. Redistributions in binary form must reproduce the above copyright 42 1.1 ozaki * notice, this list of conditions and the following disclaimer in the 43 1.1 ozaki * documentation and/or other materials provided with the distribution. 44 1.1 ozaki * 45 1.1 ozaki * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 46 1.1 ozaki * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 47 1.1 ozaki * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 48 1.1 ozaki * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 49 1.1 ozaki * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 50 1.1 ozaki * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 51 1.1 ozaki * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 52 1.1 ozaki * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 53 1.1 ozaki * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 54 1.1 ozaki * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 55 1.1 ozaki */ 56 1.1 ozaki 57 1.1 ozaki /* 58 1.9 msaitoh * Driver for Micrel KSZ8xxx 10/100 and KSZ9xxx 10/100/1000 PHY. 59 1.1 ozaki */ 60 1.1 ozaki 61 1.1 ozaki #include <sys/cdefs.h> 62 1.15 jmcneill __KERNEL_RCSID(0, "$NetBSD: micphy.c,v 1.15 2022/10/31 22:45:13 jmcneill Exp $"); 63 1.1 ozaki 64 1.1 ozaki #include "opt_mii.h" 65 1.1 ozaki 66 1.1 ozaki #include <sys/param.h> 67 1.1 ozaki #include <sys/systm.h> 68 1.1 ozaki #include <sys/kernel.h> 69 1.1 ozaki #include <sys/device.h> 70 1.1 ozaki #include <sys/socket.h> 71 1.1 ozaki #include <sys/errno.h> 72 1.1 ozaki 73 1.1 ozaki #include <net/if.h> 74 1.1 ozaki #include <net/if_media.h> 75 1.1 ozaki 76 1.1 ozaki #include <dev/mii/mii.h> 77 1.1 ozaki #include <dev/mii/miivar.h> 78 1.1 ozaki #include <dev/mii/miidevs.h> 79 1.1 ozaki 80 1.1 ozaki static int micphymatch(device_t, cfdata_t, void *); 81 1.1 ozaki static void micphyattach(device_t, device_t, void *); 82 1.6 msaitoh static void micphy_reset(struct mii_softc *); 83 1.6 msaitoh static int micphy_service(struct mii_softc *, struct mii_data *, int); 84 1.1 ozaki 85 1.14 thorpej CFATTACH_DECL_NEW(micphy, sizeof(struct mii_softc), 86 1.14 thorpej micphymatch, micphyattach, mii_phy_detach, mii_phy_activate); 87 1.1 ozaki 88 1.1 ozaki static int micphy_service(struct mii_softc *, struct mii_data *, int); 89 1.9 msaitoh static void micphy_status(struct mii_softc *); 90 1.1 ozaki static void micphy_fixup(struct mii_softc *, int, int, device_t); 91 1.1 ozaki 92 1.1 ozaki static const struct mii_phy_funcs micphy_funcs = { 93 1.9 msaitoh micphy_service, micphy_status, micphy_reset, 94 1.9 msaitoh }; 95 1.9 msaitoh 96 1.9 msaitoh struct micphy_softc { 97 1.9 msaitoh struct mii_softc sc_mii; 98 1.9 msaitoh uint32_t sc_lstype; /* Type of link status register */ 99 1.1 ozaki }; 100 1.1 ozaki 101 1.1 ozaki static const struct mii_phydesc micphys[] = { 102 1.9 msaitoh MII_PHY_DESC(MICREL, KSZ8041), 103 1.9 msaitoh MII_PHY_DESC(MICREL, KSZ8051), /* +8021,8031 */ 104 1.9 msaitoh MII_PHY_DESC(MICREL, KSZ8061), 105 1.9 msaitoh MII_PHY_DESC(MICREL, KSZ8081), /* +8051,8091 */ 106 1.9 msaitoh MII_PHY_DESC(MICREL, KS8737), 107 1.9 msaitoh MII_PHY_DESC(MICREL, KSZ9021_8001_8721), 108 1.9 msaitoh MII_PHY_DESC(MICREL, KSZ9031), 109 1.9 msaitoh MII_PHY_DESC(MICREL, KSZ9131), 110 1.9 msaitoh MII_PHY_DESC(MICREL, KSZ9477), /* +LAN7430internal */ 111 1.7 christos MII_PHY_END, 112 1.1 ozaki }; 113 1.1 ozaki 114 1.9 msaitoh /* 115 1.11 msaitoh * Model Rev. Media LSTYPE Devices 116 1.9 msaitoh * 117 1.9 msaitoh * 0x11 100 1F_42 KSZ8041 118 1.9 msaitoh * 0x13 100 1F_42? KSZ8041RNLI 119 1.9 msaitoh * 0x15 ? 100 1E_20 KSZ8051 120 1.9 msaitoh * 0x5 100 1E_20 KSZ8021 121 1.9 msaitoh * 0x6 100 1E_20 KSZ8031 122 1.9 msaitoh * 0x16 ? 100 1E_20 KSZ8081 123 1.9 msaitoh * ? 100 1E_20 KSZ8091 124 1.9 msaitoh * 0x17 100 1E_20 KSZ8061 125 1.9 msaitoh * 0x21 0x0 giga GIGA KSZ9021 126 1.9 msaitoh * 0x1 giga GIGA KSZ9021RLRN 127 1.9 msaitoh * 0x9 100 1F_42 KSZ8721BL/SL 128 1.9 msaitoh * 0x9 100 none? KSZ8721CL 129 1.9 msaitoh * 0xa 100 1F_42 KSZ8001 130 1.9 msaitoh * 0x22 giga GIGA KSZ9031 131 1.11 msaitoh * 0x23 1? gigasw GIGA KSZ9477 (No master/slave bit) 132 1.9 msaitoh * 5? giga GIGA LAN7430internal 133 1.11 msaitoh * 0x24 giga GIGA KSZ9131 134 1.11 msaitoh * 0x32 100 1F_42 KS8737 135 1.9 msaitoh */ 136 1.9 msaitoh 137 1.9 msaitoh /* Type of link status register */ 138 1.9 msaitoh #define MICPHYF_LSTYPE_DEFAULT 0 139 1.9 msaitoh #define MICPHYF_LSTYPE_1F_42 1 140 1.9 msaitoh #define MICPHYF_LSTYPE_1E_20 2 141 1.9 msaitoh #define MICPHYF_LSTYPE_GIGA 3 142 1.9 msaitoh 143 1.9 msaitoh /* Return if the device is Gigabit (KSZ9021) */ 144 1.9 msaitoh #define KSZ_MODEL21H_GIGA(rev) \ 145 1.9 msaitoh ((((rev) & 0x0e) == 0) ? true : false) 146 1.9 msaitoh 147 1.9 msaitoh #define KSZ_XREG_CONTROL 0x0b 148 1.9 msaitoh #define KSZ_XREG_WRITE 0x0c 149 1.9 msaitoh #define KSZ_XREG_READ 0x0d 150 1.9 msaitoh #define KSZ_XREG_CTL_SEL_READ 0x0000 151 1.9 msaitoh #define KSZ_XREG_CTL_SEL_WRITE 0x8000 152 1.9 msaitoh 153 1.9 msaitoh #define REG_RGMII_CLOCK_AND_CONTROL 0x104 154 1.9 msaitoh #define REG_RGMII_RX_DATA 0x105 155 1.9 msaitoh 156 1.9 msaitoh /* PHY control 1 register for 10/100 PHYs (KSZ80[235689]1) */ 157 1.9 msaitoh #define KSZ8051_PHYCTL1 0x1e 158 1.9 msaitoh #define KSZ8051_PHY_LINK 0x0100 159 1.9 msaitoh #define KSZ8051_PHY_MDIX 0x0020 160 1.9 msaitoh #define KSZ8051_PHY_FDX 0x0004 161 1.9 msaitoh #define KSZ8051_PHY_SPD_MASK 0x0003 162 1.9 msaitoh #define KSZ8051_PHY_SPD_10T 0x0001 163 1.9 msaitoh #define KSZ8051_PHY_SPD_100TX 0x0002 164 1.9 msaitoh 165 1.9 msaitoh /* PHY control 2 register for 10/100 PHYs (KSZ8041, KSZ8721 and KSZ8001) */ 166 1.9 msaitoh #define KSZ8041_PHYCTL2 0x1f 167 1.9 msaitoh #define KSZ8041_PHY_ACOMP 0x0080 168 1.9 msaitoh #define KSZ8041_PHY_SPD_MASK 0x001c 169 1.9 msaitoh #define KSZ8041_PHY_SPD_10T 0x0004 170 1.9 msaitoh #define KSZ8041_PHY_SPD_100TX 0x0008 171 1.9 msaitoh #define KSZ8041_PHY_FDX 0x0010 172 1.9 msaitoh #define KSZ8051_PHYCTL2 0x1f 173 1.9 msaitoh 174 1.9 msaitoh /* PHY control register for Gigabit PHYs */ 175 1.9 msaitoh #define KSZ_GPHYCTL 0x1f 176 1.9 msaitoh #define KSZ_GPHY_SPD_1000T 0x0040 177 1.9 msaitoh #define KSZ_GPHY_SPD_100TX 0x0020 178 1.9 msaitoh #define KSZ_GPHY_SPD_10T 0x0010 179 1.9 msaitoh #define KSZ_GPHY_FDX 0x0008 180 1.9 msaitoh #define KSZ_GPHY_1000T_MS 0x0004 181 1.6 msaitoh 182 1.1 ozaki static int 183 1.1 ozaki micphymatch(device_t parent, cfdata_t match, void *aux) 184 1.1 ozaki { 185 1.1 ozaki struct mii_attach_args *ma = aux; 186 1.1 ozaki 187 1.1 ozaki if (mii_phy_match(ma, micphys) != NULL) 188 1.1 ozaki return 10; 189 1.1 ozaki 190 1.1 ozaki return 1; 191 1.1 ozaki } 192 1.1 ozaki 193 1.1 ozaki static void 194 1.1 ozaki micphyattach(device_t parent, device_t self, void *aux) 195 1.1 ozaki { 196 1.9 msaitoh struct micphy_softc *msc = device_private(self); 197 1.9 msaitoh struct mii_softc *sc = &msc->sc_mii; 198 1.1 ozaki struct mii_attach_args *ma = aux; 199 1.1 ozaki struct mii_data *mii = ma->mii_data; 200 1.1 ozaki int model = MII_MODEL(ma->mii_id2); 201 1.1 ozaki int rev = MII_REV(ma->mii_id2); 202 1.1 ozaki const struct mii_phydesc *mpd; 203 1.1 ozaki 204 1.1 ozaki mpd = mii_phy_match(ma, micphys); 205 1.1 ozaki aprint_naive(": Media interface\n"); 206 1.1 ozaki aprint_normal(": %s, rev. %d\n", mpd->mpd_name, rev); 207 1.1 ozaki 208 1.1 ozaki sc->mii_dev = self; 209 1.1 ozaki sc->mii_inst = mii->mii_instance; 210 1.1 ozaki sc->mii_phy = ma->mii_phyno; 211 1.1 ozaki sc->mii_funcs = &micphy_funcs; 212 1.1 ozaki sc->mii_pdata = mii; 213 1.1 ozaki sc->mii_flags = ma->mii_flags; 214 1.1 ozaki 215 1.9 msaitoh if ((sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8041) 216 1.9 msaitoh || (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8041RNLI) 217 1.9 msaitoh || (sc->mii_mpd_model == MII_MODEL_MICREL_KS8737) 218 1.9 msaitoh || ((sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9021_8001_8721) 219 1.9 msaitoh && !KSZ_MODEL21H_GIGA(sc->mii_mpd_rev))) { 220 1.9 msaitoh msc->sc_lstype = MICPHYF_LSTYPE_1F_42; 221 1.9 msaitoh } else if ((sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8051) 222 1.9 msaitoh || (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8081) 223 1.9 msaitoh || (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8061)) { 224 1.9 msaitoh msc->sc_lstype = MICPHYF_LSTYPE_1E_20; 225 1.9 msaitoh } else if (((sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9021_8001_8721) 226 1.9 msaitoh && KSZ_MODEL21H_GIGA(sc->mii_mpd_rev)) 227 1.9 msaitoh || (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9031) 228 1.9 msaitoh || (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9477) 229 1.9 msaitoh || (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9131)) { 230 1.9 msaitoh msc->sc_lstype = MICPHYF_LSTYPE_GIGA; 231 1.9 msaitoh } else 232 1.9 msaitoh msc->sc_lstype = MICPHYF_LSTYPE_DEFAULT; 233 1.9 msaitoh 234 1.13 thorpej mii_lock(mii); 235 1.13 thorpej 236 1.1 ozaki PHY_RESET(sc); 237 1.1 ozaki 238 1.1 ozaki micphy_fixup(sc, model, rev, parent); 239 1.1 ozaki 240 1.5 skrll PHY_READ(sc, MII_BMSR, &sc->mii_capabilities); 241 1.5 skrll sc->mii_capabilities &= ma->mii_capmask; 242 1.1 ozaki if (sc->mii_capabilities & BMSR_EXTSTAT) 243 1.5 skrll PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities); 244 1.10 msaitoh 245 1.13 thorpej mii_unlock(mii); 246 1.13 thorpej 247 1.10 msaitoh mii_phy_add_media(sc); 248 1.1 ozaki } 249 1.1 ozaki 250 1.6 msaitoh static void 251 1.6 msaitoh micphy_reset(struct mii_softc *sc) 252 1.6 msaitoh { 253 1.6 msaitoh uint16_t reg; 254 1.6 msaitoh 255 1.13 thorpej KASSERT(mii_locked(sc->mii_pdata)); 256 1.13 thorpej 257 1.6 msaitoh /* 258 1.8 msaitoh * The 8081 has no "sticky bits" that survive a soft reset; several 259 1.8 msaitoh * bits in the Phy Control Register 2 must be preserved across the 260 1.8 msaitoh * reset. These bits are set up by the bootloader; they control how the 261 1.8 msaitoh * phy interfaces to the board (such as clock frequency and LED 262 1.8 msaitoh * behavior). 263 1.6 msaitoh */ 264 1.6 msaitoh if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8081) 265 1.9 msaitoh PHY_READ(sc, KSZ8051_PHYCTL2, ®); 266 1.6 msaitoh mii_phy_reset(sc); 267 1.6 msaitoh if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8081) 268 1.9 msaitoh PHY_WRITE(sc, KSZ8051_PHYCTL2, reg); 269 1.6 msaitoh } 270 1.6 msaitoh 271 1.1 ozaki static int 272 1.1 ozaki micphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) 273 1.1 ozaki { 274 1.1 ozaki struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 275 1.5 skrll uint16_t reg; 276 1.1 ozaki 277 1.13 thorpej KASSERT(mii_locked(mii)); 278 1.13 thorpej 279 1.1 ozaki switch (cmd) { 280 1.1 ozaki case MII_POLLSTAT: 281 1.8 msaitoh /* If we're not polling our PHY instance, just return. */ 282 1.1 ozaki if (IFM_INST(ife->ifm_media) != sc->mii_inst) 283 1.1 ozaki return 0; 284 1.1 ozaki break; 285 1.1 ozaki 286 1.1 ozaki case MII_MEDIACHG: 287 1.1 ozaki /* 288 1.1 ozaki * If the media indicates a different PHY instance, 289 1.1 ozaki * isolate ourselves. 290 1.1 ozaki */ 291 1.1 ozaki if (IFM_INST(ife->ifm_media) != sc->mii_inst) { 292 1.5 skrll PHY_READ(sc, MII_BMCR, ®); 293 1.1 ozaki PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO); 294 1.1 ozaki return 0; 295 1.1 ozaki } 296 1.1 ozaki 297 1.8 msaitoh /* If the interface is not up, don't do anything. */ 298 1.1 ozaki if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 299 1.1 ozaki break; 300 1.1 ozaki 301 1.1 ozaki mii_phy_setmedia(sc); 302 1.1 ozaki break; 303 1.1 ozaki 304 1.1 ozaki case MII_TICK: 305 1.8 msaitoh /* If we're not currently selected, just return. */ 306 1.1 ozaki if (IFM_INST(ife->ifm_media) != sc->mii_inst) 307 1.1 ozaki return 0; 308 1.1 ozaki 309 1.1 ozaki if (mii_phy_tick(sc) == EJUSTRETURN) 310 1.1 ozaki return 0; 311 1.1 ozaki break; 312 1.1 ozaki 313 1.1 ozaki case MII_DOWN: 314 1.1 ozaki mii_phy_down(sc); 315 1.1 ozaki return 0; 316 1.1 ozaki } 317 1.1 ozaki 318 1.1 ozaki /* Update the media status. */ 319 1.1 ozaki mii_phy_status(sc); 320 1.1 ozaki 321 1.1 ozaki /* Callback if something changed. */ 322 1.1 ozaki mii_phy_update(sc, cmd); 323 1.1 ozaki return 0; 324 1.1 ozaki } 325 1.1 ozaki 326 1.8 msaitoh static void 327 1.8 msaitoh micphy_writexreg(struct mii_softc *sc, uint32_t reg, uint32_t wval) 328 1.1 ozaki { 329 1.5 skrll uint16_t rval __debugused; 330 1.1 ozaki 331 1.9 msaitoh PHY_WRITE(sc, KSZ_XREG_CONTROL, KSZ_XREG_CTL_SEL_WRITE | reg); 332 1.9 msaitoh PHY_WRITE(sc, KSZ_XREG_WRITE, wval); 333 1.9 msaitoh PHY_WRITE(sc, KSZ_XREG_CONTROL, KSZ_XREG_CTL_SEL_READ | reg); 334 1.9 msaitoh PHY_READ(sc, KSZ_XREG_READ, &rval); 335 1.1 ozaki KDASSERT(wval == rval); 336 1.1 ozaki } 337 1.1 ozaki 338 1.1 ozaki static void 339 1.1 ozaki micphy_fixup(struct mii_softc *sc, int model, int rev, device_t parent) 340 1.1 ozaki { 341 1.13 thorpej 342 1.13 thorpej KASSERT(mii_locked(sc->mii_pdata)); 343 1.13 thorpej 344 1.1 ozaki switch (model) { 345 1.9 msaitoh case MII_MODEL_MICREL_KSZ9021_8001_8721: 346 1.1 ozaki if (!device_is_a(parent, "cpsw")) 347 1.1 ozaki break; 348 1.1 ozaki 349 1.8 msaitoh aprint_normal_dev(sc->mii_dev, 350 1.8 msaitoh "adjusting RGMII signal timing for cpsw\n"); 351 1.1 ozaki 352 1.1 ozaki // RGMII RX Data Pad Skew 353 1.1 ozaki micphy_writexreg(sc, REG_RGMII_RX_DATA, 0x0000); 354 1.1 ozaki 355 1.1 ozaki // RGMII Clock and Control Pad Skew 356 1.1 ozaki micphy_writexreg(sc, REG_RGMII_CLOCK_AND_CONTROL, 0x9090); 357 1.1 ozaki 358 1.1 ozaki break; 359 1.8 msaitoh default: 360 1.8 msaitoh break; 361 1.1 ozaki } 362 1.1 ozaki 363 1.1 ozaki return; 364 1.1 ozaki } 365 1.9 msaitoh 366 1.9 msaitoh static void 367 1.9 msaitoh micphy_status(struct mii_softc *sc) 368 1.9 msaitoh { 369 1.9 msaitoh struct micphy_softc *msc = device_private(sc->mii_dev); 370 1.9 msaitoh struct mii_data *mii = sc->mii_pdata; 371 1.9 msaitoh uint16_t bmsr, bmcr, sr; 372 1.9 msaitoh 373 1.13 thorpej KASSERT(mii_locked(mii)); 374 1.13 thorpej 375 1.9 msaitoh /* For unknown devices */ 376 1.9 msaitoh if (msc->sc_lstype == MICPHYF_LSTYPE_DEFAULT) { 377 1.9 msaitoh ukphy_status(sc); 378 1.9 msaitoh return; 379 1.9 msaitoh } 380 1.9 msaitoh 381 1.9 msaitoh mii->mii_media_status = IFM_AVALID; 382 1.9 msaitoh mii->mii_media_active = IFM_ETHER; 383 1.9 msaitoh 384 1.9 msaitoh PHY_READ(sc, MII_BMCR, &bmcr); 385 1.9 msaitoh 386 1.9 msaitoh PHY_READ(sc, MII_BMSR, &bmsr); 387 1.9 msaitoh PHY_READ(sc, MII_BMSR, &bmsr); 388 1.9 msaitoh if (bmsr & BMSR_LINK) 389 1.9 msaitoh mii->mii_media_status |= IFM_ACTIVE; 390 1.9 msaitoh 391 1.9 msaitoh if (bmcr & BMCR_AUTOEN) { 392 1.9 msaitoh if ((bmsr & BMSR_ACOMP) == 0) { 393 1.9 msaitoh mii->mii_media_active |= IFM_NONE; 394 1.9 msaitoh return; 395 1.9 msaitoh } 396 1.9 msaitoh } 397 1.9 msaitoh 398 1.9 msaitoh if (msc->sc_lstype == MICPHYF_LSTYPE_1F_42) { 399 1.9 msaitoh PHY_READ(sc, KSZ8041_PHYCTL2, &sr); 400 1.9 msaitoh if ((sr & KSZ8041_PHY_SPD_MASK) == 0) 401 1.9 msaitoh mii->mii_media_active |= IFM_NONE; 402 1.9 msaitoh else if (sr & KSZ8041_PHY_SPD_100TX) 403 1.9 msaitoh mii->mii_media_active |= IFM_100_TX; 404 1.9 msaitoh else if (sr & KSZ8041_PHY_SPD_10T) 405 1.9 msaitoh mii->mii_media_active |= IFM_10_T; 406 1.9 msaitoh if (sr & KSZ8041_PHY_FDX) 407 1.9 msaitoh mii->mii_media_active |= IFM_FDX 408 1.9 msaitoh | mii_phy_flowstatus(sc); 409 1.9 msaitoh } else if (msc->sc_lstype == MICPHYF_LSTYPE_1E_20) { 410 1.9 msaitoh PHY_READ(sc, KSZ8051_PHYCTL1, &sr); 411 1.9 msaitoh if ((sr & KSZ8051_PHY_SPD_MASK) == 0) 412 1.9 msaitoh mii->mii_media_active |= IFM_NONE; 413 1.9 msaitoh else if (sr & KSZ8051_PHY_SPD_100TX) 414 1.9 msaitoh mii->mii_media_active |= IFM_100_TX; 415 1.9 msaitoh else if (sr & KSZ8051_PHY_SPD_10T) 416 1.9 msaitoh mii->mii_media_active |= IFM_10_T; 417 1.9 msaitoh if (sr & KSZ8051_PHY_FDX) 418 1.9 msaitoh mii->mii_media_active |= IFM_FDX 419 1.9 msaitoh | mii_phy_flowstatus(sc); 420 1.9 msaitoh } else if (msc->sc_lstype == MICPHYF_LSTYPE_GIGA) { 421 1.9 msaitoh /* 9021/9031/7430/9131 gphy */ 422 1.9 msaitoh PHY_READ(sc, KSZ_GPHYCTL, &sr); 423 1.9 msaitoh if (sr & KSZ_GPHY_SPD_1000T) 424 1.9 msaitoh mii->mii_media_active |= IFM_1000_T; 425 1.9 msaitoh else if (sr & KSZ_GPHY_SPD_100TX) 426 1.9 msaitoh mii->mii_media_active |= IFM_100_TX; 427 1.9 msaitoh else if (sr & KSZ_GPHY_SPD_10T) 428 1.9 msaitoh mii->mii_media_active |= IFM_10_T; 429 1.9 msaitoh else 430 1.9 msaitoh mii->mii_media_active |= IFM_NONE; 431 1.9 msaitoh if ((mii->mii_media_active & IFM_1000_T) 432 1.9 msaitoh && (sr & KSZ_GPHY_1000T_MS)) 433 1.9 msaitoh mii->mii_media_active |= IFM_ETH_MASTER; 434 1.9 msaitoh if (sr & KSZ_GPHY_FDX) 435 1.9 msaitoh mii->mii_media_active |= IFM_FDX 436 1.9 msaitoh | mii_phy_flowstatus(sc); 437 1.9 msaitoh else 438 1.9 msaitoh mii->mii_media_active |= IFM_HDX; 439 1.9 msaitoh } 440 1.9 msaitoh } 441