1d1307e81SPyun YongHyeon /*- 2718cf2ccSPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3718cf2ccSPedro F. Giffuni * 4d1307e81SPyun YongHyeon * Copyright (c) 2008, Pyun YongHyeon <yongari@FreeBSD.org> 5d1307e81SPyun YongHyeon * All rights reserved. 6d1307e81SPyun YongHyeon * 7d1307e81SPyun YongHyeon * Redistribution and use in source and binary forms, with or without 8d1307e81SPyun YongHyeon * modification, are permitted provided that the following conditions 9d1307e81SPyun YongHyeon * are met: 10d1307e81SPyun YongHyeon * 1. Redistributions of source code must retain the above copyright 11d1307e81SPyun YongHyeon * notice unmodified, this list of conditions, and the following 12d1307e81SPyun YongHyeon * disclaimer. 13d1307e81SPyun YongHyeon * 2. Redistributions in binary form must reproduce the above copyright 14d1307e81SPyun YongHyeon * notice, this list of conditions and the following disclaimer in the 15d1307e81SPyun YongHyeon * documentation and/or other materials provided with the distribution. 16d1307e81SPyun YongHyeon * 17d1307e81SPyun YongHyeon * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18d1307e81SPyun YongHyeon * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19d1307e81SPyun YongHyeon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20d1307e81SPyun YongHyeon * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21d1307e81SPyun YongHyeon * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22d1307e81SPyun YongHyeon * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23d1307e81SPyun YongHyeon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24d1307e81SPyun YongHyeon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25d1307e81SPyun YongHyeon * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26d1307e81SPyun YongHyeon * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27d1307e81SPyun YongHyeon * SUCH DAMAGE. 28d1307e81SPyun YongHyeon */ 29d1307e81SPyun YongHyeon 30d1307e81SPyun YongHyeon #include <sys/cdefs.h> 31d1307e81SPyun YongHyeon __FBSDID("$FreeBSD$"); 32d1307e81SPyun YongHyeon 33d1307e81SPyun YongHyeon /* 34d1307e81SPyun YongHyeon * Driver for the Attansic/Atheros F1 10/100/1000 PHY. 35d1307e81SPyun YongHyeon */ 36d1307e81SPyun YongHyeon 37d1307e81SPyun YongHyeon #include <sys/param.h> 38d1307e81SPyun YongHyeon #include <sys/systm.h> 39d1307e81SPyun YongHyeon #include <sys/kernel.h> 40d1307e81SPyun YongHyeon #include <sys/module.h> 41d1307e81SPyun YongHyeon #include <sys/socket.h> 42d1307e81SPyun YongHyeon #include <sys/bus.h> 43d1307e81SPyun YongHyeon 44d1307e81SPyun YongHyeon #include <net/if.h> 45d1307e81SPyun YongHyeon #include <net/if_media.h> 46d1307e81SPyun YongHyeon 47d1307e81SPyun YongHyeon #include <dev/mii/mii.h> 48d1307e81SPyun YongHyeon #include <dev/mii/miivar.h> 49d1307e81SPyun YongHyeon #include "miidevs.h" 50d1307e81SPyun YongHyeon 51d1307e81SPyun YongHyeon #include <dev/mii/atphyreg.h> 52d1307e81SPyun YongHyeon 53d1307e81SPyun YongHyeon #include "miibus_if.h" 54d1307e81SPyun YongHyeon 55d1307e81SPyun YongHyeon static int atphy_probe(device_t); 56d1307e81SPyun YongHyeon static int atphy_attach(device_t); 57d1307e81SPyun YongHyeon 58d1307e81SPyun YongHyeon static device_method_t atphy_methods[] = { 59d1307e81SPyun YongHyeon /* Device interface. */ 60d1307e81SPyun YongHyeon DEVMETHOD(device_probe, atphy_probe), 61d1307e81SPyun YongHyeon DEVMETHOD(device_attach, atphy_attach), 62d1307e81SPyun YongHyeon DEVMETHOD(device_detach, mii_phy_detach), 63d1307e81SPyun YongHyeon DEVMETHOD(device_shutdown, bus_generic_shutdown), 64604f5f1fSMarius Strobl DEVMETHOD_END 65d1307e81SPyun YongHyeon }; 66d1307e81SPyun YongHyeon 67d1307e81SPyun YongHyeon static driver_t atphy_driver = { 68d1307e81SPyun YongHyeon "atphy", 69d1307e81SPyun YongHyeon atphy_methods, 703fcb7a53SMarius Strobl sizeof(struct mii_softc) 71d1307e81SPyun YongHyeon }; 72d1307e81SPyun YongHyeon 73*f438c2ffSJohn Baldwin DRIVER_MODULE(atphy, miibus, atphy_driver, 0, 0); 74d1307e81SPyun YongHyeon 75d1307e81SPyun YongHyeon static int atphy_service(struct mii_softc *, struct mii_data *, int); 76d1307e81SPyun YongHyeon static void atphy_status(struct mii_softc *); 77d1307e81SPyun YongHyeon static void atphy_reset(struct mii_softc *); 78d1307e81SPyun YongHyeon static uint16_t atphy_anar(struct ifmedia_entry *); 79991ab941SMarius Strobl static int atphy_setmedia(struct mii_softc *, int); 80d1307e81SPyun YongHyeon 81d1307e81SPyun YongHyeon static const struct mii_phydesc atphys[] = { 823fcb7a53SMarius Strobl MII_PHY_DESC(xxATHEROS, F1), 833fcb7a53SMarius Strobl MII_PHY_DESC(xxATHEROS, F1_7), 84f26725deSNathan Whitehorn MII_PHY_DESC(xxATHEROS, AR8021), 853fcb7a53SMarius Strobl MII_PHY_DESC(xxATHEROS, F2), 86d1307e81SPyun YongHyeon MII_PHY_END 87d1307e81SPyun YongHyeon }; 88d1307e81SPyun YongHyeon 893fcb7a53SMarius Strobl static const struct mii_phy_funcs atphy_funcs = { 903fcb7a53SMarius Strobl atphy_service, 913fcb7a53SMarius Strobl atphy_status, 923fcb7a53SMarius Strobl atphy_reset 933fcb7a53SMarius Strobl }; 943fcb7a53SMarius Strobl 95d1307e81SPyun YongHyeon static int 96d1307e81SPyun YongHyeon atphy_probe(device_t dev) 97d1307e81SPyun YongHyeon { 98d1307e81SPyun YongHyeon 99d1307e81SPyun YongHyeon return (mii_phy_dev_probe(dev, atphys, BUS_PROBE_DEFAULT)); 100d1307e81SPyun YongHyeon } 101d1307e81SPyun YongHyeon 102d1307e81SPyun YongHyeon static int 103d1307e81SPyun YongHyeon atphy_attach(device_t dev) 104d1307e81SPyun YongHyeon { 105d1307e81SPyun YongHyeon 1063fcb7a53SMarius Strobl mii_phy_dev_attach(dev, MIIF_NOMANPAUSE, &atphy_funcs, 1); 107d1307e81SPyun YongHyeon return (0); 108d1307e81SPyun YongHyeon } 109d1307e81SPyun YongHyeon 110d1307e81SPyun YongHyeon static int 111d1307e81SPyun YongHyeon atphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) 112d1307e81SPyun YongHyeon { 113d1307e81SPyun YongHyeon struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 114d1307e81SPyun YongHyeon uint16_t anar, bmcr, bmsr; 115d1307e81SPyun YongHyeon 116d1307e81SPyun YongHyeon switch (cmd) { 117d1307e81SPyun YongHyeon case MII_POLLSTAT: 118d1307e81SPyun YongHyeon break; 119d1307e81SPyun YongHyeon 120d1307e81SPyun YongHyeon case MII_MEDIACHG: 121d1307e81SPyun YongHyeon if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO || 122d1307e81SPyun YongHyeon IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) { 123991ab941SMarius Strobl atphy_setmedia(sc, ife->ifm_media); 124d1307e81SPyun YongHyeon break; 125d1307e81SPyun YongHyeon } 126d1307e81SPyun YongHyeon 127d1307e81SPyun YongHyeon bmcr = 0; 128d1307e81SPyun YongHyeon switch (IFM_SUBTYPE(ife->ifm_media)) { 129d1307e81SPyun YongHyeon case IFM_100_TX: 130d1307e81SPyun YongHyeon bmcr = BMCR_S100; 131d1307e81SPyun YongHyeon break; 132d1307e81SPyun YongHyeon case IFM_10_T: 133d1307e81SPyun YongHyeon bmcr = BMCR_S10; 134d1307e81SPyun YongHyeon break; 135d1307e81SPyun YongHyeon case IFM_NONE: 136d1307e81SPyun YongHyeon bmcr = PHY_READ(sc, MII_BMCR); 137d1307e81SPyun YongHyeon /* 138d1307e81SPyun YongHyeon * XXX 139d1307e81SPyun YongHyeon * Due to an unknown reason powering down PHY resulted 140991ab941SMarius Strobl * in unexpected results such as inaccessibility of 141d1307e81SPyun YongHyeon * hardware of freshly rebooted system. Disable 142d1307e81SPyun YongHyeon * powering down PHY until I got more information for 143d1307e81SPyun YongHyeon * Attansic/Atheros PHY hardwares. 144d1307e81SPyun YongHyeon */ 145d1307e81SPyun YongHyeon PHY_WRITE(sc, MII_BMCR, bmcr | BMCR_ISO); 146d1307e81SPyun YongHyeon goto done; 147d1307e81SPyun YongHyeon default: 148d1307e81SPyun YongHyeon return (EINVAL); 149d1307e81SPyun YongHyeon } 150d1307e81SPyun YongHyeon 151d1307e81SPyun YongHyeon anar = atphy_anar(ife); 15234259ba3SMarius Strobl if ((ife->ifm_media & IFM_FDX) != 0) { 153d1307e81SPyun YongHyeon bmcr |= BMCR_FDX; 15434259ba3SMarius Strobl if ((ife->ifm_media & IFM_FLOW) != 0 || 155991ab941SMarius Strobl (sc->mii_flags & MIIF_FORCEPAUSE) != 0) 156991ab941SMarius Strobl anar |= ANAR_PAUSE_TOWARDS; 157d1307e81SPyun YongHyeon } 158d1307e81SPyun YongHyeon 159d1307e81SPyun YongHyeon if ((sc->mii_extcapabilities & (EXTSR_1000TFDX | 160d1307e81SPyun YongHyeon EXTSR_1000THDX)) != 0) 161d1307e81SPyun YongHyeon PHY_WRITE(sc, MII_100T2CR, 0); 162d1307e81SPyun YongHyeon PHY_WRITE(sc, MII_ANAR, anar | ANAR_CSMA); 163d1307e81SPyun YongHyeon 164d1307e81SPyun YongHyeon /* 165d1307e81SPyun YongHyeon * Reset the PHY so all changes take effect. 166d1307e81SPyun YongHyeon */ 167d2cd2263SPyun YongHyeon PHY_WRITE(sc, MII_BMCR, bmcr | BMCR_RESET | BMCR_AUTOEN | 168d2cd2263SPyun YongHyeon BMCR_STARTNEG); 169d1307e81SPyun YongHyeon done: 170d1307e81SPyun YongHyeon break; 171d1307e81SPyun YongHyeon 172d1307e81SPyun YongHyeon case MII_TICK: 173d1307e81SPyun YongHyeon /* 174d1307e81SPyun YongHyeon * Only used for autonegotiation. 175d1307e81SPyun YongHyeon */ 176d1307e81SPyun YongHyeon if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) { 177d1307e81SPyun YongHyeon sc->mii_ticks = 0; 178d1307e81SPyun YongHyeon break; 179d1307e81SPyun YongHyeon } 180d1307e81SPyun YongHyeon 181d1307e81SPyun YongHyeon /* 182991ab941SMarius Strobl * Check for link. 183d1307e81SPyun YongHyeon * Read the status register twice; BMSR_LINK is latch-low. 184d1307e81SPyun YongHyeon */ 185d1307e81SPyun YongHyeon bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); 186d1307e81SPyun YongHyeon if (bmsr & BMSR_LINK) { 187d1307e81SPyun YongHyeon sc->mii_ticks = 0; 188d1307e81SPyun YongHyeon break; 189d1307e81SPyun YongHyeon } 190d1307e81SPyun YongHyeon 191d1307e81SPyun YongHyeon /* Announce link loss right after it happens. */ 192d1307e81SPyun YongHyeon if (sc->mii_ticks++ == 0) 193d1307e81SPyun YongHyeon break; 194d1307e81SPyun YongHyeon if (sc->mii_ticks <= sc->mii_anegticks) 195d1307e81SPyun YongHyeon return (0); 196d1307e81SPyun YongHyeon 197d1307e81SPyun YongHyeon sc->mii_ticks = 0; 198991ab941SMarius Strobl atphy_setmedia(sc, ife->ifm_media); 199d1307e81SPyun YongHyeon break; 200d1307e81SPyun YongHyeon } 201d1307e81SPyun YongHyeon 202d1307e81SPyun YongHyeon /* Update the media status. */ 2033fcb7a53SMarius Strobl PHY_STATUS(sc); 204d1307e81SPyun YongHyeon 205d1307e81SPyun YongHyeon /* Callback if something changed. */ 206d1307e81SPyun YongHyeon mii_phy_update(sc, cmd); 207d1307e81SPyun YongHyeon return (0); 208d1307e81SPyun YongHyeon } 209d1307e81SPyun YongHyeon 210d1307e81SPyun YongHyeon static void 211d1307e81SPyun YongHyeon atphy_status(struct mii_softc *sc) 212d1307e81SPyun YongHyeon { 213d1307e81SPyun YongHyeon struct mii_data *mii = sc->mii_pdata; 214d1307e81SPyun YongHyeon uint32_t bmsr, bmcr, ssr; 215d1307e81SPyun YongHyeon 216d1307e81SPyun YongHyeon mii->mii_media_status = IFM_AVALID; 217d1307e81SPyun YongHyeon mii->mii_media_active = IFM_ETHER; 218d1307e81SPyun YongHyeon 219d1307e81SPyun YongHyeon bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); 220d1307e81SPyun YongHyeon if ((bmsr & BMSR_LINK) != 0) 221d1307e81SPyun YongHyeon mii->mii_media_status |= IFM_ACTIVE; 222d1307e81SPyun YongHyeon 223d1307e81SPyun YongHyeon bmcr = PHY_READ(sc, MII_BMCR); 224d1307e81SPyun YongHyeon if ((bmcr & BMCR_ISO) != 0) { 225d1307e81SPyun YongHyeon mii->mii_media_active |= IFM_NONE; 226d1307e81SPyun YongHyeon mii->mii_media_status = 0; 227d1307e81SPyun YongHyeon return; 228d1307e81SPyun YongHyeon } 229d1307e81SPyun YongHyeon 230d1307e81SPyun YongHyeon if ((bmcr & BMCR_LOOP) != 0) 231d1307e81SPyun YongHyeon mii->mii_media_active |= IFM_LOOP; 232d1307e81SPyun YongHyeon 233d1307e81SPyun YongHyeon ssr = PHY_READ(sc, ATPHY_SSR); 234d1307e81SPyun YongHyeon if ((ssr & ATPHY_SSR_SPD_DPLX_RESOLVED) == 0) { 235d1307e81SPyun YongHyeon /* Erg, still trying, I guess... */ 236d1307e81SPyun YongHyeon mii->mii_media_active |= IFM_NONE; 237d1307e81SPyun YongHyeon return; 238d1307e81SPyun YongHyeon } 239d1307e81SPyun YongHyeon 240d1307e81SPyun YongHyeon switch (ssr & ATPHY_SSR_SPEED_MASK) { 241d1307e81SPyun YongHyeon case ATPHY_SSR_1000MBS: 242d1307e81SPyun YongHyeon mii->mii_media_active |= IFM_1000_T; 243d1307e81SPyun YongHyeon /* 244991ab941SMarius Strobl * atphy(4) has a valid link so reset mii_ticks. 245d1307e81SPyun YongHyeon * Resetting mii_ticks is needed in order to 246d1307e81SPyun YongHyeon * detect link loss after auto-negotiation. 247d1307e81SPyun YongHyeon */ 248d1307e81SPyun YongHyeon sc->mii_ticks = 0; 249d1307e81SPyun YongHyeon break; 250d1307e81SPyun YongHyeon case ATPHY_SSR_100MBS: 251d1307e81SPyun YongHyeon mii->mii_media_active |= IFM_100_TX; 252d1307e81SPyun YongHyeon sc->mii_ticks = 0; 253d1307e81SPyun YongHyeon break; 254d1307e81SPyun YongHyeon case ATPHY_SSR_10MBS: 255d1307e81SPyun YongHyeon mii->mii_media_active |= IFM_10_T; 256d1307e81SPyun YongHyeon sc->mii_ticks = 0; 257d1307e81SPyun YongHyeon break; 258d1307e81SPyun YongHyeon default: 259d1307e81SPyun YongHyeon mii->mii_media_active |= IFM_NONE; 260d1307e81SPyun YongHyeon return; 261d1307e81SPyun YongHyeon } 262d1307e81SPyun YongHyeon 263d1307e81SPyun YongHyeon if ((ssr & ATPHY_SSR_DUPLEX) != 0) 264991ab941SMarius Strobl mii->mii_media_active |= IFM_FDX | mii_phy_flowstatus(sc); 265d1307e81SPyun YongHyeon else 266d1307e81SPyun YongHyeon mii->mii_media_active |= IFM_HDX; 267d1307e81SPyun YongHyeon 268991ab941SMarius Strobl if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) && 269991ab941SMarius Strobl (PHY_READ(sc, MII_100T2SR) & GTSR_MS_RES) != 0) 270991ab941SMarius Strobl mii->mii_media_active |= IFM_ETH_MASTER; 271d1307e81SPyun YongHyeon } 272d1307e81SPyun YongHyeon 273d1307e81SPyun YongHyeon static void 274d1307e81SPyun YongHyeon atphy_reset(struct mii_softc *sc) 275d1307e81SPyun YongHyeon { 276bab85d8dSMarius Strobl struct ifmedia_entry *ife = sc->mii_pdata->mii_media.ifm_cur; 277d1307e81SPyun YongHyeon uint32_t reg; 278d1307e81SPyun YongHyeon int i; 279d1307e81SPyun YongHyeon 280d1307e81SPyun YongHyeon /* Take PHY out of power down mode. */ 281d1307e81SPyun YongHyeon PHY_WRITE(sc, 29, 0x29); 282d1307e81SPyun YongHyeon PHY_WRITE(sc, 30, 0); 283d1307e81SPyun YongHyeon 284d1307e81SPyun YongHyeon reg = PHY_READ(sc, ATPHY_SCR); 285d1307e81SPyun YongHyeon /* Enable automatic crossover. */ 286d1307e81SPyun YongHyeon reg |= ATPHY_SCR_AUTO_X_MODE; 287d1307e81SPyun YongHyeon /* Disable power down. */ 288d1307e81SPyun YongHyeon reg &= ~ATPHY_SCR_MAC_PDOWN; 289d1307e81SPyun YongHyeon /* Enable CRS on Tx. */ 290d1307e81SPyun YongHyeon reg |= ATPHY_SCR_ASSERT_CRS_ON_TX; 291d1307e81SPyun YongHyeon /* Auto correction for reversed cable polarity. */ 292d1307e81SPyun YongHyeon reg |= ATPHY_SCR_POLARITY_REVERSAL; 293d1307e81SPyun YongHyeon PHY_WRITE(sc, ATPHY_SCR, reg); 294d1307e81SPyun YongHyeon 295d1307e81SPyun YongHyeon /* Workaround F1 bug to reset phy. */ 296bab85d8dSMarius Strobl atphy_setmedia(sc, ife == NULL ? IFM_AUTO : ife->ifm_media); 297d1307e81SPyun YongHyeon 298d1307e81SPyun YongHyeon for (i = 0; i < 1000; i++) { 299d1307e81SPyun YongHyeon DELAY(1); 300d1307e81SPyun YongHyeon if ((PHY_READ(sc, MII_BMCR) & BMCR_RESET) == 0) 301d1307e81SPyun YongHyeon break; 302d1307e81SPyun YongHyeon } 303d1307e81SPyun YongHyeon } 304d1307e81SPyun YongHyeon 305d1307e81SPyun YongHyeon static uint16_t 306d1307e81SPyun YongHyeon atphy_anar(struct ifmedia_entry *ife) 307d1307e81SPyun YongHyeon { 308d1307e81SPyun YongHyeon uint16_t anar; 309d1307e81SPyun YongHyeon 310d1307e81SPyun YongHyeon anar = 0; 311d1307e81SPyun YongHyeon switch (IFM_SUBTYPE(ife->ifm_media)) { 312d1307e81SPyun YongHyeon case IFM_AUTO: 313d1307e81SPyun YongHyeon anar |= ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10; 314d1307e81SPyun YongHyeon return (anar); 315d1307e81SPyun YongHyeon case IFM_1000_T: 316d1307e81SPyun YongHyeon return (anar); 317d1307e81SPyun YongHyeon case IFM_100_TX: 318d1307e81SPyun YongHyeon anar |= ANAR_TX; 319d1307e81SPyun YongHyeon break; 320d1307e81SPyun YongHyeon case IFM_10_T: 321d1307e81SPyun YongHyeon anar |= ANAR_10; 322d1307e81SPyun YongHyeon break; 323d1307e81SPyun YongHyeon default: 324d1307e81SPyun YongHyeon return (0); 325d1307e81SPyun YongHyeon } 326d1307e81SPyun YongHyeon 32734259ba3SMarius Strobl if ((ife->ifm_media & IFM_FDX) != 0) { 328d1307e81SPyun YongHyeon if (IFM_SUBTYPE(ife->ifm_media) == IFM_100_TX) 329d1307e81SPyun YongHyeon anar |= ANAR_TX_FD; 330d1307e81SPyun YongHyeon else 331d1307e81SPyun YongHyeon anar |= ANAR_10_FD; 332d1307e81SPyun YongHyeon } 333d1307e81SPyun YongHyeon 334d1307e81SPyun YongHyeon return (anar); 335d1307e81SPyun YongHyeon } 336d1307e81SPyun YongHyeon 337d1307e81SPyun YongHyeon static int 338991ab941SMarius Strobl atphy_setmedia(struct mii_softc *sc, int media) 339d1307e81SPyun YongHyeon { 340d1307e81SPyun YongHyeon uint16_t anar; 341d1307e81SPyun YongHyeon 342991ab941SMarius Strobl anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA; 34334259ba3SMarius Strobl if ((IFM_SUBTYPE(media) == IFM_AUTO || (media & IFM_FDX) != 0) && 34434259ba3SMarius Strobl ((media & IFM_FLOW) != 0 || 34534259ba3SMarius Strobl (sc->mii_flags & MIIF_FORCEPAUSE) != 0)) 346991ab941SMarius Strobl anar |= ANAR_PAUSE_TOWARDS; 347991ab941SMarius Strobl PHY_WRITE(sc, MII_ANAR, anar); 34834259ba3SMarius Strobl if ((sc->mii_extcapabilities & 34934259ba3SMarius Strobl (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0) 350d1307e81SPyun YongHyeon PHY_WRITE(sc, MII_100T2CR, GTCR_ADV_1000TFDX | 351d1307e81SPyun YongHyeon GTCR_ADV_1000THDX); 352f6d9580dSPyun YongHyeon else if (sc->mii_mpd_model == MII_MODEL_xxATHEROS_F1) { 353f6d9580dSPyun YongHyeon /* 354f6d9580dSPyun YongHyeon * AR8132 has 10/100 PHY and the PHY uses the same 355f6d9580dSPyun YongHyeon * model number of F1 gigabit PHY. The PHY has no 356f6d9580dSPyun YongHyeon * ability to establish gigabit link so explicitly 357f6d9580dSPyun YongHyeon * disable 1000baseT configuration for the PHY. 358f6d9580dSPyun YongHyeon * Otherwise, there is a case that atphy(4) could 359f6d9580dSPyun YongHyeon * not establish a link against gigabit link partner 360f6d9580dSPyun YongHyeon * unless the link partner supports down-shifting. 361f6d9580dSPyun YongHyeon */ 362f6d9580dSPyun YongHyeon PHY_WRITE(sc, MII_100T2CR, 0); 363f6d9580dSPyun YongHyeon } 364d1307e81SPyun YongHyeon PHY_WRITE(sc, MII_BMCR, BMCR_RESET | BMCR_AUTOEN | BMCR_STARTNEG); 365d1307e81SPyun YongHyeon 366d1307e81SPyun YongHyeon return (EJUSTRETURN); 367d1307e81SPyun YongHyeon } 368