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