1 /* 2 * Marvell 88E6xxx Switch Global 2 Registers support (device address 3 * 0x1C) 4 * 5 * Copyright (c) 2008 Marvell Semiconductor 6 * 7 * Copyright (c) 2016 Vivien Didelot <vivien.didelot@savoirfairelinux.com> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 */ 14 15 #include <linux/irqdomain.h> 16 #include "mv88e6xxx.h" 17 #include "global2.h" 18 19 #define ADDR_GLOBAL2 0x1c 20 21 static int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val) 22 { 23 return mv88e6xxx_read(chip, ADDR_GLOBAL2, reg, val); 24 } 25 26 static int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val) 27 { 28 return mv88e6xxx_write(chip, ADDR_GLOBAL2, reg, val); 29 } 30 31 static int mv88e6xxx_g2_update(struct mv88e6xxx_chip *chip, int reg, u16 update) 32 { 33 return mv88e6xxx_update(chip, ADDR_GLOBAL2, reg, update); 34 } 35 36 static int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask) 37 { 38 return mv88e6xxx_wait(chip, ADDR_GLOBAL2, reg, mask); 39 } 40 41 /* Offset 0x02: Management Enable 2x */ 42 /* Offset 0x03: Management Enable 0x */ 43 44 int mv88e6095_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip) 45 { 46 int err; 47 48 /* Consider the frames with reserved multicast destination 49 * addresses matching 01:80:c2:00:00:2x as MGMT. 50 */ 51 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_2X)) { 52 err = mv88e6xxx_g2_write(chip, GLOBAL2_MGMT_EN_2X, 0xffff); 53 if (err) 54 return err; 55 } 56 57 /* Consider the frames with reserved multicast destination 58 * addresses matching 01:80:c2:00:00:0x as MGMT. 59 */ 60 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_0X)) 61 return mv88e6xxx_g2_write(chip, GLOBAL2_MGMT_EN_0X, 0xffff); 62 63 return 0; 64 } 65 66 /* Offset 0x06: Device Mapping Table register */ 67 68 static int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, 69 int target, int port) 70 { 71 u16 val = (target << 8) | (port & 0xf); 72 73 return mv88e6xxx_g2_update(chip, GLOBAL2_DEVICE_MAPPING, val); 74 } 75 76 static int mv88e6xxx_g2_set_device_mapping(struct mv88e6xxx_chip *chip) 77 { 78 int target, port; 79 int err; 80 81 /* Initialize the routing port to the 32 possible target devices */ 82 for (target = 0; target < 32; ++target) { 83 port = 0xf; 84 85 if (target < DSA_MAX_SWITCHES) { 86 port = chip->ds->rtable[target]; 87 if (port == DSA_RTABLE_NONE) 88 port = 0xf; 89 } 90 91 err = mv88e6xxx_g2_device_mapping_write(chip, target, port); 92 if (err) 93 break; 94 } 95 96 return err; 97 } 98 99 /* Offset 0x07: Trunk Mask Table register */ 100 101 static int mv88e6xxx_g2_trunk_mask_write(struct mv88e6xxx_chip *chip, int num, 102 bool hask, u16 mask) 103 { 104 const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1; 105 u16 val = (num << 12) | (mask & port_mask); 106 107 if (hask) 108 val |= GLOBAL2_TRUNK_MASK_HASK; 109 110 return mv88e6xxx_g2_update(chip, GLOBAL2_TRUNK_MASK, val); 111 } 112 113 /* Offset 0x08: Trunk Mapping Table register */ 114 115 static int mv88e6xxx_g2_trunk_mapping_write(struct mv88e6xxx_chip *chip, int id, 116 u16 map) 117 { 118 const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1; 119 u16 val = (id << 11) | (map & port_mask); 120 121 return mv88e6xxx_g2_update(chip, GLOBAL2_TRUNK_MAPPING, val); 122 } 123 124 static int mv88e6xxx_g2_clear_trunk(struct mv88e6xxx_chip *chip) 125 { 126 const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1; 127 int i, err; 128 129 /* Clear all eight possible Trunk Mask vectors */ 130 for (i = 0; i < 8; ++i) { 131 err = mv88e6xxx_g2_trunk_mask_write(chip, i, false, port_mask); 132 if (err) 133 return err; 134 } 135 136 /* Clear all sixteen possible Trunk ID routing vectors */ 137 for (i = 0; i < 16; ++i) { 138 err = mv88e6xxx_g2_trunk_mapping_write(chip, i, 0); 139 if (err) 140 return err; 141 } 142 143 return 0; 144 } 145 146 /* Offset 0x09: Ingress Rate Command register 147 * Offset 0x0A: Ingress Rate Data register 148 */ 149 150 static int mv88e6xxx_g2_clear_irl(struct mv88e6xxx_chip *chip) 151 { 152 int port, err; 153 154 /* Init all Ingress Rate Limit resources of all ports */ 155 for (port = 0; port < mv88e6xxx_num_ports(chip); ++port) { 156 /* XXX newer chips (like 88E6390) have different 2-bit ops */ 157 err = mv88e6xxx_g2_write(chip, GLOBAL2_IRL_CMD, 158 GLOBAL2_IRL_CMD_OP_INIT_ALL | 159 (port << 8)); 160 if (err) 161 break; 162 163 /* Wait for the operation to complete */ 164 err = mv88e6xxx_g2_wait(chip, GLOBAL2_IRL_CMD, 165 GLOBAL2_IRL_CMD_BUSY); 166 if (err) 167 break; 168 } 169 170 return err; 171 } 172 173 /* Offset 0x0D: Switch MAC/WoL/WoF register */ 174 175 static int mv88e6xxx_g2_switch_mac_write(struct mv88e6xxx_chip *chip, 176 unsigned int pointer, u8 data) 177 { 178 u16 val = (pointer << 8) | data; 179 180 return mv88e6xxx_g2_update(chip, GLOBAL2_SWITCH_MAC, val); 181 } 182 183 int mv88e6xxx_g2_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr) 184 { 185 int i, err; 186 187 for (i = 0; i < 6; i++) { 188 err = mv88e6xxx_g2_switch_mac_write(chip, i, addr[i]); 189 if (err) 190 break; 191 } 192 193 return err; 194 } 195 196 /* Offset 0x0F: Priority Override Table */ 197 198 static int mv88e6xxx_g2_pot_write(struct mv88e6xxx_chip *chip, int pointer, 199 u8 data) 200 { 201 u16 val = (pointer << 8) | (data & 0x7); 202 203 return mv88e6xxx_g2_update(chip, GLOBAL2_PRIO_OVERRIDE, val); 204 } 205 206 static int mv88e6xxx_g2_clear_pot(struct mv88e6xxx_chip *chip) 207 { 208 int i, err; 209 210 /* Clear all sixteen possible Priority Override entries */ 211 for (i = 0; i < 16; i++) { 212 err = mv88e6xxx_g2_pot_write(chip, i, 0); 213 if (err) 214 break; 215 } 216 217 return err; 218 } 219 220 /* Offset 0x14: EEPROM Command 221 * Offset 0x15: EEPROM Data 222 */ 223 224 static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip) 225 { 226 return mv88e6xxx_g2_wait(chip, GLOBAL2_EEPROM_CMD, 227 GLOBAL2_EEPROM_CMD_BUSY | 228 GLOBAL2_EEPROM_CMD_RUNNING); 229 } 230 231 static int mv88e6xxx_g2_eeprom_cmd(struct mv88e6xxx_chip *chip, u16 cmd) 232 { 233 int err; 234 235 err = mv88e6xxx_g2_write(chip, GLOBAL2_EEPROM_CMD, cmd); 236 if (err) 237 return err; 238 239 return mv88e6xxx_g2_eeprom_wait(chip); 240 } 241 242 static int mv88e6xxx_g2_eeprom_read16(struct mv88e6xxx_chip *chip, 243 u8 addr, u16 *data) 244 { 245 u16 cmd = GLOBAL2_EEPROM_CMD_OP_READ | addr; 246 int err; 247 248 err = mv88e6xxx_g2_eeprom_wait(chip); 249 if (err) 250 return err; 251 252 err = mv88e6xxx_g2_eeprom_cmd(chip, cmd); 253 if (err) 254 return err; 255 256 return mv88e6xxx_g2_read(chip, GLOBAL2_EEPROM_DATA, data); 257 } 258 259 static int mv88e6xxx_g2_eeprom_write16(struct mv88e6xxx_chip *chip, 260 u8 addr, u16 data) 261 { 262 u16 cmd = GLOBAL2_EEPROM_CMD_OP_WRITE | addr; 263 int err; 264 265 err = mv88e6xxx_g2_eeprom_wait(chip); 266 if (err) 267 return err; 268 269 err = mv88e6xxx_g2_write(chip, GLOBAL2_EEPROM_DATA, data); 270 if (err) 271 return err; 272 273 return mv88e6xxx_g2_eeprom_cmd(chip, cmd); 274 } 275 276 int mv88e6xxx_g2_get_eeprom16(struct mv88e6xxx_chip *chip, 277 struct ethtool_eeprom *eeprom, u8 *data) 278 { 279 unsigned int offset = eeprom->offset; 280 unsigned int len = eeprom->len; 281 u16 val; 282 int err; 283 284 eeprom->len = 0; 285 286 if (offset & 1) { 287 err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val); 288 if (err) 289 return err; 290 291 *data++ = (val >> 8) & 0xff; 292 293 offset++; 294 len--; 295 eeprom->len++; 296 } 297 298 while (len >= 2) { 299 err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val); 300 if (err) 301 return err; 302 303 *data++ = val & 0xff; 304 *data++ = (val >> 8) & 0xff; 305 306 offset += 2; 307 len -= 2; 308 eeprom->len += 2; 309 } 310 311 if (len) { 312 err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val); 313 if (err) 314 return err; 315 316 *data++ = val & 0xff; 317 318 offset++; 319 len--; 320 eeprom->len++; 321 } 322 323 return 0; 324 } 325 326 int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip, 327 struct ethtool_eeprom *eeprom, u8 *data) 328 { 329 unsigned int offset = eeprom->offset; 330 unsigned int len = eeprom->len; 331 u16 val; 332 int err; 333 334 /* Ensure the RO WriteEn bit is set */ 335 err = mv88e6xxx_g2_read(chip, GLOBAL2_EEPROM_CMD, &val); 336 if (err) 337 return err; 338 339 if (!(val & GLOBAL2_EEPROM_CMD_WRITE_EN)) 340 return -EROFS; 341 342 eeprom->len = 0; 343 344 if (offset & 1) { 345 err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val); 346 if (err) 347 return err; 348 349 val = (*data++ << 8) | (val & 0xff); 350 351 err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val); 352 if (err) 353 return err; 354 355 offset++; 356 len--; 357 eeprom->len++; 358 } 359 360 while (len >= 2) { 361 val = *data++; 362 val |= *data++ << 8; 363 364 err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val); 365 if (err) 366 return err; 367 368 offset += 2; 369 len -= 2; 370 eeprom->len += 2; 371 } 372 373 if (len) { 374 err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val); 375 if (err) 376 return err; 377 378 val = (val & 0xff00) | *data++; 379 380 err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val); 381 if (err) 382 return err; 383 384 offset++; 385 len--; 386 eeprom->len++; 387 } 388 389 return 0; 390 } 391 392 /* Offset 0x18: SMI PHY Command Register 393 * Offset 0x19: SMI PHY Data Register 394 */ 395 396 static int mv88e6xxx_g2_smi_phy_wait(struct mv88e6xxx_chip *chip) 397 { 398 return mv88e6xxx_g2_wait(chip, GLOBAL2_SMI_PHY_CMD, 399 GLOBAL2_SMI_PHY_CMD_BUSY); 400 } 401 402 static int mv88e6xxx_g2_smi_phy_cmd(struct mv88e6xxx_chip *chip, u16 cmd) 403 { 404 int err; 405 406 err = mv88e6xxx_g2_write(chip, GLOBAL2_SMI_PHY_CMD, cmd); 407 if (err) 408 return err; 409 410 return mv88e6xxx_g2_smi_phy_wait(chip); 411 } 412 413 int mv88e6xxx_g2_smi_phy_read(struct mv88e6xxx_chip *chip, int addr, int reg, 414 u16 *val) 415 { 416 u16 cmd = GLOBAL2_SMI_PHY_CMD_OP_22_READ_DATA | (addr << 5) | reg; 417 int err; 418 419 err = mv88e6xxx_g2_smi_phy_wait(chip); 420 if (err) 421 return err; 422 423 err = mv88e6xxx_g2_smi_phy_cmd(chip, cmd); 424 if (err) 425 return err; 426 427 return mv88e6xxx_g2_read(chip, GLOBAL2_SMI_PHY_DATA, val); 428 } 429 430 int mv88e6xxx_g2_smi_phy_write(struct mv88e6xxx_chip *chip, int addr, int reg, 431 u16 val) 432 { 433 u16 cmd = GLOBAL2_SMI_PHY_CMD_OP_22_WRITE_DATA | (addr << 5) | reg; 434 int err; 435 436 err = mv88e6xxx_g2_smi_phy_wait(chip); 437 if (err) 438 return err; 439 440 err = mv88e6xxx_g2_write(chip, GLOBAL2_SMI_PHY_DATA, val); 441 if (err) 442 return err; 443 444 return mv88e6xxx_g2_smi_phy_cmd(chip, cmd); 445 } 446 447 static void mv88e6xxx_g2_irq_mask(struct irq_data *d) 448 { 449 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d); 450 unsigned int n = d->hwirq; 451 452 chip->g2_irq.masked |= (1 << n); 453 } 454 455 static void mv88e6xxx_g2_irq_unmask(struct irq_data *d) 456 { 457 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d); 458 unsigned int n = d->hwirq; 459 460 chip->g2_irq.masked &= ~(1 << n); 461 } 462 463 static irqreturn_t mv88e6xxx_g2_irq_thread_fn(int irq, void *dev_id) 464 { 465 struct mv88e6xxx_chip *chip = dev_id; 466 unsigned int nhandled = 0; 467 unsigned int sub_irq; 468 unsigned int n; 469 int err; 470 u16 reg; 471 472 mutex_lock(&chip->reg_lock); 473 err = mv88e6xxx_g2_read(chip, GLOBAL2_INT_SOURCE, ®); 474 mutex_unlock(&chip->reg_lock); 475 if (err) 476 goto out; 477 478 for (n = 0; n < 16; ++n) { 479 if (reg & (1 << n)) { 480 sub_irq = irq_find_mapping(chip->g2_irq.domain, n); 481 handle_nested_irq(sub_irq); 482 ++nhandled; 483 } 484 } 485 out: 486 return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE); 487 } 488 489 static void mv88e6xxx_g2_irq_bus_lock(struct irq_data *d) 490 { 491 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d); 492 493 mutex_lock(&chip->reg_lock); 494 } 495 496 static void mv88e6xxx_g2_irq_bus_sync_unlock(struct irq_data *d) 497 { 498 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d); 499 500 mv88e6xxx_g2_write(chip, GLOBAL2_INT_MASK, ~chip->g2_irq.masked); 501 502 mutex_unlock(&chip->reg_lock); 503 } 504 505 static struct irq_chip mv88e6xxx_g2_irq_chip = { 506 .name = "mv88e6xxx-g2", 507 .irq_mask = mv88e6xxx_g2_irq_mask, 508 .irq_unmask = mv88e6xxx_g2_irq_unmask, 509 .irq_bus_lock = mv88e6xxx_g2_irq_bus_lock, 510 .irq_bus_sync_unlock = mv88e6xxx_g2_irq_bus_sync_unlock, 511 }; 512 513 static int mv88e6xxx_g2_irq_domain_map(struct irq_domain *d, 514 unsigned int irq, 515 irq_hw_number_t hwirq) 516 { 517 struct mv88e6xxx_chip *chip = d->host_data; 518 519 irq_set_chip_data(irq, d->host_data); 520 irq_set_chip_and_handler(irq, &chip->g2_irq.chip, handle_level_irq); 521 irq_set_noprobe(irq); 522 523 return 0; 524 } 525 526 static const struct irq_domain_ops mv88e6xxx_g2_irq_domain_ops = { 527 .map = mv88e6xxx_g2_irq_domain_map, 528 .xlate = irq_domain_xlate_twocell, 529 }; 530 531 void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip *chip) 532 { 533 int irq, virq; 534 535 free_irq(chip->device_irq, chip); 536 irq_dispose_mapping(chip->device_irq); 537 538 for (irq = 0; irq < 16; irq++) { 539 virq = irq_find_mapping(chip->g2_irq.domain, irq); 540 irq_dispose_mapping(virq); 541 } 542 543 irq_domain_remove(chip->g2_irq.domain); 544 } 545 546 int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip) 547 { 548 int err, irq, virq; 549 550 if (!chip->dev->of_node) 551 return -EINVAL; 552 553 chip->g2_irq.domain = irq_domain_add_simple( 554 chip->dev->of_node, 16, 0, &mv88e6xxx_g2_irq_domain_ops, chip); 555 if (!chip->g2_irq.domain) 556 return -ENOMEM; 557 558 for (irq = 0; irq < 16; irq++) 559 irq_create_mapping(chip->g2_irq.domain, irq); 560 561 chip->g2_irq.chip = mv88e6xxx_g2_irq_chip; 562 chip->g2_irq.masked = ~0; 563 564 chip->device_irq = irq_find_mapping(chip->g1_irq.domain, 565 GLOBAL_STATUS_IRQ_DEVICE); 566 if (chip->device_irq < 0) { 567 err = chip->device_irq; 568 goto out; 569 } 570 571 err = request_threaded_irq(chip->device_irq, NULL, 572 mv88e6xxx_g2_irq_thread_fn, 573 IRQF_ONESHOT, "mv88e6xxx-g1", chip); 574 if (err) 575 goto out; 576 577 return 0; 578 579 out: 580 for (irq = 0; irq < 16; irq++) { 581 virq = irq_find_mapping(chip->g2_irq.domain, irq); 582 irq_dispose_mapping(virq); 583 } 584 585 irq_domain_remove(chip->g2_irq.domain); 586 587 return err; 588 } 589 590 int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip) 591 { 592 u16 reg; 593 int err; 594 595 /* Ignore removed tag data on doubly tagged packets, disable 596 * flow control messages, force flow control priority to the 597 * highest, and send all special multicast frames to the CPU 598 * port at the highest priority. 599 */ 600 reg = GLOBAL2_SWITCH_MGMT_FORCE_FLOW_CTRL_PRI | (0x7 << 4); 601 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_0X) || 602 mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_2X)) 603 reg |= GLOBAL2_SWITCH_MGMT_RSVD2CPU | 0x7; 604 err = mv88e6xxx_g2_write(chip, GLOBAL2_SWITCH_MGMT, reg); 605 if (err) 606 return err; 607 608 /* Program the DSA routing table. */ 609 err = mv88e6xxx_g2_set_device_mapping(chip); 610 if (err) 611 return err; 612 613 /* Clear all trunk masks and mapping. */ 614 err = mv88e6xxx_g2_clear_trunk(chip); 615 if (err) 616 return err; 617 618 if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_IRL)) { 619 /* Disable ingress rate limiting by resetting all per port 620 * ingress rate limit resources to their initial state. 621 */ 622 err = mv88e6xxx_g2_clear_irl(chip); 623 if (err) 624 return err; 625 } 626 627 if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_PVT)) { 628 /* Initialize Cross-chip Port VLAN Table to reset defaults */ 629 err = mv88e6xxx_g2_write(chip, GLOBAL2_PVT_ADDR, 630 GLOBAL2_PVT_ADDR_OP_INIT_ONES); 631 if (err) 632 return err; 633 } 634 635 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_POT)) { 636 /* Clear the priority override table. */ 637 err = mv88e6xxx_g2_clear_pot(chip); 638 if (err) 639 return err; 640 } 641 642 return 0; 643 } 644