linux/drivers/net/phy/mscc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: (GPL-2.0 OR MIT)
   2/*
   3 * Driver for Microsemi VSC85xx PHYs
   4 *
   5 * Author: Nagaraju Lakkaraju
   6 * License: Dual MIT/GPL
   7 * Copyright (c) 2016 Microsemi Corporation
   8 */
   9
  10#include <linux/firmware.h>
  11#include <linux/jiffies.h>
  12#include <linux/kernel.h>
  13#include <linux/module.h>
  14#include <linux/mdio.h>
  15#include <linux/mii.h>
  16#include <linux/phy.h>
  17#include <linux/of.h>
  18#include <linux/netdevice.h>
  19#include <dt-bindings/net/mscc-phy-vsc8531.h>
  20
  21enum rgmii_rx_clock_delay {
  22        RGMII_RX_CLK_DELAY_0_2_NS = 0,
  23        RGMII_RX_CLK_DELAY_0_8_NS = 1,
  24        RGMII_RX_CLK_DELAY_1_1_NS = 2,
  25        RGMII_RX_CLK_DELAY_1_7_NS = 3,
  26        RGMII_RX_CLK_DELAY_2_0_NS = 4,
  27        RGMII_RX_CLK_DELAY_2_3_NS = 5,
  28        RGMII_RX_CLK_DELAY_2_6_NS = 6,
  29        RGMII_RX_CLK_DELAY_3_4_NS = 7
  30};
  31
  32/* Microsemi VSC85xx PHY registers */
  33/* IEEE 802. Std Registers */
  34#define MSCC_PHY_BYPASS_CONTROL           18
  35#define DISABLE_HP_AUTO_MDIX_MASK         0x0080
  36#define DISABLE_PAIR_SWAP_CORR_MASK       0x0020
  37#define DISABLE_POLARITY_CORR_MASK        0x0010
  38#define PARALLEL_DET_IGNORE_ADVERTISED    0x0008
  39
  40#define MSCC_PHY_EXT_CNTL_STATUS          22
  41#define SMI_BROADCAST_WR_EN               0x0001
  42
  43#define MSCC_PHY_ERR_RX_CNT               19
  44#define MSCC_PHY_ERR_FALSE_CARRIER_CNT    20
  45#define MSCC_PHY_ERR_LINK_DISCONNECT_CNT  21
  46#define ERR_CNT_MASK                      GENMASK(7, 0)
  47
  48#define MSCC_PHY_EXT_PHY_CNTL_1           23
  49#define MAC_IF_SELECTION_MASK             0x1800
  50#define MAC_IF_SELECTION_GMII             0
  51#define MAC_IF_SELECTION_RMII             1
  52#define MAC_IF_SELECTION_RGMII            2
  53#define MAC_IF_SELECTION_POS              11
  54#define VSC8584_MAC_IF_SELECTION_MASK     0x1000
  55#define VSC8584_MAC_IF_SELECTION_SGMII    0
  56#define VSC8584_MAC_IF_SELECTION_1000BASEX 1
  57#define VSC8584_MAC_IF_SELECTION_POS      12
  58#define FAR_END_LOOPBACK_MODE_MASK        0x0008
  59#define MEDIA_OP_MODE_MASK                0x0700
  60#define MEDIA_OP_MODE_COPPER              0
  61#define MEDIA_OP_MODE_SERDES              1
  62#define MEDIA_OP_MODE_1000BASEX           2
  63#define MEDIA_OP_MODE_100BASEFX           3
  64#define MEDIA_OP_MODE_AMS_COPPER_SERDES   5
  65#define MEDIA_OP_MODE_AMS_COPPER_1000BASEX      6
  66#define MEDIA_OP_MODE_AMS_COPPER_100BASEFX      7
  67#define MEDIA_OP_MODE_POS                 8
  68
  69#define MSCC_PHY_EXT_PHY_CNTL_2           24
  70
  71#define MII_VSC85XX_INT_MASK              25
  72#define MII_VSC85XX_INT_MASK_MASK         0xa000
  73#define MII_VSC85XX_INT_MASK_WOL          0x0040
  74#define MII_VSC85XX_INT_STATUS            26
  75
  76#define MSCC_PHY_WOL_MAC_CONTROL          27
  77#define EDGE_RATE_CNTL_POS                5
  78#define EDGE_RATE_CNTL_MASK               0x00E0
  79
  80#define MSCC_PHY_DEV_AUX_CNTL             28
  81#define HP_AUTO_MDIX_X_OVER_IND_MASK      0x2000
  82
  83#define MSCC_PHY_LED_MODE_SEL             29
  84#define LED_MODE_SEL_POS(x)               ((x) * 4)
  85#define LED_MODE_SEL_MASK(x)              (GENMASK(3, 0) << LED_MODE_SEL_POS(x))
  86#define LED_MODE_SEL(x, mode)             (((mode) << LED_MODE_SEL_POS(x)) & LED_MODE_SEL_MASK(x))
  87
  88#define MSCC_EXT_PAGE_CSR_CNTL_17         17
  89#define MSCC_EXT_PAGE_CSR_CNTL_18         18
  90
  91#define MSCC_EXT_PAGE_CSR_CNTL_19         19
  92#define MSCC_PHY_CSR_CNTL_19_REG_ADDR(x)  (x)
  93#define MSCC_PHY_CSR_CNTL_19_TARGET(x)    ((x) << 12)
  94#define MSCC_PHY_CSR_CNTL_19_READ         BIT(14)
  95#define MSCC_PHY_CSR_CNTL_19_CMD          BIT(15)
  96
  97#define MSCC_EXT_PAGE_CSR_CNTL_20         20
  98#define MSCC_PHY_CSR_CNTL_20_TARGET(x)    (x)
  99
 100#define PHY_MCB_TARGET                    0x07
 101#define PHY_MCB_S6G_WRITE                 BIT(31)
 102#define PHY_MCB_S6G_READ                  BIT(30)
 103
 104#define PHY_S6G_PLL5G_CFG0                0x06
 105#define PHY_S6G_LCPLL_CFG                 0x11
 106#define PHY_S6G_PLL_CFG                   0x2b
 107#define PHY_S6G_COMMON_CFG                0x2c
 108#define PHY_S6G_GPC_CFG                   0x2e
 109#define PHY_S6G_MISC_CFG                  0x3b
 110#define PHY_MCB_S6G_CFG                   0x3f
 111#define PHY_S6G_DFT_CFG2                  0x3e
 112#define PHY_S6G_PLL_STATUS                0x31
 113#define PHY_S6G_IB_STATUS0                0x2f
 114
 115#define PHY_S6G_SYS_RST_POS               31
 116#define PHY_S6G_ENA_LANE_POS              18
 117#define PHY_S6G_ENA_LOOP_POS              8
 118#define PHY_S6G_QRATE_POS                 6
 119#define PHY_S6G_IF_MODE_POS               4
 120#define PHY_S6G_PLL_ENA_OFFS_POS          21
 121#define PHY_S6G_PLL_FSM_CTRL_DATA_POS     8
 122#define PHY_S6G_PLL_FSM_ENA_POS           7
 123
 124#define MSCC_EXT_PAGE_ACCESS              31
 125#define MSCC_PHY_PAGE_STANDARD            0x0000 /* Standard registers */
 126#define MSCC_PHY_PAGE_EXTENDED            0x0001 /* Extended registers */
 127#define MSCC_PHY_PAGE_EXTENDED_2          0x0002 /* Extended reg - page 2 */
 128#define MSCC_PHY_PAGE_EXTENDED_3          0x0003 /* Extended reg - page 3 */
 129#define MSCC_PHY_PAGE_EXTENDED_4          0x0004 /* Extended reg - page 4 */
 130#define MSCC_PHY_PAGE_CSR_CNTL            MSCC_PHY_PAGE_EXTENDED_4
 131/* Extended reg - GPIO; this is a bank of registers that are shared for all PHYs
 132 * in the same package.
 133 */
 134#define MSCC_PHY_PAGE_EXTENDED_GPIO       0x0010 /* Extended reg - GPIO */
 135#define MSCC_PHY_PAGE_TEST                0x2a30 /* Test reg */
 136#define MSCC_PHY_PAGE_TR                  0x52b5 /* Token ring registers */
 137
 138/* Extended Page 1 Registers */
 139#define MSCC_PHY_CU_MEDIA_CRC_VALID_CNT   18
 140#define VALID_CRC_CNT_CRC_MASK            GENMASK(13, 0)
 141
 142#define MSCC_PHY_EXT_MODE_CNTL            19
 143#define FORCE_MDI_CROSSOVER_MASK          0x000C
 144#define FORCE_MDI_CROSSOVER_MDIX          0x000C
 145#define FORCE_MDI_CROSSOVER_MDI           0x0008
 146
 147#define MSCC_PHY_ACTIPHY_CNTL             20
 148#define PHY_ADDR_REVERSED                 0x0200
 149#define DOWNSHIFT_CNTL_MASK               0x001C
 150#define DOWNSHIFT_EN                      0x0010
 151#define DOWNSHIFT_CNTL_POS                2
 152
 153#define MSCC_PHY_EXT_PHY_CNTL_4           23
 154#define PHY_CNTL_4_ADDR_POS               11
 155
 156#define MSCC_PHY_VERIPHY_CNTL_2           25
 157
 158#define MSCC_PHY_VERIPHY_CNTL_3           26
 159
 160/* Extended Page 2 Registers */
 161#define MSCC_PHY_CU_PMD_TX_CNTL           16
 162
 163#define MSCC_PHY_RGMII_CNTL               20
 164#define RGMII_RX_CLK_DELAY_MASK           0x0070
 165#define RGMII_RX_CLK_DELAY_POS            4
 166
 167#define MSCC_PHY_WOL_LOWER_MAC_ADDR       21
 168#define MSCC_PHY_WOL_MID_MAC_ADDR         22
 169#define MSCC_PHY_WOL_UPPER_MAC_ADDR       23
 170#define MSCC_PHY_WOL_LOWER_PASSWD         24
 171#define MSCC_PHY_WOL_MID_PASSWD           25
 172#define MSCC_PHY_WOL_UPPER_PASSWD         26
 173
 174#define MSCC_PHY_WOL_MAC_CONTROL          27
 175#define SECURE_ON_ENABLE                  0x8000
 176#define SECURE_ON_PASSWD_LEN_4            0x4000
 177
 178/* Extended Page 3 Registers */
 179#define MSCC_PHY_SERDES_TX_VALID_CNT      21
 180#define MSCC_PHY_SERDES_TX_CRC_ERR_CNT    22
 181#define MSCC_PHY_SERDES_RX_VALID_CNT      28
 182#define MSCC_PHY_SERDES_RX_CRC_ERR_CNT    29
 183
 184/* Extended page GPIO Registers */
 185#define MSCC_DW8051_CNTL_STATUS           0
 186#define MICRO_NSOFT_RESET                 0x8000
 187#define RUN_FROM_INT_ROM                  0x4000
 188#define AUTOINC_ADDR                      0x2000
 189#define PATCH_RAM_CLK                     0x1000
 190#define MICRO_PATCH_EN                    0x0080
 191#define DW8051_CLK_EN                     0x0010
 192#define MICRO_CLK_EN                      0x0008
 193#define MICRO_CLK_DIVIDE(x)               ((x) >> 1)
 194#define MSCC_DW8051_VLD_MASK              0xf1ff
 195
 196/* x Address in range 1-4 */
 197#define MSCC_TRAP_ROM_ADDR(x)             ((x) * 2 + 1)
 198#define MSCC_PATCH_RAM_ADDR(x)            (((x) + 1) * 2)
 199#define MSCC_INT_MEM_ADDR                 11
 200
 201#define MSCC_INT_MEM_CNTL                 12
 202#define READ_SFR                          0x6000
 203#define READ_PRAM                         0x4000
 204#define READ_ROM                          0x2000
 205#define READ_RAM                          0x0000
 206#define INT_MEM_WRITE_EN                  0x1000
 207#define EN_PATCH_RAM_TRAP_ADDR(x)         (0x0100 << ((x) - 1))
 208#define INT_MEM_DATA_M                    0x00ff
 209#define INT_MEM_DATA(x)                   (INT_MEM_DATA_M & (x))
 210
 211#define MSCC_PHY_PROC_CMD                 18
 212#define PROC_CMD_NCOMPLETED               0x8000
 213#define PROC_CMD_FAILED                   0x4000
 214#define PROC_CMD_SGMII_PORT(x)            ((x) << 8)
 215#define PROC_CMD_FIBER_PORT(x)            (0x0100 << (x) % 4)
 216#define PROC_CMD_QSGMII_PORT              0x0c00
 217#define PROC_CMD_RST_CONF_PORT            0x0080
 218#define PROC_CMD_RECONF_PORT              0x0000
 219#define PROC_CMD_READ_MOD_WRITE_PORT      0x0040
 220#define PROC_CMD_WRITE                    0x0040
 221#define PROC_CMD_READ                     0x0000
 222#define PROC_CMD_FIBER_DISABLE            0x0020
 223#define PROC_CMD_FIBER_100BASE_FX         0x0010
 224#define PROC_CMD_FIBER_1000BASE_X         0x0000
 225#define PROC_CMD_SGMII_MAC                0x0030
 226#define PROC_CMD_QSGMII_MAC               0x0020
 227#define PROC_CMD_NO_MAC_CONF              0x0000
 228#define PROC_CMD_1588_DEFAULT_INIT        0x0010
 229#define PROC_CMD_NOP                      0x000f
 230#define PROC_CMD_PHY_INIT                 0x000a
 231#define PROC_CMD_CRC16                    0x0008
 232#define PROC_CMD_FIBER_MEDIA_CONF         0x0001
 233#define PROC_CMD_MCB_ACCESS_MAC_CONF      0x0000
 234#define PROC_CMD_NCOMPLETED_TIMEOUT_MS    500
 235
 236#define MSCC_PHY_MAC_CFG_FASTLINK         19
 237#define MAC_CFG_MASK                      0xc000
 238#define MAC_CFG_SGMII                     0x0000
 239#define MAC_CFG_QSGMII                    0x4000
 240
 241/* Test page Registers */
 242#define MSCC_PHY_TEST_PAGE_5              5
 243#define MSCC_PHY_TEST_PAGE_8              8
 244#define MSCC_PHY_TEST_PAGE_9              9
 245#define MSCC_PHY_TEST_PAGE_20             20
 246#define MSCC_PHY_TEST_PAGE_24             24
 247
 248/* Token ring page Registers */
 249#define MSCC_PHY_TR_CNTL                  16
 250#define TR_WRITE                          0x8000
 251#define TR_ADDR(x)                        (0x7fff & (x))
 252#define MSCC_PHY_TR_LSB                   17
 253#define MSCC_PHY_TR_MSB                   18
 254
 255/* Microsemi PHY ID's */
 256#define PHY_ID_VSC8514                    0x00070670
 257#define PHY_ID_VSC8530                    0x00070560
 258#define PHY_ID_VSC8531                    0x00070570
 259#define PHY_ID_VSC8540                    0x00070760
 260#define PHY_ID_VSC8541                    0x00070770
 261#define PHY_ID_VSC8574                    0x000704a0
 262#define PHY_ID_VSC8584                    0x000707c0
 263
 264#define MSCC_VDDMAC_1500                  1500
 265#define MSCC_VDDMAC_1800                  1800
 266#define MSCC_VDDMAC_2500                  2500
 267#define MSCC_VDDMAC_3300                  3300
 268
 269#define DOWNSHIFT_COUNT_MAX               5
 270
 271#define MAX_LEDS                          4
 272
 273#define VSC8584_SUPP_LED_MODES (BIT(VSC8531_LINK_ACTIVITY) | \
 274                                BIT(VSC8531_LINK_1000_ACTIVITY) | \
 275                                BIT(VSC8531_LINK_100_ACTIVITY) | \
 276                                BIT(VSC8531_LINK_10_ACTIVITY) | \
 277                                BIT(VSC8531_LINK_100_1000_ACTIVITY) | \
 278                                BIT(VSC8531_LINK_10_1000_ACTIVITY) | \
 279                                BIT(VSC8531_LINK_10_100_ACTIVITY) | \
 280                                BIT(VSC8584_LINK_100FX_1000X_ACTIVITY) | \
 281                                BIT(VSC8531_DUPLEX_COLLISION) | \
 282                                BIT(VSC8531_COLLISION) | \
 283                                BIT(VSC8531_ACTIVITY) | \
 284                                BIT(VSC8584_100FX_1000X_ACTIVITY) | \
 285                                BIT(VSC8531_AUTONEG_FAULT) | \
 286                                BIT(VSC8531_SERIAL_MODE) | \
 287                                BIT(VSC8531_FORCE_LED_OFF) | \
 288                                BIT(VSC8531_FORCE_LED_ON))
 289
 290#define VSC85XX_SUPP_LED_MODES (BIT(VSC8531_LINK_ACTIVITY) | \
 291                                BIT(VSC8531_LINK_1000_ACTIVITY) | \
 292                                BIT(VSC8531_LINK_100_ACTIVITY) | \
 293                                BIT(VSC8531_LINK_10_ACTIVITY) | \
 294                                BIT(VSC8531_LINK_100_1000_ACTIVITY) | \
 295                                BIT(VSC8531_LINK_10_1000_ACTIVITY) | \
 296                                BIT(VSC8531_LINK_10_100_ACTIVITY) | \
 297                                BIT(VSC8531_DUPLEX_COLLISION) | \
 298                                BIT(VSC8531_COLLISION) | \
 299                                BIT(VSC8531_ACTIVITY) | \
 300                                BIT(VSC8531_AUTONEG_FAULT) | \
 301                                BIT(VSC8531_SERIAL_MODE) | \
 302                                BIT(VSC8531_FORCE_LED_OFF) | \
 303                                BIT(VSC8531_FORCE_LED_ON))
 304
 305#define MSCC_VSC8584_REVB_INT8051_FW            "mscc_vsc8584_revb_int8051_fb48.bin"
 306#define MSCC_VSC8584_REVB_INT8051_FW_START_ADDR 0xe800
 307#define MSCC_VSC8584_REVB_INT8051_FW_CRC        0xfb48
 308
 309#define MSCC_VSC8574_REVB_INT8051_FW            "mscc_vsc8574_revb_int8051_29e8.bin"
 310#define MSCC_VSC8574_REVB_INT8051_FW_START_ADDR 0x4000
 311#define MSCC_VSC8574_REVB_INT8051_FW_CRC        0x29e8
 312
 313#define VSC8584_REVB                            0x0001
 314#define MSCC_DEV_REV_MASK                       GENMASK(3, 0)
 315
 316struct reg_val {
 317        u16     reg;
 318        u32     val;
 319};
 320
 321struct vsc85xx_hw_stat {
 322        const char *string;
 323        u8 reg;
 324        u16 page;
 325        u16 mask;
 326};
 327
 328static const struct vsc85xx_hw_stat vsc85xx_hw_stats[] = {
 329        {
 330                .string = "phy_receive_errors",
 331                .reg    = MSCC_PHY_ERR_RX_CNT,
 332                .page   = MSCC_PHY_PAGE_STANDARD,
 333                .mask   = ERR_CNT_MASK,
 334        }, {
 335                .string = "phy_false_carrier",
 336                .reg    = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
 337                .page   = MSCC_PHY_PAGE_STANDARD,
 338                .mask   = ERR_CNT_MASK,
 339        }, {
 340                .string = "phy_cu_media_link_disconnect",
 341                .reg    = MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
 342                .page   = MSCC_PHY_PAGE_STANDARD,
 343                .mask   = ERR_CNT_MASK,
 344        }, {
 345                .string = "phy_cu_media_crc_good_count",
 346                .reg    = MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
 347                .page   = MSCC_PHY_PAGE_EXTENDED,
 348                .mask   = VALID_CRC_CNT_CRC_MASK,
 349        }, {
 350                .string = "phy_cu_media_crc_error_count",
 351                .reg    = MSCC_PHY_EXT_PHY_CNTL_4,
 352                .page   = MSCC_PHY_PAGE_EXTENDED,
 353                .mask   = ERR_CNT_MASK,
 354        },
 355};
 356
 357static const struct vsc85xx_hw_stat vsc8584_hw_stats[] = {
 358        {
 359                .string = "phy_receive_errors",
 360                .reg    = MSCC_PHY_ERR_RX_CNT,
 361                .page   = MSCC_PHY_PAGE_STANDARD,
 362                .mask   = ERR_CNT_MASK,
 363        }, {
 364                .string = "phy_false_carrier",
 365                .reg    = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
 366                .page   = MSCC_PHY_PAGE_STANDARD,
 367                .mask   = ERR_CNT_MASK,
 368        }, {
 369                .string = "phy_cu_media_link_disconnect",
 370                .reg    = MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
 371                .page   = MSCC_PHY_PAGE_STANDARD,
 372                .mask   = ERR_CNT_MASK,
 373        }, {
 374                .string = "phy_cu_media_crc_good_count",
 375                .reg    = MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
 376                .page   = MSCC_PHY_PAGE_EXTENDED,
 377                .mask   = VALID_CRC_CNT_CRC_MASK,
 378        }, {
 379                .string = "phy_cu_media_crc_error_count",
 380                .reg    = MSCC_PHY_EXT_PHY_CNTL_4,
 381                .page   = MSCC_PHY_PAGE_EXTENDED,
 382                .mask   = ERR_CNT_MASK,
 383        }, {
 384                .string = "phy_serdes_tx_good_pkt_count",
 385                .reg    = MSCC_PHY_SERDES_TX_VALID_CNT,
 386                .page   = MSCC_PHY_PAGE_EXTENDED_3,
 387                .mask   = VALID_CRC_CNT_CRC_MASK,
 388        }, {
 389                .string = "phy_serdes_tx_bad_crc_count",
 390                .reg    = MSCC_PHY_SERDES_TX_CRC_ERR_CNT,
 391                .page   = MSCC_PHY_PAGE_EXTENDED_3,
 392                .mask   = ERR_CNT_MASK,
 393        }, {
 394                .string = "phy_serdes_rx_good_pkt_count",
 395                .reg    = MSCC_PHY_SERDES_RX_VALID_CNT,
 396                .page   = MSCC_PHY_PAGE_EXTENDED_3,
 397                .mask   = VALID_CRC_CNT_CRC_MASK,
 398        }, {
 399                .string = "phy_serdes_rx_bad_crc_count",
 400                .reg    = MSCC_PHY_SERDES_RX_CRC_ERR_CNT,
 401                .page   = MSCC_PHY_PAGE_EXTENDED_3,
 402                .mask   = ERR_CNT_MASK,
 403        },
 404};
 405
 406struct vsc8531_private {
 407        int rate_magic;
 408        u16 supp_led_modes;
 409        u32 leds_mode[MAX_LEDS];
 410        u8 nleds;
 411        const struct vsc85xx_hw_stat *hw_stats;
 412        u64 *stats;
 413        int nstats;
 414        bool pkg_init;
 415        /* For multiple port PHYs; the MDIO address of the base PHY in the
 416         * package.
 417         */
 418        unsigned int base_addr;
 419};
 420
 421#ifdef CONFIG_OF_MDIO
 422struct vsc8531_edge_rate_table {
 423        u32 vddmac;
 424        u32 slowdown[8];
 425};
 426
 427static const struct vsc8531_edge_rate_table edge_table[] = {
 428        {MSCC_VDDMAC_3300, { 0, 2,  4,  7, 10, 17, 29, 53} },
 429        {MSCC_VDDMAC_2500, { 0, 3,  6, 10, 14, 23, 37, 63} },
 430        {MSCC_VDDMAC_1800, { 0, 5,  9, 16, 23, 35, 52, 76} },
 431        {MSCC_VDDMAC_1500, { 0, 6, 14, 21, 29, 42, 58, 77} },
 432};
 433#endif /* CONFIG_OF_MDIO */
 434
 435static int vsc85xx_phy_read_page(struct phy_device *phydev)
 436{
 437        return __phy_read(phydev, MSCC_EXT_PAGE_ACCESS);
 438}
 439
 440static int vsc85xx_phy_write_page(struct phy_device *phydev, int page)
 441{
 442        return __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, page);
 443}
 444
 445static int vsc85xx_get_sset_count(struct phy_device *phydev)
 446{
 447        struct vsc8531_private *priv = phydev->priv;
 448
 449        if (!priv)
 450                return 0;
 451
 452        return priv->nstats;
 453}
 454
 455static void vsc85xx_get_strings(struct phy_device *phydev, u8 *data)
 456{
 457        struct vsc8531_private *priv = phydev->priv;
 458        int i;
 459
 460        if (!priv)
 461                return;
 462
 463        for (i = 0; i < priv->nstats; i++)
 464                strlcpy(data + i * ETH_GSTRING_LEN, priv->hw_stats[i].string,
 465                        ETH_GSTRING_LEN);
 466}
 467
 468static u64 vsc85xx_get_stat(struct phy_device *phydev, int i)
 469{
 470        struct vsc8531_private *priv = phydev->priv;
 471        int val;
 472
 473        val = phy_read_paged(phydev, priv->hw_stats[i].page,
 474                             priv->hw_stats[i].reg);
 475        if (val < 0)
 476                return U64_MAX;
 477
 478        val = val & priv->hw_stats[i].mask;
 479        priv->stats[i] += val;
 480
 481        return priv->stats[i];
 482}
 483
 484static void vsc85xx_get_stats(struct phy_device *phydev,
 485                              struct ethtool_stats *stats, u64 *data)
 486{
 487        struct vsc8531_private *priv = phydev->priv;
 488        int i;
 489
 490        if (!priv)
 491                return;
 492
 493        for (i = 0; i < priv->nstats; i++)
 494                data[i] = vsc85xx_get_stat(phydev, i);
 495}
 496
 497static int vsc85xx_led_cntl_set(struct phy_device *phydev,
 498                                u8 led_num,
 499                                u8 mode)
 500{
 501        int rc;
 502        u16 reg_val;
 503
 504        mutex_lock(&phydev->lock);
 505        reg_val = phy_read(phydev, MSCC_PHY_LED_MODE_SEL);
 506        reg_val &= ~LED_MODE_SEL_MASK(led_num);
 507        reg_val |= LED_MODE_SEL(led_num, (u16)mode);
 508        rc = phy_write(phydev, MSCC_PHY_LED_MODE_SEL, reg_val);
 509        mutex_unlock(&phydev->lock);
 510
 511        return rc;
 512}
 513
 514static int vsc85xx_mdix_get(struct phy_device *phydev, u8 *mdix)
 515{
 516        u16 reg_val;
 517
 518        reg_val = phy_read(phydev, MSCC_PHY_DEV_AUX_CNTL);
 519        if (reg_val & HP_AUTO_MDIX_X_OVER_IND_MASK)
 520                *mdix = ETH_TP_MDI_X;
 521        else
 522                *mdix = ETH_TP_MDI;
 523
 524        return 0;
 525}
 526
 527static int vsc85xx_mdix_set(struct phy_device *phydev, u8 mdix)
 528{
 529        int rc;
 530        u16 reg_val;
 531
 532        reg_val = phy_read(phydev, MSCC_PHY_BYPASS_CONTROL);
 533        if (mdix == ETH_TP_MDI || mdix == ETH_TP_MDI_X) {
 534                reg_val |= (DISABLE_PAIR_SWAP_CORR_MASK |
 535                            DISABLE_POLARITY_CORR_MASK  |
 536                            DISABLE_HP_AUTO_MDIX_MASK);
 537        } else {
 538                reg_val &= ~(DISABLE_PAIR_SWAP_CORR_MASK |
 539                             DISABLE_POLARITY_CORR_MASK  |
 540                             DISABLE_HP_AUTO_MDIX_MASK);
 541        }
 542        rc = phy_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg_val);
 543        if (rc)
 544                return rc;
 545
 546        reg_val = 0;
 547
 548        if (mdix == ETH_TP_MDI)
 549                reg_val = FORCE_MDI_CROSSOVER_MDI;
 550        else if (mdix == ETH_TP_MDI_X)
 551                reg_val = FORCE_MDI_CROSSOVER_MDIX;
 552
 553        rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
 554                              MSCC_PHY_EXT_MODE_CNTL, FORCE_MDI_CROSSOVER_MASK,
 555                              reg_val);
 556        if (rc < 0)
 557                return rc;
 558
 559        return genphy_restart_aneg(phydev);
 560}
 561
 562static int vsc85xx_downshift_get(struct phy_device *phydev, u8 *count)
 563{
 564        int reg_val;
 565
 566        reg_val = phy_read_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
 567                                 MSCC_PHY_ACTIPHY_CNTL);
 568        if (reg_val < 0)
 569                return reg_val;
 570
 571        reg_val &= DOWNSHIFT_CNTL_MASK;
 572        if (!(reg_val & DOWNSHIFT_EN))
 573                *count = DOWNSHIFT_DEV_DISABLE;
 574        else
 575                *count = ((reg_val & ~DOWNSHIFT_EN) >> DOWNSHIFT_CNTL_POS) + 2;
 576
 577        return 0;
 578}
 579
 580static int vsc85xx_downshift_set(struct phy_device *phydev, u8 count)
 581{
 582        if (count == DOWNSHIFT_DEV_DEFAULT_COUNT) {
 583                /* Default downshift count 3 (i.e. Bit3:2 = 0b01) */
 584                count = ((1 << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
 585        } else if (count > DOWNSHIFT_COUNT_MAX || count == 1) {
 586                phydev_err(phydev, "Downshift count should be 2,3,4 or 5\n");
 587                return -ERANGE;
 588        } else if (count) {
 589                /* Downshift count is either 2,3,4 or 5 */
 590                count = (((count - 2) << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
 591        }
 592
 593        return phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
 594                                MSCC_PHY_ACTIPHY_CNTL, DOWNSHIFT_CNTL_MASK,
 595                                count);
 596}
 597
 598static int vsc85xx_wol_set(struct phy_device *phydev,
 599                           struct ethtool_wolinfo *wol)
 600{
 601        int rc;
 602        u16 reg_val;
 603        u8  i;
 604        u16 pwd[3] = {0, 0, 0};
 605        struct ethtool_wolinfo *wol_conf = wol;
 606        u8 *mac_addr = phydev->attached_dev->dev_addr;
 607
 608        mutex_lock(&phydev->lock);
 609        rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
 610        if (rc < 0) {
 611                rc = phy_restore_page(phydev, rc, rc);
 612                goto out_unlock;
 613        }
 614
 615        if (wol->wolopts & WAKE_MAGIC) {
 616                /* Store the device address for the magic packet */
 617                for (i = 0; i < ARRAY_SIZE(pwd); i++)
 618                        pwd[i] = mac_addr[5 - (i * 2 + 1)] << 8 |
 619                                 mac_addr[5 - i * 2];
 620                __phy_write(phydev, MSCC_PHY_WOL_LOWER_MAC_ADDR, pwd[0]);
 621                __phy_write(phydev, MSCC_PHY_WOL_MID_MAC_ADDR, pwd[1]);
 622                __phy_write(phydev, MSCC_PHY_WOL_UPPER_MAC_ADDR, pwd[2]);
 623        } else {
 624                __phy_write(phydev, MSCC_PHY_WOL_LOWER_MAC_ADDR, 0);
 625                __phy_write(phydev, MSCC_PHY_WOL_MID_MAC_ADDR, 0);
 626                __phy_write(phydev, MSCC_PHY_WOL_UPPER_MAC_ADDR, 0);
 627        }
 628
 629        if (wol_conf->wolopts & WAKE_MAGICSECURE) {
 630                for (i = 0; i < ARRAY_SIZE(pwd); i++)
 631                        pwd[i] = wol_conf->sopass[5 - (i * 2 + 1)] << 8 |
 632                                 wol_conf->sopass[5 - i * 2];
 633                __phy_write(phydev, MSCC_PHY_WOL_LOWER_PASSWD, pwd[0]);
 634                __phy_write(phydev, MSCC_PHY_WOL_MID_PASSWD, pwd[1]);
 635                __phy_write(phydev, MSCC_PHY_WOL_UPPER_PASSWD, pwd[2]);
 636        } else {
 637                __phy_write(phydev, MSCC_PHY_WOL_LOWER_PASSWD, 0);
 638                __phy_write(phydev, MSCC_PHY_WOL_MID_PASSWD, 0);
 639                __phy_write(phydev, MSCC_PHY_WOL_UPPER_PASSWD, 0);
 640        }
 641
 642        reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
 643        if (wol_conf->wolopts & WAKE_MAGICSECURE)
 644                reg_val |= SECURE_ON_ENABLE;
 645        else
 646                reg_val &= ~SECURE_ON_ENABLE;
 647        __phy_write(phydev, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
 648
 649        rc = phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
 650        if (rc < 0)
 651                goto out_unlock;
 652
 653        if (wol->wolopts & WAKE_MAGIC) {
 654                /* Enable the WOL interrupt */
 655                reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
 656                reg_val |= MII_VSC85XX_INT_MASK_WOL;
 657                rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
 658                if (rc)
 659                        goto out_unlock;
 660        } else {
 661                /* Disable the WOL interrupt */
 662                reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
 663                reg_val &= (~MII_VSC85XX_INT_MASK_WOL);
 664                rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
 665                if (rc)
 666                        goto out_unlock;
 667        }
 668        /* Clear WOL iterrupt status */
 669        reg_val = phy_read(phydev, MII_VSC85XX_INT_STATUS);
 670
 671out_unlock:
 672        mutex_unlock(&phydev->lock);
 673
 674        return rc;
 675}
 676
 677static void vsc85xx_wol_get(struct phy_device *phydev,
 678                            struct ethtool_wolinfo *wol)
 679{
 680        int rc;
 681        u16 reg_val;
 682        u8  i;
 683        u16 pwd[3] = {0, 0, 0};
 684        struct ethtool_wolinfo *wol_conf = wol;
 685
 686        mutex_lock(&phydev->lock);
 687        rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
 688        if (rc < 0)
 689                goto out_unlock;
 690
 691        reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
 692        if (reg_val & SECURE_ON_ENABLE)
 693                wol_conf->wolopts |= WAKE_MAGICSECURE;
 694        if (wol_conf->wolopts & WAKE_MAGICSECURE) {
 695                pwd[0] = __phy_read(phydev, MSCC_PHY_WOL_LOWER_PASSWD);
 696                pwd[1] = __phy_read(phydev, MSCC_PHY_WOL_MID_PASSWD);
 697                pwd[2] = __phy_read(phydev, MSCC_PHY_WOL_UPPER_PASSWD);
 698                for (i = 0; i < ARRAY_SIZE(pwd); i++) {
 699                        wol_conf->sopass[5 - i * 2] = pwd[i] & 0x00ff;
 700                        wol_conf->sopass[5 - (i * 2 + 1)] = (pwd[i] & 0xff00)
 701                                                            >> 8;
 702                }
 703        }
 704
 705out_unlock:
 706        phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
 707        mutex_unlock(&phydev->lock);
 708}
 709
 710#ifdef CONFIG_OF_MDIO
 711static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
 712{
 713        u32 vdd, sd;
 714        int i, j;
 715        struct device *dev = &phydev->mdio.dev;
 716        struct device_node *of_node = dev->of_node;
 717        u8 sd_array_size = ARRAY_SIZE(edge_table[0].slowdown);
 718
 719        if (!of_node)
 720                return -ENODEV;
 721
 722        if (of_property_read_u32(of_node, "vsc8531,vddmac", &vdd))
 723                vdd = MSCC_VDDMAC_3300;
 724
 725        if (of_property_read_u32(of_node, "vsc8531,edge-slowdown", &sd))
 726                sd = 0;
 727
 728        for (i = 0; i < ARRAY_SIZE(edge_table); i++)
 729                if (edge_table[i].vddmac == vdd)
 730                        for (j = 0; j < sd_array_size; j++)
 731                                if (edge_table[i].slowdown[j] == sd)
 732                                        return (sd_array_size - j - 1);
 733
 734        return -EINVAL;
 735}
 736
 737static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
 738                                   char *led,
 739                                   u32 default_mode)
 740{
 741        struct vsc8531_private *priv = phydev->priv;
 742        struct device *dev = &phydev->mdio.dev;
 743        struct device_node *of_node = dev->of_node;
 744        u32 led_mode;
 745        int err;
 746
 747        if (!of_node)
 748                return -ENODEV;
 749
 750        led_mode = default_mode;
 751        err = of_property_read_u32(of_node, led, &led_mode);
 752        if (!err && !(BIT(led_mode) & priv->supp_led_modes)) {
 753                phydev_err(phydev, "DT %s invalid\n", led);
 754                return -EINVAL;
 755        }
 756
 757        return led_mode;
 758}
 759
 760#else
 761static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
 762{
 763        return 0;
 764}
 765
 766static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
 767                                   char *led,
 768                                   u8 default_mode)
 769{
 770        return default_mode;
 771}
 772#endif /* CONFIG_OF_MDIO */
 773
 774static int vsc85xx_dt_led_modes_get(struct phy_device *phydev,
 775                                    u32 *default_mode)
 776{
 777        struct vsc8531_private *priv = phydev->priv;
 778        char led_dt_prop[28];
 779        int i, ret;
 780
 781        for (i = 0; i < priv->nleds; i++) {
 782                ret = sprintf(led_dt_prop, "vsc8531,led-%d-mode", i);
 783                if (ret < 0)
 784                        return ret;
 785
 786                ret = vsc85xx_dt_led_mode_get(phydev, led_dt_prop,
 787                                              default_mode[i]);
 788                if (ret < 0)
 789                        return ret;
 790                priv->leds_mode[i] = ret;
 791        }
 792
 793        return 0;
 794}
 795
 796static int vsc85xx_edge_rate_cntl_set(struct phy_device *phydev, u8 edge_rate)
 797{
 798        int rc;
 799
 800        mutex_lock(&phydev->lock);
 801        rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
 802                              MSCC_PHY_WOL_MAC_CONTROL, EDGE_RATE_CNTL_MASK,
 803                              edge_rate << EDGE_RATE_CNTL_POS);
 804        mutex_unlock(&phydev->lock);
 805
 806        return rc;
 807}
 808
 809static int vsc85xx_mac_if_set(struct phy_device *phydev,
 810                              phy_interface_t interface)
 811{
 812        int rc;
 813        u16 reg_val;
 814
 815        mutex_lock(&phydev->lock);
 816        reg_val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
 817        reg_val &= ~(MAC_IF_SELECTION_MASK);
 818        switch (interface) {
 819        case PHY_INTERFACE_MODE_RGMII:
 820                reg_val |= (MAC_IF_SELECTION_RGMII << MAC_IF_SELECTION_POS);
 821                break;
 822        case PHY_INTERFACE_MODE_RMII:
 823                reg_val |= (MAC_IF_SELECTION_RMII << MAC_IF_SELECTION_POS);
 824                break;
 825        case PHY_INTERFACE_MODE_MII:
 826        case PHY_INTERFACE_MODE_GMII:
 827                reg_val |= (MAC_IF_SELECTION_GMII << MAC_IF_SELECTION_POS);
 828                break;
 829        default:
 830                rc = -EINVAL;
 831                goto out_unlock;
 832        }
 833        rc = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, reg_val);
 834        if (rc)
 835                goto out_unlock;
 836
 837        rc = genphy_soft_reset(phydev);
 838
 839out_unlock:
 840        mutex_unlock(&phydev->lock);
 841
 842        return rc;
 843}
 844
 845static int vsc85xx_default_config(struct phy_device *phydev)
 846{
 847        int rc;
 848        u16 reg_val;
 849
 850        phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
 851        mutex_lock(&phydev->lock);
 852
 853        reg_val = RGMII_RX_CLK_DELAY_1_1_NS << RGMII_RX_CLK_DELAY_POS;
 854
 855        rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
 856                              MSCC_PHY_RGMII_CNTL, RGMII_RX_CLK_DELAY_MASK,
 857                              reg_val);
 858
 859        mutex_unlock(&phydev->lock);
 860
 861        return rc;
 862}
 863
 864static int vsc85xx_get_tunable(struct phy_device *phydev,
 865                               struct ethtool_tunable *tuna, void *data)
 866{
 867        switch (tuna->id) {
 868        case ETHTOOL_PHY_DOWNSHIFT:
 869                return vsc85xx_downshift_get(phydev, (u8 *)data);
 870        default:
 871                return -EINVAL;
 872        }
 873}
 874
 875static int vsc85xx_set_tunable(struct phy_device *phydev,
 876                               struct ethtool_tunable *tuna,
 877                               const void *data)
 878{
 879        switch (tuna->id) {
 880        case ETHTOOL_PHY_DOWNSHIFT:
 881                return vsc85xx_downshift_set(phydev, *(u8 *)data);
 882        default:
 883                return -EINVAL;
 884        }
 885}
 886
 887/* mdiobus lock should be locked when using this function */
 888static void vsc85xx_tr_write(struct phy_device *phydev, u16 addr, u32 val)
 889{
 890        __phy_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
 891        __phy_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
 892        __phy_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
 893}
 894
 895static int vsc8531_pre_init_seq_set(struct phy_device *phydev)
 896{
 897        int rc;
 898        const struct reg_val init_seq[] = {
 899                {0x0f90, 0x00688980},
 900                {0x0696, 0x00000003},
 901                {0x07fa, 0x0050100f},
 902                {0x1686, 0x00000004},
 903        };
 904        unsigned int i;
 905        int oldpage;
 906
 907        rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_STANDARD,
 908                              MSCC_PHY_EXT_CNTL_STATUS, SMI_BROADCAST_WR_EN,
 909                              SMI_BROADCAST_WR_EN);
 910        if (rc < 0)
 911                return rc;
 912        rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
 913                              MSCC_PHY_TEST_PAGE_24, 0, 0x0400);
 914        if (rc < 0)
 915                return rc;
 916        rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
 917                              MSCC_PHY_TEST_PAGE_5, 0x0a00, 0x0e00);
 918        if (rc < 0)
 919                return rc;
 920        rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
 921                              MSCC_PHY_TEST_PAGE_8, 0x8000, 0x8000);
 922        if (rc < 0)
 923                return rc;
 924
 925        mutex_lock(&phydev->lock);
 926        oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
 927        if (oldpage < 0)
 928                goto out_unlock;
 929
 930        for (i = 0; i < ARRAY_SIZE(init_seq); i++)
 931                vsc85xx_tr_write(phydev, init_seq[i].reg, init_seq[i].val);
 932
 933out_unlock:
 934        oldpage = phy_restore_page(phydev, oldpage, oldpage);
 935        mutex_unlock(&phydev->lock);
 936
 937        return oldpage;
 938}
 939
 940static int vsc85xx_eee_init_seq_set(struct phy_device *phydev)
 941{
 942        const struct reg_val init_eee[] = {
 943                {0x0f82, 0x0012b00a},
 944                {0x1686, 0x00000004},
 945                {0x168c, 0x00d2c46f},
 946                {0x17a2, 0x00000620},
 947                {0x16a0, 0x00eeffdd},
 948                {0x16a6, 0x00071448},
 949                {0x16a4, 0x0013132f},
 950                {0x16a8, 0x00000000},
 951                {0x0ffc, 0x00c0a028},
 952                {0x0fe8, 0x0091b06c},
 953                {0x0fea, 0x00041600},
 954                {0x0f80, 0x00000af4},
 955                {0x0fec, 0x00901809},
 956                {0x0fee, 0x0000a6a1},
 957                {0x0ffe, 0x00b01007},
 958                {0x16b0, 0x00eeff00},
 959                {0x16b2, 0x00007000},
 960                {0x16b4, 0x00000814},
 961        };
 962        unsigned int i;
 963        int oldpage;
 964
 965        mutex_lock(&phydev->lock);
 966        oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
 967        if (oldpage < 0)
 968                goto out_unlock;
 969
 970        for (i = 0; i < ARRAY_SIZE(init_eee); i++)
 971                vsc85xx_tr_write(phydev, init_eee[i].reg, init_eee[i].val);
 972
 973out_unlock:
 974        oldpage = phy_restore_page(phydev, oldpage, oldpage);
 975        mutex_unlock(&phydev->lock);
 976
 977        return oldpage;
 978}
 979
 980/* phydev->bus->mdio_lock should be locked when using this function */
 981static int phy_base_write(struct phy_device *phydev, u32 regnum, u16 val)
 982{
 983        struct vsc8531_private *priv = phydev->priv;
 984
 985        if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
 986                dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
 987                dump_stack();
 988        }
 989
 990        return __mdiobus_write(phydev->mdio.bus, priv->base_addr, regnum, val);
 991}
 992
 993/* phydev->bus->mdio_lock should be locked when using this function */
 994static int phy_base_read(struct phy_device *phydev, u32 regnum)
 995{
 996        struct vsc8531_private *priv = phydev->priv;
 997
 998        if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
 999                dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
1000                dump_stack();
1001        }
1002
1003        return __mdiobus_read(phydev->mdio.bus, priv->base_addr, regnum);
1004}
1005
1006/* bus->mdio_lock should be locked when using this function */
1007static void vsc8584_csr_write(struct phy_device *phydev, u16 addr, u32 val)
1008{
1009        phy_base_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
1010        phy_base_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
1011        phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
1012}
1013
1014/* bus->mdio_lock should be locked when using this function */
1015static int vsc8584_cmd(struct phy_device *phydev, u16 val)
1016{
1017        unsigned long deadline;
1018        u16 reg_val;
1019
1020        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1021                       MSCC_PHY_PAGE_EXTENDED_GPIO);
1022
1023        phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NCOMPLETED | val);
1024
1025        deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
1026        do {
1027                reg_val = phy_base_read(phydev, MSCC_PHY_PROC_CMD);
1028        } while (time_before(jiffies, deadline) &&
1029                 (reg_val & PROC_CMD_NCOMPLETED) &&
1030                 !(reg_val & PROC_CMD_FAILED));
1031
1032        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1033
1034        if (reg_val & PROC_CMD_FAILED)
1035                return -EIO;
1036
1037        if (reg_val & PROC_CMD_NCOMPLETED)
1038                return -ETIMEDOUT;
1039
1040        return 0;
1041}
1042
1043/* bus->mdio_lock should be locked when using this function */
1044static int vsc8584_micro_deassert_reset(struct phy_device *phydev,
1045                                        bool patch_en)
1046{
1047        u32 enable, release;
1048
1049        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1050                       MSCC_PHY_PAGE_EXTENDED_GPIO);
1051
1052        enable = RUN_FROM_INT_ROM | MICRO_CLK_EN | DW8051_CLK_EN;
1053        release = MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
1054                MICRO_CLK_EN;
1055
1056        if (patch_en) {
1057                enable |= MICRO_PATCH_EN;
1058                release |= MICRO_PATCH_EN;
1059
1060                /* Clear all patches */
1061                phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
1062        }
1063
1064        /* Enable 8051 Micro clock; CLEAR/SET patch present; disable PRAM clock
1065         * override and addr. auto-incr; operate at 125 MHz
1066         */
1067        phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, enable);
1068        /* Release 8051 Micro SW reset */
1069        phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, release);
1070
1071        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1072
1073        return 0;
1074}
1075
1076/* bus->mdio_lock should be locked when using this function */
1077static int vsc8584_micro_assert_reset(struct phy_device *phydev)
1078{
1079        int ret;
1080        u16 reg;
1081
1082        ret = vsc8584_cmd(phydev, PROC_CMD_NOP);
1083        if (ret)
1084                return ret;
1085
1086        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1087                       MSCC_PHY_PAGE_EXTENDED_GPIO);
1088
1089        reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1090        reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
1091        phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
1092
1093        phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(4), 0x005b);
1094        phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(4), 0x005b);
1095
1096        reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1097        reg |= EN_PATCH_RAM_TRAP_ADDR(4);
1098        phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
1099
1100        phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NOP);
1101
1102        reg = phy_base_read(phydev, MSCC_DW8051_CNTL_STATUS);
1103        reg &= ~MICRO_NSOFT_RESET;
1104        phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, reg);
1105
1106        phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_MCB_ACCESS_MAC_CONF |
1107                       PROC_CMD_SGMII_PORT(0) | PROC_CMD_NO_MAC_CONF |
1108                       PROC_CMD_READ);
1109
1110        reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1111        reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
1112        phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
1113
1114        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1115
1116        return 0;
1117}
1118
1119/* bus->mdio_lock should be locked when using this function */
1120static int vsc8584_get_fw_crc(struct phy_device *phydev, u16 start, u16 size,
1121                              u16 *crc)
1122{
1123        int ret;
1124
1125        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
1126
1127        phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_2, start);
1128        phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_3, size);
1129
1130        /* Start Micro command */
1131        ret = vsc8584_cmd(phydev, PROC_CMD_CRC16);
1132        if (ret)
1133                goto out;
1134
1135        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
1136
1137        *crc = phy_base_read(phydev, MSCC_PHY_VERIPHY_CNTL_2);
1138
1139out:
1140        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1141
1142        return ret;
1143}
1144
1145/* bus->mdio_lock should be locked when using this function */
1146static int vsc8584_patch_fw(struct phy_device *phydev,
1147                            const struct firmware *fw)
1148{
1149        int i, ret;
1150
1151        ret = vsc8584_micro_assert_reset(phydev);
1152        if (ret) {
1153                dev_err(&phydev->mdio.dev,
1154                        "%s: failed to assert reset of micro\n", __func__);
1155                return ret;
1156        }
1157
1158        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1159                       MSCC_PHY_PAGE_EXTENDED_GPIO);
1160
1161        /* Hold 8051 Micro in SW Reset, Enable auto incr address and patch clock
1162         * Disable the 8051 Micro clock
1163         */
1164        phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, RUN_FROM_INT_ROM |
1165                       AUTOINC_ADDR | PATCH_RAM_CLK | MICRO_CLK_EN |
1166                       MICRO_CLK_DIVIDE(2));
1167        phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_PRAM | INT_MEM_WRITE_EN |
1168                       INT_MEM_DATA(2));
1169        phy_base_write(phydev, MSCC_INT_MEM_ADDR, 0x0000);
1170
1171        for (i = 0; i < fw->size; i++)
1172                phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_PRAM |
1173                               INT_MEM_WRITE_EN | fw->data[i]);
1174
1175        /* Clear internal memory access */
1176        phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
1177
1178        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1179
1180        return 0;
1181}
1182
1183/* bus->mdio_lock should be locked when using this function */
1184static bool vsc8574_is_serdes_init(struct phy_device *phydev)
1185{
1186        u16 reg;
1187        bool ret;
1188
1189        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1190                       MSCC_PHY_PAGE_EXTENDED_GPIO);
1191
1192        reg = phy_base_read(phydev, MSCC_TRAP_ROM_ADDR(1));
1193        if (reg != 0x3eb7) {
1194                ret = false;
1195                goto out;
1196        }
1197
1198        reg = phy_base_read(phydev, MSCC_PATCH_RAM_ADDR(1));
1199        if (reg != 0x4012) {
1200                ret = false;
1201                goto out;
1202        }
1203
1204        reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1205        if (reg != EN_PATCH_RAM_TRAP_ADDR(1)) {
1206                ret = false;
1207                goto out;
1208        }
1209
1210        reg = phy_base_read(phydev, MSCC_DW8051_CNTL_STATUS);
1211        if ((MICRO_NSOFT_RESET | RUN_FROM_INT_ROM |  DW8051_CLK_EN |
1212             MICRO_CLK_EN) != (reg & MSCC_DW8051_VLD_MASK)) {
1213                ret = false;
1214                goto out;
1215        }
1216
1217        ret = true;
1218out:
1219        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1220
1221        return ret;
1222}
1223
1224/* bus->mdio_lock should be locked when using this function */
1225static int vsc8574_config_pre_init(struct phy_device *phydev)
1226{
1227        const struct reg_val pre_init1[] = {
1228                {0x0fae, 0x000401bd},
1229                {0x0fac, 0x000f000f},
1230                {0x17a0, 0x00a0f147},
1231                {0x0fe4, 0x00052f54},
1232                {0x1792, 0x0027303d},
1233                {0x07fe, 0x00000704},
1234                {0x0fe0, 0x00060150},
1235                {0x0f82, 0x0012b00a},
1236                {0x0f80, 0x00000d74},
1237                {0x02e0, 0x00000012},
1238                {0x03a2, 0x00050208},
1239                {0x03b2, 0x00009186},
1240                {0x0fb0, 0x000e3700},
1241                {0x1688, 0x00049f81},
1242                {0x0fd2, 0x0000ffff},
1243                {0x168a, 0x00039fa2},
1244                {0x1690, 0x0020640b},
1245                {0x0258, 0x00002220},
1246                {0x025a, 0x00002a20},
1247                {0x025c, 0x00003060},
1248                {0x025e, 0x00003fa0},
1249                {0x03a6, 0x0000e0f0},
1250                {0x0f92, 0x00001489},
1251                {0x16a2, 0x00007000},
1252                {0x16a6, 0x00071448},
1253                {0x16a0, 0x00eeffdd},
1254                {0x0fe8, 0x0091b06c},
1255                {0x0fea, 0x00041600},
1256                {0x16b0, 0x00eeff00},
1257                {0x16b2, 0x00007000},
1258                {0x16b4, 0x00000814},
1259                {0x0f90, 0x00688980},
1260                {0x03a4, 0x0000d8f0},
1261                {0x0fc0, 0x00000400},
1262                {0x07fa, 0x0050100f},
1263                {0x0796, 0x00000003},
1264                {0x07f8, 0x00c3ff98},
1265                {0x0fa4, 0x0018292a},
1266                {0x168c, 0x00d2c46f},
1267                {0x17a2, 0x00000620},
1268                {0x16a4, 0x0013132f},
1269                {0x16a8, 0x00000000},
1270                {0x0ffc, 0x00c0a028},
1271                {0x0fec, 0x00901c09},
1272                {0x0fee, 0x0004a6a1},
1273                {0x0ffe, 0x00b01807},
1274        };
1275        const struct reg_val pre_init2[] = {
1276                {0x0486, 0x0008a518},
1277                {0x0488, 0x006dc696},
1278                {0x048a, 0x00000912},
1279                {0x048e, 0x00000db6},
1280                {0x049c, 0x00596596},
1281                {0x049e, 0x00000514},
1282                {0x04a2, 0x00410280},
1283                {0x04a4, 0x00000000},
1284                {0x04a6, 0x00000000},
1285                {0x04a8, 0x00000000},
1286                {0x04aa, 0x00000000},
1287                {0x04ae, 0x007df7dd},
1288                {0x04b0, 0x006d95d4},
1289                {0x04b2, 0x00492410},
1290        };
1291        struct device *dev = &phydev->mdio.dev;
1292        const struct firmware *fw;
1293        unsigned int i;
1294        u16 crc, reg;
1295        bool serdes_init;
1296        int ret;
1297
1298        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1299
1300        /* all writes below are broadcasted to all PHYs in the same package */
1301        reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1302        reg |= SMI_BROADCAST_WR_EN;
1303        phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1304
1305        phy_base_write(phydev, MII_VSC85XX_INT_MASK, 0);
1306
1307        /* The below register writes are tweaking analog and electrical
1308         * configuration that were determined through characterization by PHY
1309         * engineers. These don't mean anything more than "these are the best
1310         * values".
1311         */
1312        phy_base_write(phydev, MSCC_PHY_EXT_PHY_CNTL_2, 0x0040);
1313
1314        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1315
1316        phy_base_write(phydev, MSCC_PHY_TEST_PAGE_20, 0x4320);
1317        phy_base_write(phydev, MSCC_PHY_TEST_PAGE_24, 0x0c00);
1318        phy_base_write(phydev, MSCC_PHY_TEST_PAGE_9, 0x18ca);
1319        phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1b20);
1320
1321        reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1322        reg |= 0x8000;
1323        phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1324
1325        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1326
1327        for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
1328                vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
1329
1330        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_2);
1331
1332        phy_base_write(phydev, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
1333
1334        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1335
1336        for (i = 0; i < ARRAY_SIZE(pre_init2); i++)
1337                vsc8584_csr_write(phydev, pre_init2[i].reg, pre_init2[i].val);
1338
1339        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1340
1341        reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1342        reg &= ~0x8000;
1343        phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1344
1345        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1346
1347        /* end of write broadcasting */
1348        reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1349        reg &= ~SMI_BROADCAST_WR_EN;
1350        phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1351
1352        ret = request_firmware(&fw, MSCC_VSC8574_REVB_INT8051_FW, dev);
1353        if (ret) {
1354                dev_err(dev, "failed to load firmware %s, ret: %d\n",
1355                        MSCC_VSC8574_REVB_INT8051_FW, ret);
1356                return ret;
1357        }
1358
1359        /* Add one byte to size for the one added by the patch_fw function */
1360        ret = vsc8584_get_fw_crc(phydev,
1361                                 MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
1362                                 fw->size + 1, &crc);
1363        if (ret)
1364                goto out;
1365
1366        if (crc == MSCC_VSC8574_REVB_INT8051_FW_CRC) {
1367                serdes_init = vsc8574_is_serdes_init(phydev);
1368
1369                if (!serdes_init) {
1370                        ret = vsc8584_micro_assert_reset(phydev);
1371                        if (ret) {
1372                                dev_err(dev,
1373                                        "%s: failed to assert reset of micro\n",
1374                                        __func__);
1375                                goto out;
1376                        }
1377                }
1378        } else {
1379                dev_dbg(dev, "FW CRC is not the expected one, patching FW\n");
1380
1381                serdes_init = false;
1382
1383                if (vsc8584_patch_fw(phydev, fw))
1384                        dev_warn(dev,
1385                                 "failed to patch FW, expect non-optimal device\n");
1386        }
1387
1388        if (!serdes_init) {
1389                phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1390                               MSCC_PHY_PAGE_EXTENDED_GPIO);
1391
1392                phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(1), 0x3eb7);
1393                phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(1), 0x4012);
1394                phy_base_write(phydev, MSCC_INT_MEM_CNTL,
1395                               EN_PATCH_RAM_TRAP_ADDR(1));
1396
1397                vsc8584_micro_deassert_reset(phydev, false);
1398
1399                /* Add one byte to size for the one added by the patch_fw
1400                 * function
1401                 */
1402                ret = vsc8584_get_fw_crc(phydev,
1403                                         MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
1404                                         fw->size + 1, &crc);
1405                if (ret)
1406                        goto out;
1407
1408                if (crc != MSCC_VSC8574_REVB_INT8051_FW_CRC)
1409                        dev_warn(dev,
1410                                 "FW CRC after patching is not the expected one, expect non-optimal device\n");
1411        }
1412
1413        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1414                       MSCC_PHY_PAGE_EXTENDED_GPIO);
1415
1416        ret = vsc8584_cmd(phydev, PROC_CMD_1588_DEFAULT_INIT |
1417                          PROC_CMD_PHY_INIT);
1418
1419out:
1420        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1421
1422        release_firmware(fw);
1423
1424        return ret;
1425}
1426
1427/* bus->mdio_lock should be locked when using this function */
1428static int vsc8584_config_pre_init(struct phy_device *phydev)
1429{
1430        const struct reg_val pre_init1[] = {
1431                {0x07fa, 0x0050100f},
1432                {0x1688, 0x00049f81},
1433                {0x0f90, 0x00688980},
1434                {0x03a4, 0x0000d8f0},
1435                {0x0fc0, 0x00000400},
1436                {0x0f82, 0x0012b002},
1437                {0x1686, 0x00000004},
1438                {0x168c, 0x00d2c46f},
1439                {0x17a2, 0x00000620},
1440                {0x16a0, 0x00eeffdd},
1441                {0x16a6, 0x00071448},
1442                {0x16a4, 0x0013132f},
1443                {0x16a8, 0x00000000},
1444                {0x0ffc, 0x00c0a028},
1445                {0x0fe8, 0x0091b06c},
1446                {0x0fea, 0x00041600},
1447                {0x0f80, 0x00fffaff},
1448                {0x0fec, 0x00901809},
1449                {0x0ffe, 0x00b01007},
1450                {0x16b0, 0x00eeff00},
1451                {0x16b2, 0x00007000},
1452                {0x16b4, 0x00000814},
1453        };
1454        const struct reg_val pre_init2[] = {
1455                {0x0486, 0x0008a518},
1456                {0x0488, 0x006dc696},
1457                {0x048a, 0x00000912},
1458        };
1459        const struct firmware *fw;
1460        struct device *dev = &phydev->mdio.dev;
1461        unsigned int i;
1462        u16 crc, reg;
1463        int ret;
1464
1465        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1466
1467        /* all writes below are broadcasted to all PHYs in the same package */
1468        reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1469        reg |= SMI_BROADCAST_WR_EN;
1470        phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1471
1472        phy_base_write(phydev, MII_VSC85XX_INT_MASK, 0);
1473
1474        reg = phy_base_read(phydev,  MSCC_PHY_BYPASS_CONTROL);
1475        reg |= PARALLEL_DET_IGNORE_ADVERTISED;
1476        phy_base_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg);
1477
1478        /* The below register writes are tweaking analog and electrical
1479         * configuration that were determined through characterization by PHY
1480         * engineers. These don't mean anything more than "these are the best
1481         * values".
1482         */
1483        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_3);
1484
1485        phy_base_write(phydev, MSCC_PHY_SERDES_TX_CRC_ERR_CNT, 0x2000);
1486
1487        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1488
1489        phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1f20);
1490
1491        reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1492        reg |= 0x8000;
1493        phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1494
1495        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1496
1497        phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x2fa4));
1498
1499        reg = phy_base_read(phydev, MSCC_PHY_TR_MSB);
1500        reg &= ~0x007f;
1501        reg |= 0x0019;
1502        phy_base_write(phydev, MSCC_PHY_TR_MSB, reg);
1503
1504        phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x0fa4));
1505
1506        for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
1507                vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
1508
1509        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_2);
1510
1511        phy_base_write(phydev, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
1512
1513        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1514
1515        for (i = 0; i < ARRAY_SIZE(pre_init2); i++)
1516                vsc8584_csr_write(phydev, pre_init2[i].reg, pre_init2[i].val);
1517
1518        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1519
1520        reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1521        reg &= ~0x8000;
1522        phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1523
1524        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1525
1526        /* end of write broadcasting */
1527        reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1528        reg &= ~SMI_BROADCAST_WR_EN;
1529        phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1530
1531        ret = request_firmware(&fw, MSCC_VSC8584_REVB_INT8051_FW, dev);
1532        if (ret) {
1533                dev_err(dev, "failed to load firmware %s, ret: %d\n",
1534                        MSCC_VSC8584_REVB_INT8051_FW, ret);
1535                return ret;
1536        }
1537
1538        /* Add one byte to size for the one added by the patch_fw function */
1539        ret = vsc8584_get_fw_crc(phydev,
1540                                 MSCC_VSC8584_REVB_INT8051_FW_START_ADDR,
1541                                 fw->size + 1, &crc);
1542        if (ret)
1543                goto out;
1544
1545        if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC) {
1546                dev_dbg(dev, "FW CRC is not the expected one, patching FW\n");
1547                if (vsc8584_patch_fw(phydev, fw))
1548                        dev_warn(dev,
1549                                 "failed to patch FW, expect non-optimal device\n");
1550        }
1551
1552        vsc8584_micro_deassert_reset(phydev, false);
1553
1554        /* Add one byte to size for the one added by the patch_fw function */
1555        ret = vsc8584_get_fw_crc(phydev,
1556                                 MSCC_VSC8584_REVB_INT8051_FW_START_ADDR,
1557                                 fw->size + 1, &crc);
1558        if (ret)
1559                goto out;
1560
1561        if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC)
1562                dev_warn(dev,
1563                         "FW CRC after patching is not the expected one, expect non-optimal device\n");
1564
1565        ret = vsc8584_micro_assert_reset(phydev);
1566        if (ret)
1567                goto out;
1568
1569        vsc8584_micro_deassert_reset(phydev, true);
1570
1571out:
1572        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1573
1574        release_firmware(fw);
1575
1576        return ret;
1577}
1578
1579/* Check if one PHY has already done the init of the parts common to all PHYs
1580 * in the Quad PHY package.
1581 */
1582static bool vsc8584_is_pkg_init(struct phy_device *phydev, bool reversed)
1583{
1584        struct mdio_device **map = phydev->mdio.bus->mdio_map;
1585        struct vsc8531_private *vsc8531;
1586        struct phy_device *phy;
1587        int i, addr;
1588
1589        /* VSC8584 is a Quad PHY */
1590        for (i = 0; i < 4; i++) {
1591                vsc8531 = phydev->priv;
1592
1593                if (reversed)
1594                        addr = vsc8531->base_addr - i;
1595                else
1596                        addr = vsc8531->base_addr + i;
1597
1598                phy = container_of(map[addr], struct phy_device, mdio);
1599
1600                if ((phy->phy_id & phydev->drv->phy_id_mask) !=
1601                    (phydev->drv->phy_id & phydev->drv->phy_id_mask))
1602                        continue;
1603
1604                vsc8531 = phy->priv;
1605
1606                if (vsc8531 && vsc8531->pkg_init)
1607                        return true;
1608        }
1609
1610        return false;
1611}
1612
1613static int vsc8584_config_init(struct phy_device *phydev)
1614{
1615        struct vsc8531_private *vsc8531 = phydev->priv;
1616        u16 addr, val;
1617        int ret, i;
1618
1619        phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
1620
1621        mutex_lock(&phydev->mdio.bus->mdio_lock);
1622
1623        __mdiobus_write(phydev->mdio.bus, phydev->mdio.addr,
1624                        MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
1625        addr = __mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
1626                              MSCC_PHY_EXT_PHY_CNTL_4);
1627        addr >>= PHY_CNTL_4_ADDR_POS;
1628
1629        val = __mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
1630                             MSCC_PHY_ACTIPHY_CNTL);
1631        if (val & PHY_ADDR_REVERSED)
1632                vsc8531->base_addr = phydev->mdio.addr + addr;
1633        else
1634                vsc8531->base_addr = phydev->mdio.addr - addr;
1635
1636        /* Some parts of the init sequence are identical for every PHY in the
1637         * package. Some parts are modifying the GPIO register bank which is a
1638         * set of registers that are affecting all PHYs, a few resetting the
1639         * microprocessor common to all PHYs. The CRC check responsible of the
1640         * checking the firmware within the 8051 microprocessor can only be
1641         * accessed via the PHY whose internal address in the package is 0.
1642         * All PHYs' interrupts mask register has to be zeroed before enabling
1643         * any PHY's interrupt in this register.
1644         * For all these reasons, we need to do the init sequence once and only
1645         * once whatever is the first PHY in the package that is initialized and
1646         * do the correct init sequence for all PHYs that are package-critical
1647         * in this pre-init function.
1648         */
1649        if (!vsc8584_is_pkg_init(phydev, val & PHY_ADDR_REVERSED ? 1 : 0)) {
1650                if ((phydev->phy_id & phydev->drv->phy_id_mask) ==
1651                    (PHY_ID_VSC8574 & phydev->drv->phy_id_mask))
1652                        ret = vsc8574_config_pre_init(phydev);
1653                else if ((phydev->phy_id & phydev->drv->phy_id_mask) ==
1654                         (PHY_ID_VSC8584 & phydev->drv->phy_id_mask))
1655                        ret = vsc8584_config_pre_init(phydev);
1656                else
1657                        ret = -EINVAL;
1658
1659                if (ret)
1660                        goto err;
1661        }
1662
1663        vsc8531->pkg_init = true;
1664
1665        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1666                       MSCC_PHY_PAGE_EXTENDED_GPIO);
1667
1668        val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
1669        val &= ~MAC_CFG_MASK;
1670        if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
1671                val |= MAC_CFG_QSGMII;
1672        else
1673                val |= MAC_CFG_SGMII;
1674
1675        ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
1676        if (ret)
1677                goto err;
1678
1679        val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
1680                PROC_CMD_READ_MOD_WRITE_PORT;
1681        if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
1682                val |= PROC_CMD_QSGMII_MAC;
1683        else
1684                val |= PROC_CMD_SGMII_MAC;
1685
1686        ret = vsc8584_cmd(phydev, val);
1687        if (ret)
1688                goto err;
1689
1690        usleep_range(10000, 20000);
1691
1692        /* Disable SerDes for 100Base-FX */
1693        ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
1694                          PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
1695                          PROC_CMD_READ_MOD_WRITE_PORT |
1696                          PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_100BASE_FX);
1697        if (ret)
1698                goto err;
1699
1700        /* Disable SerDes for 1000Base-X */
1701        ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
1702                          PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
1703                          PROC_CMD_READ_MOD_WRITE_PORT |
1704                          PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X);
1705        if (ret)
1706                goto err;
1707
1708        mutex_unlock(&phydev->mdio.bus->mdio_lock);
1709
1710        phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1711
1712        val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
1713        val &= ~(MEDIA_OP_MODE_MASK | VSC8584_MAC_IF_SELECTION_MASK);
1714        val |= MEDIA_OP_MODE_COPPER | (VSC8584_MAC_IF_SELECTION_SGMII <<
1715                                       VSC8584_MAC_IF_SELECTION_POS);
1716        ret = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, val);
1717
1718        ret = genphy_soft_reset(phydev);
1719        if (ret)
1720                return ret;
1721
1722        for (i = 0; i < vsc8531->nleds; i++) {
1723                ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
1724                if (ret)
1725                        return ret;
1726        }
1727
1728        return genphy_config_init(phydev);
1729
1730err:
1731        mutex_unlock(&phydev->mdio.bus->mdio_lock);
1732        return ret;
1733}
1734
1735static int vsc85xx_config_init(struct phy_device *phydev)
1736{
1737        int rc, i, phy_id;
1738        struct vsc8531_private *vsc8531 = phydev->priv;
1739
1740        rc = vsc85xx_default_config(phydev);
1741        if (rc)
1742                return rc;
1743
1744        rc = vsc85xx_mac_if_set(phydev, phydev->interface);
1745        if (rc)
1746                return rc;
1747
1748        rc = vsc85xx_edge_rate_cntl_set(phydev, vsc8531->rate_magic);
1749        if (rc)
1750                return rc;
1751
1752        phy_id = phydev->drv->phy_id & phydev->drv->phy_id_mask;
1753        if (PHY_ID_VSC8531 == phy_id || PHY_ID_VSC8541 == phy_id ||
1754            PHY_ID_VSC8530 == phy_id || PHY_ID_VSC8540 == phy_id) {
1755                rc = vsc8531_pre_init_seq_set(phydev);
1756                if (rc)
1757                        return rc;
1758        }
1759
1760        rc = vsc85xx_eee_init_seq_set(phydev);
1761        if (rc)
1762                return rc;
1763
1764        for (i = 0; i < vsc8531->nleds; i++) {
1765                rc = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
1766                if (rc)
1767                        return rc;
1768        }
1769
1770        return genphy_config_init(phydev);
1771}
1772
1773static int vsc8584_did_interrupt(struct phy_device *phydev)
1774{
1775        int rc = 0;
1776
1777        if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
1778                rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
1779
1780        return (rc < 0) ? 0 : rc & MII_VSC85XX_INT_MASK_MASK;
1781}
1782
1783static int vsc8514_config_pre_init(struct phy_device *phydev)
1784{
1785        /* These are the settings to override the silicon default
1786         * values to handle hardware performance of PHY. They
1787         * are set at Power-On state and remain until PHY Reset.
1788         */
1789        const struct reg_val pre_init1[] = {
1790                {0x0f90, 0x00688980},
1791                {0x0786, 0x00000003},
1792                {0x07fa, 0x0050100f},
1793                {0x0f82, 0x0012b002},
1794                {0x1686, 0x00000004},
1795                {0x168c, 0x00d2c46f},
1796                {0x17a2, 0x00000620},
1797                {0x16a0, 0x00eeffdd},
1798                {0x16a6, 0x00071448},
1799                {0x16a4, 0x0013132f},
1800                {0x16a8, 0x00000000},
1801                {0x0ffc, 0x00c0a028},
1802                {0x0fe8, 0x0091b06c},
1803                {0x0fea, 0x00041600},
1804                {0x0f80, 0x00fffaff},
1805                {0x0fec, 0x00901809},
1806                {0x0ffe, 0x00b01007},
1807                {0x16b0, 0x00eeff00},
1808                {0x16b2, 0x00007000},
1809                {0x16b4, 0x00000814},
1810        };
1811        unsigned int i;
1812        u16 reg;
1813
1814        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1815
1816        /* all writes below are broadcasted to all PHYs in the same package */
1817        reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1818        reg |= SMI_BROADCAST_WR_EN;
1819        phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1820
1821        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1822
1823        reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1824        reg |= BIT(15);
1825        phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1826
1827        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1828
1829        for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
1830                vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
1831
1832        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1833
1834        reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1835        reg &= ~BIT(15);
1836        phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1837
1838        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1839
1840        reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1841        reg &= ~SMI_BROADCAST_WR_EN;
1842        phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1843
1844        return 0;
1845}
1846
1847static u32 vsc85xx_csr_ctrl_phy_read(struct phy_device *phydev,
1848                                     u32 target, u32 reg)
1849{
1850        unsigned long deadline;
1851        u32 val, val_l, val_h;
1852
1853        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
1854
1855        /* CSR registers are grouped under different Target IDs.
1856         * 6-bit Target_ID is split between MSCC_EXT_PAGE_CSR_CNTL_20 and
1857         * MSCC_EXT_PAGE_CSR_CNTL_19 registers.
1858         * Target_ID[5:2] maps to bits[3:0] of MSCC_EXT_PAGE_CSR_CNTL_20
1859         * and Target_ID[1:0] maps to bits[13:12] of MSCC_EXT_PAGE_CSR_CNTL_19.
1860         */
1861
1862        /* Setup the Target ID */
1863        phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_20,
1864                       MSCC_PHY_CSR_CNTL_20_TARGET(target >> 2));
1865
1866        /* Trigger CSR Action - Read into the CSR's */
1867        phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_19,
1868                       MSCC_PHY_CSR_CNTL_19_CMD | MSCC_PHY_CSR_CNTL_19_READ |
1869                       MSCC_PHY_CSR_CNTL_19_REG_ADDR(reg) |
1870                       MSCC_PHY_CSR_CNTL_19_TARGET(target & 0x3));
1871
1872        /* Wait for register access*/
1873        deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
1874        do {
1875                usleep_range(500, 1000);
1876                val = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_19);
1877        } while (time_before(jiffies, deadline) &&
1878                !(val & MSCC_PHY_CSR_CNTL_19_CMD));
1879
1880        if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
1881                return 0xffffffff;
1882
1883        /* Read the Least Significant Word (LSW) (17) */
1884        val_l = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_17);
1885
1886        /* Read the Most Significant Word (MSW) (18) */
1887        val_h = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_18);
1888
1889        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1890                       MSCC_PHY_PAGE_STANDARD);
1891
1892        return (val_h << 16) | val_l;
1893}
1894
1895static int vsc85xx_csr_ctrl_phy_write(struct phy_device *phydev,
1896                                      u32 target, u32 reg, u32 val)
1897{
1898        unsigned long deadline;
1899
1900        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
1901
1902        /* CSR registers are grouped under different Target IDs.
1903         * 6-bit Target_ID is split between MSCC_EXT_PAGE_CSR_CNTL_20 and
1904         * MSCC_EXT_PAGE_CSR_CNTL_19 registers.
1905         * Target_ID[5:2] maps to bits[3:0] of MSCC_EXT_PAGE_CSR_CNTL_20
1906         * and Target_ID[1:0] maps to bits[13:12] of MSCC_EXT_PAGE_CSR_CNTL_19.
1907         */
1908
1909        /* Setup the Target ID */
1910        phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_20,
1911                       MSCC_PHY_CSR_CNTL_20_TARGET(target >> 2));
1912
1913        /* Write the Least Significant Word (LSW) (17) */
1914        phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_17, (u16)val);
1915
1916        /* Write the Most Significant Word (MSW) (18) */
1917        phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_18, (u16)(val >> 16));
1918
1919        /* Trigger CSR Action - Write into the CSR's */
1920        phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_19,
1921                       MSCC_PHY_CSR_CNTL_19_CMD |
1922                       MSCC_PHY_CSR_CNTL_19_REG_ADDR(reg) |
1923                       MSCC_PHY_CSR_CNTL_19_TARGET(target & 0x3));
1924
1925        /* Wait for register access */
1926        deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
1927        do {
1928                usleep_range(500, 1000);
1929                val = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_19);
1930        } while (time_before(jiffies, deadline) &&
1931                 !(val & MSCC_PHY_CSR_CNTL_19_CMD));
1932
1933        if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
1934                return -ETIMEDOUT;
1935
1936        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1937                       MSCC_PHY_PAGE_STANDARD);
1938
1939        return 0;
1940}
1941
1942static int __phy_write_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb,
1943                               u32 op)
1944{
1945        unsigned long deadline;
1946        u32 val;
1947        int ret;
1948
1949        ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET, reg,
1950                                         op | (1 << mcb));
1951        if (ret)
1952                return -EINVAL;
1953
1954        deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
1955        do {
1956                usleep_range(500, 1000);
1957                val = vsc85xx_csr_ctrl_phy_read(phydev, PHY_MCB_TARGET, reg);
1958
1959                if (val == 0xffffffff)
1960                        return -EIO;
1961
1962        } while (time_before(jiffies, deadline) && (val & op));
1963
1964        if (val & op)
1965                return -ETIMEDOUT;
1966
1967        return 0;
1968}
1969
1970/* Trigger a read to the spcified MCB */
1971static int phy_update_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
1972{
1973        return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_READ);
1974}
1975
1976/* Trigger a write to the spcified MCB */
1977static int phy_commit_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
1978{
1979        return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_WRITE);
1980}
1981
1982static int vsc8514_config_init(struct phy_device *phydev)
1983{
1984        struct vsc8531_private *vsc8531 = phydev->priv;
1985        unsigned long deadline;
1986        u16 val, addr;
1987        int ret, i;
1988        u32 reg;
1989
1990        phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
1991
1992        mutex_lock(&phydev->mdio.bus->mdio_lock);
1993
1994        __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
1995
1996        addr = __phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_4);
1997        addr >>= PHY_CNTL_4_ADDR_POS;
1998
1999        val = __phy_read(phydev, MSCC_PHY_ACTIPHY_CNTL);
2000
2001        if (val & PHY_ADDR_REVERSED)
2002                vsc8531->base_addr = phydev->mdio.addr + addr;
2003        else
2004                vsc8531->base_addr = phydev->mdio.addr - addr;
2005
2006        /* Some parts of the init sequence are identical for every PHY in the
2007         * package. Some parts are modifying the GPIO register bank which is a
2008         * set of registers that are affecting all PHYs, a few resetting the
2009         * microprocessor common to all PHYs.
2010         * All PHYs' interrupts mask register has to be zeroed before enabling
2011         * any PHY's interrupt in this register.
2012         * For all these reasons, we need to do the init sequence once and only
2013         * once whatever is the first PHY in the package that is initialized and
2014         * do the correct init sequence for all PHYs that are package-critical
2015         * in this pre-init function.
2016         */
2017        if (!vsc8584_is_pkg_init(phydev, val & PHY_ADDR_REVERSED ? 1 : 0))
2018                vsc8514_config_pre_init(phydev);
2019
2020        vsc8531->pkg_init = true;
2021
2022        phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
2023                       MSCC_PHY_PAGE_EXTENDED_GPIO);
2024
2025        val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
2026
2027        val &= ~MAC_CFG_MASK;
2028        val |= MAC_CFG_QSGMII;
2029        ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
2030
2031        if (ret)
2032                goto err;
2033
2034        ret = vsc8584_cmd(phydev,
2035                          PROC_CMD_MCB_ACCESS_MAC_CONF |
2036                          PROC_CMD_RST_CONF_PORT |
2037                          PROC_CMD_READ_MOD_WRITE_PORT | PROC_CMD_QSGMII_MAC);
2038        if (ret)
2039                goto err;
2040
2041        /* 6g mcb */
2042        phy_update_mcb_s6g(phydev, PHY_MCB_S6G_CFG, 0);
2043        /* lcpll mcb */
2044        phy_update_mcb_s6g(phydev, PHY_S6G_LCPLL_CFG, 0);
2045        /* pll5gcfg0 */
2046        ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
2047                                         PHY_S6G_PLL5G_CFG0, 0x7036f145);
2048        if (ret)
2049                goto err;
2050
2051        phy_commit_mcb_s6g(phydev, PHY_S6G_LCPLL_CFG, 0);
2052        /* pllcfg */
2053        ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
2054                                         PHY_S6G_PLL_CFG,
2055                                         (3 << PHY_S6G_PLL_ENA_OFFS_POS) |
2056                                         (120 << PHY_S6G_PLL_FSM_CTRL_DATA_POS)
2057                                         | (0 << PHY_S6G_PLL_FSM_ENA_POS));
2058        if (ret)
2059                goto err;
2060
2061        /* commoncfg */
2062        ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
2063                                         PHY_S6G_COMMON_CFG,
2064                                         (0 << PHY_S6G_SYS_RST_POS) |
2065                                         (0 << PHY_S6G_ENA_LANE_POS) |
2066                                         (0 << PHY_S6G_ENA_LOOP_POS) |
2067                                         (0 << PHY_S6G_QRATE_POS) |
2068                                         (3 << PHY_S6G_IF_MODE_POS));
2069        if (ret)
2070                goto err;
2071
2072        /* misccfg */
2073        ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
2074                                         PHY_S6G_MISC_CFG, 1);
2075        if (ret)
2076                goto err;
2077
2078        /* gpcfg */
2079        ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
2080                                         PHY_S6G_GPC_CFG, 768);
2081        if (ret)
2082                goto err;
2083
2084        phy_commit_mcb_s6g(phydev, PHY_S6G_DFT_CFG2, 0);
2085
2086        deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
2087        do {
2088                usleep_range(500, 1000);
2089                phy_update_mcb_s6g(phydev, PHY_MCB_S6G_CFG,
2090                                   0); /* read 6G MCB into CSRs */
2091                reg = vsc85xx_csr_ctrl_phy_read(phydev, PHY_MCB_TARGET,
2092                                                PHY_S6G_PLL_STATUS);
2093                if (reg == 0xffffffff) {
2094                        mutex_unlock(&phydev->mdio.bus->mdio_lock);
2095                        return -EIO;
2096                }
2097
2098        } while (time_before(jiffies, deadline) && (reg & BIT(12)));
2099
2100        if (reg & BIT(12)) {
2101                mutex_unlock(&phydev->mdio.bus->mdio_lock);
2102                return -ETIMEDOUT;
2103        }
2104
2105        /* misccfg */
2106        ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
2107                                         PHY_S6G_MISC_CFG, 0);
2108        if (ret)
2109                goto err;
2110
2111        phy_commit_mcb_s6g(phydev, PHY_MCB_S6G_CFG, 0);
2112
2113        deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
2114        do {
2115                usleep_range(500, 1000);
2116                phy_update_mcb_s6g(phydev, PHY_MCB_S6G_CFG,
2117                                   0); /* read 6G MCB into CSRs */
2118                reg = vsc85xx_csr_ctrl_phy_read(phydev, PHY_MCB_TARGET,
2119                                                PHY_S6G_IB_STATUS0);
2120                if (reg == 0xffffffff) {
2121                        mutex_unlock(&phydev->mdio.bus->mdio_lock);
2122                        return -EIO;
2123                }
2124
2125        } while (time_before(jiffies, deadline) && !(reg & BIT(8)));
2126
2127        if (!(reg & BIT(8))) {
2128                mutex_unlock(&phydev->mdio.bus->mdio_lock);
2129                return -ETIMEDOUT;
2130        }
2131
2132        mutex_unlock(&phydev->mdio.bus->mdio_lock);
2133
2134        ret = phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
2135
2136        if (ret)
2137                return ret;
2138
2139        ret = phy_modify(phydev, MSCC_PHY_EXT_PHY_CNTL_1, MEDIA_OP_MODE_MASK,
2140                         MEDIA_OP_MODE_COPPER);
2141
2142        if (ret)
2143                return ret;
2144
2145        ret = genphy_soft_reset(phydev);
2146
2147        if (ret)
2148                return ret;
2149
2150        for (i = 0; i < vsc8531->nleds; i++) {
2151                ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
2152                if (ret)
2153                        return ret;
2154        }
2155
2156        return ret;
2157
2158err:
2159        mutex_unlock(&phydev->mdio.bus->mdio_lock);
2160        return ret;
2161}
2162
2163static int vsc85xx_ack_interrupt(struct phy_device *phydev)
2164{
2165        int rc = 0;
2166
2167        if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
2168                rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
2169
2170        return (rc < 0) ? rc : 0;
2171}
2172
2173static int vsc85xx_config_intr(struct phy_device *phydev)
2174{
2175        int rc;
2176
2177        if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
2178                rc = phy_write(phydev, MII_VSC85XX_INT_MASK,
2179                               MII_VSC85XX_INT_MASK_MASK);
2180        } else {
2181                rc = phy_write(phydev, MII_VSC85XX_INT_MASK, 0);
2182                if (rc < 0)
2183                        return rc;
2184                rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
2185        }
2186
2187        return rc;
2188}
2189
2190static int vsc85xx_config_aneg(struct phy_device *phydev)
2191{
2192        int rc;
2193
2194        rc = vsc85xx_mdix_set(phydev, phydev->mdix_ctrl);
2195        if (rc < 0)
2196                return rc;
2197
2198        return genphy_config_aneg(phydev);
2199}
2200
2201static int vsc85xx_read_status(struct phy_device *phydev)
2202{
2203        int rc;
2204
2205        rc = vsc85xx_mdix_get(phydev, &phydev->mdix);
2206        if (rc < 0)
2207                return rc;
2208
2209        return genphy_read_status(phydev);
2210}
2211
2212static int vsc8514_probe(struct phy_device *phydev)
2213{
2214        struct vsc8531_private *vsc8531;
2215        u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
2216           VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
2217           VSC8531_DUPLEX_COLLISION};
2218
2219        vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2220        if (!vsc8531)
2221                return -ENOMEM;
2222
2223        phydev->priv = vsc8531;
2224
2225        vsc8531->nleds = 4;
2226        vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES;
2227        vsc8531->hw_stats = vsc85xx_hw_stats;
2228        vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats);
2229        vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
2230                                      sizeof(u64), GFP_KERNEL);
2231        if (!vsc8531->stats)
2232                return -ENOMEM;
2233
2234        return vsc85xx_dt_led_modes_get(phydev, default_mode);
2235}
2236
2237static int vsc8574_probe(struct phy_device *phydev)
2238{
2239        struct vsc8531_private *vsc8531;
2240        u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
2241           VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
2242           VSC8531_DUPLEX_COLLISION};
2243
2244        vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2245        if (!vsc8531)
2246                return -ENOMEM;
2247
2248        phydev->priv = vsc8531;
2249
2250        vsc8531->nleds = 4;
2251        vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES;
2252        vsc8531->hw_stats = vsc8584_hw_stats;
2253        vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats);
2254        vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
2255                                      sizeof(u64), GFP_KERNEL);
2256        if (!vsc8531->stats)
2257                return -ENOMEM;
2258
2259        return vsc85xx_dt_led_modes_get(phydev, default_mode);
2260}
2261
2262static int vsc8584_probe(struct phy_device *phydev)
2263{
2264        struct vsc8531_private *vsc8531;
2265        u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
2266           VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
2267           VSC8531_DUPLEX_COLLISION};
2268
2269        if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) {
2270                dev_err(&phydev->mdio.dev, "Only VSC8584 revB is supported.\n");
2271                return -ENOTSUPP;
2272        }
2273
2274        vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2275        if (!vsc8531)
2276                return -ENOMEM;
2277
2278        phydev->priv = vsc8531;
2279
2280        vsc8531->nleds = 4;
2281        vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES;
2282        vsc8531->hw_stats = vsc8584_hw_stats;
2283        vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats);
2284        vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
2285                                      sizeof(u64), GFP_KERNEL);
2286        if (!vsc8531->stats)
2287                return -ENOMEM;
2288
2289        return vsc85xx_dt_led_modes_get(phydev, default_mode);
2290}
2291
2292static int vsc85xx_probe(struct phy_device *phydev)
2293{
2294        struct vsc8531_private *vsc8531;
2295        int rate_magic;
2296        u32 default_mode[2] = {VSC8531_LINK_1000_ACTIVITY,
2297           VSC8531_LINK_100_ACTIVITY};
2298
2299        rate_magic = vsc85xx_edge_rate_magic_get(phydev);
2300        if (rate_magic < 0)
2301                return rate_magic;
2302
2303        vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2304        if (!vsc8531)
2305                return -ENOMEM;
2306
2307        phydev->priv = vsc8531;
2308
2309        vsc8531->rate_magic = rate_magic;
2310        vsc8531->nleds = 2;
2311        vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES;
2312        vsc8531->hw_stats = vsc85xx_hw_stats;
2313        vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats);
2314        vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
2315                                      sizeof(u64), GFP_KERNEL);
2316        if (!vsc8531->stats)
2317                return -ENOMEM;
2318
2319        return vsc85xx_dt_led_modes_get(phydev, default_mode);
2320}
2321
2322/* Microsemi VSC85xx PHYs */
2323static struct phy_driver vsc85xx_driver[] = {
2324{
2325        .phy_id         = PHY_ID_VSC8514,
2326        .name           = "Microsemi GE VSC8514 SyncE",
2327        .phy_id_mask    = 0xfffffff0,
2328        .soft_reset     = &genphy_soft_reset,
2329        .config_init    = &vsc8514_config_init,
2330        .config_aneg    = &vsc85xx_config_aneg,
2331        .read_status    = &vsc85xx_read_status,
2332        .ack_interrupt  = &vsc85xx_ack_interrupt,
2333        .config_intr    = &vsc85xx_config_intr,
2334        .suspend        = &genphy_suspend,
2335        .resume         = &genphy_resume,
2336        .probe          = &vsc8514_probe,
2337        .set_wol        = &vsc85xx_wol_set,
2338        .get_wol        = &vsc85xx_wol_get,
2339        .get_tunable    = &vsc85xx_get_tunable,
2340        .set_tunable    = &vsc85xx_set_tunable,
2341        .read_page      = &vsc85xx_phy_read_page,
2342        .write_page     = &vsc85xx_phy_write_page,
2343        .get_sset_count = &vsc85xx_get_sset_count,
2344        .get_strings    = &vsc85xx_get_strings,
2345        .get_stats      = &vsc85xx_get_stats,
2346},
2347{
2348        .phy_id         = PHY_ID_VSC8530,
2349        .name           = "Microsemi FE VSC8530",
2350        .phy_id_mask    = 0xfffffff0,
2351        /* PHY_BASIC_FEATURES */
2352        .soft_reset     = &genphy_soft_reset,
2353        .config_init    = &vsc85xx_config_init,
2354        .config_aneg    = &vsc85xx_config_aneg,
2355        .aneg_done      = &genphy_aneg_done,
2356        .read_status    = &vsc85xx_read_status,
2357        .ack_interrupt  = &vsc85xx_ack_interrupt,
2358        .config_intr    = &vsc85xx_config_intr,
2359        .suspend        = &genphy_suspend,
2360        .resume         = &genphy_resume,
2361        .probe          = &vsc85xx_probe,
2362        .set_wol        = &vsc85xx_wol_set,
2363        .get_wol        = &vsc85xx_wol_get,
2364        .get_tunable    = &vsc85xx_get_tunable,
2365        .set_tunable    = &vsc85xx_set_tunable,
2366        .read_page      = &vsc85xx_phy_read_page,
2367        .write_page     = &vsc85xx_phy_write_page,
2368        .get_sset_count = &vsc85xx_get_sset_count,
2369        .get_strings    = &vsc85xx_get_strings,
2370        .get_stats      = &vsc85xx_get_stats,
2371},
2372{
2373        .phy_id         = PHY_ID_VSC8531,
2374        .name           = "Microsemi VSC8531",
2375        .phy_id_mask    = 0xfffffff0,
2376        /* PHY_GBIT_FEATURES */
2377        .soft_reset     = &genphy_soft_reset,
2378        .config_init    = &vsc85xx_config_init,
2379        .config_aneg    = &vsc85xx_config_aneg,
2380        .aneg_done      = &genphy_aneg_done,
2381        .read_status    = &vsc85xx_read_status,
2382        .ack_interrupt  = &vsc85xx_ack_interrupt,
2383        .config_intr    = &vsc85xx_config_intr,
2384        .suspend        = &genphy_suspend,
2385        .resume         = &genphy_resume,
2386        .probe          = &vsc85xx_probe,
2387        .set_wol        = &vsc85xx_wol_set,
2388        .get_wol        = &vsc85xx_wol_get,
2389        .get_tunable    = &vsc85xx_get_tunable,
2390        .set_tunable    = &vsc85xx_set_tunable,
2391        .read_page      = &vsc85xx_phy_read_page,
2392        .write_page     = &vsc85xx_phy_write_page,
2393        .get_sset_count = &vsc85xx_get_sset_count,
2394        .get_strings    = &vsc85xx_get_strings,
2395        .get_stats      = &vsc85xx_get_stats,
2396},
2397{
2398        .phy_id         = PHY_ID_VSC8540,
2399        .name           = "Microsemi FE VSC8540 SyncE",
2400        .phy_id_mask    = 0xfffffff0,
2401        /* PHY_BASIC_FEATURES */
2402        .soft_reset     = &genphy_soft_reset,
2403        .config_init    = &vsc85xx_config_init,
2404        .config_aneg    = &vsc85xx_config_aneg,
2405        .aneg_done      = &genphy_aneg_done,
2406        .read_status    = &vsc85xx_read_status,
2407        .ack_interrupt  = &vsc85xx_ack_interrupt,
2408        .config_intr    = &vsc85xx_config_intr,
2409        .suspend        = &genphy_suspend,
2410        .resume         = &genphy_resume,
2411        .probe          = &vsc85xx_probe,
2412        .set_wol        = &vsc85xx_wol_set,
2413        .get_wol        = &vsc85xx_wol_get,
2414        .get_tunable    = &vsc85xx_get_tunable,
2415        .set_tunable    = &vsc85xx_set_tunable,
2416        .read_page      = &vsc85xx_phy_read_page,
2417        .write_page     = &vsc85xx_phy_write_page,
2418        .get_sset_count = &vsc85xx_get_sset_count,
2419        .get_strings    = &vsc85xx_get_strings,
2420        .get_stats      = &vsc85xx_get_stats,
2421},
2422{
2423        .phy_id         = PHY_ID_VSC8541,
2424        .name           = "Microsemi VSC8541 SyncE",
2425        .phy_id_mask    = 0xfffffff0,
2426        /* PHY_GBIT_FEATURES */
2427        .soft_reset     = &genphy_soft_reset,
2428        .config_init    = &vsc85xx_config_init,
2429        .config_aneg    = &vsc85xx_config_aneg,
2430        .aneg_done      = &genphy_aneg_done,
2431        .read_status    = &vsc85xx_read_status,
2432        .ack_interrupt  = &vsc85xx_ack_interrupt,
2433        .config_intr    = &vsc85xx_config_intr,
2434        .suspend        = &genphy_suspend,
2435        .resume         = &genphy_resume,
2436        .probe          = &vsc85xx_probe,
2437        .set_wol        = &vsc85xx_wol_set,
2438        .get_wol        = &vsc85xx_wol_get,
2439        .get_tunable    = &vsc85xx_get_tunable,
2440        .set_tunable    = &vsc85xx_set_tunable,
2441        .read_page      = &vsc85xx_phy_read_page,
2442        .write_page     = &vsc85xx_phy_write_page,
2443        .get_sset_count = &vsc85xx_get_sset_count,
2444        .get_strings    = &vsc85xx_get_strings,
2445        .get_stats      = &vsc85xx_get_stats,
2446},
2447{
2448        .phy_id         = PHY_ID_VSC8574,
2449        .name           = "Microsemi GE VSC8574 SyncE",
2450        .phy_id_mask    = 0xfffffff0,
2451        /* PHY_GBIT_FEATURES */
2452        .soft_reset     = &genphy_soft_reset,
2453        .config_init    = &vsc8584_config_init,
2454        .config_aneg    = &vsc85xx_config_aneg,
2455        .aneg_done      = &genphy_aneg_done,
2456        .read_status    = &vsc85xx_read_status,
2457        .ack_interrupt  = &vsc85xx_ack_interrupt,
2458        .config_intr    = &vsc85xx_config_intr,
2459        .did_interrupt  = &vsc8584_did_interrupt,
2460        .suspend        = &genphy_suspend,
2461        .resume         = &genphy_resume,
2462        .probe          = &vsc8574_probe,
2463        .set_wol        = &vsc85xx_wol_set,
2464        .get_wol        = &vsc85xx_wol_get,
2465        .get_tunable    = &vsc85xx_get_tunable,
2466        .set_tunable    = &vsc85xx_set_tunable,
2467        .read_page      = &vsc85xx_phy_read_page,
2468        .write_page     = &vsc85xx_phy_write_page,
2469        .get_sset_count = &vsc85xx_get_sset_count,
2470        .get_strings    = &vsc85xx_get_strings,
2471        .get_stats      = &vsc85xx_get_stats,
2472},
2473{
2474        .phy_id         = PHY_ID_VSC8584,
2475        .name           = "Microsemi GE VSC8584 SyncE",
2476        .phy_id_mask    = 0xfffffff0,
2477        /* PHY_GBIT_FEATURES */
2478        .soft_reset     = &genphy_soft_reset,
2479        .config_init    = &vsc8584_config_init,
2480        .config_aneg    = &vsc85xx_config_aneg,
2481        .aneg_done      = &genphy_aneg_done,
2482        .read_status    = &vsc85xx_read_status,
2483        .ack_interrupt  = &vsc85xx_ack_interrupt,
2484        .config_intr    = &vsc85xx_config_intr,
2485        .did_interrupt  = &vsc8584_did_interrupt,
2486        .suspend        = &genphy_suspend,
2487        .resume         = &genphy_resume,
2488        .probe          = &vsc8584_probe,
2489        .get_tunable    = &vsc85xx_get_tunable,
2490        .set_tunable    = &vsc85xx_set_tunable,
2491        .read_page      = &vsc85xx_phy_read_page,
2492        .write_page     = &vsc85xx_phy_write_page,
2493        .get_sset_count = &vsc85xx_get_sset_count,
2494        .get_strings    = &vsc85xx_get_strings,
2495        .get_stats      = &vsc85xx_get_stats,
2496}
2497
2498};
2499
2500module_phy_driver(vsc85xx_driver);
2501
2502static struct mdio_device_id __maybe_unused vsc85xx_tbl[] = {
2503        { PHY_ID_VSC8514, 0xfffffff0, },
2504        { PHY_ID_VSC8530, 0xfffffff0, },
2505        { PHY_ID_VSC8531, 0xfffffff0, },
2506        { PHY_ID_VSC8540, 0xfffffff0, },
2507        { PHY_ID_VSC8541, 0xfffffff0, },
2508        { PHY_ID_VSC8574, 0xfffffff0, },
2509        { PHY_ID_VSC8584, 0xfffffff0, },
2510        { }
2511};
2512
2513MODULE_DEVICE_TABLE(mdio, vsc85xx_tbl);
2514
2515MODULE_DESCRIPTION("Microsemi VSC85xx PHY driver");
2516MODULE_AUTHOR("Nagaraju Lakkaraju");
2517MODULE_LICENSE("Dual MIT/GPL");
2518