root/drivers/net/dsa/yt921x.h
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Copyright (c) 2025 David Yang
 */

#ifndef __YT921X_H
#define __YT921X_H

#include <net/dsa.h>

#define YT921X_SMI_SWITCHID_M           GENMASK(3, 2)
#define  YT921X_SMI_SWITCHID(x)                 FIELD_PREP(YT921X_SMI_SWITCHID_M, (x))
#define YT921X_SMI_AD                   BIT(1)
#define  YT921X_SMI_ADDR                        0
#define  YT921X_SMI_DATA                        YT921X_SMI_AD
#define YT921X_SMI_RW                   BIT(0)
#define  YT921X_SMI_WRITE                       0
#define  YT921X_SMI_READ                        YT921X_SMI_RW

#define YT921X_SWITCHID_NUM             4

#define YT921X_RST                      0x80000
#define  YT921X_RST_HW                          BIT(31)
#define  YT921X_RST_SW                          BIT(1)
#define YT921X_FUNC                     0x80004
#define  YT921X_FUNC_MIB                        BIT(1)
#define YT921X_CHIP_ID                  0x80008
#define  YT921X_CHIP_ID_MAJOR                   GENMASK(31, 16)
#define YT921X_EXT_CPU_PORT             0x8000c
#define  YT921X_EXT_CPU_PORT_TAG_EN             BIT(15)
#define  YT921X_EXT_CPU_PORT_PORT_EN            BIT(14)
#define  YT921X_EXT_CPU_PORT_PORT_M             GENMASK(3, 0)
#define   YT921X_EXT_CPU_PORT_PORT(x)                   FIELD_PREP(YT921X_EXT_CPU_PORT_PORT_M, (x))
#define YT921X_CPU_TAG_TPID             0x80010
#define  YT921X_CPU_TAG_TPID_TPID_M             GENMASK(15, 0)
/* Same as ETH_P_YT921X, but this represents the true HW default, while the
 * former is a local convention chosen by us.
 */
