Commit 611ba753 authored by David S. Miller's avatar David S. Miller

Merge branch 'HW-support-for-VCAP-IS1-and-ES0-in-mscc_ocelot'

Vladimir Oltean says:

====================
HW support for VCAP IS1 and ES0 in mscc_ocelot

The patches from RFC series "Offload tc-flower to mscc_ocelot switch
using VCAP chains" have been split into 2:
https://patchwork.ozlabs.org/project/netdev/list/?series=204810&state=*

This is the boring part, that deals with the prerequisites, and not with
tc-flower integration. Apart from the initialization of some hardware
blocks, which at this point still don't do anything, no new
functionality is introduced.

- Key and action field offsets are defined for the supported switches.
- VCAP properties are added to the driver for the new TCAM blocks. But
  instead of adding them manually as was done for IS2, which is error
  prone, the driver is refactored to read these parameters from
  hardware, which is possible.
- Some improvements regarding the processing of struct ocelot_vcap_filter.
- Extending the code to be compatible with full and quarter keys.

This series was tested, along with other patches not yet submitted, on
the Felix and Seville switches.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 879456be 98642d1a
......@@ -134,11 +134,13 @@ switch@1010000 {
<0x1280000 0x100>,
<0x1800000 0x80000>,
<0x1880000 0x10000>,
<0x1040000 0x10000>,
<0x1050000 0x10000>,
<0x1060000 0x10000>;
reg-names = "sys", "rew", "qs", "ptp", "port0", "port1",
"port2", "port3", "port4", "port5", "port6",
"port7", "port8", "port9", "port10", "qsys",
"ana", "s2";
"ana", "s0", "s1", "s2";
interrupts = <18 21 22>;
interrupt-names = "ptp_rdy", "xtr", "inj";
......
......@@ -435,8 +435,6 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
ocelot->num_stats = felix->info->num_stats;
ocelot->shared_queue_sz = felix->info->shared_queue_sz;
ocelot->num_mact_rows = felix->info->num_mact_rows;
ocelot->vcap_is2_keys = felix->info->vcap_is2_keys;
ocelot->vcap_is2_actions= felix->info->vcap_is2_actions;
ocelot->vcap = felix->info->vcap;
ocelot->ops = felix->info->ops;
ocelot->inj_prefix = OCELOT_TAG_PREFIX_SHORT;
......
......@@ -21,9 +21,7 @@ struct felix_info {
unsigned int num_stats;
int num_ports;
int num_tx_queues;
struct vcap_field *vcap_is2_keys;
struct vcap_field *vcap_is2_actions;
const struct vcap_props *vcap;
struct vcap_props *vcap;
int switch_pci_bar;
int imdio_pci_bar;
const struct ptp_clock_info *ptp_caps;
......
......@@ -16,9 +16,6 @@
#include <linux/pci.h>
#include "felix.h"
#define VSC9959_VCAP_IS2_CNT 1024
#define VSC9959_VCAP_IS2_ENTRY_WIDTH 376
#define VSC9959_VCAP_PORT_CNT 6
#define VSC9959_TAS_GCL_ENTRY_MAX 63
static const u32 vsc9959_ana_regmap[] = {
......@@ -138,14 +135,27 @@ static const u32 vsc9959_qs_regmap[] = {
REG_RESERVED(QS_INH_DBG),
};
static const u32 vsc9959_s2_regmap[] = {
REG(S2_CORE_UPDATE_CTRL, 0x000000),
REG(S2_CORE_MV_CFG, 0x000004),
REG(S2_CACHE_ENTRY_DAT, 0x000008),
REG(S2_CACHE_MASK_DAT, 0x000108),
REG(S2_CACHE_ACTION_DAT, 0x000208),
REG(S2_CACHE_CNT_DAT, 0x000308),
REG(S2_CACHE_TG_DAT, 0x000388),
static const u32 vsc9959_vcap_regmap[] = {
/* VCAP_CORE_CFG */
REG(VCAP_CORE_UPDATE_CTRL, 0x000000),
REG(VCAP_CORE_MV_CFG, 0x000004),
/* VCAP_CORE_CACHE */
REG(VCAP_CACHE_ENTRY_DAT, 0x000008),
REG(VCAP_CACHE_MASK_DAT, 0x000108),
REG(VCAP_CACHE_ACTION_DAT, 0x000208),
REG(VCAP_CACHE_CNT_DAT, 0x000308),
REG(VCAP_CACHE_TG_DAT, 0x000388),
/* VCAP_CONST */
REG(VCAP_CONST_VCAP_VER, 0x000398),
REG(VCAP_CONST_ENTRY_WIDTH, 0x00039c),
REG(VCAP_CONST_ENTRY_CNT, 0x0003a0),
REG(VCAP_CONST_ENTRY_SWCNT, 0x0003a4),
REG(VCAP_CONST_ENTRY_TG_WIDTH, 0x0003a8),
REG(VCAP_CONST_ACTION_DEF_CNT, 0x0003ac),
REG(VCAP_CONST_ACTION_WIDTH, 0x0003b0),
REG(VCAP_CONST_CNT_WIDTH, 0x0003b4),
REG(VCAP_CONST_CORE_CNT, 0x0003b8),
REG(VCAP_CONST_IF_CNT, 0x0003bc),
};
static const u32 vsc9959_qsys_regmap[] = {
......@@ -359,7 +369,9 @@ static const u32 *vsc9959_regmap[TARGET_MAX] = {
[QSYS] = vsc9959_qsys_regmap,
[REW] = vsc9959_rew_regmap,
[SYS] = vsc9959_sys_regmap,
[S2] = vsc9959_s2_regmap,
[S0] = vsc9959_vcap_regmap,
[S1] = vsc9959_vcap_regmap,
[S2] = vsc9959_vcap_regmap,
[PTP] = vsc9959_ptp_regmap,
[GCB] = vsc9959_gcb_regmap,
[DEV_GMII] = vsc9959_dev_gmii_regmap,
......@@ -392,6 +404,16 @@ static const struct resource vsc9959_target_io_res[TARGET_MAX] = {
.end = 0x001ffff,
.name = "sys",
},
[S0] = {
.start = 0x0040000,
.end = 0x00403ff,
.name = "s0",
},
[S1] = {
.start = 0x0050000,
.end = 0x00503ff,
.name = "s1",
},
[S2] = {
.start = 0x0060000,
.end = 0x00603ff,
......@@ -596,6 +618,112 @@ static const struct ocelot_stat_layout vsc9959_stats_layout[] = {
{ .offset = 0x111, .name = "drop_green_prio_7", },
};
static const struct vcap_field vsc9959_vcap_es0_keys[] = {
[VCAP_ES0_EGR_PORT] = { 0, 3},
[VCAP_ES0_IGR_PORT] = { 3, 3},
[VCAP_ES0_RSV] = { 6, 2},
[VCAP_ES0_L2_MC] = { 8, 1},
[VCAP_ES0_L2_BC] = { 9, 1},
[VCAP_ES0_VID] = { 10, 12},
[VCAP_ES0_DP] = { 22, 1},
[VCAP_ES0_PCP] = { 23, 3},
};
static const struct vcap_field vsc9959_vcap_es0_actions[] = {
[VCAP_ES0_ACT_PUSH_OUTER_TAG] = { 0, 2},
[VCAP_ES0_ACT_PUSH_INNER_TAG] = { 2, 1},
[VCAP_ES0_ACT_TAG_A_TPID_SEL] = { 3, 2},
[VCAP_ES0_ACT_TAG_A_VID_SEL] = { 5, 1},
[VCAP_ES0_ACT_TAG_A_PCP_SEL] = { 6, 2},
[VCAP_ES0_ACT_TAG_A_DEI_SEL] = { 8, 2},
[VCAP_ES0_ACT_TAG_B_TPID_SEL] = { 10, 2},
[VCAP_ES0_ACT_TAG_B_VID_SEL] = { 12, 1},
[VCAP_ES0_ACT_TAG_B_PCP_SEL] = { 13, 2},
[VCAP_ES0_ACT_TAG_B_DEI_SEL] = { 15, 2},
[VCAP_ES0_ACT_VID_A_VAL] = { 17, 12},
[VCAP_ES0_ACT_PCP_A_VAL] = { 29, 3},
[VCAP_ES0_ACT_DEI_A_VAL] = { 32, 1},
[VCAP_ES0_ACT_VID_B_VAL] = { 33, 12},
[VCAP_ES0_ACT_PCP_B_VAL] = { 45, 3},
[VCAP_ES0_ACT_DEI_B_VAL] = { 48, 1},
[VCAP_ES0_ACT_RSV] = { 49, 23},
[VCAP_ES0_ACT_HIT_STICKY] = { 72, 1},
};
static const struct vcap_field vsc9959_vcap_is1_keys[] = {
[VCAP_IS1_HK_TYPE] = { 0, 1},
[VCAP_IS1_HK_LOOKUP] = { 1, 2},
[VCAP_IS1_HK_IGR_PORT_MASK] = { 3, 7},
[VCAP_IS1_HK_RSV] = { 10, 9},
[VCAP_IS1_HK_OAM_Y1731] = { 19, 1},
[VCAP_IS1_HK_L2_MC] = { 20, 1},
[VCAP_IS1_HK_L2_BC] = { 21, 1},
[VCAP_IS1_HK_IP_MC] = { 22, 1},
[VCAP_IS1_HK_VLAN_TAGGED] = { 23, 1},
[VCAP_IS1_HK_VLAN_DBL_TAGGED] = { 24, 1},
[VCAP_IS1_HK_TPID] = { 25, 1},
[VCAP_IS1_HK_VID] = { 26, 12},
[VCAP_IS1_HK_DEI] = { 38, 1},
[VCAP_IS1_HK_PCP] = { 39, 3},
/* Specific Fields for IS1 Half Key S1_NORMAL */
[VCAP_IS1_HK_L2_SMAC] = { 42, 48},
[VCAP_IS1_HK_ETYPE_LEN] = { 90, 1},
[VCAP_IS1_HK_ETYPE] = { 91, 16},
[VCAP_IS1_HK_IP_SNAP] = {107, 1},
[VCAP_IS1_HK_IP4] = {108, 1},
/* Layer-3 Information */
[VCAP_IS1_HK_L3_FRAGMENT] = {109, 1},
[VCAP_IS1_HK_L3_FRAG_OFS_GT0] = {110, 1},
[VCAP_IS1_HK_L3_OPTIONS] = {111, 1},
[VCAP_IS1_HK_L3_DSCP] = {112, 6},
[VCAP_IS1_HK_L3_IP4_SIP] = {118, 32},
/* Layer-4 Information */
[VCAP_IS1_HK_TCP_UDP] = {150, 1},
[VCAP_IS1_HK_TCP] = {151, 1},
[VCAP_IS1_HK_L4_SPORT] = {152, 16},
[VCAP_IS1_HK_L4_RNG] = {168, 8},
/* Specific Fields for IS1 Half Key S1_5TUPLE_IP4 */
[VCAP_IS1_HK_IP4_INNER_TPID] = { 42, 1},
[VCAP_IS1_HK_IP4_INNER_VID] = { 43, 12},
[VCAP_IS1_HK_IP4_INNER_DEI] = { 55, 1},
[VCAP_IS1_HK_IP4_INNER_PCP] = { 56, 3},
[VCAP_IS1_HK_IP4_IP4] = { 59, 1},
[VCAP_IS1_HK_IP4_L3_FRAGMENT] = { 60, 1},
[VCAP_IS1_HK_IP4_L3_FRAG_OFS_GT0] = { 61, 1},
[VCAP_IS1_HK_IP4_L3_OPTIONS] = { 62, 1},
[VCAP_IS1_HK_IP4_L3_DSCP] = { 63, 6},
[VCAP_IS1_HK_IP4_L3_IP4_DIP] = { 69, 32},
[VCAP_IS1_HK_IP4_L3_IP4_SIP] = {101, 32},
[VCAP_IS1_HK_IP4_L3_PROTO] = {133, 8},
[VCAP_IS1_HK_IP4_TCP_UDP] = {141, 1},
[VCAP_IS1_HK_IP4_TCP] = {142, 1},
[VCAP_IS1_HK_IP4_L4_RNG] = {143, 8},
[VCAP_IS1_HK_IP4_IP_PAYLOAD_S1_5TUPLE] = {151, 32},
};
static const struct vcap_field vsc9959_vcap_is1_actions[] = {
[VCAP_IS1_ACT_DSCP_ENA] = { 0, 1},
[VCAP_IS1_ACT_DSCP_VAL] = { 1, 6},
[VCAP_IS1_ACT_QOS_ENA] = { 7, 1},
[VCAP_IS1_ACT_QOS_VAL] = { 8, 3},
[VCAP_IS1_ACT_DP_ENA] = { 11, 1},
[VCAP_IS1_ACT_DP_VAL] = { 12, 1},
[VCAP_IS1_ACT_PAG_OVERRIDE_MASK] = { 13, 8},
[VCAP_IS1_ACT_PAG_VAL] = { 21, 8},
[VCAP_IS1_ACT_RSV] = { 29, 9},
[VCAP_IS1_ACT_VID_REPLACE_ENA] = { 38, 1},
[VCAP_IS1_ACT_VID_ADD_VAL] = { 39, 12},
[VCAP_IS1_ACT_FID_SEL] = { 51, 2},
[VCAP_IS1_ACT_FID_VAL] = { 53, 13},
[VCAP_IS1_ACT_PCP_DEI_ENA] = { 66, 1},
[VCAP_IS1_ACT_PCP_VAL] = { 67, 3},
[VCAP_IS1_ACT_DEI_VAL] = { 70, 1},
[VCAP_IS1_ACT_VLAN_POP_CNT_ENA] = { 71, 1},
[VCAP_IS1_ACT_VLAN_POP_CNT] = { 72, 2},
[VCAP_IS1_ACT_CUSTOM_ACE_TYPE_ENA] = { 74, 4},
[VCAP_IS1_ACT_HIT_STICKY] = { 78, 1},
};
static struct vcap_field vsc9959_vcap_is2_keys[] = {
/* Common: 41 bits */
[VCAP_IS2_TYPE] = { 0, 4},
......@@ -694,15 +822,32 @@ static struct vcap_field vsc9959_vcap_is2_actions[] = {
[VCAP_IS2_ACT_HIT_CNT] = { 49, 32},
};
static const struct vcap_props vsc9959_vcap_props[] = {
static struct vcap_props vsc9959_vcap_props[] = {
[VCAP_ES0] = {
.action_type_width = 0,
.action_table = {
[ES0_ACTION_TYPE_NORMAL] = {
.width = 72, /* HIT_STICKY not included */
.count = 1,
},
},
.target = S0,
.keys = vsc9959_vcap_es0_keys,
.actions = vsc9959_vcap_es0_actions,
},
[VCAP_IS1] = {
.action_type_width = 0,
.action_table = {
[IS1_ACTION_TYPE_NORMAL] = {
.width = 78, /* HIT_STICKY not included */
.count = 4,
},
},
.target = S1,
.keys = vsc9959_vcap_is1_keys,
.actions = vsc9959_vcap_is1_actions,
},
[VCAP_IS2] = {
.tg_width = 2,
.sw_count = 4,
.entry_count = VSC9959_VCAP_IS2_CNT,
.entry_width = VSC9959_VCAP_IS2_ENTRY_WIDTH,
.action_count = VSC9959_VCAP_IS2_CNT +
VSC9959_VCAP_PORT_CNT + 2,
.action_width = 89,
.action_type_width = 1,
.action_table = {
[IS2_ACTION_TYPE_NORMAL] = {
......@@ -714,8 +859,9 @@ static const struct vcap_props vsc9959_vcap_props[] = {
.count = 4
},
},
.counter_words = 4,
.counter_width = 32,
.target = S2,
.keys = vsc9959_vcap_is2_keys,
.actions = vsc9959_vcap_is2_actions,
},
};
......@@ -1184,8 +1330,6 @@ static const struct felix_info felix_info_vsc9959 = {
.ops = &vsc9959_ops,
.stats_layout = vsc9959_stats_layout,
.num_stats = ARRAY_SIZE(vsc9959_stats_layout),
.vcap_is2_keys = vsc9959_vcap_is2_keys,
.vcap_is2_actions = vsc9959_vcap_is2_actions,
.vcap = vsc9959_vcap_props,
.shared_queue_sz = 128 * 1024,
.num_mact_rows = 2048,
......
......@@ -12,10 +12,6 @@
#include <linux/iopoll.h>
#include "felix.h"
#define VSC9953_VCAP_IS2_CNT 1024
#define VSC9953_VCAP_IS2_ENTRY_WIDTH 376
#define VSC9953_VCAP_PORT_CNT 10
#define MSCC_MIIM_CMD_OPR_WRITE BIT(1)
#define MSCC_MIIM_CMD_OPR_READ BIT(2)
#define MSCC_MIIM_CMD_WRDATA_SHIFT 4
......@@ -140,14 +136,27 @@ static const u32 vsc9953_qs_regmap[] = {
REG_RESERVED(QS_INH_DBG),
};
static const u32 vsc9953_s2_regmap[] = {
REG(S2_CORE_UPDATE_CTRL, 0x000000),
REG(S2_CORE_MV_CFG, 0x000004),
REG(S2_CACHE_ENTRY_DAT, 0x000008),
REG(S2_CACHE_MASK_DAT, 0x000108),
REG(S2_CACHE_ACTION_DAT, 0x000208),
REG(S2_CACHE_CNT_DAT, 0x000308),
REG(S2_CACHE_TG_DAT, 0x000388),
static const u32 vsc9953_vcap_regmap[] = {
/* VCAP_CORE_CFG */
REG(VCAP_CORE_UPDATE_CTRL, 0x000000),
REG(VCAP_CORE_MV_CFG, 0x000004),
/* VCAP_CORE_CACHE */
REG(VCAP_CACHE_ENTRY_DAT, 0x000008),
REG(VCAP_CACHE_MASK_DAT, 0x000108),
REG(VCAP_CACHE_ACTION_DAT, 0x000208),
REG(VCAP_CACHE_CNT_DAT, 0x000308),
REG(VCAP_CACHE_TG_DAT, 0x000388),
/* VCAP_CONST */
REG(VCAP_CONST_VCAP_VER, 0x000398),
REG(VCAP_CONST_ENTRY_WIDTH, 0x00039c),
REG(VCAP_CONST_ENTRY_CNT, 0x0003a0),
REG(VCAP_CONST_ENTRY_SWCNT, 0x0003a4),
REG(VCAP_CONST_ENTRY_TG_WIDTH, 0x0003a8),
REG(VCAP_CONST_ACTION_DEF_CNT, 0x0003ac),
REG(VCAP_CONST_ACTION_WIDTH, 0x0003b0),
REG(VCAP_CONST_CNT_WIDTH, 0x0003b4),
REG_RESERVED(VCAP_CONST_CORE_CNT),
REG_RESERVED(VCAP_CONST_IF_CNT),
};
static const u32 vsc9953_qsys_regmap[] = {
......@@ -352,7 +361,9 @@ static const u32 *vsc9953_regmap[TARGET_MAX] = {
[QSYS] = vsc9953_qsys_regmap,
[REW] = vsc9953_rew_regmap,
[SYS] = vsc9953_sys_regmap,
[S2] = vsc9953_s2_regmap,
[S0] = vsc9953_vcap_regmap,
[S1] = vsc9953_vcap_regmap,
[S2] = vsc9953_vcap_regmap,
[GCB] = vsc9953_gcb_regmap,
[DEV_GMII] = vsc9953_dev_gmii_regmap,
};
......@@ -384,6 +395,16 @@ static const struct resource vsc9953_target_io_res[TARGET_MAX] = {
.end = 0x001ffff,
.name = "sys",
},
[S0] = {
.start = 0x0040000,
.end = 0x00403ff,
.name = "s0",
},
[S1] = {
.start = 0x0050000,
.end = 0x00503ff,
.name = "s1",
},
[S2] = {
.start = 0x0060000,
.end = 0x00603ff,
......@@ -599,6 +620,112 @@ static const struct ocelot_stat_layout vsc9953_stats_layout[] = {
{ .offset = 0x91, .name = "drop_green_prio_7", },
};
static const struct vcap_field vsc9953_vcap_es0_keys[] = {
[VCAP_ES0_EGR_PORT] = { 0, 4},
[VCAP_ES0_IGR_PORT] = { 4, 4},
[VCAP_ES0_RSV] = { 8, 2},
[VCAP_ES0_L2_MC] = { 10, 1},
[VCAP_ES0_L2_BC] = { 11, 1},
[VCAP_ES0_VID] = { 12, 12},
[VCAP_ES0_DP] = { 24, 1},
[VCAP_ES0_PCP] = { 25, 3},
};
static const struct vcap_field vsc9953_vcap_es0_actions[] = {
[VCAP_ES0_ACT_PUSH_OUTER_TAG] = { 0, 2},
[VCAP_ES0_ACT_PUSH_INNER_TAG] = { 2, 1},
[VCAP_ES0_ACT_TAG_A_TPID_SEL] = { 3, 2},
[VCAP_ES0_ACT_TAG_A_VID_SEL] = { 5, 1},
[VCAP_ES0_ACT_TAG_A_PCP_SEL] = { 6, 2},
[VCAP_ES0_ACT_TAG_A_DEI_SEL] = { 8, 2},
[VCAP_ES0_ACT_TAG_B_TPID_SEL] = { 10, 2},
[VCAP_ES0_ACT_TAG_B_VID_SEL] = { 12, 1},
[VCAP_ES0_ACT_TAG_B_PCP_SEL] = { 13, 2},
[VCAP_ES0_ACT_TAG_B_DEI_SEL] = { 15, 2},
[VCAP_ES0_ACT_VID_A_VAL] = { 17, 12},
[VCAP_ES0_ACT_PCP_A_VAL] = { 29, 3},
[VCAP_ES0_ACT_DEI_A_VAL] = { 32, 1},
[VCAP_ES0_ACT_VID_B_VAL] = { 33, 12},
[VCAP_ES0_ACT_PCP_B_VAL] = { 45, 3},
[VCAP_ES0_ACT_DEI_B_VAL] = { 48, 1},
[VCAP_ES0_ACT_RSV] = { 49, 24},
[VCAP_ES0_ACT_HIT_STICKY] = { 73, 1},
};
static const struct vcap_field vsc9953_vcap_is1_keys[] = {
[VCAP_IS1_HK_TYPE] = { 0, 1},
[VCAP_IS1_HK_LOOKUP] = { 1, 2},
[VCAP_IS1_HK_IGR_PORT_MASK] = { 3, 11},
[VCAP_IS1_HK_RSV] = { 14, 10},
/* VCAP_IS1_HK_OAM_Y1731 not supported */
[VCAP_IS1_HK_L2_MC] = { 24, 1},
[VCAP_IS1_HK_L2_BC] = { 25, 1},
[VCAP_IS1_HK_IP_MC] = { 26, 1},
[VCAP_IS1_HK_VLAN_TAGGED] = { 27, 1},
[VCAP_IS1_HK_VLAN_DBL_TAGGED] = { 28, 1},
[VCAP_IS1_HK_TPID] = { 29, 1},
[VCAP_IS1_HK_VID] = { 30, 12},
[VCAP_IS1_HK_DEI] = { 42, 1},
[VCAP_IS1_HK_PCP] = { 43, 3},
/* Specific Fields for IS1 Half Key S1_NORMAL */
[VCAP_IS1_HK_L2_SMAC] = { 46, 48},
[VCAP_IS1_HK_ETYPE_LEN] = { 94, 1},
[VCAP_IS1_HK_ETYPE] = { 95, 16},
[VCAP_IS1_HK_IP_SNAP] = {111, 1},
[VCAP_IS1_HK_IP4] = {112, 1},
/* Layer-3 Information */
[VCAP_IS1_HK_L3_FRAGMENT] = {113, 1},
[VCAP_IS1_HK_L3_FRAG_OFS_GT0] = {114, 1},
[VCAP_IS1_HK_L3_OPTIONS] = {115, 1},
[VCAP_IS1_HK_L3_DSCP] = {116, 6},
[VCAP_IS1_HK_L3_IP4_SIP] = {122, 32},
/* Layer-4 Information */
[VCAP_IS1_HK_TCP_UDP] = {154, 1},
[VCAP_IS1_HK_TCP] = {155, 1},
[VCAP_IS1_HK_L4_SPORT] = {156, 16},
[VCAP_IS1_HK_L4_RNG] = {172, 8},
/* Specific Fields for IS1 Half Key S1_5TUPLE_IP4 */
[VCAP_IS1_HK_IP4_INNER_TPID] = { 46, 1},
[VCAP_IS1_HK_IP4_INNER_VID] = { 47, 12},
[VCAP_IS1_HK_IP4_INNER_DEI] = { 59, 1},
[VCAP_IS1_HK_IP4_INNER_PCP] = { 60, 3},
[VCAP_IS1_HK_IP4_IP4] = { 63, 1},
[VCAP_IS1_HK_IP4_L3_FRAGMENT] = { 64, 1},
[VCAP_IS1_HK_IP4_L3_FRAG_OFS_GT0] = { 65, 1},
[VCAP_IS1_HK_IP4_L3_OPTIONS] = { 66, 1},
[VCAP_IS1_HK_IP4_L3_DSCP] = { 67, 6},
[VCAP_IS1_HK_IP4_L3_IP4_DIP] = { 73, 32},
[VCAP_IS1_HK_IP4_L3_IP4_SIP] = {105, 32},
[VCAP_IS1_HK_IP4_L3_PROTO] = {137, 8},
[VCAP_IS1_HK_IP4_TCP_UDP] = {145, 1},
[VCAP_IS1_HK_IP4_TCP] = {146, 1},
[VCAP_IS1_HK_IP4_L4_RNG] = {147, 8},
[VCAP_IS1_HK_IP4_IP_PAYLOAD_S1_5TUPLE] = {155, 32},
};
static const struct vcap_field vsc9953_vcap_is1_actions[] = {
[VCAP_IS1_ACT_DSCP_ENA] = { 0, 1},
[VCAP_IS1_ACT_DSCP_VAL] = { 1, 6},
[VCAP_IS1_ACT_QOS_ENA] = { 7, 1},
[VCAP_IS1_ACT_QOS_VAL] = { 8, 3},
[VCAP_IS1_ACT_DP_ENA] = { 11, 1},
[VCAP_IS1_ACT_DP_VAL] = { 12, 1},
[VCAP_IS1_ACT_PAG_OVERRIDE_MASK] = { 13, 8},
[VCAP_IS1_ACT_PAG_VAL] = { 21, 8},
[VCAP_IS1_ACT_RSV] = { 29, 11},
[VCAP_IS1_ACT_VID_REPLACE_ENA] = { 40, 1},
[VCAP_IS1_ACT_VID_ADD_VAL] = { 41, 12},
[VCAP_IS1_ACT_FID_SEL] = { 53, 2},
[VCAP_IS1_ACT_FID_VAL] = { 55, 13},
[VCAP_IS1_ACT_PCP_DEI_ENA] = { 68, 1},
[VCAP_IS1_ACT_PCP_VAL] = { 69, 3},
[VCAP_IS1_ACT_DEI_VAL] = { 72, 1},
[VCAP_IS1_ACT_VLAN_POP_CNT_ENA] = { 73, 1},
[VCAP_IS1_ACT_VLAN_POP_CNT] = { 74, 2},
[VCAP_IS1_ACT_CUSTOM_ACE_TYPE_ENA] = { 76, 4},
[VCAP_IS1_ACT_HIT_STICKY] = { 80, 1},
};
static struct vcap_field vsc9953_vcap_is2_keys[] = {
/* Common: 41 bits */
[VCAP_IS2_TYPE] = { 0, 4},
......@@ -684,15 +811,32 @@ static struct vcap_field vsc9953_vcap_is2_actions[] = {
[VCAP_IS2_ACT_HIT_CNT] = { 50, 32},
};
static const struct vcap_props vsc9953_vcap_props[] = {
static struct vcap_props vsc9953_vcap_props[] = {
[VCAP_ES0] = {
.action_type_width = 0,
.action_table = {
[ES0_ACTION_TYPE_NORMAL] = {
.width = 73, /* HIT_STICKY not included */
.count = 1,
},
},
.target = S0,
.keys = vsc9953_vcap_es0_keys,
.actions = vsc9953_vcap_es0_actions,
},
[VCAP_IS1] = {
.action_type_width = 0,
.action_table = {
[IS1_ACTION_TYPE_NORMAL] = {
.width = 80, /* HIT_STICKY not included */
.count = 4,
},
},
.target = S1,
.keys = vsc9953_vcap_is1_keys,
.actions = vsc9953_vcap_is1_actions,
},
[VCAP_IS2] = {
.tg_width = 2,
.sw_count = 4,
.entry_count = VSC9953_VCAP_IS2_CNT,
.entry_width = VSC9953_VCAP_IS2_ENTRY_WIDTH,
.action_count = VSC9953_VCAP_IS2_CNT +
VSC9953_VCAP_PORT_CNT + 2,
.action_width = 101,
.action_type_width = 1,
.action_table = {
[IS2_ACTION_TYPE_NORMAL] = {
......@@ -704,8 +848,9 @@ static const struct vcap_props vsc9953_vcap_props[] = {
.count = 4
},
},
.counter_words = 4,
.counter_width = 32,
.target = S2,
.keys = vsc9953_vcap_is2_keys,
.actions = vsc9953_vcap_is2_actions,
},
};
......@@ -1031,8 +1176,6 @@ static const struct felix_info seville_info_vsc9953 = {
.ops = &vsc9953_ops,
.stats_layout = vsc9953_stats_layout,
.num_stats = ARRAY_SIZE(vsc9953_stats_layout),
.vcap_is2_keys = vsc9953_vcap_is2_keys,
.vcap_is2_actions = vsc9953_vcap_is2_actions,
.vcap = vsc9953_vcap_props,
.shared_queue_sz = 2048 * 1024,
.num_mact_rows = 2048,
......
......@@ -5,6 +5,7 @@
* Copyright (c) 2017 Microsemi Corporation
*/
#include <linux/if_bridge.h>
#include <soc/mscc/ocelot_vcap.h>
#include "ocelot.h"
#include "ocelot_vcap.h"
......
......@@ -44,8 +44,8 @@ static int ocelot_flower_parse_action(struct flow_cls_offload *f,
return 0;
}
static int ocelot_flower_parse(struct flow_cls_offload *f,
struct ocelot_vcap_filter *filter)
static int ocelot_flower_parse_key(struct flow_cls_offload *f,
struct ocelot_vcap_filter *filter)
{
struct flow_rule *rule = flow_cls_offload_flow_rule(f);
struct flow_dissector *dissector = rule->match.dissector;
......@@ -179,9 +179,22 @@ static int ocelot_flower_parse(struct flow_cls_offload *f,
}
/* else, a filter of type OCELOT_VCAP_KEY_ANY is implicitly added */
return 0;
}
static int ocelot_flower_parse(struct flow_cls_offload *f,
struct ocelot_vcap_filter *filter)
{
int ret;
filter->prio = f->common.prio;
filter->id = f->cookie;
return ocelot_flower_parse_action(f, filter);
ret = ocelot_flower_parse_action(f, filter);
if (ret)
return ret;
return ocelot_flower_parse_key(f, filter);
}
static struct ocelot_vcap_filter
......@@ -221,28 +234,33 @@ EXPORT_SYMBOL_GPL(ocelot_cls_flower_replace);
int ocelot_cls_flower_destroy(struct ocelot *ocelot, int port,
struct flow_cls_offload *f, bool ingress)
{
struct ocelot_vcap_filter filter;
struct ocelot_vcap_block *block = &ocelot->block;
struct ocelot_vcap_filter *filter;
filter.prio = f->common.prio;
filter.id = f->cookie;
filter = ocelot_vcap_block_find_filter_by_id(block, f->cookie);
if (!filter)
return 0;
return ocelot_vcap_filter_del(ocelot, &filter);
return ocelot_vcap_filter_del(ocelot, filter);
}
EXPORT_SYMBOL_GPL(ocelot_cls_flower_destroy);
int ocelot_cls_flower_stats(struct ocelot *ocelot, int port,
struct flow_cls_offload *f, bool ingress)
{
struct ocelot_vcap_filter filter;
struct ocelot_vcap_block *block = &ocelot->block;
struct ocelot_vcap_filter *filter;
int ret;
filter.prio = f->common.prio;
filter.id = f->cookie;
ret = ocelot_vcap_filter_stats_update(ocelot, &filter);
filter = ocelot_vcap_block_find_filter_by_id(block, f->cookie);
if (!filter)
return 0;
ret = ocelot_vcap_filter_stats_update(ocelot, filter);
if (ret)
return ret;
flow_stats_update(&f->stats, 0x0, filter.stats.pkts, 0, 0x0,
flow_stats_update(&f->stats, 0x0, filter->stats.pkts, 0, 0x0,
FLOW_ACTION_HW_STATS_IMMEDIATE);
return 0;
}
......
......@@ -71,6 +71,23 @@ void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg)
}
EXPORT_SYMBOL(ocelot_port_writel);
u32 __ocelot_target_read_ix(struct ocelot *ocelot, enum ocelot_target target,
u32 reg, u32 offset)
{
u32 val;
regmap_read(ocelot->targets[target],
ocelot->map[target][reg] + offset, &val);
return val;
}
void __ocelot_target_write_ix(struct ocelot *ocelot, enum ocelot_target target,
u32 val, u32 reg, u32 offset)
{
regmap_write(ocelot->targets[target],
ocelot->map[target][reg] + offset, val);
}
int ocelot_regfields_init(struct ocelot *ocelot,
const struct reg_field *const regfields)
{
......
/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
/* Microsemi Ocelot Switch driver
* Copyright (c) 2018 Microsemi Corporation
*/
#ifndef _OCELOT_S2_CORE_H_
#define _OCELOT_S2_CORE_H_
#define S2_CORE_UPDATE_CTRL_UPDATE_CMD(x) (((x) << 22) & GENMASK(24, 22))
#define S2_CORE_UPDATE_CTRL_UPDATE_CMD_M GENMASK(24, 22)
#define S2_CORE_UPDATE_CTRL_UPDATE_CMD_X(x) (((x) & GENMASK(24, 22)) >> 22)
#define S2_CORE_UPDATE_CTRL_UPDATE_ENTRY_DIS BIT(21)
#define S2_CORE_UPDATE_CTRL_UPDATE_ACTION_DIS BIT(20)
#define S2_CORE_UPDATE_CTRL_UPDATE_CNT_DIS BIT(19)
#define S2_CORE_UPDATE_CTRL_UPDATE_ADDR(x) (((x) << 3) & GENMASK(18, 3))
#define S2_CORE_UPDATE_CTRL_UPDATE_ADDR_M GENMASK(18, 3)
#define S2_CORE_UPDATE_CTRL_UPDATE_ADDR_X(x) (((x) & GENMASK(18, 3)) >> 3)
#define S2_CORE_UPDATE_CTRL_UPDATE_SHOT BIT(2)
#define S2_CORE_UPDATE_CTRL_CLEAR_CACHE BIT(1)
#define S2_CORE_UPDATE_CTRL_MV_TRAFFIC_IGN BIT(0)
#define S2_CORE_MV_CFG_MV_NUM_POS(x) (((x) << 16) & GENMASK(31, 16))
#define S2_CORE_MV_CFG_MV_NUM_POS_M GENMASK(31, 16)
#define S2_CORE_MV_CFG_MV_NUM_POS_X(x) (((x) & GENMASK(31, 16)) >> 16)
#define S2_CORE_MV_CFG_MV_SIZE(x) ((x) & GENMASK(15, 0))
#define S2_CORE_MV_CFG_MV_SIZE_M GENMASK(15, 0)
#define S2_CACHE_ENTRY_DAT_RSZ 0x4
#define S2_CACHE_MASK_DAT_RSZ 0x4
#define S2_CACHE_ACTION_DAT_RSZ 0x4
#define S2_CACHE_CNT_DAT_RSZ 0x4
#define S2_STICKY_VCAP_ROW_DELETED_STICKY BIT(0)
#define S2_BIST_CTRL_TCAM_BIST BIT(1)
#define S2_BIST_CTRL_TCAM_INIT BIT(0)
#define S2_BIST_CFG_TCAM_BIST_SOE_ENA BIT(8)
#define S2_BIST_CFG_TCAM_HCG_DIS BIT(7)
#define S2_BIST_CFG_TCAM_CG_DIS BIT(6)
#define S2_BIST_CFG_TCAM_BIAS(x) ((x) & GENMASK(5, 0))
#define S2_BIST_CFG_TCAM_BIAS_M GENMASK(5, 0)
#define S2_BIST_STAT_BIST_RT_ERR BIT(15)
#define S2_BIST_STAT_BIST_PENC_ERR BIT(14)
#define S2_BIST_STAT_BIST_COMP_ERR BIT(13)
#define S2_BIST_STAT_BIST_ADDR_ERR BIT(12)
#define S2_BIST_STAT_BIST_BL1E_ERR BIT(11)
#define S2_BIST_STAT_BIST_BL1_ERR BIT(10)
#define S2_BIST_STAT_BIST_BL0E_ERR BIT(9)
#define S2_BIST_STAT_BIST_BL0_ERR BIT(8)
#define S2_BIST_STAT_BIST_PH1_ERR BIT(7)
#define S2_BIST_STAT_BIST_PH0_ERR BIT(6)
#define S2_BIST_STAT_BIST_PV1_ERR BIT(5)
#define S2_BIST_STAT_BIST_PV0_ERR BIT(4)
#define S2_BIST_STAT_BIST_RUN BIT(3)
#define S2_BIST_STAT_BIST_ERR BIT(2)
#define S2_BIST_STAT_BIST_BUSY BIT(1)
#define S2_BIST_STAT_TCAM_RDY BIT(0)
#endif /* _OCELOT_S2_CORE_H_ */
This diff is collapsed.
......@@ -221,7 +221,10 @@ int ocelot_vcap_filter_del(struct ocelot *ocelot,
struct ocelot_vcap_filter *rule);
int ocelot_vcap_filter_stats_update(struct ocelot *ocelot,
struct ocelot_vcap_filter *rule);
struct ocelot_vcap_filter *
ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, int id);
void ocelot_detect_vcap_constants(struct ocelot *ocelot);
int ocelot_vcap_init(struct ocelot *ocelot);
int ocelot_setup_tc_cls_flower(struct ocelot_port_private *priv,
......
......@@ -19,10 +19,6 @@
#include "ocelot.h"
#define IFH_EXTRACT_BITFIELD64(x, o, w) (((x) >> (o)) & GENMASK_ULL((w) - 1, 0))
#define VSC7514_VCAP_IS2_CNT 64
#define VSC7514_VCAP_IS2_ENTRY_WIDTH 376
#define VSC7514_VCAP_IS2_ACTION_WIDTH 99
#define VSC7514_VCAP_PORT_CNT 11
static const u32 ocelot_ana_regmap[] = {
REG(ANA_ADVLEARN, 0x009000),
......@@ -241,14 +237,27 @@ static const u32 ocelot_sys_regmap[] = {
REG(SYS_PTP_CFG, 0x0006c4),
};
static const u32 ocelot_s2_regmap[] = {
REG(S2_CORE_UPDATE_CTRL, 0x000000),
REG(S2_CORE_MV_CFG, 0x000004),
REG(S2_CACHE_ENTRY_DAT, 0x000008),
REG(S2_CACHE_MASK_DAT, 0x000108),
REG(S2_CACHE_ACTION_DAT, 0x000208),
REG(S2_CACHE_CNT_DAT, 0x000308),
REG(S2_CACHE_TG_DAT, 0x000388),
static const u32 ocelot_vcap_regmap[] = {
/* VCAP_CORE_CFG */
REG(VCAP_CORE_UPDATE_CTRL, 0x000000),
REG(VCAP_CORE_MV_CFG, 0x000004),
/* VCAP_CORE_CACHE */
REG(VCAP_CACHE_ENTRY_DAT, 0x000008),
REG(VCAP_CACHE_MASK_DAT, 0x000108),
REG(VCAP_CACHE_ACTION_DAT, 0x000208),
REG(VCAP_CACHE_CNT_DAT, 0x000308),
REG(VCAP_CACHE_TG_DAT, 0x000388),
/* VCAP_CONST */
REG(VCAP_CONST_VCAP_VER, 0x000398),
REG(VCAP_CONST_ENTRY_WIDTH, 0x00039c),
REG(VCAP_CONST_ENTRY_CNT, 0x0003a0),
REG(VCAP_CONST_ENTRY_SWCNT, 0x0003a4),
REG(VCAP_CONST_ENTRY_TG_WIDTH, 0x0003a8),
REG(VCAP_CONST_ACTION_DEF_CNT, 0x0003ac),
REG(VCAP_CONST_ACTION_WIDTH, 0x0003b0),
REG(VCAP_CONST_CNT_WIDTH, 0x0003b4),
REG(VCAP_CONST_CORE_CNT, 0x0003b8),
REG(VCAP_CONST_IF_CNT, 0x0003bc),
};
static const u32 ocelot_ptp_regmap[] = {
......@@ -311,7 +320,7 @@ static const u32 *ocelot_regmap[TARGET_MAX] = {
[QSYS] = ocelot_qsys_regmap,
[REW] = ocelot_rew_regmap,
[SYS] = ocelot_sys_regmap,
[S2] = ocelot_s2_regmap,
[S2] = ocelot_vcap_regmap,
[PTP] = ocelot_ptp_regmap,
[DEV_GMII] = ocelot_dev_gmii_regmap,
};
......@@ -756,6 +765,113 @@ static const struct ocelot_ops ocelot_ops = {
.wm_enc = ocelot_wm_enc,
};
static const struct vcap_field vsc7514_vcap_es0_keys[] = {
[VCAP_ES0_EGR_PORT] = { 0, 4},
[VCAP_ES0_IGR_PORT] = { 4, 4},
[VCAP_ES0_RSV] = { 8, 2},
[VCAP_ES0_L2_MC] = { 10, 1},
[VCAP_ES0_L2_BC] = { 11, 1},
[VCAP_ES0_VID] = { 12, 12},
[VCAP_ES0_DP] = { 24, 1},
[VCAP_ES0_PCP] = { 25, 3},
};
static const struct vcap_field vsc7514_vcap_es0_actions[] = {
[VCAP_ES0_ACT_PUSH_OUTER_TAG] = { 0, 2},
[VCAP_ES0_ACT_PUSH_INNER_TAG] = { 2, 1},
[VCAP_ES0_ACT_TAG_A_TPID_SEL] = { 3, 2},
[VCAP_ES0_ACT_TAG_A_VID_SEL] = { 5, 1},
[VCAP_ES0_ACT_TAG_A_PCP_SEL] = { 6, 2},
[VCAP_ES0_ACT_TAG_A_DEI_SEL] = { 8, 2},
[VCAP_ES0_ACT_TAG_B_TPID_SEL] = { 10, 2},
[VCAP_ES0_ACT_TAG_B_VID_SEL] = { 12, 1},
[VCAP_ES0_ACT_TAG_B_PCP_SEL] = { 13, 2},
[VCAP_ES0_ACT_TAG_B_DEI_SEL] = { 15, 2},
[VCAP_ES0_ACT_VID_A_VAL] = { 17, 12},
[VCAP_ES0_ACT_PCP_A_VAL] = { 29, 3},
[VCAP_ES0_ACT_DEI_A_VAL] = { 32, 1},
[VCAP_ES0_ACT_VID_B_VAL] = { 33, 12},
[VCAP_ES0_ACT_PCP_B_VAL] = { 45, 3},
[VCAP_ES0_ACT_DEI_B_VAL] = { 48, 1},
[VCAP_ES0_ACT_RSV] = { 49, 24},
[VCAP_ES0_ACT_HIT_STICKY] = { 73, 1},
};
static const struct vcap_field vsc7514_vcap_is1_keys[] = {
[VCAP_IS1_HK_TYPE] = { 0, 1},
[VCAP_IS1_HK_LOOKUP] = { 1, 2},
[VCAP_IS1_HK_IGR_PORT_MASK] = { 3, 12},
[VCAP_IS1_HK_RSV] = { 15, 9},
[VCAP_IS1_HK_OAM_Y1731] = { 24, 1},
[VCAP_IS1_HK_L2_MC] = { 25, 1},
[VCAP_IS1_HK_L2_BC] = { 26, 1},
[VCAP_IS1_HK_IP_MC] = { 27, 1},
[VCAP_IS1_HK_VLAN_TAGGED] = { 28, 1},
[VCAP_IS1_HK_VLAN_DBL_TAGGED] = { 29, 1},
[VCAP_IS1_HK_TPID] = { 30, 1},
[VCAP_IS1_HK_VID] = { 31, 12},
[VCAP_IS1_HK_DEI] = { 43, 1},
[VCAP_IS1_HK_PCP] = { 44, 3},
/* Specific Fields for IS1 Half Key S1_NORMAL */
[VCAP_IS1_HK_L2_SMAC] = { 47, 48},
[VCAP_IS1_HK_ETYPE_LEN] = { 95, 1},
[VCAP_IS1_HK_ETYPE] = { 96, 16},
[VCAP_IS1_HK_IP_SNAP] = {112, 1},
[VCAP_IS1_HK_IP4] = {113, 1},
/* Layer-3 Information */
[VCAP_IS1_HK_L3_FRAGMENT] = {114, 1},
[VCAP_IS1_HK_L3_FRAG_OFS_GT0] = {115, 1},
[VCAP_IS1_HK_L3_OPTIONS] = {116, 1},
[VCAP_IS1_HK_L3_DSCP] = {117, 6},
[VCAP_IS1_HK_L3_IP4_SIP] = {123, 32},
/* Layer-4 Information */
[VCAP_IS1_HK_TCP_UDP] = {155, 1},
[VCAP_IS1_HK_TCP] = {156, 1},
[VCAP_IS1_HK_L4_SPORT] = {157, 16},
[VCAP_IS1_HK_L4_RNG] = {173, 8},
/* Specific Fields for IS1 Half Key S1_5TUPLE_IP4 */
[VCAP_IS1_HK_IP4_INNER_TPID] = { 47, 1},
[VCAP_IS1_HK_IP4_INNER_VID] = { 48, 12},
[VCAP_IS1_HK_IP4_INNER_DEI] = { 60, 1},
[VCAP_IS1_HK_IP4_INNER_PCP] = { 61, 3},
[VCAP_IS1_HK_IP4_IP4] = { 64, 1},
[VCAP_IS1_HK_IP4_L3_FRAGMENT] = { 65, 1},
[VCAP_IS1_HK_IP4_L3_FRAG_OFS_GT0] = { 66, 1},
[VCAP_IS1_HK_IP4_L3_OPTIONS] = { 67, 1},
[VCAP_IS1_HK_IP4_L3_DSCP] = { 68, 6},
[VCAP_IS1_HK_IP4_L3_IP4_DIP] = { 74, 32},
[VCAP_IS1_HK_IP4_L3_IP4_SIP] = {106, 32},
[VCAP_IS1_HK_IP4_L3_PROTO] = {138, 8},
[VCAP_IS1_HK_IP4_TCP_UDP] = {146, 1},
[VCAP_IS1_HK_IP4_TCP] = {147, 1},
[VCAP_IS1_HK_IP4_L4_RNG] = {148, 8},
[VCAP_IS1_HK_IP4_IP_PAYLOAD_S1_5TUPLE] = {156, 32},
};
static const struct vcap_field vsc7514_vcap_is1_actions[] = {
[VCAP_IS1_ACT_DSCP_ENA] = { 0, 1},
[VCAP_IS1_ACT_DSCP_VAL] = { 1, 6},
[VCAP_IS1_ACT_QOS_ENA] = { 7, 1},
[VCAP_IS1_ACT_QOS_VAL] = { 8, 3},
[VCAP_IS1_ACT_DP_ENA] = { 11, 1},
[VCAP_IS1_ACT_DP_VAL] = { 12, 1},
[VCAP_IS1_ACT_PAG_OVERRIDE_MASK] = { 13, 8},
[VCAP_IS1_ACT_PAG_VAL] = { 21, 8},
[VCAP_IS1_ACT_RSV] = { 29, 9},
/* The fields below are incorrectly shifted by 2 in the manual */
[VCAP_IS1_ACT_VID_REPLACE_ENA] = { 38, 1},
[VCAP_IS1_ACT_VID_ADD_VAL] = { 39, 12},
[VCAP_IS1_ACT_FID_SEL] = { 51, 2},
[VCAP_IS1_ACT_FID_VAL] = { 53, 13},
[VCAP_IS1_ACT_PCP_DEI_ENA] = { 66, 1},
[VCAP_IS1_ACT_PCP_VAL] = { 67, 3},
[VCAP_IS1_ACT_DEI_VAL] = { 70, 1},
[VCAP_IS1_ACT_VLAN_POP_CNT_ENA] = { 71, 1},
[VCAP_IS1_ACT_VLAN_POP_CNT] = { 72, 2},
[VCAP_IS1_ACT_CUSTOM_ACE_TYPE_ENA] = { 74, 4},
[VCAP_IS1_ACT_HIT_STICKY] = { 78, 1},
};
static const struct vcap_field vsc7514_vcap_is2_keys[] = {
/* Common: 46 bits */
[VCAP_IS2_TYPE] = { 0, 4},
......@@ -854,15 +970,32 @@ static const struct vcap_field vsc7514_vcap_is2_actions[] = {
[VCAP_IS2_ACT_HIT_CNT] = { 49, 32},
};
static const struct vcap_props vsc7514_vcap_props[] = {
static struct vcap_props vsc7514_vcap_props[] = {
[VCAP_ES0] = {
.action_type_width = 0,
.action_table = {
[ES0_ACTION_TYPE_NORMAL] = {
.width = 73, /* HIT_STICKY not included */
.count = 1,
},
},
.target = S0,
.keys = vsc7514_vcap_es0_keys,
.actions = vsc7514_vcap_es0_actions,
},
[VCAP_IS1] = {
.action_type_width = 0,
.action_table = {
[IS1_ACTION_TYPE_NORMAL] = {
.width = 78, /* HIT_STICKY not included */
.count = 4,
},
},
.target = S1,
.keys = vsc7514_vcap_is1_keys,
.actions = vsc7514_vcap_is1_actions,
},
[VCAP_IS2] = {
.tg_width = 2,
.sw_count = 4,
.entry_count = VSC7514_VCAP_IS2_CNT,
.entry_width = VSC7514_VCAP_IS2_ENTRY_WIDTH,
.action_count = VSC7514_VCAP_IS2_CNT +
VSC7514_VCAP_PORT_CNT + 2,
.action_width = 99,
.action_type_width = 1,
.action_table = {
[IS2_ACTION_TYPE_NORMAL] = {
......@@ -874,8 +1007,9 @@ static const struct vcap_props vsc7514_vcap_props[] = {
.count = 4
},
},
.counter_words = 4,
.counter_width = 32,
.target = S2,
.keys = vsc7514_vcap_is2_keys,
.actions = vsc7514_vcap_is2_actions,
},
};
......@@ -1037,6 +1171,8 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
{ QSYS, "qsys" },
{ ANA, "ana" },
{ QS, "qs" },
{ S0, "s0" },
{ S1, "s1" },
{ S2, "s2" },
{ PTP, "ptp", 1 },
};
......@@ -1113,8 +1249,6 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
ocelot->num_phys_ports = of_get_child_count(ports);
ocelot->vcap_is2_keys = vsc7514_vcap_is2_keys;
ocelot->vcap_is2_actions = vsc7514_vcap_is2_actions;
ocelot->vcap = vsc7514_vcap_props;
ocelot->inj_prefix = OCELOT_TAG_PREFIX_NONE;
ocelot->xtr_prefix = OCELOT_TAG_PREFIX_NONE;
......
......@@ -123,6 +123,8 @@ enum ocelot_target {
QSYS,
REW,
SYS,
S0,
S1,
S2,
HSIO,
PTP,
......@@ -393,13 +395,6 @@ enum ocelot_reg {
SYS_CM_DATA_RD,
SYS_CM_OP,
SYS_CM_DATA,
S2_CORE_UPDATE_CTRL = S2 << TARGET_OFFSET,
S2_CORE_MV_CFG,
S2_CACHE_ENTRY_DAT,
S2_CACHE_MASK_DAT,
S2_CACHE_ACTION_DAT,
S2_CACHE_CNT_DAT,
S2_CACHE_TG_DAT,
PTP_PIN_CFG = PTP << TARGET_OFFSET,
PTP_PIN_TOD_SEC_MSB,
PTP_PIN_TOD_SEC_LSB,
......@@ -518,6 +513,29 @@ enum ocelot_regfield {
REGFIELD_MAX
};
enum {
/* VCAP_CORE_CFG */
VCAP_CORE_UPDATE_CTRL,
VCAP_CORE_MV_CFG,
/* VCAP_CORE_CACHE */
VCAP_CACHE_ENTRY_DAT,
VCAP_CACHE_MASK_DAT,
VCAP_CACHE_ACTION_DAT,
VCAP_CACHE_CNT_DAT,
VCAP_CACHE_TG_DAT,
/* VCAP_CONST */
VCAP_CONST_VCAP_VER,
VCAP_CONST_ENTRY_WIDTH,
VCAP_CONST_ENTRY_CNT,
VCAP_CONST_ENTRY_SWCNT,
VCAP_CONST_ENTRY_TG_WIDTH,
VCAP_CONST_ACTION_DEF_CNT,
VCAP_CONST_ACTION_WIDTH,
VCAP_CONST_CNT_WIDTH,
VCAP_CONST_CORE_CNT,
VCAP_CONST_IF_CNT,
};
enum ocelot_ptp_pins {
PTP_PIN_0,
PTP_PIN_1,
......@@ -614,10 +632,7 @@ struct ocelot {
struct list_head multicast;
struct ocelot_vcap_block block;
const struct vcap_field *vcap_is2_keys;
const struct vcap_field *vcap_is2_actions;
const struct vcap_props *vcap;
struct vcap_props *vcap;
/* Workqueue to check statistics for overflow with its lock */
struct mutex stats_lock;
......@@ -661,6 +676,24 @@ struct ocelot_policer {
#define ocelot_fields_write(ocelot, id, reg, val) regmap_fields_write((ocelot)->regfields[(reg)], (id), (val))
#define ocelot_fields_read(ocelot, id, reg, val) regmap_fields_read((ocelot)->regfields[(reg)], (id), (val))
#define ocelot_target_read_ix(ocelot, target, reg, gi, ri) \
__ocelot_target_read_ix(ocelot, target, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri))
#define ocelot_target_read_gix(ocelot, target, reg, gi) \
__ocelot_target_read_ix(ocelot, target, reg, reg##_GSZ * (gi))
#define ocelot_target_read_rix(ocelot, target, reg, ri) \
__ocelot_target_read_ix(ocelot, target, reg, reg##_RSZ * (ri))
#define ocelot_target_read(ocelot, target, reg) \
__ocelot_target_read_ix(ocelot, target, reg, 0)
#define ocelot_target_write_ix(ocelot, target, val, reg, gi, ri) \
__ocelot_target_write_ix(ocelot, target, val, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri))
#define ocelot_target_write_gix(ocelot, target, val, reg, gi) \
__ocelot_target_write_ix(ocelot, target, val, reg, reg##_GSZ * (gi))
#define ocelot_target_write_rix(ocelot, target, val, reg, ri) \
__ocelot_target_write_ix(ocelot, target, val, reg, reg##_RSZ * (ri))
#define ocelot_target_write(ocelot, target, val, reg) \
__ocelot_target_write_ix(ocelot, target, val, reg, 0)
/* I/O */
u32 ocelot_port_readl(struct ocelot_port *port, u32 reg);
void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg);
......@@ -668,6 +701,10 @@ u32 __ocelot_read_ix(struct ocelot *ocelot, u32 reg, u32 offset);
void __ocelot_write_ix(struct ocelot *ocelot, u32 val, u32 reg, u32 offset);
void __ocelot_rmw_ix(struct ocelot *ocelot, u32 val, u32 mask, u32 reg,
u32 offset);
u32 __ocelot_target_read_ix(struct ocelot *ocelot, enum ocelot_target target,
u32 reg, u32 offset);
void __ocelot_target_write_ix(struct ocelot *ocelot, enum ocelot_target target,
u32 val, u32 reg, u32 offset);
/* Hardware initialization */
int ocelot_regfields_init(struct ocelot *ocelot,
......
......@@ -6,17 +6,22 @@
#ifndef _OCELOT_VCAP_H_
#define _OCELOT_VCAP_H_
#include <soc/mscc/ocelot.h>
/* =================================================================
* VCAP Common
* =================================================================
*/
enum {
/* VCAP_IS1, */
VCAP_ES0,
VCAP_IS1,
VCAP_IS2,
/* VCAP_ES0, */
__VCAP_COUNT,
};
#define OCELOT_NUM_VCAP_BLOCKS __VCAP_COUNT
struct vcap_props {
u16 tg_width; /* Type-group width (in bits) */
u16 sw_count; /* Sub word count */
......@@ -33,6 +38,11 @@ struct vcap_props {
} action_table[2];
u16 counter_words; /* Number of counter words */
u16 counter_width; /* Counter width (in bits) */
enum ocelot_target target;
const struct vcap_field *keys;
const struct vcap_field *actions;
};
/* VCAP Type-Group values */
......@@ -41,6 +51,61 @@ struct vcap_props {
#define VCAP_TG_HALF 2 /* Half entry */
#define VCAP_TG_QUARTER 3 /* Quarter entry */
#define VCAP_CORE_UPDATE_CTRL_UPDATE_CMD(x) (((x) << 22) & GENMASK(24, 22))
#define VCAP_CORE_UPDATE_CTRL_UPDATE_CMD_M GENMASK(24, 22)
#define VCAP_CORE_UPDATE_CTRL_UPDATE_CMD_X(x) (((x) & GENMASK(24, 22)) >> 22)
#define VCAP_CORE_UPDATE_CTRL_UPDATE_ENTRY_DIS BIT(21)
#define VCAP_CORE_UPDATE_CTRL_UPDATE_ACTION_DIS BIT(20)
#define VCAP_CORE_UPDATE_CTRL_UPDATE_CNT_DIS BIT(19)
#define VCAP_CORE_UPDATE_CTRL_UPDATE_ADDR(x) (((x) << 3) & GENMASK(18, 3))
#define VCAP_CORE_UPDATE_CTRL_UPDATE_ADDR_M GENMASK(18, 3)
#define VCAP_CORE_UPDATE_CTRL_UPDATE_ADDR_X(x) (((x) & GENMASK(18, 3)) >> 3)
#define VCAP_CORE_UPDATE_CTRL_UPDATE_SHOT BIT(2)
#define VCAP_CORE_UPDATE_CTRL_CLEAR_CACHE BIT(1)
#define VCAP_CORE_UPDATE_CTRL_MV_TRAFFIC_IGN BIT(0)
#define VCAP_CORE_MV_CFG_MV_NUM_POS(x) (((x) << 16) & GENMASK(31, 16))
#define VCAP_CORE_MV_CFG_MV_NUM_POS_M GENMASK(31, 16)
#define VCAP_CORE_MV_CFG_MV_NUM_POS_X(x) (((x) & GENMASK(31, 16)) >> 16)
#define VCAP_CORE_MV_CFG_MV_SIZE(x) ((x) & GENMASK(15, 0))
#define VCAP_CORE_MV_CFG_MV_SIZE_M GENMASK(15, 0)
#define VCAP_CACHE_ENTRY_DAT_RSZ 0x4
#define VCAP_CACHE_MASK_DAT_RSZ 0x4
#define VCAP_CACHE_ACTION_DAT_RSZ 0x4
#define VCAP_CACHE_CNT_DAT_RSZ 0x4
#define VCAP_STICKY_VCAP_ROW_DELETED_STICKY BIT(0)
#define TCAM_BIST_CTRL_TCAM_BIST BIT(1)
#define TCAM_BIST_CTRL_TCAM_INIT BIT(0)
#define TCAM_BIST_CFG_TCAM_BIST_SOE_ENA BIT(8)
#define TCAM_BIST_CFG_TCAM_HCG_DIS BIT(7)
#define TCAM_BIST_CFG_TCAM_CG_DIS BIT(6)
#define TCAM_BIST_CFG_TCAM_BIAS(x) ((x) & GENMASK(5, 0))
#define TCAM_BIST_CFG_TCAM_BIAS_M GENMASK(5, 0)
#define TCAM_BIST_STAT_BIST_RT_ERR BIT(15)
#define TCAM_BIST_STAT_BIST_PENC_ERR BIT(14)
#define TCAM_BIST_STAT_BIST_COMP_ERR BIT(13)
#define TCAM_BIST_STAT_BIST_ADDR_ERR BIT(12)
#define TCAM_BIST_STAT_BIST_BL1E_ERR BIT(11)
#define TCAM_BIST_STAT_BIST_BL1_ERR BIT(10)
#define TCAM_BIST_STAT_BIST_BL0E_ERR BIT(9)
#define TCAM_BIST_STAT_BIST_BL0_ERR BIT(8)
#define TCAM_BIST_STAT_BIST_PH1_ERR BIT(7)
#define TCAM_BIST_STAT_BIST_PH0_ERR BIT(6)
#define TCAM_BIST_STAT_BIST_PV1_ERR BIT(5)
#define TCAM_BIST_STAT_BIST_PV0_ERR BIT(4)
#define TCAM_BIST_STAT_BIST_RUN BIT(3)
#define TCAM_BIST_STAT_BIST_ERR BIT(2)
#define TCAM_BIST_STAT_BIST_BUSY BIT(1)
#define TCAM_BIST_STAT_TCAM_RDY BIT(0)
/* =================================================================
* VCAP IS2
* =================================================================
......@@ -202,4 +267,137 @@ enum vcap_is2_action_field {
VCAP_IS2_ACT_HIT_CNT,
};
/* =================================================================
* VCAP IS1
* =================================================================
*/
/* IS1 half key types */
#define IS1_TYPE_S1_NORMAL 0
#define IS1_TYPE_S1_5TUPLE_IP4 1
/* IS1 full key types */
#define IS1_TYPE_S1_NORMAL_IP6 0
#define IS1_TYPE_S1_7TUPLE 1
#define IS2_TYPE_S1_5TUPLE_IP6 2
enum {
IS1_ACTION_TYPE_NORMAL,
IS1_ACTION_TYPE_MAX,
};
enum vcap_is1_half_key_field {
VCAP_IS1_HK_TYPE,
VCAP_IS1_HK_LOOKUP,
VCAP_IS1_HK_IGR_PORT_MASK,
VCAP_IS1_HK_RSV,
VCAP_IS1_HK_OAM_Y1731,
VCAP_IS1_HK_L2_MC,
VCAP_IS1_HK_L2_BC,
VCAP_IS1_HK_IP_MC,
VCAP_IS1_HK_VLAN_TAGGED,
VCAP_IS1_HK_VLAN_DBL_TAGGED,
VCAP_IS1_HK_TPID,
VCAP_IS1_HK_VID,
VCAP_IS1_HK_DEI,
VCAP_IS1_HK_PCP,
/* Specific Fields for IS1 Half Key S1_NORMAL */
VCAP_IS1_HK_L2_SMAC,
VCAP_IS1_HK_ETYPE_LEN,
VCAP_IS1_HK_ETYPE,
VCAP_IS1_HK_IP_SNAP,
VCAP_IS1_HK_IP4,
VCAP_IS1_HK_L3_FRAGMENT,
VCAP_IS1_HK_L3_FRAG_OFS_GT0,
VCAP_IS1_HK_L3_OPTIONS,
VCAP_IS1_HK_L3_DSCP,
VCAP_IS1_HK_L3_IP4_SIP,
VCAP_IS1_HK_TCP_UDP,
VCAP_IS1_HK_TCP,
VCAP_IS1_HK_L4_SPORT,
VCAP_IS1_HK_L4_RNG,
/* Specific Fields for IS1 Half Key S1_5TUPLE_IP4 */
VCAP_IS1_HK_IP4_INNER_TPID,
VCAP_IS1_HK_IP4_INNER_VID,
VCAP_IS1_HK_IP4_INNER_DEI,
VCAP_IS1_HK_IP4_INNER_PCP,
VCAP_IS1_HK_IP4_IP4,
VCAP_IS1_HK_IP4_L3_FRAGMENT,
VCAP_IS1_HK_IP4_L3_FRAG_OFS_GT0,
VCAP_IS1_HK_IP4_L3_OPTIONS,
VCAP_IS1_HK_IP4_L3_DSCP,
VCAP_IS1_HK_IP4_L3_IP4_DIP,
VCAP_IS1_HK_IP4_L3_IP4_SIP,
VCAP_IS1_HK_IP4_L3_PROTO,
VCAP_IS1_HK_IP4_TCP_UDP,
VCAP_IS1_HK_IP4_TCP,
VCAP_IS1_HK_IP4_L4_RNG,
VCAP_IS1_HK_IP4_IP_PAYLOAD_S1_5TUPLE,
};
enum vcap_is1_action_field {
VCAP_IS1_ACT_DSCP_ENA,
VCAP_IS1_ACT_DSCP_VAL,
VCAP_IS1_ACT_QOS_ENA,
VCAP_IS1_ACT_QOS_VAL,
VCAP_IS1_ACT_DP_ENA,
VCAP_IS1_ACT_DP_VAL,
VCAP_IS1_ACT_PAG_OVERRIDE_MASK,
VCAP_IS1_ACT_PAG_VAL,
VCAP_IS1_ACT_RSV,
VCAP_IS1_ACT_VID_REPLACE_ENA,
VCAP_IS1_ACT_VID_ADD_VAL,
VCAP_IS1_ACT_FID_SEL,
VCAP_IS1_ACT_FID_VAL,
VCAP_IS1_ACT_PCP_DEI_ENA,
VCAP_IS1_ACT_PCP_VAL,
VCAP_IS1_ACT_DEI_VAL,
VCAP_IS1_ACT_VLAN_POP_CNT_ENA,
VCAP_IS1_ACT_VLAN_POP_CNT,
VCAP_IS1_ACT_CUSTOM_ACE_TYPE_ENA,
VCAP_IS1_ACT_HIT_STICKY,
};
/* =================================================================
* VCAP ES0
* =================================================================
*/
enum {
ES0_ACTION_TYPE_NORMAL,
ES0_ACTION_TYPE_MAX,
};
enum vcap_es0_key_field {
VCAP_ES0_EGR_PORT,
VCAP_ES0_IGR_PORT,
VCAP_ES0_RSV,
VCAP_ES0_L2_MC,
VCAP_ES0_L2_BC,
VCAP_ES0_VID,
VCAP_ES0_DP,
VCAP_ES0_PCP,
};
enum vcap_es0_action_field {
VCAP_ES0_ACT_PUSH_OUTER_TAG,
VCAP_ES0_ACT_PUSH_INNER_TAG,
VCAP_ES0_ACT_TAG_A_TPID_SEL,
VCAP_ES0_ACT_TAG_A_VID_SEL,
VCAP_ES0_ACT_TAG_A_PCP_SEL,
VCAP_ES0_ACT_TAG_A_DEI_SEL,
VCAP_ES0_ACT_TAG_B_TPID_SEL,
VCAP_ES0_ACT_TAG_B_VID_SEL,
VCAP_ES0_ACT_TAG_B_PCP_SEL,
VCAP_ES0_ACT_TAG_B_DEI_SEL,
VCAP_ES0_ACT_VID_A_VAL,
VCAP_ES0_ACT_PCP_A_VAL,
VCAP_ES0_ACT_DEI_A_VAL,
VCAP_ES0_ACT_VID_B_VAL,
VCAP_ES0_ACT_PCP_B_VAL,
VCAP_ES0_ACT_DEI_B_VAL,
VCAP_ES0_ACT_RSV,
VCAP_ES0_ACT_HIT_STICKY,
};
#endif /* _OCELOT_VCAP_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment