linux/drivers/net/dsa/ocelot/seville_vsc9953.c
<<
>>
Prefs
   1// SPDX-License-Identifier: (GPL-2.0 OR MIT)
   2/* Distributed Switch Architecture VSC9953 driver
   3 * Copyright (C) 2020, Maxim Kochetkov <fido_max@inbox.ru>
   4 */
   5#include <linux/types.h>
   6#include <soc/mscc/ocelot_vcap.h>
   7#include <soc/mscc/ocelot_sys.h>
   8#include <soc/mscc/ocelot.h>
   9#include <linux/of_platform.h>
  10#include <linux/pcs-lynx.h>
  11#include <linux/dsa/ocelot.h>
  12#include <linux/iopoll.h>
  13#include "felix.h"
  14
  15#define MSCC_MIIM_CMD_OPR_WRITE                 BIT(1)
  16#define MSCC_MIIM_CMD_OPR_READ                  BIT(2)
  17#define MSCC_MIIM_CMD_WRDATA_SHIFT              4
  18#define MSCC_MIIM_CMD_REGAD_SHIFT               20
  19#define MSCC_MIIM_CMD_PHYAD_SHIFT               25
  20#define MSCC_MIIM_CMD_VLD                       BIT(31)
  21
  22static const u32 vsc9953_ana_regmap[] = {
  23        REG(ANA_ADVLEARN,                       0x00b500),
  24        REG(ANA_VLANMASK,                       0x00b504),
  25        REG_RESERVED(ANA_PORT_B_DOMAIN),
  26        REG(ANA_ANAGEFIL,                       0x00b50c),
  27        REG(ANA_ANEVENTS,                       0x00b510),
  28        REG(ANA_STORMLIMIT_BURST,               0x00b514),
  29        REG(ANA_STORMLIMIT_CFG,                 0x00b518),
  30        REG(ANA_ISOLATED_PORTS,                 0x00b528),
  31        REG(ANA_COMMUNITY_PORTS,                0x00b52c),
  32        REG(ANA_AUTOAGE,                        0x00b530),
  33        REG(ANA_MACTOPTIONS,                    0x00b534),
  34        REG(ANA_LEARNDISC,                      0x00b538),
  35        REG(ANA_AGENCTRL,                       0x00b53c),
  36        REG(ANA_MIRRORPORTS,                    0x00b540),
  37        REG(ANA_EMIRRORPORTS,                   0x00b544),
  38        REG(ANA_FLOODING,                       0x00b548),
  39        REG(ANA_FLOODING_IPMC,                  0x00b54c),
  40        REG(ANA_SFLOW_CFG,                      0x00b550),
  41        REG(ANA_PORT_MODE,                      0x00b57c),
  42        REG_RESERVED(ANA_CUT_THRU_CFG),
  43        REG(ANA_PGID_PGID,                      0x00b600),
  44        REG(ANA_TABLES_ANMOVED,                 0x00b4ac),
  45        REG(ANA_TABLES_MACHDATA,                0x00b4b0),
  46        REG(ANA_TABLES_MACLDATA,                0x00b4b4),
  47        REG_RESERVED(ANA_TABLES_STREAMDATA),
  48        REG(ANA_TABLES_MACACCESS,               0x00b4b8),
  49        REG(ANA_TABLES_MACTINDX,                0x00b4bc),
  50        REG(ANA_TABLES_VLANACCESS,              0x00b4c0),
  51        REG(ANA_TABLES_VLANTIDX,                0x00b4c4),
  52        REG_RESERVED(ANA_TABLES_ISDXACCESS),
  53        REG_RESERVED(ANA_TABLES_ISDXTIDX),
  54        REG(ANA_TABLES_ENTRYLIM,                0x00b480),
  55        REG_RESERVED(ANA_TABLES_PTP_ID_HIGH),
  56        REG_RESERVED(ANA_TABLES_PTP_ID_LOW),
  57        REG_RESERVED(ANA_TABLES_STREAMACCESS),
  58        REG_RESERVED(ANA_TABLES_STREAMTIDX),
  59        REG_RESERVED(ANA_TABLES_SEQ_HISTORY),
  60        REG_RESERVED(ANA_TABLES_SEQ_MASK),
  61        REG_RESERVED(ANA_TABLES_SFID_MASK),
  62        REG_RESERVED(ANA_TABLES_SFIDACCESS),
  63        REG_RESERVED(ANA_TABLES_SFIDTIDX),
  64        REG_RESERVED(ANA_MSTI_STATE),
  65        REG_RESERVED(ANA_OAM_UPM_LM_CNT),
  66        REG_RESERVED(ANA_SG_ACCESS_CTRL),
  67        REG_RESERVED(ANA_SG_CONFIG_REG_1),
  68        REG_RESERVED(ANA_SG_CONFIG_REG_2),
  69        REG_RESERVED(ANA_SG_CONFIG_REG_3),
  70        REG_RESERVED(ANA_SG_CONFIG_REG_4),
  71        REG_RESERVED(ANA_SG_CONFIG_REG_5),
  72        REG_RESERVED(ANA_SG_GCL_GS_CONFIG),
  73        REG_RESERVED(ANA_SG_GCL_TI_CONFIG),
  74        REG_RESERVED(ANA_SG_STATUS_REG_1),
  75        REG_RESERVED(ANA_SG_STATUS_REG_2),
  76        REG_RESERVED(ANA_SG_STATUS_REG_3),
  77        REG(ANA_PORT_VLAN_CFG,                  0x000000),
  78        REG(ANA_PORT_DROP_CFG,                  0x000004),
  79        REG(ANA_PORT_QOS_CFG,                   0x000008),
  80        REG(ANA_PORT_VCAP_CFG,                  0x00000c),
  81        REG(ANA_PORT_VCAP_S1_KEY_CFG,           0x000010),
  82        REG(ANA_PORT_VCAP_S2_CFG,               0x00001c),
  83        REG(ANA_PORT_PCP_DEI_MAP,               0x000020),
  84        REG(ANA_PORT_CPU_FWD_CFG,               0x000060),
  85        REG(ANA_PORT_CPU_FWD_BPDU_CFG,          0x000064),
  86        REG(ANA_PORT_CPU_FWD_GARP_CFG,          0x000068),
  87        REG(ANA_PORT_CPU_FWD_CCM_CFG,           0x00006c),
  88        REG(ANA_PORT_PORT_CFG,                  0x000070),
  89        REG(ANA_PORT_POL_CFG,                   0x000074),
  90        REG_RESERVED(ANA_PORT_PTP_CFG),
  91        REG_RESERVED(ANA_PORT_PTP_DLY1_CFG),
  92        REG_RESERVED(ANA_PORT_PTP_DLY2_CFG),
  93        REG_RESERVED(ANA_PORT_SFID_CFG),
  94        REG(ANA_PFC_PFC_CFG,                    0x00c000),
  95        REG_RESERVED(ANA_PFC_PFC_TIMER),
  96        REG_RESERVED(ANA_IPT_OAM_MEP_CFG),
  97        REG_RESERVED(ANA_IPT_IPT),
  98        REG_RESERVED(ANA_PPT_PPT),
  99        REG_RESERVED(ANA_FID_MAP_FID_MAP),
 100        REG(ANA_AGGR_CFG,                       0x00c600),
 101        REG(ANA_CPUQ_CFG,                       0x00c604),
 102        REG_RESERVED(ANA_CPUQ_CFG2),
 103        REG(ANA_CPUQ_8021_CFG,                  0x00c60c),
 104        REG(ANA_DSCP_CFG,                       0x00c64c),
 105        REG(ANA_DSCP_REWR_CFG,                  0x00c74c),
 106        REG(ANA_VCAP_RNG_TYPE_CFG,              0x00c78c),
 107        REG(ANA_VCAP_RNG_VAL_CFG,               0x00c7ac),
 108        REG_RESERVED(ANA_VRAP_CFG),
 109        REG_RESERVED(ANA_VRAP_HDR_DATA),
 110        REG_RESERVED(ANA_VRAP_HDR_MASK),
 111        REG(ANA_DISCARD_CFG,                    0x00c7d8),
 112        REG(ANA_FID_CFG,                        0x00c7dc),
 113        REG(ANA_POL_PIR_CFG,                    0x00a000),
 114        REG(ANA_POL_CIR_CFG,                    0x00a004),
 115        REG(ANA_POL_MODE_CFG,                   0x00a008),
 116        REG(ANA_POL_PIR_STATE,                  0x00a00c),
 117        REG(ANA_POL_CIR_STATE,                  0x00a010),
 118        REG_RESERVED(ANA_POL_STATE),
 119        REG(ANA_POL_FLOWC,                      0x00c280),
 120        REG(ANA_POL_HYST,                       0x00c2ec),
 121        REG_RESERVED(ANA_POL_MISC_CFG),
 122};
 123
 124static const u32 vsc9953_qs_regmap[] = {
 125        REG(QS_XTR_GRP_CFG,                     0x000000),
 126        REG(QS_XTR_RD,                          0x000008),
 127        REG(QS_XTR_FRM_PRUNING,                 0x000010),
 128        REG(QS_XTR_FLUSH,                       0x000018),
 129        REG(QS_XTR_DATA_PRESENT,                0x00001c),
 130        REG(QS_XTR_CFG,                         0x000020),
 131        REG(QS_INJ_GRP_CFG,                     0x000024),
 132        REG(QS_INJ_WR,                          0x00002c),
 133        REG(QS_INJ_CTRL,                        0x000034),
 134        REG(QS_INJ_STATUS,                      0x00003c),
 135        REG(QS_INJ_ERR,                         0x000040),
 136        REG_RESERVED(QS_INH_DBG),
 137};
 138
 139static const u32 vsc9953_vcap_regmap[] = {
 140        /* VCAP_CORE_CFG */
 141        REG(VCAP_CORE_UPDATE_CTRL,              0x000000),
 142        REG(VCAP_CORE_MV_CFG,                   0x000004),
 143        /* VCAP_CORE_CACHE */
 144        REG(VCAP_CACHE_ENTRY_DAT,               0x000008),
 145        REG(VCAP_CACHE_MASK_DAT,                0x000108),
 146        REG(VCAP_CACHE_ACTION_DAT,              0x000208),
 147        REG(VCAP_CACHE_CNT_DAT,                 0x000308),
 148        REG(VCAP_CACHE_TG_DAT,                  0x000388),
 149        /* VCAP_CONST */
 150        REG(VCAP_CONST_VCAP_VER,                0x000398),
 151        REG(VCAP_CONST_ENTRY_WIDTH,             0x00039c),
 152        REG(VCAP_CONST_ENTRY_CNT,               0x0003a0),
 153        REG(VCAP_CONST_ENTRY_SWCNT,             0x0003a4),
 154        REG(VCAP_CONST_ENTRY_TG_WIDTH,          0x0003a8),
 155        REG(VCAP_CONST_ACTION_DEF_CNT,          0x0003ac),
 156        REG(VCAP_CONST_ACTION_WIDTH,            0x0003b0),
 157        REG(VCAP_CONST_CNT_WIDTH,               0x0003b4),
 158        REG_RESERVED(VCAP_CONST_CORE_CNT),
 159        REG_RESERVED(VCAP_CONST_IF_CNT),
 160};
 161
 162static const u32 vsc9953_qsys_regmap[] = {
 163        REG(QSYS_PORT_MODE,                     0x003600),
 164        REG(QSYS_SWITCH_PORT_MODE,              0x003630),
 165        REG(QSYS_STAT_CNT_CFG,                  0x00365c),
 166        REG(QSYS_EEE_CFG,                       0x003660),
 167        REG(QSYS_EEE_THRES,                     0x003688),
 168        REG(QSYS_IGR_NO_SHARING,                0x00368c),
 169        REG(QSYS_EGR_NO_SHARING,                0x003690),
 170        REG(QSYS_SW_STATUS,                     0x003694),
 171        REG(QSYS_EXT_CPU_CFG,                   0x0036c0),
 172        REG_RESERVED(QSYS_PAD_CFG),
 173        REG(QSYS_CPU_GROUP_MAP,                 0x0036c8),
 174        REG_RESERVED(QSYS_QMAP),
 175        REG_RESERVED(QSYS_ISDX_SGRP),
 176        REG_RESERVED(QSYS_TIMED_FRAME_ENTRY),
 177        REG_RESERVED(QSYS_TFRM_MISC),
 178        REG_RESERVED(QSYS_TFRM_PORT_DLY),
 179        REG_RESERVED(QSYS_TFRM_TIMER_CFG_1),
 180        REG_RESERVED(QSYS_TFRM_TIMER_CFG_2),
 181        REG_RESERVED(QSYS_TFRM_TIMER_CFG_3),
 182        REG_RESERVED(QSYS_TFRM_TIMER_CFG_4),
 183        REG_RESERVED(QSYS_TFRM_TIMER_CFG_5),
 184        REG_RESERVED(QSYS_TFRM_TIMER_CFG_6),
 185        REG_RESERVED(QSYS_TFRM_TIMER_CFG_7),
 186        REG_RESERVED(QSYS_TFRM_TIMER_CFG_8),
 187        REG(QSYS_RED_PROFILE,                   0x003724),
 188        REG(QSYS_RES_QOS_MODE,                  0x003764),
 189        REG(QSYS_RES_CFG,                       0x004000),
 190        REG(QSYS_RES_STAT,                      0x004004),
 191        REG(QSYS_EGR_DROP_MODE,                 0x003768),
 192        REG(QSYS_EQ_CTRL,                       0x00376c),
 193        REG_RESERVED(QSYS_EVENTS_CORE),
 194        REG_RESERVED(QSYS_QMAXSDU_CFG_0),
 195        REG_RESERVED(QSYS_QMAXSDU_CFG_1),
 196        REG_RESERVED(QSYS_QMAXSDU_CFG_2),
 197        REG_RESERVED(QSYS_QMAXSDU_CFG_3),
 198        REG_RESERVED(QSYS_QMAXSDU_CFG_4),
 199        REG_RESERVED(QSYS_QMAXSDU_CFG_5),
 200        REG_RESERVED(QSYS_QMAXSDU_CFG_6),
 201        REG_RESERVED(QSYS_QMAXSDU_CFG_7),
 202        REG_RESERVED(QSYS_PREEMPTION_CFG),
 203        REG(QSYS_CIR_CFG,                       0x000000),
 204        REG_RESERVED(QSYS_EIR_CFG),
 205        REG(QSYS_SE_CFG,                        0x000008),
 206        REG(QSYS_SE_DWRR_CFG,                   0x00000c),
 207        REG_RESERVED(QSYS_SE_CONNECT),
 208        REG_RESERVED(QSYS_SE_DLB_SENSE),
 209        REG(QSYS_CIR_STATE,                     0x000044),
 210        REG_RESERVED(QSYS_EIR_STATE),
 211        REG_RESERVED(QSYS_SE_STATE),
 212        REG(QSYS_HSCH_MISC_CFG,                 0x003774),
 213        REG_RESERVED(QSYS_TAG_CONFIG),
 214        REG_RESERVED(QSYS_TAS_PARAM_CFG_CTRL),
 215        REG_RESERVED(QSYS_PORT_MAX_SDU),
 216        REG_RESERVED(QSYS_PARAM_CFG_REG_1),
 217        REG_RESERVED(QSYS_PARAM_CFG_REG_2),
 218        REG_RESERVED(QSYS_PARAM_CFG_REG_3),
 219        REG_RESERVED(QSYS_PARAM_CFG_REG_4),
 220        REG_RESERVED(QSYS_PARAM_CFG_REG_5),
 221        REG_RESERVED(QSYS_GCL_CFG_REG_1),
 222        REG_RESERVED(QSYS_GCL_CFG_REG_2),
 223        REG_RESERVED(QSYS_PARAM_STATUS_REG_1),
 224        REG_RESERVED(QSYS_PARAM_STATUS_REG_2),
 225        REG_RESERVED(QSYS_PARAM_STATUS_REG_3),
 226        REG_RESERVED(QSYS_PARAM_STATUS_REG_4),
 227        REG_RESERVED(QSYS_PARAM_STATUS_REG_5),
 228        REG_RESERVED(QSYS_PARAM_STATUS_REG_6),
 229        REG_RESERVED(QSYS_PARAM_STATUS_REG_7),
 230        REG_RESERVED(QSYS_PARAM_STATUS_REG_8),
 231        REG_RESERVED(QSYS_PARAM_STATUS_REG_9),
 232        REG_RESERVED(QSYS_GCL_STATUS_REG_1),
 233        REG_RESERVED(QSYS_GCL_STATUS_REG_2),
 234};
 235
 236static const u32 vsc9953_rew_regmap[] = {
 237        REG(REW_PORT_VLAN_CFG,                  0x000000),
 238        REG(REW_TAG_CFG,                        0x000004),
 239        REG(REW_PORT_CFG,                       0x000008),
 240        REG(REW_DSCP_CFG,                       0x00000c),
 241        REG(REW_PCP_DEI_QOS_MAP_CFG,            0x000010),
 242        REG_RESERVED(REW_PTP_CFG),
 243        REG_RESERVED(REW_PTP_DLY1_CFG),
 244        REG_RESERVED(REW_RED_TAG_CFG),
 245        REG(REW_DSCP_REMAP_DP1_CFG,             0x000610),
 246        REG(REW_DSCP_REMAP_CFG,                 0x000710),
 247        REG_RESERVED(REW_STAT_CFG),
 248        REG_RESERVED(REW_REW_STICKY),
 249        REG_RESERVED(REW_PPT),
 250};
 251
 252static const u32 vsc9953_sys_regmap[] = {
 253        REG(SYS_COUNT_RX_OCTETS,                0x000000),
 254        REG(SYS_COUNT_RX_MULTICAST,             0x000008),
 255        REG(SYS_COUNT_RX_SHORTS,                0x000010),
 256        REG(SYS_COUNT_RX_FRAGMENTS,             0x000014),
 257        REG(SYS_COUNT_RX_JABBERS,               0x000018),
 258        REG(SYS_COUNT_RX_64,                    0x000024),
 259        REG(SYS_COUNT_RX_65_127,                0x000028),
 260        REG(SYS_COUNT_RX_128_255,               0x00002c),
 261        REG(SYS_COUNT_RX_256_1023,              0x000030),
 262        REG(SYS_COUNT_RX_1024_1526,             0x000034),
 263        REG(SYS_COUNT_RX_1527_MAX,              0x000038),
 264        REG(SYS_COUNT_RX_LONGS,                 0x000048),
 265        REG(SYS_COUNT_TX_OCTETS,                0x000100),
 266        REG(SYS_COUNT_TX_COLLISION,             0x000110),
 267        REG(SYS_COUNT_TX_DROPS,                 0x000114),
 268        REG(SYS_COUNT_TX_64,                    0x00011c),
 269        REG(SYS_COUNT_TX_65_127,                0x000120),
 270        REG(SYS_COUNT_TX_128_511,               0x000124),
 271        REG(SYS_COUNT_TX_512_1023,              0x000128),
 272        REG(SYS_COUNT_TX_1024_1526,             0x00012c),
 273        REG(SYS_COUNT_TX_1527_MAX,              0x000130),
 274        REG(SYS_COUNT_TX_AGING,                 0x000178),
 275        REG(SYS_RESET_CFG,                      0x000318),
 276        REG_RESERVED(SYS_SR_ETYPE_CFG),
 277        REG(SYS_VLAN_ETYPE_CFG,                 0x000320),
 278        REG(SYS_PORT_MODE,                      0x000324),
 279        REG(SYS_FRONT_PORT_MODE,                0x000354),
 280        REG(SYS_FRM_AGING,                      0x00037c),
 281        REG(SYS_STAT_CFG,                       0x000380),
 282        REG_RESERVED(SYS_SW_STATUS),
 283        REG_RESERVED(SYS_MISC_CFG),
 284        REG_RESERVED(SYS_REW_MAC_HIGH_CFG),
 285        REG_RESERVED(SYS_REW_MAC_LOW_CFG),
 286        REG_RESERVED(SYS_TIMESTAMP_OFFSET),
 287        REG(SYS_PAUSE_CFG,                      0x00044c),
 288        REG(SYS_PAUSE_TOT_CFG,                  0x000478),
 289        REG(SYS_ATOP,                           0x00047c),
 290        REG(SYS_ATOP_TOT_CFG,                   0x0004a8),
 291        REG(SYS_MAC_FC_CFG,                     0x0004ac),
 292        REG(SYS_MMGT,                           0x0004d4),
 293        REG_RESERVED(SYS_MMGT_FAST),
 294        REG_RESERVED(SYS_EVENTS_DIF),
 295        REG_RESERVED(SYS_EVENTS_CORE),
 296        REG_RESERVED(SYS_CNT),
 297        REG_RESERVED(SYS_PTP_STATUS),
 298        REG_RESERVED(SYS_PTP_TXSTAMP),
 299        REG_RESERVED(SYS_PTP_NXT),
 300        REG_RESERVED(SYS_PTP_CFG),
 301        REG_RESERVED(SYS_RAM_INIT),
 302        REG_RESERVED(SYS_CM_ADDR),
 303        REG_RESERVED(SYS_CM_DATA_WR),
 304        REG_RESERVED(SYS_CM_DATA_RD),
 305        REG_RESERVED(SYS_CM_OP),
 306        REG_RESERVED(SYS_CM_DATA),
 307};
 308
 309static const u32 vsc9953_gcb_regmap[] = {
 310        REG(GCB_SOFT_RST,                       0x000008),
 311        REG(GCB_MIIM_MII_STATUS,                0x0000ac),
 312        REG(GCB_MIIM_MII_CMD,                   0x0000b4),
 313        REG(GCB_MIIM_MII_DATA,                  0x0000b8),
 314};
 315
 316static const u32 vsc9953_dev_gmii_regmap[] = {
 317        REG(DEV_CLOCK_CFG,                      0x0),
 318        REG(DEV_PORT_MISC,                      0x4),
 319        REG_RESERVED(DEV_EVENTS),
 320        REG(DEV_EEE_CFG,                        0xc),
 321        REG_RESERVED(DEV_RX_PATH_DELAY),
 322        REG_RESERVED(DEV_TX_PATH_DELAY),
 323        REG_RESERVED(DEV_PTP_PREDICT_CFG),
 324        REG(DEV_MAC_ENA_CFG,                    0x10),
 325        REG(DEV_MAC_MODE_CFG,                   0x14),
 326        REG(DEV_MAC_MAXLEN_CFG,                 0x18),
 327        REG(DEV_MAC_TAGS_CFG,                   0x1c),
 328        REG(DEV_MAC_ADV_CHK_CFG,                0x20),
 329        REG(DEV_MAC_IFG_CFG,                    0x24),
 330        REG(DEV_MAC_HDX_CFG,                    0x28),
 331        REG_RESERVED(DEV_MAC_DBG_CFG),
 332        REG(DEV_MAC_FC_MAC_LOW_CFG,             0x30),
 333        REG(DEV_MAC_FC_MAC_HIGH_CFG,            0x34),
 334        REG(DEV_MAC_STICKY,                     0x38),
 335        REG_RESERVED(PCS1G_CFG),
 336        REG_RESERVED(PCS1G_MODE_CFG),
 337        REG_RESERVED(PCS1G_SD_CFG),
 338        REG_RESERVED(PCS1G_ANEG_CFG),
 339        REG_RESERVED(PCS1G_ANEG_NP_CFG),
 340        REG_RESERVED(PCS1G_LB_CFG),
 341        REG_RESERVED(PCS1G_DBG_CFG),
 342        REG_RESERVED(PCS1G_CDET_CFG),
 343        REG_RESERVED(PCS1G_ANEG_STATUS),
 344        REG_RESERVED(PCS1G_ANEG_NP_STATUS),
 345        REG_RESERVED(PCS1G_LINK_STATUS),
 346        REG_RESERVED(PCS1G_LINK_DOWN_CNT),
 347        REG_RESERVED(PCS1G_STICKY),
 348        REG_RESERVED(PCS1G_DEBUG_STATUS),
 349        REG_RESERVED(PCS1G_LPI_CFG),
 350        REG_RESERVED(PCS1G_LPI_WAKE_ERROR_CNT),
 351        REG_RESERVED(PCS1G_LPI_STATUS),
 352        REG_RESERVED(PCS1G_TSTPAT_MODE_CFG),
 353        REG_RESERVED(PCS1G_TSTPAT_STATUS),
 354        REG_RESERVED(DEV_PCS_FX100_CFG),
 355        REG_RESERVED(DEV_PCS_FX100_STATUS),
 356};
 357
 358static const u32 *vsc9953_regmap[TARGET_MAX] = {
 359        [ANA]           = vsc9953_ana_regmap,
 360        [QS]            = vsc9953_qs_regmap,
 361        [QSYS]          = vsc9953_qsys_regmap,
 362        [REW]           = vsc9953_rew_regmap,
 363        [SYS]           = vsc9953_sys_regmap,
 364        [S0]            = vsc9953_vcap_regmap,
 365        [S1]            = vsc9953_vcap_regmap,
 366        [S2]            = vsc9953_vcap_regmap,
 367        [GCB]           = vsc9953_gcb_regmap,
 368        [DEV_GMII]      = vsc9953_dev_gmii_regmap,
 369};
 370
 371/* Addresses are relative to the device's base address */
 372static const struct resource vsc9953_target_io_res[TARGET_MAX] = {
 373        [ANA] = {
 374                .start  = 0x0280000,
 375                .end    = 0x028ffff,
 376                .name   = "ana",
 377        },
 378        [QS] = {
 379                .start  = 0x0080000,
 380                .end    = 0x00800ff,
 381                .name   = "qs",
 382        },
 383        [QSYS] = {
 384                .start  = 0x0200000,
 385                .end    = 0x021ffff,
 386                .name   = "qsys",
 387        },
 388        [REW] = {
 389                .start  = 0x0030000,
 390                .end    = 0x003ffff,
 391                .name   = "rew",
 392        },
 393        [SYS] = {
 394                .start  = 0x0010000,
 395                .end    = 0x001ffff,
 396                .name   = "sys",
 397        },
 398        [S0] = {
 399                .start  = 0x0040000,
 400                .end    = 0x00403ff,
 401                .name   = "s0",
 402        },
 403        [S1] = {
 404                .start  = 0x0050000,
 405                .end    = 0x00503ff,
 406                .name   = "s1",
 407        },
 408        [S2] = {
 409                .start  = 0x0060000,
 410                .end    = 0x00603ff,
 411                .name   = "s2",
 412        },
 413        [PTP] = {
 414                .start  = 0x0090000,
 415                .end    = 0x00900cb,
 416                .name   = "ptp",
 417        },
 418        [GCB] = {
 419                .start  = 0x0070000,
 420                .end    = 0x00701ff,
 421                .name   = "devcpu_gcb",
 422        },
 423};
 424
 425static const struct resource vsc9953_port_io_res[] = {
 426        {
 427                .start  = 0x0100000,
 428                .end    = 0x010ffff,
 429                .name   = "port0",
 430        },
 431        {
 432                .start  = 0x0110000,
 433                .end    = 0x011ffff,
 434                .name   = "port1",
 435        },
 436        {
 437                .start  = 0x0120000,
 438                .end    = 0x012ffff,
 439                .name   = "port2",
 440        },
 441        {
 442                .start  = 0x0130000,
 443                .end    = 0x013ffff,
 444                .name   = "port3",
 445        },
 446        {
 447                .start  = 0x0140000,
 448                .end    = 0x014ffff,
 449                .name   = "port4",
 450        },
 451        {
 452                .start  = 0x0150000,
 453                .end    = 0x015ffff,
 454                .name   = "port5",
 455        },
 456        {
 457                .start  = 0x0160000,
 458                .end    = 0x016ffff,
 459                .name   = "port6",
 460        },
 461        {
 462                .start  = 0x0170000,
 463                .end    = 0x017ffff,
 464                .name   = "port7",
 465        },
 466        {
 467                .start  = 0x0180000,
 468                .end    = 0x018ffff,
 469                .name   = "port8",
 470        },
 471        {
 472                .start  = 0x0190000,
 473                .end    = 0x019ffff,
 474                .name   = "port9",
 475        },
 476};
 477
 478static const struct reg_field vsc9953_regfields[REGFIELD_MAX] = {
 479        [ANA_ADVLEARN_VLAN_CHK] = REG_FIELD(ANA_ADVLEARN, 10, 10),
 480        [ANA_ADVLEARN_LEARN_MIRROR] = REG_FIELD(ANA_ADVLEARN, 0, 9),
 481        [ANA_ANEVENTS_AUTOAGE] = REG_FIELD(ANA_ANEVENTS, 24, 24),
 482        [ANA_ANEVENTS_STORM_DROP] = REG_FIELD(ANA_ANEVENTS, 22, 22),
 483        [ANA_ANEVENTS_LEARN_DROP] = REG_FIELD(ANA_ANEVENTS, 21, 21),
 484        [ANA_ANEVENTS_AGED_ENTRY] = REG_FIELD(ANA_ANEVENTS, 20, 20),
 485        [ANA_ANEVENTS_CPU_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 19, 19),
 486        [ANA_ANEVENTS_AUTO_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 18, 18),
 487        [ANA_ANEVENTS_LEARN_REMOVE] = REG_FIELD(ANA_ANEVENTS, 17, 17),
 488        [ANA_ANEVENTS_AUTO_LEARNED] = REG_FIELD(ANA_ANEVENTS, 16, 16),
 489        [ANA_ANEVENTS_AUTO_MOVED] = REG_FIELD(ANA_ANEVENTS, 15, 15),
 490        [ANA_ANEVENTS_CLASSIFIED_DROP] = REG_FIELD(ANA_ANEVENTS, 13, 13),
 491        [ANA_ANEVENTS_CLASSIFIED_COPY] = REG_FIELD(ANA_ANEVENTS, 12, 12),
 492        [ANA_ANEVENTS_VLAN_DISCARD] = REG_FIELD(ANA_ANEVENTS, 11, 11),
 493        [ANA_ANEVENTS_FWD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 10, 10),
 494        [ANA_ANEVENTS_MULTICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 9, 9),
 495        [ANA_ANEVENTS_UNICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 8, 8),
 496        [ANA_ANEVENTS_DEST_KNOWN] = REG_FIELD(ANA_ANEVENTS, 7, 7),
 497        [ANA_ANEVENTS_BUCKET3_MATCH] = REG_FIELD(ANA_ANEVENTS, 6, 6),
 498        [ANA_ANEVENTS_BUCKET2_MATCH] = REG_FIELD(ANA_ANEVENTS, 5, 5),
 499        [ANA_ANEVENTS_BUCKET1_MATCH] = REG_FIELD(ANA_ANEVENTS, 4, 4),
 500        [ANA_ANEVENTS_BUCKET0_MATCH] = REG_FIELD(ANA_ANEVENTS, 3, 3),
 501        [ANA_ANEVENTS_CPU_OPERATION] = REG_FIELD(ANA_ANEVENTS, 2, 2),
 502        [ANA_ANEVENTS_DMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 1, 1),
 503        [ANA_ANEVENTS_SMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 0, 0),
 504        [ANA_TABLES_MACACCESS_B_DOM] = REG_FIELD(ANA_TABLES_MACACCESS, 16, 16),
 505        [ANA_TABLES_MACTINDX_BUCKET] = REG_FIELD(ANA_TABLES_MACTINDX, 11, 12),
 506        [ANA_TABLES_MACTINDX_M_INDEX] = REG_FIELD(ANA_TABLES_MACTINDX, 0, 10),
 507        [SYS_RESET_CFG_CORE_ENA] = REG_FIELD(SYS_RESET_CFG, 7, 7),
 508        [SYS_RESET_CFG_MEM_ENA] = REG_FIELD(SYS_RESET_CFG, 6, 6),
 509        [SYS_RESET_CFG_MEM_INIT] = REG_FIELD(SYS_RESET_CFG, 5, 5),
 510        [GCB_SOFT_RST_SWC_RST] = REG_FIELD(GCB_SOFT_RST, 0, 0),
 511        [GCB_MIIM_MII_STATUS_PENDING] = REG_FIELD(GCB_MIIM_MII_STATUS, 2, 2),
 512        [GCB_MIIM_MII_STATUS_BUSY] = REG_FIELD(GCB_MIIM_MII_STATUS, 3, 3),
 513        /* Replicated per number of ports (11), register size 4 per port */
 514        [QSYS_SWITCH_PORT_MODE_PORT_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 13, 13, 11, 4),
 515        [QSYS_SWITCH_PORT_MODE_YEL_RSRVD] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 10, 10, 11, 4),
 516        [QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 9, 9, 11, 4),
 517        [QSYS_SWITCH_PORT_MODE_TX_PFC_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 1, 8, 11, 4),
 518        [QSYS_SWITCH_PORT_MODE_TX_PFC_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 0, 0, 11, 4),
 519        [SYS_PORT_MODE_INCL_INJ_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 4, 5, 11, 4),
 520        [SYS_PORT_MODE_INCL_XTR_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 2, 3, 11, 4),
 521        [SYS_PORT_MODE_INCL_HDR_ERR] = REG_FIELD_ID(SYS_PORT_MODE, 0, 0, 11, 4),
 522        [SYS_PAUSE_CFG_PAUSE_START] = REG_FIELD_ID(SYS_PAUSE_CFG, 11, 20, 11, 4),
 523        [SYS_PAUSE_CFG_PAUSE_STOP] = REG_FIELD_ID(SYS_PAUSE_CFG, 1, 10, 11, 4),
 524        [SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 11, 4),
 525};
 526
 527static const struct ocelot_stat_layout vsc9953_stats_layout[] = {
 528        { .offset = 0x00,       .name = "rx_octets", },
 529        { .offset = 0x01,       .name = "rx_unicast", },
 530        { .offset = 0x02,       .name = "rx_multicast", },
 531        { .offset = 0x03,       .name = "rx_broadcast", },
 532        { .offset = 0x04,       .name = "rx_shorts", },
 533        { .offset = 0x05,       .name = "rx_fragments", },
 534        { .offset = 0x06,       .name = "rx_jabbers", },
 535        { .offset = 0x07,       .name = "rx_crc_align_errs", },
 536        { .offset = 0x08,       .name = "rx_sym_errs", },
 537        { .offset = 0x09,       .name = "rx_frames_below_65_octets", },
 538        { .offset = 0x0A,       .name = "rx_frames_65_to_127_octets", },
 539        { .offset = 0x0B,       .name = "rx_frames_128_to_255_octets", },
 540        { .offset = 0x0C,       .name = "rx_frames_256_to_511_octets", },
 541        { .offset = 0x0D,       .name = "rx_frames_512_to_1023_octets", },
 542        { .offset = 0x0E,       .name = "rx_frames_1024_to_1526_octets", },
 543        { .offset = 0x0F,       .name = "rx_frames_over_1526_octets", },
 544        { .offset = 0x10,       .name = "rx_pause", },
 545        { .offset = 0x11,       .name = "rx_control", },
 546        { .offset = 0x12,       .name = "rx_longs", },
 547        { .offset = 0x13,       .name = "rx_classified_drops", },
 548        { .offset = 0x14,       .name = "rx_red_prio_0", },
 549        { .offset = 0x15,       .name = "rx_red_prio_1", },
 550        { .offset = 0x16,       .name = "rx_red_prio_2", },
 551        { .offset = 0x17,       .name = "rx_red_prio_3", },
 552        { .offset = 0x18,       .name = "rx_red_prio_4", },
 553        { .offset = 0x19,       .name = "rx_red_prio_5", },
 554        { .offset = 0x1A,       .name = "rx_red_prio_6", },
 555        { .offset = 0x1B,       .name = "rx_red_prio_7", },
 556        { .offset = 0x1C,       .name = "rx_yellow_prio_0", },
 557        { .offset = 0x1D,       .name = "rx_yellow_prio_1", },
 558        { .offset = 0x1E,       .name = "rx_yellow_prio_2", },
 559        { .offset = 0x1F,       .name = "rx_yellow_prio_3", },
 560        { .offset = 0x20,       .name = "rx_yellow_prio_4", },
 561        { .offset = 0x21,       .name = "rx_yellow_prio_5", },
 562        { .offset = 0x22,       .name = "rx_yellow_prio_6", },
 563        { .offset = 0x23,       .name = "rx_yellow_prio_7", },
 564        { .offset = 0x24,       .name = "rx_green_prio_0", },
 565        { .offset = 0x25,       .name = "rx_green_prio_1", },
 566        { .offset = 0x26,       .name = "rx_green_prio_2", },
 567        { .offset = 0x27,       .name = "rx_green_prio_3", },
 568        { .offset = 0x28,       .name = "rx_green_prio_4", },
 569        { .offset = 0x29,       .name = "rx_green_prio_5", },
 570        { .offset = 0x2A,       .name = "rx_green_prio_6", },
 571        { .offset = 0x2B,       .name = "rx_green_prio_7", },
 572        { .offset = 0x40,       .name = "tx_octets", },
 573        { .offset = 0x41,       .name = "tx_unicast", },
 574        { .offset = 0x42,       .name = "tx_multicast", },
 575        { .offset = 0x43,       .name = "tx_broadcast", },
 576        { .offset = 0x44,       .name = "tx_collision", },
 577        { .offset = 0x45,       .name = "tx_drops", },
 578        { .offset = 0x46,       .name = "tx_pause", },
 579        { .offset = 0x47,       .name = "tx_frames_below_65_octets", },
 580        { .offset = 0x48,       .name = "tx_frames_65_to_127_octets", },
 581        { .offset = 0x49,       .name = "tx_frames_128_255_octets", },
 582        { .offset = 0x4A,       .name = "tx_frames_256_511_octets", },
 583        { .offset = 0x4B,       .name = "tx_frames_512_1023_octets", },
 584        { .offset = 0x4C,       .name = "tx_frames_1024_1526_octets", },
 585        { .offset = 0x4D,       .name = "tx_frames_over_1526_octets", },
 586        { .offset = 0x4E,       .name = "tx_yellow_prio_0", },
 587        { .offset = 0x4F,       .name = "tx_yellow_prio_1", },
 588        { .offset = 0x50,       .name = "tx_yellow_prio_2", },
 589        { .offset = 0x51,       .name = "tx_yellow_prio_3", },
 590        { .offset = 0x52,       .name = "tx_yellow_prio_4", },
 591        { .offset = 0x53,       .name = "tx_yellow_prio_5", },
 592        { .offset = 0x54,       .name = "tx_yellow_prio_6", },
 593        { .offset = 0x55,       .name = "tx_yellow_prio_7", },
 594        { .offset = 0x56,       .name = "tx_green_prio_0", },
 595        { .offset = 0x57,       .name = "tx_green_prio_1", },
 596        { .offset = 0x58,       .name = "tx_green_prio_2", },
 597        { .offset = 0x59,       .name = "tx_green_prio_3", },
 598        { .offset = 0x5A,       .name = "tx_green_prio_4", },
 599        { .offset = 0x5B,       .name = "tx_green_prio_5", },
 600        { .offset = 0x5C,       .name = "tx_green_prio_6", },
 601        { .offset = 0x5D,       .name = "tx_green_prio_7", },
 602        { .offset = 0x5E,       .name = "tx_aged", },
 603        { .offset = 0x80,       .name = "drop_local", },
 604        { .offset = 0x81,       .name = "drop_tail", },
 605        { .offset = 0x82,       .name = "drop_yellow_prio_0", },
 606        { .offset = 0x83,       .name = "drop_yellow_prio_1", },
 607        { .offset = 0x84,       .name = "drop_yellow_prio_2", },
 608        { .offset = 0x85,       .name = "drop_yellow_prio_3", },
 609        { .offset = 0x86,       .name = "drop_yellow_prio_4", },
 610        { .offset = 0x87,       .name = "drop_yellow_prio_5", },
 611        { .offset = 0x88,       .name = "drop_yellow_prio_6", },
 612        { .offset = 0x89,       .name = "drop_yellow_prio_7", },
 613        { .offset = 0x8A,       .name = "drop_green_prio_0", },
 614        { .offset = 0x8B,       .name = "drop_green_prio_1", },
 615        { .offset = 0x8C,       .name = "drop_green_prio_2", },
 616        { .offset = 0x8D,       .name = "drop_green_prio_3", },
 617        { .offset = 0x8E,       .name = "drop_green_prio_4", },
 618        { .offset = 0x8F,       .name = "drop_green_prio_5", },
 619        { .offset = 0x90,       .name = "drop_green_prio_6", },
 620        { .offset = 0x91,       .name = "drop_green_prio_7", },
 621};
 622
 623static const struct vcap_field vsc9953_vcap_es0_keys[] = {
 624        [VCAP_ES0_EGR_PORT]                     = {  0,  4},
 625        [VCAP_ES0_IGR_PORT]                     = {  4,  4},
 626        [VCAP_ES0_RSV]                          = {  8,  2},
 627        [VCAP_ES0_L2_MC]                        = { 10,  1},
 628        [VCAP_ES0_L2_BC]                        = { 11,  1},
 629        [VCAP_ES0_VID]                          = { 12, 12},
 630        [VCAP_ES0_DP]                           = { 24,  1},
 631        [VCAP_ES0_PCP]                          = { 25,  3},
 632};
 633
 634static const struct vcap_field vsc9953_vcap_es0_actions[] = {
 635        [VCAP_ES0_ACT_PUSH_OUTER_TAG]           = {  0,  2},
 636        [VCAP_ES0_ACT_PUSH_INNER_TAG]           = {  2,  1},
 637        [VCAP_ES0_ACT_TAG_A_TPID_SEL]           = {  3,  2},
 638        [VCAP_ES0_ACT_TAG_A_VID_SEL]            = {  5,  1},
 639        [VCAP_ES0_ACT_TAG_A_PCP_SEL]            = {  6,  2},
 640        [VCAP_ES0_ACT_TAG_A_DEI_SEL]            = {  8,  2},
 641        [VCAP_ES0_ACT_TAG_B_TPID_SEL]           = { 10,  2},
 642        [VCAP_ES0_ACT_TAG_B_VID_SEL]            = { 12,  1},
 643        [VCAP_ES0_ACT_TAG_B_PCP_SEL]            = { 13,  2},
 644        [VCAP_ES0_ACT_TAG_B_DEI_SEL]            = { 15,  2},
 645        [VCAP_ES0_ACT_VID_A_VAL]                = { 17, 12},
 646        [VCAP_ES0_ACT_PCP_A_VAL]                = { 29,  3},
 647        [VCAP_ES0_ACT_DEI_A_VAL]                = { 32,  1},
 648        [VCAP_ES0_ACT_VID_B_VAL]                = { 33, 12},
 649        [VCAP_ES0_ACT_PCP_B_VAL]                = { 45,  3},
 650        [VCAP_ES0_ACT_DEI_B_VAL]                = { 48,  1},
 651        [VCAP_ES0_ACT_RSV]                      = { 49, 24},
 652        [VCAP_ES0_ACT_HIT_STICKY]               = { 73,  1},
 653};
 654
 655static const struct vcap_field vsc9953_vcap_is1_keys[] = {
 656        [VCAP_IS1_HK_TYPE]                      = {  0,   1},
 657        [VCAP_IS1_HK_LOOKUP]                    = {  1,   2},
 658        [VCAP_IS1_HK_IGR_PORT_MASK]             = {  3,  11},
 659        [VCAP_IS1_HK_RSV]                       = { 14,  10},
 660        /* VCAP_IS1_HK_OAM_Y1731 not supported */
 661        [VCAP_IS1_HK_L2_MC]                     = { 24,   1},
 662        [VCAP_IS1_HK_L2_BC]                     = { 25,   1},
 663        [VCAP_IS1_HK_IP_MC]                     = { 26,   1},
 664        [VCAP_IS1_HK_VLAN_TAGGED]               = { 27,   1},
 665        [VCAP_IS1_HK_VLAN_DBL_TAGGED]           = { 28,   1},
 666        [VCAP_IS1_HK_TPID]                      = { 29,   1},
 667        [VCAP_IS1_HK_VID]                       = { 30,  12},
 668        [VCAP_IS1_HK_DEI]                       = { 42,   1},
 669        [VCAP_IS1_HK_PCP]                       = { 43,   3},
 670        /* Specific Fields for IS1 Half Key S1_NORMAL */
 671        [VCAP_IS1_HK_L2_SMAC]                   = { 46,  48},
 672        [VCAP_IS1_HK_ETYPE_LEN]                 = { 94,   1},
 673        [VCAP_IS1_HK_ETYPE]                     = { 95,  16},
 674        [VCAP_IS1_HK_IP_SNAP]                   = {111,   1},
 675        [VCAP_IS1_HK_IP4]                       = {112,   1},
 676        /* Layer-3 Information */
 677        [VCAP_IS1_HK_L3_FRAGMENT]               = {113,   1},
 678        [VCAP_IS1_HK_L3_FRAG_OFS_GT0]           = {114,   1},
 679        [VCAP_IS1_HK_L3_OPTIONS]                = {115,   1},
 680        [VCAP_IS1_HK_L3_DSCP]                   = {116,   6},
 681        [VCAP_IS1_HK_L3_IP4_SIP]                = {122,  32},
 682        /* Layer-4 Information */
 683        [VCAP_IS1_HK_TCP_UDP]                   = {154,   1},
 684        [VCAP_IS1_HK_TCP]                       = {155,   1},
 685        [VCAP_IS1_HK_L4_SPORT]                  = {156,  16},
 686        [VCAP_IS1_HK_L4_RNG]                    = {172,   8},
 687        /* Specific Fields for IS1 Half Key S1_5TUPLE_IP4 */
 688        [VCAP_IS1_HK_IP4_INNER_TPID]            = { 46,   1},
 689        [VCAP_IS1_HK_IP4_INNER_VID]             = { 47,  12},
 690        [VCAP_IS1_HK_IP4_INNER_DEI]             = { 59,   1},
 691        [VCAP_IS1_HK_IP4_INNER_PCP]             = { 60,   3},
 692        [VCAP_IS1_HK_IP4_IP4]                   = { 63,   1},
 693        [VCAP_IS1_HK_IP4_L3_FRAGMENT]           = { 64,   1},
 694        [VCAP_IS1_HK_IP4_L3_FRAG_OFS_GT0]       = { 65,   1},
 695        [VCAP_IS1_HK_IP4_L3_OPTIONS]            = { 66,   1},
 696        [VCAP_IS1_HK_IP4_L3_DSCP]               = { 67,   6},
 697        [VCAP_IS1_HK_IP4_L3_IP4_DIP]            = { 73,  32},
 698        [VCAP_IS1_HK_IP4_L3_IP4_SIP]            = {105,  32},
 699        [VCAP_IS1_HK_IP4_L3_PROTO]              = {137,   8},
 700        [VCAP_IS1_HK_IP4_TCP_UDP]               = {145,   1},
 701        [VCAP_IS1_HK_IP4_TCP]                   = {146,   1},
 702        [VCAP_IS1_HK_IP4_L4_RNG]                = {147,   8},
 703        [VCAP_IS1_HK_IP4_IP_PAYLOAD_S1_5TUPLE]  = {155,  32},
 704};
 705
 706static const struct vcap_field vsc9953_vcap_is1_actions[] = {
 707        [VCAP_IS1_ACT_DSCP_ENA]                 = {  0,  1},
 708        [VCAP_IS1_ACT_DSCP_VAL]                 = {  1,  6},
 709        [VCAP_IS1_ACT_QOS_ENA]                  = {  7,  1},
 710        [VCAP_IS1_ACT_QOS_VAL]                  = {  8,  3},
 711        [VCAP_IS1_ACT_DP_ENA]                   = { 11,  1},
 712        [VCAP_IS1_ACT_DP_VAL]                   = { 12,  1},
 713        [VCAP_IS1_ACT_PAG_OVERRIDE_MASK]        = { 13,  8},
 714        [VCAP_IS1_ACT_PAG_VAL]                  = { 21,  8},
 715        [VCAP_IS1_ACT_RSV]                      = { 29, 11},
 716        [VCAP_IS1_ACT_VID_REPLACE_ENA]          = { 40,  1},
 717        [VCAP_IS1_ACT_VID_ADD_VAL]              = { 41, 12},
 718        [VCAP_IS1_ACT_FID_SEL]                  = { 53,  2},
 719        [VCAP_IS1_ACT_FID_VAL]                  = { 55, 13},
 720        [VCAP_IS1_ACT_PCP_DEI_ENA]              = { 68,  1},
 721        [VCAP_IS1_ACT_PCP_VAL]                  = { 69,  3},
 722        [VCAP_IS1_ACT_DEI_VAL]                  = { 72,  1},
 723        [VCAP_IS1_ACT_VLAN_POP_CNT_ENA]         = { 73,  1},
 724        [VCAP_IS1_ACT_VLAN_POP_CNT]             = { 74,  2},
 725        [VCAP_IS1_ACT_CUSTOM_ACE_TYPE_ENA]      = { 76,  4},
 726        [VCAP_IS1_ACT_HIT_STICKY]               = { 80,  1},
 727};
 728
 729static struct vcap_field vsc9953_vcap_is2_keys[] = {
 730        /* Common: 41 bits */
 731        [VCAP_IS2_TYPE]                         = {  0,   4},
 732        [VCAP_IS2_HK_FIRST]                     = {  4,   1},
 733        [VCAP_IS2_HK_PAG]                       = {  5,   8},
 734        [VCAP_IS2_HK_IGR_PORT_MASK]             = { 13,  11},
 735        [VCAP_IS2_HK_RSV2]                      = { 24,   1},
 736        [VCAP_IS2_HK_HOST_MATCH]                = { 25,   1},
 737        [VCAP_IS2_HK_L2_MC]                     = { 26,   1},
 738        [VCAP_IS2_HK_L2_BC]                     = { 27,   1},
 739        [VCAP_IS2_HK_VLAN_TAGGED]               = { 28,   1},
 740        [VCAP_IS2_HK_VID]                       = { 29,  12},
 741        [VCAP_IS2_HK_DEI]                       = { 41,   1},
 742        [VCAP_IS2_HK_PCP]                       = { 42,   3},
 743        /* MAC_ETYPE / MAC_LLC / MAC_SNAP / OAM common */
 744        [VCAP_IS2_HK_L2_DMAC]                   = { 45,  48},
 745        [VCAP_IS2_HK_L2_SMAC]                   = { 93,  48},
 746        /* MAC_ETYPE (TYPE=000) */
 747        [VCAP_IS2_HK_MAC_ETYPE_ETYPE]           = {141,  16},
 748        [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0]     = {157,  16},
 749        [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1]     = {173,   8},
 750        [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2]     = {181,   3},
 751        /* MAC_LLC (TYPE=001) */
 752        [VCAP_IS2_HK_MAC_LLC_L2_LLC]            = {141,  40},
 753        /* MAC_SNAP (TYPE=010) */
 754        [VCAP_IS2_HK_MAC_SNAP_L2_SNAP]          = {141,  40},
 755        /* MAC_ARP (TYPE=011) */
 756        [VCAP_IS2_HK_MAC_ARP_SMAC]              = { 45,  48},
 757        [VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK]     = { 93,   1},
 758        [VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK]    = { 94,   1},
 759        [VCAP_IS2_HK_MAC_ARP_LEN_OK]            = { 95,   1},
 760        [VCAP_IS2_HK_MAC_ARP_TARGET_MATCH]      = { 96,   1},
 761        [VCAP_IS2_HK_MAC_ARP_SENDER_MATCH]      = { 97,   1},
 762        [VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN]    = { 98,   1},
 763        [VCAP_IS2_HK_MAC_ARP_OPCODE]            = { 99,   2},
 764        [VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP]        = {101,  32},
 765        [VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP]        = {133,  32},
 766        [VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP]        = {165,   1},
 767        /* IP4_TCP_UDP / IP4_OTHER common */
 768        [VCAP_IS2_HK_IP4]                       = { 45,   1},
 769        [VCAP_IS2_HK_L3_FRAGMENT]               = { 46,   1},
 770        [VCAP_IS2_HK_L3_FRAG_OFS_GT0]           = { 47,   1},
 771        [VCAP_IS2_HK_L3_OPTIONS]                = { 48,   1},
 772        [VCAP_IS2_HK_IP4_L3_TTL_GT0]            = { 49,   1},
 773        [VCAP_IS2_HK_L3_TOS]                    = { 50,   8},
 774        [VCAP_IS2_HK_L3_IP4_DIP]                = { 58,  32},
 775        [VCAP_IS2_HK_L3_IP4_SIP]                = { 90,  32},
 776        [VCAP_IS2_HK_DIP_EQ_SIP]                = {122,   1},
 777        /* IP4_TCP_UDP (TYPE=100) */
 778        [VCAP_IS2_HK_TCP]                       = {123,   1},
 779        [VCAP_IS2_HK_L4_DPORT]                  = {124,  16},
 780        [VCAP_IS2_HK_L4_SPORT]                  = {140,  16},
 781        [VCAP_IS2_HK_L4_RNG]                    = {156,   8},
 782        [VCAP_IS2_HK_L4_SPORT_EQ_DPORT]         = {164,   1},
 783        [VCAP_IS2_HK_L4_SEQUENCE_EQ0]           = {165,   1},
 784        [VCAP_IS2_HK_L4_FIN]                    = {166,   1},
 785        [VCAP_IS2_HK_L4_SYN]                    = {167,   1},
 786        [VCAP_IS2_HK_L4_RST]                    = {168,   1},
 787        [VCAP_IS2_HK_L4_PSH]                    = {169,   1},
 788        [VCAP_IS2_HK_L4_ACK]                    = {170,   1},
 789        [VCAP_IS2_HK_L4_URG]                    = {171,   1},
 790        /* IP4_OTHER (TYPE=101) */
 791        [VCAP_IS2_HK_IP4_L3_PROTO]              = {123,   8},
 792        [VCAP_IS2_HK_L3_PAYLOAD]                = {131,  56},
 793        /* IP6_STD (TYPE=110) */
 794        [VCAP_IS2_HK_IP6_L3_TTL_GT0]            = { 45,   1},
 795        [VCAP_IS2_HK_L3_IP6_SIP]                = { 46, 128},
 796        [VCAP_IS2_HK_IP6_L3_PROTO]              = {174,   8},
 797};
 798
 799static struct vcap_field vsc9953_vcap_is2_actions[] = {
 800        [VCAP_IS2_ACT_HIT_ME_ONCE]              = {  0,  1},
 801        [VCAP_IS2_ACT_CPU_COPY_ENA]             = {  1,  1},
 802        [VCAP_IS2_ACT_CPU_QU_NUM]               = {  2,  3},
 803        [VCAP_IS2_ACT_MASK_MODE]                = {  5,  2},
 804        [VCAP_IS2_ACT_MIRROR_ENA]               = {  7,  1},
 805        [VCAP_IS2_ACT_LRN_DIS]                  = {  8,  1},
 806        [VCAP_IS2_ACT_POLICE_ENA]               = {  9,  1},
 807        [VCAP_IS2_ACT_POLICE_IDX]               = { 10,  8},
 808        [VCAP_IS2_ACT_POLICE_VCAP_ONLY]         = { 21,  1},
 809        [VCAP_IS2_ACT_PORT_MASK]                = { 22, 10},
 810        [VCAP_IS2_ACT_ACL_ID]                   = { 44,  6},
 811        [VCAP_IS2_ACT_HIT_CNT]                  = { 50, 32},
 812};
 813
 814static struct vcap_props vsc9953_vcap_props[] = {
 815        [VCAP_ES0] = {
 816                .action_type_width = 0,
 817                .action_table = {
 818                        [ES0_ACTION_TYPE_NORMAL] = {
 819                                .width = 73, /* HIT_STICKY not included */
 820                                .count = 1,
 821                        },
 822                },
 823                .target = S0,
 824                .keys = vsc9953_vcap_es0_keys,
 825                .actions = vsc9953_vcap_es0_actions,
 826        },
 827        [VCAP_IS1] = {
 828                .action_type_width = 0,
 829                .action_table = {
 830                        [IS1_ACTION_TYPE_NORMAL] = {
 831                                .width = 80, /* HIT_STICKY not included */
 832                                .count = 4,
 833                        },
 834                },
 835                .target = S1,
 836                .keys = vsc9953_vcap_is1_keys,
 837                .actions = vsc9953_vcap_is1_actions,
 838        },
 839        [VCAP_IS2] = {
 840                .action_type_width = 1,
 841                .action_table = {
 842                        [IS2_ACTION_TYPE_NORMAL] = {
 843                                .width = 50, /* HIT_CNT not included */
 844                                .count = 2
 845                        },
 846                        [IS2_ACTION_TYPE_SMAC_SIP] = {
 847                                .width = 6,
 848                                .count = 4
 849                        },
 850                },
 851                .target = S2,
 852                .keys = vsc9953_vcap_is2_keys,
 853                .actions = vsc9953_vcap_is2_actions,
 854        },
 855};
 856
 857#define VSC9953_INIT_TIMEOUT                    50000
 858#define VSC9953_GCB_RST_SLEEP                   100
 859#define VSC9953_SYS_RAMINIT_SLEEP               80
 860#define VCS9953_MII_TIMEOUT                     10000
 861
 862static int vsc9953_gcb_soft_rst_status(struct ocelot *ocelot)
 863{
 864        int val;
 865
 866        ocelot_field_read(ocelot, GCB_SOFT_RST_SWC_RST, &val);
 867
 868        return val;
 869}
 870
 871static int vsc9953_sys_ram_init_status(struct ocelot *ocelot)
 872{
 873        int val;
 874
 875        ocelot_field_read(ocelot, SYS_RESET_CFG_MEM_INIT, &val);
 876
 877        return val;
 878}
 879
 880static int vsc9953_gcb_miim_pending_status(struct ocelot *ocelot)
 881{
 882        int val;
 883
 884        ocelot_field_read(ocelot, GCB_MIIM_MII_STATUS_PENDING, &val);
 885
 886        return val;
 887}
 888
 889static int vsc9953_gcb_miim_busy_status(struct ocelot *ocelot)
 890{
 891        int val;
 892
 893        ocelot_field_read(ocelot, GCB_MIIM_MII_STATUS_BUSY, &val);
 894
 895        return val;
 896}
 897
 898static int vsc9953_mdio_write(struct mii_bus *bus, int phy_id, int regnum,
 899                              u16 value)
 900{
 901        struct ocelot *ocelot = bus->priv;
 902        int err, cmd, val;
 903
 904        /* Wait while MIIM controller becomes idle */
 905        err = readx_poll_timeout(vsc9953_gcb_miim_pending_status, ocelot,
 906                                 val, !val, 10, VCS9953_MII_TIMEOUT);
 907        if (err) {
 908                dev_err(ocelot->dev, "MDIO write: pending timeout\n");
 909                goto out;
 910        }
 911
 912        cmd = MSCC_MIIM_CMD_VLD | (phy_id << MSCC_MIIM_CMD_PHYAD_SHIFT) |
 913              (regnum << MSCC_MIIM_CMD_REGAD_SHIFT) |
 914              (value << MSCC_MIIM_CMD_WRDATA_SHIFT) |
 915              MSCC_MIIM_CMD_OPR_WRITE;
 916
 917        ocelot_write(ocelot, cmd, GCB_MIIM_MII_CMD);
 918
 919out:
 920        return err;
 921}
 922
 923static int vsc9953_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
 924{
 925        struct ocelot *ocelot = bus->priv;
 926        int err, cmd, val;
 927
 928        /* Wait until MIIM controller becomes idle */
 929        err = readx_poll_timeout(vsc9953_gcb_miim_pending_status, ocelot,
 930                                 val, !val, 10, VCS9953_MII_TIMEOUT);
 931        if (err) {
 932                dev_err(ocelot->dev, "MDIO read: pending timeout\n");
 933                goto out;
 934        }
 935
 936        /* Write the MIIM COMMAND register */
 937        cmd = MSCC_MIIM_CMD_VLD | (phy_id << MSCC_MIIM_CMD_PHYAD_SHIFT) |
 938              (regnum << MSCC_MIIM_CMD_REGAD_SHIFT) | MSCC_MIIM_CMD_OPR_READ;
 939
 940        ocelot_write(ocelot, cmd, GCB_MIIM_MII_CMD);
 941
 942        /* Wait while read operation via the MIIM controller is in progress */
 943        err = readx_poll_timeout(vsc9953_gcb_miim_busy_status, ocelot,
 944                                 val, !val, 10, VCS9953_MII_TIMEOUT);
 945        if (err) {
 946                dev_err(ocelot->dev, "MDIO read: busy timeout\n");
 947                goto out;
 948        }
 949
 950        val = ocelot_read(ocelot, GCB_MIIM_MII_DATA);
 951
 952        err = val & 0xFFFF;
 953out:
 954        return err;
 955}
 956
 957/* CORE_ENA is in SYS:SYSTEM:RESET_CFG
 958 * MEM_INIT is in SYS:SYSTEM:RESET_CFG
 959 * MEM_ENA is in SYS:SYSTEM:RESET_CFG
 960 */
 961static int vsc9953_reset(struct ocelot *ocelot)
 962{
 963        int val, err;
 964
 965        /* soft-reset the switch core */
 966        ocelot_field_write(ocelot, GCB_SOFT_RST_SWC_RST, 1);
 967
 968        err = readx_poll_timeout(vsc9953_gcb_soft_rst_status, ocelot, val, !val,
 969                                 VSC9953_GCB_RST_SLEEP, VSC9953_INIT_TIMEOUT);
 970        if (err) {
 971                dev_err(ocelot->dev, "timeout: switch core reset\n");
 972                return err;
 973        }
 974
 975        /* initialize switch mem ~40us */
 976        ocelot_field_write(ocelot, SYS_RESET_CFG_MEM_ENA, 1);
 977        ocelot_field_write(ocelot, SYS_RESET_CFG_MEM_INIT, 1);
 978
 979        err = readx_poll_timeout(vsc9953_sys_ram_init_status, ocelot, val, !val,
 980                                 VSC9953_SYS_RAMINIT_SLEEP,
 981                                 VSC9953_INIT_TIMEOUT);
 982        if (err) {
 983                dev_err(ocelot->dev, "timeout: switch sram init\n");
 984                return err;
 985        }
 986
 987        /* enable switch core */
 988        ocelot_field_write(ocelot, SYS_RESET_CFG_CORE_ENA, 1);
 989
 990        return 0;
 991}
 992
 993static void vsc9953_phylink_validate(struct ocelot *ocelot, int port,
 994                                     unsigned long *supported,
 995                                     struct phylink_link_state *state)
 996{
 997        struct ocelot_port *ocelot_port = ocelot->ports[port];
 998        __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
 999
1000        if (state->interface != PHY_INTERFACE_MODE_NA &&
1001            state->interface != ocelot_port->phy_mode) {
1002                bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
1003                return;
1004        }
1005
1006        phylink_set_port_modes(mask);
1007        phylink_set(mask, Autoneg);
1008        phylink_set(mask, Pause);
1009        phylink_set(mask, Asym_Pause);
1010        phylink_set(mask, 10baseT_Full);
1011        phylink_set(mask, 10baseT_Half);
1012        phylink_set(mask, 100baseT_Full);
1013        phylink_set(mask, 100baseT_Half);
1014        phylink_set(mask, 1000baseT_Full);
1015
1016        if (state->interface == PHY_INTERFACE_MODE_INTERNAL) {
1017                phylink_set(mask, 2500baseT_Full);
1018                phylink_set(mask, 2500baseX_Full);
1019        }
1020
1021        bitmap_and(supported, supported, mask,
1022                   __ETHTOOL_LINK_MODE_MASK_NBITS);
1023        bitmap_and(state->advertising, state->advertising, mask,
1024                   __ETHTOOL_LINK_MODE_MASK_NBITS);
1025}
1026
1027static int vsc9953_prevalidate_phy_mode(struct ocelot *ocelot, int port,
1028                                        phy_interface_t phy_mode)
1029{
1030        switch (phy_mode) {
1031        case PHY_INTERFACE_MODE_INTERNAL:
1032                if (port != 8 && port != 9)
1033                        return -ENOTSUPP;
1034                return 0;
1035        case PHY_INTERFACE_MODE_SGMII:
1036        case PHY_INTERFACE_MODE_QSGMII:
1037                /* Not supported on internal to-CPU ports */
1038                if (port == 8 || port == 9)
1039                        return -ENOTSUPP;
1040                return 0;
1041        default:
1042                return -ENOTSUPP;
1043        }
1044}
1045
1046/* Watermark encode
1047 * Bit 9:   Unit; 0:1, 1:16
1048 * Bit 8-0: Value to be multiplied with unit
1049 */
1050static u16 vsc9953_wm_enc(u16 value)
1051{
1052        WARN_ON(value >= 16 * BIT(9));
1053
1054        if (value >= BIT(9))
1055                return BIT(9) | (value / 16);
1056
1057        return value;
1058}
1059
1060static u16 vsc9953_wm_dec(u16 wm)
1061{
1062        WARN_ON(wm & ~GENMASK(9, 0));
1063
1064        if (wm & BIT(9))
1065                return (wm & GENMASK(8, 0)) * 16;
1066
1067        return wm;
1068}
1069
1070static void vsc9953_wm_stat(u32 val, u32 *inuse, u32 *maxuse)
1071{
1072        *inuse = (val & GENMASK(25, 13)) >> 13;
1073        *maxuse = val & GENMASK(12, 0);
1074}
1075
1076static const struct ocelot_ops vsc9953_ops = {
1077        .reset                  = vsc9953_reset,
1078        .wm_enc                 = vsc9953_wm_enc,
1079        .wm_dec                 = vsc9953_wm_dec,
1080        .wm_stat                = vsc9953_wm_stat,
1081        .port_to_netdev         = felix_port_to_netdev,
1082        .netdev_to_port         = felix_netdev_to_port,
1083};
1084
1085static int vsc9953_mdio_bus_alloc(struct ocelot *ocelot)
1086{
1087        struct felix *felix = ocelot_to_felix(ocelot);
1088        struct device *dev = ocelot->dev;
1089        struct mii_bus *bus;
1090        int port;
1091        int rc;
1092
1093        felix->pcs = devm_kcalloc(dev, felix->info->num_ports,
1094                                  sizeof(struct phy_device *),
1095                                  GFP_KERNEL);
1096        if (!felix->pcs) {
1097                dev_err(dev, "failed to allocate array for PCS PHYs\n");
1098                return -ENOMEM;
1099        }
1100
1101        bus = devm_mdiobus_alloc(dev);
1102        if (!bus)
1103                return -ENOMEM;
1104
1105        bus->name = "VSC9953 internal MDIO bus";
1106        bus->read = vsc9953_mdio_read;
1107        bus->write = vsc9953_mdio_write;
1108        bus->parent = dev;
1109        bus->priv = ocelot;
1110        snprintf(bus->id, MII_BUS_ID_SIZE, "%s-imdio", dev_name(dev));
1111
1112        /* Needed in order to initialize the bus mutex lock */
1113        rc = mdiobus_register(bus);
1114        if (rc < 0) {
1115                dev_err(dev, "failed to register MDIO bus\n");
1116                return rc;
1117        }
1118
1119        felix->imdio = bus;
1120
1121        for (port = 0; port < felix->info->num_ports; port++) {
1122                struct ocelot_port *ocelot_port = ocelot->ports[port];
1123                int addr = port + 4;
1124                struct mdio_device *pcs;
1125                struct lynx_pcs *lynx;
1126
1127                if (dsa_is_unused_port(felix->ds, port))
1128                        continue;
1129
1130                if (ocelot_port->phy_mode == PHY_INTERFACE_MODE_INTERNAL)
1131                        continue;
1132
1133                pcs = mdio_device_create(felix->imdio, addr);
1134                if (IS_ERR(pcs))
1135                        continue;
1136
1137                lynx = lynx_pcs_create(pcs);
1138                if (!lynx) {
1139                        mdio_device_free(pcs);
1140                        continue;
1141                }
1142
1143                felix->pcs[port] = lynx;
1144
1145                dev_info(dev, "Found PCS at internal MDIO address %d\n", addr);
1146        }
1147
1148        return 0;
1149}
1150
1151static void vsc9953_mdio_bus_free(struct ocelot *ocelot)
1152{
1153        struct felix *felix = ocelot_to_felix(ocelot);
1154        int port;
1155
1156        for (port = 0; port < ocelot->num_phys_ports; port++) {
1157                struct lynx_pcs *pcs = felix->pcs[port];
1158
1159                if (!pcs)
1160                        continue;
1161
1162                mdio_device_free(pcs->mdio);
1163                lynx_pcs_destroy(pcs);
1164        }
1165        mdiobus_unregister(felix->imdio);
1166}
1167
1168static const struct felix_info seville_info_vsc9953 = {
1169        .target_io_res          = vsc9953_target_io_res,
1170        .port_io_res            = vsc9953_port_io_res,
1171        .regfields              = vsc9953_regfields,
1172        .map                    = vsc9953_regmap,
1173        .ops                    = &vsc9953_ops,
1174        .stats_layout           = vsc9953_stats_layout,
1175        .num_stats              = ARRAY_SIZE(vsc9953_stats_layout),
1176        .vcap                   = vsc9953_vcap_props,
1177        .num_mact_rows          = 2048,
1178        .num_ports              = 10,
1179        .num_tx_queues          = OCELOT_NUM_TC,
1180        .mdio_bus_alloc         = vsc9953_mdio_bus_alloc,
1181        .mdio_bus_free          = vsc9953_mdio_bus_free,
1182        .phylink_validate       = vsc9953_phylink_validate,
1183        .prevalidate_phy_mode   = vsc9953_prevalidate_phy_mode,
1184};
1185
1186static int seville_probe(struct platform_device *pdev)
1187{
1188        struct dsa_switch *ds;
1189        struct ocelot *ocelot;
1190        struct resource *res;
1191        struct felix *felix;
1192        int err;
1193
1194        felix = kzalloc(sizeof(struct felix), GFP_KERNEL);
1195        if (!felix) {
1196                err = -ENOMEM;
1197                dev_err(&pdev->dev, "Failed to allocate driver memory\n");
1198                goto err_alloc_felix;
1199        }
1200
1201        platform_set_drvdata(pdev, felix);
1202
1203        ocelot = &felix->ocelot;
1204        ocelot->dev = &pdev->dev;
1205        ocelot->num_flooding_pgids = 1;
1206        felix->info = &seville_info_vsc9953;
1207
1208        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1209        if (!res) {
1210                err = -EINVAL;
1211                dev_err(&pdev->dev, "Invalid resource\n");
1212                goto err_alloc_felix;
1213        }
1214        felix->switch_base = res->start;
1215
1216        ds = kzalloc(sizeof(struct dsa_switch), GFP_KERNEL);
1217        if (!ds) {
1218                err = -ENOMEM;
1219                dev_err(&pdev->dev, "Failed to allocate DSA switch\n");
1220                goto err_alloc_ds;
1221        }
1222
1223        ds->dev = &pdev->dev;
1224        ds->num_ports = felix->info->num_ports;
1225        ds->ops = &felix_switch_ops;
1226        ds->priv = ocelot;
1227        felix->ds = ds;
1228        felix->tag_proto = DSA_TAG_PROTO_SEVILLE;
1229
1230        err = dsa_register_switch(ds);
1231        if (err) {
1232                dev_err(&pdev->dev, "Failed to register DSA switch: %d\n", err);
1233                goto err_register_ds;
1234        }
1235
1236        return 0;
1237
1238err_register_ds:
1239        kfree(ds);
1240err_alloc_ds:
1241err_alloc_felix:
1242        kfree(felix);
1243        return err;
1244}
1245
1246static int seville_remove(struct platform_device *pdev)
1247{
1248        struct felix *felix = platform_get_drvdata(pdev);
1249
1250        if (!felix)
1251                return 0;
1252
1253        dsa_unregister_switch(felix->ds);
1254
1255        kfree(felix->ds);
1256        kfree(felix);
1257
1258        platform_set_drvdata(pdev, NULL);
1259
1260        return 0;
1261}
1262
1263static void seville_shutdown(struct platform_device *pdev)
1264{
1265        struct felix *felix = platform_get_drvdata(pdev);
1266
1267        if (!felix)
1268                return;
1269
1270        dsa_switch_shutdown(felix->ds);
1271
1272        platform_set_drvdata(pdev, NULL);
1273}
1274
1275static const struct of_device_id seville_of_match[] = {
1276        { .compatible = "mscc,vsc9953-switch" },
1277        { },
1278};
1279MODULE_DEVICE_TABLE(of, seville_of_match);
1280
1281static struct platform_driver seville_vsc9953_driver = {
1282        .probe          = seville_probe,
1283        .remove         = seville_remove,
1284        .shutdown       = seville_shutdown,
1285        .driver = {
1286                .name           = "mscc_seville",
1287                .of_match_table = of_match_ptr(seville_of_match),
1288        },
1289};
1290module_platform_driver(seville_vsc9953_driver);
1291
1292MODULE_DESCRIPTION("Seville Switch driver");
1293MODULE_LICENSE("GPL v2");
1294