#define   YT921X_CPU_TAG_TPID_TPID_DEFAULT              0x9988
#define YT921X_PVID_SEL                 0x80014
#define  YT921X_PVID_SEL_SVID_PORTn(port)       BIT(port)
#define YT921X_SERDES_CTRL              0x80028
#define  YT921X_SERDES_CTRL_PORTn_TEST(port)    BIT((port) - 3)
#define  YT921X_SERDES_CTRL_PORTn(port)         BIT((port) - 8)
#define YT921X_IO_LEVEL                 0x80030
#define  YT9215_IO_LEVEL_NORMAL_M               GENMASK(5, 4)
#define   YT9215_IO_LEVEL_NORMAL(x)                     FIELD_PREP(YT9215_IO_LEVEL_NORMAL_M, (x))
#define   YT9215_IO_LEVEL_NORMAL_3V3                    YT9215_IO_LEVEL_NORMAL(0)
#define   YT9215_IO_LEVEL_NORMAL_1V8                    YT9215_IO_LEVEL_NORMAL(3)
#define  YT9215_IO_LEVEL_RGMII1_M               GENMASK(3, 2)
#define   YT9215_IO_LEVEL_RGMII1(x)                     FIELD_PREP(YT9215_IO_LEVEL_RGMII1_M, (x))
#define   YT9215_IO_LEVEL_RGMII1_3V3                    YT9215_IO_LEVEL_RGMII1(0)
#define   YT9215_IO_LEVEL_RGMII1_2V5                    YT9215_IO_LEVEL_RGMII1(1)
#define   YT9215_IO_LEVEL_RGMII1_1V8                    YT9215_IO_LEVEL_RGMII1(2)
#define  YT9215_IO_LEVEL_RGMII0_M               GENMASK(1, 0)
#define   YT9215_IO_LEVEL_RGMII0(x)                     FIELD_PREP(YT9215_IO_LEVEL_RGMII0_M, (x))
#define   YT9215_IO_LEVEL_RGMII0_3V3                    YT9215_IO_LEVEL_RGMII0(0)
#define   YT9215_IO_LEVEL_RGMII0_2V5                    YT9215_IO_LEVEL_RGMII0(1)
#define   YT9215_IO_LEVEL_RGMII0_1V8                    YT9215_IO_LEVEL_RGMII0(2)
#define  YT9218_IO_LEVEL_RGMII1_M               GENMASK(5, 4)
#define   YT9218_IO_LEVEL_RGMII1(x)                     FIELD_PREP(YT9218_IO_LEVEL_RGMII1_M, (x))
#define   YT9218_IO_LEVEL_RGMII1_3V3                    YT9218_IO_LEVEL_RGMII1(0)
#define   YT9218_IO_LEVEL_RGMII1_2V5                    YT9218_IO_LEVEL_RGMII1(1)
#define   YT9218_IO_LEVEL_RGMII1_1V8                    YT9218_IO_LEVEL_RGMII1(2)
#define  YT9218_IO_LEVEL_RGMII0_M               GENMASK(3, 2)
#define   YT9218_IO_LEVEL_RGMII0(x)                     FIELD_PREP(YT9218_IO_LEVEL_RGMII0_M, (x))
#define   YT9218_IO_LEVEL_RGMII0_3V3                    YT9218_IO_LEVEL_RGMII0(0)
#define   YT9218_IO_LEVEL_RGMII0_2V5                    YT9218_IO_LEVEL_RGMII0(1)
#define   YT9218_IO_LEVEL_RGMII0_1V8                    YT9218_IO_LEVEL_RGMII0(2)
#define  YT9218_IO_LEVEL_NORMAL_M               GENMASK(1, 0)
#define   YT9218_IO_LEVEL_NORMAL(x)                     FIELD_PREP(YT9218_IO_LEVEL_NORMAL_M, (x))
#define   YT9218_IO_LEVEL_NORMAL_3V3                    YT9218_IO_LEVEL_NORMAL(0)
#define   YT9218_IO_LEVEL_NORMAL_1V8                    YT9218_IO_LEVEL_NORMAL(3)
#define YT921X_MAC_ADDR_HI2             0x80080
#define YT921X_MAC_ADDR_LO4             0x80084
#define YT921X_SERDESn(port)            (0x8008c + 4 * ((port) - 8))
#define  YT921X_SERDES_MODE_M                   GENMASK(9, 7)
#define   YT921X_SERDES_MODE(x)                         FIELD_PREP(YT921X_SERDES_MODE_M, (x))
#define   YT921X_SERDES_MODE_SGMII                      YT921X_SERDES_MODE(0)
#define   YT921X_SERDES_MODE_REVSGMII                   YT921X_SERDES_MODE(1)
#define   YT921X_SERDES_MODE_1000BASEX                  YT921X_SERDES_MODE(2)
#define   YT921X_SERDES_MODE_100BASEX                   YT921X_SERDES_MODE(3)
#define   YT921X_SERDES_MODE_2500BASEX                  YT921X_SERDES_MODE(4)
#define  YT921X_SERDES_RX_PAUSE                 BIT(6)
#define  YT921X_SERDES_TX_PAUSE                 BIT(5)
#define  YT921X_SERDES_LINK                     BIT(4)  /* force link */
#define  YT921X_SERDES_DUPLEX_FULL              BIT(3)
#define  YT921X_SERDES_SPEED_M                  GENMASK(2, 0)
#define   YT921X_SERDES_SPEED(x)                        FIELD_PREP(YT921X_SERDES_SPEED_M, (x))
#define   YT921X_SERDES_SPEED_10                        YT921X_SERDES_SPEED(0)
#define   YT921X_SERDES_SPEED_100                       YT921X_SERDES_SPEED(1)
#define   YT921X_SERDES_SPEED_1000                      YT921X_SERDES_SPEED(2)
#define   YT921X_SERDES_SPEED_10000                     YT921X_SERDES_SPEED(3)
#define   YT921X_SERDES_SPEED_2500                      YT921X_SERDES_SPEED(4)
#define YT921X_PORTn_CTRL(port)         (0x80100 + 4 * (port))
#define  YT921X_PORT_CTRL_PAUSE_AN              BIT(10)
#define YT921X_PORTn_STATUS(port)       (0x80200 + 4 * (port))
#define  YT921X_PORT_LINK                       BIT(9)  /* CTRL: auto negotiation */
#define  YT921X_PORT_HALF_PAUSE                 BIT(8)  /* Half-duplex back pressure mode */
#define  YT921X_PORT_DUPLEX_FULL                BIT(7)
#define  YT921X_PORT_RX_PAUSE                   BIT(6)
#define  YT921X_PORT_TX_PAUSE                   BIT(5)
#define  YT921X_PORT_RX_MAC_EN                  BIT(4)
#define  YT921X_PORT_TX_MAC_EN                  BIT(3)
#define  YT921X_PORT_SPEED_M                    GENMASK(2, 0)
#define   YT921X_PORT_SPEED(x)                          FIELD_PREP(YT921X_PORT_SPEED_M, (x))
#define   YT921X_PORT_SPEED_10                          YT921X_PORT_SPEED(0)
#define   YT921X_PORT_SPEED_100                         YT921X_PORT_SPEED(1)
#define   YT921X_PORT_SPEED_1000                        YT921X_PORT_SPEED(2)
#define   YT921X_PORT_SPEED_10000                       YT921X_PORT_SPEED(3)
#define   YT921X_PORT_SPEED_2500                        YT921X_PORT_SPEED(4)
#define YT921X_PON_STRAP_FUNC           0x80320
#define YT921X_PON_STRAP_VAL            0x80324
#define YT921X_PON_STRAP_CAP            0x80328
#define  YT921X_PON_STRAP_EEE                   BIT(16)
#define  YT921X_PON_STRAP_LOOP_DETECT           BIT(7)
#define YT921X_MDIO_POLLINGn(port)      (0x80364 + 4 * ((port) - 8))
#define  YT921X_MDIO_POLLING_DUPLEX_FULL        BIT(4)
#define  YT921X_MDIO_POLLING_LINK               BIT(3)
#define  YT921X_MDIO_POLLING_SPEED_M            GENMASK(2, 0)
#define   YT921X_MDIO_POLLING_SPEED(x)                  FIELD_PREP(YT921X_MDIO_POLLING_SPEED_M, (x))
#define   YT921X_MDIO_POLLING_SPEED_10                  YT921X_MDIO_POLLING_SPEED(0)
#define   YT921X_MDIO_POLLING_SPEED_100                 YT921X_MDIO_POLLING_SPEED(1)
#define   YT921X_MDIO_POLLING_SPEED_1000                YT921X_MDIO_POLLING_SPEED(2)
#define   YT921X_MDIO_POLLING_SPEED_10000               YT921X_MDIO_POLLING_SPEED(3)
#define   YT921X_MDIO_POLLING_SPEED_2500                YT921X_MDIO_POLLING_SPEED(4)
#define YT921X_SENSOR                   0x8036c
#define  YT921X_SENSOR_TEMP                     BIT(18)
#define YT921X_TEMP                     0x80374
#define YT921X_CHIP_MODE                0x80388
#define  YT921X_CHIP_MODE_MODE                  GENMASK(1, 0)
#define YT921X_XMII_CTRL                0x80394
#define  YT921X_XMII_CTRL_PORTn(port)           BIT(9 - (port))  /* Yes, it's reversed */
#define YT921X_XMIIn(port)              (0x80400 + 8 * ((port) - 8))
#define  YT921X_XMII_MODE_M                     GENMASK(31, 29)
#define   YT921X_XMII_MODE(x)                           FIELD_PREP(YT921X_XMII_MODE_M, (x))
#define   YT921X_XMII_MODE_MII                          YT921X_XMII_MODE(0)
#define   YT921X_XMII_MODE_REVMII                       YT921X_XMII_MODE(1)
#define   YT921X_XMII_MODE_RMII                         YT921X_XMII_MODE(2)
#define   YT921X_XMII_MODE_REVRMII                      YT921X_XMII_MODE(3)
#define   YT921X_XMII_MODE_RGMII                        YT921X_XMII_MODE(4)
#define   YT921X_XMII_MODE_DISABLE                      YT921X_XMII_MODE(5)
#define  YT921X_XMII_LINK                       BIT(19)  /* force link */
#define  YT921X_XMII_EN                         BIT(18)
#define  YT921X_XMII_SOFT_RST                   BIT(17)
#define  YT921X_XMII_RGMII_TX_DELAY_150PS_M     GENMASK(16, 13)
#define   YT921X_XMII_RGMII_TX_DELAY_150PS(x)           FIELD_PREP(YT921X_XMII_RGMII_TX_DELAY_150PS_M, (x))
#define  YT921X_XMII_TX_CLK_IN                  BIT(11)
#define  YT921X_XMII_RX_CLK_IN                  BIT(10)
#define  YT921X_XMII_RGMII_TX_DELAY_2NS         BIT(8)
#define  YT921X_XMII_RGMII_TX_CLK_OUT           BIT(7)
#define  YT921X_XMII_RGMII_RX_DELAY_150PS_M     GENMASK(6, 3)
#define   YT921X_XMII_RGMII_RX_DELAY_150PS(x)           FIELD_PREP(YT921X_XMII_RGMII_RX_DELAY_150PS_M, (x))
#define  YT921X_XMII_RMII_PHY_TX_CLK_OUT        BIT(2)
#define  YT921X_XMII_REVMII_TX_CLK_OUT          BIT(1)
#define  YT921X_XMII_REVMII_RX_CLK_OUT          BIT(0)

