root/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pch_gbe_phy_get_id
  2. pch_gbe_phy_read_reg_miic
  3. pch_gbe_phy_write_reg_miic
  4. pch_gbe_phy_sw_reset
  5. pch_gbe_phy_hw_reset
  6. pch_gbe_phy_power_up
  7. pch_gbe_phy_power_down
  8. pch_gbe_phy_set_rgmii
  9. pch_gbe_phy_tx_clk_delay
  10. pch_gbe_phy_init_setting
  11. pch_gbe_phy_disable_hibernate

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) 1999 - 2010 Intel Corporation.
   4  * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
   5  *
   6  * This code was derived from the Intel e1000e Linux driver.
   7  */
   8 
   9 #include "pch_gbe.h"
  10 #include "pch_gbe_phy.h"
  11 
  12 #define PHY_MAX_REG_ADDRESS   0x1F      /* 5 bit address bus (0-0x1F) */
  13 
  14 /* PHY 1000 MII Register/Bit Definitions */
  15 /* PHY Registers defined by IEEE */
  16 #define PHY_CONTROL           0x00  /* Control Register */
  17 #define PHY_STATUS            0x01  /* Status Regiser */
  18 #define PHY_ID1               0x02  /* Phy Id Register (word 1) */
  19 #define PHY_ID2               0x03  /* Phy Id Register (word 2) */
  20 #define PHY_AUTONEG_ADV       0x04  /* Autoneg Advertisement */
  21 #define PHY_LP_ABILITY        0x05  /* Link Partner Ability (Base Page) */
  22 #define PHY_AUTONEG_EXP       0x06  /* Autoneg Expansion Register */
  23 #define PHY_NEXT_PAGE_TX      0x07  /* Next Page TX */
  24 #define PHY_LP_NEXT_PAGE      0x08  /* Link Partner Next Page */
  25 #define PHY_1000T_CTRL        0x09  /* 1000Base-T Control Register */
  26 #define PHY_1000T_STATUS      0x0A  /* 1000Base-T Status Register */
  27 #define PHY_EXT_STATUS        0x0F  /* Extended Status Register */
  28 #define PHY_PHYSP_CONTROL     0x10  /* PHY Specific Control Register */
  29 #define PHY_EXT_PHYSP_CONTROL 0x14  /* Extended PHY Specific Control Register */
  30 #define PHY_LED_CONTROL       0x18  /* LED Control Register */
  31 #define PHY_EXT_PHYSP_STATUS  0x1B  /* Extended PHY Specific Status Register */
  32 
  33 /* PHY Control Register */
  34 #define MII_CR_SPEED_SELECT_MSB 0x0040  /* bits 6,13: 10=1000, 01=100, 00=10 */
  35 #define MII_CR_COLL_TEST_ENABLE 0x0080  /* Collision test enable */
  36 #define MII_CR_FULL_DUPLEX      0x0100  /* FDX =1, half duplex =0 */
  37 #define MII_CR_RESTART_AUTO_NEG 0x0200  /* Restart auto negotiation */
  38 #define MII_CR_ISOLATE          0x0400  /* Isolate PHY from MII */
  39 #define MII_CR_POWER_DOWN       0x0800  /* Power down */
  40 #define MII_CR_AUTO_NEG_EN      0x1000  /* Auto Neg Enable */
  41 #define MII_CR_SPEED_SELECT_LSB 0x2000  /* bits 6,13: 10=1000, 01=100, 00=10 */
  42 #define MII_CR_LOOPBACK         0x4000  /* 0 = normal, 1 = loopback */
  43 #define MII_CR_RESET            0x8000  /* 0 = normal, 1 = PHY reset */
  44 #define MII_CR_SPEED_1000       0x0040
  45 #define MII_CR_SPEED_100        0x2000
  46 #define MII_CR_SPEED_10         0x0000
  47 
  48 /* PHY Status Register */
  49 #define MII_SR_EXTENDED_CAPS     0x0001 /* Extended register capabilities */
  50 #define MII_SR_JABBER_DETECT     0x0002 /* Jabber Detected */
  51 #define MII_SR_LINK_STATUS       0x0004 /* Link Status 1 = link */
  52 #define MII_SR_AUTONEG_CAPS      0x0008 /* Auto Neg Capable */
  53 #define MII_SR_REMOTE_FAULT      0x0010 /* Remote Fault Detect */
  54 #define MII_SR_AUTONEG_COMPLETE  0x0020 /* Auto Neg Complete */
  55 #define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */
  56 #define MII_SR_EXTENDED_STATUS   0x0100 /* Ext. status info in Reg 0x0F */
  57 #define MII_SR_100T2_HD_CAPS     0x0200 /* 100T2 Half Duplex Capable */
  58 #define MII_SR_100T2_FD_CAPS     0x0400 /* 100T2 Full Duplex Capable */
  59 #define MII_SR_10T_HD_CAPS       0x0800 /* 10T   Half Duplex Capable */
  60 #define MII_SR_10T_FD_CAPS       0x1000 /* 10T   Full Duplex Capable */
  61 #define MII_SR_100X_HD_CAPS      0x2000 /* 100X  Half Duplex Capable */
  62 #define MII_SR_100X_FD_CAPS      0x4000 /* 100X  Full Duplex Capable */
  63 #define MII_SR_100T4_CAPS        0x8000 /* 100T4 Capable */
  64 
  65 /* AR8031 PHY Debug Registers */
  66 #define PHY_AR803X_ID           0x00001374
  67 #define PHY_AR8031_DBG_OFF      0x1D
  68 #define PHY_AR8031_DBG_DAT      0x1E
  69 #define PHY_AR8031_SERDES       0x05
  70 #define PHY_AR8031_HIBERNATE    0x0B
  71 #define PHY_AR8031_SERDES_TX_CLK_DLY   0x0100 /* TX clock delay of 2.0ns */
  72 #define PHY_AR8031_PS_HIB_EN           0x8000 /* Hibernate enable */
  73 
  74 /* Phy Id Register (word 2) */
  75 #define PHY_REVISION_MASK        0x000F
  76 
  77 /* PHY Specific Control Register */
  78 #define PHYSP_CTRL_ASSERT_CRS_TX  0x0800
  79 
  80 
  81 /* Default value of PHY register */
  82 #define PHY_CONTROL_DEFAULT         0x1140 /* Control Register */
  83 #define PHY_AUTONEG_ADV_DEFAULT     0x01e0 /* Autoneg Advertisement */
  84 #define PHY_NEXT_PAGE_TX_DEFAULT    0x2001 /* Next Page TX */
  85 #define PHY_1000T_CTRL_DEFAULT      0x0300 /* 1000Base-T Control Register */
  86 #define PHY_PHYSP_CONTROL_DEFAULT   0x01EE /* PHY Specific Control Register */
  87 
  88 /**
  89  * pch_gbe_phy_get_id - Retrieve the PHY ID and revision
  90  * @hw:        Pointer to the HW structure
  91  * Returns
  92  *      0:                      Successful.
  93  *      Negative value:         Failed.
  94  */
  95 s32 pch_gbe_phy_get_id(struct pch_gbe_hw *hw)
  96 {
  97         struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
  98         struct pch_gbe_phy_info *phy = &hw->phy;
  99         s32 ret;
 100         u16 phy_id1;
 101         u16 phy_id2;
 102 
 103         ret = pch_gbe_phy_read_reg_miic(hw, PHY_ID1, &phy_id1);
 104         if (ret)
 105                 return ret;
 106         ret = pch_gbe_phy_read_reg_miic(hw, PHY_ID2, &phy_id2);
 107         if (ret)
 108                 return ret;
 109         /*
 110          * PHY_ID1: [bit15-0:ID(21-6)]
 111          * PHY_ID2: [bit15-10:ID(5-0)][bit9-4:Model][bit3-0:revision]
 112          */
 113         phy->id = (u32)phy_id1;
 114         phy->id = ((phy->id << 6) | ((phy_id2 & 0xFC00) >> 10));
 115         phy->revision = (u32) (phy_id2 & 0x000F);
 116         netdev_dbg(adapter->netdev,
 117                    "phy->id : 0x%08x  phy->revision : 0x%08x\n",
 118                    phy->id, phy->revision);
 119         return 0;
 120 }
 121 
 122 /**
 123  * pch_gbe_phy_read_reg_miic - Read MII control register
 124  * @hw:      Pointer to the HW structure
 125  * @offset:  Register offset to be read
 126  * @data:    Pointer to the read data
 127  * Returns
 128  *      0:              Successful.
 129  *      -EINVAL:        Invalid argument.
 130  */
 131 s32 pch_gbe_phy_read_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 *data)
 132 {
 133         struct pch_gbe_phy_info *phy = &hw->phy;
 134 
 135         if (offset > PHY_MAX_REG_ADDRESS) {
 136                 struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
 137 
 138                 netdev_err(adapter->netdev, "PHY Address %d is out of range\n",
 139                            offset);
 140                 return -EINVAL;
 141         }
 142         *data = pch_gbe_mac_ctrl_miim(hw, phy->addr, PCH_GBE_HAL_MIIM_READ,
 143                                       offset, (u16)0);
 144         return 0;
 145 }
 146 
 147 /**
 148  * pch_gbe_phy_write_reg_miic - Write MII control register
 149  * @hw:      Pointer to the HW structure
 150  * @offset:  Register offset to be read
 151  * @data:    data to write to register at offset
 152  * Returns
 153  *      0:              Successful.
 154  *      -EINVAL:        Invalid argument.
 155  */
 156 s32 pch_gbe_phy_write_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 data)
 157 {
 158         struct pch_gbe_phy_info *phy = &hw->phy;
 159 
 160         if (offset > PHY_MAX_REG_ADDRESS) {
 161                 struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
 162 
 163                 netdev_err(adapter->netdev, "PHY Address %d is out of range\n",
 164                            offset);
 165                 return -EINVAL;
 166         }
 167         pch_gbe_mac_ctrl_miim(hw, phy->addr, PCH_GBE_HAL_MIIM_WRITE,
 168                                  offset, data);
 169         return 0;
 170 }
 171 
 172 /**
 173  * pch_gbe_phy_sw_reset - PHY software reset
 174  * @hw:             Pointer to the HW structure
 175  */
 176 static void pch_gbe_phy_sw_reset(struct pch_gbe_hw *hw)
 177 {
 178         u16 phy_ctrl;
 179 
 180         pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &phy_ctrl);
 181         phy_ctrl |= MII_CR_RESET;
 182         pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, phy_ctrl);
 183         udelay(1);
 184 }
 185 
 186 /**
 187  * pch_gbe_phy_hw_reset - PHY hardware reset
 188  * @hw:    Pointer to the HW structure
 189  */
 190 void pch_gbe_phy_hw_reset(struct pch_gbe_hw *hw)
 191 {
 192         pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, PHY_CONTROL_DEFAULT);
 193         pch_gbe_phy_write_reg_miic(hw, PHY_AUTONEG_ADV,
 194                                         PHY_AUTONEG_ADV_DEFAULT);
 195         pch_gbe_phy_write_reg_miic(hw, PHY_NEXT_PAGE_TX,
 196                                         PHY_NEXT_PAGE_TX_DEFAULT);
 197         pch_gbe_phy_write_reg_miic(hw, PHY_1000T_CTRL, PHY_1000T_CTRL_DEFAULT);
 198         pch_gbe_phy_write_reg_miic(hw, PHY_PHYSP_CONTROL,
 199                                         PHY_PHYSP_CONTROL_DEFAULT);
 200 }
 201 
 202 /**
 203  * pch_gbe_phy_power_up - restore link in case the phy was powered down
 204  * @hw:    Pointer to the HW structure
 205  */
 206 void pch_gbe_phy_power_up(struct pch_gbe_hw *hw)
 207 {
 208         u16 mii_reg;
 209 
 210         mii_reg = 0;
 211         /* Just clear the power down bit to wake the phy back up */
 212         /* according to the manual, the phy will retain its
 213          * settings across a power-down/up cycle */
 214         pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &mii_reg);
 215         mii_reg &= ~MII_CR_POWER_DOWN;
 216         pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, mii_reg);
 217 }
 218 
 219 /**
 220  * pch_gbe_phy_power_down - Power down PHY
 221  * @hw:    Pointer to the HW structure
 222  */
 223 void pch_gbe_phy_power_down(struct pch_gbe_hw *hw)
 224 {
 225         u16 mii_reg;
 226 
 227         mii_reg = 0;
 228         /* Power down the PHY so no link is implied when interface is down *
 229          * The PHY cannot be powered down if any of the following is TRUE *
 230          * (a) WoL is enabled
 231          * (b) AMT is active
 232          */
 233         pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &mii_reg);
 234         mii_reg |= MII_CR_POWER_DOWN;
 235         pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, mii_reg);
 236         mdelay(1);
 237 }
 238 
 239 /**
 240  * pch_gbe_phy_set_rgmii - RGMII interface setting
 241  * @hw:             Pointer to the HW structure
 242  */
 243 void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw)
 244 {
 245         pch_gbe_phy_sw_reset(hw);
 246 }
 247 
 248 /**
 249  * pch_gbe_phy_tx_clk_delay - Setup TX clock delay via the PHY
 250  * @hw:             Pointer to the HW structure
 251  * Returns
 252  *      0:              Successful.
 253  *      -EINVAL:        Invalid argument.
 254  */
 255 static int pch_gbe_phy_tx_clk_delay(struct pch_gbe_hw *hw)
 256 {
 257         /* The RGMII interface requires a ~2ns TX clock delay. This is typically
 258          * done in layout with a longer trace or via PHY strapping, but can also
 259          * be done via PHY configuration registers.
 260          */
 261         struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
 262         u16 mii_reg;
 263         int ret = 0;
 264 
 265         switch (hw->phy.id) {
 266         case PHY_AR803X_ID:
 267                 netdev_dbg(adapter->netdev,
 268                            "Configuring AR803X PHY for 2ns TX clock delay\n");
 269                 pch_gbe_phy_read_reg_miic(hw, PHY_AR8031_DBG_OFF, &mii_reg);
 270                 ret = pch_gbe_phy_write_reg_miic(hw, PHY_AR8031_DBG_OFF,
 271                                                  PHY_AR8031_SERDES);
 272                 if (ret)
 273                         break;
 274 
 275                 pch_gbe_phy_read_reg_miic(hw, PHY_AR8031_DBG_DAT, &mii_reg);
 276                 mii_reg |= PHY_AR8031_SERDES_TX_CLK_DLY;
 277                 ret = pch_gbe_phy_write_reg_miic(hw, PHY_AR8031_DBG_DAT,
 278                                                  mii_reg);
 279                 break;
 280         default:
 281                 netdev_err(adapter->netdev,
 282                            "Unknown PHY (%x), could not set TX clock delay\n",
 283                            hw->phy.id);
 284                 return -EINVAL;
 285         }
 286 
 287         if (ret)
 288                 netdev_err(adapter->netdev,
 289                            "Could not configure tx clock delay for PHY\n");
 290         return ret;
 291 }
 292 
 293 /**
 294  * pch_gbe_phy_init_setting - PHY initial setting
 295  * @hw:             Pointer to the HW structure
 296  */
 297 void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw)
 298 {
 299         struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
 300         struct ethtool_cmd     cmd = { .cmd = ETHTOOL_GSET };
 301         int ret;
 302         u16 mii_reg;
 303 
 304         ret = mii_ethtool_gset(&adapter->mii, &cmd);
 305         if (ret)
 306                 netdev_err(adapter->netdev, "Error: mii_ethtool_gset\n");
 307 
 308         ethtool_cmd_speed_set(&cmd, hw->mac.link_speed);
 309         cmd.duplex = hw->mac.link_duplex;
 310         cmd.advertising = hw->phy.autoneg_advertised;
 311         cmd.autoneg = hw->mac.autoneg;
 312         pch_gbe_phy_write_reg_miic(hw, MII_BMCR, BMCR_RESET);
 313         ret = mii_ethtool_sset(&adapter->mii, &cmd);
 314         if (ret)
 315                 netdev_err(adapter->netdev, "Error: mii_ethtool_sset\n");
 316 
 317         pch_gbe_phy_sw_reset(hw);
 318 
 319         pch_gbe_phy_read_reg_miic(hw, PHY_PHYSP_CONTROL, &mii_reg);
 320         mii_reg |= PHYSP_CTRL_ASSERT_CRS_TX;
 321         pch_gbe_phy_write_reg_miic(hw, PHY_PHYSP_CONTROL, mii_reg);
 322 
 323         /* Setup a TX clock delay on certain platforms */
 324         if (adapter->pdata && adapter->pdata->phy_tx_clk_delay)
 325                 pch_gbe_phy_tx_clk_delay(hw);
 326 }
 327 
 328 /**
 329  * pch_gbe_phy_disable_hibernate - Disable the PHY low power state
 330  * @hw:             Pointer to the HW structure
 331  * Returns
 332  *      0:              Successful.
 333  *      -EINVAL:        Invalid argument.
 334  */
 335 int pch_gbe_phy_disable_hibernate(struct pch_gbe_hw *hw)
 336 {
 337         struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
 338         u16 mii_reg;
 339         int ret = 0;
 340 
 341         switch (hw->phy.id) {
 342         case PHY_AR803X_ID:
 343                 netdev_dbg(adapter->netdev,
 344                            "Disabling hibernation for AR803X PHY\n");
 345                 ret = pch_gbe_phy_write_reg_miic(hw, PHY_AR8031_DBG_OFF,
 346                                                  PHY_AR8031_HIBERNATE);
 347                 if (ret)
 348                         break;
 349 
 350                 pch_gbe_phy_read_reg_miic(hw, PHY_AR8031_DBG_DAT, &mii_reg);
 351                 mii_reg &= ~PHY_AR8031_PS_HIB_EN;
 352                 ret = pch_gbe_phy_write_reg_miic(hw, PHY_AR8031_DBG_DAT,
 353                                                  mii_reg);
 354                 break;
 355         default:
 356                 netdev_err(adapter->netdev,
 357                            "Unknown PHY (%x), could not disable hibernation\n",
 358                            hw->phy.id);
 359                 return -EINVAL;
 360         }
 361 
 362         if (ret)
 363                 netdev_err(adapter->netdev,
 364                            "Could not disable PHY hibernation\n");
 365         return ret;
 366 }

/* [<][>][^][v][top][bottom][index][help] */