cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

felix_vsc9959.c (69732B)


      1// SPDX-License-Identifier: (GPL-2.0 OR MIT)
      2/* Copyright 2017 Microsemi Corporation
      3 * Copyright 2018-2019 NXP
      4 */
      5#include <linux/fsl/enetc_mdio.h>
      6#include <soc/mscc/ocelot_qsys.h>
      7#include <soc/mscc/ocelot_vcap.h>
      8#include <soc/mscc/ocelot_ana.h>
      9#include <soc/mscc/ocelot_ptp.h>
     10#include <soc/mscc/ocelot_sys.h>
     11#include <net/tc_act/tc_gate.h>
     12#include <soc/mscc/ocelot.h>
     13#include <linux/dsa/ocelot.h>
     14#include <linux/pcs-lynx.h>
     15#include <net/pkt_sched.h>
     16#include <linux/iopoll.h>
     17#include <linux/mdio.h>
     18#include <linux/pci.h>
     19#include "felix.h"
     20
     21#define VSC9959_NUM_PORTS		6
     22
     23#define VSC9959_TAS_GCL_ENTRY_MAX	63
     24#define VSC9959_VCAP_POLICER_BASE	63
     25#define VSC9959_VCAP_POLICER_MAX	383
     26#define VSC9959_SWITCH_PCI_BAR		4
     27#define VSC9959_IMDIO_PCI_BAR		0
     28
     29#define VSC9959_PORT_MODE_SERDES	(OCELOT_PORT_MODE_SGMII | \
     30					 OCELOT_PORT_MODE_QSGMII | \
     31					 OCELOT_PORT_MODE_1000BASEX | \
     32					 OCELOT_PORT_MODE_2500BASEX | \
     33					 OCELOT_PORT_MODE_USXGMII)
     34
     35static const u32 vsc9959_port_modes[VSC9959_NUM_PORTS] = {
     36	VSC9959_PORT_MODE_SERDES,
     37	VSC9959_PORT_MODE_SERDES,
     38	VSC9959_PORT_MODE_SERDES,
     39	VSC9959_PORT_MODE_SERDES,
     40	OCELOT_PORT_MODE_INTERNAL,
     41	OCELOT_PORT_MODE_INTERNAL,
     42};
     43
     44static const u32 vsc9959_ana_regmap[] = {
     45	REG(ANA_ADVLEARN,			0x0089a0),
     46	REG(ANA_VLANMASK,			0x0089a4),
     47	REG_RESERVED(ANA_PORT_B_DOMAIN),
     48	REG(ANA_ANAGEFIL,			0x0089ac),
     49	REG(ANA_ANEVENTS,			0x0089b0),
     50	REG(ANA_STORMLIMIT_BURST,		0x0089b4),
     51	REG(ANA_STORMLIMIT_CFG,			0x0089b8),
     52	REG(ANA_ISOLATED_PORTS,			0x0089c8),
     53	REG(ANA_COMMUNITY_PORTS,		0x0089cc),
     54	REG(ANA_AUTOAGE,			0x0089d0),
     55	REG(ANA_MACTOPTIONS,			0x0089d4),
     56	REG(ANA_LEARNDISC,			0x0089d8),
     57	REG(ANA_AGENCTRL,			0x0089dc),
     58	REG(ANA_MIRRORPORTS,			0x0089e0),
     59	REG(ANA_EMIRRORPORTS,			0x0089e4),
     60	REG(ANA_FLOODING,			0x0089e8),
     61	REG(ANA_FLOODING_IPMC,			0x008a08),
     62	REG(ANA_SFLOW_CFG,			0x008a0c),
     63	REG(ANA_PORT_MODE,			0x008a28),
     64	REG(ANA_CUT_THRU_CFG,			0x008a48),
     65	REG(ANA_PGID_PGID,			0x008400),
     66	REG(ANA_TABLES_ANMOVED,			0x007f1c),
     67	REG(ANA_TABLES_MACHDATA,		0x007f20),
     68	REG(ANA_TABLES_MACLDATA,		0x007f24),
     69	REG(ANA_TABLES_STREAMDATA,		0x007f28),
     70	REG(ANA_TABLES_MACACCESS,		0x007f2c),
     71	REG(ANA_TABLES_MACTINDX,		0x007f30),
     72	REG(ANA_TABLES_VLANACCESS,		0x007f34),
     73	REG(ANA_TABLES_VLANTIDX,		0x007f38),
     74	REG(ANA_TABLES_ISDXACCESS,		0x007f3c),
     75	REG(ANA_TABLES_ISDXTIDX,		0x007f40),
     76	REG(ANA_TABLES_ENTRYLIM,		0x007f00),
     77	REG(ANA_TABLES_PTP_ID_HIGH,		0x007f44),
     78	REG(ANA_TABLES_PTP_ID_LOW,		0x007f48),
     79	REG(ANA_TABLES_STREAMACCESS,		0x007f4c),
     80	REG(ANA_TABLES_STREAMTIDX,		0x007f50),
     81	REG(ANA_TABLES_SEQ_HISTORY,		0x007f54),
     82	REG(ANA_TABLES_SEQ_MASK,		0x007f58),
     83	REG(ANA_TABLES_SFID_MASK,		0x007f5c),
     84	REG(ANA_TABLES_SFIDACCESS,		0x007f60),
     85	REG(ANA_TABLES_SFIDTIDX,		0x007f64),
     86	REG(ANA_MSTI_STATE,			0x008600),
     87	REG(ANA_OAM_UPM_LM_CNT,			0x008000),
     88	REG(ANA_SG_ACCESS_CTRL,			0x008a64),
     89	REG(ANA_SG_CONFIG_REG_1,		0x007fb0),
     90	REG(ANA_SG_CONFIG_REG_2,		0x007fb4),
     91	REG(ANA_SG_CONFIG_REG_3,		0x007fb8),
     92	REG(ANA_SG_CONFIG_REG_4,		0x007fbc),
     93	REG(ANA_SG_CONFIG_REG_5,		0x007fc0),
     94	REG(ANA_SG_GCL_GS_CONFIG,		0x007f80),
     95	REG(ANA_SG_GCL_TI_CONFIG,		0x007f90),
     96	REG(ANA_SG_STATUS_REG_1,		0x008980),
     97	REG(ANA_SG_STATUS_REG_2,		0x008984),
     98	REG(ANA_SG_STATUS_REG_3,		0x008988),
     99	REG(ANA_PORT_VLAN_CFG,			0x007800),
    100	REG(ANA_PORT_DROP_CFG,			0x007804),
    101	REG(ANA_PORT_QOS_CFG,			0x007808),
    102	REG(ANA_PORT_VCAP_CFG,			0x00780c),
    103	REG(ANA_PORT_VCAP_S1_KEY_CFG,		0x007810),
    104	REG(ANA_PORT_VCAP_S2_CFG,		0x00781c),
    105	REG(ANA_PORT_PCP_DEI_MAP,		0x007820),
    106	REG(ANA_PORT_CPU_FWD_CFG,		0x007860),
    107	REG(ANA_PORT_CPU_FWD_BPDU_CFG,		0x007864),
    108	REG(ANA_PORT_CPU_FWD_GARP_CFG,		0x007868),
    109	REG(ANA_PORT_CPU_FWD_CCM_CFG,		0x00786c),
    110	REG(ANA_PORT_PORT_CFG,			0x007870),
    111	REG(ANA_PORT_POL_CFG,			0x007874),
    112	REG(ANA_PORT_PTP_CFG,			0x007878),
    113	REG(ANA_PORT_PTP_DLY1_CFG,		0x00787c),
    114	REG(ANA_PORT_PTP_DLY2_CFG,		0x007880),
    115	REG(ANA_PORT_SFID_CFG,			0x007884),
    116	REG(ANA_PFC_PFC_CFG,			0x008800),
    117	REG_RESERVED(ANA_PFC_PFC_TIMER),
    118	REG_RESERVED(ANA_IPT_OAM_MEP_CFG),
    119	REG_RESERVED(ANA_IPT_IPT),
    120	REG_RESERVED(ANA_PPT_PPT),
    121	REG_RESERVED(ANA_FID_MAP_FID_MAP),
    122	REG(ANA_AGGR_CFG,			0x008a68),
    123	REG(ANA_CPUQ_CFG,			0x008a6c),
    124	REG_RESERVED(ANA_CPUQ_CFG2),
    125	REG(ANA_CPUQ_8021_CFG,			0x008a74),
    126	REG(ANA_DSCP_CFG,			0x008ab4),
    127	REG(ANA_DSCP_REWR_CFG,			0x008bb4),
    128	REG(ANA_VCAP_RNG_TYPE_CFG,		0x008bf4),
    129	REG(ANA_VCAP_RNG_VAL_CFG,		0x008c14),
    130	REG_RESERVED(ANA_VRAP_CFG),
    131	REG_RESERVED(ANA_VRAP_HDR_DATA),
    132	REG_RESERVED(ANA_VRAP_HDR_MASK),
    133	REG(ANA_DISCARD_CFG,			0x008c40),
    134	REG(ANA_FID_CFG,			0x008c44),
    135	REG(ANA_POL_PIR_CFG,			0x004000),
    136	REG(ANA_POL_CIR_CFG,			0x004004),
    137	REG(ANA_POL_MODE_CFG,			0x004008),
    138	REG(ANA_POL_PIR_STATE,			0x00400c),
    139	REG(ANA_POL_CIR_STATE,			0x004010),
    140	REG_RESERVED(ANA_POL_STATE),
    141	REG(ANA_POL_FLOWC,			0x008c48),
    142	REG(ANA_POL_HYST,			0x008cb4),
    143	REG_RESERVED(ANA_POL_MISC_CFG),
    144};
    145
    146static const u32 vsc9959_qs_regmap[] = {
    147	REG(QS_XTR_GRP_CFG,			0x000000),
    148	REG(QS_XTR_RD,				0x000008),
    149	REG(QS_XTR_FRM_PRUNING,			0x000010),
    150	REG(QS_XTR_FLUSH,			0x000018),
    151	REG(QS_XTR_DATA_PRESENT,		0x00001c),
    152	REG(QS_XTR_CFG,				0x000020),
    153	REG(QS_INJ_GRP_CFG,			0x000024),
    154	REG(QS_INJ_WR,				0x00002c),
    155	REG(QS_INJ_CTRL,			0x000034),
    156	REG(QS_INJ_STATUS,			0x00003c),
    157	REG(QS_INJ_ERR,				0x000040),
    158	REG_RESERVED(QS_INH_DBG),
    159};
    160
    161static const u32 vsc9959_vcap_regmap[] = {
    162	/* VCAP_CORE_CFG */
    163	REG(VCAP_CORE_UPDATE_CTRL,		0x000000),
    164	REG(VCAP_CORE_MV_CFG,			0x000004),
    165	/* VCAP_CORE_CACHE */
    166	REG(VCAP_CACHE_ENTRY_DAT,		0x000008),
    167	REG(VCAP_CACHE_MASK_DAT,		0x000108),
    168	REG(VCAP_CACHE_ACTION_DAT,		0x000208),
    169	REG(VCAP_CACHE_CNT_DAT,			0x000308),
    170	REG(VCAP_CACHE_TG_DAT,			0x000388),
    171	/* VCAP_CONST */
    172	REG(VCAP_CONST_VCAP_VER,		0x000398),
    173	REG(VCAP_CONST_ENTRY_WIDTH,		0x00039c),
    174	REG(VCAP_CONST_ENTRY_CNT,		0x0003a0),
    175	REG(VCAP_CONST_ENTRY_SWCNT,		0x0003a4),
    176	REG(VCAP_CONST_ENTRY_TG_WIDTH,		0x0003a8),
    177	REG(VCAP_CONST_ACTION_DEF_CNT,		0x0003ac),
    178	REG(VCAP_CONST_ACTION_WIDTH,		0x0003b0),
    179	REG(VCAP_CONST_CNT_WIDTH,		0x0003b4),
    180	REG(VCAP_CONST_CORE_CNT,		0x0003b8),
    181	REG(VCAP_CONST_IF_CNT,			0x0003bc),
    182};
    183
    184static const u32 vsc9959_qsys_regmap[] = {
    185	REG(QSYS_PORT_MODE,			0x00f460),
    186	REG(QSYS_SWITCH_PORT_MODE,		0x00f480),
    187	REG(QSYS_STAT_CNT_CFG,			0x00f49c),
    188	REG(QSYS_EEE_CFG,			0x00f4a0),
    189	REG(QSYS_EEE_THRES,			0x00f4b8),
    190	REG(QSYS_IGR_NO_SHARING,		0x00f4bc),
    191	REG(QSYS_EGR_NO_SHARING,		0x00f4c0),
    192	REG(QSYS_SW_STATUS,			0x00f4c4),
    193	REG(QSYS_EXT_CPU_CFG,			0x00f4e0),
    194	REG_RESERVED(QSYS_PAD_CFG),
    195	REG(QSYS_CPU_GROUP_MAP,			0x00f4e8),
    196	REG_RESERVED(QSYS_QMAP),
    197	REG_RESERVED(QSYS_ISDX_SGRP),
    198	REG_RESERVED(QSYS_TIMED_FRAME_ENTRY),
    199	REG(QSYS_TFRM_MISC,			0x00f50c),
    200	REG(QSYS_TFRM_PORT_DLY,			0x00f510),
    201	REG(QSYS_TFRM_TIMER_CFG_1,		0x00f514),
    202	REG(QSYS_TFRM_TIMER_CFG_2,		0x00f518),
    203	REG(QSYS_TFRM_TIMER_CFG_3,		0x00f51c),
    204	REG(QSYS_TFRM_TIMER_CFG_4,		0x00f520),
    205	REG(QSYS_TFRM_TIMER_CFG_5,		0x00f524),
    206	REG(QSYS_TFRM_TIMER_CFG_6,		0x00f528),
    207	REG(QSYS_TFRM_TIMER_CFG_7,		0x00f52c),
    208	REG(QSYS_TFRM_TIMER_CFG_8,		0x00f530),
    209	REG(QSYS_RED_PROFILE,			0x00f534),
    210	REG(QSYS_RES_QOS_MODE,			0x00f574),
    211	REG(QSYS_RES_CFG,			0x00c000),
    212	REG(QSYS_RES_STAT,			0x00c004),
    213	REG(QSYS_EGR_DROP_MODE,			0x00f578),
    214	REG(QSYS_EQ_CTRL,			0x00f57c),
    215	REG_RESERVED(QSYS_EVENTS_CORE),
    216	REG(QSYS_QMAXSDU_CFG_0,			0x00f584),
    217	REG(QSYS_QMAXSDU_CFG_1,			0x00f5a0),
    218	REG(QSYS_QMAXSDU_CFG_2,			0x00f5bc),
    219	REG(QSYS_QMAXSDU_CFG_3,			0x00f5d8),
    220	REG(QSYS_QMAXSDU_CFG_4,			0x00f5f4),
    221	REG(QSYS_QMAXSDU_CFG_5,			0x00f610),
    222	REG(QSYS_QMAXSDU_CFG_6,			0x00f62c),
    223	REG(QSYS_QMAXSDU_CFG_7,			0x00f648),
    224	REG(QSYS_PREEMPTION_CFG,		0x00f664),
    225	REG(QSYS_CIR_CFG,			0x000000),
    226	REG(QSYS_EIR_CFG,			0x000004),
    227	REG(QSYS_SE_CFG,			0x000008),
    228	REG(QSYS_SE_DWRR_CFG,			0x00000c),
    229	REG_RESERVED(QSYS_SE_CONNECT),
    230	REG(QSYS_SE_DLB_SENSE,			0x000040),
    231	REG(QSYS_CIR_STATE,			0x000044),
    232	REG(QSYS_EIR_STATE,			0x000048),
    233	REG_RESERVED(QSYS_SE_STATE),
    234	REG(QSYS_HSCH_MISC_CFG,			0x00f67c),
    235	REG(QSYS_TAG_CONFIG,			0x00f680),
    236	REG(QSYS_TAS_PARAM_CFG_CTRL,		0x00f698),
    237	REG(QSYS_PORT_MAX_SDU,			0x00f69c),
    238	REG(QSYS_PARAM_CFG_REG_1,		0x00f440),
    239	REG(QSYS_PARAM_CFG_REG_2,		0x00f444),
    240	REG(QSYS_PARAM_CFG_REG_3,		0x00f448),
    241	REG(QSYS_PARAM_CFG_REG_4,		0x00f44c),
    242	REG(QSYS_PARAM_CFG_REG_5,		0x00f450),
    243	REG(QSYS_GCL_CFG_REG_1,			0x00f454),
    244	REG(QSYS_GCL_CFG_REG_2,			0x00f458),
    245	REG(QSYS_PARAM_STATUS_REG_1,		0x00f400),
    246	REG(QSYS_PARAM_STATUS_REG_2,		0x00f404),
    247	REG(QSYS_PARAM_STATUS_REG_3,		0x00f408),
    248	REG(QSYS_PARAM_STATUS_REG_4,		0x00f40c),
    249	REG(QSYS_PARAM_STATUS_REG_5,		0x00f410),
    250	REG(QSYS_PARAM_STATUS_REG_6,		0x00f414),
    251	REG(QSYS_PARAM_STATUS_REG_7,		0x00f418),
    252	REG(QSYS_PARAM_STATUS_REG_8,		0x00f41c),
    253	REG(QSYS_PARAM_STATUS_REG_9,		0x00f420),
    254	REG(QSYS_GCL_STATUS_REG_1,		0x00f424),
    255	REG(QSYS_GCL_STATUS_REG_2,		0x00f428),
    256};
    257
    258static const u32 vsc9959_rew_regmap[] = {
    259	REG(REW_PORT_VLAN_CFG,			0x000000),
    260	REG(REW_TAG_CFG,			0x000004),
    261	REG(REW_PORT_CFG,			0x000008),
    262	REG(REW_DSCP_CFG,			0x00000c),
    263	REG(REW_PCP_DEI_QOS_MAP_CFG,		0x000010),
    264	REG(REW_PTP_CFG,			0x000050),
    265	REG(REW_PTP_DLY1_CFG,			0x000054),
    266	REG(REW_RED_TAG_CFG,			0x000058),
    267	REG(REW_DSCP_REMAP_DP1_CFG,		0x000410),
    268	REG(REW_DSCP_REMAP_CFG,			0x000510),
    269	REG_RESERVED(REW_STAT_CFG),
    270	REG_RESERVED(REW_REW_STICKY),
    271	REG_RESERVED(REW_PPT),
    272};
    273
    274static const u32 vsc9959_sys_regmap[] = {
    275	REG(SYS_COUNT_RX_OCTETS,		0x000000),
    276	REG(SYS_COUNT_RX_MULTICAST,		0x000008),
    277	REG(SYS_COUNT_RX_SHORTS,		0x000010),
    278	REG(SYS_COUNT_RX_FRAGMENTS,		0x000014),
    279	REG(SYS_COUNT_RX_JABBERS,		0x000018),
    280	REG(SYS_COUNT_RX_64,			0x000024),
    281	REG(SYS_COUNT_RX_65_127,		0x000028),
    282	REG(SYS_COUNT_RX_128_255,		0x00002c),
    283	REG(SYS_COUNT_RX_256_1023,		0x000030),
    284	REG(SYS_COUNT_RX_1024_1526,		0x000034),
    285	REG(SYS_COUNT_RX_1527_MAX,		0x000038),
    286	REG(SYS_COUNT_RX_LONGS,			0x000044),
    287	REG(SYS_COUNT_TX_OCTETS,		0x000200),
    288	REG(SYS_COUNT_TX_COLLISION,		0x000210),
    289	REG(SYS_COUNT_TX_DROPS,			0x000214),
    290	REG(SYS_COUNT_TX_64,			0x00021c),
    291	REG(SYS_COUNT_TX_65_127,		0x000220),
    292	REG(SYS_COUNT_TX_128_511,		0x000224),
    293	REG(SYS_COUNT_TX_512_1023,		0x000228),
    294	REG(SYS_COUNT_TX_1024_1526,		0x00022c),
    295	REG(SYS_COUNT_TX_1527_MAX,		0x000230),
    296	REG(SYS_COUNT_TX_AGING,			0x000278),
    297	REG(SYS_RESET_CFG,			0x000e00),
    298	REG(SYS_SR_ETYPE_CFG,			0x000e04),
    299	REG(SYS_VLAN_ETYPE_CFG,			0x000e08),
    300	REG(SYS_PORT_MODE,			0x000e0c),
    301	REG(SYS_FRONT_PORT_MODE,		0x000e2c),
    302	REG(SYS_FRM_AGING,			0x000e44),
    303	REG(SYS_STAT_CFG,			0x000e48),
    304	REG(SYS_SW_STATUS,			0x000e4c),
    305	REG_RESERVED(SYS_MISC_CFG),
    306	REG(SYS_REW_MAC_HIGH_CFG,		0x000e6c),
    307	REG(SYS_REW_MAC_LOW_CFG,		0x000e84),
    308	REG(SYS_TIMESTAMP_OFFSET,		0x000e9c),
    309	REG(SYS_PAUSE_CFG,			0x000ea0),
    310	REG(SYS_PAUSE_TOT_CFG,			0x000ebc),
    311	REG(SYS_ATOP,				0x000ec0),
    312	REG(SYS_ATOP_TOT_CFG,			0x000edc),
    313	REG(SYS_MAC_FC_CFG,			0x000ee0),
    314	REG(SYS_MMGT,				0x000ef8),
    315	REG_RESERVED(SYS_MMGT_FAST),
    316	REG_RESERVED(SYS_EVENTS_DIF),
    317	REG_RESERVED(SYS_EVENTS_CORE),
    318	REG(SYS_CNT,				0x000000),
    319	REG(SYS_PTP_STATUS,			0x000f14),
    320	REG(SYS_PTP_TXSTAMP,			0x000f18),
    321	REG(SYS_PTP_NXT,			0x000f1c),
    322	REG(SYS_PTP_CFG,			0x000f20),
    323	REG(SYS_RAM_INIT,			0x000f24),
    324	REG_RESERVED(SYS_CM_ADDR),
    325	REG_RESERVED(SYS_CM_DATA_WR),
    326	REG_RESERVED(SYS_CM_DATA_RD),
    327	REG_RESERVED(SYS_CM_OP),
    328	REG_RESERVED(SYS_CM_DATA),
    329};
    330
    331static const u32 vsc9959_ptp_regmap[] = {
    332	REG(PTP_PIN_CFG,			0x000000),
    333	REG(PTP_PIN_TOD_SEC_MSB,		0x000004),
    334	REG(PTP_PIN_TOD_SEC_LSB,		0x000008),
    335	REG(PTP_PIN_TOD_NSEC,			0x00000c),
    336	REG(PTP_PIN_WF_HIGH_PERIOD,		0x000014),
    337	REG(PTP_PIN_WF_LOW_PERIOD,		0x000018),
    338	REG(PTP_CFG_MISC,			0x0000a0),
    339	REG(PTP_CLK_CFG_ADJ_CFG,		0x0000a4),
    340	REG(PTP_CLK_CFG_ADJ_FREQ,		0x0000a8),
    341};
    342
    343static const u32 vsc9959_gcb_regmap[] = {
    344	REG(GCB_SOFT_RST,			0x000004),
    345};
    346
    347static const u32 vsc9959_dev_gmii_regmap[] = {
    348	REG(DEV_CLOCK_CFG,			0x0),
    349	REG(DEV_PORT_MISC,			0x4),
    350	REG(DEV_EVENTS,				0x8),
    351	REG(DEV_EEE_CFG,			0xc),
    352	REG(DEV_RX_PATH_DELAY,			0x10),
    353	REG(DEV_TX_PATH_DELAY,			0x14),
    354	REG(DEV_PTP_PREDICT_CFG,		0x18),
    355	REG(DEV_MAC_ENA_CFG,			0x1c),
    356	REG(DEV_MAC_MODE_CFG,			0x20),
    357	REG(DEV_MAC_MAXLEN_CFG,			0x24),
    358	REG(DEV_MAC_TAGS_CFG,			0x28),
    359	REG(DEV_MAC_ADV_CHK_CFG,		0x2c),
    360	REG(DEV_MAC_IFG_CFG,			0x30),
    361	REG(DEV_MAC_HDX_CFG,			0x34),
    362	REG(DEV_MAC_DBG_CFG,			0x38),
    363	REG(DEV_MAC_FC_MAC_LOW_CFG,		0x3c),
    364	REG(DEV_MAC_FC_MAC_HIGH_CFG,		0x40),
    365	REG(DEV_MAC_STICKY,			0x44),
    366	REG_RESERVED(PCS1G_CFG),
    367	REG_RESERVED(PCS1G_MODE_CFG),
    368	REG_RESERVED(PCS1G_SD_CFG),
    369	REG_RESERVED(PCS1G_ANEG_CFG),
    370	REG_RESERVED(PCS1G_ANEG_NP_CFG),
    371	REG_RESERVED(PCS1G_LB_CFG),
    372	REG_RESERVED(PCS1G_DBG_CFG),
    373	REG_RESERVED(PCS1G_CDET_CFG),
    374	REG_RESERVED(PCS1G_ANEG_STATUS),
    375	REG_RESERVED(PCS1G_ANEG_NP_STATUS),
    376	REG_RESERVED(PCS1G_LINK_STATUS),
    377	REG_RESERVED(PCS1G_LINK_DOWN_CNT),
    378	REG_RESERVED(PCS1G_STICKY),
    379	REG_RESERVED(PCS1G_DEBUG_STATUS),
    380	REG_RESERVED(PCS1G_LPI_CFG),
    381	REG_RESERVED(PCS1G_LPI_WAKE_ERROR_CNT),
    382	REG_RESERVED(PCS1G_LPI_STATUS),
    383	REG_RESERVED(PCS1G_TSTPAT_MODE_CFG),
    384	REG_RESERVED(PCS1G_TSTPAT_STATUS),
    385	REG_RESERVED(DEV_PCS_FX100_CFG),
    386	REG_RESERVED(DEV_PCS_FX100_STATUS),
    387};
    388
    389static const u32 *vsc9959_regmap[TARGET_MAX] = {
    390	[ANA]	= vsc9959_ana_regmap,
    391	[QS]	= vsc9959_qs_regmap,
    392	[QSYS]	= vsc9959_qsys_regmap,
    393	[REW]	= vsc9959_rew_regmap,
    394	[SYS]	= vsc9959_sys_regmap,
    395	[S0]	= vsc9959_vcap_regmap,
    396	[S1]	= vsc9959_vcap_regmap,
    397	[S2]	= vsc9959_vcap_regmap,
    398	[PTP]	= vsc9959_ptp_regmap,
    399	[GCB]	= vsc9959_gcb_regmap,
    400	[DEV_GMII] = vsc9959_dev_gmii_regmap,
    401};
    402
    403/* Addresses are relative to the PCI device's base address */
    404static const struct resource vsc9959_target_io_res[TARGET_MAX] = {
    405	[ANA] = {
    406		.start	= 0x0280000,
    407		.end	= 0x028ffff,
    408		.name	= "ana",
    409	},
    410	[QS] = {
    411		.start	= 0x0080000,
    412		.end	= 0x00800ff,
    413		.name	= "qs",
    414	},
    415	[QSYS] = {
    416		.start	= 0x0200000,
    417		.end	= 0x021ffff,
    418		.name	= "qsys",
    419	},
    420	[REW] = {
    421		.start	= 0x0030000,
    422		.end	= 0x003ffff,
    423		.name	= "rew",
    424	},
    425	[SYS] = {
    426		.start	= 0x0010000,
    427		.end	= 0x001ffff,
    428		.name	= "sys",
    429	},
    430	[S0] = {
    431		.start	= 0x0040000,
    432		.end	= 0x00403ff,
    433		.name	= "s0",
    434	},
    435	[S1] = {
    436		.start	= 0x0050000,
    437		.end	= 0x00503ff,
    438		.name	= "s1",
    439	},
    440	[S2] = {
    441		.start	= 0x0060000,
    442		.end	= 0x00603ff,
    443		.name	= "s2",
    444	},
    445	[PTP] = {
    446		.start	= 0x0090000,
    447		.end	= 0x00900cb,
    448		.name	= "ptp",
    449	},
    450	[GCB] = {
    451		.start	= 0x0070000,
    452		.end	= 0x00701ff,
    453		.name	= "devcpu_gcb",
    454	},
    455};
    456
    457static const struct resource vsc9959_port_io_res[] = {
    458	{
    459		.start	= 0x0100000,
    460		.end	= 0x010ffff,
    461		.name	= "port0",
    462	},
    463	{
    464		.start	= 0x0110000,
    465		.end	= 0x011ffff,
    466		.name	= "port1",
    467	},
    468	{
    469		.start	= 0x0120000,
    470		.end	= 0x012ffff,
    471		.name	= "port2",
    472	},
    473	{
    474		.start	= 0x0130000,
    475		.end	= 0x013ffff,
    476		.name	= "port3",
    477	},
    478	{
    479		.start	= 0x0140000,
    480		.end	= 0x014ffff,
    481		.name	= "port4",
    482	},
    483	{
    484		.start	= 0x0150000,
    485		.end	= 0x015ffff,
    486		.name	= "port5",
    487	},
    488};
    489
    490/* Port MAC 0 Internal MDIO bus through which the SerDes acting as an
    491 * SGMII/QSGMII MAC PCS can be found.
    492 */
    493static const struct resource vsc9959_imdio_res = {
    494	.start		= 0x8030,
    495	.end		= 0x8040,
    496	.name		= "imdio",
    497};
    498
    499static const struct reg_field vsc9959_regfields[REGFIELD_MAX] = {
    500	[ANA_ADVLEARN_VLAN_CHK] = REG_FIELD(ANA_ADVLEARN, 6, 6),
    501	[ANA_ADVLEARN_LEARN_MIRROR] = REG_FIELD(ANA_ADVLEARN, 0, 5),
    502	[ANA_ANEVENTS_FLOOD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 30, 30),
    503	[ANA_ANEVENTS_AUTOAGE] = REG_FIELD(ANA_ANEVENTS, 26, 26),
    504	[ANA_ANEVENTS_STORM_DROP] = REG_FIELD(ANA_ANEVENTS, 24, 24),
    505	[ANA_ANEVENTS_LEARN_DROP] = REG_FIELD(ANA_ANEVENTS, 23, 23),
    506	[ANA_ANEVENTS_AGED_ENTRY] = REG_FIELD(ANA_ANEVENTS, 22, 22),
    507	[ANA_ANEVENTS_CPU_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 21, 21),
    508	[ANA_ANEVENTS_AUTO_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 20, 20),
    509	[ANA_ANEVENTS_LEARN_REMOVE] = REG_FIELD(ANA_ANEVENTS, 19, 19),
    510	[ANA_ANEVENTS_AUTO_LEARNED] = REG_FIELD(ANA_ANEVENTS, 18, 18),
    511	[ANA_ANEVENTS_AUTO_MOVED] = REG_FIELD(ANA_ANEVENTS, 17, 17),
    512	[ANA_ANEVENTS_CLASSIFIED_DROP] = REG_FIELD(ANA_ANEVENTS, 15, 15),
    513	[ANA_ANEVENTS_CLASSIFIED_COPY] = REG_FIELD(ANA_ANEVENTS, 14, 14),
    514	[ANA_ANEVENTS_VLAN_DISCARD] = REG_FIELD(ANA_ANEVENTS, 13, 13),
    515	[ANA_ANEVENTS_FWD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 12, 12),
    516	[ANA_ANEVENTS_MULTICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 11, 11),
    517	[ANA_ANEVENTS_UNICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 10, 10),
    518	[ANA_ANEVENTS_DEST_KNOWN] = REG_FIELD(ANA_ANEVENTS, 9, 9),
    519	[ANA_ANEVENTS_BUCKET3_MATCH] = REG_FIELD(ANA_ANEVENTS, 8, 8),
    520	[ANA_ANEVENTS_BUCKET2_MATCH] = REG_FIELD(ANA_ANEVENTS, 7, 7),
    521	[ANA_ANEVENTS_BUCKET1_MATCH] = REG_FIELD(ANA_ANEVENTS, 6, 6),
    522	[ANA_ANEVENTS_BUCKET0_MATCH] = REG_FIELD(ANA_ANEVENTS, 5, 5),
    523	[ANA_ANEVENTS_CPU_OPERATION] = REG_FIELD(ANA_ANEVENTS, 4, 4),
    524	[ANA_ANEVENTS_DMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 3, 3),
    525	[ANA_ANEVENTS_SMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 2, 2),
    526	[ANA_ANEVENTS_SEQ_GEN_ERR_0] = REG_FIELD(ANA_ANEVENTS, 1, 1),
    527	[ANA_ANEVENTS_SEQ_GEN_ERR_1] = REG_FIELD(ANA_ANEVENTS, 0, 0),
    528	[ANA_TABLES_MACACCESS_B_DOM] = REG_FIELD(ANA_TABLES_MACACCESS, 16, 16),
    529	[ANA_TABLES_MACTINDX_BUCKET] = REG_FIELD(ANA_TABLES_MACTINDX, 11, 12),
    530	[ANA_TABLES_MACTINDX_M_INDEX] = REG_FIELD(ANA_TABLES_MACTINDX, 0, 10),
    531	[SYS_RESET_CFG_CORE_ENA] = REG_FIELD(SYS_RESET_CFG, 0, 0),
    532	[GCB_SOFT_RST_SWC_RST] = REG_FIELD(GCB_SOFT_RST, 0, 0),
    533	/* Replicated per number of ports (7), register size 4 per port */
    534	[QSYS_SWITCH_PORT_MODE_PORT_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 14, 14, 7, 4),
    535	[QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 11, 13, 7, 4),
    536	[QSYS_SWITCH_PORT_MODE_YEL_RSRVD] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 10, 10, 7, 4),
    537	[QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 9, 9, 7, 4),
    538	[QSYS_SWITCH_PORT_MODE_TX_PFC_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 1, 8, 7, 4),
    539	[QSYS_SWITCH_PORT_MODE_TX_PFC_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 0, 0, 7, 4),
    540	[SYS_PORT_MODE_DATA_WO_TS] = REG_FIELD_ID(SYS_PORT_MODE, 5, 6, 7, 4),
    541	[SYS_PORT_MODE_INCL_INJ_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 3, 4, 7, 4),
    542	[SYS_PORT_MODE_INCL_XTR_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 1, 2, 7, 4),
    543	[SYS_PORT_MODE_INCL_HDR_ERR] = REG_FIELD_ID(SYS_PORT_MODE, 0, 0, 7, 4),
    544	[SYS_PAUSE_CFG_PAUSE_START] = REG_FIELD_ID(SYS_PAUSE_CFG, 10, 18, 7, 4),
    545	[SYS_PAUSE_CFG_PAUSE_STOP] = REG_FIELD_ID(SYS_PAUSE_CFG, 1, 9, 7, 4),
    546	[SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 7, 4),
    547};
    548
    549static const struct ocelot_stat_layout vsc9959_stats_layout[] = {
    550	{ .offset = 0x00,	.name = "rx_octets", },
    551	{ .offset = 0x01,	.name = "rx_unicast", },
    552	{ .offset = 0x02,	.name = "rx_multicast", },
    553	{ .offset = 0x03,	.name = "rx_broadcast", },
    554	{ .offset = 0x04,	.name = "rx_shorts", },
    555	{ .offset = 0x05,	.name = "rx_fragments", },
    556	{ .offset = 0x06,	.name = "rx_jabbers", },
    557	{ .offset = 0x07,	.name = "rx_crc_align_errs", },
    558	{ .offset = 0x08,	.name = "rx_sym_errs", },
    559	{ .offset = 0x09,	.name = "rx_frames_below_65_octets", },
    560	{ .offset = 0x0A,	.name = "rx_frames_65_to_127_octets", },
    561	{ .offset = 0x0B,	.name = "rx_frames_128_to_255_octets", },
    562	{ .offset = 0x0C,	.name = "rx_frames_256_to_511_octets", },
    563	{ .offset = 0x0D,	.name = "rx_frames_512_to_1023_octets", },
    564	{ .offset = 0x0E,	.name = "rx_frames_1024_to_1526_octets", },
    565	{ .offset = 0x0F,	.name = "rx_frames_over_1526_octets", },
    566	{ .offset = 0x10,	.name = "rx_pause", },
    567	{ .offset = 0x11,	.name = "rx_control", },
    568	{ .offset = 0x12,	.name = "rx_longs", },
    569	{ .offset = 0x13,	.name = "rx_classified_drops", },
    570	{ .offset = 0x14,	.name = "rx_red_prio_0", },
    571	{ .offset = 0x15,	.name = "rx_red_prio_1", },
    572	{ .offset = 0x16,	.name = "rx_red_prio_2", },
    573	{ .offset = 0x17,	.name = "rx_red_prio_3", },
    574	{ .offset = 0x18,	.name = "rx_red_prio_4", },
    575	{ .offset = 0x19,	.name = "rx_red_prio_5", },
    576	{ .offset = 0x1A,	.name = "rx_red_prio_6", },
    577	{ .offset = 0x1B,	.name = "rx_red_prio_7", },
    578	{ .offset = 0x1C,	.name = "rx_yellow_prio_0", },
    579	{ .offset = 0x1D,	.name = "rx_yellow_prio_1", },
    580	{ .offset = 0x1E,	.name = "rx_yellow_prio_2", },
    581	{ .offset = 0x1F,	.name = "rx_yellow_prio_3", },
    582	{ .offset = 0x20,	.name = "rx_yellow_prio_4", },
    583	{ .offset = 0x21,	.name = "rx_yellow_prio_5", },
    584	{ .offset = 0x22,	.name = "rx_yellow_prio_6", },
    585	{ .offset = 0x23,	.name = "rx_yellow_prio_7", },
    586	{ .offset = 0x24,	.name = "rx_green_prio_0", },
    587	{ .offset = 0x25,	.name = "rx_green_prio_1", },
    588	{ .offset = 0x26,	.name = "rx_green_prio_2", },
    589	{ .offset = 0x27,	.name = "rx_green_prio_3", },
    590	{ .offset = 0x28,	.name = "rx_green_prio_4", },
    591	{ .offset = 0x29,	.name = "rx_green_prio_5", },
    592	{ .offset = 0x2A,	.name = "rx_green_prio_6", },
    593	{ .offset = 0x2B,	.name = "rx_green_prio_7", },
    594	{ .offset = 0x80,	.name = "tx_octets", },
    595	{ .offset = 0x81,	.name = "tx_unicast", },
    596	{ .offset = 0x82,	.name = "tx_multicast", },
    597	{ .offset = 0x83,	.name = "tx_broadcast", },
    598	{ .offset = 0x84,	.name = "tx_collision", },
    599	{ .offset = 0x85,	.name = "tx_drops", },
    600	{ .offset = 0x86,	.name = "tx_pause", },
    601	{ .offset = 0x87,	.name = "tx_frames_below_65_octets", },
    602	{ .offset = 0x88,	.name = "tx_frames_65_to_127_octets", },
    603	{ .offset = 0x89,	.name = "tx_frames_128_255_octets", },
    604	{ .offset = 0x8B,	.name = "tx_frames_256_511_octets", },
    605	{ .offset = 0x8C,	.name = "tx_frames_1024_1526_octets", },
    606	{ .offset = 0x8D,	.name = "tx_frames_over_1526_octets", },
    607	{ .offset = 0x8E,	.name = "tx_yellow_prio_0", },
    608	{ .offset = 0x8F,	.name = "tx_yellow_prio_1", },
    609	{ .offset = 0x90,	.name = "tx_yellow_prio_2", },
    610	{ .offset = 0x91,	.name = "tx_yellow_prio_3", },
    611	{ .offset = 0x92,	.name = "tx_yellow_prio_4", },
    612	{ .offset = 0x93,	.name = "tx_yellow_prio_5", },
    613	{ .offset = 0x94,	.name = "tx_yellow_prio_6", },
    614	{ .offset = 0x95,	.name = "tx_yellow_prio_7", },
    615	{ .offset = 0x96,	.name = "tx_green_prio_0", },
    616	{ .offset = 0x97,	.name = "tx_green_prio_1", },
    617	{ .offset = 0x98,	.name = "tx_green_prio_2", },
    618	{ .offset = 0x99,	.name = "tx_green_prio_3", },
    619	{ .offset = 0x9A,	.name = "tx_green_prio_4", },
    620	{ .offset = 0x9B,	.name = "tx_green_prio_5", },
    621	{ .offset = 0x9C,	.name = "tx_green_prio_6", },
    622	{ .offset = 0x9D,	.name = "tx_green_prio_7", },
    623	{ .offset = 0x9E,	.name = "tx_aged", },
    624	{ .offset = 0x100,	.name = "drop_local", },
    625	{ .offset = 0x101,	.name = "drop_tail", },
    626	{ .offset = 0x102,	.name = "drop_yellow_prio_0", },
    627	{ .offset = 0x103,	.name = "drop_yellow_prio_1", },
    628	{ .offset = 0x104,	.name = "drop_yellow_prio_2", },
    629	{ .offset = 0x105,	.name = "drop_yellow_prio_3", },
    630	{ .offset = 0x106,	.name = "drop_yellow_prio_4", },
    631	{ .offset = 0x107,	.name = "drop_yellow_prio_5", },
    632	{ .offset = 0x108,	.name = "drop_yellow_prio_6", },
    633	{ .offset = 0x109,	.name = "drop_yellow_prio_7", },
    634	{ .offset = 0x10A,	.name = "drop_green_prio_0", },
    635	{ .offset = 0x10B,	.name = "drop_green_prio_1", },
    636	{ .offset = 0x10C,	.name = "drop_green_prio_2", },
    637	{ .offset = 0x10D,	.name = "drop_green_prio_3", },
    638	{ .offset = 0x10E,	.name = "drop_green_prio_4", },
    639	{ .offset = 0x10F,	.name = "drop_green_prio_5", },
    640	{ .offset = 0x110,	.name = "drop_green_prio_6", },
    641	{ .offset = 0x111,	.name = "drop_green_prio_7", },
    642	OCELOT_STAT_END
    643};
    644
    645static const struct vcap_field vsc9959_vcap_es0_keys[] = {
    646	[VCAP_ES0_EGR_PORT]			= {  0,  3},
    647	[VCAP_ES0_IGR_PORT]			= {  3,  3},
    648	[VCAP_ES0_RSV]				= {  6,  2},
    649	[VCAP_ES0_L2_MC]			= {  8,  1},
    650	[VCAP_ES0_L2_BC]			= {  9,  1},
    651	[VCAP_ES0_VID]				= { 10, 12},
    652	[VCAP_ES0_DP]				= { 22,  1},
    653	[VCAP_ES0_PCP]				= { 23,  3},
    654};
    655
    656static const struct vcap_field vsc9959_vcap_es0_actions[] = {
    657	[VCAP_ES0_ACT_PUSH_OUTER_TAG]		= {  0,  2},
    658	[VCAP_ES0_ACT_PUSH_INNER_TAG]		= {  2,  1},
    659	[VCAP_ES0_ACT_TAG_A_TPID_SEL]		= {  3,  2},
    660	[VCAP_ES0_ACT_TAG_A_VID_SEL]		= {  5,  1},
    661	[VCAP_ES0_ACT_TAG_A_PCP_SEL]		= {  6,  2},
    662	[VCAP_ES0_ACT_TAG_A_DEI_SEL]		= {  8,  2},
    663	[VCAP_ES0_ACT_TAG_B_TPID_SEL]		= { 10,  2},
    664	[VCAP_ES0_ACT_TAG_B_VID_SEL]		= { 12,  1},
    665	[VCAP_ES0_ACT_TAG_B_PCP_SEL]		= { 13,  2},
    666	[VCAP_ES0_ACT_TAG_B_DEI_SEL]		= { 15,  2},
    667	[VCAP_ES0_ACT_VID_A_VAL]		= { 17, 12},
    668	[VCAP_ES0_ACT_PCP_A_VAL]		= { 29,  3},
    669	[VCAP_ES0_ACT_DEI_A_VAL]		= { 32,  1},
    670	[VCAP_ES0_ACT_VID_B_VAL]		= { 33, 12},
    671	[VCAP_ES0_ACT_PCP_B_VAL]		= { 45,  3},
    672	[VCAP_ES0_ACT_DEI_B_VAL]		= { 48,  1},
    673	[VCAP_ES0_ACT_RSV]			= { 49, 23},
    674	[VCAP_ES0_ACT_HIT_STICKY]		= { 72,  1},
    675};
    676
    677static const struct vcap_field vsc9959_vcap_is1_keys[] = {
    678	[VCAP_IS1_HK_TYPE]			= {  0,   1},
    679	[VCAP_IS1_HK_LOOKUP]			= {  1,   2},
    680	[VCAP_IS1_HK_IGR_PORT_MASK]		= {  3,   7},
    681	[VCAP_IS1_HK_RSV]			= { 10,   9},
    682	[VCAP_IS1_HK_OAM_Y1731]			= { 19,   1},
    683	[VCAP_IS1_HK_L2_MC]			= { 20,   1},
    684	[VCAP_IS1_HK_L2_BC]			= { 21,   1},
    685	[VCAP_IS1_HK_IP_MC]			= { 22,   1},
    686	[VCAP_IS1_HK_VLAN_TAGGED]		= { 23,   1},
    687	[VCAP_IS1_HK_VLAN_DBL_TAGGED]		= { 24,   1},
    688	[VCAP_IS1_HK_TPID]			= { 25,   1},
    689	[VCAP_IS1_HK_VID]			= { 26,  12},
    690	[VCAP_IS1_HK_DEI]			= { 38,   1},
    691	[VCAP_IS1_HK_PCP]			= { 39,   3},
    692	/* Specific Fields for IS1 Half Key S1_NORMAL */
    693	[VCAP_IS1_HK_L2_SMAC]			= { 42,  48},
    694	[VCAP_IS1_HK_ETYPE_LEN]			= { 90,   1},
    695	[VCAP_IS1_HK_ETYPE]			= { 91,  16},
    696	[VCAP_IS1_HK_IP_SNAP]			= {107,   1},
    697	[VCAP_IS1_HK_IP4]			= {108,   1},
    698	/* Layer-3 Information */
    699	[VCAP_IS1_HK_L3_FRAGMENT]		= {109,   1},
    700	[VCAP_IS1_HK_L3_FRAG_OFS_GT0]		= {110,   1},
    701	[VCAP_IS1_HK_L3_OPTIONS]		= {111,   1},
    702	[VCAP_IS1_HK_L3_DSCP]			= {112,   6},
    703	[VCAP_IS1_HK_L3_IP4_SIP]		= {118,  32},
    704	/* Layer-4 Information */
    705	[VCAP_IS1_HK_TCP_UDP]			= {150,   1},
    706	[VCAP_IS1_HK_TCP]			= {151,   1},
    707	[VCAP_IS1_HK_L4_SPORT]			= {152,  16},
    708	[VCAP_IS1_HK_L4_RNG]			= {168,   8},
    709	/* Specific Fields for IS1 Half Key S1_5TUPLE_IP4 */
    710	[VCAP_IS1_HK_IP4_INNER_TPID]            = { 42,   1},
    711	[VCAP_IS1_HK_IP4_INNER_VID]		= { 43,  12},
    712	[VCAP_IS1_HK_IP4_INNER_DEI]		= { 55,   1},
    713	[VCAP_IS1_HK_IP4_INNER_PCP]		= { 56,   3},
    714	[VCAP_IS1_HK_IP4_IP4]			= { 59,   1},
    715	[VCAP_IS1_HK_IP4_L3_FRAGMENT]		= { 60,   1},
    716	[VCAP_IS1_HK_IP4_L3_FRAG_OFS_GT0]	= { 61,   1},
    717	[VCAP_IS1_HK_IP4_L3_OPTIONS]		= { 62,   1},
    718	[VCAP_IS1_HK_IP4_L3_DSCP]		= { 63,   6},
    719	[VCAP_IS1_HK_IP4_L3_IP4_DIP]		= { 69,  32},
    720	[VCAP_IS1_HK_IP4_L3_IP4_SIP]		= {101,  32},
    721	[VCAP_IS1_HK_IP4_L3_PROTO]		= {133,   8},
    722	[VCAP_IS1_HK_IP4_TCP_UDP]		= {141,   1},
    723	[VCAP_IS1_HK_IP4_TCP]			= {142,   1},
    724	[VCAP_IS1_HK_IP4_L4_RNG]		= {143,   8},
    725	[VCAP_IS1_HK_IP4_IP_PAYLOAD_S1_5TUPLE]	= {151,  32},
    726};
    727
    728static const struct vcap_field vsc9959_vcap_is1_actions[] = {
    729	[VCAP_IS1_ACT_DSCP_ENA]			= {  0,  1},
    730	[VCAP_IS1_ACT_DSCP_VAL]			= {  1,  6},
    731	[VCAP_IS1_ACT_QOS_ENA]			= {  7,  1},
    732	[VCAP_IS1_ACT_QOS_VAL]			= {  8,  3},
    733	[VCAP_IS1_ACT_DP_ENA]			= { 11,  1},
    734	[VCAP_IS1_ACT_DP_VAL]			= { 12,  1},
    735	[VCAP_IS1_ACT_PAG_OVERRIDE_MASK]	= { 13,  8},
    736	[VCAP_IS1_ACT_PAG_VAL]			= { 21,  8},
    737	[VCAP_IS1_ACT_RSV]			= { 29,  9},
    738	/* The fields below are incorrectly shifted by 2 in the manual */
    739	[VCAP_IS1_ACT_VID_REPLACE_ENA]		= { 38,  1},
    740	[VCAP_IS1_ACT_VID_ADD_VAL]		= { 39, 12},
    741	[VCAP_IS1_ACT_FID_SEL]			= { 51,  2},
    742	[VCAP_IS1_ACT_FID_VAL]			= { 53, 13},
    743	[VCAP_IS1_ACT_PCP_DEI_ENA]		= { 66,  1},
    744	[VCAP_IS1_ACT_PCP_VAL]			= { 67,  3},
    745	[VCAP_IS1_ACT_DEI_VAL]			= { 70,  1},
    746	[VCAP_IS1_ACT_VLAN_POP_CNT_ENA]		= { 71,  1},
    747	[VCAP_IS1_ACT_VLAN_POP_CNT]		= { 72,  2},
    748	[VCAP_IS1_ACT_CUSTOM_ACE_TYPE_ENA]	= { 74,  4},
    749	[VCAP_IS1_ACT_HIT_STICKY]		= { 78,  1},
    750};
    751
    752static struct vcap_field vsc9959_vcap_is2_keys[] = {
    753	/* Common: 41 bits */
    754	[VCAP_IS2_TYPE]				= {  0,   4},
    755	[VCAP_IS2_HK_FIRST]			= {  4,   1},
    756	[VCAP_IS2_HK_PAG]			= {  5,   8},
    757	[VCAP_IS2_HK_IGR_PORT_MASK]		= { 13,   7},
    758	[VCAP_IS2_HK_RSV2]			= { 20,   1},
    759	[VCAP_IS2_HK_HOST_MATCH]		= { 21,   1},
    760	[VCAP_IS2_HK_L2_MC]			= { 22,   1},
    761	[VCAP_IS2_HK_L2_BC]			= { 23,   1},
    762	[VCAP_IS2_HK_VLAN_TAGGED]		= { 24,   1},
    763	[VCAP_IS2_HK_VID]			= { 25,  12},
    764	[VCAP_IS2_HK_DEI]			= { 37,   1},
    765	[VCAP_IS2_HK_PCP]			= { 38,   3},
    766	/* MAC_ETYPE / MAC_LLC / MAC_SNAP / OAM common */
    767	[VCAP_IS2_HK_L2_DMAC]			= { 41,  48},
    768	[VCAP_IS2_HK_L2_SMAC]			= { 89,  48},
    769	/* MAC_ETYPE (TYPE=000) */
    770	[VCAP_IS2_HK_MAC_ETYPE_ETYPE]		= {137,  16},
    771	[VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0]	= {153,  16},
    772	[VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1]	= {169,   8},
    773	[VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2]	= {177,   3},
    774	/* MAC_LLC (TYPE=001) */
    775	[VCAP_IS2_HK_MAC_LLC_L2_LLC]		= {137,  40},
    776	/* MAC_SNAP (TYPE=010) */
    777	[VCAP_IS2_HK_MAC_SNAP_L2_SNAP]		= {137,  40},
    778	/* MAC_ARP (TYPE=011) */
    779	[VCAP_IS2_HK_MAC_ARP_SMAC]		= { 41,  48},
    780	[VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK]	= { 89,   1},
    781	[VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK]	= { 90,   1},
    782	[VCAP_IS2_HK_MAC_ARP_LEN_OK]		= { 91,   1},
    783	[VCAP_IS2_HK_MAC_ARP_TARGET_MATCH]	= { 92,   1},
    784	[VCAP_IS2_HK_MAC_ARP_SENDER_MATCH]	= { 93,   1},
    785	[VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN]	= { 94,   1},
    786	[VCAP_IS2_HK_MAC_ARP_OPCODE]		= { 95,   2},
    787	[VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP]	= { 97,  32},
    788	[VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP]	= {129,  32},
    789	[VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP]	= {161,   1},
    790	/* IP4_TCP_UDP / IP4_OTHER common */
    791	[VCAP_IS2_HK_IP4]			= { 41,   1},
    792	[VCAP_IS2_HK_L3_FRAGMENT]		= { 42,   1},
    793	[VCAP_IS2_HK_L3_FRAG_OFS_GT0]		= { 43,   1},
    794	[VCAP_IS2_HK_L3_OPTIONS]		= { 44,   1},
    795	[VCAP_IS2_HK_IP4_L3_TTL_GT0]		= { 45,   1},
    796	[VCAP_IS2_HK_L3_TOS]			= { 46,   8},
    797	[VCAP_IS2_HK_L3_IP4_DIP]		= { 54,  32},
    798	[VCAP_IS2_HK_L3_IP4_SIP]		= { 86,  32},
    799	[VCAP_IS2_HK_DIP_EQ_SIP]		= {118,   1},
    800	/* IP4_TCP_UDP (TYPE=100) */
    801	[VCAP_IS2_HK_TCP]			= {119,   1},
    802	[VCAP_IS2_HK_L4_DPORT]			= {120,  16},
    803	[VCAP_IS2_HK_L4_SPORT]			= {136,  16},
    804	[VCAP_IS2_HK_L4_RNG]			= {152,   8},
    805	[VCAP_IS2_HK_L4_SPORT_EQ_DPORT]		= {160,   1},
    806	[VCAP_IS2_HK_L4_SEQUENCE_EQ0]		= {161,   1},
    807	[VCAP_IS2_HK_L4_FIN]			= {162,   1},
    808	[VCAP_IS2_HK_L4_SYN]			= {163,   1},
    809	[VCAP_IS2_HK_L4_RST]			= {164,   1},
    810	[VCAP_IS2_HK_L4_PSH]			= {165,   1},
    811	[VCAP_IS2_HK_L4_ACK]			= {166,   1},
    812	[VCAP_IS2_HK_L4_URG]			= {167,   1},
    813	[VCAP_IS2_HK_L4_1588_DOM]		= {168,   8},
    814	[VCAP_IS2_HK_L4_1588_VER]		= {176,   4},
    815	/* IP4_OTHER (TYPE=101) */
    816	[VCAP_IS2_HK_IP4_L3_PROTO]		= {119,   8},
    817	[VCAP_IS2_HK_L3_PAYLOAD]		= {127,  56},
    818	/* IP6_STD (TYPE=110) */
    819	[VCAP_IS2_HK_IP6_L3_TTL_GT0]		= { 41,   1},
    820	[VCAP_IS2_HK_L3_IP6_SIP]		= { 42, 128},
    821	[VCAP_IS2_HK_IP6_L3_PROTO]		= {170,   8},
    822	/* OAM (TYPE=111) */
    823	[VCAP_IS2_HK_OAM_MEL_FLAGS]		= {137,   7},
    824	[VCAP_IS2_HK_OAM_VER]			= {144,   5},
    825	[VCAP_IS2_HK_OAM_OPCODE]		= {149,   8},
    826	[VCAP_IS2_HK_OAM_FLAGS]			= {157,   8},
    827	[VCAP_IS2_HK_OAM_MEPID]			= {165,  16},
    828	[VCAP_IS2_HK_OAM_CCM_CNTS_EQ0]		= {181,   1},
    829	[VCAP_IS2_HK_OAM_IS_Y1731]		= {182,   1},
    830};
    831
    832static struct vcap_field vsc9959_vcap_is2_actions[] = {
    833	[VCAP_IS2_ACT_HIT_ME_ONCE]		= {  0,  1},
    834	[VCAP_IS2_ACT_CPU_COPY_ENA]		= {  1,  1},
    835	[VCAP_IS2_ACT_CPU_QU_NUM]		= {  2,  3},
    836	[VCAP_IS2_ACT_MASK_MODE]		= {  5,  2},
    837	[VCAP_IS2_ACT_MIRROR_ENA]		= {  7,  1},
    838	[VCAP_IS2_ACT_LRN_DIS]			= {  8,  1},
    839	[VCAP_IS2_ACT_POLICE_ENA]		= {  9,  1},
    840	[VCAP_IS2_ACT_POLICE_IDX]		= { 10,  9},
    841	[VCAP_IS2_ACT_POLICE_VCAP_ONLY]		= { 19,  1},
    842	[VCAP_IS2_ACT_PORT_MASK]		= { 20,  6},
    843	[VCAP_IS2_ACT_REW_OP]			= { 26,  9},
    844	[VCAP_IS2_ACT_SMAC_REPLACE_ENA]		= { 35,  1},
    845	[VCAP_IS2_ACT_RSV]			= { 36,  2},
    846	[VCAP_IS2_ACT_ACL_ID]			= { 38,  6},
    847	[VCAP_IS2_ACT_HIT_CNT]			= { 44, 32},
    848};
    849
    850static struct vcap_props vsc9959_vcap_props[] = {
    851	[VCAP_ES0] = {
    852		.action_type_width = 0,
    853		.action_table = {
    854			[ES0_ACTION_TYPE_NORMAL] = {
    855				.width = 72, /* HIT_STICKY not included */
    856				.count = 1,
    857			},
    858		},
    859		.target = S0,
    860		.keys = vsc9959_vcap_es0_keys,
    861		.actions = vsc9959_vcap_es0_actions,
    862	},
    863	[VCAP_IS1] = {
    864		.action_type_width = 0,
    865		.action_table = {
    866			[IS1_ACTION_TYPE_NORMAL] = {
    867				.width = 78, /* HIT_STICKY not included */
    868				.count = 4,
    869			},
    870		},
    871		.target = S1,
    872		.keys = vsc9959_vcap_is1_keys,
    873		.actions = vsc9959_vcap_is1_actions,
    874	},
    875	[VCAP_IS2] = {
    876		.action_type_width = 1,
    877		.action_table = {
    878			[IS2_ACTION_TYPE_NORMAL] = {
    879				.width = 44,
    880				.count = 2
    881			},
    882			[IS2_ACTION_TYPE_SMAC_SIP] = {
    883				.width = 6,
    884				.count = 4
    885			},
    886		},
    887		.target = S2,
    888		.keys = vsc9959_vcap_is2_keys,
    889		.actions = vsc9959_vcap_is2_actions,
    890	},
    891};
    892
    893static const struct ptp_clock_info vsc9959_ptp_caps = {
    894	.owner		= THIS_MODULE,
    895	.name		= "felix ptp",
    896	.max_adj	= 0x7fffffff,
    897	.n_alarm	= 0,
    898	.n_ext_ts	= 0,
    899	.n_per_out	= OCELOT_PTP_PINS_NUM,
    900	.n_pins		= OCELOT_PTP_PINS_NUM,
    901	.pps		= 0,
    902	.gettime64	= ocelot_ptp_gettime64,
    903	.settime64	= ocelot_ptp_settime64,
    904	.adjtime	= ocelot_ptp_adjtime,
    905	.adjfine	= ocelot_ptp_adjfine,
    906	.verify		= ocelot_ptp_verify,
    907	.enable		= ocelot_ptp_enable,
    908};
    909
    910#define VSC9959_INIT_TIMEOUT			50000
    911#define VSC9959_GCB_RST_SLEEP			100
    912#define VSC9959_SYS_RAMINIT_SLEEP		80
    913
    914static int vsc9959_gcb_soft_rst_status(struct ocelot *ocelot)
    915{
    916	int val;
    917
    918	ocelot_field_read(ocelot, GCB_SOFT_RST_SWC_RST, &val);
    919
    920	return val;
    921}
    922
    923static int vsc9959_sys_ram_init_status(struct ocelot *ocelot)
    924{
    925	return ocelot_read(ocelot, SYS_RAM_INIT);
    926}
    927
    928/* CORE_ENA is in SYS:SYSTEM:RESET_CFG
    929 * RAM_INIT is in SYS:RAM_CTRL:RAM_INIT
    930 */
    931static int vsc9959_reset(struct ocelot *ocelot)
    932{
    933	int val, err;
    934
    935	/* soft-reset the switch core */
    936	ocelot_field_write(ocelot, GCB_SOFT_RST_SWC_RST, 1);
    937
    938	err = readx_poll_timeout(vsc9959_gcb_soft_rst_status, ocelot, val, !val,
    939				 VSC9959_GCB_RST_SLEEP, VSC9959_INIT_TIMEOUT);
    940	if (err) {
    941		dev_err(ocelot->dev, "timeout: switch core reset\n");
    942		return err;
    943	}
    944
    945	/* initialize switch mem ~40us */
    946	ocelot_write(ocelot, SYS_RAM_INIT_RAM_INIT, SYS_RAM_INIT);
    947	err = readx_poll_timeout(vsc9959_sys_ram_init_status, ocelot, val, !val,
    948				 VSC9959_SYS_RAMINIT_SLEEP,
    949				 VSC9959_INIT_TIMEOUT);
    950	if (err) {
    951		dev_err(ocelot->dev, "timeout: switch sram init\n");
    952		return err;
    953	}
    954
    955	/* enable switch core */
    956	ocelot_field_write(ocelot, SYS_RESET_CFG_CORE_ENA, 1);
    957
    958	return 0;
    959}
    960
    961static void vsc9959_phylink_validate(struct ocelot *ocelot, int port,
    962				     unsigned long *supported,
    963				     struct phylink_link_state *state)
    964{
    965	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
    966
    967	phylink_set_port_modes(mask);
    968	phylink_set(mask, Autoneg);
    969	phylink_set(mask, Pause);
    970	phylink_set(mask, Asym_Pause);
    971	phylink_set(mask, 10baseT_Half);
    972	phylink_set(mask, 10baseT_Full);
    973	phylink_set(mask, 100baseT_Half);
    974	phylink_set(mask, 100baseT_Full);
    975	phylink_set(mask, 1000baseT_Half);
    976	phylink_set(mask, 1000baseT_Full);
    977	phylink_set(mask, 1000baseX_Full);
    978
    979	if (state->interface == PHY_INTERFACE_MODE_INTERNAL ||
    980	    state->interface == PHY_INTERFACE_MODE_2500BASEX ||
    981	    state->interface == PHY_INTERFACE_MODE_USXGMII) {
    982		phylink_set(mask, 2500baseT_Full);
    983		phylink_set(mask, 2500baseX_Full);
    984	}
    985
    986	linkmode_and(supported, supported, mask);
    987	linkmode_and(state->advertising, state->advertising, mask);
    988}
    989
    990/* Watermark encode
    991 * Bit 8:   Unit; 0:1, 1:16
    992 * Bit 7-0: Value to be multiplied with unit
    993 */
    994static u16 vsc9959_wm_enc(u16 value)
    995{
    996	WARN_ON(value >= 16 * BIT(8));
    997
    998	if (value >= BIT(8))
    999		return BIT(8) | (value / 16);
   1000
   1001	return value;
   1002}
   1003
   1004static u16 vsc9959_wm_dec(u16 wm)
   1005{
   1006	WARN_ON(wm & ~GENMASK(8, 0));
   1007
   1008	if (wm & BIT(8))
   1009		return (wm & GENMASK(7, 0)) * 16;
   1010
   1011	return wm;
   1012}
   1013
   1014static void vsc9959_wm_stat(u32 val, u32 *inuse, u32 *maxuse)
   1015{
   1016	*inuse = (val & GENMASK(23, 12)) >> 12;
   1017	*maxuse = val & GENMASK(11, 0);
   1018}
   1019
   1020static int vsc9959_mdio_bus_alloc(struct ocelot *ocelot)
   1021{
   1022	struct felix *felix = ocelot_to_felix(ocelot);
   1023	struct enetc_mdio_priv *mdio_priv;
   1024	struct device *dev = ocelot->dev;
   1025	void __iomem *imdio_regs;
   1026	struct resource res;
   1027	struct enetc_hw *hw;
   1028	struct mii_bus *bus;
   1029	int port;
   1030	int rc;
   1031
   1032	felix->pcs = devm_kcalloc(dev, felix->info->num_ports,
   1033				  sizeof(struct phylink_pcs *),
   1034				  GFP_KERNEL);
   1035	if (!felix->pcs) {
   1036		dev_err(dev, "failed to allocate array for PCS PHYs\n");
   1037		return -ENOMEM;
   1038	}
   1039
   1040	memcpy(&res, felix->info->imdio_res, sizeof(res));
   1041	res.flags = IORESOURCE_MEM;
   1042	res.start += felix->imdio_base;
   1043	res.end += felix->imdio_base;
   1044
   1045	imdio_regs = devm_ioremap_resource(dev, &res);
   1046	if (IS_ERR(imdio_regs))
   1047		return PTR_ERR(imdio_regs);
   1048
   1049	hw = enetc_hw_alloc(dev, imdio_regs);
   1050	if (IS_ERR(hw)) {
   1051		dev_err(dev, "failed to allocate ENETC HW structure\n");
   1052		return PTR_ERR(hw);
   1053	}
   1054
   1055	bus = mdiobus_alloc_size(sizeof(*mdio_priv));
   1056	if (!bus)
   1057		return -ENOMEM;
   1058
   1059	bus->name = "VSC9959 internal MDIO bus";
   1060	bus->read = enetc_mdio_read;
   1061	bus->write = enetc_mdio_write;
   1062	bus->parent = dev;
   1063	mdio_priv = bus->priv;
   1064	mdio_priv->hw = hw;
   1065	/* This gets added to imdio_regs, which already maps addresses
   1066	 * starting with the proper offset.
   1067	 */
   1068	mdio_priv->mdio_base = 0;
   1069	snprintf(bus->id, MII_BUS_ID_SIZE, "%s-imdio", dev_name(dev));
   1070
   1071	/* Needed in order to initialize the bus mutex lock */
   1072	rc = mdiobus_register(bus);
   1073	if (rc < 0) {
   1074		dev_err(dev, "failed to register MDIO bus\n");
   1075		mdiobus_free(bus);
   1076		return rc;
   1077	}
   1078
   1079	felix->imdio = bus;
   1080
   1081	for (port = 0; port < felix->info->num_ports; port++) {
   1082		struct ocelot_port *ocelot_port = ocelot->ports[port];
   1083		struct phylink_pcs *phylink_pcs;
   1084		struct mdio_device *mdio_device;
   1085
   1086		if (dsa_is_unused_port(felix->ds, port))
   1087			continue;
   1088
   1089		if (ocelot_port->phy_mode == PHY_INTERFACE_MODE_INTERNAL)
   1090			continue;
   1091
   1092		mdio_device = mdio_device_create(felix->imdio, port);
   1093		if (IS_ERR(mdio_device))
   1094			continue;
   1095
   1096		phylink_pcs = lynx_pcs_create(mdio_device);
   1097		if (!phylink_pcs) {
   1098			mdio_device_free(mdio_device);
   1099			continue;
   1100		}
   1101
   1102		felix->pcs[port] = phylink_pcs;
   1103
   1104		dev_info(dev, "Found PCS at internal MDIO address %d\n", port);
   1105	}
   1106
   1107	return 0;
   1108}
   1109
   1110static void vsc9959_mdio_bus_free(struct ocelot *ocelot)
   1111{
   1112	struct felix *felix = ocelot_to_felix(ocelot);
   1113	int port;
   1114
   1115	for (port = 0; port < ocelot->num_phys_ports; port++) {
   1116		struct phylink_pcs *phylink_pcs = felix->pcs[port];
   1117		struct mdio_device *mdio_device;
   1118
   1119		if (!phylink_pcs)
   1120			continue;
   1121
   1122		mdio_device = lynx_get_mdio_device(phylink_pcs);
   1123		mdio_device_free(mdio_device);
   1124		lynx_pcs_destroy(phylink_pcs);
   1125	}
   1126	mdiobus_unregister(felix->imdio);
   1127	mdiobus_free(felix->imdio);
   1128}
   1129
   1130static void vsc9959_sched_speed_set(struct ocelot *ocelot, int port,
   1131				    u32 speed)
   1132{
   1133	u8 tas_speed;
   1134
   1135	switch (speed) {
   1136	case SPEED_10:
   1137		tas_speed = OCELOT_SPEED_10;
   1138		break;
   1139	case SPEED_100:
   1140		tas_speed = OCELOT_SPEED_100;
   1141		break;
   1142	case SPEED_1000:
   1143		tas_speed = OCELOT_SPEED_1000;
   1144		break;
   1145	case SPEED_2500:
   1146		tas_speed = OCELOT_SPEED_2500;
   1147		break;
   1148	default:
   1149		tas_speed = OCELOT_SPEED_1000;
   1150		break;
   1151	}
   1152
   1153	ocelot_rmw_rix(ocelot,
   1154		       QSYS_TAG_CONFIG_LINK_SPEED(tas_speed),
   1155		       QSYS_TAG_CONFIG_LINK_SPEED_M,
   1156		       QSYS_TAG_CONFIG, port);
   1157}
   1158
   1159static void vsc9959_new_base_time(struct ocelot *ocelot, ktime_t base_time,
   1160				  u64 cycle_time,
   1161				  struct timespec64 *new_base_ts)
   1162{
   1163	struct timespec64 ts;
   1164	ktime_t new_base_time;
   1165	ktime_t current_time;
   1166
   1167	ocelot_ptp_gettime64(&ocelot->ptp_info, &ts);
   1168	current_time = timespec64_to_ktime(ts);
   1169	new_base_time = base_time;
   1170
   1171	if (base_time < current_time) {
   1172		u64 nr_of_cycles = current_time - base_time;
   1173
   1174		do_div(nr_of_cycles, cycle_time);
   1175		new_base_time += cycle_time * (nr_of_cycles + 1);
   1176	}
   1177
   1178	*new_base_ts = ktime_to_timespec64(new_base_time);
   1179}
   1180
   1181static u32 vsc9959_tas_read_cfg_status(struct ocelot *ocelot)
   1182{
   1183	return ocelot_read(ocelot, QSYS_TAS_PARAM_CFG_CTRL);
   1184}
   1185
   1186static void vsc9959_tas_gcl_set(struct ocelot *ocelot, const u32 gcl_ix,
   1187				struct tc_taprio_sched_entry *entry)
   1188{
   1189	ocelot_write(ocelot,
   1190		     QSYS_GCL_CFG_REG_1_GCL_ENTRY_NUM(gcl_ix) |
   1191		     QSYS_GCL_CFG_REG_1_GATE_STATE(entry->gate_mask),
   1192		     QSYS_GCL_CFG_REG_1);
   1193	ocelot_write(ocelot, entry->interval, QSYS_GCL_CFG_REG_2);
   1194}
   1195
   1196static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port,
   1197				    struct tc_taprio_qopt_offload *taprio)
   1198{
   1199	struct timespec64 base_ts;
   1200	int ret, i;
   1201	u32 val;
   1202
   1203	if (!taprio->enable) {
   1204		ocelot_rmw_rix(ocelot,
   1205			       QSYS_TAG_CONFIG_INIT_GATE_STATE(0xFF),
   1206			       QSYS_TAG_CONFIG_ENABLE |
   1207			       QSYS_TAG_CONFIG_INIT_GATE_STATE_M,
   1208			       QSYS_TAG_CONFIG, port);
   1209
   1210		return 0;
   1211	}
   1212
   1213	if (taprio->cycle_time > NSEC_PER_SEC ||
   1214	    taprio->cycle_time_extension >= NSEC_PER_SEC)
   1215		return -EINVAL;
   1216
   1217	if (taprio->num_entries > VSC9959_TAS_GCL_ENTRY_MAX)
   1218		return -ERANGE;
   1219
   1220	/* Enable guard band. The switch will schedule frames without taking
   1221	 * their length into account. Thus we'll always need to enable the
   1222	 * guard band which reserves the time of a maximum sized frame at the
   1223	 * end of the time window.
   1224	 *
   1225	 * Although the ALWAYS_GUARD_BAND_SCH_Q bit is global for all ports, we
   1226	 * need to set PORT_NUM, because subsequent writes to PARAM_CFG_REG_n
   1227	 * operate on the port number.
   1228	 */
   1229	ocelot_rmw(ocelot, QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM(port) |
   1230		   QSYS_TAS_PARAM_CFG_CTRL_ALWAYS_GUARD_BAND_SCH_Q,
   1231		   QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM_M |
   1232		   QSYS_TAS_PARAM_CFG_CTRL_ALWAYS_GUARD_BAND_SCH_Q,
   1233		   QSYS_TAS_PARAM_CFG_CTRL);
   1234
   1235	/* Hardware errata -  Admin config could not be overwritten if
   1236	 * config is pending, need reset the TAS module
   1237	 */
   1238	val = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_8);
   1239	if (val & QSYS_PARAM_STATUS_REG_8_CONFIG_PENDING)
   1240		return  -EBUSY;
   1241
   1242	ocelot_rmw_rix(ocelot,
   1243		       QSYS_TAG_CONFIG_ENABLE |
   1244		       QSYS_TAG_CONFIG_INIT_GATE_STATE(0xFF) |
   1245		       QSYS_TAG_CONFIG_SCH_TRAFFIC_QUEUES(0xFF),
   1246		       QSYS_TAG_CONFIG_ENABLE |
   1247		       QSYS_TAG_CONFIG_INIT_GATE_STATE_M |
   1248		       QSYS_TAG_CONFIG_SCH_TRAFFIC_QUEUES_M,
   1249		       QSYS_TAG_CONFIG, port);
   1250
   1251	vsc9959_new_base_time(ocelot, taprio->base_time,
   1252			      taprio->cycle_time, &base_ts);
   1253	ocelot_write(ocelot, base_ts.tv_nsec, QSYS_PARAM_CFG_REG_1);
   1254	ocelot_write(ocelot, lower_32_bits(base_ts.tv_sec), QSYS_PARAM_CFG_REG_2);
   1255	val = upper_32_bits(base_ts.tv_sec);
   1256	ocelot_write(ocelot,
   1257		     QSYS_PARAM_CFG_REG_3_BASE_TIME_SEC_MSB(val) |
   1258		     QSYS_PARAM_CFG_REG_3_LIST_LENGTH(taprio->num_entries),
   1259		     QSYS_PARAM_CFG_REG_3);
   1260	ocelot_write(ocelot, taprio->cycle_time, QSYS_PARAM_CFG_REG_4);
   1261	ocelot_write(ocelot, taprio->cycle_time_extension, QSYS_PARAM_CFG_REG_5);
   1262
   1263	for (i = 0; i < taprio->num_entries; i++)
   1264		vsc9959_tas_gcl_set(ocelot, i, &taprio->entries[i]);
   1265
   1266	ocelot_rmw(ocelot, QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE,
   1267		   QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE,
   1268		   QSYS_TAS_PARAM_CFG_CTRL);
   1269
   1270	ret = readx_poll_timeout(vsc9959_tas_read_cfg_status, ocelot, val,
   1271				 !(val & QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE),
   1272				 10, 100000);
   1273
   1274	return ret;
   1275}
   1276
   1277static int vsc9959_qos_port_cbs_set(struct dsa_switch *ds, int port,
   1278				    struct tc_cbs_qopt_offload *cbs_qopt)
   1279{
   1280	struct ocelot *ocelot = ds->priv;
   1281	int port_ix = port * 8 + cbs_qopt->queue;
   1282	u32 rate, burst;
   1283
   1284	if (cbs_qopt->queue >= ds->num_tx_queues)
   1285		return -EINVAL;
   1286
   1287	if (!cbs_qopt->enable) {
   1288		ocelot_write_gix(ocelot, QSYS_CIR_CFG_CIR_RATE(0) |
   1289				 QSYS_CIR_CFG_CIR_BURST(0),
   1290				 QSYS_CIR_CFG, port_ix);
   1291
   1292		ocelot_rmw_gix(ocelot, 0, QSYS_SE_CFG_SE_AVB_ENA,
   1293			       QSYS_SE_CFG, port_ix);
   1294
   1295		return 0;
   1296	}
   1297
   1298	/* Rate unit is 100 kbps */
   1299	rate = DIV_ROUND_UP(cbs_qopt->idleslope, 100);
   1300	/* Avoid using zero rate */
   1301	rate = clamp_t(u32, rate, 1, GENMASK(14, 0));
   1302	/* Burst unit is 4kB */
   1303	burst = DIV_ROUND_UP(cbs_qopt->hicredit, 4096);
   1304	/* Avoid using zero burst size */
   1305	burst = clamp_t(u32, burst, 1, GENMASK(5, 0));
   1306	ocelot_write_gix(ocelot,
   1307			 QSYS_CIR_CFG_CIR_RATE(rate) |
   1308			 QSYS_CIR_CFG_CIR_BURST(burst),
   1309			 QSYS_CIR_CFG,
   1310			 port_ix);
   1311
   1312	ocelot_rmw_gix(ocelot,
   1313		       QSYS_SE_CFG_SE_FRM_MODE(0) |
   1314		       QSYS_SE_CFG_SE_AVB_ENA,
   1315		       QSYS_SE_CFG_SE_AVB_ENA |
   1316		       QSYS_SE_CFG_SE_FRM_MODE_M,
   1317		       QSYS_SE_CFG,
   1318		       port_ix);
   1319
   1320	return 0;
   1321}
   1322
   1323static int vsc9959_port_setup_tc(struct dsa_switch *ds, int port,
   1324				 enum tc_setup_type type,
   1325				 void *type_data)
   1326{
   1327	struct ocelot *ocelot = ds->priv;
   1328
   1329	switch (type) {
   1330	case TC_SETUP_QDISC_TAPRIO:
   1331		return vsc9959_qos_port_tas_set(ocelot, port, type_data);
   1332	case TC_SETUP_QDISC_CBS:
   1333		return vsc9959_qos_port_cbs_set(ds, port, type_data);
   1334	default:
   1335		return -EOPNOTSUPP;
   1336	}
   1337}
   1338
   1339#define VSC9959_PSFP_SFID_MAX			175
   1340#define VSC9959_PSFP_GATE_ID_MAX		183
   1341#define VSC9959_PSFP_POLICER_BASE		63
   1342#define VSC9959_PSFP_POLICER_MAX		383
   1343#define VSC9959_PSFP_GATE_LIST_NUM		4
   1344#define VSC9959_PSFP_GATE_CYCLETIME_MIN		5000
   1345
   1346struct felix_stream {
   1347	struct list_head list;
   1348	unsigned long id;
   1349	bool dummy;
   1350	int ports;
   1351	int port;
   1352	u8 dmac[ETH_ALEN];
   1353	u16 vid;
   1354	s8 prio;
   1355	u8 sfid_valid;
   1356	u8 ssid_valid;
   1357	u32 sfid;
   1358	u32 ssid;
   1359};
   1360
   1361struct felix_stream_filter {
   1362	struct list_head list;
   1363	refcount_t refcount;
   1364	u32 index;
   1365	u8 enable;
   1366	int portmask;
   1367	u8 sg_valid;
   1368	u32 sgid;
   1369	u8 fm_valid;
   1370	u32 fmid;
   1371	u8 prio_valid;
   1372	u8 prio;
   1373	u32 maxsdu;
   1374};
   1375
   1376struct felix_stream_filter_counters {
   1377	u32 match;
   1378	u32 not_pass_gate;
   1379	u32 not_pass_sdu;
   1380	u32 red;
   1381};
   1382
   1383struct felix_stream_gate {
   1384	u32 index;
   1385	u8 enable;
   1386	u8 ipv_valid;
   1387	u8 init_ipv;
   1388	u64 basetime;
   1389	u64 cycletime;
   1390	u64 cycletime_ext;
   1391	u32 num_entries;
   1392	struct action_gate_entry entries[];
   1393};
   1394
   1395struct felix_stream_gate_entry {
   1396	struct list_head list;
   1397	refcount_t refcount;
   1398	u32 index;
   1399};
   1400
   1401static int vsc9959_stream_identify(struct flow_cls_offload *f,
   1402				   struct felix_stream *stream)
   1403{
   1404	struct flow_rule *rule = flow_cls_offload_flow_rule(f);
   1405	struct flow_dissector *dissector = rule->match.dissector;
   1406
   1407	if (dissector->used_keys &
   1408	    ~(BIT(FLOW_DISSECTOR_KEY_CONTROL) |
   1409	      BIT(FLOW_DISSECTOR_KEY_BASIC) |
   1410	      BIT(FLOW_DISSECTOR_KEY_VLAN) |
   1411	      BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS)))
   1412		return -EOPNOTSUPP;
   1413
   1414	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
   1415		struct flow_match_eth_addrs match;
   1416
   1417		flow_rule_match_eth_addrs(rule, &match);
   1418		ether_addr_copy(stream->dmac, match.key->dst);
   1419		if (!is_zero_ether_addr(match.mask->src))
   1420			return -EOPNOTSUPP;
   1421	} else {
   1422		return -EOPNOTSUPP;
   1423	}
   1424
   1425	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
   1426		struct flow_match_vlan match;
   1427
   1428		flow_rule_match_vlan(rule, &match);
   1429		if (match.mask->vlan_priority)
   1430			stream->prio = match.key->vlan_priority;
   1431		else
   1432			stream->prio = -1;
   1433
   1434		if (!match.mask->vlan_id)
   1435			return -EOPNOTSUPP;
   1436		stream->vid = match.key->vlan_id;
   1437	} else {
   1438		return -EOPNOTSUPP;
   1439	}
   1440
   1441	stream->id = f->cookie;
   1442
   1443	return 0;
   1444}
   1445
   1446static int vsc9959_mact_stream_set(struct ocelot *ocelot,
   1447				   struct felix_stream *stream,
   1448				   struct netlink_ext_ack *extack)
   1449{
   1450	enum macaccess_entry_type type;
   1451	int ret, sfid, ssid;
   1452	u32 vid, dst_idx;
   1453	u8 mac[ETH_ALEN];
   1454
   1455	ether_addr_copy(mac, stream->dmac);
   1456	vid = stream->vid;
   1457
   1458	/* Stream identification desn't support to add a stream with non
   1459	 * existent MAC (The MAC entry has not been learned in MAC table).
   1460	 */
   1461	ret = ocelot_mact_lookup(ocelot, &dst_idx, mac, vid, &type);
   1462	if (ret) {
   1463		if (extack)
   1464			NL_SET_ERR_MSG_MOD(extack, "Stream is not learned in MAC table");
   1465		return -EOPNOTSUPP;
   1466	}
   1467
   1468	if ((stream->sfid_valid || stream->ssid_valid) &&
   1469	    type == ENTRYTYPE_NORMAL)
   1470		type = ENTRYTYPE_LOCKED;
   1471
   1472	sfid = stream->sfid_valid ? stream->sfid : -1;
   1473	ssid = stream->ssid_valid ? stream->ssid : -1;
   1474
   1475	ret = ocelot_mact_learn_streamdata(ocelot, dst_idx, mac, vid, type,
   1476					   sfid, ssid);
   1477
   1478	return ret;
   1479}
   1480
   1481static struct felix_stream *
   1482vsc9959_stream_table_lookup(struct list_head *stream_list,
   1483			    struct felix_stream *stream)
   1484{
   1485	struct felix_stream *tmp;
   1486
   1487	list_for_each_entry(tmp, stream_list, list)
   1488		if (ether_addr_equal(tmp->dmac, stream->dmac) &&
   1489		    tmp->vid == stream->vid)
   1490			return tmp;
   1491
   1492	return NULL;
   1493}
   1494
   1495static int vsc9959_stream_table_add(struct ocelot *ocelot,
   1496				    struct list_head *stream_list,
   1497				    struct felix_stream *stream,
   1498				    struct netlink_ext_ack *extack)
   1499{
   1500	struct felix_stream *stream_entry;
   1501	int ret;
   1502
   1503	stream_entry = kmemdup(stream, sizeof(*stream_entry), GFP_KERNEL);
   1504	if (!stream_entry)
   1505		return -ENOMEM;
   1506
   1507	if (!stream->dummy) {
   1508		ret = vsc9959_mact_stream_set(ocelot, stream_entry, extack);
   1509		if (ret) {
   1510			kfree(stream_entry);
   1511			return ret;
   1512		}
   1513	}
   1514
   1515	list_add_tail(&stream_entry->list, stream_list);
   1516
   1517	return 0;
   1518}
   1519
   1520static struct felix_stream *
   1521vsc9959_stream_table_get(struct list_head *stream_list, unsigned long id)
   1522{
   1523	struct felix_stream *tmp;
   1524
   1525	list_for_each_entry(tmp, stream_list, list)
   1526		if (tmp->id == id)
   1527			return tmp;
   1528
   1529	return NULL;
   1530}
   1531
   1532static void vsc9959_stream_table_del(struct ocelot *ocelot,
   1533				     struct felix_stream *stream)
   1534{
   1535	if (!stream->dummy)
   1536		vsc9959_mact_stream_set(ocelot, stream, NULL);
   1537
   1538	list_del(&stream->list);
   1539	kfree(stream);
   1540}
   1541
   1542static u32 vsc9959_sfi_access_status(struct ocelot *ocelot)
   1543{
   1544	return ocelot_read(ocelot, ANA_TABLES_SFIDACCESS);
   1545}
   1546
   1547static int vsc9959_psfp_sfi_set(struct ocelot *ocelot,
   1548				struct felix_stream_filter *sfi)
   1549{
   1550	u32 val;
   1551
   1552	if (sfi->index > VSC9959_PSFP_SFID_MAX)
   1553		return -EINVAL;
   1554
   1555	if (!sfi->enable) {
   1556		ocelot_write(ocelot, ANA_TABLES_SFIDTIDX_SFID_INDEX(sfi->index),
   1557			     ANA_TABLES_SFIDTIDX);
   1558
   1559		val = ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(SFIDACCESS_CMD_WRITE);
   1560		ocelot_write(ocelot, val, ANA_TABLES_SFIDACCESS);
   1561
   1562		return readx_poll_timeout(vsc9959_sfi_access_status, ocelot, val,
   1563					  (!ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(val)),
   1564					  10, 100000);
   1565	}
   1566
   1567	if (sfi->sgid > VSC9959_PSFP_GATE_ID_MAX ||
   1568	    sfi->fmid > VSC9959_PSFP_POLICER_MAX)
   1569		return -EINVAL;
   1570
   1571	ocelot_write(ocelot,
   1572		     (sfi->sg_valid ? ANA_TABLES_SFIDTIDX_SGID_VALID : 0) |
   1573		     ANA_TABLES_SFIDTIDX_SGID(sfi->sgid) |
   1574		     (sfi->fm_valid ? ANA_TABLES_SFIDTIDX_POL_ENA : 0) |
   1575		     ANA_TABLES_SFIDTIDX_POL_IDX(sfi->fmid) |
   1576		     ANA_TABLES_SFIDTIDX_SFID_INDEX(sfi->index),
   1577		     ANA_TABLES_SFIDTIDX);
   1578
   1579	ocelot_write(ocelot,
   1580		     (sfi->prio_valid ? ANA_TABLES_SFIDACCESS_IGR_PRIO_MATCH_ENA : 0) |
   1581		     ANA_TABLES_SFIDACCESS_IGR_PRIO(sfi->prio) |
   1582		     ANA_TABLES_SFIDACCESS_MAX_SDU_LEN(sfi->maxsdu) |
   1583		     ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(SFIDACCESS_CMD_WRITE),
   1584		     ANA_TABLES_SFIDACCESS);
   1585
   1586	return readx_poll_timeout(vsc9959_sfi_access_status, ocelot, val,
   1587				  (!ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(val)),
   1588				  10, 100000);
   1589}
   1590
   1591static int vsc9959_psfp_sfidmask_set(struct ocelot *ocelot, u32 sfid, int ports)
   1592{
   1593	u32 val;
   1594
   1595	ocelot_rmw(ocelot,
   1596		   ANA_TABLES_SFIDTIDX_SFID_INDEX(sfid),
   1597		   ANA_TABLES_SFIDTIDX_SFID_INDEX_M,
   1598		   ANA_TABLES_SFIDTIDX);
   1599
   1600	ocelot_write(ocelot,
   1601		     ANA_TABLES_SFID_MASK_IGR_PORT_MASK(ports) |
   1602		     ANA_TABLES_SFID_MASK_IGR_SRCPORT_MATCH_ENA,
   1603		     ANA_TABLES_SFID_MASK);
   1604
   1605	ocelot_rmw(ocelot,
   1606		   ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(SFIDACCESS_CMD_WRITE),
   1607		   ANA_TABLES_SFIDACCESS_SFID_TBL_CMD_M,
   1608		   ANA_TABLES_SFIDACCESS);
   1609
   1610	return readx_poll_timeout(vsc9959_sfi_access_status, ocelot, val,
   1611				  (!ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(val)),
   1612				  10, 100000);
   1613}
   1614
   1615static int vsc9959_psfp_sfi_list_add(struct ocelot *ocelot,
   1616				     struct felix_stream_filter *sfi,
   1617				     struct list_head *pos)
   1618{
   1619	struct felix_stream_filter *sfi_entry;
   1620	int ret;
   1621
   1622	sfi_entry = kmemdup(sfi, sizeof(*sfi_entry), GFP_KERNEL);
   1623	if (!sfi_entry)
   1624		return -ENOMEM;
   1625
   1626	refcount_set(&sfi_entry->refcount, 1);
   1627
   1628	ret = vsc9959_psfp_sfi_set(ocelot, sfi_entry);
   1629	if (ret) {
   1630		kfree(sfi_entry);
   1631		return ret;
   1632	}
   1633
   1634	vsc9959_psfp_sfidmask_set(ocelot, sfi->index, sfi->portmask);
   1635
   1636	list_add(&sfi_entry->list, pos);
   1637
   1638	return 0;
   1639}
   1640
   1641static int vsc9959_psfp_sfi_table_add(struct ocelot *ocelot,
   1642				      struct felix_stream_filter *sfi)
   1643{
   1644	struct list_head *pos, *q, *last;
   1645	struct felix_stream_filter *tmp;
   1646	struct ocelot_psfp_list *psfp;
   1647	u32 insert = 0;
   1648
   1649	psfp = &ocelot->psfp;
   1650	last = &psfp->sfi_list;
   1651
   1652	list_for_each_safe(pos, q, &psfp->sfi_list) {
   1653		tmp = list_entry(pos, struct felix_stream_filter, list);
   1654		if (sfi->sg_valid == tmp->sg_valid &&
   1655		    sfi->fm_valid == tmp->fm_valid &&
   1656		    sfi->portmask == tmp->portmask &&
   1657		    tmp->sgid == sfi->sgid &&
   1658		    tmp->fmid == sfi->fmid) {
   1659			sfi->index = tmp->index;
   1660			refcount_inc(&tmp->refcount);
   1661			return 0;
   1662		}
   1663		/* Make sure that the index is increasing in order. */
   1664		if (tmp->index == insert) {
   1665			last = pos;
   1666			insert++;
   1667		}
   1668	}
   1669	sfi->index = insert;
   1670
   1671	return vsc9959_psfp_sfi_list_add(ocelot, sfi, last);
   1672}
   1673
   1674static int vsc9959_psfp_sfi_table_add2(struct ocelot *ocelot,
   1675				       struct felix_stream_filter *sfi,
   1676				       struct felix_stream_filter *sfi2)
   1677{
   1678	struct felix_stream_filter *tmp;
   1679	struct list_head *pos, *q, *last;
   1680	struct ocelot_psfp_list *psfp;
   1681	u32 insert = 0;
   1682	int ret;
   1683
   1684	psfp = &ocelot->psfp;
   1685	last = &psfp->sfi_list;
   1686
   1687	list_for_each_safe(pos, q, &psfp->sfi_list) {
   1688		tmp = list_entry(pos, struct felix_stream_filter, list);
   1689		/* Make sure that the index is increasing in order. */
   1690		if (tmp->index >= insert + 2)
   1691			break;
   1692
   1693		insert = tmp->index + 1;
   1694		last = pos;
   1695	}
   1696	sfi->index = insert;
   1697
   1698	ret = vsc9959_psfp_sfi_list_add(ocelot, sfi, last);
   1699	if (ret)
   1700		return ret;
   1701
   1702	sfi2->index = insert + 1;
   1703
   1704	return vsc9959_psfp_sfi_list_add(ocelot, sfi2, last->next);
   1705}
   1706
   1707static struct felix_stream_filter *
   1708vsc9959_psfp_sfi_table_get(struct list_head *sfi_list, u32 index)
   1709{
   1710	struct felix_stream_filter *tmp;
   1711
   1712	list_for_each_entry(tmp, sfi_list, list)
   1713		if (tmp->index == index)
   1714			return tmp;
   1715
   1716	return NULL;
   1717}
   1718
   1719static void vsc9959_psfp_sfi_table_del(struct ocelot *ocelot, u32 index)
   1720{
   1721	struct felix_stream_filter *tmp, *n;
   1722	struct ocelot_psfp_list *psfp;
   1723	u8 z;
   1724
   1725	psfp = &ocelot->psfp;
   1726
   1727	list_for_each_entry_safe(tmp, n, &psfp->sfi_list, list)
   1728		if (tmp->index == index) {
   1729			z = refcount_dec_and_test(&tmp->refcount);
   1730			if (z) {
   1731				tmp->enable = 0;
   1732				vsc9959_psfp_sfi_set(ocelot, tmp);
   1733				list_del(&tmp->list);
   1734				kfree(tmp);
   1735			}
   1736			break;
   1737		}
   1738}
   1739
   1740static void vsc9959_psfp_parse_gate(const struct flow_action_entry *entry,
   1741				    struct felix_stream_gate *sgi)
   1742{
   1743	sgi->index = entry->hw_index;
   1744	sgi->ipv_valid = (entry->gate.prio < 0) ? 0 : 1;
   1745	sgi->init_ipv = (sgi->ipv_valid) ? entry->gate.prio : 0;
   1746	sgi->basetime = entry->gate.basetime;
   1747	sgi->cycletime = entry->gate.cycletime;
   1748	sgi->num_entries = entry->gate.num_entries;
   1749	sgi->enable = 1;
   1750
   1751	memcpy(sgi->entries, entry->gate.entries,
   1752	       entry->gate.num_entries * sizeof(struct action_gate_entry));
   1753}
   1754
   1755static u32 vsc9959_sgi_cfg_status(struct ocelot *ocelot)
   1756{
   1757	return ocelot_read(ocelot, ANA_SG_ACCESS_CTRL);
   1758}
   1759
   1760static int vsc9959_psfp_sgi_set(struct ocelot *ocelot,
   1761				struct felix_stream_gate *sgi)
   1762{
   1763	struct action_gate_entry *e;
   1764	struct timespec64 base_ts;
   1765	u32 interval_sum = 0;
   1766	u32 val;
   1767	int i;
   1768
   1769	if (sgi->index > VSC9959_PSFP_GATE_ID_MAX)
   1770		return -EINVAL;
   1771
   1772	ocelot_write(ocelot, ANA_SG_ACCESS_CTRL_SGID(sgi->index),
   1773		     ANA_SG_ACCESS_CTRL);
   1774
   1775	if (!sgi->enable) {
   1776		ocelot_rmw(ocelot, ANA_SG_CONFIG_REG_3_INIT_GATE_STATE,
   1777			   ANA_SG_CONFIG_REG_3_INIT_GATE_STATE |
   1778			   ANA_SG_CONFIG_REG_3_GATE_ENABLE,
   1779			   ANA_SG_CONFIG_REG_3);
   1780
   1781		return 0;
   1782	}
   1783
   1784	if (sgi->cycletime < VSC9959_PSFP_GATE_CYCLETIME_MIN ||
   1785	    sgi->cycletime > NSEC_PER_SEC)
   1786		return -EINVAL;
   1787
   1788	if (sgi->num_entries > VSC9959_PSFP_GATE_LIST_NUM)
   1789		return -EINVAL;
   1790
   1791	vsc9959_new_base_time(ocelot, sgi->basetime, sgi->cycletime, &base_ts);
   1792	ocelot_write(ocelot, base_ts.tv_nsec, ANA_SG_CONFIG_REG_1);
   1793	val = lower_32_bits(base_ts.tv_sec);
   1794	ocelot_write(ocelot, val, ANA_SG_CONFIG_REG_2);
   1795
   1796	val = upper_32_bits(base_ts.tv_sec);
   1797	ocelot_write(ocelot,
   1798		     (sgi->ipv_valid ? ANA_SG_CONFIG_REG_3_IPV_VALID : 0) |
   1799		     ANA_SG_CONFIG_REG_3_INIT_IPV(sgi->init_ipv) |
   1800		     ANA_SG_CONFIG_REG_3_GATE_ENABLE |
   1801		     ANA_SG_CONFIG_REG_3_LIST_LENGTH(sgi->num_entries) |
   1802		     ANA_SG_CONFIG_REG_3_INIT_GATE_STATE |
   1803		     ANA_SG_CONFIG_REG_3_BASE_TIME_SEC_MSB(val),
   1804		     ANA_SG_CONFIG_REG_3);
   1805
   1806	ocelot_write(ocelot, sgi->cycletime, ANA_SG_CONFIG_REG_4);
   1807
   1808	e = sgi->entries;
   1809	for (i = 0; i < sgi->num_entries; i++) {
   1810		u32 ips = (e[i].ipv < 0) ? 0 : (e[i].ipv + 8);
   1811
   1812		ocelot_write_rix(ocelot, ANA_SG_GCL_GS_CONFIG_IPS(ips) |
   1813				 (e[i].gate_state ?
   1814				  ANA_SG_GCL_GS_CONFIG_GATE_STATE : 0),
   1815				 ANA_SG_GCL_GS_CONFIG, i);
   1816
   1817		interval_sum += e[i].interval;
   1818		ocelot_write_rix(ocelot, interval_sum, ANA_SG_GCL_TI_CONFIG, i);
   1819	}
   1820
   1821	ocelot_rmw(ocelot, ANA_SG_ACCESS_CTRL_CONFIG_CHANGE,
   1822		   ANA_SG_ACCESS_CTRL_CONFIG_CHANGE,
   1823		   ANA_SG_ACCESS_CTRL);
   1824
   1825	return readx_poll_timeout(vsc9959_sgi_cfg_status, ocelot, val,
   1826				  (!(ANA_SG_ACCESS_CTRL_CONFIG_CHANGE & val)),
   1827				  10, 100000);
   1828}
   1829
   1830static int vsc9959_psfp_sgi_table_add(struct ocelot *ocelot,
   1831				      struct felix_stream_gate *sgi)
   1832{
   1833	struct felix_stream_gate_entry *tmp;
   1834	struct ocelot_psfp_list *psfp;
   1835	int ret;
   1836
   1837	psfp = &ocelot->psfp;
   1838
   1839	list_for_each_entry(tmp, &psfp->sgi_list, list)
   1840		if (tmp->index == sgi->index) {
   1841			refcount_inc(&tmp->refcount);
   1842			return 0;
   1843		}
   1844
   1845	tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
   1846	if (!tmp)
   1847		return -ENOMEM;
   1848
   1849	ret = vsc9959_psfp_sgi_set(ocelot, sgi);
   1850	if (ret) {
   1851		kfree(tmp);
   1852		return ret;
   1853	}
   1854
   1855	tmp->index = sgi->index;
   1856	refcount_set(&tmp->refcount, 1);
   1857	list_add_tail(&tmp->list, &psfp->sgi_list);
   1858
   1859	return 0;
   1860}
   1861
   1862static void vsc9959_psfp_sgi_table_del(struct ocelot *ocelot,
   1863				       u32 index)
   1864{
   1865	struct felix_stream_gate_entry *tmp, *n;
   1866	struct felix_stream_gate sgi = {0};
   1867	struct ocelot_psfp_list *psfp;
   1868	u8 z;
   1869
   1870	psfp = &ocelot->psfp;
   1871
   1872	list_for_each_entry_safe(tmp, n, &psfp->sgi_list, list)
   1873		if (tmp->index == index) {
   1874			z = refcount_dec_and_test(&tmp->refcount);
   1875			if (z) {
   1876				sgi.index = index;
   1877				sgi.enable = 0;
   1878				vsc9959_psfp_sgi_set(ocelot, &sgi);
   1879				list_del(&tmp->list);
   1880				kfree(tmp);
   1881			}
   1882			break;
   1883		}
   1884}
   1885
   1886static void vsc9959_psfp_counters_get(struct ocelot *ocelot, u32 index,
   1887				      struct felix_stream_filter_counters *counters)
   1888{
   1889	mutex_lock(&ocelot->stats_lock);
   1890
   1891	ocelot_rmw(ocelot, SYS_STAT_CFG_STAT_VIEW(index),
   1892		   SYS_STAT_CFG_STAT_VIEW_M,
   1893		   SYS_STAT_CFG);
   1894
   1895	counters->match = ocelot_read_gix(ocelot, SYS_CNT, 0x200);
   1896	counters->not_pass_gate = ocelot_read_gix(ocelot, SYS_CNT, 0x201);
   1897	counters->not_pass_sdu = ocelot_read_gix(ocelot, SYS_CNT, 0x202);
   1898	counters->red = ocelot_read_gix(ocelot, SYS_CNT, 0x203);
   1899
   1900	/* Clear the PSFP counter. */
   1901	ocelot_write(ocelot,
   1902		     SYS_STAT_CFG_STAT_VIEW(index) |
   1903		     SYS_STAT_CFG_STAT_CLEAR_SHOT(0x10),
   1904		     SYS_STAT_CFG);
   1905
   1906	mutex_unlock(&ocelot->stats_lock);
   1907}
   1908
   1909static int vsc9959_psfp_filter_add(struct ocelot *ocelot, int port,
   1910				   struct flow_cls_offload *f)
   1911{
   1912	struct netlink_ext_ack *extack = f->common.extack;
   1913	struct felix_stream_filter old_sfi, *sfi_entry;
   1914	struct felix_stream_filter sfi = {0};
   1915	const struct flow_action_entry *a;
   1916	struct felix_stream *stream_entry;
   1917	struct felix_stream stream = {0};
   1918	struct felix_stream_gate *sgi;
   1919	struct ocelot_psfp_list *psfp;
   1920	struct ocelot_policer pol;
   1921	int ret, i, size;
   1922	u64 rate, burst;
   1923	u32 index;
   1924
   1925	psfp = &ocelot->psfp;
   1926
   1927	ret = vsc9959_stream_identify(f, &stream);
   1928	if (ret) {
   1929		NL_SET_ERR_MSG_MOD(extack, "Only can match on VID, PCP, and dest MAC");
   1930		return ret;
   1931	}
   1932
   1933	flow_action_for_each(i, a, &f->rule->action) {
   1934		switch (a->id) {
   1935		case FLOW_ACTION_GATE:
   1936			size = struct_size(sgi, entries, a->gate.num_entries);
   1937			sgi = kzalloc(size, GFP_KERNEL);
   1938			if (!sgi) {
   1939				ret = -ENOMEM;
   1940				goto err;
   1941			}
   1942			vsc9959_psfp_parse_gate(a, sgi);
   1943			ret = vsc9959_psfp_sgi_table_add(ocelot, sgi);
   1944			if (ret) {
   1945				kfree(sgi);
   1946				goto err;
   1947			}
   1948			sfi.sg_valid = 1;
   1949			sfi.sgid = sgi->index;
   1950			kfree(sgi);
   1951			break;
   1952		case FLOW_ACTION_POLICE:
   1953			index = a->hw_index + VSC9959_PSFP_POLICER_BASE;
   1954			if (index > VSC9959_PSFP_POLICER_MAX) {
   1955				ret = -EINVAL;
   1956				goto err;
   1957			}
   1958
   1959			rate = a->police.rate_bytes_ps;
   1960			burst = rate * PSCHED_NS2TICKS(a->police.burst);
   1961			pol = (struct ocelot_policer) {
   1962				.burst = div_u64(burst, PSCHED_TICKS_PER_SEC),
   1963				.rate = div_u64(rate, 1000) * 8,
   1964			};
   1965			ret = ocelot_vcap_policer_add(ocelot, index, &pol);
   1966			if (ret)
   1967				goto err;
   1968
   1969			sfi.fm_valid = 1;
   1970			sfi.fmid = index;
   1971			sfi.maxsdu = a->police.mtu;
   1972			break;
   1973		default:
   1974			return -EOPNOTSUPP;
   1975		}
   1976	}
   1977
   1978	stream.ports = BIT(port);
   1979	stream.port = port;
   1980
   1981	sfi.portmask = stream.ports;
   1982	sfi.prio_valid = (stream.prio < 0 ? 0 : 1);
   1983	sfi.prio = (sfi.prio_valid ? stream.prio : 0);
   1984	sfi.enable = 1;
   1985
   1986	/* Check if stream is set. */
   1987	stream_entry = vsc9959_stream_table_lookup(&psfp->stream_list, &stream);
   1988	if (stream_entry) {
   1989		if (stream_entry->ports & BIT(port)) {
   1990			NL_SET_ERR_MSG_MOD(extack,
   1991					   "The stream is added on this port");
   1992			ret = -EEXIST;
   1993			goto err;
   1994		}
   1995
   1996		if (stream_entry->ports != BIT(stream_entry->port)) {
   1997			NL_SET_ERR_MSG_MOD(extack,
   1998					   "The stream is added on two ports");
   1999			ret = -EEXIST;
   2000			goto err;
   2001		}
   2002
   2003		stream_entry->ports |= BIT(port);
   2004		stream.ports = stream_entry->ports;
   2005
   2006		sfi_entry = vsc9959_psfp_sfi_table_get(&psfp->sfi_list,
   2007						       stream_entry->sfid);
   2008		memcpy(&old_sfi, sfi_entry, sizeof(old_sfi));
   2009
   2010		vsc9959_psfp_sfi_table_del(ocelot, stream_entry->sfid);
   2011
   2012		old_sfi.portmask = stream_entry->ports;
   2013		sfi.portmask = stream.ports;
   2014
   2015		if (stream_entry->port > port) {
   2016			ret = vsc9959_psfp_sfi_table_add2(ocelot, &sfi,
   2017							  &old_sfi);
   2018			stream_entry->dummy = true;
   2019		} else {
   2020			ret = vsc9959_psfp_sfi_table_add2(ocelot, &old_sfi,
   2021							  &sfi);
   2022			stream.dummy = true;
   2023		}
   2024		if (ret)
   2025			goto err;
   2026
   2027		stream_entry->sfid = old_sfi.index;
   2028	} else {
   2029		ret = vsc9959_psfp_sfi_table_add(ocelot, &sfi);
   2030		if (ret)
   2031			goto err;
   2032	}
   2033
   2034	stream.sfid = sfi.index;
   2035	stream.sfid_valid = 1;
   2036	ret = vsc9959_stream_table_add(ocelot, &psfp->stream_list,
   2037				       &stream, extack);
   2038	if (ret) {
   2039		vsc9959_psfp_sfi_table_del(ocelot, stream.sfid);
   2040		goto err;
   2041	}
   2042
   2043	return 0;
   2044
   2045err:
   2046	if (sfi.sg_valid)
   2047		vsc9959_psfp_sgi_table_del(ocelot, sfi.sgid);
   2048
   2049	if (sfi.fm_valid)
   2050		ocelot_vcap_policer_del(ocelot, sfi.fmid);
   2051
   2052	return ret;
   2053}
   2054
   2055static int vsc9959_psfp_filter_del(struct ocelot *ocelot,
   2056				   struct flow_cls_offload *f)
   2057{
   2058	struct felix_stream *stream, tmp, *stream_entry;
   2059	static struct felix_stream_filter *sfi;
   2060	struct ocelot_psfp_list *psfp;
   2061
   2062	psfp = &ocelot->psfp;
   2063
   2064	stream = vsc9959_stream_table_get(&psfp->stream_list, f->cookie);
   2065	if (!stream)
   2066		return -ENOMEM;
   2067
   2068	sfi = vsc9959_psfp_sfi_table_get(&psfp->sfi_list, stream->sfid);
   2069	if (!sfi)
   2070		return -ENOMEM;
   2071
   2072	if (sfi->sg_valid)
   2073		vsc9959_psfp_sgi_table_del(ocelot, sfi->sgid);
   2074
   2075	if (sfi->fm_valid)
   2076		ocelot_vcap_policer_del(ocelot, sfi->fmid);
   2077
   2078	vsc9959_psfp_sfi_table_del(ocelot, stream->sfid);
   2079
   2080	memcpy(&tmp, stream, sizeof(tmp));
   2081
   2082	stream->sfid_valid = 0;
   2083	vsc9959_stream_table_del(ocelot, stream);
   2084
   2085	stream_entry = vsc9959_stream_table_lookup(&psfp->stream_list, &tmp);
   2086	if (stream_entry) {
   2087		stream_entry->ports = BIT(stream_entry->port);
   2088		if (stream_entry->dummy) {
   2089			stream_entry->dummy = false;
   2090			vsc9959_mact_stream_set(ocelot, stream_entry, NULL);
   2091		}
   2092		vsc9959_psfp_sfidmask_set(ocelot, stream_entry->sfid,
   2093					  stream_entry->ports);
   2094	}
   2095
   2096	return 0;
   2097}
   2098
   2099static int vsc9959_psfp_stats_get(struct ocelot *ocelot,
   2100				  struct flow_cls_offload *f,
   2101				  struct flow_stats *stats)
   2102{
   2103	struct felix_stream_filter_counters counters;
   2104	struct ocelot_psfp_list *psfp;
   2105	struct felix_stream *stream;
   2106
   2107	psfp = &ocelot->psfp;
   2108	stream = vsc9959_stream_table_get(&psfp->stream_list, f->cookie);
   2109	if (!stream)
   2110		return -ENOMEM;
   2111
   2112	vsc9959_psfp_counters_get(ocelot, stream->sfid, &counters);
   2113
   2114	stats->pkts = counters.match;
   2115	stats->drops = counters.not_pass_gate + counters.not_pass_sdu +
   2116		       counters.red;
   2117
   2118	return 0;
   2119}
   2120
   2121static void vsc9959_psfp_init(struct ocelot *ocelot)
   2122{
   2123	struct ocelot_psfp_list *psfp = &ocelot->psfp;
   2124
   2125	INIT_LIST_HEAD(&psfp->stream_list);
   2126	INIT_LIST_HEAD(&psfp->sfi_list);
   2127	INIT_LIST_HEAD(&psfp->sgi_list);
   2128}
   2129
   2130/* When using cut-through forwarding and the egress port runs at a higher data
   2131 * rate than the ingress port, the packet currently under transmission would
   2132 * suffer an underrun since it would be transmitted faster than it is received.
   2133 * The Felix switch implementation of cut-through forwarding does not check in
   2134 * hardware whether this condition is satisfied or not, so we must restrict the
   2135 * list of ports that have cut-through forwarding enabled on egress to only be
   2136 * the ports operating at the lowest link speed within their respective
   2137 * forwarding domain.
   2138 */
   2139static void vsc9959_cut_through_fwd(struct ocelot *ocelot)
   2140{
   2141	struct felix *felix = ocelot_to_felix(ocelot);
   2142	struct dsa_switch *ds = felix->ds;
   2143	int port, other_port;
   2144
   2145	lockdep_assert_held(&ocelot->fwd_domain_lock);
   2146
   2147	for (port = 0; port < ocelot->num_phys_ports; port++) {
   2148		struct ocelot_port *ocelot_port = ocelot->ports[port];
   2149		int min_speed = ocelot_port->speed;
   2150		unsigned long mask = 0;
   2151		u32 tmp, val = 0;
   2152
   2153		/* Disable cut-through on ports that are down */
   2154		if (ocelot_port->speed <= 0)
   2155			goto set;
   2156
   2157		if (dsa_is_cpu_port(ds, port)) {
   2158			/* Ocelot switches forward from the NPI port towards
   2159			 * any port, regardless of it being in the NPI port's
   2160			 * forwarding domain or not.
   2161			 */
   2162			mask = dsa_user_ports(ds);
   2163		} else {
   2164			mask = ocelot_get_bridge_fwd_mask(ocelot, port);
   2165			mask &= ~BIT(port);
   2166			if (ocelot->npi >= 0)
   2167				mask |= BIT(ocelot->npi);
   2168			else
   2169				mask |= ocelot_port_assigned_dsa_8021q_cpu_mask(ocelot,
   2170										port);
   2171		}
   2172
   2173		/* Calculate the minimum link speed, among the ports that are
   2174		 * up, of this source port's forwarding domain.
   2175		 */
   2176		for_each_set_bit(other_port, &mask, ocelot->num_phys_ports) {
   2177			struct ocelot_port *other_ocelot_port;
   2178
   2179			other_ocelot_port = ocelot->ports[other_port];
   2180			if (other_ocelot_port->speed <= 0)
   2181				continue;
   2182
   2183			if (min_speed > other_ocelot_port->speed)
   2184				min_speed = other_ocelot_port->speed;
   2185		}
   2186
   2187		/* Enable cut-through forwarding for all traffic classes. */
   2188		if (ocelot_port->speed == min_speed)
   2189			val = GENMASK(7, 0);
   2190
   2191set:
   2192		tmp = ocelot_read_rix(ocelot, ANA_CUT_THRU_CFG, port);
   2193		if (tmp == val)
   2194			continue;
   2195
   2196		dev_dbg(ocelot->dev,
   2197			"port %d fwd mask 0x%lx speed %d min_speed %d, %s cut-through forwarding\n",
   2198			port, mask, ocelot_port->speed, min_speed,
   2199			val ? "enabling" : "disabling");
   2200
   2201		ocelot_write_rix(ocelot, val, ANA_CUT_THRU_CFG, port);
   2202	}
   2203}
   2204
   2205static const struct ocelot_ops vsc9959_ops = {
   2206	.reset			= vsc9959_reset,
   2207	.wm_enc			= vsc9959_wm_enc,
   2208	.wm_dec			= vsc9959_wm_dec,
   2209	.wm_stat		= vsc9959_wm_stat,
   2210	.port_to_netdev		= felix_port_to_netdev,
   2211	.netdev_to_port		= felix_netdev_to_port,
   2212	.psfp_init		= vsc9959_psfp_init,
   2213	.psfp_filter_add	= vsc9959_psfp_filter_add,
   2214	.psfp_filter_del	= vsc9959_psfp_filter_del,
   2215	.psfp_stats_get		= vsc9959_psfp_stats_get,
   2216	.cut_through_fwd	= vsc9959_cut_through_fwd,
   2217};
   2218
   2219static const struct felix_info felix_info_vsc9959 = {
   2220	.target_io_res		= vsc9959_target_io_res,
   2221	.port_io_res		= vsc9959_port_io_res,
   2222	.imdio_res		= &vsc9959_imdio_res,
   2223	.regfields		= vsc9959_regfields,
   2224	.map			= vsc9959_regmap,
   2225	.ops			= &vsc9959_ops,
   2226	.stats_layout		= vsc9959_stats_layout,
   2227	.vcap			= vsc9959_vcap_props,
   2228	.vcap_pol_base		= VSC9959_VCAP_POLICER_BASE,
   2229	.vcap_pol_max		= VSC9959_VCAP_POLICER_MAX,
   2230	.vcap_pol_base2		= 0,
   2231	.vcap_pol_max2		= 0,
   2232	.num_mact_rows		= 2048,
   2233	.num_ports		= VSC9959_NUM_PORTS,
   2234	.num_tx_queues		= OCELOT_NUM_TC,
   2235	.quirk_no_xtr_irq	= true,
   2236	.ptp_caps		= &vsc9959_ptp_caps,
   2237	.mdio_bus_alloc		= vsc9959_mdio_bus_alloc,
   2238	.mdio_bus_free		= vsc9959_mdio_bus_free,
   2239	.phylink_validate	= vsc9959_phylink_validate,
   2240	.port_modes		= vsc9959_port_modes,
   2241	.port_setup_tc		= vsc9959_port_setup_tc,
   2242	.port_sched_speed_set	= vsc9959_sched_speed_set,
   2243	.init_regmap		= ocelot_regmap_init,
   2244};
   2245
   2246static irqreturn_t felix_irq_handler(int irq, void *data)
   2247{
   2248	struct ocelot *ocelot = (struct ocelot *)data;
   2249
   2250	/* The INTB interrupt is used for both PTP TX timestamp interrupt
   2251	 * and preemption status change interrupt on each port.
   2252	 *
   2253	 * - Get txtstamp if have
   2254	 * - TODO: handle preemption. Without handling it, driver may get
   2255	 *   interrupt storm.
   2256	 */
   2257
   2258	ocelot_get_txtstamp(ocelot);
   2259
   2260	return IRQ_HANDLED;
   2261}
   2262
   2263static int felix_pci_probe(struct pci_dev *pdev,
   2264			   const struct pci_device_id *id)
   2265{
   2266	struct dsa_switch *ds;
   2267	struct ocelot *ocelot;
   2268	struct felix *felix;
   2269	int err;
   2270
   2271	if (pdev->dev.of_node && !of_device_is_available(pdev->dev.of_node)) {
   2272		dev_info(&pdev->dev, "device is disabled, skipping\n");
   2273		return -ENODEV;
   2274	}
   2275
   2276	err = pci_enable_device(pdev);
   2277	if (err) {
   2278		dev_err(&pdev->dev, "device enable failed\n");
   2279		goto err_pci_enable;
   2280	}
   2281
   2282	felix = kzalloc(sizeof(struct felix), GFP_KERNEL);
   2283	if (!felix) {
   2284		err = -ENOMEM;
   2285		dev_err(&pdev->dev, "Failed to allocate driver memory\n");
   2286		goto err_alloc_felix;
   2287	}
   2288
   2289	pci_set_drvdata(pdev, felix);
   2290	ocelot = &felix->ocelot;
   2291	ocelot->dev = &pdev->dev;
   2292	ocelot->num_flooding_pgids = OCELOT_NUM_TC;
   2293	felix->info = &felix_info_vsc9959;
   2294	felix->switch_base = pci_resource_start(pdev, VSC9959_SWITCH_PCI_BAR);
   2295	felix->imdio_base = pci_resource_start(pdev, VSC9959_IMDIO_PCI_BAR);
   2296
   2297	pci_set_master(pdev);
   2298
   2299	err = devm_request_threaded_irq(&pdev->dev, pdev->irq, NULL,
   2300					&felix_irq_handler, IRQF_ONESHOT,
   2301					"felix-intb", ocelot);
   2302	if (err) {
   2303		dev_err(&pdev->dev, "Failed to request irq\n");
   2304		goto err_alloc_irq;
   2305	}
   2306
   2307	ocelot->ptp = 1;
   2308
   2309	ds = kzalloc(sizeof(struct dsa_switch), GFP_KERNEL);
   2310	if (!ds) {
   2311		err = -ENOMEM;
   2312		dev_err(&pdev->dev, "Failed to allocate DSA switch\n");
   2313		goto err_alloc_ds;
   2314	}
   2315
   2316	ds->dev = &pdev->dev;
   2317	ds->num_ports = felix->info->num_ports;
   2318	ds->num_tx_queues = felix->info->num_tx_queues;
   2319	ds->ops = &felix_switch_ops;
   2320	ds->priv = ocelot;
   2321	felix->ds = ds;
   2322	felix->tag_proto = DSA_TAG_PROTO_OCELOT;
   2323
   2324	err = dsa_register_switch(ds);
   2325	if (err) {
   2326		dev_err_probe(&pdev->dev, err, "Failed to register DSA switch\n");
   2327		goto err_register_ds;
   2328	}
   2329
   2330	return 0;
   2331
   2332err_register_ds:
   2333	kfree(ds);
   2334err_alloc_ds:
   2335err_alloc_irq:
   2336	kfree(felix);
   2337err_alloc_felix:
   2338	pci_disable_device(pdev);
   2339err_pci_enable:
   2340	return err;
   2341}
   2342
   2343static void felix_pci_remove(struct pci_dev *pdev)
   2344{
   2345	struct felix *felix = pci_get_drvdata(pdev);
   2346
   2347	if (!felix)
   2348		return;
   2349
   2350	dsa_unregister_switch(felix->ds);
   2351
   2352	kfree(felix->ds);
   2353	kfree(felix);
   2354
   2355	pci_disable_device(pdev);
   2356
   2357	pci_set_drvdata(pdev, NULL);
   2358}
   2359
   2360static void felix_pci_shutdown(struct pci_dev *pdev)
   2361{
   2362	struct felix *felix = pci_get_drvdata(pdev);
   2363
   2364	if (!felix)
   2365		return;
   2366
   2367	dsa_switch_shutdown(felix->ds);
   2368
   2369	pci_set_drvdata(pdev, NULL);
   2370}
   2371
   2372static struct pci_device_id felix_ids[] = {
   2373	{
   2374		/* NXP LS1028A */
   2375		PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0xEEF0),
   2376	},
   2377	{ 0, }
   2378};
   2379MODULE_DEVICE_TABLE(pci, felix_ids);
   2380
   2381static struct pci_driver felix_vsc9959_pci_driver = {
   2382	.name		= "mscc_felix",
   2383	.id_table	= felix_ids,
   2384	.probe		= felix_pci_probe,
   2385	.remove		= felix_pci_remove,
   2386	.shutdown	= felix_pci_shutdown,
   2387};
   2388module_pci_driver(felix_vsc9959_pci_driver);
   2389
   2390MODULE_DESCRIPTION("Felix Switch driver");
   2391MODULE_LICENSE("GPL v2");