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