#define YT921X_MACn_FRAME(port)         (0x81008 + 0x1000 * (port))
#define  YT921X_MAC_FRAME_SIZE_M                GENMASK(21, 8)
#define   YT921X_MAC_FRAME_SIZE(x)                      FIELD_PREP(YT921X_MAC_FRAME_SIZE_M, (x))

#define YT921X_EEEn_VAL(port)           (0xa0000 + 0x40 * (port))
#define  YT921X_EEE_VAL_DATA                    BIT(1)

#define YT921X_EEE_CTRL                 0xb0000
#define  YT921X_EEE_CTRL_ENn(port)              BIT(port)

#define YT921X_MIB_CTRL                 0xc0004
#define  YT921X_MIB_CTRL_CLEAN                  BIT(30)
#define  YT921X_MIB_CTRL_PORT_M                 GENMASK(6, 3)
#define   YT921X_MIB_CTRL_PORT(x)                       FIELD_PREP(YT921X_MIB_CTRL_PORT_M, (x))
#define  YT921X_MIB_CTRL_ONE_PORT               BIT(1)
#define  YT921X_MIB_CTRL_ALL_PORT               BIT(0)
#define YT921X_MIBn_DATA0(port)         (0xc0100 + 0x100 * (port))
#define YT921X_MIBn_DATAm(port, x)      (YT921X_MIBn_DATA0(port) + 4 * (x))
#define  YT921X_MIB_DATA_RX_BROADCAST           0x00
#define  YT921X_MIB_DATA_RX_PAUSE               0x04
#define  YT921X_MIB_DATA_RX_MULTICAST           0x08
#define  YT921X_MIB_DATA_RX_CRC_ERR             0x0c

#define  YT921X_MIB_DATA_RX_ALIGN_ERR           0x10
#define  YT921X_MIB_DATA_RX_UNDERSIZE_ERR       0x14
#define  YT921X_MIB_DATA_RX_FRAG_ERR            0x18
#define  YT921X_MIB_DATA_RX_PKT_SZ_64           0x1c

#define  YT921X_MIB_DATA_RX_PKT_SZ_65_TO_127    0x20
#define  YT921X_MIB_DATA_RX_PKT_SZ_128_TO_255   0x24
#define  YT921X_MIB_DATA_RX_PKT_SZ_256_TO_511   0x28
#define  YT921X_MIB_DATA_RX_PKT_SZ_512_TO_1023  0x2c

#define  YT921X_MIB_DATA_RX_PKT_SZ_1024_TO_1518 0x30
#define  YT921X_MIB_DATA_RX_PKT_SZ_1519_TO_MAX  0x34
/* 0x38: unused */
#define  YT921X_MIB_DATA_RX_GOOD_BYTES          0x3c

/* 0x40: 64 bytes */
#define  YT921X_MIB_DATA_RX_BAD_BYTES           0x44
/* 0x48: 64 bytes */
#define  YT921X_MIB_DATA_RX_OVERSIZE_ERR        0x4c

#define  YT921X_MIB_DATA_RX_DROPPED             0x50
#define  YT921X_MIB_DATA_TX_BROADCAST           0x54
#define  YT921X_MIB_DATA_TX_PAUSE               0x58
#define  YT921X_MIB_DATA_TX_MULTICAST           0x5c

#define  YT921X_MIB_DATA_TX_UNDERSIZE_ERR       0x60
#define  YT921X_MIB_DATA_TX_PKT_SZ_64           0x64
#define  YT921X_MIB_DATA_TX_PKT_SZ_65_TO_127    0x68
#define  YT921X_MIB_DATA_TX_PKT_SZ_128_TO_255   0x6c

#define  YT921X_MIB_DATA_TX_PKT_SZ_256_TO_511   0x70
#define  YT921X_MIB_DATA_TX_PKT_SZ_512_TO_1023  0x74
#define  YT921X_MIB_DATA_TX_PKT_SZ_1024_TO_1518 0x78
#define  YT921X_MIB_DATA_TX_PKT_SZ_1519_TO_MAX  0x7c

/* 0x80: unused */
#define  YT921X_MIB_DATA_TX_GOOD_BYTES          0x84
/* 0x88: 64 bytes */
#define  YT921X_MIB_DATA_TX_COLLISION           0x8c

