1 /* 2 * Texas Instruments N-Port Ethernet Switch Address Lookup Engine 3 * 4 * Copyright (C) 2012 Texas Instruments 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation version 2. 9 * 10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 11 * kind, whether express or implied; without even the implied warranty 12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 */ 15 #include <linux/kernel.h> 16 #include <linux/module.h> 17 #include <linux/platform_device.h> 18 #include <linux/seq_file.h> 19 #include <linux/slab.h> 20 #include <linux/err.h> 21 #include <linux/io.h> 22 #include <linux/stat.h> 23 #include <linux/sysfs.h> 24 #include <linux/etherdevice.h> 25 26 #include "cpsw_ale.h" 27 28 #define BITMASK(bits) (BIT(bits) - 1) 29 30 #define ALE_VERSION_MAJOR(rev, mask) (((rev) >> 8) & (mask)) 31 #define ALE_VERSION_MINOR(rev) (rev & 0xff) 32 #define ALE_VERSION_1R3 0x0103 33 #define ALE_VERSION_1R4 0x0104 34 35 /* ALE Registers */ 36 #define ALE_IDVER 0x00 37 #define ALE_STATUS 0x04 38 #define ALE_CONTROL 0x08 39 #define ALE_PRESCALE 0x10 40 #define ALE_UNKNOWNVLAN 0x18 41 #define ALE_TABLE_CONTROL 0x20 42 #define ALE_TABLE 0x34 43 #define ALE_PORTCTL 0x40 44 45 /* ALE NetCP NU switch specific Registers */ 46 #define ALE_UNKNOWNVLAN_MEMBER 0x90 47 #define ALE_UNKNOWNVLAN_UNREG_MCAST_FLOOD 0x94 48 #define ALE_UNKNOWNVLAN_REG_MCAST_FLOOD 0x98 49 #define ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS 0x9C 50 #define ALE_VLAN_MASK_MUX(reg) (0xc0 + (0x4 * (reg))) 51 52 #define ALE_TABLE_WRITE BIT(31) 53 54 #define ALE_TYPE_FREE 0 55 #define ALE_TYPE_ADDR 1 56 #define ALE_TYPE_VLAN 2 57 #define ALE_TYPE_VLAN_ADDR 3 58 59 #define ALE_UCAST_PERSISTANT 0 60 #define ALE_UCAST_UNTOUCHED 1 61 #define ALE_UCAST_OUI 2 62 #define ALE_UCAST_TOUCHED 3 63 64 #define ALE_TABLE_SIZE_MULTIPLIER 1024 65 #define ALE_STATUS_SIZE_MASK 0x1f 66 #define ALE_TABLE_SIZE_DEFAULT 64 67 68 static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits) 69 { 70 int idx; 71 72 idx = start / 32; 73 start -= idx * 32; 74 idx = 2 - idx; /* flip */ 75 return (ale_entry[idx] >> start) & BITMASK(bits); 76 } 77 78 static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits, 79 u32 value) 80 { 81 int idx; 82 83 value &= BITMASK(bits); 84 idx = start / 32; 85 start -= idx * 32; 86 idx = 2 - idx; /* flip */ 87 ale_entry[idx] &= ~(BITMASK(bits) << start); 88 ale_entry[idx] |= (value << start); 89 } 90 91 #define DEFINE_ALE_FIELD(name, start, bits) \ 92 static inline int cpsw_ale_get_##name(u32 *ale_entry) \ 93 { \ 94 return cpsw_ale_get_field(ale_entry, start, bits); \ 95 } \ 96 static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value) \ 97 { \ 98 cpsw_ale_set_field(ale_entry, start, bits, value); \ 99 } 100 101 #define DEFINE_ALE_FIELD1(name, start) \ 102 static inline int cpsw_ale_get_##name(u32 *ale_entry, u32 bits) \ 103 { \ 104 return cpsw_ale_get_field(ale_entry, start, bits); \ 105 } \ 106 static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value, \ 107 u32 bits) \ 108 { \ 109 cpsw_ale_set_field(ale_entry, start, bits, value); \ 110 } 111 112 DEFINE_ALE_FIELD(entry_type, 60, 2) 113 DEFINE_ALE_FIELD(vlan_id, 48, 12) 114 DEFINE_ALE_FIELD(mcast_state, 62, 2) 115 DEFINE_ALE_FIELD1(port_mask, 66) 116 DEFINE_ALE_FIELD(super, 65, 1) 117 DEFINE_ALE_FIELD(ucast_type, 62, 2) 118 DEFINE_ALE_FIELD1(port_num, 66) 119 DEFINE_ALE_FIELD(blocked, 65, 1) 120 DEFINE_ALE_FIELD(secure, 64, 1) 121 DEFINE_ALE_FIELD1(vlan_untag_force, 24) 122 DEFINE_ALE_FIELD1(vlan_reg_mcast, 16) 123 DEFINE_ALE_FIELD1(vlan_unreg_mcast, 8) 124 DEFINE_ALE_FIELD1(vlan_member_list, 0) 125 DEFINE_ALE_FIELD(mcast, 40, 1) 126 /* ALE NetCP nu switch specific */ 127 DEFINE_ALE_FIELD(vlan_unreg_mcast_idx, 20, 3) 128 DEFINE_ALE_FIELD(vlan_reg_mcast_idx, 44, 3) 129 130 /* The MAC address field in the ALE entry cannot be macroized as above */ 131 static inline void cpsw_ale_get_addr(u32 *ale_entry, u8 *addr) 132 { 133 int i; 134 135 for (i = 0; i < 6; i++) 136 addr[i] = cpsw_ale_get_field(ale_entry, 40 - 8*i, 8); 137 } 138 139 static inline void cpsw_ale_set_addr(u32 *ale_entry, u8 *addr) 140 { 141 int i; 142 143 for (i = 0; i < 6; i++) 144 cpsw_ale_set_field(ale_entry, 40 - 8*i, 8, addr[i]); 145 } 146 147 static int cpsw_ale_read(struct cpsw_ale *ale, int idx, u32 *ale_entry) 148 { 149 int i; 150 151 WARN_ON(idx > ale->params.ale_entries); 152 153 writel_relaxed(idx, ale->params.ale_regs + ALE_TABLE_CONTROL); 154 155 for (i = 0; i < ALE_ENTRY_WORDS; i++) 156 ale_entry[i] = readl_relaxed(ale->params.ale_regs + 157 ALE_TABLE + 4 * i); 158 159 return idx; 160 } 161 162 static int cpsw_ale_write(struct cpsw_ale *ale, int idx, u32 *ale_entry) 163 { 164 int i; 165 166 WARN_ON(idx > ale->params.ale_entries); 167 168 for (i = 0; i < ALE_ENTRY_WORDS; i++) 169 writel_relaxed(ale_entry[i], ale->params.ale_regs + 170 ALE_TABLE + 4 * i); 171 172 writel_relaxed(idx | ALE_TABLE_WRITE, ale->params.ale_regs + 173 ALE_TABLE_CONTROL); 174 175 return idx; 176 } 177 178 static int cpsw_ale_match_addr(struct cpsw_ale *ale, u8 *addr, u16 vid) 179 { 180 u32 ale_entry[ALE_ENTRY_WORDS]; 181 int type, idx; 182 183 for (idx = 0; idx < ale->params.ale_entries; idx++) { 184 u8 entry_addr[6]; 185 186 cpsw_ale_read(ale, idx, ale_entry); 187 type = cpsw_ale_get_entry_type(ale_entry); 188 if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR) 189 continue; 190 if (cpsw_ale_get_vlan_id(ale_entry) != vid) 191 continue; 192 cpsw_ale_get_addr(ale_entry, entry_addr); 193 if (ether_addr_equal(entry_addr, addr)) 194 return idx; 195 } 196 return -ENOENT; 197 } 198 199 static int cpsw_ale_match_vlan(struct cpsw_ale *ale, u16 vid) 200 { 201 u32 ale_entry[ALE_ENTRY_WORDS]; 202 int type, idx; 203 204 for (idx = 0; idx < ale->params.ale_entries; idx++) { 205 cpsw_ale_read(ale, idx, ale_entry); 206 type = cpsw_ale_get_entry_type(ale_entry); 207 if (type != ALE_TYPE_VLAN) 208 continue; 209 if (cpsw_ale_get_vlan_id(ale_entry) == vid) 210 return idx; 211 } 212 return -ENOENT; 213 } 214 215 static int cpsw_ale_match_free(struct cpsw_ale *ale) 216 { 217 u32 ale_entry[ALE_ENTRY_WORDS]; 218 int type, idx; 219 220 for (idx = 0; idx < ale->params.ale_entries; idx++) { 221 cpsw_ale_read(ale, idx, ale_entry); 222 type = cpsw_ale_get_entry_type(ale_entry); 223 if (type == ALE_TYPE_FREE) 224 return idx; 225 } 226 return -ENOENT; 227 } 228 229 static int cpsw_ale_find_ageable(struct cpsw_ale *ale) 230 { 231 u32 ale_entry[ALE_ENTRY_WORDS]; 232 int type, idx; 233 234 for (idx = 0; idx < ale->params.ale_entries; idx++) { 235 cpsw_ale_read(ale, idx, ale_entry); 236 type = cpsw_ale_get_entry_type(ale_entry); 237 if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR) 238 continue; 239 if (cpsw_ale_get_mcast(ale_entry)) 240 continue; 241 type = cpsw_ale_get_ucast_type(ale_entry); 242 if (type != ALE_UCAST_PERSISTANT && 243 type != ALE_UCAST_OUI) 244 return idx; 245 } 246 return -ENOENT; 247 } 248 249 static void cpsw_ale_flush_mcast(struct cpsw_ale *ale, u32 *ale_entry, 250 int port_mask) 251 { 252 int mask; 253 254 mask = cpsw_ale_get_port_mask(ale_entry, 255 ale->port_mask_bits); 256 if ((mask & port_mask) == 0) 257 return; /* ports dont intersect, not interested */ 258 mask &= ~port_mask; 259 260 /* free if only remaining port is host port */ 261 if (mask) 262 cpsw_ale_set_port_mask(ale_entry, mask, 263 ale->port_mask_bits); 264 else 265 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); 266 } 267 268 int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid) 269 { 270 u32 ale_entry[ALE_ENTRY_WORDS]; 271 int ret, idx; 272 273 for (idx = 0; idx < ale->params.ale_entries; idx++) { 274 cpsw_ale_read(ale, idx, ale_entry); 275 ret = cpsw_ale_get_entry_type(ale_entry); 276 if (ret != ALE_TYPE_ADDR && ret != ALE_TYPE_VLAN_ADDR) 277 continue; 278 279 /* if vid passed is -1 then remove all multicast entry from 280 * the table irrespective of vlan id, if a valid vlan id is 281 * passed then remove only multicast added to that vlan id. 282 * if vlan id doesn't match then move on to next entry. 283 */ 284 if (vid != -1 && cpsw_ale_get_vlan_id(ale_entry) != vid) 285 continue; 286 287 if (cpsw_ale_get_mcast(ale_entry)) { 288 u8 addr[6]; 289 290 cpsw_ale_get_addr(ale_entry, addr); 291 if (!is_broadcast_ether_addr(addr)) 292 cpsw_ale_flush_mcast(ale, ale_entry, port_mask); 293 } 294 295 cpsw_ale_write(ale, idx, ale_entry); 296 } 297 return 0; 298 } 299 EXPORT_SYMBOL_GPL(cpsw_ale_flush_multicast); 300 301 static inline void cpsw_ale_set_vlan_entry_type(u32 *ale_entry, 302 int flags, u16 vid) 303 { 304 if (flags & ALE_VLAN) { 305 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_VLAN_ADDR); 306 cpsw_ale_set_vlan_id(ale_entry, vid); 307 } else { 308 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR); 309 } 310 } 311 312 int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port, 313 int flags, u16 vid) 314 { 315 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; 316 int idx; 317 318 cpsw_ale_set_vlan_entry_type(ale_entry, flags, vid); 319 320 cpsw_ale_set_addr(ale_entry, addr); 321 cpsw_ale_set_ucast_type(ale_entry, ALE_UCAST_PERSISTANT); 322 cpsw_ale_set_secure(ale_entry, (flags & ALE_SECURE) ? 1 : 0); 323 cpsw_ale_set_blocked(ale_entry, (flags & ALE_BLOCKED) ? 1 : 0); 324 cpsw_ale_set_port_num(ale_entry, port, ale->port_num_bits); 325 326 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); 327 if (idx < 0) 328 idx = cpsw_ale_match_free(ale); 329 if (idx < 0) 330 idx = cpsw_ale_find_ageable(ale); 331 if (idx < 0) 332 return -ENOMEM; 333 334 cpsw_ale_write(ale, idx, ale_entry); 335 return 0; 336 } 337 EXPORT_SYMBOL_GPL(cpsw_ale_add_ucast); 338 339 int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port, 340 int flags, u16 vid) 341 { 342 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; 343 int idx; 344 345 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); 346 if (idx < 0) 347 return -ENOENT; 348 349 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); 350 cpsw_ale_write(ale, idx, ale_entry); 351 return 0; 352 } 353 EXPORT_SYMBOL_GPL(cpsw_ale_del_ucast); 354 355 int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask, 356 int flags, u16 vid, int mcast_state) 357 { 358 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; 359 int idx, mask; 360 361 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); 362 if (idx >= 0) 363 cpsw_ale_read(ale, idx, ale_entry); 364 365 cpsw_ale_set_vlan_entry_type(ale_entry, flags, vid); 366 367 cpsw_ale_set_addr(ale_entry, addr); 368 cpsw_ale_set_super(ale_entry, (flags & ALE_BLOCKED) ? 1 : 0); 369 cpsw_ale_set_mcast_state(ale_entry, mcast_state); 370 371 mask = cpsw_ale_get_port_mask(ale_entry, 372 ale->port_mask_bits); 373 port_mask |= mask; 374 cpsw_ale_set_port_mask(ale_entry, port_mask, 375 ale->port_mask_bits); 376 377 if (idx < 0) 378 idx = cpsw_ale_match_free(ale); 379 if (idx < 0) 380 idx = cpsw_ale_find_ageable(ale); 381 if (idx < 0) 382 return -ENOMEM; 383 384 cpsw_ale_write(ale, idx, ale_entry); 385 return 0; 386 } 387 EXPORT_SYMBOL_GPL(cpsw_ale_add_mcast); 388 389 int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask, 390 int flags, u16 vid) 391 { 392 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; 393 int idx; 394 395 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); 396 if (idx < 0) 397 return -EINVAL; 398 399 cpsw_ale_read(ale, idx, ale_entry); 400 401 if (port_mask) 402 cpsw_ale_set_port_mask(ale_entry, port_mask, 403 ale->port_mask_bits); 404 else 405 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); 406 407 cpsw_ale_write(ale, idx, ale_entry); 408 return 0; 409 } 410 EXPORT_SYMBOL_GPL(cpsw_ale_del_mcast); 411 412 /* ALE NetCP NU switch specific vlan functions */ 413 static void cpsw_ale_set_vlan_mcast(struct cpsw_ale *ale, u32 *ale_entry, 414 int reg_mcast, int unreg_mcast) 415 { 416 int idx; 417 418 /* Set VLAN registered multicast flood mask */ 419 idx = cpsw_ale_get_vlan_reg_mcast_idx(ale_entry); 420 writel(reg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx)); 421 422 /* Set VLAN unregistered multicast flood mask */ 423 idx = cpsw_ale_get_vlan_unreg_mcast_idx(ale_entry); 424 writel(unreg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx)); 425 } 426 427 int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port, int untag, 428 int reg_mcast, int unreg_mcast) 429 { 430 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; 431 int idx; 432 433 idx = cpsw_ale_match_vlan(ale, vid); 434 if (idx >= 0) 435 cpsw_ale_read(ale, idx, ale_entry); 436 437 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_VLAN); 438 cpsw_ale_set_vlan_id(ale_entry, vid); 439 440 cpsw_ale_set_vlan_untag_force(ale_entry, untag, ale->vlan_field_bits); 441 if (!ale->params.nu_switch_ale) { 442 cpsw_ale_set_vlan_reg_mcast(ale_entry, reg_mcast, 443 ale->vlan_field_bits); 444 cpsw_ale_set_vlan_unreg_mcast(ale_entry, unreg_mcast, 445 ale->vlan_field_bits); 446 } else { 447 cpsw_ale_set_vlan_mcast(ale, ale_entry, reg_mcast, unreg_mcast); 448 } 449 cpsw_ale_set_vlan_member_list(ale_entry, port, ale->vlan_field_bits); 450 451 if (idx < 0) 452 idx = cpsw_ale_match_free(ale); 453 if (idx < 0) 454 idx = cpsw_ale_find_ageable(ale); 455 if (idx < 0) 456 return -ENOMEM; 457 458 cpsw_ale_write(ale, idx, ale_entry); 459 return 0; 460 } 461 EXPORT_SYMBOL_GPL(cpsw_ale_add_vlan); 462 463 int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port_mask) 464 { 465 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; 466 int idx; 467 468 idx = cpsw_ale_match_vlan(ale, vid); 469 if (idx < 0) 470 return -ENOENT; 471 472 cpsw_ale_read(ale, idx, ale_entry); 473 474 if (port_mask) 475 cpsw_ale_set_vlan_member_list(ale_entry, port_mask, 476 ale->vlan_field_bits); 477 else 478 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); 479 480 cpsw_ale_write(ale, idx, ale_entry); 481 return 0; 482 } 483 EXPORT_SYMBOL_GPL(cpsw_ale_del_vlan); 484 485 void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti) 486 { 487 u32 ale_entry[ALE_ENTRY_WORDS]; 488 int type, idx; 489 int unreg_mcast = 0; 490 491 /* Only bother doing the work if the setting is actually changing */ 492 if (ale->allmulti == allmulti) 493 return; 494 495 /* Remember the new setting to check against next time */ 496 ale->allmulti = allmulti; 497 498 for (idx = 0; idx < ale->params.ale_entries; idx++) { 499 cpsw_ale_read(ale, idx, ale_entry); 500 type = cpsw_ale_get_entry_type(ale_entry); 501 if (type != ALE_TYPE_VLAN) 502 continue; 503 504 unreg_mcast = 505 cpsw_ale_get_vlan_unreg_mcast(ale_entry, 506 ale->vlan_field_bits); 507 if (allmulti) 508 unreg_mcast |= 1; 509 else 510 unreg_mcast &= ~1; 511 cpsw_ale_set_vlan_unreg_mcast(ale_entry, unreg_mcast, 512 ale->vlan_field_bits); 513 cpsw_ale_write(ale, idx, ale_entry); 514 } 515 } 516 EXPORT_SYMBOL_GPL(cpsw_ale_set_allmulti); 517 518 struct ale_control_info { 519 const char *name; 520 int offset, port_offset; 521 int shift, port_shift; 522 int bits; 523 }; 524 525 static struct ale_control_info ale_controls[ALE_NUM_CONTROLS] = { 526 [ALE_ENABLE] = { 527 .name = "enable", 528 .offset = ALE_CONTROL, 529 .port_offset = 0, 530 .shift = 31, 531 .port_shift = 0, 532 .bits = 1, 533 }, 534 [ALE_CLEAR] = { 535 .name = "clear", 536 .offset = ALE_CONTROL, 537 .port_offset = 0, 538 .shift = 30, 539 .port_shift = 0, 540 .bits = 1, 541 }, 542 [ALE_AGEOUT] = { 543 .name = "ageout", 544 .offset = ALE_CONTROL, 545 .port_offset = 0, 546 .shift = 29, 547 .port_shift = 0, 548 .bits = 1, 549 }, 550 [ALE_P0_UNI_FLOOD] = { 551 .name = "port0_unicast_flood", 552 .offset = ALE_CONTROL, 553 .port_offset = 0, 554 .shift = 8, 555 .port_shift = 0, 556 .bits = 1, 557 }, 558 [ALE_VLAN_NOLEARN] = { 559 .name = "vlan_nolearn", 560 .offset = ALE_CONTROL, 561 .port_offset = 0, 562 .shift = 7, 563 .port_shift = 0, 564 .bits = 1, 565 }, 566 [ALE_NO_PORT_VLAN] = { 567 .name = "no_port_vlan", 568 .offset = ALE_CONTROL, 569 .port_offset = 0, 570 .shift = 6, 571 .port_shift = 0, 572 .bits = 1, 573 }, 574 [ALE_OUI_DENY] = { 575 .name = "oui_deny", 576 .offset = ALE_CONTROL, 577 .port_offset = 0, 578 .shift = 5, 579 .port_shift = 0, 580 .bits = 1, 581 }, 582 [ALE_BYPASS] = { 583 .name = "bypass", 584 .offset = ALE_CONTROL, 585 .port_offset = 0, 586 .shift = 4, 587 .port_shift = 0, 588 .bits = 1, 589 }, 590 [ALE_RATE_LIMIT_TX] = { 591 .name = "rate_limit_tx", 592 .offset = ALE_CONTROL, 593 .port_offset = 0, 594 .shift = 3, 595 .port_shift = 0, 596 .bits = 1, 597 }, 598 [ALE_VLAN_AWARE] = { 599 .name = "vlan_aware", 600 .offset = ALE_CONTROL, 601 .port_offset = 0, 602 .shift = 2, 603 .port_shift = 0, 604 .bits = 1, 605 }, 606 [ALE_AUTH_ENABLE] = { 607 .name = "auth_enable", 608 .offset = ALE_CONTROL, 609 .port_offset = 0, 610 .shift = 1, 611 .port_shift = 0, 612 .bits = 1, 613 }, 614 [ALE_RATE_LIMIT] = { 615 .name = "rate_limit", 616 .offset = ALE_CONTROL, 617 .port_offset = 0, 618 .shift = 0, 619 .port_shift = 0, 620 .bits = 1, 621 }, 622 [ALE_PORT_STATE] = { 623 .name = "port_state", 624 .offset = ALE_PORTCTL, 625 .port_offset = 4, 626 .shift = 0, 627 .port_shift = 0, 628 .bits = 2, 629 }, 630 [ALE_PORT_DROP_UNTAGGED] = { 631 .name = "drop_untagged", 632 .offset = ALE_PORTCTL, 633 .port_offset = 4, 634 .shift = 2, 635 .port_shift = 0, 636 .bits = 1, 637 }, 638 [ALE_PORT_DROP_UNKNOWN_VLAN] = { 639 .name = "drop_unknown", 640 .offset = ALE_PORTCTL, 641 .port_offset = 4, 642 .shift = 3, 643 .port_shift = 0, 644 .bits = 1, 645 }, 646 [ALE_PORT_NOLEARN] = { 647 .name = "nolearn", 648 .offset = ALE_PORTCTL, 649 .port_offset = 4, 650 .shift = 4, 651 .port_shift = 0, 652 .bits = 1, 653 }, 654 [ALE_PORT_NO_SA_UPDATE] = { 655 .name = "no_source_update", 656 .offset = ALE_PORTCTL, 657 .port_offset = 4, 658 .shift = 5, 659 .port_shift = 0, 660 .bits = 1, 661 }, 662 [ALE_PORT_MCAST_LIMIT] = { 663 .name = "mcast_limit", 664 .offset = ALE_PORTCTL, 665 .port_offset = 4, 666 .shift = 16, 667 .port_shift = 0, 668 .bits = 8, 669 }, 670 [ALE_PORT_BCAST_LIMIT] = { 671 .name = "bcast_limit", 672 .offset = ALE_PORTCTL, 673 .port_offset = 4, 674 .shift = 24, 675 .port_shift = 0, 676 .bits = 8, 677 }, 678 [ALE_PORT_UNKNOWN_VLAN_MEMBER] = { 679 .name = "unknown_vlan_member", 680 .offset = ALE_UNKNOWNVLAN, 681 .port_offset = 0, 682 .shift = 0, 683 .port_shift = 0, 684 .bits = 6, 685 }, 686 [ALE_PORT_UNKNOWN_MCAST_FLOOD] = { 687 .name = "unknown_mcast_flood", 688 .offset = ALE_UNKNOWNVLAN, 689 .port_offset = 0, 690 .shift = 8, 691 .port_shift = 0, 692 .bits = 6, 693 }, 694 [ALE_PORT_UNKNOWN_REG_MCAST_FLOOD] = { 695 .name = "unknown_reg_flood", 696 .offset = ALE_UNKNOWNVLAN, 697 .port_offset = 0, 698 .shift = 16, 699 .port_shift = 0, 700 .bits = 6, 701 }, 702 [ALE_PORT_UNTAGGED_EGRESS] = { 703 .name = "untagged_egress", 704 .offset = ALE_UNKNOWNVLAN, 705 .port_offset = 0, 706 .shift = 24, 707 .port_shift = 0, 708 .bits = 6, 709 }, 710 }; 711 712 int cpsw_ale_control_set(struct cpsw_ale *ale, int port, int control, 713 int value) 714 { 715 const struct ale_control_info *info; 716 int offset, shift; 717 u32 tmp, mask; 718 719 if (control < 0 || control >= ARRAY_SIZE(ale_controls)) 720 return -EINVAL; 721 722 info = &ale_controls[control]; 723 if (info->port_offset == 0 && info->port_shift == 0) 724 port = 0; /* global, port is a dont care */ 725 726 if (port < 0 || port >= ale->params.ale_ports) 727 return -EINVAL; 728 729 mask = BITMASK(info->bits); 730 if (value & ~mask) 731 return -EINVAL; 732 733 offset = info->offset + (port * info->port_offset); 734 shift = info->shift + (port * info->port_shift); 735 736 tmp = readl_relaxed(ale->params.ale_regs + offset); 737 tmp = (tmp & ~(mask << shift)) | (value << shift); 738 writel_relaxed(tmp, ale->params.ale_regs + offset); 739 740 return 0; 741 } 742 EXPORT_SYMBOL_GPL(cpsw_ale_control_set); 743 744 int cpsw_ale_control_get(struct cpsw_ale *ale, int port, int control) 745 { 746 const struct ale_control_info *info; 747 int offset, shift; 748 u32 tmp; 749 750 if (control < 0 || control >= ARRAY_SIZE(ale_controls)) 751 return -EINVAL; 752 753 info = &ale_controls[control]; 754 if (info->port_offset == 0 && info->port_shift == 0) 755 port = 0; /* global, port is a dont care */ 756 757 if (port < 0 || port >= ale->params.ale_ports) 758 return -EINVAL; 759 760 offset = info->offset + (port * info->port_offset); 761 shift = info->shift + (port * info->port_shift); 762 763 tmp = readl_relaxed(ale->params.ale_regs + offset) >> shift; 764 return tmp & BITMASK(info->bits); 765 } 766 EXPORT_SYMBOL_GPL(cpsw_ale_control_get); 767 768 static void cpsw_ale_timer(struct timer_list *t) 769 { 770 struct cpsw_ale *ale = from_timer(ale, t, timer); 771 772 cpsw_ale_control_set(ale, 0, ALE_AGEOUT, 1); 773 774 if (ale->ageout) { 775 ale->timer.expires = jiffies + ale->ageout; 776 add_timer(&ale->timer); 777 } 778 } 779 780 void cpsw_ale_start(struct cpsw_ale *ale) 781 { 782 cpsw_ale_control_set(ale, 0, ALE_ENABLE, 1); 783 cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1); 784 785 timer_setup(&ale->timer, cpsw_ale_timer, 0); 786 if (ale->ageout) { 787 ale->timer.expires = jiffies + ale->ageout; 788 add_timer(&ale->timer); 789 } 790 } 791 EXPORT_SYMBOL_GPL(cpsw_ale_start); 792 793 void cpsw_ale_stop(struct cpsw_ale *ale) 794 { 795 del_timer_sync(&ale->timer); 796 cpsw_ale_control_set(ale, 0, ALE_ENABLE, 0); 797 } 798 EXPORT_SYMBOL_GPL(cpsw_ale_stop); 799 800 struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params) 801 { 802 struct cpsw_ale *ale; 803 u32 rev, ale_entries; 804 805 ale = devm_kzalloc(params->dev, sizeof(*ale), GFP_KERNEL); 806 if (!ale) 807 return NULL; 808 809 ale->params = *params; 810 ale->ageout = ale->params.ale_ageout * HZ; 811 812 rev = readl_relaxed(ale->params.ale_regs + ALE_IDVER); 813 if (!ale->params.major_ver_mask) 814 ale->params.major_ver_mask = 0xff; 815 ale->version = 816 (ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask) << 8) | 817 ALE_VERSION_MINOR(rev); 818 dev_info(ale->params.dev, "initialized cpsw ale version %d.%d\n", 819 ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask), 820 ALE_VERSION_MINOR(rev)); 821 822 if (!ale->params.ale_entries) { 823 ale_entries = 824 readl_relaxed(ale->params.ale_regs + ALE_STATUS) & 825 ALE_STATUS_SIZE_MASK; 826 /* ALE available on newer NetCP switches has introduced 827 * a register, ALE_STATUS, to indicate the size of ALE 828 * table which shows the size as a multiple of 1024 entries. 829 * For these, params.ale_entries will be set to zero. So 830 * read the register and update the value of ale_entries. 831 * ALE table on NetCP lite, is much smaller and is indicated 832 * by a value of zero in ALE_STATUS. So use a default value 833 * of ALE_TABLE_SIZE_DEFAULT for this. Caller is expected 834 * to set the value of ale_entries for all other versions 835 * of ALE. 836 */ 837 if (!ale_entries) 838 ale_entries = ALE_TABLE_SIZE_DEFAULT; 839 else 840 ale_entries *= ALE_TABLE_SIZE_MULTIPLIER; 841 ale->params.ale_entries = ale_entries; 842 } 843 dev_info(ale->params.dev, 844 "ALE Table size %ld\n", ale->params.ale_entries); 845 846 /* set default bits for existing h/w */ 847 ale->port_mask_bits = ale->params.ale_ports; 848 ale->port_num_bits = order_base_2(ale->params.ale_ports); 849 ale->vlan_field_bits = ale->params.ale_ports; 850 851 /* Set defaults override for ALE on NetCP NU switch and for version 852 * 1R3 853 */ 854 if (ale->params.nu_switch_ale) { 855 /* Separate registers for unknown vlan configuration. 856 * Also there are N bits, where N is number of ale 857 * ports and shift value should be 0 858 */ 859 ale_controls[ALE_PORT_UNKNOWN_VLAN_MEMBER].bits = 860 ale->params.ale_ports; 861 ale_controls[ALE_PORT_UNKNOWN_VLAN_MEMBER].offset = 862 ALE_UNKNOWNVLAN_MEMBER; 863 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].bits = 864 ale->params.ale_ports; 865 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].shift = 0; 866 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].offset = 867 ALE_UNKNOWNVLAN_UNREG_MCAST_FLOOD; 868 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].bits = 869 ale->params.ale_ports; 870 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].shift = 0; 871 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].offset = 872 ALE_UNKNOWNVLAN_REG_MCAST_FLOOD; 873 ale_controls[ALE_PORT_UNTAGGED_EGRESS].bits = 874 ale->params.ale_ports; 875 ale_controls[ALE_PORT_UNTAGGED_EGRESS].shift = 0; 876 ale_controls[ALE_PORT_UNTAGGED_EGRESS].offset = 877 ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS; 878 } 879 880 return ale; 881 } 882 EXPORT_SYMBOL_GPL(cpsw_ale_create); 883 884 void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data) 885 { 886 int i; 887 888 for (i = 0; i < ale->params.ale_entries; i++) { 889 cpsw_ale_read(ale, i, data); 890 data += ALE_ENTRY_WORDS; 891 } 892 } 893 EXPORT_SYMBOL_GPL(cpsw_ale_dump); 894 895 MODULE_LICENSE("GPL v2"); 896 MODULE_DESCRIPTION("TI CPSW ALE driver"); 897 MODULE_AUTHOR("Texas Instruments"); 898