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