#define  YT921X_MIB_DATA_TX_EXCESSIVE_COLLISION 0x90
#define  YT921X_MIB_DATA_TX_MULTIPLE_COLLISION  0x94
#define  YT921X_MIB_DATA_TX_SINGLE_COLLISION    0x98
#define  YT921X_MIB_DATA_TX_PKT                 0x9c

#define  YT921X_MIB_DATA_TX_DEFERRED            0xa0
#define  YT921X_MIB_DATA_TX_LATE_COLLISION      0xa4
#define  YT921X_MIB_DATA_RX_OAM                 0xa8
#define  YT921X_MIB_DATA_TX_OAM                 0xac

#define YT921X_EDATA_CTRL               0xe0000
#define  YT921X_EDATA_CTRL_ADDR_M               GENMASK(15, 8)
#define   YT921X_EDATA_CTRL_ADDR(x)                     FIELD_PREP(YT921X_EDATA_CTRL_ADDR_M, (x))
#define  YT921X_EDATA_CTRL_OP_M                 GENMASK(3, 0)
#define   YT921X_EDATA_CTRL_OP(x)                       FIELD_PREP(YT921X_EDATA_CTRL_OP_M, (x))
#define   YT921X_EDATA_CTRL_READ                        YT921X_EDATA_CTRL_OP(5)
#define YT921X_EDATA_DATA               0xe0004
#define  YT921X_EDATA_DATA_DATA_M                       GENMASK(31, 24)
#define  YT921X_EDATA_DATA_STATUS_M             GENMASK(3, 0)
#define   YT921X_EDATA_DATA_STATUS(x)                   FIELD_PREP(YT921X_EDATA_DATA_STATUS_M, (x))
#define   YT921X_EDATA_DATA_IDLE                        YT921X_EDATA_DATA_STATUS(3)

#define YT921X_EXT_MBUS_OP              0x6a000
#define YT921X_INT_MBUS_OP              0xf0000
#define  YT921X_MBUS_OP_START                   BIT(0)
#define YT921X_EXT_MBUS_CTRL            0x6a004
#define YT921X_INT_MBUS_CTRL            0xf0004
#define  YT921X_MBUS_CTRL_PORT_M                GENMASK(25, 21)
#define   YT921X_MBUS_CTRL_PORT(x)                      FIELD_PREP(YT921X_MBUS_CTRL_PORT_M, (x))
#define  YT921X_MBUS_CTRL_REG_M                 GENMASK(20, 16)
#define   YT921X_MBUS_CTRL_REG(x)                       FIELD_PREP(YT921X_MBUS_CTRL_REG_M, (x))
#define  YT921X_MBUS_CTRL_TYPE_M                GENMASK(11, 8)  /* wild guess */
#define   YT921X_MBUS_CTRL_TYPE(x)                      FIELD_PREP(YT921X_MBUS_CTRL_TYPE_M, (x))
#define   YT921X_MBUS_CTRL_TYPE_C22                     YT921X_MBUS_CTRL_TYPE(4)
#define  YT921X_MBUS_CTRL_OP_M                  GENMASK(3, 2)  /* wild guess */
#define   YT921X_MBUS_CTRL_OP(x)                        FIELD_PREP(YT921X_MBUS_CTRL_OP_M, (x))
#define   YT921X_MBUS_CTRL_WRITE                        YT921X_MBUS_CTRL_OP(1)
#define   YT921X_MBUS_CTRL_READ                         YT921X_MBUS_CTRL_OP(2)
#define YT921X_EXT_MBUS_DOUT            0x6a008
#define YT921X_INT_MBUS_DOUT            0xf0008
#define YT921X_EXT_MBUS_DIN             0x6a00c
#define YT921X_INT_MBUS_DIN             0xf000c

#define YT921X_PORTn_EGR(port)          (0x100000 + 4 * (port))
#define  YT921X_PORT_EGR_TPID_CTAG_M            GENMASK(5, 4)
#define   YT921X_PORT_EGR_TPID_CTAG(x)                  FIELD_PREP(YT921X_PORT_EGR_TPID_CTAG_M, (x))
#define  YT921X_PORT_EGR_TPID_STAG_M            GENMASK(3, 2)
#define   YT921X_PORT_EGR_TPID_STAG(x)                  FIELD_PREP(YT921X_PORT_EGR_TPID_STAG_M, (x))
#define YT921X_TPID_EGRn(x)             (0x100300 + 4 * (x))    /* [0, 3] */
#define  YT921X_TPID_EGR_TPID_M                 GENMASK(15, 0)

#define YT921X_IPM_DSCPn(n)             (0x180000 + 4 * (n))    /* Internal Priority Map */
#define YT921X_IPM_PCPn(map, dei, pcp)  (0x180100 + 4 * (16 * (map) + 8 * (dei) + (pcp)))
#define  YT921X_IPM_PRIO_M                      GENMASK(4, 2)
#define   YT921X_IPM_PRIO(x)                            FIELD_PREP(YT921X_IPM_PRIO_M, (x))
#define  YT921X_IPM_COLOR_M                     GENMASK(1, 0)
#define   YT921X_IPM_COLOR(x)                           FIELD_PREP(YT921X_IPM_COLOR_M, (x))
#define   YT921X_IPM_COLOR_GREEN                        YT921X_IPM_COLOR(0)
#define   YT921X_IPM_COLOR_YELLOW                       YT921X_IPM_COLOR(1)
#define   YT921X_IPM_COLOR_RED                          YT921X_IPM_COLOR(2)
#define YT921X_PORTn_QOS(port)          (0x180180 + 4 * (port))
#define  YT921X_PORT_QOS_CVLAN_PRIO_MAP_ID      BIT(5)
#define  YT921X_PORT_QOS_SVLAN_PRIO_MAP_ID      BIT(4)
#define  YT921X_PORT_QOS_PRIO_M                 GENMASK(3, 1)
#define   YT921X_PORT_QOS_PRIO(x)                       FIELD_PREP(YT921X_PORT_QOS_PRIO_M, (x))
#define  YT921X_PORT_QOS_PRIO_EN                BIT(0)
#define YT921X_PORTn_PRIO_ORD(port)     (0x180200 + 4 * (port))
#define  YT921X_PORT_PRIO_ORD_APPm_M(m)         GENMASK(3 * (m) + 2, 3 * (m))
#define   YT921X_PORT_PRIO_ORD_APPm(m, x)               ((x) << (3 * (m)))      /* 0: disabled, except PORT_QOS_PRIO */

