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