net: phy: move the mscc driver to its own directory
authorAntoine Tenart <antoine.tenart@bootlin.com>
Fri, 13 Mar 2020 09:48:00 +0000 (10:48 +0100)
committerDavid S. Miller <davem@davemloft.net>
Sun, 15 Mar 2020 04:06:45 +0000 (21:06 -0700)
The MSCC PHY driver is growing, with lots of space consuming features
(firmware support, full initialization, MACsec...). It's becoming hard
to read and navigate in its source code. This patch moves the MSCC
driver to its own directory, without modifying anything, as a
preparation for splitting up its features into dedicated files.

Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/phy/Makefile
drivers/net/phy/mscc.c [deleted file]
drivers/net/phy/mscc/Makefile [new file with mode: 0644]
drivers/net/phy/mscc/mscc.c [new file with mode: 0644]
drivers/net/phy/mscc/mscc_fc_buffer.h [new file with mode: 0644]
drivers/net/phy/mscc/mscc_mac.h [new file with mode: 0644]
drivers/net/phy/mscc/mscc_macsec.h [new file with mode: 0644]
drivers/net/phy/mscc_fc_buffer.h [deleted file]
drivers/net/phy/mscc_mac.h [deleted file]
drivers/net/phy/mscc_macsec.h [deleted file]

index 26f8039f300fafce8a461b1f186a250433fcce76..70774ab474e6e41c5f76de61b65e5feae1ec515c 100644 (file)
@@ -89,7 +89,7 @@ obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o
 obj-$(CONFIG_MICREL_PHY)       += micrel.o
 obj-$(CONFIG_MICROCHIP_PHY)    += microchip.o
 obj-$(CONFIG_MICROCHIP_T1_PHY) += microchip_t1.o
-obj-$(CONFIG_MICROSEMI_PHY)    += mscc.o
+obj-$(CONFIG_MICROSEMI_PHY)    += mscc/
 obj-$(CONFIG_NATIONAL_PHY)     += national.o
 obj-$(CONFIG_NXP_TJA11XX_PHY)  += nxp-tja11xx.o
 obj-$(CONFIG_QSEMI_PHY)                += qsemi.o
diff --git a/drivers/net/phy/mscc.c b/drivers/net/phy/mscc.c
deleted file mode 100644 (file)
index b2eac7e..0000000
+++ /dev/null
@@ -1,3830 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Driver for Microsemi VSC85xx PHYs
- *
- * Author: Nagaraju Lakkaraju
- * License: Dual MIT/GPL
- * Copyright (c) 2016 Microsemi Corporation
- */
-
-#include <linux/firmware.h>
-#include <linux/jiffies.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/mdio.h>
-#include <linux/mii.h>
-#include <linux/phy.h>
-#include <linux/of.h>
-#include <linux/netdevice.h>
-#include <dt-bindings/net/mscc-phy-vsc8531.h>
-
-#include <linux/scatterlist.h>
-#include <crypto/skcipher.h>
-
-#if IS_ENABLED(CONFIG_MACSEC)
-#include <net/macsec.h>
-#endif
-
-#include "mscc_macsec.h"
-#include "mscc_mac.h"
-#include "mscc_fc_buffer.h"
-
-enum rgmii_rx_clock_delay {
-       RGMII_RX_CLK_DELAY_0_2_NS = 0,
-       RGMII_RX_CLK_DELAY_0_8_NS = 1,
-       RGMII_RX_CLK_DELAY_1_1_NS = 2,
-       RGMII_RX_CLK_DELAY_1_7_NS = 3,
-       RGMII_RX_CLK_DELAY_2_0_NS = 4,
-       RGMII_RX_CLK_DELAY_2_3_NS = 5,
-       RGMII_RX_CLK_DELAY_2_6_NS = 6,
-       RGMII_RX_CLK_DELAY_3_4_NS = 7
-};
-
-/* Microsemi VSC85xx PHY registers */
-/* IEEE 802. Std Registers */
-#define MSCC_PHY_BYPASS_CONTROL                  18
-#define DISABLE_HP_AUTO_MDIX_MASK        0x0080
-#define DISABLE_PAIR_SWAP_CORR_MASK      0x0020
-#define DISABLE_POLARITY_CORR_MASK       0x0010
-#define PARALLEL_DET_IGNORE_ADVERTISED    0x0008
-
-#define MSCC_PHY_EXT_CNTL_STATUS          22
-#define SMI_BROADCAST_WR_EN              0x0001
-
-#define MSCC_PHY_ERR_RX_CNT              19
-#define MSCC_PHY_ERR_FALSE_CARRIER_CNT   20
-#define MSCC_PHY_ERR_LINK_DISCONNECT_CNT  21
-#define ERR_CNT_MASK                     GENMASK(7, 0)
-
-#define MSCC_PHY_EXT_PHY_CNTL_1           23
-#define MAC_IF_SELECTION_MASK             0x1800
-#define MAC_IF_SELECTION_GMII             0
-#define MAC_IF_SELECTION_RMII             1
-#define MAC_IF_SELECTION_RGMII            2
-#define MAC_IF_SELECTION_POS              11
-#define VSC8584_MAC_IF_SELECTION_MASK     0x1000
-#define VSC8584_MAC_IF_SELECTION_SGMII    0
-#define VSC8584_MAC_IF_SELECTION_1000BASEX 1
-#define VSC8584_MAC_IF_SELECTION_POS      12
-#define FAR_END_LOOPBACK_MODE_MASK        0x0008
-#define MEDIA_OP_MODE_MASK               0x0700
-#define MEDIA_OP_MODE_COPPER             0
-#define MEDIA_OP_MODE_SERDES             1
-#define MEDIA_OP_MODE_1000BASEX                  2
-#define MEDIA_OP_MODE_100BASEFX                  3
-#define MEDIA_OP_MODE_AMS_COPPER_SERDES          5
-#define MEDIA_OP_MODE_AMS_COPPER_1000BASEX     6
-#define MEDIA_OP_MODE_AMS_COPPER_100BASEFX     7
-#define MEDIA_OP_MODE_POS                8
-
-#define MSCC_PHY_EXT_PHY_CNTL_2                  24
-
-#define MII_VSC85XX_INT_MASK             25
-#define MII_VSC85XX_INT_MASK_MDINT       BIT(15)
-#define MII_VSC85XX_INT_MASK_LINK_CHG    BIT(13)
-#define MII_VSC85XX_INT_MASK_WOL         BIT(6)
-#define MII_VSC85XX_INT_MASK_EXT         BIT(5)
-#define MII_VSC85XX_INT_STATUS           26
-
-#define MII_VSC85XX_INT_MASK_MASK        (MII_VSC85XX_INT_MASK_MDINT    | \
-                                          MII_VSC85XX_INT_MASK_LINK_CHG | \
-                                          MII_VSC85XX_INT_MASK_EXT)
-
-#define MSCC_PHY_WOL_MAC_CONTROL          27
-#define EDGE_RATE_CNTL_POS                5
-#define EDGE_RATE_CNTL_MASK               0x00E0
-
-#define MSCC_PHY_DEV_AUX_CNTL            28
-#define HP_AUTO_MDIX_X_OVER_IND_MASK     0x2000
-
-#define MSCC_PHY_LED_MODE_SEL            29
-#define LED_MODE_SEL_POS(x)              ((x) * 4)
-#define LED_MODE_SEL_MASK(x)             (GENMASK(3, 0) << LED_MODE_SEL_POS(x))
-#define LED_MODE_SEL(x, mode)            (((mode) << LED_MODE_SEL_POS(x)) & LED_MODE_SEL_MASK(x))
-
-#define MSCC_EXT_PAGE_CSR_CNTL_17        17
-#define MSCC_EXT_PAGE_CSR_CNTL_18        18
-
-#define MSCC_EXT_PAGE_CSR_CNTL_19        19
-#define MSCC_PHY_CSR_CNTL_19_REG_ADDR(x)  (x)
-#define MSCC_PHY_CSR_CNTL_19_TARGET(x)   ((x) << 12)
-#define MSCC_PHY_CSR_CNTL_19_READ        BIT(14)
-#define MSCC_PHY_CSR_CNTL_19_CMD         BIT(15)
-
-#define MSCC_EXT_PAGE_CSR_CNTL_20        20
-#define MSCC_PHY_CSR_CNTL_20_TARGET(x)   (x)
-
-#define PHY_MCB_TARGET                   0x07
-#define PHY_MCB_S6G_WRITE                BIT(31)
-#define PHY_MCB_S6G_READ                 BIT(30)
-
-#define PHY_S6G_PLL5G_CFG0               0x06
-#define PHY_S6G_LCPLL_CFG                0x11
-#define PHY_S6G_PLL_CFG                          0x2b
-#define PHY_S6G_COMMON_CFG               0x2c
-#define PHY_S6G_GPC_CFG                          0x2e
-#define PHY_S6G_MISC_CFG                 0x3b
-#define PHY_MCB_S6G_CFG                          0x3f
-#define PHY_S6G_DFT_CFG2                 0x3e
-#define PHY_S6G_PLL_STATUS               0x31
-#define PHY_S6G_IB_STATUS0               0x2f
-
-#define PHY_S6G_SYS_RST_POS              31
-#define PHY_S6G_ENA_LANE_POS             18
-#define PHY_S6G_ENA_LOOP_POS             8
-#define PHY_S6G_QRATE_POS                6
-#define PHY_S6G_IF_MODE_POS              4
-#define PHY_S6G_PLL_ENA_OFFS_POS         21
-#define PHY_S6G_PLL_FSM_CTRL_DATA_POS    8
-#define PHY_S6G_PLL_FSM_ENA_POS                  7
-
-#define MSCC_EXT_PAGE_MACSEC_17                  17
-#define MSCC_EXT_PAGE_MACSEC_18                  18
-
-#define MSCC_EXT_PAGE_MACSEC_19                  19
-#define MSCC_PHY_MACSEC_19_REG_ADDR(x)   (x)
-#define MSCC_PHY_MACSEC_19_TARGET(x)     ((x) << 12)
-#define MSCC_PHY_MACSEC_19_READ                  BIT(14)
-#define MSCC_PHY_MACSEC_19_CMD           BIT(15)
-
-#define MSCC_EXT_PAGE_MACSEC_20                  20
-#define MSCC_PHY_MACSEC_20_TARGET(x)     (x)
-enum macsec_bank {
-       FC_BUFFER   = 0x04,
-       HOST_MAC    = 0x05,
-       LINE_MAC    = 0x06,
-       IP_1588     = 0x0e,
-       MACSEC_INGR = 0x38,
-       MACSEC_EGR  = 0x3c,
-};
-
-#define MSCC_EXT_PAGE_ACCESS             31
-#define MSCC_PHY_PAGE_STANDARD           0x0000 /* Standard registers */
-#define MSCC_PHY_PAGE_EXTENDED           0x0001 /* Extended registers */
-#define MSCC_PHY_PAGE_EXTENDED_2         0x0002 /* Extended reg - page 2 */
-#define MSCC_PHY_PAGE_EXTENDED_3         0x0003 /* Extended reg - page 3 */
-#define MSCC_PHY_PAGE_EXTENDED_4         0x0004 /* Extended reg - page 4 */
-#define MSCC_PHY_PAGE_CSR_CNTL           MSCC_PHY_PAGE_EXTENDED_4
-#define MSCC_PHY_PAGE_MACSEC             MSCC_PHY_PAGE_EXTENDED_4
-/* Extended reg - GPIO; this is a bank of registers that are shared for all PHYs
- * in the same package.
- */
-#define MSCC_PHY_PAGE_EXTENDED_GPIO      0x0010 /* Extended reg - GPIO */
-#define MSCC_PHY_PAGE_TEST               0x2a30 /* Test reg */
-#define MSCC_PHY_PAGE_TR                 0x52b5 /* Token ring registers */
-
-/* Extended Page 1 Registers */
-#define MSCC_PHY_CU_MEDIA_CRC_VALID_CNT          18
-#define VALID_CRC_CNT_CRC_MASK           GENMASK(13, 0)
-
-#define MSCC_PHY_EXT_MODE_CNTL           19
-#define FORCE_MDI_CROSSOVER_MASK         0x000C
-#define FORCE_MDI_CROSSOVER_MDIX         0x000C
-#define FORCE_MDI_CROSSOVER_MDI                  0x0008
-
-#define MSCC_PHY_ACTIPHY_CNTL            20
-#define PHY_ADDR_REVERSED                0x0200
-#define DOWNSHIFT_CNTL_MASK              0x001C
-#define DOWNSHIFT_EN                     0x0010
-#define DOWNSHIFT_CNTL_POS               2
-
-#define MSCC_PHY_EXT_PHY_CNTL_4                  23
-#define PHY_CNTL_4_ADDR_POS              11
-
-#define MSCC_PHY_VERIPHY_CNTL_2                  25
-
-#define MSCC_PHY_VERIPHY_CNTL_3                  26
-
-/* Extended Page 2 Registers */
-#define MSCC_PHY_CU_PMD_TX_CNTL                  16
-
-#define MSCC_PHY_RGMII_CNTL              20
-#define RGMII_RX_CLK_DELAY_MASK                  0x0070
-#define RGMII_RX_CLK_DELAY_POS           4
-
-#define MSCC_PHY_WOL_LOWER_MAC_ADDR      21
-#define MSCC_PHY_WOL_MID_MAC_ADDR        22
-#define MSCC_PHY_WOL_UPPER_MAC_ADDR      23
-#define MSCC_PHY_WOL_LOWER_PASSWD        24
-#define MSCC_PHY_WOL_MID_PASSWD                  25
-#define MSCC_PHY_WOL_UPPER_PASSWD        26
-
-#define MSCC_PHY_WOL_MAC_CONTROL         27
-#define SECURE_ON_ENABLE                 0x8000
-#define SECURE_ON_PASSWD_LEN_4           0x4000
-
-#define MSCC_PHY_EXTENDED_INT            28
-#define MSCC_PHY_EXTENDED_INT_MS_EGR     BIT(9)
-
-/* Extended Page 3 Registers */
-#define MSCC_PHY_SERDES_TX_VALID_CNT     21
-#define MSCC_PHY_SERDES_TX_CRC_ERR_CNT   22
-#define MSCC_PHY_SERDES_RX_VALID_CNT     28
-#define MSCC_PHY_SERDES_RX_CRC_ERR_CNT   29
-
-/* Extended page GPIO Registers */
-#define MSCC_DW8051_CNTL_STATUS                  0
-#define MICRO_NSOFT_RESET                0x8000
-#define RUN_FROM_INT_ROM                 0x4000
-#define AUTOINC_ADDR                     0x2000
-#define PATCH_RAM_CLK                    0x1000
-#define MICRO_PATCH_EN                   0x0080
-#define DW8051_CLK_EN                    0x0010
-#define MICRO_CLK_EN                     0x0008
-#define MICRO_CLK_DIVIDE(x)              ((x) >> 1)
-#define MSCC_DW8051_VLD_MASK             0xf1ff
-
-/* x Address in range 1-4 */
-#define MSCC_TRAP_ROM_ADDR(x)            ((x) * 2 + 1)
-#define MSCC_PATCH_RAM_ADDR(x)           (((x) + 1) * 2)
-#define MSCC_INT_MEM_ADDR                11
-
-#define MSCC_INT_MEM_CNTL                12
-#define READ_SFR                         0x6000
-#define READ_PRAM                        0x4000
-#define READ_ROM                         0x2000
-#define READ_RAM                         0x0000
-#define INT_MEM_WRITE_EN                 0x1000
-#define EN_PATCH_RAM_TRAP_ADDR(x)        (0x0100 << ((x) - 1))
-#define INT_MEM_DATA_M                   0x00ff
-#define INT_MEM_DATA(x)                          (INT_MEM_DATA_M & (x))
-
-#define MSCC_PHY_PROC_CMD                18
-#define PROC_CMD_NCOMPLETED              0x8000
-#define PROC_CMD_FAILED                          0x4000
-#define PROC_CMD_SGMII_PORT(x)           ((x) << 8)
-#define PROC_CMD_FIBER_PORT(x)           (0x0100 << (x) % 4)
-#define PROC_CMD_QSGMII_PORT             0x0c00
-#define PROC_CMD_RST_CONF_PORT           0x0080
-#define PROC_CMD_RECONF_PORT             0x0000
-#define PROC_CMD_READ_MOD_WRITE_PORT     0x0040
-#define PROC_CMD_WRITE                   0x0040
-#define PROC_CMD_READ                    0x0000
-#define PROC_CMD_FIBER_DISABLE           0x0020
-#define PROC_CMD_FIBER_100BASE_FX        0x0010
-#define PROC_CMD_FIBER_1000BASE_X        0x0000
-#define PROC_CMD_SGMII_MAC               0x0030
-#define PROC_CMD_QSGMII_MAC              0x0020
-#define PROC_CMD_NO_MAC_CONF             0x0000
-#define PROC_CMD_1588_DEFAULT_INIT       0x0010
-#define PROC_CMD_NOP                     0x000f
-#define PROC_CMD_PHY_INIT                0x000a
-#define PROC_CMD_CRC16                   0x0008
-#define PROC_CMD_FIBER_MEDIA_CONF        0x0001
-#define PROC_CMD_MCB_ACCESS_MAC_CONF     0x0000
-#define PROC_CMD_NCOMPLETED_TIMEOUT_MS    500
-
-#define MSCC_PHY_MAC_CFG_FASTLINK        19
-#define MAC_CFG_MASK                     0xc000
-#define MAC_CFG_SGMII                    0x0000
-#define MAC_CFG_QSGMII                   0x4000
-
-/* Test page Registers */
-#define MSCC_PHY_TEST_PAGE_5             5
-#define MSCC_PHY_TEST_PAGE_8             8
-#define MSCC_PHY_TEST_PAGE_9             9
-#define MSCC_PHY_TEST_PAGE_20            20
-#define MSCC_PHY_TEST_PAGE_24            24
-
-/* Token ring page Registers */
-#define MSCC_PHY_TR_CNTL                 16
-#define TR_WRITE                         0x8000
-#define TR_ADDR(x)                       (0x7fff & (x))
-#define MSCC_PHY_TR_LSB                          17
-#define MSCC_PHY_TR_MSB                          18
-
-/* Microsemi PHY ID's
- *   Code assumes lowest nibble is 0
- */
-#define PHY_ID_VSC8504                   0x000704c0
-#define PHY_ID_VSC8514                   0x00070670
-#define PHY_ID_VSC8530                   0x00070560
-#define PHY_ID_VSC8531                   0x00070570
-#define PHY_ID_VSC8540                   0x00070760
-#define PHY_ID_VSC8541                   0x00070770
-#define PHY_ID_VSC8552                   0x000704e0
-#define PHY_ID_VSC856X                   0x000707e0
-#define PHY_ID_VSC8572                   0x000704d0
-#define PHY_ID_VSC8574                   0x000704a0
-#define PHY_ID_VSC8575                   0x000707d0
-#define PHY_ID_VSC8582                   0x000707b0
-#define PHY_ID_VSC8584                   0x000707c0
-
-#define MSCC_VDDMAC_1500                 1500
-#define MSCC_VDDMAC_1800                 1800
-#define MSCC_VDDMAC_2500                 2500
-#define MSCC_VDDMAC_3300                 3300
-
-#define DOWNSHIFT_COUNT_MAX              5
-
-#define MAX_LEDS                         4
-
-#define VSC8584_SUPP_LED_MODES (BIT(VSC8531_LINK_ACTIVITY) | \
-                               BIT(VSC8531_LINK_1000_ACTIVITY) | \
-                               BIT(VSC8531_LINK_100_ACTIVITY) | \
-                               BIT(VSC8531_LINK_10_ACTIVITY) | \
-                               BIT(VSC8531_LINK_100_1000_ACTIVITY) | \
-                               BIT(VSC8531_LINK_10_1000_ACTIVITY) | \
-                               BIT(VSC8531_LINK_10_100_ACTIVITY) | \
-                               BIT(VSC8584_LINK_100FX_1000X_ACTIVITY) | \
-                               BIT(VSC8531_DUPLEX_COLLISION) | \
-                               BIT(VSC8531_COLLISION) | \
-                               BIT(VSC8531_ACTIVITY) | \
-                               BIT(VSC8584_100FX_1000X_ACTIVITY) | \
-                               BIT(VSC8531_AUTONEG_FAULT) | \
-                               BIT(VSC8531_SERIAL_MODE) | \
-                               BIT(VSC8531_FORCE_LED_OFF) | \
-                               BIT(VSC8531_FORCE_LED_ON))
-
-#define VSC85XX_SUPP_LED_MODES (BIT(VSC8531_LINK_ACTIVITY) | \
-                               BIT(VSC8531_LINK_1000_ACTIVITY) | \
-                               BIT(VSC8531_LINK_100_ACTIVITY) | \
-                               BIT(VSC8531_LINK_10_ACTIVITY) | \
-                               BIT(VSC8531_LINK_100_1000_ACTIVITY) | \
-                               BIT(VSC8531_LINK_10_1000_ACTIVITY) | \
-                               BIT(VSC8531_LINK_10_100_ACTIVITY) | \
-                               BIT(VSC8531_DUPLEX_COLLISION) | \
-                               BIT(VSC8531_COLLISION) | \
-                               BIT(VSC8531_ACTIVITY) | \
-                               BIT(VSC8531_AUTONEG_FAULT) | \
-                               BIT(VSC8531_SERIAL_MODE) | \
-                               BIT(VSC8531_FORCE_LED_OFF) | \
-                               BIT(VSC8531_FORCE_LED_ON))
-
-#define MSCC_VSC8584_REVB_INT8051_FW           "microchip/mscc_vsc8584_revb_int8051_fb48.bin"
-#define MSCC_VSC8584_REVB_INT8051_FW_START_ADDR        0xe800
-#define MSCC_VSC8584_REVB_INT8051_FW_CRC       0xfb48
-
-#define MSCC_VSC8574_REVB_INT8051_FW           "microchip/mscc_vsc8574_revb_int8051_29e8.bin"
-#define MSCC_VSC8574_REVB_INT8051_FW_START_ADDR        0x4000
-#define MSCC_VSC8574_REVB_INT8051_FW_CRC       0x29e8
-
-#define VSC8584_REVB                           0x0001
-#define MSCC_DEV_REV_MASK                      GENMASK(3, 0)
-
-struct reg_val {
-       u16     reg;
-       u32     val;
-};
-
-struct vsc85xx_hw_stat {
-       const char *string;
-       u8 reg;
-       u16 page;
-       u16 mask;
-};
-
-static const struct vsc85xx_hw_stat vsc85xx_hw_stats[] = {
-       {
-               .string = "phy_receive_errors",
-               .reg    = MSCC_PHY_ERR_RX_CNT,
-               .page   = MSCC_PHY_PAGE_STANDARD,
-               .mask   = ERR_CNT_MASK,
-       }, {
-               .string = "phy_false_carrier",
-               .reg    = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
-               .page   = MSCC_PHY_PAGE_STANDARD,
-               .mask   = ERR_CNT_MASK,
-       }, {
-               .string = "phy_cu_media_link_disconnect",
-               .reg    = MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
-               .page   = MSCC_PHY_PAGE_STANDARD,
-               .mask   = ERR_CNT_MASK,
-       }, {
-               .string = "phy_cu_media_crc_good_count",
-               .reg    = MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
-               .page   = MSCC_PHY_PAGE_EXTENDED,
-               .mask   = VALID_CRC_CNT_CRC_MASK,
-       }, {
-               .string = "phy_cu_media_crc_error_count",
-               .reg    = MSCC_PHY_EXT_PHY_CNTL_4,
-               .page   = MSCC_PHY_PAGE_EXTENDED,
-               .mask   = ERR_CNT_MASK,
-       },
-};
-
-static const struct vsc85xx_hw_stat vsc8584_hw_stats[] = {
-       {
-               .string = "phy_receive_errors",
-               .reg    = MSCC_PHY_ERR_RX_CNT,
-               .page   = MSCC_PHY_PAGE_STANDARD,
-               .mask   = ERR_CNT_MASK,
-       }, {
-               .string = "phy_false_carrier",
-               .reg    = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
-               .page   = MSCC_PHY_PAGE_STANDARD,
-               .mask   = ERR_CNT_MASK,
-       }, {
-               .string = "phy_cu_media_link_disconnect",
-               .reg    = MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
-               .page   = MSCC_PHY_PAGE_STANDARD,
-               .mask   = ERR_CNT_MASK,
-       }, {
-               .string = "phy_cu_media_crc_good_count",
-               .reg    = MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
-               .page   = MSCC_PHY_PAGE_EXTENDED,
-               .mask   = VALID_CRC_CNT_CRC_MASK,
-       }, {
-               .string = "phy_cu_media_crc_error_count",
-               .reg    = MSCC_PHY_EXT_PHY_CNTL_4,
-               .page   = MSCC_PHY_PAGE_EXTENDED,
-               .mask   = ERR_CNT_MASK,
-       }, {
-               .string = "phy_serdes_tx_good_pkt_count",
-               .reg    = MSCC_PHY_SERDES_TX_VALID_CNT,
-               .page   = MSCC_PHY_PAGE_EXTENDED_3,
-               .mask   = VALID_CRC_CNT_CRC_MASK,
-       }, {
-               .string = "phy_serdes_tx_bad_crc_count",
-               .reg    = MSCC_PHY_SERDES_TX_CRC_ERR_CNT,
-               .page   = MSCC_PHY_PAGE_EXTENDED_3,
-               .mask   = ERR_CNT_MASK,
-       }, {
-               .string = "phy_serdes_rx_good_pkt_count",
-               .reg    = MSCC_PHY_SERDES_RX_VALID_CNT,
-               .page   = MSCC_PHY_PAGE_EXTENDED_3,
-               .mask   = VALID_CRC_CNT_CRC_MASK,
-       }, {
-               .string = "phy_serdes_rx_bad_crc_count",
-               .reg    = MSCC_PHY_SERDES_RX_CRC_ERR_CNT,
-               .page   = MSCC_PHY_PAGE_EXTENDED_3,
-               .mask   = ERR_CNT_MASK,
-       },
-};
-
-#if IS_ENABLED(CONFIG_MACSEC)
-struct macsec_flow {
-       struct list_head list;
-       enum mscc_macsec_destination_ports port;
-       enum macsec_bank bank;
-       u32 index;
-       int assoc_num;
-       bool has_transformation;
-
-       /* Highest takes precedence [0..15] */
-       u8 priority;
-
-       u8 key[MACSEC_KEYID_LEN];
-
-       union {
-               struct macsec_rx_sa *rx_sa;
-               struct macsec_tx_sa *tx_sa;
-       };
-
-       /* Matching */
-       struct {
-               u8 sci:1;
-               u8 tagged:1;
-               u8 untagged:1;
-               u8 etype:1;
-       } match;
-
-       u16 etype;
-
-       /* Action */
-       struct {
-               u8 bypass:1;
-               u8 drop:1;
-       } action;
-
-};
-#endif
-
-struct vsc8531_private {
-       int rate_magic;
-       u16 supp_led_modes;
-       u32 leds_mode[MAX_LEDS];
-       u8 nleds;
-       const struct vsc85xx_hw_stat *hw_stats;
-       u64 *stats;
-       int nstats;
-       bool pkg_init;
-       /* For multiple port PHYs; the MDIO address of the base PHY in the
-        * package.
-        */
-       unsigned int base_addr;
-
-#if IS_ENABLED(CONFIG_MACSEC)
-       /* MACsec fields:
-        * - One SecY per device (enforced at the s/w implementation level)
-        * - macsec_flows: list of h/w flows
-        * - ingr_flows: bitmap of ingress flows
-        * - egr_flows: bitmap of egress flows
-        */
-       struct macsec_secy *secy;
-       struct list_head macsec_flows;
-       unsigned long ingr_flows;
-       unsigned long egr_flows;
-#endif
-};
-
-#ifdef CONFIG_OF_MDIO
-struct vsc8531_edge_rate_table {
-       u32 vddmac;
-       u32 slowdown[8];
-};
-
-static const struct vsc8531_edge_rate_table edge_table[] = {
-       {MSCC_VDDMAC_3300, { 0, 2,  4,  7, 10, 17, 29, 53} },
-       {MSCC_VDDMAC_2500, { 0, 3,  6, 10, 14, 23, 37, 63} },
-       {MSCC_VDDMAC_1800, { 0, 5,  9, 16, 23, 35, 52, 76} },
-       {MSCC_VDDMAC_1500, { 0, 6, 14, 21, 29, 42, 58, 77} },
-};
-#endif /* CONFIG_OF_MDIO */
-
-static int vsc85xx_phy_read_page(struct phy_device *phydev)
-{
-       return __phy_read(phydev, MSCC_EXT_PAGE_ACCESS);
-}
-
-static int vsc85xx_phy_write_page(struct phy_device *phydev, int page)
-{
-       return __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, page);
-}
-
-static int vsc85xx_get_sset_count(struct phy_device *phydev)
-{
-       struct vsc8531_private *priv = phydev->priv;
-
-       if (!priv)
-               return 0;
-
-       return priv->nstats;
-}
-
-static void vsc85xx_get_strings(struct phy_device *phydev, u8 *data)
-{
-       struct vsc8531_private *priv = phydev->priv;
-       int i;
-
-       if (!priv)
-               return;
-
-       for (i = 0; i < priv->nstats; i++)
-               strlcpy(data + i * ETH_GSTRING_LEN, priv->hw_stats[i].string,
-                       ETH_GSTRING_LEN);
-}
-
-static u64 vsc85xx_get_stat(struct phy_device *phydev, int i)
-{
-       struct vsc8531_private *priv = phydev->priv;
-       int val;
-
-       val = phy_read_paged(phydev, priv->hw_stats[i].page,
-                            priv->hw_stats[i].reg);
-       if (val < 0)
-               return U64_MAX;
-
-       val = val & priv->hw_stats[i].mask;
-       priv->stats[i] += val;
-
-       return priv->stats[i];
-}
-
-static void vsc85xx_get_stats(struct phy_device *phydev,
-                             struct ethtool_stats *stats, u64 *data)
-{
-       struct vsc8531_private *priv = phydev->priv;
-       int i;
-
-       if (!priv)
-               return;
-
-       for (i = 0; i < priv->nstats; i++)
-               data[i] = vsc85xx_get_stat(phydev, i);
-}
-
-static int vsc85xx_led_cntl_set(struct phy_device *phydev,
-                               u8 led_num,
-                               u8 mode)
-{
-       int rc;
-       u16 reg_val;
-
-       mutex_lock(&phydev->lock);
-       reg_val = phy_read(phydev, MSCC_PHY_LED_MODE_SEL);
-       reg_val &= ~LED_MODE_SEL_MASK(led_num);
-       reg_val |= LED_MODE_SEL(led_num, (u16)mode);
-       rc = phy_write(phydev, MSCC_PHY_LED_MODE_SEL, reg_val);
-       mutex_unlock(&phydev->lock);
-
-       return rc;
-}
-
-static int vsc85xx_mdix_get(struct phy_device *phydev, u8 *mdix)
-{
-       u16 reg_val;
-
-       reg_val = phy_read(phydev, MSCC_PHY_DEV_AUX_CNTL);
-       if (reg_val & HP_AUTO_MDIX_X_OVER_IND_MASK)
-               *mdix = ETH_TP_MDI_X;
-       else
-               *mdix = ETH_TP_MDI;
-
-       return 0;
-}
-
-static int vsc85xx_mdix_set(struct phy_device *phydev, u8 mdix)
-{
-       int rc;
-       u16 reg_val;
-
-       reg_val = phy_read(phydev, MSCC_PHY_BYPASS_CONTROL);
-       if (mdix == ETH_TP_MDI || mdix == ETH_TP_MDI_X) {
-               reg_val |= (DISABLE_PAIR_SWAP_CORR_MASK |
-                           DISABLE_POLARITY_CORR_MASK  |
-                           DISABLE_HP_AUTO_MDIX_MASK);
-       } else {
-               reg_val &= ~(DISABLE_PAIR_SWAP_CORR_MASK |
-                            DISABLE_POLARITY_CORR_MASK  |
-                            DISABLE_HP_AUTO_MDIX_MASK);
-       }
-       rc = phy_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg_val);
-       if (rc)
-               return rc;
-
-       reg_val = 0;
-
-       if (mdix == ETH_TP_MDI)
-               reg_val = FORCE_MDI_CROSSOVER_MDI;
-       else if (mdix == ETH_TP_MDI_X)
-               reg_val = FORCE_MDI_CROSSOVER_MDIX;
-
-       rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
-                             MSCC_PHY_EXT_MODE_CNTL, FORCE_MDI_CROSSOVER_MASK,
-                             reg_val);
-       if (rc < 0)
-               return rc;
-
-       return genphy_restart_aneg(phydev);
-}
-
-static int vsc85xx_downshift_get(struct phy_device *phydev, u8 *count)
-{
-       int reg_val;
-
-       reg_val = phy_read_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
-                                MSCC_PHY_ACTIPHY_CNTL);
-       if (reg_val < 0)
-               return reg_val;
-
-       reg_val &= DOWNSHIFT_CNTL_MASK;
-       if (!(reg_val & DOWNSHIFT_EN))
-               *count = DOWNSHIFT_DEV_DISABLE;
-       else
-               *count = ((reg_val & ~DOWNSHIFT_EN) >> DOWNSHIFT_CNTL_POS) + 2;
-
-       return 0;
-}
-
-static int vsc85xx_downshift_set(struct phy_device *phydev, u8 count)
-{
-       if (count == DOWNSHIFT_DEV_DEFAULT_COUNT) {
-               /* Default downshift count 3 (i.e. Bit3:2 = 0b01) */
-               count = ((1 << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
-       } else if (count > DOWNSHIFT_COUNT_MAX || count == 1) {
-               phydev_err(phydev, "Downshift count should be 2,3,4 or 5\n");
-               return -ERANGE;
-       } else if (count) {
-               /* Downshift count is either 2,3,4 or 5 */
-               count = (((count - 2) << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
-       }
-
-       return phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
-                               MSCC_PHY_ACTIPHY_CNTL, DOWNSHIFT_CNTL_MASK,
-                               count);
-}
-
-static int vsc85xx_wol_set(struct phy_device *phydev,
-                          struct ethtool_wolinfo *wol)
-{
-       int rc;
-       u16 reg_val;
-       u8  i;
-       u16 pwd[3] = {0, 0, 0};
-       struct ethtool_wolinfo *wol_conf = wol;
-       u8 *mac_addr = phydev->attached_dev->dev_addr;
-
-       mutex_lock(&phydev->lock);
-       rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
-       if (rc < 0) {
-               rc = phy_restore_page(phydev, rc, rc);
-               goto out_unlock;
-       }
-
-       if (wol->wolopts & WAKE_MAGIC) {
-               /* Store the device address for the magic packet */
-               for (i = 0; i < ARRAY_SIZE(pwd); i++)
-                       pwd[i] = mac_addr[5 - (i * 2 + 1)] << 8 |
-                                mac_addr[5 - i * 2];
-               __phy_write(phydev, MSCC_PHY_WOL_LOWER_MAC_ADDR, pwd[0]);
-               __phy_write(phydev, MSCC_PHY_WOL_MID_MAC_ADDR, pwd[1]);
-               __phy_write(phydev, MSCC_PHY_WOL_UPPER_MAC_ADDR, pwd[2]);
-       } else {
-               __phy_write(phydev, MSCC_PHY_WOL_LOWER_MAC_ADDR, 0);
-               __phy_write(phydev, MSCC_PHY_WOL_MID_MAC_ADDR, 0);
-               __phy_write(phydev, MSCC_PHY_WOL_UPPER_MAC_ADDR, 0);
-       }
-
-       if (wol_conf->wolopts & WAKE_MAGICSECURE) {
-               for (i = 0; i < ARRAY_SIZE(pwd); i++)
-                       pwd[i] = wol_conf->sopass[5 - (i * 2 + 1)] << 8 |
-                                wol_conf->sopass[5 - i * 2];
-               __phy_write(phydev, MSCC_PHY_WOL_LOWER_PASSWD, pwd[0]);
-               __phy_write(phydev, MSCC_PHY_WOL_MID_PASSWD, pwd[1]);
-               __phy_write(phydev, MSCC_PHY_WOL_UPPER_PASSWD, pwd[2]);
-       } else {
-               __phy_write(phydev, MSCC_PHY_WOL_LOWER_PASSWD, 0);
-               __phy_write(phydev, MSCC_PHY_WOL_MID_PASSWD, 0);
-               __phy_write(phydev, MSCC_PHY_WOL_UPPER_PASSWD, 0);
-       }
-
-       reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
-       if (wol_conf->wolopts & WAKE_MAGICSECURE)
-               reg_val |= SECURE_ON_ENABLE;
-       else
-               reg_val &= ~SECURE_ON_ENABLE;
-       __phy_write(phydev, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
-
-       rc = phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
-       if (rc < 0)
-               goto out_unlock;
-
-       if (wol->wolopts & WAKE_MAGIC) {
-               /* Enable the WOL interrupt */
-               reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
-               reg_val |= MII_VSC85XX_INT_MASK_WOL;
-               rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
-               if (rc)
-                       goto out_unlock;
-       } else {
-               /* Disable the WOL interrupt */
-               reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
-               reg_val &= (~MII_VSC85XX_INT_MASK_WOL);
-               rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
-               if (rc)
-                       goto out_unlock;
-       }
-       /* Clear WOL iterrupt status */
-       reg_val = phy_read(phydev, MII_VSC85XX_INT_STATUS);
-
-out_unlock:
-       mutex_unlock(&phydev->lock);
-
-       return rc;
-}
-
-static void vsc85xx_wol_get(struct phy_device *phydev,
-                           struct ethtool_wolinfo *wol)
-{
-       int rc;
-       u16 reg_val;
-       u8  i;
-       u16 pwd[3] = {0, 0, 0};
-       struct ethtool_wolinfo *wol_conf = wol;
-
-       mutex_lock(&phydev->lock);
-       rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
-       if (rc < 0)
-               goto out_unlock;
-
-       reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
-       if (reg_val & SECURE_ON_ENABLE)
-               wol_conf->wolopts |= WAKE_MAGICSECURE;
-       if (wol_conf->wolopts & WAKE_MAGICSECURE) {
-               pwd[0] = __phy_read(phydev, MSCC_PHY_WOL_LOWER_PASSWD);
-               pwd[1] = __phy_read(phydev, MSCC_PHY_WOL_MID_PASSWD);
-               pwd[2] = __phy_read(phydev, MSCC_PHY_WOL_UPPER_PASSWD);
-               for (i = 0; i < ARRAY_SIZE(pwd); i++) {
-                       wol_conf->sopass[5 - i * 2] = pwd[i] & 0x00ff;
-                       wol_conf->sopass[5 - (i * 2 + 1)] = (pwd[i] & 0xff00)
-                                                           >> 8;
-               }
-       }
-
-out_unlock:
-       phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
-       mutex_unlock(&phydev->lock);
-}
-
-#ifdef CONFIG_OF_MDIO
-static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
-{
-       u32 vdd, sd;
-       int i, j;
-       struct device *dev = &phydev->mdio.dev;
-       struct device_node *of_node = dev->of_node;
-       u8 sd_array_size = ARRAY_SIZE(edge_table[0].slowdown);
-
-       if (!of_node)
-               return -ENODEV;
-
-       if (of_property_read_u32(of_node, "vsc8531,vddmac", &vdd))
-               vdd = MSCC_VDDMAC_3300;
-
-       if (of_property_read_u32(of_node, "vsc8531,edge-slowdown", &sd))
-               sd = 0;
-
-       for (i = 0; i < ARRAY_SIZE(edge_table); i++)
-               if (edge_table[i].vddmac == vdd)
-                       for (j = 0; j < sd_array_size; j++)
-                               if (edge_table[i].slowdown[j] == sd)
-                                       return (sd_array_size - j - 1);
-
-       return -EINVAL;
-}
-
-static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
-                                  char *led,
-                                  u32 default_mode)
-{
-       struct vsc8531_private *priv = phydev->priv;
-       struct device *dev = &phydev->mdio.dev;
-       struct device_node *of_node = dev->of_node;
-       u32 led_mode;
-       int err;
-
-       if (!of_node)
-               return -ENODEV;
-
-       led_mode = default_mode;
-       err = of_property_read_u32(of_node, led, &led_mode);
-       if (!err && !(BIT(led_mode) & priv->supp_led_modes)) {
-               phydev_err(phydev, "DT %s invalid\n", led);
-               return -EINVAL;
-       }
-
-       return led_mode;
-}
-
-#else
-static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
-{
-       return 0;
-}
-
-static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
-                                  char *led,
-                                  u8 default_mode)
-{
-       return default_mode;
-}
-#endif /* CONFIG_OF_MDIO */
-
-static int vsc85xx_dt_led_modes_get(struct phy_device *phydev,
-                                   u32 *default_mode)
-{
-       struct vsc8531_private *priv = phydev->priv;
-       char led_dt_prop[28];
-       int i, ret;
-
-       for (i = 0; i < priv->nleds; i++) {
-               ret = sprintf(led_dt_prop, "vsc8531,led-%d-mode", i);
-               if (ret < 0)
-                       return ret;
-
-               ret = vsc85xx_dt_led_mode_get(phydev, led_dt_prop,
-                                             default_mode[i]);
-               if (ret < 0)
-                       return ret;
-               priv->leds_mode[i] = ret;
-       }
-
-       return 0;
-}
-
-static int vsc85xx_edge_rate_cntl_set(struct phy_device *phydev, u8 edge_rate)
-{
-       int rc;
-
-       mutex_lock(&phydev->lock);
-       rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
-                             MSCC_PHY_WOL_MAC_CONTROL, EDGE_RATE_CNTL_MASK,
-                             edge_rate << EDGE_RATE_CNTL_POS);
-       mutex_unlock(&phydev->lock);
-
-       return rc;
-}
-
-static int vsc85xx_mac_if_set(struct phy_device *phydev,
-                             phy_interface_t interface)
-{
-       int rc;
-       u16 reg_val;
-
-       mutex_lock(&phydev->lock);
-       reg_val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
-       reg_val &= ~(MAC_IF_SELECTION_MASK);
-       switch (interface) {
-       case PHY_INTERFACE_MODE_RGMII:
-               reg_val |= (MAC_IF_SELECTION_RGMII << MAC_IF_SELECTION_POS);
-               break;
-       case PHY_INTERFACE_MODE_RMII:
-               reg_val |= (MAC_IF_SELECTION_RMII << MAC_IF_SELECTION_POS);
-               break;
-       case PHY_INTERFACE_MODE_MII:
-       case PHY_INTERFACE_MODE_GMII:
-               reg_val |= (MAC_IF_SELECTION_GMII << MAC_IF_SELECTION_POS);
-               break;
-       default:
-               rc = -EINVAL;
-               goto out_unlock;
-       }
-       rc = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, reg_val);
-       if (rc)
-               goto out_unlock;
-
-       rc = genphy_soft_reset(phydev);
-
-out_unlock:
-       mutex_unlock(&phydev->lock);
-
-       return rc;
-}
-
-static int vsc85xx_default_config(struct phy_device *phydev)
-{
-       int rc;
-       u16 reg_val;
-
-       phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
-       mutex_lock(&phydev->lock);
-
-       reg_val = RGMII_RX_CLK_DELAY_1_1_NS << RGMII_RX_CLK_DELAY_POS;
-
-       rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
-                             MSCC_PHY_RGMII_CNTL, RGMII_RX_CLK_DELAY_MASK,
-                             reg_val);
-
-       mutex_unlock(&phydev->lock);
-
-       return rc;
-}
-
-static int vsc85xx_get_tunable(struct phy_device *phydev,
-                              struct ethtool_tunable *tuna, void *data)
-{
-       switch (tuna->id) {
-       case ETHTOOL_PHY_DOWNSHIFT:
-               return vsc85xx_downshift_get(phydev, (u8 *)data);
-       default:
-               return -EINVAL;
-       }
-}
-
-static int vsc85xx_set_tunable(struct phy_device *phydev,
-                              struct ethtool_tunable *tuna,
-                              const void *data)
-{
-       switch (tuna->id) {
-       case ETHTOOL_PHY_DOWNSHIFT:
-               return vsc85xx_downshift_set(phydev, *(u8 *)data);
-       default:
-               return -EINVAL;
-       }
-}
-
-/* mdiobus lock should be locked when using this function */
-static void vsc85xx_tr_write(struct phy_device *phydev, u16 addr, u32 val)
-{
-       __phy_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
-       __phy_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
-       __phy_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
-}
-
-static int vsc8531_pre_init_seq_set(struct phy_device *phydev)
-{
-       int rc;
-       static const struct reg_val init_seq[] = {
-               {0x0f90, 0x00688980},
-               {0x0696, 0x00000003},
-               {0x07fa, 0x0050100f},
-               {0x1686, 0x00000004},
-       };
-       unsigned int i;
-       int oldpage;
-
-       rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_STANDARD,
-                             MSCC_PHY_EXT_CNTL_STATUS, SMI_BROADCAST_WR_EN,
-                             SMI_BROADCAST_WR_EN);
-       if (rc < 0)
-               return rc;
-       rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
-                             MSCC_PHY_TEST_PAGE_24, 0, 0x0400);
-       if (rc < 0)
-               return rc;
-       rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
-                             MSCC_PHY_TEST_PAGE_5, 0x0a00, 0x0e00);
-       if (rc < 0)
-               return rc;
-       rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
-                             MSCC_PHY_TEST_PAGE_8, 0x8000, 0x8000);
-       if (rc < 0)
-               return rc;
-
-       mutex_lock(&phydev->lock);
-       oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
-       if (oldpage < 0)
-               goto out_unlock;
-
-       for (i = 0; i < ARRAY_SIZE(init_seq); i++)
-               vsc85xx_tr_write(phydev, init_seq[i].reg, init_seq[i].val);
-
-out_unlock:
-       oldpage = phy_restore_page(phydev, oldpage, oldpage);
-       mutex_unlock(&phydev->lock);
-
-       return oldpage;
-}
-
-static int vsc85xx_eee_init_seq_set(struct phy_device *phydev)
-{
-       static const struct reg_val init_eee[] = {
-               {0x0f82, 0x0012b00a},
-               {0x1686, 0x00000004},
-               {0x168c, 0x00d2c46f},
-               {0x17a2, 0x00000620},
-               {0x16a0, 0x00eeffdd},
-               {0x16a6, 0x00071448},
-               {0x16a4, 0x0013132f},
-               {0x16a8, 0x00000000},
-               {0x0ffc, 0x00c0a028},
-               {0x0fe8, 0x0091b06c},
-               {0x0fea, 0x00041600},
-               {0x0f80, 0x00000af4},
-               {0x0fec, 0x00901809},
-               {0x0fee, 0x0000a6a1},
-               {0x0ffe, 0x00b01007},
-               {0x16b0, 0x00eeff00},
-               {0x16b2, 0x00007000},
-               {0x16b4, 0x00000814},
-       };
-       unsigned int i;
-       int oldpage;
-
-       mutex_lock(&phydev->lock);
-       oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
-       if (oldpage < 0)
-               goto out_unlock;
-
-       for (i = 0; i < ARRAY_SIZE(init_eee); i++)
-               vsc85xx_tr_write(phydev, init_eee[i].reg, init_eee[i].val);
-
-out_unlock:
-       oldpage = phy_restore_page(phydev, oldpage, oldpage);
-       mutex_unlock(&phydev->lock);
-
-       return oldpage;
-}
-
-/* phydev->bus->mdio_lock should be locked when using this function */
-static int phy_base_write(struct phy_device *phydev, u32 regnum, u16 val)
-{
-       struct vsc8531_private *priv = phydev->priv;
-
-       if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
-               dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
-               dump_stack();
-       }
-
-       return __mdiobus_write(phydev->mdio.bus, priv->base_addr, regnum, val);
-}
-
-/* phydev->bus->mdio_lock should be locked when using this function */
-static int phy_base_read(struct phy_device *phydev, u32 regnum)
-{
-       struct vsc8531_private *priv = phydev->priv;
-
-       if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
-               dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
-               dump_stack();
-       }
-
-       return __mdiobus_read(phydev->mdio.bus, priv->base_addr, regnum);
-}
-
-/* bus->mdio_lock should be locked when using this function */
-static void vsc8584_csr_write(struct phy_device *phydev, u16 addr, u32 val)
-{
-       phy_base_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
-       phy_base_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
-       phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
-}
-
-/* bus->mdio_lock should be locked when using this function */
-static int vsc8584_cmd(struct phy_device *phydev, u16 val)
-{
-       unsigned long deadline;
-       u16 reg_val;
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
-                      MSCC_PHY_PAGE_EXTENDED_GPIO);
-
-       phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NCOMPLETED | val);
-
-       deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
-       do {
-               reg_val = phy_base_read(phydev, MSCC_PHY_PROC_CMD);
-       } while (time_before(jiffies, deadline) &&
-                (reg_val & PROC_CMD_NCOMPLETED) &&
-                !(reg_val & PROC_CMD_FAILED));
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
-
-       if (reg_val & PROC_CMD_FAILED)
-               return -EIO;
-
-       if (reg_val & PROC_CMD_NCOMPLETED)
-               return -ETIMEDOUT;
-
-       return 0;
-}
-
-/* bus->mdio_lock should be locked when using this function */
-static int vsc8584_micro_deassert_reset(struct phy_device *phydev,
-                                       bool patch_en)
-{
-       u32 enable, release;
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
-                      MSCC_PHY_PAGE_EXTENDED_GPIO);
-
-       enable = RUN_FROM_INT_ROM | MICRO_CLK_EN | DW8051_CLK_EN;
-       release = MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
-               MICRO_CLK_EN;
-
-       if (patch_en) {
-               enable |= MICRO_PATCH_EN;
-               release |= MICRO_PATCH_EN;
-
-               /* Clear all patches */
-               phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
-       }
-
-       /* Enable 8051 Micro clock; CLEAR/SET patch present; disable PRAM clock
-        * override and addr. auto-incr; operate at 125 MHz
-        */
-       phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, enable);
-       /* Release 8051 Micro SW reset */
-       phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, release);
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
-
-       return 0;
-}
-
-/* bus->mdio_lock should be locked when using this function */
-static int vsc8584_micro_assert_reset(struct phy_device *phydev)
-{
-       int ret;
-       u16 reg;
-
-       ret = vsc8584_cmd(phydev, PROC_CMD_NOP);
-       if (ret)
-               return ret;
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
-                      MSCC_PHY_PAGE_EXTENDED_GPIO);
-
-       reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
-       reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
-       phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
-
-       phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(4), 0x005b);
-       phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(4), 0x005b);
-
-       reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
-       reg |= EN_PATCH_RAM_TRAP_ADDR(4);
-       phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
-
-       phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NOP);
-
-       reg = phy_base_read(phydev, MSCC_DW8051_CNTL_STATUS);
-       reg &= ~MICRO_NSOFT_RESET;
-       phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, reg);
-
-       phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_MCB_ACCESS_MAC_CONF |
-                      PROC_CMD_SGMII_PORT(0) | PROC_CMD_NO_MAC_CONF |
-                      PROC_CMD_READ);
-
-       reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
-       reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
-       phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
-
-       return 0;
-}
-
-/* bus->mdio_lock should be locked when using this function */
-static int vsc8584_get_fw_crc(struct phy_device *phydev, u16 start, u16 size,
-                             u16 *crc)
-{
-       int ret;
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
-
-       phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_2, start);
-       phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_3, size);
-
-       /* Start Micro command */
-       ret = vsc8584_cmd(phydev, PROC_CMD_CRC16);
-       if (ret)
-               goto out;
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
-
-       *crc = phy_base_read(phydev, MSCC_PHY_VERIPHY_CNTL_2);
-
-out:
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
-
-       return ret;
-}
-
-/* bus->mdio_lock should be locked when using this function */
-static int vsc8584_patch_fw(struct phy_device *phydev,
-                           const struct firmware *fw)
-{
-       int i, ret;
-
-       ret = vsc8584_micro_assert_reset(phydev);
-       if (ret) {
-               dev_err(&phydev->mdio.dev,
-                       "%s: failed to assert reset of micro\n", __func__);
-               return ret;
-       }
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
-                      MSCC_PHY_PAGE_EXTENDED_GPIO);
-
-       /* Hold 8051 Micro in SW Reset, Enable auto incr address and patch clock
-        * Disable the 8051 Micro clock
-        */
-       phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, RUN_FROM_INT_ROM |
-                      AUTOINC_ADDR | PATCH_RAM_CLK | MICRO_CLK_EN |
-                      MICRO_CLK_DIVIDE(2));
-       phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_PRAM | INT_MEM_WRITE_EN |
-                      INT_MEM_DATA(2));
-       phy_base_write(phydev, MSCC_INT_MEM_ADDR, 0x0000);
-
-       for (i = 0; i < fw->size; i++)
-               phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_PRAM |
-                              INT_MEM_WRITE_EN | fw->data[i]);
-
-       /* Clear internal memory access */
-       phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
-
-       return 0;
-}
-
-/* bus->mdio_lock should be locked when using this function */
-static bool vsc8574_is_serdes_init(struct phy_device *phydev)
-{
-       u16 reg;
-       bool ret;
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
-                      MSCC_PHY_PAGE_EXTENDED_GPIO);
-
-       reg = phy_base_read(phydev, MSCC_TRAP_ROM_ADDR(1));
-       if (reg != 0x3eb7) {
-               ret = false;
-               goto out;
-       }
-
-       reg = phy_base_read(phydev, MSCC_PATCH_RAM_ADDR(1));
-       if (reg != 0x4012) {
-               ret = false;
-               goto out;
-       }
-
-       reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
-       if (reg != EN_PATCH_RAM_TRAP_ADDR(1)) {
-               ret = false;
-               goto out;
-       }
-
-       reg = phy_base_read(phydev, MSCC_DW8051_CNTL_STATUS);
-       if ((MICRO_NSOFT_RESET | RUN_FROM_INT_ROM |  DW8051_CLK_EN |
-            MICRO_CLK_EN) != (reg & MSCC_DW8051_VLD_MASK)) {
-               ret = false;
-               goto out;
-       }
-
-       ret = true;
-out:
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
-
-       return ret;
-}
-
-/* bus->mdio_lock should be locked when using this function */
-static int vsc8574_config_pre_init(struct phy_device *phydev)
-{
-       static const struct reg_val pre_init1[] = {
-               {0x0fae, 0x000401bd},
-               {0x0fac, 0x000f000f},
-               {0x17a0, 0x00a0f147},
-               {0x0fe4, 0x00052f54},
-               {0x1792, 0x0027303d},
-               {0x07fe, 0x00000704},
-               {0x0fe0, 0x00060150},
-               {0x0f82, 0x0012b00a},
-               {0x0f80, 0x00000d74},
-               {0x02e0, 0x00000012},
-               {0x03a2, 0x00050208},
-               {0x03b2, 0x00009186},
-               {0x0fb0, 0x000e3700},
-               {0x1688, 0x00049f81},
-               {0x0fd2, 0x0000ffff},
-               {0x168a, 0x00039fa2},
-               {0x1690, 0x0020640b},
-               {0x0258, 0x00002220},
-               {0x025a, 0x00002a20},
-               {0x025c, 0x00003060},
-               {0x025e, 0x00003fa0},
-               {0x03a6, 0x0000e0f0},
-               {0x0f92, 0x00001489},
-               {0x16a2, 0x00007000},
-               {0x16a6, 0x00071448},
-               {0x16a0, 0x00eeffdd},
-               {0x0fe8, 0x0091b06c},
-               {0x0fea, 0x00041600},
-               {0x16b0, 0x00eeff00},
-               {0x16b2, 0x00007000},
-               {0x16b4, 0x00000814},
-               {0x0f90, 0x00688980},
-               {0x03a4, 0x0000d8f0},
-               {0x0fc0, 0x00000400},
-               {0x07fa, 0x0050100f},
-               {0x0796, 0x00000003},
-               {0x07f8, 0x00c3ff98},
-               {0x0fa4, 0x0018292a},
-               {0x168c, 0x00d2c46f},
-               {0x17a2, 0x00000620},
-               {0x16a4, 0x0013132f},
-               {0x16a8, 0x00000000},
-               {0x0ffc, 0x00c0a028},
-               {0x0fec, 0x00901c09},
-               {0x0fee, 0x0004a6a1},
-               {0x0ffe, 0x00b01807},
-       };
-       static const struct reg_val pre_init2[] = {
-               {0x0486, 0x0008a518},
-               {0x0488, 0x006dc696},
-               {0x048a, 0x00000912},
-               {0x048e, 0x00000db6},
-               {0x049c, 0x00596596},
-               {0x049e, 0x00000514},
-               {0x04a2, 0x00410280},
-               {0x04a4, 0x00000000},
-               {0x04a6, 0x00000000},
-               {0x04a8, 0x00000000},
-               {0x04aa, 0x00000000},
-               {0x04ae, 0x007df7dd},
-               {0x04b0, 0x006d95d4},
-               {0x04b2, 0x00492410},
-       };
-       struct device *dev = &phydev->mdio.dev;
-       const struct firmware *fw;
-       unsigned int i;
-       u16 crc, reg;
-       bool serdes_init;
-       int ret;
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
-
-       /* all writes below are broadcasted to all PHYs in the same package */
-       reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
-       reg |= SMI_BROADCAST_WR_EN;
-       phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
-
-       phy_base_write(phydev, MII_VSC85XX_INT_MASK, 0);
-
-       /* The below register writes are tweaking analog and electrical
-        * configuration that were determined through characterization by PHY
-        * engineers. These don't mean anything more than "these are the best
-        * values".
-        */
-       phy_base_write(phydev, MSCC_PHY_EXT_PHY_CNTL_2, 0x0040);
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
-
-       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_20, 0x4320);
-       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_24, 0x0c00);
-       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_9, 0x18ca);
-       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1b20);
-
-       reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
-       reg |= 0x8000;
-       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
-
-       for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
-               vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_2);
-
-       phy_base_write(phydev, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
-
-       for (i = 0; i < ARRAY_SIZE(pre_init2); i++)
-               vsc8584_csr_write(phydev, pre_init2[i].reg, pre_init2[i].val);
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
-
-       reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
-       reg &= ~0x8000;
-       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
-
-       /* end of write broadcasting */
-       reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
-       reg &= ~SMI_BROADCAST_WR_EN;
-       phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
-
-       ret = request_firmware(&fw, MSCC_VSC8574_REVB_INT8051_FW, dev);
-       if (ret) {
-               dev_err(dev, "failed to load firmware %s, ret: %d\n",
-                       MSCC_VSC8574_REVB_INT8051_FW, ret);
-               return ret;
-       }
-
-       /* Add one byte to size for the one added by the patch_fw function */
-       ret = vsc8584_get_fw_crc(phydev,
-                                MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
-                                fw->size + 1, &crc);
-       if (ret)
-               goto out;
-
-       if (crc == MSCC_VSC8574_REVB_INT8051_FW_CRC) {
-               serdes_init = vsc8574_is_serdes_init(phydev);
-
-               if (!serdes_init) {
-                       ret = vsc8584_micro_assert_reset(phydev);
-                       if (ret) {
-                               dev_err(dev,
-                                       "%s: failed to assert reset of micro\n",
-                                       __func__);
-                               goto out;
-                       }
-               }
-       } else {
-               dev_dbg(dev, "FW CRC is not the expected one, patching FW\n");
-
-               serdes_init = false;
-
-               if (vsc8584_patch_fw(phydev, fw))
-                       dev_warn(dev,
-                                "failed to patch FW, expect non-optimal device\n");
-       }
-
-       if (!serdes_init) {
-               phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
-                              MSCC_PHY_PAGE_EXTENDED_GPIO);
-
-               phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(1), 0x3eb7);
-               phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(1), 0x4012);
-               phy_base_write(phydev, MSCC_INT_MEM_CNTL,
-                              EN_PATCH_RAM_TRAP_ADDR(1));
-
-               vsc8584_micro_deassert_reset(phydev, false);
-
-               /* Add one byte to size for the one added by the patch_fw
-                * function
-                */
-               ret = vsc8584_get_fw_crc(phydev,
-                                        MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
-                                        fw->size + 1, &crc);
-               if (ret)
-                       goto out;
-
-               if (crc != MSCC_VSC8574_REVB_INT8051_FW_CRC)
-                       dev_warn(dev,
-                                "FW CRC after patching is not the expected one, expect non-optimal device\n");
-       }
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
-                      MSCC_PHY_PAGE_EXTENDED_GPIO);
-
-       ret = vsc8584_cmd(phydev, PROC_CMD_1588_DEFAULT_INIT |
-                         PROC_CMD_PHY_INIT);
-
-out:
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
-
-       release_firmware(fw);
-
-       return ret;
-}
-
-/* bus->mdio_lock should be locked when using this function */
-static int vsc8584_config_pre_init(struct phy_device *phydev)
-{
-       static const struct reg_val pre_init1[] = {
-               {0x07fa, 0x0050100f},
-               {0x1688, 0x00049f81},
-               {0x0f90, 0x00688980},
-               {0x03a4, 0x0000d8f0},
-               {0x0fc0, 0x00000400},
-               {0x0f82, 0x0012b002},
-               {0x1686, 0x00000004},
-               {0x168c, 0x00d2c46f},
-               {0x17a2, 0x00000620},
-               {0x16a0, 0x00eeffdd},
-               {0x16a6, 0x00071448},
-               {0x16a4, 0x0013132f},
-               {0x16a8, 0x00000000},
-               {0x0ffc, 0x00c0a028},
-               {0x0fe8, 0x0091b06c},
-               {0x0fea, 0x00041600},
-               {0x0f80, 0x00fffaff},
-               {0x0fec, 0x00901809},
-               {0x0ffe, 0x00b01007},
-               {0x16b0, 0x00eeff00},
-               {0x16b2, 0x00007000},
-               {0x16b4, 0x00000814},
-       };
-       static const struct reg_val pre_init2[] = {
-               {0x0486, 0x0008a518},
-               {0x0488, 0x006dc696},
-               {0x048a, 0x00000912},
-       };
-       const struct firmware *fw;
-       struct device *dev = &phydev->mdio.dev;
-       unsigned int i;
-       u16 crc, reg;
-       int ret;
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
-
-       /* all writes below are broadcasted to all PHYs in the same package */
-       reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
-       reg |= SMI_BROADCAST_WR_EN;
-       phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
-
-       phy_base_write(phydev, MII_VSC85XX_INT_MASK, 0);
-
-       reg = phy_base_read(phydev,  MSCC_PHY_BYPASS_CONTROL);
-       reg |= PARALLEL_DET_IGNORE_ADVERTISED;
-       phy_base_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg);
-
-       /* The below register writes are tweaking analog and electrical
-        * configuration that were determined through characterization by PHY
-        * engineers. These don't mean anything more than "these are the best
-        * values".
-        */
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_3);
-
-       phy_base_write(phydev, MSCC_PHY_SERDES_TX_CRC_ERR_CNT, 0x2000);
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
-
-       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1f20);
-
-       reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
-       reg |= 0x8000;
-       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
-
-       phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x2fa4));
-
-       reg = phy_base_read(phydev, MSCC_PHY_TR_MSB);
-       reg &= ~0x007f;
-       reg |= 0x0019;
-       phy_base_write(phydev, MSCC_PHY_TR_MSB, reg);
-
-       phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x0fa4));
-
-       for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
-               vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_2);
-
-       phy_base_write(phydev, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
-
-       for (i = 0; i < ARRAY_SIZE(pre_init2); i++)
-               vsc8584_csr_write(phydev, pre_init2[i].reg, pre_init2[i].val);
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
-
-       reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
-       reg &= ~0x8000;
-       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
-
-       /* end of write broadcasting */
-       reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
-       reg &= ~SMI_BROADCAST_WR_EN;
-       phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
-
-       ret = request_firmware(&fw, MSCC_VSC8584_REVB_INT8051_FW, dev);
-       if (ret) {
-               dev_err(dev, "failed to load firmware %s, ret: %d\n",
-                       MSCC_VSC8584_REVB_INT8051_FW, ret);
-               return ret;
-       }
-
-       /* Add one byte to size for the one added by the patch_fw function */
-       ret = vsc8584_get_fw_crc(phydev,
-                                MSCC_VSC8584_REVB_INT8051_FW_START_ADDR,
-                                fw->size + 1, &crc);
-       if (ret)
-               goto out;
-
-       if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC) {
-               dev_dbg(dev, "FW CRC is not the expected one, patching FW\n");
-               if (vsc8584_patch_fw(phydev, fw))
-                       dev_warn(dev,
-                                "failed to patch FW, expect non-optimal device\n");
-       }
-
-       vsc8584_micro_deassert_reset(phydev, false);
-
-       /* Add one byte to size for the one added by the patch_fw function */
-       ret = vsc8584_get_fw_crc(phydev,
-                                MSCC_VSC8584_REVB_INT8051_FW_START_ADDR,
-                                fw->size + 1, &crc);
-       if (ret)
-               goto out;
-
-       if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC)
-               dev_warn(dev,
-                        "FW CRC after patching is not the expected one, expect non-optimal device\n");
-
-       ret = vsc8584_micro_assert_reset(phydev);
-       if (ret)
-               goto out;
-
-       vsc8584_micro_deassert_reset(phydev, true);
-
-out:
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
-
-       release_firmware(fw);
-
-       return ret;
-}
-
-#if IS_ENABLED(CONFIG_MACSEC)
-static u32 vsc8584_macsec_phy_read(struct phy_device *phydev,
-                                  enum macsec_bank bank, u32 reg)
-{
-       u32 val, val_l = 0, val_h = 0;
-       unsigned long deadline;
-       int rc;
-
-       rc = phy_select_page(phydev, MSCC_PHY_PAGE_MACSEC);
-       if (rc < 0)
-               goto failed;
-
-       __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_20,
-                   MSCC_PHY_MACSEC_20_TARGET(bank >> 2));
-
-       if (bank >> 2 == 0x1)
-               /* non-MACsec access */
-               bank &= 0x3;
-       else
-               bank = 0;
-
-       __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_19,
-                   MSCC_PHY_MACSEC_19_CMD | MSCC_PHY_MACSEC_19_READ |
-                   MSCC_PHY_MACSEC_19_REG_ADDR(reg) |
-                   MSCC_PHY_MACSEC_19_TARGET(bank));
-
-       deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
-       do {
-               val = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_19);
-       } while (time_before(jiffies, deadline) && !(val & MSCC_PHY_MACSEC_19_CMD));
-
-       val_l = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_17);
-       val_h = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_18);
-
-failed:
-       phy_restore_page(phydev, rc, rc);
-
-       return (val_h << 16) | val_l;
-}
-
-static void vsc8584_macsec_phy_write(struct phy_device *phydev,
-                                    enum macsec_bank bank, u32 reg, u32 val)
-{
-       unsigned long deadline;
-       int rc;
-
-       rc = phy_select_page(phydev, MSCC_PHY_PAGE_MACSEC);
-       if (rc < 0)
-               goto failed;
-
-       __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_20,
-                   MSCC_PHY_MACSEC_20_TARGET(bank >> 2));
-
-       if ((bank >> 2 == 0x1) || (bank >> 2 == 0x3))
-               bank &= 0x3;
-       else
-               /* MACsec access */
-               bank = 0;
-
-       __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_17, (u16)val);
-       __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_18, (u16)(val >> 16));
-
-       __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_19,
-                   MSCC_PHY_MACSEC_19_CMD | MSCC_PHY_MACSEC_19_REG_ADDR(reg) |
-                   MSCC_PHY_MACSEC_19_TARGET(bank));
-
-       deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
-       do {
-               val = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_19);
-       } while (time_before(jiffies, deadline) && !(val & MSCC_PHY_MACSEC_19_CMD));
-
-failed:
-       phy_restore_page(phydev, rc, rc);
-}
-
-static void vsc8584_macsec_classification(struct phy_device *phydev,
-                                         enum macsec_bank bank)
-{
-       /* enable VLAN tag parsing */
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_CP_TAG,
-                                MSCC_MS_SAM_CP_TAG_PARSE_STAG |
-                                MSCC_MS_SAM_CP_TAG_PARSE_QTAG |
-                                MSCC_MS_SAM_CP_TAG_PARSE_QINQ);
-}
-
-static void vsc8584_macsec_flow_default_action(struct phy_device *phydev,
-                                              enum macsec_bank bank,
-                                              bool block)
-{
-       u32 port = (bank == MACSEC_INGR) ?
-                   MSCC_MS_PORT_UNCONTROLLED : MSCC_MS_PORT_COMMON;
-       u32 action = MSCC_MS_FLOW_BYPASS;
-
-       if (block)
-               action = MSCC_MS_FLOW_DROP;
-
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_NM_FLOW_NCP,
-                                /* MACsec untagged */
-                                MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_FLOW_TYPE(action) |
-                                MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_DROP_ACTION(MSCC_MS_ACTION_DROP) |
-                                MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_DEST_PORT(port) |
-                                /* MACsec tagged */
-                                MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_FLOW_TYPE(action) |
-                                MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_DROP_ACTION(MSCC_MS_ACTION_DROP) |
-                                MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_DEST_PORT(port) |
-                                /* Bad tag */
-                                MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_FLOW_TYPE(action) |
-                                MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_DROP_ACTION(MSCC_MS_ACTION_DROP) |
-                                MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_DEST_PORT(port) |
-                                /* Kay tag */
-                                MSCC_MS_SAM_NM_FLOW_NCP_KAY_FLOW_TYPE(action) |
-                                MSCC_MS_SAM_NM_FLOW_NCP_KAY_DROP_ACTION(MSCC_MS_ACTION_DROP) |
-                                MSCC_MS_SAM_NM_FLOW_NCP_KAY_DEST_PORT(port));
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_NM_FLOW_CP,
-                                /* MACsec untagged */
-                                MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_FLOW_TYPE(action) |
-                                MSCC_MS_SAM_NM_FLOW_CP_UNTAGGED_DROP_ACTION(MSCC_MS_ACTION_DROP) |
-                                MSCC_MS_SAM_NM_FLOW_CP_UNTAGGED_DEST_PORT(port) |
-                                /* MACsec tagged */
-                                MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_FLOW_TYPE(action) |
-                                MSCC_MS_SAM_NM_FLOW_CP_TAGGED_DROP_ACTION(MSCC_MS_ACTION_DROP) |
-                                MSCC_MS_SAM_NM_FLOW_CP_TAGGED_DEST_PORT(port) |
-                                /* Bad tag */
-                                MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_FLOW_TYPE(action) |
-                                MSCC_MS_SAM_NM_FLOW_CP_BADTAG_DROP_ACTION(MSCC_MS_ACTION_DROP) |
-                                MSCC_MS_SAM_NM_FLOW_CP_BADTAG_DEST_PORT(port) |
-                                /* Kay tag */
-                                MSCC_MS_SAM_NM_FLOW_NCP_KAY_FLOW_TYPE(action) |
-                                MSCC_MS_SAM_NM_FLOW_CP_KAY_DROP_ACTION(MSCC_MS_ACTION_DROP) |
-                                MSCC_MS_SAM_NM_FLOW_CP_KAY_DEST_PORT(port));
-}
-
-static void vsc8584_macsec_integrity_checks(struct phy_device *phydev,
-                                           enum macsec_bank bank)
-{
-       u32 val;
-
-       if (bank != MACSEC_INGR)
-               return;
-
-       /* Set default rules to pass unmatched frames */
-       val = vsc8584_macsec_phy_read(phydev, bank,
-                                     MSCC_MS_PARAMS2_IG_CC_CONTROL);
-       val |= MSCC_MS_PARAMS2_IG_CC_CONTROL_NON_MATCH_CTRL_ACT |
-              MSCC_MS_PARAMS2_IG_CC_CONTROL_NON_MATCH_ACT;
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_PARAMS2_IG_CC_CONTROL,
-                                val);
-
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_PARAMS2_IG_CP_TAG,
-                                MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_STAG |
-                                MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_QTAG |
-                                MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_QINQ);
-}
-
-static void vsc8584_macsec_block_init(struct phy_device *phydev,
-                                     enum macsec_bank bank)
-{
-       u32 val;
-       int i;
-
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_ENA_CFG,
-                                MSCC_MS_ENA_CFG_SW_RST |
-                                MSCC_MS_ENA_CFG_MACSEC_BYPASS_ENA);
-
-       /* Set the MACsec block out of s/w reset and enable clocks */
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_ENA_CFG,
-                                MSCC_MS_ENA_CFG_CLK_ENA);
-
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_STATUS_CONTEXT_CTRL,
-                                bank == MACSEC_INGR ? 0xe5880214 : 0xe5880218);
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_MISC_CONTROL,
-                                MSCC_MS_MISC_CONTROL_MC_LATENCY_FIX(bank == MACSEC_INGR ? 57 : 40) |
-                                MSCC_MS_MISC_CONTROL_XFORM_REC_SIZE(bank == MACSEC_INGR ? 1 : 2));
-
-       /* Clear the counters */
-       val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_COUNT_CONTROL);
-       val |= MSCC_MS_COUNT_CONTROL_AUTO_CNTR_RESET;
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_COUNT_CONTROL, val);
-
-       /* Enable octet increment mode */
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_PP_CTRL,
-                                MSCC_MS_PP_CTRL_MACSEC_OCTET_INCR_MODE);
-
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_BLOCK_CTX_UPDATE, 0x3);
-
-       val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_COUNT_CONTROL);
-       val |= MSCC_MS_COUNT_CONTROL_RESET_ALL;
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_COUNT_CONTROL, val);
-
-       /* Set the MTU */
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_NON_VLAN_MTU_CHECK,
-                                MSCC_MS_NON_VLAN_MTU_CHECK_NV_MTU_COMPARE(32761) |
-                                MSCC_MS_NON_VLAN_MTU_CHECK_NV_MTU_COMP_DROP);
-
-       for (i = 0; i < 8; i++)
-               vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_VLAN_MTU_CHECK(i),
-                                        MSCC_MS_VLAN_MTU_CHECK_MTU_COMPARE(32761) |
-                                        MSCC_MS_VLAN_MTU_CHECK_MTU_COMP_DROP);
-
-       if (bank == MACSEC_EGR) {
-               val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_INTR_CTRL_STATUS);
-               val &= ~MSCC_MS_INTR_CTRL_STATUS_INTR_ENABLE_M;
-               vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_INTR_CTRL_STATUS, val);
-
-               vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_FC_CFG,
-                                        MSCC_MS_FC_CFG_FCBUF_ENA |
-                                        MSCC_MS_FC_CFG_LOW_THRESH(0x1) |
-                                        MSCC_MS_FC_CFG_HIGH_THRESH(0x4) |
-                                        MSCC_MS_FC_CFG_LOW_BYTES_VAL(0x4) |
-                                        MSCC_MS_FC_CFG_HIGH_BYTES_VAL(0x6));
-       }
-
-       vsc8584_macsec_classification(phydev, bank);
-       vsc8584_macsec_flow_default_action(phydev, bank, false);
-       vsc8584_macsec_integrity_checks(phydev, bank);
-
-       /* Enable the MACsec block */
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_ENA_CFG,
-                                MSCC_MS_ENA_CFG_CLK_ENA |
-                                MSCC_MS_ENA_CFG_MACSEC_ENA |
-                                MSCC_MS_ENA_CFG_MACSEC_SPEED_MODE(0x5));
-}
-
-static void vsc8584_macsec_mac_init(struct phy_device *phydev,
-                                   enum macsec_bank bank)
-{
-       u32 val;
-       int i;
-
-       /* Clear host & line stats */
-       for (i = 0; i < 36; i++)
-               vsc8584_macsec_phy_write(phydev, bank, 0x1c + i, 0);
-
-       val = vsc8584_macsec_phy_read(phydev, bank,
-                                     MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL);
-       val &= ~MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_MODE_M;
-       val |= MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_MODE(2) |
-              MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_VALUE(0xffff);
-       vsc8584_macsec_phy_write(phydev, bank,
-                                MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL, val);
-
-       val = vsc8584_macsec_phy_read(phydev, bank,
-                                     MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_2);
-       val |= 0xffff;
-       vsc8584_macsec_phy_write(phydev, bank,
-                                MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_2, val);
-
-       val = vsc8584_macsec_phy_read(phydev, bank,
-                                     MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL);
-       if (bank == HOST_MAC)
-               val |= MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_TIMER_ENA |
-                      MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_FRAME_DROP_ENA;
-       else
-               val |= MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_REACT_ENA |
-                      MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_FRAME_DROP_ENA |
-                      MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_MODE |
-                      MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_EARLY_PAUSE_DETECT_ENA;
-       vsc8584_macsec_phy_write(phydev, bank,
-                                MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL, val);
-
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_PKTINF_CFG,
-                                MSCC_MAC_CFG_PKTINF_CFG_STRIP_FCS_ENA |
-                                MSCC_MAC_CFG_PKTINF_CFG_INSERT_FCS_ENA |
-                                MSCC_MAC_CFG_PKTINF_CFG_LPI_RELAY_ENA |
-                                MSCC_MAC_CFG_PKTINF_CFG_STRIP_PREAMBLE_ENA |
-                                MSCC_MAC_CFG_PKTINF_CFG_INSERT_PREAMBLE_ENA |
-                                (bank == HOST_MAC ?
-                                 MSCC_MAC_CFG_PKTINF_CFG_ENABLE_TX_PADDING : 0));
-
-       val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MAC_CFG_MODE_CFG);
-       val &= ~MSCC_MAC_CFG_MODE_CFG_DISABLE_DIC;
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_MODE_CFG, val);
-
-       val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MAC_CFG_MAXLEN_CFG);
-       val &= ~MSCC_MAC_CFG_MAXLEN_CFG_MAX_LEN_M;
-       val |= MSCC_MAC_CFG_MAXLEN_CFG_MAX_LEN(10240);
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_MAXLEN_CFG, val);
-
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_ADV_CHK_CFG,
-                                MSCC_MAC_CFG_ADV_CHK_CFG_SFD_CHK_ENA |
-                                MSCC_MAC_CFG_ADV_CHK_CFG_PRM_CHK_ENA |
-                                MSCC_MAC_CFG_ADV_CHK_CFG_OOR_ERR_ENA |
-                                MSCC_MAC_CFG_ADV_CHK_CFG_INR_ERR_ENA);
-
-       val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MAC_CFG_LFS_CFG);
-       val &= ~MSCC_MAC_CFG_LFS_CFG_LFS_MODE_ENA;
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_LFS_CFG, val);
-
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_ENA_CFG,
-                                MSCC_MAC_CFG_ENA_CFG_RX_CLK_ENA |
-                                MSCC_MAC_CFG_ENA_CFG_TX_CLK_ENA |
-                                MSCC_MAC_CFG_ENA_CFG_RX_ENA |
-                                MSCC_MAC_CFG_ENA_CFG_TX_ENA);
-}
-
-/* Must be called with mdio_lock taken */
-static int vsc8584_macsec_init(struct phy_device *phydev)
-{
-       u32 val;
-
-       vsc8584_macsec_block_init(phydev, MACSEC_INGR);
-       vsc8584_macsec_block_init(phydev, MACSEC_EGR);
-       vsc8584_macsec_mac_init(phydev, HOST_MAC);
-       vsc8584_macsec_mac_init(phydev, LINE_MAC);
-
-       vsc8584_macsec_phy_write(phydev, FC_BUFFER,
-                                MSCC_FCBUF_FC_READ_THRESH_CFG,
-                                MSCC_FCBUF_FC_READ_THRESH_CFG_TX_THRESH(4) |
-                                MSCC_FCBUF_FC_READ_THRESH_CFG_RX_THRESH(5));
-
-       val = vsc8584_macsec_phy_read(phydev, FC_BUFFER, MSCC_FCBUF_MODE_CFG);
-       val |= MSCC_FCBUF_MODE_CFG_PAUSE_GEN_ENA |
-              MSCC_FCBUF_MODE_CFG_RX_PPM_RATE_ADAPT_ENA |
-              MSCC_FCBUF_MODE_CFG_TX_PPM_RATE_ADAPT_ENA;
-       vsc8584_macsec_phy_write(phydev, FC_BUFFER, MSCC_FCBUF_MODE_CFG, val);
-
-       vsc8584_macsec_phy_write(phydev, FC_BUFFER, MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG,
-                                MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_THRESH(8) |
-                                MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_OFFSET(9));
-
-       val = vsc8584_macsec_phy_read(phydev, FC_BUFFER,
-                                     MSCC_FCBUF_TX_DATA_QUEUE_CFG);
-       val &= ~(MSCC_FCBUF_TX_DATA_QUEUE_CFG_START_M |
-                MSCC_FCBUF_TX_DATA_QUEUE_CFG_END_M);
-       val |= MSCC_FCBUF_TX_DATA_QUEUE_CFG_START(0) |
-               MSCC_FCBUF_TX_DATA_QUEUE_CFG_END(5119);
-       vsc8584_macsec_phy_write(phydev, FC_BUFFER,
-                                MSCC_FCBUF_TX_DATA_QUEUE_CFG, val);
-
-       val = vsc8584_macsec_phy_read(phydev, FC_BUFFER, MSCC_FCBUF_ENA_CFG);
-       val |= MSCC_FCBUF_ENA_CFG_TX_ENA | MSCC_FCBUF_ENA_CFG_RX_ENA;
-       vsc8584_macsec_phy_write(phydev, FC_BUFFER, MSCC_FCBUF_ENA_CFG, val);
-
-       val = vsc8584_macsec_phy_read(phydev, IP_1588,
-                                     MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL);
-       val &= ~MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE_M;
-       val |= MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE(4);
-       vsc8584_macsec_phy_write(phydev, IP_1588,
-                                MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL, val);
-
-       return 0;
-}
-
-static void vsc8584_macsec_flow(struct phy_device *phydev,
-                               struct macsec_flow *flow)
-{
-       struct vsc8531_private *priv = phydev->priv;
-       enum macsec_bank bank = flow->bank;
-       u32 val, match = 0, mask = 0, action = 0, idx = flow->index;
-
-       if (flow->match.tagged)
-               match |= MSCC_MS_SAM_MISC_MATCH_TAGGED;
-       if (flow->match.untagged)
-               match |= MSCC_MS_SAM_MISC_MATCH_UNTAGGED;
-
-       if (bank == MACSEC_INGR && flow->assoc_num >= 0) {
-               match |= MSCC_MS_SAM_MISC_MATCH_AN(flow->assoc_num);
-               mask |= MSCC_MS_SAM_MASK_AN_MASK(0x3);
-       }
-
-       if (bank == MACSEC_INGR && flow->match.sci && flow->rx_sa->sc->sci) {
-               match |= MSCC_MS_SAM_MISC_MATCH_TCI(BIT(3));
-               mask |= MSCC_MS_SAM_MASK_TCI_MASK(BIT(3)) |
-                       MSCC_MS_SAM_MASK_SCI_MASK;
-
-               vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_MATCH_SCI_LO(idx),
-                                        lower_32_bits(flow->rx_sa->sc->sci));
-               vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_MATCH_SCI_HI(idx),
-                                        upper_32_bits(flow->rx_sa->sc->sci));
-       }
-
-       if (flow->match.etype) {
-               mask |= MSCC_MS_SAM_MASK_MAC_ETYPE_MASK;
-
-               vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_MAC_SA_MATCH_HI(idx),
-                                        MSCC_MS_SAM_MAC_SA_MATCH_HI_ETYPE(htons(flow->etype)));
-       }
-
-       match |= MSCC_MS_SAM_MISC_MATCH_PRIORITY(flow->priority);
-
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_MISC_MATCH(idx), match);
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_MASK(idx), mask);
-
-       /* Action for matching packets */
-       if (flow->action.drop)
-               action = MSCC_MS_FLOW_DROP;
-       else if (flow->action.bypass || flow->port == MSCC_MS_PORT_UNCONTROLLED)
-               action = MSCC_MS_FLOW_BYPASS;
-       else
-               action = (bank == MACSEC_INGR) ?
-                        MSCC_MS_FLOW_INGRESS : MSCC_MS_FLOW_EGRESS;
-
-       val = MSCC_MS_SAM_FLOW_CTRL_FLOW_TYPE(action) |
-             MSCC_MS_SAM_FLOW_CTRL_DROP_ACTION(MSCC_MS_ACTION_DROP) |
-             MSCC_MS_SAM_FLOW_CTRL_DEST_PORT(flow->port);
-
-       if (action == MSCC_MS_FLOW_BYPASS)
-               goto write_ctrl;
-
-       if (bank == MACSEC_INGR) {
-               if (priv->secy->replay_protect)
-                       val |= MSCC_MS_SAM_FLOW_CTRL_REPLAY_PROTECT;
-               if (priv->secy->validate_frames == MACSEC_VALIDATE_STRICT)
-                       val |= MSCC_MS_SAM_FLOW_CTRL_VALIDATE_FRAMES(MSCC_MS_VALIDATE_STRICT);
-               else if (priv->secy->validate_frames == MACSEC_VALIDATE_CHECK)
-                       val |= MSCC_MS_SAM_FLOW_CTRL_VALIDATE_FRAMES(MSCC_MS_VALIDATE_CHECK);
-       } else if (bank == MACSEC_EGR) {
-               if (priv->secy->protect_frames)
-                       val |= MSCC_MS_SAM_FLOW_CTRL_PROTECT_FRAME;
-               if (priv->secy->tx_sc.encrypt)
-                       val |= MSCC_MS_SAM_FLOW_CTRL_CONF_PROTECT;
-               if (priv->secy->tx_sc.send_sci)
-                       val |= MSCC_MS_SAM_FLOW_CTRL_INCLUDE_SCI;
-       }
-
-write_ctrl:
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_FLOW_CTRL(idx), val);
-}
-
-static struct macsec_flow *vsc8584_macsec_find_flow(struct macsec_context *ctx,
-                                                   enum macsec_bank bank)
-{
-       struct vsc8531_private *priv = ctx->phydev->priv;
-       struct macsec_flow *pos, *tmp;
-
-       list_for_each_entry_safe(pos, tmp, &priv->macsec_flows, list)
-               if (pos->assoc_num == ctx->sa.assoc_num && pos->bank == bank)
-                       return pos;
-
-       return ERR_PTR(-ENOENT);
-}
-
-static void vsc8584_macsec_flow_enable(struct phy_device *phydev,
-                                      struct macsec_flow *flow)
-{
-       enum macsec_bank bank = flow->bank;
-       u32 val, idx = flow->index;
-
-       if ((flow->bank == MACSEC_INGR && flow->rx_sa && !flow->rx_sa->active) ||
-           (flow->bank == MACSEC_EGR && flow->tx_sa && !flow->tx_sa->active))
-               return;
-
-       /* Enable */
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_ENTRY_SET1, BIT(idx));
-
-       /* Set in-use */
-       val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_SAM_FLOW_CTRL(idx));
-       val |= MSCC_MS_SAM_FLOW_CTRL_SA_IN_USE;
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_FLOW_CTRL(idx), val);
-}
-
-static void vsc8584_macsec_flow_disable(struct phy_device *phydev,
-                                       struct macsec_flow *flow)
-{
-       enum macsec_bank bank = flow->bank;
-       u32 val, idx = flow->index;
-
-       /* Disable */
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_ENTRY_CLEAR1, BIT(idx));
-
-       /* Clear in-use */
-       val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_SAM_FLOW_CTRL(idx));
-       val &= ~MSCC_MS_SAM_FLOW_CTRL_SA_IN_USE;
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_FLOW_CTRL(idx), val);
-}
-
-static u32 vsc8584_macsec_flow_context_id(struct macsec_flow *flow)
-{
-       if (flow->bank == MACSEC_INGR)
-               return flow->index + MSCC_MS_MAX_FLOWS;
-
-       return flow->index;
-}
-
-/* Derive the AES key to get a key for the hash autentication */
-static int vsc8584_macsec_derive_key(const u8 key[MACSEC_KEYID_LEN],
-                                    u16 key_len, u8 hkey[16])
-{
-       struct crypto_skcipher *tfm = crypto_alloc_skcipher("ecb(aes)", 0, 0);
-       struct skcipher_request *req = NULL;
-       struct scatterlist src, dst;
-       DECLARE_CRYPTO_WAIT(wait);
-       u32 input[4] = {0};
-       int ret;
-
-       if (IS_ERR(tfm))
-               return PTR_ERR(tfm);
-
-       req = skcipher_request_alloc(tfm, GFP_KERNEL);
-       if (!req) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
-                                     CRYPTO_TFM_REQ_MAY_SLEEP, crypto_req_done,
-                                     &wait);
-       ret = crypto_skcipher_setkey(tfm, key, key_len);
-       if (ret < 0)
-               goto out;
-
-       sg_init_one(&src, input, 16);
-       sg_init_one(&dst, hkey, 16);
-       skcipher_request_set_crypt(req, &src, &dst, 16, NULL);
-
-       ret = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
-
-out:
-       skcipher_request_free(req);
-       crypto_free_skcipher(tfm);
-       return ret;
-}
-
-static int vsc8584_macsec_transformation(struct phy_device *phydev,
-                                        struct macsec_flow *flow)
-{
-       struct vsc8531_private *priv = phydev->priv;
-       enum macsec_bank bank = flow->bank;
-       int i, ret, index = flow->index;
-       u32 rec = 0, control = 0;
-       u8 hkey[16];
-       sci_t sci;
-
-       ret = vsc8584_macsec_derive_key(flow->key, priv->secy->key_len, hkey);
-       if (ret)
-               return ret;
-
-       switch (priv->secy->key_len) {
-       case 16:
-               control |= CONTROL_CRYPTO_ALG(CTRYPTO_ALG_AES_CTR_128);
-               break;
-       case 32:
-               control |= CONTROL_CRYPTO_ALG(CTRYPTO_ALG_AES_CTR_256);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       control |= (bank == MACSEC_EGR) ?
-                  (CONTROL_TYPE_EGRESS | CONTROL_AN(priv->secy->tx_sc.encoding_sa)) :
-                  (CONTROL_TYPE_INGRESS | CONTROL_SEQ_MASK);
-
-       control |= CONTROL_UPDATE_SEQ | CONTROL_ENCRYPT_AUTH | CONTROL_KEY_IN_CTX |
-                  CONTROL_IV0 | CONTROL_IV1 | CONTROL_IV_IN_SEQ |
-                  CONTROL_DIGEST_TYPE(0x2) | CONTROL_SEQ_TYPE(0x1) |
-                  CONTROL_AUTH_ALG(AUTH_ALG_AES_GHAS) | CONTROL_CONTEXT_ID;
-
-       /* Set the control word */
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_XFORM_REC(index, rec++),
-                                control);
-
-       /* Set the context ID. Must be unique. */
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_XFORM_REC(index, rec++),
-                                vsc8584_macsec_flow_context_id(flow));
-
-       /* Set the encryption/decryption key */
-       for (i = 0; i < priv->secy->key_len / sizeof(u32); i++)
-               vsc8584_macsec_phy_write(phydev, bank,
-                                        MSCC_MS_XFORM_REC(index, rec++),
-                                        ((u32 *)flow->key)[i]);
-
-       /* Set the authentication key */
-       for (i = 0; i < 4; i++)
-               vsc8584_macsec_phy_write(phydev, bank,
-                                        MSCC_MS_XFORM_REC(index, rec++),
-                                        ((u32 *)hkey)[i]);
-
-       /* Initial sequence number */
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_XFORM_REC(index, rec++),
-                                bank == MACSEC_INGR ?
-                                flow->rx_sa->next_pn : flow->tx_sa->next_pn);
-
-       if (bank == MACSEC_INGR)
-               /* Set the mask (replay window size) */
-               vsc8584_macsec_phy_write(phydev, bank,
-                                        MSCC_MS_XFORM_REC(index, rec++),
-                                        priv->secy->replay_window);
-
-       /* Set the input vectors */
-       sci = bank == MACSEC_INGR ? flow->rx_sa->sc->sci : priv->secy->sci;
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_XFORM_REC(index, rec++),
-                                lower_32_bits(sci));
-       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_XFORM_REC(index, rec++),
-                                upper_32_bits(sci));
-
-       while (rec < 20)
-               vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_XFORM_REC(index, rec++),
-                                        0);
-
-       flow->has_transformation = true;
-       return 0;
-}
-
-static struct macsec_flow *vsc8584_macsec_alloc_flow(struct vsc8531_private *priv,
-                                                    enum macsec_bank bank)
-{
-       unsigned long *bitmap = bank == MACSEC_INGR ?
-                               &priv->ingr_flows : &priv->egr_flows;
-       struct macsec_flow *flow;
-       int index;
-
-       index = find_first_zero_bit(bitmap, MSCC_MS_MAX_FLOWS);
-
-       if (index == MSCC_MS_MAX_FLOWS)
-               return ERR_PTR(-ENOMEM);
-
-       flow = kzalloc(sizeof(*flow), GFP_KERNEL);
-       if (!flow)
-               return ERR_PTR(-ENOMEM);
-
-       set_bit(index, bitmap);
-       flow->index = index;
-       flow->bank = bank;
-       flow->priority = 8;
-       flow->assoc_num = -1;
-
-       list_add_tail(&flow->list, &priv->macsec_flows);
-       return flow;
-}
-
-static void vsc8584_macsec_free_flow(struct vsc8531_private *priv,
-                                    struct macsec_flow *flow)
-{
-       unsigned long *bitmap = flow->bank == MACSEC_INGR ?
-                               &priv->ingr_flows : &priv->egr_flows;
-
-       list_del(&flow->list);
-       clear_bit(flow->index, bitmap);
-       kfree(flow);
-}
-
-static int vsc8584_macsec_add_flow(struct phy_device *phydev,
-                                  struct macsec_flow *flow, bool update)
-{
-       int ret;
-
-       flow->port = MSCC_MS_PORT_CONTROLLED;
-       vsc8584_macsec_flow(phydev, flow);
-
-       if (update)
-               return 0;
-
-       ret = vsc8584_macsec_transformation(phydev, flow);
-       if (ret) {
-               vsc8584_macsec_free_flow(phydev->priv, flow);
-               return ret;
-       }
-
-       return 0;
-}
-
-static int vsc8584_macsec_default_flows(struct phy_device *phydev)
-{
-       struct macsec_flow *flow;
-
-       /* Add a rule to let the MKA traffic go through, ingress */
-       flow = vsc8584_macsec_alloc_flow(phydev->priv, MACSEC_INGR);
-       if (IS_ERR(flow))
-               return PTR_ERR(flow);
-
-       flow->priority = 15;
-       flow->port = MSCC_MS_PORT_UNCONTROLLED;
-       flow->match.tagged = 1;
-       flow->match.untagged = 1;
-       flow->match.etype = 1;
-       flow->etype = ETH_P_PAE;
-       flow->action.bypass = 1;
-
-       vsc8584_macsec_flow(phydev, flow);
-       vsc8584_macsec_flow_enable(phydev, flow);
-
-       /* Add a rule to let the MKA traffic go through, egress */
-       flow = vsc8584_macsec_alloc_flow(phydev->priv, MACSEC_EGR);
-       if (IS_ERR(flow))
-               return PTR_ERR(flow);
-
-       flow->priority = 15;
-       flow->port = MSCC_MS_PORT_COMMON;
-       flow->match.untagged = 1;
-       flow->match.etype = 1;
-       flow->etype = ETH_P_PAE;
-       flow->action.bypass = 1;
-
-       vsc8584_macsec_flow(phydev, flow);
-       vsc8584_macsec_flow_enable(phydev, flow);
-
-       return 0;
-}
-
-static void vsc8584_macsec_del_flow(struct phy_device *phydev,
-                                   struct macsec_flow *flow)
-{
-       vsc8584_macsec_flow_disable(phydev, flow);
-       vsc8584_macsec_free_flow(phydev->priv, flow);
-}
-
-static int __vsc8584_macsec_add_rxsa(struct macsec_context *ctx,
-                                    struct macsec_flow *flow, bool update)
-{
-       struct phy_device *phydev = ctx->phydev;
-       struct vsc8531_private *priv = phydev->priv;
-
-       if (!flow) {
-               flow = vsc8584_macsec_alloc_flow(priv, MACSEC_INGR);
-               if (IS_ERR(flow))
-                       return PTR_ERR(flow);
-
-               memcpy(flow->key, ctx->sa.key, priv->secy->key_len);
-       }
-
-       flow->assoc_num = ctx->sa.assoc_num;
-       flow->rx_sa = ctx->sa.rx_sa;
-
-       /* Always match tagged packets on ingress */
-       flow->match.tagged = 1;
-       flow->match.sci = 1;
-
-       if (priv->secy->validate_frames != MACSEC_VALIDATE_DISABLED)
-               flow->match.untagged = 1;
-
-       return vsc8584_macsec_add_flow(phydev, flow, update);
-}
-
-static int __vsc8584_macsec_add_txsa(struct macsec_context *ctx,
-                                    struct macsec_flow *flow, bool update)
-{
-       struct phy_device *phydev = ctx->phydev;
-       struct vsc8531_private *priv = phydev->priv;
-
-       if (!flow) {
-               flow = vsc8584_macsec_alloc_flow(priv, MACSEC_EGR);
-               if (IS_ERR(flow))
-                       return PTR_ERR(flow);
-
-               memcpy(flow->key, ctx->sa.key, priv->secy->key_len);
-       }
-
-       flow->assoc_num = ctx->sa.assoc_num;
-       flow->tx_sa = ctx->sa.tx_sa;
-
-       /* Always match untagged packets on egress */
-       flow->match.untagged = 1;
-
-       return vsc8584_macsec_add_flow(phydev, flow, update);
-}
-
-static int vsc8584_macsec_dev_open(struct macsec_context *ctx)
-{
-       struct vsc8531_private *priv = ctx->phydev->priv;
-       struct macsec_flow *flow, *tmp;
-
-       /* No operation to perform before the commit step */
-       if (ctx->prepare)
-               return 0;
-
-       list_for_each_entry_safe(flow, tmp, &priv->macsec_flows, list)
-               vsc8584_macsec_flow_enable(ctx->phydev, flow);
-
-       return 0;
-}
-
-static int vsc8584_macsec_dev_stop(struct macsec_context *ctx)
-{
-       struct vsc8531_private *priv = ctx->phydev->priv;
-       struct macsec_flow *flow, *tmp;
-
-       /* No operation to perform before the commit step */
-       if (ctx->prepare)
-               return 0;
-
-       list_for_each_entry_safe(flow, tmp, &priv->macsec_flows, list)
-               vsc8584_macsec_flow_disable(ctx->phydev, flow);
-
-       return 0;
-}
-
-static int vsc8584_macsec_add_secy(struct macsec_context *ctx)
-{
-       struct vsc8531_private *priv = ctx->phydev->priv;
-       struct macsec_secy *secy = ctx->secy;
-
-       if (ctx->prepare) {
-               if (priv->secy)
-                       return -EEXIST;
-
-               return 0;
-       }
-
-       priv->secy = secy;
-
-       vsc8584_macsec_flow_default_action(ctx->phydev, MACSEC_EGR,
-                                          secy->validate_frames != MACSEC_VALIDATE_DISABLED);
-       vsc8584_macsec_flow_default_action(ctx->phydev, MACSEC_INGR,
-                                          secy->validate_frames != MACSEC_VALIDATE_DISABLED);
-
-       return vsc8584_macsec_default_flows(ctx->phydev);
-}
-
-static int vsc8584_macsec_del_secy(struct macsec_context *ctx)
-{
-       struct vsc8531_private *priv = ctx->phydev->priv;
-       struct macsec_flow *flow, *tmp;
-
-       /* No operation to perform before the commit step */
-       if (ctx->prepare)
-               return 0;
-
-       list_for_each_entry_safe(flow, tmp, &priv->macsec_flows, list)
-               vsc8584_macsec_del_flow(ctx->phydev, flow);
-
-       vsc8584_macsec_flow_default_action(ctx->phydev, MACSEC_EGR, false);
-       vsc8584_macsec_flow_default_action(ctx->phydev, MACSEC_INGR, false);
-
-       priv->secy = NULL;
-       return 0;
-}
-
-static int vsc8584_macsec_upd_secy(struct macsec_context *ctx)
-{
-       /* No operation to perform before the commit step */
-       if (ctx->prepare)
-               return 0;
-
-       vsc8584_macsec_del_secy(ctx);
-       return vsc8584_macsec_add_secy(ctx);
-}
-
-static int vsc8584_macsec_add_rxsc(struct macsec_context *ctx)
-{
-       /* Nothing to do */
-       return 0;
-}
-
-static int vsc8584_macsec_upd_rxsc(struct macsec_context *ctx)
-{
-       return -EOPNOTSUPP;
-}
-
-static int vsc8584_macsec_del_rxsc(struct macsec_context *ctx)
-{
-       struct vsc8531_private *priv = ctx->phydev->priv;
-       struct macsec_flow *flow, *tmp;
-
-       /* No operation to perform before the commit step */
-       if (ctx->prepare)
-               return 0;
-
-       list_for_each_entry_safe(flow, tmp, &priv->macsec_flows, list) {
-               if (flow->bank == MACSEC_INGR && flow->rx_sa &&
-                   flow->rx_sa->sc->sci == ctx->rx_sc->sci)
-                       vsc8584_macsec_del_flow(ctx->phydev, flow);
-       }
-
-       return 0;
-}
-
-static int vsc8584_macsec_add_rxsa(struct macsec_context *ctx)
-{
-       struct macsec_flow *flow = NULL;
-
-       if (ctx->prepare)
-               return __vsc8584_macsec_add_rxsa(ctx, flow, false);
-
-       flow = vsc8584_macsec_find_flow(ctx, MACSEC_INGR);
-       if (IS_ERR(flow))
-               return PTR_ERR(flow);
-
-       vsc8584_macsec_flow_enable(ctx->phydev, flow);
-       return 0;
-}
-
-static int vsc8584_macsec_upd_rxsa(struct macsec_context *ctx)
-{
-       struct macsec_flow *flow;
-
-       flow = vsc8584_macsec_find_flow(ctx, MACSEC_INGR);
-       if (IS_ERR(flow))
-               return PTR_ERR(flow);
-
-       if (ctx->prepare) {
-               /* Make sure the flow is disabled before updating it */
-               vsc8584_macsec_flow_disable(ctx->phydev, flow);
-
-               return __vsc8584_macsec_add_rxsa(ctx, flow, true);
-       }
-
-       vsc8584_macsec_flow_enable(ctx->phydev, flow);
-       return 0;
-}
-
-static int vsc8584_macsec_del_rxsa(struct macsec_context *ctx)
-{
-       struct macsec_flow *flow;
-
-       flow = vsc8584_macsec_find_flow(ctx, MACSEC_INGR);
-
-       if (IS_ERR(flow))
-               return PTR_ERR(flow);
-       if (ctx->prepare)
-               return 0;
-
-       vsc8584_macsec_del_flow(ctx->phydev, flow);
-       return 0;
-}
-
-static int vsc8584_macsec_add_txsa(struct macsec_context *ctx)
-{
-       struct macsec_flow *flow = NULL;
-
-       if (ctx->prepare)
-               return __vsc8584_macsec_add_txsa(ctx, flow, false);
-
-       flow = vsc8584_macsec_find_flow(ctx, MACSEC_EGR);
-       if (IS_ERR(flow))
-               return PTR_ERR(flow);
-
-       vsc8584_macsec_flow_enable(ctx->phydev, flow);
-       return 0;
-}
-
-static int vsc8584_macsec_upd_txsa(struct macsec_context *ctx)
-{
-       struct macsec_flow *flow;
-
-       flow = vsc8584_macsec_find_flow(ctx, MACSEC_EGR);
-       if (IS_ERR(flow))
-               return PTR_ERR(flow);
-
-       if (ctx->prepare) {
-               /* Make sure the flow is disabled before updating it */
-               vsc8584_macsec_flow_disable(ctx->phydev, flow);
-
-               return __vsc8584_macsec_add_txsa(ctx, flow, true);
-       }
-
-       vsc8584_macsec_flow_enable(ctx->phydev, flow);
-       return 0;
-}
-
-static int vsc8584_macsec_del_txsa(struct macsec_context *ctx)
-{
-       struct macsec_flow *flow;
-
-       flow = vsc8584_macsec_find_flow(ctx, MACSEC_EGR);
-
-       if (IS_ERR(flow))
-               return PTR_ERR(flow);
-       if (ctx->prepare)
-               return 0;
-
-       vsc8584_macsec_del_flow(ctx->phydev, flow);
-       return 0;
-}
-
-static struct macsec_ops vsc8584_macsec_ops = {
-       .mdo_dev_open = vsc8584_macsec_dev_open,
-       .mdo_dev_stop = vsc8584_macsec_dev_stop,
-       .mdo_add_secy = vsc8584_macsec_add_secy,
-       .mdo_upd_secy = vsc8584_macsec_upd_secy,
-       .mdo_del_secy = vsc8584_macsec_del_secy,
-       .mdo_add_rxsc = vsc8584_macsec_add_rxsc,
-       .mdo_upd_rxsc = vsc8584_macsec_upd_rxsc,
-       .mdo_del_rxsc = vsc8584_macsec_del_rxsc,
-       .mdo_add_rxsa = vsc8584_macsec_add_rxsa,
-       .mdo_upd_rxsa = vsc8584_macsec_upd_rxsa,
-       .mdo_del_rxsa = vsc8584_macsec_del_rxsa,
-       .mdo_add_txsa = vsc8584_macsec_add_txsa,
-       .mdo_upd_txsa = vsc8584_macsec_upd_txsa,
-       .mdo_del_txsa = vsc8584_macsec_del_txsa,
-};
-#endif /* CONFIG_MACSEC */
-
-/* Check if one PHY has already done the init of the parts common to all PHYs
- * in the Quad PHY package.
- */
-static bool vsc8584_is_pkg_init(struct phy_device *phydev, bool reversed)
-{
-       struct mdio_device **map = phydev->mdio.bus->mdio_map;
-       struct vsc8531_private *vsc8531;
-       struct phy_device *phy;
-       int i, addr;
-
-       /* VSC8584 is a Quad PHY */
-       for (i = 0; i < 4; i++) {
-               vsc8531 = phydev->priv;
-
-               if (reversed)
-                       addr = vsc8531->base_addr - i;
-               else
-                       addr = vsc8531->base_addr + i;
-
-               if (!map[addr])
-                       continue;
-
-               phy = container_of(map[addr], struct phy_device, mdio);
-
-               if ((phy->phy_id & phydev->drv->phy_id_mask) !=
-                   (phydev->drv->phy_id & phydev->drv->phy_id_mask))
-                       continue;
-
-               vsc8531 = phy->priv;
-
-               if (vsc8531 && vsc8531->pkg_init)
-                       return true;
-       }
-
-       return false;
-}
-
-static int vsc8584_config_init(struct phy_device *phydev)
-{
-       struct vsc8531_private *vsc8531 = phydev->priv;
-       u16 addr, val;
-       int ret, i;
-
-       phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
-
-       mutex_lock(&phydev->mdio.bus->mdio_lock);
-
-       __mdiobus_write(phydev->mdio.bus, phydev->mdio.addr,
-                       MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
-       addr = __mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
-                             MSCC_PHY_EXT_PHY_CNTL_4);
-       addr >>= PHY_CNTL_4_ADDR_POS;
-
-       val = __mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
-                            MSCC_PHY_ACTIPHY_CNTL);
-       if (val & PHY_ADDR_REVERSED)
-               vsc8531->base_addr = phydev->mdio.addr + addr;
-       else
-               vsc8531->base_addr = phydev->mdio.addr - addr;
-
-       /* Some parts of the init sequence are identical for every PHY in the
-        * package. Some parts are modifying the GPIO register bank which is a
-        * set of registers that are affecting all PHYs, a few resetting the
-        * microprocessor common to all PHYs. The CRC check responsible of the
-        * checking the firmware within the 8051 microprocessor can only be
-        * accessed via the PHY whose internal address in the package is 0.
-        * All PHYs' interrupts mask register has to be zeroed before enabling
-        * any PHY's interrupt in this register.
-        * For all these reasons, we need to do the init sequence once and only
-        * once whatever is the first PHY in the package that is initialized and
-        * do the correct init sequence for all PHYs that are package-critical
-        * in this pre-init function.
-        */
-       if (!vsc8584_is_pkg_init(phydev, val & PHY_ADDR_REVERSED ? 1 : 0)) {
-               /* The following switch statement assumes that the lowest
-                * nibble of the phy_id_mask is always 0. This works because
-                * the lowest nibble of the PHY_ID's below are also 0.
-                */
-               WARN_ON(phydev->drv->phy_id_mask & 0xf);
-
-               switch (phydev->phy_id & phydev->drv->phy_id_mask) {
-               case PHY_ID_VSC8504:
-               case PHY_ID_VSC8552:
-               case PHY_ID_VSC8572:
-               case PHY_ID_VSC8574:
-                       ret = vsc8574_config_pre_init(phydev);
-                       break;
-               case PHY_ID_VSC856X:
-               case PHY_ID_VSC8575:
-               case PHY_ID_VSC8582:
-               case PHY_ID_VSC8584:
-                       ret = vsc8584_config_pre_init(phydev);
-                       break;
-               default:
-                       ret = -EINVAL;
-                       break;
-               }
-
-               if (ret)
-                       goto err;
-       }
-
-       vsc8531->pkg_init = true;
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
-                      MSCC_PHY_PAGE_EXTENDED_GPIO);
-
-       val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
-       val &= ~MAC_CFG_MASK;
-       if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
-               val |= MAC_CFG_QSGMII;
-       else
-               val |= MAC_CFG_SGMII;
-
-       ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
-       if (ret)
-               goto err;
-
-       val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
-               PROC_CMD_READ_MOD_WRITE_PORT;
-       if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
-               val |= PROC_CMD_QSGMII_MAC;
-       else
-               val |= PROC_CMD_SGMII_MAC;
-
-       ret = vsc8584_cmd(phydev, val);
-       if (ret)
-               goto err;
-
-       usleep_range(10000, 20000);
-
-       /* Disable SerDes for 100Base-FX */
-       ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
-                         PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
-                         PROC_CMD_READ_MOD_WRITE_PORT |
-                         PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_100BASE_FX);
-       if (ret)
-               goto err;
-
-       /* Disable SerDes for 1000Base-X */
-       ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
-                         PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
-                         PROC_CMD_READ_MOD_WRITE_PORT |
-                         PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X);
-       if (ret)
-               goto err;
-
-       mutex_unlock(&phydev->mdio.bus->mdio_lock);
-
-#if IS_ENABLED(CONFIG_MACSEC)
-       /* MACsec */
-       switch (phydev->phy_id & phydev->drv->phy_id_mask) {
-       case PHY_ID_VSC856X:
-       case PHY_ID_VSC8575:
-       case PHY_ID_VSC8582:
-       case PHY_ID_VSC8584:
-               INIT_LIST_HEAD(&vsc8531->macsec_flows);
-               vsc8531->secy = NULL;
-
-               phydev->macsec_ops = &vsc8584_macsec_ops;
-
-               ret = vsc8584_macsec_init(phydev);
-               if (ret)
-                       goto err;
-       }
-#endif
-
-       phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
-
-       val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
-       val &= ~(MEDIA_OP_MODE_MASK | VSC8584_MAC_IF_SELECTION_MASK);
-       val |= (MEDIA_OP_MODE_COPPER << MEDIA_OP_MODE_POS) |
-              (VSC8584_MAC_IF_SELECTION_SGMII << VSC8584_MAC_IF_SELECTION_POS);
-       ret = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, val);
-
-       ret = genphy_soft_reset(phydev);
-       if (ret)
-               return ret;
-
-       for (i = 0; i < vsc8531->nleds; i++) {
-               ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
-               if (ret)
-                       return ret;
-       }
-
-       return 0;
-
-err:
-       mutex_unlock(&phydev->mdio.bus->mdio_lock);
-       return ret;
-}
-
-static int vsc8584_handle_interrupt(struct phy_device *phydev)
-{
-#if IS_ENABLED(CONFIG_MACSEC)
-       struct vsc8531_private *priv = phydev->priv;
-       struct macsec_flow *flow, *tmp;
-       u32 cause, rec;
-
-       /* Check MACsec PN rollover */
-       cause = vsc8584_macsec_phy_read(phydev, MACSEC_EGR,
-                                       MSCC_MS_INTR_CTRL_STATUS);
-       cause &= MSCC_MS_INTR_CTRL_STATUS_INTR_CLR_STATUS_M;
-       if (!(cause & MACSEC_INTR_CTRL_STATUS_ROLLOVER))
-               goto skip_rollover;
-
-       rec = 6 + priv->secy->key_len / sizeof(u32);
-       list_for_each_entry_safe(flow, tmp, &priv->macsec_flows, list) {
-               u32 val;
-
-               if (flow->bank != MACSEC_EGR || !flow->has_transformation)
-                       continue;
-
-               val = vsc8584_macsec_phy_read(phydev, MACSEC_EGR,
-                                             MSCC_MS_XFORM_REC(flow->index, rec));
-               if (val == 0xffffffff) {
-                       vsc8584_macsec_flow_disable(phydev, flow);
-                       macsec_pn_wrapped(priv->secy, flow->tx_sa);
-                       break;
-               }
-       }
-
-skip_rollover:
-#endif
-
-       phy_mac_interrupt(phydev);
-       return 0;
-}
-
-static int vsc85xx_config_init(struct phy_device *phydev)
-{
-       int rc, i, phy_id;
-       struct vsc8531_private *vsc8531 = phydev->priv;
-
-       rc = vsc85xx_default_config(phydev);
-       if (rc)
-               return rc;
-
-       rc = vsc85xx_mac_if_set(phydev, phydev->interface);
-       if (rc)
-               return rc;
-
-       rc = vsc85xx_edge_rate_cntl_set(phydev, vsc8531->rate_magic);
-       if (rc)
-               return rc;
-
-       phy_id = phydev->drv->phy_id & phydev->drv->phy_id_mask;
-       if (PHY_ID_VSC8531 == phy_id || PHY_ID_VSC8541 == phy_id ||
-           PHY_ID_VSC8530 == phy_id || PHY_ID_VSC8540 == phy_id) {
-               rc = vsc8531_pre_init_seq_set(phydev);
-               if (rc)
-                       return rc;
-       }
-
-       rc = vsc85xx_eee_init_seq_set(phydev);
-       if (rc)
-               return rc;
-
-       for (i = 0; i < vsc8531->nleds; i++) {
-               rc = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
-               if (rc)
-                       return rc;
-       }
-
-       return 0;
-}
-
-static int vsc8584_did_interrupt(struct phy_device *phydev)
-{
-       int rc = 0;
-
-       if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
-               rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
-
-       return (rc < 0) ? 0 : rc & MII_VSC85XX_INT_MASK_MASK;
-}
-
-static int vsc8514_config_pre_init(struct phy_device *phydev)
-{
-       /* These are the settings to override the silicon default
-        * values to handle hardware performance of PHY. They
-        * are set at Power-On state and remain until PHY Reset.
-        */
-       static const struct reg_val pre_init1[] = {
-               {0x0f90, 0x00688980},
-               {0x0786, 0x00000003},
-               {0x07fa, 0x0050100f},
-               {0x0f82, 0x0012b002},
-               {0x1686, 0x00000004},
-               {0x168c, 0x00d2c46f},
-               {0x17a2, 0x00000620},
-               {0x16a0, 0x00eeffdd},
-               {0x16a6, 0x00071448},
-               {0x16a4, 0x0013132f},
-               {0x16a8, 0x00000000},
-               {0x0ffc, 0x00c0a028},
-               {0x0fe8, 0x0091b06c},
-               {0x0fea, 0x00041600},
-               {0x0f80, 0x00fffaff},
-               {0x0fec, 0x00901809},
-               {0x0ffe, 0x00b01007},
-               {0x16b0, 0x00eeff00},
-               {0x16b2, 0x00007000},
-               {0x16b4, 0x00000814},
-       };
-       unsigned int i;
-       u16 reg;
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
-
-       /* all writes below are broadcasted to all PHYs in the same package */
-       reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
-       reg |= SMI_BROADCAST_WR_EN;
-       phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
-
-       reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
-       reg |= BIT(15);
-       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
-
-       for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
-               vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
-
-       reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
-       reg &= ~BIT(15);
-       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
-
-       reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
-       reg &= ~SMI_BROADCAST_WR_EN;
-       phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
-
-       return 0;
-}
-
-static u32 vsc85xx_csr_ctrl_phy_read(struct phy_device *phydev,
-                                    u32 target, u32 reg)
-{
-       unsigned long deadline;
-       u32 val, val_l, val_h;
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
-
-       /* CSR registers are grouped under different Target IDs.
-        * 6-bit Target_ID is split between MSCC_EXT_PAGE_CSR_CNTL_20 and
-        * MSCC_EXT_PAGE_CSR_CNTL_19 registers.
-        * Target_ID[5:2] maps to bits[3:0] of MSCC_EXT_PAGE_CSR_CNTL_20
-        * and Target_ID[1:0] maps to bits[13:12] of MSCC_EXT_PAGE_CSR_CNTL_19.
-        */
-
-       /* Setup the Target ID */
-       phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_20,
-                      MSCC_PHY_CSR_CNTL_20_TARGET(target >> 2));
-
-       /* Trigger CSR Action - Read into the CSR's */
-       phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_19,
-                      MSCC_PHY_CSR_CNTL_19_CMD | MSCC_PHY_CSR_CNTL_19_READ |
-                      MSCC_PHY_CSR_CNTL_19_REG_ADDR(reg) |
-                      MSCC_PHY_CSR_CNTL_19_TARGET(target & 0x3));
-
-       /* Wait for register access*/
-       deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
-       do {
-               usleep_range(500, 1000);
-               val = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_19);
-       } while (time_before(jiffies, deadline) &&
-               !(val & MSCC_PHY_CSR_CNTL_19_CMD));
-
-       if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
-               return 0xffffffff;
-
-       /* Read the Least Significant Word (LSW) (17) */
-       val_l = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_17);
-
-       /* Read the Most Significant Word (MSW) (18) */
-       val_h = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_18);
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
-                      MSCC_PHY_PAGE_STANDARD);
-
-       return (val_h << 16) | val_l;
-}
-
-static int vsc85xx_csr_ctrl_phy_write(struct phy_device *phydev,
-                                     u32 target, u32 reg, u32 val)
-{
-       unsigned long deadline;
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
-
-       /* CSR registers are grouped under different Target IDs.
-        * 6-bit Target_ID is split between MSCC_EXT_PAGE_CSR_CNTL_20 and
-        * MSCC_EXT_PAGE_CSR_CNTL_19 registers.
-        * Target_ID[5:2] maps to bits[3:0] of MSCC_EXT_PAGE_CSR_CNTL_20
-        * and Target_ID[1:0] maps to bits[13:12] of MSCC_EXT_PAGE_CSR_CNTL_19.
-        */
-
-       /* Setup the Target ID */
-       phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_20,
-                      MSCC_PHY_CSR_CNTL_20_TARGET(target >> 2));
-
-       /* Write the Least Significant Word (LSW) (17) */
-       phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_17, (u16)val);
-
-       /* Write the Most Significant Word (MSW) (18) */
-       phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_18, (u16)(val >> 16));
-
-       /* Trigger CSR Action - Write into the CSR's */
-       phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_19,
-                      MSCC_PHY_CSR_CNTL_19_CMD |
-                      MSCC_PHY_CSR_CNTL_19_REG_ADDR(reg) |
-                      MSCC_PHY_CSR_CNTL_19_TARGET(target & 0x3));
-
-       /* Wait for register access */
-       deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
-       do {
-               usleep_range(500, 1000);
-               val = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_19);
-       } while (time_before(jiffies, deadline) &&
-                !(val & MSCC_PHY_CSR_CNTL_19_CMD));
-
-       if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
-               return -ETIMEDOUT;
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
-                      MSCC_PHY_PAGE_STANDARD);
-
-       return 0;
-}
-
-static int __phy_write_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb,
-                              u32 op)
-{
-       unsigned long deadline;
-       u32 val;
-       int ret;
-
-       ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET, reg,
-                                        op | (1 << mcb));
-       if (ret)
-               return -EINVAL;
-
-       deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
-       do {
-               usleep_range(500, 1000);
-               val = vsc85xx_csr_ctrl_phy_read(phydev, PHY_MCB_TARGET, reg);
-
-               if (val == 0xffffffff)
-                       return -EIO;
-
-       } while (time_before(jiffies, deadline) && (val & op));
-
-       if (val & op)
-               return -ETIMEDOUT;
-
-       return 0;
-}
-
-/* Trigger a read to the spcified MCB */
-static int phy_update_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
-{
-       return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_READ);
-}
-
-/* Trigger a write to the spcified MCB */
-static int phy_commit_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
-{
-       return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_WRITE);
-}
-
-static int vsc8514_config_init(struct phy_device *phydev)
-{
-       struct vsc8531_private *vsc8531 = phydev->priv;
-       unsigned long deadline;
-       u16 val, addr;
-       int ret, i;
-       u32 reg;
-
-       phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
-
-       mutex_lock(&phydev->mdio.bus->mdio_lock);
-
-       __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
-
-       addr = __phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_4);
-       addr >>= PHY_CNTL_4_ADDR_POS;
-
-       val = __phy_read(phydev, MSCC_PHY_ACTIPHY_CNTL);
-
-       if (val & PHY_ADDR_REVERSED)
-               vsc8531->base_addr = phydev->mdio.addr + addr;
-       else
-               vsc8531->base_addr = phydev->mdio.addr - addr;
-
-       /* Some parts of the init sequence are identical for every PHY in the
-        * package. Some parts are modifying the GPIO register bank which is a
-        * set of registers that are affecting all PHYs, a few resetting the
-        * microprocessor common to all PHYs.
-        * All PHYs' interrupts mask register has to be zeroed before enabling
-        * any PHY's interrupt in this register.
-        * For all these reasons, we need to do the init sequence once and only
-        * once whatever is the first PHY in the package that is initialized and
-        * do the correct init sequence for all PHYs that are package-critical
-        * in this pre-init function.
-        */
-       if (!vsc8584_is_pkg_init(phydev, val & PHY_ADDR_REVERSED ? 1 : 0))
-               vsc8514_config_pre_init(phydev);
-
-       vsc8531->pkg_init = true;
-
-       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
-                      MSCC_PHY_PAGE_EXTENDED_GPIO);
-
-       val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
-
-       val &= ~MAC_CFG_MASK;
-       val |= MAC_CFG_QSGMII;
-       ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
-
-       if (ret)
-               goto err;
-
-       ret = vsc8584_cmd(phydev,
-                         PROC_CMD_MCB_ACCESS_MAC_CONF |
-                         PROC_CMD_RST_CONF_PORT |
-                         PROC_CMD_READ_MOD_WRITE_PORT | PROC_CMD_QSGMII_MAC);
-       if (ret)
-               goto err;
-
-       /* 6g mcb */
-       phy_update_mcb_s6g(phydev, PHY_MCB_S6G_CFG, 0);
-       /* lcpll mcb */
-       phy_update_mcb_s6g(phydev, PHY_S6G_LCPLL_CFG, 0);
-       /* pll5gcfg0 */
-       ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
-                                        PHY_S6G_PLL5G_CFG0, 0x7036f145);
-       if (ret)
-               goto err;
-
-       phy_commit_mcb_s6g(phydev, PHY_S6G_LCPLL_CFG, 0);
-       /* pllcfg */
-       ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
-                                        PHY_S6G_PLL_CFG,
-                                        (3 << PHY_S6G_PLL_ENA_OFFS_POS) |
-                                        (120 << PHY_S6G_PLL_FSM_CTRL_DATA_POS)
-                                        | (0 << PHY_S6G_PLL_FSM_ENA_POS));
-       if (ret)
-               goto err;
-
-       /* commoncfg */
-       ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
-                                        PHY_S6G_COMMON_CFG,
-                                        (0 << PHY_S6G_SYS_RST_POS) |
-                                        (0 << PHY_S6G_ENA_LANE_POS) |
-                                        (0 << PHY_S6G_ENA_LOOP_POS) |
-                                        (0 << PHY_S6G_QRATE_POS) |
-                                        (3 << PHY_S6G_IF_MODE_POS));
-       if (ret)
-               goto err;
-
-       /* misccfg */
-       ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
-                                        PHY_S6G_MISC_CFG, 1);
-       if (ret)
-               goto err;
-
-       /* gpcfg */
-       ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
-                                        PHY_S6G_GPC_CFG, 768);
-       if (ret)
-               goto err;
-
-       phy_commit_mcb_s6g(phydev, PHY_S6G_DFT_CFG2, 0);
-
-       deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
-       do {
-               usleep_range(500, 1000);
-               phy_update_mcb_s6g(phydev, PHY_MCB_S6G_CFG,
-                                  0); /* read 6G MCB into CSRs */
-               reg = vsc85xx_csr_ctrl_phy_read(phydev, PHY_MCB_TARGET,
-                                               PHY_S6G_PLL_STATUS);
-               if (reg == 0xffffffff) {
-                       mutex_unlock(&phydev->mdio.bus->mdio_lock);
-                       return -EIO;
-               }
-
-       } while (time_before(jiffies, deadline) && (reg & BIT(12)));
-
-       if (reg & BIT(12)) {
-               mutex_unlock(&phydev->mdio.bus->mdio_lock);
-               return -ETIMEDOUT;
-       }
-
-       /* misccfg */
-       ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
-                                        PHY_S6G_MISC_CFG, 0);
-       if (ret)
-               goto err;
-
-       phy_commit_mcb_s6g(phydev, PHY_MCB_S6G_CFG, 0);
-
-       deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
-       do {
-               usleep_range(500, 1000);
-               phy_update_mcb_s6g(phydev, PHY_MCB_S6G_CFG,
-                                  0); /* read 6G MCB into CSRs */
-               reg = vsc85xx_csr_ctrl_phy_read(phydev, PHY_MCB_TARGET,
-                                               PHY_S6G_IB_STATUS0);
-               if (reg == 0xffffffff) {
-                       mutex_unlock(&phydev->mdio.bus->mdio_lock);
-                       return -EIO;
-               }
-
-       } while (time_before(jiffies, deadline) && !(reg & BIT(8)));
-
-       if (!(reg & BIT(8))) {
-               mutex_unlock(&phydev->mdio.bus->mdio_lock);
-               return -ETIMEDOUT;
-       }
-
-       mutex_unlock(&phydev->mdio.bus->mdio_lock);
-
-       ret = phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
-
-       if (ret)
-               return ret;
-
-       ret = phy_modify(phydev, MSCC_PHY_EXT_PHY_CNTL_1, MEDIA_OP_MODE_MASK,
-                        MEDIA_OP_MODE_COPPER << MEDIA_OP_MODE_POS);
-
-       if (ret)
-               return ret;
-
-       ret = genphy_soft_reset(phydev);
-
-       if (ret)
-               return ret;
-
-       for (i = 0; i < vsc8531->nleds; i++) {
-               ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
-               if (ret)
-                       return ret;
-       }
-
-       return ret;
-
-err:
-       mutex_unlock(&phydev->mdio.bus->mdio_lock);
-       return ret;
-}
-
-static int vsc85xx_ack_interrupt(struct phy_device *phydev)
-{
-       int rc = 0;
-
-       if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
-               rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
-
-       return (rc < 0) ? rc : 0;
-}
-
-static int vsc85xx_config_intr(struct phy_device *phydev)
-{
-       int rc;
-
-       if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
-#if IS_ENABLED(CONFIG_MACSEC)
-               phy_write(phydev, MSCC_EXT_PAGE_ACCESS,
-                         MSCC_PHY_PAGE_EXTENDED_2);
-               phy_write(phydev, MSCC_PHY_EXTENDED_INT,
-                         MSCC_PHY_EXTENDED_INT_MS_EGR);
-               phy_write(phydev, MSCC_EXT_PAGE_ACCESS,
-                         MSCC_PHY_PAGE_STANDARD);
-
-               vsc8584_macsec_phy_write(phydev, MACSEC_EGR,
-                                        MSCC_MS_AIC_CTRL, 0xf);
-               vsc8584_macsec_phy_write(phydev, MACSEC_EGR,
-                       MSCC_MS_INTR_CTRL_STATUS,
-                       MSCC_MS_INTR_CTRL_STATUS_INTR_ENABLE(MACSEC_INTR_CTRL_STATUS_ROLLOVER));
-#endif
-               rc = phy_write(phydev, MII_VSC85XX_INT_MASK,
-                              MII_VSC85XX_INT_MASK_MASK);
-       } else {
-               rc = phy_write(phydev, MII_VSC85XX_INT_MASK, 0);
-               if (rc < 0)
-                       return rc;
-               rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
-       }
-
-       return rc;
-}
-
-static int vsc85xx_config_aneg(struct phy_device *phydev)
-{
-       int rc;
-
-       rc = vsc85xx_mdix_set(phydev, phydev->mdix_ctrl);
-       if (rc < 0)
-               return rc;
-
-       return genphy_config_aneg(phydev);
-}
-
-static int vsc85xx_read_status(struct phy_device *phydev)
-{
-       int rc;
-
-       rc = vsc85xx_mdix_get(phydev, &phydev->mdix);
-       if (rc < 0)
-               return rc;
-
-       return genphy_read_status(phydev);
-}
-
-static int vsc8514_probe(struct phy_device *phydev)
-{
-       struct vsc8531_private *vsc8531;
-       u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
-          VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
-          VSC8531_DUPLEX_COLLISION};
-
-       vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
-       if (!vsc8531)
-               return -ENOMEM;
-
-       phydev->priv = vsc8531;
-
-       vsc8531->nleds = 4;
-       vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES;
-       vsc8531->hw_stats = vsc85xx_hw_stats;
-       vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats);
-       vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
-                                     sizeof(u64), GFP_KERNEL);
-       if (!vsc8531->stats)
-               return -ENOMEM;
-
-       return vsc85xx_dt_led_modes_get(phydev, default_mode);
-}
-
-static int vsc8574_probe(struct phy_device *phydev)
-{
-       struct vsc8531_private *vsc8531;
-       u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
-          VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
-          VSC8531_DUPLEX_COLLISION};
-
-       vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
-       if (!vsc8531)
-               return -ENOMEM;
-
-       phydev->priv = vsc8531;
-
-       vsc8531->nleds = 4;
-       vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES;
-       vsc8531->hw_stats = vsc8584_hw_stats;
-       vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats);
-       vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
-                                     sizeof(u64), GFP_KERNEL);
-       if (!vsc8531->stats)
-               return -ENOMEM;
-
-       return vsc85xx_dt_led_modes_get(phydev, default_mode);
-}
-
-static int vsc8584_probe(struct phy_device *phydev)
-{
-       struct vsc8531_private *vsc8531;
-       u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
-          VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
-          VSC8531_DUPLEX_COLLISION};
-
-       if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) {
-               dev_err(&phydev->mdio.dev, "Only VSC8584 revB is supported.\n");
-               return -ENOTSUPP;
-       }
-
-       vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
-       if (!vsc8531)
-               return -ENOMEM;
-
-       phydev->priv = vsc8531;
-
-       vsc8531->nleds = 4;
-       vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES;
-       vsc8531->hw_stats = vsc8584_hw_stats;
-       vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats);
-       vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
-                                     sizeof(u64), GFP_KERNEL);
-       if (!vsc8531->stats)
-               return -ENOMEM;
-
-       return vsc85xx_dt_led_modes_get(phydev, default_mode);
-}
-
-static int vsc85xx_probe(struct phy_device *phydev)
-{
-       struct vsc8531_private *vsc8531;
-       int rate_magic;
-       u32 default_mode[2] = {VSC8531_LINK_1000_ACTIVITY,
-          VSC8531_LINK_100_ACTIVITY};
-
-       rate_magic = vsc85xx_edge_rate_magic_get(phydev);
-       if (rate_magic < 0)
-               return rate_magic;
-
-       vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
-       if (!vsc8531)
-               return -ENOMEM;
-
-       phydev->priv = vsc8531;
-
-       vsc8531->rate_magic = rate_magic;
-       vsc8531->nleds = 2;
-       vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES;
-       vsc8531->hw_stats = vsc85xx_hw_stats;
-       vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats);
-       vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
-                                     sizeof(u64), GFP_KERNEL);
-       if (!vsc8531->stats)
-               return -ENOMEM;
-
-       return vsc85xx_dt_led_modes_get(phydev, default_mode);
-}
-
-/* Microsemi VSC85xx PHYs */
-static struct phy_driver vsc85xx_driver[] = {
-{
-       .phy_id         = PHY_ID_VSC8504,
-       .name           = "Microsemi GE VSC8504 SyncE",
-       .phy_id_mask    = 0xfffffff0,
-       /* PHY_GBIT_FEATURES */
-       .soft_reset     = &genphy_soft_reset,
-       .config_init    = &vsc8584_config_init,
-       .config_aneg    = &vsc85xx_config_aneg,
-       .aneg_done      = &genphy_aneg_done,
-       .read_status    = &vsc85xx_read_status,
-       .ack_interrupt  = &vsc85xx_ack_interrupt,
-       .config_intr    = &vsc85xx_config_intr,
-       .did_interrupt  = &vsc8584_did_interrupt,
-       .suspend        = &genphy_suspend,
-       .resume         = &genphy_resume,
-       .probe          = &vsc8574_probe,
-       .set_wol        = &vsc85xx_wol_set,
-       .get_wol        = &vsc85xx_wol_get,
-       .get_tunable    = &vsc85xx_get_tunable,
-       .set_tunable    = &vsc85xx_set_tunable,
-       .read_page      = &vsc85xx_phy_read_page,
-       .write_page     = &vsc85xx_phy_write_page,
-       .get_sset_count = &vsc85xx_get_sset_count,
-       .get_strings    = &vsc85xx_get_strings,
-       .get_stats      = &vsc85xx_get_stats,
-},
-{
-       .phy_id         = PHY_ID_VSC8514,
-       .name           = "Microsemi GE VSC8514 SyncE",
-       .phy_id_mask    = 0xfffffff0,
-       .soft_reset     = &genphy_soft_reset,
-       .config_init    = &vsc8514_config_init,
-       .config_aneg    = &vsc85xx_config_aneg,
-       .read_status    = &vsc85xx_read_status,
-       .ack_interrupt  = &vsc85xx_ack_interrupt,
-       .config_intr    = &vsc85xx_config_intr,
-       .suspend        = &genphy_suspend,
-       .resume         = &genphy_resume,
-       .probe          = &vsc8514_probe,
-       .set_wol        = &vsc85xx_wol_set,
-       .get_wol        = &vsc85xx_wol_get,
-       .get_tunable    = &vsc85xx_get_tunable,
-       .set_tunable    = &vsc85xx_set_tunable,
-       .read_page      = &vsc85xx_phy_read_page,
-       .write_page     = &vsc85xx_phy_write_page,
-       .get_sset_count = &vsc85xx_get_sset_count,
-       .get_strings    = &vsc85xx_get_strings,
-       .get_stats      = &vsc85xx_get_stats,
-},
-{
-       .phy_id         = PHY_ID_VSC8530,
-       .name           = "Microsemi FE VSC8530",
-       .phy_id_mask    = 0xfffffff0,
-       /* PHY_BASIC_FEATURES */
-       .soft_reset     = &genphy_soft_reset,
-       .config_init    = &vsc85xx_config_init,
-       .config_aneg    = &vsc85xx_config_aneg,
-       .read_status    = &vsc85xx_read_status,
-       .ack_interrupt  = &vsc85xx_ack_interrupt,
-       .config_intr    = &vsc85xx_config_intr,
-       .suspend        = &genphy_suspend,
-       .resume         = &genphy_resume,
-       .probe          = &vsc85xx_probe,
-       .set_wol        = &vsc85xx_wol_set,
-       .get_wol        = &vsc85xx_wol_get,
-       .get_tunable    = &vsc85xx_get_tunable,
-       .set_tunable    = &vsc85xx_set_tunable,
-       .read_page      = &vsc85xx_phy_read_page,
-       .write_page     = &vsc85xx_phy_write_page,
-       .get_sset_count = &vsc85xx_get_sset_count,
-       .get_strings    = &vsc85xx_get_strings,
-       .get_stats      = &vsc85xx_get_stats,
-},
-{
-       .phy_id         = PHY_ID_VSC8531,
-       .name           = "Microsemi VSC8531",
-       .phy_id_mask    = 0xfffffff0,
-       /* PHY_GBIT_FEATURES */
-       .soft_reset     = &genphy_soft_reset,
-       .config_init    = &vsc85xx_config_init,
-       .config_aneg    = &vsc85xx_config_aneg,
-       .read_status    = &vsc85xx_read_status,
-       .ack_interrupt  = &vsc85xx_ack_interrupt,
-       .config_intr    = &vsc85xx_config_intr,
-       .suspend        = &genphy_suspend,
-       .resume         = &genphy_resume,
-       .probe          = &vsc85xx_probe,
-       .set_wol        = &vsc85xx_wol_set,
-       .get_wol        = &vsc85xx_wol_get,
-       .get_tunable    = &vsc85xx_get_tunable,
-       .set_tunable    = &vsc85xx_set_tunable,
-       .read_page      = &vsc85xx_phy_read_page,
-       .write_page     = &vsc85xx_phy_write_page,
-       .get_sset_count = &vsc85xx_get_sset_count,
-       .get_strings    = &vsc85xx_get_strings,
-       .get_stats      = &vsc85xx_get_stats,
-},
-{
-       .phy_id         = PHY_ID_VSC8540,
-       .name           = "Microsemi FE VSC8540 SyncE",
-       .phy_id_mask    = 0xfffffff0,
-       /* PHY_BASIC_FEATURES */
-       .soft_reset     = &genphy_soft_reset,
-       .config_init    = &vsc85xx_config_init,
-       .config_aneg    = &vsc85xx_config_aneg,
-       .read_status    = &vsc85xx_read_status,
-       .ack_interrupt  = &vsc85xx_ack_interrupt,
-       .config_intr    = &vsc85xx_config_intr,
-       .suspend        = &genphy_suspend,
-       .resume         = &genphy_resume,
-       .probe          = &vsc85xx_probe,
-       .set_wol        = &vsc85xx_wol_set,
-       .get_wol        = &vsc85xx_wol_get,
-       .get_tunable    = &vsc85xx_get_tunable,
-       .set_tunable    = &vsc85xx_set_tunable,
-       .read_page      = &vsc85xx_phy_read_page,
-       .write_page     = &vsc85xx_phy_write_page,
-       .get_sset_count = &vsc85xx_get_sset_count,
-       .get_strings    = &vsc85xx_get_strings,
-       .get_stats      = &vsc85xx_get_stats,
-},
-{
-       .phy_id         = PHY_ID_VSC8541,
-       .name           = "Microsemi VSC8541 SyncE",
-       .phy_id_mask    = 0xfffffff0,
-       /* PHY_GBIT_FEATURES */
-       .soft_reset     = &genphy_soft_reset,
-       .config_init    = &vsc85xx_config_init,
-       .config_aneg    = &vsc85xx_config_aneg,
-       .read_status    = &vsc85xx_read_status,
-       .ack_interrupt  = &vsc85xx_ack_interrupt,
-       .config_intr    = &vsc85xx_config_intr,
-       .suspend        = &genphy_suspend,
-       .resume         = &genphy_resume,
-       .probe          = &vsc85xx_probe,
-       .set_wol        = &vsc85xx_wol_set,
-       .get_wol        = &vsc85xx_wol_get,
-       .get_tunable    = &vsc85xx_get_tunable,
-       .set_tunable    = &vsc85xx_set_tunable,
-       .read_page      = &vsc85xx_phy_read_page,
-       .write_page     = &vsc85xx_phy_write_page,
-       .get_sset_count = &vsc85xx_get_sset_count,
-       .get_strings    = &vsc85xx_get_strings,
-       .get_stats      = &vsc85xx_get_stats,
-},
-{
-       .phy_id         = PHY_ID_VSC8552,
-       .name           = "Microsemi GE VSC8552 SyncE",
-       .phy_id_mask    = 0xfffffff0,
-       /* PHY_GBIT_FEATURES */
-       .soft_reset     = &genphy_soft_reset,
-       .config_init    = &vsc8584_config_init,
-       .config_aneg    = &vsc85xx_config_aneg,
-       .read_status    = &vsc85xx_read_status,
-       .ack_interrupt  = &vsc85xx_ack_interrupt,
-       .config_intr    = &vsc85xx_config_intr,
-       .did_interrupt  = &vsc8584_did_interrupt,
-       .suspend        = &genphy_suspend,
-       .resume         = &genphy_resume,
-       .probe          = &vsc8574_probe,
-       .set_wol        = &vsc85xx_wol_set,
-       .get_wol        = &vsc85xx_wol_get,
-       .get_tunable    = &vsc85xx_get_tunable,
-       .set_tunable    = &vsc85xx_set_tunable,
-       .read_page      = &vsc85xx_phy_read_page,
-       .write_page     = &vsc85xx_phy_write_page,
-       .get_sset_count = &vsc85xx_get_sset_count,
-       .get_strings    = &vsc85xx_get_strings,
-       .get_stats      = &vsc85xx_get_stats,
-},
-{
-       .phy_id         = PHY_ID_VSC856X,
-       .name           = "Microsemi GE VSC856X SyncE",
-       .phy_id_mask    = 0xfffffff0,
-       /* PHY_GBIT_FEATURES */
-       .soft_reset     = &genphy_soft_reset,
-       .config_init    = &vsc8584_config_init,
-       .config_aneg    = &vsc85xx_config_aneg,
-       .read_status    = &vsc85xx_read_status,
-       .ack_interrupt  = &vsc85xx_ack_interrupt,
-       .config_intr    = &vsc85xx_config_intr,
-       .did_interrupt  = &vsc8584_did_interrupt,
-       .suspend        = &genphy_suspend,
-       .resume         = &genphy_resume,
-       .probe          = &vsc8584_probe,
-       .get_tunable    = &vsc85xx_get_tunable,
-       .set_tunable    = &vsc85xx_set_tunable,
-       .read_page      = &vsc85xx_phy_read_page,
-       .write_page     = &vsc85xx_phy_write_page,
-       .get_sset_count = &vsc85xx_get_sset_count,
-       .get_strings    = &vsc85xx_get_strings,
-       .get_stats      = &vsc85xx_get_stats,
-},
-{
-       .phy_id         = PHY_ID_VSC8572,
-       .name           = "Microsemi GE VSC8572 SyncE",
-       .phy_id_mask    = 0xfffffff0,
-       /* PHY_GBIT_FEATURES */
-       .soft_reset     = &genphy_soft_reset,
-       .config_init    = &vsc8584_config_init,
-       .config_aneg    = &vsc85xx_config_aneg,
-       .aneg_done      = &genphy_aneg_done,
-       .read_status    = &vsc85xx_read_status,
-       .handle_interrupt = &vsc8584_handle_interrupt,
-       .ack_interrupt  = &vsc85xx_ack_interrupt,
-       .config_intr    = &vsc85xx_config_intr,
-       .did_interrupt  = &vsc8584_did_interrupt,
-       .suspend        = &genphy_suspend,
-       .resume         = &genphy_resume,
-       .probe          = &vsc8574_probe,
-       .set_wol        = &vsc85xx_wol_set,
-       .get_wol        = &vsc85xx_wol_get,
-       .get_tunable    = &vsc85xx_get_tunable,
-       .set_tunable    = &vsc85xx_set_tunable,
-       .read_page      = &vsc85xx_phy_read_page,
-       .write_page     = &vsc85xx_phy_write_page,
-       .get_sset_count = &vsc85xx_get_sset_count,
-       .get_strings    = &vsc85xx_get_strings,
-       .get_stats      = &vsc85xx_get_stats,
-},
-{
-       .phy_id         = PHY_ID_VSC8574,
-       .name           = "Microsemi GE VSC8574 SyncE",
-       .phy_id_mask    = 0xfffffff0,
-       /* PHY_GBIT_FEATURES */
-       .soft_reset     = &genphy_soft_reset,
-       .config_init    = &vsc8584_config_init,
-       .config_aneg    = &vsc85xx_config_aneg,
-       .aneg_done      = &genphy_aneg_done,
-       .read_status    = &vsc85xx_read_status,
-       .ack_interrupt  = &vsc85xx_ack_interrupt,
-       .config_intr    = &vsc85xx_config_intr,
-       .did_interrupt  = &vsc8584_did_interrupt,
-       .suspend        = &genphy_suspend,
-       .resume         = &genphy_resume,
-       .probe          = &vsc8574_probe,
-       .set_wol        = &vsc85xx_wol_set,
-       .get_wol        = &vsc85xx_wol_get,
-       .get_tunable    = &vsc85xx_get_tunable,
-       .set_tunable    = &vsc85xx_set_tunable,
-       .read_page      = &vsc85xx_phy_read_page,
-       .write_page     = &vsc85xx_phy_write_page,
-       .get_sset_count = &vsc85xx_get_sset_count,
-       .get_strings    = &vsc85xx_get_strings,
-       .get_stats      = &vsc85xx_get_stats,
-},
-{
-       .phy_id         = PHY_ID_VSC8575,
-       .name           = "Microsemi GE VSC8575 SyncE",
-       .phy_id_mask    = 0xfffffff0,
-       /* PHY_GBIT_FEATURES */
-       .soft_reset     = &genphy_soft_reset,
-       .config_init    = &vsc8584_config_init,
-       .config_aneg    = &vsc85xx_config_aneg,
-       .aneg_done      = &genphy_aneg_done,
-       .read_status    = &vsc85xx_read_status,
-       .handle_interrupt = &vsc8584_handle_interrupt,
-       .ack_interrupt  = &vsc85xx_ack_interrupt,
-       .config_intr    = &vsc85xx_config_intr,
-       .did_interrupt  = &vsc8584_did_interrupt,
-       .suspend        = &genphy_suspend,
-       .resume         = &genphy_resume,
-       .probe          = &vsc8584_probe,
-       .get_tunable    = &vsc85xx_get_tunable,
-       .set_tunable    = &vsc85xx_set_tunable,
-       .read_page      = &vsc85xx_phy_read_page,
-       .write_page     = &vsc85xx_phy_write_page,
-       .get_sset_count = &vsc85xx_get_sset_count,
-       .get_strings    = &vsc85xx_get_strings,
-       .get_stats      = &vsc85xx_get_stats,
-},
-{
-       .phy_id         = PHY_ID_VSC8582,
-       .name           = "Microsemi GE VSC8582 SyncE",
-       .phy_id_mask    = 0xfffffff0,
-       /* PHY_GBIT_FEATURES */
-       .soft_reset     = &genphy_soft_reset,
-       .config_init    = &vsc8584_config_init,
-       .config_aneg    = &vsc85xx_config_aneg,
-       .aneg_done      = &genphy_aneg_done,
-       .read_status    = &vsc85xx_read_status,
-       .handle_interrupt = &vsc8584_handle_interrupt,
-       .ack_interrupt  = &vsc85xx_ack_interrupt,
-       .config_intr    = &vsc85xx_config_intr,
-       .did_interrupt  = &vsc8584_did_interrupt,
-       .suspend        = &genphy_suspend,
-       .resume         = &genphy_resume,
-       .probe          = &vsc8584_probe,
-       .get_tunable    = &vsc85xx_get_tunable,
-       .set_tunable    = &vsc85xx_set_tunable,
-       .read_page      = &vsc85xx_phy_read_page,
-       .write_page     = &vsc85xx_phy_write_page,
-       .get_sset_count = &vsc85xx_get_sset_count,
-       .get_strings    = &vsc85xx_get_strings,
-       .get_stats      = &vsc85xx_get_stats,
-},
-{
-       .phy_id         = PHY_ID_VSC8584,
-       .name           = "Microsemi GE VSC8584 SyncE",
-       .phy_id_mask    = 0xfffffff0,
-       /* PHY_GBIT_FEATURES */
-       .soft_reset     = &genphy_soft_reset,
-       .config_init    = &vsc8584_config_init,
-       .config_aneg    = &vsc85xx_config_aneg,
-       .aneg_done      = &genphy_aneg_done,
-       .read_status    = &vsc85xx_read_status,
-       .handle_interrupt = &vsc8584_handle_interrupt,
-       .ack_interrupt  = &vsc85xx_ack_interrupt,
-       .config_intr    = &vsc85xx_config_intr,
-       .did_interrupt  = &vsc8584_did_interrupt,
-       .suspend        = &genphy_suspend,
-       .resume         = &genphy_resume,
-       .probe          = &vsc8584_probe,
-       .get_tunable    = &vsc85xx_get_tunable,
-       .set_tunable    = &vsc85xx_set_tunable,
-       .read_page      = &vsc85xx_phy_read_page,
-       .write_page     = &vsc85xx_phy_write_page,
-       .get_sset_count = &vsc85xx_get_sset_count,
-       .get_strings    = &vsc85xx_get_strings,
-       .get_stats      = &vsc85xx_get_stats,
-}
-
-};
-
-module_phy_driver(vsc85xx_driver);
-
-static struct mdio_device_id __maybe_unused vsc85xx_tbl[] = {
-       { PHY_ID_VSC8504, 0xfffffff0, },
-       { PHY_ID_VSC8514, 0xfffffff0, },
-       { PHY_ID_VSC8530, 0xfffffff0, },
-       { PHY_ID_VSC8531, 0xfffffff0, },
-       { PHY_ID_VSC8540, 0xfffffff0, },
-       { PHY_ID_VSC8541, 0xfffffff0, },
-       { PHY_ID_VSC8552, 0xfffffff0, },
-       { PHY_ID_VSC856X, 0xfffffff0, },
-       { PHY_ID_VSC8572, 0xfffffff0, },
-       { PHY_ID_VSC8574, 0xfffffff0, },
-       { PHY_ID_VSC8575, 0xfffffff0, },
-       { PHY_ID_VSC8582, 0xfffffff0, },
-       { PHY_ID_VSC8584, 0xfffffff0, },
-       { }
-};
-
-MODULE_DEVICE_TABLE(mdio, vsc85xx_tbl);
-
-MODULE_DESCRIPTION("Microsemi VSC85xx PHY driver");
-MODULE_AUTHOR("Nagaraju Lakkaraju");
-MODULE_LICENSE("Dual MIT/GPL");
diff --git a/drivers/net/phy/mscc/Makefile b/drivers/net/phy/mscc/Makefile
new file mode 100644 (file)
index 0000000..e419ed1
--- /dev/null
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for MSCC networking PHY driver
+
+obj-$(CONFIG_MICROSEMI_PHY) += mscc.o
diff --git a/drivers/net/phy/mscc/mscc.c b/drivers/net/phy/mscc/mscc.c
new file mode 100644 (file)
index 0000000..b2eac7e
--- /dev/null
@@ -0,0 +1,3830 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Driver for Microsemi VSC85xx PHYs
+ *
+ * Author: Nagaraju Lakkaraju
+ * License: Dual MIT/GPL
+ * Copyright (c) 2016 Microsemi Corporation
+ */
+
+#include <linux/firmware.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mdio.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/of.h>
+#include <linux/netdevice.h>
+#include <dt-bindings/net/mscc-phy-vsc8531.h>
+
+#include <linux/scatterlist.h>
+#include <crypto/skcipher.h>
+
+#if IS_ENABLED(CONFIG_MACSEC)
+#include <net/macsec.h>
+#endif
+
+#include "mscc_macsec.h"
+#include "mscc_mac.h"
+#include "mscc_fc_buffer.h"
+
+enum rgmii_rx_clock_delay {
+       RGMII_RX_CLK_DELAY_0_2_NS = 0,
+       RGMII_RX_CLK_DELAY_0_8_NS = 1,
+       RGMII_RX_CLK_DELAY_1_1_NS = 2,
+       RGMII_RX_CLK_DELAY_1_7_NS = 3,
+       RGMII_RX_CLK_DELAY_2_0_NS = 4,
+       RGMII_RX_CLK_DELAY_2_3_NS = 5,
+       RGMII_RX_CLK_DELAY_2_6_NS = 6,
+       RGMII_RX_CLK_DELAY_3_4_NS = 7
+};
+
+/* Microsemi VSC85xx PHY registers */
+/* IEEE 802. Std Registers */
+#define MSCC_PHY_BYPASS_CONTROL                  18
+#define DISABLE_HP_AUTO_MDIX_MASK        0x0080
+#define DISABLE_PAIR_SWAP_CORR_MASK      0x0020
+#define DISABLE_POLARITY_CORR_MASK       0x0010
+#define PARALLEL_DET_IGNORE_ADVERTISED    0x0008
+
+#define MSCC_PHY_EXT_CNTL_STATUS          22
+#define SMI_BROADCAST_WR_EN              0x0001
+
+#define MSCC_PHY_ERR_RX_CNT              19
+#define MSCC_PHY_ERR_FALSE_CARRIER_CNT   20
+#define MSCC_PHY_ERR_LINK_DISCONNECT_CNT  21
+#define ERR_CNT_MASK                     GENMASK(7, 0)
+
+#define MSCC_PHY_EXT_PHY_CNTL_1           23
+#define MAC_IF_SELECTION_MASK             0x1800
+#define MAC_IF_SELECTION_GMII             0
+#define MAC_IF_SELECTION_RMII             1
+#define MAC_IF_SELECTION_RGMII            2
+#define MAC_IF_SELECTION_POS              11
+#define VSC8584_MAC_IF_SELECTION_MASK     0x1000
+#define VSC8584_MAC_IF_SELECTION_SGMII    0
+#define VSC8584_MAC_IF_SELECTION_1000BASEX 1
+#define VSC8584_MAC_IF_SELECTION_POS      12
+#define FAR_END_LOOPBACK_MODE_MASK        0x0008
+#define MEDIA_OP_MODE_MASK               0x0700
+#define MEDIA_OP_MODE_COPPER             0
+#define MEDIA_OP_MODE_SERDES             1
+#define MEDIA_OP_MODE_1000BASEX                  2
+#define MEDIA_OP_MODE_100BASEFX                  3
+#define MEDIA_OP_MODE_AMS_COPPER_SERDES          5
+#define MEDIA_OP_MODE_AMS_COPPER_1000BASEX     6
+#define MEDIA_OP_MODE_AMS_COPPER_100BASEFX     7
+#define MEDIA_OP_MODE_POS                8
+
+#define MSCC_PHY_EXT_PHY_CNTL_2                  24
+
+#define MII_VSC85XX_INT_MASK             25
+#define MII_VSC85XX_INT_MASK_MDINT       BIT(15)
+#define MII_VSC85XX_INT_MASK_LINK_CHG    BIT(13)
+#define MII_VSC85XX_INT_MASK_WOL         BIT(6)
+#define MII_VSC85XX_INT_MASK_EXT         BIT(5)
+#define MII_VSC85XX_INT_STATUS           26
+
+#define MII_VSC85XX_INT_MASK_MASK        (MII_VSC85XX_INT_MASK_MDINT    | \
+                                          MII_VSC85XX_INT_MASK_LINK_CHG | \
+                                          MII_VSC85XX_INT_MASK_EXT)
+
+#define MSCC_PHY_WOL_MAC_CONTROL          27
+#define EDGE_RATE_CNTL_POS                5
+#define EDGE_RATE_CNTL_MASK               0x00E0
+
+#define MSCC_PHY_DEV_AUX_CNTL            28
+#define HP_AUTO_MDIX_X_OVER_IND_MASK     0x2000
+
+#define MSCC_PHY_LED_MODE_SEL            29
+#define LED_MODE_SEL_POS(x)              ((x) * 4)
+#define LED_MODE_SEL_MASK(x)             (GENMASK(3, 0) << LED_MODE_SEL_POS(x))
+#define LED_MODE_SEL(x, mode)            (((mode) << LED_MODE_SEL_POS(x)) & LED_MODE_SEL_MASK(x))
+
+#define MSCC_EXT_PAGE_CSR_CNTL_17        17
+#define MSCC_EXT_PAGE_CSR_CNTL_18        18
+
+#define MSCC_EXT_PAGE_CSR_CNTL_19        19
+#define MSCC_PHY_CSR_CNTL_19_REG_ADDR(x)  (x)
+#define MSCC_PHY_CSR_CNTL_19_TARGET(x)   ((x) << 12)
+#define MSCC_PHY_CSR_CNTL_19_READ        BIT(14)
+#define MSCC_PHY_CSR_CNTL_19_CMD         BIT(15)
+
+#define MSCC_EXT_PAGE_CSR_CNTL_20        20
+#define MSCC_PHY_CSR_CNTL_20_TARGET(x)   (x)
+
+#define PHY_MCB_TARGET                   0x07
+#define PHY_MCB_S6G_WRITE                BIT(31)
+#define PHY_MCB_S6G_READ                 BIT(30)
+
+#define PHY_S6G_PLL5G_CFG0               0x06
+#define PHY_S6G_LCPLL_CFG                0x11
+#define PHY_S6G_PLL_CFG                          0x2b
+#define PHY_S6G_COMMON_CFG               0x2c
+#define PHY_S6G_GPC_CFG                          0x2e
+#define PHY_S6G_MISC_CFG                 0x3b
+#define PHY_MCB_S6G_CFG                          0x3f
+#define PHY_S6G_DFT_CFG2                 0x3e
+#define PHY_S6G_PLL_STATUS               0x31
+#define PHY_S6G_IB_STATUS0               0x2f
+
+#define PHY_S6G_SYS_RST_POS              31
+#define PHY_S6G_ENA_LANE_POS             18
+#define PHY_S6G_ENA_LOOP_POS             8
+#define PHY_S6G_QRATE_POS                6
+#define PHY_S6G_IF_MODE_POS              4
+#define PHY_S6G_PLL_ENA_OFFS_POS         21
+#define PHY_S6G_PLL_FSM_CTRL_DATA_POS    8
+#define PHY_S6G_PLL_FSM_ENA_POS                  7
+
+#define MSCC_EXT_PAGE_MACSEC_17                  17
+#define MSCC_EXT_PAGE_MACSEC_18                  18
+
+#define MSCC_EXT_PAGE_MACSEC_19                  19
+#define MSCC_PHY_MACSEC_19_REG_ADDR(x)   (x)
+#define MSCC_PHY_MACSEC_19_TARGET(x)     ((x) << 12)
+#define MSCC_PHY_MACSEC_19_READ                  BIT(14)
+#define MSCC_PHY_MACSEC_19_CMD           BIT(15)
+
+#define MSCC_EXT_PAGE_MACSEC_20                  20
+#define MSCC_PHY_MACSEC_20_TARGET(x)     (x)
+enum macsec_bank {
+       FC_BUFFER   = 0x04,
+       HOST_MAC    = 0x05,
+       LINE_MAC    = 0x06,
+       IP_1588     = 0x0e,
+       MACSEC_INGR = 0x38,
+       MACSEC_EGR  = 0x3c,
+};
+
+#define MSCC_EXT_PAGE_ACCESS             31
+#define MSCC_PHY_PAGE_STANDARD           0x0000 /* Standard registers */
+#define MSCC_PHY_PAGE_EXTENDED           0x0001 /* Extended registers */
+#define MSCC_PHY_PAGE_EXTENDED_2         0x0002 /* Extended reg - page 2 */
+#define MSCC_PHY_PAGE_EXTENDED_3         0x0003 /* Extended reg - page 3 */
+#define MSCC_PHY_PAGE_EXTENDED_4         0x0004 /* Extended reg - page 4 */
+#define MSCC_PHY_PAGE_CSR_CNTL           MSCC_PHY_PAGE_EXTENDED_4
+#define MSCC_PHY_PAGE_MACSEC             MSCC_PHY_PAGE_EXTENDED_4
+/* Extended reg - GPIO; this is a bank of registers that are shared for all PHYs
+ * in the same package.
+ */
+#define MSCC_PHY_PAGE_EXTENDED_GPIO      0x0010 /* Extended reg - GPIO */
+#define MSCC_PHY_PAGE_TEST               0x2a30 /* Test reg */
+#define MSCC_PHY_PAGE_TR                 0x52b5 /* Token ring registers */
+
+/* Extended Page 1 Registers */
+#define MSCC_PHY_CU_MEDIA_CRC_VALID_CNT          18
+#define VALID_CRC_CNT_CRC_MASK           GENMASK(13, 0)
+
+#define MSCC_PHY_EXT_MODE_CNTL           19
+#define FORCE_MDI_CROSSOVER_MASK         0x000C
+#define FORCE_MDI_CROSSOVER_MDIX         0x000C
+#define FORCE_MDI_CROSSOVER_MDI                  0x0008
+
+#define MSCC_PHY_ACTIPHY_CNTL            20
+#define PHY_ADDR_REVERSED                0x0200
+#define DOWNSHIFT_CNTL_MASK              0x001C
+#define DOWNSHIFT_EN                     0x0010
+#define DOWNSHIFT_CNTL_POS               2
+
+#define MSCC_PHY_EXT_PHY_CNTL_4                  23
+#define PHY_CNTL_4_ADDR_POS              11
+
+#define MSCC_PHY_VERIPHY_CNTL_2                  25
+
+#define MSCC_PHY_VERIPHY_CNTL_3                  26
+
+/* Extended Page 2 Registers */
+#define MSCC_PHY_CU_PMD_TX_CNTL                  16
+
+#define MSCC_PHY_RGMII_CNTL              20
+#define RGMII_RX_CLK_DELAY_MASK                  0x0070
+#define RGMII_RX_CLK_DELAY_POS           4
+
+#define MSCC_PHY_WOL_LOWER_MAC_ADDR      21
+#define MSCC_PHY_WOL_MID_MAC_ADDR        22
+#define MSCC_PHY_WOL_UPPER_MAC_ADDR      23
+#define MSCC_PHY_WOL_LOWER_PASSWD        24
+#define MSCC_PHY_WOL_MID_PASSWD                  25
+#define MSCC_PHY_WOL_UPPER_PASSWD        26
+
+#define MSCC_PHY_WOL_MAC_CONTROL         27
+#define SECURE_ON_ENABLE                 0x8000
+#define SECURE_ON_PASSWD_LEN_4           0x4000
+
+#define MSCC_PHY_EXTENDED_INT            28
+#define MSCC_PHY_EXTENDED_INT_MS_EGR     BIT(9)
+
+/* Extended Page 3 Registers */
+#define MSCC_PHY_SERDES_TX_VALID_CNT     21
+#define MSCC_PHY_SERDES_TX_CRC_ERR_CNT   22
+#define MSCC_PHY_SERDES_RX_VALID_CNT     28
+#define MSCC_PHY_SERDES_RX_CRC_ERR_CNT   29
+
+/* Extended page GPIO Registers */
+#define MSCC_DW8051_CNTL_STATUS                  0
+#define MICRO_NSOFT_RESET                0x8000
+#define RUN_FROM_INT_ROM                 0x4000
+#define AUTOINC_ADDR                     0x2000
+#define PATCH_RAM_CLK                    0x1000
+#define MICRO_PATCH_EN                   0x0080
+#define DW8051_CLK_EN                    0x0010
+#define MICRO_CLK_EN                     0x0008
+#define MICRO_CLK_DIVIDE(x)              ((x) >> 1)
+#define MSCC_DW8051_VLD_MASK             0xf1ff
+
+/* x Address in range 1-4 */
+#define MSCC_TRAP_ROM_ADDR(x)            ((x) * 2 + 1)
+#define MSCC_PATCH_RAM_ADDR(x)           (((x) + 1) * 2)
+#define MSCC_INT_MEM_ADDR                11
+
+#define MSCC_INT_MEM_CNTL                12
+#define READ_SFR                         0x6000
+#define READ_PRAM                        0x4000
+#define READ_ROM                         0x2000
+#define READ_RAM                         0x0000
+#define INT_MEM_WRITE_EN                 0x1000
+#define EN_PATCH_RAM_TRAP_ADDR(x)        (0x0100 << ((x) - 1))
+#define INT_MEM_DATA_M                   0x00ff
+#define INT_MEM_DATA(x)                          (INT_MEM_DATA_M & (x))
+
+#define MSCC_PHY_PROC_CMD                18
+#define PROC_CMD_NCOMPLETED              0x8000
+#define PROC_CMD_FAILED                          0x4000
+#define PROC_CMD_SGMII_PORT(x)           ((x) << 8)
+#define PROC_CMD_FIBER_PORT(x)           (0x0100 << (x) % 4)
+#define PROC_CMD_QSGMII_PORT             0x0c00
+#define PROC_CMD_RST_CONF_PORT           0x0080
+#define PROC_CMD_RECONF_PORT             0x0000
+#define PROC_CMD_READ_MOD_WRITE_PORT     0x0040
+#define PROC_CMD_WRITE                   0x0040
+#define PROC_CMD_READ                    0x0000
+#define PROC_CMD_FIBER_DISABLE           0x0020
+#define PROC_CMD_FIBER_100BASE_FX        0x0010
+#define PROC_CMD_FIBER_1000BASE_X        0x0000
+#define PROC_CMD_SGMII_MAC               0x0030
+#define PROC_CMD_QSGMII_MAC              0x0020
+#define PROC_CMD_NO_MAC_CONF             0x0000
+#define PROC_CMD_1588_DEFAULT_INIT       0x0010
+#define PROC_CMD_NOP                     0x000f
+#define PROC_CMD_PHY_INIT                0x000a
+#define PROC_CMD_CRC16                   0x0008
+#define PROC_CMD_FIBER_MEDIA_CONF        0x0001
+#define PROC_CMD_MCB_ACCESS_MAC_CONF     0x0000
+#define PROC_CMD_NCOMPLETED_TIMEOUT_MS    500
+
+#define MSCC_PHY_MAC_CFG_FASTLINK        19
+#define MAC_CFG_MASK                     0xc000
+#define MAC_CFG_SGMII                    0x0000
+#define MAC_CFG_QSGMII                   0x4000
+
+/* Test page Registers */
+#define MSCC_PHY_TEST_PAGE_5             5
+#define MSCC_PHY_TEST_PAGE_8             8
+#define MSCC_PHY_TEST_PAGE_9             9
+#define MSCC_PHY_TEST_PAGE_20            20
+#define MSCC_PHY_TEST_PAGE_24            24
+
+/* Token ring page Registers */
+#define MSCC_PHY_TR_CNTL                 16
+#define TR_WRITE                         0x8000
+#define TR_ADDR(x)                       (0x7fff & (x))
+#define MSCC_PHY_TR_LSB                          17
+#define MSCC_PHY_TR_MSB                          18
+
+/* Microsemi PHY ID's
+ *   Code assumes lowest nibble is 0
+ */
+#define PHY_ID_VSC8504                   0x000704c0
+#define PHY_ID_VSC8514                   0x00070670
+#define PHY_ID_VSC8530                   0x00070560
+#define PHY_ID_VSC8531                   0x00070570
+#define PHY_ID_VSC8540                   0x00070760
+#define PHY_ID_VSC8541                   0x00070770
+#define PHY_ID_VSC8552                   0x000704e0
+#define PHY_ID_VSC856X                   0x000707e0
+#define PHY_ID_VSC8572                   0x000704d0
+#define PHY_ID_VSC8574                   0x000704a0
+#define PHY_ID_VSC8575                   0x000707d0
+#define PHY_ID_VSC8582                   0x000707b0
+#define PHY_ID_VSC8584                   0x000707c0
+
+#define MSCC_VDDMAC_1500                 1500
+#define MSCC_VDDMAC_1800                 1800
+#define MSCC_VDDMAC_2500                 2500
+#define MSCC_VDDMAC_3300                 3300
+
+#define DOWNSHIFT_COUNT_MAX              5
+
+#define MAX_LEDS                         4
+
+#define VSC8584_SUPP_LED_MODES (BIT(VSC8531_LINK_ACTIVITY) | \
+                               BIT(VSC8531_LINK_1000_ACTIVITY) | \
+                               BIT(VSC8531_LINK_100_ACTIVITY) | \
+                               BIT(VSC8531_LINK_10_ACTIVITY) | \
+                               BIT(VSC8531_LINK_100_1000_ACTIVITY) | \
+                               BIT(VSC8531_LINK_10_1000_ACTIVITY) | \
+                               BIT(VSC8531_LINK_10_100_ACTIVITY) | \
+                               BIT(VSC8584_LINK_100FX_1000X_ACTIVITY) | \
+                               BIT(VSC8531_DUPLEX_COLLISION) | \
+                               BIT(VSC8531_COLLISION) | \
+                               BIT(VSC8531_ACTIVITY) | \
+                               BIT(VSC8584_100FX_1000X_ACTIVITY) | \
+                               BIT(VSC8531_AUTONEG_FAULT) | \
+                               BIT(VSC8531_SERIAL_MODE) | \
+                               BIT(VSC8531_FORCE_LED_OFF) | \
+                               BIT(VSC8531_FORCE_LED_ON))
+
+#define VSC85XX_SUPP_LED_MODES (BIT(VSC8531_LINK_ACTIVITY) | \
+                               BIT(VSC8531_LINK_1000_ACTIVITY) | \
+                               BIT(VSC8531_LINK_100_ACTIVITY) | \
+                               BIT(VSC8531_LINK_10_ACTIVITY) | \
+                               BIT(VSC8531_LINK_100_1000_ACTIVITY) | \
+                               BIT(VSC8531_LINK_10_1000_ACTIVITY) | \
+                               BIT(VSC8531_LINK_10_100_ACTIVITY) | \
+                               BIT(VSC8531_DUPLEX_COLLISION) | \
+                               BIT(VSC8531_COLLISION) | \
+                               BIT(VSC8531_ACTIVITY) | \
+                               BIT(VSC8531_AUTONEG_FAULT) | \
+                               BIT(VSC8531_SERIAL_MODE) | \
+                               BIT(VSC8531_FORCE_LED_OFF) | \
+                               BIT(VSC8531_FORCE_LED_ON))
+
+#define MSCC_VSC8584_REVB_INT8051_FW           "microchip/mscc_vsc8584_revb_int8051_fb48.bin"
+#define MSCC_VSC8584_REVB_INT8051_FW_START_ADDR        0xe800
+#define MSCC_VSC8584_REVB_INT8051_FW_CRC       0xfb48
+
+#define MSCC_VSC8574_REVB_INT8051_FW           "microchip/mscc_vsc8574_revb_int8051_29e8.bin"
+#define MSCC_VSC8574_REVB_INT8051_FW_START_ADDR        0x4000
+#define MSCC_VSC8574_REVB_INT8051_FW_CRC       0x29e8
+
+#define VSC8584_REVB                           0x0001
+#define MSCC_DEV_REV_MASK                      GENMASK(3, 0)
+
+struct reg_val {
+       u16     reg;
+       u32     val;
+};
+
+struct vsc85xx_hw_stat {
+       const char *string;
+       u8 reg;
+       u16 page;
+       u16 mask;
+};
+
+static const struct vsc85xx_hw_stat vsc85xx_hw_stats[] = {
+       {
+               .string = "phy_receive_errors",
+               .reg    = MSCC_PHY_ERR_RX_CNT,
+               .page   = MSCC_PHY_PAGE_STANDARD,
+               .mask   = ERR_CNT_MASK,
+       }, {
+               .string = "phy_false_carrier",
+               .reg    = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
+               .page   = MSCC_PHY_PAGE_STANDARD,
+               .mask   = ERR_CNT_MASK,
+       }, {
+               .string = "phy_cu_media_link_disconnect",
+               .reg    = MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
+               .page   = MSCC_PHY_PAGE_STANDARD,
+               .mask   = ERR_CNT_MASK,
+       }, {
+               .string = "phy_cu_media_crc_good_count",
+               .reg    = MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
+               .page   = MSCC_PHY_PAGE_EXTENDED,
+               .mask   = VALID_CRC_CNT_CRC_MASK,
+       }, {
+               .string = "phy_cu_media_crc_error_count",
+               .reg    = MSCC_PHY_EXT_PHY_CNTL_4,
+               .page   = MSCC_PHY_PAGE_EXTENDED,
+               .mask   = ERR_CNT_MASK,
+       },
+};
+
+static const struct vsc85xx_hw_stat vsc8584_hw_stats[] = {
+       {
+               .string = "phy_receive_errors",
+               .reg    = MSCC_PHY_ERR_RX_CNT,
+               .page   = MSCC_PHY_PAGE_STANDARD,
+               .mask   = ERR_CNT_MASK,
+       }, {
+               .string = "phy_false_carrier",
+               .reg    = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
+               .page   = MSCC_PHY_PAGE_STANDARD,
+               .mask   = ERR_CNT_MASK,
+       }, {
+               .string = "phy_cu_media_link_disconnect",
+               .reg    = MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
+               .page   = MSCC_PHY_PAGE_STANDARD,
+               .mask   = ERR_CNT_MASK,
+       }, {
+               .string = "phy_cu_media_crc_good_count",
+               .reg    = MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
+               .page   = MSCC_PHY_PAGE_EXTENDED,
+               .mask   = VALID_CRC_CNT_CRC_MASK,
+       }, {
+               .string = "phy_cu_media_crc_error_count",
+               .reg    = MSCC_PHY_EXT_PHY_CNTL_4,
+               .page   = MSCC_PHY_PAGE_EXTENDED,
+               .mask   = ERR_CNT_MASK,
+       }, {
+               .string = "phy_serdes_tx_good_pkt_count",
+               .reg    = MSCC_PHY_SERDES_TX_VALID_CNT,
+               .page   = MSCC_PHY_PAGE_EXTENDED_3,
+               .mask   = VALID_CRC_CNT_CRC_MASK,
+       }, {
+               .string = "phy_serdes_tx_bad_crc_count",
+               .reg    = MSCC_PHY_SERDES_TX_CRC_ERR_CNT,
+               .page   = MSCC_PHY_PAGE_EXTENDED_3,
+               .mask   = ERR_CNT_MASK,
+       }, {
+               .string = "phy_serdes_rx_good_pkt_count",
+               .reg    = MSCC_PHY_SERDES_RX_VALID_CNT,
+               .page   = MSCC_PHY_PAGE_EXTENDED_3,
+               .mask   = VALID_CRC_CNT_CRC_MASK,
+       }, {
+               .string = "phy_serdes_rx_bad_crc_count",
+               .reg    = MSCC_PHY_SERDES_RX_CRC_ERR_CNT,
+               .page   = MSCC_PHY_PAGE_EXTENDED_3,
+               .mask   = ERR_CNT_MASK,
+       },
+};
+
+#if IS_ENABLED(CONFIG_MACSEC)
+struct macsec_flow {
+       struct list_head list;
+       enum mscc_macsec_destination_ports port;
+       enum macsec_bank bank;
+       u32 index;
+       int assoc_num;
+       bool has_transformation;
+
+       /* Highest takes precedence [0..15] */
+       u8 priority;
+
+       u8 key[MACSEC_KEYID_LEN];
+
+       union {
+               struct macsec_rx_sa *rx_sa;
+               struct macsec_tx_sa *tx_sa;
+       };
+
+       /* Matching */
+       struct {
+               u8 sci:1;
+               u8 tagged:1;
+               u8 untagged:1;
+               u8 etype:1;
+       } match;
+
+       u16 etype;
+
+       /* Action */
+       struct {
+               u8 bypass:1;
+               u8 drop:1;
+       } action;
+
+};
+#endif
+
+struct vsc8531_private {
+       int rate_magic;
+       u16 supp_led_modes;
+       u32 leds_mode[MAX_LEDS];
+       u8 nleds;
+       const struct vsc85xx_hw_stat *hw_stats;
+       u64 *stats;
+       int nstats;
+       bool pkg_init;
+       /* For multiple port PHYs; the MDIO address of the base PHY in the
+        * package.
+        */
+       unsigned int base_addr;
+
+#if IS_ENABLED(CONFIG_MACSEC)
+       /* MACsec fields:
+        * - One SecY per device (enforced at the s/w implementation level)
+        * - macsec_flows: list of h/w flows
+        * - ingr_flows: bitmap of ingress flows
+        * - egr_flows: bitmap of egress flows
+        */
+       struct macsec_secy *secy;
+       struct list_head macsec_flows;
+       unsigned long ingr_flows;
+       unsigned long egr_flows;
+#endif
+};
+
+#ifdef CONFIG_OF_MDIO
+struct vsc8531_edge_rate_table {
+       u32 vddmac;
+       u32 slowdown[8];
+};
+
+static const struct vsc8531_edge_rate_table edge_table[] = {
+       {MSCC_VDDMAC_3300, { 0, 2,  4,  7, 10, 17, 29, 53} },
+       {MSCC_VDDMAC_2500, { 0, 3,  6, 10, 14, 23, 37, 63} },
+       {MSCC_VDDMAC_1800, { 0, 5,  9, 16, 23, 35, 52, 76} },
+       {MSCC_VDDMAC_1500, { 0, 6, 14, 21, 29, 42, 58, 77} },
+};
+#endif /* CONFIG_OF_MDIO */
+
+static int vsc85xx_phy_read_page(struct phy_device *phydev)
+{
+       return __phy_read(phydev, MSCC_EXT_PAGE_ACCESS);
+}
+
+static int vsc85xx_phy_write_page(struct phy_device *phydev, int page)
+{
+       return __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, page);
+}
+
+static int vsc85xx_get_sset_count(struct phy_device *phydev)
+{
+       struct vsc8531_private *priv = phydev->priv;
+
+       if (!priv)
+               return 0;
+
+       return priv->nstats;
+}
+
+static void vsc85xx_get_strings(struct phy_device *phydev, u8 *data)
+{
+       struct vsc8531_private *priv = phydev->priv;
+       int i;
+
+       if (!priv)
+               return;
+
+       for (i = 0; i < priv->nstats; i++)
+               strlcpy(data + i * ETH_GSTRING_LEN, priv->hw_stats[i].string,
+                       ETH_GSTRING_LEN);
+}
+
+static u64 vsc85xx_get_stat(struct phy_device *phydev, int i)
+{
+       struct vsc8531_private *priv = phydev->priv;
+       int val;
+
+       val = phy_read_paged(phydev, priv->hw_stats[i].page,
+                            priv->hw_stats[i].reg);
+       if (val < 0)
+               return U64_MAX;
+
+       val = val & priv->hw_stats[i].mask;
+       priv->stats[i] += val;
+
+       return priv->stats[i];
+}
+
+static void vsc85xx_get_stats(struct phy_device *phydev,
+                             struct ethtool_stats *stats, u64 *data)
+{
+       struct vsc8531_private *priv = phydev->priv;
+       int i;
+
+       if (!priv)
+               return;
+
+       for (i = 0; i < priv->nstats; i++)
+               data[i] = vsc85xx_get_stat(phydev, i);
+}
+
+static int vsc85xx_led_cntl_set(struct phy_device *phydev,
+                               u8 led_num,
+                               u8 mode)
+{
+       int rc;
+       u16 reg_val;
+
+       mutex_lock(&phydev->lock);
+       reg_val = phy_read(phydev, MSCC_PHY_LED_MODE_SEL);
+       reg_val &= ~LED_MODE_SEL_MASK(led_num);
+       reg_val |= LED_MODE_SEL(led_num, (u16)mode);
+       rc = phy_write(phydev, MSCC_PHY_LED_MODE_SEL, reg_val);
+       mutex_unlock(&phydev->lock);
+
+       return rc;
+}
+
+static int vsc85xx_mdix_get(struct phy_device *phydev, u8 *mdix)
+{
+       u16 reg_val;
+
+       reg_val = phy_read(phydev, MSCC_PHY_DEV_AUX_CNTL);
+       if (reg_val & HP_AUTO_MDIX_X_OVER_IND_MASK)
+               *mdix = ETH_TP_MDI_X;
+       else
+               *mdix = ETH_TP_MDI;
+
+       return 0;
+}
+
+static int vsc85xx_mdix_set(struct phy_device *phydev, u8 mdix)
+{
+       int rc;
+       u16 reg_val;
+
+       reg_val = phy_read(phydev, MSCC_PHY_BYPASS_CONTROL);
+       if (mdix == ETH_TP_MDI || mdix == ETH_TP_MDI_X) {
+               reg_val |= (DISABLE_PAIR_SWAP_CORR_MASK |
+                           DISABLE_POLARITY_CORR_MASK  |
+                           DISABLE_HP_AUTO_MDIX_MASK);
+       } else {
+               reg_val &= ~(DISABLE_PAIR_SWAP_CORR_MASK |
+                            DISABLE_POLARITY_CORR_MASK  |
+                            DISABLE_HP_AUTO_MDIX_MASK);
+       }
+       rc = phy_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg_val);
+       if (rc)
+               return rc;
+
+       reg_val = 0;
+
+       if (mdix == ETH_TP_MDI)
+               reg_val = FORCE_MDI_CROSSOVER_MDI;
+       else if (mdix == ETH_TP_MDI_X)
+               reg_val = FORCE_MDI_CROSSOVER_MDIX;
+
+       rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
+                             MSCC_PHY_EXT_MODE_CNTL, FORCE_MDI_CROSSOVER_MASK,
+                             reg_val);
+       if (rc < 0)
+               return rc;
+
+       return genphy_restart_aneg(phydev);
+}
+
+static int vsc85xx_downshift_get(struct phy_device *phydev, u8 *count)
+{
+       int reg_val;
+
+       reg_val = phy_read_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
+                                MSCC_PHY_ACTIPHY_CNTL);
+       if (reg_val < 0)
+               return reg_val;
+
+       reg_val &= DOWNSHIFT_CNTL_MASK;
+       if (!(reg_val & DOWNSHIFT_EN))
+               *count = DOWNSHIFT_DEV_DISABLE;
+       else
+               *count = ((reg_val & ~DOWNSHIFT_EN) >> DOWNSHIFT_CNTL_POS) + 2;
+
+       return 0;
+}
+
+static int vsc85xx_downshift_set(struct phy_device *phydev, u8 count)
+{
+       if (count == DOWNSHIFT_DEV_DEFAULT_COUNT) {
+               /* Default downshift count 3 (i.e. Bit3:2 = 0b01) */
+               count = ((1 << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
+       } else if (count > DOWNSHIFT_COUNT_MAX || count == 1) {
+               phydev_err(phydev, "Downshift count should be 2,3,4 or 5\n");
+               return -ERANGE;
+       } else if (count) {
+               /* Downshift count is either 2,3,4 or 5 */
+               count = (((count - 2) << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
+       }
+
+       return phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
+                               MSCC_PHY_ACTIPHY_CNTL, DOWNSHIFT_CNTL_MASK,
+                               count);
+}
+
+static int vsc85xx_wol_set(struct phy_device *phydev,
+                          struct ethtool_wolinfo *wol)
+{
+       int rc;
+       u16 reg_val;
+       u8  i;
+       u16 pwd[3] = {0, 0, 0};
+       struct ethtool_wolinfo *wol_conf = wol;
+       u8 *mac_addr = phydev->attached_dev->dev_addr;
+
+       mutex_lock(&phydev->lock);
+       rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
+       if (rc < 0) {
+               rc = phy_restore_page(phydev, rc, rc);
+               goto out_unlock;
+       }
+
+       if (wol->wolopts & WAKE_MAGIC) {
+               /* Store the device address for the magic packet */
+               for (i = 0; i < ARRAY_SIZE(pwd); i++)
+                       pwd[i] = mac_addr[5 - (i * 2 + 1)] << 8 |
+                                mac_addr[5 - i * 2];
+               __phy_write(phydev, MSCC_PHY_WOL_LOWER_MAC_ADDR, pwd[0]);
+               __phy_write(phydev, MSCC_PHY_WOL_MID_MAC_ADDR, pwd[1]);
+               __phy_write(phydev, MSCC_PHY_WOL_UPPER_MAC_ADDR, pwd[2]);
+       } else {
+               __phy_write(phydev, MSCC_PHY_WOL_LOWER_MAC_ADDR, 0);
+               __phy_write(phydev, MSCC_PHY_WOL_MID_MAC_ADDR, 0);
+               __phy_write(phydev, MSCC_PHY_WOL_UPPER_MAC_ADDR, 0);
+       }
+
+       if (wol_conf->wolopts & WAKE_MAGICSECURE) {
+               for (i = 0; i < ARRAY_SIZE(pwd); i++)
+                       pwd[i] = wol_conf->sopass[5 - (i * 2 + 1)] << 8 |
+                                wol_conf->sopass[5 - i * 2];
+               __phy_write(phydev, MSCC_PHY_WOL_LOWER_PASSWD, pwd[0]);
+               __phy_write(phydev, MSCC_PHY_WOL_MID_PASSWD, pwd[1]);
+               __phy_write(phydev, MSCC_PHY_WOL_UPPER_PASSWD, pwd[2]);
+       } else {
+               __phy_write(phydev, MSCC_PHY_WOL_LOWER_PASSWD, 0);
+               __phy_write(phydev, MSCC_PHY_WOL_MID_PASSWD, 0);
+               __phy_write(phydev, MSCC_PHY_WOL_UPPER_PASSWD, 0);
+       }
+
+       reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
+       if (wol_conf->wolopts & WAKE_MAGICSECURE)
+               reg_val |= SECURE_ON_ENABLE;
+       else
+               reg_val &= ~SECURE_ON_ENABLE;
+       __phy_write(phydev, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
+
+       rc = phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
+       if (rc < 0)
+               goto out_unlock;
+
+       if (wol->wolopts & WAKE_MAGIC) {
+               /* Enable the WOL interrupt */
+               reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
+               reg_val |= MII_VSC85XX_INT_MASK_WOL;
+               rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
+               if (rc)
+                       goto out_unlock;
+       } else {
+               /* Disable the WOL interrupt */
+               reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
+               reg_val &= (~MII_VSC85XX_INT_MASK_WOL);
+               rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
+               if (rc)
+                       goto out_unlock;
+       }
+       /* Clear WOL iterrupt status */
+       reg_val = phy_read(phydev, MII_VSC85XX_INT_STATUS);
+
+out_unlock:
+       mutex_unlock(&phydev->lock);
+
+       return rc;
+}
+
+static void vsc85xx_wol_get(struct phy_device *phydev,
+                           struct ethtool_wolinfo *wol)
+{
+       int rc;
+       u16 reg_val;
+       u8  i;
+       u16 pwd[3] = {0, 0, 0};
+       struct ethtool_wolinfo *wol_conf = wol;
+
+       mutex_lock(&phydev->lock);
+       rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
+       if (rc < 0)
+               goto out_unlock;
+
+       reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
+       if (reg_val & SECURE_ON_ENABLE)
+               wol_conf->wolopts |= WAKE_MAGICSECURE;
+       if (wol_conf->wolopts & WAKE_MAGICSECURE) {
+               pwd[0] = __phy_read(phydev, MSCC_PHY_WOL_LOWER_PASSWD);
+               pwd[1] = __phy_read(phydev, MSCC_PHY_WOL_MID_PASSWD);
+               pwd[2] = __phy_read(phydev, MSCC_PHY_WOL_UPPER_PASSWD);
+               for (i = 0; i < ARRAY_SIZE(pwd); i++) {
+                       wol_conf->sopass[5 - i * 2] = pwd[i] & 0x00ff;
+                       wol_conf->sopass[5 - (i * 2 + 1)] = (pwd[i] & 0xff00)
+                                                           >> 8;
+               }
+       }
+
+out_unlock:
+       phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
+       mutex_unlock(&phydev->lock);
+}
+
+#ifdef CONFIG_OF_MDIO
+static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
+{
+       u32 vdd, sd;
+       int i, j;
+       struct device *dev = &phydev->mdio.dev;
+       struct device_node *of_node = dev->of_node;
+       u8 sd_array_size = ARRAY_SIZE(edge_table[0].slowdown);
+
+       if (!of_node)
+               return -ENODEV;
+
+       if (of_property_read_u32(of_node, "vsc8531,vddmac", &vdd))
+               vdd = MSCC_VDDMAC_3300;
+
+       if (of_property_read_u32(of_node, "vsc8531,edge-slowdown", &sd))
+               sd = 0;
+
+       for (i = 0; i < ARRAY_SIZE(edge_table); i++)
+               if (edge_table[i].vddmac == vdd)
+                       for (j = 0; j < sd_array_size; j++)
+                               if (edge_table[i].slowdown[j] == sd)
+                                       return (sd_array_size - j - 1);
+
+       return -EINVAL;
+}
+
+static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
+                                  char *led,
+                                  u32 default_mode)
+{
+       struct vsc8531_private *priv = phydev->priv;
+       struct device *dev = &phydev->mdio.dev;
+       struct device_node *of_node = dev->of_node;
+       u32 led_mode;
+       int err;
+
+       if (!of_node)
+               return -ENODEV;
+
+       led_mode = default_mode;
+       err = of_property_read_u32(of_node, led, &led_mode);
+       if (!err && !(BIT(led_mode) & priv->supp_led_modes)) {
+               phydev_err(phydev, "DT %s invalid\n", led);
+               return -EINVAL;
+       }
+
+       return led_mode;
+}
+
+#else
+static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
+{
+       return 0;
+}
+
+static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
+                                  char *led,
+                                  u8 default_mode)
+{
+       return default_mode;
+}
+#endif /* CONFIG_OF_MDIO */
+
+static int vsc85xx_dt_led_modes_get(struct phy_device *phydev,
+                                   u32 *default_mode)
+{
+       struct vsc8531_private *priv = phydev->priv;
+       char led_dt_prop[28];
+       int i, ret;
+
+       for (i = 0; i < priv->nleds; i++) {
+               ret = sprintf(led_dt_prop, "vsc8531,led-%d-mode", i);
+               if (ret < 0)
+                       return ret;
+
+               ret = vsc85xx_dt_led_mode_get(phydev, led_dt_prop,
+                                             default_mode[i]);
+               if (ret < 0)
+                       return ret;
+               priv->leds_mode[i] = ret;
+       }
+
+       return 0;
+}
+
+static int vsc85xx_edge_rate_cntl_set(struct phy_device *phydev, u8 edge_rate)
+{
+       int rc;
+
+       mutex_lock(&phydev->lock);
+       rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
+                             MSCC_PHY_WOL_MAC_CONTROL, EDGE_RATE_CNTL_MASK,
+                             edge_rate << EDGE_RATE_CNTL_POS);
+       mutex_unlock(&phydev->lock);
+
+       return rc;
+}
+
+static int vsc85xx_mac_if_set(struct phy_device *phydev,
+                             phy_interface_t interface)
+{
+       int rc;
+       u16 reg_val;
+
+       mutex_lock(&phydev->lock);
+       reg_val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
+       reg_val &= ~(MAC_IF_SELECTION_MASK);
+       switch (interface) {
+       case PHY_INTERFACE_MODE_RGMII:
+               reg_val |= (MAC_IF_SELECTION_RGMII << MAC_IF_SELECTION_POS);
+               break;
+       case PHY_INTERFACE_MODE_RMII:
+               reg_val |= (MAC_IF_SELECTION_RMII << MAC_IF_SELECTION_POS);
+               break;
+       case PHY_INTERFACE_MODE_MII:
+       case PHY_INTERFACE_MODE_GMII:
+               reg_val |= (MAC_IF_SELECTION_GMII << MAC_IF_SELECTION_POS);
+               break;
+       default:
+               rc = -EINVAL;
+               goto out_unlock;
+       }
+       rc = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, reg_val);
+       if (rc)
+               goto out_unlock;
+
+       rc = genphy_soft_reset(phydev);
+
+out_unlock:
+       mutex_unlock(&phydev->lock);
+
+       return rc;
+}
+
+static int vsc85xx_default_config(struct phy_device *phydev)
+{
+       int rc;
+       u16 reg_val;
+
+       phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
+       mutex_lock(&phydev->lock);
+
+       reg_val = RGMII_RX_CLK_DELAY_1_1_NS << RGMII_RX_CLK_DELAY_POS;
+
+       rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
+                             MSCC_PHY_RGMII_CNTL, RGMII_RX_CLK_DELAY_MASK,
+                             reg_val);
+
+       mutex_unlock(&phydev->lock);
+
+       return rc;
+}
+
+static int vsc85xx_get_tunable(struct phy_device *phydev,
+                              struct ethtool_tunable *tuna, void *data)
+{
+       switch (tuna->id) {
+       case ETHTOOL_PHY_DOWNSHIFT:
+               return vsc85xx_downshift_get(phydev, (u8 *)data);
+       default:
+               return -EINVAL;
+       }
+}
+
+static int vsc85xx_set_tunable(struct phy_device *phydev,
+                              struct ethtool_tunable *tuna,
+                              const void *data)
+{
+       switch (tuna->id) {
+       case ETHTOOL_PHY_DOWNSHIFT:
+               return vsc85xx_downshift_set(phydev, *(u8 *)data);
+       default:
+               return -EINVAL;
+       }
+}
+
+/* mdiobus lock should be locked when using this function */
+static void vsc85xx_tr_write(struct phy_device *phydev, u16 addr, u32 val)
+{
+       __phy_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
+       __phy_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
+       __phy_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
+}
+
+static int vsc8531_pre_init_seq_set(struct phy_device *phydev)
+{
+       int rc;
+       static const struct reg_val init_seq[] = {
+               {0x0f90, 0x00688980},
+               {0x0696, 0x00000003},
+               {0x07fa, 0x0050100f},
+               {0x1686, 0x00000004},
+       };
+       unsigned int i;
+       int oldpage;
+
+       rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_STANDARD,
+                             MSCC_PHY_EXT_CNTL_STATUS, SMI_BROADCAST_WR_EN,
+                             SMI_BROADCAST_WR_EN);
+       if (rc < 0)
+               return rc;
+       rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
+                             MSCC_PHY_TEST_PAGE_24, 0, 0x0400);
+       if (rc < 0)
+               return rc;
+       rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
+                             MSCC_PHY_TEST_PAGE_5, 0x0a00, 0x0e00);
+       if (rc < 0)
+               return rc;
+       rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
+                             MSCC_PHY_TEST_PAGE_8, 0x8000, 0x8000);
+       if (rc < 0)
+               return rc;
+
+       mutex_lock(&phydev->lock);
+       oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
+       if (oldpage < 0)
+               goto out_unlock;
+
+       for (i = 0; i < ARRAY_SIZE(init_seq); i++)
+               vsc85xx_tr_write(phydev, init_seq[i].reg, init_seq[i].val);
+
+out_unlock:
+       oldpage = phy_restore_page(phydev, oldpage, oldpage);
+       mutex_unlock(&phydev->lock);
+
+       return oldpage;
+}
+
+static int vsc85xx_eee_init_seq_set(struct phy_device *phydev)
+{
+       static const struct reg_val init_eee[] = {
+               {0x0f82, 0x0012b00a},
+               {0x1686, 0x00000004},
+               {0x168c, 0x00d2c46f},
+               {0x17a2, 0x00000620},
+               {0x16a0, 0x00eeffdd},
+               {0x16a6, 0x00071448},
+               {0x16a4, 0x0013132f},
+               {0x16a8, 0x00000000},
+               {0x0ffc, 0x00c0a028},
+               {0x0fe8, 0x0091b06c},
+               {0x0fea, 0x00041600},
+               {0x0f80, 0x00000af4},
+               {0x0fec, 0x00901809},
+               {0x0fee, 0x0000a6a1},
+               {0x0ffe, 0x00b01007},
+               {0x16b0, 0x00eeff00},
+               {0x16b2, 0x00007000},
+               {0x16b4, 0x00000814},
+       };
+       unsigned int i;
+       int oldpage;
+
+       mutex_lock(&phydev->lock);
+       oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
+       if (oldpage < 0)
+               goto out_unlock;
+
+       for (i = 0; i < ARRAY_SIZE(init_eee); i++)
+               vsc85xx_tr_write(phydev, init_eee[i].reg, init_eee[i].val);
+
+out_unlock:
+       oldpage = phy_restore_page(phydev, oldpage, oldpage);
+       mutex_unlock(&phydev->lock);
+
+       return oldpage;
+}
+
+/* phydev->bus->mdio_lock should be locked when using this function */
+static int phy_base_write(struct phy_device *phydev, u32 regnum, u16 val)
+{
+       struct vsc8531_private *priv = phydev->priv;
+
+       if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
+               dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
+               dump_stack();
+       }
+
+       return __mdiobus_write(phydev->mdio.bus, priv->base_addr, regnum, val);
+}
+
+/* phydev->bus->mdio_lock should be locked when using this function */
+static int phy_base_read(struct phy_device *phydev, u32 regnum)
+{
+       struct vsc8531_private *priv = phydev->priv;
+
+       if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
+               dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
+               dump_stack();
+       }
+
+       return __mdiobus_read(phydev->mdio.bus, priv->base_addr, regnum);
+}
+
+/* bus->mdio_lock should be locked when using this function */
+static void vsc8584_csr_write(struct phy_device *phydev, u16 addr, u32 val)
+{
+       phy_base_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
+       phy_base_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
+       phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
+}
+
+/* bus->mdio_lock should be locked when using this function */
+static int vsc8584_cmd(struct phy_device *phydev, u16 val)
+{
+       unsigned long deadline;
+       u16 reg_val;
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
+                      MSCC_PHY_PAGE_EXTENDED_GPIO);
+
+       phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NCOMPLETED | val);
+
+       deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
+       do {
+               reg_val = phy_base_read(phydev, MSCC_PHY_PROC_CMD);
+       } while (time_before(jiffies, deadline) &&
+                (reg_val & PROC_CMD_NCOMPLETED) &&
+                !(reg_val & PROC_CMD_FAILED));
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+       if (reg_val & PROC_CMD_FAILED)
+               return -EIO;
+
+       if (reg_val & PROC_CMD_NCOMPLETED)
+               return -ETIMEDOUT;
+
+       return 0;
+}
+
+/* bus->mdio_lock should be locked when using this function */
+static int vsc8584_micro_deassert_reset(struct phy_device *phydev,
+                                       bool patch_en)
+{
+       u32 enable, release;
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
+                      MSCC_PHY_PAGE_EXTENDED_GPIO);
+
+       enable = RUN_FROM_INT_ROM | MICRO_CLK_EN | DW8051_CLK_EN;
+       release = MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
+               MICRO_CLK_EN;
+
+       if (patch_en) {
+               enable |= MICRO_PATCH_EN;
+               release |= MICRO_PATCH_EN;
+
+               /* Clear all patches */
+               phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
+       }
+
+       /* Enable 8051 Micro clock; CLEAR/SET patch present; disable PRAM clock
+        * override and addr. auto-incr; operate at 125 MHz
+        */
+       phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, enable);
+       /* Release 8051 Micro SW reset */
+       phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, release);
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+       return 0;
+}
+
+/* bus->mdio_lock should be locked when using this function */
+static int vsc8584_micro_assert_reset(struct phy_device *phydev)
+{
+       int ret;
+       u16 reg;
+
+       ret = vsc8584_cmd(phydev, PROC_CMD_NOP);
+       if (ret)
+               return ret;
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
+                      MSCC_PHY_PAGE_EXTENDED_GPIO);
+
+       reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
+       reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
+       phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
+
+       phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(4), 0x005b);
+       phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(4), 0x005b);
+
+       reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
+       reg |= EN_PATCH_RAM_TRAP_ADDR(4);
+       phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
+
+       phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NOP);
+
+       reg = phy_base_read(phydev, MSCC_DW8051_CNTL_STATUS);
+       reg &= ~MICRO_NSOFT_RESET;
+       phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, reg);
+
+       phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_MCB_ACCESS_MAC_CONF |
+                      PROC_CMD_SGMII_PORT(0) | PROC_CMD_NO_MAC_CONF |
+                      PROC_CMD_READ);
+
+       reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
+       reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
+       phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+       return 0;
+}
+
+/* bus->mdio_lock should be locked when using this function */
+static int vsc8584_get_fw_crc(struct phy_device *phydev, u16 start, u16 size,
+                             u16 *crc)
+{
+       int ret;
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
+
+       phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_2, start);
+       phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_3, size);
+
+       /* Start Micro command */
+       ret = vsc8584_cmd(phydev, PROC_CMD_CRC16);
+       if (ret)
+               goto out;
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
+
+       *crc = phy_base_read(phydev, MSCC_PHY_VERIPHY_CNTL_2);
+
+out:
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+       return ret;
+}
+
+/* bus->mdio_lock should be locked when using this function */
+static int vsc8584_patch_fw(struct phy_device *phydev,
+                           const struct firmware *fw)
+{
+       int i, ret;
+
+       ret = vsc8584_micro_assert_reset(phydev);
+       if (ret) {
+               dev_err(&phydev->mdio.dev,
+                       "%s: failed to assert reset of micro\n", __func__);
+               return ret;
+       }
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
+                      MSCC_PHY_PAGE_EXTENDED_GPIO);
+
+       /* Hold 8051 Micro in SW Reset, Enable auto incr address and patch clock
+        * Disable the 8051 Micro clock
+        */
+       phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, RUN_FROM_INT_ROM |
+                      AUTOINC_ADDR | PATCH_RAM_CLK | MICRO_CLK_EN |
+                      MICRO_CLK_DIVIDE(2));
+       phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_PRAM | INT_MEM_WRITE_EN |
+                      INT_MEM_DATA(2));
+       phy_base_write(phydev, MSCC_INT_MEM_ADDR, 0x0000);
+
+       for (i = 0; i < fw->size; i++)
+               phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_PRAM |
+                              INT_MEM_WRITE_EN | fw->data[i]);
+
+       /* Clear internal memory access */
+       phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+       return 0;
+}
+
+/* bus->mdio_lock should be locked when using this function */
+static bool vsc8574_is_serdes_init(struct phy_device *phydev)
+{
+       u16 reg;
+       bool ret;
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
+                      MSCC_PHY_PAGE_EXTENDED_GPIO);
+
+       reg = phy_base_read(phydev, MSCC_TRAP_ROM_ADDR(1));
+       if (reg != 0x3eb7) {
+               ret = false;
+               goto out;
+       }
+
+       reg = phy_base_read(phydev, MSCC_PATCH_RAM_ADDR(1));
+       if (reg != 0x4012) {
+               ret = false;
+               goto out;
+       }
+
+       reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
+       if (reg != EN_PATCH_RAM_TRAP_ADDR(1)) {
+               ret = false;
+               goto out;
+       }
+
+       reg = phy_base_read(phydev, MSCC_DW8051_CNTL_STATUS);
+       if ((MICRO_NSOFT_RESET | RUN_FROM_INT_ROM |  DW8051_CLK_EN |
+            MICRO_CLK_EN) != (reg & MSCC_DW8051_VLD_MASK)) {
+               ret = false;
+               goto out;
+       }
+
+       ret = true;
+out:
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+       return ret;
+}
+
+/* bus->mdio_lock should be locked when using this function */
+static int vsc8574_config_pre_init(struct phy_device *phydev)
+{
+       static const struct reg_val pre_init1[] = {
+               {0x0fae, 0x000401bd},
+               {0x0fac, 0x000f000f},
+               {0x17a0, 0x00a0f147},
+               {0x0fe4, 0x00052f54},
+               {0x1792, 0x0027303d},
+               {0x07fe, 0x00000704},
+               {0x0fe0, 0x00060150},
+               {0x0f82, 0x0012b00a},
+               {0x0f80, 0x00000d74},
+               {0x02e0, 0x00000012},
+               {0x03a2, 0x00050208},
+               {0x03b2, 0x00009186},
+               {0x0fb0, 0x000e3700},
+               {0x1688, 0x00049f81},
+               {0x0fd2, 0x0000ffff},
+               {0x168a, 0x00039fa2},
+               {0x1690, 0x0020640b},
+               {0x0258, 0x00002220},
+               {0x025a, 0x00002a20},
+               {0x025c, 0x00003060},
+               {0x025e, 0x00003fa0},
+               {0x03a6, 0x0000e0f0},
+               {0x0f92, 0x00001489},
+               {0x16a2, 0x00007000},
+               {0x16a6, 0x00071448},
+               {0x16a0, 0x00eeffdd},
+               {0x0fe8, 0x0091b06c},
+               {0x0fea, 0x00041600},
+               {0x16b0, 0x00eeff00},
+               {0x16b2, 0x00007000},
+               {0x16b4, 0x00000814},
+               {0x0f90, 0x00688980},
+               {0x03a4, 0x0000d8f0},
+               {0x0fc0, 0x00000400},
+               {0x07fa, 0x0050100f},
+               {0x0796, 0x00000003},
+               {0x07f8, 0x00c3ff98},
+               {0x0fa4, 0x0018292a},
+               {0x168c, 0x00d2c46f},
+               {0x17a2, 0x00000620},
+               {0x16a4, 0x0013132f},
+               {0x16a8, 0x00000000},
+               {0x0ffc, 0x00c0a028},
+               {0x0fec, 0x00901c09},
+               {0x0fee, 0x0004a6a1},
+               {0x0ffe, 0x00b01807},
+       };
+       static const struct reg_val pre_init2[] = {
+               {0x0486, 0x0008a518},
+               {0x0488, 0x006dc696},
+               {0x048a, 0x00000912},
+               {0x048e, 0x00000db6},
+               {0x049c, 0x00596596},
+               {0x049e, 0x00000514},
+               {0x04a2, 0x00410280},
+               {0x04a4, 0x00000000},
+               {0x04a6, 0x00000000},
+               {0x04a8, 0x00000000},
+               {0x04aa, 0x00000000},
+               {0x04ae, 0x007df7dd},
+               {0x04b0, 0x006d95d4},
+               {0x04b2, 0x00492410},
+       };
+       struct device *dev = &phydev->mdio.dev;
+       const struct firmware *fw;
+       unsigned int i;
+       u16 crc, reg;
+       bool serdes_init;
+       int ret;
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+       /* all writes below are broadcasted to all PHYs in the same package */
+       reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
+       reg |= SMI_BROADCAST_WR_EN;
+       phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
+
+       phy_base_write(phydev, MII_VSC85XX_INT_MASK, 0);
+
+       /* The below register writes are tweaking analog and electrical
+        * configuration that were determined through characterization by PHY
+        * engineers. These don't mean anything more than "these are the best
+        * values".
+        */
+       phy_base_write(phydev, MSCC_PHY_EXT_PHY_CNTL_2, 0x0040);
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
+
+       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_20, 0x4320);
+       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_24, 0x0c00);
+       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_9, 0x18ca);
+       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1b20);
+
+       reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
+       reg |= 0x8000;
+       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
+
+       for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
+               vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_2);
+
+       phy_base_write(phydev, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
+
+       for (i = 0; i < ARRAY_SIZE(pre_init2); i++)
+               vsc8584_csr_write(phydev, pre_init2[i].reg, pre_init2[i].val);
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
+
+       reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
+       reg &= ~0x8000;
+       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+       /* end of write broadcasting */
+       reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
+       reg &= ~SMI_BROADCAST_WR_EN;
+       phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
+
+       ret = request_firmware(&fw, MSCC_VSC8574_REVB_INT8051_FW, dev);
+       if (ret) {
+               dev_err(dev, "failed to load firmware %s, ret: %d\n",
+                       MSCC_VSC8574_REVB_INT8051_FW, ret);
+               return ret;
+       }
+
+       /* Add one byte to size for the one added by the patch_fw function */
+       ret = vsc8584_get_fw_crc(phydev,
+                                MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
+                                fw->size + 1, &crc);
+       if (ret)
+               goto out;
+
+       if (crc == MSCC_VSC8574_REVB_INT8051_FW_CRC) {
+               serdes_init = vsc8574_is_serdes_init(phydev);
+
+               if (!serdes_init) {
+                       ret = vsc8584_micro_assert_reset(phydev);
+                       if (ret) {
+                               dev_err(dev,
+                                       "%s: failed to assert reset of micro\n",
+                                       __func__);
+                               goto out;
+                       }
+               }
+       } else {
+               dev_dbg(dev, "FW CRC is not the expected one, patching FW\n");
+
+               serdes_init = false;
+
+               if (vsc8584_patch_fw(phydev, fw))
+                       dev_warn(dev,
+                                "failed to patch FW, expect non-optimal device\n");
+       }
+
+       if (!serdes_init) {
+               phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
+                              MSCC_PHY_PAGE_EXTENDED_GPIO);
+
+               phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(1), 0x3eb7);
+               phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(1), 0x4012);
+               phy_base_write(phydev, MSCC_INT_MEM_CNTL,
+                              EN_PATCH_RAM_TRAP_ADDR(1));
+
+               vsc8584_micro_deassert_reset(phydev, false);
+
+               /* Add one byte to size for the one added by the patch_fw
+                * function
+                */
+               ret = vsc8584_get_fw_crc(phydev,
+                                        MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
+                                        fw->size + 1, &crc);
+               if (ret)
+                       goto out;
+
+               if (crc != MSCC_VSC8574_REVB_INT8051_FW_CRC)
+                       dev_warn(dev,
+                                "FW CRC after patching is not the expected one, expect non-optimal device\n");
+       }
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
+                      MSCC_PHY_PAGE_EXTENDED_GPIO);
+
+       ret = vsc8584_cmd(phydev, PROC_CMD_1588_DEFAULT_INIT |
+                         PROC_CMD_PHY_INIT);
+
+out:
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+       release_firmware(fw);
+
+       return ret;
+}
+
+/* bus->mdio_lock should be locked when using this function */
+static int vsc8584_config_pre_init(struct phy_device *phydev)
+{
+       static const struct reg_val pre_init1[] = {
+               {0x07fa, 0x0050100f},
+               {0x1688, 0x00049f81},
+               {0x0f90, 0x00688980},
+               {0x03a4, 0x0000d8f0},
+               {0x0fc0, 0x00000400},
+               {0x0f82, 0x0012b002},
+               {0x1686, 0x00000004},
+               {0x168c, 0x00d2c46f},
+               {0x17a2, 0x00000620},
+               {0x16a0, 0x00eeffdd},
+               {0x16a6, 0x00071448},
+               {0x16a4, 0x0013132f},
+               {0x16a8, 0x00000000},
+               {0x0ffc, 0x00c0a028},
+               {0x0fe8, 0x0091b06c},
+               {0x0fea, 0x00041600},
+               {0x0f80, 0x00fffaff},
+               {0x0fec, 0x00901809},
+               {0x0ffe, 0x00b01007},
+               {0x16b0, 0x00eeff00},
+               {0x16b2, 0x00007000},
+               {0x16b4, 0x00000814},
+       };
+       static const struct reg_val pre_init2[] = {
+               {0x0486, 0x0008a518},
+               {0x0488, 0x006dc696},
+               {0x048a, 0x00000912},
+       };
+       const struct firmware *fw;
+       struct device *dev = &phydev->mdio.dev;
+       unsigned int i;
+       u16 crc, reg;
+       int ret;
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+       /* all writes below are broadcasted to all PHYs in the same package */
+       reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
+       reg |= SMI_BROADCAST_WR_EN;
+       phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
+
+       phy_base_write(phydev, MII_VSC85XX_INT_MASK, 0);
+
+       reg = phy_base_read(phydev,  MSCC_PHY_BYPASS_CONTROL);
+       reg |= PARALLEL_DET_IGNORE_ADVERTISED;
+       phy_base_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg);
+
+       /* The below register writes are tweaking analog and electrical
+        * configuration that were determined through characterization by PHY
+        * engineers. These don't mean anything more than "these are the best
+        * values".
+        */
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_3);
+
+       phy_base_write(phydev, MSCC_PHY_SERDES_TX_CRC_ERR_CNT, 0x2000);
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
+
+       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1f20);
+
+       reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
+       reg |= 0x8000;
+       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
+
+       phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x2fa4));
+
+       reg = phy_base_read(phydev, MSCC_PHY_TR_MSB);
+       reg &= ~0x007f;
+       reg |= 0x0019;
+       phy_base_write(phydev, MSCC_PHY_TR_MSB, reg);
+
+       phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x0fa4));
+
+       for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
+               vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_2);
+
+       phy_base_write(phydev, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
+
+       for (i = 0; i < ARRAY_SIZE(pre_init2); i++)
+               vsc8584_csr_write(phydev, pre_init2[i].reg, pre_init2[i].val);
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
+
+       reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
+       reg &= ~0x8000;
+       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+       /* end of write broadcasting */
+       reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
+       reg &= ~SMI_BROADCAST_WR_EN;
+       phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
+
+       ret = request_firmware(&fw, MSCC_VSC8584_REVB_INT8051_FW, dev);
+       if (ret) {
+               dev_err(dev, "failed to load firmware %s, ret: %d\n",
+                       MSCC_VSC8584_REVB_INT8051_FW, ret);
+               return ret;
+       }
+
+       /* Add one byte to size for the one added by the patch_fw function */
+       ret = vsc8584_get_fw_crc(phydev,
+                                MSCC_VSC8584_REVB_INT8051_FW_START_ADDR,
+                                fw->size + 1, &crc);
+       if (ret)
+               goto out;
+
+       if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC) {
+               dev_dbg(dev, "FW CRC is not the expected one, patching FW\n");
+               if (vsc8584_patch_fw(phydev, fw))
+                       dev_warn(dev,
+                                "failed to patch FW, expect non-optimal device\n");
+       }
+
+       vsc8584_micro_deassert_reset(phydev, false);
+
+       /* Add one byte to size for the one added by the patch_fw function */
+       ret = vsc8584_get_fw_crc(phydev,
+                                MSCC_VSC8584_REVB_INT8051_FW_START_ADDR,
+                                fw->size + 1, &crc);
+       if (ret)
+               goto out;
+
+       if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC)
+               dev_warn(dev,
+                        "FW CRC after patching is not the expected one, expect non-optimal device\n");
+
+       ret = vsc8584_micro_assert_reset(phydev);
+       if (ret)
+               goto out;
+
+       vsc8584_micro_deassert_reset(phydev, true);
+
+out:
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+       release_firmware(fw);
+
+       return ret;
+}
+
+#if IS_ENABLED(CONFIG_MACSEC)
+static u32 vsc8584_macsec_phy_read(struct phy_device *phydev,
+                                  enum macsec_bank bank, u32 reg)
+{
+       u32 val, val_l = 0, val_h = 0;
+       unsigned long deadline;
+       int rc;
+
+       rc = phy_select_page(phydev, MSCC_PHY_PAGE_MACSEC);
+       if (rc < 0)
+               goto failed;
+
+       __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_20,
+                   MSCC_PHY_MACSEC_20_TARGET(bank >> 2));
+
+       if (bank >> 2 == 0x1)
+               /* non-MACsec access */
+               bank &= 0x3;
+       else
+               bank = 0;
+
+       __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_19,
+                   MSCC_PHY_MACSEC_19_CMD | MSCC_PHY_MACSEC_19_READ |
+                   MSCC_PHY_MACSEC_19_REG_ADDR(reg) |
+                   MSCC_PHY_MACSEC_19_TARGET(bank));
+
+       deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
+       do {
+               val = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_19);
+       } while (time_before(jiffies, deadline) && !(val & MSCC_PHY_MACSEC_19_CMD));
+
+       val_l = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_17);
+       val_h = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_18);
+
+failed:
+       phy_restore_page(phydev, rc, rc);
+
+       return (val_h << 16) | val_l;
+}
+
+static void vsc8584_macsec_phy_write(struct phy_device *phydev,
+                                    enum macsec_bank bank, u32 reg, u32 val)
+{
+       unsigned long deadline;
+       int rc;
+
+       rc = phy_select_page(phydev, MSCC_PHY_PAGE_MACSEC);
+       if (rc < 0)
+               goto failed;
+
+       __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_20,
+                   MSCC_PHY_MACSEC_20_TARGET(bank >> 2));
+
+       if ((bank >> 2 == 0x1) || (bank >> 2 == 0x3))
+               bank &= 0x3;
+       else
+               /* MACsec access */
+               bank = 0;
+
+       __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_17, (u16)val);
+       __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_18, (u16)(val >> 16));
+
+       __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_19,
+                   MSCC_PHY_MACSEC_19_CMD | MSCC_PHY_MACSEC_19_REG_ADDR(reg) |
+                   MSCC_PHY_MACSEC_19_TARGET(bank));
+
+       deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
+       do {
+               val = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_19);
+       } while (time_before(jiffies, deadline) && !(val & MSCC_PHY_MACSEC_19_CMD));
+
+failed:
+       phy_restore_page(phydev, rc, rc);
+}
+
+static void vsc8584_macsec_classification(struct phy_device *phydev,
+                                         enum macsec_bank bank)
+{
+       /* enable VLAN tag parsing */
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_CP_TAG,
+                                MSCC_MS_SAM_CP_TAG_PARSE_STAG |
+                                MSCC_MS_SAM_CP_TAG_PARSE_QTAG |
+                                MSCC_MS_SAM_CP_TAG_PARSE_QINQ);
+}
+
+static void vsc8584_macsec_flow_default_action(struct phy_device *phydev,
+                                              enum macsec_bank bank,
+                                              bool block)
+{
+       u32 port = (bank == MACSEC_INGR) ?
+                   MSCC_MS_PORT_UNCONTROLLED : MSCC_MS_PORT_COMMON;
+       u32 action = MSCC_MS_FLOW_BYPASS;
+
+       if (block)
+               action = MSCC_MS_FLOW_DROP;
+
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_NM_FLOW_NCP,
+                                /* MACsec untagged */
+                                MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_FLOW_TYPE(action) |
+                                MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_DROP_ACTION(MSCC_MS_ACTION_DROP) |
+                                MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_DEST_PORT(port) |
+                                /* MACsec tagged */
+                                MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_FLOW_TYPE(action) |
+                                MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_DROP_ACTION(MSCC_MS_ACTION_DROP) |
+                                MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_DEST_PORT(port) |
+                                /* Bad tag */
+                                MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_FLOW_TYPE(action) |
+                                MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_DROP_ACTION(MSCC_MS_ACTION_DROP) |
+                                MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_DEST_PORT(port) |
+                                /* Kay tag */
+                                MSCC_MS_SAM_NM_FLOW_NCP_KAY_FLOW_TYPE(action) |
+                                MSCC_MS_SAM_NM_FLOW_NCP_KAY_DROP_ACTION(MSCC_MS_ACTION_DROP) |
+                                MSCC_MS_SAM_NM_FLOW_NCP_KAY_DEST_PORT(port));
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_NM_FLOW_CP,
+                                /* MACsec untagged */
+                                MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_FLOW_TYPE(action) |
+                                MSCC_MS_SAM_NM_FLOW_CP_UNTAGGED_DROP_ACTION(MSCC_MS_ACTION_DROP) |
+                                MSCC_MS_SAM_NM_FLOW_CP_UNTAGGED_DEST_PORT(port) |
+                                /* MACsec tagged */
+                                MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_FLOW_TYPE(action) |
+                                MSCC_MS_SAM_NM_FLOW_CP_TAGGED_DROP_ACTION(MSCC_MS_ACTION_DROP) |
+                                MSCC_MS_SAM_NM_FLOW_CP_TAGGED_DEST_PORT(port) |
+                                /* Bad tag */
+                                MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_FLOW_TYPE(action) |
+                                MSCC_MS_SAM_NM_FLOW_CP_BADTAG_DROP_ACTION(MSCC_MS_ACTION_DROP) |
+                                MSCC_MS_SAM_NM_FLOW_CP_BADTAG_DEST_PORT(port) |
+                                /* Kay tag */
+                                MSCC_MS_SAM_NM_FLOW_NCP_KAY_FLOW_TYPE(action) |
+                                MSCC_MS_SAM_NM_FLOW_CP_KAY_DROP_ACTION(MSCC_MS_ACTION_DROP) |
+                                MSCC_MS_SAM_NM_FLOW_CP_KAY_DEST_PORT(port));
+}
+
+static void vsc8584_macsec_integrity_checks(struct phy_device *phydev,
+                                           enum macsec_bank bank)
+{
+       u32 val;
+
+       if (bank != MACSEC_INGR)
+               return;
+
+       /* Set default rules to pass unmatched frames */
+       val = vsc8584_macsec_phy_read(phydev, bank,
+                                     MSCC_MS_PARAMS2_IG_CC_CONTROL);
+       val |= MSCC_MS_PARAMS2_IG_CC_CONTROL_NON_MATCH_CTRL_ACT |
+              MSCC_MS_PARAMS2_IG_CC_CONTROL_NON_MATCH_ACT;
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_PARAMS2_IG_CC_CONTROL,
+                                val);
+
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_PARAMS2_IG_CP_TAG,
+                                MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_STAG |
+                                MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_QTAG |
+                                MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_QINQ);
+}
+
+static void vsc8584_macsec_block_init(struct phy_device *phydev,
+                                     enum macsec_bank bank)
+{
+       u32 val;
+       int i;
+
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_ENA_CFG,
+                                MSCC_MS_ENA_CFG_SW_RST |
+                                MSCC_MS_ENA_CFG_MACSEC_BYPASS_ENA);
+
+       /* Set the MACsec block out of s/w reset and enable clocks */
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_ENA_CFG,
+                                MSCC_MS_ENA_CFG_CLK_ENA);
+
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_STATUS_CONTEXT_CTRL,
+                                bank == MACSEC_INGR ? 0xe5880214 : 0xe5880218);
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_MISC_CONTROL,
+                                MSCC_MS_MISC_CONTROL_MC_LATENCY_FIX(bank == MACSEC_INGR ? 57 : 40) |
+                                MSCC_MS_MISC_CONTROL_XFORM_REC_SIZE(bank == MACSEC_INGR ? 1 : 2));
+
+       /* Clear the counters */
+       val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_COUNT_CONTROL);
+       val |= MSCC_MS_COUNT_CONTROL_AUTO_CNTR_RESET;
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_COUNT_CONTROL, val);
+
+       /* Enable octet increment mode */
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_PP_CTRL,
+                                MSCC_MS_PP_CTRL_MACSEC_OCTET_INCR_MODE);
+
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_BLOCK_CTX_UPDATE, 0x3);
+
+       val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_COUNT_CONTROL);
+       val |= MSCC_MS_COUNT_CONTROL_RESET_ALL;
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_COUNT_CONTROL, val);
+
+       /* Set the MTU */
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_NON_VLAN_MTU_CHECK,
+                                MSCC_MS_NON_VLAN_MTU_CHECK_NV_MTU_COMPARE(32761) |
+                                MSCC_MS_NON_VLAN_MTU_CHECK_NV_MTU_COMP_DROP);
+
+       for (i = 0; i < 8; i++)
+               vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_VLAN_MTU_CHECK(i),
+                                        MSCC_MS_VLAN_MTU_CHECK_MTU_COMPARE(32761) |
+                                        MSCC_MS_VLAN_MTU_CHECK_MTU_COMP_DROP);
+
+       if (bank == MACSEC_EGR) {
+               val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_INTR_CTRL_STATUS);
+               val &= ~MSCC_MS_INTR_CTRL_STATUS_INTR_ENABLE_M;
+               vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_INTR_CTRL_STATUS, val);
+
+               vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_FC_CFG,
+                                        MSCC_MS_FC_CFG_FCBUF_ENA |
+                                        MSCC_MS_FC_CFG_LOW_THRESH(0x1) |
+                                        MSCC_MS_FC_CFG_HIGH_THRESH(0x4) |
+                                        MSCC_MS_FC_CFG_LOW_BYTES_VAL(0x4) |
+                                        MSCC_MS_FC_CFG_HIGH_BYTES_VAL(0x6));
+       }
+
+       vsc8584_macsec_classification(phydev, bank);
+       vsc8584_macsec_flow_default_action(phydev, bank, false);
+       vsc8584_macsec_integrity_checks(phydev, bank);
+
+       /* Enable the MACsec block */
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_ENA_CFG,
+                                MSCC_MS_ENA_CFG_CLK_ENA |
+                                MSCC_MS_ENA_CFG_MACSEC_ENA |
+                                MSCC_MS_ENA_CFG_MACSEC_SPEED_MODE(0x5));
+}
+
+static void vsc8584_macsec_mac_init(struct phy_device *phydev,
+                                   enum macsec_bank bank)
+{
+       u32 val;
+       int i;
+
+       /* Clear host & line stats */
+       for (i = 0; i < 36; i++)
+               vsc8584_macsec_phy_write(phydev, bank, 0x1c + i, 0);
+
+       val = vsc8584_macsec_phy_read(phydev, bank,
+                                     MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL);
+       val &= ~MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_MODE_M;
+       val |= MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_MODE(2) |
+              MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_VALUE(0xffff);
+       vsc8584_macsec_phy_write(phydev, bank,
+                                MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL, val);
+
+       val = vsc8584_macsec_phy_read(phydev, bank,
+                                     MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_2);
+       val |= 0xffff;
+       vsc8584_macsec_phy_write(phydev, bank,
+                                MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_2, val);
+
+       val = vsc8584_macsec_phy_read(phydev, bank,
+                                     MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL);
+       if (bank == HOST_MAC)
+               val |= MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_TIMER_ENA |
+                      MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_FRAME_DROP_ENA;
+       else
+               val |= MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_REACT_ENA |
+                      MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_FRAME_DROP_ENA |
+                      MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_MODE |
+                      MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_EARLY_PAUSE_DETECT_ENA;
+       vsc8584_macsec_phy_write(phydev, bank,
+                                MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL, val);
+
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_PKTINF_CFG,
+                                MSCC_MAC_CFG_PKTINF_CFG_STRIP_FCS_ENA |
+                                MSCC_MAC_CFG_PKTINF_CFG_INSERT_FCS_ENA |
+                                MSCC_MAC_CFG_PKTINF_CFG_LPI_RELAY_ENA |
+                                MSCC_MAC_CFG_PKTINF_CFG_STRIP_PREAMBLE_ENA |
+                                MSCC_MAC_CFG_PKTINF_CFG_INSERT_PREAMBLE_ENA |
+                                (bank == HOST_MAC ?
+                                 MSCC_MAC_CFG_PKTINF_CFG_ENABLE_TX_PADDING : 0));
+
+       val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MAC_CFG_MODE_CFG);
+       val &= ~MSCC_MAC_CFG_MODE_CFG_DISABLE_DIC;
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_MODE_CFG, val);
+
+       val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MAC_CFG_MAXLEN_CFG);
+       val &= ~MSCC_MAC_CFG_MAXLEN_CFG_MAX_LEN_M;
+       val |= MSCC_MAC_CFG_MAXLEN_CFG_MAX_LEN(10240);
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_MAXLEN_CFG, val);
+
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_ADV_CHK_CFG,
+                                MSCC_MAC_CFG_ADV_CHK_CFG_SFD_CHK_ENA |
+                                MSCC_MAC_CFG_ADV_CHK_CFG_PRM_CHK_ENA |
+                                MSCC_MAC_CFG_ADV_CHK_CFG_OOR_ERR_ENA |
+                                MSCC_MAC_CFG_ADV_CHK_CFG_INR_ERR_ENA);
+
+       val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MAC_CFG_LFS_CFG);
+       val &= ~MSCC_MAC_CFG_LFS_CFG_LFS_MODE_ENA;
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_LFS_CFG, val);
+
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_ENA_CFG,
+                                MSCC_MAC_CFG_ENA_CFG_RX_CLK_ENA |
+                                MSCC_MAC_CFG_ENA_CFG_TX_CLK_ENA |
+                                MSCC_MAC_CFG_ENA_CFG_RX_ENA |
+                                MSCC_MAC_CFG_ENA_CFG_TX_ENA);
+}
+
+/* Must be called with mdio_lock taken */
+static int vsc8584_macsec_init(struct phy_device *phydev)
+{
+       u32 val;
+
+       vsc8584_macsec_block_init(phydev, MACSEC_INGR);
+       vsc8584_macsec_block_init(phydev, MACSEC_EGR);
+       vsc8584_macsec_mac_init(phydev, HOST_MAC);
+       vsc8584_macsec_mac_init(phydev, LINE_MAC);
+
+       vsc8584_macsec_phy_write(phydev, FC_BUFFER,
+                                MSCC_FCBUF_FC_READ_THRESH_CFG,
+                                MSCC_FCBUF_FC_READ_THRESH_CFG_TX_THRESH(4) |
+                                MSCC_FCBUF_FC_READ_THRESH_CFG_RX_THRESH(5));
+
+       val = vsc8584_macsec_phy_read(phydev, FC_BUFFER, MSCC_FCBUF_MODE_CFG);
+       val |= MSCC_FCBUF_MODE_CFG_PAUSE_GEN_ENA |
+              MSCC_FCBUF_MODE_CFG_RX_PPM_RATE_ADAPT_ENA |
+              MSCC_FCBUF_MODE_CFG_TX_PPM_RATE_ADAPT_ENA;
+       vsc8584_macsec_phy_write(phydev, FC_BUFFER, MSCC_FCBUF_MODE_CFG, val);
+
+       vsc8584_macsec_phy_write(phydev, FC_BUFFER, MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG,
+                                MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_THRESH(8) |
+                                MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_OFFSET(9));
+
+       val = vsc8584_macsec_phy_read(phydev, FC_BUFFER,
+                                     MSCC_FCBUF_TX_DATA_QUEUE_CFG);
+       val &= ~(MSCC_FCBUF_TX_DATA_QUEUE_CFG_START_M |
+                MSCC_FCBUF_TX_DATA_QUEUE_CFG_END_M);
+       val |= MSCC_FCBUF_TX_DATA_QUEUE_CFG_START(0) |
+               MSCC_FCBUF_TX_DATA_QUEUE_CFG_END(5119);
+       vsc8584_macsec_phy_write(phydev, FC_BUFFER,
+                                MSCC_FCBUF_TX_DATA_QUEUE_CFG, val);
+
+       val = vsc8584_macsec_phy_read(phydev, FC_BUFFER, MSCC_FCBUF_ENA_CFG);
+       val |= MSCC_FCBUF_ENA_CFG_TX_ENA | MSCC_FCBUF_ENA_CFG_RX_ENA;
+       vsc8584_macsec_phy_write(phydev, FC_BUFFER, MSCC_FCBUF_ENA_CFG, val);
+
+       val = vsc8584_macsec_phy_read(phydev, IP_1588,
+                                     MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL);
+       val &= ~MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE_M;
+       val |= MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE(4);
+       vsc8584_macsec_phy_write(phydev, IP_1588,
+                                MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL, val);
+
+       return 0;
+}
+
+static void vsc8584_macsec_flow(struct phy_device *phydev,
+                               struct macsec_flow *flow)
+{
+       struct vsc8531_private *priv = phydev->priv;
+       enum macsec_bank bank = flow->bank;
+       u32 val, match = 0, mask = 0, action = 0, idx = flow->index;
+
+       if (flow->match.tagged)
+               match |= MSCC_MS_SAM_MISC_MATCH_TAGGED;
+       if (flow->match.untagged)
+               match |= MSCC_MS_SAM_MISC_MATCH_UNTAGGED;
+
+       if (bank == MACSEC_INGR && flow->assoc_num >= 0) {
+               match |= MSCC_MS_SAM_MISC_MATCH_AN(flow->assoc_num);
+               mask |= MSCC_MS_SAM_MASK_AN_MASK(0x3);
+       }
+
+       if (bank == MACSEC_INGR && flow->match.sci && flow->rx_sa->sc->sci) {
+               match |= MSCC_MS_SAM_MISC_MATCH_TCI(BIT(3));
+               mask |= MSCC_MS_SAM_MASK_TCI_MASK(BIT(3)) |
+                       MSCC_MS_SAM_MASK_SCI_MASK;
+
+               vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_MATCH_SCI_LO(idx),
+                                        lower_32_bits(flow->rx_sa->sc->sci));
+               vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_MATCH_SCI_HI(idx),
+                                        upper_32_bits(flow->rx_sa->sc->sci));
+       }
+
+       if (flow->match.etype) {
+               mask |= MSCC_MS_SAM_MASK_MAC_ETYPE_MASK;
+
+               vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_MAC_SA_MATCH_HI(idx),
+                                        MSCC_MS_SAM_MAC_SA_MATCH_HI_ETYPE(htons(flow->etype)));
+       }
+
+       match |= MSCC_MS_SAM_MISC_MATCH_PRIORITY(flow->priority);
+
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_MISC_MATCH(idx), match);
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_MASK(idx), mask);
+
+       /* Action for matching packets */
+       if (flow->action.drop)
+               action = MSCC_MS_FLOW_DROP;
+       else if (flow->action.bypass || flow->port == MSCC_MS_PORT_UNCONTROLLED)
+               action = MSCC_MS_FLOW_BYPASS;
+       else
+               action = (bank == MACSEC_INGR) ?
+                        MSCC_MS_FLOW_INGRESS : MSCC_MS_FLOW_EGRESS;
+
+       val = MSCC_MS_SAM_FLOW_CTRL_FLOW_TYPE(action) |
+             MSCC_MS_SAM_FLOW_CTRL_DROP_ACTION(MSCC_MS_ACTION_DROP) |
+             MSCC_MS_SAM_FLOW_CTRL_DEST_PORT(flow->port);
+
+       if (action == MSCC_MS_FLOW_BYPASS)
+               goto write_ctrl;
+
+       if (bank == MACSEC_INGR) {
+               if (priv->secy->replay_protect)
+                       val |= MSCC_MS_SAM_FLOW_CTRL_REPLAY_PROTECT;
+               if (priv->secy->validate_frames == MACSEC_VALIDATE_STRICT)
+                       val |= MSCC_MS_SAM_FLOW_CTRL_VALIDATE_FRAMES(MSCC_MS_VALIDATE_STRICT);
+               else if (priv->secy->validate_frames == MACSEC_VALIDATE_CHECK)
+                       val |= MSCC_MS_SAM_FLOW_CTRL_VALIDATE_FRAMES(MSCC_MS_VALIDATE_CHECK);
+       } else if (bank == MACSEC_EGR) {
+               if (priv->secy->protect_frames)
+                       val |= MSCC_MS_SAM_FLOW_CTRL_PROTECT_FRAME;
+               if (priv->secy->tx_sc.encrypt)
+                       val |= MSCC_MS_SAM_FLOW_CTRL_CONF_PROTECT;
+               if (priv->secy->tx_sc.send_sci)
+                       val |= MSCC_MS_SAM_FLOW_CTRL_INCLUDE_SCI;
+       }
+
+write_ctrl:
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_FLOW_CTRL(idx), val);
+}
+
+static struct macsec_flow *vsc8584_macsec_find_flow(struct macsec_context *ctx,
+                                                   enum macsec_bank bank)
+{
+       struct vsc8531_private *priv = ctx->phydev->priv;
+       struct macsec_flow *pos, *tmp;
+
+       list_for_each_entry_safe(pos, tmp, &priv->macsec_flows, list)
+               if (pos->assoc_num == ctx->sa.assoc_num && pos->bank == bank)
+                       return pos;
+
+       return ERR_PTR(-ENOENT);
+}
+
+static void vsc8584_macsec_flow_enable(struct phy_device *phydev,
+                                      struct macsec_flow *flow)
+{
+       enum macsec_bank bank = flow->bank;
+       u32 val, idx = flow->index;
+
+       if ((flow->bank == MACSEC_INGR && flow->rx_sa && !flow->rx_sa->active) ||
+           (flow->bank == MACSEC_EGR && flow->tx_sa && !flow->tx_sa->active))
+               return;
+
+       /* Enable */
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_ENTRY_SET1, BIT(idx));
+
+       /* Set in-use */
+       val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_SAM_FLOW_CTRL(idx));
+       val |= MSCC_MS_SAM_FLOW_CTRL_SA_IN_USE;
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_FLOW_CTRL(idx), val);
+}
+
+static void vsc8584_macsec_flow_disable(struct phy_device *phydev,
+                                       struct macsec_flow *flow)
+{
+       enum macsec_bank bank = flow->bank;
+       u32 val, idx = flow->index;
+
+       /* Disable */
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_ENTRY_CLEAR1, BIT(idx));
+
+       /* Clear in-use */
+       val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_SAM_FLOW_CTRL(idx));
+       val &= ~MSCC_MS_SAM_FLOW_CTRL_SA_IN_USE;
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_FLOW_CTRL(idx), val);
+}
+
+static u32 vsc8584_macsec_flow_context_id(struct macsec_flow *flow)
+{
+       if (flow->bank == MACSEC_INGR)
+               return flow->index + MSCC_MS_MAX_FLOWS;
+
+       return flow->index;
+}
+
+/* Derive the AES key to get a key for the hash autentication */
+static int vsc8584_macsec_derive_key(const u8 key[MACSEC_KEYID_LEN],
+                                    u16 key_len, u8 hkey[16])
+{
+       struct crypto_skcipher *tfm = crypto_alloc_skcipher("ecb(aes)", 0, 0);
+       struct skcipher_request *req = NULL;
+       struct scatterlist src, dst;
+       DECLARE_CRYPTO_WAIT(wait);
+       u32 input[4] = {0};
+       int ret;
+
+       if (IS_ERR(tfm))
+               return PTR_ERR(tfm);
+
+       req = skcipher_request_alloc(tfm, GFP_KERNEL);
+       if (!req) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
+                                     CRYPTO_TFM_REQ_MAY_SLEEP, crypto_req_done,
+                                     &wait);
+       ret = crypto_skcipher_setkey(tfm, key, key_len);
+       if (ret < 0)
+               goto out;
+
+       sg_init_one(&src, input, 16);
+       sg_init_one(&dst, hkey, 16);
+       skcipher_request_set_crypt(req, &src, &dst, 16, NULL);
+
+       ret = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
+
+out:
+       skcipher_request_free(req);
+       crypto_free_skcipher(tfm);
+       return ret;
+}
+
+static int vsc8584_macsec_transformation(struct phy_device *phydev,
+                                        struct macsec_flow *flow)
+{
+       struct vsc8531_private *priv = phydev->priv;
+       enum macsec_bank bank = flow->bank;
+       int i, ret, index = flow->index;
+       u32 rec = 0, control = 0;
+       u8 hkey[16];
+       sci_t sci;
+
+       ret = vsc8584_macsec_derive_key(flow->key, priv->secy->key_len, hkey);
+       if (ret)
+               return ret;
+
+       switch (priv->secy->key_len) {
+       case 16:
+               control |= CONTROL_CRYPTO_ALG(CTRYPTO_ALG_AES_CTR_128);
+               break;
+       case 32:
+               control |= CONTROL_CRYPTO_ALG(CTRYPTO_ALG_AES_CTR_256);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       control |= (bank == MACSEC_EGR) ?
+                  (CONTROL_TYPE_EGRESS | CONTROL_AN(priv->secy->tx_sc.encoding_sa)) :
+                  (CONTROL_TYPE_INGRESS | CONTROL_SEQ_MASK);
+
+       control |= CONTROL_UPDATE_SEQ | CONTROL_ENCRYPT_AUTH | CONTROL_KEY_IN_CTX |
+                  CONTROL_IV0 | CONTROL_IV1 | CONTROL_IV_IN_SEQ |
+                  CONTROL_DIGEST_TYPE(0x2) | CONTROL_SEQ_TYPE(0x1) |
+                  CONTROL_AUTH_ALG(AUTH_ALG_AES_GHAS) | CONTROL_CONTEXT_ID;
+
+       /* Set the control word */
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_XFORM_REC(index, rec++),
+                                control);
+
+       /* Set the context ID. Must be unique. */
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_XFORM_REC(index, rec++),
+                                vsc8584_macsec_flow_context_id(flow));
+
+       /* Set the encryption/decryption key */
+       for (i = 0; i < priv->secy->key_len / sizeof(u32); i++)
+               vsc8584_macsec_phy_write(phydev, bank,
+                                        MSCC_MS_XFORM_REC(index, rec++),
+                                        ((u32 *)flow->key)[i]);
+
+       /* Set the authentication key */
+       for (i = 0; i < 4; i++)
+               vsc8584_macsec_phy_write(phydev, bank,
+                                        MSCC_MS_XFORM_REC(index, rec++),
+                                        ((u32 *)hkey)[i]);
+
+       /* Initial sequence number */
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_XFORM_REC(index, rec++),
+                                bank == MACSEC_INGR ?
+                                flow->rx_sa->next_pn : flow->tx_sa->next_pn);
+
+       if (bank == MACSEC_INGR)
+               /* Set the mask (replay window size) */
+               vsc8584_macsec_phy_write(phydev, bank,
+                                        MSCC_MS_XFORM_REC(index, rec++),
+                                        priv->secy->replay_window);
+
+       /* Set the input vectors */
+       sci = bank == MACSEC_INGR ? flow->rx_sa->sc->sci : priv->secy->sci;
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_XFORM_REC(index, rec++),
+                                lower_32_bits(sci));
+       vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_XFORM_REC(index, rec++),
+                                upper_32_bits(sci));
+
+       while (rec < 20)
+               vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_XFORM_REC(index, rec++),
+                                        0);
+
+       flow->has_transformation = true;
+       return 0;
+}
+
+static struct macsec_flow *vsc8584_macsec_alloc_flow(struct vsc8531_private *priv,
+                                                    enum macsec_bank bank)
+{
+       unsigned long *bitmap = bank == MACSEC_INGR ?
+                               &priv->ingr_flows : &priv->egr_flows;
+       struct macsec_flow *flow;
+       int index;
+
+       index = find_first_zero_bit(bitmap, MSCC_MS_MAX_FLOWS);
+
+       if (index == MSCC_MS_MAX_FLOWS)
+               return ERR_PTR(-ENOMEM);
+
+       flow = kzalloc(sizeof(*flow), GFP_KERNEL);
+       if (!flow)
+               return ERR_PTR(-ENOMEM);
+
+       set_bit(index, bitmap);
+       flow->index = index;
+       flow->bank = bank;
+       flow->priority = 8;
+       flow->assoc_num = -1;
+
+       list_add_tail(&flow->list, &priv->macsec_flows);
+       return flow;
+}
+
+static void vsc8584_macsec_free_flow(struct vsc8531_private *priv,
+                                    struct macsec_flow *flow)
+{
+       unsigned long *bitmap = flow->bank == MACSEC_INGR ?
+                               &priv->ingr_flows : &priv->egr_flows;
+
+       list_del(&flow->list);
+       clear_bit(flow->index, bitmap);
+       kfree(flow);
+}
+
+static int vsc8584_macsec_add_flow(struct phy_device *phydev,
+                                  struct macsec_flow *flow, bool update)
+{
+       int ret;
+
+       flow->port = MSCC_MS_PORT_CONTROLLED;
+       vsc8584_macsec_flow(phydev, flow);
+
+       if (update)
+               return 0;
+
+       ret = vsc8584_macsec_transformation(phydev, flow);
+       if (ret) {
+               vsc8584_macsec_free_flow(phydev->priv, flow);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int vsc8584_macsec_default_flows(struct phy_device *phydev)
+{
+       struct macsec_flow *flow;
+
+       /* Add a rule to let the MKA traffic go through, ingress */
+       flow = vsc8584_macsec_alloc_flow(phydev->priv, MACSEC_INGR);
+       if (IS_ERR(flow))
+               return PTR_ERR(flow);
+
+       flow->priority = 15;
+       flow->port = MSCC_MS_PORT_UNCONTROLLED;
+       flow->match.tagged = 1;
+       flow->match.untagged = 1;
+       flow->match.etype = 1;
+       flow->etype = ETH_P_PAE;
+       flow->action.bypass = 1;
+
+       vsc8584_macsec_flow(phydev, flow);
+       vsc8584_macsec_flow_enable(phydev, flow);
+
+       /* Add a rule to let the MKA traffic go through, egress */
+       flow = vsc8584_macsec_alloc_flow(phydev->priv, MACSEC_EGR);
+       if (IS_ERR(flow))
+               return PTR_ERR(flow);
+
+       flow->priority = 15;
+       flow->port = MSCC_MS_PORT_COMMON;
+       flow->match.untagged = 1;
+       flow->match.etype = 1;
+       flow->etype = ETH_P_PAE;
+       flow->action.bypass = 1;
+
+       vsc8584_macsec_flow(phydev, flow);
+       vsc8584_macsec_flow_enable(phydev, flow);
+
+       return 0;
+}
+
+static void vsc8584_macsec_del_flow(struct phy_device *phydev,
+                                   struct macsec_flow *flow)
+{
+       vsc8584_macsec_flow_disable(phydev, flow);
+       vsc8584_macsec_free_flow(phydev->priv, flow);
+}
+
+static int __vsc8584_macsec_add_rxsa(struct macsec_context *ctx,
+                                    struct macsec_flow *flow, bool update)
+{
+       struct phy_device *phydev = ctx->phydev;
+       struct vsc8531_private *priv = phydev->priv;
+
+       if (!flow) {
+               flow = vsc8584_macsec_alloc_flow(priv, MACSEC_INGR);
+               if (IS_ERR(flow))
+                       return PTR_ERR(flow);
+
+               memcpy(flow->key, ctx->sa.key, priv->secy->key_len);
+       }
+
+       flow->assoc_num = ctx->sa.assoc_num;
+       flow->rx_sa = ctx->sa.rx_sa;
+
+       /* Always match tagged packets on ingress */
+       flow->match.tagged = 1;
+       flow->match.sci = 1;
+
+       if (priv->secy->validate_frames != MACSEC_VALIDATE_DISABLED)
+               flow->match.untagged = 1;
+
+       return vsc8584_macsec_add_flow(phydev, flow, update);
+}
+
+static int __vsc8584_macsec_add_txsa(struct macsec_context *ctx,
+                                    struct macsec_flow *flow, bool update)
+{
+       struct phy_device *phydev = ctx->phydev;
+       struct vsc8531_private *priv = phydev->priv;
+
+       if (!flow) {
+               flow = vsc8584_macsec_alloc_flow(priv, MACSEC_EGR);
+               if (IS_ERR(flow))
+                       return PTR_ERR(flow);
+
+               memcpy(flow->key, ctx->sa.key, priv->secy->key_len);
+       }
+
+       flow->assoc_num = ctx->sa.assoc_num;
+       flow->tx_sa = ctx->sa.tx_sa;
+
+       /* Always match untagged packets on egress */
+       flow->match.untagged = 1;
+
+       return vsc8584_macsec_add_flow(phydev, flow, update);
+}
+
+static int vsc8584_macsec_dev_open(struct macsec_context *ctx)
+{
+       struct vsc8531_private *priv = ctx->phydev->priv;
+       struct macsec_flow *flow, *tmp;
+
+       /* No operation to perform before the commit step */
+       if (ctx->prepare)
+               return 0;
+
+       list_for_each_entry_safe(flow, tmp, &priv->macsec_flows, list)
+               vsc8584_macsec_flow_enable(ctx->phydev, flow);
+
+       return 0;
+}
+
+static int vsc8584_macsec_dev_stop(struct macsec_context *ctx)
+{
+       struct vsc8531_private *priv = ctx->phydev->priv;
+       struct macsec_flow *flow, *tmp;
+
+       /* No operation to perform before the commit step */
+       if (ctx->prepare)
+               return 0;
+
+       list_for_each_entry_safe(flow, tmp, &priv->macsec_flows, list)
+               vsc8584_macsec_flow_disable(ctx->phydev, flow);
+
+       return 0;
+}
+
+static int vsc8584_macsec_add_secy(struct macsec_context *ctx)
+{
+       struct vsc8531_private *priv = ctx->phydev->priv;
+       struct macsec_secy *secy = ctx->secy;
+
+       if (ctx->prepare) {
+               if (priv->secy)
+                       return -EEXIST;
+
+               return 0;
+       }
+
+       priv->secy = secy;
+
+       vsc8584_macsec_flow_default_action(ctx->phydev, MACSEC_EGR,
+                                          secy->validate_frames != MACSEC_VALIDATE_DISABLED);
+       vsc8584_macsec_flow_default_action(ctx->phydev, MACSEC_INGR,
+                                          secy->validate_frames != MACSEC_VALIDATE_DISABLED);
+
+       return vsc8584_macsec_default_flows(ctx->phydev);
+}
+
+static int vsc8584_macsec_del_secy(struct macsec_context *ctx)
+{
+       struct vsc8531_private *priv = ctx->phydev->priv;
+       struct macsec_flow *flow, *tmp;
+
+       /* No operation to perform before the commit step */
+       if (ctx->prepare)
+               return 0;
+
+       list_for_each_entry_safe(flow, tmp, &priv->macsec_flows, list)
+               vsc8584_macsec_del_flow(ctx->phydev, flow);
+
+       vsc8584_macsec_flow_default_action(ctx->phydev, MACSEC_EGR, false);
+       vsc8584_macsec_flow_default_action(ctx->phydev, MACSEC_INGR, false);
+
+       priv->secy = NULL;
+       return 0;
+}
+
+static int vsc8584_macsec_upd_secy(struct macsec_context *ctx)
+{
+       /* No operation to perform before the commit step */
+       if (ctx->prepare)
+               return 0;
+
+       vsc8584_macsec_del_secy(ctx);
+       return vsc8584_macsec_add_secy(ctx);
+}
+
+static int vsc8584_macsec_add_rxsc(struct macsec_context *ctx)
+{
+       /* Nothing to do */
+       return 0;
+}
+
+static int vsc8584_macsec_upd_rxsc(struct macsec_context *ctx)
+{
+       return -EOPNOTSUPP;
+}
+
+static int vsc8584_macsec_del_rxsc(struct macsec_context *ctx)
+{
+       struct vsc8531_private *priv = ctx->phydev->priv;
+       struct macsec_flow *flow, *tmp;
+
+       /* No operation to perform before the commit step */
+       if (ctx->prepare)
+               return 0;
+
+       list_for_each_entry_safe(flow, tmp, &priv->macsec_flows, list) {
+               if (flow->bank == MACSEC_INGR && flow->rx_sa &&
+                   flow->rx_sa->sc->sci == ctx->rx_sc->sci)
+                       vsc8584_macsec_del_flow(ctx->phydev, flow);
+       }
+
+       return 0;
+}
+
+static int vsc8584_macsec_add_rxsa(struct macsec_context *ctx)
+{
+       struct macsec_flow *flow = NULL;
+
+       if (ctx->prepare)
+               return __vsc8584_macsec_add_rxsa(ctx, flow, false);
+
+       flow = vsc8584_macsec_find_flow(ctx, MACSEC_INGR);
+       if (IS_ERR(flow))
+               return PTR_ERR(flow);
+
+       vsc8584_macsec_flow_enable(ctx->phydev, flow);
+       return 0;
+}
+
+static int vsc8584_macsec_upd_rxsa(struct macsec_context *ctx)
+{
+       struct macsec_flow *flow;
+
+       flow = vsc8584_macsec_find_flow(ctx, MACSEC_INGR);
+       if (IS_ERR(flow))
+               return PTR_ERR(flow);
+
+       if (ctx->prepare) {
+               /* Make sure the flow is disabled before updating it */
+               vsc8584_macsec_flow_disable(ctx->phydev, flow);
+
+               return __vsc8584_macsec_add_rxsa(ctx, flow, true);
+       }
+
+       vsc8584_macsec_flow_enable(ctx->phydev, flow);
+       return 0;
+}
+
+static int vsc8584_macsec_del_rxsa(struct macsec_context *ctx)
+{
+       struct macsec_flow *flow;
+
+       flow = vsc8584_macsec_find_flow(ctx, MACSEC_INGR);
+
+       if (IS_ERR(flow))
+               return PTR_ERR(flow);
+       if (ctx->prepare)
+               return 0;
+
+       vsc8584_macsec_del_flow(ctx->phydev, flow);
+       return 0;
+}
+
+static int vsc8584_macsec_add_txsa(struct macsec_context *ctx)
+{
+       struct macsec_flow *flow = NULL;
+
+       if (ctx->prepare)
+               return __vsc8584_macsec_add_txsa(ctx, flow, false);
+
+       flow = vsc8584_macsec_find_flow(ctx, MACSEC_EGR);
+       if (IS_ERR(flow))
+               return PTR_ERR(flow);
+
+       vsc8584_macsec_flow_enable(ctx->phydev, flow);
+       return 0;
+}
+
+static int vsc8584_macsec_upd_txsa(struct macsec_context *ctx)
+{
+       struct macsec_flow *flow;
+
+       flow = vsc8584_macsec_find_flow(ctx, MACSEC_EGR);
+       if (IS_ERR(flow))
+               return PTR_ERR(flow);
+
+       if (ctx->prepare) {
+               /* Make sure the flow is disabled before updating it */
+               vsc8584_macsec_flow_disable(ctx->phydev, flow);
+
+               return __vsc8584_macsec_add_txsa(ctx, flow, true);
+       }
+
+       vsc8584_macsec_flow_enable(ctx->phydev, flow);
+       return 0;
+}
+
+static int vsc8584_macsec_del_txsa(struct macsec_context *ctx)
+{
+       struct macsec_flow *flow;
+
+       flow = vsc8584_macsec_find_flow(ctx, MACSEC_EGR);
+
+       if (IS_ERR(flow))
+               return PTR_ERR(flow);
+       if (ctx->prepare)
+               return 0;
+
+       vsc8584_macsec_del_flow(ctx->phydev, flow);
+       return 0;
+}
+
+static struct macsec_ops vsc8584_macsec_ops = {
+       .mdo_dev_open = vsc8584_macsec_dev_open,
+       .mdo_dev_stop = vsc8584_macsec_dev_stop,
+       .mdo_add_secy = vsc8584_macsec_add_secy,
+       .mdo_upd_secy = vsc8584_macsec_upd_secy,
+       .mdo_del_secy = vsc8584_macsec_del_secy,
+       .mdo_add_rxsc = vsc8584_macsec_add_rxsc,
+       .mdo_upd_rxsc = vsc8584_macsec_upd_rxsc,
+       .mdo_del_rxsc = vsc8584_macsec_del_rxsc,
+       .mdo_add_rxsa = vsc8584_macsec_add_rxsa,
+       .mdo_upd_rxsa = vsc8584_macsec_upd_rxsa,
+       .mdo_del_rxsa = vsc8584_macsec_del_rxsa,
+       .mdo_add_txsa = vsc8584_macsec_add_txsa,
+       .mdo_upd_txsa = vsc8584_macsec_upd_txsa,
+       .mdo_del_txsa = vsc8584_macsec_del_txsa,
+};
+#endif /* CONFIG_MACSEC */
+
+/* Check if one PHY has already done the init of the parts common to all PHYs
+ * in the Quad PHY package.
+ */
+static bool vsc8584_is_pkg_init(struct phy_device *phydev, bool reversed)
+{
+       struct mdio_device **map = phydev->mdio.bus->mdio_map;
+       struct vsc8531_private *vsc8531;
+       struct phy_device *phy;
+       int i, addr;
+
+       /* VSC8584 is a Quad PHY */
+       for (i = 0; i < 4; i++) {
+               vsc8531 = phydev->priv;
+
+               if (reversed)
+                       addr = vsc8531->base_addr - i;
+               else
+                       addr = vsc8531->base_addr + i;
+
+               if (!map[addr])
+                       continue;
+
+               phy = container_of(map[addr], struct phy_device, mdio);
+
+               if ((phy->phy_id & phydev->drv->phy_id_mask) !=
+                   (phydev->drv->phy_id & phydev->drv->phy_id_mask))
+                       continue;
+
+               vsc8531 = phy->priv;
+
+               if (vsc8531 && vsc8531->pkg_init)
+                       return true;
+       }
+
+       return false;
+}
+
+static int vsc8584_config_init(struct phy_device *phydev)
+{
+       struct vsc8531_private *vsc8531 = phydev->priv;
+       u16 addr, val;
+       int ret, i;
+
+       phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
+
+       mutex_lock(&phydev->mdio.bus->mdio_lock);
+
+       __mdiobus_write(phydev->mdio.bus, phydev->mdio.addr,
+                       MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
+       addr = __mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
+                             MSCC_PHY_EXT_PHY_CNTL_4);
+       addr >>= PHY_CNTL_4_ADDR_POS;
+
+       val = __mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
+                            MSCC_PHY_ACTIPHY_CNTL);
+       if (val & PHY_ADDR_REVERSED)
+               vsc8531->base_addr = phydev->mdio.addr + addr;
+       else
+               vsc8531->base_addr = phydev->mdio.addr - addr;
+
+       /* Some parts of the init sequence are identical for every PHY in the
+        * package. Some parts are modifying the GPIO register bank which is a
+        * set of registers that are affecting all PHYs, a few resetting the
+        * microprocessor common to all PHYs. The CRC check responsible of the
+        * checking the firmware within the 8051 microprocessor can only be
+        * accessed via the PHY whose internal address in the package is 0.
+        * All PHYs' interrupts mask register has to be zeroed before enabling
+        * any PHY's interrupt in this register.
+        * For all these reasons, we need to do the init sequence once and only
+        * once whatever is the first PHY in the package that is initialized and
+        * do the correct init sequence for all PHYs that are package-critical
+        * in this pre-init function.
+        */
+       if (!vsc8584_is_pkg_init(phydev, val & PHY_ADDR_REVERSED ? 1 : 0)) {
+               /* The following switch statement assumes that the lowest
+                * nibble of the phy_id_mask is always 0. This works because
+                * the lowest nibble of the PHY_ID's below are also 0.
+                */
+               WARN_ON(phydev->drv->phy_id_mask & 0xf);
+
+               switch (phydev->phy_id & phydev->drv->phy_id_mask) {
+               case PHY_ID_VSC8504:
+               case PHY_ID_VSC8552:
+               case PHY_ID_VSC8572:
+               case PHY_ID_VSC8574:
+                       ret = vsc8574_config_pre_init(phydev);
+                       break;
+               case PHY_ID_VSC856X:
+               case PHY_ID_VSC8575:
+               case PHY_ID_VSC8582:
+               case PHY_ID_VSC8584:
+                       ret = vsc8584_config_pre_init(phydev);
+                       break;
+               default:
+                       ret = -EINVAL;
+                       break;
+               }
+
+               if (ret)
+                       goto err;
+       }
+
+       vsc8531->pkg_init = true;
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
+                      MSCC_PHY_PAGE_EXTENDED_GPIO);
+
+       val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
+       val &= ~MAC_CFG_MASK;
+       if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
+               val |= MAC_CFG_QSGMII;
+       else
+               val |= MAC_CFG_SGMII;
+
+       ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
+       if (ret)
+               goto err;
+
+       val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
+               PROC_CMD_READ_MOD_WRITE_PORT;
+       if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
+               val |= PROC_CMD_QSGMII_MAC;
+       else
+               val |= PROC_CMD_SGMII_MAC;
+
+       ret = vsc8584_cmd(phydev, val);
+       if (ret)
+               goto err;
+
+       usleep_range(10000, 20000);
+
+       /* Disable SerDes for 100Base-FX */
+       ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
+                         PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
+                         PROC_CMD_READ_MOD_WRITE_PORT |
+                         PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_100BASE_FX);
+       if (ret)
+               goto err;
+
+       /* Disable SerDes for 1000Base-X */
+       ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
+                         PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
+                         PROC_CMD_READ_MOD_WRITE_PORT |
+                         PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X);
+       if (ret)
+               goto err;
+
+       mutex_unlock(&phydev->mdio.bus->mdio_lock);
+
+#if IS_ENABLED(CONFIG_MACSEC)
+       /* MACsec */
+       switch (phydev->phy_id & phydev->drv->phy_id_mask) {
+       case PHY_ID_VSC856X:
+       case PHY_ID_VSC8575:
+       case PHY_ID_VSC8582:
+       case PHY_ID_VSC8584:
+               INIT_LIST_HEAD(&vsc8531->macsec_flows);
+               vsc8531->secy = NULL;
+
+               phydev->macsec_ops = &vsc8584_macsec_ops;
+
+               ret = vsc8584_macsec_init(phydev);
+               if (ret)
+                       goto err;
+       }
+#endif
+
+       phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+       val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
+       val &= ~(MEDIA_OP_MODE_MASK | VSC8584_MAC_IF_SELECTION_MASK);
+       val |= (MEDIA_OP_MODE_COPPER << MEDIA_OP_MODE_POS) |
+              (VSC8584_MAC_IF_SELECTION_SGMII << VSC8584_MAC_IF_SELECTION_POS);
+       ret = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, val);
+
+       ret = genphy_soft_reset(phydev);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < vsc8531->nleds; i++) {
+               ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+
+err:
+       mutex_unlock(&phydev->mdio.bus->mdio_lock);
+       return ret;
+}
+
+static int vsc8584_handle_interrupt(struct phy_device *phydev)
+{
+#if IS_ENABLED(CONFIG_MACSEC)
+       struct vsc8531_private *priv = phydev->priv;
+       struct macsec_flow *flow, *tmp;
+       u32 cause, rec;
+
+       /* Check MACsec PN rollover */
+       cause = vsc8584_macsec_phy_read(phydev, MACSEC_EGR,
+                                       MSCC_MS_INTR_CTRL_STATUS);
+       cause &= MSCC_MS_INTR_CTRL_STATUS_INTR_CLR_STATUS_M;
+       if (!(cause & MACSEC_INTR_CTRL_STATUS_ROLLOVER))
+               goto skip_rollover;
+
+       rec = 6 + priv->secy->key_len / sizeof(u32);
+       list_for_each_entry_safe(flow, tmp, &priv->macsec_flows, list) {
+               u32 val;
+
+               if (flow->bank != MACSEC_EGR || !flow->has_transformation)
+                       continue;
+
+               val = vsc8584_macsec_phy_read(phydev, MACSEC_EGR,
+                                             MSCC_MS_XFORM_REC(flow->index, rec));
+               if (val == 0xffffffff) {
+                       vsc8584_macsec_flow_disable(phydev, flow);
+                       macsec_pn_wrapped(priv->secy, flow->tx_sa);
+                       break;
+               }
+       }
+
+skip_rollover:
+#endif
+
+       phy_mac_interrupt(phydev);
+       return 0;
+}
+
+static int vsc85xx_config_init(struct phy_device *phydev)
+{
+       int rc, i, phy_id;
+       struct vsc8531_private *vsc8531 = phydev->priv;
+
+       rc = vsc85xx_default_config(phydev);
+       if (rc)
+               return rc;
+
+       rc = vsc85xx_mac_if_set(phydev, phydev->interface);
+       if (rc)
+               return rc;
+
+       rc = vsc85xx_edge_rate_cntl_set(phydev, vsc8531->rate_magic);
+       if (rc)
+               return rc;
+
+       phy_id = phydev->drv->phy_id & phydev->drv->phy_id_mask;
+       if (PHY_ID_VSC8531 == phy_id || PHY_ID_VSC8541 == phy_id ||
+           PHY_ID_VSC8530 == phy_id || PHY_ID_VSC8540 == phy_id) {
+               rc = vsc8531_pre_init_seq_set(phydev);
+               if (rc)
+                       return rc;
+       }
+
+       rc = vsc85xx_eee_init_seq_set(phydev);
+       if (rc)
+               return rc;
+
+       for (i = 0; i < vsc8531->nleds; i++) {
+               rc = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
+               if (rc)
+                       return rc;
+       }
+
+       return 0;
+}
+
+static int vsc8584_did_interrupt(struct phy_device *phydev)
+{
+       int rc = 0;
+
+       if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
+               rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
+
+       return (rc < 0) ? 0 : rc & MII_VSC85XX_INT_MASK_MASK;
+}
+
+static int vsc8514_config_pre_init(struct phy_device *phydev)
+{
+       /* These are the settings to override the silicon default
+        * values to handle hardware performance of PHY. They
+        * are set at Power-On state and remain until PHY Reset.
+        */
+       static const struct reg_val pre_init1[] = {
+               {0x0f90, 0x00688980},
+               {0x0786, 0x00000003},
+               {0x07fa, 0x0050100f},
+               {0x0f82, 0x0012b002},
+               {0x1686, 0x00000004},
+               {0x168c, 0x00d2c46f},
+               {0x17a2, 0x00000620},
+               {0x16a0, 0x00eeffdd},
+               {0x16a6, 0x00071448},
+               {0x16a4, 0x0013132f},
+               {0x16a8, 0x00000000},
+               {0x0ffc, 0x00c0a028},
+               {0x0fe8, 0x0091b06c},
+               {0x0fea, 0x00041600},
+               {0x0f80, 0x00fffaff},
+               {0x0fec, 0x00901809},
+               {0x0ffe, 0x00b01007},
+               {0x16b0, 0x00eeff00},
+               {0x16b2, 0x00007000},
+               {0x16b4, 0x00000814},
+       };
+       unsigned int i;
+       u16 reg;
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+       /* all writes below are broadcasted to all PHYs in the same package */
+       reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
+       reg |= SMI_BROADCAST_WR_EN;
+       phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
+
+       reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
+       reg |= BIT(15);
+       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
+
+       for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
+               vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
+
+       reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
+       reg &= ~BIT(15);
+       phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+       reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
+       reg &= ~SMI_BROADCAST_WR_EN;
+       phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
+
+       return 0;
+}
+
+static u32 vsc85xx_csr_ctrl_phy_read(struct phy_device *phydev,
+                                    u32 target, u32 reg)
+{
+       unsigned long deadline;
+       u32 val, val_l, val_h;
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
+
+       /* CSR registers are grouped under different Target IDs.
+        * 6-bit Target_ID is split between MSCC_EXT_PAGE_CSR_CNTL_20 and
+        * MSCC_EXT_PAGE_CSR_CNTL_19 registers.
+        * Target_ID[5:2] maps to bits[3:0] of MSCC_EXT_PAGE_CSR_CNTL_20
+        * and Target_ID[1:0] maps to bits[13:12] of MSCC_EXT_PAGE_CSR_CNTL_19.
+        */
+
+       /* Setup the Target ID */
+       phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_20,
+                      MSCC_PHY_CSR_CNTL_20_TARGET(target >> 2));
+
+       /* Trigger CSR Action - Read into the CSR's */
+       phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_19,
+                      MSCC_PHY_CSR_CNTL_19_CMD | MSCC_PHY_CSR_CNTL_19_READ |
+                      MSCC_PHY_CSR_CNTL_19_REG_ADDR(reg) |
+                      MSCC_PHY_CSR_CNTL_19_TARGET(target & 0x3));
+
+       /* Wait for register access*/
+       deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
+       do {
+               usleep_range(500, 1000);
+               val = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_19);
+       } while (time_before(jiffies, deadline) &&
+               !(val & MSCC_PHY_CSR_CNTL_19_CMD));
+
+       if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
+               return 0xffffffff;
+
+       /* Read the Least Significant Word (LSW) (17) */
+       val_l = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_17);
+
+       /* Read the Most Significant Word (MSW) (18) */
+       val_h = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_18);
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
+                      MSCC_PHY_PAGE_STANDARD);
+
+       return (val_h << 16) | val_l;
+}
+
+static int vsc85xx_csr_ctrl_phy_write(struct phy_device *phydev,
+                                     u32 target, u32 reg, u32 val)
+{
+       unsigned long deadline;
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
+
+       /* CSR registers are grouped under different Target IDs.
+        * 6-bit Target_ID is split between MSCC_EXT_PAGE_CSR_CNTL_20 and
+        * MSCC_EXT_PAGE_CSR_CNTL_19 registers.
+        * Target_ID[5:2] maps to bits[3:0] of MSCC_EXT_PAGE_CSR_CNTL_20
+        * and Target_ID[1:0] maps to bits[13:12] of MSCC_EXT_PAGE_CSR_CNTL_19.
+        */
+
+       /* Setup the Target ID */
+       phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_20,
+                      MSCC_PHY_CSR_CNTL_20_TARGET(target >> 2));
+
+       /* Write the Least Significant Word (LSW) (17) */
+       phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_17, (u16)val);
+
+       /* Write the Most Significant Word (MSW) (18) */
+       phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_18, (u16)(val >> 16));
+
+       /* Trigger CSR Action - Write into the CSR's */
+       phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_19,
+                      MSCC_PHY_CSR_CNTL_19_CMD |
+                      MSCC_PHY_CSR_CNTL_19_REG_ADDR(reg) |
+                      MSCC_PHY_CSR_CNTL_19_TARGET(target & 0x3));
+
+       /* Wait for register access */
+       deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
+       do {
+               usleep_range(500, 1000);
+               val = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_19);
+       } while (time_before(jiffies, deadline) &&
+                !(val & MSCC_PHY_CSR_CNTL_19_CMD));
+
+       if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
+               return -ETIMEDOUT;
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
+                      MSCC_PHY_PAGE_STANDARD);
+
+       return 0;
+}
+
+static int __phy_write_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb,
+                              u32 op)
+{
+       unsigned long deadline;
+       u32 val;
+       int ret;
+
+       ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET, reg,
+                                        op | (1 << mcb));
+       if (ret)
+               return -EINVAL;
+
+       deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
+       do {
+               usleep_range(500, 1000);
+               val = vsc85xx_csr_ctrl_phy_read(phydev, PHY_MCB_TARGET, reg);
+
+               if (val == 0xffffffff)
+                       return -EIO;
+
+       } while (time_before(jiffies, deadline) && (val & op));
+
+       if (val & op)
+               return -ETIMEDOUT;
+
+       return 0;
+}
+
+/* Trigger a read to the spcified MCB */
+static int phy_update_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
+{
+       return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_READ);
+}
+
+/* Trigger a write to the spcified MCB */
+static int phy_commit_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
+{
+       return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_WRITE);
+}
+
+static int vsc8514_config_init(struct phy_device *phydev)
+{
+       struct vsc8531_private *vsc8531 = phydev->priv;
+       unsigned long deadline;
+       u16 val, addr;
+       int ret, i;
+       u32 reg;
+
+       phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
+
+       mutex_lock(&phydev->mdio.bus->mdio_lock);
+
+       __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
+
+       addr = __phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_4);
+       addr >>= PHY_CNTL_4_ADDR_POS;
+
+       val = __phy_read(phydev, MSCC_PHY_ACTIPHY_CNTL);
+
+       if (val & PHY_ADDR_REVERSED)
+               vsc8531->base_addr = phydev->mdio.addr + addr;
+       else
+               vsc8531->base_addr = phydev->mdio.addr - addr;
+
+       /* Some parts of the init sequence are identical for every PHY in the
+        * package. Some parts are modifying the GPIO register bank which is a
+        * set of registers that are affecting all PHYs, a few resetting the
+        * microprocessor common to all PHYs.
+        * All PHYs' interrupts mask register has to be zeroed before enabling
+        * any PHY's interrupt in this register.
+        * For all these reasons, we need to do the init sequence once and only
+        * once whatever is the first PHY in the package that is initialized and
+        * do the correct init sequence for all PHYs that are package-critical
+        * in this pre-init function.
+        */
+       if (!vsc8584_is_pkg_init(phydev, val & PHY_ADDR_REVERSED ? 1 : 0))
+               vsc8514_config_pre_init(phydev);
+
+       vsc8531->pkg_init = true;
+
+       phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
+                      MSCC_PHY_PAGE_EXTENDED_GPIO);
+
+       val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
+
+       val &= ~MAC_CFG_MASK;
+       val |= MAC_CFG_QSGMII;
+       ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
+
+       if (ret)
+               goto err;
+
+       ret = vsc8584_cmd(phydev,
+                         PROC_CMD_MCB_ACCESS_MAC_CONF |
+                         PROC_CMD_RST_CONF_PORT |
+                         PROC_CMD_READ_MOD_WRITE_PORT | PROC_CMD_QSGMII_MAC);
+       if (ret)
+               goto err;
+
+       /* 6g mcb */
+       phy_update_mcb_s6g(phydev, PHY_MCB_S6G_CFG, 0);
+       /* lcpll mcb */
+       phy_update_mcb_s6g(phydev, PHY_S6G_LCPLL_CFG, 0);
+       /* pll5gcfg0 */
+       ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
+                                        PHY_S6G_PLL5G_CFG0, 0x7036f145);
+       if (ret)
+               goto err;
+
+       phy_commit_mcb_s6g(phydev, PHY_S6G_LCPLL_CFG, 0);
+       /* pllcfg */
+       ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
+                                        PHY_S6G_PLL_CFG,
+                                        (3 << PHY_S6G_PLL_ENA_OFFS_POS) |
+                                        (120 << PHY_S6G_PLL_FSM_CTRL_DATA_POS)
+                                        | (0 << PHY_S6G_PLL_FSM_ENA_POS));
+       if (ret)
+               goto err;
+
+       /* commoncfg */
+       ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
+                                        PHY_S6G_COMMON_CFG,
+                                        (0 << PHY_S6G_SYS_RST_POS) |
+                                        (0 << PHY_S6G_ENA_LANE_POS) |
+                                        (0 << PHY_S6G_ENA_LOOP_POS) |
+                                        (0 << PHY_S6G_QRATE_POS) |
+                                        (3 << PHY_S6G_IF_MODE_POS));
+       if (ret)
+               goto err;
+
+       /* misccfg */
+       ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
+                                        PHY_S6G_MISC_CFG, 1);
+       if (ret)
+               goto err;
+
+       /* gpcfg */
+       ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
+                                        PHY_S6G_GPC_CFG, 768);
+       if (ret)
+               goto err;
+
+       phy_commit_mcb_s6g(phydev, PHY_S6G_DFT_CFG2, 0);
+
+       deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
+       do {
+               usleep_range(500, 1000);
+               phy_update_mcb_s6g(phydev, PHY_MCB_S6G_CFG,
+                                  0); /* read 6G MCB into CSRs */
+               reg = vsc85xx_csr_ctrl_phy_read(phydev, PHY_MCB_TARGET,
+                                               PHY_S6G_PLL_STATUS);
+               if (reg == 0xffffffff) {
+                       mutex_unlock(&phydev->mdio.bus->mdio_lock);
+                       return -EIO;
+               }
+
+       } while (time_before(jiffies, deadline) && (reg & BIT(12)));
+
+       if (reg & BIT(12)) {
+               mutex_unlock(&phydev->mdio.bus->mdio_lock);
+               return -ETIMEDOUT;
+       }
+
+       /* misccfg */
+       ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
+                                        PHY_S6G_MISC_CFG, 0);
+       if (ret)
+               goto err;
+
+       phy_commit_mcb_s6g(phydev, PHY_MCB_S6G_CFG, 0);
+
+       deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
+       do {
+               usleep_range(500, 1000);
+               phy_update_mcb_s6g(phydev, PHY_MCB_S6G_CFG,
+                                  0); /* read 6G MCB into CSRs */
+               reg = vsc85xx_csr_ctrl_phy_read(phydev, PHY_MCB_TARGET,
+                                               PHY_S6G_IB_STATUS0);
+               if (reg == 0xffffffff) {
+                       mutex_unlock(&phydev->mdio.bus->mdio_lock);
+                       return -EIO;
+               }
+
+       } while (time_before(jiffies, deadline) && !(reg & BIT(8)));
+
+       if (!(reg & BIT(8))) {
+               mutex_unlock(&phydev->mdio.bus->mdio_lock);
+               return -ETIMEDOUT;
+       }
+
+       mutex_unlock(&phydev->mdio.bus->mdio_lock);
+
+       ret = phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+       if (ret)
+               return ret;
+
+       ret = phy_modify(phydev, MSCC_PHY_EXT_PHY_CNTL_1, MEDIA_OP_MODE_MASK,
+                        MEDIA_OP_MODE_COPPER << MEDIA_OP_MODE_POS);
+
+       if (ret)
+               return ret;
+
+       ret = genphy_soft_reset(phydev);
+
+       if (ret)
+               return ret;
+
+       for (i = 0; i < vsc8531->nleds; i++) {
+               ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
+               if (ret)
+                       return ret;
+       }
+
+       return ret;
+
+err:
+       mutex_unlock(&phydev->mdio.bus->mdio_lock);
+       return ret;
+}
+
+static int vsc85xx_ack_interrupt(struct phy_device *phydev)
+{
+       int rc = 0;
+
+       if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
+               rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
+
+       return (rc < 0) ? rc : 0;
+}
+
+static int vsc85xx_config_intr(struct phy_device *phydev)
+{
+       int rc;
+
+       if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
+#if IS_ENABLED(CONFIG_MACSEC)
+               phy_write(phydev, MSCC_EXT_PAGE_ACCESS,
+                         MSCC_PHY_PAGE_EXTENDED_2);
+               phy_write(phydev, MSCC_PHY_EXTENDED_INT,
+                         MSCC_PHY_EXTENDED_INT_MS_EGR);
+               phy_write(phydev, MSCC_EXT_PAGE_ACCESS,
+                         MSCC_PHY_PAGE_STANDARD);
+
+               vsc8584_macsec_phy_write(phydev, MACSEC_EGR,
+                                        MSCC_MS_AIC_CTRL, 0xf);
+               vsc8584_macsec_phy_write(phydev, MACSEC_EGR,
+                       MSCC_MS_INTR_CTRL_STATUS,
+                       MSCC_MS_INTR_CTRL_STATUS_INTR_ENABLE(MACSEC_INTR_CTRL_STATUS_ROLLOVER));
+#endif
+               rc = phy_write(phydev, MII_VSC85XX_INT_MASK,
+                              MII_VSC85XX_INT_MASK_MASK);
+       } else {
+               rc = phy_write(phydev, MII_VSC85XX_INT_MASK, 0);
+               if (rc < 0)
+                       return rc;
+               rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
+       }
+
+       return rc;
+}
+
+static int vsc85xx_config_aneg(struct phy_device *phydev)
+{
+       int rc;
+
+       rc = vsc85xx_mdix_set(phydev, phydev->mdix_ctrl);
+       if (rc < 0)
+               return rc;
+
+       return genphy_config_aneg(phydev);
+}
+
+static int vsc85xx_read_status(struct phy_device *phydev)
+{
+       int rc;
+
+       rc = vsc85xx_mdix_get(phydev, &phydev->mdix);
+       if (rc < 0)
+               return rc;
+
+       return genphy_read_status(phydev);
+}
+
+static int vsc8514_probe(struct phy_device *phydev)
+{
+       struct vsc8531_private *vsc8531;
+       u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
+          VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
+          VSC8531_DUPLEX_COLLISION};
+
+       vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
+       if (!vsc8531)
+               return -ENOMEM;
+
+       phydev->priv = vsc8531;
+
+       vsc8531->nleds = 4;
+       vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES;
+       vsc8531->hw_stats = vsc85xx_hw_stats;
+       vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats);
+       vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
+                                     sizeof(u64), GFP_KERNEL);
+       if (!vsc8531->stats)
+               return -ENOMEM;
+
+       return vsc85xx_dt_led_modes_get(phydev, default_mode);
+}
+
+static int vsc8574_probe(struct phy_device *phydev)
+{
+       struct vsc8531_private *vsc8531;
+       u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
+          VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
+          VSC8531_DUPLEX_COLLISION};
+
+       vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
+       if (!vsc8531)
+               return -ENOMEM;
+
+       phydev->priv = vsc8531;
+
+       vsc8531->nleds = 4;
+       vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES;
+       vsc8531->hw_stats = vsc8584_hw_stats;
+       vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats);
+       vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
+                                     sizeof(u64), GFP_KERNEL);
+       if (!vsc8531->stats)
+               return -ENOMEM;
+
+       return vsc85xx_dt_led_modes_get(phydev, default_mode);
+}
+
+static int vsc8584_probe(struct phy_device *phydev)
+{
+       struct vsc8531_private *vsc8531;
+       u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
+          VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
+          VSC8531_DUPLEX_COLLISION};
+
+       if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) {
+               dev_err(&phydev->mdio.dev, "Only VSC8584 revB is supported.\n");
+               return -ENOTSUPP;
+       }
+
+       vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
+       if (!vsc8531)
+               return -ENOMEM;
+
+       phydev->priv = vsc8531;
+
+       vsc8531->nleds = 4;
+       vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES;
+       vsc8531->hw_stats = vsc8584_hw_stats;
+       vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats);
+       vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
+                                     sizeof(u64), GFP_KERNEL);
+       if (!vsc8531->stats)
+               return -ENOMEM;
+
+       return vsc85xx_dt_led_modes_get(phydev, default_mode);
+}
+
+static int vsc85xx_probe(struct phy_device *phydev)
+{
+       struct vsc8531_private *vsc8531;
+       int rate_magic;
+       u32 default_mode[2] = {VSC8531_LINK_1000_ACTIVITY,
+          VSC8531_LINK_100_ACTIVITY};
+
+       rate_magic = vsc85xx_edge_rate_magic_get(phydev);
+       if (rate_magic < 0)
+               return rate_magic;
+
+       vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
+       if (!vsc8531)
+               return -ENOMEM;
+
+       phydev->priv = vsc8531;
+
+       vsc8531->rate_magic = rate_magic;
+       vsc8531->nleds = 2;
+       vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES;
+       vsc8531->hw_stats = vsc85xx_hw_stats;
+       vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats);
+       vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
+                                     sizeof(u64), GFP_KERNEL);
+       if (!vsc8531->stats)
+               return -ENOMEM;
+
+       return vsc85xx_dt_led_modes_get(phydev, default_mode);
+}
+
+/* Microsemi VSC85xx PHYs */
+static struct phy_driver vsc85xx_driver[] = {
+{
+       .phy_id         = PHY_ID_VSC8504,
+       .name           = "Microsemi GE VSC8504 SyncE",
+       .phy_id_mask    = 0xfffffff0,
+       /* PHY_GBIT_FEATURES */
+       .soft_reset     = &genphy_soft_reset,
+       .config_init    = &vsc8584_config_init,
+       .config_aneg    = &vsc85xx_config_aneg,
+       .aneg_done      = &genphy_aneg_done,
+       .read_status    = &vsc85xx_read_status,
+       .ack_interrupt  = &vsc85xx_ack_interrupt,
+       .config_intr    = &vsc85xx_config_intr,
+       .did_interrupt  = &vsc8584_did_interrupt,
+       .suspend        = &genphy_suspend,
+       .resume         = &genphy_resume,
+       .probe          = &vsc8574_probe,
+       .set_wol        = &vsc85xx_wol_set,
+       .get_wol        = &vsc85xx_wol_get,
+       .get_tunable    = &vsc85xx_get_tunable,
+       .set_tunable    = &vsc85xx_set_tunable,
+       .read_page      = &vsc85xx_phy_read_page,
+       .write_page     = &vsc85xx_phy_write_page,
+       .get_sset_count = &vsc85xx_get_sset_count,
+       .get_strings    = &vsc85xx_get_strings,
+       .get_stats      = &vsc85xx_get_stats,
+},
+{
+       .phy_id         = PHY_ID_VSC8514,
+       .name           = "Microsemi GE VSC8514 SyncE",
+       .phy_id_mask    = 0xfffffff0,
+       .soft_reset     = &genphy_soft_reset,
+       .config_init    = &vsc8514_config_init,
+       .config_aneg    = &vsc85xx_config_aneg,
+       .read_status    = &vsc85xx_read_status,
+       .ack_interrupt  = &vsc85xx_ack_interrupt,
+       .config_intr    = &vsc85xx_config_intr,
+       .suspend        = &genphy_suspend,
+       .resume         = &genphy_resume,
+       .probe          = &vsc8514_probe,
+       .set_wol        = &vsc85xx_wol_set,
+       .get_wol        = &vsc85xx_wol_get,
+       .get_tunable    = &vsc85xx_get_tunable,
+       .set_tunable    = &vsc85xx_set_tunable,
+       .read_page      = &vsc85xx_phy_read_page,
+       .write_page     = &vsc85xx_phy_write_page,
+       .get_sset_count = &vsc85xx_get_sset_count,
+       .get_strings    = &vsc85xx_get_strings,
+       .get_stats      = &vsc85xx_get_stats,
+},
+{
+       .phy_id         = PHY_ID_VSC8530,
+       .name           = "Microsemi FE VSC8530",
+       .phy_id_mask    = 0xfffffff0,
+       /* PHY_BASIC_FEATURES */
+       .soft_reset     = &genphy_soft_reset,
+       .config_init    = &vsc85xx_config_init,
+       .config_aneg    = &vsc85xx_config_aneg,
+       .read_status    = &vsc85xx_read_status,
+       .ack_interrupt  = &vsc85xx_ack_interrupt,
+       .config_intr    = &vsc85xx_config_intr,
+       .suspend        = &genphy_suspend,
+       .resume         = &genphy_resume,
+       .probe          = &vsc85xx_probe,
+       .set_wol        = &vsc85xx_wol_set,
+       .get_wol        = &vsc85xx_wol_get,
+       .get_tunable    = &vsc85xx_get_tunable,
+       .set_tunable    = &vsc85xx_set_tunable,
+       .read_page      = &vsc85xx_phy_read_page,
+       .write_page     = &vsc85xx_phy_write_page,
+       .get_sset_count = &vsc85xx_get_sset_count,
+       .get_strings    = &vsc85xx_get_strings,
+       .get_stats      = &vsc85xx_get_stats,
+},
+{
+       .phy_id         = PHY_ID_VSC8531,
+       .name           = "Microsemi VSC8531",
+       .phy_id_mask    = 0xfffffff0,
+       /* PHY_GBIT_FEATURES */
+       .soft_reset     = &genphy_soft_reset,
+       .config_init    = &vsc85xx_config_init,
+       .config_aneg    = &vsc85xx_config_aneg,
+       .read_status    = &vsc85xx_read_status,
+       .ack_interrupt  = &vsc85xx_ack_interrupt,
+       .config_intr    = &vsc85xx_config_intr,
+       .suspend        = &genphy_suspend,
+       .resume         = &genphy_resume,
+       .probe          = &vsc85xx_probe,
+       .set_wol        = &vsc85xx_wol_set,
+       .get_wol        = &vsc85xx_wol_get,
+       .get_tunable    = &vsc85xx_get_tunable,
+       .set_tunable    = &vsc85xx_set_tunable,
+       .read_page      = &vsc85xx_phy_read_page,
+       .write_page     = &vsc85xx_phy_write_page,
+       .get_sset_count = &vsc85xx_get_sset_count,
+       .get_strings    = &vsc85xx_get_strings,
+       .get_stats      = &vsc85xx_get_stats,
+},
+{
+       .phy_id         = PHY_ID_VSC8540,
+       .name           = "Microsemi FE VSC8540 SyncE",
+       .phy_id_mask    = 0xfffffff0,
+       /* PHY_BASIC_FEATURES */
+       .soft_reset     = &genphy_soft_reset,
+       .config_init    = &vsc85xx_config_init,
+       .config_aneg    = &vsc85xx_config_aneg,
+       .read_status    = &vsc85xx_read_status,
+       .ack_interrupt  = &vsc85xx_ack_interrupt,
+       .config_intr    = &vsc85xx_config_intr,
+       .suspend        = &genphy_suspend,
+       .resume         = &genphy_resume,
+       .probe          = &vsc85xx_probe,
+       .set_wol        = &vsc85xx_wol_set,
+       .get_wol        = &vsc85xx_wol_get,
+       .get_tunable    = &vsc85xx_get_tunable,
+       .set_tunable    = &vsc85xx_set_tunable,
+       .read_page      = &vsc85xx_phy_read_page,
+       .write_page     = &vsc85xx_phy_write_page,
+       .get_sset_count = &vsc85xx_get_sset_count,
+       .get_strings    = &vsc85xx_get_strings,
+       .get_stats      = &vsc85xx_get_stats,
+},
+{
+       .phy_id         = PHY_ID_VSC8541,
+       .name           = "Microsemi VSC8541 SyncE",
+       .phy_id_mask    = 0xfffffff0,
+       /* PHY_GBIT_FEATURES */
+       .soft_reset     = &genphy_soft_reset,
+       .config_init    = &vsc85xx_config_init,
+       .config_aneg    = &vsc85xx_config_aneg,
+       .read_status    = &vsc85xx_read_status,
+       .ack_interrupt  = &vsc85xx_ack_interrupt,
+       .config_intr    = &vsc85xx_config_intr,
+       .suspend        = &genphy_suspend,
+       .resume         = &genphy_resume,
+       .probe          = &vsc85xx_probe,
+       .set_wol        = &vsc85xx_wol_set,
+       .get_wol        = &vsc85xx_wol_get,
+       .get_tunable    = &vsc85xx_get_tunable,
+       .set_tunable    = &vsc85xx_set_tunable,
+       .read_page      = &vsc85xx_phy_read_page,
+       .write_page     = &vsc85xx_phy_write_page,
+       .get_sset_count = &vsc85xx_get_sset_count,
+       .get_strings    = &vsc85xx_get_strings,
+       .get_stats      = &vsc85xx_get_stats,
+},
+{
+       .phy_id         = PHY_ID_VSC8552,
+       .name           = "Microsemi GE VSC8552 SyncE",
+       .phy_id_mask    = 0xfffffff0,
+       /* PHY_GBIT_FEATURES */
+       .soft_reset     = &genphy_soft_reset,
+       .config_init    = &vsc8584_config_init,
+       .config_aneg    = &vsc85xx_config_aneg,
+       .read_status    = &vsc85xx_read_status,
+       .ack_interrupt  = &vsc85xx_ack_interrupt,
+       .config_intr    = &vsc85xx_config_intr,
+       .did_interrupt  = &vsc8584_did_interrupt,
+       .suspend        = &genphy_suspend,
+       .resume         = &genphy_resume,
+       .probe          = &vsc8574_probe,
+       .set_wol        = &vsc85xx_wol_set,
+       .get_wol        = &vsc85xx_wol_get,
+       .get_tunable    = &vsc85xx_get_tunable,
+       .set_tunable    = &vsc85xx_set_tunable,
+       .read_page      = &vsc85xx_phy_read_page,
+       .write_page     = &vsc85xx_phy_write_page,
+       .get_sset_count = &vsc85xx_get_sset_count,
+       .get_strings    = &vsc85xx_get_strings,
+       .get_stats      = &vsc85xx_get_stats,
+},
+{
+       .phy_id         = PHY_ID_VSC856X,
+       .name           = "Microsemi GE VSC856X SyncE",
+       .phy_id_mask    = 0xfffffff0,
+       /* PHY_GBIT_FEATURES */
+       .soft_reset     = &genphy_soft_reset,
+       .config_init    = &vsc8584_config_init,
+       .config_aneg    = &vsc85xx_config_aneg,
+       .read_status    = &vsc85xx_read_status,
+       .ack_interrupt  = &vsc85xx_ack_interrupt,
+       .config_intr    = &vsc85xx_config_intr,
+       .did_interrupt  = &vsc8584_did_interrupt,
+       .suspend        = &genphy_suspend,
+       .resume         = &genphy_resume,
+       .probe          = &vsc8584_probe,
+       .get_tunable    = &vsc85xx_get_tunable,
+       .set_tunable    = &vsc85xx_set_tunable,
+       .read_page      = &vsc85xx_phy_read_page,
+       .write_page     = &vsc85xx_phy_write_page,
+       .get_sset_count = &vsc85xx_get_sset_count,
+       .get_strings    = &vsc85xx_get_strings,
+       .get_stats      = &vsc85xx_get_stats,
+},
+{
+       .phy_id         = PHY_ID_VSC8572,
+       .name           = "Microsemi GE VSC8572 SyncE",
+       .phy_id_mask    = 0xfffffff0,
+       /* PHY_GBIT_FEATURES */
+       .soft_reset     = &genphy_soft_reset,
+       .config_init    = &vsc8584_config_init,
+       .config_aneg    = &vsc85xx_config_aneg,
+       .aneg_done      = &genphy_aneg_done,
+       .read_status    = &vsc85xx_read_status,
+       .handle_interrupt = &vsc8584_handle_interrupt,
+       .ack_interrupt  = &vsc85xx_ack_interrupt,
+       .config_intr    = &vsc85xx_config_intr,
+       .did_interrupt  = &vsc8584_did_interrupt,
+       .suspend        = &genphy_suspend,
+       .resume         = &genphy_resume,
+       .probe          = &vsc8574_probe,
+       .set_wol        = &vsc85xx_wol_set,
+       .get_wol        = &vsc85xx_wol_get,
+       .get_tunable    = &vsc85xx_get_tunable,
+       .set_tunable    = &vsc85xx_set_tunable,
+       .read_page      = &vsc85xx_phy_read_page,
+       .write_page     = &vsc85xx_phy_write_page,
+       .get_sset_count = &vsc85xx_get_sset_count,
+       .get_strings    = &vsc85xx_get_strings,
+       .get_stats      = &vsc85xx_get_stats,
+},
+{
+       .phy_id         = PHY_ID_VSC8574,
+       .name           = "Microsemi GE VSC8574 SyncE",
+       .phy_id_mask    = 0xfffffff0,
+       /* PHY_GBIT_FEATURES */
+       .soft_reset     = &genphy_soft_reset,
+       .config_init    = &vsc8584_config_init,
+       .config_aneg    = &vsc85xx_config_aneg,
+       .aneg_done      = &genphy_aneg_done,
+       .read_status    = &vsc85xx_read_status,
+       .ack_interrupt  = &vsc85xx_ack_interrupt,
+       .config_intr    = &vsc85xx_config_intr,
+       .did_interrupt  = &vsc8584_did_interrupt,
+       .suspend        = &genphy_suspend,
+       .resume         = &genphy_resume,
+       .probe          = &vsc8574_probe,
+       .set_wol        = &vsc85xx_wol_set,
+       .get_wol        = &vsc85xx_wol_get,
+       .get_tunable    = &vsc85xx_get_tunable,
+       .set_tunable    = &vsc85xx_set_tunable,
+       .read_page      = &vsc85xx_phy_read_page,
+       .write_page     = &vsc85xx_phy_write_page,
+       .get_sset_count = &vsc85xx_get_sset_count,
+       .get_strings    = &vsc85xx_get_strings,
+       .get_stats      = &vsc85xx_get_stats,
+},
+{
+       .phy_id         = PHY_ID_VSC8575,
+       .name           = "Microsemi GE VSC8575 SyncE",
+       .phy_id_mask    = 0xfffffff0,
+       /* PHY_GBIT_FEATURES */
+       .soft_reset     = &genphy_soft_reset,
+       .config_init    = &vsc8584_config_init,
+       .config_aneg    = &vsc85xx_config_aneg,
+       .aneg_done      = &genphy_aneg_done,
+       .read_status    = &vsc85xx_read_status,
+       .handle_interrupt = &vsc8584_handle_interrupt,
+       .ack_interrupt  = &vsc85xx_ack_interrupt,
+       .config_intr    = &vsc85xx_config_intr,
+       .did_interrupt  = &vsc8584_did_interrupt,
+       .suspend        = &genphy_suspend,
+       .resume         = &genphy_resume,
+       .probe          = &vsc8584_probe,
+       .get_tunable    = &vsc85xx_get_tunable,
+       .set_tunable    = &vsc85xx_set_tunable,
+       .read_page      = &vsc85xx_phy_read_page,
+       .write_page     = &vsc85xx_phy_write_page,
+       .get_sset_count = &vsc85xx_get_sset_count,
+       .get_strings    = &vsc85xx_get_strings,
+       .get_stats      = &vsc85xx_get_stats,
+},
+{
+       .phy_id         = PHY_ID_VSC8582,
+       .name           = "Microsemi GE VSC8582 SyncE",
+       .phy_id_mask    = 0xfffffff0,
+       /* PHY_GBIT_FEATURES */
+       .soft_reset     = &genphy_soft_reset,
+       .config_init    = &vsc8584_config_init,
+       .config_aneg    = &vsc85xx_config_aneg,
+       .aneg_done      = &genphy_aneg_done,
+       .read_status    = &vsc85xx_read_status,
+       .handle_interrupt = &vsc8584_handle_interrupt,
+       .ack_interrupt  = &vsc85xx_ack_interrupt,
+       .config_intr    = &vsc85xx_config_intr,
+       .did_interrupt  = &vsc8584_did_interrupt,
+       .suspend        = &genphy_suspend,
+       .resume         = &genphy_resume,
+       .probe          = &vsc8584_probe,
+       .get_tunable    = &vsc85xx_get_tunable,
+       .set_tunable    = &vsc85xx_set_tunable,
+       .read_page      = &vsc85xx_phy_read_page,
+       .write_page     = &vsc85xx_phy_write_page,
+       .get_sset_count = &vsc85xx_get_sset_count,
+       .get_strings    = &vsc85xx_get_strings,
+       .get_stats      = &vsc85xx_get_stats,
+},
+{
+       .phy_id         = PHY_ID_VSC8584,
+       .name           = "Microsemi GE VSC8584 SyncE",
+       .phy_id_mask    = 0xfffffff0,
+       /* PHY_GBIT_FEATURES */
+       .soft_reset     = &genphy_soft_reset,
+       .config_init    = &vsc8584_config_init,
+       .config_aneg    = &vsc85xx_config_aneg,
+       .aneg_done      = &genphy_aneg_done,
+       .read_status    = &vsc85xx_read_status,
+       .handle_interrupt = &vsc8584_handle_interrupt,
+       .ack_interrupt  = &vsc85xx_ack_interrupt,
+       .config_intr    = &vsc85xx_config_intr,
+       .did_interrupt  = &vsc8584_did_interrupt,
+       .suspend        = &genphy_suspend,
+       .resume         = &genphy_resume,
+       .probe          = &vsc8584_probe,
+       .get_tunable    = &vsc85xx_get_tunable,
+       .set_tunable    = &vsc85xx_set_tunable,
+       .read_page      = &vsc85xx_phy_read_page,
+       .write_page     = &vsc85xx_phy_write_page,
+       .get_sset_count = &vsc85xx_get_sset_count,
+       .get_strings    = &vsc85xx_get_strings,
+       .get_stats      = &vsc85xx_get_stats,
+}
+
+};
+
+module_phy_driver(vsc85xx_driver);
+
+static struct mdio_device_id __maybe_unused vsc85xx_tbl[] = {
+       { PHY_ID_VSC8504, 0xfffffff0, },
+       { PHY_ID_VSC8514, 0xfffffff0, },
+       { PHY_ID_VSC8530, 0xfffffff0, },
+       { PHY_ID_VSC8531, 0xfffffff0, },
+       { PHY_ID_VSC8540, 0xfffffff0, },
+       { PHY_ID_VSC8541, 0xfffffff0, },
+       { PHY_ID_VSC8552, 0xfffffff0, },
+       { PHY_ID_VSC856X, 0xfffffff0, },
+       { PHY_ID_VSC8572, 0xfffffff0, },
+       { PHY_ID_VSC8574, 0xfffffff0, },
+       { PHY_ID_VSC8575, 0xfffffff0, },
+       { PHY_ID_VSC8582, 0xfffffff0, },
+       { PHY_ID_VSC8584, 0xfffffff0, },
+       { }
+};
+
+MODULE_DEVICE_TABLE(mdio, vsc85xx_tbl);
+
+MODULE_DESCRIPTION("Microsemi VSC85xx PHY driver");
+MODULE_AUTHOR("Nagaraju Lakkaraju");
+MODULE_LICENSE("Dual MIT/GPL");
diff --git a/drivers/net/phy/mscc/mscc_fc_buffer.h b/drivers/net/phy/mscc/mscc_fc_buffer.h
new file mode 100644 (file)
index 0000000..7e9c0e8
--- /dev/null
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Microsemi Ocelot Switch driver
+ *
+ * Copyright (C) 2019 Microsemi Corporation
+ */
+
+#ifndef _MSCC_OCELOT_FC_BUFFER_H_
+#define _MSCC_OCELOT_FC_BUFFER_H_
+
+#define MSCC_FCBUF_ENA_CFG                                     0x00
+#define MSCC_FCBUF_MODE_CFG                                    0x01
+#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG                   0x02
+#define MSCC_FCBUF_TX_CTRL_QUEUE_CFG                           0x03
+#define MSCC_FCBUF_TX_DATA_QUEUE_CFG                           0x04
+#define MSCC_FCBUF_RX_DATA_QUEUE_CFG                           0x05
+#define MSCC_FCBUF_TX_BUFF_XON_XOFF_THRESH_CFG                 0x06
+#define MSCC_FCBUF_FC_READ_THRESH_CFG                          0x07
+#define MSCC_FCBUF_TX_FRM_GAP_COMP                             0x08
+
+#define MSCC_FCBUF_ENA_CFG_TX_ENA                              BIT(0)
+#define MSCC_FCBUF_ENA_CFG_RX_ENA                              BIT(4)
+
+#define MSCC_FCBUF_MODE_CFG_DROP_BEHAVIOUR                     BIT(4)
+#define MSCC_FCBUF_MODE_CFG_PAUSE_REACT_ENA                    BIT(8)
+#define MSCC_FCBUF_MODE_CFG_RX_PPM_RATE_ADAPT_ENA              BIT(12)
+#define MSCC_FCBUF_MODE_CFG_TX_PPM_RATE_ADAPT_ENA              BIT(16)
+#define MSCC_FCBUF_MODE_CFG_TX_CTRL_QUEUE_ENA                  BIT(20)
+#define MSCC_FCBUF_MODE_CFG_PAUSE_GEN_ENA                      BIT(24)
+#define MSCC_FCBUF_MODE_CFG_INCLUDE_PAUSE_RCVD_IN_PAUSE_GEN    BIT(28)
+
+#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_THRESH(x)      (x)
+#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_THRESH_M       GENMASK(15, 0)
+#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_OFFSET(x)      ((x) << 16)
+#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_OFFSET_M       GENMASK(19, 16)
+#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_RX_THRESH(x)      ((x) << 20)
+#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_RX_THRESH_M       GENMASK(31, 20)
+
+#define MSCC_FCBUF_TX_CTRL_QUEUE_CFG_START(x)                  (x)
+#define MSCC_FCBUF_TX_CTRL_QUEUE_CFG_START_M                   GENMASK(15, 0)
+#define MSCC_FCBUF_TX_CTRL_QUEUE_CFG_END(x)                    ((x) << 16)
+#define MSCC_FCBUF_TX_CTRL_QUEUE_CFG_END_M                     GENMASK(31, 16)
+
+#define MSCC_FCBUF_TX_DATA_QUEUE_CFG_START(x)                  (x)
+#define MSCC_FCBUF_TX_DATA_QUEUE_CFG_START_M                   GENMASK(15, 0)
+#define MSCC_FCBUF_TX_DATA_QUEUE_CFG_END(x)                    ((x) << 16)
+#define MSCC_FCBUF_TX_DATA_QUEUE_CFG_END_M                     GENMASK(31, 16)
+
+#define MSCC_FCBUF_RX_DATA_QUEUE_CFG_START(x)                  (x)
+#define MSCC_FCBUF_RX_DATA_QUEUE_CFG_START_M                   GENMASK(15, 0)
+#define MSCC_FCBUF_RX_DATA_QUEUE_CFG_END(x)                    ((x) << 16)
+#define MSCC_FCBUF_RX_DATA_QUEUE_CFG_END_M                     GENMASK(31, 16)
+
+#define MSCC_FCBUF_TX_BUFF_XON_XOFF_THRESH_CFG_XOFF_THRESH(x)  (x)
+#define MSCC_FCBUF_TX_BUFF_XON_XOFF_THRESH_CFG_XOFF_THRESH_M   GENMASK(15, 0)
+#define MSCC_FCBUF_TX_BUFF_XON_XOFF_THRESH_CFG_XON_THRESH(x)   ((x) << 16)
+#define MSCC_FCBUF_TX_BUFF_XON_XOFF_THRESH_CFG_XON_THRESH_M    GENMASK(31, 16)
+
+#define MSCC_FCBUF_FC_READ_THRESH_CFG_TX_THRESH(x)             (x)
+#define MSCC_FCBUF_FC_READ_THRESH_CFG_TX_THRESH_M              GENMASK(15, 0)
+#define MSCC_FCBUF_FC_READ_THRESH_CFG_RX_THRESH(x)             ((x) << 16)
+#define MSCC_FCBUF_FC_READ_THRESH_CFG_RX_THRESH_M              GENMASK(31, 16)
+
+#endif
diff --git a/drivers/net/phy/mscc/mscc_mac.h b/drivers/net/phy/mscc/mscc_mac.h
new file mode 100644 (file)
index 0000000..9420ee5
--- /dev/null
@@ -0,0 +1,159 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Microsemi Ocelot Switch driver
+ *
+ * Copyright (c) 2017 Microsemi Corporation
+ */
+
+#ifndef _MSCC_OCELOT_LINE_MAC_H_
+#define _MSCC_OCELOT_LINE_MAC_H_
+
+#define MSCC_MAC_CFG_ENA_CFG                                   0x00
+#define MSCC_MAC_CFG_MODE_CFG                                  0x01
+#define MSCC_MAC_CFG_MAXLEN_CFG                                        0x02
+#define MSCC_MAC_CFG_NUM_TAGS_CFG                              0x03
+#define MSCC_MAC_CFG_TAGS_CFG                                  0x04
+#define MSCC_MAC_CFG_ADV_CHK_CFG                               0x07
+#define MSCC_MAC_CFG_LFS_CFG                                   0x08
+#define MSCC_MAC_CFG_LB_CFG                                    0x09
+#define MSCC_MAC_CFG_PKTINF_CFG                                        0x0a
+#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL                       0x0b
+#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_2                     0x0c
+#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL                       0x0d
+#define MSCC_MAC_PAUSE_CFG_STATE                               0x0e
+#define MSCC_MAC_PAUSE_CFG_MAC_ADDRESS_LSB                     0x0f
+#define MSCC_MAC_PAUSE_CFG_MAC_ADDRESS_MSB                     0x10
+#define MSCC_MAC_STATUS_RX_LANE_STICKY_0                       0x11
+#define MSCC_MAC_STATUS_RX_LANE_STICKY_1                       0x12
+#define MSCC_MAC_STATUS_TX_MONITOR_STICKY                      0x13
+#define MSCC_MAC_STATUS_TX_MONITOR_STICKY_MASK                 0x14
+#define MSCC_MAC_STATUS_STICKY                                 0x15
+#define MSCC_MAC_STATUS_STICKY_MASK                            0x16
+#define MSCC_MAC_STATS_32BIT_RX_HIH_CKSM_ERR_CNT               0x17
+#define MSCC_MAC_STATS_32BIT_RX_XGMII_PROT_ERR_CNT             0x18
+#define MSCC_MAC_STATS_32BIT_RX_SYMBOL_ERR_CNT                 0x19
+#define MSCC_MAC_STATS_32BIT_RX_PAUSE_CNT                      0x1a
+#define MSCC_MAC_STATS_32BIT_RX_UNSUP_OPCODE_CNT               0x1b
+#define MSCC_MAC_STATS_32BIT_RX_UC_CNT                         0x1c
+#define MSCC_MAC_STATS_32BIT_RX_MC_CNT                         0x1d
+#define MSCC_MAC_STATS_32BIT_RX_BC_CNT                         0x1e
+#define MSCC_MAC_STATS_32BIT_RX_CRC_ERR_CNT                    0x1f
+#define MSCC_MAC_STATS_32BIT_RX_UNDERSIZE_CNT                  0x20
+#define MSCC_MAC_STATS_32BIT_RX_FRAGMENTS_CNT                  0x21
+#define MSCC_MAC_STATS_32BIT_RX_IN_RANGE_LEN_ERR_CNT           0x22
+#define MSCC_MAC_STATS_32BIT_RX_OUT_OF_RANGE_LEN_ERR_CNT       0x23
+#define MSCC_MAC_STATS_32BIT_RX_OVERSIZE_CNT                   0x24
+#define MSCC_MAC_STATS_32BIT_RX_JABBERS_CNT                    0x25
+#define MSCC_MAC_STATS_32BIT_RX_SIZE64_CNT                     0x26
+#define MSCC_MAC_STATS_32BIT_RX_SIZE65TO127_CNT                        0x27
+#define MSCC_MAC_STATS_32BIT_RX_SIZE128TO255_CNT               0x28
+#define MSCC_MAC_STATS_32BIT_RX_SIZE256TO511_CNT               0x29
+#define MSCC_MAC_STATS_32BIT_RX_SIZE512TO1023_CNT              0x2a
+#define MSCC_MAC_STATS_32BIT_RX_SIZE1024TO1518_CNT             0x2b
+#define MSCC_MAC_STATS_32BIT_RX_SIZE1519TOMAX_CNT              0x2c
+#define MSCC_MAC_STATS_32BIT_RX_IPG_SHRINK_CNT                 0x2d
+#define MSCC_MAC_STATS_32BIT_TX_PAUSE_CNT                      0x2e
+#define MSCC_MAC_STATS_32BIT_TX_UC_CNT                         0x2f
+#define MSCC_MAC_STATS_32BIT_TX_MC_CNT                         0x30
+#define MSCC_MAC_STATS_32BIT_TX_BC_CNT                         0x31
+#define MSCC_MAC_STATS_32BIT_TX_SIZE64_CNT                     0x32
+#define MSCC_MAC_STATS_32BIT_TX_SIZE65TO127_CNT                        0x33
+#define MSCC_MAC_STATS_32BIT_TX_SIZE128TO255_CNT               0x34
+#define MSCC_MAC_STATS_32BIT_TX_SIZE256TO511_CNT               0x35
+#define MSCC_MAC_STATS_32BIT_TX_SIZE512TO1023_CNT              0x36
+#define MSCC_MAC_STATS_32BIT_TX_SIZE1024TO1518_CNT             0x37
+#define MSCC_MAC_STATS_32BIT_TX_SIZE1519TOMAX_CNT              0x38
+#define MSCC_MAC_STATS_40BIT_RX_BAD_BYTES_CNT                  0x39
+#define MSCC_MAC_STATS_40BIT_RX_BAD_BYTES_MSB_CNT              0x3a
+#define MSCC_MAC_STATS_40BIT_RX_OK_BYTES_CNT                   0x3b
+#define MSCC_MAC_STATS_40BIT_RX_OK_BYTES_MSB_CNT               0x3c
+#define MSCC_MAC_STATS_40BIT_RX_IN_BYTES_CNT                   0x3d
+#define MSCC_MAC_STATS_40BIT_RX_IN_BYTES_MSB_CNT               0x3e
+#define MSCC_MAC_STATS_40BIT_TX_OK_BYTES_CNT                   0x3f
+#define MSCC_MAC_STATS_40BIT_TX_OK_BYTES_MSB_CNT               0x40
+#define MSCC_MAC_STATS_40BIT_TX_OUT_BYTES_CNT                  0x41
+#define MSCC_MAC_STATS_40BIT_TX_OUT_BYTES_MSB_CNT              0x42
+
+#define MSCC_MAC_CFG_ENA_CFG_RX_CLK_ENA                                BIT(0)
+#define MSCC_MAC_CFG_ENA_CFG_TX_CLK_ENA                                BIT(4)
+#define MSCC_MAC_CFG_ENA_CFG_RX_SW_RST                         BIT(8)
+#define MSCC_MAC_CFG_ENA_CFG_TX_SW_RST                         BIT(12)
+#define MSCC_MAC_CFG_ENA_CFG_RX_ENA                            BIT(16)
+#define MSCC_MAC_CFG_ENA_CFG_TX_ENA                            BIT(20)
+
+#define MSCC_MAC_CFG_MODE_CFG_FORCE_CW_UPDATE_INTERVAL(x)      ((x) << 20)
+#define MSCC_MAC_CFG_MODE_CFG_FORCE_CW_UPDATE_INTERVAL_M       GENMASK(29, 20)
+#define MSCC_MAC_CFG_MODE_CFG_FORCE_CW_UPDATE                  BIT(16)
+#define MSCC_MAC_CFG_MODE_CFG_TUNNEL_PAUSE_FRAMES              BIT(14)
+#define MSCC_MAC_CFG_MODE_CFG_MAC_PREAMBLE_CFG(x)              ((x) << 10)
+#define MSCC_MAC_CFG_MODE_CFG_MAC_PREAMBLE_CFG_M               GENMASK(12, 10)
+#define MSCC_MAC_CFG_MODE_CFG_MAC_IPG_CFG                      BIT(6)
+#define MSCC_MAC_CFG_MODE_CFG_XGMII_GEN_MODE_ENA               BIT(4)
+#define MSCC_MAC_CFG_MODE_CFG_HIH_CRC_CHECK                    BIT(2)
+#define MSCC_MAC_CFG_MODE_CFG_UNDERSIZED_FRAME_DROP_DIS                BIT(1)
+#define MSCC_MAC_CFG_MODE_CFG_DISABLE_DIC                      BIT(0)
+
+#define MSCC_MAC_CFG_MAXLEN_CFG_MAX_LEN_TAG_CHK                        BIT(16)
+#define MSCC_MAC_CFG_MAXLEN_CFG_MAX_LEN(x)                     (x)
+#define MSCC_MAC_CFG_MAXLEN_CFG_MAX_LEN_M                      GENMASK(15, 0)
+
+#define MSCC_MAC_CFG_TAGS_CFG_RSZ                              0x4
+#define MSCC_MAC_CFG_TAGS_CFG_TAG_ID(x)                                ((x) << 16)
+#define MSCC_MAC_CFG_TAGS_CFG_TAG_ID_M                         GENMASK(31, 16)
+#define MSCC_MAC_CFG_TAGS_CFG_TAG_ENA                          BIT(4)
+
+#define MSCC_MAC_CFG_ADV_CHK_CFG_EXT_EOP_CHK_ENA               BIT(24)
+#define MSCC_MAC_CFG_ADV_CHK_CFG_EXT_SOP_CHK_ENA               BIT(20)
+#define MSCC_MAC_CFG_ADV_CHK_CFG_SFD_CHK_ENA                   BIT(16)
+#define MSCC_MAC_CFG_ADV_CHK_CFG_PRM_SHK_CHK_DIS               BIT(12)
+#define MSCC_MAC_CFG_ADV_CHK_CFG_PRM_CHK_ENA                   BIT(8)
+#define MSCC_MAC_CFG_ADV_CHK_CFG_OOR_ERR_ENA                   BIT(4)
+#define MSCC_MAC_CFG_ADV_CHK_CFG_INR_ERR_ENA                   BIT(0)
+
+#define MSCC_MAC_CFG_LFS_CFG_LFS_INH_TX                                BIT(8)
+#define MSCC_MAC_CFG_LFS_CFG_LFS_DIS_TX                                BIT(4)
+#define MSCC_MAC_CFG_LFS_CFG_LFS_UNIDIR_ENA                    BIT(3)
+#define MSCC_MAC_CFG_LFS_CFG_USE_LEADING_EDGE_DETECT           BIT(2)
+#define MSCC_MAC_CFG_LFS_CFG_SPURIOUS_Q_DIS                    BIT(1)
+#define MSCC_MAC_CFG_LFS_CFG_LFS_MODE_ENA                      BIT(0)
+
+#define MSCC_MAC_CFG_LB_CFG_XGMII_HOST_LB_ENA                  BIT(4)
+#define MSCC_MAC_CFG_LB_CFG_XGMII_PHY_LB_ENA                   BIT(0)
+
+#define MSCC_MAC_CFG_PKTINF_CFG_STRIP_FCS_ENA                  BIT(0)
+#define MSCC_MAC_CFG_PKTINF_CFG_INSERT_FCS_ENA                 BIT(4)
+#define MSCC_MAC_CFG_PKTINF_CFG_STRIP_PREAMBLE_ENA             BIT(8)
+#define MSCC_MAC_CFG_PKTINF_CFG_INSERT_PREAMBLE_ENA            BIT(12)
+#define MSCC_MAC_CFG_PKTINF_CFG_LPI_RELAY_ENA                  BIT(16)
+#define MSCC_MAC_CFG_PKTINF_CFG_LF_RELAY_ENA                   BIT(20)
+#define MSCC_MAC_CFG_PKTINF_CFG_RF_RELAY_ENA                   BIT(24)
+#define MSCC_MAC_CFG_PKTINF_CFG_ENABLE_TX_PADDING              BIT(25)
+#define MSCC_MAC_CFG_PKTINF_CFG_ENABLE_RX_PADDING              BIT(26)
+#define MSCC_MAC_CFG_PKTINF_CFG_ENABLE_4BYTE_PREAMBLE          BIT(27)
+#define MSCC_MAC_CFG_PKTINF_CFG_MACSEC_BYPASS_NUM_PTP_STALL_CLKS(x)    ((x) << 28)
+#define MSCC_MAC_CFG_PKTINF_CFG_MACSEC_BYPASS_NUM_PTP_STALL_CLKS_M     GENMASK(30, 28)
+
+#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_VALUE(x)                ((x) << 16)
+#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_VALUE_M         GENMASK(31, 16)
+#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_WAIT_FOR_LPI_LOW      BIT(12)
+#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_USE_PAUSE_STALL_ENA   BIT(8)
+#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_REPL_MODE       BIT(4)
+#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_FRC_FRAME       BIT(2)
+#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_MODE(x)         (x)
+#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_MODE_M          GENMASK(1, 0)
+
+#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_EARLY_PAUSE_DETECT_ENA        BIT(16)
+#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PRE_CRC_MODE          BIT(20)
+#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_TIMER_ENA       BIT(12)
+#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_REACT_ENA       BIT(8)
+#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_FRAME_DROP_ENA  BIT(4)
+#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_MODE            BIT(0)
+
+#define MSCC_MAC_PAUSE_CFG_STATE_PAUSE_STATE                   BIT(0)
+#define MSCC_MAC_PAUSE_CFG_STATE_MAC_TX_PAUSE_GEN              BIT(4)
+
+#define MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL                      0x2
+#define MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE(x)     (x)
+#define MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE_M      GENMASK(2, 0)
+
+#endif /* _MSCC_OCELOT_LINE_MAC_H_ */
diff --git a/drivers/net/phy/mscc/mscc_macsec.h b/drivers/net/phy/mscc/mscc_macsec.h
new file mode 100644 (file)
index 0000000..d9ab6ab
--- /dev/null
@@ -0,0 +1,266 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Microsemi Ocelot Switch driver
+ *
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef _MSCC_OCELOT_MACSEC_H_
+#define _MSCC_OCELOT_MACSEC_H_
+
+#define MSCC_MS_MAX_FLOWS              16
+
+#define CONTROL_TYPE_EGRESS            0x6
+#define CONTROL_TYPE_INGRESS           0xf
+#define CONTROL_IV0                    BIT(5)
+#define CONTROL_IV1                    BIT(6)
+#define CONTROL_IV2                    BIT(7)
+#define CONTROL_UPDATE_SEQ             BIT(13)
+#define CONTROL_IV_IN_SEQ              BIT(14)
+#define CONTROL_ENCRYPT_AUTH           BIT(15)
+#define CONTROL_KEY_IN_CTX             BIT(16)
+#define CONTROL_CRYPTO_ALG(x)          ((x) << 17)
+#define     CTRYPTO_ALG_AES_CTR_128    0x5
+#define     CTRYPTO_ALG_AES_CTR_192    0x6
+#define     CTRYPTO_ALG_AES_CTR_256    0x7
+#define CONTROL_DIGEST_TYPE(x)         ((x) << 21)
+#define CONTROL_AUTH_ALG(x)            ((x) << 23)
+#define     AUTH_ALG_AES_GHAS          0x4
+#define CONTROL_AN(x)                  ((x) << 26)
+#define CONTROL_SEQ_TYPE(x)            ((x) << 28)
+#define CONTROL_SEQ_MASK               BIT(30)
+#define CONTROL_CONTEXT_ID             BIT(31)
+
+enum mscc_macsec_destination_ports {
+       MSCC_MS_PORT_COMMON             = 0,
+       MSCC_MS_PORT_RSVD               = 1,
+       MSCC_MS_PORT_CONTROLLED         = 2,
+       MSCC_MS_PORT_UNCONTROLLED       = 3,
+};
+
+enum mscc_macsec_drop_actions {
+       MSCC_MS_ACTION_BYPASS_CRC       = 0,
+       MSCC_MS_ACTION_BYPASS_BAD       = 1,
+       MSCC_MS_ACTION_DROP             = 2,
+       MSCC_MS_ACTION_BYPASS           = 3,
+};
+
+enum mscc_macsec_flow_types {
+       MSCC_MS_FLOW_BYPASS             = 0,
+       MSCC_MS_FLOW_DROP               = 1,
+       MSCC_MS_FLOW_INGRESS            = 2,
+       MSCC_MS_FLOW_EGRESS             = 3,
+};
+
+enum mscc_macsec_validate_levels {
+       MSCC_MS_VALIDATE_DISABLED       = 0,
+       MSCC_MS_VALIDATE_CHECK          = 1,
+       MSCC_MS_VALIDATE_STRICT         = 2,
+};
+
+#define MSCC_MS_XFORM_REC(x, y)                (((x) << 5) + (y))
+#define MSCC_MS_ENA_CFG                        0x800
+#define MSCC_MS_FC_CFG                 0x804
+#define MSCC_MS_SAM_MAC_SA_MATCH_LO(x) (0x1000 + ((x) << 4))
+#define MSCC_MS_SAM_MAC_SA_MATCH_HI(x) (0x1001 + ((x) << 4))
+#define MSCC_MS_SAM_MISC_MATCH(x)      (0x1004 + ((x) << 4))
+#define MSCC_MS_SAM_MATCH_SCI_LO(x)    (0x1005 + ((x) << 4))
+#define MSCC_MS_SAM_MATCH_SCI_HI(x)    (0x1006 + ((x) << 4))
+#define MSCC_MS_SAM_MASK(x)            (0x1007 + ((x) << 4))
+#define MSCC_MS_SAM_ENTRY_SET1         0x1808
+#define MSCC_MS_SAM_ENTRY_CLEAR1       0x180c
+#define MSCC_MS_SAM_FLOW_CTRL(x)       (0x1c00 + (x))
+#define MSCC_MS_SAM_CP_TAG             0x1e40
+#define MSCC_MS_SAM_NM_FLOW_NCP                0x1e51
+#define MSCC_MS_SAM_NM_FLOW_CP         0x1e52
+#define MSCC_MS_MISC_CONTROL           0x1e5f
+#define MSCC_MS_COUNT_CONTROL          0x3204
+#define MSCC_MS_PARAMS2_IG_CC_CONTROL  0x3a10
+#define MSCC_MS_PARAMS2_IG_CP_TAG      0x3a14
+#define MSCC_MS_VLAN_MTU_CHECK(x)      (0x3c40 + (x))
+#define MSCC_MS_NON_VLAN_MTU_CHECK     0x3c48
+#define MSCC_MS_PP_CTRL                        0x3c4b
+#define MSCC_MS_STATUS_CONTEXT_CTRL    0x3d02
+#define MSCC_MS_INTR_CTRL_STATUS       0x3d04
+#define MSCC_MS_BLOCK_CTX_UPDATE       0x3d0c
+#define MSCC_MS_AIC_CTRL               0x3e02
+
+/* MACSEC_ENA_CFG */
+#define MSCC_MS_ENA_CFG_CLK_ENA                                BIT(0)
+#define MSCC_MS_ENA_CFG_SW_RST                         BIT(1)
+#define MSCC_MS_ENA_CFG_MACSEC_BYPASS_ENA              BIT(8)
+#define MSCC_MS_ENA_CFG_MACSEC_ENA                     BIT(9)
+#define MSCC_MS_ENA_CFG_MACSEC_SPEED_MODE(x)           ((x) << 10)
+#define MSCC_MS_ENA_CFG_MACSEC_SPEED_MODE_M            GENMASK(12, 10)
+
+/* MACSEC_FC_CFG */
+#define MSCC_MS_FC_CFG_FCBUF_ENA                       BIT(0)
+#define MSCC_MS_FC_CFG_USE_PKT_EXPANSION_INDICATION    BIT(1)
+#define MSCC_MS_FC_CFG_LOW_THRESH(x)                   ((x) << 4)
+#define MSCC_MS_FC_CFG_LOW_THRESH_M                    GENMASK(7, 4)
+#define MSCC_MS_FC_CFG_HIGH_THRESH(x)                  ((x) << 8)
+#define MSCC_MS_FC_CFG_HIGH_THRESH_M                   GENMASK(11, 8)
+#define MSCC_MS_FC_CFG_LOW_BYTES_VAL(x)                        ((x) << 12)
+#define MSCC_MS_FC_CFG_LOW_BYTES_VAL_M                 GENMASK(14, 12)
+#define MSCC_MS_FC_CFG_HIGH_BYTES_VAL(x)               ((x) << 16)
+#define MSCC_MS_FC_CFG_HIGH_BYTES_VAL_M                        GENMASK(18, 16)
+
+/* MSCC_MS_SAM_MAC_SA_MATCH_HI */
+#define MSCC_MS_SAM_MAC_SA_MATCH_HI_ETYPE(x)           ((x) << 16)
+#define MSCC_MS_SAM_MAC_SA_MATCH_HI_ETYPE_M            GENMASK(31, 16)
+
+/* MACSEC_SAM_MISC_MATCH */
+#define MSCC_MS_SAM_MISC_MATCH_VLAN_VALID              BIT(0)
+#define MSCC_MS_SAM_MISC_MATCH_QINQ_FOUND              BIT(1)
+#define MSCC_MS_SAM_MISC_MATCH_STAG_VALID              BIT(2)
+#define MSCC_MS_SAM_MISC_MATCH_QTAG_VALID              BIT(3)
+#define MSCC_MS_SAM_MISC_MATCH_VLAN_UP(x)              ((x) << 4)
+#define MSCC_MS_SAM_MISC_MATCH_VLAN_UP_M               GENMASK(6, 4)
+#define MSCC_MS_SAM_MISC_MATCH_CONTROL_PACKET          BIT(7)
+#define MSCC_MS_SAM_MISC_MATCH_UNTAGGED                        BIT(8)
+#define MSCC_MS_SAM_MISC_MATCH_TAGGED                  BIT(9)
+#define MSCC_MS_SAM_MISC_MATCH_BAD_TAG                 BIT(10)
+#define MSCC_MS_SAM_MISC_MATCH_KAY_TAG                 BIT(11)
+#define MSCC_MS_SAM_MISC_MATCH_SOURCE_PORT(x)          ((x) << 12)
+#define MSCC_MS_SAM_MISC_MATCH_SOURCE_PORT_M           GENMASK(13, 12)
+#define MSCC_MS_SAM_MISC_MATCH_PRIORITY(x)             ((x) << 16)
+#define MSCC_MS_SAM_MISC_MATCH_PRIORITY_M              GENMASK(19, 16)
+#define MSCC_MS_SAM_MISC_MATCH_AN(x)                   ((x) << 24)
+#define MSCC_MS_SAM_MISC_MATCH_TCI(x)                  ((x) << 26)
+
+/* MACSEC_SAM_MASK */
+#define MSCC_MS_SAM_MASK_MAC_SA_MASK(x)                        (x)
+#define MSCC_MS_SAM_MASK_MAC_SA_MASK_M                 GENMASK(5, 0)
+#define MSCC_MS_SAM_MASK_MAC_DA_MASK(x)                        ((x) << 6)
+#define MSCC_MS_SAM_MASK_MAC_DA_MASK_M                 GENMASK(11, 6)
+#define MSCC_MS_SAM_MASK_MAC_ETYPE_MASK                        BIT(12)
+#define MSCC_MS_SAM_MASK_VLAN_VLD_MASK                 BIT(13)
+#define MSCC_MS_SAM_MASK_QINQ_FOUND_MASK               BIT(14)
+#define MSCC_MS_SAM_MASK_STAG_VLD_MASK                 BIT(15)
+#define MSCC_MS_SAM_MASK_QTAG_VLD_MASK                 BIT(16)
+#define MSCC_MS_SAM_MASK_VLAN_UP_MASK                  BIT(17)
+#define MSCC_MS_SAM_MASK_VLAN_ID_MASK                  BIT(18)
+#define MSCC_MS_SAM_MASK_SOURCE_PORT_MASK              BIT(19)
+#define MSCC_MS_SAM_MASK_CTL_PACKET_MASK               BIT(20)
+#define MSCC_MS_SAM_MASK_VLAN_UP_INNER_MASK            BIT(21)
+#define MSCC_MS_SAM_MASK_VLAN_ID_INNER_MASK            BIT(22)
+#define MSCC_MS_SAM_MASK_SCI_MASK                      BIT(23)
+#define MSCC_MS_SAM_MASK_AN_MASK(x)                    ((x) << 24)
+#define MSCC_MS_SAM_MASK_TCI_MASK(x)                   ((x) << 26)
+
+/* MACSEC_SAM_FLOW_CTRL_EGR */
+#define MSCC_MS_SAM_FLOW_CTRL_FLOW_TYPE(x)             (x)
+#define MSCC_MS_SAM_FLOW_CTRL_FLOW_TYPE_M              GENMASK(1, 0)
+#define MSCC_MS_SAM_FLOW_CTRL_DEST_PORT(x)             ((x) << 2)
+#define MSCC_MS_SAM_FLOW_CTRL_DEST_PORT_M              GENMASK(3, 2)
+#define MSCC_MS_SAM_FLOW_CTRL_RESV_4                   BIT(4)
+#define MSCC_MS_SAM_FLOW_CTRL_FLOW_CRYPT_AUTH          BIT(5)
+#define MSCC_MS_SAM_FLOW_CTRL_DROP_ACTION(x)           ((x) << 6)
+#define MSCC_MS_SAM_FLOW_CTRL_DROP_ACTION_M            GENMASK(7, 6)
+#define MSCC_MS_SAM_FLOW_CTRL_RESV_15_TO_8(x)          ((x) << 8)
+#define MSCC_MS_SAM_FLOW_CTRL_RESV_15_TO_8_M           GENMASK(15, 8)
+#define MSCC_MS_SAM_FLOW_CTRL_PROTECT_FRAME            BIT(16)
+#define MSCC_MS_SAM_FLOW_CTRL_REPLAY_PROTECT           BIT(16)
+#define MSCC_MS_SAM_FLOW_CTRL_SA_IN_USE                        BIT(17)
+#define MSCC_MS_SAM_FLOW_CTRL_INCLUDE_SCI              BIT(18)
+#define MSCC_MS_SAM_FLOW_CTRL_USE_ES                   BIT(19)
+#define MSCC_MS_SAM_FLOW_CTRL_USE_SCB                  BIT(20)
+#define MSCC_MS_SAM_FLOW_CTRL_VALIDATE_FRAMES(x)       ((x) << 19)
+#define MSCC_MS_SAM_FLOW_CTRL_TAG_BYPASS_SIZE(x)       ((x) << 21)
+#define MSCC_MS_SAM_FLOW_CTRL_TAG_BYPASS_SIZE_M                GENMASK(22, 21)
+#define MSCC_MS_SAM_FLOW_CTRL_RESV_23                  BIT(23)
+#define MSCC_MS_SAM_FLOW_CTRL_CONFIDENTIALITY_OFFSET(x)        ((x) << 24)
+#define MSCC_MS_SAM_FLOW_CTRL_CONFIDENTIALITY_OFFSET_M GENMASK(30, 24)
+#define MSCC_MS_SAM_FLOW_CTRL_CONF_PROTECT             BIT(31)
+
+/* MACSEC_SAM_CP_TAG */
+#define MSCC_MS_SAM_CP_TAG_MAP_TBL(x)                  (x)
+#define MSCC_MS_SAM_CP_TAG_MAP_TBL_M                   GENMASK(23, 0)
+#define MSCC_MS_SAM_CP_TAG_DEF_UP(x)                   ((x) << 24)
+#define MSCC_MS_SAM_CP_TAG_DEF_UP_M                    GENMASK(26, 24)
+#define MSCC_MS_SAM_CP_TAG_STAG_UP_EN                  BIT(27)
+#define MSCC_MS_SAM_CP_TAG_QTAG_UP_EN                  BIT(28)
+#define MSCC_MS_SAM_CP_TAG_PARSE_QINQ                  BIT(29)
+#define MSCC_MS_SAM_CP_TAG_PARSE_STAG                  BIT(30)
+#define MSCC_MS_SAM_CP_TAG_PARSE_QTAG                  BIT(31)
+
+/* MACSEC_SAM_NM_FLOW_NCP */
+#define MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_FLOW_TYPE(x)  (x)
+#define MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_DEST_PORT(x)  ((x) << 2)
+#define MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_DROP_ACTION(x)        ((x) << 6)
+#define MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_FLOW_TYPE(x)    ((x) << 8)
+#define MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_DEST_PORT(x)    ((x) << 10)
+#define MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_DROP_ACTION(x)  ((x) << 14)
+#define MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_FLOW_TYPE(x)    ((x) << 16)
+#define MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_DEST_PORT(x)    ((x) << 18)
+#define MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_DROP_ACTION(x)  ((x) << 22)
+#define MSCC_MS_SAM_NM_FLOW_NCP_KAY_FLOW_TYPE(x)       ((x) << 24)
+#define MSCC_MS_SAM_NM_FLOW_NCP_KAY_DEST_PORT(x)       ((x) << 26)
+#define MSCC_MS_SAM_NM_FLOW_NCP_KAY_DROP_ACTION(x)     ((x) << 30)
+
+/* MACSEC_SAM_NM_FLOW_CP */
+#define MSCC_MS_SAM_NM_FLOW_CP_UNTAGGED_FLOW_TYPE(x)   (x)
+#define MSCC_MS_SAM_NM_FLOW_CP_UNTAGGED_DEST_PORT(x)   ((x) << 2)
+#define MSCC_MS_SAM_NM_FLOW_CP_UNTAGGED_DROP_ACTION(x) ((x) << 6)
+#define MSCC_MS_SAM_NM_FLOW_CP_TAGGED_FLOW_TYPE(x)     ((x) << 8)
+#define MSCC_MS_SAM_NM_FLOW_CP_TAGGED_DEST_PORT(x)     ((x) << 10)
+#define MSCC_MS_SAM_NM_FLOW_CP_TAGGED_DROP_ACTION(x)   ((x) << 14)
+#define MSCC_MS_SAM_NM_FLOW_CP_BADTAG_FLOW_TYPE(x)     ((x) << 16)
+#define MSCC_MS_SAM_NM_FLOW_CP_BADTAG_DEST_PORT(x)     ((x) << 18)
+#define MSCC_MS_SAM_NM_FLOW_CP_BADTAG_DROP_ACTION(x)   ((x) << 22)
+#define MSCC_MS_SAM_NM_FLOW_CP_KAY_FLOW_TYPE(x)                ((x) << 24)
+#define MSCC_MS_SAM_NM_FLOW_CP_KAY_DEST_PORT(x)                ((x) << 26)
+#define MSCC_MS_SAM_NM_FLOW_CP_KAY_DROP_ACTION(x)      ((x) << 30)
+
+/* MACSEC_MISC_CONTROL */
+#define MSCC_MS_MISC_CONTROL_MC_LATENCY_FIX(x)         (x)
+#define MSCC_MS_MISC_CONTROL_MC_LATENCY_FIX_M          GENMASK(5, 0)
+#define MSCC_MS_MISC_CONTROL_STATIC_BYPASS             BIT(8)
+#define MSCC_MS_MISC_CONTROL_NM_MACSEC_EN              BIT(9)
+#define MSCC_MS_MISC_CONTROL_VALIDATE_FRAMES(x)                ((x) << 10)
+#define MSCC_MS_MISC_CONTROL_VALIDATE_FRAMES_M         GENMASK(11, 10)
+#define MSCC_MS_MISC_CONTROL_XFORM_REC_SIZE(x)         ((x) << 24)
+#define MSCC_MS_MISC_CONTROL_XFORM_REC_SIZE_M          GENMASK(25, 24)
+
+/* MACSEC_COUNT_CONTROL */
+#define MSCC_MS_COUNT_CONTROL_RESET_ALL                        BIT(0)
+#define MSCC_MS_COUNT_CONTROL_DEBUG_ACCESS             BIT(1)
+#define MSCC_MS_COUNT_CONTROL_SATURATE_CNTRS           BIT(2)
+#define MSCC_MS_COUNT_CONTROL_AUTO_CNTR_RESET          BIT(3)
+
+/* MACSEC_PARAMS2_IG_CC_CONTROL */
+#define MSCC_MS_PARAMS2_IG_CC_CONTROL_NON_MATCH_CTRL_ACT       BIT(14)
+#define MSCC_MS_PARAMS2_IG_CC_CONTROL_NON_MATCH_ACT    BIT(15)
+
+/* MACSEC_PARAMS2_IG_CP_TAG */
+#define MSCC_MS_PARAMS2_IG_CP_TAG_MAP_TBL(x)           (x)
+#define MSCC_MS_PARAMS2_IG_CP_TAG_MAP_TBL_M            GENMASK(23, 0)
+#define MSCC_MS_PARAMS2_IG_CP_TAG_DEF_UP(x)            ((x) << 24)
+#define MSCC_MS_PARAMS2_IG_CP_TAG_DEF_UP_M             GENMASK(26, 24)
+#define MSCC_MS_PARAMS2_IG_CP_TAG_STAG_UP_EN           BIT(27)
+#define MSCC_MS_PARAMS2_IG_CP_TAG_QTAG_UP_EN           BIT(28)
+#define MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_QINQ           BIT(29)
+#define MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_STAG           BIT(30)
+#define MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_QTAG           BIT(31)
+
+/* MACSEC_VLAN_MTU_CHECK */
+#define MSCC_MS_VLAN_MTU_CHECK_MTU_COMPARE(x)          (x)
+#define MSCC_MS_VLAN_MTU_CHECK_MTU_COMPARE_M           GENMASK(14, 0)
+#define MSCC_MS_VLAN_MTU_CHECK_MTU_COMP_DROP           BIT(15)
+
+/* MACSEC_NON_VLAN_MTU_CHECK */
+#define MSCC_MS_NON_VLAN_MTU_CHECK_NV_MTU_COMPARE(x)   (x)
+#define MSCC_MS_NON_VLAN_MTU_CHECK_NV_MTU_COMPARE_M    GENMASK(14, 0)
+#define MSCC_MS_NON_VLAN_MTU_CHECK_NV_MTU_COMP_DROP    BIT(15)
+
+/* MACSEC_PP_CTRL */
+#define MSCC_MS_PP_CTRL_MACSEC_OCTET_INCR_MODE         BIT(0)
+
+/* MACSEC_INTR_CTRL_STATUS */
+#define MSCC_MS_INTR_CTRL_STATUS_INTR_CLR_STATUS(x)    (x)
+#define MSCC_MS_INTR_CTRL_STATUS_INTR_CLR_STATUS_M     GENMASK(15, 0)
+#define MSCC_MS_INTR_CTRL_STATUS_INTR_ENABLE(x)                ((x) << 16)
+#define MSCC_MS_INTR_CTRL_STATUS_INTR_ENABLE_M         GENMASK(31, 16)
+#define MACSEC_INTR_CTRL_STATUS_ROLLOVER               BIT(5)
+
+#endif
diff --git a/drivers/net/phy/mscc_fc_buffer.h b/drivers/net/phy/mscc_fc_buffer.h
deleted file mode 100644 (file)
index 7e9c0e8..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
-/*
- * Microsemi Ocelot Switch driver
- *
- * Copyright (C) 2019 Microsemi Corporation
- */
-
-#ifndef _MSCC_OCELOT_FC_BUFFER_H_
-#define _MSCC_OCELOT_FC_BUFFER_H_
-
-#define MSCC_FCBUF_ENA_CFG                                     0x00
-#define MSCC_FCBUF_MODE_CFG                                    0x01
-#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG                   0x02
-#define MSCC_FCBUF_TX_CTRL_QUEUE_CFG                           0x03
-#define MSCC_FCBUF_TX_DATA_QUEUE_CFG                           0x04
-#define MSCC_FCBUF_RX_DATA_QUEUE_CFG                           0x05
-#define MSCC_FCBUF_TX_BUFF_XON_XOFF_THRESH_CFG                 0x06
-#define MSCC_FCBUF_FC_READ_THRESH_CFG                          0x07
-#define MSCC_FCBUF_TX_FRM_GAP_COMP                             0x08
-
-#define MSCC_FCBUF_ENA_CFG_TX_ENA                              BIT(0)
-#define MSCC_FCBUF_ENA_CFG_RX_ENA                              BIT(4)
-
-#define MSCC_FCBUF_MODE_CFG_DROP_BEHAVIOUR                     BIT(4)
-#define MSCC_FCBUF_MODE_CFG_PAUSE_REACT_ENA                    BIT(8)
-#define MSCC_FCBUF_MODE_CFG_RX_PPM_RATE_ADAPT_ENA              BIT(12)
-#define MSCC_FCBUF_MODE_CFG_TX_PPM_RATE_ADAPT_ENA              BIT(16)
-#define MSCC_FCBUF_MODE_CFG_TX_CTRL_QUEUE_ENA                  BIT(20)
-#define MSCC_FCBUF_MODE_CFG_PAUSE_GEN_ENA                      BIT(24)
-#define MSCC_FCBUF_MODE_CFG_INCLUDE_PAUSE_RCVD_IN_PAUSE_GEN    BIT(28)
-
-#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_THRESH(x)      (x)
-#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_THRESH_M       GENMASK(15, 0)
-#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_OFFSET(x)      ((x) << 16)
-#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_OFFSET_M       GENMASK(19, 16)
-#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_RX_THRESH(x)      ((x) << 20)
-#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_RX_THRESH_M       GENMASK(31, 20)
-
-#define MSCC_FCBUF_TX_CTRL_QUEUE_CFG_START(x)                  (x)
-#define MSCC_FCBUF_TX_CTRL_QUEUE_CFG_START_M                   GENMASK(15, 0)
-#define MSCC_FCBUF_TX_CTRL_QUEUE_CFG_END(x)                    ((x) << 16)
-#define MSCC_FCBUF_TX_CTRL_QUEUE_CFG_END_M                     GENMASK(31, 16)
-
-#define MSCC_FCBUF_TX_DATA_QUEUE_CFG_START(x)                  (x)
-#define MSCC_FCBUF_TX_DATA_QUEUE_CFG_START_M                   GENMASK(15, 0)
-#define MSCC_FCBUF_TX_DATA_QUEUE_CFG_END(x)                    ((x) << 16)
-#define MSCC_FCBUF_TX_DATA_QUEUE_CFG_END_M                     GENMASK(31, 16)
-
-#define MSCC_FCBUF_RX_DATA_QUEUE_CFG_START(x)                  (x)
-#define MSCC_FCBUF_RX_DATA_QUEUE_CFG_START_M                   GENMASK(15, 0)
-#define MSCC_FCBUF_RX_DATA_QUEUE_CFG_END(x)                    ((x) << 16)
-#define MSCC_FCBUF_RX_DATA_QUEUE_CFG_END_M                     GENMASK(31, 16)
-
-#define MSCC_FCBUF_TX_BUFF_XON_XOFF_THRESH_CFG_XOFF_THRESH(x)  (x)
-#define MSCC_FCBUF_TX_BUFF_XON_XOFF_THRESH_CFG_XOFF_THRESH_M   GENMASK(15, 0)
-#define MSCC_FCBUF_TX_BUFF_XON_XOFF_THRESH_CFG_XON_THRESH(x)   ((x) << 16)
-#define MSCC_FCBUF_TX_BUFF_XON_XOFF_THRESH_CFG_XON_THRESH_M    GENMASK(31, 16)
-
-#define MSCC_FCBUF_FC_READ_THRESH_CFG_TX_THRESH(x)             (x)
-#define MSCC_FCBUF_FC_READ_THRESH_CFG_TX_THRESH_M              GENMASK(15, 0)
-#define MSCC_FCBUF_FC_READ_THRESH_CFG_RX_THRESH(x)             ((x) << 16)
-#define MSCC_FCBUF_FC_READ_THRESH_CFG_RX_THRESH_M              GENMASK(31, 16)
-
-#endif
diff --git a/drivers/net/phy/mscc_mac.h b/drivers/net/phy/mscc_mac.h
deleted file mode 100644 (file)
index 9420ee5..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
-/*
- * Microsemi Ocelot Switch driver
- *
- * Copyright (c) 2017 Microsemi Corporation
- */
-
-#ifndef _MSCC_OCELOT_LINE_MAC_H_
-#define _MSCC_OCELOT_LINE_MAC_H_
-
-#define MSCC_MAC_CFG_ENA_CFG                                   0x00
-#define MSCC_MAC_CFG_MODE_CFG                                  0x01
-#define MSCC_MAC_CFG_MAXLEN_CFG                                        0x02
-#define MSCC_MAC_CFG_NUM_TAGS_CFG                              0x03
-#define MSCC_MAC_CFG_TAGS_CFG                                  0x04
-#define MSCC_MAC_CFG_ADV_CHK_CFG                               0x07
-#define MSCC_MAC_CFG_LFS_CFG                                   0x08
-#define MSCC_MAC_CFG_LB_CFG                                    0x09
-#define MSCC_MAC_CFG_PKTINF_CFG                                        0x0a
-#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL                       0x0b
-#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_2                     0x0c
-#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL                       0x0d
-#define MSCC_MAC_PAUSE_CFG_STATE                               0x0e
-#define MSCC_MAC_PAUSE_CFG_MAC_ADDRESS_LSB                     0x0f
-#define MSCC_MAC_PAUSE_CFG_MAC_ADDRESS_MSB                     0x10
-#define MSCC_MAC_STATUS_RX_LANE_STICKY_0                       0x11
-#define MSCC_MAC_STATUS_RX_LANE_STICKY_1                       0x12
-#define MSCC_MAC_STATUS_TX_MONITOR_STICKY                      0x13
-#define MSCC_MAC_STATUS_TX_MONITOR_STICKY_MASK                 0x14
-#define MSCC_MAC_STATUS_STICKY                                 0x15
-#define MSCC_MAC_STATUS_STICKY_MASK                            0x16
-#define MSCC_MAC_STATS_32BIT_RX_HIH_CKSM_ERR_CNT               0x17
-#define MSCC_MAC_STATS_32BIT_RX_XGMII_PROT_ERR_CNT             0x18
-#define MSCC_MAC_STATS_32BIT_RX_SYMBOL_ERR_CNT                 0x19
-#define MSCC_MAC_STATS_32BIT_RX_PAUSE_CNT                      0x1a
-#define MSCC_MAC_STATS_32BIT_RX_UNSUP_OPCODE_CNT               0x1b
-#define MSCC_MAC_STATS_32BIT_RX_UC_CNT                         0x1c
-#define MSCC_MAC_STATS_32BIT_RX_MC_CNT                         0x1d
-#define MSCC_MAC_STATS_32BIT_RX_BC_CNT                         0x1e
-#define MSCC_MAC_STATS_32BIT_RX_CRC_ERR_CNT                    0x1f
-#define MSCC_MAC_STATS_32BIT_RX_UNDERSIZE_CNT                  0x20
-#define MSCC_MAC_STATS_32BIT_RX_FRAGMENTS_CNT                  0x21
-#define MSCC_MAC_STATS_32BIT_RX_IN_RANGE_LEN_ERR_CNT           0x22
-#define MSCC_MAC_STATS_32BIT_RX_OUT_OF_RANGE_LEN_ERR_CNT       0x23
-#define MSCC_MAC_STATS_32BIT_RX_OVERSIZE_CNT                   0x24
-#define MSCC_MAC_STATS_32BIT_RX_JABBERS_CNT                    0x25
-#define MSCC_MAC_STATS_32BIT_RX_SIZE64_CNT                     0x26
-#define MSCC_MAC_STATS_32BIT_RX_SIZE65TO127_CNT                        0x27
-#define MSCC_MAC_STATS_32BIT_RX_SIZE128TO255_CNT               0x28
-#define MSCC_MAC_STATS_32BIT_RX_SIZE256TO511_CNT               0x29
-#define MSCC_MAC_STATS_32BIT_RX_SIZE512TO1023_CNT              0x2a
-#define MSCC_MAC_STATS_32BIT_RX_SIZE1024TO1518_CNT             0x2b
-#define MSCC_MAC_STATS_32BIT_RX_SIZE1519TOMAX_CNT              0x2c
-#define MSCC_MAC_STATS_32BIT_RX_IPG_SHRINK_CNT                 0x2d
-#define MSCC_MAC_STATS_32BIT_TX_PAUSE_CNT                      0x2e
-#define MSCC_MAC_STATS_32BIT_TX_UC_CNT                         0x2f
-#define MSCC_MAC_STATS_32BIT_TX_MC_CNT                         0x30
-#define MSCC_MAC_STATS_32BIT_TX_BC_CNT                         0x31
-#define MSCC_MAC_STATS_32BIT_TX_SIZE64_CNT                     0x32
-#define MSCC_MAC_STATS_32BIT_TX_SIZE65TO127_CNT                        0x33
-#define MSCC_MAC_STATS_32BIT_TX_SIZE128TO255_CNT               0x34
-#define MSCC_MAC_STATS_32BIT_TX_SIZE256TO511_CNT               0x35
-#define MSCC_MAC_STATS_32BIT_TX_SIZE512TO1023_CNT              0x36
-#define MSCC_MAC_STATS_32BIT_TX_SIZE1024TO1518_CNT             0x37
-#define MSCC_MAC_STATS_32BIT_TX_SIZE1519TOMAX_CNT              0x38
-#define MSCC_MAC_STATS_40BIT_RX_BAD_BYTES_CNT                  0x39
-#define MSCC_MAC_STATS_40BIT_RX_BAD_BYTES_MSB_CNT              0x3a
-#define MSCC_MAC_STATS_40BIT_RX_OK_BYTES_CNT                   0x3b
-#define MSCC_MAC_STATS_40BIT_RX_OK_BYTES_MSB_CNT               0x3c
-#define MSCC_MAC_STATS_40BIT_RX_IN_BYTES_CNT                   0x3d
-#define MSCC_MAC_STATS_40BIT_RX_IN_BYTES_MSB_CNT               0x3e
-#define MSCC_MAC_STATS_40BIT_TX_OK_BYTES_CNT                   0x3f
-#define MSCC_MAC_STATS_40BIT_TX_OK_BYTES_MSB_CNT               0x40
-#define MSCC_MAC_STATS_40BIT_TX_OUT_BYTES_CNT                  0x41
-#define MSCC_MAC_STATS_40BIT_TX_OUT_BYTES_MSB_CNT              0x42
-
-#define MSCC_MAC_CFG_ENA_CFG_RX_CLK_ENA                                BIT(0)
-#define MSCC_MAC_CFG_ENA_CFG_TX_CLK_ENA                                BIT(4)
-#define MSCC_MAC_CFG_ENA_CFG_RX_SW_RST                         BIT(8)
-#define MSCC_MAC_CFG_ENA_CFG_TX_SW_RST                         BIT(12)
-#define MSCC_MAC_CFG_ENA_CFG_RX_ENA                            BIT(16)
-#define MSCC_MAC_CFG_ENA_CFG_TX_ENA                            BIT(20)
-
-#define MSCC_MAC_CFG_MODE_CFG_FORCE_CW_UPDATE_INTERVAL(x)      ((x) << 20)
-#define MSCC_MAC_CFG_MODE_CFG_FORCE_CW_UPDATE_INTERVAL_M       GENMASK(29, 20)
-#define MSCC_MAC_CFG_MODE_CFG_FORCE_CW_UPDATE                  BIT(16)
-#define MSCC_MAC_CFG_MODE_CFG_TUNNEL_PAUSE_FRAMES              BIT(14)
-#define MSCC_MAC_CFG_MODE_CFG_MAC_PREAMBLE_CFG(x)              ((x) << 10)
-#define MSCC_MAC_CFG_MODE_CFG_MAC_PREAMBLE_CFG_M               GENMASK(12, 10)
-#define MSCC_MAC_CFG_MODE_CFG_MAC_IPG_CFG                      BIT(6)
-#define MSCC_MAC_CFG_MODE_CFG_XGMII_GEN_MODE_ENA               BIT(4)
-#define MSCC_MAC_CFG_MODE_CFG_HIH_CRC_CHECK                    BIT(2)
-#define MSCC_MAC_CFG_MODE_CFG_UNDERSIZED_FRAME_DROP_DIS                BIT(1)
-#define MSCC_MAC_CFG_MODE_CFG_DISABLE_DIC                      BIT(0)
-
-#define MSCC_MAC_CFG_MAXLEN_CFG_MAX_LEN_TAG_CHK                        BIT(16)
-#define MSCC_MAC_CFG_MAXLEN_CFG_MAX_LEN(x)                     (x)
-#define MSCC_MAC_CFG_MAXLEN_CFG_MAX_LEN_M                      GENMASK(15, 0)
-
-#define MSCC_MAC_CFG_TAGS_CFG_RSZ                              0x4
-#define MSCC_MAC_CFG_TAGS_CFG_TAG_ID(x)                                ((x) << 16)
-#define MSCC_MAC_CFG_TAGS_CFG_TAG_ID_M                         GENMASK(31, 16)
-#define MSCC_MAC_CFG_TAGS_CFG_TAG_ENA                          BIT(4)
-
-#define MSCC_MAC_CFG_ADV_CHK_CFG_EXT_EOP_CHK_ENA               BIT(24)
-#define MSCC_MAC_CFG_ADV_CHK_CFG_EXT_SOP_CHK_ENA               BIT(20)
-#define MSCC_MAC_CFG_ADV_CHK_CFG_SFD_CHK_ENA                   BIT(16)
-#define MSCC_MAC_CFG_ADV_CHK_CFG_PRM_SHK_CHK_DIS               BIT(12)
-#define MSCC_MAC_CFG_ADV_CHK_CFG_PRM_CHK_ENA                   BIT(8)
-#define MSCC_MAC_CFG_ADV_CHK_CFG_OOR_ERR_ENA                   BIT(4)
-#define MSCC_MAC_CFG_ADV_CHK_CFG_INR_ERR_ENA                   BIT(0)
-
-#define MSCC_MAC_CFG_LFS_CFG_LFS_INH_TX                                BIT(8)
-#define MSCC_MAC_CFG_LFS_CFG_LFS_DIS_TX                                BIT(4)
-#define MSCC_MAC_CFG_LFS_CFG_LFS_UNIDIR_ENA                    BIT(3)
-#define MSCC_MAC_CFG_LFS_CFG_USE_LEADING_EDGE_DETECT           BIT(2)
-#define MSCC_MAC_CFG_LFS_CFG_SPURIOUS_Q_DIS                    BIT(1)
-#define MSCC_MAC_CFG_LFS_CFG_LFS_MODE_ENA                      BIT(0)
-
-#define MSCC_MAC_CFG_LB_CFG_XGMII_HOST_LB_ENA                  BIT(4)
-#define MSCC_MAC_CFG_LB_CFG_XGMII_PHY_LB_ENA                   BIT(0)
-
-#define MSCC_MAC_CFG_PKTINF_CFG_STRIP_FCS_ENA                  BIT(0)
-#define MSCC_MAC_CFG_PKTINF_CFG_INSERT_FCS_ENA                 BIT(4)
-#define MSCC_MAC_CFG_PKTINF_CFG_STRIP_PREAMBLE_ENA             BIT(8)
-#define MSCC_MAC_CFG_PKTINF_CFG_INSERT_PREAMBLE_ENA            BIT(12)
-#define MSCC_MAC_CFG_PKTINF_CFG_LPI_RELAY_ENA                  BIT(16)
-#define MSCC_MAC_CFG_PKTINF_CFG_LF_RELAY_ENA                   BIT(20)
-#define MSCC_MAC_CFG_PKTINF_CFG_RF_RELAY_ENA                   BIT(24)
-#define MSCC_MAC_CFG_PKTINF_CFG_ENABLE_TX_PADDING              BIT(25)
-#define MSCC_MAC_CFG_PKTINF_CFG_ENABLE_RX_PADDING              BIT(26)
-#define MSCC_MAC_CFG_PKTINF_CFG_ENABLE_4BYTE_PREAMBLE          BIT(27)
-#define MSCC_MAC_CFG_PKTINF_CFG_MACSEC_BYPASS_NUM_PTP_STALL_CLKS(x)    ((x) << 28)
-#define MSCC_MAC_CFG_PKTINF_CFG_MACSEC_BYPASS_NUM_PTP_STALL_CLKS_M     GENMASK(30, 28)
-
-#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_VALUE(x)                ((x) << 16)
-#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_VALUE_M         GENMASK(31, 16)
-#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_WAIT_FOR_LPI_LOW      BIT(12)
-#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_USE_PAUSE_STALL_ENA   BIT(8)
-#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_REPL_MODE       BIT(4)
-#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_FRC_FRAME       BIT(2)
-#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_MODE(x)         (x)
-#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_MODE_M          GENMASK(1, 0)
-
-#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_EARLY_PAUSE_DETECT_ENA        BIT(16)
-#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PRE_CRC_MODE          BIT(20)
-#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_TIMER_ENA       BIT(12)
-#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_REACT_ENA       BIT(8)
-#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_FRAME_DROP_ENA  BIT(4)
-#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_MODE            BIT(0)
-
-#define MSCC_MAC_PAUSE_CFG_STATE_PAUSE_STATE                   BIT(0)
-#define MSCC_MAC_PAUSE_CFG_STATE_MAC_TX_PAUSE_GEN              BIT(4)
-
-#define MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL                      0x2
-#define MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE(x)     (x)
-#define MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE_M      GENMASK(2, 0)
-
-#endif /* _MSCC_OCELOT_LINE_MAC_H_ */
diff --git a/drivers/net/phy/mscc_macsec.h b/drivers/net/phy/mscc_macsec.h
deleted file mode 100644 (file)
index d9ab6ab..0000000
+++ /dev/null
@@ -1,266 +0,0 @@
-/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
-/*
- * Microsemi Ocelot Switch driver
- *
- * Copyright (c) 2018 Microsemi Corporation
- */
-
-#ifndef _MSCC_OCELOT_MACSEC_H_
-#define _MSCC_OCELOT_MACSEC_H_
-
-#define MSCC_MS_MAX_FLOWS              16
-
-#define CONTROL_TYPE_EGRESS            0x6
-#define CONTROL_TYPE_INGRESS           0xf
-#define CONTROL_IV0                    BIT(5)
-#define CONTROL_IV1                    BIT(6)
-#define CONTROL_IV2                    BIT(7)
-#define CONTROL_UPDATE_SEQ             BIT(13)
-#define CONTROL_IV_IN_SEQ              BIT(14)
-#define CONTROL_ENCRYPT_AUTH           BIT(15)
-#define CONTROL_KEY_IN_CTX             BIT(16)
-#define CONTROL_CRYPTO_ALG(x)          ((x) << 17)
-#define     CTRYPTO_ALG_AES_CTR_128    0x5
-#define     CTRYPTO_ALG_AES_CTR_192    0x6
-#define     CTRYPTO_ALG_AES_CTR_256    0x7
-#define CONTROL_DIGEST_TYPE(x)         ((x) << 21)
-#define CONTROL_AUTH_ALG(x)            ((x) << 23)
-#define     AUTH_ALG_AES_GHAS          0x4
-#define CONTROL_AN(x)                  ((x) << 26)
-#define CONTROL_SEQ_TYPE(x)            ((x) << 28)
-#define CONTROL_SEQ_MASK               BIT(30)
-#define CONTROL_CONTEXT_ID             BIT(31)
-
-enum mscc_macsec_destination_ports {
-       MSCC_MS_PORT_COMMON             = 0,
-       MSCC_MS_PORT_RSVD               = 1,
-       MSCC_MS_PORT_CONTROLLED         = 2,
-       MSCC_MS_PORT_UNCONTROLLED       = 3,
-};
-
-enum mscc_macsec_drop_actions {
-       MSCC_MS_ACTION_BYPASS_CRC       = 0,
-       MSCC_MS_ACTION_BYPASS_BAD       = 1,
-       MSCC_MS_ACTION_DROP             = 2,
-       MSCC_MS_ACTION_BYPASS           = 3,
-};
-
-enum mscc_macsec_flow_types {
-       MSCC_MS_FLOW_BYPASS             = 0,
-       MSCC_MS_FLOW_DROP               = 1,
-       MSCC_MS_FLOW_INGRESS            = 2,
-       MSCC_MS_FLOW_EGRESS             = 3,
-};
-
-enum mscc_macsec_validate_levels {
-       MSCC_MS_VALIDATE_DISABLED       = 0,
-       MSCC_MS_VALIDATE_CHECK          = 1,
-       MSCC_MS_VALIDATE_STRICT         = 2,
-};
-
-#define MSCC_MS_XFORM_REC(x, y)                (((x) << 5) + (y))
-#define MSCC_MS_ENA_CFG                        0x800
-#define MSCC_MS_FC_CFG                 0x804
-#define MSCC_MS_SAM_MAC_SA_MATCH_LO(x) (0x1000 + ((x) << 4))
-#define MSCC_MS_SAM_MAC_SA_MATCH_HI(x) (0x1001 + ((x) << 4))
-#define MSCC_MS_SAM_MISC_MATCH(x)      (0x1004 + ((x) << 4))
-#define MSCC_MS_SAM_MATCH_SCI_LO(x)    (0x1005 + ((x) << 4))
-#define MSCC_MS_SAM_MATCH_SCI_HI(x)    (0x1006 + ((x) << 4))
-#define MSCC_MS_SAM_MASK(x)            (0x1007 + ((x) << 4))
-#define MSCC_MS_SAM_ENTRY_SET1         0x1808
-#define MSCC_MS_SAM_ENTRY_CLEAR1       0x180c
-#define MSCC_MS_SAM_FLOW_CTRL(x)       (0x1c00 + (x))
-#define MSCC_MS_SAM_CP_TAG             0x1e40
-#define MSCC_MS_SAM_NM_FLOW_NCP                0x1e51
-#define MSCC_MS_SAM_NM_FLOW_CP         0x1e52
-#define MSCC_MS_MISC_CONTROL           0x1e5f
-#define MSCC_MS_COUNT_CONTROL          0x3204
-#define MSCC_MS_PARAMS2_IG_CC_CONTROL  0x3a10
-#define MSCC_MS_PARAMS2_IG_CP_TAG      0x3a14
-#define MSCC_MS_VLAN_MTU_CHECK(x)      (0x3c40 + (x))
-#define MSCC_MS_NON_VLAN_MTU_CHECK     0x3c48
-#define MSCC_MS_PP_CTRL                        0x3c4b
-#define MSCC_MS_STATUS_CONTEXT_CTRL    0x3d02
-#define MSCC_MS_INTR_CTRL_STATUS       0x3d04
-#define MSCC_MS_BLOCK_CTX_UPDATE       0x3d0c
-#define MSCC_MS_AIC_CTRL               0x3e02
-
-/* MACSEC_ENA_CFG */
-#define MSCC_MS_ENA_CFG_CLK_ENA                                BIT(0)
-#define MSCC_MS_ENA_CFG_SW_RST                         BIT(1)
-#define MSCC_MS_ENA_CFG_MACSEC_BYPASS_ENA              BIT(8)
-#define MSCC_MS_ENA_CFG_MACSEC_ENA                     BIT(9)
-#define MSCC_MS_ENA_CFG_MACSEC_SPEED_MODE(x)           ((x) << 10)
-#define MSCC_MS_ENA_CFG_MACSEC_SPEED_MODE_M            GENMASK(12, 10)
-
-/* MACSEC_FC_CFG */
-#define MSCC_MS_FC_CFG_FCBUF_ENA                       BIT(0)
-#define MSCC_MS_FC_CFG_USE_PKT_EXPANSION_INDICATION    BIT(1)
-#define MSCC_MS_FC_CFG_LOW_THRESH(x)                   ((x) << 4)
-#define MSCC_MS_FC_CFG_LOW_THRESH_M                    GENMASK(7, 4)
-#define MSCC_MS_FC_CFG_HIGH_THRESH(x)                  ((x) << 8)
-#define MSCC_MS_FC_CFG_HIGH_THRESH_M                   GENMASK(11, 8)
-#define MSCC_MS_FC_CFG_LOW_BYTES_VAL(x)                        ((x) << 12)
-#define MSCC_MS_FC_CFG_LOW_BYTES_VAL_M                 GENMASK(14, 12)
-#define MSCC_MS_FC_CFG_HIGH_BYTES_VAL(x)               ((x) << 16)
-#define MSCC_MS_FC_CFG_HIGH_BYTES_VAL_M                        GENMASK(18, 16)
-
-/* MSCC_MS_SAM_MAC_SA_MATCH_HI */
-#define MSCC_MS_SAM_MAC_SA_MATCH_HI_ETYPE(x)           ((x) << 16)
-#define MSCC_MS_SAM_MAC_SA_MATCH_HI_ETYPE_M            GENMASK(31, 16)
-
-/* MACSEC_SAM_MISC_MATCH */
-#define MSCC_MS_SAM_MISC_MATCH_VLAN_VALID              BIT(0)
-#define MSCC_MS_SAM_MISC_MATCH_QINQ_FOUND              BIT(1)
-#define MSCC_MS_SAM_MISC_MATCH_STAG_VALID              BIT(2)
-#define MSCC_MS_SAM_MISC_MATCH_QTAG_VALID              BIT(3)
-#define MSCC_MS_SAM_MISC_MATCH_VLAN_UP(x)              ((x) << 4)
-#define MSCC_MS_SAM_MISC_MATCH_VLAN_UP_M               GENMASK(6, 4)
-#define MSCC_MS_SAM_MISC_MATCH_CONTROL_PACKET          BIT(7)
-#define MSCC_MS_SAM_MISC_MATCH_UNTAGGED                        BIT(8)
-#define MSCC_MS_SAM_MISC_MATCH_TAGGED                  BIT(9)
-#define MSCC_MS_SAM_MISC_MATCH_BAD_TAG                 BIT(10)
-#define MSCC_MS_SAM_MISC_MATCH_KAY_TAG                 BIT(11)
-#define MSCC_MS_SAM_MISC_MATCH_SOURCE_PORT(x)          ((x) << 12)
-#define MSCC_MS_SAM_MISC_MATCH_SOURCE_PORT_M           GENMASK(13, 12)
-#define MSCC_MS_SAM_MISC_MATCH_PRIORITY(x)             ((x) << 16)
-#define MSCC_MS_SAM_MISC_MATCH_PRIORITY_M              GENMASK(19, 16)
-#define MSCC_MS_SAM_MISC_MATCH_AN(x)                   ((x) << 24)
-#define MSCC_MS_SAM_MISC_MATCH_TCI(x)                  ((x) << 26)
-
-/* MACSEC_SAM_MASK */
-#define MSCC_MS_SAM_MASK_MAC_SA_MASK(x)                        (x)
-#define MSCC_MS_SAM_MASK_MAC_SA_MASK_M                 GENMASK(5, 0)
-#define MSCC_MS_SAM_MASK_MAC_DA_MASK(x)                        ((x) << 6)
-#define MSCC_MS_SAM_MASK_MAC_DA_MASK_M                 GENMASK(11, 6)
-#define MSCC_MS_SAM_MASK_MAC_ETYPE_MASK                        BIT(12)
-#define MSCC_MS_SAM_MASK_VLAN_VLD_MASK                 BIT(13)
-#define MSCC_MS_SAM_MASK_QINQ_FOUND_MASK               BIT(14)
-#define MSCC_MS_SAM_MASK_STAG_VLD_MASK                 BIT(15)
-#define MSCC_MS_SAM_MASK_QTAG_VLD_MASK                 BIT(16)
-#define MSCC_MS_SAM_MASK_VLAN_UP_MASK                  BIT(17)
-#define MSCC_MS_SAM_MASK_VLAN_ID_MASK                  BIT(18)
-#define MSCC_MS_SAM_MASK_SOURCE_PORT_MASK              BIT(19)
-#define MSCC_MS_SAM_MASK_CTL_PACKET_MASK               BIT(20)
-#define MSCC_MS_SAM_MASK_VLAN_UP_INNER_MASK            BIT(21)
-#define MSCC_MS_SAM_MASK_VLAN_ID_INNER_MASK            BIT(22)
-#define MSCC_MS_SAM_MASK_SCI_MASK                      BIT(23)
-#define MSCC_MS_SAM_MASK_AN_MASK(x)                    ((x) << 24)
-#define MSCC_MS_SAM_MASK_TCI_MASK(x)                   ((x) << 26)
-
-/* MACSEC_SAM_FLOW_CTRL_EGR */
-#define MSCC_MS_SAM_FLOW_CTRL_FLOW_TYPE(x)             (x)
-#define MSCC_MS_SAM_FLOW_CTRL_FLOW_TYPE_M              GENMASK(1, 0)
-#define MSCC_MS_SAM_FLOW_CTRL_DEST_PORT(x)             ((x) << 2)
-#define MSCC_MS_SAM_FLOW_CTRL_DEST_PORT_M              GENMASK(3, 2)
-#define MSCC_MS_SAM_FLOW_CTRL_RESV_4                   BIT(4)
-#define MSCC_MS_SAM_FLOW_CTRL_FLOW_CRYPT_AUTH          BIT(5)
-#define MSCC_MS_SAM_FLOW_CTRL_DROP_ACTION(x)           ((x) << 6)
-#define MSCC_MS_SAM_FLOW_CTRL_DROP_ACTION_M            GENMASK(7, 6)
-#define MSCC_MS_SAM_FLOW_CTRL_RESV_15_TO_8(x)          ((x) << 8)
-#define MSCC_MS_SAM_FLOW_CTRL_RESV_15_TO_8_M           GENMASK(15, 8)
-#define MSCC_MS_SAM_FLOW_CTRL_PROTECT_FRAME            BIT(16)
-#define MSCC_MS_SAM_FLOW_CTRL_REPLAY_PROTECT           BIT(16)
-#define MSCC_MS_SAM_FLOW_CTRL_SA_IN_USE                        BIT(17)
-#define MSCC_MS_SAM_FLOW_CTRL_INCLUDE_SCI              BIT(18)
-#define MSCC_MS_SAM_FLOW_CTRL_USE_ES                   BIT(19)
-#define MSCC_MS_SAM_FLOW_CTRL_USE_SCB                  BIT(20)
-#define MSCC_MS_SAM_FLOW_CTRL_VALIDATE_FRAMES(x)       ((x) << 19)
-#define MSCC_MS_SAM_FLOW_CTRL_TAG_BYPASS_SIZE(x)       ((x) << 21)
-#define MSCC_MS_SAM_FLOW_CTRL_TAG_BYPASS_SIZE_M                GENMASK(22, 21)
-#define MSCC_MS_SAM_FLOW_CTRL_RESV_23                  BIT(23)
-#define MSCC_MS_SAM_FLOW_CTRL_CONFIDENTIALITY_OFFSET(x)        ((x) << 24)
-#define MSCC_MS_SAM_FLOW_CTRL_CONFIDENTIALITY_OFFSET_M GENMASK(30, 24)
-#define MSCC_MS_SAM_FLOW_CTRL_CONF_PROTECT             BIT(31)
-
-/* MACSEC_SAM_CP_TAG */
-#define MSCC_MS_SAM_CP_TAG_MAP_TBL(x)                  (x)
-#define MSCC_MS_SAM_CP_TAG_MAP_TBL_M                   GENMASK(23, 0)
-#define MSCC_MS_SAM_CP_TAG_DEF_UP(x)                   ((x) << 24)
-#define MSCC_MS_SAM_CP_TAG_DEF_UP_M                    GENMASK(26, 24)
-#define MSCC_MS_SAM_CP_TAG_STAG_UP_EN                  BIT(27)
-#define MSCC_MS_SAM_CP_TAG_QTAG_UP_EN                  BIT(28)
-#define MSCC_MS_SAM_CP_TAG_PARSE_QINQ                  BIT(29)
-#define MSCC_MS_SAM_CP_TAG_PARSE_STAG                  BIT(30)
-#define MSCC_MS_SAM_CP_TAG_PARSE_QTAG                  BIT(31)
-
-/* MACSEC_SAM_NM_FLOW_NCP */
-#define MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_FLOW_TYPE(x)  (x)
-#define MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_DEST_PORT(x)  ((x) << 2)
-#define MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_DROP_ACTION(x)        ((x) << 6)
-#define MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_FLOW_TYPE(x)    ((x) << 8)
-#define MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_DEST_PORT(x)    ((x) << 10)
-#define MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_DROP_ACTION(x)  ((x) << 14)
-#define MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_FLOW_TYPE(x)    ((x) << 16)
-#define MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_DEST_PORT(x)    ((x) << 18)
-#define MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_DROP_ACTION(x)  ((x) << 22)
-#define MSCC_MS_SAM_NM_FLOW_NCP_KAY_FLOW_TYPE(x)       ((x) << 24)
-#define MSCC_MS_SAM_NM_FLOW_NCP_KAY_DEST_PORT(x)       ((x) << 26)
-#define MSCC_MS_SAM_NM_FLOW_NCP_KAY_DROP_ACTION(x)     ((x) << 30)
-
-/* MACSEC_SAM_NM_FLOW_CP */
-#define MSCC_MS_SAM_NM_FLOW_CP_UNTAGGED_FLOW_TYPE(x)   (x)
-#define MSCC_MS_SAM_NM_FLOW_CP_UNTAGGED_DEST_PORT(x)   ((x) << 2)
-#define MSCC_MS_SAM_NM_FLOW_CP_UNTAGGED_DROP_ACTION(x) ((x) << 6)
-#define MSCC_MS_SAM_NM_FLOW_CP_TAGGED_FLOW_TYPE(x)     ((x) << 8)
-#define MSCC_MS_SAM_NM_FLOW_CP_TAGGED_DEST_PORT(x)     ((x) << 10)
-#define MSCC_MS_SAM_NM_FLOW_CP_TAGGED_DROP_ACTION(x)   ((x) << 14)
-#define MSCC_MS_SAM_NM_FLOW_CP_BADTAG_FLOW_TYPE(x)     ((x) << 16)
-#define MSCC_MS_SAM_NM_FLOW_CP_BADTAG_DEST_PORT(x)     ((x) << 18)
-#define MSCC_MS_SAM_NM_FLOW_CP_BADTAG_DROP_ACTION(x)   ((x) << 22)
-#define MSCC_MS_SAM_NM_FLOW_CP_KAY_FLOW_TYPE(x)                ((x) << 24)
-#define MSCC_MS_SAM_NM_FLOW_CP_KAY_DEST_PORT(x)                ((x) << 26)
-#define MSCC_MS_SAM_NM_FLOW_CP_KAY_DROP_ACTION(x)      ((x) << 30)
-
-/* MACSEC_MISC_CONTROL */
-#define MSCC_MS_MISC_CONTROL_MC_LATENCY_FIX(x)         (x)
-#define MSCC_MS_MISC_CONTROL_MC_LATENCY_FIX_M          GENMASK(5, 0)
-#define MSCC_MS_MISC_CONTROL_STATIC_BYPASS             BIT(8)
-#define MSCC_MS_MISC_CONTROL_NM_MACSEC_EN              BIT(9)
-#define MSCC_MS_MISC_CONTROL_VALIDATE_FRAMES(x)                ((x) << 10)
-#define MSCC_MS_MISC_CONTROL_VALIDATE_FRAMES_M         GENMASK(11, 10)
-#define MSCC_MS_MISC_CONTROL_XFORM_REC_SIZE(x)         ((x) << 24)
-#define MSCC_MS_MISC_CONTROL_XFORM_REC_SIZE_M          GENMASK(25, 24)
-
-/* MACSEC_COUNT_CONTROL */
-#define MSCC_MS_COUNT_CONTROL_RESET_ALL                        BIT(0)
-#define MSCC_MS_COUNT_CONTROL_DEBUG_ACCESS             BIT(1)
-#define MSCC_MS_COUNT_CONTROL_SATURATE_CNTRS           BIT(2)
-#define MSCC_MS_COUNT_CONTROL_AUTO_CNTR_RESET          BIT(3)
-
-/* MACSEC_PARAMS2_IG_CC_CONTROL */
-#define MSCC_MS_PARAMS2_IG_CC_CONTROL_NON_MATCH_CTRL_ACT       BIT(14)
-#define MSCC_MS_PARAMS2_IG_CC_CONTROL_NON_MATCH_ACT    BIT(15)
-
-/* MACSEC_PARAMS2_IG_CP_TAG */
-#define MSCC_MS_PARAMS2_IG_CP_TAG_MAP_TBL(x)           (x)
-#define MSCC_MS_PARAMS2_IG_CP_TAG_MAP_TBL_M            GENMASK(23, 0)
-#define MSCC_MS_PARAMS2_IG_CP_TAG_DEF_UP(x)            ((x) << 24)
-#define MSCC_MS_PARAMS2_IG_CP_TAG_DEF_UP_M             GENMASK(26, 24)
-#define MSCC_MS_PARAMS2_IG_CP_TAG_STAG_UP_EN           BIT(27)
-#define MSCC_MS_PARAMS2_IG_CP_TAG_QTAG_UP_EN           BIT(28)
-#define MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_QINQ           BIT(29)
-#define MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_STAG           BIT(30)
-#define MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_QTAG           BIT(31)
-
-/* MACSEC_VLAN_MTU_CHECK */
-#define MSCC_MS_VLAN_MTU_CHECK_MTU_COMPARE(x)          (x)
-#define MSCC_MS_VLAN_MTU_CHECK_MTU_COMPARE_M           GENMASK(14, 0)
-#define MSCC_MS_VLAN_MTU_CHECK_MTU_COMP_DROP           BIT(15)
-
-/* MACSEC_NON_VLAN_MTU_CHECK */
-#define MSCC_MS_NON_VLAN_MTU_CHECK_NV_MTU_COMPARE(x)   (x)
-#define MSCC_MS_NON_VLAN_MTU_CHECK_NV_MTU_COMPARE_M    GENMASK(14, 0)
-#define MSCC_MS_NON_VLAN_MTU_CHECK_NV_MTU_COMP_DROP    BIT(15)
-
-/* MACSEC_PP_CTRL */
-#define MSCC_MS_PP_CTRL_MACSEC_OCTET_INCR_MODE         BIT(0)
-
-/* MACSEC_INTR_CTRL_STATUS */
-#define MSCC_MS_INTR_CTRL_STATUS_INTR_CLR_STATUS(x)    (x)
-#define MSCC_MS_INTR_CTRL_STATUS_INTR_CLR_STATUS_M     GENMASK(15, 0)
-#define MSCC_MS_INTR_CTRL_STATUS_INTR_ENABLE(x)                ((x) << 16)
-#define MSCC_MS_INTR_CTRL_STATUS_INTR_ENABLE_M         GENMASK(31, 16)
-#define MACSEC_INTR_CTRL_STATUS_ROLLOVER               BIT(5)
-
-#endif