enum yt921x_app_selector {
        YT921X_APP_SEL_MAC_SA,
        YT921X_APP_SEL_MAC_DA,
        YT921X_APP_SEL_VID,
        YT921X_APP_SEL_ACL,
        YT921X_APP_SEL_DSCP,
        YT921X_APP_SEL_CVLAN_PCP,
        YT921X_APP_SEL_SVLAN_PCP,
        /* The physical port, i.e. YT921X_PORT_QOS_PRIO */
        YT921X_APP_SEL_PORT,
        YT921X_APP_SEL_NUM
};

#define YT921X_VLAN_IGR_FILTER          0x180280
#define  YT921X_VLAN_IGR_FILTER_PORTn_BYPASS_IGMP(port) BIT((port) + 11)
#define  YT921X_VLAN_IGR_FILTER_PORTn(port)     BIT(port)
#define YT921X_PORTn_ISOLATION(port)    (0x180294 + 4 * (port))
#define  YT921X_PORT_ISOLATION_BLOCKn(port)     BIT(port)
#define YT921X_STPn(n)                  (0x18038c + 4 * (n))
#define  YT921X_STP_PORTn_M(port)               GENMASK(2 * (port) + 1, 2 * (port))
#define   YT921X_STP_PORTn(port, x)                     ((x) << (2 * (port)))
#define   YT921X_STP_PORTn_DISABLED(port)               YT921X_STP_PORTn(port, 0)
#define   YT921X_STP_PORTn_LEARNING(port)               YT921X_STP_PORTn(port, 1)
#define   YT921X_STP_PORTn_BLOCKING(port)               YT921X_STP_PORTn(port, 2)
#define   YT921X_STP_PORTn_FORWARD(port)                YT921X_STP_PORTn(port, 3)
#define YT921X_PORTn_LEARN(port)        (0x1803d0 + 4 * (port))
#define  YT921X_PORT_LEARN_VID_LEARN_MULTI_EN   BIT(22)
#define  YT921X_PORT_LEARN_VID_LEARN_MODE       BIT(21)
#define  YT921X_PORT_LEARN_VID_LEARN_EN         BIT(20)
#define  YT921X_PORT_LEARN_SUSPEND_COPY_EN      BIT(19)
#define  YT921X_PORT_LEARN_SUSPEND_DROP_EN      BIT(18)
#define  YT921X_PORT_LEARN_DIS                  BIT(17)
#define  YT921X_PORT_LEARN_LIMIT_EN             BIT(16)
#define  YT921X_PORT_LEARN_LIMIT_M              GENMASK(15, 8)
#define   YT921X_PORT_LEARN_LIMIT(x)                    FIELD_PREP(YT921X_PORT_LEARN_LIMIT_M, (x))
#define  YT921X_PORT_LEARN_DROP_ON_EXCEEDED     BIT(2)
#define  YT921X_PORT_LEARN_MODE_M               GENMASK(1, 0)
#define   YT921X_PORT_LEARN_MODE(x)                     FIELD_PREP(YT921X_PORT_LEARN_MODE_M, (x))
#define   YT921X_PORT_LEARN_MODE_AUTO                   YT921X_PORT_LEARN_MODE(0)
#define   YT921X_PORT_LEARN_MODE_AUTO_AND_COPY          YT921X_PORT_LEARN_MODE(1)
#define   YT921X_PORT_LEARN_MODE_CPU_CONTROL            YT921X_PORT_LEARN_MODE(2)
#define YT921X_AGEING                   0x180440
#define  YT921X_AGEING_INTERVAL_M               GENMASK(15, 0)
#define YT921X_FDB_IN0                  0x180454
#define YT921X_FDB_IN1                  0x180458
#define YT921X_FDB_IN2                  0x18045c
#define YT921X_FDB_OP                   0x180460
#define  YT921X_FDB_OP_INDEX_M                  GENMASK(22, 11)
#define   YT921X_FDB_OP_INDEX(x)                        FIELD_PREP(YT921X_FDB_OP_INDEX_M, (x))
#define  YT921X_FDB_OP_MODE_INDEX               BIT(10)  /* mac+fid / index */
#define  YT921X_FDB_OP_FLUSH_MCAST              BIT(9)  /* ucast / mcast */
#define  YT921X_FDB_OP_FLUSH_M                  GENMASK(8, 7)
#define   YT921X_FDB_OP_FLUSH(x)                        FIELD_PREP(YT921X_FDB_OP_FLUSH_M, (x))
#define   YT921X_FDB_OP_FLUSH_ALL                       YT921X_FDB_OP_FLUSH(0)
#define   YT921X_FDB_OP_FLUSH_PORT                      YT921X_FDB_OP_FLUSH(1)
#define   YT921X_FDB_OP_FLUSH_PORT_VID                  YT921X_FDB_OP_FLUSH(2)
#define   YT921X_FDB_OP_FLUSH_VID                       YT921X_FDB_OP_FLUSH(3)
#define  YT921X_FDB_OP_FLUSH_STATIC             BIT(6)
#define  YT921X_FDB_OP_NEXT_TYPE_M              GENMASK(5, 4)
#define   YT921X_FDB_OP_NEXT_TYPE(x)                    FIELD_PREP(YT921X_FDB_OP_NEXT_TYPE_M, (x))
#define   YT921X_FDB_OP_NEXT_TYPE_UCAST_PORT            YT921X_FDB_OP_NEXT_TYPE(0)
#define   YT921X_FDB_OP_NEXT_TYPE_UCAST_VID             YT921X_FDB_OP_NEXT_TYPE(1)
#define   YT921X_FDB_OP_NEXT_TYPE_UCAST                 YT921X_FDB_OP_NEXT_TYPE(2)
#define   YT921X_FDB_OP_NEXT_TYPE_MCAST                 YT921X_FDB_OP_NEXT_TYPE(3)
#define  YT921X_FDB_OP_OP_M                     GENMASK(3, 1)
#define   YT921X_FDB_OP_OP(x)                           FIELD_PREP(YT921X_FDB_OP_OP_M, (x))
#define   YT921X_FDB_OP_OP_ADD                          YT921X_FDB_OP_OP(0)
#define   YT921X_FDB_OP_OP_DEL                          YT921X_FDB_OP_OP(1)
#define   YT921X_FDB_OP_OP_GET_ONE                      YT921X_FDB_OP_OP(2)
#define   YT921X_FDB_OP_OP_GET_NEXT                     YT921X_FDB_OP_OP(3)
#define   YT921X_FDB_OP_OP_FLUSH                        YT921X_FDB_OP_OP(4)
#define  YT921X_FDB_OP_START                    BIT(0)
#define YT921X_FDB_RESULT               0x180464
#define  YT921X_FDB_RESULT_DONE                 BIT(15)
#define  YT921X_FDB_RESULT_NOTFOUND             BIT(14)
#define  YT921X_FDB_RESULT_OVERWRITED           BIT(13)
#define  YT921X_FDB_RESULT_INDEX_M              GENMASK(11, 0)
#define   YT921X_FDB_RESULT_INDEX(x)                    FIELD_PREP(YT921X_FDB_RESULT_INDEX_M, (x))
#define YT921X_FDB_OUT0                 0x1804b0
#define  YT921X_FDB_IO0_ADDR_HI4_M              GENMASK(31, 0)
#define YT921X_FDB_OUT1                 0x1804b4
#define  YT921X_FDB_IO1_EGR_PRIO_EN             BIT(31)
#define  YT921X_FDB_IO1_STATUS_M                GENMASK(30, 28)
#define   YT921X_FDB_IO1_STATUS(x)                      FIELD_PREP(YT921X_FDB_IO1_STATUS_M, (x))
#define   YT921X_FDB_IO1_STATUS_INVALID                 YT921X_FDB_IO1_STATUS(0)
#define   YT921X_FDB_IO1_STATUS_MIN_TIME                YT921X_FDB_IO1_STATUS(1)
#define   YT921X_FDB_IO1_STATUS_MOVE_AGING_MAX_TIME     YT921X_FDB_IO1_STATUS(3)
#define   YT921X_FDB_IO1_STATUS_MAX_TIME                YT921X_FDB_IO1_STATUS(5)
#define   YT921X_FDB_IO1_STATUS_PENDING                 YT921X_FDB_IO1_STATUS(6)
#define   YT921X_FDB_IO1_STATUS_STATIC                  YT921X_FDB_IO1_STATUS(7)
#define  YT921X_FDB_IO1_FID_M                   GENMASK(27, 16)  /* filtering ID (VID) */
#define   YT921X_FDB_IO1_FID(x)                         FIELD_PREP(YT921X_FDB_IO1_FID_M, (x))
#define  YT921X_FDB_IO1_ADDR_LO2_M              GENMASK(15, 0)
#define YT921X_FDB_OUT2                 0x1804b8
#define  YT921X_FDB_IO2_MOVE_AGING_STATUS_M     GENMASK(31, 30)
#define  YT921X_FDB_IO2_IGR_DROP                BIT(29)
#define  YT921X_FDB_IO2_EGR_PORTS_M             GENMASK(28, 18)
#define   YT921X_FDB_IO2_EGR_PORTS(x)                   FIELD_PREP(YT921X_FDB_IO2_EGR_PORTS_M, (x))
#define  YT921X_FDB_IO2_EGR_DROP                BIT(17)
#define  YT921X_FDB_IO2_COPY_TO_CPU             BIT(16)
#define  YT921X_FDB_IO2_IGR_PRIO_EN             BIT(15)
#define  YT921X_FDB_IO2_PRIO_M                  GENMASK(14, 12)
#define   YT921X_FDB_IO2_PRIO(x)                        FIELD_PREP(YT921X_FDB_IO2_PRIO_M, (x))
#define  YT921X_FDB_IO2_NEW_VID_M               GENMASK(11, 0)
#define   YT921X_FDB_IO2_NEW_VID(x)                     FIELD_PREP(YT921X_FDB_IO2_NEW_VID_M, (x))
#define YT921X_FILTER_UNK_UCAST         0x180508
#define YT921X_FILTER_UNK_MCAST         0x18050c
#define YT921X_FILTER_MCAST             0x180510
#define YT921X_FILTER_BCAST             0x180514
#define  YT921X_FILTER_PORTS_M                  GENMASK(10, 0)
#define   YT921X_FILTER_PORTS(x)                        FIELD_PREP(YT921X_FILTER_PORTS_M, (x))
#define  YT921X_FILTER_PORTn(port)              BIT(port)
#define YT921X_VLAN_EGR_FILTER          0x180598
#define  YT921X_VLAN_EGR_FILTER_PORTn(port)     BIT(port)
#define YT921X_LAG_GROUPn(n)            (0x1805a8 + 4 * (n))
#define  YT921X_LAG_GROUP_PORTS_M               GENMASK(13, 3)
#define   YT921X_LAG_GROUP_PORTS(x)                     FIELD_PREP(YT921X_LAG_GROUP_PORTS_M, (x))
#define  YT921X_LAG_GROUP_MEMBER_NUM_M          GENMASK(2, 0)
#define   YT921X_LAG_GROUP_MEMBER_NUM(x)                FIELD_PREP(YT921X_LAG_GROUP_MEMBER_NUM_M, (x))
#define YT921X_LAG_MEMBERnm(n, m)       (0x1805b0 + 4 * (4 * (n) + (m)))
#define  YT921X_LAG_MEMBER_PORT_M               GENMASK(3, 0)
#define   YT921X_LAG_MEMBER_PORT(x)                     FIELD_PREP(YT921X_LAG_MEMBER_PORT_M, (x))
#define YT921X_CPU_COPY                 0x180690
#define  YT921X_CPU_COPY_FORCE_INT_PORT         BIT(2)
#define  YT921X_CPU_COPY_TO_INT_CPU             BIT(1)
#define  YT921X_CPU_COPY_TO_EXT_CPU             BIT(0)
#define YT921X_ACT_UNK_UCAST            0x180734
#define YT921X_ACT_UNK_MCAST            0x180738
#define  YT921X_ACT_UNK_MCAST_BYPASS_DROP_RMA   BIT(23)
#define  YT921X_ACT_UNK_MCAST_BYPASS_DROP_IGMP  BIT(22)
#define  YT921X_ACT_UNK_ACTn_M(port)            GENMASK(2 * (port) + 1, 2 * (port))
#define   YT921X_ACT_UNK_ACTn(port, x)                  ((x) << (2 * (port)))
#define   YT921X_ACT_UNK_ACTn_FORWARD(port)             YT921X_ACT_UNK_ACTn(port, 0)  /* flood */
#define   YT921X_ACT_UNK_ACTn_TRAP(port)                YT921X_ACT_UNK_ACTn(port, 1)  /* steer to CPU */
#define   YT921X_ACT_UNK_ACTn_DROP(port)                YT921X_ACT_UNK_ACTn(port, 2)  /* discard */
/* NEVER use this action; see comments in the tag driver */
#define   YT921X_ACT_UNK_ACTn_COPY(port)                YT921X_ACT_UNK_ACTn(port, 3)  /* flood and copy */
#define YT921X_FDB_HW_FLUSH             0x180958
#define  YT921X_FDB_HW_FLUSH_ON_LINKDOWN        BIT(0)

