// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Marvell 88E6xxx Switch Port Registers support
*
* Copyright (c) 2008 Marvell Semiconductor
*
* Copyright (c) 2016-2017 Savoir-faire Linux Inc.
* Vivien Didelot <vivien.didelot@savoirfairelinux.com>
*/
#include <linux/bitfield.h>
#include <linux/if_bridge.h>
#include <linux/phy.h>
#include <linux/phylink.h>
#include "chip.h"
#include "port.h"
#include "serdes.h"
int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
u16 *val)
{
int addr = chip->info->port_base_addr + port;
return mv88e6xxx_read(chip, addr, reg, val);
}
int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
u16 val)
{
int addr = chip->info->port_base_addr + port;
return mv88e6xxx_write(chip, addr, reg, val);
}
/* Offset 0x00: MAC (or PCS or Physical) Status Register
*
* For most devices, this is read only. However the 6185 has the MyPause
* bit read/write.
*/
int mv88e6185_port_set_pause(struct mv88e6xxx_chip *chip, int port,
int pause)
{
u16 reg;
int err;
err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
if (err)
return err;
if (pause)
reg |= MV88E6XXX_PORT_STS_MY_PAUSE;
else
reg &= ~MV88E6XXX_PORT_STS_MY_PAUSE;
return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
}
/* Offset 0x01: MAC (or PCS or Physical) Control Register
*
* Link, Duplex and Flow Control have one force bit, one value bit.
*
* For port's MAC speed, ForceSpd (or SpdValue) bits 1:0 program the value.
* Alternative values require the 200BASE (or AltSpeed) bit 12 set.
* Newer chips need a ForcedSpd bit 13 set to consider the value.
*/
static int mv88e6xxx_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
phy_interface_t mode)
{
u16 reg;
int err;
err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
if (err)
return err;
reg &= ~(MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK);
switch (mode)