1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Marvell 88E6xxx VLAN [Spanning Tree] Translation Unit (VTU [STU]) support 4 * 5 * Copyright (c) 2008 Marvell Semiconductor 6 * Copyright (c) 2015 CMC Electronics, Inc. 7 * Copyright (c) 2017 Savoir-faire Linux, Inc. 8 */ 9 10 #include <linux/bitfield.h> 11 #include <linux/interrupt.h> 12 #include <linux/irqdomain.h> 13 14 #include "chip.h" 15 #include "global1.h" 16 17 /* Offset 0x02: VTU FID Register */ 18 19 static int mv88e6xxx_g1_vtu_fid_read(struct mv88e6xxx_chip *chip, 20 struct mv88e6xxx_vtu_entry *entry) 21 { 22 u16 val; 23 int err; 24 25 err = mv88e6xxx_g1_read(chip, MV88E6352_G1_VTU_FID, &val); 26 if (err) 27 return err; 28 29 entry->fid = val & MV88E6352_G1_VTU_FID_MASK; 30 31 return 0; 32 } 33 34 static int mv88e6xxx_g1_vtu_fid_write(struct mv88e6xxx_chip *chip, 35 struct mv88e6xxx_vtu_entry *entry) 36 { 37 u16 val = entry->fid & MV88E6352_G1_VTU_FID_MASK; 38 39 return mv88e6xxx_g1_write(chip, MV88E6352_G1_VTU_FID, val); 40 } 41 42 /* Offset 0x03: VTU SID Register */ 43 44 static int mv88e6xxx_g1_vtu_sid_read(struct mv88e6xxx_chip *chip, 45 struct mv88e6xxx_vtu_entry *entry) 46 { 47 u16 val; 48 int err; 49 50 err = mv88e6xxx_g1_read(chip, MV88E6352_G1_VTU_SID, &val); 51 if (err) 52 return err; 53 54 entry->sid = val & MV88E6352_G1_VTU_SID_MASK; 55 56 return 0; 57 } 58 59 static int mv88e6xxx_g1_vtu_sid_write(struct mv88e6xxx_chip *chip, 60 struct mv88e6xxx_vtu_entry *entry) 61 { 62 u16 val = entry->sid & MV88E6352_G1_VTU_SID_MASK; 63 64 return mv88e6xxx_g1_write(chip, MV88E6352_G1_VTU_SID, val); 65 } 66 67 /* Offset 0x05: VTU Operation Register */ 68 69 static int mv88e6xxx_g1_vtu_op_wait(struct mv88e6xxx_chip *chip) 70 { 71 int bit = __bf_shf(MV88E6XXX_G1_VTU_OP_BUSY); 72 73 return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_VTU_OP, bit, 0); 74 } 75 76 static int mv88e6xxx_g1_vtu_op(struct mv88e6xxx_chip *chip, u16 op) 77 { 78 int err; 79 80 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_OP, 81 MV88E6XXX_G1_VTU_OP_BUSY | op); 82 if (err) 83 return err; 84 85 return mv88e6xxx_g1_vtu_op_wait(chip); 86 } 87 88 /* Offset 0x06: VTU VID Register */ 89 90 static int mv88e6xxx_g1_vtu_vid_read(struct mv88e6xxx_chip *chip, 91 struct mv88e6xxx_vtu_entry *entry) 92 { 93 u16 val; 94 int err; 95 96 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_VID, &val); 97 if (err) 98 return err; 99 100 entry->vid = val & 0xfff; 101 102 if (val & MV88E6390_G1_VTU_VID_PAGE) 103 entry->vid |= 0x1000; 104 105 entry->valid = !!(val & MV88E6XXX_G1_VTU_VID_VALID); 106 107 return 0; 108 } 109 110 static int mv88e6xxx_g1_vtu_vid_write(struct mv88e6xxx_chip *chip, 111 struct mv88e6xxx_vtu_entry *entry) 112 { 113 u16 val = entry->vid & 0xfff; 114 115 if (entry->vid & 0x1000) 116 val |= MV88E6390_G1_VTU_VID_PAGE; 117 118 if (entry->valid) 119 val |= MV88E6XXX_G1_VTU_VID_VALID; 120 121 return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_VID, val); 122 } 123 124 /* Offset 0x07: VTU/STU Data Register 1 125 * Offset 0x08: VTU/STU Data Register 2 126 * Offset 0x09: VTU/STU Data Register 3 127 */ 128 129 static int mv88e6185_g1_vtu_data_read(struct mv88e6xxx_chip *chip, 130 struct mv88e6xxx_vtu_entry *entry) 131 { 132 u16 regs[3]; 133 int i; 134 135 /* Read all 3 VTU/STU Data registers */ 136 for (i = 0; i < 3; ++i) { 137 u16 *reg = ®s[i]; 138 int err; 139 140 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg); 141 if (err) 142 return err; 143 } 144 145 /* Extract MemberTag and PortState data */ 146 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { 147 unsigned int member_offset = (i % 4) * 4; 148 unsigned int state_offset = member_offset + 2; 149 150 entry->member[i] = (regs[i / 4] >> member_offset) & 0x3; 151 entry->state[i] = (regs[i / 4] >> state_offset) & 0x3; 152 } 153 154 return 0; 155 } 156 157 static int mv88e6185_g1_vtu_data_write(struct mv88e6xxx_chip *chip, 158 struct mv88e6xxx_vtu_entry *entry) 159 { 160 u16 regs[3] = { 0 }; 161 int i; 162 163 /* Insert MemberTag and PortState data */ 164 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { 165 unsigned int member_offset = (i % 4) * 4; 166 unsigned int state_offset = member_offset + 2; 167 168 regs[i / 4] |= (entry->member[i] & 0x3) << member_offset; 169 regs[i / 4] |= (entry->state[i] & 0x3) << state_offset; 170 } 171 172 /* Write all 3 VTU/STU Data registers */ 173 for (i = 0; i < 3; ++i) { 174 u16 reg = regs[i]; 175 int err; 176 177 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg); 178 if (err) 179 return err; 180 } 181 182 return 0; 183 } 184 185 static int mv88e6390_g1_vtu_data_read(struct mv88e6xxx_chip *chip, u8 *data) 186 { 187 u16 regs[2]; 188 int i; 189 190 /* Read the 2 VTU/STU Data registers */ 191 for (i = 0; i < 2; ++i) { 192 u16 *reg = ®s[i]; 193 int err; 194 195 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg); 196 if (err) 197 return err; 198 } 199 200 /* Extract data */ 201 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { 202 unsigned int offset = (i % 8) * 2; 203 204 data[i] = (regs[i / 8] >> offset) & 0x3; 205 } 206 207 return 0; 208 } 209 210 static int mv88e6390_g1_vtu_data_write(struct mv88e6xxx_chip *chip, u8 *data) 211 { 212 u16 regs[2] = { 0 }; 213 int i; 214 215 /* Insert data */ 216 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { 217 unsigned int offset = (i % 8) * 2; 218 219 regs[i / 8] |= (data[i] & 0x3) << offset; 220 } 221 222 /* Write the 2 VTU/STU Data registers */ 223 for (i = 0; i < 2; ++i) { 224 u16 reg = regs[i]; 225 int err; 226 227 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg); 228 if (err) 229 return err; 230 } 231 232 return 0; 233 } 234 235 /* VLAN Translation Unit Operations */ 236 237 static int mv88e6xxx_g1_vtu_stu_getnext(struct mv88e6xxx_chip *chip, 238 struct mv88e6xxx_vtu_entry *entry) 239 { 240 int err; 241 242 err = mv88e6xxx_g1_vtu_sid_write(chip, entry); 243 if (err) 244 return err; 245 246 err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_STU_GET_NEXT); 247 if (err) 248 return err; 249 250 err = mv88e6xxx_g1_vtu_sid_read(chip, entry); 251 if (err) 252 return err; 253 254 return mv88e6xxx_g1_vtu_vid_read(chip, entry); 255 } 256 257 static int mv88e6xxx_g1_vtu_stu_get(struct mv88e6xxx_chip *chip, 258 struct mv88e6xxx_vtu_entry *vtu) 259 { 260 struct mv88e6xxx_vtu_entry stu; 261 int err; 262 263 err = mv88e6xxx_g1_vtu_sid_read(chip, vtu); 264 if (err) 265 return err; 266 267 stu.sid = vtu->sid - 1; 268 269 err = mv88e6xxx_g1_vtu_stu_getnext(chip, &stu); 270 if (err) 271 return err; 272 273 if (stu.sid != vtu->sid || !stu.valid) 274 return -EINVAL; 275 276 return 0; 277 } 278 279 static int mv88e6xxx_g1_vtu_getnext(struct mv88e6xxx_chip *chip, 280 struct mv88e6xxx_vtu_entry *entry) 281 { 282 int err; 283 284 err = mv88e6xxx_g1_vtu_op_wait(chip); 285 if (err) 286 return err; 287 288 /* To get the next higher active VID, the VTU GetNext operation can be 289 * started again without setting the VID registers since it already 290 * contains the last VID. 291 * 292 * To save a few hardware accesses and abstract this to the caller, 293 * write the VID only once, when the entry is given as invalid. 294 */ 295 if (!entry->valid) { 296 err = mv88e6xxx_g1_vtu_vid_write(chip, entry); 297 if (err) 298 return err; 299 } 300 301 err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_GET_NEXT); 302 if (err) 303 return err; 304 305 return mv88e6xxx_g1_vtu_vid_read(chip, entry); 306 } 307 308 int mv88e6250_g1_vtu_getnext(struct mv88e6xxx_chip *chip, 309 struct mv88e6xxx_vtu_entry *entry) 310 { 311 u16 val; 312 int err; 313 314 err = mv88e6xxx_g1_vtu_getnext(chip, entry); 315 if (err) 316 return err; 317 318 if (entry->valid) { 319 err = mv88e6185_g1_vtu_data_read(chip, entry); 320 if (err) 321 return err; 322 323 /* VTU DBNum[3:0] are located in VTU Operation 3:0 324 * VTU DBNum[5:4] are located in VTU Operation 9:8 325 */ 326 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val); 327 if (err) 328 return err; 329 330 entry->fid = val & 0x000f; 331 entry->fid |= (val & 0x0300) >> 4; 332 } 333 334 return 0; 335 } 336 337 int mv88e6185_g1_vtu_getnext(struct mv88e6xxx_chip *chip, 338 struct mv88e6xxx_vtu_entry *entry) 339 { 340 u16 val; 341 int err; 342 343 err = mv88e6xxx_g1_vtu_getnext(chip, entry); 344 if (err) 345 return err; 346 347 if (entry->valid) { 348 err = mv88e6185_g1_vtu_data_read(chip, entry); 349 if (err) 350 return err; 351 352 /* VTU DBNum[3:0] are located in VTU Operation 3:0 353 * VTU DBNum[7:4] are located in VTU Operation 11:8 354 */ 355 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val); 356 if (err) 357 return err; 358 359 entry->fid = val & 0x000f; 360 entry->fid |= (val & 0x0f00) >> 4; 361 } 362 363 return 0; 364 } 365 366 int mv88e6352_g1_vtu_getnext(struct mv88e6xxx_chip *chip, 367 struct mv88e6xxx_vtu_entry *entry) 368 { 369 int err; 370 371 /* Fetch VLAN MemberTag data from the VTU */ 372 err = mv88e6xxx_g1_vtu_getnext(chip, entry); 373 if (err) 374 return err; 375 376 if (entry->valid) { 377 /* Fetch (and mask) VLAN PortState data from the STU */ 378 err = mv88e6xxx_g1_vtu_stu_get(chip, entry); 379 if (err) 380 return err; 381 382 err = mv88e6185_g1_vtu_data_read(chip, entry); 383 if (err) 384 return err; 385 386 err = mv88e6xxx_g1_vtu_fid_read(chip, entry); 387 if (err) 388 return err; 389 } 390 391 return 0; 392 } 393 394 int mv88e6390_g1_vtu_getnext(struct mv88e6xxx_chip *chip, 395 struct mv88e6xxx_vtu_entry *entry) 396 { 397 int err; 398 399 /* Fetch VLAN MemberTag data from the VTU */ 400 err = mv88e6xxx_g1_vtu_getnext(chip, entry); 401 if (err) 402 return err; 403 404 if (entry->valid) { 405 err = mv88e6390_g1_vtu_data_read(chip, entry->member); 406 if (err) 407 return err; 408 409 /* Fetch VLAN PortState data from the STU */ 410 err = mv88e6xxx_g1_vtu_stu_get(chip, entry); 411 if (err) 412 return err; 413 414 err = mv88e6390_g1_vtu_data_read(chip, entry->state); 415 if (err) 416 return err; 417 418 err = mv88e6xxx_g1_vtu_fid_read(chip, entry); 419 if (err) 420 return err; 421 } 422 423 return 0; 424 } 425 426 int mv88e6250_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip, 427 struct mv88e6xxx_vtu_entry *entry) 428 { 429 u16 op = MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE; 430 int err; 431 432 err = mv88e6xxx_g1_vtu_op_wait(chip); 433 if (err) 434 return err; 435 436 err = mv88e6xxx_g1_vtu_vid_write(chip, entry); 437 if (err) 438 return err; 439 440 if (entry->valid) { 441 err = mv88e6185_g1_vtu_data_write(chip, entry); 442 if (err) 443 return err; 444 445 /* VTU DBNum[3:0] are located in VTU Operation 3:0 446 * VTU DBNum[5:4] are located in VTU Operation 9:8 447 */ 448 op |= entry->fid & 0x000f; 449 op |= (entry->fid & 0x0030) << 4; 450 } 451 452 return mv88e6xxx_g1_vtu_op(chip, op); 453 } 454 455 int mv88e6185_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip, 456 struct mv88e6xxx_vtu_entry *entry) 457 { 458 u16 op = MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE; 459 int err; 460 461 err = mv88e6xxx_g1_vtu_op_wait(chip); 462 if (err) 463 return err; 464 465 err = mv88e6xxx_g1_vtu_vid_write(chip, entry); 466 if (err) 467 return err; 468 469 if (entry->valid) { 470 err = mv88e6185_g1_vtu_data_write(chip, entry); 471 if (err) 472 return err; 473 474 /* VTU DBNum[3:0] are located in VTU Operation 3:0 475 * VTU DBNum[7:4] are located in VTU Operation 11:8 476 */ 477 op |= entry->fid & 0x000f; 478 op |= (entry->fid & 0x00f0) << 4; 479 } 480 481 return mv88e6xxx_g1_vtu_op(chip, op); 482 } 483 484 int mv88e6352_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip, 485 struct mv88e6xxx_vtu_entry *entry) 486 { 487 int err; 488 489 err = mv88e6xxx_g1_vtu_op_wait(chip); 490 if (err) 491 return err; 492 493 err = mv88e6xxx_g1_vtu_vid_write(chip, entry); 494 if (err) 495 return err; 496 497 if (entry->valid) { 498 /* Write MemberTag and PortState data */ 499 err = mv88e6185_g1_vtu_data_write(chip, entry); 500 if (err) 501 return err; 502 503 err = mv88e6xxx_g1_vtu_sid_write(chip, entry); 504 if (err) 505 return err; 506 507 /* Load STU entry */ 508 err = mv88e6xxx_g1_vtu_op(chip, 509 MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE); 510 if (err) 511 return err; 512 513 err = mv88e6xxx_g1_vtu_fid_write(chip, entry); 514 if (err) 515 return err; 516 } 517 518 /* Load/Purge VTU entry */ 519 return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE); 520 } 521 522 int mv88e6390_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip, 523 struct mv88e6xxx_vtu_entry *entry) 524 { 525 int err; 526 527 err = mv88e6xxx_g1_vtu_op_wait(chip); 528 if (err) 529 return err; 530 531 err = mv88e6xxx_g1_vtu_vid_write(chip, entry); 532 if (err) 533 return err; 534 535 if (entry->valid) { 536 /* Write PortState data */ 537 err = mv88e6390_g1_vtu_data_write(chip, entry->state); 538 if (err) 539 return err; 540 541 err = mv88e6xxx_g1_vtu_sid_write(chip, entry); 542 if (err) 543 return err; 544 545 /* Load STU entry */ 546 err = mv88e6xxx_g1_vtu_op(chip, 547 MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE); 548 if (err) 549 return err; 550 551 /* Write MemberTag data */ 552 err = mv88e6390_g1_vtu_data_write(chip, entry->member); 553 if (err) 554 return err; 555 556 err = mv88e6xxx_g1_vtu_fid_write(chip, entry); 557 if (err) 558 return err; 559 } 560 561 /* Load/Purge VTU entry */ 562 return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE); 563 } 564 565 int mv88e6xxx_g1_vtu_flush(struct mv88e6xxx_chip *chip) 566 { 567 int err; 568 569 err = mv88e6xxx_g1_vtu_op_wait(chip); 570 if (err) 571 return err; 572 573 return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_FLUSH_ALL); 574 } 575 576 static irqreturn_t mv88e6xxx_g1_vtu_prob_irq_thread_fn(int irq, void *dev_id) 577 { 578 struct mv88e6xxx_chip *chip = dev_id; 579 struct mv88e6xxx_vtu_entry entry; 580 int spid; 581 int err; 582 u16 val; 583 584 mv88e6xxx_reg_lock(chip); 585 586 err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_GET_CLR_VIOLATION); 587 if (err) 588 goto out; 589 590 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val); 591 if (err) 592 goto out; 593 594 err = mv88e6xxx_g1_vtu_vid_read(chip, &entry); 595 if (err) 596 goto out; 597 598 spid = val & MV88E6XXX_G1_VTU_OP_SPID_MASK; 599 600 if (val & MV88E6XXX_G1_VTU_OP_MEMBER_VIOLATION) { 601 dev_err_ratelimited(chip->dev, "VTU member violation for vid %d, source port %d\n", 602 entry.vid, spid); 603 chip->ports[spid].vtu_member_violation++; 604 } 605 606 if (val & MV88E6XXX_G1_VTU_OP_MISS_VIOLATION) { 607 dev_dbg_ratelimited(chip->dev, "VTU miss violation for vid %d, source port %d\n", 608 entry.vid, spid); 609 chip->ports[spid].vtu_miss_violation++; 610 } 611 612 mv88e6xxx_reg_unlock(chip); 613 614 return IRQ_HANDLED; 615 616 out: 617 mv88e6xxx_reg_unlock(chip); 618 619 dev_err(chip->dev, "VTU problem: error %d while handling interrupt\n", 620 err); 621 622 return IRQ_HANDLED; 623 } 624 625 int mv88e6xxx_g1_vtu_prob_irq_setup(struct mv88e6xxx_chip *chip) 626 { 627 int err; 628 629 chip->vtu_prob_irq = irq_find_mapping(chip->g1_irq.domain, 630 MV88E6XXX_G1_STS_IRQ_VTU_PROB); 631 if (chip->vtu_prob_irq < 0) 632 return chip->vtu_prob_irq; 633 634 err = request_threaded_irq(chip->vtu_prob_irq, NULL, 635 mv88e6xxx_g1_vtu_prob_irq_thread_fn, 636 IRQF_ONESHOT, "mv88e6xxx-g1-vtu-prob", 637 chip); 638 if (err) 639 irq_dispose_mapping(chip->vtu_prob_irq); 640 641 return err; 642 } 643 644 void mv88e6xxx_g1_vtu_prob_irq_free(struct mv88e6xxx_chip *chip) 645 { 646 free_irq(chip->vtu_prob_irq, chip); 647 irq_dispose_mapping(chip->vtu_prob_irq); 648 } 649