#define YT921X_VLANn_CTRL(vlan)         (0x188000 + 8 * (vlan))
#define  YT921X_VLAN_CTRL_UNTAG_PORTS_M         GENMASK_ULL(50, 40)
#define   YT921X_VLAN_CTRL_UNTAG_PORTS(x)               FIELD_PREP(YT921X_VLAN_CTRL_UNTAG_PORTS_M, (x))
#define  YT921X_VLAN_CTRL_UNTAG_PORTn(port)     BIT_ULL((port) + 40)
#define  YT921X_VLAN_CTRL_STP_ID_M              GENMASK_ULL(39, 36)
#define   YT921X_VLAN_CTRL_STP_ID(x)                    FIELD_PREP(YT921X_VLAN_CTRL_STP_ID_M, (x))
#define  YT921X_VLAN_CTRL_SVLAN_EN              BIT_ULL(35)
#define  YT921X_VLAN_CTRL_FID_M                 GENMASK_ULL(34, 23)
#define   YT921X_VLAN_CTRL_FID(x)                       FIELD_PREP(YT921X_VLAN_CTRL_FID_M, (x))
#define  YT921X_VLAN_CTRL_LEARN_DIS             BIT_ULL(22)
#define  YT921X_VLAN_CTRL_PRIO_EN               BIT_ULL(21)
#define  YT921X_VLAN_CTRL_PRIO_M                GENMASK_ULL(20, 18)
#define   YT921X_VLAN_CTRL_PRIO(x)                      FIELD_PREP(YT921X_VLAN_CTRL_PRIO_M, (x))
#define  YT921X_VLAN_CTRL_PORTS_M               GENMASK_ULL(17, 7)
#define   YT921X_VLAN_CTRL_PORTS(x)                     FIELD_PREP(YT921X_VLAN_CTRL_PORTS_M, (x))
#define  YT921X_VLAN_CTRL_PORTn(port)           BIT_ULL((port) + 7)
#define  YT921X_VLAN_CTRL_BYPASS_1X_AC          BIT_ULL(6)
#define  YT921X_VLAN_CTRL_METER_EN              BIT_ULL(5)
#define  YT921X_VLAN_CTRL_METER_ID_M            GENMASK_ULL(4, 0)

