linux/drivers/net/dsa/mv88e6xxx/serdes.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Marvell 88E6xxx SERDES manipulation, via SMI bus
   4 *
   5 * Copyright (c) 2008 Marvell Semiconductor
   6 *
   7 * Copyright (c) 2017 Andrew Lunn <andrew@lunn.ch>
   8 */
   9
  10#include <linux/interrupt.h>
  11#include <linux/irqdomain.h>
  12#include <linux/mii.h>
  13
  14#include "chip.h"
  15#include "global2.h"
  16#include "phy.h"
  17#include "port.h"
  18#include "serdes.h"
  19
  20static int mv88e6352_serdes_read(struct mv88e6xxx_chip *chip, int reg,
  21                                 u16 *val)
  22{
  23        return mv88e6xxx_phy_page_read(chip, MV88E6352_ADDR_SERDES,
  24                                       MV88E6352_SERDES_PAGE_FIBER,
  25                                       reg, val);
  26}
  27
  28static int mv88e6352_serdes_write(struct mv88e6xxx_chip *chip, int reg,
  29                                  u16 val)
  30{
  31        return mv88e6xxx_phy_page_write(chip, MV88E6352_ADDR_SERDES,
  32                                        MV88E6352_SERDES_PAGE_FIBER,
  33                                        reg, val);
  34}
  35
  36static int mv88e6390_serdes_read(struct mv88e6xxx_chip *chip,
  37                                 int lane, int device, int reg, u16 *val)
  38{
  39        int reg_c45 = MII_ADDR_C45 | device << 16 | reg;
  40
  41        return mv88e6xxx_phy_read(chip, lane, reg_c45, val);
  42}
  43
  44static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip,
  45                                  int lane, int device, int reg, u16 val)
  46{
  47        int reg_c45 = MII_ADDR_C45 | device << 16 | reg;
  48
  49        return mv88e6xxx_phy_write(chip, lane, reg_c45, val);
  50}
  51
  52static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip,
  53                                          u16 bmsr, u16 lpa, u16 status,
  54                                          struct phylink_link_state *state)
  55{
  56        state->link = false;
  57
  58        /* If the BMSR reports that the link had failed, report this to
  59         * phylink.
  60         */
  61        if (!(bmsr & BMSR_LSTATUS))
  62                return 0;
  63
  64        state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK);
  65        state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
  66
  67        if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) {
  68                /* The Spped and Duplex Resolved register is 1 if AN is enabled
  69                 * and complete, or if AN is disabled. So with disabled AN we
  70                 * still get here on link up.
  71                 */
  72                state->duplex = status &
  73                                MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ?
  74                                                 DUPLEX_FULL : DUPLEX_HALF;
  75
  76                if (status & MV88E6390_SGMII_PHY_STATUS_TX_PAUSE)
  77                        state->pause |= MLO_PAUSE_TX;
  78                if (status & MV88E6390_SGMII_PHY_STATUS_RX_PAUSE)
  79                        state->pause |= MLO_PAUSE_RX;
  80
  81                switch (status & MV88E6390_SGMII_PHY_STATUS_SPEED_MASK) {
  82                case MV88E6390_SGMII_PHY_STATUS_SPEED_1000:
  83                        if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
  84                                state->speed = SPEED_2500;
  85                        else
  86                                state->speed = SPEED_1000;
  87                        break;
  88                case MV88E6390_SGMII_PHY_STATUS_SPEED_100:
  89                        state->speed = SPEED_100;
  90                        break;
  91                case MV88E6390_SGMII_PHY_STATUS_SPEED_10:
  92                        state->speed = SPEED_10;
  93                        break;
  94                default:
  95                        dev_err(chip->dev, "invalid PHY speed\n");
  96                        return -EINVAL;
  97                }
  98        } else if (state->link &&
  99                   state->interface != PHY_INTERFACE_MODE_SGMII) {
 100                /* If Speed and Duplex Resolved register is 0 and link is up, it
 101                 * means that AN was enabled, but link partner had it disabled
 102                 * and the PHY invoked the Auto-Negotiation Bypass feature and
 103                 * linked anyway.
 104                 */
 105                state->duplex = DUPLEX_FULL;
 106                if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
 107                        state->speed = SPEED_2500;
 108                else
 109                        state->speed = SPEED_1000;
 110        } else {
 111                state->link = false;
 112        }
 113
 114        if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
 115                mii_lpa_mod_linkmode_x(state->lp_advertising, lpa,
 116                                       ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
 117        else if (state->interface == PHY_INTERFACE_MODE_1000BASEX)
 118                mii_lpa_mod_linkmode_x(state->lp_advertising, lpa,
 119                                       ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
 120
 121        return 0;
 122}
 123
 124int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
 125                           bool up)
 126{
 127        u16 val, new_val;
 128        int err;
 129
 130        err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
 131        if (err)
 132                return err;
 133
 134        if (up)
 135                new_val = val & ~BMCR_PDOWN;
 136        else
 137                new_val = val | BMCR_PDOWN;
 138
 139        if (val != new_val)
 140                err = mv88e6352_serdes_write(chip, MII_BMCR, new_val);
 141
 142        return err;
 143}
 144
 145int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
 146                                int lane, unsigned int mode,
 147                                phy_interface_t interface,
 148                                const unsigned long *advertise)
 149{
 150        u16 adv, bmcr, val;
 151        bool changed;
 152        int err;
 153
 154        switch (interface) {
 155        case PHY_INTERFACE_MODE_SGMII:
 156                adv = 0x0001;
 157                break;
 158
 159        case PHY_INTERFACE_MODE_1000BASEX:
 160                adv = linkmode_adv_to_mii_adv_x(advertise,
 161                                        ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
 162                break;
 163
 164        default:
 165                return 0;
 166        }
 167
 168        err = mv88e6352_serdes_read(chip, MII_ADVERTISE, &val);
 169        if (err)
 170                return err;
 171
 172        changed = val != adv;
 173        if (changed) {
 174                err = mv88e6352_serdes_write(chip, MII_ADVERTISE, adv);
 175                if (err)
 176                        return err;
 177        }
 178
 179        err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
 180        if (err)
 181                return err;
 182
 183        if (phylink_autoneg_inband(mode))
 184                bmcr = val | BMCR_ANENABLE;
 185        else
 186                bmcr = val & ~BMCR_ANENABLE;
 187
 188        if (bmcr == val)
 189                return changed;
 190
 191        return mv88e6352_serdes_write(chip, MII_BMCR, bmcr);
 192}
 193
 194int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
 195                                   int lane, struct phylink_link_state *state)
 196{
 197        u16 bmsr, lpa, status;
 198        int err;
 199
 200        err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr);
 201        if (err) {
 202                dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err);
 203                return err;
 204        }
 205
 206        err = mv88e6352_serdes_read(chip, 0x11, &status);
 207        if (err) {
 208                dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
 209                return err;
 210        }
 211
 212        err = mv88e6352_serdes_read(chip, MII_LPA, &lpa);
 213        if (err) {
 214                dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err);
 215                return err;
 216        }
 217
 218        return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state);
 219}
 220
 221int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
 222                                    int lane)
 223{
 224        u16 bmcr;
 225        int err;
 226
 227        err = mv88e6352_serdes_read(chip, MII_BMCR, &bmcr);
 228        if (err)
 229                return err;
 230
 231        return mv88e6352_serdes_write(chip, MII_BMCR, bmcr | BMCR_ANRESTART);
 232}
 233
 234int mv88e6352_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
 235                                 int lane, int speed, int duplex)
 236{
 237        u16 val, bmcr;
 238        int err;
 239
 240        err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
 241        if (err)
 242                return err;
 243
 244        bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
 245        switch (speed) {
 246        case SPEED_1000:
 247                bmcr |= BMCR_SPEED1000;
 248                break;
 249        case SPEED_100:
 250                bmcr |= BMCR_SPEED100;
 251                break;
 252        case SPEED_10:
 253                break;
 254        }
 255
 256        if (duplex == DUPLEX_FULL)
 257                bmcr |= BMCR_FULLDPLX;
 258
 259        if (bmcr == val)
 260                return 0;
 261
 262        return mv88e6352_serdes_write(chip, MII_BMCR, bmcr);
 263}
 264
 265int mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
 266{
 267        u8 cmode = chip->ports[port].cmode;
 268        int lane = -ENODEV;
 269
 270        if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASEX) ||
 271            (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX) ||
 272            (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII))
 273                lane = 0xff; /* Unused */
 274
 275        return lane;
 276}
 277
 278struct mv88e6352_serdes_hw_stat {
 279        char string[ETH_GSTRING_LEN];
 280        int sizeof_stat;
 281        int reg;
 282};
 283
 284static struct mv88e6352_serdes_hw_stat mv88e6352_serdes_hw_stats[] = {
 285        { "serdes_fibre_rx_error", 16, 21 },
 286        { "serdes_PRBS_error", 32, 24 },
 287};
 288
 289int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
 290{
 291        int err;
 292
 293        err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
 294        if (err <= 0)
 295                return err;
 296
 297        return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
 298}
 299
 300int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
 301                                 int port, uint8_t *data)
 302{
 303        struct mv88e6352_serdes_hw_stat *stat;
 304        int err, i;
 305
 306        err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
 307        if (err <= 0)
 308                return err;
 309
 310        for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
 311                stat = &mv88e6352_serdes_hw_stats[i];
 312                memcpy(data + i * ETH_GSTRING_LEN, stat->string,
 313                       ETH_GSTRING_LEN);
 314        }
 315        return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
 316}
 317
 318static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip,
 319                                          struct mv88e6352_serdes_hw_stat *stat)
 320{
 321        u64 val = 0;
 322        u16 reg;
 323        int err;
 324
 325        err = mv88e6352_serdes_read(chip, stat->reg, &reg);
 326        if (err) {
 327                dev_err(chip->dev, "failed to read statistic\n");
 328                return 0;
 329        }
 330
 331        val = reg;
 332
 333        if (stat->sizeof_stat == 32) {
 334                err = mv88e6352_serdes_read(chip, stat->reg + 1, &reg);
 335                if (err) {
 336                        dev_err(chip->dev, "failed to read statistic\n");
 337                        return 0;
 338                }
 339                val = val << 16 | reg;
 340        }
 341
 342        return val;
 343}
 344
 345int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
 346                               uint64_t *data)
 347{
 348        struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port];
 349        struct mv88e6352_serdes_hw_stat *stat;
 350        int i, err;
 351        u64 value;
 352
 353        err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
 354        if (err <= 0)
 355                return err;
 356
 357        BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) >
 358                     ARRAY_SIZE(mv88e6xxx_port->serdes_stats));
 359
 360        for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
 361                stat = &mv88e6352_serdes_hw_stats[i];
 362                value = mv88e6352_serdes_get_stat(chip, stat);
 363                mv88e6xxx_port->serdes_stats[i] += value;
 364                data[i] = mv88e6xxx_port->serdes_stats[i];
 365        }
 366
 367        return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
 368}
 369
 370static void mv88e6352_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
 371{
 372        u16 bmsr;
 373        int err;
 374
 375        /* If the link has dropped, we want to know about it. */
 376        err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr);
 377        if (err) {
 378                dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
 379                return;
 380        }
 381
 382        dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS));
 383}
 384
 385irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
 386                                        int lane)
 387{
 388        irqreturn_t ret = IRQ_NONE;
 389        u16 status;
 390        int err;
 391
 392        err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_INT_STATUS, &status);
 393        if (err)
 394                return ret;
 395
 396        if (status & MV88E6352_SERDES_INT_LINK_CHANGE) {
 397                ret = IRQ_HANDLED;
 398                mv88e6352_serdes_irq_link(chip, port);
 399        }
 400
 401        return ret;
 402}
 403
 404int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
 405                                bool enable)
 406{
 407        u16 val = 0;
 408
 409        if (enable)
 410                val |= MV88E6352_SERDES_INT_LINK_CHANGE;
 411
 412        return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, val);
 413}
 414
 415unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
 416{
 417        return irq_find_mapping(chip->g2_irq.domain, MV88E6352_SERDES_IRQ);
 418}
 419
 420int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
 421{
 422        int err;
 423
 424        mv88e6xxx_reg_lock(chip);
 425        err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
 426        mv88e6xxx_reg_unlock(chip);
 427        if (err <= 0)
 428                return err;
 429
 430        return 32 * sizeof(u16);
 431}
 432
 433void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
 434{
 435        u16 *p = _p;
 436        u16 reg;
 437        int err;
 438        int i;
 439
 440        err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
 441        if (err <= 0)
 442                return;
 443
 444        for (i = 0 ; i < 32; i++) {
 445                err = mv88e6352_serdes_read(chip, i, &reg);
 446                if (!err)
 447                        p[i] = reg;
 448        }
 449}
 450
 451int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
 452{
 453        u8 cmode = chip->ports[port].cmode;
 454        int lane = -ENODEV;
 455
 456        switch (port) {
 457        case 5:
 458                if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
 459                    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
 460                    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
 461                        lane = MV88E6341_PORT5_LANE;
 462                break;
 463        }
 464
 465        return lane;
 466}
 467
 468int mv88e6185_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
 469                           bool up)
 470{
 471        /* The serdes power can't be controlled on this switch chip but we need
 472         * to supply this function to avoid returning -EOPNOTSUPP in
 473         * mv88e6xxx_serdes_power_up/mv88e6xxx_serdes_power_down
 474         */
 475        return 0;
 476}
 477
 478int mv88e6185_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
 479{
 480        /* There are no configurable serdes lanes on this switch chip but we
 481         * need to return a non-negative lane number so that callers of
 482         * mv88e6xxx_serdes_get_lane() know this is a serdes port.
 483         */
 484        switch (chip->ports[port].cmode) {
 485        case MV88E6185_PORT_STS_CMODE_SERDES:
 486        case MV88E6185_PORT_STS_CMODE_1000BASE_X:
 487                return 0;
 488        default:
 489                return -ENODEV;
 490        }
 491}
 492
 493int mv88e6185_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
 494                                   int lane, struct phylink_link_state *state)
 495{
 496        int err;
 497        u16 status;
 498
 499        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status);
 500        if (err)
 501                return err;
 502
 503        state->link = !!(status & MV88E6XXX_PORT_STS_LINK);
 504
 505        if (state->link) {
 506                state->duplex = status & MV88E6XXX_PORT_STS_DUPLEX ? DUPLEX_FULL : DUPLEX_HALF;
 507
 508                switch (status &  MV88E6XXX_PORT_STS_SPEED_MASK) {
 509                case MV88E6XXX_PORT_STS_SPEED_1000:
 510                        state->speed = SPEED_1000;
 511                        break;
 512                case MV88E6XXX_PORT_STS_SPEED_100:
 513                        state->speed = SPEED_100;
 514                        break;
 515                case MV88E6XXX_PORT_STS_SPEED_10:
 516                        state->speed = SPEED_10;
 517                        break;
 518                default:
 519                        dev_err(chip->dev, "invalid PHY speed\n");
 520                        return -EINVAL;
 521                }
 522        } else {
 523                state->duplex = DUPLEX_UNKNOWN;
 524                state->speed = SPEED_UNKNOWN;
 525        }
 526
 527        return 0;
 528}
 529
 530int mv88e6097_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
 531                                bool enable)
 532{
 533        u8 cmode = chip->ports[port].cmode;
 534
 535        /* The serdes interrupts are enabled in the G2_INT_MASK register. We
 536         * need to return 0 to avoid returning -EOPNOTSUPP in
 537         * mv88e6xxx_serdes_irq_enable/mv88e6xxx_serdes_irq_disable
 538         */
 539        switch (cmode) {
 540        case MV88E6185_PORT_STS_CMODE_SERDES:
 541        case MV88E6185_PORT_STS_CMODE_1000BASE_X:
 542                return 0;
 543        }
 544
 545        return -EOPNOTSUPP;
 546}
 547
 548static void mv88e6097_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
 549{
 550        u16 status;
 551        int err;
 552
 553        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status);
 554        if (err) {
 555                dev_err(chip->dev, "can't read port status: %d\n", err);
 556                return;
 557        }
 558
 559        dsa_port_phylink_mac_change(chip->ds, port, !!(status & MV88E6XXX_PORT_STS_LINK));
 560}
 561
 562irqreturn_t mv88e6097_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
 563                                        int lane)
 564{
 565        u8 cmode = chip->ports[port].cmode;
 566
 567        switch (cmode) {
 568        case MV88E6185_PORT_STS_CMODE_SERDES:
 569        case MV88E6185_PORT_STS_CMODE_1000BASE_X:
 570                mv88e6097_serdes_irq_link(chip, port);
 571                return IRQ_HANDLED;
 572        }
 573
 574        return IRQ_NONE;
 575}
 576
 577int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
 578{
 579        u8 cmode = chip->ports[port].cmode;
 580        int lane = -ENODEV;
 581
 582        switch (port) {
 583        case 9:
 584                if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
 585                    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
 586                    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
 587                        lane = MV88E6390_PORT9_LANE0;
 588                break;
 589        case 10:
 590                if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
 591                    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
 592                    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
 593                        lane = MV88E6390_PORT10_LANE0;
 594                break;
 595        }
 596
 597        return lane;
 598}
 599
 600int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
 601{
 602        u8 cmode_port = chip->ports[port].cmode;
 603        u8 cmode_port10 = chip->ports[10].cmode;
 604        u8 cmode_port9 = chip->ports[9].cmode;
 605        int lane = -ENODEV;
 606
 607        switch (port) {
 608        case 2:
 609                if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
 610                    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
 611                    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
 612                        if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
 613                                lane = MV88E6390_PORT9_LANE1;
 614                break;
 615        case 3:
 616                if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
 617                    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
 618                    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
 619                    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
 620                        if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
 621                                lane = MV88E6390_PORT9_LANE2;
 622                break;
 623        case 4:
 624                if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
 625                    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
 626                    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
 627                    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
 628                        if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
 629                                lane = MV88E6390_PORT9_LANE3;
 630                break;
 631        case 5:
 632                if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
 633                    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
 634                    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
 635                        if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
 636                                lane = MV88E6390_PORT10_LANE1;
 637                break;
 638        case 6:
 639                if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
 640                    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
 641                    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
 642                    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
 643                        if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
 644                                lane = MV88E6390_PORT10_LANE2;
 645                break;
 646        case 7:
 647                if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
 648                    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
 649                    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
 650                    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
 651                        if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
 652                                lane = MV88E6390_PORT10_LANE3;
 653                break;
 654        case 9:
 655                if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
 656                    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
 657                    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
 658                    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
 659                    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
 660                        lane = MV88E6390_PORT9_LANE0;
 661                break;
 662        case 10:
 663                if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
 664                    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
 665                    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
 666                    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
 667                    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
 668                        lane = MV88E6390_PORT10_LANE0;
 669                break;
 670        }
 671
 672        return lane;
 673}
 674
 675/* Only Ports 0, 9 and 10 have SERDES lanes. Return the SERDES lane address
 676 * a port is using else Returns -ENODEV.
 677 */
 678int mv88e6393x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
 679{
 680        u8 cmode = chip->ports[port].cmode;
 681        int lane = -ENODEV;
 682
 683        if (port != 0 && port != 9 && port != 10)
 684                return -EOPNOTSUPP;
 685
 686        if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
 687            cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
 688            cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
 689            cmode == MV88E6393X_PORT_STS_CMODE_5GBASER ||
 690            cmode == MV88E6393X_PORT_STS_CMODE_10GBASER)
 691                lane = port;
 692
 693        return lane;
 694}
 695
 696/* Set power up/down for 10GBASE-R and 10GBASE-X4/X2 */
 697static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, int lane,
 698                                      bool up)
 699{
 700        u16 val, new_val;
 701        int err;
 702
 703        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
 704                                    MV88E6390_10G_CTRL1, &val);
 705
 706        if (err)
 707                return err;
 708
 709        if (up)
 710                new_val = val & ~(MDIO_CTRL1_RESET |
 711                                  MDIO_PCS_CTRL1_LOOPBACK |
 712                                  MDIO_CTRL1_LPOWER);
 713        else
 714                new_val = val | MDIO_CTRL1_LPOWER;
 715
 716        if (val != new_val)
 717                err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
 718                                             MV88E6390_10G_CTRL1, new_val);
 719
 720        return err;
 721}
 722
 723/* Set power up/down for SGMII and 1000Base-X */
 724static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, int lane,
 725                                        bool up)
 726{
 727        u16 val, new_val;
 728        int err;
 729
 730        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
 731                                    MV88E6390_SGMII_BMCR, &val);
 732        if (err)
 733                return err;
 734
 735        if (up)
 736                new_val = val & ~(BMCR_RESET | BMCR_LOOPBACK | BMCR_PDOWN);
 737        else
 738                new_val = val | BMCR_PDOWN;
 739
 740        if (val != new_val)
 741                err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
 742                                             MV88E6390_SGMII_BMCR, new_val);
 743
 744        return err;
 745}
 746
 747struct mv88e6390_serdes_hw_stat {
 748        char string[ETH_GSTRING_LEN];
 749        int reg;
 750};
 751
 752static struct mv88e6390_serdes_hw_stat mv88e6390_serdes_hw_stats[] = {
 753        { "serdes_rx_pkts", 0xf021 },
 754        { "serdes_rx_bytes", 0xf024 },
 755        { "serdes_rx_pkts_error", 0xf027 },
 756};
 757
 758int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
 759{
 760        if (mv88e6xxx_serdes_get_lane(chip, port) < 0)
 761                return 0;
 762
 763        return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
 764}
 765
 766int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip,
 767                                 int port, uint8_t *data)
 768{
 769        struct mv88e6390_serdes_hw_stat *stat;
 770        int i;
 771
 772        if (mv88e6xxx_serdes_get_lane(chip, port) < 0)
 773                return 0;
 774
 775        for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
 776                stat = &mv88e6390_serdes_hw_stats[i];
 777                memcpy(data + i * ETH_GSTRING_LEN, stat->string,
 778                       ETH_GSTRING_LEN);
 779        }
 780        return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
 781}
 782
 783static uint64_t mv88e6390_serdes_get_stat(struct mv88e6xxx_chip *chip, int lane,
 784                                          struct mv88e6390_serdes_hw_stat *stat)
 785{
 786        u16 reg[3];
 787        int err, i;
 788
 789        for (i = 0; i < 3; i++) {
 790                err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
 791                                            stat->reg + i, &reg[i]);
 792                if (err) {
 793                        dev_err(chip->dev, "failed to read statistic\n");
 794                        return 0;
 795                }
 796        }
 797
 798        return reg[0] | ((u64)reg[1] << 16) | ((u64)reg[2] << 32);
 799}
 800
 801int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
 802                               uint64_t *data)
 803{
 804        struct mv88e6390_serdes_hw_stat *stat;
 805        int lane;
 806        int i;
 807
 808        lane = mv88e6xxx_serdes_get_lane(chip, port);
 809        if (lane < 0)
 810                return 0;
 811
 812        for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
 813                stat = &mv88e6390_serdes_hw_stats[i];
 814                data[i] = mv88e6390_serdes_get_stat(chip, lane, stat);
 815        }
 816
 817        return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
 818}
 819
 820static int mv88e6390_serdes_enable_checker(struct mv88e6xxx_chip *chip, int lane)
 821{
 822        u16 reg;
 823        int err;
 824
 825        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
 826                                    MV88E6390_PG_CONTROL, &reg);
 827        if (err)
 828                return err;
 829
 830        reg |= MV88E6390_PG_CONTROL_ENABLE_PC;
 831        return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
 832                                      MV88E6390_PG_CONTROL, reg);
 833}
 834
 835int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
 836                           bool up)
 837{
 838        u8 cmode = chip->ports[port].cmode;
 839        int err;
 840
 841        switch (cmode) {
 842        case MV88E6XXX_PORT_STS_CMODE_SGMII:
 843        case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
 844        case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
 845                err = mv88e6390_serdes_power_sgmii(chip, lane, up);
 846                break;
 847        case MV88E6XXX_PORT_STS_CMODE_XAUI:
 848        case MV88E6XXX_PORT_STS_CMODE_RXAUI:
 849                err = mv88e6390_serdes_power_10g(chip, lane, up);
 850                break;
 851        default:
 852                err = -EINVAL;
 853                break;
 854        }
 855
 856        if (!err && up)
 857                err = mv88e6390_serdes_enable_checker(chip, lane);
 858
 859        return err;
 860}
 861
 862int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
 863                                int lane, unsigned int mode,
 864                                phy_interface_t interface,
 865                                const unsigned long *advertise)
 866{
 867        u16 val, bmcr, adv;
 868        bool changed;
 869        int err;
 870
 871        switch (interface) {
 872        case PHY_INTERFACE_MODE_SGMII:
 873                adv = 0x0001;
 874                break;
 875
 876        case PHY_INTERFACE_MODE_1000BASEX:
 877                adv = linkmode_adv_to_mii_adv_x(advertise,
 878                                        ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
 879                break;
 880
 881        case PHY_INTERFACE_MODE_2500BASEX:
 882                adv = linkmode_adv_to_mii_adv_x(advertise,
 883                                        ETHTOOL_LINK_MODE_2500baseX_Full_BIT);
 884                break;
 885
 886        default:
 887                return 0;
 888        }
 889
 890        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
 891                                    MV88E6390_SGMII_ADVERTISE, &val);
 892        if (err)
 893                return err;
 894
 895        changed = val != adv;
 896        if (changed) {
 897                err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
 898                                             MV88E6390_SGMII_ADVERTISE, adv);
 899                if (err)
 900                        return err;
 901        }
 902
 903        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
 904                                    MV88E6390_SGMII_BMCR, &val);
 905        if (err)
 906                return err;
 907
 908        if (phylink_autoneg_inband(mode))
 909                bmcr = val | BMCR_ANENABLE;
 910        else
 911                bmcr = val & ~BMCR_ANENABLE;
 912
 913        /* setting ANENABLE triggers a restart of negotiation */
 914        if (bmcr == val)
 915                return changed;
 916
 917        return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
 918                                      MV88E6390_SGMII_BMCR, bmcr);
 919}
 920
 921static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
 922        int port, int lane, struct phylink_link_state *state)
 923{
 924        u16 bmsr, lpa, status;
 925        int err;
 926
 927        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
 928                                    MV88E6390_SGMII_BMSR, &bmsr);
 929        if (err) {
 930                dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err);
 931                return err;
 932        }
 933
 934        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
 935                                    MV88E6390_SGMII_PHY_STATUS, &status);
 936        if (err) {
 937                dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err);
 938                return err;
 939        }
 940
 941        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
 942                                    MV88E6390_SGMII_LPA, &lpa);
 943        if (err) {
 944                dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err);
 945                return err;
 946        }
 947
 948        return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state);
 949}
 950
 951static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
 952        int port, int lane, struct phylink_link_state *state)
 953{
 954        u16 status;
 955        int err;
 956
 957        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
 958                                    MV88E6390_10G_STAT1, &status);
 959        if (err)
 960                return err;
 961
 962        state->link = !!(status & MDIO_STAT1_LSTATUS);
 963        if (state->link) {
 964                state->speed = SPEED_10000;
 965                state->duplex = DUPLEX_FULL;
 966        }
 967
 968        return 0;
 969}
 970
 971static int mv88e6393x_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
 972                                               int port, int lane,
 973                                               struct phylink_link_state *state)
 974{
 975        u16 status;
 976        int err;
 977
 978        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
 979                                    MV88E6390_10G_STAT1, &status);
 980        if (err)
 981                return err;
 982
 983        state->link = !!(status & MDIO_STAT1_LSTATUS);
 984        if (state->link) {
 985                if (state->interface == PHY_INTERFACE_MODE_5GBASER)
 986                        state->speed = SPEED_5000;
 987                else
 988                        state->speed = SPEED_10000;
 989                state->duplex = DUPLEX_FULL;
 990        }
 991
 992        return 0;
 993}
 994
 995int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
 996                                   int lane, struct phylink_link_state *state)
 997{
 998        switch (state->interface) {
 999        case PHY_INTERFACE_MODE_SGMII:
1000        case PHY_INTERFACE_MODE_1000BASEX:
1001        case PHY_INTERFACE_MODE_2500BASEX:
1002                return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane,
1003                                                            state);
1004        case PHY_INTERFACE_MODE_XAUI:
1005        case PHY_INTERFACE_MODE_RXAUI:
1006                return mv88e6390_serdes_pcs_get_state_10g(chip, port, lane,
1007                                                          state);
1008
1009        default:
1010                return -EOPNOTSUPP;
1011        }
1012}
1013
1014int mv88e6393x_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
1015                                    int lane, struct phylink_link_state *state)
1016{
1017        switch (state->interface) {
1018        case PHY_INTERFACE_MODE_SGMII:
1019        case PHY_INTERFACE_MODE_1000BASEX:
1020        case PHY_INTERFACE_MODE_2500BASEX:
1021                return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane,
1022                                                            state);
1023        case PHY_INTERFACE_MODE_5GBASER:
1024        case PHY_INTERFACE_MODE_10GBASER:
1025                return mv88e6393x_serdes_pcs_get_state_10g(chip, port, lane,
1026                                                           state);
1027
1028        default:
1029                return -EOPNOTSUPP;
1030        }
1031}
1032
1033int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
1034                                    int lane)
1035{
1036        u16 bmcr;
1037        int err;
1038
1039        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1040                                    MV88E6390_SGMII_BMCR, &bmcr);
1041        if (err)
1042                return err;
1043
1044        return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1045                                      MV88E6390_SGMII_BMCR,
1046                                      bmcr | BMCR_ANRESTART);
1047}
1048
1049int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
1050                                 int lane, int speed, int duplex)
1051{
1052        u16 val, bmcr;
1053        int err;
1054
1055        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1056                                    MV88E6390_SGMII_BMCR, &val);
1057        if (err)
1058                return err;
1059
1060        bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000);
1061        switch (speed) {
1062        case SPEED_2500:
1063        case SPEED_1000:
1064                bmcr |= BMCR_SPEED1000;
1065                break;
1066        case SPEED_100:
1067                bmcr |= BMCR_SPEED100;
1068                break;
1069        case SPEED_10:
1070                break;
1071        }
1072
1073        if (duplex == DUPLEX_FULL)
1074                bmcr |= BMCR_FULLDPLX;
1075
1076        if (bmcr == val)
1077                return 0;
1078
1079        return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1080                                      MV88E6390_SGMII_BMCR, bmcr);
1081}
1082
1083static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip,
1084                                            int port, int lane)
1085{
1086        u16 bmsr;
1087        int err;
1088
1089        /* If the link has dropped, we want to know about it. */
1090        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1091                                    MV88E6390_SGMII_BMSR, &bmsr);
1092        if (err) {
1093                dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
1094                return;
1095        }
1096
1097        dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS));
1098}
1099
1100static void mv88e6393x_serdes_irq_link_10g(struct mv88e6xxx_chip *chip,
1101                                           int port, u8 lane)
1102{
1103        u16 status;
1104        int err;
1105
1106        /* If the link has dropped, we want to know about it. */
1107        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1108                                    MV88E6390_10G_STAT1, &status);
1109        if (err) {
1110                dev_err(chip->dev, "can't read Serdes STAT1: %d\n", err);
1111                return;
1112        }
1113
1114        dsa_port_phylink_mac_change(chip->ds, port, !!(status & MDIO_STAT1_LSTATUS));
1115}
1116
1117static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip,
1118                                             int lane, bool enable)
1119{
1120        u16 val = 0;
1121
1122        if (enable)
1123                val |= MV88E6390_SGMII_INT_LINK_DOWN |
1124                        MV88E6390_SGMII_INT_LINK_UP;
1125
1126        return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1127                                      MV88E6390_SGMII_INT_ENABLE, val);
1128}
1129
1130int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
1131                                bool enable)
1132{
1133        u8 cmode = chip->ports[port].cmode;
1134
1135        switch (cmode) {
1136        case MV88E6XXX_PORT_STS_CMODE_SGMII:
1137        case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1138        case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1139                return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable);
1140        }
1141
1142        return 0;
1143}
1144
1145static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip,
1146                                             int lane, u16 *status)
1147{
1148        int err;
1149
1150        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1151                                    MV88E6390_SGMII_INT_STATUS, status);
1152
1153        return err;
1154}
1155
1156static int mv88e6393x_serdes_irq_enable_10g(struct mv88e6xxx_chip *chip,
1157                                            u8 lane, bool enable)
1158{
1159        u16 val = 0;
1160
1161        if (enable)
1162                val |= MV88E6393X_10G_INT_LINK_CHANGE;
1163
1164        return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1165                                      MV88E6393X_10G_INT_ENABLE, val);
1166}
1167
1168int mv88e6393x_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port,
1169                                 int lane, bool enable)
1170{
1171        u8 cmode = chip->ports[port].cmode;
1172
1173        switch (cmode) {
1174        case MV88E6XXX_PORT_STS_CMODE_SGMII:
1175        case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1176        case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1177                return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable);
1178        case MV88E6393X_PORT_STS_CMODE_5GBASER:
1179        case MV88E6393X_PORT_STS_CMODE_10GBASER:
1180                return mv88e6393x_serdes_irq_enable_10g(chip, lane, enable);
1181        }
1182
1183        return 0;
1184}
1185
1186static int mv88e6393x_serdes_irq_status_10g(struct mv88e6xxx_chip *chip,
1187                                            u8 lane, u16 *status)
1188{
1189        int err;
1190
1191        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1192                                    MV88E6393X_10G_INT_STATUS, status);
1193
1194        return err;
1195}
1196
1197irqreturn_t mv88e6393x_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
1198                                         int lane)
1199{
1200        u8 cmode = chip->ports[port].cmode;
1201        irqreturn_t ret = IRQ_NONE;
1202        u16 status;
1203        int err;
1204
1205        switch (cmode) {
1206        case MV88E6XXX_PORT_STS_CMODE_SGMII:
1207        case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1208        case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1209                err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
1210                if (err)
1211                        return ret;
1212                if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
1213                              MV88E6390_SGMII_INT_LINK_UP)) {
1214                        ret = IRQ_HANDLED;
1215                        mv88e6390_serdes_irq_link_sgmii(chip, port, lane);
1216                }
1217                break;
1218        case MV88E6393X_PORT_STS_CMODE_5GBASER:
1219        case MV88E6393X_PORT_STS_CMODE_10GBASER:
1220                err = mv88e6393x_serdes_irq_status_10g(chip, lane, &status);
1221                if (err)
1222                        return err;
1223                if (status & MV88E6393X_10G_INT_LINK_CHANGE) {
1224                        ret = IRQ_HANDLED;
1225                        mv88e6393x_serdes_irq_link_10g(chip, port, lane);
1226                }
1227                break;
1228        }
1229
1230        return ret;
1231}
1232
1233irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
1234                                        int lane)
1235{
1236        u8 cmode = chip->ports[port].cmode;
1237        irqreturn_t ret = IRQ_NONE;
1238        u16 status;
1239        int err;
1240
1241        switch (cmode) {
1242        case MV88E6XXX_PORT_STS_CMODE_SGMII:
1243        case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1244        case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1245                err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
1246                if (err)
1247                        return ret;
1248                if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
1249                              MV88E6390_SGMII_INT_LINK_UP)) {
1250                        ret = IRQ_HANDLED;
1251                        mv88e6390_serdes_irq_link_sgmii(chip, port, lane);
1252                }
1253        }
1254
1255        return ret;
1256}
1257
1258unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
1259{
1260        return irq_find_mapping(chip->g2_irq.domain, port);
1261}
1262
1263static const u16 mv88e6390_serdes_regs[] = {
1264        /* SERDES common registers */
1265        0xf00a, 0xf00b, 0xf00c,
1266        0xf010, 0xf011, 0xf012, 0xf013,
1267        0xf016, 0xf017, 0xf018,
1268        0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
1269        0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
1270        0xf028, 0xf029,
1271        0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
1272        0xf038, 0xf039,
1273        /* SGMII */
1274        0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007,
1275        0x2008,
1276        0x200f,
1277        0xa000, 0xa001, 0xa002, 0xa003,
1278        /* 10Gbase-X */
1279        0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
1280        0x1008,
1281        0x100e, 0x100f,
1282        0x1018, 0x1019,
1283        0x9000, 0x9001, 0x9002, 0x9003, 0x9004,
1284        0x9006,
1285        0x9010, 0x9011, 0x9012, 0x9013, 0x9014, 0x9015, 0x9016,
1286        /* 10Gbase-R */
1287        0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027,
1288        0x1028, 0x1029, 0x102a, 0x102b,
1289};
1290
1291int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
1292{
1293        if (mv88e6xxx_serdes_get_lane(chip, port) < 0)
1294                return 0;
1295
1296        return ARRAY_SIZE(mv88e6390_serdes_regs) * sizeof(u16);
1297}
1298
1299void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
1300{
1301        u16 *p = _p;
1302        int lane;
1303        u16 reg;
1304        int err;
1305        int i;
1306
1307        lane = mv88e6xxx_serdes_get_lane(chip, port);
1308        if (lane < 0)
1309                return;
1310
1311        for (i = 0 ; i < ARRAY_SIZE(mv88e6390_serdes_regs); i++) {
1312                err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1313                                            mv88e6390_serdes_regs[i], &reg);
1314                if (!err)
1315                        p[i] = reg;
1316        }
1317}
1318
1319static const int mv88e6352_serdes_p2p_to_reg[] = {
1320        /* Index of value in microvolts corresponds to the register value */
1321        14000, 112000, 210000, 308000, 406000, 504000, 602000, 700000,
1322};
1323
1324int mv88e6352_serdes_set_tx_amplitude(struct mv88e6xxx_chip *chip, int port,
1325                                      int val)
1326{
1327        bool found = false;
1328        u16 ctrl, reg;
1329        int err;
1330        int i;
1331
1332        err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
1333        if (err <= 0)
1334                return err;
1335
1336        for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_p2p_to_reg); ++i) {
1337                if (mv88e6352_serdes_p2p_to_reg[i] == val) {
1338                        reg = i;
1339                        found = true;
1340                        break;
1341                }
1342        }
1343
1344        if (!found)
1345                return -EINVAL;
1346
1347        err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_SPEC_CTRL2, &ctrl);
1348        if (err)
1349                return err;
1350
1351        ctrl &= ~MV88E6352_SERDES_OUT_AMP_MASK;
1352        ctrl |= reg;
1353
1354        return mv88e6352_serdes_write(chip, MV88E6352_SERDES_SPEC_CTRL2, ctrl);
1355}
1356
1357static int mv88e6393x_serdes_power_lane(struct mv88e6xxx_chip *chip, int lane,
1358                                        bool on)
1359{
1360        u16 reg;
1361        int err;
1362
1363        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1364                                    MV88E6393X_SERDES_CTRL1, &reg);
1365        if (err)
1366                return err;
1367
1368        if (on)
1369                reg &= ~(MV88E6393X_SERDES_CTRL1_TX_PDOWN |
1370                         MV88E6393X_SERDES_CTRL1_RX_PDOWN);
1371        else
1372                reg |= MV88E6393X_SERDES_CTRL1_TX_PDOWN |
1373                       MV88E6393X_SERDES_CTRL1_RX_PDOWN;
1374
1375        return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1376                                      MV88E6393X_SERDES_CTRL1, reg);
1377}
1378
1379static int mv88e6393x_serdes_erratum_4_6(struct mv88e6xxx_chip *chip, int lane)
1380{
1381        u16 reg;
1382        int err;
1383
1384        /* mv88e6393x family errata 4.6:
1385         * Cannot clear PwrDn bit on SERDES if device is configured CPU_MGD
1386         * mode or P0_mode is configured for [x]MII.
1387         * Workaround: Set SERDES register 4.F002 bit 5=0 and bit 15=1.
1388         *
1389         * It seems that after this workaround the SERDES is automatically
1390         * powered up (the bit is cleared), so power it down.
1391         */
1392        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1393                                    MV88E6393X_SERDES_POC, &reg);
1394        if (err)
1395                return err;
1396
1397        reg &= ~MV88E6393X_SERDES_POC_PDOWN;
1398        reg |= MV88E6393X_SERDES_POC_RESET;
1399
1400        err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1401                                     MV88E6393X_SERDES_POC, reg);
1402        if (err)
1403                return err;
1404
1405        err = mv88e6390_serdes_power_sgmii(chip, lane, false);
1406        if (err)
1407                return err;
1408
1409        return mv88e6393x_serdes_power_lane(chip, lane, false);
1410}
1411
1412int mv88e6393x_serdes_setup_errata(struct mv88e6xxx_chip *chip)
1413{
1414        int err;
1415
1416        err = mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT0_LANE);
1417        if (err)
1418                return err;
1419
1420        err = mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT9_LANE);
1421        if (err)
1422                return err;
1423
1424        return mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT10_LANE);
1425}
1426
1427static int mv88e6393x_serdes_erratum_4_8(struct mv88e6xxx_chip *chip, int lane)
1428{
1429        u16 reg, pcs;
1430        int err;
1431
1432        /* mv88e6393x family errata 4.8:
1433         * When a SERDES port is operating in 1000BASE-X or SGMII mode link may
1434         * not come up after hardware reset or software reset of SERDES core.
1435         * Workaround is to write SERDES register 4.F074.14=1 for only those
1436         * modes and 0 in all other modes.
1437         */
1438        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1439                                    MV88E6393X_SERDES_POC, &pcs);
1440        if (err)
1441                return err;
1442
1443        pcs &= MV88E6393X_SERDES_POC_PCS_MASK;
1444
1445        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1446                                    MV88E6393X_ERRATA_4_8_REG, &reg);
1447        if (err)
1448                return err;
1449
1450        if (pcs == MV88E6393X_SERDES_POC_PCS_1000BASEX ||
1451            pcs == MV88E6393X_SERDES_POC_PCS_SGMII_PHY ||
1452            pcs == MV88E6393X_SERDES_POC_PCS_SGMII_MAC)
1453                reg |= MV88E6393X_ERRATA_4_8_BIT;
1454        else
1455                reg &= ~MV88E6393X_ERRATA_4_8_BIT;
1456
1457        return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1458                                      MV88E6393X_ERRATA_4_8_REG, reg);
1459}
1460
1461static int mv88e6393x_serdes_erratum_5_2(struct mv88e6xxx_chip *chip, int lane,
1462                                         u8 cmode)
1463{
1464        static const struct {
1465                u16 dev, reg, val, mask;
1466        } fixes[] = {
1467                { MDIO_MMD_VEND1, 0x8093, 0xcb5a, 0xffff },
1468                { MDIO_MMD_VEND1, 0x8171, 0x7088, 0xffff },
1469                { MDIO_MMD_VEND1, 0x80c9, 0x311a, 0xffff },
1470                { MDIO_MMD_VEND1, 0x80a2, 0x8000, 0xff7f },
1471                { MDIO_MMD_VEND1, 0x80a9, 0x0000, 0xfff0 },
1472                { MDIO_MMD_VEND1, 0x80a3, 0x0000, 0xf8ff },
1473                { MDIO_MMD_PHYXS, MV88E6393X_SERDES_POC,
1474                  MV88E6393X_SERDES_POC_RESET, MV88E6393X_SERDES_POC_RESET },
1475        };
1476        int err, i;
1477        u16 reg;
1478
1479        /* mv88e6393x family errata 5.2:
1480         * For optimal signal integrity the following sequence should be applied
1481         * to SERDES operating in 10G mode. These registers only apply to 10G
1482         * operation and have no effect on other speeds.
1483         */
1484        if (cmode != MV88E6393X_PORT_STS_CMODE_10GBASER)
1485                return 0;
1486
1487        for (i = 0; i < ARRAY_SIZE(fixes); ++i) {
1488                err = mv88e6390_serdes_read(chip, lane, fixes[i].dev,
1489                                            fixes[i].reg, &reg);
1490                if (err)
1491                        return err;
1492
1493                reg &= ~fixes[i].mask;
1494                reg |= fixes[i].val;
1495
1496                err = mv88e6390_serdes_write(chip, lane, fixes[i].dev,
1497                                             fixes[i].reg, reg);
1498                if (err)
1499                        return err;
1500        }
1501
1502        return 0;
1503}
1504
1505static int mv88e6393x_serdes_fix_2500basex_an(struct mv88e6xxx_chip *chip,
1506                                              int lane, u8 cmode, bool on)
1507{
1508        u16 reg;
1509        int err;
1510
1511        if (cmode != MV88E6XXX_PORT_STS_CMODE_2500BASEX)
1512                return 0;
1513
1514        /* Inband AN is broken on Amethyst in 2500base-x mode when set by
1515         * standard mechanism (via cmode).
1516         * We can get around this by configuring the PCS mode to 1000base-x
1517         * and then writing value 0x58 to register 1e.8000. (This must be done
1518         * while SerDes receiver and transmitter are disabled, which is, when
1519         * this function is called.)
1520         * It seem that when we do this configuration to 2500base-x mode (by
1521         * changing PCS mode to 1000base-x and frequency to 3.125 GHz from
1522         * 1.25 GHz) and then configure to sgmii or 1000base-x, the device
1523         * thinks that it already has SerDes at 1.25 GHz and does not change
1524         * the 1e.8000 register, leaving SerDes at 3.125 GHz.
1525         * To avoid this, change PCS mode back to 2500base-x when disabling
1526         * SerDes from 2500base-x mode.
1527         */
1528        err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
1529                                    MV88E6393X_SERDES_POC, &reg);
1530        if (err)
1531                return err;
1532
1533        reg &= ~(MV88E6393X_SERDES_POC_PCS_MASK | MV88E6393X_SERDES_POC_AN);
1534        if (on)
1535                reg |= MV88E6393X_SERDES_POC_PCS_1000BASEX |
1536                       MV88E6393X_SERDES_POC_AN;
1537        else
1538                reg |= MV88E6393X_SERDES_POC_PCS_2500BASEX;
1539        reg |= MV88E6393X_SERDES_POC_RESET;
1540
1541        err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
1542                                     MV88E6393X_SERDES_POC, reg);
1543        if (err)
1544                return err;
1545
1546        err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_VEND1, 0x8000, 0x58);
1547        if (err)
1548                return err;
1549
1550        return 0;
1551}
1552
1553int mv88e6393x_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
1554                            bool on)
1555{
1556        u8 cmode = chip->ports[port].cmode;
1557        int err;
1558
1559        if (port != 0 && port != 9 && port != 10)
1560                return -EOPNOTSUPP;
1561
1562        if (on) {
1563                err = mv88e6393x_serdes_erratum_4_8(chip, lane);
1564                if (err)
1565                        return err;
1566
1567                err = mv88e6393x_serdes_erratum_5_2(chip, lane, cmode);
1568                if (err)
1569                        return err;
1570
1571                err = mv88e6393x_serdes_fix_2500basex_an(chip, lane, cmode,
1572                                                         true);
1573                if (err)
1574                        return err;
1575
1576                err = mv88e6393x_serdes_power_lane(chip, lane, true);
1577                if (err)
1578                        return err;
1579        }
1580
1581        switch (cmode) {
1582        case MV88E6XXX_PORT_STS_CMODE_SGMII:
1583        case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
1584        case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
1585                err = mv88e6390_serdes_power_sgmii(chip, lane, on);
1586                break;
1587        case MV88E6393X_PORT_STS_CMODE_5GBASER:
1588        case MV88E6393X_PORT_STS_CMODE_10GBASER:
1589                err = mv88e6390_serdes_power_10g(chip, lane, on);
1590                break;
1591        default:
1592                err = -EINVAL;
1593                break;
1594        }
1595
1596        if (err)
1597                return err;
1598
1599        if (!on) {
1600                err = mv88e6393x_serdes_power_lane(chip, lane, false);
1601                if (err)
1602                        return err;
1603
1604                err = mv88e6393x_serdes_fix_2500basex_an(chip, lane, cmode,
1605                                                         false);
1606        }
1607
1608        return err;
1609}
1610