linux/drivers/net/dsa/mv88e6xxx/global2.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Marvell 88E6xxx Switch Global 2 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#include <linux/interrupt.h>
  13#include <linux/irqdomain.h>
  14
  15#include "chip.h"
  16#include "global1.h" /* for MV88E6XXX_G1_STS_IRQ_DEVICE */
  17#include "global2.h"
  18
  19int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val)
  20{
  21        return mv88e6xxx_read(chip, chip->info->global2_addr, reg, val);
  22}
  23
  24int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
  25{
  26        return mv88e6xxx_write(chip, chip->info->global2_addr, reg, val);
  27}
  28
  29int mv88e6xxx_g2_wait_bit(struct mv88e6xxx_chip *chip, int reg, int
  30                          bit, int val)
  31{
  32        return mv88e6xxx_wait_bit(chip, chip->info->global2_addr, reg,
  33                                  bit, val);
  34}
  35
  36/* Offset 0x00: Interrupt Source Register */
  37
  38static int mv88e6xxx_g2_int_source(struct mv88e6xxx_chip *chip, u16 *src)
  39{
  40        /* Read (and clear most of) the Interrupt Source bits */
  41        return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_INT_SRC, src);
  42}
  43
  44/* Offset 0x01: Interrupt Mask Register */
  45
  46static int mv88e6xxx_g2_int_mask(struct mv88e6xxx_chip *chip, u16 mask)
  47{
  48        return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_INT_MASK, mask);
  49}
  50
  51/* Offset 0x02: Management Enable 2x */
  52
  53static int mv88e6xxx_g2_mgmt_enable_2x(struct mv88e6xxx_chip *chip, u16 en2x)
  54{
  55        return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MGMT_EN_2X, en2x);
  56}
  57
  58/* Offset 0x03: Management Enable 0x */
  59
  60static int mv88e6xxx_g2_mgmt_enable_0x(struct mv88e6xxx_chip *chip, u16 en0x)
  61{
  62        return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MGMT_EN_0X, en0x);
  63}
  64
  65/* Offset 0x05: Switch Management Register */
  66
  67static int mv88e6xxx_g2_switch_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip,
  68                                             bool enable)
  69{
  70        u16 val;
  71        int err;
  72
  73        err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SWITCH_MGMT, &val);
  74        if (err)
  75                return err;
  76
  77        if (enable)
  78                val |= MV88E6XXX_G2_SWITCH_MGMT_RSVD2CPU;
  79        else
  80                val &= ~MV88E6XXX_G2_SWITCH_MGMT_RSVD2CPU;
  81
  82        return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SWITCH_MGMT, val);
  83}
  84
  85int mv88e6185_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
  86{
  87        int err;
  88
  89        /* Consider the frames with reserved multicast destination
  90         * addresses matching 01:80:c2:00:00:0x as MGMT.
  91         */
  92        err = mv88e6xxx_g2_mgmt_enable_0x(chip, 0xffff);
  93        if (err)
  94                return err;
  95
  96        return mv88e6xxx_g2_switch_mgmt_rsvd2cpu(chip, true);
  97}
  98
  99int mv88e6352_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
 100{
 101        int err;
 102
 103        /* Consider the frames with reserved multicast destination
 104         * addresses matching 01:80:c2:00:00:2x as MGMT.
 105         */
 106        err = mv88e6xxx_g2_mgmt_enable_2x(chip, 0xffff);
 107        if (err)
 108                return err;
 109
 110        return mv88e6185_g2_mgmt_rsvd2cpu(chip);
 111}
 112
 113/* Offset 0x06: Device Mapping Table register */
 114
 115int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, int target,
 116                                      int port)
 117{
 118        u16 val = (target << 8) | (port & 0x1f);
 119        /* Modern chips use 5 bits to define a device mapping port,
 120         * but bit 4 is reserved on older chips, so it is safe to use.
 121         */
 122
 123        return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_DEVICE_MAPPING,
 124                                  MV88E6XXX_G2_DEVICE_MAPPING_UPDATE | val);
 125}
 126
 127/* Offset 0x07: Trunk Mask Table register */
 128
 129static int mv88e6xxx_g2_trunk_mask_write(struct mv88e6xxx_chip *chip, int num,
 130                                         bool hash, u16 mask)
 131{
 132        u16 val = (num << 12) | (mask & mv88e6xxx_port_mask(chip));
 133
 134        if (hash)
 135                val |= MV88E6XXX_G2_TRUNK_MASK_HASH;
 136
 137        return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_TRUNK_MASK,
 138                                  MV88E6XXX_G2_TRUNK_MASK_UPDATE | val);
 139}
 140
 141/* Offset 0x08: Trunk Mapping Table register */
 142
 143static int mv88e6xxx_g2_trunk_mapping_write(struct mv88e6xxx_chip *chip, int id,
 144                                            u16 map)
 145{
 146        const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1;
 147        u16 val = (id << 11) | (map & port_mask);
 148
 149        return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_TRUNK_MAPPING,
 150                                  MV88E6XXX_G2_TRUNK_MAPPING_UPDATE | val);
 151}
 152
 153int mv88e6xxx_g2_trunk_clear(struct mv88e6xxx_chip *chip)
 154{
 155        const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1;
 156        int i, err;
 157
 158        /* Clear all eight possible Trunk Mask vectors */
 159        for (i = 0; i < 8; ++i) {
 160                err = mv88e6xxx_g2_trunk_mask_write(chip, i, false, port_mask);
 161                if (err)
 162                        return err;
 163        }
 164
 165        /* Clear all sixteen possible Trunk ID routing vectors */
 166        for (i = 0; i < 16; ++i) {
 167                err = mv88e6xxx_g2_trunk_mapping_write(chip, i, 0);
 168                if (err)
 169                        return err;
 170        }
 171
 172        return 0;
 173}
 174
 175/* Offset 0x09: Ingress Rate Command register
 176 * Offset 0x0A: Ingress Rate Data register
 177 */
 178
 179static int mv88e6xxx_g2_irl_wait(struct mv88e6xxx_chip *chip)
 180{
 181        int bit = __bf_shf(MV88E6XXX_G2_IRL_CMD_BUSY);
 182
 183        return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_IRL_CMD, bit, 0);
 184}
 185
 186static int mv88e6xxx_g2_irl_op(struct mv88e6xxx_chip *chip, u16 op, int port,
 187                               int res, int reg)
 188{
 189        int err;
 190
 191        err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_IRL_CMD,
 192                                 MV88E6XXX_G2_IRL_CMD_BUSY | op | (port << 8) |
 193                                 (res << 5) | reg);
 194        if (err)
 195                return err;
 196
 197        return mv88e6xxx_g2_irl_wait(chip);
 198}
 199
 200int mv88e6352_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port)
 201{
 202        return mv88e6xxx_g2_irl_op(chip, MV88E6352_G2_IRL_CMD_OP_INIT_ALL, port,
 203                                   0, 0);
 204}
 205
 206int mv88e6390_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port)
 207{
 208        return mv88e6xxx_g2_irl_op(chip, MV88E6390_G2_IRL_CMD_OP_INIT_ALL, port,
 209                                   0, 0);
 210}
 211
 212/* Offset 0x0B: Cross-chip Port VLAN (Addr) Register
 213 * Offset 0x0C: Cross-chip Port VLAN Data Register
 214 */
 215
 216static int mv88e6xxx_g2_pvt_op_wait(struct mv88e6xxx_chip *chip)
 217{
 218        int bit = __bf_shf(MV88E6XXX_G2_PVT_ADDR_BUSY);
 219
 220        return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_PVT_ADDR, bit, 0);
 221}
 222
 223static int mv88e6xxx_g2_pvt_op(struct mv88e6xxx_chip *chip, int src_dev,
 224                               int src_port, u16 op)
 225{
 226        int err;
 227
 228        /* 9-bit Cross-chip PVT pointer: with MV88E6XXX_G2_MISC_5_BIT_PORT
 229         * cleared, source device is 5-bit, source port is 4-bit.
 230         */
 231        op |= MV88E6XXX_G2_PVT_ADDR_BUSY;
 232        op |= (src_dev & 0x1f) << 4;
 233        op |= (src_port & 0xf);
 234
 235        err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_PVT_ADDR, op);
 236        if (err)
 237                return err;
 238
 239        return mv88e6xxx_g2_pvt_op_wait(chip);
 240}
 241
 242int mv88e6xxx_g2_pvt_write(struct mv88e6xxx_chip *chip, int src_dev,
 243                           int src_port, u16 data)
 244{
 245        int err;
 246
 247        err = mv88e6xxx_g2_pvt_op_wait(chip);
 248        if (err)
 249                return err;
 250
 251        err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_PVT_DATA, data);
 252        if (err)
 253                return err;
 254
 255        return mv88e6xxx_g2_pvt_op(chip, src_dev, src_port,
 256                                   MV88E6XXX_G2_PVT_ADDR_OP_WRITE_PVLAN);
 257}
 258
 259/* Offset 0x0D: Switch MAC/WoL/WoF register */
 260
 261static int mv88e6xxx_g2_switch_mac_write(struct mv88e6xxx_chip *chip,
 262                                         unsigned int pointer, u8 data)
 263{
 264        u16 val = (pointer << 8) | data;
 265
 266        return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SWITCH_MAC,
 267                                  MV88E6XXX_G2_SWITCH_MAC_UPDATE | val);
 268}
 269
 270int mv88e6xxx_g2_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr)
 271{
 272        int i, err;
 273
 274        for (i = 0; i < 6; i++) {
 275                err = mv88e6xxx_g2_switch_mac_write(chip, i, addr[i]);
 276                if (err)
 277                        break;
 278        }
 279
 280        return err;
 281}
 282
 283/* Offset 0x0E: ATU Statistics */
 284
 285int mv88e6xxx_g2_atu_stats_set(struct mv88e6xxx_chip *chip, u16 kind, u16 bin)
 286{
 287        return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_ATU_STATS,
 288                                  kind | bin);
 289}
 290
 291int mv88e6xxx_g2_atu_stats_get(struct mv88e6xxx_chip *chip, u16 *stats)
 292{
 293        return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_ATU_STATS, stats);
 294}
 295
 296/* Offset 0x0F: Priority Override Table */
 297
 298static int mv88e6xxx_g2_pot_write(struct mv88e6xxx_chip *chip, int pointer,
 299                                  u8 data)
 300{
 301        u16 val = (pointer << 8) | (data & 0x7);
 302
 303        return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_PRIO_OVERRIDE,
 304                                  MV88E6XXX_G2_PRIO_OVERRIDE_UPDATE | val);
 305}
 306
 307int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip)
 308{
 309        int i, err;
 310
 311        /* Clear all sixteen possible Priority Override entries */
 312        for (i = 0; i < 16; i++) {
 313                err = mv88e6xxx_g2_pot_write(chip, i, 0);
 314                if (err)
 315                        break;
 316        }
 317
 318        return err;
 319}
 320
 321/* Offset 0x14: EEPROM Command
 322 * Offset 0x15: EEPROM Data (for 16-bit data access)
 323 * Offset 0x15: EEPROM Addr (for 8-bit data access)
 324 */
 325
 326static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip)
 327{
 328        int bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_BUSY);
 329        int err;
 330
 331        err = mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_EEPROM_CMD, bit, 0);
 332        if (err)
 333                return err;
 334
 335        bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_RUNNING);
 336
 337        return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_EEPROM_CMD, bit, 0);
 338}
 339
 340static int mv88e6xxx_g2_eeprom_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
 341{
 342        int err;
 343
 344        err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_EEPROM_CMD,
 345                                 MV88E6XXX_G2_EEPROM_CMD_BUSY | cmd);
 346        if (err)
 347                return err;
 348
 349        return mv88e6xxx_g2_eeprom_wait(chip);
 350}
 351
 352static int mv88e6xxx_g2_eeprom_read8(struct mv88e6xxx_chip *chip,
 353                                     u16 addr, u8 *data)
 354{
 355        u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_READ;
 356        int err;
 357
 358        err = mv88e6xxx_g2_eeprom_wait(chip);
 359        if (err)
 360                return err;
 361
 362        err = mv88e6xxx_g2_write(chip, MV88E6390_G2_EEPROM_ADDR, addr);
 363        if (err)
 364                return err;
 365
 366        err = mv88e6xxx_g2_eeprom_cmd(chip, cmd);
 367        if (err)
 368                return err;
 369
 370        err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_EEPROM_CMD, &cmd);
 371        if (err)
 372                return err;
 373
 374        *data = cmd & 0xff;
 375
 376        return 0;
 377}
 378
 379static int mv88e6xxx_g2_eeprom_write8(struct mv88e6xxx_chip *chip,
 380                                      u16 addr, u8 data)
 381{
 382        u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_WRITE |
 383                MV88E6XXX_G2_EEPROM_CMD_WRITE_EN;
 384        int err;
 385
 386        err = mv88e6xxx_g2_eeprom_wait(chip);
 387        if (err)
 388                return err;
 389
 390        err = mv88e6xxx_g2_write(chip, MV88E6390_G2_EEPROM_ADDR, addr);
 391        if (err)
 392                return err;
 393
 394        return mv88e6xxx_g2_eeprom_cmd(chip, cmd | data);
 395}
 396
 397static int mv88e6xxx_g2_eeprom_read16(struct mv88e6xxx_chip *chip,
 398                                      u8 addr, u16 *data)
 399{
 400        u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_READ | addr;
 401        int err;
 402
 403        err = mv88e6xxx_g2_eeprom_wait(chip);
 404        if (err)
 405                return err;
 406
 407        err = mv88e6xxx_g2_eeprom_cmd(chip, cmd);
 408        if (err)
 409                return err;
 410
 411        return mv88e6xxx_g2_read(chip, MV88E6352_G2_EEPROM_DATA, data);
 412}
 413
 414static int mv88e6xxx_g2_eeprom_write16(struct mv88e6xxx_chip *chip,
 415                                       u8 addr, u16 data)
 416{
 417        u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_WRITE | addr;
 418        int err;
 419
 420        err = mv88e6xxx_g2_eeprom_wait(chip);
 421        if (err)
 422                return err;
 423
 424        err = mv88e6xxx_g2_write(chip, MV88E6352_G2_EEPROM_DATA, data);
 425        if (err)
 426                return err;
 427
 428        return mv88e6xxx_g2_eeprom_cmd(chip, cmd);
 429}
 430
 431int mv88e6xxx_g2_get_eeprom8(struct mv88e6xxx_chip *chip,
 432                             struct ethtool_eeprom *eeprom, u8 *data)
 433{
 434        unsigned int offset = eeprom->offset;
 435        unsigned int len = eeprom->len;
 436        int err;
 437
 438        eeprom->len = 0;
 439
 440        while (len) {
 441                err = mv88e6xxx_g2_eeprom_read8(chip, offset, data);
 442                if (err)
 443                        return err;
 444
 445                eeprom->len++;
 446                offset++;
 447                data++;
 448                len--;
 449        }
 450
 451        return 0;
 452}
 453
 454int mv88e6xxx_g2_set_eeprom8(struct mv88e6xxx_chip *chip,
 455                             struct ethtool_eeprom *eeprom, u8 *data)
 456{
 457        unsigned int offset = eeprom->offset;
 458        unsigned int len = eeprom->len;
 459        int err;
 460
 461        eeprom->len = 0;
 462
 463        while (len) {
 464                err = mv88e6xxx_g2_eeprom_write8(chip, offset, *data);
 465                if (err)
 466                        return err;
 467
 468                eeprom->len++;
 469                offset++;
 470                data++;
 471                len--;
 472        }
 473
 474        return 0;
 475}
 476
 477int mv88e6xxx_g2_get_eeprom16(struct mv88e6xxx_chip *chip,
 478                              struct ethtool_eeprom *eeprom, u8 *data)
 479{
 480        unsigned int offset = eeprom->offset;
 481        unsigned int len = eeprom->len;
 482        u16 val;
 483        int err;
 484
 485        eeprom->len = 0;
 486
 487        if (offset & 1) {
 488                err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
 489                if (err)
 490                        return err;
 491
 492                *data++ = (val >> 8) & 0xff;
 493
 494                offset++;
 495                len--;
 496                eeprom->len++;
 497        }
 498
 499        while (len >= 2) {
 500                err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
 501                if (err)
 502                        return err;
 503
 504                *data++ = val & 0xff;
 505                *data++ = (val >> 8) & 0xff;
 506
 507                offset += 2;
 508                len -= 2;
 509                eeprom->len += 2;
 510        }
 511
 512        if (len) {
 513                err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
 514                if (err)
 515                        return err;
 516
 517                *data++ = val & 0xff;
 518
 519                offset++;
 520                len--;
 521                eeprom->len++;
 522        }
 523
 524        return 0;
 525}
 526
 527int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip,
 528                              struct ethtool_eeprom *eeprom, u8 *data)
 529{
 530        unsigned int offset = eeprom->offset;
 531        unsigned int len = eeprom->len;
 532        u16 val;
 533        int err;
 534
 535        /* Ensure the RO WriteEn bit is set */
 536        err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_EEPROM_CMD, &val);
 537        if (err)
 538                return err;
 539
 540        if (!(val & MV88E6XXX_G2_EEPROM_CMD_WRITE_EN))
 541                return -EROFS;
 542
 543        eeprom->len = 0;
 544
 545        if (offset & 1) {
 546                err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
 547                if (err)
 548                        return err;
 549
 550                val = (*data++ << 8) | (val & 0xff);
 551
 552                err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
 553                if (err)
 554                        return err;
 555
 556                offset++;
 557                len--;
 558                eeprom->len++;
 559        }
 560
 561        while (len >= 2) {
 562                val = *data++;
 563                val |= *data++ << 8;
 564
 565                err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
 566                if (err)
 567                        return err;
 568
 569                offset += 2;
 570                len -= 2;
 571                eeprom->len += 2;
 572        }
 573
 574        if (len) {
 575                err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
 576                if (err)
 577                        return err;
 578
 579                val = (val & 0xff00) | *data++;
 580
 581                err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
 582                if (err)
 583                        return err;
 584
 585                offset++;
 586                len--;
 587                eeprom->len++;
 588        }
 589
 590        return 0;
 591}
 592
 593/* Offset 0x18: SMI PHY Command Register
 594 * Offset 0x19: SMI PHY Data Register
 595 */
 596
 597static int mv88e6xxx_g2_smi_phy_wait(struct mv88e6xxx_chip *chip)
 598{
 599        int bit = __bf_shf(MV88E6XXX_G2_SMI_PHY_CMD_BUSY);
 600
 601        return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_SMI_PHY_CMD, bit, 0);
 602}
 603
 604static int mv88e6xxx_g2_smi_phy_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
 605{
 606        int err;
 607
 608        err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_CMD,
 609                                 MV88E6XXX_G2_SMI_PHY_CMD_BUSY | cmd);
 610        if (err)
 611                return err;
 612
 613        return mv88e6xxx_g2_smi_phy_wait(chip);
 614}
 615
 616static int mv88e6xxx_g2_smi_phy_access(struct mv88e6xxx_chip *chip,
 617                                       bool external, bool c45, u16 op, int dev,
 618                                       int reg)
 619{
 620        u16 cmd = op;
 621
 622        if (external)
 623                cmd |= MV88E6390_G2_SMI_PHY_CMD_FUNC_EXTERNAL;
 624        else
 625                cmd |= MV88E6390_G2_SMI_PHY_CMD_FUNC_INTERNAL; /* empty mask */
 626
 627        if (c45)
 628                cmd |= MV88E6XXX_G2_SMI_PHY_CMD_MODE_45; /* empty mask */
 629        else
 630                cmd |= MV88E6XXX_G2_SMI_PHY_CMD_MODE_22;
 631
 632        dev <<= __bf_shf(MV88E6XXX_G2_SMI_PHY_CMD_DEV_ADDR_MASK);
 633        cmd |= dev & MV88E6XXX_G2_SMI_PHY_CMD_DEV_ADDR_MASK;
 634        cmd |= reg & MV88E6XXX_G2_SMI_PHY_CMD_REG_ADDR_MASK;
 635
 636        return mv88e6xxx_g2_smi_phy_cmd(chip, cmd);
 637}
 638
 639static int mv88e6xxx_g2_smi_phy_access_c22(struct mv88e6xxx_chip *chip,
 640                                           bool external, u16 op, int dev,
 641                                           int reg)
 642{
 643        return mv88e6xxx_g2_smi_phy_access(chip, external, false, op, dev, reg);
 644}
 645
 646/* IEEE 802.3 Clause 22 Read Data Register */
 647static int mv88e6xxx_g2_smi_phy_read_data_c22(struct mv88e6xxx_chip *chip,
 648                                              bool external, int dev, int reg,
 649                                              u16 *data)
 650{
 651        u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_22_READ_DATA;
 652        int err;
 653
 654        err = mv88e6xxx_g2_smi_phy_wait(chip);
 655        if (err)
 656                return err;
 657
 658        err = mv88e6xxx_g2_smi_phy_access_c22(chip, external, op, dev, reg);
 659        if (err)
 660                return err;
 661
 662        return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
 663}
 664
 665/* IEEE 802.3 Clause 22 Write Data Register */
 666static int mv88e6xxx_g2_smi_phy_write_data_c22(struct mv88e6xxx_chip *chip,
 667                                               bool external, int dev, int reg,
 668                                               u16 data)
 669{
 670        u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_22_WRITE_DATA;
 671        int err;
 672
 673        err = mv88e6xxx_g2_smi_phy_wait(chip);
 674        if (err)
 675                return err;
 676
 677        err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
 678        if (err)
 679                return err;
 680
 681        return mv88e6xxx_g2_smi_phy_access_c22(chip, external, op, dev, reg);
 682}
 683
 684static int mv88e6xxx_g2_smi_phy_access_c45(struct mv88e6xxx_chip *chip,
 685                                           bool external, u16 op, int port,
 686                                           int dev)
 687{
 688        return mv88e6xxx_g2_smi_phy_access(chip, external, true, op, port, dev);
 689}
 690
 691/* IEEE 802.3 Clause 45 Write Address Register */
 692static int mv88e6xxx_g2_smi_phy_write_addr_c45(struct mv88e6xxx_chip *chip,
 693                                               bool external, int port, int dev,
 694                                               int addr)
 695{
 696        u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_WRITE_ADDR;
 697        int err;
 698
 699        err = mv88e6xxx_g2_smi_phy_wait(chip);
 700        if (err)
 701                return err;
 702
 703        err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, addr);
 704        if (err)
 705                return err;
 706
 707        return mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
 708}
 709
 710/* IEEE 802.3 Clause 45 Read Data Register */
 711static int mv88e6xxx_g2_smi_phy_read_data_c45(struct mv88e6xxx_chip *chip,
 712                                              bool external, int port, int dev,
 713                                              u16 *data)
 714{
 715        u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_READ_DATA;
 716        int err;
 717
 718        err = mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
 719        if (err)
 720                return err;
 721
 722        return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
 723}
 724
 725static int mv88e6xxx_g2_smi_phy_read_c45(struct mv88e6xxx_chip *chip,
 726                                         bool external, int port, int reg,
 727                                         u16 *data)
 728{
 729        int dev = (reg >> 16) & 0x1f;
 730        int addr = reg & 0xffff;
 731        int err;
 732
 733        err = mv88e6xxx_g2_smi_phy_write_addr_c45(chip, external, port, dev,
 734                                                  addr);
 735        if (err)
 736                return err;
 737
 738        return mv88e6xxx_g2_smi_phy_read_data_c45(chip, external, port, dev,
 739                                                  data);
 740}
 741
 742/* IEEE 802.3 Clause 45 Write Data Register */
 743static int mv88e6xxx_g2_smi_phy_write_data_c45(struct mv88e6xxx_chip *chip,
 744                                               bool external, int port, int dev,
 745                                               u16 data)
 746{
 747        u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_WRITE_DATA;
 748        int err;
 749
 750        err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
 751        if (err)
 752                return err;
 753
 754        return mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
 755}
 756
 757static int mv88e6xxx_g2_smi_phy_write_c45(struct mv88e6xxx_chip *chip,
 758                                          bool external, int port, int reg,
 759                                          u16 data)
 760{
 761        int dev = (reg >> 16) & 0x1f;
 762        int addr = reg & 0xffff;
 763        int err;
 764
 765        err = mv88e6xxx_g2_smi_phy_write_addr_c45(chip, external, port, dev,
 766                                                  addr);
 767        if (err)
 768                return err;
 769
 770        return mv88e6xxx_g2_smi_phy_write_data_c45(chip, external, port, dev,
 771                                                   data);
 772}
 773
 774int mv88e6xxx_g2_smi_phy_read(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
 775                              int addr, int reg, u16 *val)
 776{
 777        struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
 778        bool external = mdio_bus->external;
 779
 780        if (reg & MII_ADDR_C45)
 781                return mv88e6xxx_g2_smi_phy_read_c45(chip, external, addr, reg,
 782                                                     val);
 783
 784        return mv88e6xxx_g2_smi_phy_read_data_c22(chip, external, addr, reg,
 785                                                  val);
 786}
 787
 788int mv88e6xxx_g2_smi_phy_write(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
 789                               int addr, int reg, u16 val)
 790{
 791        struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
 792        bool external = mdio_bus->external;
 793
 794        if (reg & MII_ADDR_C45)
 795                return mv88e6xxx_g2_smi_phy_write_c45(chip, external, addr, reg,
 796                                                      val);
 797
 798        return mv88e6xxx_g2_smi_phy_write_data_c22(chip, external, addr, reg,
 799                                                   val);
 800}
 801
 802/* Offset 0x1B: Watchdog Control */
 803static int mv88e6097_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
 804{
 805        u16 reg;
 806
 807        mv88e6xxx_g2_read(chip, MV88E6352_G2_WDOG_CTL, &reg);
 808
 809        dev_info(chip->dev, "Watchdog event: 0x%04x", reg);
 810
 811        return IRQ_HANDLED;
 812}
 813
 814static void mv88e6097_watchdog_free(struct mv88e6xxx_chip *chip)
 815{
 816        u16 reg;
 817
 818        mv88e6xxx_g2_read(chip, MV88E6352_G2_WDOG_CTL, &reg);
 819
 820        reg &= ~(MV88E6352_G2_WDOG_CTL_EGRESS_ENABLE |
 821                 MV88E6352_G2_WDOG_CTL_QC_ENABLE);
 822
 823        mv88e6xxx_g2_write(chip, MV88E6352_G2_WDOG_CTL, reg);
 824}
 825
 826static int mv88e6097_watchdog_setup(struct mv88e6xxx_chip *chip)
 827{
 828        return mv88e6xxx_g2_write(chip, MV88E6352_G2_WDOG_CTL,
 829                                  MV88E6352_G2_WDOG_CTL_EGRESS_ENABLE |
 830                                  MV88E6352_G2_WDOG_CTL_QC_ENABLE |
 831                                  MV88E6352_G2_WDOG_CTL_SWRESET);
 832}
 833
 834const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops = {
 835        .irq_action = mv88e6097_watchdog_action,
 836        .irq_setup = mv88e6097_watchdog_setup,
 837        .irq_free = mv88e6097_watchdog_free,
 838};
 839
 840static void mv88e6250_watchdog_free(struct mv88e6xxx_chip *chip)
 841{
 842        u16 reg;
 843
 844        mv88e6xxx_g2_read(chip, MV88E6250_G2_WDOG_CTL, &reg);
 845
 846        reg &= ~(MV88E6250_G2_WDOG_CTL_EGRESS_ENABLE |
 847                 MV88E6250_G2_WDOG_CTL_QC_ENABLE);
 848
 849        mv88e6xxx_g2_write(chip, MV88E6250_G2_WDOG_CTL, reg);
 850}
 851
 852static int mv88e6250_watchdog_setup(struct mv88e6xxx_chip *chip)
 853{
 854        return mv88e6xxx_g2_write(chip, MV88E6250_G2_WDOG_CTL,
 855                                  MV88E6250_G2_WDOG_CTL_EGRESS_ENABLE |
 856                                  MV88E6250_G2_WDOG_CTL_QC_ENABLE |
 857                                  MV88E6250_G2_WDOG_CTL_SWRESET);
 858}
 859
 860const struct mv88e6xxx_irq_ops mv88e6250_watchdog_ops = {
 861        .irq_action = mv88e6097_watchdog_action,
 862        .irq_setup = mv88e6250_watchdog_setup,
 863        .irq_free = mv88e6250_watchdog_free,
 864};
 865
 866static int mv88e6390_watchdog_setup(struct mv88e6xxx_chip *chip)
 867{
 868        return mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
 869                                  MV88E6390_G2_WDOG_CTL_UPDATE |
 870                                  MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE |
 871                                  MV88E6390_G2_WDOG_CTL_CUT_THROUGH |
 872                                  MV88E6390_G2_WDOG_CTL_QUEUE_CONTROLLER |
 873                                  MV88E6390_G2_WDOG_CTL_EGRESS |
 874                                  MV88E6390_G2_WDOG_CTL_FORCE_IRQ);
 875}
 876
 877static int mv88e6390_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
 878{
 879        u16 reg;
 880
 881        mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
 882                           MV88E6390_G2_WDOG_CTL_PTR_EVENT);
 883        mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, &reg);
 884
 885        dev_info(chip->dev, "Watchdog event: 0x%04x",
 886                 reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);
 887
 888        mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
 889                           MV88E6390_G2_WDOG_CTL_PTR_HISTORY);
 890        mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, &reg);
 891
 892        dev_info(chip->dev, "Watchdog history: 0x%04x",
 893                 reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);
 894
 895        /* Trigger a software reset to try to recover the switch */
 896        if (chip->info->ops->reset)
 897                chip->info->ops->reset(chip);
 898
 899        mv88e6390_watchdog_setup(chip);
 900
 901        return IRQ_HANDLED;
 902}
 903
 904static void mv88e6390_watchdog_free(struct mv88e6xxx_chip *chip)
 905{
 906        mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
 907                           MV88E6390_G2_WDOG_CTL_UPDATE |
 908                           MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE);
 909}
 910
 911const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops = {
 912        .irq_action = mv88e6390_watchdog_action,
 913        .irq_setup = mv88e6390_watchdog_setup,
 914        .irq_free = mv88e6390_watchdog_free,
 915};
 916
 917static irqreturn_t mv88e6xxx_g2_watchdog_thread_fn(int irq, void *dev_id)
 918{
 919        struct mv88e6xxx_chip *chip = dev_id;
 920        irqreturn_t ret = IRQ_NONE;
 921
 922        mv88e6xxx_reg_lock(chip);
 923        if (chip->info->ops->watchdog_ops->irq_action)
 924                ret = chip->info->ops->watchdog_ops->irq_action(chip, irq);
 925        mv88e6xxx_reg_unlock(chip);
 926
 927        return ret;
 928}
 929
 930static void mv88e6xxx_g2_watchdog_free(struct mv88e6xxx_chip *chip)
 931{
 932        mv88e6xxx_reg_lock(chip);
 933        if (chip->info->ops->watchdog_ops->irq_free)
 934                chip->info->ops->watchdog_ops->irq_free(chip);
 935        mv88e6xxx_reg_unlock(chip);
 936
 937        free_irq(chip->watchdog_irq, chip);
 938        irq_dispose_mapping(chip->watchdog_irq);
 939}
 940
 941static int mv88e6xxx_g2_watchdog_setup(struct mv88e6xxx_chip *chip)
 942{
 943        int err;
 944
 945        chip->watchdog_irq = irq_find_mapping(chip->g2_irq.domain,
 946                                              MV88E6XXX_G2_INT_SOURCE_WATCHDOG);
 947        if (chip->watchdog_irq < 0)
 948                return chip->watchdog_irq;
 949
 950        snprintf(chip->watchdog_irq_name, sizeof(chip->watchdog_irq_name),
 951                 "mv88e6xxx-%s-watchdog", dev_name(chip->dev));
 952
 953        err = request_threaded_irq(chip->watchdog_irq, NULL,
 954                                   mv88e6xxx_g2_watchdog_thread_fn,
 955                                   IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
 956                                   chip->watchdog_irq_name, chip);
 957        if (err)
 958                return err;
 959
 960        mv88e6xxx_reg_lock(chip);
 961        if (chip->info->ops->watchdog_ops->irq_setup)
 962                err = chip->info->ops->watchdog_ops->irq_setup(chip);
 963        mv88e6xxx_reg_unlock(chip);
 964
 965        return err;
 966}
 967
 968/* Offset 0x1D: Misc Register */
 969
 970static int mv88e6xxx_g2_misc_5_bit_port(struct mv88e6xxx_chip *chip,
 971                                        bool port_5_bit)
 972{
 973        u16 val;
 974        int err;
 975
 976        err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_MISC, &val);
 977        if (err)
 978                return err;
 979
 980        if (port_5_bit)
 981                val |= MV88E6XXX_G2_MISC_5_BIT_PORT;
 982        else
 983                val &= ~MV88E6XXX_G2_MISC_5_BIT_PORT;
 984
 985        return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MISC, val);
 986}
 987
 988int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip)
 989{
 990        return mv88e6xxx_g2_misc_5_bit_port(chip, false);
 991}
 992
 993static void mv88e6xxx_g2_irq_mask(struct irq_data *d)
 994{
 995        struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
 996        unsigned int n = d->hwirq;
 997
 998        chip->g2_irq.masked |= (1 << n);
 999}