#define YT921X_TPID_IGRn(x)             (0x210000 + 4 * (x))    /* [0, 3] */
#define  YT921X_TPID_IGR_TPID_M                 GENMASK(15, 0)
#define YT921X_PORTn_IGR_TPID(port)     (0x210010 + 4 * (port))
#define  YT921X_PORT_IGR_TPIDn_STAG_M           GENMASK(7, 4)
#define  YT921X_PORT_IGR_TPIDn_STAG(x)          BIT((x) + 4)
#define  YT921X_PORT_IGR_TPIDn_CTAG_M           GENMASK(3, 0)
#define  YT921X_PORT_IGR_TPIDn_CTAG(x)          BIT(x)
#define YT921X_LAG_HASH                 0x210090
#define  YT921X_LAG_HASH_L4_SPORT               BIT(7)
#define  YT921X_LAG_HASH_L4_DPORT               BIT(6)
#define  YT921X_LAG_HASH_IP_PROTO               BIT(5)
#define  YT921X_LAG_HASH_IP_SRC                 BIT(4)
#define  YT921X_LAG_HASH_IP_DST                 BIT(3)
#define  YT921X_LAG_HASH_MAC_SA                 BIT(2)
#define  YT921X_LAG_HASH_MAC_DA                 BIT(1)
#define  YT921X_LAG_HASH_SRC_PORT               BIT(0)

