Linux Audio

Check our new training course

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