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 static int mv88e6185_g1_vtu_stu_data_read(struct mv88e6xxx_chip *chip, 129 u16 *regs) 130 { 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 return 0; 144 } 145 146 static int mv88e6185_g1_vtu_data_read(struct mv88e6xxx_chip *chip, 147 struct mv88e6xxx_vtu_entry *entry) 148 { 149 u16 regs[3]; 150 int err; 151 int i; 152 153 err = mv88e6185_g1_vtu_stu_data_read(chip, regs); 154 if (err) 155 return err; 156 157 /* Extract MemberTag data */ 158 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { 159 unsigned int member_offset = (i % 4) * 4; 160 161 entry->member[i] = (regs[i / 4] >> member_offset) & 0x3; 162 } 163 164 return 0; 165 } 166 167 static int mv88e6185_g1_stu_data_read(struct mv88e6xxx_chip *chip, 168 struct mv88e6xxx_vtu_entry *entry) 169 { 170 u16 regs[3]; 171 int err; 172 int i; 173 174 err = mv88e6185_g1_vtu_stu_data_read(chip, regs); 175 if (err) 176 return err; 177 178 /* Extract PortState data */ 179 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { 180 unsigned int state_offset = (i % 4) * 4 + 2; 181 182 entry->state[i] = (regs[i / 4] >> state_offset) & 0x3; 183 } 184 185 return 0; 186 } 187 188 static int mv88e6185_g1_vtu_data_write(struct mv88e6xxx_chip *chip, 189 struct mv88e6xxx_vtu_entry *entry) 190 { 191 u16 regs[3] = { 0 }; 192 int i; 193 194 /* Insert MemberTag and PortState data */ 195 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { 196 unsigned int member_offset = (i % 4) * 4; 197 unsigned int state_offset = member_offset + 2; 198 199 regs[i / 4] |= (entry->member[i] & 0x3) << member_offset; 200 regs[i / 4] |= (entry->state[i] & 0x3) << state_offset; 201 } 202 203 /* Write all 3 VTU/STU Data registers */ 204 for (i = 0; i < 3; ++i) { 205 u16 reg = regs[i]; 206 int err; 207 208 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg); 209 if (err) 210 return err; 211 } 212 213 return 0; 214 } 215 216 static int mv88e6390_g1_vtu_data_read(struct mv88e6xxx_chip *chip, u8 *data) 217 { 218 u16 regs[2]; 219 int i; 220 221 /* Read the 2 VTU/STU Data registers */ 222 for (i = 0; i < 2; ++i) { 223 u16 *reg = ®s[i]; 224 int err; 225 226 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg); 227 if (err) 228 return err; 229 } 230 231 /* Extract data */ 232 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { 233 unsigned int offset = (i % 8) * 2; 234 235 data[i] = (regs[i / 8] >> offset) & 0x3; 236 } 237 238 return 0; 239 } 240 241 static int mv88e6390_g1_vtu_data_write(struct mv88e6xxx_chip *chip, u8 *data) 242 { 243 u16 regs[2] = { 0 }; 244 int i; 245 246 /* Insert data */ 247 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { 248 unsigned int offset = (i % 8) * 2; 249 250 regs[i / 8] |= (data[i] & 0x3) << offset; 251 } 252 253 /* Write the 2 VTU/STU Data registers */ 254 for (i = 0; i < 2; ++i) { 255 u16 reg = regs[i]; 256 int err; 257 258 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg); 259 if (err) 260 return err; 261 } 262 263 return 0; 264 } 265 266 /* VLAN Translation Unit Operations */ 267 268 static int mv88e6xxx_g1_vtu_stu_getnext(struct mv88e6xxx_chip *chip, 269 struct mv88e6xxx_vtu_entry *entry) 270 { 271 int err; 272 273 err = mv88e6xxx_g1_vtu_sid_write(chip, entry); 274 if (err) 275 return err; 276 277 err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_STU_GET_NEXT); 278 if (err) 279 return err; 280 281 err = mv88e6xxx_g1_vtu_sid_read(chip, entry); 282 if (err) 283 return err; 284 285 return mv88e6xxx_g1_vtu_vid_read(chip, entry); 286 } 287 288 static int mv88e6xxx_g1_vtu_stu_get(struct mv88e6xxx_chip *chip, 289 struct mv88e6xxx_vtu_entry *vtu) 290 { 291 struct mv88e6xxx_vtu_entry stu; 292 int err; 293 294 err = mv88e6xxx_g1_vtu_sid_read(chip, vtu); 295 if (err) 296 return err; 297 298 stu.sid = vtu->sid - 1; 299 300 err = mv88e6xxx_g1_vtu_stu_getnext(chip, &stu); 301 if (err) 302 return err; 303 304 if (stu.sid != vtu->sid || !stu.valid) 305 return -EINVAL; 306 307 return 0; 308 } 309 310 int mv88e6xxx_g1_vtu_getnext(struct mv88e6xxx_chip *chip, 311 struct mv88e6xxx_vtu_entry *entry) 312 { 313 int err; 314 315 err = mv88e6xxx_g1_vtu_op_wait(chip); 316 if (err) 317 return err; 318 319 /* To get the next higher active VID, the VTU GetNext operation can be 320 * started again without setting the VID registers since it already 321 * contains the last VID. 322 * 323 * To save a few hardware accesses and abstract this to the caller, 324 * write the VID only once, when the entry is given as invalid. 325 */ 326 if (!entry->valid) { 327 err = mv88e6xxx_g1_vtu_vid_write(chip, entry); 328 if (err) 329 return err; 330 } 331 332 err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_GET_NEXT); 333 if (err) 334 return err; 335 336 return mv88e6xxx_g1_vtu_vid_read(chip, entry); 337 } 338 339 int mv88e6185_g1_vtu_getnext(struct mv88e6xxx_chip *chip, 340 struct mv88e6xxx_vtu_entry *entry) 341 { 342 u16 val; 343 int err; 344 345 err = mv88e6xxx_g1_vtu_getnext(chip, entry); 346 if (err) 347 return err; 348 349 if (entry->valid) { 350 err = mv88e6185_g1_vtu_data_read(chip, entry); 351 if (err) 352 return err; 353 354 err = mv88e6185_g1_stu_data_read(chip, entry); 355 if (err) 356 return err; 357 358 /* VTU DBNum[3:0] are located in VTU Operation 3:0 359 * VTU DBNum[7:4] ([5:4] for 6250) are located in VTU Operation 11:8 (9:8) 360 */ 361 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val); 362 if (err) 363 return err; 364 365 entry->fid = val & 0x000f; 366 entry->fid |= (val & 0x0f00) >> 4; 367 entry->fid &= mv88e6xxx_num_databases(chip) - 1; 368 } 369 370 return 0; 371 } 372 373 int mv88e6352_g1_vtu_getnext(struct mv88e6xxx_chip *chip, 374 struct mv88e6xxx_vtu_entry *entry) 375 { 376 int err; 377 378 /* Fetch VLAN MemberTag data from the VTU */ 379 err = mv88e6xxx_g1_vtu_getnext(chip, entry); 380 if (err) 381 return err; 382 383 if (entry->valid) { 384 err = mv88e6185_g1_vtu_data_read(chip, entry); 385 if (err) 386 return err; 387 388 err = mv88e6xxx_g1_vtu_fid_read(chip, entry); 389 if (err) 390 return err; 391 392 /* Fetch VLAN PortState data from the STU */ 393 err = mv88e6xxx_g1_vtu_stu_get(chip, entry); 394 if (err) 395 return err; 396 397 err = mv88e6185_g1_stu_data_read(chip, entry); 398 if (err) 399 return err; 400 } 401 402 return 0; 403 } 404 405 int mv88e6390_g1_vtu_getnext(struct mv88e6xxx_chip *chip, 406 struct mv88e6xxx_vtu_entry *entry) 407 { 408 int err; 409 410 /* Fetch VLAN MemberTag data from the VTU */ 411 err = mv88e6xxx_g1_vtu_getnext(chip, entry); 412 if (err) 413 return err; 414 415 if (entry->valid) { 416 err = mv88e6390_g1_vtu_data_read(chip, entry->member); 417 if (err) 418 return err; 419 420 /* Fetch VLAN PortState data from the STU */ 421 err = mv88e6xxx_g1_vtu_stu_get(chip, entry); 422 if (err) 423 return err; 424 425 err = mv88e6390_g1_vtu_data_read(chip, entry->state); 426 if (err) 427 return err; 428 429 err = mv88e6xxx_g1_vtu_fid_read(chip, entry); 430 if (err) 431 return err; 432 } 433 434 return 0; 435 } 436 437 int mv88e6185_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip, 438 struct mv88e6xxx_vtu_entry *entry) 439 { 440 u16 op = MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE; 441 int err; 442 443 err = mv88e6xxx_g1_vtu_op_wait(chip); 444 if (err) 445 return err; 446 447 err = mv88e6xxx_g1_vtu_vid_write(chip, entry); 448 if (err) 449 return err; 450 451 if (entry->valid) { 452 err = mv88e6185_g1_vtu_data_write(chip, entry); 453 if (err) 454 return err; 455 456 /* VTU DBNum[3:0] are located in VTU Operation 3:0 457 * VTU DBNum[7:4] are located in VTU Operation 11:8 458 * 459 * For the 6250/6220, the latter are really [5:4] and 460 * 9:8, but in those cases bits 7:6 of entry->fid are 461 * 0 since they have num_databases = 64. 462 */ 463 op |= entry->fid & 0x000f; 464 op |= (entry->fid & 0x00f0) << 4; 465 } 466 467 return mv88e6xxx_g1_vtu_op(chip, op); 468 } 469 470 int mv88e6352_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip, 471 struct mv88e6xxx_vtu_entry *entry) 472 { 473 int err; 474 475 err = mv88e6xxx_g1_vtu_op_wait(chip); 476 if (err) 477 return err; 478 479 err = mv88e6xxx_g1_vtu_vid_write(chip, entry); 480 if (err) 481 return err; 482 483 if (entry->valid) { 484 /* Write MemberTag and PortState data */ 485 err = mv88e6185_g1_vtu_data_write(chip, entry); 486 if (err) 487 return err; 488 489 err = mv88e6xxx_g1_vtu_sid_write(chip, entry); 490 if (err) 491 return err; 492 493 /* Load STU entry */ 494 err = mv88e6xxx_g1_vtu_op(chip, 495 MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE); 496 if (err) 497 return err; 498 499 err = mv88e6xxx_g1_vtu_fid_write(chip, entry); 500 if (err) 501 return err; 502 } 503 504 /* Load/Purge VTU entry */ 505 return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE); 506 } 507 508 int mv88e6390_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip, 509 struct mv88e6xxx_vtu_entry *entry) 510 { 511 int err; 512 513 err = mv88e6xxx_g1_vtu_op_wait(chip); 514 if (err) 515 return err; 516 517 err = mv88e6xxx_g1_vtu_vid_write(chip, entry); 518 if (err) 519 return err; 520 521 if (entry->valid) { 522 /* Write PortState data */ 523 err = mv88e6390_g1_vtu_data_write(chip, entry->state); 524 if (err) 525 return err; 526 527 err = mv88e6xxx_g1_vtu_sid_write(chip, entry); 528 if (err) 529 return err; 530 531 /* Load STU entry */ 532 err = mv88e6xxx_g1_vtu_op(chip, 533 MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE); 534 if (err) 535 return err; 536 537 /* Write MemberTag data */ 538 err = mv88e6390_g1_vtu_data_write(chip, entry->member); 539 if (err) 540 return err; 541 542 err = mv88e6xxx_g1_vtu_fid_write(chip, entry); 543 if (err) 544 return err; 545 } 546 547 /* Load/Purge VTU entry */ 548 return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE); 549 } 550 551 int mv88e6xxx_g1_vtu_flush(struct mv88e6xxx_chip *chip) 552 { 553 int err; 554 555 err = mv88e6xxx_g1_vtu_op_wait(chip); 556 if (err) 557 return err; 558 559 return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_FLUSH_ALL); 560 } 561 562 static irqreturn_t mv88e6xxx_g1_vtu_prob_irq_thread_fn(int irq, void *dev_id) 563 { 564 struct mv88e6xxx_chip *chip = dev_id; 565 struct mv88e6xxx_vtu_entry entry; 566 int spid; 567 int err; 568 u16 val; 569 570 mv88e6xxx_reg_lock(chip); 571 572 err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_GET_CLR_VIOLATION); 573 if (err) 574 goto out; 575 576 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val); 577 if (err) 578 goto out; 579 580 err = mv88e6xxx_g1_vtu_vid_read(chip, &entry); 581 if (err) 582 goto out; 583 584 spid = val & MV88E6XXX_G1_VTU_OP_SPID_MASK; 585 586 if (val & MV88E6XXX_G1_VTU_OP_MEMBER_VIOLATION) { 587 dev_err_ratelimited(chip->dev, "VTU member violation for vid %d, source port %d\n", 588 entry.vid, spid); 589 chip->ports[spid].vtu_member_violation++; 590 } 591 592 if (val & MV88E6XXX_G1_VTU_OP_MISS_VIOLATION) { 593 dev_dbg_ratelimited(chip->dev, "VTU miss violation for vid %d, source port %d\n", 594 entry.vid, spid); 595 chip->ports[spid].vtu_miss_violation++; 596 } 597 598 mv88e6xxx_reg_unlock(chip); 599 600 return IRQ_HANDLED; 601 602 out: 603 mv88e6xxx_reg_unlock(chip); 604 605 dev_err(chip->dev, "VTU problem: error %d while handling interrupt\n", 606 err); 607 608 return IRQ_HANDLED; 609 } 610 611 int mv88e6xxx_g1_vtu_prob_irq_setup(struct mv88e6xxx_chip *chip) 612 { 613 int err; 614 615 chip->vtu_prob_irq = irq_find_mapping(chip->g1_irq.domain, 616 MV88E6XXX_G1_STS_IRQ_VTU_PROB); 617 if (chip->vtu_prob_irq < 0) 618 return chip->vtu_prob_irq; 619 620 snprintf(chip->vtu_prob_irq_name, sizeof(chip->vtu_prob_irq_name), 621 "mv88e6xxx-%s-g1-vtu-prob", dev_name(chip->dev)); 622 623 err = request_threaded_irq(chip->vtu_prob_irq, NULL, 624 mv88e6xxx_g1_vtu_prob_irq_thread_fn, 625 IRQF_ONESHOT, chip->vtu_prob_irq_name, 626 chip); 627 if (err) 628 irq_dispose_mapping(chip->vtu_prob_irq); 629 630 return err; 631 } 632 633 void mv88e6xxx_g1_vtu_prob_irq_free(struct mv88e6xxx_chip *chip) 634 { 635 free_irq(chip->vtu_prob_irq, chip); 636 irq_dispose_mapping(chip->vtu_prob_irq); 637 } 638