1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Marvell 88E6xxx Switch Global (1) Registers support 4 * 5 * Copyright (c) 2008 Marvell Semiconductor 6 * 7 * Copyright (c) 2016-2017 Savoir-faire Linux Inc. 8 * Vivien Didelot <vivien.didelot@savoirfairelinux.com> 9 */ 10 11 #include <linux/bitfield.h> 12 13 #include "chip.h" 14 #include "global1.h" 15 16 int mv88e6xxx_g1_read(struct mv88e6xxx_chip *chip, int reg, u16 *val) 17 { 18 int addr = chip->info->global1_addr; 19 20 return mv88e6xxx_read(chip, addr, reg, val); 21 } 22 23 int mv88e6xxx_g1_write(struct mv88e6xxx_chip *chip, int reg, u16 val) 24 { 25 int addr = chip->info->global1_addr; 26 27 return mv88e6xxx_write(chip, addr, reg, val); 28 } 29 30 int mv88e6xxx_g1_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask) 31 { 32 return mv88e6xxx_wait(chip, chip->info->global1_addr, reg, mask); 33 } 34 35 /* Offset 0x00: Switch Global Status Register */ 36 37 static int mv88e6185_g1_wait_ppu_disabled(struct mv88e6xxx_chip *chip) 38 { 39 u16 state; 40 int i, err; 41 42 for (i = 0; i < 16; i++) { 43 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &state); 44 if (err) 45 return err; 46 47 /* Check the value of the PPUState bits 15:14 */ 48 state &= MV88E6185_G1_STS_PPU_STATE_MASK; 49 if (state != MV88E6185_G1_STS_PPU_STATE_POLLING) 50 return 0; 51 52 usleep_range(1000, 2000); 53 } 54 55 return -ETIMEDOUT; 56 } 57 58 static int mv88e6185_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip) 59 { 60 u16 state; 61 int i, err; 62 63 for (i = 0; i < 16; ++i) { 64 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &state); 65 if (err) 66 return err; 67 68 /* Check the value of the PPUState bits 15:14 */ 69 state &= MV88E6185_G1_STS_PPU_STATE_MASK; 70 if (state == MV88E6185_G1_STS_PPU_STATE_POLLING) 71 return 0; 72 73 usleep_range(1000, 2000); 74 } 75 76 return -ETIMEDOUT; 77 } 78 79 static int mv88e6352_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip) 80 { 81 u16 state; 82 int i, err; 83 84 for (i = 0; i < 16; ++i) { 85 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &state); 86 if (err) 87 return err; 88 89 /* Check the value of the PPUState (or InitState) bit 15 */ 90 if (state & MV88E6352_G1_STS_PPU_STATE) 91 return 0; 92 93 usleep_range(1000, 2000); 94 } 95 96 return -ETIMEDOUT; 97 } 98 99 static int mv88e6xxx_g1_wait_init_ready(struct mv88e6xxx_chip *chip) 100 { 101 const unsigned long timeout = jiffies + 1 * HZ; 102 u16 val; 103 int err; 104 105 /* Wait up to 1 second for the switch to be ready. The InitReady bit 11 106 * is set to a one when all units inside the device (ATU, VTU, etc.) 107 * have finished their initialization and are ready to accept frames. 108 */ 109 while (time_before(jiffies, timeout)) { 110 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &val); 111 if (err) 112 return err; 113 114 if (val & MV88E6XXX_G1_STS_INIT_READY) 115 break; 116 117 usleep_range(1000, 2000); 118 } 119 120 if (time_after(jiffies, timeout)) 121 return -ETIMEDOUT; 122 123 return 0; 124 } 125 126 /* Offset 0x01: Switch MAC Address Register Bytes 0 & 1 127 * Offset 0x02: Switch MAC Address Register Bytes 2 & 3 128 * Offset 0x03: Switch MAC Address Register Bytes 4 & 5 129 */ 130 int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr) 131 { 132 u16 reg; 133 int err; 134 135 reg = (addr[0] << 8) | addr[1]; 136 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_MAC_01, reg); 137 if (err) 138 return err; 139 140 reg = (addr[2] << 8) | addr[3]; 141 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_MAC_23, reg); 142 if (err) 143 return err; 144 145 reg = (addr[4] << 8) | addr[5]; 146 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_MAC_45, reg); 147 if (err) 148 return err; 149 150 return 0; 151 } 152 153 /* Offset 0x04: Switch Global Control Register */ 154 155 int mv88e6185_g1_reset(struct mv88e6xxx_chip *chip) 156 { 157 u16 val; 158 int err; 159 160 /* Set the SWReset bit 15 along with the PPUEn bit 14, to also restart 161 * the PPU, including re-doing PHY detection and initialization 162 */ 163 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val); 164 if (err) 165 return err; 166 167 val |= MV88E6XXX_G1_CTL1_SW_RESET; 168 val |= MV88E6XXX_G1_CTL1_PPU_ENABLE; 169 170 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val); 171 if (err) 172 return err; 173 174 err = mv88e6xxx_g1_wait_init_ready(chip); 175 if (err) 176 return err; 177 178 return mv88e6185_g1_wait_ppu_polling(chip); 179 } 180 181 int mv88e6352_g1_reset(struct mv88e6xxx_chip *chip) 182 { 183 u16 val; 184 int err; 185 186 /* Set the SWReset bit 15 */ 187 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val); 188 if (err) 189 return err; 190 191 val |= MV88E6XXX_G1_CTL1_SW_RESET; 192 193 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val); 194 if (err) 195 return err; 196 197 err = mv88e6xxx_g1_wait_init_ready(chip); 198 if (err) 199 return err; 200 201 return mv88e6352_g1_wait_ppu_polling(chip); 202 } 203 204 int mv88e6185_g1_ppu_enable(struct mv88e6xxx_chip *chip) 205 { 206 u16 val; 207 int err; 208 209 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val); 210 if (err) 211 return err; 212 213 val |= MV88E6XXX_G1_CTL1_PPU_ENABLE; 214 215 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val); 216 if (err) 217 return err; 218 219 return mv88e6185_g1_wait_ppu_polling(chip); 220 } 221 222 int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip *chip) 223 { 224 u16 val; 225 int err; 226 227 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val); 228 if (err) 229 return err; 230 231 val &= ~MV88E6XXX_G1_CTL1_PPU_ENABLE; 232 233 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val); 234 if (err) 235 return err; 236 237 return mv88e6185_g1_wait_ppu_disabled(chip); 238 } 239 240 /* Offset 0x10: IP-PRI Mapping Register 0 241 * Offset 0x11: IP-PRI Mapping Register 1 242 * Offset 0x12: IP-PRI Mapping Register 2 243 * Offset 0x13: IP-PRI Mapping Register 3 244 * Offset 0x14: IP-PRI Mapping Register 4 245 * Offset 0x15: IP-PRI Mapping Register 5 246 * Offset 0x16: IP-PRI Mapping Register 6 247 * Offset 0x17: IP-PRI Mapping Register 7 248 */ 249 250 int mv88e6085_g1_ip_pri_map(struct mv88e6xxx_chip *chip) 251 { 252 int err; 253 254 /* Reset the IP TOS/DiffServ/Traffic priorities to defaults */ 255 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_0, 0x0000); 256 if (err) 257 return err; 258 259 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_1, 0x0000); 260 if (err) 261 return err; 262 263 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_2, 0x5555); 264 if (err) 265 return err; 266 267 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_3, 0x5555); 268 if (err) 269 return err; 270 271 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_4, 0xaaaa); 272 if (err) 273 return err; 274 275 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_5, 0xaaaa); 276 if (err) 277 return err; 278 279 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_6, 0xffff); 280 if (err) 281 return err; 282 283 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_7, 0xffff); 284 if (err) 285 return err; 286 287 return 0; 288 } 289 290 /* Offset 0x18: IEEE-PRI Register */ 291 292 int mv88e6085_g1_ieee_pri_map(struct mv88e6xxx_chip *chip) 293 { 294 /* Reset the IEEE Tag priorities to defaults */ 295 return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IEEE_PRI, 0xfa41); 296 } 297 298 /* Offset 0x1a: Monitor Control */ 299 /* Offset 0x1a: Monitor & MGMT Control on some devices */ 300 301 int mv88e6095_g1_set_egress_port(struct mv88e6xxx_chip *chip, int port) 302 { 303 u16 reg; 304 int err; 305 306 err = mv88e6xxx_g1_read(chip, MV88E6185_G1_MONITOR_CTL, ®); 307 if (err) 308 return err; 309 310 reg &= ~(MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK | 311 MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK); 312 313 reg |= port << __bf_shf(MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK) | 314 port << __bf_shf(MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK); 315 316 return mv88e6xxx_g1_write(chip, MV88E6185_G1_MONITOR_CTL, reg); 317 } 318 319 /* Older generations also call this the ARP destination. It has been 320 * generalized in more modern devices such that more than ARP can 321 * egress it 322 */ 323 int mv88e6095_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port) 324 { 325 u16 reg; 326 int err; 327 328 err = mv88e6xxx_g1_read(chip, MV88E6185_G1_MONITOR_CTL, ®); 329 if (err) 330 return err; 331 332 reg &= ~MV88E6185_G1_MONITOR_CTL_ARP_DEST_MASK; 333 reg |= port << __bf_shf(MV88E6185_G1_MONITOR_CTL_ARP_DEST_MASK); 334 335 return mv88e6xxx_g1_write(chip, MV88E6185_G1_MONITOR_CTL, reg); 336 } 337 338 static int mv88e6390_g1_monitor_write(struct mv88e6xxx_chip *chip, 339 u16 pointer, u8 data) 340 { 341 u16 reg; 342 343 reg = MV88E6390_G1_MONITOR_MGMT_CTL_UPDATE | pointer | data; 344 345 return mv88e6xxx_g1_write(chip, MV88E6390_G1_MONITOR_MGMT_CTL, reg); 346 } 347 348 int mv88e6390_g1_set_egress_port(struct mv88e6xxx_chip *chip, int port) 349 { 350 u16 ptr; 351 int err; 352 353 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_INGRESS_DEST; 354 err = mv88e6390_g1_monitor_write(chip, ptr, port); 355 if (err) 356 return err; 357 358 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_EGRESS_DEST; 359 err = mv88e6390_g1_monitor_write(chip, ptr, port); 360 if (err) 361 return err; 362 363 return 0; 364 } 365 366 int mv88e6390_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port) 367 { 368 u16 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST; 369 370 return mv88e6390_g1_monitor_write(chip, ptr, port); 371 } 372 373 int mv88e6390_g1_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip) 374 { 375 u16 ptr; 376 int err; 377 378 /* 01:c2:80:00:00:00:00-01:c2:80:00:00:00:07 are Management */ 379 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C280000000XLO; 380 err = mv88e6390_g1_monitor_write(chip, ptr, 0xff); 381 if (err) 382 return err; 383 384 /* 01:c2:80:00:00:00:08-01:c2:80:00:00:00:0f are Management */ 385 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C280000000XHI; 386 err = mv88e6390_g1_monitor_write(chip, ptr, 0xff); 387 if (err) 388 return err; 389 390 /* 01:c2:80:00:00:00:20-01:c2:80:00:00:00:27 are Management */ 391 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C280000002XLO; 392 err = mv88e6390_g1_monitor_write(chip, ptr, 0xff); 393 if (err) 394 return err; 395 396 /* 01:c2:80:00:00:00:28-01:c2:80:00:00:00:2f are Management */ 397 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C280000002XHI; 398 err = mv88e6390_g1_monitor_write(chip, ptr, 0xff); 399 if (err) 400 return err; 401 402 return 0; 403 } 404 405 /* Offset 0x1c: Global Control 2 */ 406 407 static int mv88e6xxx_g1_ctl2_mask(struct mv88e6xxx_chip *chip, u16 mask, 408 u16 val) 409 { 410 u16 reg; 411 int err; 412 413 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL2, ®); 414 if (err) 415 return err; 416 417 reg &= ~mask; 418 reg |= val & mask; 419 420 return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL2, reg); 421 } 422 423 int mv88e6185_g1_set_cascade_port(struct mv88e6xxx_chip *chip, int port) 424 { 425 const u16 mask = MV88E6185_G1_CTL2_CASCADE_PORT_MASK; 426 427 return mv88e6xxx_g1_ctl2_mask(chip, mask, port << __bf_shf(mask)); 428 } 429 430 int mv88e6085_g1_rmu_disable(struct mv88e6xxx_chip *chip) 431 { 432 return mv88e6xxx_g1_ctl2_mask(chip, MV88E6085_G1_CTL2_P10RM | 433 MV88E6085_G1_CTL2_RM_ENABLE, 0); 434 } 435 436 int mv88e6352_g1_rmu_disable(struct mv88e6xxx_chip *chip) 437 { 438 return mv88e6xxx_g1_ctl2_mask(chip, MV88E6352_G1_CTL2_RMU_MODE_MASK, 439 MV88E6352_G1_CTL2_RMU_MODE_DISABLED); 440 } 441 442 int mv88e6390_g1_rmu_disable(struct mv88e6xxx_chip *chip) 443 { 444 return mv88e6xxx_g1_ctl2_mask(chip, MV88E6390_G1_CTL2_RMU_MODE_MASK, 445 MV88E6390_G1_CTL2_RMU_MODE_DISABLED); 446 } 447 448 int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip *chip) 449 { 450 return mv88e6xxx_g1_ctl2_mask(chip, MV88E6390_G1_CTL2_HIST_MODE_MASK, 451 MV88E6390_G1_CTL2_HIST_MODE_RX | 452 MV88E6390_G1_CTL2_HIST_MODE_TX); 453 } 454 455 int mv88e6xxx_g1_set_device_number(struct mv88e6xxx_chip *chip, int index) 456 { 457 return mv88e6xxx_g1_ctl2_mask(chip, 458 MV88E6XXX_G1_CTL2_DEVICE_NUMBER_MASK, 459 index); 460 } 461 462 /* Offset 0x1d: Statistics Operation 2 */ 463 464 int mv88e6xxx_g1_stats_wait(struct mv88e6xxx_chip *chip) 465 { 466 return mv88e6xxx_g1_wait(chip, MV88E6XXX_G1_STATS_OP, 467 MV88E6XXX_G1_STATS_OP_BUSY); 468 } 469 470 int mv88e6095_g1_stats_set_histogram(struct mv88e6xxx_chip *chip) 471 { 472 u16 val; 473 int err; 474 475 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STATS_OP, &val); 476 if (err) 477 return err; 478 479 val |= MV88E6XXX_G1_STATS_OP_HIST_RX_TX; 480 481 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP, val); 482 483 return err; 484 } 485 486 int mv88e6xxx_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port) 487 { 488 int err; 489 490 /* Snapshot the hardware statistics counters for this port. */ 491 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP, 492 MV88E6XXX_G1_STATS_OP_BUSY | 493 MV88E6XXX_G1_STATS_OP_CAPTURE_PORT | 494 MV88E6XXX_G1_STATS_OP_HIST_RX_TX | port); 495 if (err) 496 return err; 497 498 /* Wait for the snapshotting to complete. */ 499 return mv88e6xxx_g1_stats_wait(chip); 500 } 501 502 int mv88e6320_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port) 503 { 504 port = (port + 1) << 5; 505 506 return mv88e6xxx_g1_stats_snapshot(chip, port); 507 } 508 509 int mv88e6390_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port) 510 { 511 int err; 512 513 port = (port + 1) << 5; 514 515 /* Snapshot the hardware statistics counters for this port. */ 516 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP, 517 MV88E6XXX_G1_STATS_OP_BUSY | 518 MV88E6XXX_G1_STATS_OP_CAPTURE_PORT | port); 519 if (err) 520 return err; 521 522 /* Wait for the snapshotting to complete. */ 523 return mv88e6xxx_g1_stats_wait(chip); 524 } 525 526 void mv88e6xxx_g1_stats_read(struct mv88e6xxx_chip *chip, int stat, u32 *val) 527 { 528 u32 value; 529 u16 reg; 530 int err; 531 532 *val = 0; 533 534 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP, 535 MV88E6XXX_G1_STATS_OP_BUSY | 536 MV88E6XXX_G1_STATS_OP_READ_CAPTURED | stat); 537 if (err) 538 return; 539 540 err = mv88e6xxx_g1_stats_wait(chip); 541 if (err) 542 return; 543 544 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STATS_COUNTER_32, ®); 545 if (err) 546 return; 547 548 value = reg << 16; 549 550 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STATS_COUNTER_01, ®); 551 if (err) 552 return; 553 554 *val = value | reg; 555 } 556 557 int mv88e6xxx_g1_stats_clear(struct mv88e6xxx_chip *chip) 558 { 559 int err; 560 u16 val; 561 562 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STATS_OP, &val); 563 if (err) 564 return err; 565 566 /* Keep the histogram mode bits */ 567 val &= MV88E6XXX_G1_STATS_OP_HIST_RX_TX; 568 val |= MV88E6XXX_G1_STATS_OP_BUSY | MV88E6XXX_G1_STATS_OP_FLUSH_ALL; 569 570 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP, val); 571 if (err) 572 return err; 573 574 /* Wait for the flush to complete. */ 575 return mv88e6xxx_g1_stats_wait(chip); 576 } 577