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_bit(struct mv88e6xxx_chip *chip, int reg, int 31 bit, int val) 32 { 33 return mv88e6xxx_wait_bit(chip, chip->info->global1_addr, reg, 34 bit, val); 35 } 36 37 int mv88e6xxx_g1_wait_mask(struct mv88e6xxx_chip *chip, int reg, 38 u16 mask, u16 val) 39 { 40 return mv88e6xxx_wait_mask(chip, chip->info->global1_addr, reg, 41 mask, val); 42 } 43 44 /* Offset 0x00: Switch Global Status Register */ 45 46 static int mv88e6185_g1_wait_ppu_disabled(struct mv88e6xxx_chip *chip) 47 { 48 return mv88e6xxx_g1_wait_mask(chip, MV88E6XXX_G1_STS, 49 MV88E6185_G1_STS_PPU_STATE_MASK, 50 MV88E6185_G1_STS_PPU_STATE_DISABLED); 51 } 52 53 static int mv88e6185_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip) 54 { 55 return mv88e6xxx_g1_wait_mask(chip, MV88E6XXX_G1_STS, 56 MV88E6185_G1_STS_PPU_STATE_MASK, 57 MV88E6185_G1_STS_PPU_STATE_POLLING); 58 } 59 60 static int mv88e6352_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip) 61 { 62 int bit = __bf_shf(MV88E6352_G1_STS_PPU_STATE); 63 64 return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STS, bit, 1); 65 } 66 67 static int mv88e6xxx_g1_wait_init_ready(struct mv88e6xxx_chip *chip) 68 { 69 int bit = __bf_shf(MV88E6XXX_G1_STS_INIT_READY); 70 71 /* Wait up to 1 second for the switch to be ready. The InitReady bit 11 72 * is set to a one when all units inside the device (ATU, VTU, etc.) 73 * have finished their initialization and are ready to accept frames. 74 */ 75 return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STS, bit, 1); 76 } 77 78 static int mv88e6250_g1_eeprom_reload(struct mv88e6xxx_chip *chip) 79 { 80 /* MV88E6185_G1_CTL1_RELOAD_EEPROM is also valid for 88E6250 */ 81 int bit = __bf_shf(MV88E6185_G1_CTL1_RELOAD_EEPROM); 82 u16 val; 83 int err; 84 85 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val); 86 if (err) 87 return err; 88 89 val |= MV88E6185_G1_CTL1_RELOAD_EEPROM; 90 91 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val); 92 if (err) 93 return err; 94 95 return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_CTL1, bit, 0); 96 } 97 98 /* Returns 0 when done, -EBUSY when waiting, other negative codes on error */ 99 static int mv88e6xxx_g1_is_eeprom_done(struct mv88e6xxx_chip *chip) 100 { 101 u16 val; 102 int err; 103 104 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &val); 105 if (err < 0) { 106 dev_err(chip->dev, "Error reading status"); 107 return err; 108 } 109 110 /* If the switch is still resetting, it may not 111 * respond on the bus, and so MDIO read returns 112 * 0xffff. Differentiate between that, and waiting for 113 * the EEPROM to be done by bit 0 being set. 114 */ 115 if (val == 0xffff || !(val & BIT(MV88E6XXX_G1_STS_IRQ_EEPROM_DONE))) 116 return -EBUSY; 117 118 return 0; 119 } 120 121 /* As the EEInt (EEPROM done) flag clears on read if the status register, this 122 * function must be called directly after a hard reset or EEPROM ReLoad request, 123 * or the done condition may have been missed 124 */ 125 int mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip) 126 { 127 const unsigned long timeout = jiffies + 1 * HZ; 128 int ret; 129 130 /* Wait up to 1 second for the switch to finish reading the 131 * EEPROM. 132 */ 133 while (time_before(jiffies, timeout)) { 134 ret = mv88e6xxx_g1_is_eeprom_done(chip); 135 if (ret != -EBUSY) 136 return ret; 137 } 138 139 dev_err(chip->dev, "Timeout waiting for EEPROM done"); 140 return -ETIMEDOUT; 141 } 142 143 int mv88e6250_g1_wait_eeprom_done_prereset(struct mv88e6xxx_chip *chip) 144 { 145 int ret; 146 147 ret = mv88e6xxx_g1_is_eeprom_done(chip); 148 if (ret != -EBUSY) 149 return ret; 150 151 /* Pre-reset, we don't know the state of the switch - when 152 * mv88e6xxx_g1_is_eeprom_done() returns -EBUSY, that may be because 153 * the switch is actually busy reading the EEPROM, or because 154 * MV88E6XXX_G1_STS_IRQ_EEPROM_DONE has been cleared by an unrelated 155 * status register read already. 156 * 157 * To account for the latter case, trigger another EEPROM reload for 158 * another chance at seeing the done flag. 159 */ 160 ret = mv88e6250_g1_eeprom_reload(chip); 161 if (ret) 162 return ret; 163 164 return mv88e6xxx_g1_wait_eeprom_done(chip); 165 } 166 167 /* Offset 0x01: Switch MAC Address Register Bytes 0 & 1 168 * Offset 0x02: Switch MAC Address Register Bytes 2 & 3 169 * Offset 0x03: Switch MAC Address Register Bytes 4 & 5 170 */ 171 int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr) 172 { 173 u16 reg; 174 int err; 175 176 reg = (addr[0] << 8) | addr[1]; 177 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_MAC_01, reg); 178 if (err) 179 return err; 180 181 reg = (addr[2] << 8) | addr[3]; 182 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_MAC_23, reg); 183 if (err) 184 return err; 185 186 reg = (addr[4] << 8) | addr[5]; 187 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_MAC_45, reg); 188 if (err) 189 return err; 190 191 return 0; 192 } 193 194 /* Offset 0x04: Switch Global Control Register */ 195 196 int mv88e6185_g1_reset(struct mv88e6xxx_chip *chip) 197 { 198 u16 val; 199 int err; 200 201 /* Set the SWReset bit 15 along with the PPUEn bit 14, to also restart 202 * the PPU, including re-doing PHY detection and initialization 203 */ 204 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val); 205 if (err) 206 return err; 207 208 val |= MV88E6XXX_G1_CTL1_SW_RESET; 209 val |= MV88E6XXX_G1_CTL1_PPU_ENABLE; 210 211 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val); 212 if (err) 213 return err; 214 215 err = mv88e6xxx_g1_wait_init_ready(chip); 216 if (err) 217 return err; 218 219 return mv88e6185_g1_wait_ppu_polling(chip); 220 } 221 222 int mv88e6250_g1_reset(struct mv88e6xxx_chip *chip) 223 { 224 u16 val; 225 int err; 226 227 /* Set the SWReset bit 15 */ 228 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val); 229 if (err) 230 return err; 231 232 val |= MV88E6XXX_G1_CTL1_SW_RESET; 233 234 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val); 235 if (err) 236 return err; 237 238 return mv88e6xxx_g1_wait_init_ready(chip); 239 } 240 241 int mv88e6352_g1_reset(struct mv88e6xxx_chip *chip) 242 { 243 int err; 244 245 err = mv88e6250_g1_reset(chip); 246 if (err) 247 return err; 248 249 return mv88e6352_g1_wait_ppu_polling(chip); 250 } 251 252 int mv88e6185_g1_ppu_enable(struct mv88e6xxx_chip *chip) 253 { 254 u16 val; 255 int err; 256 257 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val); 258 if (err) 259 return err; 260 261 val |= MV88E6XXX_G1_CTL1_PPU_ENABLE; 262 263 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val); 264 if (err) 265 return err; 266 267 return mv88e6185_g1_wait_ppu_polling(chip); 268 } 269 270 int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip *chip) 271 { 272 u16 val; 273 int err; 274 275 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val); 276 if (err) 277 return err; 278 279 val &= ~MV88E6XXX_G1_CTL1_PPU_ENABLE; 280 281 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val); 282 if (err) 283 return err; 284 285 return mv88e6185_g1_wait_ppu_disabled(chip); 286 } 287 288 int mv88e6185_g1_set_max_frame_size(struct mv88e6xxx_chip *chip, int mtu) 289 { 290 u16 val; 291 int err; 292 293 mtu += ETH_HLEN + ETH_FCS_LEN; 294 295 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val); 296 if (err) 297 return err; 298 299 val &= ~MV88E6185_G1_CTL1_MAX_FRAME_1632; 300 301 if (mtu > 1518) 302 val |= MV88E6185_G1_CTL1_MAX_FRAME_1632; 303 304 return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val); 305 } 306 307 /* Offset 0x10: IP-PRI Mapping Register 0 308 * Offset 0x11: IP-PRI Mapping Register 1 309 * Offset 0x12: IP-PRI Mapping Register 2 310 * Offset 0x13: IP-PRI Mapping Register 3 311 * Offset 0x14: IP-PRI Mapping Register 4 312 * Offset 0x15: IP-PRI Mapping Register 5 313 * Offset 0x16: IP-PRI Mapping Register 6 314 * Offset 0x17: IP-PRI Mapping Register 7 315 */ 316 317 int mv88e6085_g1_ip_pri_map(struct mv88e6xxx_chip *chip) 318 { 319 int err; 320 321 /* Reset the IP TOS/DiffServ/Traffic priorities to defaults */ 322 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_0, 0x0000); 323 if (err) 324 return err; 325 326 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_1, 0x0000); 327 if (err) 328 return err; 329 330 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_2, 0x5555); 331 if (err) 332 return err; 333 334 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_3, 0x5555); 335 if (err) 336 return err; 337 338 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_4, 0xaaaa); 339 if (err) 340 return err; 341 342 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_5, 0xaaaa); 343 if (err) 344 return err; 345 346 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_6, 0xffff); 347 if (err) 348 return err; 349 350 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_7, 0xffff); 351 if (err) 352 return err; 353 354 return 0; 355 } 356 357 /* Offset 0x18: IEEE-PRI Register */ 358 359 int mv88e6085_g1_ieee_pri_map(struct mv88e6xxx_chip *chip) 360 { 361 /* Reset the IEEE Tag priorities to defaults */ 362 return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IEEE_PRI, 0xfa41); 363 } 364 365 int mv88e6250_g1_ieee_pri_map(struct mv88e6xxx_chip *chip) 366 { 367 /* Reset the IEEE Tag priorities to defaults */ 368 return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IEEE_PRI, 0xfa50); 369 } 370 371 /* Offset 0x1a: Monitor Control */ 372 /* Offset 0x1a: Monitor & MGMT Control on some devices */ 373 374 int mv88e6095_g1_set_egress_port(struct mv88e6xxx_chip *chip, 375 enum mv88e6xxx_egress_direction direction, 376 int port) 377 { 378 u16 reg; 379 int err; 380 381 err = mv88e6xxx_g1_read(chip, MV88E6185_G1_MONITOR_CTL, ®); 382 if (err) 383 return err; 384 385 switch (direction) { 386 case MV88E6XXX_EGRESS_DIR_INGRESS: 387 reg &= ~MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK; 388 reg |= port << 389 __bf_shf(MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK); 390 break; 391 case MV88E6XXX_EGRESS_DIR_EGRESS: 392 reg &= ~MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK; 393 reg |= port << 394 __bf_shf(MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK); 395 break; 396 default: 397 return -EINVAL; 398 } 399 400 return mv88e6xxx_g1_write(chip, MV88E6185_G1_MONITOR_CTL, reg); 401 } 402 403 /* Older generations also call this the ARP destination. It has been 404 * generalized in more modern devices such that more than ARP can 405 * egress it 406 */ 407 int mv88e6095_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port) 408 { 409 u16 reg; 410 int err; 411 412 err = mv88e6xxx_g1_read(chip, MV88E6185_G1_MONITOR_CTL, ®); 413 if (err) 414 return err; 415 416 reg &= ~MV88E6185_G1_MONITOR_CTL_ARP_DEST_MASK; 417 reg |= port << __bf_shf(MV88E6185_G1_MONITOR_CTL_ARP_DEST_MASK); 418 419 return mv88e6xxx_g1_write(chip, MV88E6185_G1_MONITOR_CTL, reg); 420 } 421 422 static int mv88e6390_g1_monitor_write(struct mv88e6xxx_chip *chip, 423 u16 pointer, u8 data) 424 { 425 u16 reg; 426 427 reg = MV88E6390_G1_MONITOR_MGMT_CTL_UPDATE | pointer | data; 428 429 return mv88e6xxx_g1_write(chip, MV88E6390_G1_MONITOR_MGMT_CTL, reg); 430 } 431 432 int mv88e6390_g1_set_egress_port(struct mv88e6xxx_chip *chip, 433 enum mv88e6xxx_egress_direction direction, 434 int port) 435 { 436 u16 ptr; 437 438 switch (direction) { 439 case MV88E6XXX_EGRESS_DIR_INGRESS: 440 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_INGRESS_DEST; 441 break; 442 case MV88E6XXX_EGRESS_DIR_EGRESS: 443 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_EGRESS_DEST; 444 break; 445 default: 446 return -EINVAL; 447 } 448 449 return mv88e6390_g1_monitor_write(chip, ptr, port); 450 } 451 452 int mv88e6390_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port) 453 { 454 u16 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST; 455 456 /* Use the default high priority for management frames sent to 457 * the CPU. 458 */ 459 port |= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST_MGMTPRI; 460 461 return mv88e6390_g1_monitor_write(chip, ptr, port); 462 } 463 464 int mv88e6390_g1_set_ptp_cpu_port(struct mv88e6xxx_chip *chip, int port) 465 { 466 u16 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_PTP_CPU_DEST; 467 468 /* Use the default high priority for PTP frames sent to 469 * the CPU. 470 */ 471 port |= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST_MGMTPRI; 472 473 return mv88e6390_g1_monitor_write(chip, ptr, port); 474 } 475 476 int mv88e6390_g1_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip) 477 { 478 u16 ptr; 479 int err; 480 481 /* 01:80:c2:00:00:00-01:80:c2:00:00:07 are Management */ 482 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C200000XLO; 483 err = mv88e6390_g1_monitor_write(chip, ptr, 0xff); 484 if (err) 485 return err; 486 487 /* 01:80:c2:00:00:08-01:80:c2:00:00:0f are Management */ 488 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C200000XHI; 489 err = mv88e6390_g1_monitor_write(chip, ptr, 0xff); 490 if (err) 491 return err; 492 493 /* 01:80:c2:00:00:20-01:80:c2:00:00:27 are Management */ 494 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C200002XLO; 495 err = mv88e6390_g1_monitor_write(chip, ptr, 0xff); 496 if (err) 497 return err; 498 499 /* 01:80:c2:00:00:28-01:80:c2:00:00:2f are Management */ 500 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C200002XHI; 501 err = mv88e6390_g1_monitor_write(chip, ptr, 0xff); 502 if (err) 503 return err; 504 505 return 0; 506 } 507 508 /* Offset 0x1c: Global Control 2 */ 509 510 static int mv88e6xxx_g1_ctl2_mask(struct mv88e6xxx_chip *chip, u16 mask, 511 u16 val) 512 { 513 u16 reg; 514 int err; 515 516 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL2, ®); 517 if (err) 518 return err; 519 520 reg &= ~mask; 521 reg |= val & mask; 522 523 return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL2, reg); 524 } 525 526 int mv88e6185_g1_set_cascade_port(struct mv88e6xxx_chip *chip, int port) 527 { 528 const u16 mask = MV88E6185_G1_CTL2_CASCADE_PORT_MASK; 529 530 return mv88e6xxx_g1_ctl2_mask(chip, mask, port << __bf_shf(mask)); 531 } 532 533 int mv88e6085_g1_rmu_disable(struct mv88e6xxx_chip *chip) 534 { 535 return mv88e6xxx_g1_ctl2_mask(chip, MV88E6085_G1_CTL2_P10RM | 536 MV88E6085_G1_CTL2_RM_ENABLE, 0); 537 } 538 539 int mv88e6352_g1_rmu_disable(struct mv88e6xxx_chip *chip) 540 { 541 return mv88e6xxx_g1_ctl2_mask(chip, MV88E6352_G1_CTL2_RMU_MODE_MASK, 542 MV88E6352_G1_CTL2_RMU_MODE_DISABLED); 543 } 544 545 int mv88e6390_g1_rmu_disable(struct mv88e6xxx_chip *chip) 546 { 547 return mv88e6xxx_g1_ctl2_mask(chip, MV88E6390_G1_CTL2_RMU_MODE_MASK, 548 MV88E6390_G1_CTL2_RMU_MODE_DISABLED); 549 } 550 551 int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip *chip) 552 { 553 return mv88e6xxx_g1_ctl2_mask(chip, MV88E6390_G1_CTL2_HIST_MODE_MASK, 554 MV88E6390_G1_CTL2_HIST_MODE_RX); 555 } 556 557 int mv88e6xxx_g1_set_device_number(struct mv88e6xxx_chip *chip, int index) 558 { 559 return mv88e6xxx_g1_ctl2_mask(chip, 560 MV88E6XXX_G1_CTL2_DEVICE_NUMBER_MASK, 561 index); 562 } 563 564 /* Offset 0x1d: Statistics Operation 2 */ 565 566 static int mv88e6xxx_g1_stats_wait(struct mv88e6xxx_chip *chip) 567 { 568 int bit = __bf_shf(MV88E6XXX_G1_STATS_OP_BUSY); 569 570 return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STATS_OP, bit, 0); 571 } 572 573 int mv88e6095_g1_stats_set_histogram(struct mv88e6xxx_chip *chip) 574 { 575 u16 val; 576 int err; 577 578 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STATS_OP, &val); 579 if (err) 580 return err; 581 582 val |= MV88E6XXX_G1_STATS_OP_HIST_RX; 583 584 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP, val); 585 586 return err; 587 } 588 589 int mv88e6xxx_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port) 590 { 591 int err; 592 593 /* Snapshot the hardware statistics counters for this port. */ 594 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP, 595 MV88E6XXX_G1_STATS_OP_BUSY | 596 MV88E6XXX_G1_STATS_OP_CAPTURE_PORT | 597 MV88E6XXX_G1_STATS_OP_HIST_RX | port); 598 if (err) 599 return err; 600 601 /* Wait for the snapshotting to complete. */ 602 return mv88e6xxx_g1_stats_wait(chip); 603 } 604 605 int mv88e6320_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port) 606 { 607 port = (port + 1) << 5; 608 609 return mv88e6xxx_g1_stats_snapshot(chip, port); 610 } 611 612 int mv88e6390_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port) 613 { 614 int err; 615 616 port = (port + 1) << 5; 617 618 /* Snapshot the hardware statistics counters for this port. */ 619 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP, 620 MV88E6XXX_G1_STATS_OP_BUSY | 621 MV88E6XXX_G1_STATS_OP_CAPTURE_PORT | port); 622 if (err) 623 return err; 624 625 /* Wait for the snapshotting to complete. */ 626 return mv88e6xxx_g1_stats_wait(chip); 627 } 628 629 void mv88e6xxx_g1_stats_read(struct mv88e6xxx_chip *chip, int stat, u32 *val) 630 { 631 u32 value; 632 u16 reg; 633 int err; 634 635 *val = 0; 636 637 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP, 638 MV88E6XXX_G1_STATS_OP_BUSY | 639 MV88E6XXX_G1_STATS_OP_READ_CAPTURED | stat); 640 if (err) 641 return; 642 643 err = mv88e6xxx_g1_stats_wait(chip); 644 if (err) 645 return; 646 647 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STATS_COUNTER_32, ®); 648 if (err) 649 return; 650 651 value = reg << 16; 652 653 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STATS_COUNTER_01, ®); 654 if (err) 655 return; 656 657 *val = value | reg; 658 } 659 660 int mv88e6xxx_g1_stats_clear(struct mv88e6xxx_chip *chip) 661 { 662 int err; 663 u16 val; 664 665 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STATS_OP, &val); 666 if (err) 667 return err; 668 669 /* Keep the histogram mode bits */ 670 val &= MV88E6XXX_G1_STATS_OP_HIST_RX_TX; 671 val |= MV88E6XXX_G1_STATS_OP_BUSY | MV88E6XXX_G1_STATS_OP_FLUSH_ALL; 672 673 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP, val); 674 if (err) 675 return err; 676 677 /* Wait for the flush to complete. */ 678 return mv88e6xxx_g1_stats_wait(chip); 679 } 680