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