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 0x0F: Priority Override Table */
 284
 285static int mv88e6xxx_g2_pot_write(struct mv88e6xxx_chip *chip, int pointer,
 286                                  u8 data)
 287{
 288        u16 val = (pointer << 8) | (data & 0x7);
 289
 290        return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_PRIO_OVERRIDE,
 291                                  MV88E6XXX_G2_PRIO_OVERRIDE_UPDATE | val);
 292}
 293
 294int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip)
 295{
 296        int i, err;
 297
 298        /* Clear all sixteen possible Priority Override entries */
 299        for (i = 0; i < 16; i++) {
 300                err = mv88e6xxx_g2_pot_write(chip, i, 0);
 301                if (err)
 302                        break;
 303        }
 304
 305        return err;
 306}
 307
 308/* Offset 0x14: EEPROM Command
 309 * Offset 0x15: EEPROM Data (for 16-bit data access)
 310 * Offset 0x15: EEPROM Addr (for 8-bit data access)
 311 */
 312
 313static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip)
 314{
 315        int bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_BUSY);
 316        int err;
 317
 318        err = mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_EEPROM_CMD, bit, 0);
 319        if (err)
 320                return err;
 321
 322        bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_RUNNING);
 323
 324        return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_EEPROM_CMD, bit, 0);
 325}
 326
 327static int mv88e6xxx_g2_eeprom_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
 328{
 329        int err;
 330
 331        err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_EEPROM_CMD,
 332                                 MV88E6XXX_G2_EEPROM_CMD_BUSY | cmd);
 333        if (err)
 334                return err;
 335
 336        return mv88e6xxx_g2_eeprom_wait(chip);
 337}
 338
 339static int mv88e6xxx_g2_eeprom_read8(struct mv88e6xxx_chip *chip,
 340                                     u16 addr, u8 *data)
 341{
 342        u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_READ;
 343        int err;
 344
 345        err = mv88e6xxx_g2_eeprom_wait(chip);
 346        if (err)
 347                return err;
 348
 349        err = mv88e6xxx_g2_write(chip, MV88E6390_G2_EEPROM_ADDR, addr);
 350        if (err)
 351                return err;
 352
 353        err = mv88e6xxx_g2_eeprom_cmd(chip, cmd);
 354        if (err)
 355                return err;
 356
 357        err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_EEPROM_CMD, &cmd);
 358        if (err)
 359                return err;
 360
 361        *data = cmd & 0xff;
 362
 363        return 0;
 364}
 365
 366static int mv88e6xxx_g2_eeprom_write8(struct mv88e6xxx_chip *chip,
 367                                      u16 addr, u8 data)
 368{
 369        u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_WRITE |
 370                MV88E6XXX_G2_EEPROM_CMD_WRITE_EN;
 371        int err;
 372
 373        err = mv88e6xxx_g2_eeprom_wait(chip);
 374        if (err)
 375                return err;
 376
 377        err = mv88e6xxx_g2_write(chip, MV88E6390_G2_EEPROM_ADDR, addr);
 378        if (err)
 379                return err;
 380
 381        return mv88e6xxx_g2_eeprom_cmd(chip, cmd | data);
 382}
 383
 384static int mv88e6xxx_g2_eeprom_read16(struct mv88e6xxx_chip *chip,
 385                                      u8 addr, u16 *data)
 386{
 387        u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_READ | addr;
 388        int err;
 389
 390        err = mv88e6xxx_g2_eeprom_wait(chip);
 391        if (err)
 392                return err;
 393
 394        err = mv88e6xxx_g2_eeprom_cmd(chip, cmd);
 395        if (err)
 396                return err;
 397
 398        return mv88e6xxx_g2_read(chip, MV88E6352_G2_EEPROM_DATA, data);
 399}
 400
 401static int mv88e6xxx_g2_eeprom_write16(struct mv88e6xxx_chip *chip,
 402                                       u8 addr, u16 data)
 403{
 404        u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_WRITE | addr;
 405        int err;
 406
 407        err = mv88e6xxx_g2_eeprom_wait(chip);
 408        if (err)
 409                return err;
 410
 411        err = mv88e6xxx_g2_write(chip, MV88E6352_G2_EEPROM_DATA, data);
 412        if (err)
 413                return err;
 414
 415        return mv88e6xxx_g2_eeprom_cmd(chip, cmd);
 416}
 417
 418int mv88e6xxx_g2_get_eeprom8(struct mv88e6xxx_chip *chip,
 419                             struct ethtool_eeprom *eeprom, u8 *data)
 420{
 421        unsigned int offset = eeprom->offset;
 422        unsigned int len = eeprom->len;
 423        int err;
 424
 425        eeprom->len = 0;
 426
 427        while (len) {
 428                err = mv88e6xxx_g2_eeprom_read8(chip, offset, data);
 429                if (err)
 430                        return err;
 431
 432                eeprom->len++;
 433                offset++;
 434                data++;
 435                len--;
 436        }
 437
 438        return 0;
 439}
 440
 441int mv88e6xxx_g2_set_eeprom8(struct mv88e6xxx_chip *chip,
 442                             struct ethtool_eeprom *eeprom, u8 *data)
 443{
 444        unsigned int offset = eeprom->offset;
 445        unsigned int len = eeprom->len;
 446        int err;
 447
 448        eeprom->len = 0;
 449
 450        while (len) {
 451                err = mv88e6xxx_g2_eeprom_write8(chip, offset, *data);
 452                if (err)
 453                        return err;
 454
 455                eeprom->len++;
 456                offset++;
 457                data++;
 458                len--;
 459        }
 460
 461        return 0;
 462}
 463
 464int mv88e6xxx_g2_get_eeprom16(struct mv88e6xxx_chip *chip,
 465                              struct ethtool_eeprom *eeprom, u8 *data)
 466{
 467        unsigned int offset = eeprom->offset;
 468        unsigned int len = eeprom->len;
 469        u16 val;
 470        int err;
 471
 472        eeprom->len = 0;
 473
 474        if (offset & 1) {
 475                err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
 476                if (err)
 477                        return err;
 478
 479                *data++ = (val >> 8) & 0xff;
 480
 481                offset++;
 482                len--;
 483                eeprom->len++;
 484        }
 485
 486        while (len >= 2) {
 487                err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
 488                if (err)
 489                        return err;
 490
 491                *data++ = val & 0xff;
 492                *data++ = (val >> 8) & 0xff;
 493
 494                offset += 2;
 495                len -= 2;
 496                eeprom->len += 2;
 497        }
 498
 499        if (len) {
 500                err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
 501                if (err)
 502                        return err;
 503
 504                *data++ = val & 0xff;
 505
 506                offset++;
 507                len--;
 508                eeprom->len++;
 509        }
 510
 511        return 0;
 512}
 513
 514int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip,
 515                              struct ethtool_eeprom *eeprom, u8 *data)
 516{
 517        unsigned int offset = eeprom->offset;
 518        unsigned int len = eeprom->len;
 519        u16 val;
 520        int err;
 521
 522        /* Ensure the RO WriteEn bit is set */
 523        err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_EEPROM_CMD, &val);
 524        if (err)
 525                return err;
 526
 527        if (!(val & MV88E6XXX_G2_EEPROM_CMD_WRITE_EN))
 528                return -EROFS;
 529
 530        eeprom->len = 0;
 531
 532        if (offset & 1) {
 533                err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
 534                if (err)
 535                        return err;
 536
 537                val = (*data++ << 8) | (val & 0xff);
 538
 539                err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
 540                if (err)
 541                        return err;
 542
 543                offset++;
 544                len--;
 545                eeprom->len++;
 546        }
 547
 548        while (len >= 2) {
 549                val = *data++;
 550                val |= *data++ << 8;
 551
 552                err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
 553                if (err)
 554                        return err;
 555
 556                offset += 2;
 557                len -= 2;
 558                eeprom->len += 2;
 559        }
 560
 561        if (len) {
 562                err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
 563                if (err)
 564                        return err;
 565
 566                val = (val & 0xff00) | *data++;
 567
 568                err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
 569                if (err)
 570                        return err;
 571
 572                offset++;
 573                len--;
 574                eeprom->len++;
 575        }
 576
 577        return 0;
 578}
 579
 580/* Offset 0x18: SMI PHY Command Register
 581 * Offset 0x19: SMI PHY Data Register
 582 */
 583
 584static int mv88e6xxx_g2_smi_phy_wait(struct mv88e6xxx_chip *chip)
 585{
 586        int bit = __bf_shf(MV88E6XXX_G2_SMI_PHY_CMD_BUSY);
 587
 588        return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_SMI_PHY_CMD, bit, 0);
 589}
 590
 591static int mv88e6xxx_g2_smi_phy_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
 592{
 593        int err;
 594
 595        err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_CMD,
 596                                 MV88E6XXX_G2_SMI_PHY_CMD_BUSY | cmd);
 597        if (err)
 598                return err;
 599
 600        return mv88e6xxx_g2_smi_phy_wait(chip);
 601}
 602
 603static int mv88e6xxx_g2_smi_phy_access(struct mv88e6xxx_chip *chip,
 604                                       bool external, bool c45, u16 op, int dev,
 605                                       int reg)
 606{
 607        u16 cmd = op;
 608
 609        if (external)
 610                cmd |= MV88E6390_G2_SMI_PHY_CMD_FUNC_EXTERNAL;
 611        else
 612                cmd |= MV88E6390_G2_SMI_PHY_CMD_FUNC_INTERNAL; /* empty mask */
 613
 614        if (c45)
 615                cmd |= MV88E6XXX_G2_SMI_PHY_CMD_MODE_45; /* empty mask */
 616        else
 617                cmd |= MV88E6XXX_G2_SMI_PHY_CMD_MODE_22;
 618
 619        dev <<= __bf_shf(MV88E6XXX_G2_SMI_PHY_CMD_DEV_ADDR_MASK);
 620        cmd |= dev & MV88E6XXX_G2_SMI_PHY_CMD_DEV_ADDR_MASK;
 621        cmd |= reg & MV88E6XXX_G2_SMI_PHY_CMD_REG_ADDR_MASK;
 622
 623        return mv88e6xxx_g2_smi_phy_cmd(chip, cmd);
 624}
 625
 626static int mv88e6xxx_g2_smi_phy_access_c22(struct mv88e6xxx_chip *chip,
 627                                           bool external, u16 op, int dev,
 628                                           int reg)
 629{
 630        return mv88e6xxx_g2_smi_phy_access(chip, external, false, op, dev, reg);
 631}
 632
 633/* IEEE 802.3 Clause 22 Read Data Register */
 634static int mv88e6xxx_g2_smi_phy_read_data_c22(struct mv88e6xxx_chip *chip,
 635                                              bool external, int dev, int reg,
 636                                              u16 *data)
 637{
 638        u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_22_READ_DATA;
 639        int err;
 640
 641        err = mv88e6xxx_g2_smi_phy_wait(chip);
 642        if (err)
 643                return err;
 644
 645        err = mv88e6xxx_g2_smi_phy_access_c22(chip, external, op, dev, reg);
 646        if (err)
 647                return err;
 648
 649        return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
 650}
 651
 652/* IEEE 802.3 Clause 22 Write Data Register */
 653static int mv88e6xxx_g2_smi_phy_write_data_c22(struct mv88e6xxx_chip *chip,
 654                                               bool external, int dev, int reg,
 655                                               u16 data)
 656{
 657        u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_22_WRITE_DATA;
 658        int err;
 659
 660        err = mv88e6xxx_g2_smi_phy_wait(chip);
 661        if (err)
 662                return err;
 663
 664        err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
 665        if (err)
 666                return err;
 667
 668        return mv88e6xxx_g2_smi_phy_access_c22(chip, external, op, dev, reg);
 669}
 670
 671static int mv88e6xxx_g2_smi_phy_access_c45(struct mv88e6xxx_chip *chip,
 672                                           bool external, u16 op, int port,
 673                                           int dev)
 674{
 675        return mv88e6xxx_g2_smi_phy_access(chip, external, true, op, port, dev);
 676}
 677
 678/* IEEE 802.3 Clause 45 Write Address Register */
 679static int mv88e6xxx_g2_smi_phy_write_addr_c45(struct mv88e6xxx_chip *chip,
 680                                               bool external, int port, int dev,
 681                                               int addr)
 682{
 683        u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_WRITE_ADDR;
 684        int err;
 685
 686        err = mv88e6xxx_g2_smi_phy_wait(chip);
 687        if (err)
 688                return err;
 689
 690        err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, addr);
 691        if (err)
 692                return err;
 693
 694        return mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
 695}
 696
 697/* IEEE 802.3 Clause 45 Read Data Register */
 698static int mv88e6xxx_g2_smi_phy_read_data_c45(struct mv88e6xxx_chip *chip,
 699                                              bool external, int port, int dev,
 700                                              u16 *data)
 701{
 702        u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_READ_DATA;
 703        int err;
 704
 705        err = mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
 706        if (err)
 707                return err;
 708
 709        return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
 710}
 711
 712static int mv88e6xxx_g2_smi_phy_read_c45(struct mv88e6xxx_chip *chip,
 713                                         bool external, int port, int reg,
 714                                         u16 *data)
 715{
 716        int dev = (reg >> 16) & 0x1f;
 717        int addr = reg & 0xffff;
 718        int err;
 719
 720        err = mv88e6xxx_g2_smi_phy_write_addr_c45(chip, external, port, dev,
 721                                                  addr);
 722        if (err)
 723                return err;
 724
 725        return mv88e6xxx_g2_smi_phy_read_data_c45(chip, external, port, dev,
 726                                                  data);
 727}
 728
 729/* IEEE 802.3 Clause 45 Write Data Register */
 730static int mv88e6xxx_g2_smi_phy_write_data_c45(struct mv88e6xxx_chip *chip,
 731                                               bool external, int port, int dev,
 732                                               u16 data)
 733{
 734        u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_WRITE_DATA;
 735        int err;
 736
 737        err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
 738        if (err)
 739                return err;
 740
 741        return mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
 742}
 743
 744static int mv88e6xxx_g2_smi_phy_write_c45(struct mv88e6xxx_chip *chip,
 745                                          bool external, int port, int reg,
 746                                          u16 data)
 747{
 748        int dev = (reg >> 16) & 0x1f;
 749        int addr = reg & 0xffff;
 750        int err;
 751
 752        err = mv88e6xxx_g2_smi_phy_write_addr_c45(chip, external, port, dev,
 753                                                  addr);
 754        if (err)
 755                return err;
 756
 757        return mv88e6xxx_g2_smi_phy_write_data_c45(chip, external, port, dev,
 758                                                   data);
 759}
 760
 761int mv88e6xxx_g2_smi_phy_read(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
 762                              int addr, int reg, u16 *val)
 763{
 764        struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
 765        bool external = mdio_bus->external;
 766
 767        if (reg & MII_ADDR_C45)
 768                return mv88e6xxx_g2_smi_phy_read_c45(chip, external, addr, reg,
 769                                                     val);
 770
 771        return mv88e6xxx_g2_smi_phy_read_data_c22(chip, external, addr, reg,
 772                                                  val);
 773}
 774
 775int mv88e6xxx_g2_smi_phy_write(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
 776                               int addr, int reg, u16 val)
 777{
 778        struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
 779        bool external = mdio_bus->external;
 780
 781        if (reg & MII_ADDR_C45)
 782                return mv88e6xxx_g2_smi_phy_write_c45(chip, external, addr, reg,
 783                                                      val);
 784
 785        return mv88e6xxx_g2_smi_phy_write_data_c22(chip, external, addr, reg,
 786                                                   val);
 787}
 788
 789/* Offset 0x1B: Watchdog Control */
 790static int mv88e6097_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
 791{
 792        u16 reg;
 793
 794        mv88e6xxx_g2_read(chip, MV88E6352_G2_WDOG_CTL, &reg);
 795
 796        dev_info(chip->dev, "Watchdog event: 0x%04x", reg);
 797
 798        return IRQ_HANDLED;
 799}
 800
 801static void mv88e6097_watchdog_free(struct mv88e6xxx_chip *chip)
 802{
 803        u16 reg;
 804
 805        mv88e6xxx_g2_read(chip, MV88E6352_G2_WDOG_CTL, &reg);
 806
 807        reg &= ~(MV88E6352_G2_WDOG_CTL_EGRESS_ENABLE |
 808                 MV88E6352_G2_WDOG_CTL_QC_ENABLE);
 809
 810        mv88e6xxx_g2_write(chip, MV88E6352_G2_WDOG_CTL, reg);
 811}
 812
 813static int mv88e6097_watchdog_setup(struct mv88e6xxx_chip *chip)
 814{
 815        return mv88e6xxx_g2_write(chip, MV88E6352_G2_WDOG_CTL,
 816                                  MV88E6352_G2_WDOG_CTL_EGRESS_ENABLE |
 817                                  MV88E6352_G2_WDOG_CTL_QC_ENABLE |
 818                                  MV88E6352_G2_WDOG_CTL_SWRESET);
 819}
 820
 821const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops = {
 822        .irq_action = mv88e6097_watchdog_action,
 823        .irq_setup = mv88e6097_watchdog_setup,
 824        .irq_free = mv88e6097_watchdog_free,
 825};
 826
 827static void mv88e6250_watchdog_free(struct mv88e6xxx_chip *chip)
 828{
 829        u16 reg;
 830
 831        mv88e6xxx_g2_read(chip, MV88E6250_G2_WDOG_CTL, &reg);
 832
 833        reg &= ~(MV88E6250_G2_WDOG_CTL_EGRESS_ENABLE |
 834                 MV88E6250_G2_WDOG_CTL_QC_ENABLE);
 835
 836        mv88e6xxx_g2_write(chip, MV88E6250_G2_WDOG_CTL, reg);
 837}
 838
 839static int mv88e6250_watchdog_setup(struct mv88e6xxx_chip *chip)
 840{
 841        return mv88e6xxx_g2_write(chip, MV88E6250_G2_WDOG_CTL,
 842                                  MV88E6250_G2_WDOG_CTL_EGRESS_ENABLE |
 843                                  MV88E6250_G2_WDOG_CTL_QC_ENABLE |
 844                                  MV88E6250_G2_WDOG_CTL_SWRESET);
 845}
 846
 847const struct mv88e6xxx_irq_ops mv88e6250_watchdog_ops = {
 848        .irq_action = mv88e6097_watchdog_action,
 849        .irq_setup = mv88e6250_watchdog_setup,
 850        .irq_free = mv88e6250_watchdog_free,
 851};
 852
 853static int mv88e6390_watchdog_setup(struct mv88e6xxx_chip *chip)
 854{
 855        return mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
 856                                  MV88E6390_G2_WDOG_CTL_UPDATE |
 857                                  MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE |
 858                                  MV88E6390_G2_WDOG_CTL_CUT_THROUGH |
 859                                  MV88E6390_G2_WDOG_CTL_QUEUE_CONTROLLER |
 860                                  MV88E6390_G2_WDOG_CTL_EGRESS |
 861                                  MV88E6390_G2_WDOG_CTL_FORCE_IRQ);
 862}
 863
 864static int mv88e6390_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
 865{
 866        int err;
 867        u16 reg;
 868
 869        mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
 870                           MV88E6390_G2_WDOG_CTL_PTR_EVENT);
 871        err = mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, &reg);
 872
 873        dev_info(chip->dev, "Watchdog event: 0x%04x",
 874                 reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);
 875
 876        mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
 877                           MV88E6390_G2_WDOG_CTL_PTR_HISTORY);
 878        err = mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, &reg);
 879
 880        dev_info(chip->dev, "Watchdog history: 0x%04x",
 881                 reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);
 882
 883        /* Trigger a software reset to try to recover the switch */
 884        if (chip->info->ops->reset)
 885                chip->info->ops->reset(chip);
 886
 887        mv88e6390_watchdog_setup(chip);
 888
 889        return IRQ_HANDLED;
 890}
 891
 892static void mv88e6390_watchdog_free(struct mv88e6xxx_chip *chip)
 893{
 894        mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
 895                           MV88E6390_G2_WDOG_CTL_UPDATE |
 896                           MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE);
 897}
 898
 899const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops = {
 900        .irq_action = mv88e6390_watchdog_action,
 901        .irq_setup = mv88e6390_watchdog_setup,
 902        .irq_free = mv88e6390_watchdog_free,
 903};
 904
 905static irqreturn_t mv88e6xxx_g2_watchdog_thread_fn(int irq, void *dev_id)
 906{
 907        struct mv88e6xxx_chip *chip = dev_id;
 908        irqreturn_t ret = IRQ_NONE;
 909
 910        mv88e6xxx_reg_lock(chip);
 911        if (chip->info->ops->watchdog_ops->irq_action)
 912                ret = chip->info->ops->watchdog_ops->irq_action(chip, irq);
 913        mv88e6xxx_reg_unlock(chip);
 914
 915        return ret;
 916}
 917
 918static void mv88e6xxx_g2_watchdog_free(struct mv88e6xxx_chip *chip)
 919{
 920        mv88e6xxx_reg_lock(chip);
 921        if (chip->info->ops->watchdog_ops->irq_free)
 922                chip->info->ops->watchdog_ops->irq_free(chip);
 923        mv88e6xxx_reg_unlock(chip);
 924
 925        free_irq(chip->watchdog_irq, chip);
 926        irq_dispose_mapping(chip->watchdog_irq);
 927}
 928
 929static int mv88e6xxx_g2_watchdog_setup(struct mv88e6xxx_chip *chip)
 930{
 931        int err;
 932
 933        chip->watchdog_irq = irq_find_mapping(chip->g2_irq.domain,
 934                                              MV88E6XXX_G2_INT_SOURCE_WATCHDOG);
 935        if (chip->watchdog_irq < 0)
 936                return chip->watchdog_irq;
 937
 938        err = request_threaded_irq(chip->watchdog_irq, NULL,
 939                                   mv88e6xxx_g2_watchdog_thread_fn,
 940                                   IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
 941                                   "mv88e6xxx-watchdog", chip);
 942        if (err)
 943                return err;
 944
 945        mv88e6xxx_reg_lock(chip);
 946        if (chip->info->ops->watchdog_ops->irq_setup)
 947                err = chip->info->ops->watchdog_ops->irq_setup(chip);
 948        mv88e6xxx_reg_unlock(chip);
 949
 950        return err;
 951}
 952
 953/* Offset 0x1D: Misc Register */
 954
 955static int mv88e6xxx_g2_misc_5_bit_port(struct mv88e6xxx_chip *chip,
 956                                        bool port_5_bit)
 957{
 958        u16 val;
 959        int err;
 960
 961        err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_MISC, &val);
 962        if (err)
 963                return err;
 964
 965        if (port_5_bit)
 966                val |= MV88E6XXX_G2_MISC_5_BIT_PORT;
 967        else
 968                val &= ~MV88E6XXX_G2_MISC_5_BIT_PORT;
 969
 970        return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MISC, val);
 971}
 972
 973int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip)
 974{
 975        return mv88e6xxx_g2_misc_5_bit_port(chip, false);
 976}
 977
 978static void mv88e6xxx_g2_irq_mask(struct irq_data *d)
 979{
 980        struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
 981        unsigned int n = d->hwirq;
 982
 983        chip->g2_irq.masked |= (1 << n);
 984}
 985
 986static void mv88e6xxx_g2_irq_unmask(struct irq_data *d)
 987{
 988        struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
 989        unsigned int n = d->hwirq;
 990
 991        chip->g2_irq.masked &= ~(1 << n);
 992}
 993
 994static irqreturn_t mv88e6xxx_g2_irq_thread_fn(int irq, void *dev_id)
 995{
 996        struct mv88e6xxx_chip *chip = dev_id;
 997        unsigned int nhandled = 0;
 998        unsigned int sub_irq;
 999        unsigned int n;
1000        int err;
1001        u16 reg;
1002
1003        mv88e6xxx_reg_lock(chip);
1004        err = mv88e6xxx_g2_int_source(chip, &reg);
1005        mv88e6xxx_reg_unlock(chip);
1006        if (err)
1007                goto out;
1008
1009        for (n = 0; n < 16; ++n) {
1010                if (reg & (1 << n)) {
1011                        sub_irq = irq_find_mapping(chip->g2_irq.domain, n);
1012                        handle_nested_irq(sub_irq);
1013                        ++nhandled;
1014                }
1015        }
1016out:
1017        return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
1018}
1019
1020static void mv88e6xxx_g2_irq_bus_lock(struct irq_data *d)
1021{
1022        struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
1023
1024        mv88e6xxx_reg_lock(chip);
1025}
1026
1027static void mv88e6xxx_g2_irq_bus_sync_unlock(struct irq_data *d)
1028{
1029        struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
1030        int err;
1031
1032        err = mv88e6xxx_g2_int_mask(chip, ~chip->g2_irq.masked);
1033        if (err)
1034                dev_err(chip->dev, "failed to mask interrupts\n");
1035
1036        mv88e6xxx_reg_unlock(chip);
1037}
1038
1039static const struct irq_chip mv88e6xxx_g2_irq_chip = {
1040        .name                   = "mv88e6xxx-g2",
1041        .irq_mask               = mv88e6xxx_g2_irq_mask,
1042        .irq_unmask             = mv88e6xxx_g2_irq_unmask,
1043        .irq_bus_lock           = mv88e6xxx_g2_irq_bus_lock,
1044        .irq_bus_sync_unlock    = mv88e6xxx_g2_irq_bus_sync_unlock,
1045};
1046
1047static int mv88e6xxx_g2_irq_domain_map(struct irq_domain *d,
1048                                       unsigned int irq,
1049                                       irq_hw_number_t hwirq)
1050{
1051        struct mv88e6xxx_chip *chip = d->host_data;
1052
1053        irq_set_chip_data(irq, d->host_data);
1054        irq_set_chip_and_handler(irq, &chip->g2_irq.chip, handle_level_irq);
1055        irq_set_noprobe(irq);
1056
1057        return 0;
1058}
1059
1060static const struct irq_domain_ops mv88e6xxx_g2_irq_domain_ops = {
1061        .map    = mv88e6xxx_g2_irq_domain_map,
1062        .xlate  = irq_domain_xlate_twocell,
1063};
1064
1065void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip *chip)
1066{
1067        int irq, virq;
1068
1069        mv88e6xxx_g2_watchdog_free(chip);
1070
1071        free_irq(chip->device_irq, chip);
1072        irq_dispose_mapping(chip->device_irq);
1073
1074        for (irq = 0; irq < 16; irq++) {
1075                virq = irq_find_mapping(chip->g2_irq.domain, irq);
1076                irq_dispose_mapping(virq);
1077        }
1078
1079        irq_domain_remove(chip->g2_irq.domain);
1080}
1081
1082int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip)
1083{
1084        int err, irq, virq;
1085
1086        chip->g2_irq.domain = irq_domain_add_simple(
1087                chip->dev->of_node, 16, 0, &mv88e6xxx_g2_irq_domain_ops, chip);
1088        if (!chip->g2_irq.domain)
1089                return -ENOMEM;
1090
1091        for (irq = 0; irq < 16; irq++)
1092                irq_create_mapping(chip->g2_irq.domain, irq);
1093
1094        chip->g2_irq.chip = mv88e6xxx_g2_irq_chip;
1095        chip->g2_irq.masked = ~0;
1096
1097        chip->device_irq = irq_find_mapping(chip->g1_irq.domain,
1098                                            MV88E6XXX_G1_STS_IRQ_DEVICE);
1099        if (chip->device_irq < 0) {
1100                err = chip->device_irq;
1101                goto out;
1102        }
1103
1104        err = request_threaded_irq(chip->device_irq, NULL,
1105                                   mv88e6xxx_g2_irq_thread_fn,
1106                                   IRQF_ONESHOT, "mv88e6xxx-g2", chip);
1107        if (err)
1108                goto out;
1109
1110        return mv88e6xxx_g2_watchdog_setup(chip);
1111
1112out:
1113        for (irq = 0; irq < 16; irq++) {
1114                virq = irq_find_mapping(chip->g2_irq.domain, irq);
1115                irq_dispose_mapping(virq);
1116        }
1117
1118        irq_domain_remove(chip->g2_irq.domain);
1119
1120        return err;
1121}
1122
1123int mv88e6xxx_g2_irq_mdio_setup(struct mv88e6xxx_chip *chip,
1124                                struct mii_bus *bus)
1125{
1126        int phy, irq, err, err_phy;
1127
1128        for (phy = 0; phy < chip->info->num_internal_phys; phy++) {
1129                irq = irq_find_mapping(chip->g2_irq.domain, phy);
1130                if (irq < 0) {
1131                        err = irq;
1132                        goto out;
1133                }
1134                bus->irq[chip->info->phy_base_addr + phy] = irq;
1135        }
1136        return 0;
1137out:
1138        err_phy = phy;
1139
1140        for (phy = 0; phy < err_phy; phy++)
1141                irq_dispose_mapping(bus->irq[phy]);
1142
1143        return err;
1144}
1145
1146void mv88e6xxx_g2_irq_mdio_free(struct mv88e6xxx_chip *chip,
1147                                struct mii_bus *bus)
1148{
1149        int phy;
1150
1151        for (phy = 0; phy < chip->info->num_internal_phys; phy++)
1152                irq_dispose_mapping(bus->irq[phy]);
1153}
1154