1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2012 Gary Mills
  24  *
  25  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  26  */
  27 /*
  28  * Copyright (c) 2008, Pyun YongHyeon <yongari@FreeBSD.org>
  29  * All rights reserved.
  30  *
  31  * Redistribution and use in source and binary forms, with or without
  32  * modification, are permitted provided that the following conditions
  33  * are met:
  34  * 1. Redistributions of source code must retain the above copyright
  35  *    notice unmodified, this list of conditions, and the following
  36  *    disclaimer.
  37  * 2. Redistributions in binary form must reproduce the above copyright
  38  *    notice, this list of conditions and the following disclaimer in the
  39  *    documentation and/or other materials provided with the distribution.
  40  *
  41  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  51  * SUCH DAMAGE.
  52  */
  53 
  54 #include <sys/mii.h>
  55 #include <sys/miiregs.h>
  56 
  57 #include "atge.h"
  58 #include "atge_cmn_reg.h"
  59 #include "atge_l1c_reg.h"
  60 #include "atge_l1e_reg.h"
  61 #include "atge_l1_reg.h"
  62 
  63 uint16_t
  64 atge_mii_read(void *arg, uint8_t phy, uint8_t reg)
  65 {
  66         atge_t  *atgep = arg;
  67         uint32_t v;
  68         int i;
  69 
  70         mutex_enter(&atgep->atge_mii_lock);
  71 
  72         OUTL(atgep, ATGE_MDIO, MDIO_OP_EXECUTE | MDIO_OP_READ |
  73             MDIO_SUP_PREAMBLE | MDIO_CLK_25_4 | MDIO_REG_ADDR(reg));
  74 
  75         for (i = PHY_TIMEOUT; i > 0; i--) {
  76                 drv_usecwait(5);
  77                 v = INL(atgep, ATGE_MDIO);
  78                 if ((v & (MDIO_OP_EXECUTE | MDIO_OP_BUSY)) == 0)
  79                         break;
  80         }
  81 
  82         mutex_exit(&atgep->atge_mii_lock);
  83 
  84         if (i == 0) {
  85                 atge_error(atgep->atge_dip, "PHY (%d) read timeout : %d",
  86                     phy, reg);
  87 
  88                 return (0xffff);
  89         }
  90 
  91         /*
  92          * Some fast ethernet chips may not be able to auto-nego with
  93          * switches even though they have 1000T based PHY. Hence we mask
  94          * 1000T based capabilities.
  95          */
  96         if (atgep->atge_flags & ATGE_FLAG_FASTETHER) {
  97                 if (reg == MII_STATUS)
  98                         v &= ~MII_STATUS_EXTSTAT;
  99                 else if (reg == MII_EXTSTATUS)
 100                         v = 0;
 101         }
 102 
 103         return ((v & MDIO_DATA_MASK) >> MDIO_DATA_SHIFT);
 104 }
 105 
 106 void
 107 atge_mii_write(void *arg, uint8_t phy, uint8_t reg, uint16_t val)
 108 {
 109         atge_t  *atgep = arg;
 110         uint32_t v;
 111         int i;
 112 
 113         mutex_enter(&atgep->atge_mii_lock);
 114 
 115         OUTL(atgep, ATGE_MDIO, MDIO_OP_EXECUTE | MDIO_OP_WRITE |
 116             (val & MDIO_DATA_MASK) << MDIO_DATA_SHIFT |
 117             MDIO_SUP_PREAMBLE | MDIO_CLK_25_4 | MDIO_REG_ADDR(reg));
 118 
 119         for (i = PHY_TIMEOUT; i > 0; i--) {
 120                 drv_usecwait(5);
 121                 v = INL(atgep, ATGE_MDIO);
 122                 if ((v & (MDIO_OP_EXECUTE | MDIO_OP_BUSY)) == 0)
 123                         break;
 124         }
 125 
 126         mutex_exit(&atgep->atge_mii_lock);
 127 
 128         if (i == 0) {
 129                 atge_error(atgep->atge_dip, "PHY (%d) write timeout:reg %d,"
 130                     "  val :%d", phy, reg, val);
 131         }
 132 }
 133 
 134 void
 135 atge_l1e_mii_reset(void *arg)
 136 {
 137         atge_t *atgep = arg;
 138         int phyaddr;
 139 
 140         phyaddr = mii_get_addr(atgep->atge_mii);
 141 
 142         OUTW(atgep, ATGE_GPHY_CTRL,
 143             GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE | GPHY_CTRL_SEL_ANA_RESET |
 144             GPHY_CTRL_PHY_PLL_ON);
 145         drv_usecwait(1000);
 146 
 147         OUTW(atgep, ATGE_GPHY_CTRL,
 148             GPHY_CTRL_EXT_RESET | GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE |
 149             GPHY_CTRL_SEL_ANA_RESET | GPHY_CTRL_PHY_PLL_ON);
 150         drv_usecwait(1000);
 151 
 152         /*
 153          * Some fast ethernet chips may not be able to auto-nego with
 154          * switches even though they have 1000T based PHY. Hence we need
 155          * to write 0 to MII_MSCONTROL control register.
 156          */
 157         if (atgep->atge_flags & ATGE_FLAG_FASTETHER)
 158                 atge_mii_write(atgep, phyaddr, MII_MSCONTROL, 0x0);
 159 
 160         /* Enable hibernation mode. */
 161         atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x0B);
 162         atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0xBC00);
 163 
 164         /* Set Class A/B for all modes. */
 165         atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x00);
 166         atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x02EF);
 167 
 168         /* Enable 10BT power saving. */
 169         atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x12);
 170         atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x4C04);
 171 
 172         /* Adjust 1000T power. */
 173         atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x04);
 174         atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x8BBB);
 175 
 176         /* 10BT center tap voltage. */
 177         atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x05);
 178         atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x2C46);
 179         drv_usecwait(1000);
 180 }
 181 
 182 void
 183 atge_l1_mii_reset(void *arg)
 184 {
 185         atge_t *atgep = arg;
 186         int linkup, i;
 187         uint16_t reg, pn;
 188         int phyaddr;
 189 
 190         phyaddr = mii_get_addr(atgep->atge_mii);
 191 
 192         OUTL(atgep, ATGE_GPHY_CTRL, GPHY_CTRL_RST);
 193         drv_usecwait(1000);
 194 
 195         OUTL(atgep, ATGE_GPHY_CTRL, GPHY_CTRL_CLR);
 196         drv_usecwait(1000);
 197 
 198         atge_mii_write(atgep, phyaddr, MII_CONTROL, MII_CONTROL_RESET);
 199 
 200         for (linkup = 0, pn = 0; pn < 4; pn++) {
 201                 atge_mii_write(atgep, phyaddr, ATPHY_CDTC,
 202                     (pn << PHY_CDTC_POFF) | PHY_CDTC_ENB);
 203 
 204                 for (i = 200; i > 0; i--) {
 205                         drv_usecwait(1000);
 206 
 207                         reg = atge_mii_read(atgep, phyaddr, ATPHY_CDTC);
 208 
 209                         if ((reg & PHY_CDTC_ENB) == 0)
 210                                 break;
 211                 }
 212 
 213                 drv_usecwait(1000);
 214 
 215                 reg = atge_mii_read(atgep, phyaddr, ATPHY_CDTS);
 216 
 217                 if ((reg & PHY_CDTS_STAT_MASK) != PHY_CDTS_STAT_OPEN) {
 218                         linkup++;
 219                         break;
 220                 }
 221         }
 222 
 223         atge_mii_write(atgep, phyaddr, MII_CONTROL,
 224             MII_CONTROL_RESET |  MII_CONTROL_ANE | MII_CONTROL_RSAN);
 225 
 226         if (linkup == 0) {
 227                 atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0);
 228                 atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x124E);
 229 
 230                 atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 1);
 231                 reg = atge_mii_read(atgep, phyaddr, ATPHY_DBG_DATA);
 232                 atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, reg | 0x03);
 233 
 234                 drv_usecwait(1500 * 1000);
 235 
 236                 atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0);
 237                 atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x024E);
 238         }
 239 }
 240 
 241 void
 242 atge_l1c_mii_reset(void *arg)
 243 {
 244         atge_t *atgep = arg;
 245         uint16_t data;
 246         int phyaddr;
 247 
 248         phyaddr = mii_get_addr(atgep->atge_mii);
 249 
 250         /* Reset magic from Linux, via Freebsd */
 251         OUTW(atgep, ATGE_GPHY_CTRL,
 252             GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE | GPHY_CTRL_SEL_ANA_RESET);
 253         (void) INW(atgep, ATGE_GPHY_CTRL);
 254         drv_usecwait(10 * 1000);
 255 
 256         OUTW(atgep, ATGE_GPHY_CTRL,
 257             GPHY_CTRL_EXT_RESET | GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE |
 258             GPHY_CTRL_SEL_ANA_RESET);
 259         (void) INW(atgep, ATGE_GPHY_CTRL);
 260         drv_usecwait(10 * 1000);
 261 
 262         /*
 263          * Some fast ethernet chips may not be able to auto-nego with
 264          * switches even though they have 1000T based PHY. Hence we need
 265          * to write 0 to MII_MSCONTROL control register.
 266          */
 267         if (atgep->atge_flags & ATGE_FLAG_FASTETHER)
 268                 atge_mii_write(atgep, phyaddr, MII_MSCONTROL, 0x0);
 269 
 270         /* DSP fixup, Vendor magic. */
 271         switch (ATGE_DID(atgep)) {
 272                 uint16_t reg;
 273 
 274         case ATGE_CHIP_AR8152V1_DEV_ID:
 275                 atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x000A);
 276                 reg = atge_mii_read(atgep, phyaddr, ATPHY_DBG_DATA);
 277                 atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, reg & 0xDFFF);
 278                 /* FALLTHROUGH */
 279         case ATGE_CHIP_AR8151V2_DEV_ID:
 280         case ATGE_CHIP_AR8151V1_DEV_ID:
 281         case ATGE_CHIP_AR8152V2_DEV_ID:
 282                 atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x003B);
 283                 reg = atge_mii_read(atgep, phyaddr, ATPHY_DBG_DATA);
 284                 atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, reg & 0xFFF7);
 285                 drv_usecwait(20 * 1000);
 286                 break;
 287         }
 288 
 289         switch (ATGE_DID(atgep)) {
 290         case ATGE_CHIP_AR8151V1_DEV_ID:
 291                 atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x0029);
 292                 atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x929D);
 293                 break;
 294         case ATGE_CHIP_AR8151V2_DEV_ID:
 295         case ATGE_CHIP_AR8152V2_DEV_ID:
 296         case ATGE_CHIP_L1CG_DEV_ID:
 297         case ATGE_CHIP_L1CF_DEV_ID:
 298                 atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x0029);
 299                 atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0xB6DD);
 300                 break;
 301         }
 302 
 303         /* Load DSP codes, vendor magic. */
 304         data = ANA_LOOP_SEL_10BT | ANA_EN_MASK_TB | ANA_EN_10BT_IDLE |
 305             ((1 << ANA_INTERVAL_SEL_TIMER_SHIFT) &
 306             ANA_INTERVAL_SEL_TIMER_MASK);
 307         atge_mii_write(atgep, phyaddr,
 308             ATPHY_DBG_ADDR, MII_ANA_CFG18);
 309         atge_mii_write(atgep, phyaddr,
 310             ATPHY_DBG_DATA, data);
 311 
 312         data = ((2 << ANA_SERDES_CDR_BW_SHIFT) & ANA_SERDES_CDR_BW_MASK) |
 313             ANA_MS_PAD_DBG | ANA_SERDES_EN_DEEM | ANA_SERDES_SEL_HSP |
 314             ANA_SERDES_EN_PLL | ANA_SERDES_EN_LCKDT;
 315         atge_mii_write(atgep, phyaddr,
 316             ATPHY_DBG_ADDR, MII_ANA_CFG5);
 317         atge_mii_write(atgep, phyaddr,
 318             ATPHY_DBG_DATA, data);
 319 
 320         data = ((44 << ANA_LONG_CABLE_TH_100_SHIFT) &
 321             ANA_LONG_CABLE_TH_100_MASK) |
 322             ((33 << ANA_SHORT_CABLE_TH_100_SHIFT) &
 323             ANA_SHORT_CABLE_TH_100_SHIFT) |
 324             ANA_BP_BAD_LINK_ACCUM | ANA_BP_SMALL_BW;
 325         atge_mii_write(atgep, phyaddr,
 326             ATPHY_DBG_ADDR, MII_ANA_CFG54);
 327         atge_mii_write(atgep, phyaddr,
 328             ATPHY_DBG_DATA, data);
 329 
 330         data = ((11 << ANA_IECHO_ADJ_3_SHIFT) & ANA_IECHO_ADJ_3_MASK) |
 331             ((11 << ANA_IECHO_ADJ_2_SHIFT) & ANA_IECHO_ADJ_2_MASK) |
 332             ((8 << ANA_IECHO_ADJ_1_SHIFT) & ANA_IECHO_ADJ_1_MASK) |
 333             ((8 << ANA_IECHO_ADJ_0_SHIFT) & ANA_IECHO_ADJ_0_MASK);
 334         atge_mii_write(atgep, phyaddr,
 335             ATPHY_DBG_ADDR, MII_ANA_CFG4);
 336         atge_mii_write(atgep, phyaddr,
 337             ATPHY_DBG_DATA, data);
 338 
 339         data = ((7 & ANA_MANUL_SWICH_ON_SHIFT) & ANA_MANUL_SWICH_ON_MASK) |
 340             ANA_RESTART_CAL | ANA_MAN_ENABLE | ANA_SEL_HSP | ANA_EN_HB |
 341             ANA_OEN_125M;
 342         atge_mii_write(atgep, phyaddr,
 343             ATPHY_DBG_ADDR, MII_ANA_CFG0);
 344         atge_mii_write(atgep, phyaddr,
 345             ATPHY_DBG_DATA, data);
 346         drv_usecwait(1000);
 347 }
 348 
 349 uint16_t
 350 atge_l1c_mii_read(void *arg, uint8_t phy, uint8_t reg)
 351 {
 352 
 353         if (phy != 0) {
 354                 /* avoid PHY address alias */
 355                 return (0xffffU);
 356         }
 357 
 358         return (atge_mii_read(arg, phy, reg));
 359 }
 360 
 361 void
 362 atge_l1c_mii_write(void *arg, uint8_t phy, uint8_t reg, uint16_t val)
 363 {
 364 
 365         if (phy != 0) {
 366                 /* avoid PHY address alias */
 367                 return;
 368         }
 369 
 370         if (reg == MII_CONTROL) {
 371                 /*
 372                  * Don't issue a reset if MII_CONTROL_RESET is set.
 373                  * Otherwise it occasionally
 374                  * advertises incorrect capability.
 375                  */
 376                 if ((val & MII_CONTROL_RESET) == 0) {
 377                         /* RESET bit is required to set mode */
 378                         atge_mii_write(arg, phy, reg, val | MII_CONTROL_RESET);
 379                 }
 380         } else {
 381                 atge_mii_write(arg, phy, reg, val);
 382         }
 383 }