Print this page
212 Atheros AR8132 / L1c Gigabit Ethernet Adapter

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/atge/atge_mii.c
          +++ new/usr/src/uts/common/io/atge/atge_mii.c
   1    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 +/*
   2   28   * Copyright (c) 2008, Pyun YongHyeon <yongari@FreeBSD.org>
   3   29   * All rights reserved.
   4   30   *
   5   31   * Redistribution and use in source and binary forms, with or without
   6   32   * modification, are permitted provided that the following conditions
   7   33   * are met:
   8   34   * 1. Redistributions of source code must retain the above copyright
   9   35   *    notice unmodified, this list of conditions, and the following
  10   36   *    disclaimer.
  11   37   * 2. Redistributions in binary form must reproduce the above copyright
↓ open down ↓ 11 lines elided ↑ open up ↑
  23   49   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  24   50   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  25   51   * SUCH DAMAGE.
  26   52   */
  27   53  
  28   54  #include <sys/mii.h>
  29   55  #include <sys/miiregs.h>
  30   56  
  31   57  #include "atge.h"
  32   58  #include "atge_cmn_reg.h"
       59 +#include "atge_l1c_reg.h"
  33   60  #include "atge_l1e_reg.h"
  34   61  #include "atge_l1_reg.h"
  35   62  
  36   63  uint16_t
  37   64  atge_mii_read(void *arg, uint8_t phy, uint8_t reg)
  38   65  {
  39   66          atge_t  *atgep = arg;
  40   67          uint32_t v;
  41   68          int i;
  42   69  
↓ open down ↓ 40 lines elided ↑ open up ↑
  83  110          uint32_t v;
  84  111          int i;
  85  112  
  86  113          mutex_enter(&atgep->atge_mii_lock);
  87  114  
  88  115          OUTL(atgep, ATGE_MDIO, MDIO_OP_EXECUTE | MDIO_OP_WRITE |
  89  116              (val & MDIO_DATA_MASK) << MDIO_DATA_SHIFT |
  90  117              MDIO_SUP_PREAMBLE | MDIO_CLK_25_4 | MDIO_REG_ADDR(reg));
  91  118  
  92  119          for (i = PHY_TIMEOUT; i > 0; i--) {
  93      -                drv_usecwait(1);
      120 +                drv_usecwait(5);
  94  121                  v = INL(atgep, ATGE_MDIO);
  95  122                  if ((v & (MDIO_OP_EXECUTE | MDIO_OP_BUSY)) == 0)
  96  123                          break;
  97  124          }
  98  125  
  99  126          mutex_exit(&atgep->atge_mii_lock);
 100  127  
 101  128          if (i == 0) {
 102  129                  atge_error(atgep->atge_dip, "PHY (%d) write timeout:reg %d,"
 103  130                      "  val :%d", phy, reg, val);
↓ open down ↓ 99 lines elided ↑ open up ↑
 203  230                  atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 1);
 204  231                  reg = atge_mii_read(atgep, phyaddr, ATPHY_DBG_DATA);
 205  232                  atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, reg | 0x03);
 206  233  
 207  234                  drv_usecwait(1500 * 1000);
 208  235  
 209  236                  atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0);
 210  237                  atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x024E);
 211  238          }
 212  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 +}
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX