cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

serdes.c (40267B)


      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}