1 // SPDX-License-Identifier: GPL-2.0+ 2 3 #include "lan966x_main.h" 4 #include "lan966x_vcap_ag_api.h" 5 #include "vcap_api.h" 6 #include "vcap_api_client.h" 7 #include "vcap_api_debugfs.h" 8 9 #define STREAMSIZE (64 * 4) 10 11 #define LAN966X_IS1_LOOKUPS 3 12 #define LAN966X_IS2_LOOKUPS 2 13 #define LAN966X_ES0_LOOKUPS 1 14 15 #define LAN966X_STAT_ESDX_GRN_BYTES 0x300 16 #define LAN966X_STAT_ESDX_GRN_PKTS 0x301 17 #define LAN966X_STAT_ESDX_YEL_BYTES 0x302 18 #define LAN966X_STAT_ESDX_YEL_PKTS 0x303 19 20 static struct lan966x_vcap_inst { 21 enum vcap_type vtype; /* type of vcap */ 22 int tgt_inst; /* hardware instance number */ 23 int lookups; /* number of lookups in this vcap type */ 24 int first_cid; /* first chain id in this vcap */ 25 int last_cid; /* last chain id in this vcap */ 26 int count; /* number of available addresses */ 27 bool ingress; /* is vcap in the ingress path */ 28 } lan966x_vcap_inst_cfg[] = { 29 { 30 .vtype = VCAP_TYPE_ES0, 31 .tgt_inst = 0, 32 .lookups = LAN966X_ES0_LOOKUPS, 33 .first_cid = LAN966X_VCAP_CID_ES0_L0, 34 .last_cid = LAN966X_VCAP_CID_ES0_MAX, 35 .count = 64, 36 }, 37 { 38 .vtype = VCAP_TYPE_IS1, /* IS1-0 */ 39 .tgt_inst = 1, 40 .lookups = LAN966X_IS1_LOOKUPS, 41 .first_cid = LAN966X_VCAP_CID_IS1_L0, 42 .last_cid = LAN966X_VCAP_CID_IS1_MAX, 43 .count = 768, 44 .ingress = true, 45 }, 46 { 47 .vtype = VCAP_TYPE_IS2, /* IS2-0 */ 48 .tgt_inst = 2, 49 .lookups = LAN966X_IS2_LOOKUPS, 50 .first_cid = LAN966X_VCAP_CID_IS2_L0, 51 .last_cid = LAN966X_VCAP_CID_IS2_MAX, 52 .count = 256, 53 .ingress = true, 54 }, 55 }; 56 57 struct lan966x_vcap_cmd_cb { 58 struct lan966x *lan966x; 59 u32 instance; 60 }; 61 62 static u32 lan966x_vcap_read_update_ctrl(const struct lan966x_vcap_cmd_cb *cb) 63 { 64 return lan_rd(cb->lan966x, VCAP_UPDATE_CTRL(cb->instance)); 65 } 66 67 static void lan966x_vcap_wait_update(struct lan966x *lan966x, int instance) 68 { 69 const struct lan966x_vcap_cmd_cb cb = { .lan966x = lan966x, 70 .instance = instance }; 71 u32 val; 72 73 readx_poll_timeout(lan966x_vcap_read_update_ctrl, &cb, val, 74 (val & VCAP_UPDATE_CTRL_UPDATE_SHOT) == 0, 10, 75 100000); 76 } 77 78 static void __lan966x_vcap_range_init(struct lan966x *lan966x, 79 struct vcap_admin *admin, 80 u32 addr, 81 u32 count) 82 { 83 lan_wr(VCAP_MV_CFG_MV_NUM_POS_SET(0) | 84 VCAP_MV_CFG_MV_SIZE_SET(count - 1), 85 lan966x, VCAP_MV_CFG(admin->tgt_inst)); 86 87 lan_wr(VCAP_UPDATE_CTRL_UPDATE_CMD_SET(VCAP_CMD_INITIALIZE) | 88 VCAP_UPDATE_CTRL_UPDATE_ENTRY_DIS_SET(0) | 89 VCAP_UPDATE_CTRL_UPDATE_ACTION_DIS_SET(0) | 90 VCAP_UPDATE_CTRL_UPDATE_CNT_DIS_SET(0) | 91 VCAP_UPDATE_CTRL_UPDATE_ADDR_SET(addr) | 92 VCAP_UPDATE_CTRL_CLEAR_CACHE_SET(true) | 93 VCAP_UPDATE_CTRL_UPDATE_SHOT_SET(1), 94 lan966x, VCAP_UPDATE_CTRL(admin->tgt_inst)); 95 96 lan966x_vcap_wait_update(lan966x, admin->tgt_inst); 97 } 98 99 static int lan966x_vcap_is1_cid_to_lookup(int cid) 100 { 101 int lookup = 0; 102 103 if (cid >= LAN966X_VCAP_CID_IS1_L1 && 104 cid < LAN966X_VCAP_CID_IS1_L2) 105 lookup = 1; 106 else if (cid >= LAN966X_VCAP_CID_IS1_L2 && 107 cid < LAN966X_VCAP_CID_IS1_MAX) 108 lookup = 2; 109 110 return lookup; 111 } 112 113 static int lan966x_vcap_is2_cid_to_lookup(int cid) 114 { 115 if (cid >= LAN966X_VCAP_CID_IS2_L1 && 116 cid < LAN966X_VCAP_CID_IS2_MAX) 117 return 1; 118 119 return 0; 120 } 121 122 /* Return the list of keysets for the vcap port configuration */ 123 static int 124 lan966x_vcap_is1_get_port_keysets(struct net_device *ndev, int lookup, 125 struct vcap_keyset_list *keysetlist, 126 u16 l3_proto) 127 { 128 struct lan966x_port *port = netdev_priv(ndev); 129 struct lan966x *lan966x = port->lan966x; 130 u32 val; 131 132 val = lan_rd(lan966x, ANA_VCAP_S1_CFG(port->chip_port, lookup)); 133 134 /* Collect all keysets for the port in a list */ 135 if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP) { 136 switch (ANA_VCAP_S1_CFG_KEY_IP4_CFG_GET(val)) { 137 case VCAP_IS1_PS_IPV4_7TUPLE: 138 vcap_keyset_list_add(keysetlist, VCAP_KFS_7TUPLE); 139 break; 140 case VCAP_IS1_PS_IPV4_5TUPLE_IP4: 141 vcap_keyset_list_add(keysetlist, VCAP_KFS_5TUPLE_IP4); 142 break; 143 case VCAP_IS1_PS_IPV4_NORMAL: 144 vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL); 145 break; 146 } 147 } 148 149 if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IPV6) { 150 switch (ANA_VCAP_S1_CFG_KEY_IP6_CFG_GET(val)) { 151 case VCAP_IS1_PS_IPV6_NORMAL: 152 case VCAP_IS1_PS_IPV6_NORMAL_IP6: 153 vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL); 154 vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL_IP6); 155 break; 156 case VCAP_IS1_PS_IPV6_5TUPLE_IP6: 157 vcap_keyset_list_add(keysetlist, VCAP_KFS_5TUPLE_IP6); 158 break; 159 case VCAP_IS1_PS_IPV6_7TUPLE: 160 vcap_keyset_list_add(keysetlist, VCAP_KFS_7TUPLE); 161 break; 162 case VCAP_IS1_PS_IPV6_5TUPLE_IP4: 163 vcap_keyset_list_add(keysetlist, VCAP_KFS_5TUPLE_IP4); 164 break; 165 case VCAP_IS1_PS_IPV6_DMAC_VID: 166 vcap_keyset_list_add(keysetlist, VCAP_KFS_DMAC_VID); 167 break; 168 } 169 } 170 171 switch (ANA_VCAP_S1_CFG_KEY_OTHER_CFG_GET(val)) { 172 case VCAP_IS1_PS_OTHER_7TUPLE: 173 vcap_keyset_list_add(keysetlist, VCAP_KFS_7TUPLE); 174 break; 175 case VCAP_IS1_PS_OTHER_NORMAL: 176 vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL); 177 break; 178 } 179 180 return 0; 181 } 182 183 static int 184 lan966x_vcap_is2_get_port_keysets(struct net_device *dev, int lookup, 185 struct vcap_keyset_list *keysetlist, 186 u16 l3_proto) 187 { 188 struct lan966x_port *port = netdev_priv(dev); 189 struct lan966x *lan966x = port->lan966x; 190 bool found = false; 191 u32 val; 192 193 val = lan_rd(lan966x, ANA_VCAP_S2_CFG(port->chip_port)); 194 195 /* Collect all keysets for the port in a list */ 196 if (l3_proto == ETH_P_ALL) 197 vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE); 198 199 if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_SNAP) { 200 if (ANA_VCAP_S2_CFG_SNAP_DIS_GET(val) & (BIT(0) << lookup)) 201 vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_LLC); 202 else 203 vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_SNAP); 204 205 found = true; 206 } 207 208 if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_CFM) { 209 if (ANA_VCAP_S2_CFG_OAM_DIS_GET(val) & (BIT(0) << lookup)) 210 vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE); 211 else 212 vcap_keyset_list_add(keysetlist, VCAP_KFS_OAM); 213 214 found = true; 215 } 216 217 if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_ARP) { 218 if (ANA_VCAP_S2_CFG_ARP_DIS_GET(val) & (BIT(0) << lookup)) 219 vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE); 220 else 221 vcap_keyset_list_add(keysetlist, VCAP_KFS_ARP); 222 223 found = true; 224 } 225 226 if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP) { 227 if (ANA_VCAP_S2_CFG_IP_OTHER_DIS_GET(val) & (BIT(0) << lookup)) 228 vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE); 229 else 230 vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER); 231 232 if (ANA_VCAP_S2_CFG_IP_TCPUDP_DIS_GET(val) & (BIT(0) << lookup)) 233 vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE); 234 else 235 vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP); 236 237 found = true; 238 } 239 240 if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IPV6) { 241 switch (ANA_VCAP_S2_CFG_IP6_CFG_GET(val) & (0x3 << lookup)) { 242 case VCAP_IS2_PS_IPV6_TCPUDP_OTHER: 243 vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_OTHER); 244 vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_TCP_UDP); 245 break; 246 case VCAP_IS2_PS_IPV6_STD: 247 vcap_keyset_list_add(keysetlist, VCAP_KFS_IP6_STD); 248 break; 249 case VCAP_IS2_PS_IPV6_IP4_TCPUDP_IP4_OTHER: 250 vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_OTHER); 251 vcap_keyset_list_add(keysetlist, VCAP_KFS_IP4_TCP_UDP); 252 break; 253 case VCAP_IS2_PS_IPV6_MAC_ETYPE: 254 vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE); 255 break; 256 } 257 258 found = true; 259 } 260 261 if (!found) 262 vcap_keyset_list_add(keysetlist, VCAP_KFS_MAC_ETYPE); 263 264 return 0; 265 } 266 267 static enum vcap_keyfield_set 268 lan966x_vcap_validate_keyset(struct net_device *dev, 269 struct vcap_admin *admin, 270 struct vcap_rule *rule, 271 struct vcap_keyset_list *kslist, 272 u16 l3_proto) 273 { 274 struct vcap_keyset_list keysetlist = {}; 275 enum vcap_keyfield_set keysets[10] = {}; 276 int lookup; 277 int err; 278 279 if (!kslist || kslist->cnt == 0) 280 return VCAP_KFS_NO_VALUE; 281 282 keysetlist.max = ARRAY_SIZE(keysets); 283 keysetlist.keysets = keysets; 284 285 switch (admin->vtype) { 286 case VCAP_TYPE_IS1: 287 lookup = lan966x_vcap_is1_cid_to_lookup(rule->vcap_chain_id); 288 err = lan966x_vcap_is1_get_port_keysets(dev, lookup, &keysetlist, 289 l3_proto); 290 break; 291 case VCAP_TYPE_IS2: 292 lookup = lan966x_vcap_is2_cid_to_lookup(rule->vcap_chain_id); 293 err = lan966x_vcap_is2_get_port_keysets(dev, lookup, &keysetlist, 294 l3_proto); 295 break; 296 case VCAP_TYPE_ES0: 297 return kslist->keysets[0]; 298 default: 299 pr_err("vcap type: %s not supported\n", 300 lan966x_vcaps[admin->vtype].name); 301 return VCAP_KFS_NO_VALUE; 302 } 303 304 if (err) 305 return VCAP_KFS_NO_VALUE; 306 307 /* Check if there is a match and return the match */ 308 for (int i = 0; i < kslist->cnt; ++i) 309 for (int j = 0; j < keysetlist.cnt; ++j) 310 if (kslist->keysets[i] == keysets[j]) 311 return kslist->keysets[i]; 312 313 return VCAP_KFS_NO_VALUE; 314 } 315 316 static bool lan966x_vcap_is2_is_first_chain(struct vcap_rule *rule) 317 { 318 return (rule->vcap_chain_id >= LAN966X_VCAP_CID_IS2_L0 && 319 rule->vcap_chain_id < LAN966X_VCAP_CID_IS2_L1); 320 } 321 322 static void lan966x_vcap_is1_add_default_fields(struct lan966x_port *port, 323 struct vcap_admin *admin, 324 struct vcap_rule *rule) 325 { 326 u32 value, mask; 327 u32 lookup; 328 329 if (vcap_rule_get_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK, 330 &value, &mask)) 331 vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK, 0, 332 ~BIT(port->chip_port)); 333 334 lookup = lan966x_vcap_is1_cid_to_lookup(rule->vcap_chain_id); 335 vcap_rule_add_key_u32(rule, VCAP_KF_LOOKUP_INDEX, lookup, 0x3); 336 } 337 338 static void lan966x_vcap_is2_add_default_fields(struct lan966x_port *port, 339 struct vcap_admin *admin, 340 struct vcap_rule *rule) 341 { 342 u32 value, mask; 343 344 if (vcap_rule_get_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK, 345 &value, &mask)) 346 vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK, 0, 347 ~BIT(port->chip_port)); 348 349 if (lan966x_vcap_is2_is_first_chain(rule)) 350 vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, 351 VCAP_BIT_1); 352 else 353 vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, 354 VCAP_BIT_0); 355 } 356 357 static void lan966x_vcap_es0_add_default_fields(struct lan966x_port *port, 358 struct vcap_admin *admin, 359 struct vcap_rule *rule) 360 { 361 vcap_rule_add_key_u32(rule, VCAP_KF_IF_EGR_PORT_NO, 362 port->chip_port, GENMASK(4, 0)); 363 } 364 365 static void lan966x_vcap_add_default_fields(struct net_device *dev, 366 struct vcap_admin *admin, 367 struct vcap_rule *rule) 368 { 369 struct lan966x_port *port = netdev_priv(dev); 370 371 switch (admin->vtype) { 372 case VCAP_TYPE_IS1: 373 lan966x_vcap_is1_add_default_fields(port, admin, rule); 374 break; 375 case VCAP_TYPE_IS2: 376 lan966x_vcap_is2_add_default_fields(port, admin, rule); 377 break; 378 case VCAP_TYPE_ES0: 379 lan966x_vcap_es0_add_default_fields(port, admin, rule); 380 break; 381 default: 382 pr_err("vcap type: %s not supported\n", 383 lan966x_vcaps[admin->vtype].name); 384 break; 385 } 386 } 387 388 static void lan966x_vcap_cache_erase(struct vcap_admin *admin) 389 { 390 memset(admin->cache.keystream, 0, STREAMSIZE); 391 memset(admin->cache.maskstream, 0, STREAMSIZE); 392 memset(admin->cache.actionstream, 0, STREAMSIZE); 393 memset(&admin->cache.counter, 0, sizeof(admin->cache.counter)); 394 } 395 396 /* The ESDX counter is only used/incremented if the frame has been classified 397 * with an ISDX > 0 (e.g by a rule in IS0). This is not mentioned in the 398 * datasheet. 399 */ 400 static void lan966x_es0_read_esdx_counter(struct lan966x *lan966x, 401 struct vcap_admin *admin, u32 id) 402 { 403 u32 counter; 404 405 id = id & 0xff; /* counter limit */ 406 mutex_lock(&lan966x->stats_lock); 407 lan_wr(SYS_STAT_CFG_STAT_VIEW_SET(id), lan966x, SYS_STAT_CFG); 408 counter = lan_rd(lan966x, SYS_CNT(LAN966X_STAT_ESDX_GRN_PKTS)) + 409 lan_rd(lan966x, SYS_CNT(LAN966X_STAT_ESDX_YEL_PKTS)); 410 mutex_unlock(&lan966x->stats_lock); 411 if (counter) 412 admin->cache.counter = counter; 413 } 414 415 static void lan966x_es0_write_esdx_counter(struct lan966x *lan966x, 416 struct vcap_admin *admin, u32 id) 417 { 418 id = id & 0xff; /* counter limit */ 419 420 mutex_lock(&lan966x->stats_lock); 421 lan_wr(SYS_STAT_CFG_STAT_VIEW_SET(id), lan966x, SYS_STAT_CFG); 422 lan_wr(0, lan966x, SYS_CNT(LAN966X_STAT_ESDX_GRN_BYTES)); 423 lan_wr(admin->cache.counter, lan966x, 424 SYS_CNT(LAN966X_STAT_ESDX_GRN_PKTS)); 425 lan_wr(0, lan966x, SYS_CNT(LAN966X_STAT_ESDX_YEL_BYTES)); 426 lan_wr(0, lan966x, SYS_CNT(LAN966X_STAT_ESDX_YEL_PKTS)); 427 mutex_unlock(&lan966x->stats_lock); 428 } 429 430 static void lan966x_vcap_cache_write(struct net_device *dev, 431 struct vcap_admin *admin, 432 enum vcap_selection sel, 433 u32 start, 434 u32 count) 435 { 436 struct lan966x_port *port = netdev_priv(dev); 437 struct lan966x *lan966x = port->lan966x; 438 u32 *keystr, *mskstr, *actstr; 439 440 keystr = &admin->cache.keystream[start]; 441 mskstr = &admin->cache.maskstream[start]; 442 actstr = &admin->cache.actionstream[start]; 443 444 switch (sel) { 445 case VCAP_SEL_ENTRY: 446 for (int i = 0; i < count; ++i) { 447 lan_wr(keystr[i] & mskstr[i], lan966x, 448 VCAP_ENTRY_DAT(admin->tgt_inst, i)); 449 lan_wr(~mskstr[i], lan966x, 450 VCAP_MASK_DAT(admin->tgt_inst, i)); 451 } 452 break; 453 case VCAP_SEL_ACTION: 454 for (int i = 0; i < count; ++i) 455 lan_wr(actstr[i], lan966x, 456 VCAP_ACTION_DAT(admin->tgt_inst, i)); 457 break; 458 case VCAP_SEL_COUNTER: 459 admin->cache.sticky = admin->cache.counter > 0; 460 lan_wr(admin->cache.counter, lan966x, 461 VCAP_CNT_DAT(admin->tgt_inst, 0)); 462 463 if (admin->vtype == VCAP_TYPE_ES0) 464 lan966x_es0_write_esdx_counter(lan966x, admin, start); 465 break; 466 default: 467 break; 468 } 469 } 470 471 static void lan966x_vcap_cache_read(struct net_device *dev, 472 struct vcap_admin *admin, 473 enum vcap_selection sel, 474 u32 start, 475 u32 count) 476 { 477 struct lan966x_port *port = netdev_priv(dev); 478 struct lan966x *lan966x = port->lan966x; 479 int instance = admin->tgt_inst; 480 u32 *keystr, *mskstr, *actstr; 481 482 keystr = &admin->cache.keystream[start]; 483 mskstr = &admin->cache.maskstream[start]; 484 actstr = &admin->cache.actionstream[start]; 485 486 if (sel & VCAP_SEL_ENTRY) { 487 for (int i = 0; i < count; ++i) { 488 keystr[i] = 489 lan_rd(lan966x, VCAP_ENTRY_DAT(instance, i)); 490 mskstr[i] = 491 ~lan_rd(lan966x, VCAP_MASK_DAT(instance, i)); 492 } 493 } 494 495 if (sel & VCAP_SEL_ACTION) 496 for (int i = 0; i < count; ++i) 497 actstr[i] = 498 lan_rd(lan966x, VCAP_ACTION_DAT(instance, i)); 499 500 if (sel & VCAP_SEL_COUNTER) { 501 admin->cache.counter = 502 lan_rd(lan966x, VCAP_CNT_DAT(instance, 0)); 503 admin->cache.sticky = admin->cache.counter > 0; 504 505 if (admin->vtype == VCAP_TYPE_ES0) 506 lan966x_es0_read_esdx_counter(lan966x, admin, start); 507 } 508 } 509 510 static void lan966x_vcap_range_init(struct net_device *dev, 511 struct vcap_admin *admin, 512 u32 addr, 513 u32 count) 514 { 515 struct lan966x_port *port = netdev_priv(dev); 516 struct lan966x *lan966x = port->lan966x; 517 518 __lan966x_vcap_range_init(lan966x, admin, addr, count); 519 } 520 521 static void lan966x_vcap_update(struct net_device *dev, 522 struct vcap_admin *admin, 523 enum vcap_command cmd, 524 enum vcap_selection sel, 525 u32 addr) 526 { 527 struct lan966x_port *port = netdev_priv(dev); 528 struct lan966x *lan966x = port->lan966x; 529 bool clear; 530 531 clear = (cmd == VCAP_CMD_INITIALIZE); 532 533 lan_wr(VCAP_MV_CFG_MV_NUM_POS_SET(0) | 534 VCAP_MV_CFG_MV_SIZE_SET(0), 535 lan966x, VCAP_MV_CFG(admin->tgt_inst)); 536 537 lan_wr(VCAP_UPDATE_CTRL_UPDATE_CMD_SET(cmd) | 538 VCAP_UPDATE_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) | 539 VCAP_UPDATE_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) | 540 VCAP_UPDATE_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) | 541 VCAP_UPDATE_CTRL_UPDATE_ADDR_SET(addr) | 542 VCAP_UPDATE_CTRL_CLEAR_CACHE_SET(clear) | 543 VCAP_UPDATE_CTRL_UPDATE_SHOT, 544 lan966x, VCAP_UPDATE_CTRL(admin->tgt_inst)); 545 546 lan966x_vcap_wait_update(lan966x, admin->tgt_inst); 547 } 548 549 static void lan966x_vcap_move(struct net_device *dev, 550 struct vcap_admin *admin, 551 u32 addr, int offset, int count) 552 { 553 struct lan966x_port *port = netdev_priv(dev); 554 struct lan966x *lan966x = port->lan966x; 555 enum vcap_command cmd; 556 u16 mv_num_pos; 557 u16 mv_size; 558 559 mv_size = count - 1; 560 if (offset > 0) { 561 mv_num_pos = offset - 1; 562 cmd = VCAP_CMD_MOVE_DOWN; 563 } else { 564 mv_num_pos = -offset - 1; 565 cmd = VCAP_CMD_MOVE_UP; 566 } 567 568 lan_wr(VCAP_MV_CFG_MV_NUM_POS_SET(mv_num_pos) | 569 VCAP_MV_CFG_MV_SIZE_SET(mv_size), 570 lan966x, VCAP_MV_CFG(admin->tgt_inst)); 571 572 lan_wr(VCAP_UPDATE_CTRL_UPDATE_CMD_SET(cmd) | 573 VCAP_UPDATE_CTRL_UPDATE_ENTRY_DIS_SET(0) | 574 VCAP_UPDATE_CTRL_UPDATE_ACTION_DIS_SET(0) | 575 VCAP_UPDATE_CTRL_UPDATE_CNT_DIS_SET(0) | 576 VCAP_UPDATE_CTRL_UPDATE_ADDR_SET(addr) | 577 VCAP_UPDATE_CTRL_CLEAR_CACHE_SET(false) | 578 VCAP_UPDATE_CTRL_UPDATE_SHOT, 579 lan966x, VCAP_UPDATE_CTRL(admin->tgt_inst)); 580 581 lan966x_vcap_wait_update(lan966x, admin->tgt_inst); 582 } 583 584 static const struct vcap_operations lan966x_vcap_ops = { 585 .validate_keyset = lan966x_vcap_validate_keyset, 586 .add_default_fields = lan966x_vcap_add_default_fields, 587 .cache_erase = lan966x_vcap_cache_erase, 588 .cache_write = lan966x_vcap_cache_write, 589 .cache_read = lan966x_vcap_cache_read, 590 .init = lan966x_vcap_range_init, 591 .update = lan966x_vcap_update, 592 .move = lan966x_vcap_move, 593 .port_info = lan966x_vcap_port_info, 594 }; 595 596 static void lan966x_vcap_admin_free(struct vcap_admin *admin) 597 { 598 if (!admin) 599 return; 600 601 kfree(admin->cache.keystream); 602 kfree(admin->cache.maskstream); 603 kfree(admin->cache.actionstream); 604 mutex_destroy(&admin->lock); 605 kfree(admin); 606 } 607 608 static struct vcap_admin * 609 lan966x_vcap_admin_alloc(struct lan966x *lan966x, struct vcap_control *ctrl, 610 const struct lan966x_vcap_inst *cfg) 611 { 612 struct vcap_admin *admin; 613 614 admin = kzalloc(sizeof(*admin), GFP_KERNEL); 615 if (!admin) 616 return ERR_PTR(-ENOMEM); 617 618 mutex_init(&admin->lock); 619 INIT_LIST_HEAD(&admin->list); 620 INIT_LIST_HEAD(&admin->rules); 621 INIT_LIST_HEAD(&admin->enabled); 622 623 admin->vtype = cfg->vtype; 624 admin->vinst = 0; 625 admin->ingress = cfg->ingress; 626 admin->w32be = true; 627 admin->tgt_inst = cfg->tgt_inst; 628 629 admin->lookups = cfg->lookups; 630 admin->lookups_per_instance = cfg->lookups; 631 632 admin->first_cid = cfg->first_cid; 633 admin->last_cid = cfg->last_cid; 634 635 admin->cache.keystream = kzalloc(STREAMSIZE, GFP_KERNEL); 636 admin->cache.maskstream = kzalloc(STREAMSIZE, GFP_KERNEL); 637 admin->cache.actionstream = kzalloc(STREAMSIZE, GFP_KERNEL); 638 if (!admin->cache.keystream || 639 !admin->cache.maskstream || 640 !admin->cache.actionstream) { 641 lan966x_vcap_admin_free(admin); 642 return ERR_PTR(-ENOMEM); 643 } 644 645 return admin; 646 } 647 648 static void lan966x_vcap_block_init(struct lan966x *lan966x, 649 struct vcap_admin *admin, 650 struct lan966x_vcap_inst *cfg) 651 { 652 admin->first_valid_addr = 0; 653 admin->last_used_addr = cfg->count; 654 admin->last_valid_addr = cfg->count - 1; 655 656 lan_wr(VCAP_CORE_IDX_CORE_IDX_SET(0), 657 lan966x, VCAP_CORE_IDX(admin->tgt_inst)); 658 lan_wr(VCAP_CORE_MAP_CORE_MAP_SET(1), 659 lan966x, VCAP_CORE_MAP(admin->tgt_inst)); 660 661 __lan966x_vcap_range_init(lan966x, admin, admin->first_valid_addr, 662 admin->last_valid_addr - 663 admin->first_valid_addr); 664 } 665 666 static void lan966x_vcap_port_key_deselection(struct lan966x *lan966x, 667 struct vcap_admin *admin) 668 { 669 u32 val; 670 671 switch (admin->vtype) { 672 case VCAP_TYPE_IS1: 673 val = ANA_VCAP_S1_CFG_KEY_IP6_CFG_SET(VCAP_IS1_PS_IPV6_5TUPLE_IP6) | 674 ANA_VCAP_S1_CFG_KEY_IP4_CFG_SET(VCAP_IS1_PS_IPV4_5TUPLE_IP4) | 675 ANA_VCAP_S1_CFG_KEY_OTHER_CFG_SET(VCAP_IS1_PS_OTHER_NORMAL); 676 677 for (int p = 0; p < lan966x->num_phys_ports; ++p) { 678 if (!lan966x->ports[p]) 679 continue; 680 681 for (int l = 0; l < LAN966X_IS1_LOOKUPS; ++l) 682 lan_wr(val, lan966x, ANA_VCAP_S1_CFG(p, l)); 683 684 lan_rmw(ANA_VCAP_CFG_S1_ENA_SET(true), 685 ANA_VCAP_CFG_S1_ENA, lan966x, 686 ANA_VCAP_CFG(p)); 687 } 688 689 break; 690 case VCAP_TYPE_IS2: 691 for (int p = 0; p < lan966x->num_phys_ports; ++p) 692 lan_wr(0, lan966x, ANA_VCAP_S2_CFG(p)); 693 694 break; 695 case VCAP_TYPE_ES0: 696 for (int p = 0; p < lan966x->num_phys_ports; ++p) 697 lan_rmw(REW_PORT_CFG_ES0_EN_SET(false), 698 REW_PORT_CFG_ES0_EN, lan966x, 699 REW_PORT_CFG(p)); 700 break; 701 default: 702 pr_err("vcap type: %s not supported\n", 703 lan966x_vcaps[admin->vtype].name); 704 break; 705 } 706 } 707 708 int lan966x_vcap_init(struct lan966x *lan966x) 709 { 710 struct lan966x_vcap_inst *cfg; 711 struct vcap_control *ctrl; 712 struct vcap_admin *admin; 713 struct dentry *dir; 714 715 ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); 716 if (!ctrl) 717 return -ENOMEM; 718 719 ctrl->vcaps = lan966x_vcaps; 720 ctrl->stats = &lan966x_vcap_stats; 721 ctrl->ops = &lan966x_vcap_ops; 722 723 INIT_LIST_HEAD(&ctrl->list); 724 for (int i = 0; i < ARRAY_SIZE(lan966x_vcap_inst_cfg); ++i) { 725 cfg = &lan966x_vcap_inst_cfg[i]; 726 727 admin = lan966x_vcap_admin_alloc(lan966x, ctrl, cfg); 728 if (IS_ERR(admin)) 729 return PTR_ERR(admin); 730 731 lan966x_vcap_block_init(lan966x, admin, cfg); 732 lan966x_vcap_port_key_deselection(lan966x, admin); 733 734 list_add_tail(&admin->list, &ctrl->list); 735 } 736 737 dir = vcap_debugfs(lan966x->dev, lan966x->debugfs_root, ctrl); 738 for (int p = 0; p < lan966x->num_phys_ports; ++p) { 739 if (lan966x->ports[p]) { 740 vcap_port_debugfs(lan966x->dev, dir, ctrl, 741 lan966x->ports[p]->dev); 742 743 lan_rmw(ANA_VCAP_S2_CFG_ENA_SET(true), 744 ANA_VCAP_S2_CFG_ENA, lan966x, 745 ANA_VCAP_S2_CFG(lan966x->ports[p]->chip_port)); 746 747 lan_rmw(ANA_VCAP_CFG_S1_ENA_SET(true), 748 ANA_VCAP_CFG_S1_ENA, lan966x, 749 ANA_VCAP_CFG(lan966x->ports[p]->chip_port)); 750 751 lan_rmw(REW_PORT_CFG_ES0_EN_SET(true), 752 REW_PORT_CFG_ES0_EN, lan966x, 753 REW_PORT_CFG(lan966x->ports[p]->chip_port)); 754 } 755 } 756 757 /* Statistics: Use ESDX from ES0 if hit, otherwise no counting */ 758 lan_rmw(REW_STAT_CFG_STAT_MODE_SET(1), 759 REW_STAT_CFG_STAT_MODE, lan966x, 760 REW_STAT_CFG); 761 762 lan966x->vcap_ctrl = ctrl; 763 764 return 0; 765 } 766 767 void lan966x_vcap_deinit(struct lan966x *lan966x) 768 { 769 struct vcap_admin *admin, *admin_next; 770 struct vcap_control *ctrl; 771 772 ctrl = lan966x->vcap_ctrl; 773 if (!ctrl) 774 return; 775 776 list_for_each_entry_safe(admin, admin_next, &ctrl->list, list) { 777 lan966x_vcap_port_key_deselection(lan966x, admin); 778 vcap_del_rules(ctrl, admin); 779 list_del(&admin->list); 780 lan966x_vcap_admin_free(admin); 781 } 782 783 kfree(ctrl); 784 } 785