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 48 const 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 */ 130 static 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 */ 137 static 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 */ 145 static u16 sparx5_vcap_es2_known_etypes[] = { 146 ETH_P_ALL, 147 ETH_P_ARP, 148 ETH_P_IP, 149 ETH_P_IPV6, 150 }; 151 152 static 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 */ 161 static 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 */ 171 static 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 */ 181 static 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 */ 191 static 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 */ 248 static 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 */ 257 static 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 */ 266 static 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 */ 277 static 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 285 static 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 */ 292 static 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 */ 308 static 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 323 static 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 */ 345 static 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 */ 364 static 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 */ 379 static 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 */ 390 static void 391 sparx5_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 */ 405 static 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 */ 459 static 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 */ 561 static void 562 sparx5_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 */ 589 static 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 */ 613 static 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 */ 676 int 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 */ 713 bool 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) */ 743 static enum vcap_keyfield_set 744 sparx5_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 800 static 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 832 static 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 844 static 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 */ 868 static 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) */ 894 static 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 902 static 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 943 static 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 */ 992 static 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 1003 static 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 1044 static 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 */ 1087 static 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 1115 static 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 1150 static 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 */ 1191 static 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 1205 static 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 1240 static 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 */ 1277 static 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 */ 1306 static 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 1316 static 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 1335 static 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 1354 static 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 */ 1374 static 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 1398 static 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 1418 static 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 1438 static 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 */ 1459 static 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 1494 static 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 1506 static 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 1518 static 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 1552 static 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 1562 static 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 1577 static 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 1592 static 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 1607 static 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 1657 static 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 1667 static 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 1683 static 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 1700 static 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 */ 1735 void 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 */ 1777 static 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 */ 1804 static 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 */ 1832 static 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 */ 1849 static 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 */ 1866 static 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 */ 1889 static 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 1929 static 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 */ 1941 static struct vcap_admin * 1942 sparx5_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 */ 1976 static 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 */ 2032 int 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 2086 void 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 } 2102