dpdk/drivers/net/ngbe/base/ngbe_phy_yt.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
   3 */
   4
   5#include "ngbe_phy_yt.h"
   6
   7#define YT_PHY_RST_WAIT_PERIOD          5
   8
   9s32 ngbe_read_phy_reg_yt(struct ngbe_hw *hw,
  10                u32 reg_addr, u32 device_type, u16 *phy_data)
  11{
  12        mdi_reg_t reg;
  13        mdi_reg_22_t reg22;
  14
  15        reg.device_type = device_type;
  16        reg.addr = reg_addr;
  17
  18        ngbe_mdi_map_register(&reg, &reg22);
  19
  20        /* Read MII reg according to media type */
  21        if (hw->phy.media_type == ngbe_media_type_fiber) {
  22                ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
  23                                        reg22.device_type, YT_SMI_PHY_SDS);
  24                ngbe_read_phy_reg_mdi(hw, reg22.addr,
  25                                        reg22.device_type, phy_data);
  26                ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
  27                                        reg22.device_type, 0);
  28        } else {
  29                ngbe_read_phy_reg_mdi(hw, reg22.addr,
  30                                        reg22.device_type, phy_data);
  31        }
  32
  33        return 0;
  34}
  35
  36s32 ngbe_write_phy_reg_yt(struct ngbe_hw *hw,
  37                u32 reg_addr, u32 device_type, u16 phy_data)
  38{
  39        mdi_reg_t reg;
  40        mdi_reg_22_t reg22;
  41
  42        reg.device_type = device_type;
  43        reg.addr = reg_addr;
  44
  45        ngbe_mdi_map_register(&reg, &reg22);
  46
  47        /* Write MII reg according to media type */
  48        if (hw->phy.media_type == ngbe_media_type_fiber) {
  49                ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
  50                                        reg22.device_type, YT_SMI_PHY_SDS);
  51                ngbe_write_phy_reg_mdi(hw, reg22.addr,
  52                                        reg22.device_type, phy_data);
  53                ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
  54                                        reg22.device_type, 0);
  55        } else {
  56                ngbe_write_phy_reg_mdi(hw, reg22.addr,
  57                                        reg22.device_type, phy_data);
  58        }
  59
  60        return 0;
  61}
  62
  63s32 ngbe_read_phy_reg_ext_yt(struct ngbe_hw *hw,
  64                u32 reg_addr, u32 device_type, u16 *phy_data)
  65{
  66        ngbe_write_phy_reg_mdi(hw, 0x1E, device_type, reg_addr);
  67        ngbe_read_phy_reg_mdi(hw, 0x1F, device_type, phy_data);
  68
  69        return 0;
  70}
  71
  72s32 ngbe_write_phy_reg_ext_yt(struct ngbe_hw *hw,
  73                u32 reg_addr, u32 device_type, u16 phy_data)
  74{
  75        ngbe_write_phy_reg_mdi(hw, 0x1E, device_type, reg_addr);
  76        ngbe_write_phy_reg_mdi(hw, 0x1F, device_type, phy_data);
  77
  78        return 0;
  79}
  80
  81s32 ngbe_read_phy_reg_sds_ext_yt(struct ngbe_hw *hw,
  82                u32 reg_addr, u32 device_type, u16 *phy_data)
  83{
  84        ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, YT_SMI_PHY_SDS);
  85        ngbe_read_phy_reg_ext_yt(hw, reg_addr, device_type, phy_data);
  86        ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, 0);
  87
  88        return 0;
  89}
  90
  91s32 ngbe_write_phy_reg_sds_ext_yt(struct ngbe_hw *hw,
  92                u32 reg_addr, u32 device_type, u16 phy_data)
  93{
  94        ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, YT_SMI_PHY_SDS);
  95        ngbe_write_phy_reg_ext_yt(hw, reg_addr, device_type, phy_data);
  96        ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, 0);
  97
  98        return 0;
  99}
 100
 101s32 ngbe_init_phy_yt(struct ngbe_hw *hw)
 102{
 103        u16 value = 0;
 104
 105        DEBUGFUNC("ngbe_init_phy_yt");
 106
 107        if (hw->phy.type != ngbe_phy_yt8521s_sfi)
 108                return 0;
 109
 110        /* select sds area register */
 111        ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0);
 112        /* enable interrupts */
 113        ngbe_write_phy_reg_mdi(hw, YT_INTR, 0, YT_INTR_ENA_MASK);
 114
 115        /* select fiber_to_rgmii first in multiplex */
 116        ngbe_read_phy_reg_ext_yt(hw, YT_MISC, 0, &value);
 117        value |= YT_MISC_FIBER_PRIO;
 118        ngbe_write_phy_reg_ext_yt(hw, YT_MISC, 0, value);
 119
 120        hw->phy.read_reg(hw, YT_BCR, 0, &value);
 121        value |= YT_BCR_PWDN;
 122        hw->phy.write_reg(hw, YT_BCR, 0, value);
 123
 124        return 0;
 125}
 126
 127s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed,
 128                                bool autoneg_wait_to_complete)
 129{
 130        u16 value_r4 = 0;
 131        u16 value_r9 = 0;
 132        u16 value;
 133
 134        DEBUGFUNC("ngbe_setup_phy_link_yt");
 135        UNREFERENCED_PARAMETER(autoneg_wait_to_complete);
 136
 137        hw->phy.autoneg_advertised = 0;
 138
 139        if (hw->phy.type == ngbe_phy_yt8521s) {
 140                /*disable 100/10base-T Self-negotiation ability*/
 141                hw->phy.read_reg(hw, YT_ANA, 0, &value);
 142                value &= ~(YT_ANA_100BASET_FULL | YT_ANA_10BASET_FULL);
 143                hw->phy.write_reg(hw, YT_ANA, 0, value);
 144
 145                /*disable 1000base-T Self-negotiation ability*/
 146                hw->phy.read_reg(hw, YT_MS_CTRL, 0, &value);
 147                value &= ~YT_MS_1000BASET_FULL;
 148                hw->phy.write_reg(hw, YT_MS_CTRL, 0, value);
 149
 150                if (speed & NGBE_LINK_SPEED_1GB_FULL) {
 151                        hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
 152                        value_r9 |= YT_MS_1000BASET_FULL;
 153                }
 154                if (speed & NGBE_LINK_SPEED_100M_FULL) {
 155                        hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_100M_FULL;
 156                        value_r4 |= YT_ANA_100BASET_FULL;
 157                }
 158                if (speed & NGBE_LINK_SPEED_10M_FULL) {
 159                        hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_10M_FULL;
 160                        value_r4 |= YT_ANA_10BASET_FULL;
 161                }
 162
 163                /* enable 1000base-T Self-negotiation ability */
 164                hw->phy.read_reg(hw, YT_MS_CTRL, 0, &value);
 165                value |= value_r9;
 166                hw->phy.write_reg(hw, YT_MS_CTRL, 0, value);
 167
 168                /* enable 100/10base-T Self-negotiation ability */
 169                hw->phy.read_reg(hw, YT_ANA, 0, &value);
 170                value |= value_r4;
 171                hw->phy.write_reg(hw, YT_ANA, 0, value);
 172
 173                /* software reset to make the above configuration take effect*/
 174                hw->phy.read_reg(hw, YT_BCR, 0, &value);
 175                value |= YT_BCR_RESET;
 176                hw->phy.write_reg(hw, YT_BCR, 0, value);
 177        } else {
 178                hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
 179
 180                /* RGMII_Config1 : Config rx and tx training delay */
 181                value = YT_RGMII_CONF1_RXDELAY |
 182                        YT_RGMII_CONF1_TXDELAY_FE |
 183                        YT_RGMII_CONF1_TXDELAY;
 184                ngbe_write_phy_reg_ext_yt(hw, YT_RGMII_CONF1, 0, value);
 185                value = YT_CHIP_MODE_SEL(1) |
 186                        YT_CHIP_SW_LDO_EN |
 187                        YT_CHIP_SW_RST;
 188                ngbe_write_phy_reg_ext_yt(hw, YT_CHIP, 0, value);
 189
 190                /* software reset */
 191                ngbe_write_phy_reg_sds_ext_yt(hw, 0x0, 0, 0x9140);
 192
 193                /* power on phy */
 194                hw->phy.read_reg(hw, YT_BCR, 0, &value);
 195                value &= ~YT_BCR_PWDN;
 196                hw->phy.write_reg(hw, YT_BCR, 0, value);
 197        }
 198
 199        ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0);
 200        ngbe_read_phy_reg_mdi(hw, YT_INTR_STATUS, 0, &value);
 201
 202        return 0;
 203}
 204
 205s32 ngbe_reset_phy_yt(struct ngbe_hw *hw)
 206{
 207        u32 i;
 208        u16 ctrl = 0;
 209        s32 status = 0;
 210
 211        DEBUGFUNC("ngbe_reset_phy_yt");
 212
 213        if (hw->phy.type != ngbe_phy_yt8521s &&
 214                hw->phy.type != ngbe_phy_yt8521s_sfi)
 215                return NGBE_ERR_PHY_TYPE;
 216
 217        status = hw->phy.read_reg(hw, YT_BCR, 0, &ctrl);
 218        /* sds software reset */
 219        ctrl |= YT_BCR_RESET;
 220        status = hw->phy.write_reg(hw, YT_BCR, 0, ctrl);
 221
 222        for (i = 0; i < YT_PHY_RST_WAIT_PERIOD; i++) {
 223                status = hw->phy.read_reg(hw, YT_BCR, 0, &ctrl);
 224                if (!(ctrl & YT_BCR_RESET))
 225                        break;
 226                msleep(1);
 227        }
 228
 229        if (i == YT_PHY_RST_WAIT_PERIOD) {
 230                DEBUGOUT("PHY reset polling failed to complete.\n");
 231                return NGBE_ERR_RESET_FAILED;
 232        }
 233
 234        return status;
 235}
 236
 237s32 ngbe_get_phy_advertised_pause_yt(struct ngbe_hw *hw, u8 *pause_bit)
 238{
 239        u16 value;
 240        s32 status = 0;
 241
 242        DEBUGFUNC("ngbe_get_phy_advertised_pause_yt");
 243
 244        status = hw->phy.read_reg(hw, YT_ANA, 0, &value);
 245        value &= YT_FANA_PAUSE_MASK;
 246        *pause_bit = (u8)(value >> 7);
 247
 248        return status;
 249}
 250
 251s32 ngbe_get_phy_lp_advertised_pause_yt(struct ngbe_hw *hw, u8 *pause_bit)
 252{
 253        u16 value;
 254        s32 status = 0;
 255
 256        DEBUGFUNC("ngbe_get_phy_lp_advertised_pause_yt");
 257
 258        status = hw->phy.read_reg(hw, YT_LPAR, 0, &value);
 259        value &= YT_FLPAR_PAUSE_MASK;
 260        *pause_bit = (u8)(value >> 7);
 261
 262        return status;
 263}
 264
 265s32 ngbe_set_phy_pause_adv_yt(struct ngbe_hw *hw, u16 pause_bit)
 266{
 267        u16 value;
 268        s32 status = 0;
 269
 270        DEBUGFUNC("ngbe_set_phy_pause_adv_yt");
 271
 272
 273        status = hw->phy.read_reg(hw, YT_ANA, 0, &value);
 274        value &= ~YT_FANA_PAUSE_MASK;
 275        value |= pause_bit;
 276        status = hw->phy.write_reg(hw, YT_ANA, 0, value);
 277
 278        return status;
 279}
 280
 281s32 ngbe_check_phy_link_yt(struct ngbe_hw *hw,
 282                u32 *speed, bool *link_up)
 283{
 284        s32 status = 0;
 285        u16 phy_link = 0;
 286        u16 phy_speed = 0;
 287        u16 phy_data = 0;
 288        u16 insr = 0;
 289
 290        DEBUGFUNC("ngbe_check_phy_link_yt");
 291
 292        /* Initialize speed and link to default case */
 293        *link_up = false;
 294        *speed = NGBE_LINK_SPEED_UNKNOWN;
 295
 296        ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0);
 297        ngbe_read_phy_reg_mdi(hw, YT_INTR_STATUS, 0, &insr);
 298
 299        status = hw->phy.read_reg(hw, YT_SPST, 0, &phy_data);
 300        phy_link = phy_data & YT_SPST_LINK;
 301        phy_speed = phy_data & YT_SPST_SPEED_MASK;
 302
 303        if (phy_link) {
 304                *link_up = true;
 305
 306                if (phy_speed == YT_SPST_SPEED_1000M)
 307                        *speed = NGBE_LINK_SPEED_1GB_FULL;
 308                else if (phy_speed == YT_SPST_SPEED_100M)
 309                        *speed = NGBE_LINK_SPEED_100M_FULL;
 310                else if (phy_speed == YT_SPST_SPEED_10M)
 311                        *speed = NGBE_LINK_SPEED_10M_FULL;
 312        }
 313
 314        return status;
 315}
 316
 317