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 } 856 857 static void sparx5_vcap_es2_add_default_fields(struct net_device *ndev, 858 struct vcap_admin *admin, 859 struct vcap_rule *rule) 860 { 861 const struct vcap_field *field; 862 bool is_first; 863 864 /* Add egress port mask matching the net device */ 865 field = vcap_lookup_keyfield(rule, VCAP_KF_IF_EGR_PORT_MASK); 866 if (field) 867 sparx5_vcap_add_egress_range_port_mask(rule, ndev); 868 869 /* Add key that selects the first/second lookup */ 870 is_first = sparx5_vcap_es2_is_first_chain(rule); 871 872 if (is_first) 873 vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, 874 VCAP_BIT_1); 875 else 876 vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, 877 VCAP_BIT_0); 878 } 879 880 /* API callback used for adding default fields to a rule */ 881 static void sparx5_vcap_add_default_fields(struct net_device *ndev, 882 struct vcap_admin *admin, 883 struct vcap_rule *rule) 884 { 885 struct sparx5_port *port; 886 887 /* add the lookup bit */ 888 switch (admin->vtype) { 889 case VCAP_TYPE_IS0: 890 case VCAP_TYPE_IS2: 891 sparx5_vcap_ingress_add_default_fields(ndev, admin, rule); 892 break; 893 case VCAP_TYPE_ES0: 894 sparx5_vcap_es0_add_default_fields(ndev, admin, rule); 895 break; 896 case VCAP_TYPE_ES2: 897 sparx5_vcap_es2_add_default_fields(ndev, admin, rule); 898 break; 899 default: 900 port = netdev_priv(ndev); 901 sparx5_vcap_type_err(port->sparx5, admin, __func__); 902 break; 903 } 904 } 905 906 /* API callback used for erasing the vcap cache area (not the register area) */ 907 static void sparx5_vcap_cache_erase(struct vcap_admin *admin) 908 { 909 memset(admin->cache.keystream, 0, STREAMSIZE); 910 memset(admin->cache.maskstream, 0, STREAMSIZE); 911 memset(admin->cache.actionstream, 0, STREAMSIZE); 912 memset(&admin->cache.counter, 0, sizeof(admin->cache.counter)); 913 } 914 915 static void sparx5_vcap_is0_cache_write(struct sparx5 *sparx5, 916 struct vcap_admin *admin, 917 enum vcap_selection sel, 918 u32 start, 919 u32 count) 920 { 921 u32 *keystr, *mskstr, *actstr; 922 int idx; 923 924 keystr = &admin->cache.keystream[start]; 925 mskstr = &admin->cache.maskstream[start]; 926 actstr = &admin->cache.actionstream[start]; 927 928 switch (sel) { 929 case VCAP_SEL_ENTRY: 930 for (idx = 0; idx < count; ++idx) { 931 /* Avoid 'match-off' by setting value & mask */ 932 spx5_wr(keystr[idx] & mskstr[idx], sparx5, 933 VCAP_SUPER_VCAP_ENTRY_DAT(idx)); 934 spx5_wr(~mskstr[idx], sparx5, 935 VCAP_SUPER_VCAP_MASK_DAT(idx)); 936 } 937 break; 938 case VCAP_SEL_ACTION: 939 for (idx = 0; idx < count; ++idx) 940 spx5_wr(actstr[idx], sparx5, 941 VCAP_SUPER_VCAP_ACTION_DAT(idx)); 942 break; 943 case VCAP_SEL_ALL: 944 pr_err("%s:%d: cannot write all streams at once\n", 945 __func__, __LINE__); 946 break; 947 default: 948 break; 949 } 950 951 if (sel & VCAP_SEL_COUNTER) 952 spx5_wr(admin->cache.counter, sparx5, 953 VCAP_SUPER_VCAP_CNT_DAT(0)); 954 } 955 956 static void sparx5_vcap_is2_cache_write(struct sparx5 *sparx5, 957 struct vcap_admin *admin, 958 enum vcap_selection sel, 959 u32 start, 960 u32 count) 961 { 962 u32 *keystr, *mskstr, *actstr; 963 int idx; 964 965 keystr = &admin->cache.keystream[start]; 966 mskstr = &admin->cache.maskstream[start]; 967 actstr = &admin->cache.actionstream[start]; 968 969 switch (sel) { 970 case VCAP_SEL_ENTRY: 971 for (idx = 0; idx < count; ++idx) { 972 /* Avoid 'match-off' by setting value & mask */ 973 spx5_wr(keystr[idx] & mskstr[idx], sparx5, 974 VCAP_SUPER_VCAP_ENTRY_DAT(idx)); 975 spx5_wr(~mskstr[idx], sparx5, 976 VCAP_SUPER_VCAP_MASK_DAT(idx)); 977 } 978 break; 979 case VCAP_SEL_ACTION: 980 for (idx = 0; idx < count; ++idx) 981 spx5_wr(actstr[idx], sparx5, 982 VCAP_SUPER_VCAP_ACTION_DAT(idx)); 983 break; 984 case VCAP_SEL_ALL: 985 pr_err("%s:%d: cannot write all streams at once\n", 986 __func__, __LINE__); 987 break; 988 default: 989 break; 990 } 991 if (sel & VCAP_SEL_COUNTER) { 992 start = start & 0xfff; /* counter limit */ 993 if (admin->vinst == 0) 994 spx5_wr(admin->cache.counter, sparx5, 995 ANA_ACL_CNT_A(start)); 996 else 997 spx5_wr(admin->cache.counter, sparx5, 998 ANA_ACL_CNT_B(start)); 999 spx5_wr(admin->cache.sticky, sparx5, 1000 VCAP_SUPER_VCAP_CNT_DAT(0)); 1001 } 1002 } 1003 1004 /* Use ESDX counters located in the XQS */ 1005 static void sparx5_es0_write_esdx_counter(struct sparx5 *sparx5, 1006 struct vcap_admin *admin, u32 id) 1007 { 1008 mutex_lock(&sparx5->queue_stats_lock); 1009 spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(id), sparx5, XQS_STAT_CFG); 1010 spx5_wr(admin->cache.counter, sparx5, 1011 XQS_CNT(SPARX5_STAT_ESDX_GRN_PKTS)); 1012 spx5_wr(0, sparx5, XQS_CNT(SPARX5_STAT_ESDX_YEL_PKTS)); 1013 mutex_unlock(&sparx5->queue_stats_lock); 1014 } 1015 1016 static void sparx5_vcap_es0_cache_write(struct sparx5 *sparx5, 1017 struct vcap_admin *admin, 1018 enum vcap_selection sel, 1019 u32 start, 1020 u32 count) 1021 { 1022 u32 *keystr, *mskstr, *actstr; 1023 int idx; 1024 1025 keystr = &admin->cache.keystream[start]; 1026 mskstr = &admin->cache.maskstream[start]; 1027 actstr = &admin->cache.actionstream[start]; 1028 1029 switch (sel) { 1030 case VCAP_SEL_ENTRY: 1031 for (idx = 0; idx < count; ++idx) { 1032 /* Avoid 'match-off' by setting value & mask */ 1033 spx5_wr(keystr[idx] & mskstr[idx], sparx5, 1034 VCAP_ES0_VCAP_ENTRY_DAT(idx)); 1035 spx5_wr(~mskstr[idx], sparx5, 1036 VCAP_ES0_VCAP_MASK_DAT(idx)); 1037 } 1038 break; 1039 case VCAP_SEL_ACTION: 1040 for (idx = 0; idx < count; ++idx) 1041 spx5_wr(actstr[idx], sparx5, 1042 VCAP_ES0_VCAP_ACTION_DAT(idx)); 1043 break; 1044 case VCAP_SEL_ALL: 1045 pr_err("%s:%d: cannot write all streams at once\n", 1046 __func__, __LINE__); 1047 break; 1048 default: 1049 break; 1050 } 1051 if (sel & VCAP_SEL_COUNTER) { 1052 spx5_wr(admin->cache.counter, sparx5, VCAP_ES0_VCAP_CNT_DAT(0)); 1053 sparx5_es0_write_esdx_counter(sparx5, admin, start); 1054 } 1055 } 1056 1057 static void sparx5_vcap_es2_cache_write(struct sparx5 *sparx5, 1058 struct vcap_admin *admin, 1059 enum vcap_selection sel, 1060 u32 start, 1061 u32 count) 1062 { 1063 u32 *keystr, *mskstr, *actstr; 1064 int idx; 1065 1066 keystr = &admin->cache.keystream[start]; 1067 mskstr = &admin->cache.maskstream[start]; 1068 actstr = &admin->cache.actionstream[start]; 1069 1070 switch (sel) { 1071 case VCAP_SEL_ENTRY: 1072 for (idx = 0; idx < count; ++idx) { 1073 /* Avoid 'match-off' by setting value & mask */ 1074 spx5_wr(keystr[idx] & mskstr[idx], sparx5, 1075 VCAP_ES2_VCAP_ENTRY_DAT(idx)); 1076 spx5_wr(~mskstr[idx], sparx5, 1077 VCAP_ES2_VCAP_MASK_DAT(idx)); 1078 } 1079 break; 1080 case VCAP_SEL_ACTION: 1081 for (idx = 0; idx < count; ++idx) 1082 spx5_wr(actstr[idx], sparx5, 1083 VCAP_ES2_VCAP_ACTION_DAT(idx)); 1084 break; 1085 case VCAP_SEL_ALL: 1086 pr_err("%s:%d: cannot write all streams at once\n", 1087 __func__, __LINE__); 1088 break; 1089 default: 1090 break; 1091 } 1092 if (sel & VCAP_SEL_COUNTER) { 1093 start = start & 0x7ff; /* counter limit */ 1094 spx5_wr(admin->cache.counter, sparx5, EACL_ES2_CNT(start)); 1095 spx5_wr(admin->cache.sticky, sparx5, VCAP_ES2_VCAP_CNT_DAT(0)); 1096 } 1097 } 1098 1099 /* API callback used for writing to the VCAP cache */ 1100 static void sparx5_vcap_cache_write(struct net_device *ndev, 1101 struct vcap_admin *admin, 1102 enum vcap_selection sel, 1103 u32 start, 1104 u32 count) 1105 { 1106 struct sparx5_port *port = netdev_priv(ndev); 1107 struct sparx5 *sparx5 = port->sparx5; 1108 1109 switch (admin->vtype) { 1110 case VCAP_TYPE_IS0: 1111 sparx5_vcap_is0_cache_write(sparx5, admin, sel, start, count); 1112 break; 1113 case VCAP_TYPE_IS2: 1114 sparx5_vcap_is2_cache_write(sparx5, admin, sel, start, count); 1115 break; 1116 case VCAP_TYPE_ES0: 1117 sparx5_vcap_es0_cache_write(sparx5, admin, sel, start, count); 1118 break; 1119 case VCAP_TYPE_ES2: 1120 sparx5_vcap_es2_cache_write(sparx5, admin, sel, start, count); 1121 break; 1122 default: 1123 sparx5_vcap_type_err(sparx5, admin, __func__); 1124 break; 1125 } 1126 } 1127 1128 static void sparx5_vcap_is0_cache_read(struct sparx5 *sparx5, 1129 struct vcap_admin *admin, 1130 enum vcap_selection sel, 1131 u32 start, 1132 u32 count) 1133 { 1134 u32 *keystr, *mskstr, *actstr; 1135 int idx; 1136 1137 keystr = &admin->cache.keystream[start]; 1138 mskstr = &admin->cache.maskstream[start]; 1139 actstr = &admin->cache.actionstream[start]; 1140 1141 if (sel & VCAP_SEL_ENTRY) { 1142 for (idx = 0; idx < count; ++idx) { 1143 keystr[idx] = spx5_rd(sparx5, 1144 VCAP_SUPER_VCAP_ENTRY_DAT(idx)); 1145 mskstr[idx] = ~spx5_rd(sparx5, 1146 VCAP_SUPER_VCAP_MASK_DAT(idx)); 1147 } 1148 } 1149 1150 if (sel & VCAP_SEL_ACTION) 1151 for (idx = 0; idx < count; ++idx) 1152 actstr[idx] = spx5_rd(sparx5, 1153 VCAP_SUPER_VCAP_ACTION_DAT(idx)); 1154 1155 if (sel & VCAP_SEL_COUNTER) { 1156 admin->cache.counter = 1157 spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0)); 1158 admin->cache.sticky = 1159 spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0)); 1160 } 1161 } 1162 1163 static void sparx5_vcap_is2_cache_read(struct sparx5 *sparx5, 1164 struct vcap_admin *admin, 1165 enum vcap_selection sel, 1166 u32 start, 1167 u32 count) 1168 { 1169 u32 *keystr, *mskstr, *actstr; 1170 int idx; 1171 1172 keystr = &admin->cache.keystream[start]; 1173 mskstr = &admin->cache.maskstream[start]; 1174 actstr = &admin->cache.actionstream[start]; 1175 1176 if (sel & VCAP_SEL_ENTRY) { 1177 for (idx = 0; idx < count; ++idx) { 1178 keystr[idx] = spx5_rd(sparx5, 1179 VCAP_SUPER_VCAP_ENTRY_DAT(idx)); 1180 mskstr[idx] = ~spx5_rd(sparx5, 1181 VCAP_SUPER_VCAP_MASK_DAT(idx)); 1182 } 1183 } 1184 1185 if (sel & VCAP_SEL_ACTION) 1186 for (idx = 0; idx < count; ++idx) 1187 actstr[idx] = spx5_rd(sparx5, 1188 VCAP_SUPER_VCAP_ACTION_DAT(idx)); 1189 1190 if (sel & VCAP_SEL_COUNTER) { 1191 start = start & 0xfff; /* counter limit */ 1192 if (admin->vinst == 0) 1193 admin->cache.counter = 1194 spx5_rd(sparx5, ANA_ACL_CNT_A(start)); 1195 else 1196 admin->cache.counter = 1197 spx5_rd(sparx5, ANA_ACL_CNT_B(start)); 1198 admin->cache.sticky = 1199 spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0)); 1200 } 1201 } 1202 1203 /* Use ESDX counters located in the XQS */ 1204 static void sparx5_es0_read_esdx_counter(struct sparx5 *sparx5, 1205 struct vcap_admin *admin, u32 id) 1206 { 1207 u32 counter; 1208 1209 mutex_lock(&sparx5->queue_stats_lock); 1210 spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(id), sparx5, XQS_STAT_CFG); 1211 counter = spx5_rd(sparx5, XQS_CNT(SPARX5_STAT_ESDX_GRN_PKTS)) + 1212 spx5_rd(sparx5, XQS_CNT(SPARX5_STAT_ESDX_YEL_PKTS)); 1213 mutex_unlock(&sparx5->queue_stats_lock); 1214 if (counter) 1215 admin->cache.counter = counter; 1216 } 1217 1218 static void sparx5_vcap_es0_cache_read(struct sparx5 *sparx5, 1219 struct vcap_admin *admin, 1220 enum vcap_selection sel, 1221 u32 start, 1222 u32 count) 1223 { 1224 u32 *keystr, *mskstr, *actstr; 1225 int idx; 1226 1227 keystr = &admin->cache.keystream[start]; 1228 mskstr = &admin->cache.maskstream[start]; 1229 actstr = &admin->cache.actionstream[start]; 1230 1231 if (sel & VCAP_SEL_ENTRY) { 1232 for (idx = 0; idx < count; ++idx) { 1233 keystr[idx] = 1234 spx5_rd(sparx5, VCAP_ES0_VCAP_ENTRY_DAT(idx)); 1235 mskstr[idx] = 1236 ~spx5_rd(sparx5, VCAP_ES0_VCAP_MASK_DAT(idx)); 1237 } 1238 } 1239 1240 if (sel & VCAP_SEL_ACTION) 1241 for (idx = 0; idx < count; ++idx) 1242 actstr[idx] = 1243 spx5_rd(sparx5, VCAP_ES0_VCAP_ACTION_DAT(idx)); 1244 1245 if (sel & VCAP_SEL_COUNTER) { 1246 admin->cache.counter = 1247 spx5_rd(sparx5, VCAP_ES0_VCAP_CNT_DAT(0)); 1248 admin->cache.sticky = admin->cache.counter; 1249 sparx5_es0_read_esdx_counter(sparx5, admin, start); 1250 } 1251 } 1252 1253 static void sparx5_vcap_es2_cache_read(struct sparx5 *sparx5, 1254 struct vcap_admin *admin, 1255 enum vcap_selection sel, 1256 u32 start, 1257 u32 count) 1258 { 1259 u32 *keystr, *mskstr, *actstr; 1260 int idx; 1261 1262 keystr = &admin->cache.keystream[start]; 1263 mskstr = &admin->cache.maskstream[start]; 1264 actstr = &admin->cache.actionstream[start]; 1265 1266 if (sel & VCAP_SEL_ENTRY) { 1267 for (idx = 0; idx < count; ++idx) { 1268 keystr[idx] = 1269 spx5_rd(sparx5, VCAP_ES2_VCAP_ENTRY_DAT(idx)); 1270 mskstr[idx] = 1271 ~spx5_rd(sparx5, VCAP_ES2_VCAP_MASK_DAT(idx)); 1272 } 1273 } 1274 1275 if (sel & VCAP_SEL_ACTION) 1276 for (idx = 0; idx < count; ++idx) 1277 actstr[idx] = 1278 spx5_rd(sparx5, VCAP_ES2_VCAP_ACTION_DAT(idx)); 1279 1280 if (sel & VCAP_SEL_COUNTER) { 1281 start = start & 0x7ff; /* counter limit */ 1282 admin->cache.counter = 1283 spx5_rd(sparx5, EACL_ES2_CNT(start)); 1284 admin->cache.sticky = 1285 spx5_rd(sparx5, VCAP_ES2_VCAP_CNT_DAT(0)); 1286 } 1287 } 1288 1289 /* API callback used for reading from the VCAP into the VCAP cache */ 1290 static void sparx5_vcap_cache_read(struct net_device *ndev, 1291 struct vcap_admin *admin, 1292 enum vcap_selection sel, 1293 u32 start, 1294 u32 count) 1295 { 1296 struct sparx5_port *port = netdev_priv(ndev); 1297 struct sparx5 *sparx5 = port->sparx5; 1298 1299 switch (admin->vtype) { 1300 case VCAP_TYPE_IS0: 1301 sparx5_vcap_is0_cache_read(sparx5, admin, sel, start, count); 1302 break; 1303 case VCAP_TYPE_IS2: 1304 sparx5_vcap_is2_cache_read(sparx5, admin, sel, start, count); 1305 break; 1306 case VCAP_TYPE_ES0: 1307 sparx5_vcap_es0_cache_read(sparx5, admin, sel, start, count); 1308 break; 1309 case VCAP_TYPE_ES2: 1310 sparx5_vcap_es2_cache_read(sparx5, admin, sel, start, count); 1311 break; 1312 default: 1313 sparx5_vcap_type_err(sparx5, admin, __func__); 1314 break; 1315 } 1316 } 1317 1318 /* API callback used for initializing a VCAP address range */ 1319 static void sparx5_vcap_range_init(struct net_device *ndev, 1320 struct vcap_admin *admin, u32 addr, 1321 u32 count) 1322 { 1323 struct sparx5_port *port = netdev_priv(ndev); 1324 struct sparx5 *sparx5 = port->sparx5; 1325 1326 _sparx5_vcap_range_init(sparx5, admin, addr, count); 1327 } 1328 1329 static void sparx5_vcap_super_update(struct sparx5 *sparx5, 1330 enum vcap_command cmd, 1331 enum vcap_selection sel, u32 addr) 1332 { 1333 bool clear = (cmd == VCAP_CMD_INITIALIZE); 1334 1335 spx5_wr(VCAP_SUPER_CFG_MV_NUM_POS_SET(0) | 1336 VCAP_SUPER_CFG_MV_SIZE_SET(0), sparx5, VCAP_SUPER_CFG); 1337 spx5_wr(VCAP_SUPER_CTRL_UPDATE_CMD_SET(cmd) | 1338 VCAP_SUPER_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) | 1339 VCAP_SUPER_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) | 1340 VCAP_SUPER_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) | 1341 VCAP_SUPER_CTRL_UPDATE_ADDR_SET(addr) | 1342 VCAP_SUPER_CTRL_CLEAR_CACHE_SET(clear) | 1343 VCAP_SUPER_CTRL_UPDATE_SHOT_SET(true), 1344 sparx5, VCAP_SUPER_CTRL); 1345 sparx5_vcap_wait_super_update(sparx5); 1346 } 1347 1348 static void sparx5_vcap_es0_update(struct sparx5 *sparx5, 1349 enum vcap_command cmd, 1350 enum vcap_selection sel, u32 addr) 1351 { 1352 bool clear = (cmd == VCAP_CMD_INITIALIZE); 1353 1354 spx5_wr(VCAP_ES0_CFG_MV_NUM_POS_SET(0) | 1355 VCAP_ES0_CFG_MV_SIZE_SET(0), sparx5, VCAP_ES0_CFG); 1356 spx5_wr(VCAP_ES0_CTRL_UPDATE_CMD_SET(cmd) | 1357 VCAP_ES0_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) | 1358 VCAP_ES0_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) | 1359 VCAP_ES0_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) | 1360 VCAP_ES0_CTRL_UPDATE_ADDR_SET(addr) | 1361 VCAP_ES0_CTRL_CLEAR_CACHE_SET(clear) | 1362 VCAP_ES0_CTRL_UPDATE_SHOT_SET(true), 1363 sparx5, VCAP_ES0_CTRL); 1364 sparx5_vcap_wait_es0_update(sparx5); 1365 } 1366 1367 static void sparx5_vcap_es2_update(struct sparx5 *sparx5, 1368 enum vcap_command cmd, 1369 enum vcap_selection sel, u32 addr) 1370 { 1371 bool clear = (cmd == VCAP_CMD_INITIALIZE); 1372 1373 spx5_wr(VCAP_ES2_CFG_MV_NUM_POS_SET(0) | 1374 VCAP_ES2_CFG_MV_SIZE_SET(0), sparx5, VCAP_ES2_CFG); 1375 spx5_wr(VCAP_ES2_CTRL_UPDATE_CMD_SET(cmd) | 1376 VCAP_ES2_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) | 1377 VCAP_ES2_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) | 1378 VCAP_ES2_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) | 1379 VCAP_ES2_CTRL_UPDATE_ADDR_SET(addr) | 1380 VCAP_ES2_CTRL_CLEAR_CACHE_SET(clear) | 1381 VCAP_ES2_CTRL_UPDATE_SHOT_SET(true), 1382 sparx5, VCAP_ES2_CTRL); 1383 sparx5_vcap_wait_es2_update(sparx5); 1384 } 1385 1386 /* API callback used for updating the VCAP cache */ 1387 static void sparx5_vcap_update(struct net_device *ndev, 1388 struct vcap_admin *admin, enum vcap_command cmd, 1389 enum vcap_selection sel, u32 addr) 1390 { 1391 struct sparx5_port *port = netdev_priv(ndev); 1392 struct sparx5 *sparx5 = port->sparx5; 1393 1394 switch (admin->vtype) { 1395 case VCAP_TYPE_IS0: 1396 case VCAP_TYPE_IS2: 1397 sparx5_vcap_super_update(sparx5, cmd, sel, addr); 1398 break; 1399 case VCAP_TYPE_ES0: 1400 sparx5_vcap_es0_update(sparx5, cmd, sel, addr); 1401 break; 1402 case VCAP_TYPE_ES2: 1403 sparx5_vcap_es2_update(sparx5, cmd, sel, addr); 1404 break; 1405 default: 1406 sparx5_vcap_type_err(sparx5, admin, __func__); 1407 break; 1408 } 1409 } 1410 1411 static void sparx5_vcap_super_move(struct sparx5 *sparx5, 1412 u32 addr, 1413 enum vcap_command cmd, 1414 u16 mv_num_pos, 1415 u16 mv_size) 1416 { 1417 spx5_wr(VCAP_SUPER_CFG_MV_NUM_POS_SET(mv_num_pos) | 1418 VCAP_SUPER_CFG_MV_SIZE_SET(mv_size), 1419 sparx5, VCAP_SUPER_CFG); 1420 spx5_wr(VCAP_SUPER_CTRL_UPDATE_CMD_SET(cmd) | 1421 VCAP_SUPER_CTRL_UPDATE_ENTRY_DIS_SET(0) | 1422 VCAP_SUPER_CTRL_UPDATE_ACTION_DIS_SET(0) | 1423 VCAP_SUPER_CTRL_UPDATE_CNT_DIS_SET(0) | 1424 VCAP_SUPER_CTRL_UPDATE_ADDR_SET(addr) | 1425 VCAP_SUPER_CTRL_CLEAR_CACHE_SET(false) | 1426 VCAP_SUPER_CTRL_UPDATE_SHOT_SET(true), 1427 sparx5, VCAP_SUPER_CTRL); 1428 sparx5_vcap_wait_super_update(sparx5); 1429 } 1430 1431 static void sparx5_vcap_es0_move(struct sparx5 *sparx5, 1432 u32 addr, 1433 enum vcap_command cmd, 1434 u16 mv_num_pos, 1435 u16 mv_size) 1436 { 1437 spx5_wr(VCAP_ES0_CFG_MV_NUM_POS_SET(mv_num_pos) | 1438 VCAP_ES0_CFG_MV_SIZE_SET(mv_size), 1439 sparx5, VCAP_ES0_CFG); 1440 spx5_wr(VCAP_ES0_CTRL_UPDATE_CMD_SET(cmd) | 1441 VCAP_ES0_CTRL_UPDATE_ENTRY_DIS_SET(0) | 1442 VCAP_ES0_CTRL_UPDATE_ACTION_DIS_SET(0) | 1443 VCAP_ES0_CTRL_UPDATE_CNT_DIS_SET(0) | 1444 VCAP_ES0_CTRL_UPDATE_ADDR_SET(addr) | 1445 VCAP_ES0_CTRL_CLEAR_CACHE_SET(false) | 1446 VCAP_ES0_CTRL_UPDATE_SHOT_SET(true), 1447 sparx5, VCAP_ES0_CTRL); 1448 sparx5_vcap_wait_es0_update(sparx5); 1449 } 1450 1451 static void sparx5_vcap_es2_move(struct sparx5 *sparx5, 1452 u32 addr, 1453 enum vcap_command cmd, 1454 u16 mv_num_pos, 1455 u16 mv_size) 1456 { 1457 spx5_wr(VCAP_ES2_CFG_MV_NUM_POS_SET(mv_num_pos) | 1458 VCAP_ES2_CFG_MV_SIZE_SET(mv_size), 1459 sparx5, VCAP_ES2_CFG); 1460 spx5_wr(VCAP_ES2_CTRL_UPDATE_CMD_SET(cmd) | 1461 VCAP_ES2_CTRL_UPDATE_ENTRY_DIS_SET(0) | 1462 VCAP_ES2_CTRL_UPDATE_ACTION_DIS_SET(0) | 1463 VCAP_ES2_CTRL_UPDATE_CNT_DIS_SET(0) | 1464 VCAP_ES2_CTRL_UPDATE_ADDR_SET(addr) | 1465 VCAP_ES2_CTRL_CLEAR_CACHE_SET(false) | 1466 VCAP_ES2_CTRL_UPDATE_SHOT_SET(true), 1467 sparx5, VCAP_ES2_CTRL); 1468 sparx5_vcap_wait_es2_update(sparx5); 1469 } 1470 1471 /* API callback used for moving a block of rules in the VCAP */ 1472 static void sparx5_vcap_move(struct net_device *ndev, struct vcap_admin *admin, 1473 u32 addr, int offset, int count) 1474 { 1475 struct sparx5_port *port = netdev_priv(ndev); 1476 struct sparx5 *sparx5 = port->sparx5; 1477 enum vcap_command cmd; 1478 u16 mv_num_pos; 1479 u16 mv_size; 1480 1481 mv_size = count - 1; 1482 if (offset > 0) { 1483 mv_num_pos = offset - 1; 1484 cmd = VCAP_CMD_MOVE_DOWN; 1485 } else { 1486 mv_num_pos = -offset - 1; 1487 cmd = VCAP_CMD_MOVE_UP; 1488 } 1489 1490 switch (admin->vtype) { 1491 case VCAP_TYPE_IS0: 1492 case VCAP_TYPE_IS2: 1493 sparx5_vcap_super_move(sparx5, addr, cmd, mv_num_pos, mv_size); 1494 break; 1495 case VCAP_TYPE_ES0: 1496 sparx5_vcap_es0_move(sparx5, addr, cmd, mv_num_pos, mv_size); 1497 break; 1498 case VCAP_TYPE_ES2: 1499 sparx5_vcap_es2_move(sparx5, addr, cmd, mv_num_pos, mv_size); 1500 break; 1501 default: 1502 sparx5_vcap_type_err(sparx5, admin, __func__); 1503 break; 1504 } 1505 } 1506 1507 static struct vcap_operations sparx5_vcap_ops = { 1508 .validate_keyset = sparx5_vcap_validate_keyset, 1509 .add_default_fields = sparx5_vcap_add_default_fields, 1510 .cache_erase = sparx5_vcap_cache_erase, 1511 .cache_write = sparx5_vcap_cache_write, 1512 .cache_read = sparx5_vcap_cache_read, 1513 .init = sparx5_vcap_range_init, 1514 .update = sparx5_vcap_update, 1515 .move = sparx5_vcap_move, 1516 .port_info = sparx5_port_info, 1517 }; 1518 1519 /* Enable IS0 lookups per port and set the keyset generation */ 1520 static void sparx5_vcap_is0_port_key_selection(struct sparx5 *sparx5, 1521 struct vcap_admin *admin) 1522 { 1523 int portno, lookup; 1524 u32 keysel; 1525 1526 keysel = VCAP_IS0_KEYSEL(false, 1527 VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE, 1528 VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4, 1529 VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE, 1530 VCAP_IS0_PS_MPLS_FOLLOW_ETYPE, 1531 VCAP_IS0_PS_MPLS_FOLLOW_ETYPE, 1532 VCAP_IS0_PS_MLBS_FOLLOW_ETYPE); 1533 for (lookup = 0; lookup < admin->lookups; ++lookup) { 1534 for (portno = 0; portno < SPX5_PORTS; ++portno) { 1535 spx5_wr(keysel, sparx5, 1536 ANA_CL_ADV_CL_CFG(portno, lookup)); 1537 spx5_rmw(ANA_CL_ADV_CL_CFG_LOOKUP_ENA, 1538 ANA_CL_ADV_CL_CFG_LOOKUP_ENA, 1539 sparx5, 1540 ANA_CL_ADV_CL_CFG(portno, lookup)); 1541 } 1542 } 1543 } 1544 1545 /* Enable IS2 lookups per port and set the keyset generation */ 1546 static void sparx5_vcap_is2_port_key_selection(struct sparx5 *sparx5, 1547 struct vcap_admin *admin) 1548 { 1549 int portno, lookup; 1550 u32 keysel; 1551 1552 keysel = VCAP_IS2_KEYSEL(true, VCAP_IS2_PS_NONETH_MAC_ETYPE, 1553 VCAP_IS2_PS_IPV4_MC_IP4_TCP_UDP_OTHER, 1554 VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER, 1555 VCAP_IS2_PS_IPV6_MC_IP_7TUPLE, 1556 VCAP_IS2_PS_IPV6_UC_IP_7TUPLE, 1557 VCAP_IS2_PS_ARP_ARP); 1558 for (lookup = 0; lookup < admin->lookups; ++lookup) { 1559 for (portno = 0; portno < SPX5_PORTS; ++portno) { 1560 spx5_wr(keysel, sparx5, 1561 ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup)); 1562 } 1563 } 1564 /* IS2 lookups are in bit 0:3 */ 1565 for (portno = 0; portno < SPX5_PORTS; ++portno) 1566 spx5_rmw(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0xf), 1567 ANA_ACL_VCAP_S2_CFG_SEC_ENA, 1568 sparx5, 1569 ANA_ACL_VCAP_S2_CFG(portno)); 1570 } 1571 1572 /* Enable ES0 lookups per port and set the keyset generation */ 1573 static void sparx5_vcap_es0_port_key_selection(struct sparx5 *sparx5, 1574 struct vcap_admin *admin) 1575 { 1576 int portno; 1577 u32 keysel; 1578 1579 keysel = VCAP_ES0_KEYSEL(VCAP_ES0_PS_FORCE_ISDX_LOOKUPS); 1580 for (portno = 0; portno < SPX5_PORTS; ++portno) 1581 spx5_rmw(keysel, REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA, 1582 sparx5, REW_RTAG_ETAG_CTRL(portno)); 1583 1584 spx5_rmw(REW_ES0_CTRL_ES0_LU_ENA_SET(1), REW_ES0_CTRL_ES0_LU_ENA, 1585 sparx5, REW_ES0_CTRL); 1586 } 1587 1588 /* Enable ES2 lookups per port and set the keyset generation */ 1589 static void sparx5_vcap_es2_port_key_selection(struct sparx5 *sparx5, 1590 struct vcap_admin *admin) 1591 { 1592 int portno, lookup; 1593 u32 keysel; 1594 1595 keysel = VCAP_ES2_KEYSEL(true, VCAP_ES2_PS_ARP_MAC_ETYPE, 1596 VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER, 1597 VCAP_ES2_PS_IPV6_IP_7TUPLE); 1598 for (lookup = 0; lookup < admin->lookups; ++lookup) 1599 for (portno = 0; portno < SPX5_PORTS; ++portno) 1600 spx5_wr(keysel, sparx5, 1601 EACL_VCAP_ES2_KEY_SEL(portno, lookup)); 1602 } 1603 1604 /* Enable lookups per port and set the keyset generation */ 1605 static void sparx5_vcap_port_key_selection(struct sparx5 *sparx5, 1606 struct vcap_admin *admin) 1607 { 1608 switch (admin->vtype) { 1609 case VCAP_TYPE_IS0: 1610 sparx5_vcap_is0_port_key_selection(sparx5, admin); 1611 break; 1612 case VCAP_TYPE_IS2: 1613 sparx5_vcap_is2_port_key_selection(sparx5, admin); 1614 break; 1615 case VCAP_TYPE_ES0: 1616 sparx5_vcap_es0_port_key_selection(sparx5, admin); 1617 break; 1618 case VCAP_TYPE_ES2: 1619 sparx5_vcap_es2_port_key_selection(sparx5, admin); 1620 break; 1621 default: 1622 sparx5_vcap_type_err(sparx5, admin, __func__); 1623 break; 1624 } 1625 } 1626 1627 /* Disable lookups per port */ 1628 static void sparx5_vcap_port_key_deselection(struct sparx5 *sparx5, 1629 struct vcap_admin *admin) 1630 { 1631 int portno, lookup; 1632 1633 switch (admin->vtype) { 1634 case VCAP_TYPE_IS0: 1635 for (lookup = 0; lookup < admin->lookups; ++lookup) 1636 for (portno = 0; portno < SPX5_PORTS; ++portno) 1637 spx5_rmw(ANA_CL_ADV_CL_CFG_LOOKUP_ENA_SET(0), 1638 ANA_CL_ADV_CL_CFG_LOOKUP_ENA, 1639 sparx5, 1640 ANA_CL_ADV_CL_CFG(portno, lookup)); 1641 break; 1642 case VCAP_TYPE_IS2: 1643 for (portno = 0; portno < SPX5_PORTS; ++portno) 1644 spx5_rmw(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0), 1645 ANA_ACL_VCAP_S2_CFG_SEC_ENA, 1646 sparx5, 1647 ANA_ACL_VCAP_S2_CFG(portno)); 1648 break; 1649 case VCAP_TYPE_ES0: 1650 spx5_rmw(REW_ES0_CTRL_ES0_LU_ENA_SET(0), 1651 REW_ES0_CTRL_ES0_LU_ENA, sparx5, REW_ES0_CTRL); 1652 break; 1653 case VCAP_TYPE_ES2: 1654 for (lookup = 0; lookup < admin->lookups; ++lookup) 1655 for (portno = 0; portno < SPX5_PORTS; ++portno) 1656 spx5_rmw(EACL_VCAP_ES2_KEY_SEL_KEY_ENA_SET(0), 1657 EACL_VCAP_ES2_KEY_SEL_KEY_ENA, 1658 sparx5, 1659 EACL_VCAP_ES2_KEY_SEL(portno, lookup)); 1660 break; 1661 default: 1662 sparx5_vcap_type_err(sparx5, admin, __func__); 1663 break; 1664 } 1665 } 1666 1667 static void sparx5_vcap_admin_free(struct vcap_admin *admin) 1668 { 1669 if (!admin) 1670 return; 1671 mutex_destroy(&admin->lock); 1672 kfree(admin->cache.keystream); 1673 kfree(admin->cache.maskstream); 1674 kfree(admin->cache.actionstream); 1675 kfree(admin); 1676 } 1677 1678 /* Allocate a vcap instance with a rule list and a cache area */ 1679 static struct vcap_admin * 1680 sparx5_vcap_admin_alloc(struct sparx5 *sparx5, struct vcap_control *ctrl, 1681 const struct sparx5_vcap_inst *cfg) 1682 { 1683 struct vcap_admin *admin; 1684 1685 admin = kzalloc(sizeof(*admin), GFP_KERNEL); 1686 if (!admin) 1687 return ERR_PTR(-ENOMEM); 1688 INIT_LIST_HEAD(&admin->list); 1689 INIT_LIST_HEAD(&admin->rules); 1690 INIT_LIST_HEAD(&admin->enabled); 1691 mutex_init(&admin->lock); 1692 admin->vtype = cfg->vtype; 1693 admin->vinst = cfg->vinst; 1694 admin->ingress = cfg->ingress; 1695 admin->lookups = cfg->lookups; 1696 admin->lookups_per_instance = cfg->lookups_per_instance; 1697 admin->first_cid = cfg->first_cid; 1698 admin->last_cid = cfg->last_cid; 1699 admin->cache.keystream = 1700 kzalloc(STREAMSIZE, GFP_KERNEL); 1701 admin->cache.maskstream = 1702 kzalloc(STREAMSIZE, GFP_KERNEL); 1703 admin->cache.actionstream = 1704 kzalloc(STREAMSIZE, GFP_KERNEL); 1705 if (!admin->cache.keystream || !admin->cache.maskstream || 1706 !admin->cache.actionstream) { 1707 sparx5_vcap_admin_free(admin); 1708 return ERR_PTR(-ENOMEM); 1709 } 1710 return admin; 1711 } 1712 1713 /* Do block allocations and provide addresses for VCAP instances */ 1714 static void sparx5_vcap_block_alloc(struct sparx5 *sparx5, 1715 struct vcap_admin *admin, 1716 const struct sparx5_vcap_inst *cfg) 1717 { 1718 int idx, cores; 1719 1720 switch (admin->vtype) { 1721 case VCAP_TYPE_IS0: 1722 case VCAP_TYPE_IS2: 1723 /* Super VCAP block mapping and address configuration. Block 0 1724 * is assigned addresses 0 through 3071, block 1 is assigned 1725 * addresses 3072 though 6143, and so on. 1726 */ 1727 for (idx = cfg->blockno; idx < cfg->blockno + cfg->blocks; 1728 ++idx) { 1729 spx5_wr(VCAP_SUPER_IDX_CORE_IDX_SET(idx), sparx5, 1730 VCAP_SUPER_IDX); 1731 spx5_wr(VCAP_SUPER_MAP_CORE_MAP_SET(cfg->map_id), 1732 sparx5, VCAP_SUPER_MAP); 1733 } 1734 admin->first_valid_addr = cfg->blockno * SUPER_VCAP_BLK_SIZE; 1735 admin->last_used_addr = admin->first_valid_addr + 1736 cfg->blocks * SUPER_VCAP_BLK_SIZE; 1737 admin->last_valid_addr = admin->last_used_addr - 1; 1738 break; 1739 case VCAP_TYPE_ES0: 1740 admin->first_valid_addr = 0; 1741 admin->last_used_addr = cfg->count; 1742 admin->last_valid_addr = cfg->count - 1; 1743 cores = spx5_rd(sparx5, VCAP_ES0_CORE_CNT); 1744 for (idx = 0; idx < cores; ++idx) { 1745 spx5_wr(VCAP_ES0_IDX_CORE_IDX_SET(idx), sparx5, 1746 VCAP_ES0_IDX); 1747 spx5_wr(VCAP_ES0_MAP_CORE_MAP_SET(1), sparx5, 1748 VCAP_ES0_MAP); 1749 } 1750 break; 1751 case VCAP_TYPE_ES2: 1752 admin->first_valid_addr = 0; 1753 admin->last_used_addr = cfg->count; 1754 admin->last_valid_addr = cfg->count - 1; 1755 cores = spx5_rd(sparx5, VCAP_ES2_CORE_CNT); 1756 for (idx = 0; idx < cores; ++idx) { 1757 spx5_wr(VCAP_ES2_IDX_CORE_IDX_SET(idx), sparx5, 1758 VCAP_ES2_IDX); 1759 spx5_wr(VCAP_ES2_MAP_CORE_MAP_SET(1), sparx5, 1760 VCAP_ES2_MAP); 1761 } 1762 break; 1763 default: 1764 sparx5_vcap_type_err(sparx5, admin, __func__); 1765 break; 1766 } 1767 } 1768 1769 /* Allocate a vcap control and vcap instances and configure the system */ 1770 int sparx5_vcap_init(struct sparx5 *sparx5) 1771 { 1772 const struct sparx5_vcap_inst *cfg; 1773 struct vcap_control *ctrl; 1774 struct vcap_admin *admin; 1775 struct dentry *dir; 1776 int err = 0, idx; 1777 1778 /* Create a VCAP control instance that owns the platform specific VCAP 1779 * model with VCAP instances and information about keysets, keys, 1780 * actionsets and actions 1781 * - Create administrative state for each available VCAP 1782 * - Lists of rules 1783 * - Address information 1784 * - Initialize VCAP blocks 1785 * - Configure port keysets 1786 */ 1787 ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); 1788 if (!ctrl) 1789 return -ENOMEM; 1790 1791 sparx5->vcap_ctrl = ctrl; 1792 /* select the sparx5 VCAP model */ 1793 ctrl->vcaps = sparx5_vcaps; 1794 ctrl->stats = &sparx5_vcap_stats; 1795 /* Setup callbacks to allow the API to use the VCAP HW */ 1796 ctrl->ops = &sparx5_vcap_ops; 1797 1798 INIT_LIST_HEAD(&ctrl->list); 1799 for (idx = 0; idx < ARRAY_SIZE(sparx5_vcap_inst_cfg); ++idx) { 1800 cfg = &sparx5_vcap_inst_cfg[idx]; 1801 admin = sparx5_vcap_admin_alloc(sparx5, ctrl, cfg); 1802 if (IS_ERR(admin)) { 1803 err = PTR_ERR(admin); 1804 pr_err("%s:%d: vcap allocation failed: %d\n", 1805 __func__, __LINE__, err); 1806 return err; 1807 } 1808 sparx5_vcap_block_alloc(sparx5, admin, cfg); 1809 sparx5_vcap_block_init(sparx5, admin); 1810 if (cfg->vinst == 0) 1811 sparx5_vcap_port_key_selection(sparx5, admin); 1812 list_add_tail(&admin->list, &ctrl->list); 1813 } 1814 dir = vcap_debugfs(sparx5->dev, sparx5->debugfs_root, ctrl); 1815 for (idx = 0; idx < SPX5_PORTS; ++idx) 1816 if (sparx5->ports[idx]) 1817 vcap_port_debugfs(sparx5->dev, dir, ctrl, 1818 sparx5->ports[idx]->ndev); 1819 1820 return err; 1821 } 1822 1823 void sparx5_vcap_destroy(struct sparx5 *sparx5) 1824 { 1825 struct vcap_control *ctrl = sparx5->vcap_ctrl; 1826 struct vcap_admin *admin, *admin_next; 1827 1828 if (!ctrl) 1829 return; 1830 1831 list_for_each_entry_safe(admin, admin_next, &ctrl->list, list) { 1832 sparx5_vcap_port_key_deselection(sparx5, admin); 1833 vcap_del_rules(ctrl, admin); 1834 list_del(&admin->list); 1835 sparx5_vcap_admin_free(admin); 1836 } 1837 kfree(ctrl); 1838 } 1839