1000
1001static void mv88e6xxx_g2_irq_unmask(struct irq_data *d)
1002{
1003        struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
1004        unsigned int n = d->hwirq;
1005
1006        chip->g2_irq.masked &= ~(1 << n);
1007}
1008
1009static irqreturn_t mv88e6xxx_g2_irq_thread_fn(int irq, void *dev_id)
1010{
1011        struct mv88e6xxx_chip *chip = dev_id;
1012        unsigned int nhandled = 0;
1013        unsigned int sub_irq;
1014        unsigned int n;
1015        int err;
1016        u16 reg;
1017
1018        mv88e6xxx_reg_lock(chip);
1019        err = mv88e6xxx_g2_int_source(chip, &reg);
1020        mv88e6xxx_reg_unlock(chip);
1021        if (err)
1022                goto out;
1023
1024        for (n = 0; n < 16; ++n) {
1025                if (reg & (1 << n)) {
1026                        sub_irq = irq_find_mapping(chip->g2_irq.domain, n);
1027                        handle_nested_irq(sub_irq);
1028                        ++nhandled;
1029                }
1030        }
1031out:
1032        return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
1033}
1034
1035static void mv88e6xxx_g2_irq_bus_lock(struct irq_data *d)
1036{
1037        struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
1038
1039        mv88e6xxx_reg_lock(chip);
1040}
1041
1042static void mv88e6xxx_g2_irq_bus_sync_unlock(struct irq_data *d)
1043{
1044        struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
1045        int err;
1046
1047        err = mv88e6xxx_g2_int_mask(chip, ~chip->g2_irq.masked);
1048        if (err)
1049                dev_err(chip->dev, "failed to mask interrupts\n");
1050
1051        mv88e6xxx_reg_unlock(chip);
1052}
1053
1054static const struct irq_chip mv88e6xxx_g2_irq_chip = {
1055        .name                   = "mv88e6xxx-g2",
1056        .irq_mask               = mv88e6xxx_g2_irq_mask,
1057        .irq_unmask             = mv88e6xxx_g2_irq_unmask,
1058        .irq_bus_lock           = mv88e6xxx_g2_irq_bus_lock,
1059        .irq_bus_sync_unlock    = mv88e6xxx_g2_irq_bus_sync_unlock,
1060};
1061
1062static int mv88e6xxx_g2_irq_domain_map(struct irq_domain *d,
1063                                       unsigned int irq,
1064                                       irq_hw_number_t hwirq)
1065{
1066        struct mv88e6xxx_chip *chip = d->host_data;
1067
1068        irq_set_chip_data(irq, d->host_data);
1069        irq_set_chip_and_handler(irq, &chip->g2_irq.chip, handle_level_irq);
1070        irq_set_noprobe(irq);
1071
1072        return 0;
1073}
1074
1075static const struct irq_domain_ops mv88e6xxx_g2_irq_domain_ops = {
1076        .map    = mv88e6xxx_g2_irq_domain_map,
1077        .xlate  = irq_domain_xlate_twocell,
1078};
1079
1080void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip *chip)
1081{
1082        int irq, virq;
1083
1084        mv88e6xxx_g2_watchdog_free(chip);
1085
1086        free_irq(chip->device_irq, chip);
1087        irq_dispose_mapping(chip->device_irq);
1088
1089        for (irq = 0; irq < 16; irq++) {
1090                virq = irq_find_mapping(chip->g2_irq.domain, irq);
1091                irq_dispose_mapping(virq);
1092        }
1093
1094        irq_domain_remove(chip->g2_irq.domain);
1095}
1096
1097int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip)
1098{
1099        int err, irq, virq;
1100
1101        chip->g2_irq.masked = ~0;
1102        mv88e6xxx_reg_lock(chip);
1103        err = mv88e6xxx_g2_int_mask(chip, ~chip->g2_irq.masked);
1104        mv88e6xxx_reg_unlock(chip);
1105        if (err)
1106                return err;
1107
1108        chip->g2_irq.domain = irq_domain_add_simple(
1109                chip->dev->of_node, 16, 0, &mv88e6xxx_g2_irq_domain_ops, chip);
1110        if (!chip->g2_irq.domain)
1111                return -ENOMEM;
1112
1113        for (irq = 0; irq < 16; irq++)
1114                irq_create_mapping(chip->g2_irq.domain, irq);
1115
1116        chip->g2_irq.chip = mv88e6xxx_g2_irq_chip;
1117
1118        chip->device_irq = irq_find_mapping(chip->g1_irq.domain,
1119                                            MV88E6XXX_G1_STS_IRQ_DEVICE);
1120        if (chip->device_irq < 0) {
1121                err = chip->device_irq;
1122                goto out;
1123        }
1124
1125        snprintf(chip->device_irq_name, sizeof(chip->device_irq_name),
1126                 "mv88e6xxx-%s-g2", dev_name(chip->dev));
1127
1128        err = request_threaded_irq(chip->device_irq, NULL,
1129                                   mv88e6xxx_g2_irq_thread_fn,
1130                                   IRQF_ONESHOT, chip->device_irq_name, chip);
1131        if (err)
1132                goto out;
1133
1134        return mv88e6xxx_g2_watchdog_setup(chip);
1135
1136out:
1137        for (irq = 0; irq < 16; irq++) {
1138                virq = irq_find_mapping(chip->g2_irq.domain, irq);
1139                irq_dispose_mapping(virq);
1140        }
1141
1142        irq_domain_remove(chip->g2_irq.domain);
1143
1144        return err;
1145}
1146
1147int mv88e6xxx_g2_irq_mdio_setup(struct mv88e6xxx_chip *chip,
1148                                struct mii_bus *bus)
1149{
1150        int phy, irq, err, err_phy;
1151
1152        for (phy = 0; phy < chip->info->num_internal_phys; phy++) {
1153                irq = irq_find_mapping(chip->g2_irq.domain, phy);
1154                if (irq < 0) {
1155                        err = irq;
1156                        goto out;
1157                }
1158                bus->irq[chip->info->phy_base_addr + phy] = irq;
1159        }
1160        return 0;
1161out:
1162        err_phy = phy;
1163
1164        for (phy = 0; phy < err_phy; phy++)
1165                irq_dispose_mapping(bus->irq[phy]);
1166
1167        return err;
1168}
1169
1170void mv88e6xxx_g2_irq_mdio_free(struct mv88e6xxx_chip *chip,
1171                                struct mii_bus *bus)
1172{
1173        int phy;
1174
1175        for (phy = 0; phy < chip->info->num_internal_phys; phy++)
1176                irq_dispose_mapping(bus->irq[phy]);
1177}
1178