Linux Audio

Check our new training course

Loading...
v6.8
   1// SPDX-License-Identifier: GPL-2.0+
   2/* Microchip Sparx5 Switch driver VCAP implementation
   3 *
   4 * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries.
   5 *
   6 * The Sparx5 Chip Register Model can be browsed at this location:
   7 * https://github.com/microchip-ung/sparx-5_reginfo
   8 */
   9
  10#include "vcap_api_debugfs.h"
  11#include "sparx5_main_regs.h"
  12#include "sparx5_main.h"
  13#include "sparx5_vcap_impl.h"
  14#include "sparx5_vcap_ag_api.h"
  15#include "sparx5_vcap_debugfs.h"
  16
  17#define SUPER_VCAP_BLK_SIZE 3072 /* addresses per Super VCAP block */
  18#define STREAMSIZE (64 * 4)  /* bytes in the VCAP cache area */
  19
  20#define SPARX5_IS2_LOOKUPS 4
  21#define VCAP_IS2_KEYSEL(_ena, _noneth, _v4_mc, _v4_uc, _v6_mc, _v6_uc, _arp) \
  22	(ANA_ACL_VCAP_S2_KEY_SEL_KEY_SEL_ENA_SET(_ena) | \
  23	 ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL_SET(_noneth) | \
  24	 ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL_SET(_v4_mc) | \
  25	 ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL_SET(_v4_uc) | \
  26	 ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL_SET(_v6_mc) | \
  27	 ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL_SET(_v6_uc) | \
  28	 ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL_SET(_arp))
  29
  30#define SPARX5_IS0_LOOKUPS 6
  31#define VCAP_IS0_KEYSEL(_ena, _etype, _ipv4, _ipv6, _mpls_uc, _mpls_mc, _mlbs) \
  32	(ANA_CL_ADV_CL_CFG_LOOKUP_ENA_SET(_ena) | \
  33	ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL_SET(_etype) | \
  34	ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL_SET(_ipv4) | \
  35	ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL_SET(_ipv6) | \
  36	ANA_CL_ADV_CL_CFG_MPLS_UC_CLM_KEY_SEL_SET(_mpls_uc) | \
  37	ANA_CL_ADV_CL_CFG_MPLS_MC_CLM_KEY_SEL_SET(_mpls_mc) | \
  38	ANA_CL_ADV_CL_CFG_MLBS_CLM_KEY_SEL_SET(_mlbs))
  39
  40#define SPARX5_ES0_LOOKUPS 1
  41#define VCAP_ES0_KEYSEL(_key) (REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA_SET(_key))
  42#define SPARX5_STAT_ESDX_GRN_PKTS  0x300
  43#define SPARX5_STAT_ESDX_YEL_PKTS  0x301
  44
  45#define SPARX5_ES2_LOOKUPS 2
  46#define VCAP_ES2_KEYSEL(_ena, _arp, _ipv4, _ipv6) \
  47	(EACL_VCAP_ES2_KEY_SEL_KEY_ENA_SET(_ena) | \
  48	EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL_SET(_arp) | \
  49	EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL_SET(_ipv4) | \
  50	EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL_SET(_ipv6))
  51
  52static struct sparx5_vcap_inst {
  53	enum vcap_type vtype; /* type of vcap */
  54	int vinst; /* instance number within the same type */
  55	int lookups; /* number of lookups in this vcap type */
  56	int lookups_per_instance; /* number of lookups in this instance */
  57	int first_cid; /* first chain id in this vcap */
  58	int last_cid; /* last chain id in this vcap */
  59	int count; /* number of available addresses, not in super vcap */
  60	int map_id; /* id in the super vcap block mapping (if applicable) */
  61	int blockno; /* starting block in super vcap (if applicable) */
  62	int blocks; /* number of blocks in super vcap (if applicable) */
  63	bool ingress; /* is vcap in the ingress path */
  64} sparx5_vcap_inst_cfg[] = {
  65	{
  66		.vtype = VCAP_TYPE_IS0, /* CLM-0 */
  67		.vinst = 0,
  68		.map_id = 1,
  69		.lookups = SPARX5_IS0_LOOKUPS,
  70		.lookups_per_instance = SPARX5_IS0_LOOKUPS / 3,
  71		.first_cid = SPARX5_VCAP_CID_IS0_L0,
  72		.last_cid = SPARX5_VCAP_CID_IS0_L2 - 1,
  73		.blockno = 8, /* Maps block 8-9 */
  74		.blocks = 2,
  75		.ingress = true,
  76	},
  77	{
  78		.vtype = VCAP_TYPE_IS0, /* CLM-1 */
  79		.vinst = 1,
  80		.map_id = 2,
  81		.lookups = SPARX5_IS0_LOOKUPS,
  82		.lookups_per_instance = SPARX5_IS0_LOOKUPS / 3,
  83		.first_cid = SPARX5_VCAP_CID_IS0_L2,
  84		.last_cid = SPARX5_VCAP_CID_IS0_L4 - 1,
  85		.blockno = 6, /* Maps block 6-7 */
  86		.blocks = 2,
  87		.ingress = true,
  88	},
  89	{
  90		.vtype = VCAP_TYPE_IS0, /* CLM-2 */
  91		.vinst = 2,
  92		.map_id = 3,
  93		.lookups = SPARX5_IS0_LOOKUPS,
  94		.lookups_per_instance = SPARX5_IS0_LOOKUPS / 3,
  95		.first_cid = SPARX5_VCAP_CID_IS0_L4,
  96		.last_cid = SPARX5_VCAP_CID_IS0_MAX,
  97		.blockno = 4, /* Maps block 4-5 */
  98		.blocks = 2,
  99		.ingress = true,
 100	},
 101	{
 102		.vtype = VCAP_TYPE_IS2, /* IS2-0 */
 103		.vinst = 0,
 104		.map_id = 4,
 105		.lookups = SPARX5_IS2_LOOKUPS,
 106		.lookups_per_instance = SPARX5_IS2_LOOKUPS / 2,
 107		.first_cid = SPARX5_VCAP_CID_IS2_L0,
 108		.last_cid = SPARX5_VCAP_CID_IS2_L2 - 1,
 109		.blockno = 0, /* Maps block 0-1 */
 110		.blocks = 2,
 111		.ingress = true,
 112	},
 113	{
 114		.vtype = VCAP_TYPE_IS2, /* IS2-1 */
 115		.vinst = 1,
 116		.map_id = 5,
 117		.lookups = SPARX5_IS2_LOOKUPS,
 118		.lookups_per_instance = SPARX5_IS2_LOOKUPS / 2,
 119		.first_cid = SPARX5_VCAP_CID_IS2_L2,
 120		.last_cid = SPARX5_VCAP_CID_IS2_MAX,
 121		.blockno = 2, /* Maps block 2-3 */
 122		.blocks = 2,
 123		.ingress = true,
 124	},
 125	{
 126		.vtype = VCAP_TYPE_ES0,
 127		.lookups = SPARX5_ES0_LOOKUPS,
 128		.lookups_per_instance = SPARX5_ES0_LOOKUPS,
 129		.first_cid = SPARX5_VCAP_CID_ES0_L0,
 130		.last_cid = SPARX5_VCAP_CID_ES0_MAX,
 131		.count = 4096, /* Addresses according to datasheet */
 132		.ingress = false,
 133	},
 134	{
 135		.vtype = VCAP_TYPE_ES2,
 136		.lookups = SPARX5_ES2_LOOKUPS,
 137		.lookups_per_instance = SPARX5_ES2_LOOKUPS,
 138		.first_cid = SPARX5_VCAP_CID_ES2_L0,
 139		.last_cid = SPARX5_VCAP_CID_ES2_MAX,
 140		.count = 12288, /* Addresses according to datasheet */
 141		.ingress = false,
 142	},
 143};
 144
 145/* These protocols have dedicated keysets in IS0 and a TC dissector */
 146static u16 sparx5_vcap_is0_known_etypes[] = {
 147	ETH_P_ALL,
 148	ETH_P_IP,
 149	ETH_P_IPV6,
 150};
 151
 152/* These protocols have dedicated keysets in IS2 and a TC dissector */
 153static u16 sparx5_vcap_is2_known_etypes[] = {
 154	ETH_P_ALL,
 155	ETH_P_ARP,
 156	ETH_P_IP,
 157	ETH_P_IPV6,
 158};
 159
 160/* These protocols have dedicated keysets in ES2 and a TC dissector */
 161static u16 sparx5_vcap_es2_known_etypes[] = {
 162	ETH_P_ALL,
 163	ETH_P_ARP,
 164	ETH_P_IP,
 165	ETH_P_IPV6,
 166};
 167
 168static void sparx5_vcap_type_err(struct sparx5 *sparx5,
 169				 struct vcap_admin *admin,
 170				 const char *fname)
 171{
 172	pr_err("%s: vcap type: %s not supported\n",
 173	       fname, sparx5_vcaps[admin->vtype].name);
 174}
 175
 176/* Await the super VCAP completion of the current operation */
 177static void sparx5_vcap_wait_super_update(struct sparx5 *sparx5)
 178{
 179	u32 value;
 180
 181	read_poll_timeout(spx5_rd, value,
 182			  !VCAP_SUPER_CTRL_UPDATE_SHOT_GET(value), 500, 10000,
 183			  false, sparx5, VCAP_SUPER_CTRL);
 184}
 185
 186/* Await the ES0 VCAP completion of the current operation */
 187static void sparx5_vcap_wait_es0_update(struct sparx5 *sparx5)
 188{
 189	u32 value;
 190
 191	read_poll_timeout(spx5_rd, value,
 192			  !VCAP_ES0_CTRL_UPDATE_SHOT_GET(value), 500, 10000,
 193			  false, sparx5, VCAP_ES0_CTRL);
 194}
 195
 196/* Await the ES2 VCAP completion of the current operation */
 197static void sparx5_vcap_wait_es2_update(struct sparx5 *sparx5)
 198{
 199	u32 value;
 200
 201	read_poll_timeout(spx5_rd, value,
 202			  !VCAP_ES2_CTRL_UPDATE_SHOT_GET(value), 500, 10000,
 203			  false, sparx5, VCAP_ES2_CTRL);
 204}
 205
 206/* Initializing a VCAP address range */
 207static void _sparx5_vcap_range_init(struct sparx5 *sparx5,
 208				    struct vcap_admin *admin,
 209				    u32 addr, u32 count)
 210{
 211	u32 size = count - 1;
 212
 213	switch (admin->vtype) {
 214	case VCAP_TYPE_IS0:
 215	case VCAP_TYPE_IS2:
 216		spx5_wr(VCAP_SUPER_CFG_MV_NUM_POS_SET(0) |
 217			VCAP_SUPER_CFG_MV_SIZE_SET(size),
 218			sparx5, VCAP_SUPER_CFG);
 219		spx5_wr(VCAP_SUPER_CTRL_UPDATE_CMD_SET(VCAP_CMD_INITIALIZE) |
 220			VCAP_SUPER_CTRL_UPDATE_ENTRY_DIS_SET(0) |
 221			VCAP_SUPER_CTRL_UPDATE_ACTION_DIS_SET(0) |
 222			VCAP_SUPER_CTRL_UPDATE_CNT_DIS_SET(0) |
 223			VCAP_SUPER_CTRL_UPDATE_ADDR_SET(addr) |
 224			VCAP_SUPER_CTRL_CLEAR_CACHE_SET(true) |
 225			VCAP_SUPER_CTRL_UPDATE_SHOT_SET(true),
 226			sparx5, VCAP_SUPER_CTRL);
 227		sparx5_vcap_wait_super_update(sparx5);
 228		break;
 229	case VCAP_TYPE_ES0:
 230		spx5_wr(VCAP_ES0_CFG_MV_NUM_POS_SET(0) |
 231				VCAP_ES0_CFG_MV_SIZE_SET(size),
 232			sparx5, VCAP_ES0_CFG);
 233		spx5_wr(VCAP_ES0_CTRL_UPDATE_CMD_SET(VCAP_CMD_INITIALIZE) |
 234				VCAP_ES0_CTRL_UPDATE_ENTRY_DIS_SET(0) |
 235				VCAP_ES0_CTRL_UPDATE_ACTION_DIS_SET(0) |
 236				VCAP_ES0_CTRL_UPDATE_CNT_DIS_SET(0) |
 237				VCAP_ES0_CTRL_UPDATE_ADDR_SET(addr) |
 238				VCAP_ES0_CTRL_CLEAR_CACHE_SET(true) |
 239				VCAP_ES0_CTRL_UPDATE_SHOT_SET(true),
 240			sparx5, VCAP_ES0_CTRL);
 241		sparx5_vcap_wait_es0_update(sparx5);
 242		break;
 243	case VCAP_TYPE_ES2:
 244		spx5_wr(VCAP_ES2_CFG_MV_NUM_POS_SET(0) |
 245			VCAP_ES2_CFG_MV_SIZE_SET(size),
 246			sparx5, VCAP_ES2_CFG);
 247		spx5_wr(VCAP_ES2_CTRL_UPDATE_CMD_SET(VCAP_CMD_INITIALIZE) |
 248			VCAP_ES2_CTRL_UPDATE_ENTRY_DIS_SET(0) |
 249			VCAP_ES2_CTRL_UPDATE_ACTION_DIS_SET(0) |
 250			VCAP_ES2_CTRL_UPDATE_CNT_DIS_SET(0) |
 251			VCAP_ES2_CTRL_UPDATE_ADDR_SET(addr) |
 252			VCAP_ES2_CTRL_CLEAR_CACHE_SET(true) |
 253			VCAP_ES2_CTRL_UPDATE_SHOT_SET(true),
 254			sparx5, VCAP_ES2_CTRL);
 255		sparx5_vcap_wait_es2_update(sparx5);
 256		break;
 257	default:
 258		sparx5_vcap_type_err(sparx5, admin, __func__);
 259		break;
 260	}
 261}
 262
 263/* Initializing VCAP rule data area */
 264static void sparx5_vcap_block_init(struct sparx5 *sparx5,
 265				   struct vcap_admin *admin)
 266{
 267	_sparx5_vcap_range_init(sparx5, admin, admin->first_valid_addr,
 268				admin->last_valid_addr -
 269					admin->first_valid_addr);
 270}
 271
 272/* Get the keyset name from the sparx5 VCAP model */
 273static const char *sparx5_vcap_keyset_name(struct net_device *ndev,
 274					   enum vcap_keyfield_set keyset)
 275{
 276	struct sparx5_port *port = netdev_priv(ndev);
 277
 278	return vcap_keyset_name(port->sparx5->vcap_ctrl, keyset);
 279}
 280
 281/* Check if this is the first lookup of IS0 */
 282static bool sparx5_vcap_is0_is_first_chain(struct vcap_rule *rule)
 283{
 284	return (rule->vcap_chain_id >= SPARX5_VCAP_CID_IS0_L0 &&
 285		rule->vcap_chain_id < SPARX5_VCAP_CID_IS0_L1) ||
 286		((rule->vcap_chain_id >= SPARX5_VCAP_CID_IS0_L2 &&
 287		  rule->vcap_chain_id < SPARX5_VCAP_CID_IS0_L3)) ||
 288		((rule->vcap_chain_id >= SPARX5_VCAP_CID_IS0_L4 &&
 289		  rule->vcap_chain_id < SPARX5_VCAP_CID_IS0_L5));
 290}
 291
 292/* Check if this is the first lookup of IS2 */
 293static bool sparx5_vcap_is2_is_first_chain(struct vcap_rule *rule)
 294{
 295	return (rule->vcap_chain_id >= SPARX5_VCAP_CID_IS2_L0 &&
 296		rule->vcap_chain_id < SPARX5_VCAP_CID_IS2_L1) ||
 297		((rule->vcap_chain_id >= SPARX5_VCAP_CID_IS2_L2 &&
 298		  rule->vcap_chain_id < SPARX5_VCAP_CID_IS2_L3));
 299}
 300
 301static bool sparx5_vcap_es2_is_first_chain(struct vcap_rule *rule)
 302{
 303	return (rule->vcap_chain_id >= SPARX5_VCAP_CID_ES2_L0 &&
 304		rule->vcap_chain_id < SPARX5_VCAP_CID_ES2_L1);
 305}
 306
 307/* Set the narrow range ingress port mask on a rule */
 308static void sparx5_vcap_add_ingress_range_port_mask(struct vcap_rule *rule,
 309						    struct net_device *ndev)
 310{
 311	struct sparx5_port *port = netdev_priv(ndev);
 312	u32 port_mask;
 313	u32 range;
 314
 315	range = port->portno / BITS_PER_TYPE(u32);
 316	/* Port bit set to match-any */
 317	port_mask = ~BIT(port->portno % BITS_PER_TYPE(u32));
 318	vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK_SEL, 0, 0xf);
 319	vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK_RNG, range, 0xf);
 320	vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK, 0, port_mask);
 321}
 322
 323/* Set the wide range ingress port mask on a rule */
 324static void sparx5_vcap_add_wide_port_mask(struct vcap_rule *rule,
 325					   struct net_device *ndev)
 326{
 327	struct sparx5_port *port = netdev_priv(ndev);
 328	struct vcap_u72_key port_mask;
 329	u32 range;
 330
 331	/* Port bit set to match-any */
 332	memset(port_mask.value, 0, sizeof(port_mask.value));
 333	memset(port_mask.mask, 0xff, sizeof(port_mask.mask));
 334	range = port->portno / BITS_PER_BYTE;
 335	port_mask.mask[range] = ~BIT(port->portno % BITS_PER_BYTE);
 336	vcap_rule_add_key_u72(rule, VCAP_KF_IF_IGR_PORT_MASK, &port_mask);
 337}
 338
 339static void sparx5_vcap_add_egress_range_port_mask(struct vcap_rule *rule,
 340						   struct net_device *ndev)
 341{
 342	struct sparx5_port *port = netdev_priv(ndev);
 343	u32 port_mask;
 344	u32 range;
 345
 346	/* Mask range selects:
 347	 * 0-2: Physical/Logical egress port number 0-31, 32–63, 64.
 348	 * 3-5: Virtual Interface Number 0-31, 32-63, 64.
 349	 * 6: CPU queue Number 0-7.
 350	 *
 351	 * Use physical/logical port ranges (0-2)
 352	 */
 353	range = port->portno / BITS_PER_TYPE(u32);
 354	/* Port bit set to match-any */
 355	port_mask = ~BIT(port->portno % BITS_PER_TYPE(u32));
 356	vcap_rule_add_key_u32(rule, VCAP_KF_IF_EGR_PORT_MASK_RNG, range, 0xf);
 357	vcap_rule_add_key_u32(rule, VCAP_KF_IF_EGR_PORT_MASK, 0, port_mask);
 358}
 359
 360/* Convert IS0 chain id to vcap lookup id */
 361static int sparx5_vcap_is0_cid_to_lookup(int cid)
 362{
 363	int lookup = 0;
 364
 365	if (cid >= SPARX5_VCAP_CID_IS0_L1 && cid < SPARX5_VCAP_CID_IS0_L2)
 366		lookup = 1;
 367	else if (cid >= SPARX5_VCAP_CID_IS0_L2 && cid < SPARX5_VCAP_CID_IS0_L3)
 368		lookup = 2;
 369	else if (cid >= SPARX5_VCAP_CID_IS0_L3 && cid < SPARX5_VCAP_CID_IS0_L4)
 370		lookup = 3;
 371	else if (cid >= SPARX5_VCAP_CID_IS0_L4 && cid < SPARX5_VCAP_CID_IS0_L5)
 372		lookup = 4;
 373	else if (cid >= SPARX5_VCAP_CID_IS0_L5 && cid < SPARX5_VCAP_CID_IS0_MAX)
 374		lookup = 5;
 375
 376	return lookup;
 377}
 378
 379/* Convert IS2 chain id to vcap lookup id */
 380static int sparx5_vcap_is2_cid_to_lookup(int cid)
 381{
 382	int lookup = 0;
 383
 384	if (cid >= SPARX5_VCAP_CID_IS2_L1 && cid < SPARX5_VCAP_CID_IS2_L2)
 385		lookup = 1;
 386	else if (cid >= SPARX5_VCAP_CID_IS2_L2 && cid < SPARX5_VCAP_CID_IS2_L3)
 387		lookup = 2;
 388	else if (cid >= SPARX5_VCAP_CID_IS2_L3 && cid < SPARX5_VCAP_CID_IS2_MAX)
 389		lookup = 3;
 390
 391	return lookup;
 392}
 393
 394/* Convert ES2 chain id to vcap lookup id */
 395static int sparx5_vcap_es2_cid_to_lookup(int cid)
 396{
 397	int lookup = 0;
 398
 399	if (cid >= SPARX5_VCAP_CID_ES2_L1)
 400		lookup = 1;
 401
 402	return lookup;
 403}
 404
 405/* Add ethernet type IS0 keyset to a list */
 406static void
 407sparx5_vcap_is0_get_port_etype_keysets(struct vcap_keyset_list *keysetlist,
 408				       u32 value)
 409{
 410	switch (ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL_GET(value)) {
 411	case VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE:
 412		vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL_7TUPLE);
 413		break;
 414	case VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4:
 415		vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL_5TUPLE_IP4);
 416		break;
 417	}
 418}
 419
 420/* Return the list of keysets for the vcap port configuration */
 421static int sparx5_vcap_is0_get_port_keysets(struct net_device *ndev,
 422					    int lookup,
 423					    struct vcap_keyset_list *keysetlist,
 424					    u16 l3_proto)
 425{
 426	struct sparx5_port *port = netdev_priv(ndev);
 427	struct sparx5 *sparx5 = port->sparx5;
 428	int portno = port->portno;
 429	u32 value;
 430
 431	value = spx5_rd(sparx5, ANA_CL_ADV_CL_CFG(portno, lookup));
 432
 433	/* Collect all keysets for the port in a list */
 434	if (l3_proto == ETH_P_ALL)
 435		sparx5_vcap_is0_get_port_etype_keysets(keysetlist, value);
 436
 437	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP)
 438		switch (ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL_GET(value)) {
 439		case VCAP_IS0_PS_ETYPE_DEFAULT:
 440			sparx5_vcap_is0_get_port_etype_keysets(keysetlist,
 441							       value);
 442			break;
 443		case VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE:
 444			vcap_keyset_list_add(keysetlist,
 445					     VCAP_KFS_NORMAL_7TUPLE);
 446			break;
 447		case VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4:
 448			vcap_keyset_list_add(keysetlist,
 449					     VCAP_KFS_NORMAL_5TUPLE_IP4);
 450			break;
 451		}
 452
 453	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IPV6)
 454		switch (ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL_GET(value)) {
 455		case VCAP_IS0_PS_ETYPE_DEFAULT:
 456			sparx5_vcap_is0_get_port_etype_keysets(keysetlist,
 457							       value);
 458			break;
 459		case VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE:
 460			vcap_keyset_list_add(keysetlist,
 461					     VCAP_KFS_NORMAL_7TUPLE);
 462			break;
 463		case VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4:
 464			vcap_keyset_list_add(keysetlist,
 465					     VCAP_KFS_NORMAL_5TUPLE_IP4);
 466			break;
 467		}
 468
 469	if (l3_proto != ETH_P_IP && l3_proto != ETH_P_IPV6)
 470		sparx5_vcap_is0_get_port_etype_keysets(keysetlist, value);
 471	return 0;
 472}
 473
 474/* Return the list of keysets for the vcap port configuration */
 475static int sparx5_vcap_is2_get_port_keysets(struct net_device *ndev,
 476					    int lookup,
 477					    struct vcap_keyset_list *keysetlist,
 478					    u16 l3_proto)
 479{
 480	struct sparx5_port *port = netdev_priv(ndev);
 481	struct sparx5 *sparx5 = port->sparx5;
 482	int portno = port->portno;
 483	u32 value;
 484
 485	value = spx5_rd(sparx5, ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
 486
 487	/* Collect all keysets for the port in a list */
 488	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_ARP) {
 489		switch (ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL_GET(value)) {
 490		case VCAP_IS2_PS_ARP_MAC_ETYPE:
 491			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
 492			break;
 493		case VCAP_IS2_PS_ARP_ARP:
 494			vcap_keyset_list_add(keysetlist, VCAP_KFS_ARP);
 495			break;
 496		}
 497	}
 498
 499	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP) {
 500		switch (ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL_GET(value)) {
 501		case VCAP_IS2_PS_IPV4_UC_MAC_ETYPE:
 502			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
 503			break;
 504		case VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER:
 505			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
 506			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
 507			break;
 508		case VCAP_IS2_PS_IPV4_UC_IP_7TUPLE:
 509			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
 510			break;
 511		}
 512
 513		switch (ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL_GET(value)) {
 514		case VCAP_IS2_PS_IPV4_MC_MAC_ETYPE:
 515			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
 516			break;
 517		case VCAP_IS2_PS_IPV4_MC_IP4_TCP_UDP_OTHER:
 518			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
 519			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
 520			break;
 521		case VCAP_IS2_PS_IPV4_MC_IP_7TUPLE:
 522			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
 523			break;
 524		}
 525	}
 526
 527	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IPV6) {
 528		switch (ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL_GET(value)) {
 529		case VCAP_IS2_PS_IPV6_UC_MAC_ETYPE:
 530			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
 531			break;
 532		case VCAP_IS2_PS_IPV6_UC_IP_7TUPLE:
 533			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
 534			break;
 535		case VCAP_IS2_PS_IPV6_UC_IP6_STD:
 536			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
 537			break;
 538		case VCAP_IS2_PS_IPV6_UC_IP4_TCP_UDP_OTHER:
 539			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
 540			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
 541			break;
 542		}
 543
 544		switch (ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL_GET(value)) {
 545		case VCAP_IS2_PS_IPV6_MC_MAC_ETYPE:
 546			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
 547			break;
 548		case VCAP_IS2_PS_IPV6_MC_IP_7TUPLE:
 549			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
 550			break;
 551		case VCAP_IS2_PS_IPV6_MC_IP6_STD:
 552			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
 553			break;
 554		case VCAP_IS2_PS_IPV6_MC_IP4_TCP_UDP_OTHER:
 555			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
 556			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
 557			break;
 558		case VCAP_IS2_PS_IPV6_MC_IP6_VID:
 559			/* Not used */
 560			break;
 561		}
 562	}
 563
 564	if (l3_proto != ETH_P_ARP && l3_proto != ETH_P_IP &&
 565	    l3_proto != ETH_P_IPV6) {
 566		switch (ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL_GET(value)) {
 567		case VCAP_IS2_PS_NONETH_MAC_ETYPE:
 568			/* IS2 non-classified frames generate MAC_ETYPE */
 569			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
 570			break;
 571		}
 572	}
 573	return 0;
 574}
 575
 576/* Return the keysets for the vcap port IP4 traffic class configuration */
 577static void
 578sparx5_vcap_es2_get_port_ipv4_keysets(struct vcap_keyset_list *keysetlist,
 579				      u32 value)
 580{
 581	switch (EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL_GET(value)) {
 582	case VCAP_ES2_PS_IPV4_MAC_ETYPE:
 583		vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
 584		break;
 585	case VCAP_ES2_PS_IPV4_IP_7TUPLE:
 586		vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
 587		break;
 588	case VCAP_ES2_PS_IPV4_IP4_TCP_UDP_VID:
 589		vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
 590		break;
 591	case VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER:
 592		vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
 593		vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
 594		break;
 595	case VCAP_ES2_PS_IPV4_IP4_VID:
 596		/* Not used */
 597		break;
 598	case VCAP_ES2_PS_IPV4_IP4_OTHER:
 599		vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
 600		break;
 601	}
 602}
 603
 604/* Return the list of keysets for the vcap port configuration */
 605static int sparx5_vcap_es0_get_port_keysets(struct net_device *ndev,
 606					    struct vcap_keyset_list *keysetlist,
 607					    u16 l3_proto)
 608{
 609	struct sparx5_port *port = netdev_priv(ndev);
 610	struct sparx5 *sparx5 = port->sparx5;
 611	int portno = port->portno;
 612	u32 value;
 613
 614	value = spx5_rd(sparx5, REW_RTAG_ETAG_CTRL(portno));
 615
 616	/* Collect all keysets for the port in a list */
 617	switch (REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA_GET(value)) {
 618	case VCAP_ES0_PS_NORMAL_SELECTION:
 619	case VCAP_ES0_PS_FORCE_ISDX_LOOKUPS:
 620		vcap_keyset_list_add(keysetlist, VCAP_KFS_ISDX);
 621		break;
 622	default:
 623		break;
 624	}
 625	return 0;
 626}
 627
 628/* Return the list of keysets for the vcap port configuration */
 629static int sparx5_vcap_es2_get_port_keysets(struct net_device *ndev,
 630					    int lookup,
 631					    struct vcap_keyset_list *keysetlist,
 632					    u16 l3_proto)
 633{
 634	struct sparx5_port *port = netdev_priv(ndev);
 635	struct sparx5 *sparx5 = port->sparx5;
 636	int portno = port->portno;
 637	u32 value;
 638
 639	value = spx5_rd(sparx5, EACL_VCAP_ES2_KEY_SEL(portno, lookup));
 640
 641	/* Collect all keysets for the port in a list */
 642	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_ARP) {
 643		switch (EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL_GET(value)) {
 644		case VCAP_ES2_PS_ARP_MAC_ETYPE:
 645			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
 646			break;
 647		case VCAP_ES2_PS_ARP_ARP:
 648			vcap_keyset_list_add(keysetlist, VCAP_KFS_ARP);
 649			break;
 650		}
 651	}
 652
 653	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP)
 654		sparx5_vcap_es2_get_port_ipv4_keysets(keysetlist, value);
 655
 656	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IPV6) {
 657		switch (EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL_GET(value)) {
 658		case VCAP_ES2_PS_IPV6_MAC_ETYPE:
 659			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
 660			break;
 661		case VCAP_ES2_PS_IPV6_IP_7TUPLE:
 662			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
 663			break;
 664		case VCAP_ES2_PS_IPV6_IP_7TUPLE_VID:
 665			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
 666			break;
 667		case VCAP_ES2_PS_IPV6_IP_7TUPLE_STD:
 668			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
 669			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
 670			break;
 671		case VCAP_ES2_PS_IPV6_IP6_VID:
 672			/* Not used */
 673			break;
 674		case VCAP_ES2_PS_IPV6_IP6_STD:
 675			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
 676			break;
 677		case VCAP_ES2_PS_IPV6_IP4_DOWNGRADE:
 678			sparx5_vcap_es2_get_port_ipv4_keysets(keysetlist,
 679							      value);
 680			break;
 681		}
 682	}
 683
 684	if (l3_proto != ETH_P_ARP && l3_proto != ETH_P_IP &&
 685	    l3_proto != ETH_P_IPV6) {
 686		vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
 687	}
 688	return 0;
 689}
 690
 691/* Get the port keyset for the vcap lookup */
 692int sparx5_vcap_get_port_keyset(struct net_device *ndev,
 693				struct vcap_admin *admin,
 694				int cid,
 695				u16 l3_proto,
 696				struct vcap_keyset_list *kslist)
 697{
 698	int lookup, err = -EINVAL;
 699	struct sparx5_port *port;
 700
 701	switch (admin->vtype) {
 702	case VCAP_TYPE_IS0:
 703		lookup = sparx5_vcap_is0_cid_to_lookup(cid);
 704		err = sparx5_vcap_is0_get_port_keysets(ndev, lookup, kslist,
 705						       l3_proto);
 706		break;
 707	case VCAP_TYPE_IS2:
 708		lookup = sparx5_vcap_is2_cid_to_lookup(cid);
 709		err = sparx5_vcap_is2_get_port_keysets(ndev, lookup, kslist,
 710						       l3_proto);
 711		break;
 712	case VCAP_TYPE_ES0:
 713		err = sparx5_vcap_es0_get_port_keysets(ndev, kslist, l3_proto);
 714		break;
 715	case VCAP_TYPE_ES2:
 716		lookup = sparx5_vcap_es2_cid_to_lookup(cid);
 717		err = sparx5_vcap_es2_get_port_keysets(ndev, lookup, kslist,
 718						       l3_proto);
 719		break;
 720	default:
 721		port = netdev_priv(ndev);
 722		sparx5_vcap_type_err(port->sparx5, admin, __func__);
 723		break;
 724	}
 725	return err;
 726}
 727
 728/* Check if the ethertype is supported by the vcap port classification */
 729bool sparx5_vcap_is_known_etype(struct vcap_admin *admin, u16 etype)
 730{
 731	const u16 *known_etypes;
 732	int size, idx;
 733
 734	switch (admin->vtype) {
 735	case VCAP_TYPE_IS0:
 736		known_etypes = sparx5_vcap_is0_known_etypes;
 737		size = ARRAY_SIZE(sparx5_vcap_is0_known_etypes);
 738		break;
 739	case VCAP_TYPE_IS2:
 740		known_etypes = sparx5_vcap_is2_known_etypes;
 741		size = ARRAY_SIZE(sparx5_vcap_is2_known_etypes);
 742		break;
 743	case VCAP_TYPE_ES0:
 744		return true;
 745	case VCAP_TYPE_ES2:
 746		known_etypes = sparx5_vcap_es2_known_etypes;
 747		size = ARRAY_SIZE(sparx5_vcap_es2_known_etypes);
 748		break;
 749	default:
 750		return false;
 751	}
 752	for (idx = 0; idx < size; ++idx)
 753		if (known_etypes[idx] == etype)
 754			return true;
 755	return false;
 756}
 757
 758/* API callback used for validating a field keyset (check the port keysets) */
 759static enum vcap_keyfield_set
 760sparx5_vcap_validate_keyset(struct net_device *ndev,
 761			    struct vcap_admin *admin,
 762			    struct vcap_rule *rule,
 763			    struct vcap_keyset_list *kslist,
 764			    u16 l3_proto)
 765{
 766	struct vcap_keyset_list keysetlist = {};
 767	enum vcap_keyfield_set keysets[10] = {};
 768	struct sparx5_port *port;
 769	int idx, jdx, lookup;
 770
 771	if (!kslist || kslist->cnt == 0)
 772		return VCAP_KFS_NO_VALUE;
 773
 774	keysetlist.max = ARRAY_SIZE(keysets);
 775	keysetlist.keysets = keysets;
 776
 777	/* Get a list of currently configured keysets in the lookups */
 778	switch (admin->vtype) {
 779	case VCAP_TYPE_IS0:
 780		lookup = sparx5_vcap_is0_cid_to_lookup(rule->vcap_chain_id);
 781		sparx5_vcap_is0_get_port_keysets(ndev, lookup, &keysetlist,
 782						 l3_proto);
 783		break;
 784	case VCAP_TYPE_IS2:
 785		lookup = sparx5_vcap_is2_cid_to_lookup(rule->vcap_chain_id);
 786		sparx5_vcap_is2_get_port_keysets(ndev, lookup, &keysetlist,
 787						 l3_proto);
 788		break;
 789	case VCAP_TYPE_ES0:
 790		sparx5_vcap_es0_get_port_keysets(ndev, &keysetlist, l3_proto);
 791		break;
 792	case VCAP_TYPE_ES2:
 793		lookup = sparx5_vcap_es2_cid_to_lookup(rule->vcap_chain_id);
 794		sparx5_vcap_es2_get_port_keysets(ndev, lookup, &keysetlist,
 795						 l3_proto);
 796		break;
 797	default:
 798		port = netdev_priv(ndev);
 799		sparx5_vcap_type_err(port->sparx5, admin, __func__);
 800		break;
 801	}
 802
 803	/* Check if there is a match and return the match */
 804	for (idx = 0; idx < kslist->cnt; ++idx)
 805		for (jdx = 0; jdx < keysetlist.cnt; ++jdx)
 806			if (kslist->keysets[idx] == keysets[jdx])
 807				return kslist->keysets[idx];
 808
 809	pr_err("%s:%d: %s not supported in port key selection\n",
 810	       __func__, __LINE__,
 811	       sparx5_vcap_keyset_name(ndev, kslist->keysets[0]));
 812
 813	return -ENOENT;
 814}
 815
 816static void sparx5_vcap_ingress_add_default_fields(struct net_device *ndev,
 817						   struct vcap_admin *admin,
 818						   struct vcap_rule *rule)
 819{
 820	const struct vcap_field *field;
 821	bool is_first;
 822
 823	/* Add ingress port mask matching the net device */
 824	field = vcap_lookup_keyfield(rule, VCAP_KF_IF_IGR_PORT_MASK);
 825	if (field && field->width == SPX5_PORTS)
 826		sparx5_vcap_add_wide_port_mask(rule, ndev);
 827	else if (field && field->width == BITS_PER_TYPE(u32))
 828		sparx5_vcap_add_ingress_range_port_mask(rule, ndev);
 829	else
 830		pr_err("%s:%d: %s: could not add an ingress port mask for: %s\n",
 831		       __func__, __LINE__, netdev_name(ndev),
 832		       sparx5_vcap_keyset_name(ndev, rule->keyset));
 833
 834	if (admin->vtype == VCAP_TYPE_IS0)
 835		is_first = sparx5_vcap_is0_is_first_chain(rule);
 836	else
 837		is_first = sparx5_vcap_is2_is_first_chain(rule);
 838
 839	/* Add key that selects the first/second lookup */
 840	if (is_first)
 841		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
 842				      VCAP_BIT_1);
 843	else
 844		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
 845				      VCAP_BIT_0);
 846}
 847
 848static void sparx5_vcap_es0_add_default_fields(struct net_device *ndev,
 849					       struct vcap_admin *admin,
 850					       struct vcap_rule *rule)
 851{
 852	struct sparx5_port *port = netdev_priv(ndev);
 853
 854	vcap_rule_add_key_u32(rule, VCAP_KF_IF_EGR_PORT_NO, port->portno, ~0);
 855	/* Match untagged frames if there was no VLAN key */
 856	vcap_rule_add_key_u32(rule, VCAP_KF_8021Q_TPID, SPX5_TPID_SEL_UNTAGGED,
 857			      ~0);
 858}
 859
 860static void sparx5_vcap_es2_add_default_fields(struct net_device *ndev,
 861					       struct vcap_admin *admin,
 862					       struct vcap_rule *rule)
 863{
 864	const struct vcap_field *field;
 865	bool is_first;
 866
 867	/* Add egress port mask matching the net device */
 868	field = vcap_lookup_keyfield(rule, VCAP_KF_IF_EGR_PORT_MASK);
 869	if (field)
 870		sparx5_vcap_add_egress_range_port_mask(rule, ndev);
 871
 872	/* Add key that selects the first/second lookup */
 873	is_first = sparx5_vcap_es2_is_first_chain(rule);
 874
 875	if (is_first)
 876		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
 877				      VCAP_BIT_1);
 878	else
 879		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
 880				      VCAP_BIT_0);
 881}
 882
 883/* API callback used for adding default fields to a rule */
 884static void sparx5_vcap_add_default_fields(struct net_device *ndev,
 885					   struct vcap_admin *admin,
 886					   struct vcap_rule *rule)
 887{
 888	struct sparx5_port *port;
 889
 890	/* add the lookup bit */
 891	switch (admin->vtype) {
 892	case VCAP_TYPE_IS0:
 893	case VCAP_TYPE_IS2:
 894		sparx5_vcap_ingress_add_default_fields(ndev, admin, rule);
 895		break;
 896	case VCAP_TYPE_ES0:
 897		sparx5_vcap_es0_add_default_fields(ndev, admin, rule);
 898		break;
 899	case VCAP_TYPE_ES2:
 900		sparx5_vcap_es2_add_default_fields(ndev, admin, rule);
 901		break;
 902	default:
 903		port = netdev_priv(ndev);
 904		sparx5_vcap_type_err(port->sparx5, admin, __func__);
 905		break;
 906	}
 907}
 908
 909/* API callback used for erasing the vcap cache area (not the register area) */
 910static void sparx5_vcap_cache_erase(struct vcap_admin *admin)
 911{
 912	memset(admin->cache.keystream, 0, STREAMSIZE);
 913	memset(admin->cache.maskstream, 0, STREAMSIZE);
 914	memset(admin->cache.actionstream, 0, STREAMSIZE);
 915	memset(&admin->cache.counter, 0, sizeof(admin->cache.counter));
 916}
 917
 918static void sparx5_vcap_is0_cache_write(struct sparx5 *sparx5,
 919					struct vcap_admin *admin,
 920					enum vcap_selection sel,
 921					u32 start,
 922					u32 count)
 923{
 924	u32 *keystr, *mskstr, *actstr;
 925	int idx;
 926
 927	keystr = &admin->cache.keystream[start];
 928	mskstr = &admin->cache.maskstream[start];
 929	actstr = &admin->cache.actionstream[start];
 930
 931	switch (sel) {
 932	case VCAP_SEL_ENTRY:
 933		for (idx = 0; idx < count; ++idx) {
 934			/* Avoid 'match-off' by setting value & mask */
 935			spx5_wr(keystr[idx] & mskstr[idx], sparx5,
 936				VCAP_SUPER_VCAP_ENTRY_DAT(idx));
 937			spx5_wr(~mskstr[idx], sparx5,
 938				VCAP_SUPER_VCAP_MASK_DAT(idx));
 939		}
 940		break;
 941	case VCAP_SEL_ACTION:
 942		for (idx = 0; idx < count; ++idx)
 943			spx5_wr(actstr[idx], sparx5,
 944				VCAP_SUPER_VCAP_ACTION_DAT(idx));
 945		break;
 946	case VCAP_SEL_ALL:
 947		pr_err("%s:%d: cannot write all streams at once\n",
 948		       __func__, __LINE__);
 949		break;
 950	default:
 951		break;
 952	}
 953
 954	if (sel & VCAP_SEL_COUNTER)
 955		spx5_wr(admin->cache.counter, sparx5,
 956			VCAP_SUPER_VCAP_CNT_DAT(0));
 957}
 958
 959static void sparx5_vcap_is2_cache_write(struct sparx5 *sparx5,
 960					struct vcap_admin *admin,
 961					enum vcap_selection sel,
 962					u32 start,
 963					u32 count)
 964{
 965	u32 *keystr, *mskstr, *actstr;
 966	int idx;
 967
 968	keystr = &admin->cache.keystream[start];
 969	mskstr = &admin->cache.maskstream[start];
 970	actstr = &admin->cache.actionstream[start];
 971
 972	switch (sel) {
 973	case VCAP_SEL_ENTRY:
 974		for (idx = 0; idx < count; ++idx) {
 975			/* Avoid 'match-off' by setting value & mask */
 976			spx5_wr(keystr[idx] & mskstr[idx], sparx5,
 977				VCAP_SUPER_VCAP_ENTRY_DAT(idx));
 978			spx5_wr(~mskstr[idx], sparx5,
 979				VCAP_SUPER_VCAP_MASK_DAT(idx));
 980		}
 981		break;
 982	case VCAP_SEL_ACTION:
 983		for (idx = 0; idx < count; ++idx)
 984			spx5_wr(actstr[idx], sparx5,
 985				VCAP_SUPER_VCAP_ACTION_DAT(idx));
 986		break;
 987	case VCAP_SEL_ALL:
 988		pr_err("%s:%d: cannot write all streams at once\n",
 989		       __func__, __LINE__);
 990		break;
 991	default:
 992		break;
 993	}
 994	if (sel & VCAP_SEL_COUNTER) {
 995		start = start & 0xfff; /* counter limit */
 996		if (admin->vinst == 0)
 997			spx5_wr(admin->cache.counter, sparx5,
 998				ANA_ACL_CNT_A(start));
 999		else
1000			spx5_wr(admin->cache.counter, sparx5,
1001				ANA_ACL_CNT_B(start));
1002		spx5_wr(admin->cache.sticky, sparx5,
1003			VCAP_SUPER_VCAP_CNT_DAT(0));
1004	}
1005}
1006
1007/* Use ESDX counters located in the XQS */
1008static void sparx5_es0_write_esdx_counter(struct sparx5 *sparx5,
1009					  struct vcap_admin *admin, u32 id)
1010{
1011	mutex_lock(&sparx5->queue_stats_lock);
1012	spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(id), sparx5, XQS_STAT_CFG);
1013	spx5_wr(admin->cache.counter, sparx5,
1014		XQS_CNT(SPARX5_STAT_ESDX_GRN_PKTS));
1015	spx5_wr(0, sparx5, XQS_CNT(SPARX5_STAT_ESDX_YEL_PKTS));
1016	mutex_unlock(&sparx5->queue_stats_lock);
1017}
1018
1019static void sparx5_vcap_es0_cache_write(struct sparx5 *sparx5,
1020					struct vcap_admin *admin,
1021					enum vcap_selection sel,
1022					u32 start,
1023					u32 count)
1024{
1025	u32 *keystr, *mskstr, *actstr;
1026	int idx;
1027
1028	keystr = &admin->cache.keystream[start];
1029	mskstr = &admin->cache.maskstream[start];
1030	actstr = &admin->cache.actionstream[start];
1031
1032	switch (sel) {
1033	case VCAP_SEL_ENTRY:
1034		for (idx = 0; idx < count; ++idx) {
1035			/* Avoid 'match-off' by setting value & mask */
1036			spx5_wr(keystr[idx] & mskstr[idx], sparx5,
1037				VCAP_ES0_VCAP_ENTRY_DAT(idx));
1038			spx5_wr(~mskstr[idx], sparx5,
1039				VCAP_ES0_VCAP_MASK_DAT(idx));
1040		}
1041		break;
1042	case VCAP_SEL_ACTION:
1043		for (idx = 0; idx < count; ++idx)
1044			spx5_wr(actstr[idx], sparx5,
1045				VCAP_ES0_VCAP_ACTION_DAT(idx));
1046		break;
1047	case VCAP_SEL_ALL:
1048		pr_err("%s:%d: cannot write all streams at once\n",
1049		       __func__, __LINE__);
1050		break;
1051	default:
1052		break;
1053	}
1054	if (sel & VCAP_SEL_COUNTER) {
1055		spx5_wr(admin->cache.counter, sparx5, VCAP_ES0_VCAP_CNT_DAT(0));
1056		sparx5_es0_write_esdx_counter(sparx5, admin, start);
1057	}
1058}
1059
1060static void sparx5_vcap_es2_cache_write(struct sparx5 *sparx5,
1061					struct vcap_admin *admin,
1062					enum vcap_selection sel,
1063					u32 start,
1064					u32 count)
1065{
1066	u32 *keystr, *mskstr, *actstr;
1067	int idx;
1068
1069	keystr = &admin->cache.keystream[start];
1070	mskstr = &admin->cache.maskstream[start];
1071	actstr = &admin->cache.actionstream[start];
1072
1073	switch (sel) {
1074	case VCAP_SEL_ENTRY:
1075		for (idx = 0; idx < count; ++idx) {
1076			/* Avoid 'match-off' by setting value & mask */
1077			spx5_wr(keystr[idx] & mskstr[idx], sparx5,
1078				VCAP_ES2_VCAP_ENTRY_DAT(idx));
1079			spx5_wr(~mskstr[idx], sparx5,
1080				VCAP_ES2_VCAP_MASK_DAT(idx));
1081		}
1082		break;
1083	case VCAP_SEL_ACTION:
1084		for (idx = 0; idx < count; ++idx)
1085			spx5_wr(actstr[idx], sparx5,
1086				VCAP_ES2_VCAP_ACTION_DAT(idx));
1087		break;
1088	case VCAP_SEL_ALL:
1089		pr_err("%s:%d: cannot write all streams at once\n",
1090		       __func__, __LINE__);
1091		break;
1092	default:
1093		break;
1094	}
1095	if (sel & VCAP_SEL_COUNTER) {
1096		start = start & 0x7ff; /* counter limit */
1097		spx5_wr(admin->cache.counter, sparx5, EACL_ES2_CNT(start));
1098		spx5_wr(admin->cache.sticky, sparx5, VCAP_ES2_VCAP_CNT_DAT(0));
1099	}
1100}
1101
1102/* API callback used for writing to the VCAP cache */
1103static void sparx5_vcap_cache_write(struct net_device *ndev,
1104				    struct vcap_admin *admin,
1105				    enum vcap_selection sel,
1106				    u32 start,
1107				    u32 count)
1108{
1109	struct sparx5_port *port = netdev_priv(ndev);
1110	struct sparx5 *sparx5 = port->sparx5;
1111
1112	switch (admin->vtype) {
1113	case VCAP_TYPE_IS0:
1114		sparx5_vcap_is0_cache_write(sparx5, admin, sel, start, count);
1115		break;
1116	case VCAP_TYPE_IS2:
1117		sparx5_vcap_is2_cache_write(sparx5, admin, sel, start, count);
1118		break;
1119	case VCAP_TYPE_ES0:
1120		sparx5_vcap_es0_cache_write(sparx5, admin, sel, start, count);
1121		break;
1122	case VCAP_TYPE_ES2:
1123		sparx5_vcap_es2_cache_write(sparx5, admin, sel, start, count);
1124		break;
1125	default:
1126		sparx5_vcap_type_err(sparx5, admin, __func__);
1127		break;
1128	}
1129}
1130
1131static void sparx5_vcap_is0_cache_read(struct sparx5 *sparx5,
1132				       struct vcap_admin *admin,
1133				       enum vcap_selection sel,
1134				       u32 start,
1135				       u32 count)
1136{
1137	u32 *keystr, *mskstr, *actstr;
1138	int idx;
1139
1140	keystr = &admin->cache.keystream[start];
1141	mskstr = &admin->cache.maskstream[start];
1142	actstr = &admin->cache.actionstream[start];
1143
1144	if (sel & VCAP_SEL_ENTRY) {
1145		for (idx = 0; idx < count; ++idx) {
1146			keystr[idx] = spx5_rd(sparx5,
1147					      VCAP_SUPER_VCAP_ENTRY_DAT(idx));
1148			mskstr[idx] = ~spx5_rd(sparx5,
1149					       VCAP_SUPER_VCAP_MASK_DAT(idx));
1150		}
1151	}
1152
1153	if (sel & VCAP_SEL_ACTION)
1154		for (idx = 0; idx < count; ++idx)
1155			actstr[idx] = spx5_rd(sparx5,
1156					      VCAP_SUPER_VCAP_ACTION_DAT(idx));
1157
1158	if (sel & VCAP_SEL_COUNTER) {
1159		admin->cache.counter =
1160			spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0));
1161		admin->cache.sticky =
1162			spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0));
1163	}
1164}
1165
1166static void sparx5_vcap_is2_cache_read(struct sparx5 *sparx5,
1167				       struct vcap_admin *admin,
1168				       enum vcap_selection sel,
1169				       u32 start,
1170				       u32 count)
1171{
1172	u32 *keystr, *mskstr, *actstr;
1173	int idx;
1174
1175	keystr = &admin->cache.keystream[start];
1176	mskstr = &admin->cache.maskstream[start];
1177	actstr = &admin->cache.actionstream[start];
1178
1179	if (sel & VCAP_SEL_ENTRY) {
1180		for (idx = 0; idx < count; ++idx) {
1181			keystr[idx] = spx5_rd(sparx5,
1182					      VCAP_SUPER_VCAP_ENTRY_DAT(idx));
1183			mskstr[idx] = ~spx5_rd(sparx5,
1184					       VCAP_SUPER_VCAP_MASK_DAT(idx));
1185		}
1186	}
1187
1188	if (sel & VCAP_SEL_ACTION)
1189		for (idx = 0; idx < count; ++idx)
1190			actstr[idx] = spx5_rd(sparx5,
1191					      VCAP_SUPER_VCAP_ACTION_DAT(idx));
1192
1193	if (sel & VCAP_SEL_COUNTER) {
1194		start = start & 0xfff; /* counter limit */
1195		if (admin->vinst == 0)
1196			admin->cache.counter =
1197				spx5_rd(sparx5, ANA_ACL_CNT_A(start));
1198		else
1199			admin->cache.counter =
1200				spx5_rd(sparx5, ANA_ACL_CNT_B(start));
1201		admin->cache.sticky =
1202			spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0));
1203	}
1204}
1205
1206/* Use ESDX counters located in the XQS */
1207static void sparx5_es0_read_esdx_counter(struct sparx5 *sparx5,
1208					 struct vcap_admin *admin, u32 id)
1209{
1210	u32 counter;
1211
1212	mutex_lock(&sparx5->queue_stats_lock);
1213	spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(id), sparx5, XQS_STAT_CFG);
1214	counter = spx5_rd(sparx5, XQS_CNT(SPARX5_STAT_ESDX_GRN_PKTS)) +
1215		spx5_rd(sparx5, XQS_CNT(SPARX5_STAT_ESDX_YEL_PKTS));
1216	mutex_unlock(&sparx5->queue_stats_lock);
1217	if (counter)
1218		admin->cache.counter = counter;
1219}
1220
1221static void sparx5_vcap_es0_cache_read(struct sparx5 *sparx5,
1222				       struct vcap_admin *admin,
1223				       enum vcap_selection sel,
1224				       u32 start,
1225				       u32 count)
1226{
1227	u32 *keystr, *mskstr, *actstr;
1228	int idx;
1229
1230	keystr = &admin->cache.keystream[start];
1231	mskstr = &admin->cache.maskstream[start];
1232	actstr = &admin->cache.actionstream[start];
1233
1234	if (sel & VCAP_SEL_ENTRY) {
1235		for (idx = 0; idx < count; ++idx) {
1236			keystr[idx] =
1237				spx5_rd(sparx5, VCAP_ES0_VCAP_ENTRY_DAT(idx));
1238			mskstr[idx] =
1239				~spx5_rd(sparx5, VCAP_ES0_VCAP_MASK_DAT(idx));
1240		}
1241	}
1242
1243	if (sel & VCAP_SEL_ACTION)
1244		for (idx = 0; idx < count; ++idx)
1245			actstr[idx] =
1246				spx5_rd(sparx5, VCAP_ES0_VCAP_ACTION_DAT(idx));
1247
1248	if (sel & VCAP_SEL_COUNTER) {
1249		admin->cache.counter =
1250			spx5_rd(sparx5, VCAP_ES0_VCAP_CNT_DAT(0));
1251		admin->cache.sticky = admin->cache.counter;
1252		sparx5_es0_read_esdx_counter(sparx5, admin, start);
1253	}
1254}
1255
1256static void sparx5_vcap_es2_cache_read(struct sparx5 *sparx5,
1257				       struct vcap_admin *admin,
1258				       enum vcap_selection sel,
1259				       u32 start,
1260				       u32 count)
1261{
1262	u32 *keystr, *mskstr, *actstr;
1263	int idx;
1264
1265	keystr = &admin->cache.keystream[start];
1266	mskstr = &admin->cache.maskstream[start];
1267	actstr = &admin->cache.actionstream[start];
1268
1269	if (sel & VCAP_SEL_ENTRY) {
1270		for (idx = 0; idx < count; ++idx) {
1271			keystr[idx] =
1272				spx5_rd(sparx5, VCAP_ES2_VCAP_ENTRY_DAT(idx));
1273			mskstr[idx] =
1274				~spx5_rd(sparx5, VCAP_ES2_VCAP_MASK_DAT(idx));
1275		}
1276	}
1277
1278	if (sel & VCAP_SEL_ACTION)
1279		for (idx = 0; idx < count; ++idx)
1280			actstr[idx] =
1281				spx5_rd(sparx5, VCAP_ES2_VCAP_ACTION_DAT(idx));
1282
1283	if (sel & VCAP_SEL_COUNTER) {
1284		start = start & 0x7ff; /* counter limit */
1285		admin->cache.counter =
1286			spx5_rd(sparx5, EACL_ES2_CNT(start));
1287		admin->cache.sticky =
1288			spx5_rd(sparx5, VCAP_ES2_VCAP_CNT_DAT(0));
1289	}
1290}
1291
1292/* API callback used for reading from the VCAP into the VCAP cache */
1293static void sparx5_vcap_cache_read(struct net_device *ndev,
1294				   struct vcap_admin *admin,
1295				   enum vcap_selection sel,
1296				   u32 start,
1297				   u32 count)
1298{
1299	struct sparx5_port *port = netdev_priv(ndev);
1300	struct sparx5 *sparx5 = port->sparx5;
1301
1302	switch (admin->vtype) {
1303	case VCAP_TYPE_IS0:
1304		sparx5_vcap_is0_cache_read(sparx5, admin, sel, start, count);
1305		break;
1306	case VCAP_TYPE_IS2:
1307		sparx5_vcap_is2_cache_read(sparx5, admin, sel, start, count);
1308		break;
1309	case VCAP_TYPE_ES0:
1310		sparx5_vcap_es0_cache_read(sparx5, admin, sel, start, count);
1311		break;
1312	case VCAP_TYPE_ES2:
1313		sparx5_vcap_es2_cache_read(sparx5, admin, sel, start, count);
1314		break;
1315	default:
1316		sparx5_vcap_type_err(sparx5, admin, __func__);
1317		break;
1318	}
1319}
1320
1321/* API callback used for initializing a VCAP address range */
1322static void sparx5_vcap_range_init(struct net_device *ndev,
1323				   struct vcap_admin *admin, u32 addr,
1324				   u32 count)
1325{
1326	struct sparx5_port *port = netdev_priv(ndev);
1327	struct sparx5 *sparx5 = port->sparx5;
1328
1329	_sparx5_vcap_range_init(sparx5, admin, addr, count);
1330}
1331
1332static void sparx5_vcap_super_update(struct sparx5 *sparx5,
1333				     enum vcap_command cmd,
1334				     enum vcap_selection sel, u32 addr)
1335{
1336	bool clear = (cmd == VCAP_CMD_INITIALIZE);
1337
1338	spx5_wr(VCAP_SUPER_CFG_MV_NUM_POS_SET(0) |
1339		VCAP_SUPER_CFG_MV_SIZE_SET(0), sparx5, VCAP_SUPER_CFG);
1340	spx5_wr(VCAP_SUPER_CTRL_UPDATE_CMD_SET(cmd) |
1341		VCAP_SUPER_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) |
1342		VCAP_SUPER_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) |
1343		VCAP_SUPER_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) |
1344		VCAP_SUPER_CTRL_UPDATE_ADDR_SET(addr) |
1345		VCAP_SUPER_CTRL_CLEAR_CACHE_SET(clear) |
1346		VCAP_SUPER_CTRL_UPDATE_SHOT_SET(true),
1347		sparx5, VCAP_SUPER_CTRL);
1348	sparx5_vcap_wait_super_update(sparx5);
1349}
1350
1351static void sparx5_vcap_es0_update(struct sparx5 *sparx5,
1352				   enum vcap_command cmd,
1353				   enum vcap_selection sel, u32 addr)
1354{
1355	bool clear = (cmd == VCAP_CMD_INITIALIZE);
1356
1357	spx5_wr(VCAP_ES0_CFG_MV_NUM_POS_SET(0) |
1358		VCAP_ES0_CFG_MV_SIZE_SET(0), sparx5, VCAP_ES0_CFG);
1359	spx5_wr(VCAP_ES0_CTRL_UPDATE_CMD_SET(cmd) |
1360		VCAP_ES0_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) |
1361		VCAP_ES0_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) |
1362		VCAP_ES0_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) |
1363		VCAP_ES0_CTRL_UPDATE_ADDR_SET(addr) |
1364		VCAP_ES0_CTRL_CLEAR_CACHE_SET(clear) |
1365		VCAP_ES0_CTRL_UPDATE_SHOT_SET(true),
1366		sparx5, VCAP_ES0_CTRL);
1367	sparx5_vcap_wait_es0_update(sparx5);
1368}
1369
1370static void sparx5_vcap_es2_update(struct sparx5 *sparx5,
1371				   enum vcap_command cmd,
1372				   enum vcap_selection sel, u32 addr)
1373{
1374	bool clear = (cmd == VCAP_CMD_INITIALIZE);
1375
1376	spx5_wr(VCAP_ES2_CFG_MV_NUM_POS_SET(0) |
1377		VCAP_ES2_CFG_MV_SIZE_SET(0), sparx5, VCAP_ES2_CFG);
1378	spx5_wr(VCAP_ES2_CTRL_UPDATE_CMD_SET(cmd) |
1379		VCAP_ES2_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) |
1380		VCAP_ES2_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) |
1381		VCAP_ES2_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) |
1382		VCAP_ES2_CTRL_UPDATE_ADDR_SET(addr) |
1383		VCAP_ES2_CTRL_CLEAR_CACHE_SET(clear) |
1384		VCAP_ES2_CTRL_UPDATE_SHOT_SET(true),
1385		sparx5, VCAP_ES2_CTRL);
1386	sparx5_vcap_wait_es2_update(sparx5);
1387}
1388
1389/* API callback used for updating the VCAP cache */
1390static void sparx5_vcap_update(struct net_device *ndev,
1391			       struct vcap_admin *admin, enum vcap_command cmd,
1392			       enum vcap_selection sel, u32 addr)
1393{
1394	struct sparx5_port *port = netdev_priv(ndev);
1395	struct sparx5 *sparx5 = port->sparx5;
1396
1397	switch (admin->vtype) {
1398	case VCAP_TYPE_IS0:
1399	case VCAP_TYPE_IS2:
1400		sparx5_vcap_super_update(sparx5, cmd, sel, addr);
1401		break;
1402	case VCAP_TYPE_ES0:
1403		sparx5_vcap_es0_update(sparx5, cmd, sel, addr);
1404		break;
1405	case VCAP_TYPE_ES2:
1406		sparx5_vcap_es2_update(sparx5, cmd, sel, addr);
1407		break;
1408	default:
1409		sparx5_vcap_type_err(sparx5, admin, __func__);
1410		break;
1411	}
1412}
1413
1414static void sparx5_vcap_super_move(struct sparx5 *sparx5,
1415				   u32 addr,
1416				   enum vcap_command cmd,
1417				   u16 mv_num_pos,
1418				   u16 mv_size)
1419{
1420	spx5_wr(VCAP_SUPER_CFG_MV_NUM_POS_SET(mv_num_pos) |
1421		VCAP_SUPER_CFG_MV_SIZE_SET(mv_size),
1422		sparx5, VCAP_SUPER_CFG);
1423	spx5_wr(VCAP_SUPER_CTRL_UPDATE_CMD_SET(cmd) |
1424		VCAP_SUPER_CTRL_UPDATE_ENTRY_DIS_SET(0) |
1425		VCAP_SUPER_CTRL_UPDATE_ACTION_DIS_SET(0) |
1426		VCAP_SUPER_CTRL_UPDATE_CNT_DIS_SET(0) |
1427		VCAP_SUPER_CTRL_UPDATE_ADDR_SET(addr) |
1428		VCAP_SUPER_CTRL_CLEAR_CACHE_SET(false) |
1429		VCAP_SUPER_CTRL_UPDATE_SHOT_SET(true),
1430		sparx5, VCAP_SUPER_CTRL);
1431	sparx5_vcap_wait_super_update(sparx5);
1432}
1433
1434static void sparx5_vcap_es0_move(struct sparx5 *sparx5,
1435				 u32 addr,
1436				 enum vcap_command cmd,
1437				 u16 mv_num_pos,
1438				 u16 mv_size)
1439{
1440	spx5_wr(VCAP_ES0_CFG_MV_NUM_POS_SET(mv_num_pos) |
1441		VCAP_ES0_CFG_MV_SIZE_SET(mv_size),
1442		sparx5, VCAP_ES0_CFG);
1443	spx5_wr(VCAP_ES0_CTRL_UPDATE_CMD_SET(cmd) |
1444		VCAP_ES0_CTRL_UPDATE_ENTRY_DIS_SET(0) |
1445		VCAP_ES0_CTRL_UPDATE_ACTION_DIS_SET(0) |
1446		VCAP_ES0_CTRL_UPDATE_CNT_DIS_SET(0) |
1447		VCAP_ES0_CTRL_UPDATE_ADDR_SET(addr) |
1448		VCAP_ES0_CTRL_CLEAR_CACHE_SET(false) |
1449		VCAP_ES0_CTRL_UPDATE_SHOT_SET(true),
1450		sparx5, VCAP_ES0_CTRL);
1451	sparx5_vcap_wait_es0_update(sparx5);
1452}
1453
1454static void sparx5_vcap_es2_move(struct sparx5 *sparx5,
1455				 u32 addr,
1456				 enum vcap_command cmd,
1457				 u16 mv_num_pos,
1458				 u16 mv_size)
1459{
1460	spx5_wr(VCAP_ES2_CFG_MV_NUM_POS_SET(mv_num_pos) |
1461		VCAP_ES2_CFG_MV_SIZE_SET(mv_size),
1462		sparx5, VCAP_ES2_CFG);
1463	spx5_wr(VCAP_ES2_CTRL_UPDATE_CMD_SET(cmd) |
1464		VCAP_ES2_CTRL_UPDATE_ENTRY_DIS_SET(0) |
1465		VCAP_ES2_CTRL_UPDATE_ACTION_DIS_SET(0) |
1466		VCAP_ES2_CTRL_UPDATE_CNT_DIS_SET(0) |
1467		VCAP_ES2_CTRL_UPDATE_ADDR_SET(addr) |
1468		VCAP_ES2_CTRL_CLEAR_CACHE_SET(false) |
1469		VCAP_ES2_CTRL_UPDATE_SHOT_SET(true),
1470		sparx5, VCAP_ES2_CTRL);
1471	sparx5_vcap_wait_es2_update(sparx5);
1472}
1473
1474/* API callback used for moving a block of rules in the VCAP */
1475static void sparx5_vcap_move(struct net_device *ndev, struct vcap_admin *admin,
1476			     u32 addr, int offset, int count)
1477{
1478	struct sparx5_port *port = netdev_priv(ndev);
1479	struct sparx5 *sparx5 = port->sparx5;
1480	enum vcap_command cmd;
1481	u16 mv_num_pos;
1482	u16 mv_size;
1483
1484	mv_size = count - 1;
1485	if (offset > 0) {
1486		mv_num_pos = offset - 1;
1487		cmd = VCAP_CMD_MOVE_DOWN;
1488	} else {
1489		mv_num_pos = -offset - 1;
1490		cmd = VCAP_CMD_MOVE_UP;
1491	}
1492
1493	switch (admin->vtype) {
1494	case VCAP_TYPE_IS0:
1495	case VCAP_TYPE_IS2:
1496		sparx5_vcap_super_move(sparx5, addr, cmd, mv_num_pos, mv_size);
1497		break;
1498	case VCAP_TYPE_ES0:
1499		sparx5_vcap_es0_move(sparx5, addr, cmd, mv_num_pos, mv_size);
1500		break;
1501	case VCAP_TYPE_ES2:
1502		sparx5_vcap_es2_move(sparx5, addr, cmd, mv_num_pos, mv_size);
1503		break;
1504	default:
1505		sparx5_vcap_type_err(sparx5, admin, __func__);
1506		break;
1507	}
1508}
1509
1510static struct vcap_operations sparx5_vcap_ops = {
1511	.validate_keyset = sparx5_vcap_validate_keyset,
1512	.add_default_fields = sparx5_vcap_add_default_fields,
1513	.cache_erase = sparx5_vcap_cache_erase,
1514	.cache_write = sparx5_vcap_cache_write,
1515	.cache_read = sparx5_vcap_cache_read,
1516	.init = sparx5_vcap_range_init,
1517	.update = sparx5_vcap_update,
1518	.move = sparx5_vcap_move,
1519	.port_info = sparx5_port_info,
1520};
1521
1522static u32 sparx5_vcap_is0_keyset_to_etype_ps(enum vcap_keyfield_set keyset)
1523{
1524	switch (keyset) {
1525	case VCAP_KFS_NORMAL_7TUPLE:
1526		return VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE;
1527	case VCAP_KFS_NORMAL_5TUPLE_IP4:
1528		return VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4;
1529	default:
1530		return VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE;
1531	}
1532}
1533
1534static void sparx5_vcap_is0_set_port_keyset(struct net_device *ndev, int lookup,
1535					    enum vcap_keyfield_set keyset,
1536					    int l3_proto)
1537{
1538	struct sparx5_port *port = netdev_priv(ndev);
1539	struct sparx5 *sparx5 = port->sparx5;
1540	int portno = port->portno;
1541	u32 value;
1542
1543	switch (l3_proto) {
1544	case ETH_P_IP:
1545		value = sparx5_vcap_is0_keyset_to_etype_ps(keyset);
1546		spx5_rmw(ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL_SET(value),
1547			 ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL,
1548			 sparx5,
1549			 ANA_CL_ADV_CL_CFG(portno, lookup));
1550		break;
1551	case ETH_P_IPV6:
1552		value = sparx5_vcap_is0_keyset_to_etype_ps(keyset);
1553		spx5_rmw(ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL_SET(value),
1554			 ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL,
1555			 sparx5,
1556			 ANA_CL_ADV_CL_CFG(portno, lookup));
1557		break;
1558	default:
1559		value = sparx5_vcap_is0_keyset_to_etype_ps(keyset);
1560		spx5_rmw(ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL_SET(value),
1561			 ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL,
1562			 sparx5,
1563			 ANA_CL_ADV_CL_CFG(portno, lookup));
1564		break;
1565	}
1566}
1567
1568static u32 sparx5_vcap_is2_keyset_to_arp_ps(enum vcap_keyfield_set keyset)
1569{
1570	switch (keyset) {
1571	case VCAP_KFS_ARP:
1572		return VCAP_IS2_PS_ARP_ARP;
1573	default:
1574		return VCAP_IS2_PS_ARP_MAC_ETYPE;
1575	}
1576}
1577
1578static u32 sparx5_vcap_is2_keyset_to_ipv4_ps(enum vcap_keyfield_set keyset)
1579{
1580	switch (keyset) {
1581	case VCAP_KFS_MAC_ETYPE:
1582		return VCAP_IS2_PS_IPV4_UC_MAC_ETYPE;
1583	case VCAP_KFS_IP4_OTHER:
1584	case VCAP_KFS_IP4_TCP_UDP:
1585		return VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER;
1586	case VCAP_KFS_IP_7TUPLE:
1587		return VCAP_IS2_PS_IPV4_UC_IP_7TUPLE;
1588	default:
1589		return VCAP_KFS_NO_VALUE;
1590	}
1591}
1592
1593static u32 sparx5_vcap_is2_keyset_to_ipv6_uc_ps(enum vcap_keyfield_set keyset)
1594{
1595	switch (keyset) {
1596	case VCAP_KFS_MAC_ETYPE:
1597		return VCAP_IS2_PS_IPV6_UC_MAC_ETYPE;
1598	case VCAP_KFS_IP4_OTHER:
1599	case VCAP_KFS_IP4_TCP_UDP:
1600		return VCAP_IS2_PS_IPV6_UC_IP4_TCP_UDP_OTHER;
1601	case VCAP_KFS_IP_7TUPLE:
1602		return VCAP_IS2_PS_IPV6_UC_IP_7TUPLE;
1603	default:
1604		return VCAP_KFS_NO_VALUE;
1605	}
1606}
1607
1608static u32 sparx5_vcap_is2_keyset_to_ipv6_mc_ps(enum vcap_keyfield_set keyset)
1609{
1610	switch (keyset) {
1611	case VCAP_KFS_MAC_ETYPE:
1612		return VCAP_IS2_PS_IPV6_MC_MAC_ETYPE;
1613	case VCAP_KFS_IP4_OTHER:
1614	case VCAP_KFS_IP4_TCP_UDP:
1615		return VCAP_IS2_PS_IPV6_MC_IP4_TCP_UDP_OTHER;
1616	case VCAP_KFS_IP_7TUPLE:
1617		return VCAP_IS2_PS_IPV6_MC_IP_7TUPLE;
1618	default:
1619		return VCAP_KFS_NO_VALUE;
1620	}
1621}
1622
1623static void sparx5_vcap_is2_set_port_keyset(struct net_device *ndev, int lookup,
1624					    enum vcap_keyfield_set keyset,
1625					    int l3_proto)
1626{
1627	struct sparx5_port *port = netdev_priv(ndev);
1628	struct sparx5 *sparx5 = port->sparx5;
1629	int portno = port->portno;
1630	u32 value;
1631
1632	switch (l3_proto) {
1633	case ETH_P_ARP:
1634		value = sparx5_vcap_is2_keyset_to_arp_ps(keyset);
1635		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL_SET(value),
1636			 ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL,
1637			 sparx5,
1638			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1639		break;
1640	case ETH_P_IP:
1641		value = sparx5_vcap_is2_keyset_to_ipv4_ps(keyset);
1642		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL_SET(value),
1643			 ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL,
1644			 sparx5,
1645			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1646		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL_SET(value),
1647			 ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL,
1648			 sparx5,
1649			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1650		break;
1651	case ETH_P_IPV6:
1652		value = sparx5_vcap_is2_keyset_to_ipv6_uc_ps(keyset);
1653		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL_SET(value),
1654			 ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL,
1655			 sparx5,
1656			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1657		value = sparx5_vcap_is2_keyset_to_ipv6_mc_ps(keyset);
1658		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL_SET(value),
1659			 ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL,
1660			 sparx5,
1661			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1662		break;
1663	default:
1664		value = VCAP_IS2_PS_NONETH_MAC_ETYPE;
1665		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL_SET(value),
1666			 ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL,
1667			 sparx5,
1668			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1669		break;
1670	}
1671}
1672
1673static u32 sparx5_vcap_es2_keyset_to_arp_ps(enum vcap_keyfield_set keyset)
1674{
1675	switch (keyset) {
1676	case VCAP_KFS_ARP:
1677		return VCAP_ES2_PS_ARP_ARP;
1678	default:
1679		return VCAP_ES2_PS_ARP_MAC_ETYPE;
1680	}
1681}
1682
1683static u32 sparx5_vcap_es2_keyset_to_ipv4_ps(enum vcap_keyfield_set keyset)
1684{
1685	switch (keyset) {
1686	case VCAP_KFS_MAC_ETYPE:
1687		return VCAP_ES2_PS_IPV4_MAC_ETYPE;
1688	case VCAP_KFS_IP_7TUPLE:
1689		return VCAP_ES2_PS_IPV4_IP_7TUPLE;
1690	case VCAP_KFS_IP4_TCP_UDP:
1691		return VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER;
1692	case VCAP_KFS_IP4_OTHER:
1693		return VCAP_ES2_PS_IPV4_IP4_OTHER;
1694	default:
1695		return VCAP_ES2_PS_IPV4_MAC_ETYPE;
1696	}
1697}
1698
1699static u32 sparx5_vcap_es2_keyset_to_ipv6_ps(enum vcap_keyfield_set keyset)
1700{
1701	switch (keyset) {
1702	case VCAP_KFS_MAC_ETYPE:
1703		return VCAP_ES2_PS_IPV6_MAC_ETYPE;
1704	case VCAP_KFS_IP4_TCP_UDP:
1705	case VCAP_KFS_IP4_OTHER:
1706		return VCAP_ES2_PS_IPV6_IP4_DOWNGRADE;
1707	case VCAP_KFS_IP_7TUPLE:
1708		return VCAP_ES2_PS_IPV6_IP_7TUPLE;
1709	case VCAP_KFS_IP6_STD:
1710		return VCAP_ES2_PS_IPV6_IP6_STD;
1711	default:
1712		return VCAP_ES2_PS_IPV6_MAC_ETYPE;
1713	}
1714}
1715
1716static void sparx5_vcap_es2_set_port_keyset(struct net_device *ndev, int lookup,
1717					    enum vcap_keyfield_set keyset,
1718					    int l3_proto)
1719{
1720	struct sparx5_port *port = netdev_priv(ndev);
1721	struct sparx5 *sparx5 = port->sparx5;
1722	int portno = port->portno;
1723	u32 value;
1724
1725	switch (l3_proto) {
1726	case ETH_P_IP:
1727		value = sparx5_vcap_es2_keyset_to_ipv4_ps(keyset);
1728		spx5_rmw(EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL_SET(value),
1729			 EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL,
1730			 sparx5,
1731			 EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1732		break;
1733	case ETH_P_IPV6:
1734		value = sparx5_vcap_es2_keyset_to_ipv6_ps(keyset);
1735		spx5_rmw(EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL_SET(value),
1736			 EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL,
1737			 sparx5,
1738			 EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1739		break;
1740	case ETH_P_ARP:
1741		value = sparx5_vcap_es2_keyset_to_arp_ps(keyset);
1742		spx5_rmw(EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL_SET(value),
1743			 EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL,
1744			 sparx5,
1745			 EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1746		break;
1747	}
1748}
1749
1750/* Change the port keyset for the lookup and protocol */
1751void sparx5_vcap_set_port_keyset(struct net_device *ndev,
1752				 struct vcap_admin *admin,
1753				 int cid,
1754				 u16 l3_proto,
1755				 enum vcap_keyfield_set keyset,
1756				 struct vcap_keyset_list *orig)
1757{
1758	struct sparx5_port *port;
1759	int lookup;
1760
1761	switch (admin->vtype) {
1762	case VCAP_TYPE_IS0:
1763		lookup = sparx5_vcap_is0_cid_to_lookup(cid);
1764		if (orig)
1765			sparx5_vcap_is0_get_port_keysets(ndev, lookup, orig,
1766							 l3_proto);
1767		sparx5_vcap_is0_set_port_keyset(ndev, lookup, keyset, l3_proto);
1768		break;
1769	case VCAP_TYPE_IS2:
1770		lookup = sparx5_vcap_is2_cid_to_lookup(cid);
1771		if (orig)
1772			sparx5_vcap_is2_get_port_keysets(ndev, lookup, orig,
1773							 l3_proto);
1774		sparx5_vcap_is2_set_port_keyset(ndev, lookup, keyset, l3_proto);
1775		break;
1776	case VCAP_TYPE_ES0:
1777		break;
1778	case VCAP_TYPE_ES2:
1779		lookup = sparx5_vcap_es2_cid_to_lookup(cid);
1780		if (orig)
1781			sparx5_vcap_es2_get_port_keysets(ndev, lookup, orig,
1782							 l3_proto);
1783		sparx5_vcap_es2_set_port_keyset(ndev, lookup, keyset, l3_proto);
1784		break;
1785	default:
1786		port = netdev_priv(ndev);
1787		sparx5_vcap_type_err(port->sparx5, admin, __func__);
1788		break;
1789	}
1790}
1791
1792/* Enable IS0 lookups per port and set the keyset generation */
1793static void sparx5_vcap_is0_port_key_selection(struct sparx5 *sparx5,
1794					       struct vcap_admin *admin)
1795{
1796	int portno, lookup;
1797	u32 keysel;
1798
1799	keysel = VCAP_IS0_KEYSEL(false,
1800				 VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE,
1801				 VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4,
1802				 VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE,
1803				 VCAP_IS0_PS_MPLS_FOLLOW_ETYPE,
1804				 VCAP_IS0_PS_MPLS_FOLLOW_ETYPE,
1805				 VCAP_IS0_PS_MLBS_FOLLOW_ETYPE);
1806	for (lookup = 0; lookup < admin->lookups; ++lookup) {
1807		for (portno = 0; portno < SPX5_PORTS; ++portno) {
1808			spx5_wr(keysel, sparx5,
1809				ANA_CL_ADV_CL_CFG(portno, lookup));
1810			spx5_rmw(ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1811				 ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1812				 sparx5,
1813				 ANA_CL_ADV_CL_CFG(portno, lookup));
1814		}
1815	}
1816}
1817
1818/* Enable IS2 lookups per port and set the keyset generation */
1819static void sparx5_vcap_is2_port_key_selection(struct sparx5 *sparx5,
1820					       struct vcap_admin *admin)
1821{
1822	int portno, lookup;
1823	u32 keysel;
1824
1825	keysel = VCAP_IS2_KEYSEL(true, VCAP_IS2_PS_NONETH_MAC_ETYPE,
1826				 VCAP_IS2_PS_IPV4_MC_IP4_TCP_UDP_OTHER,
1827				 VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER,
1828				 VCAP_IS2_PS_IPV6_MC_IP_7TUPLE,
1829				 VCAP_IS2_PS_IPV6_UC_IP_7TUPLE,
1830				 VCAP_IS2_PS_ARP_ARP);
1831	for (lookup = 0; lookup < admin->lookups; ++lookup) {
1832		for (portno = 0; portno < SPX5_PORTS; ++portno) {
1833			spx5_wr(keysel, sparx5,
1834				ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1835		}
1836	}
1837	/* IS2 lookups are in bit 0:3 */
1838	for (portno = 0; portno < SPX5_PORTS; ++portno)
1839		spx5_rmw(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0xf),
1840			 ANA_ACL_VCAP_S2_CFG_SEC_ENA,
1841			 sparx5,
1842			 ANA_ACL_VCAP_S2_CFG(portno));
1843}
1844
1845/* Enable ES0 lookups per port and set the keyset generation */
1846static void sparx5_vcap_es0_port_key_selection(struct sparx5 *sparx5,
1847					       struct vcap_admin *admin)
1848{
1849	int portno;
1850	u32 keysel;
1851
1852	keysel = VCAP_ES0_KEYSEL(VCAP_ES0_PS_FORCE_ISDX_LOOKUPS);
1853	for (portno = 0; portno < SPX5_PORTS; ++portno)
1854		spx5_rmw(keysel, REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA,
1855			 sparx5, REW_RTAG_ETAG_CTRL(portno));
1856
1857	spx5_rmw(REW_ES0_CTRL_ES0_LU_ENA_SET(1), REW_ES0_CTRL_ES0_LU_ENA,
1858		 sparx5, REW_ES0_CTRL);
1859}
1860
1861/* Enable ES2 lookups per port and set the keyset generation */
1862static void sparx5_vcap_es2_port_key_selection(struct sparx5 *sparx5,
1863					       struct vcap_admin *admin)
1864{
1865	int portno, lookup;
1866	u32 keysel;
1867
1868	keysel = VCAP_ES2_KEYSEL(true, VCAP_ES2_PS_ARP_MAC_ETYPE,
1869				 VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER,
1870				 VCAP_ES2_PS_IPV6_IP_7TUPLE);
1871	for (lookup = 0; lookup < admin->lookups; ++lookup)
1872		for (portno = 0; portno < SPX5_PORTS; ++portno)
1873			spx5_wr(keysel, sparx5,
1874				EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1875}
1876
1877/* Enable lookups per port and set the keyset generation */
1878static void sparx5_vcap_port_key_selection(struct sparx5 *sparx5,
1879					   struct vcap_admin *admin)
1880{
1881	switch (admin->vtype) {
1882	case VCAP_TYPE_IS0:
1883		sparx5_vcap_is0_port_key_selection(sparx5, admin);
1884		break;
1885	case VCAP_TYPE_IS2:
1886		sparx5_vcap_is2_port_key_selection(sparx5, admin);
1887		break;
1888	case VCAP_TYPE_ES0:
1889		sparx5_vcap_es0_port_key_selection(sparx5, admin);
1890		break;
1891	case VCAP_TYPE_ES2:
1892		sparx5_vcap_es2_port_key_selection(sparx5, admin);
1893		break;
1894	default:
1895		sparx5_vcap_type_err(sparx5, admin, __func__);
1896		break;
1897	}
1898}
1899
1900/* Disable lookups per port */
1901static void sparx5_vcap_port_key_deselection(struct sparx5 *sparx5,
1902					     struct vcap_admin *admin)
1903{
1904	int portno, lookup;
1905
1906	switch (admin->vtype) {
1907	case VCAP_TYPE_IS0:
1908		for (lookup = 0; lookup < admin->lookups; ++lookup)
1909			for (portno = 0; portno < SPX5_PORTS; ++portno)
1910				spx5_rmw(ANA_CL_ADV_CL_CFG_LOOKUP_ENA_SET(0),
1911					 ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1912					 sparx5,
1913					 ANA_CL_ADV_CL_CFG(portno, lookup));
1914		break;
1915	case VCAP_TYPE_IS2:
1916		for (portno = 0; portno < SPX5_PORTS; ++portno)
1917			spx5_rmw(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0),
1918				 ANA_ACL_VCAP_S2_CFG_SEC_ENA,
1919				 sparx5,
1920				 ANA_ACL_VCAP_S2_CFG(portno));
1921		break;
1922	case VCAP_TYPE_ES0:
1923		spx5_rmw(REW_ES0_CTRL_ES0_LU_ENA_SET(0),
1924			 REW_ES0_CTRL_ES0_LU_ENA, sparx5, REW_ES0_CTRL);
1925		break;
1926	case VCAP_TYPE_ES2:
1927		for (lookup = 0; lookup < admin->lookups; ++lookup)
1928			for (portno = 0; portno < SPX5_PORTS; ++portno)
1929				spx5_rmw(EACL_VCAP_ES2_KEY_SEL_KEY_ENA_SET(0),
1930					 EACL_VCAP_ES2_KEY_SEL_KEY_ENA,
1931					 sparx5,
1932					 EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1933		break;
1934	default:
1935		sparx5_vcap_type_err(sparx5, admin, __func__);
1936		break;
1937	}
1938}
1939
1940static void sparx5_vcap_admin_free(struct vcap_admin *admin)
1941{
1942	if (!admin)
1943		return;
1944	mutex_destroy(&admin->lock);
1945	kfree(admin->cache.keystream);
1946	kfree(admin->cache.maskstream);
1947	kfree(admin->cache.actionstream);
1948	kfree(admin);
1949}
1950
1951/* Allocate a vcap instance with a rule list and a cache area */
1952static struct vcap_admin *
1953sparx5_vcap_admin_alloc(struct sparx5 *sparx5, struct vcap_control *ctrl,
1954			const struct sparx5_vcap_inst *cfg)
1955{
1956	struct vcap_admin *admin;
1957
1958	admin = kzalloc(sizeof(*admin), GFP_KERNEL);
1959	if (!admin)
1960		return ERR_PTR(-ENOMEM);
1961	INIT_LIST_HEAD(&admin->list);
1962	INIT_LIST_HEAD(&admin->rules);
1963	INIT_LIST_HEAD(&admin->enabled);
1964	mutex_init(&admin->lock);
1965	admin->vtype = cfg->vtype;
1966	admin->vinst = cfg->vinst;
1967	admin->ingress = cfg->ingress;
1968	admin->lookups = cfg->lookups;
1969	admin->lookups_per_instance = cfg->lookups_per_instance;
1970	admin->first_cid = cfg->first_cid;
1971	admin->last_cid = cfg->last_cid;
1972	admin->cache.keystream =
1973		kzalloc(STREAMSIZE, GFP_KERNEL);
1974	admin->cache.maskstream =
1975		kzalloc(STREAMSIZE, GFP_KERNEL);
1976	admin->cache.actionstream =
1977		kzalloc(STREAMSIZE, GFP_KERNEL);
1978	if (!admin->cache.keystream || !admin->cache.maskstream ||
1979	    !admin->cache.actionstream) {
1980		sparx5_vcap_admin_free(admin);
1981		return ERR_PTR(-ENOMEM);
1982	}
1983	return admin;
1984}
1985
1986/* Do block allocations and provide addresses for VCAP instances */
1987static void sparx5_vcap_block_alloc(struct sparx5 *sparx5,
1988				    struct vcap_admin *admin,
1989				    const struct sparx5_vcap_inst *cfg)
1990{
1991	int idx, cores;
1992
1993	switch (admin->vtype) {
1994	case VCAP_TYPE_IS0:
1995	case VCAP_TYPE_IS2:
1996		/* Super VCAP block mapping and address configuration. Block 0
1997		 * is assigned addresses 0 through 3071, block 1 is assigned
1998		 * addresses 3072 though 6143, and so on.
1999		 */
2000		for (idx = cfg->blockno; idx < cfg->blockno + cfg->blocks;
2001		     ++idx) {
2002			spx5_wr(VCAP_SUPER_IDX_CORE_IDX_SET(idx), sparx5,
2003				VCAP_SUPER_IDX);
2004			spx5_wr(VCAP_SUPER_MAP_CORE_MAP_SET(cfg->map_id),
2005				sparx5, VCAP_SUPER_MAP);
2006		}
2007		admin->first_valid_addr = cfg->blockno * SUPER_VCAP_BLK_SIZE;
2008		admin->last_used_addr = admin->first_valid_addr +
2009			cfg->blocks * SUPER_VCAP_BLK_SIZE;
2010		admin->last_valid_addr = admin->last_used_addr - 1;
2011		break;
2012	case VCAP_TYPE_ES0:
2013		admin->first_valid_addr = 0;
2014		admin->last_used_addr = cfg->count;
2015		admin->last_valid_addr = cfg->count - 1;
2016		cores = spx5_rd(sparx5, VCAP_ES0_CORE_CNT);
2017		for (idx = 0; idx < cores; ++idx) {
2018			spx5_wr(VCAP_ES0_IDX_CORE_IDX_SET(idx), sparx5,
2019				VCAP_ES0_IDX);
2020			spx5_wr(VCAP_ES0_MAP_CORE_MAP_SET(1), sparx5,
2021				VCAP_ES0_MAP);
2022		}
2023		break;
2024	case VCAP_TYPE_ES2:
2025		admin->first_valid_addr = 0;
2026		admin->last_used_addr = cfg->count;
2027		admin->last_valid_addr = cfg->count - 1;
2028		cores = spx5_rd(sparx5, VCAP_ES2_CORE_CNT);
2029		for (idx = 0; idx < cores; ++idx) {
2030			spx5_wr(VCAP_ES2_IDX_CORE_IDX_SET(idx), sparx5,
2031				VCAP_ES2_IDX);
2032			spx5_wr(VCAP_ES2_MAP_CORE_MAP_SET(1), sparx5,
2033				VCAP_ES2_MAP);
2034		}
2035		break;
2036	default:
2037		sparx5_vcap_type_err(sparx5, admin, __func__);
2038		break;
2039	}
2040}
2041
2042/* Allocate a vcap control and vcap instances and configure the system */
2043int sparx5_vcap_init(struct sparx5 *sparx5)
2044{
2045	const struct sparx5_vcap_inst *cfg;
2046	struct vcap_control *ctrl;
2047	struct vcap_admin *admin;
2048	struct dentry *dir;
2049	int err = 0, idx;
2050
2051	/* Create a VCAP control instance that owns the platform specific VCAP
2052	 * model with VCAP instances and information about keysets, keys,
2053	 * actionsets and actions
2054	 * - Create administrative state for each available VCAP
2055	 *   - Lists of rules
2056	 *   - Address information
2057	 *   - Initialize VCAP blocks
2058	 *   - Configure port keysets
2059	 */
2060	ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
2061	if (!ctrl)
2062		return -ENOMEM;
2063
2064	sparx5->vcap_ctrl = ctrl;
2065	/* select the sparx5 VCAP model */
2066	ctrl->vcaps = sparx5_vcaps;
2067	ctrl->stats = &sparx5_vcap_stats;
2068	/* Setup callbacks to allow the API to use the VCAP HW */
2069	ctrl->ops = &sparx5_vcap_ops;
2070
2071	INIT_LIST_HEAD(&ctrl->list);
2072	for (idx = 0; idx < ARRAY_SIZE(sparx5_vcap_inst_cfg); ++idx) {
2073		cfg = &sparx5_vcap_inst_cfg[idx];
2074		admin = sparx5_vcap_admin_alloc(sparx5, ctrl, cfg);
2075		if (IS_ERR(admin)) {
2076			err = PTR_ERR(admin);
2077			pr_err("%s:%d: vcap allocation failed: %d\n",
2078			       __func__, __LINE__, err);
2079			return err;
2080		}
2081		sparx5_vcap_block_alloc(sparx5, admin, cfg);
2082		sparx5_vcap_block_init(sparx5, admin);
2083		if (cfg->vinst == 0)
2084			sparx5_vcap_port_key_selection(sparx5, admin);
2085		list_add_tail(&admin->list, &ctrl->list);
2086	}
2087	dir = vcap_debugfs(sparx5->dev, sparx5->debugfs_root, ctrl);
2088	for (idx = 0; idx < SPX5_PORTS; ++idx)
2089		if (sparx5->ports[idx])
2090			vcap_port_debugfs(sparx5->dev, dir, ctrl,
2091					  sparx5->ports[idx]->ndev);
2092
2093	return err;
2094}
2095
2096void sparx5_vcap_destroy(struct sparx5 *sparx5)
2097{
2098	struct vcap_control *ctrl = sparx5->vcap_ctrl;
2099	struct vcap_admin *admin, *admin_next;
2100
2101	if (!ctrl)
2102		return;
2103
2104	list_for_each_entry_safe(admin, admin_next, &ctrl->list, list) {
2105		sparx5_vcap_port_key_deselection(sparx5, admin);
2106		vcap_del_rules(ctrl, admin);
2107		list_del(&admin->list);
2108		sparx5_vcap_admin_free(admin);
2109	}
2110	kfree(ctrl);
2111}
v6.9.4
   1// SPDX-License-Identifier: GPL-2.0+
   2/* Microchip Sparx5 Switch driver VCAP implementation
   3 *
   4 * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries.
   5 *
   6 * The Sparx5 Chip Register Model can be browsed at this location:
   7 * https://github.com/microchip-ung/sparx-5_reginfo
   8 */
   9
  10#include "vcap_api_debugfs.h"
  11#include "sparx5_main_regs.h"
  12#include "sparx5_main.h"
  13#include "sparx5_vcap_impl.h"
  14#include "sparx5_vcap_ag_api.h"
  15#include "sparx5_vcap_debugfs.h"
  16
  17#define SUPER_VCAP_BLK_SIZE 3072 /* addresses per Super VCAP block */
  18#define STREAMSIZE (64 * 4)  /* bytes in the VCAP cache area */
  19
  20#define SPARX5_IS2_LOOKUPS 4
  21#define VCAP_IS2_KEYSEL(_ena, _noneth, _v4_mc, _v4_uc, _v6_mc, _v6_uc, _arp) \
  22	(ANA_ACL_VCAP_S2_KEY_SEL_KEY_SEL_ENA_SET(_ena) | \
  23	 ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL_SET(_noneth) | \
  24	 ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL_SET(_v4_mc) | \
  25	 ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL_SET(_v4_uc) | \
  26	 ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL_SET(_v6_mc) | \
  27	 ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL_SET(_v6_uc) | \
  28	 ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL_SET(_arp))
  29
  30#define SPARX5_IS0_LOOKUPS 6
  31#define VCAP_IS0_KEYSEL(_ena, _etype, _ipv4, _ipv6, _mpls_uc, _mpls_mc, _mlbs) \
  32	(ANA_CL_ADV_CL_CFG_LOOKUP_ENA_SET(_ena) | \
  33	ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL_SET(_etype) | \
  34	ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL_SET(_ipv4) | \
  35	ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL_SET(_ipv6) | \
  36	ANA_CL_ADV_CL_CFG_MPLS_UC_CLM_KEY_SEL_SET(_mpls_uc) | \
  37	ANA_CL_ADV_CL_CFG_MPLS_MC_CLM_KEY_SEL_SET(_mpls_mc) | \
  38	ANA_CL_ADV_CL_CFG_MLBS_CLM_KEY_SEL_SET(_mlbs))
  39
  40#define SPARX5_ES0_LOOKUPS 1
  41#define VCAP_ES0_KEYSEL(_key) (REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA_SET(_key))
  42#define SPARX5_STAT_ESDX_GRN_PKTS  0x300
  43#define SPARX5_STAT_ESDX_YEL_PKTS  0x301
  44
  45#define SPARX5_ES2_LOOKUPS 2
  46#define VCAP_ES2_KEYSEL(_ena, _arp, _ipv4, _ipv6) \
  47	(EACL_VCAP_ES2_KEY_SEL_KEY_ENA_SET(_ena) | \
  48	EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL_SET(_arp) | \
  49	EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL_SET(_ipv4) | \
  50	EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL_SET(_ipv6))
  51
  52static struct sparx5_vcap_inst {
  53	enum vcap_type vtype; /* type of vcap */
  54	int vinst; /* instance number within the same type */
  55	int lookups; /* number of lookups in this vcap type */
  56	int lookups_per_instance; /* number of lookups in this instance */
  57	int first_cid; /* first chain id in this vcap */
  58	int last_cid; /* last chain id in this vcap */
  59	int count; /* number of available addresses, not in super vcap */
  60	int map_id; /* id in the super vcap block mapping (if applicable) */
  61	int blockno; /* starting block in super vcap (if applicable) */
  62	int blocks; /* number of blocks in super vcap (if applicable) */
  63	bool ingress; /* is vcap in the ingress path */
  64} sparx5_vcap_inst_cfg[] = {
  65	{
  66		.vtype = VCAP_TYPE_IS0, /* CLM-0 */
  67		.vinst = 0,
  68		.map_id = 1,
  69		.lookups = SPARX5_IS0_LOOKUPS,
  70		.lookups_per_instance = SPARX5_IS0_LOOKUPS / 3,
  71		.first_cid = SPARX5_VCAP_CID_IS0_L0,
  72		.last_cid = SPARX5_VCAP_CID_IS0_L2 - 1,
  73		.blockno = 8, /* Maps block 8-9 */
  74		.blocks = 2,
  75		.ingress = true,
  76	},
  77	{
  78		.vtype = VCAP_TYPE_IS0, /* CLM-1 */
  79		.vinst = 1,
  80		.map_id = 2,
  81		.lookups = SPARX5_IS0_LOOKUPS,
  82		.lookups_per_instance = SPARX5_IS0_LOOKUPS / 3,
  83		.first_cid = SPARX5_VCAP_CID_IS0_L2,
  84		.last_cid = SPARX5_VCAP_CID_IS0_L4 - 1,
  85		.blockno = 6, /* Maps block 6-7 */
  86		.blocks = 2,
  87		.ingress = true,
  88	},
  89	{
  90		.vtype = VCAP_TYPE_IS0, /* CLM-2 */
  91		.vinst = 2,
  92		.map_id = 3,
  93		.lookups = SPARX5_IS0_LOOKUPS,
  94		.lookups_per_instance = SPARX5_IS0_LOOKUPS / 3,
  95		.first_cid = SPARX5_VCAP_CID_IS0_L4,
  96		.last_cid = SPARX5_VCAP_CID_IS0_MAX,
  97		.blockno = 4, /* Maps block 4-5 */
  98		.blocks = 2,
  99		.ingress = true,
 100	},
 101	{
 102		.vtype = VCAP_TYPE_IS2, /* IS2-0 */
 103		.vinst = 0,
 104		.map_id = 4,
 105		.lookups = SPARX5_IS2_LOOKUPS,
 106		.lookups_per_instance = SPARX5_IS2_LOOKUPS / 2,
 107		.first_cid = SPARX5_VCAP_CID_IS2_L0,
 108		.last_cid = SPARX5_VCAP_CID_IS2_L2 - 1,
 109		.blockno = 0, /* Maps block 0-1 */
 110		.blocks = 2,
 111		.ingress = true,
 112	},
 113	{
 114		.vtype = VCAP_TYPE_IS2, /* IS2-1 */
 115		.vinst = 1,
 116		.map_id = 5,
 117		.lookups = SPARX5_IS2_LOOKUPS,
 118		.lookups_per_instance = SPARX5_IS2_LOOKUPS / 2,
 119		.first_cid = SPARX5_VCAP_CID_IS2_L2,
 120		.last_cid = SPARX5_VCAP_CID_IS2_MAX,
 121		.blockno = 2, /* Maps block 2-3 */
 122		.blocks = 2,
 123		.ingress = true,
 124	},
 125	{
 126		.vtype = VCAP_TYPE_ES0,
 127		.lookups = SPARX5_ES0_LOOKUPS,
 128		.lookups_per_instance = SPARX5_ES0_LOOKUPS,
 129		.first_cid = SPARX5_VCAP_CID_ES0_L0,
 130		.last_cid = SPARX5_VCAP_CID_ES0_MAX,
 131		.count = 4096, /* Addresses according to datasheet */
 132		.ingress = false,
 133	},
 134	{
 135		.vtype = VCAP_TYPE_ES2,
 136		.lookups = SPARX5_ES2_LOOKUPS,
 137		.lookups_per_instance = SPARX5_ES2_LOOKUPS,
 138		.first_cid = SPARX5_VCAP_CID_ES2_L0,
 139		.last_cid = SPARX5_VCAP_CID_ES2_MAX,
 140		.count = 12288, /* Addresses according to datasheet */
 141		.ingress = false,
 142	},
 143};
 144
 145/* These protocols have dedicated keysets in IS0 and a TC dissector */
 146static u16 sparx5_vcap_is0_known_etypes[] = {
 147	ETH_P_ALL,
 148	ETH_P_IP,
 149	ETH_P_IPV6,
 150};
 151
 152/* These protocols have dedicated keysets in IS2 and a TC dissector */
 153static u16 sparx5_vcap_is2_known_etypes[] = {
 154	ETH_P_ALL,
 155	ETH_P_ARP,
 156	ETH_P_IP,
 157	ETH_P_IPV6,
 158};
 159
 160/* These protocols have dedicated keysets in ES2 and a TC dissector */
 161static u16 sparx5_vcap_es2_known_etypes[] = {
 162	ETH_P_ALL,
 163	ETH_P_ARP,
 164	ETH_P_IP,
 165	ETH_P_IPV6,
 166};
 167
 168static void sparx5_vcap_type_err(struct sparx5 *sparx5,
 169				 struct vcap_admin *admin,
 170				 const char *fname)
 171{
 172	pr_err("%s: vcap type: %s not supported\n",
 173	       fname, sparx5_vcaps[admin->vtype].name);
 174}
 175
 176/* Await the super VCAP completion of the current operation */
 177static void sparx5_vcap_wait_super_update(struct sparx5 *sparx5)
 178{
 179	u32 value;
 180
 181	read_poll_timeout(spx5_rd, value,
 182			  !VCAP_SUPER_CTRL_UPDATE_SHOT_GET(value), 500, 10000,
 183			  false, sparx5, VCAP_SUPER_CTRL);
 184}
 185
 186/* Await the ES0 VCAP completion of the current operation */
 187static void sparx5_vcap_wait_es0_update(struct sparx5 *sparx5)
 188{
 189	u32 value;
 190
 191	read_poll_timeout(spx5_rd, value,
 192			  !VCAP_ES0_CTRL_UPDATE_SHOT_GET(value), 500, 10000,
 193			  false, sparx5, VCAP_ES0_CTRL);
 194}
 195
 196/* Await the ES2 VCAP completion of the current operation */
 197static void sparx5_vcap_wait_es2_update(struct sparx5 *sparx5)
 198{
 199	u32 value;
 200
 201	read_poll_timeout(spx5_rd, value,
 202			  !VCAP_ES2_CTRL_UPDATE_SHOT_GET(value), 500, 10000,
 203			  false, sparx5, VCAP_ES2_CTRL);
 204}
 205
 206/* Initializing a VCAP address range */
 207static void _sparx5_vcap_range_init(struct sparx5 *sparx5,
 208				    struct vcap_admin *admin,
 209				    u32 addr, u32 count)
 210{
 211	u32 size = count - 1;
 212
 213	switch (admin->vtype) {
 214	case VCAP_TYPE_IS0:
 215	case VCAP_TYPE_IS2:
 216		spx5_wr(VCAP_SUPER_CFG_MV_NUM_POS_SET(0) |
 217			VCAP_SUPER_CFG_MV_SIZE_SET(size),
 218			sparx5, VCAP_SUPER_CFG);
 219		spx5_wr(VCAP_SUPER_CTRL_UPDATE_CMD_SET(VCAP_CMD_INITIALIZE) |
 220			VCAP_SUPER_CTRL_UPDATE_ENTRY_DIS_SET(0) |
 221			VCAP_SUPER_CTRL_UPDATE_ACTION_DIS_SET(0) |
 222			VCAP_SUPER_CTRL_UPDATE_CNT_DIS_SET(0) |
 223			VCAP_SUPER_CTRL_UPDATE_ADDR_SET(addr) |
 224			VCAP_SUPER_CTRL_CLEAR_CACHE_SET(true) |
 225			VCAP_SUPER_CTRL_UPDATE_SHOT_SET(true),
 226			sparx5, VCAP_SUPER_CTRL);
 227		sparx5_vcap_wait_super_update(sparx5);
 228		break;
 229	case VCAP_TYPE_ES0:
 230		spx5_wr(VCAP_ES0_CFG_MV_NUM_POS_SET(0) |
 231				VCAP_ES0_CFG_MV_SIZE_SET(size),
 232			sparx5, VCAP_ES0_CFG);
 233		spx5_wr(VCAP_ES0_CTRL_UPDATE_CMD_SET(VCAP_CMD_INITIALIZE) |
 234				VCAP_ES0_CTRL_UPDATE_ENTRY_DIS_SET(0) |
 235				VCAP_ES0_CTRL_UPDATE_ACTION_DIS_SET(0) |
 236				VCAP_ES0_CTRL_UPDATE_CNT_DIS_SET(0) |
 237				VCAP_ES0_CTRL_UPDATE_ADDR_SET(addr) |
 238				VCAP_ES0_CTRL_CLEAR_CACHE_SET(true) |
 239				VCAP_ES0_CTRL_UPDATE_SHOT_SET(true),
 240			sparx5, VCAP_ES0_CTRL);
 241		sparx5_vcap_wait_es0_update(sparx5);
 242		break;
 243	case VCAP_TYPE_ES2:
 244		spx5_wr(VCAP_ES2_CFG_MV_NUM_POS_SET(0) |
 245			VCAP_ES2_CFG_MV_SIZE_SET(size),
 246			sparx5, VCAP_ES2_CFG);
 247		spx5_wr(VCAP_ES2_CTRL_UPDATE_CMD_SET(VCAP_CMD_INITIALIZE) |
 248			VCAP_ES2_CTRL_UPDATE_ENTRY_DIS_SET(0) |
 249			VCAP_ES2_CTRL_UPDATE_ACTION_DIS_SET(0) |
 250			VCAP_ES2_CTRL_UPDATE_CNT_DIS_SET(0) |
 251			VCAP_ES2_CTRL_UPDATE_ADDR_SET(addr) |
 252			VCAP_ES2_CTRL_CLEAR_CACHE_SET(true) |
 253			VCAP_ES2_CTRL_UPDATE_SHOT_SET(true),
 254			sparx5, VCAP_ES2_CTRL);
 255		sparx5_vcap_wait_es2_update(sparx5);
 256		break;
 257	default:
 258		sparx5_vcap_type_err(sparx5, admin, __func__);
 259		break;
 260	}
 261}
 262
 263/* Initializing VCAP rule data area */
 264static void sparx5_vcap_block_init(struct sparx5 *sparx5,
 265				   struct vcap_admin *admin)
 266{
 267	_sparx5_vcap_range_init(sparx5, admin, admin->first_valid_addr,
 268				admin->last_valid_addr -
 269					admin->first_valid_addr);
 270}
 271
 272/* Get the keyset name from the sparx5 VCAP model */
 273static const char *sparx5_vcap_keyset_name(struct net_device *ndev,
 274					   enum vcap_keyfield_set keyset)
 275{
 276	struct sparx5_port *port = netdev_priv(ndev);
 277
 278	return vcap_keyset_name(port->sparx5->vcap_ctrl, keyset);
 279}
 280
 281/* Check if this is the first lookup of IS0 */
 282static bool sparx5_vcap_is0_is_first_chain(struct vcap_rule *rule)
 283{
 284	return (rule->vcap_chain_id >= SPARX5_VCAP_CID_IS0_L0 &&
 285		rule->vcap_chain_id < SPARX5_VCAP_CID_IS0_L1) ||
 286		((rule->vcap_chain_id >= SPARX5_VCAP_CID_IS0_L2 &&
 287		  rule->vcap_chain_id < SPARX5_VCAP_CID_IS0_L3)) ||
 288		((rule->vcap_chain_id >= SPARX5_VCAP_CID_IS0_L4 &&
 289		  rule->vcap_chain_id < SPARX5_VCAP_CID_IS0_L5));
 290}
 291
 292/* Check if this is the first lookup of IS2 */
 293static bool sparx5_vcap_is2_is_first_chain(struct vcap_rule *rule)
 294{
 295	return (rule->vcap_chain_id >= SPARX5_VCAP_CID_IS2_L0 &&
 296		rule->vcap_chain_id < SPARX5_VCAP_CID_IS2_L1) ||
 297		((rule->vcap_chain_id >= SPARX5_VCAP_CID_IS2_L2 &&
 298		  rule->vcap_chain_id < SPARX5_VCAP_CID_IS2_L3));
 299}
 300
 301static bool sparx5_vcap_es2_is_first_chain(struct vcap_rule *rule)
 302{
 303	return (rule->vcap_chain_id >= SPARX5_VCAP_CID_ES2_L0 &&
 304		rule->vcap_chain_id < SPARX5_VCAP_CID_ES2_L1);
 305}
 306
 307/* Set the narrow range ingress port mask on a rule */
 308static void sparx5_vcap_add_ingress_range_port_mask(struct vcap_rule *rule,
 309						    struct net_device *ndev)
 310{
 311	struct sparx5_port *port = netdev_priv(ndev);
 312	u32 port_mask;
 313	u32 range;
 314
 315	range = port->portno / BITS_PER_TYPE(u32);
 316	/* Port bit set to match-any */
 317	port_mask = ~BIT(port->portno % BITS_PER_TYPE(u32));
 318	vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK_SEL, 0, 0xf);
 319	vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK_RNG, range, 0xf);
 320	vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK, 0, port_mask);
 321}
 322
 323/* Set the wide range ingress port mask on a rule */
 324static void sparx5_vcap_add_wide_port_mask(struct vcap_rule *rule,
 325					   struct net_device *ndev)
 326{
 327	struct sparx5_port *port = netdev_priv(ndev);
 328	struct vcap_u72_key port_mask;
 329	u32 range;
 330
 331	/* Port bit set to match-any */
 332	memset(port_mask.value, 0, sizeof(port_mask.value));
 333	memset(port_mask.mask, 0xff, sizeof(port_mask.mask));
 334	range = port->portno / BITS_PER_BYTE;
 335	port_mask.mask[range] = ~BIT(port->portno % BITS_PER_BYTE);
 336	vcap_rule_add_key_u72(rule, VCAP_KF_IF_IGR_PORT_MASK, &port_mask);
 337}
 338
 339static void sparx5_vcap_add_egress_range_port_mask(struct vcap_rule *rule,
 340						   struct net_device *ndev)
 341{
 342	struct sparx5_port *port = netdev_priv(ndev);
 343	u32 port_mask;
 344	u32 range;
 345
 346	/* Mask range selects:
 347	 * 0-2: Physical/Logical egress port number 0-31, 32–63, 64.
 348	 * 3-5: Virtual Interface Number 0-31, 32-63, 64.
 349	 * 6: CPU queue Number 0-7.
 350	 *
 351	 * Use physical/logical port ranges (0-2)
 352	 */
 353	range = port->portno / BITS_PER_TYPE(u32);
 354	/* Port bit set to match-any */
 355	port_mask = ~BIT(port->portno % BITS_PER_TYPE(u32));
 356	vcap_rule_add_key_u32(rule, VCAP_KF_IF_EGR_PORT_MASK_RNG, range, 0xf);
 357	vcap_rule_add_key_u32(rule, VCAP_KF_IF_EGR_PORT_MASK, 0, port_mask);
 358}
 359
 360/* Convert IS0 chain id to vcap lookup id */
 361static int sparx5_vcap_is0_cid_to_lookup(int cid)
 362{
 363	int lookup = 0;
 364
 365	if (cid >= SPARX5_VCAP_CID_IS0_L1 && cid < SPARX5_VCAP_CID_IS0_L2)
 366		lookup = 1;
 367	else if (cid >= SPARX5_VCAP_CID_IS0_L2 && cid < SPARX5_VCAP_CID_IS0_L3)
 368		lookup = 2;
 369	else if (cid >= SPARX5_VCAP_CID_IS0_L3 && cid < SPARX5_VCAP_CID_IS0_L4)
 370		lookup = 3;
 371	else if (cid >= SPARX5_VCAP_CID_IS0_L4 && cid < SPARX5_VCAP_CID_IS0_L5)
 372		lookup = 4;
 373	else if (cid >= SPARX5_VCAP_CID_IS0_L5 && cid < SPARX5_VCAP_CID_IS0_MAX)
 374		lookup = 5;
 375
 376	return lookup;
 377}
 378
 379/* Convert IS2 chain id to vcap lookup id */
 380static int sparx5_vcap_is2_cid_to_lookup(int cid)
 381{
 382	int lookup = 0;
 383
 384	if (cid >= SPARX5_VCAP_CID_IS2_L1 && cid < SPARX5_VCAP_CID_IS2_L2)
 385		lookup = 1;
 386	else if (cid >= SPARX5_VCAP_CID_IS2_L2 && cid < SPARX5_VCAP_CID_IS2_L3)
 387		lookup = 2;
 388	else if (cid >= SPARX5_VCAP_CID_IS2_L3 && cid < SPARX5_VCAP_CID_IS2_MAX)
 389		lookup = 3;
 390
 391	return lookup;
 392}
 393
 394/* Convert ES2 chain id to vcap lookup id */
 395static int sparx5_vcap_es2_cid_to_lookup(int cid)
 396{
 397	int lookup = 0;
 398
 399	if (cid >= SPARX5_VCAP_CID_ES2_L1)
 400		lookup = 1;
 401
 402	return lookup;
 403}
 404
 405/* Add ethernet type IS0 keyset to a list */
 406static void
 407sparx5_vcap_is0_get_port_etype_keysets(struct vcap_keyset_list *keysetlist,
 408				       u32 value)
 409{
 410	switch (ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL_GET(value)) {
 411	case VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE:
 412		vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL_7TUPLE);
 413		break;
 414	case VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4:
 415		vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL_5TUPLE_IP4);
 416		break;
 417	}
 418}
 419
 420/* Return the list of keysets for the vcap port configuration */
 421static int sparx5_vcap_is0_get_port_keysets(struct net_device *ndev,
 422					    int lookup,
 423					    struct vcap_keyset_list *keysetlist,
 424					    u16 l3_proto)
 425{
 426	struct sparx5_port *port = netdev_priv(ndev);
 427	struct sparx5 *sparx5 = port->sparx5;
 428	int portno = port->portno;
 429	u32 value;
 430
 431	value = spx5_rd(sparx5, ANA_CL_ADV_CL_CFG(portno, lookup));
 432
 433	/* Collect all keysets for the port in a list */
 434	if (l3_proto == ETH_P_ALL)
 435		sparx5_vcap_is0_get_port_etype_keysets(keysetlist, value);
 436
 437	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP)
 438		switch (ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL_GET(value)) {
 439		case VCAP_IS0_PS_ETYPE_DEFAULT:
 440			sparx5_vcap_is0_get_port_etype_keysets(keysetlist,
 441							       value);
 442			break;
 443		case VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE:
 444			vcap_keyset_list_add(keysetlist,
 445					     VCAP_KFS_NORMAL_7TUPLE);
 446			break;
 447		case VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4:
 448			vcap_keyset_list_add(keysetlist,
 449					     VCAP_KFS_NORMAL_5TUPLE_IP4);
 450			break;
 451		}
 452
 453	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IPV6)
 454		switch (ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL_GET(value)) {
 455		case VCAP_IS0_PS_ETYPE_DEFAULT:
 456			sparx5_vcap_is0_get_port_etype_keysets(keysetlist,
 457							       value);
 458			break;
 459		case VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE:
 460			vcap_keyset_list_add(keysetlist,
 461					     VCAP_KFS_NORMAL_7TUPLE);
 462			break;
 463		case VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4:
 464			vcap_keyset_list_add(keysetlist,
 465					     VCAP_KFS_NORMAL_5TUPLE_IP4);
 466			break;
 467		}
 468
 469	if (l3_proto != ETH_P_IP && l3_proto != ETH_P_IPV6)
 470		sparx5_vcap_is0_get_port_etype_keysets(keysetlist, value);
 471	return 0;
 472}
 473
 474/* Return the list of keysets for the vcap port configuration */
 475static int sparx5_vcap_is2_get_port_keysets(struct net_device *ndev,
 476					    int lookup,
 477					    struct vcap_keyset_list *keysetlist,
 478					    u16 l3_proto)
 479{
 480	struct sparx5_port *port = netdev_priv(ndev);
 481	struct sparx5 *sparx5 = port->sparx5;
 482	int portno = port->portno;
 483	u32 value;
 484
 485	value = spx5_rd(sparx5, ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
 486
 487	/* Collect all keysets for the port in a list */
 488	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_ARP) {
 489		switch (ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL_GET(value)) {
 490		case VCAP_IS2_PS_ARP_MAC_ETYPE:
 491			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
 492			break;
 493		case VCAP_IS2_PS_ARP_ARP:
 494			vcap_keyset_list_add(keysetlist, VCAP_KFS_ARP);
 495			break;
 496		}
 497	}
 498
 499	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP) {
 500		switch (ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL_GET(value)) {
 501		case VCAP_IS2_PS_IPV4_UC_MAC_ETYPE:
 502			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
 503			break;
 504		case VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER:
 505			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
 506			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
 507			break;
 508		case VCAP_IS2_PS_IPV4_UC_IP_7TUPLE:
 509			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
 510			break;
 511		}
 512
 513		switch (ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL_GET(value)) {
 514		case VCAP_IS2_PS_IPV4_MC_MAC_ETYPE:
 515			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
 516			break;
 517		case VCAP_IS2_PS_IPV4_MC_IP4_TCP_UDP_OTHER:
 518			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
 519			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
 520			break;
 521		case VCAP_IS2_PS_IPV4_MC_IP_7TUPLE:
 522			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
 523			break;
 524		}
 525	}
 526
 527	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IPV6) {
 528		switch (ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL_GET(value)) {
 529		case VCAP_IS2_PS_IPV6_UC_MAC_ETYPE:
 530			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
 531			break;
 532		case VCAP_IS2_PS_IPV6_UC_IP_7TUPLE:
 533			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
 534			break;
 535		case VCAP_IS2_PS_IPV6_UC_IP6_STD:
 536			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
 537			break;
 538		case VCAP_IS2_PS_IPV6_UC_IP4_TCP_UDP_OTHER:
 539			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
 540			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
 541			break;
 542		}
 543
 544		switch (ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL_GET(value)) {
 545		case VCAP_IS2_PS_IPV6_MC_MAC_ETYPE:
 546			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
 547			break;
 548		case VCAP_IS2_PS_IPV6_MC_IP_7TUPLE:
 549			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
 550			break;
 551		case VCAP_IS2_PS_IPV6_MC_IP6_STD:
 552			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
 553			break;
 554		case VCAP_IS2_PS_IPV6_MC_IP4_TCP_UDP_OTHER:
 555			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
 556			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
 557			break;
 558		case VCAP_IS2_PS_IPV6_MC_IP6_VID:
 559			/* Not used */
 560			break;
 561		}
 562	}
 563
 564	if (l3_proto != ETH_P_ARP && l3_proto != ETH_P_IP &&
 565	    l3_proto != ETH_P_IPV6) {
 566		switch (ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL_GET(value)) {
 567		case VCAP_IS2_PS_NONETH_MAC_ETYPE:
 568			/* IS2 non-classified frames generate MAC_ETYPE */
 569			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
 570			break;
 571		}
 572	}
 573	return 0;
 574}
 575
 576/* Return the keysets for the vcap port IP4 traffic class configuration */
 577static void
 578sparx5_vcap_es2_get_port_ipv4_keysets(struct vcap_keyset_list *keysetlist,
 579				      u32 value)
 580{
 581	switch (EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL_GET(value)) {
 582	case VCAP_ES2_PS_IPV4_MAC_ETYPE:
 583		vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
 584		break;
 585	case VCAP_ES2_PS_IPV4_IP_7TUPLE:
 586		vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
 587		break;
 588	case VCAP_ES2_PS_IPV4_IP4_TCP_UDP_VID:
 589		vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
 590		break;
 591	case VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER:
 592		vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP);
 593		vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
 594		break;
 595	case VCAP_ES2_PS_IPV4_IP4_VID:
 596		/* Not used */
 597		break;
 598	case VCAP_ES2_PS_IPV4_IP4_OTHER:
 599		vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER);
 600		break;
 601	}
 602}
 603
 604/* Return the list of keysets for the vcap port configuration */
 605static int sparx5_vcap_es0_get_port_keysets(struct net_device *ndev,
 606					    struct vcap_keyset_list *keysetlist,
 607					    u16 l3_proto)
 608{
 609	struct sparx5_port *port = netdev_priv(ndev);
 610	struct sparx5 *sparx5 = port->sparx5;
 611	int portno = port->portno;
 612	u32 value;
 613
 614	value = spx5_rd(sparx5, REW_RTAG_ETAG_CTRL(portno));
 615
 616	/* Collect all keysets for the port in a list */
 617	switch (REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA_GET(value)) {
 618	case VCAP_ES0_PS_NORMAL_SELECTION:
 619	case VCAP_ES0_PS_FORCE_ISDX_LOOKUPS:
 620		vcap_keyset_list_add(keysetlist, VCAP_KFS_ISDX);
 621		break;
 622	default:
 623		break;
 624	}
 625	return 0;
 626}
 627
 628/* Return the list of keysets for the vcap port configuration */
 629static int sparx5_vcap_es2_get_port_keysets(struct net_device *ndev,
 630					    int lookup,
 631					    struct vcap_keyset_list *keysetlist,
 632					    u16 l3_proto)
 633{
 634	struct sparx5_port *port = netdev_priv(ndev);
 635	struct sparx5 *sparx5 = port->sparx5;
 636	int portno = port->portno;
 637	u32 value;
 638
 639	value = spx5_rd(sparx5, EACL_VCAP_ES2_KEY_SEL(portno, lookup));
 640
 641	/* Collect all keysets for the port in a list */
 642	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_ARP) {
 643		switch (EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL_GET(value)) {
 644		case VCAP_ES2_PS_ARP_MAC_ETYPE:
 645			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
 646			break;
 647		case VCAP_ES2_PS_ARP_ARP:
 648			vcap_keyset_list_add(keysetlist, VCAP_KFS_ARP);
 649			break;
 650		}
 651	}
 652
 653	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP)
 654		sparx5_vcap_es2_get_port_ipv4_keysets(keysetlist, value);
 655
 656	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IPV6) {
 657		switch (EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL_GET(value)) {
 658		case VCAP_ES2_PS_IPV6_MAC_ETYPE:
 659			vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
 660			break;
 661		case VCAP_ES2_PS_IPV6_IP_7TUPLE:
 662			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
 663			break;
 664		case VCAP_ES2_PS_IPV6_IP_7TUPLE_VID:
 665			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
 666			break;
 667		case VCAP_ES2_PS_IPV6_IP_7TUPLE_STD:
 668			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP_7TUPLE);
 669			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
 670			break;
 671		case VCAP_ES2_PS_IPV6_IP6_VID:
 672			/* Not used */
 673			break;
 674		case VCAP_ES2_PS_IPV6_IP6_STD:
 675			vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD);
 676			break;
 677		case VCAP_ES2_PS_IPV6_IP4_DOWNGRADE:
 678			sparx5_vcap_es2_get_port_ipv4_keysets(keysetlist,
 679							      value);
 680			break;
 681		}
 682	}
 683
 684	if (l3_proto != ETH_P_ARP && l3_proto != ETH_P_IP &&
 685	    l3_proto != ETH_P_IPV6) {
 686		vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE);
 687	}
 688	return 0;
 689}
 690
 691/* Get the port keyset for the vcap lookup */
 692int sparx5_vcap_get_port_keyset(struct net_device *ndev,
 693				struct vcap_admin *admin,
 694				int cid,
 695				u16 l3_proto,
 696				struct vcap_keyset_list *kslist)
 697{
 698	int lookup, err = -EINVAL;
 699	struct sparx5_port *port;
 700
 701	switch (admin->vtype) {
 702	case VCAP_TYPE_IS0:
 703		lookup = sparx5_vcap_is0_cid_to_lookup(cid);
 704		err = sparx5_vcap_is0_get_port_keysets(ndev, lookup, kslist,
 705						       l3_proto);
 706		break;
 707	case VCAP_TYPE_IS2:
 708		lookup = sparx5_vcap_is2_cid_to_lookup(cid);
 709		err = sparx5_vcap_is2_get_port_keysets(ndev, lookup, kslist,
 710						       l3_proto);
 711		break;
 712	case VCAP_TYPE_ES0:
 713		err = sparx5_vcap_es0_get_port_keysets(ndev, kslist, l3_proto);
 714		break;
 715	case VCAP_TYPE_ES2:
 716		lookup = sparx5_vcap_es2_cid_to_lookup(cid);
 717		err = sparx5_vcap_es2_get_port_keysets(ndev, lookup, kslist,
 718						       l3_proto);
 719		break;
 720	default:
 721		port = netdev_priv(ndev);
 722		sparx5_vcap_type_err(port->sparx5, admin, __func__);
 723		break;
 724	}
 725	return err;
 726}
 727
 728/* Check if the ethertype is supported by the vcap port classification */
 729bool sparx5_vcap_is_known_etype(struct vcap_admin *admin, u16 etype)
 730{
 731	const u16 *known_etypes;
 732	int size, idx;
 733
 734	switch (admin->vtype) {
 735	case VCAP_TYPE_IS0:
 736		known_etypes = sparx5_vcap_is0_known_etypes;
 737		size = ARRAY_SIZE(sparx5_vcap_is0_known_etypes);
 738		break;
 739	case VCAP_TYPE_IS2:
 740		known_etypes = sparx5_vcap_is2_known_etypes;
 741		size = ARRAY_SIZE(sparx5_vcap_is2_known_etypes);
 742		break;
 743	case VCAP_TYPE_ES0:
 744		return true;
 745	case VCAP_TYPE_ES2:
 746		known_etypes = sparx5_vcap_es2_known_etypes;
 747		size = ARRAY_SIZE(sparx5_vcap_es2_known_etypes);
 748		break;
 749	default:
 750		return false;
 751	}
 752	for (idx = 0; idx < size; ++idx)
 753		if (known_etypes[idx] == etype)
 754			return true;
 755	return false;
 756}
 757
 758/* API callback used for validating a field keyset (check the port keysets) */
 759static enum vcap_keyfield_set
 760sparx5_vcap_validate_keyset(struct net_device *ndev,
 761			    struct vcap_admin *admin,
 762			    struct vcap_rule *rule,
 763			    struct vcap_keyset_list *kslist,
 764			    u16 l3_proto)
 765{
 766	struct vcap_keyset_list keysetlist = {};
 767	enum vcap_keyfield_set keysets[10] = {};
 768	struct sparx5_port *port;
 769	int idx, jdx, lookup;
 770
 771	if (!kslist || kslist->cnt == 0)
 772		return VCAP_KFS_NO_VALUE;
 773
 774	keysetlist.max = ARRAY_SIZE(keysets);
 775	keysetlist.keysets = keysets;
 776
 777	/* Get a list of currently configured keysets in the lookups */
 778	switch (admin->vtype) {
 779	case VCAP_TYPE_IS0:
 780		lookup = sparx5_vcap_is0_cid_to_lookup(rule->vcap_chain_id);
 781		sparx5_vcap_is0_get_port_keysets(ndev, lookup, &keysetlist,
 782						 l3_proto);
 783		break;
 784	case VCAP_TYPE_IS2:
 785		lookup = sparx5_vcap_is2_cid_to_lookup(rule->vcap_chain_id);
 786		sparx5_vcap_is2_get_port_keysets(ndev, lookup, &keysetlist,
 787						 l3_proto);
 788		break;
 789	case VCAP_TYPE_ES0:
 790		sparx5_vcap_es0_get_port_keysets(ndev, &keysetlist, l3_proto);
 791		break;
 792	case VCAP_TYPE_ES2:
 793		lookup = sparx5_vcap_es2_cid_to_lookup(rule->vcap_chain_id);
 794		sparx5_vcap_es2_get_port_keysets(ndev, lookup, &keysetlist,
 795						 l3_proto);
 796		break;
 797	default:
 798		port = netdev_priv(ndev);
 799		sparx5_vcap_type_err(port->sparx5, admin, __func__);
 800		break;
 801	}
 802
 803	/* Check if there is a match and return the match */
 804	for (idx = 0; idx < kslist->cnt; ++idx)
 805		for (jdx = 0; jdx < keysetlist.cnt; ++jdx)
 806			if (kslist->keysets[idx] == keysets[jdx])
 807				return kslist->keysets[idx];
 808
 809	pr_err("%s:%d: %s not supported in port key selection\n",
 810	       __func__, __LINE__,
 811	       sparx5_vcap_keyset_name(ndev, kslist->keysets[0]));
 812
 813	return -ENOENT;
 814}
 815
 816static void sparx5_vcap_ingress_add_default_fields(struct net_device *ndev,
 817						   struct vcap_admin *admin,
 818						   struct vcap_rule *rule)
 819{
 820	const struct vcap_field *field;
 821	bool is_first;
 822
 823	/* Add ingress port mask matching the net device */
 824	field = vcap_lookup_keyfield(rule, VCAP_KF_IF_IGR_PORT_MASK);
 825	if (field && field->width == SPX5_PORTS)
 826		sparx5_vcap_add_wide_port_mask(rule, ndev);
 827	else if (field && field->width == BITS_PER_TYPE(u32))
 828		sparx5_vcap_add_ingress_range_port_mask(rule, ndev);
 829	else
 830		pr_err("%s:%d: %s: could not add an ingress port mask for: %s\n",
 831		       __func__, __LINE__, netdev_name(ndev),
 832		       sparx5_vcap_keyset_name(ndev, rule->keyset));
 833
 834	if (admin->vtype == VCAP_TYPE_IS0)
 835		is_first = sparx5_vcap_is0_is_first_chain(rule);
 836	else
 837		is_first = sparx5_vcap_is2_is_first_chain(rule);
 838
 839	/* Add key that selects the first/second lookup */
 840	if (is_first)
 841		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
 842				      VCAP_BIT_1);
 843	else
 844		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
 845				      VCAP_BIT_0);
 846}
 847
 848static void sparx5_vcap_es0_add_default_fields(struct net_device *ndev,
 849					       struct vcap_admin *admin,
 850					       struct vcap_rule *rule)
 851{
 852	struct sparx5_port *port = netdev_priv(ndev);
 853
 854	vcap_rule_add_key_u32(rule, VCAP_KF_IF_EGR_PORT_NO, port->portno, ~0);
 855	/* Match untagged frames if there was no VLAN key */
 856	vcap_rule_add_key_u32(rule, VCAP_KF_8021Q_TPID, SPX5_TPID_SEL_UNTAGGED,
 857			      ~0);
 858}
 859
 860static void sparx5_vcap_es2_add_default_fields(struct net_device *ndev,
 861					       struct vcap_admin *admin,
 862					       struct vcap_rule *rule)
 863{
 864	const struct vcap_field *field;
 865	bool is_first;
 866
 867	/* Add egress port mask matching the net device */
 868	field = vcap_lookup_keyfield(rule, VCAP_KF_IF_EGR_PORT_MASK);
 869	if (field)
 870		sparx5_vcap_add_egress_range_port_mask(rule, ndev);
 871
 872	/* Add key that selects the first/second lookup */
 873	is_first = sparx5_vcap_es2_is_first_chain(rule);
 874
 875	if (is_first)
 876		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
 877				      VCAP_BIT_1);
 878	else
 879		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
 880				      VCAP_BIT_0);
 881}
 882
 883/* API callback used for adding default fields to a rule */
 884static void sparx5_vcap_add_default_fields(struct net_device *ndev,
 885					   struct vcap_admin *admin,
 886					   struct vcap_rule *rule)
 887{
 888	struct sparx5_port *port;
 889
 890	/* add the lookup bit */
 891	switch (admin->vtype) {
 892	case VCAP_TYPE_IS0:
 893	case VCAP_TYPE_IS2:
 894		sparx5_vcap_ingress_add_default_fields(ndev, admin, rule);
 895		break;
 896	case VCAP_TYPE_ES0:
 897		sparx5_vcap_es0_add_default_fields(ndev, admin, rule);
 898		break;
 899	case VCAP_TYPE_ES2:
 900		sparx5_vcap_es2_add_default_fields(ndev, admin, rule);
 901		break;
 902	default:
 903		port = netdev_priv(ndev);
 904		sparx5_vcap_type_err(port->sparx5, admin, __func__);
 905		break;
 906	}
 907}
 908
 909/* API callback used for erasing the vcap cache area (not the register area) */
 910static void sparx5_vcap_cache_erase(struct vcap_admin *admin)
 911{
 912	memset(admin->cache.keystream, 0, STREAMSIZE);
 913	memset(admin->cache.maskstream, 0, STREAMSIZE);
 914	memset(admin->cache.actionstream, 0, STREAMSIZE);
 915	memset(&admin->cache.counter, 0, sizeof(admin->cache.counter));
 916}
 917
 918static void sparx5_vcap_is0_cache_write(struct sparx5 *sparx5,
 919					struct vcap_admin *admin,
 920					enum vcap_selection sel,
 921					u32 start,
 922					u32 count)
 923{
 924	u32 *keystr, *mskstr, *actstr;
 925	int idx;
 926
 927	keystr = &admin->cache.keystream[start];
 928	mskstr = &admin->cache.maskstream[start];
 929	actstr = &admin->cache.actionstream[start];
 930
 931	switch (sel) {
 932	case VCAP_SEL_ENTRY:
 933		for (idx = 0; idx < count; ++idx) {
 934			/* Avoid 'match-off' by setting value & mask */
 935			spx5_wr(keystr[idx] & mskstr[idx], sparx5,
 936				VCAP_SUPER_VCAP_ENTRY_DAT(idx));
 937			spx5_wr(~mskstr[idx], sparx5,
 938				VCAP_SUPER_VCAP_MASK_DAT(idx));
 939		}
 940		break;
 941	case VCAP_SEL_ACTION:
 942		for (idx = 0; idx < count; ++idx)
 943			spx5_wr(actstr[idx], sparx5,
 944				VCAP_SUPER_VCAP_ACTION_DAT(idx));
 945		break;
 946	case VCAP_SEL_ALL:
 947		pr_err("%s:%d: cannot write all streams at once\n",
 948		       __func__, __LINE__);
 949		break;
 950	default:
 951		break;
 952	}
 953
 954	if (sel & VCAP_SEL_COUNTER)
 955		spx5_wr(admin->cache.counter, sparx5,
 956			VCAP_SUPER_VCAP_CNT_DAT(0));
 957}
 958
 959static void sparx5_vcap_is2_cache_write(struct sparx5 *sparx5,
 960					struct vcap_admin *admin,
 961					enum vcap_selection sel,
 962					u32 start,
 963					u32 count)
 964{
 965	u32 *keystr, *mskstr, *actstr;
 966	int idx;
 967
 968	keystr = &admin->cache.keystream[start];
 969	mskstr = &admin->cache.maskstream[start];
 970	actstr = &admin->cache.actionstream[start];
 971
 972	switch (sel) {
 973	case VCAP_SEL_ENTRY:
 974		for (idx = 0; idx < count; ++idx) {
 975			/* Avoid 'match-off' by setting value & mask */
 976			spx5_wr(keystr[idx] & mskstr[idx], sparx5,
 977				VCAP_SUPER_VCAP_ENTRY_DAT(idx));
 978			spx5_wr(~mskstr[idx], sparx5,
 979				VCAP_SUPER_VCAP_MASK_DAT(idx));
 980		}
 981		break;
 982	case VCAP_SEL_ACTION:
 983		for (idx = 0; idx < count; ++idx)
 984			spx5_wr(actstr[idx], sparx5,
 985				VCAP_SUPER_VCAP_ACTION_DAT(idx));
 986		break;
 987	case VCAP_SEL_ALL:
 988		pr_err("%s:%d: cannot write all streams at once\n",
 989		       __func__, __LINE__);
 990		break;
 991	default:
 992		break;
 993	}
 994	if (sel & VCAP_SEL_COUNTER) {
 995		start = start & 0xfff; /* counter limit */
 996		if (admin->vinst == 0)
 997			spx5_wr(admin->cache.counter, sparx5,
 998				ANA_ACL_CNT_A(start));
 999		else
1000			spx5_wr(admin->cache.counter, sparx5,
1001				ANA_ACL_CNT_B(start));
1002		spx5_wr(admin->cache.sticky, sparx5,
1003			VCAP_SUPER_VCAP_CNT_DAT(0));
1004	}
1005}
1006
1007/* Use ESDX counters located in the XQS */
1008static void sparx5_es0_write_esdx_counter(struct sparx5 *sparx5,
1009					  struct vcap_admin *admin, u32 id)
1010{
1011	mutex_lock(&sparx5->queue_stats_lock);
1012	spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(id), sparx5, XQS_STAT_CFG);
1013	spx5_wr(admin->cache.counter, sparx5,
1014		XQS_CNT(SPARX5_STAT_ESDX_GRN_PKTS));
1015	spx5_wr(0, sparx5, XQS_CNT(SPARX5_STAT_ESDX_YEL_PKTS));
1016	mutex_unlock(&sparx5->queue_stats_lock);
1017}
1018
1019static void sparx5_vcap_es0_cache_write(struct sparx5 *sparx5,
1020					struct vcap_admin *admin,
1021					enum vcap_selection sel,
1022					u32 start,
1023					u32 count)
1024{
1025	u32 *keystr, *mskstr, *actstr;
1026	int idx;
1027
1028	keystr = &admin->cache.keystream[start];
1029	mskstr = &admin->cache.maskstream[start];
1030	actstr = &admin->cache.actionstream[start];
1031
1032	switch (sel) {
1033	case VCAP_SEL_ENTRY:
1034		for (idx = 0; idx < count; ++idx) {
1035			/* Avoid 'match-off' by setting value & mask */
1036			spx5_wr(keystr[idx] & mskstr[idx], sparx5,
1037				VCAP_ES0_VCAP_ENTRY_DAT(idx));
1038			spx5_wr(~mskstr[idx], sparx5,
1039				VCAP_ES0_VCAP_MASK_DAT(idx));
1040		}
1041		break;
1042	case VCAP_SEL_ACTION:
1043		for (idx = 0; idx < count; ++idx)
1044			spx5_wr(actstr[idx], sparx5,
1045				VCAP_ES0_VCAP_ACTION_DAT(idx));
1046		break;
1047	case VCAP_SEL_ALL:
1048		pr_err("%s:%d: cannot write all streams at once\n",
1049		       __func__, __LINE__);
1050		break;
1051	default:
1052		break;
1053	}
1054	if (sel & VCAP_SEL_COUNTER) {
1055		spx5_wr(admin->cache.counter, sparx5, VCAP_ES0_VCAP_CNT_DAT(0));
1056		sparx5_es0_write_esdx_counter(sparx5, admin, start);
1057	}
1058}
1059
1060static void sparx5_vcap_es2_cache_write(struct sparx5 *sparx5,
1061					struct vcap_admin *admin,
1062					enum vcap_selection sel,
1063					u32 start,
1064					u32 count)
1065{
1066	u32 *keystr, *mskstr, *actstr;
1067	int idx;
1068
1069	keystr = &admin->cache.keystream[start];
1070	mskstr = &admin->cache.maskstream[start];
1071	actstr = &admin->cache.actionstream[start];
1072
1073	switch (sel) {
1074	case VCAP_SEL_ENTRY:
1075		for (idx = 0; idx < count; ++idx) {
1076			/* Avoid 'match-off' by setting value & mask */
1077			spx5_wr(keystr[idx] & mskstr[idx], sparx5,
1078				VCAP_ES2_VCAP_ENTRY_DAT(idx));
1079			spx5_wr(~mskstr[idx], sparx5,
1080				VCAP_ES2_VCAP_MASK_DAT(idx));
1081		}
1082		break;
1083	case VCAP_SEL_ACTION:
1084		for (idx = 0; idx < count; ++idx)
1085			spx5_wr(actstr[idx], sparx5,
1086				VCAP_ES2_VCAP_ACTION_DAT(idx));
1087		break;
1088	case VCAP_SEL_ALL:
1089		pr_err("%s:%d: cannot write all streams at once\n",
1090		       __func__, __LINE__);
1091		break;
1092	default:
1093		break;
1094	}
1095	if (sel & VCAP_SEL_COUNTER) {
1096		start = start & 0x7ff; /* counter limit */
1097		spx5_wr(admin->cache.counter, sparx5, EACL_ES2_CNT(start));
1098		spx5_wr(admin->cache.sticky, sparx5, VCAP_ES2_VCAP_CNT_DAT(0));
1099	}
1100}
1101
1102/* API callback used for writing to the VCAP cache */
1103static void sparx5_vcap_cache_write(struct net_device *ndev,
1104				    struct vcap_admin *admin,
1105				    enum vcap_selection sel,
1106				    u32 start,
1107				    u32 count)
1108{
1109	struct sparx5_port *port = netdev_priv(ndev);
1110	struct sparx5 *sparx5 = port->sparx5;
1111
1112	switch (admin->vtype) {
1113	case VCAP_TYPE_IS0:
1114		sparx5_vcap_is0_cache_write(sparx5, admin, sel, start, count);
1115		break;
1116	case VCAP_TYPE_IS2:
1117		sparx5_vcap_is2_cache_write(sparx5, admin, sel, start, count);
1118		break;
1119	case VCAP_TYPE_ES0:
1120		sparx5_vcap_es0_cache_write(sparx5, admin, sel, start, count);
1121		break;
1122	case VCAP_TYPE_ES2:
1123		sparx5_vcap_es2_cache_write(sparx5, admin, sel, start, count);
1124		break;
1125	default:
1126		sparx5_vcap_type_err(sparx5, admin, __func__);
1127		break;
1128	}
1129}
1130
1131static void sparx5_vcap_is0_cache_read(struct sparx5 *sparx5,
1132				       struct vcap_admin *admin,
1133				       enum vcap_selection sel,
1134				       u32 start,
1135				       u32 count)
1136{
1137	u32 *keystr, *mskstr, *actstr;
1138	int idx;
1139
1140	keystr = &admin->cache.keystream[start];
1141	mskstr = &admin->cache.maskstream[start];
1142	actstr = &admin->cache.actionstream[start];
1143
1144	if (sel & VCAP_SEL_ENTRY) {
1145		for (idx = 0; idx < count; ++idx) {
1146			keystr[idx] = spx5_rd(sparx5,
1147					      VCAP_SUPER_VCAP_ENTRY_DAT(idx));
1148			mskstr[idx] = ~spx5_rd(sparx5,
1149					       VCAP_SUPER_VCAP_MASK_DAT(idx));
1150		}
1151	}
1152
1153	if (sel & VCAP_SEL_ACTION)
1154		for (idx = 0; idx < count; ++idx)
1155			actstr[idx] = spx5_rd(sparx5,
1156					      VCAP_SUPER_VCAP_ACTION_DAT(idx));
1157
1158	if (sel & VCAP_SEL_COUNTER) {
1159		admin->cache.counter =
1160			spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0));
1161		admin->cache.sticky =
1162			spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0));
1163	}
1164}
1165
1166static void sparx5_vcap_is2_cache_read(struct sparx5 *sparx5,
1167				       struct vcap_admin *admin,
1168				       enum vcap_selection sel,
1169				       u32 start,
1170				       u32 count)
1171{
1172	u32 *keystr, *mskstr, *actstr;
1173	int idx;
1174
1175	keystr = &admin->cache.keystream[start];
1176	mskstr = &admin->cache.maskstream[start];
1177	actstr = &admin->cache.actionstream[start];
1178
1179	if (sel & VCAP_SEL_ENTRY) {
1180		for (idx = 0; idx < count; ++idx) {
1181			keystr[idx] = spx5_rd(sparx5,
1182					      VCAP_SUPER_VCAP_ENTRY_DAT(idx));
1183			mskstr[idx] = ~spx5_rd(sparx5,
1184					       VCAP_SUPER_VCAP_MASK_DAT(idx));
1185		}
1186	}
1187
1188	if (sel & VCAP_SEL_ACTION)
1189		for (idx = 0; idx < count; ++idx)
1190			actstr[idx] = spx5_rd(sparx5,
1191					      VCAP_SUPER_VCAP_ACTION_DAT(idx));
1192
1193	if (sel & VCAP_SEL_COUNTER) {
1194		start = start & 0xfff; /* counter limit */
1195		if (admin->vinst == 0)
1196			admin->cache.counter =
1197				spx5_rd(sparx5, ANA_ACL_CNT_A(start));
1198		else
1199			admin->cache.counter =
1200				spx5_rd(sparx5, ANA_ACL_CNT_B(start));
1201		admin->cache.sticky =
1202			spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0));
1203	}
1204}
1205
1206/* Use ESDX counters located in the XQS */
1207static void sparx5_es0_read_esdx_counter(struct sparx5 *sparx5,
1208					 struct vcap_admin *admin, u32 id)
1209{
1210	u32 counter;
1211
1212	mutex_lock(&sparx5->queue_stats_lock);
1213	spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(id), sparx5, XQS_STAT_CFG);
1214	counter = spx5_rd(sparx5, XQS_CNT(SPARX5_STAT_ESDX_GRN_PKTS)) +
1215		spx5_rd(sparx5, XQS_CNT(SPARX5_STAT_ESDX_YEL_PKTS));
1216	mutex_unlock(&sparx5->queue_stats_lock);
1217	if (counter)
1218		admin->cache.counter = counter;
1219}
1220
1221static void sparx5_vcap_es0_cache_read(struct sparx5 *sparx5,
1222				       struct vcap_admin *admin,
1223				       enum vcap_selection sel,
1224				       u32 start,
1225				       u32 count)
1226{
1227	u32 *keystr, *mskstr, *actstr;
1228	int idx;
1229
1230	keystr = &admin->cache.keystream[start];
1231	mskstr = &admin->cache.maskstream[start];
1232	actstr = &admin->cache.actionstream[start];
1233
1234	if (sel & VCAP_SEL_ENTRY) {
1235		for (idx = 0; idx < count; ++idx) {
1236			keystr[idx] =
1237				spx5_rd(sparx5, VCAP_ES0_VCAP_ENTRY_DAT(idx));
1238			mskstr[idx] =
1239				~spx5_rd(sparx5, VCAP_ES0_VCAP_MASK_DAT(idx));
1240		}
1241	}
1242
1243	if (sel & VCAP_SEL_ACTION)
1244		for (idx = 0; idx < count; ++idx)
1245			actstr[idx] =
1246				spx5_rd(sparx5, VCAP_ES0_VCAP_ACTION_DAT(idx));
1247
1248	if (sel & VCAP_SEL_COUNTER) {
1249		admin->cache.counter =
1250			spx5_rd(sparx5, VCAP_ES0_VCAP_CNT_DAT(0));
1251		admin->cache.sticky = admin->cache.counter;
1252		sparx5_es0_read_esdx_counter(sparx5, admin, start);
1253	}
1254}
1255
1256static void sparx5_vcap_es2_cache_read(struct sparx5 *sparx5,
1257				       struct vcap_admin *admin,
1258				       enum vcap_selection sel,
1259				       u32 start,
1260				       u32 count)
1261{
1262	u32 *keystr, *mskstr, *actstr;
1263	int idx;
1264
1265	keystr = &admin->cache.keystream[start];
1266	mskstr = &admin->cache.maskstream[start];
1267	actstr = &admin->cache.actionstream[start];
1268
1269	if (sel & VCAP_SEL_ENTRY) {
1270		for (idx = 0; idx < count; ++idx) {
1271			keystr[idx] =
1272				spx5_rd(sparx5, VCAP_ES2_VCAP_ENTRY_DAT(idx));
1273			mskstr[idx] =
1274				~spx5_rd(sparx5, VCAP_ES2_VCAP_MASK_DAT(idx));
1275		}
1276	}
1277
1278	if (sel & VCAP_SEL_ACTION)
1279		for (idx = 0; idx < count; ++idx)
1280			actstr[idx] =
1281				spx5_rd(sparx5, VCAP_ES2_VCAP_ACTION_DAT(idx));
1282
1283	if (sel & VCAP_SEL_COUNTER) {
1284		start = start & 0x7ff; /* counter limit */
1285		admin->cache.counter =
1286			spx5_rd(sparx5, EACL_ES2_CNT(start));
1287		admin->cache.sticky =
1288			spx5_rd(sparx5, VCAP_ES2_VCAP_CNT_DAT(0));
1289	}
1290}
1291
1292/* API callback used for reading from the VCAP into the VCAP cache */
1293static void sparx5_vcap_cache_read(struct net_device *ndev,
1294				   struct vcap_admin *admin,
1295				   enum vcap_selection sel,
1296				   u32 start,
1297				   u32 count)
1298{
1299	struct sparx5_port *port = netdev_priv(ndev);
1300	struct sparx5 *sparx5 = port->sparx5;
1301
1302	switch (admin->vtype) {
1303	case VCAP_TYPE_IS0:
1304		sparx5_vcap_is0_cache_read(sparx5, admin, sel, start, count);
1305		break;
1306	case VCAP_TYPE_IS2:
1307		sparx5_vcap_is2_cache_read(sparx5, admin, sel, start, count);
1308		break;
1309	case VCAP_TYPE_ES0:
1310		sparx5_vcap_es0_cache_read(sparx5, admin, sel, start, count);
1311		break;
1312	case VCAP_TYPE_ES2:
1313		sparx5_vcap_es2_cache_read(sparx5, admin, sel, start, count);
1314		break;
1315	default:
1316		sparx5_vcap_type_err(sparx5, admin, __func__);
1317		break;
1318	}
1319}
1320
1321/* API callback used for initializing a VCAP address range */
1322static void sparx5_vcap_range_init(struct net_device *ndev,
1323				   struct vcap_admin *admin, u32 addr,
1324				   u32 count)
1325{
1326	struct sparx5_port *port = netdev_priv(ndev);
1327	struct sparx5 *sparx5 = port->sparx5;
1328
1329	_sparx5_vcap_range_init(sparx5, admin, addr, count);
1330}
1331
1332static void sparx5_vcap_super_update(struct sparx5 *sparx5,
1333				     enum vcap_command cmd,
1334				     enum vcap_selection sel, u32 addr)
1335{
1336	bool clear = (cmd == VCAP_CMD_INITIALIZE);
1337
1338	spx5_wr(VCAP_SUPER_CFG_MV_NUM_POS_SET(0) |
1339		VCAP_SUPER_CFG_MV_SIZE_SET(0), sparx5, VCAP_SUPER_CFG);
1340	spx5_wr(VCAP_SUPER_CTRL_UPDATE_CMD_SET(cmd) |
1341		VCAP_SUPER_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) |
1342		VCAP_SUPER_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) |
1343		VCAP_SUPER_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) |
1344		VCAP_SUPER_CTRL_UPDATE_ADDR_SET(addr) |
1345		VCAP_SUPER_CTRL_CLEAR_CACHE_SET(clear) |
1346		VCAP_SUPER_CTRL_UPDATE_SHOT_SET(true),
1347		sparx5, VCAP_SUPER_CTRL);
1348	sparx5_vcap_wait_super_update(sparx5);
1349}
1350
1351static void sparx5_vcap_es0_update(struct sparx5 *sparx5,
1352				   enum vcap_command cmd,
1353				   enum vcap_selection sel, u32 addr)
1354{
1355	bool clear = (cmd == VCAP_CMD_INITIALIZE);
1356
1357	spx5_wr(VCAP_ES0_CFG_MV_NUM_POS_SET(0) |
1358		VCAP_ES0_CFG_MV_SIZE_SET(0), sparx5, VCAP_ES0_CFG);
1359	spx5_wr(VCAP_ES0_CTRL_UPDATE_CMD_SET(cmd) |
1360		VCAP_ES0_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) |
1361		VCAP_ES0_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) |
1362		VCAP_ES0_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) |
1363		VCAP_ES0_CTRL_UPDATE_ADDR_SET(addr) |
1364		VCAP_ES0_CTRL_CLEAR_CACHE_SET(clear) |
1365		VCAP_ES0_CTRL_UPDATE_SHOT_SET(true),
1366		sparx5, VCAP_ES0_CTRL);
1367	sparx5_vcap_wait_es0_update(sparx5);
1368}
1369
1370static void sparx5_vcap_es2_update(struct sparx5 *sparx5,
1371				   enum vcap_command cmd,
1372				   enum vcap_selection sel, u32 addr)
1373{
1374	bool clear = (cmd == VCAP_CMD_INITIALIZE);
1375
1376	spx5_wr(VCAP_ES2_CFG_MV_NUM_POS_SET(0) |
1377		VCAP_ES2_CFG_MV_SIZE_SET(0), sparx5, VCAP_ES2_CFG);
1378	spx5_wr(VCAP_ES2_CTRL_UPDATE_CMD_SET(cmd) |
1379		VCAP_ES2_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) |
1380		VCAP_ES2_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) |
1381		VCAP_ES2_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) |
1382		VCAP_ES2_CTRL_UPDATE_ADDR_SET(addr) |
1383		VCAP_ES2_CTRL_CLEAR_CACHE_SET(clear) |
1384		VCAP_ES2_CTRL_UPDATE_SHOT_SET(true),
1385		sparx5, VCAP_ES2_CTRL);
1386	sparx5_vcap_wait_es2_update(sparx5);
1387}
1388
1389/* API callback used for updating the VCAP cache */
1390static void sparx5_vcap_update(struct net_device *ndev,
1391			       struct vcap_admin *admin, enum vcap_command cmd,
1392			       enum vcap_selection sel, u32 addr)
1393{
1394	struct sparx5_port *port = netdev_priv(ndev);
1395	struct sparx5 *sparx5 = port->sparx5;
1396
1397	switch (admin->vtype) {
1398	case VCAP_TYPE_IS0:
1399	case VCAP_TYPE_IS2:
1400		sparx5_vcap_super_update(sparx5, cmd, sel, addr);
1401		break;
1402	case VCAP_TYPE_ES0:
1403		sparx5_vcap_es0_update(sparx5, cmd, sel, addr);
1404		break;
1405	case VCAP_TYPE_ES2:
1406		sparx5_vcap_es2_update(sparx5, cmd, sel, addr);
1407		break;
1408	default:
1409		sparx5_vcap_type_err(sparx5, admin, __func__);
1410		break;
1411	}
1412}
1413
1414static void sparx5_vcap_super_move(struct sparx5 *sparx5,
1415				   u32 addr,
1416				   enum vcap_command cmd,
1417				   u16 mv_num_pos,
1418				   u16 mv_size)
1419{
1420	spx5_wr(VCAP_SUPER_CFG_MV_NUM_POS_SET(mv_num_pos) |
1421		VCAP_SUPER_CFG_MV_SIZE_SET(mv_size),
1422		sparx5, VCAP_SUPER_CFG);
1423	spx5_wr(VCAP_SUPER_CTRL_UPDATE_CMD_SET(cmd) |
1424		VCAP_SUPER_CTRL_UPDATE_ENTRY_DIS_SET(0) |
1425		VCAP_SUPER_CTRL_UPDATE_ACTION_DIS_SET(0) |
1426		VCAP_SUPER_CTRL_UPDATE_CNT_DIS_SET(0) |
1427		VCAP_SUPER_CTRL_UPDATE_ADDR_SET(addr) |
1428		VCAP_SUPER_CTRL_CLEAR_CACHE_SET(false) |
1429		VCAP_SUPER_CTRL_UPDATE_SHOT_SET(true),
1430		sparx5, VCAP_SUPER_CTRL);
1431	sparx5_vcap_wait_super_update(sparx5);
1432}
1433
1434static void sparx5_vcap_es0_move(struct sparx5 *sparx5,
1435				 u32 addr,
1436				 enum vcap_command cmd,
1437				 u16 mv_num_pos,
1438				 u16 mv_size)
1439{
1440	spx5_wr(VCAP_ES0_CFG_MV_NUM_POS_SET(mv_num_pos) |
1441		VCAP_ES0_CFG_MV_SIZE_SET(mv_size),
1442		sparx5, VCAP_ES0_CFG);
1443	spx5_wr(VCAP_ES0_CTRL_UPDATE_CMD_SET(cmd) |
1444		VCAP_ES0_CTRL_UPDATE_ENTRY_DIS_SET(0) |
1445		VCAP_ES0_CTRL_UPDATE_ACTION_DIS_SET(0) |
1446		VCAP_ES0_CTRL_UPDATE_CNT_DIS_SET(0) |
1447		VCAP_ES0_CTRL_UPDATE_ADDR_SET(addr) |
1448		VCAP_ES0_CTRL_CLEAR_CACHE_SET(false) |
1449		VCAP_ES0_CTRL_UPDATE_SHOT_SET(true),
1450		sparx5, VCAP_ES0_CTRL);
1451	sparx5_vcap_wait_es0_update(sparx5);
1452}
1453
1454static void sparx5_vcap_es2_move(struct sparx5 *sparx5,
1455				 u32 addr,
1456				 enum vcap_command cmd,
1457				 u16 mv_num_pos,
1458				 u16 mv_size)
1459{
1460	spx5_wr(VCAP_ES2_CFG_MV_NUM_POS_SET(mv_num_pos) |
1461		VCAP_ES2_CFG_MV_SIZE_SET(mv_size),
1462		sparx5, VCAP_ES2_CFG);
1463	spx5_wr(VCAP_ES2_CTRL_UPDATE_CMD_SET(cmd) |
1464		VCAP_ES2_CTRL_UPDATE_ENTRY_DIS_SET(0) |
1465		VCAP_ES2_CTRL_UPDATE_ACTION_DIS_SET(0) |
1466		VCAP_ES2_CTRL_UPDATE_CNT_DIS_SET(0) |
1467		VCAP_ES2_CTRL_UPDATE_ADDR_SET(addr) |
1468		VCAP_ES2_CTRL_CLEAR_CACHE_SET(false) |
1469		VCAP_ES2_CTRL_UPDATE_SHOT_SET(true),
1470		sparx5, VCAP_ES2_CTRL);
1471	sparx5_vcap_wait_es2_update(sparx5);
1472}
1473
1474/* API callback used for moving a block of rules in the VCAP */
1475static void sparx5_vcap_move(struct net_device *ndev, struct vcap_admin *admin,
1476			     u32 addr, int offset, int count)
1477{
1478	struct sparx5_port *port = netdev_priv(ndev);
1479	struct sparx5 *sparx5 = port->sparx5;
1480	enum vcap_command cmd;
1481	u16 mv_num_pos;
1482	u16 mv_size;
1483
1484	mv_size = count - 1;
1485	if (offset > 0) {
1486		mv_num_pos = offset - 1;
1487		cmd = VCAP_CMD_MOVE_DOWN;
1488	} else {
1489		mv_num_pos = -offset - 1;
1490		cmd = VCAP_CMD_MOVE_UP;
1491	}
1492
1493	switch (admin->vtype) {
1494	case VCAP_TYPE_IS0:
1495	case VCAP_TYPE_IS2:
1496		sparx5_vcap_super_move(sparx5, addr, cmd, mv_num_pos, mv_size);
1497		break;
1498	case VCAP_TYPE_ES0:
1499		sparx5_vcap_es0_move(sparx5, addr, cmd, mv_num_pos, mv_size);
1500		break;
1501	case VCAP_TYPE_ES2:
1502		sparx5_vcap_es2_move(sparx5, addr, cmd, mv_num_pos, mv_size);
1503		break;
1504	default:
1505		sparx5_vcap_type_err(sparx5, admin, __func__);
1506		break;
1507	}
1508}
1509
1510static struct vcap_operations sparx5_vcap_ops = {
1511	.validate_keyset = sparx5_vcap_validate_keyset,
1512	.add_default_fields = sparx5_vcap_add_default_fields,
1513	.cache_erase = sparx5_vcap_cache_erase,
1514	.cache_write = sparx5_vcap_cache_write,
1515	.cache_read = sparx5_vcap_cache_read,
1516	.init = sparx5_vcap_range_init,
1517	.update = sparx5_vcap_update,
1518	.move = sparx5_vcap_move,
1519	.port_info = sparx5_port_info,
1520};
1521
1522static u32 sparx5_vcap_is0_keyset_to_etype_ps(enum vcap_keyfield_set keyset)
1523{
1524	switch (keyset) {
1525	case VCAP_KFS_NORMAL_7TUPLE:
1526		return VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE;
1527	case VCAP_KFS_NORMAL_5TUPLE_IP4:
1528		return VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4;
1529	default:
1530		return VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE;
1531	}
1532}
1533
1534static void sparx5_vcap_is0_set_port_keyset(struct net_device *ndev, int lookup,
1535					    enum vcap_keyfield_set keyset,
1536					    int l3_proto)
1537{
1538	struct sparx5_port *port = netdev_priv(ndev);
1539	struct sparx5 *sparx5 = port->sparx5;
1540	int portno = port->portno;
1541	u32 value;
1542
1543	switch (l3_proto) {
1544	case ETH_P_IP:
1545		value = sparx5_vcap_is0_keyset_to_etype_ps(keyset);
1546		spx5_rmw(ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL_SET(value),
1547			 ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL,
1548			 sparx5,
1549			 ANA_CL_ADV_CL_CFG(portno, lookup));
1550		break;
1551	case ETH_P_IPV6:
1552		value = sparx5_vcap_is0_keyset_to_etype_ps(keyset);
1553		spx5_rmw(ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL_SET(value),
1554			 ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL,
1555			 sparx5,
1556			 ANA_CL_ADV_CL_CFG(portno, lookup));
1557		break;
1558	default:
1559		value = sparx5_vcap_is0_keyset_to_etype_ps(keyset);
1560		spx5_rmw(ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL_SET(value),
1561			 ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL,
1562			 sparx5,
1563			 ANA_CL_ADV_CL_CFG(portno, lookup));
1564		break;
1565	}
1566}
1567
1568static u32 sparx5_vcap_is2_keyset_to_arp_ps(enum vcap_keyfield_set keyset)
1569{
1570	switch (keyset) {
1571	case VCAP_KFS_ARP:
1572		return VCAP_IS2_PS_ARP_ARP;
1573	default:
1574		return VCAP_IS2_PS_ARP_MAC_ETYPE;
1575	}
1576}
1577
1578static u32 sparx5_vcap_is2_keyset_to_ipv4_ps(enum vcap_keyfield_set keyset)
1579{
1580	switch (keyset) {
1581	case VCAP_KFS_MAC_ETYPE:
1582		return VCAP_IS2_PS_IPV4_UC_MAC_ETYPE;
1583	case VCAP_KFS_IP4_OTHER:
1584	case VCAP_KFS_IP4_TCP_UDP:
1585		return VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER;
1586	case VCAP_KFS_IP_7TUPLE:
1587		return VCAP_IS2_PS_IPV4_UC_IP_7TUPLE;
1588	default:
1589		return VCAP_KFS_NO_VALUE;
1590	}
1591}
1592
1593static u32 sparx5_vcap_is2_keyset_to_ipv6_uc_ps(enum vcap_keyfield_set keyset)
1594{
1595	switch (keyset) {
1596	case VCAP_KFS_MAC_ETYPE:
1597		return VCAP_IS2_PS_IPV6_UC_MAC_ETYPE;
1598	case VCAP_KFS_IP4_OTHER:
1599	case VCAP_KFS_IP4_TCP_UDP:
1600		return VCAP_IS2_PS_IPV6_UC_IP4_TCP_UDP_OTHER;
1601	case VCAP_KFS_IP_7TUPLE:
1602		return VCAP_IS2_PS_IPV6_UC_IP_7TUPLE;
1603	default:
1604		return VCAP_KFS_NO_VALUE;
1605	}
1606}
1607
1608static u32 sparx5_vcap_is2_keyset_to_ipv6_mc_ps(enum vcap_keyfield_set keyset)
1609{
1610	switch (keyset) {
1611	case VCAP_KFS_MAC_ETYPE:
1612		return VCAP_IS2_PS_IPV6_MC_MAC_ETYPE;
1613	case VCAP_KFS_IP4_OTHER:
1614	case VCAP_KFS_IP4_TCP_UDP:
1615		return VCAP_IS2_PS_IPV6_MC_IP4_TCP_UDP_OTHER;
1616	case VCAP_KFS_IP_7TUPLE:
1617		return VCAP_IS2_PS_IPV6_MC_IP_7TUPLE;
1618	default:
1619		return VCAP_KFS_NO_VALUE;
1620	}
1621}
1622
1623static void sparx5_vcap_is2_set_port_keyset(struct net_device *ndev, int lookup,
1624					    enum vcap_keyfield_set keyset,
1625					    int l3_proto)
1626{
1627	struct sparx5_port *port = netdev_priv(ndev);
1628	struct sparx5 *sparx5 = port->sparx5;
1629	int portno = port->portno;
1630	u32 value;
1631
1632	switch (l3_proto) {
1633	case ETH_P_ARP:
1634		value = sparx5_vcap_is2_keyset_to_arp_ps(keyset);
1635		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL_SET(value),
1636			 ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL,
1637			 sparx5,
1638			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1639		break;
1640	case ETH_P_IP:
1641		value = sparx5_vcap_is2_keyset_to_ipv4_ps(keyset);
1642		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL_SET(value),
1643			 ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL,
1644			 sparx5,
1645			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1646		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL_SET(value),
1647			 ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL,
1648			 sparx5,
1649			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1650		break;
1651	case ETH_P_IPV6:
1652		value = sparx5_vcap_is2_keyset_to_ipv6_uc_ps(keyset);
1653		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL_SET(value),
1654			 ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL,
1655			 sparx5,
1656			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1657		value = sparx5_vcap_is2_keyset_to_ipv6_mc_ps(keyset);
1658		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL_SET(value),
1659			 ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL,
1660			 sparx5,
1661			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1662		break;
1663	default:
1664		value = VCAP_IS2_PS_NONETH_MAC_ETYPE;
1665		spx5_rmw(ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL_SET(value),
1666			 ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL,
1667			 sparx5,
1668			 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1669		break;
1670	}
1671}
1672
1673static u32 sparx5_vcap_es2_keyset_to_arp_ps(enum vcap_keyfield_set keyset)
1674{
1675	switch (keyset) {
1676	case VCAP_KFS_ARP:
1677		return VCAP_ES2_PS_ARP_ARP;
1678	default:
1679		return VCAP_ES2_PS_ARP_MAC_ETYPE;
1680	}
1681}
1682
1683static u32 sparx5_vcap_es2_keyset_to_ipv4_ps(enum vcap_keyfield_set keyset)
1684{
1685	switch (keyset) {
1686	case VCAP_KFS_MAC_ETYPE:
1687		return VCAP_ES2_PS_IPV4_MAC_ETYPE;
1688	case VCAP_KFS_IP_7TUPLE:
1689		return VCAP_ES2_PS_IPV4_IP_7TUPLE;
1690	case VCAP_KFS_IP4_TCP_UDP:
1691		return VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER;
1692	case VCAP_KFS_IP4_OTHER:
1693		return VCAP_ES2_PS_IPV4_IP4_OTHER;
1694	default:
1695		return VCAP_ES2_PS_IPV4_MAC_ETYPE;
1696	}
1697}
1698
1699static u32 sparx5_vcap_es2_keyset_to_ipv6_ps(enum vcap_keyfield_set keyset)
1700{
1701	switch (keyset) {
1702	case VCAP_KFS_MAC_ETYPE:
1703		return VCAP_ES2_PS_IPV6_MAC_ETYPE;
1704	case VCAP_KFS_IP4_TCP_UDP:
1705	case VCAP_KFS_IP4_OTHER:
1706		return VCAP_ES2_PS_IPV6_IP4_DOWNGRADE;
1707	case VCAP_KFS_IP_7TUPLE:
1708		return VCAP_ES2_PS_IPV6_IP_7TUPLE;
1709	case VCAP_KFS_IP6_STD:
1710		return VCAP_ES2_PS_IPV6_IP6_STD;
1711	default:
1712		return VCAP_ES2_PS_IPV6_MAC_ETYPE;
1713	}
1714}
1715
1716static void sparx5_vcap_es2_set_port_keyset(struct net_device *ndev, int lookup,
1717					    enum vcap_keyfield_set keyset,
1718					    int l3_proto)
1719{
1720	struct sparx5_port *port = netdev_priv(ndev);
1721	struct sparx5 *sparx5 = port->sparx5;
1722	int portno = port->portno;
1723	u32 value;
1724
1725	switch (l3_proto) {
1726	case ETH_P_IP:
1727		value = sparx5_vcap_es2_keyset_to_ipv4_ps(keyset);
1728		spx5_rmw(EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL_SET(value),
1729			 EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL,
1730			 sparx5,
1731			 EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1732		break;
1733	case ETH_P_IPV6:
1734		value = sparx5_vcap_es2_keyset_to_ipv6_ps(keyset);
1735		spx5_rmw(EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL_SET(value),
1736			 EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL,
1737			 sparx5,
1738			 EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1739		break;
1740	case ETH_P_ARP:
1741		value = sparx5_vcap_es2_keyset_to_arp_ps(keyset);
1742		spx5_rmw(EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL_SET(value),
1743			 EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL,
1744			 sparx5,
1745			 EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1746		break;
1747	}
1748}
1749
1750/* Change the port keyset for the lookup and protocol */
1751void sparx5_vcap_set_port_keyset(struct net_device *ndev,
1752				 struct vcap_admin *admin,
1753				 int cid,
1754				 u16 l3_proto,
1755				 enum vcap_keyfield_set keyset,
1756				 struct vcap_keyset_list *orig)
1757{
1758	struct sparx5_port *port;
1759	int lookup;
1760
1761	switch (admin->vtype) {
1762	case VCAP_TYPE_IS0:
1763		lookup = sparx5_vcap_is0_cid_to_lookup(cid);
1764		if (orig)
1765			sparx5_vcap_is0_get_port_keysets(ndev, lookup, orig,
1766							 l3_proto);
1767		sparx5_vcap_is0_set_port_keyset(ndev, lookup, keyset, l3_proto);
1768		break;
1769	case VCAP_TYPE_IS2:
1770		lookup = sparx5_vcap_is2_cid_to_lookup(cid);
1771		if (orig)
1772			sparx5_vcap_is2_get_port_keysets(ndev, lookup, orig,
1773							 l3_proto);
1774		sparx5_vcap_is2_set_port_keyset(ndev, lookup, keyset, l3_proto);
1775		break;
1776	case VCAP_TYPE_ES0:
1777		break;
1778	case VCAP_TYPE_ES2:
1779		lookup = sparx5_vcap_es2_cid_to_lookup(cid);
1780		if (orig)
1781			sparx5_vcap_es2_get_port_keysets(ndev, lookup, orig,
1782							 l3_proto);
1783		sparx5_vcap_es2_set_port_keyset(ndev, lookup, keyset, l3_proto);
1784		break;
1785	default:
1786		port = netdev_priv(ndev);
1787		sparx5_vcap_type_err(port->sparx5, admin, __func__);
1788		break;
1789	}
1790}
1791
1792/* Enable IS0 lookups per port and set the keyset generation */
1793static void sparx5_vcap_is0_port_key_selection(struct sparx5 *sparx5,
1794					       struct vcap_admin *admin)
1795{
1796	int portno, lookup;
1797	u32 keysel;
1798
1799	keysel = VCAP_IS0_KEYSEL(false,
1800				 VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE,
1801				 VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4,
1802				 VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE,
1803				 VCAP_IS0_PS_MPLS_FOLLOW_ETYPE,
1804				 VCAP_IS0_PS_MPLS_FOLLOW_ETYPE,
1805				 VCAP_IS0_PS_MLBS_FOLLOW_ETYPE);
1806	for (lookup = 0; lookup < admin->lookups; ++lookup) {
1807		for (portno = 0; portno < SPX5_PORTS; ++portno) {
1808			spx5_wr(keysel, sparx5,
1809				ANA_CL_ADV_CL_CFG(portno, lookup));
1810			spx5_rmw(ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1811				 ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1812				 sparx5,
1813				 ANA_CL_ADV_CL_CFG(portno, lookup));
1814		}
1815	}
1816}
1817
1818/* Enable IS2 lookups per port and set the keyset generation */
1819static void sparx5_vcap_is2_port_key_selection(struct sparx5 *sparx5,
1820					       struct vcap_admin *admin)
1821{
1822	int portno, lookup;
1823	u32 keysel;
1824
1825	keysel = VCAP_IS2_KEYSEL(true, VCAP_IS2_PS_NONETH_MAC_ETYPE,
1826				 VCAP_IS2_PS_IPV4_MC_IP4_TCP_UDP_OTHER,
1827				 VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER,
1828				 VCAP_IS2_PS_IPV6_MC_IP_7TUPLE,
1829				 VCAP_IS2_PS_IPV6_UC_IP_7TUPLE,
1830				 VCAP_IS2_PS_ARP_ARP);
1831	for (lookup = 0; lookup < admin->lookups; ++lookup) {
1832		for (portno = 0; portno < SPX5_PORTS; ++portno) {
1833			spx5_wr(keysel, sparx5,
1834				ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
1835		}
1836	}
1837	/* IS2 lookups are in bit 0:3 */
1838	for (portno = 0; portno < SPX5_PORTS; ++portno)
1839		spx5_rmw(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0xf),
1840			 ANA_ACL_VCAP_S2_CFG_SEC_ENA,
1841			 sparx5,
1842			 ANA_ACL_VCAP_S2_CFG(portno));
1843}
1844
1845/* Enable ES0 lookups per port and set the keyset generation */
1846static void sparx5_vcap_es0_port_key_selection(struct sparx5 *sparx5,
1847					       struct vcap_admin *admin)
1848{
1849	int portno;
1850	u32 keysel;
1851
1852	keysel = VCAP_ES0_KEYSEL(VCAP_ES0_PS_FORCE_ISDX_LOOKUPS);
1853	for (portno = 0; portno < SPX5_PORTS; ++portno)
1854		spx5_rmw(keysel, REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA,
1855			 sparx5, REW_RTAG_ETAG_CTRL(portno));
1856
1857	spx5_rmw(REW_ES0_CTRL_ES0_LU_ENA_SET(1), REW_ES0_CTRL_ES0_LU_ENA,
1858		 sparx5, REW_ES0_CTRL);
1859}
1860
1861/* Enable ES2 lookups per port and set the keyset generation */
1862static void sparx5_vcap_es2_port_key_selection(struct sparx5 *sparx5,
1863					       struct vcap_admin *admin)
1864{
1865	int portno, lookup;
1866	u32 keysel;
1867
1868	keysel = VCAP_ES2_KEYSEL(true, VCAP_ES2_PS_ARP_MAC_ETYPE,
1869				 VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER,
1870				 VCAP_ES2_PS_IPV6_IP_7TUPLE);
1871	for (lookup = 0; lookup < admin->lookups; ++lookup)
1872		for (portno = 0; portno < SPX5_PORTS; ++portno)
1873			spx5_wr(keysel, sparx5,
1874				EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1875}
1876
1877/* Enable lookups per port and set the keyset generation */
1878static void sparx5_vcap_port_key_selection(struct sparx5 *sparx5,
1879					   struct vcap_admin *admin)
1880{
1881	switch (admin->vtype) {
1882	case VCAP_TYPE_IS0:
1883		sparx5_vcap_is0_port_key_selection(sparx5, admin);
1884		break;
1885	case VCAP_TYPE_IS2:
1886		sparx5_vcap_is2_port_key_selection(sparx5, admin);
1887		break;
1888	case VCAP_TYPE_ES0:
1889		sparx5_vcap_es0_port_key_selection(sparx5, admin);
1890		break;
1891	case VCAP_TYPE_ES2:
1892		sparx5_vcap_es2_port_key_selection(sparx5, admin);
1893		break;
1894	default:
1895		sparx5_vcap_type_err(sparx5, admin, __func__);
1896		break;
1897	}
1898}
1899
1900/* Disable lookups per port */
1901static void sparx5_vcap_port_key_deselection(struct sparx5 *sparx5,
1902					     struct vcap_admin *admin)
1903{
1904	int portno, lookup;
1905
1906	switch (admin->vtype) {
1907	case VCAP_TYPE_IS0:
1908		for (lookup = 0; lookup < admin->lookups; ++lookup)
1909			for (portno = 0; portno < SPX5_PORTS; ++portno)
1910				spx5_rmw(ANA_CL_ADV_CL_CFG_LOOKUP_ENA_SET(0),
1911					 ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
1912					 sparx5,
1913					 ANA_CL_ADV_CL_CFG(portno, lookup));
1914		break;
1915	case VCAP_TYPE_IS2:
1916		for (portno = 0; portno < SPX5_PORTS; ++portno)
1917			spx5_rmw(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0),
1918				 ANA_ACL_VCAP_S2_CFG_SEC_ENA,
1919				 sparx5,
1920				 ANA_ACL_VCAP_S2_CFG(portno));
1921		break;
1922	case VCAP_TYPE_ES0:
1923		spx5_rmw(REW_ES0_CTRL_ES0_LU_ENA_SET(0),
1924			 REW_ES0_CTRL_ES0_LU_ENA, sparx5, REW_ES0_CTRL);
1925		break;
1926	case VCAP_TYPE_ES2:
1927		for (lookup = 0; lookup < admin->lookups; ++lookup)
1928			for (portno = 0; portno < SPX5_PORTS; ++portno)
1929				spx5_rmw(EACL_VCAP_ES2_KEY_SEL_KEY_ENA_SET(0),
1930					 EACL_VCAP_ES2_KEY_SEL_KEY_ENA,
1931					 sparx5,
1932					 EACL_VCAP_ES2_KEY_SEL(portno, lookup));
1933		break;
1934	default:
1935		sparx5_vcap_type_err(sparx5, admin, __func__);
1936		break;
1937	}
1938}
1939
1940static void sparx5_vcap_admin_free(struct vcap_admin *admin)
1941{
1942	if (!admin)
1943		return;
1944	mutex_destroy(&admin->lock);
1945	kfree(admin->cache.keystream);
1946	kfree(admin->cache.maskstream);
1947	kfree(admin->cache.actionstream);
1948	kfree(admin);
1949}
1950
1951/* Allocate a vcap instance with a rule list and a cache area */
1952static struct vcap_admin *
1953sparx5_vcap_admin_alloc(struct sparx5 *sparx5, struct vcap_control *ctrl,
1954			const struct sparx5_vcap_inst *cfg)
1955{
1956	struct vcap_admin *admin;
1957
1958	admin = kzalloc(sizeof(*admin), GFP_KERNEL);
1959	if (!admin)
1960		return ERR_PTR(-ENOMEM);
1961	INIT_LIST_HEAD(&admin->list);
1962	INIT_LIST_HEAD(&admin->rules);
1963	INIT_LIST_HEAD(&admin->enabled);
1964	mutex_init(&admin->lock);
1965	admin->vtype = cfg->vtype;
1966	admin->vinst = cfg->vinst;
1967	admin->ingress = cfg->ingress;
1968	admin->lookups = cfg->lookups;
1969	admin->lookups_per_instance = cfg->lookups_per_instance;
1970	admin->first_cid = cfg->first_cid;
1971	admin->last_cid = cfg->last_cid;
1972	admin->cache.keystream =
1973		kzalloc(STREAMSIZE, GFP_KERNEL);
1974	admin->cache.maskstream =
1975		kzalloc(STREAMSIZE, GFP_KERNEL);
1976	admin->cache.actionstream =
1977		kzalloc(STREAMSIZE, GFP_KERNEL);
1978	if (!admin->cache.keystream || !admin->cache.maskstream ||
1979	    !admin->cache.actionstream) {
1980		sparx5_vcap_admin_free(admin);
1981		return ERR_PTR(-ENOMEM);
1982	}
1983	return admin;
1984}
1985
1986/* Do block allocations and provide addresses for VCAP instances */
1987static void sparx5_vcap_block_alloc(struct sparx5 *sparx5,
1988				    struct vcap_admin *admin,
1989				    const struct sparx5_vcap_inst *cfg)
1990{
1991	int idx, cores;
1992
1993	switch (admin->vtype) {
1994	case VCAP_TYPE_IS0:
1995	case VCAP_TYPE_IS2:
1996		/* Super VCAP block mapping and address configuration. Block 0
1997		 * is assigned addresses 0 through 3071, block 1 is assigned
1998		 * addresses 3072 though 6143, and so on.
1999		 */
2000		for (idx = cfg->blockno; idx < cfg->blockno + cfg->blocks;
2001		     ++idx) {
2002			spx5_wr(VCAP_SUPER_IDX_CORE_IDX_SET(idx), sparx5,
2003				VCAP_SUPER_IDX);
2004			spx5_wr(VCAP_SUPER_MAP_CORE_MAP_SET(cfg->map_id),
2005				sparx5, VCAP_SUPER_MAP);
2006		}
2007		admin->first_valid_addr = cfg->blockno * SUPER_VCAP_BLK_SIZE;
2008		admin->last_used_addr = admin->first_valid_addr +
2009			cfg->blocks * SUPER_VCAP_BLK_SIZE;
2010		admin->last_valid_addr = admin->last_used_addr - 1;
2011		break;
2012	case VCAP_TYPE_ES0:
2013		admin->first_valid_addr = 0;
2014		admin->last_used_addr = cfg->count;
2015		admin->last_valid_addr = cfg->count - 1;
2016		cores = spx5_rd(sparx5, VCAP_ES0_CORE_CNT);
2017		for (idx = 0; idx < cores; ++idx) {
2018			spx5_wr(VCAP_ES0_IDX_CORE_IDX_SET(idx), sparx5,
2019				VCAP_ES0_IDX);
2020			spx5_wr(VCAP_ES0_MAP_CORE_MAP_SET(1), sparx5,
2021				VCAP_ES0_MAP);
2022		}
2023		break;
2024	case VCAP_TYPE_ES2:
2025		admin->first_valid_addr = 0;
2026		admin->last_used_addr = cfg->count;
2027		admin->last_valid_addr = cfg->count - 1;
2028		cores = spx5_rd(sparx5, VCAP_ES2_CORE_CNT);
2029		for (idx = 0; idx < cores; ++idx) {
2030			spx5_wr(VCAP_ES2_IDX_CORE_IDX_SET(idx), sparx5,
2031				VCAP_ES2_IDX);
2032			spx5_wr(VCAP_ES2_MAP_CORE_MAP_SET(1), sparx5,
2033				VCAP_ES2_MAP);
2034		}
2035		break;
2036	default:
2037		sparx5_vcap_type_err(sparx5, admin, __func__);
2038		break;
2039	}
2040}
2041
2042/* Allocate a vcap control and vcap instances and configure the system */
2043int sparx5_vcap_init(struct sparx5 *sparx5)
2044{
2045	const struct sparx5_vcap_inst *cfg;
2046	struct vcap_control *ctrl;
2047	struct vcap_admin *admin;
2048	struct dentry *dir;
2049	int err = 0, idx;
2050
2051	/* Create a VCAP control instance that owns the platform specific VCAP
2052	 * model with VCAP instances and information about keysets, keys,
2053	 * actionsets and actions
2054	 * - Create administrative state for each available VCAP
2055	 *   - Lists of rules
2056	 *   - Address information
2057	 *   - Initialize VCAP blocks
2058	 *   - Configure port keysets
2059	 */
2060	ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
2061	if (!ctrl)
2062		return -ENOMEM;
2063
2064	sparx5->vcap_ctrl = ctrl;
2065	/* select the sparx5 VCAP model */
2066	ctrl->vcaps = sparx5_vcaps;
2067	ctrl->stats = &sparx5_vcap_stats;
2068	/* Setup callbacks to allow the API to use the VCAP HW */
2069	ctrl->ops = &sparx5_vcap_ops;
2070
2071	INIT_LIST_HEAD(&ctrl->list);
2072	for (idx = 0; idx < ARRAY_SIZE(sparx5_vcap_inst_cfg); ++idx) {
2073		cfg = &sparx5_vcap_inst_cfg[idx];
2074		admin = sparx5_vcap_admin_alloc(sparx5, ctrl, cfg);
2075		if (IS_ERR(admin)) {
2076			err = PTR_ERR(admin);
2077			pr_err("%s:%d: vcap allocation failed: %d\n",
2078			       __func__, __LINE__, err);
2079			return err;
2080		}
2081		sparx5_vcap_block_alloc(sparx5, admin, cfg);
2082		sparx5_vcap_block_init(sparx5, admin);
2083		if (cfg->vinst == 0)
2084			sparx5_vcap_port_key_selection(sparx5, admin);
2085		list_add_tail(&admin->list, &ctrl->list);
2086	}
2087	dir = vcap_debugfs(sparx5->dev, sparx5->debugfs_root, ctrl);
2088	for (idx = 0; idx < SPX5_PORTS; ++idx)
2089		if (sparx5->ports[idx])
2090			vcap_port_debugfs(sparx5->dev, dir, ctrl,
2091					  sparx5->ports[idx]->ndev);
2092
2093	return err;
2094}
2095
2096void sparx5_vcap_destroy(struct sparx5 *sparx5)
2097{
2098	struct vcap_control *ctrl = sparx5->vcap_ctrl;
2099	struct vcap_admin *admin, *admin_next;
2100
2101	if (!ctrl)
2102		return;
2103
2104	list_for_each_entry_safe(admin, admin_next, &ctrl->list, list) {
2105		sparx5_vcap_port_key_deselection(sparx5, admin);
2106		vcap_del_rules(ctrl, admin);
2107		list_del(&admin->list);
2108		sparx5_vcap_admin_free(admin);
2109	}
2110	kfree(ctrl);
2111}