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