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 mv88e6185_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[7:4] are located in VTU Operation 11: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 & 0x0f00) >> 4; 330 } 331 332 return 0; 333 } 334 335 int mv88e6352_g1_vtu_getnext(struct mv88e6xxx_chip *chip, 336 struct mv88e6xxx_vtu_entry *entry) 337 { 338 int err; 339 340 /* Fetch VLAN MemberTag data from the VTU */ 341 err = mv88e6xxx_g1_vtu_getnext(chip, entry); 342 if (err) 343 return err; 344 345 if (entry->valid) { 346 /* Fetch (and mask) VLAN PortState data from the STU */ 347 err = mv88e6xxx_g1_vtu_stu_get(chip, entry); 348 if (err) 349 return err; 350 351 err = mv88e6185_g1_vtu_data_read(chip, entry); 352 if (err) 353 return err; 354 355 err = mv88e6xxx_g1_vtu_fid_read(chip, entry); 356 if (err) 357 return err; 358 } 359 360 return 0; 361 } 362 363 int mv88e6390_g1_vtu_getnext(struct mv88e6xxx_chip *chip, 364 struct mv88e6xxx_vtu_entry *entry) 365 { 366 int err; 367 368 /* Fetch VLAN MemberTag data from the VTU */ 369 err = mv88e6xxx_g1_vtu_getnext(chip, entry); 370 if (err) 371 return err; 372 373 if (entry->valid) { 374 err = mv88e6390_g1_vtu_data_read(chip, entry->member); 375 if (err) 376 return err; 377 378 /* Fetch VLAN PortState data from the STU */ 379 err = mv88e6xxx_g1_vtu_stu_get(chip, entry); 380 if (err) 381 return err; 382 383 err = mv88e6390_g1_vtu_data_read(chip, entry->state); 384 if (err) 385 return err; 386 387 err = mv88e6xxx_g1_vtu_fid_read(chip, entry); 388 if (err) 389 return err; 390 } 391 392 return 0; 393 } 394 395 int mv88e6185_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip, 396 struct mv88e6xxx_vtu_entry *entry) 397 { 398 u16 op = MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE; 399 int err; 400 401 err = mv88e6xxx_g1_vtu_op_wait(chip); 402 if (err) 403 return err; 404 405 err = mv88e6xxx_g1_vtu_vid_write(chip, entry); 406 if (err) 407 return err; 408 409 if (entry->valid) { 410 err = mv88e6185_g1_vtu_data_write(chip, entry); 411 if (err) 412 return err; 413 414 /* VTU DBNum[3:0] are located in VTU Operation 3:0 415 * VTU DBNum[7:4] are located in VTU Operation 11:8 416 */ 417 op |= entry->fid & 0x000f; 418 op |= (entry->fid & 0x00f0) << 8; 419 } 420 421 return mv88e6xxx_g1_vtu_op(chip, op); 422 } 423 424 int mv88e6352_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip, 425 struct mv88e6xxx_vtu_entry *entry) 426 { 427 int err; 428 429 err = mv88e6xxx_g1_vtu_op_wait(chip); 430 if (err) 431 return err; 432 433 err = mv88e6xxx_g1_vtu_vid_write(chip, entry); 434 if (err) 435 return err; 436 437 if (entry->valid) { 438 /* Write MemberTag and PortState data */ 439 err = mv88e6185_g1_vtu_data_write(chip, entry); 440 if (err) 441 return err; 442 443 err = mv88e6xxx_g1_vtu_sid_write(chip, entry); 444 if (err) 445 return err; 446 447 /* Load STU entry */ 448 err = mv88e6xxx_g1_vtu_op(chip, 449 MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE); 450 if (err) 451 return err; 452 453 err = mv88e6xxx_g1_vtu_fid_write(chip, entry); 454 if (err) 455 return err; 456 } 457 458 /* Load/Purge VTU entry */ 459 return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE); 460 } 461 462 int mv88e6390_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip, 463 struct mv88e6xxx_vtu_entry *entry) 464 { 465 int err; 466 467 err = mv88e6xxx_g1_vtu_op_wait(chip); 468 if (err) 469 return err; 470 471 err = mv88e6xxx_g1_vtu_vid_write(chip, entry); 472 if (err) 473 return err; 474 475 if (entry->valid) { 476 /* Write PortState data */ 477 err = mv88e6390_g1_vtu_data_write(chip, entry->state); 478 if (err) 479 return err; 480 481 err = mv88e6xxx_g1_vtu_sid_write(chip, entry); 482 if (err) 483 return err; 484 485 /* Load STU entry */ 486 err = mv88e6xxx_g1_vtu_op(chip, 487 MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE); 488 if (err) 489 return err; 490 491 /* Write MemberTag data */ 492 err = mv88e6390_g1_vtu_data_write(chip, entry->member); 493 if (err) 494 return err; 495 496 err = mv88e6xxx_g1_vtu_fid_write(chip, entry); 497 if (err) 498 return err; 499 } 500 501 /* Load/Purge VTU entry */ 502 return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE); 503 } 504 505 int mv88e6xxx_g1_vtu_flush(struct mv88e6xxx_chip *chip) 506 { 507 int err; 508 509 err = mv88e6xxx_g1_vtu_op_wait(chip); 510 if (err) 511 return err; 512 513 return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_FLUSH_ALL); 514 } 515 516 static irqreturn_t mv88e6xxx_g1_vtu_prob_irq_thread_fn(int irq, void *dev_id) 517 { 518 struct mv88e6xxx_chip *chip = dev_id; 519 struct mv88e6xxx_vtu_entry entry; 520 int spid; 521 int err; 522 u16 val; 523 524 mutex_lock(&chip->reg_lock); 525 526 err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_GET_CLR_VIOLATION); 527 if (err) 528 goto out; 529 530 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val); 531 if (err) 532 goto out; 533 534 err = mv88e6xxx_g1_vtu_vid_read(chip, &entry); 535 if (err) 536 goto out; 537 538 spid = val & MV88E6XXX_G1_VTU_OP_SPID_MASK; 539 540 if (val & MV88E6XXX_G1_VTU_OP_MEMBER_VIOLATION) { 541 dev_err_ratelimited(chip->dev, "VTU member violation for vid %d, source port %d\n", 542 entry.vid, spid); 543 chip->ports[spid].vtu_member_violation++; 544 } 545 546 if (val & MV88E6XXX_G1_VTU_OP_MISS_VIOLATION) { 547 dev_dbg_ratelimited(chip->dev, "VTU miss violation for vid %d, source port %d\n", 548 entry.vid, spid); 549 chip->ports[spid].vtu_miss_violation++; 550 } 551 552 mutex_unlock(&chip->reg_lock); 553 554 return IRQ_HANDLED; 555 556 out: 557 mutex_unlock(&chip->reg_lock); 558 559 dev_err(chip->dev, "VTU problem: error %d while handling interrupt\n", 560 err); 561 562 return IRQ_HANDLED; 563 } 564 565 int mv88e6xxx_g1_vtu_prob_irq_setup(struct mv88e6xxx_chip *chip) 566 { 567 int err; 568 569 chip->vtu_prob_irq = irq_find_mapping(chip->g1_irq.domain, 570 MV88E6XXX_G1_STS_IRQ_VTU_PROB); 571 if (chip->vtu_prob_irq < 0) 572 return chip->vtu_prob_irq; 573 574 err = request_threaded_irq(chip->vtu_prob_irq, NULL, 575 mv88e6xxx_g1_vtu_prob_irq_thread_fn, 576 IRQF_ONESHOT, "mv88e6xxx-g1-vtu-prob", 577 chip); 578 if (err) 579 irq_dispose_mapping(chip->vtu_prob_irq); 580 581 return err; 582 } 583 584 void mv88e6xxx_g1_vtu_prob_irq_free(struct mv88e6xxx_chip *chip) 585 { 586 free_irq(chip->vtu_prob_irq, chip); 587 irq_dispose_mapping(chip->vtu_prob_irq); 588 } 589