cpsw_ale.c (37313B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Texas Instruments N-Port Ethernet Switch Address Lookup Engine 4 * 5 * Copyright (C) 2012 Texas Instruments 6 * 7 */ 8#include <linux/bitmap.h> 9#include <linux/if_vlan.h> 10#include <linux/kernel.h> 11#include <linux/module.h> 12#include <linux/platform_device.h> 13#include <linux/seq_file.h> 14#include <linux/slab.h> 15#include <linux/err.h> 16#include <linux/io.h> 17#include <linux/stat.h> 18#include <linux/sysfs.h> 19#include <linux/etherdevice.h> 20 21#include "cpsw_ale.h" 22 23#define BITMASK(bits) (BIT(bits) - 1) 24 25#define ALE_VERSION_MAJOR(rev, mask) (((rev) >> 8) & (mask)) 26#define ALE_VERSION_MINOR(rev) (rev & 0xff) 27#define ALE_VERSION_1R3 0x0103 28#define ALE_VERSION_1R4 0x0104 29 30/* ALE Registers */ 31#define ALE_IDVER 0x00 32#define ALE_STATUS 0x04 33#define ALE_CONTROL 0x08 34#define ALE_PRESCALE 0x10 35#define ALE_AGING_TIMER 0x14 36#define ALE_UNKNOWNVLAN 0x18 37#define ALE_TABLE_CONTROL 0x20 38#define ALE_TABLE 0x34 39#define ALE_PORTCTL 0x40 40 41/* ALE NetCP NU switch specific Registers */ 42#define ALE_UNKNOWNVLAN_MEMBER 0x90 43#define ALE_UNKNOWNVLAN_UNREG_MCAST_FLOOD 0x94 44#define ALE_UNKNOWNVLAN_REG_MCAST_FLOOD 0x98 45#define ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS 0x9C 46#define ALE_VLAN_MASK_MUX(reg) (0xc0 + (0x4 * (reg))) 47 48#define AM65_CPSW_ALE_THREAD_DEF_REG 0x134 49 50/* ALE_AGING_TIMER */ 51#define ALE_AGING_TIMER_MASK GENMASK(23, 0) 52 53#define ALE_RATE_LIMIT_MIN_PPS 1000 54 55/** 56 * struct ale_entry_fld - The ALE tbl entry field description 57 * @start_bit: field start bit 58 * @num_bits: field bit length 59 * @flags: field flags 60 */ 61struct ale_entry_fld { 62 u8 start_bit; 63 u8 num_bits; 64 u8 flags; 65}; 66 67enum { 68 CPSW_ALE_F_STATUS_REG = BIT(0), /* Status register present */ 69 CPSW_ALE_F_HW_AUTOAGING = BIT(1), /* HW auto aging */ 70 71 CPSW_ALE_F_COUNT 72}; 73 74/** 75 * struct cpsw_ale_dev_id - The ALE version/SoC specific configuration 76 * @dev_id: ALE version/SoC id 77 * @features: features supported by ALE 78 * @tbl_entries: number of ALE entries 79 * @major_ver_mask: mask of ALE Major Version Value in ALE_IDVER reg. 80 * @nu_switch_ale: NU Switch ALE 81 * @vlan_entry_tbl: ALE vlan entry fields description tbl 82 */ 83struct cpsw_ale_dev_id { 84 const char *dev_id; 85 u32 features; 86 u32 tbl_entries; 87 u32 major_ver_mask; 88 bool nu_switch_ale; 89 const struct ale_entry_fld *vlan_entry_tbl; 90}; 91 92#define ALE_TABLE_WRITE BIT(31) 93 94#define ALE_TYPE_FREE 0 95#define ALE_TYPE_ADDR 1 96#define ALE_TYPE_VLAN 2 97#define ALE_TYPE_VLAN_ADDR 3 98 99#define ALE_UCAST_PERSISTANT 0 100#define ALE_UCAST_UNTOUCHED 1 101#define ALE_UCAST_OUI 2 102#define ALE_UCAST_TOUCHED 3 103 104#define ALE_TABLE_SIZE_MULTIPLIER 1024 105#define ALE_STATUS_SIZE_MASK 0x1f 106 107static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits) 108{ 109 int idx; 110 111 idx = start / 32; 112 start -= idx * 32; 113 idx = 2 - idx; /* flip */ 114 return (ale_entry[idx] >> start) & BITMASK(bits); 115} 116 117static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits, 118 u32 value) 119{ 120 int idx; 121 122 value &= BITMASK(bits); 123 idx = start / 32; 124 start -= idx * 32; 125 idx = 2 - idx; /* flip */ 126 ale_entry[idx] &= ~(BITMASK(bits) << start); 127 ale_entry[idx] |= (value << start); 128} 129 130#define DEFINE_ALE_FIELD(name, start, bits) \ 131static inline int cpsw_ale_get_##name(u32 *ale_entry) \ 132{ \ 133 return cpsw_ale_get_field(ale_entry, start, bits); \ 134} \ 135static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value) \ 136{ \ 137 cpsw_ale_set_field(ale_entry, start, bits, value); \ 138} 139 140#define DEFINE_ALE_FIELD1(name, start) \ 141static inline int cpsw_ale_get_##name(u32 *ale_entry, u32 bits) \ 142{ \ 143 return cpsw_ale_get_field(ale_entry, start, bits); \ 144} \ 145static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value, \ 146 u32 bits) \ 147{ \ 148 cpsw_ale_set_field(ale_entry, start, bits, value); \ 149} 150 151enum { 152 ALE_ENT_VID_MEMBER_LIST = 0, 153 ALE_ENT_VID_UNREG_MCAST_MSK, 154 ALE_ENT_VID_REG_MCAST_MSK, 155 ALE_ENT_VID_FORCE_UNTAGGED_MSK, 156 ALE_ENT_VID_UNREG_MCAST_IDX, 157 ALE_ENT_VID_REG_MCAST_IDX, 158 ALE_ENT_VID_LAST, 159}; 160 161#define ALE_FLD_ALLOWED BIT(0) 162#define ALE_FLD_SIZE_PORT_MASK_BITS BIT(1) 163#define ALE_FLD_SIZE_PORT_NUM_BITS BIT(2) 164 165#define ALE_ENTRY_FLD(id, start, bits) \ 166[id] = { \ 167 .start_bit = start, \ 168 .num_bits = bits, \ 169 .flags = ALE_FLD_ALLOWED, \ 170} 171 172#define ALE_ENTRY_FLD_DYN_MSK_SIZE(id, start) \ 173[id] = { \ 174 .start_bit = start, \ 175 .num_bits = 0, \ 176 .flags = ALE_FLD_ALLOWED | \ 177 ALE_FLD_SIZE_PORT_MASK_BITS, \ 178} 179 180/* dm814x, am3/am4/am5, k2hk */ 181static const struct ale_entry_fld vlan_entry_cpsw[ALE_ENT_VID_LAST] = { 182 ALE_ENTRY_FLD(ALE_ENT_VID_MEMBER_LIST, 0, 3), 183 ALE_ENTRY_FLD(ALE_ENT_VID_UNREG_MCAST_MSK, 8, 3), 184 ALE_ENTRY_FLD(ALE_ENT_VID_REG_MCAST_MSK, 16, 3), 185 ALE_ENTRY_FLD(ALE_ENT_VID_FORCE_UNTAGGED_MSK, 24, 3), 186}; 187 188/* k2e/k2l, k3 am65/j721e cpsw2g */ 189static const struct ale_entry_fld vlan_entry_nu[ALE_ENT_VID_LAST] = { 190 ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_MEMBER_LIST, 0), 191 ALE_ENTRY_FLD(ALE_ENT_VID_UNREG_MCAST_IDX, 20, 3), 192 ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_FORCE_UNTAGGED_MSK, 24), 193 ALE_ENTRY_FLD(ALE_ENT_VID_REG_MCAST_IDX, 44, 3), 194}; 195 196/* K3 j721e/j7200 cpsw9g/5g, am64x cpsw3g */ 197static const struct ale_entry_fld vlan_entry_k3_cpswxg[] = { 198 ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_MEMBER_LIST, 0), 199 ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_UNREG_MCAST_MSK, 12), 200 ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_FORCE_UNTAGGED_MSK, 24), 201 ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_REG_MCAST_MSK, 36), 202}; 203 204DEFINE_ALE_FIELD(entry_type, 60, 2) 205DEFINE_ALE_FIELD(vlan_id, 48, 12) 206DEFINE_ALE_FIELD(mcast_state, 62, 2) 207DEFINE_ALE_FIELD1(port_mask, 66) 208DEFINE_ALE_FIELD(super, 65, 1) 209DEFINE_ALE_FIELD(ucast_type, 62, 2) 210DEFINE_ALE_FIELD1(port_num, 66) 211DEFINE_ALE_FIELD(blocked, 65, 1) 212DEFINE_ALE_FIELD(secure, 64, 1) 213DEFINE_ALE_FIELD(mcast, 40, 1) 214 215#define NU_VLAN_UNREG_MCAST_IDX 1 216 217static int cpsw_ale_entry_get_fld(struct cpsw_ale *ale, 218 u32 *ale_entry, 219 const struct ale_entry_fld *entry_tbl, 220 int fld_id) 221{ 222 const struct ale_entry_fld *entry_fld; 223 u32 bits; 224 225 if (!ale || !ale_entry) 226 return -EINVAL; 227 228 entry_fld = &entry_tbl[fld_id]; 229 if (!(entry_fld->flags & ALE_FLD_ALLOWED)) { 230 dev_err(ale->params.dev, "get: wrong ale fld id %d\n", fld_id); 231 return -ENOENT; 232 } 233 234 bits = entry_fld->num_bits; 235 if (entry_fld->flags & ALE_FLD_SIZE_PORT_MASK_BITS) 236 bits = ale->port_mask_bits; 237 238 return cpsw_ale_get_field(ale_entry, entry_fld->start_bit, bits); 239} 240 241static void cpsw_ale_entry_set_fld(struct cpsw_ale *ale, 242 u32 *ale_entry, 243 const struct ale_entry_fld *entry_tbl, 244 int fld_id, 245 u32 value) 246{ 247 const struct ale_entry_fld *entry_fld; 248 u32 bits; 249 250 if (!ale || !ale_entry) 251 return; 252 253 entry_fld = &entry_tbl[fld_id]; 254 if (!(entry_fld->flags & ALE_FLD_ALLOWED)) { 255 dev_err(ale->params.dev, "set: wrong ale fld id %d\n", fld_id); 256 return; 257 } 258 259 bits = entry_fld->num_bits; 260 if (entry_fld->flags & ALE_FLD_SIZE_PORT_MASK_BITS) 261 bits = ale->port_mask_bits; 262 263 cpsw_ale_set_field(ale_entry, entry_fld->start_bit, bits, value); 264} 265 266static int cpsw_ale_vlan_get_fld(struct cpsw_ale *ale, 267 u32 *ale_entry, 268 int fld_id) 269{ 270 return cpsw_ale_entry_get_fld(ale, ale_entry, 271 ale->vlan_entry_tbl, fld_id); 272} 273 274static void cpsw_ale_vlan_set_fld(struct cpsw_ale *ale, 275 u32 *ale_entry, 276 int fld_id, 277 u32 value) 278{ 279 cpsw_ale_entry_set_fld(ale, ale_entry, 280 ale->vlan_entry_tbl, fld_id, value); 281} 282 283/* The MAC address field in the ALE entry cannot be macroized as above */ 284static inline void cpsw_ale_get_addr(u32 *ale_entry, u8 *addr) 285{ 286 int i; 287 288 for (i = 0; i < 6; i++) 289 addr[i] = cpsw_ale_get_field(ale_entry, 40 - 8*i, 8); 290} 291 292static inline void cpsw_ale_set_addr(u32 *ale_entry, const u8 *addr) 293{ 294 int i; 295 296 for (i = 0; i < 6; i++) 297 cpsw_ale_set_field(ale_entry, 40 - 8*i, 8, addr[i]); 298} 299 300static int cpsw_ale_read(struct cpsw_ale *ale, int idx, u32 *ale_entry) 301{ 302 int i; 303 304 WARN_ON(idx > ale->params.ale_entries); 305 306 writel_relaxed(idx, ale->params.ale_regs + ALE_TABLE_CONTROL); 307 308 for (i = 0; i < ALE_ENTRY_WORDS; i++) 309 ale_entry[i] = readl_relaxed(ale->params.ale_regs + 310 ALE_TABLE + 4 * i); 311 312 return idx; 313} 314 315static int cpsw_ale_write(struct cpsw_ale *ale, int idx, u32 *ale_entry) 316{ 317 int i; 318 319 WARN_ON(idx > ale->params.ale_entries); 320 321 for (i = 0; i < ALE_ENTRY_WORDS; i++) 322 writel_relaxed(ale_entry[i], ale->params.ale_regs + 323 ALE_TABLE + 4 * i); 324 325 writel_relaxed(idx | ALE_TABLE_WRITE, ale->params.ale_regs + 326 ALE_TABLE_CONTROL); 327 328 return idx; 329} 330 331static int cpsw_ale_match_addr(struct cpsw_ale *ale, const u8 *addr, u16 vid) 332{ 333 u32 ale_entry[ALE_ENTRY_WORDS]; 334 int type, idx; 335 336 for (idx = 0; idx < ale->params.ale_entries; idx++) { 337 u8 entry_addr[6]; 338 339 cpsw_ale_read(ale, idx, ale_entry); 340 type = cpsw_ale_get_entry_type(ale_entry); 341 if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR) 342 continue; 343 if (cpsw_ale_get_vlan_id(ale_entry) != vid) 344 continue; 345 cpsw_ale_get_addr(ale_entry, entry_addr); 346 if (ether_addr_equal(entry_addr, addr)) 347 return idx; 348 } 349 return -ENOENT; 350} 351 352static int cpsw_ale_match_vlan(struct cpsw_ale *ale, u16 vid) 353{ 354 u32 ale_entry[ALE_ENTRY_WORDS]; 355 int type, idx; 356 357 for (idx = 0; idx < ale->params.ale_entries; idx++) { 358 cpsw_ale_read(ale, idx, ale_entry); 359 type = cpsw_ale_get_entry_type(ale_entry); 360 if (type != ALE_TYPE_VLAN) 361 continue; 362 if (cpsw_ale_get_vlan_id(ale_entry) == vid) 363 return idx; 364 } 365 return -ENOENT; 366} 367 368static int cpsw_ale_match_free(struct cpsw_ale *ale) 369{ 370 u32 ale_entry[ALE_ENTRY_WORDS]; 371 int type, idx; 372 373 for (idx = 0; idx < ale->params.ale_entries; idx++) { 374 cpsw_ale_read(ale, idx, ale_entry); 375 type = cpsw_ale_get_entry_type(ale_entry); 376 if (type == ALE_TYPE_FREE) 377 return idx; 378 } 379 return -ENOENT; 380} 381 382static int cpsw_ale_find_ageable(struct cpsw_ale *ale) 383{ 384 u32 ale_entry[ALE_ENTRY_WORDS]; 385 int type, idx; 386 387 for (idx = 0; idx < ale->params.ale_entries; idx++) { 388 cpsw_ale_read(ale, idx, ale_entry); 389 type = cpsw_ale_get_entry_type(ale_entry); 390 if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR) 391 continue; 392 if (cpsw_ale_get_mcast(ale_entry)) 393 continue; 394 type = cpsw_ale_get_ucast_type(ale_entry); 395 if (type != ALE_UCAST_PERSISTANT && 396 type != ALE_UCAST_OUI) 397 return idx; 398 } 399 return -ENOENT; 400} 401 402static void cpsw_ale_flush_mcast(struct cpsw_ale *ale, u32 *ale_entry, 403 int port_mask) 404{ 405 int mask; 406 407 mask = cpsw_ale_get_port_mask(ale_entry, 408 ale->port_mask_bits); 409 if ((mask & port_mask) == 0) 410 return; /* ports dont intersect, not interested */ 411 mask &= ~port_mask; 412 413 /* free if only remaining port is host port */ 414 if (mask) 415 cpsw_ale_set_port_mask(ale_entry, mask, 416 ale->port_mask_bits); 417 else 418 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); 419} 420 421int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid) 422{ 423 u32 ale_entry[ALE_ENTRY_WORDS]; 424 int ret, idx; 425 426 for (idx = 0; idx < ale->params.ale_entries; idx++) { 427 cpsw_ale_read(ale, idx, ale_entry); 428 ret = cpsw_ale_get_entry_type(ale_entry); 429 if (ret != ALE_TYPE_ADDR && ret != ALE_TYPE_VLAN_ADDR) 430 continue; 431 432 /* if vid passed is -1 then remove all multicast entry from 433 * the table irrespective of vlan id, if a valid vlan id is 434 * passed then remove only multicast added to that vlan id. 435 * if vlan id doesn't match then move on to next entry. 436 */ 437 if (vid != -1 && cpsw_ale_get_vlan_id(ale_entry) != vid) 438 continue; 439 440 if (cpsw_ale_get_mcast(ale_entry)) { 441 u8 addr[6]; 442 443 if (cpsw_ale_get_super(ale_entry)) 444 continue; 445 446 cpsw_ale_get_addr(ale_entry, addr); 447 if (!is_broadcast_ether_addr(addr)) 448 cpsw_ale_flush_mcast(ale, ale_entry, port_mask); 449 } 450 451 cpsw_ale_write(ale, idx, ale_entry); 452 } 453 return 0; 454} 455 456static inline void cpsw_ale_set_vlan_entry_type(u32 *ale_entry, 457 int flags, u16 vid) 458{ 459 if (flags & ALE_VLAN) { 460 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_VLAN_ADDR); 461 cpsw_ale_set_vlan_id(ale_entry, vid); 462 } else { 463 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR); 464 } 465} 466 467int cpsw_ale_add_ucast(struct cpsw_ale *ale, const u8 *addr, int port, 468 int flags, u16 vid) 469{ 470 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; 471 int idx; 472 473 cpsw_ale_set_vlan_entry_type(ale_entry, flags, vid); 474 475 cpsw_ale_set_addr(ale_entry, addr); 476 cpsw_ale_set_ucast_type(ale_entry, ALE_UCAST_PERSISTANT); 477 cpsw_ale_set_secure(ale_entry, (flags & ALE_SECURE) ? 1 : 0); 478 cpsw_ale_set_blocked(ale_entry, (flags & ALE_BLOCKED) ? 1 : 0); 479 cpsw_ale_set_port_num(ale_entry, port, ale->port_num_bits); 480 481 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); 482 if (idx < 0) 483 idx = cpsw_ale_match_free(ale); 484 if (idx < 0) 485 idx = cpsw_ale_find_ageable(ale); 486 if (idx < 0) 487 return -ENOMEM; 488 489 cpsw_ale_write(ale, idx, ale_entry); 490 return 0; 491} 492 493int cpsw_ale_del_ucast(struct cpsw_ale *ale, const u8 *addr, int port, 494 int flags, u16 vid) 495{ 496 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; 497 int idx; 498 499 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); 500 if (idx < 0) 501 return -ENOENT; 502 503 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); 504 cpsw_ale_write(ale, idx, ale_entry); 505 return 0; 506} 507 508int cpsw_ale_add_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask, 509 int flags, u16 vid, int mcast_state) 510{ 511 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; 512 int idx, mask; 513 514 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); 515 if (idx >= 0) 516 cpsw_ale_read(ale, idx, ale_entry); 517 518 cpsw_ale_set_vlan_entry_type(ale_entry, flags, vid); 519 520 cpsw_ale_set_addr(ale_entry, addr); 521 cpsw_ale_set_super(ale_entry, (flags & ALE_SUPER) ? 1 : 0); 522 cpsw_ale_set_mcast_state(ale_entry, mcast_state); 523 524 mask = cpsw_ale_get_port_mask(ale_entry, 525 ale->port_mask_bits); 526 port_mask |= mask; 527 cpsw_ale_set_port_mask(ale_entry, port_mask, 528 ale->port_mask_bits); 529 530 if (idx < 0) 531 idx = cpsw_ale_match_free(ale); 532 if (idx < 0) 533 idx = cpsw_ale_find_ageable(ale); 534 if (idx < 0) 535 return -ENOMEM; 536 537 cpsw_ale_write(ale, idx, ale_entry); 538 return 0; 539} 540 541int cpsw_ale_del_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask, 542 int flags, u16 vid) 543{ 544 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; 545 int mcast_members = 0; 546 int idx; 547 548 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); 549 if (idx < 0) 550 return -ENOENT; 551 552 cpsw_ale_read(ale, idx, ale_entry); 553 554 if (port_mask) { 555 mcast_members = cpsw_ale_get_port_mask(ale_entry, 556 ale->port_mask_bits); 557 mcast_members &= ~port_mask; 558 } 559 560 if (mcast_members) 561 cpsw_ale_set_port_mask(ale_entry, mcast_members, 562 ale->port_mask_bits); 563 else 564 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); 565 566 cpsw_ale_write(ale, idx, ale_entry); 567 return 0; 568} 569 570/* ALE NetCP NU switch specific vlan functions */ 571static void cpsw_ale_set_vlan_mcast(struct cpsw_ale *ale, u32 *ale_entry, 572 int reg_mcast, int unreg_mcast) 573{ 574 int idx; 575 576 /* Set VLAN registered multicast flood mask */ 577 idx = cpsw_ale_vlan_get_fld(ale, ale_entry, 578 ALE_ENT_VID_REG_MCAST_IDX); 579 writel(reg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx)); 580 581 /* Set VLAN unregistered multicast flood mask */ 582 idx = cpsw_ale_vlan_get_fld(ale, ale_entry, 583 ALE_ENT_VID_UNREG_MCAST_IDX); 584 writel(unreg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx)); 585} 586 587static void cpsw_ale_set_vlan_untag(struct cpsw_ale *ale, u32 *ale_entry, 588 u16 vid, int untag_mask) 589{ 590 cpsw_ale_vlan_set_fld(ale, ale_entry, 591 ALE_ENT_VID_FORCE_UNTAGGED_MSK, 592 untag_mask); 593 if (untag_mask & ALE_PORT_HOST) 594 bitmap_set(ale->p0_untag_vid_mask, vid, 1); 595 else 596 bitmap_clear(ale->p0_untag_vid_mask, vid, 1); 597} 598 599int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port_mask, int untag, 600 int reg_mcast, int unreg_mcast) 601{ 602 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; 603 int idx; 604 605 idx = cpsw_ale_match_vlan(ale, vid); 606 if (idx >= 0) 607 cpsw_ale_read(ale, idx, ale_entry); 608 609 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_VLAN); 610 cpsw_ale_set_vlan_id(ale_entry, vid); 611 cpsw_ale_set_vlan_untag(ale, ale_entry, vid, untag); 612 613 if (!ale->params.nu_switch_ale) { 614 cpsw_ale_vlan_set_fld(ale, ale_entry, 615 ALE_ENT_VID_REG_MCAST_MSK, reg_mcast); 616 cpsw_ale_vlan_set_fld(ale, ale_entry, 617 ALE_ENT_VID_UNREG_MCAST_MSK, unreg_mcast); 618 } else { 619 cpsw_ale_vlan_set_fld(ale, ale_entry, 620 ALE_ENT_VID_UNREG_MCAST_IDX, 621 NU_VLAN_UNREG_MCAST_IDX); 622 cpsw_ale_set_vlan_mcast(ale, ale_entry, reg_mcast, unreg_mcast); 623 } 624 625 cpsw_ale_vlan_set_fld(ale, ale_entry, 626 ALE_ENT_VID_MEMBER_LIST, port_mask); 627 628 if (idx < 0) 629 idx = cpsw_ale_match_free(ale); 630 if (idx < 0) 631 idx = cpsw_ale_find_ageable(ale); 632 if (idx < 0) 633 return -ENOMEM; 634 635 cpsw_ale_write(ale, idx, ale_entry); 636 return 0; 637} 638 639static void cpsw_ale_vlan_del_modify_int(struct cpsw_ale *ale, u32 *ale_entry, 640 u16 vid, int port_mask) 641{ 642 int reg_mcast, unreg_mcast; 643 int members, untag; 644 645 members = cpsw_ale_vlan_get_fld(ale, ale_entry, 646 ALE_ENT_VID_MEMBER_LIST); 647 members &= ~port_mask; 648 if (!members) { 649 cpsw_ale_set_vlan_untag(ale, ale_entry, vid, 0); 650 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); 651 return; 652 } 653 654 untag = cpsw_ale_vlan_get_fld(ale, ale_entry, 655 ALE_ENT_VID_FORCE_UNTAGGED_MSK); 656 reg_mcast = cpsw_ale_vlan_get_fld(ale, ale_entry, 657 ALE_ENT_VID_REG_MCAST_MSK); 658 unreg_mcast = cpsw_ale_vlan_get_fld(ale, ale_entry, 659 ALE_ENT_VID_UNREG_MCAST_MSK); 660 untag &= members; 661 reg_mcast &= members; 662 unreg_mcast &= members; 663 664 cpsw_ale_set_vlan_untag(ale, ale_entry, vid, untag); 665 666 if (!ale->params.nu_switch_ale) { 667 cpsw_ale_vlan_set_fld(ale, ale_entry, 668 ALE_ENT_VID_REG_MCAST_MSK, reg_mcast); 669 cpsw_ale_vlan_set_fld(ale, ale_entry, 670 ALE_ENT_VID_UNREG_MCAST_MSK, unreg_mcast); 671 } else { 672 cpsw_ale_set_vlan_mcast(ale, ale_entry, reg_mcast, 673 unreg_mcast); 674 } 675 cpsw_ale_vlan_set_fld(ale, ale_entry, 676 ALE_ENT_VID_MEMBER_LIST, members); 677} 678 679int cpsw_ale_vlan_del_modify(struct cpsw_ale *ale, u16 vid, int port_mask) 680{ 681 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; 682 int idx; 683 684 idx = cpsw_ale_match_vlan(ale, vid); 685 if (idx < 0) 686 return -ENOENT; 687 688 cpsw_ale_read(ale, idx, ale_entry); 689 690 cpsw_ale_vlan_del_modify_int(ale, ale_entry, vid, port_mask); 691 cpsw_ale_write(ale, idx, ale_entry); 692 693 return 0; 694} 695 696int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port_mask) 697{ 698 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; 699 int members, idx; 700 701 idx = cpsw_ale_match_vlan(ale, vid); 702 if (idx < 0) 703 return -ENOENT; 704 705 cpsw_ale_read(ale, idx, ale_entry); 706 707 /* if !port_mask - force remove VLAN (legacy). 708 * Check if there are other VLAN members ports 709 * if no - remove VLAN. 710 * if yes it means same VLAN was added to >1 port in multi port mode, so 711 * remove port_mask ports from VLAN ALE entry excluding Host port. 712 */ 713 members = cpsw_ale_vlan_get_fld(ale, ale_entry, ALE_ENT_VID_MEMBER_LIST); 714 members &= ~port_mask; 715 716 if (!port_mask || !members) { 717 /* last port or force remove - remove VLAN */ 718 cpsw_ale_set_vlan_untag(ale, ale_entry, vid, 0); 719 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); 720 } else { 721 port_mask &= ~ALE_PORT_HOST; 722 cpsw_ale_vlan_del_modify_int(ale, ale_entry, vid, port_mask); 723 } 724 725 cpsw_ale_write(ale, idx, ale_entry); 726 727 return 0; 728} 729 730int cpsw_ale_vlan_add_modify(struct cpsw_ale *ale, u16 vid, int port_mask, 731 int untag_mask, int reg_mask, int unreg_mask) 732{ 733 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; 734 int reg_mcast_members, unreg_mcast_members; 735 int vlan_members, untag_members; 736 int idx, ret = 0; 737 738 idx = cpsw_ale_match_vlan(ale, vid); 739 if (idx >= 0) 740 cpsw_ale_read(ale, idx, ale_entry); 741 742 vlan_members = cpsw_ale_vlan_get_fld(ale, ale_entry, 743 ALE_ENT_VID_MEMBER_LIST); 744 reg_mcast_members = cpsw_ale_vlan_get_fld(ale, ale_entry, 745 ALE_ENT_VID_REG_MCAST_MSK); 746 unreg_mcast_members = 747 cpsw_ale_vlan_get_fld(ale, ale_entry, 748 ALE_ENT_VID_UNREG_MCAST_MSK); 749 untag_members = cpsw_ale_vlan_get_fld(ale, ale_entry, 750 ALE_ENT_VID_FORCE_UNTAGGED_MSK); 751 752 vlan_members |= port_mask; 753 untag_members = (untag_members & ~port_mask) | untag_mask; 754 reg_mcast_members = (reg_mcast_members & ~port_mask) | reg_mask; 755 unreg_mcast_members = (unreg_mcast_members & ~port_mask) | unreg_mask; 756 757 ret = cpsw_ale_add_vlan(ale, vid, vlan_members, untag_members, 758 reg_mcast_members, unreg_mcast_members); 759 if (ret) { 760 dev_err(ale->params.dev, "Unable to add vlan\n"); 761 return ret; 762 } 763 dev_dbg(ale->params.dev, "port mask 0x%x untag 0x%x\n", vlan_members, 764 untag_mask); 765 766 return ret; 767} 768 769void cpsw_ale_set_unreg_mcast(struct cpsw_ale *ale, int unreg_mcast_mask, 770 bool add) 771{ 772 u32 ale_entry[ALE_ENTRY_WORDS]; 773 int unreg_members = 0; 774 int type, idx; 775 776 for (idx = 0; idx < ale->params.ale_entries; idx++) { 777 cpsw_ale_read(ale, idx, ale_entry); 778 type = cpsw_ale_get_entry_type(ale_entry); 779 if (type != ALE_TYPE_VLAN) 780 continue; 781 782 unreg_members = 783 cpsw_ale_vlan_get_fld(ale, ale_entry, 784 ALE_ENT_VID_UNREG_MCAST_MSK); 785 if (add) 786 unreg_members |= unreg_mcast_mask; 787 else 788 unreg_members &= ~unreg_mcast_mask; 789 cpsw_ale_vlan_set_fld(ale, ale_entry, 790 ALE_ENT_VID_UNREG_MCAST_MSK, 791 unreg_members); 792 cpsw_ale_write(ale, idx, ale_entry); 793 } 794} 795 796static void cpsw_ale_vlan_set_unreg_mcast(struct cpsw_ale *ale, u32 *ale_entry, 797 int allmulti) 798{ 799 int unreg_mcast; 800 801 unreg_mcast = cpsw_ale_vlan_get_fld(ale, ale_entry, 802 ALE_ENT_VID_UNREG_MCAST_MSK); 803 if (allmulti) 804 unreg_mcast |= ALE_PORT_HOST; 805 else 806 unreg_mcast &= ~ALE_PORT_HOST; 807 808 cpsw_ale_vlan_set_fld(ale, ale_entry, 809 ALE_ENT_VID_UNREG_MCAST_MSK, unreg_mcast); 810} 811 812static void 813cpsw_ale_vlan_set_unreg_mcast_idx(struct cpsw_ale *ale, u32 *ale_entry, 814 int allmulti) 815{ 816 int unreg_mcast; 817 int idx; 818 819 idx = cpsw_ale_vlan_get_fld(ale, ale_entry, 820 ALE_ENT_VID_UNREG_MCAST_IDX); 821 822 unreg_mcast = readl(ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx)); 823 824 if (allmulti) 825 unreg_mcast |= ALE_PORT_HOST; 826 else 827 unreg_mcast &= ~ALE_PORT_HOST; 828 829 writel(unreg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx)); 830} 831 832void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti, int port) 833{ 834 u32 ale_entry[ALE_ENTRY_WORDS]; 835 int type, idx; 836 837 for (idx = 0; idx < ale->params.ale_entries; idx++) { 838 int vlan_members; 839 840 cpsw_ale_read(ale, idx, ale_entry); 841 type = cpsw_ale_get_entry_type(ale_entry); 842 if (type != ALE_TYPE_VLAN) 843 continue; 844 845 vlan_members = cpsw_ale_vlan_get_fld(ale, ale_entry, 846 ALE_ENT_VID_MEMBER_LIST); 847 848 if (port != -1 && !(vlan_members & BIT(port))) 849 continue; 850 851 if (!ale->params.nu_switch_ale) 852 cpsw_ale_vlan_set_unreg_mcast(ale, ale_entry, allmulti); 853 else 854 cpsw_ale_vlan_set_unreg_mcast_idx(ale, ale_entry, 855 allmulti); 856 857 cpsw_ale_write(ale, idx, ale_entry); 858 } 859} 860 861struct ale_control_info { 862 const char *name; 863 int offset, port_offset; 864 int shift, port_shift; 865 int bits; 866}; 867 868static struct ale_control_info ale_controls[ALE_NUM_CONTROLS] = { 869 [ALE_ENABLE] = { 870 .name = "enable", 871 .offset = ALE_CONTROL, 872 .port_offset = 0, 873 .shift = 31, 874 .port_shift = 0, 875 .bits = 1, 876 }, 877 [ALE_CLEAR] = { 878 .name = "clear", 879 .offset = ALE_CONTROL, 880 .port_offset = 0, 881 .shift = 30, 882 .port_shift = 0, 883 .bits = 1, 884 }, 885 [ALE_AGEOUT] = { 886 .name = "ageout", 887 .offset = ALE_CONTROL, 888 .port_offset = 0, 889 .shift = 29, 890 .port_shift = 0, 891 .bits = 1, 892 }, 893 [ALE_P0_UNI_FLOOD] = { 894 .name = "port0_unicast_flood", 895 .offset = ALE_CONTROL, 896 .port_offset = 0, 897 .shift = 8, 898 .port_shift = 0, 899 .bits = 1, 900 }, 901 [ALE_VLAN_NOLEARN] = { 902 .name = "vlan_nolearn", 903 .offset = ALE_CONTROL, 904 .port_offset = 0, 905 .shift = 7, 906 .port_shift = 0, 907 .bits = 1, 908 }, 909 [ALE_NO_PORT_VLAN] = { 910 .name = "no_port_vlan", 911 .offset = ALE_CONTROL, 912 .port_offset = 0, 913 .shift = 6, 914 .port_shift = 0, 915 .bits = 1, 916 }, 917 [ALE_OUI_DENY] = { 918 .name = "oui_deny", 919 .offset = ALE_CONTROL, 920 .port_offset = 0, 921 .shift = 5, 922 .port_shift = 0, 923 .bits = 1, 924 }, 925 [ALE_BYPASS] = { 926 .name = "bypass", 927 .offset = ALE_CONTROL, 928 .port_offset = 0, 929 .shift = 4, 930 .port_shift = 0, 931 .bits = 1, 932 }, 933 [ALE_RATE_LIMIT_TX] = { 934 .name = "rate_limit_tx", 935 .offset = ALE_CONTROL, 936 .port_offset = 0, 937 .shift = 3, 938 .port_shift = 0, 939 .bits = 1, 940 }, 941 [ALE_VLAN_AWARE] = { 942 .name = "vlan_aware", 943 .offset = ALE_CONTROL, 944 .port_offset = 0, 945 .shift = 2, 946 .port_shift = 0, 947 .bits = 1, 948 }, 949 [ALE_AUTH_ENABLE] = { 950 .name = "auth_enable", 951 .offset = ALE_CONTROL, 952 .port_offset = 0, 953 .shift = 1, 954 .port_shift = 0, 955 .bits = 1, 956 }, 957 [ALE_RATE_LIMIT] = { 958 .name = "rate_limit", 959 .offset = ALE_CONTROL, 960 .port_offset = 0, 961 .shift = 0, 962 .port_shift = 0, 963 .bits = 1, 964 }, 965 [ALE_PORT_STATE] = { 966 .name = "port_state", 967 .offset = ALE_PORTCTL, 968 .port_offset = 4, 969 .shift = 0, 970 .port_shift = 0, 971 .bits = 2, 972 }, 973 [ALE_PORT_DROP_UNTAGGED] = { 974 .name = "drop_untagged", 975 .offset = ALE_PORTCTL, 976 .port_offset = 4, 977 .shift = 2, 978 .port_shift = 0, 979 .bits = 1, 980 }, 981 [ALE_PORT_DROP_UNKNOWN_VLAN] = { 982 .name = "drop_unknown", 983 .offset = ALE_PORTCTL, 984 .port_offset = 4, 985 .shift = 3, 986 .port_shift = 0, 987 .bits = 1, 988 }, 989 [ALE_PORT_NOLEARN] = { 990 .name = "nolearn", 991 .offset = ALE_PORTCTL, 992 .port_offset = 4, 993 .shift = 4, 994 .port_shift = 0, 995 .bits = 1, 996 }, 997 [ALE_PORT_NO_SA_UPDATE] = { 998 .name = "no_source_update", 999 .offset = ALE_PORTCTL, 1000 .port_offset = 4, 1001 .shift = 5, 1002 .port_shift = 0, 1003 .bits = 1, 1004 }, 1005 [ALE_PORT_MACONLY] = { 1006 .name = "mac_only_port_mode", 1007 .offset = ALE_PORTCTL, 1008 .port_offset = 4, 1009 .shift = 11, 1010 .port_shift = 0, 1011 .bits = 1, 1012 }, 1013 [ALE_PORT_MACONLY_CAF] = { 1014 .name = "mac_only_port_caf", 1015 .offset = ALE_PORTCTL, 1016 .port_offset = 4, 1017 .shift = 13, 1018 .port_shift = 0, 1019 .bits = 1, 1020 }, 1021 [ALE_PORT_MCAST_LIMIT] = { 1022 .name = "mcast_limit", 1023 .offset = ALE_PORTCTL, 1024 .port_offset = 4, 1025 .shift = 16, 1026 .port_shift = 0, 1027 .bits = 8, 1028 }, 1029 [ALE_PORT_BCAST_LIMIT] = { 1030 .name = "bcast_limit", 1031 .offset = ALE_PORTCTL, 1032 .port_offset = 4, 1033 .shift = 24, 1034 .port_shift = 0, 1035 .bits = 8, 1036 }, 1037 [ALE_PORT_UNKNOWN_VLAN_MEMBER] = { 1038 .name = "unknown_vlan_member", 1039 .offset = ALE_UNKNOWNVLAN, 1040 .port_offset = 0, 1041 .shift = 0, 1042 .port_shift = 0, 1043 .bits = 6, 1044 }, 1045 [ALE_PORT_UNKNOWN_MCAST_FLOOD] = { 1046 .name = "unknown_mcast_flood", 1047 .offset = ALE_UNKNOWNVLAN, 1048 .port_offset = 0, 1049 .shift = 8, 1050 .port_shift = 0, 1051 .bits = 6, 1052 }, 1053 [ALE_PORT_UNKNOWN_REG_MCAST_FLOOD] = { 1054 .name = "unknown_reg_flood", 1055 .offset = ALE_UNKNOWNVLAN, 1056 .port_offset = 0, 1057 .shift = 16, 1058 .port_shift = 0, 1059 .bits = 6, 1060 }, 1061 [ALE_PORT_UNTAGGED_EGRESS] = { 1062 .name = "untagged_egress", 1063 .offset = ALE_UNKNOWNVLAN, 1064 .port_offset = 0, 1065 .shift = 24, 1066 .port_shift = 0, 1067 .bits = 6, 1068 }, 1069 [ALE_DEFAULT_THREAD_ID] = { 1070 .name = "default_thread_id", 1071 .offset = AM65_CPSW_ALE_THREAD_DEF_REG, 1072 .port_offset = 0, 1073 .shift = 0, 1074 .port_shift = 0, 1075 .bits = 6, 1076 }, 1077 [ALE_DEFAULT_THREAD_ENABLE] = { 1078 .name = "default_thread_id_enable", 1079 .offset = AM65_CPSW_ALE_THREAD_DEF_REG, 1080 .port_offset = 0, 1081 .shift = 15, 1082 .port_shift = 0, 1083 .bits = 1, 1084 }, 1085}; 1086 1087int cpsw_ale_control_set(struct cpsw_ale *ale, int port, int control, 1088 int value) 1089{ 1090 const struct ale_control_info *info; 1091 int offset, shift; 1092 u32 tmp, mask; 1093 1094 if (control < 0 || control >= ARRAY_SIZE(ale_controls)) 1095 return -EINVAL; 1096 1097 info = &ale_controls[control]; 1098 if (info->port_offset == 0 && info->port_shift == 0) 1099 port = 0; /* global, port is a dont care */ 1100 1101 if (port < 0 || port >= ale->params.ale_ports) 1102 return -EINVAL; 1103 1104 mask = BITMASK(info->bits); 1105 if (value & ~mask) 1106 return -EINVAL; 1107 1108 offset = info->offset + (port * info->port_offset); 1109 shift = info->shift + (port * info->port_shift); 1110 1111 tmp = readl_relaxed(ale->params.ale_regs + offset); 1112 tmp = (tmp & ~(mask << shift)) | (value << shift); 1113 writel_relaxed(tmp, ale->params.ale_regs + offset); 1114 1115 return 0; 1116} 1117 1118int cpsw_ale_control_get(struct cpsw_ale *ale, int port, int control) 1119{ 1120 const struct ale_control_info *info; 1121 int offset, shift; 1122 u32 tmp; 1123 1124 if (control < 0 || control >= ARRAY_SIZE(ale_controls)) 1125 return -EINVAL; 1126 1127 info = &ale_controls[control]; 1128 if (info->port_offset == 0 && info->port_shift == 0) 1129 port = 0; /* global, port is a dont care */ 1130 1131 if (port < 0 || port >= ale->params.ale_ports) 1132 return -EINVAL; 1133 1134 offset = info->offset + (port * info->port_offset); 1135 shift = info->shift + (port * info->port_shift); 1136 1137 tmp = readl_relaxed(ale->params.ale_regs + offset) >> shift; 1138 return tmp & BITMASK(info->bits); 1139} 1140 1141int cpsw_ale_rx_ratelimit_mc(struct cpsw_ale *ale, int port, unsigned int ratelimit_pps) 1142 1143{ 1144 int val = ratelimit_pps / ALE_RATE_LIMIT_MIN_PPS; 1145 u32 remainder = ratelimit_pps % ALE_RATE_LIMIT_MIN_PPS; 1146 1147 if (ratelimit_pps && !val) { 1148 dev_err(ale->params.dev, "ALE MC port:%d ratelimit min value 1000pps\n", port); 1149 return -EINVAL; 1150 } 1151 1152 if (remainder) 1153 dev_info(ale->params.dev, "ALE port:%d MC ratelimit set to %dpps (requested %d)\n", 1154 port, ratelimit_pps - remainder, ratelimit_pps); 1155 1156 cpsw_ale_control_set(ale, port, ALE_PORT_MCAST_LIMIT, val); 1157 1158 dev_dbg(ale->params.dev, "ALE port:%d MC ratelimit set %d\n", 1159 port, val * ALE_RATE_LIMIT_MIN_PPS); 1160 return 0; 1161} 1162 1163int cpsw_ale_rx_ratelimit_bc(struct cpsw_ale *ale, int port, unsigned int ratelimit_pps) 1164 1165{ 1166 int val = ratelimit_pps / ALE_RATE_LIMIT_MIN_PPS; 1167 u32 remainder = ratelimit_pps % ALE_RATE_LIMIT_MIN_PPS; 1168 1169 if (ratelimit_pps && !val) { 1170 dev_err(ale->params.dev, "ALE port:%d BC ratelimit min value 1000pps\n", port); 1171 return -EINVAL; 1172 } 1173 1174 if (remainder) 1175 dev_info(ale->params.dev, "ALE port:%d BC ratelimit set to %dpps (requested %d)\n", 1176 port, ratelimit_pps - remainder, ratelimit_pps); 1177 1178 cpsw_ale_control_set(ale, port, ALE_PORT_BCAST_LIMIT, val); 1179 1180 dev_dbg(ale->params.dev, "ALE port:%d BC ratelimit set %d\n", 1181 port, val * ALE_RATE_LIMIT_MIN_PPS); 1182 return 0; 1183} 1184 1185static void cpsw_ale_timer(struct timer_list *t) 1186{ 1187 struct cpsw_ale *ale = from_timer(ale, t, timer); 1188 1189 cpsw_ale_control_set(ale, 0, ALE_AGEOUT, 1); 1190 1191 if (ale->ageout) { 1192 ale->timer.expires = jiffies + ale->ageout; 1193 add_timer(&ale->timer); 1194 } 1195} 1196 1197static void cpsw_ale_hw_aging_timer_start(struct cpsw_ale *ale) 1198{ 1199 u32 aging_timer; 1200 1201 aging_timer = ale->params.bus_freq / 1000000; 1202 aging_timer *= ale->params.ale_ageout; 1203 1204 if (aging_timer & ~ALE_AGING_TIMER_MASK) { 1205 aging_timer = ALE_AGING_TIMER_MASK; 1206 dev_warn(ale->params.dev, 1207 "ALE aging timer overflow, set to max\n"); 1208 } 1209 1210 writel(aging_timer, ale->params.ale_regs + ALE_AGING_TIMER); 1211} 1212 1213static void cpsw_ale_hw_aging_timer_stop(struct cpsw_ale *ale) 1214{ 1215 writel(0, ale->params.ale_regs + ALE_AGING_TIMER); 1216} 1217 1218static void cpsw_ale_aging_start(struct cpsw_ale *ale) 1219{ 1220 if (!ale->params.ale_ageout) 1221 return; 1222 1223 if (ale->features & CPSW_ALE_F_HW_AUTOAGING) { 1224 cpsw_ale_hw_aging_timer_start(ale); 1225 return; 1226 } 1227 1228 timer_setup(&ale->timer, cpsw_ale_timer, 0); 1229 ale->timer.expires = jiffies + ale->ageout; 1230 add_timer(&ale->timer); 1231} 1232 1233static void cpsw_ale_aging_stop(struct cpsw_ale *ale) 1234{ 1235 if (!ale->params.ale_ageout) 1236 return; 1237 1238 if (ale->features & CPSW_ALE_F_HW_AUTOAGING) { 1239 cpsw_ale_hw_aging_timer_stop(ale); 1240 return; 1241 } 1242 1243 del_timer_sync(&ale->timer); 1244} 1245 1246void cpsw_ale_start(struct cpsw_ale *ale) 1247{ 1248 unsigned long ale_prescale; 1249 1250 /* configure Broadcast and Multicast Rate Limit 1251 * number_of_packets = (Fclk / ALE_PRESCALE) * port.BCAST/MCAST_LIMIT 1252 * ALE_PRESCALE width is 19bit and min value 0x10 1253 * port.BCAST/MCAST_LIMIT is 8bit 1254 * 1255 * For multi port configuration support the ALE_PRESCALE is configured to 1ms interval, 1256 * which allows to configure port.BCAST/MCAST_LIMIT per port and achieve: 1257 * min number_of_packets = 1000 when port.BCAST/MCAST_LIMIT = 1 1258 * max number_of_packets = 1000 * 255 = 255000 when port.BCAST/MCAST_LIMIT = 0xFF 1259 */ 1260 ale_prescale = ale->params.bus_freq / ALE_RATE_LIMIT_MIN_PPS; 1261 writel((u32)ale_prescale, ale->params.ale_regs + ALE_PRESCALE); 1262 1263 /* Allow MC/BC rate limiting globally. 1264 * The actual Rate Limit cfg enabled per-port by port.BCAST/MCAST_LIMIT 1265 */ 1266 cpsw_ale_control_set(ale, 0, ALE_RATE_LIMIT, 1); 1267 1268 cpsw_ale_control_set(ale, 0, ALE_ENABLE, 1); 1269 cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1); 1270 1271 cpsw_ale_aging_start(ale); 1272} 1273 1274void cpsw_ale_stop(struct cpsw_ale *ale) 1275{ 1276 cpsw_ale_aging_stop(ale); 1277 cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1); 1278 cpsw_ale_control_set(ale, 0, ALE_ENABLE, 0); 1279} 1280 1281static const struct cpsw_ale_dev_id cpsw_ale_id_match[] = { 1282 { 1283 /* am3/4/5, dra7. dm814x, 66ak2hk-gbe */ 1284 .dev_id = "cpsw", 1285 .tbl_entries = 1024, 1286 .major_ver_mask = 0xff, 1287 .vlan_entry_tbl = vlan_entry_cpsw, 1288 }, 1289 { 1290 /* 66ak2h_xgbe */ 1291 .dev_id = "66ak2h-xgbe", 1292 .tbl_entries = 2048, 1293 .major_ver_mask = 0xff, 1294 .vlan_entry_tbl = vlan_entry_cpsw, 1295 }, 1296 { 1297 .dev_id = "66ak2el", 1298 .features = CPSW_ALE_F_STATUS_REG, 1299 .major_ver_mask = 0x7, 1300 .nu_switch_ale = true, 1301 .vlan_entry_tbl = vlan_entry_nu, 1302 }, 1303 { 1304 .dev_id = "66ak2g", 1305 .features = CPSW_ALE_F_STATUS_REG, 1306 .tbl_entries = 64, 1307 .major_ver_mask = 0x7, 1308 .nu_switch_ale = true, 1309 .vlan_entry_tbl = vlan_entry_nu, 1310 }, 1311 { 1312 .dev_id = "am65x-cpsw2g", 1313 .features = CPSW_ALE_F_STATUS_REG | CPSW_ALE_F_HW_AUTOAGING, 1314 .tbl_entries = 64, 1315 .major_ver_mask = 0x7, 1316 .nu_switch_ale = true, 1317 .vlan_entry_tbl = vlan_entry_nu, 1318 }, 1319 { 1320 .dev_id = "j721e-cpswxg", 1321 .features = CPSW_ALE_F_STATUS_REG | CPSW_ALE_F_HW_AUTOAGING, 1322 .major_ver_mask = 0x7, 1323 .vlan_entry_tbl = vlan_entry_k3_cpswxg, 1324 }, 1325 { 1326 .dev_id = "am64-cpswxg", 1327 .features = CPSW_ALE_F_STATUS_REG | CPSW_ALE_F_HW_AUTOAGING, 1328 .major_ver_mask = 0x7, 1329 .vlan_entry_tbl = vlan_entry_k3_cpswxg, 1330 .tbl_entries = 512, 1331 }, 1332 { }, 1333}; 1334 1335static const struct 1336cpsw_ale_dev_id *cpsw_ale_match_id(const struct cpsw_ale_dev_id *id, 1337 const char *dev_id) 1338{ 1339 if (!dev_id) 1340 return NULL; 1341 1342 while (id->dev_id) { 1343 if (strcmp(dev_id, id->dev_id) == 0) 1344 return id; 1345 id++; 1346 } 1347 return NULL; 1348} 1349 1350struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params) 1351{ 1352 const struct cpsw_ale_dev_id *ale_dev_id; 1353 struct cpsw_ale *ale; 1354 u32 rev, ale_entries; 1355 1356 ale_dev_id = cpsw_ale_match_id(cpsw_ale_id_match, params->dev_id); 1357 if (!ale_dev_id) 1358 return ERR_PTR(-EINVAL); 1359 1360 params->ale_entries = ale_dev_id->tbl_entries; 1361 params->major_ver_mask = ale_dev_id->major_ver_mask; 1362 params->nu_switch_ale = ale_dev_id->nu_switch_ale; 1363 1364 ale = devm_kzalloc(params->dev, sizeof(*ale), GFP_KERNEL); 1365 if (!ale) 1366 return ERR_PTR(-ENOMEM); 1367 1368 ale->p0_untag_vid_mask = devm_bitmap_zalloc(params->dev, VLAN_N_VID, 1369 GFP_KERNEL); 1370 if (!ale->p0_untag_vid_mask) 1371 return ERR_PTR(-ENOMEM); 1372 1373 ale->params = *params; 1374 ale->ageout = ale->params.ale_ageout * HZ; 1375 ale->features = ale_dev_id->features; 1376 ale->vlan_entry_tbl = ale_dev_id->vlan_entry_tbl; 1377 1378 rev = readl_relaxed(ale->params.ale_regs + ALE_IDVER); 1379 ale->version = 1380 (ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask) << 8) | 1381 ALE_VERSION_MINOR(rev); 1382 dev_info(ale->params.dev, "initialized cpsw ale version %d.%d\n", 1383 ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask), 1384 ALE_VERSION_MINOR(rev)); 1385 1386 if (ale->features & CPSW_ALE_F_STATUS_REG && 1387 !ale->params.ale_entries) { 1388 ale_entries = 1389 readl_relaxed(ale->params.ale_regs + ALE_STATUS) & 1390 ALE_STATUS_SIZE_MASK; 1391 /* ALE available on newer NetCP switches has introduced 1392 * a register, ALE_STATUS, to indicate the size of ALE 1393 * table which shows the size as a multiple of 1024 entries. 1394 * For these, params.ale_entries will be set to zero. So 1395 * read the register and update the value of ale_entries. 1396 * return error if ale_entries is zero in ALE_STATUS. 1397 */ 1398 if (!ale_entries) 1399 return ERR_PTR(-EINVAL); 1400 1401 ale_entries *= ALE_TABLE_SIZE_MULTIPLIER; 1402 ale->params.ale_entries = ale_entries; 1403 } 1404 dev_info(ale->params.dev, 1405 "ALE Table size %ld\n", ale->params.ale_entries); 1406 1407 /* set default bits for existing h/w */ 1408 ale->port_mask_bits = ale->params.ale_ports; 1409 ale->port_num_bits = order_base_2(ale->params.ale_ports); 1410 ale->vlan_field_bits = ale->params.ale_ports; 1411 1412 /* Set defaults override for ALE on NetCP NU switch and for version 1413 * 1R3 1414 */ 1415 if (ale->params.nu_switch_ale) { 1416 /* Separate registers for unknown vlan configuration. 1417 * Also there are N bits, where N is number of ale 1418 * ports and shift value should be 0 1419 */ 1420 ale_controls[ALE_PORT_UNKNOWN_VLAN_MEMBER].bits = 1421 ale->params.ale_ports; 1422 ale_controls[ALE_PORT_UNKNOWN_VLAN_MEMBER].offset = 1423 ALE_UNKNOWNVLAN_MEMBER; 1424 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].bits = 1425 ale->params.ale_ports; 1426 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].shift = 0; 1427 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].offset = 1428 ALE_UNKNOWNVLAN_UNREG_MCAST_FLOOD; 1429 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].bits = 1430 ale->params.ale_ports; 1431 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].shift = 0; 1432 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].offset = 1433 ALE_UNKNOWNVLAN_REG_MCAST_FLOOD; 1434 ale_controls[ALE_PORT_UNTAGGED_EGRESS].bits = 1435 ale->params.ale_ports; 1436 ale_controls[ALE_PORT_UNTAGGED_EGRESS].shift = 0; 1437 ale_controls[ALE_PORT_UNTAGGED_EGRESS].offset = 1438 ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS; 1439 } 1440 1441 cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1); 1442 return ale; 1443} 1444 1445void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data) 1446{ 1447 int i; 1448 1449 for (i = 0; i < ale->params.ale_entries; i++) { 1450 cpsw_ale_read(ale, i, data); 1451 data += ALE_ENTRY_WORDS; 1452 } 1453} 1454 1455u32 cpsw_ale_get_num_entries(struct cpsw_ale *ale) 1456{ 1457 return ale ? ale->params.ale_entries : 0; 1458}