#define YT921X_PORTn_VLAN_CTRL(port)    (0x230010 + 4 * (port))
#define  YT921X_PORT_VLAN_CTRL_SVLAN_PRIO_EN    BIT(31)
#define  YT921X_PORT_VLAN_CTRL_CVLAN_PRIO_EN    BIT(30)
#define  YT921X_PORT_VLAN_CTRL_SVID_M           GENMASK(29, 18)
#define   YT921X_PORT_VLAN_CTRL_SVID(x)                 FIELD_PREP(YT921X_PORT_VLAN_CTRL_SVID_M, (x))
#define  YT921X_PORT_VLAN_CTRL_CVID_M           GENMASK(17, 6)
#define   YT921X_PORT_VLAN_CTRL_CVID(x)                 FIELD_PREP(YT921X_PORT_VLAN_CTRL_CVID_M, (x))
#define  YT921X_PORT_VLAN_CTRL_SVLAN_PRIO_M     GENMASK(5, 3)
#define  YT921X_PORT_VLAN_CTRL_CVLAN_PRIO_M     GENMASK(2, 0)
#define YT921X_PORTn_VLAN_CTRL1(port)   (0x230080 + 4 * (port))
#define  YT921X_PORT_VLAN_CTRL1_VLAN_RANGE_EN   BIT(8)
#define  YT921X_PORT_VLAN_CTRL1_VLAN_RANGE_PROFILE_ID_M GENMASK(7, 4)
#define  YT921X_PORT_VLAN_CTRL1_SVLAN_DROP_TAGGED       BIT(3)
#define  YT921X_PORT_VLAN_CTRL1_SVLAN_DROP_UNTAGGED     BIT(2)
#define  YT921X_PORT_VLAN_CTRL1_CVLAN_DROP_TAGGED       BIT(1)
#define  YT921X_PORT_VLAN_CTRL1_CVLAN_DROP_UNTAGGED     BIT(0)

#define YT921X_MIRROR                   0x300300
#define  YT921X_MIRROR_IGR_PORTS_M              GENMASK(26, 16)
#define   YT921X_MIRROR_IGR_PORTS(x)                    FIELD_PREP(YT921X_MIRROR_IGR_PORTS_M, (x))
#define  YT921X_MIRROR_IGR_PORTn(port)          BIT((port) + 16)
#define  YT921X_MIRROR_EGR_PORTS_M              GENMASK(14, 4)
#define   YT921X_MIRROR_EGR_PORTS(x)                    FIELD_PREP(YT921X_MIRROR_EGR_PORTS_M, (x))
#define  YT921X_MIRROR_EGR_PORTn(port)          BIT((port) + 4)
#define  YT921X_MIRROR_PORT_M                   GENMASK(3, 0)
#define   YT921X_MIRROR_PORT(x)                         FIELD_PREP(YT921X_MIRROR_PORT_M, (x))

#define YT921X_EDATA_EXTMODE    0xfb
#define YT921X_EDATA_LEN        0x100

#define YT921X_FDB_NUM  4096

enum yt921x_fdb_entry_status {
        YT921X_FDB_ENTRY_STATUS_INVALID = 0,
        YT921X_FDB_ENTRY_STATUS_MIN_TIME = 1,
        YT921X_FDB_ENTRY_STATUS_MOVE_AGING_MAX_TIME = 3,
        YT921X_FDB_ENTRY_STATUS_MAX_TIME = 5,
        YT921X_FDB_ENTRY_STATUS_PENDING = 6,
        YT921X_FDB_ENTRY_STATUS_STATIC = 7,
};

#define YT921X_MSTI_NUM         16

#define YT921X_LAG_NUM          2
#define YT921X_LAG_PORT_NUM     4

#define YT921X_PRIO_NUM 8

#define YT9215_MAJOR    0x9002
#define YT9218_MAJOR    0x9001

/* required for a hard reset */
#define YT921X_RST_DELAY_US     10000

#define YT921X_FRAME_SIZE_MAX   0x2400  /* 9216 */

#define YT921X_TAG_LEN  8

/* 8 internal + 2 external + 1 mcu */
#define YT921X_PORT_NUM                 11

#define yt921x_port_is_internal(port) ((port) < 8)
#define yt921x_port_is_external(port) (8 <= (port) && (port) < 9)

struct yt921x_mib {
        u64 rx_broadcast;
        u64 rx_pause;
        u64 rx_multicast;
        u64 rx_crc_errors;

        u64 rx_alignment_errors;
        u64 rx_undersize_errors;
        u64 rx_fragment_errors;
        u64 rx_64byte;

        u64 rx_65_127byte;
        u64 rx_128_255byte;
        u64 rx_256_511byte;
        u64 rx_512_1023byte;

        u64 rx_1024_1518byte;
        u64 rx_jumbo;
        u64 rx_good_bytes;

        u64 rx_bad_bytes;
        u64 rx_oversize_errors;

        u64 rx_dropped;
        u64 tx_broadcast;
        u64 tx_pause;
        u64 tx_multicast;

        u64 tx_undersize_errors;
        u64 tx_64byte;
        u64 tx_65_127byte;
        u64 tx_128_255byte;

        u64 tx_256_511byte;
        u64 tx_512_1023byte;
        u64 tx_1024_1518byte;
        u64 tx_jumbo;

        u64 tx_good_bytes;
        u64 tx_collisions;

        u64 tx_aborted_errors;
        u64 tx_multiple_collisions;
        u64 tx_single_collisions;
        u64 tx_good;

        u64 tx_deferred;
        u64 tx_late_collisions;
        u64 rx_oam;
        u64 tx_oam;
};

struct yt921x_port {
        unsigned char index;

        bool hairpin;
        bool isolated;

        struct delayed_work mib_read;
        struct yt921x_mib mib;
        u64 rx_frames;
        u64 tx_frames;
};

struct yt921x_reg_ops {
        int (*read)(void *context, u32 reg, u32 *valp);
        int (*write)(void *context, u32 reg, u32 val);
};

struct yt921x_priv {
        struct dsa_switch ds;

        const struct yt921x_info *info;
        /* cache of dsa_cpu_ports(ds) */
        u16 cpu_ports_mask;

        /* protect the access to the switch registers */
        struct mutex reg_lock;
        const struct yt921x_reg_ops *reg_ops;
        void *reg_ctx;

        /* mdio master bus */
        struct mii_bus *mbus_int;
        struct mii_bus *mbus_ext;

        struct yt921x_port ports[YT921X_PORT_NUM];

        u16 eee_ports_mask;
};

#endif