linux/drivers/net/dsa/mv88e6xxx/pcs-639x.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Marvell 88E6352 family SERDES PCS support
 *
 * Copyright (c) 2008 Marvell Semiconductor
 *
 * Copyright (c) 2017 Andrew Lunn <[email protected]>
 */
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/mii.h>

#include "chip.h"
#include "global2.h"
#include "phy.h"
#include "port.h"
#include "serdes.h"

struct mv88e639x_pcs {};

static int mv88e639x_read(struct mv88e639x_pcs *mpcs, u16 regnum, u16 *val)
{}

static int mv88e639x_write(struct mv88e639x_pcs *mpcs, u16 regnum, u16 val)
{}

static int mv88e639x_modify(struct mv88e639x_pcs *mpcs, u16 regnum, u16 mask,
			    u16 val)
{}

static int mv88e639x_modify_changed(struct mv88e639x_pcs *mpcs, u16 regnum,
				    u16 mask, u16 set)
{}

static struct mv88e639x_pcs *
mv88e639x_pcs_alloc(struct device *dev, struct mii_bus *bus, unsigned int addr,
		    int port)
{}

static irqreturn_t mv88e639x_pcs_handle_irq(int irq, void *dev_id)
{}

static int mv88e639x_pcs_setup_irq(struct mv88e639x_pcs *mpcs,
				   struct mv88e6xxx_chip *chip, int port)
{}

static void mv88e639x_pcs_teardown(struct mv88e6xxx_chip *chip, int port)
{}

static struct mv88e639x_pcs *sgmii_pcs_to_mv88e639x_pcs(struct phylink_pcs *pcs)
{}

static irqreturn_t mv88e639x_sgmii_handle_irq(struct mv88e639x_pcs *mpcs)
{}

static int mv88e639x_sgmii_pcs_control_irq(struct mv88e639x_pcs *mpcs,
					   bool enable)
{}

static int mv88e639x_sgmii_pcs_control_pwr(struct mv88e639x_pcs *mpcs,
					   bool enable)
{}

static int mv88e639x_sgmii_pcs_enable(struct phylink_pcs *pcs)
{}

static void mv88e639x_sgmii_pcs_disable(struct phylink_pcs *pcs)
{}

static void mv88e639x_sgmii_pcs_pre_config(struct phylink_pcs *pcs,
					   phy_interface_t interface)
{}

static int mv88e6390_erratum_3_14(struct mv88e639x_pcs *mpcs)
{}

static int mv88e639x_sgmii_pcs_post_config(struct phylink_pcs *pcs,
					   phy_interface_t interface)
{}

static void mv88e639x_sgmii_pcs_get_state(struct phylink_pcs *pcs,
					  struct phylink_link_state *state)
{}

static int mv88e639x_sgmii_pcs_config(struct phylink_pcs *pcs,
				      unsigned int neg_mode,
				      phy_interface_t interface,
				      const unsigned long *advertising,
				      bool permit_pause_to_mac)
{}

static void mv88e639x_sgmii_pcs_an_restart(struct phylink_pcs *pcs)
{}

static void mv88e639x_sgmii_pcs_link_up(struct phylink_pcs *pcs,
					unsigned int mode,
					phy_interface_t interface,
					int speed, int duplex)
{}

static const struct phylink_pcs_ops mv88e639x_sgmii_pcs_ops =;

static struct mv88e639x_pcs *xg_pcs_to_mv88e639x_pcs(struct phylink_pcs *pcs)
{}

static int mv88e639x_xg_pcs_enable(struct mv88e639x_pcs *mpcs)
{}

static void mv88e639x_xg_pcs_disable(struct mv88e639x_pcs *mpcs)
{}

static void mv88e639x_xg_pcs_get_state(struct phylink_pcs *pcs,
				       struct phylink_link_state *state)
{}

static int mv88e639x_xg_pcs_config(struct phylink_pcs *pcs,
				   unsigned int neg_mode,
				   phy_interface_t interface,
				   const unsigned long *advertising,
				   bool permit_pause_to_mac)
{}

static struct phylink_pcs *
mv88e639x_pcs_select(struct mv88e6xxx_chip *chip, int port,
		     phy_interface_t mode)
{}

/* Marvell 88E6390 Specific support */

static irqreturn_t mv88e6390_xg_handle_irq(struct mv88e639x_pcs *mpcs)
{}

static int mv88e6390_xg_control_irq(struct mv88e639x_pcs *mpcs, bool enable)
{}

static int mv88e6390_xg_pcs_enable(struct phylink_pcs *pcs)
{}

static void mv88e6390_xg_pcs_disable(struct phylink_pcs *pcs)
{}

static const struct phylink_pcs_ops mv88e6390_xg_pcs_ops =;

static int mv88e6390_pcs_enable_checker(struct mv88e639x_pcs *mpcs)
{}

static int mv88e6390_pcs_init(struct mv88e6xxx_chip *chip, int port)
{}

const struct mv88e6xxx_pcs_ops mv88e6390_pcs_ops =;

/* Marvell 88E6393X Specific support */

static int mv88e6393x_power_lane(struct mv88e639x_pcs *mpcs, bool enable)
{}

/* mv88e6393x family errata 4.6:
 * Cannot clear PwrDn bit on SERDES if device is configured CPU_MGD mode or
 * P0_mode is configured for [x]MII.
 * Workaround: Set SERDES register 4.F002 bit 5=0 and bit 15=1.
 *
 * It seems that after this workaround the SERDES is automatically powered up
 * (the bit is cleared), so power it down.
 */
static int mv88e6393x_erratum_4_6(struct mv88e639x_pcs *mpcs)
{}

/* mv88e6393x family errata 4.8:
 * When a SERDES port is operating in 1000BASE-X or SGMII mode link may not
 * come up after hardware reset or software reset of SERDES core. Workaround
 * is to write SERDES register 4.F074.14=1 for only those modes and 0 in all
 * other modes.
 */
static int mv88e6393x_erratum_4_8(struct mv88e639x_pcs *mpcs)
{}

/* mv88e6393x family errata 5.2:
 * For optimal signal integrity the following sequence should be applied to
 * SERDES operating in 10G mode. These registers only apply to 10G operation
 * and have no effect on other speeds.
 */
static int mv88e6393x_erratum_5_2(struct mv88e639x_pcs *mpcs)
{}

/* Inband AN is broken on Amethyst in 2500base-x mode when set by standard
 * mechanism (via cmode).
 * We can get around this by configuring the PCS mode to 1000base-x and then
 * writing value 0x58 to register 1e.8000. (This must be done while SerDes
 * receiver and transmitter are disabled, which is, when this function is
 * called.)
 * It seem that when we do this configuration to 2500base-x mode (by changing
 * PCS mode to 1000base-x and frequency to 3.125 GHz from 1.25 GHz) and then
 * configure to sgmii or 1000base-x, the device thinks that it already has
 * SerDes at 1.25 GHz and does not change the 1e.8000 register, leaving SerDes
 * at 3.125 GHz.
 * To avoid this, change PCS mode back to 2500base-x when disabling SerDes from
 * 2500base-x mode.
 */
static int mv88e6393x_fix_2500basex_an(struct mv88e639x_pcs *mpcs, bool on)
{}

static int mv88e6393x_sgmii_apply_2500basex_an(struct mv88e639x_pcs *mpcs,
					       phy_interface_t interface,
					       bool enable)
{}

static void mv88e6393x_sgmii_pcs_disable(struct phylink_pcs *pcs)
{}

static void mv88e6393x_sgmii_pcs_pre_config(struct phylink_pcs *pcs,
					    phy_interface_t interface)
{}

static int mv88e6393x_sgmii_pcs_post_config(struct phylink_pcs *pcs,
					    phy_interface_t interface)
{}

static const struct phylink_pcs_ops mv88e6393x_sgmii_pcs_ops =;

static irqreturn_t mv88e6393x_xg_handle_irq(struct mv88e639x_pcs *mpcs)
{}

static int mv88e6393x_xg_control_irq(struct mv88e639x_pcs *mpcs, bool enable)
{}

static int mv88e6393x_xg_pcs_enable(struct phylink_pcs *pcs)
{}

static void mv88e6393x_xg_pcs_disable(struct phylink_pcs *pcs)
{}

/* The PCS has to be powered down while CMODE is changed */
static void mv88e6393x_xg_pcs_pre_config(struct phylink_pcs *pcs,
					 phy_interface_t interface)
{}

static int mv88e6393x_xg_pcs_post_config(struct phylink_pcs *pcs,
					 phy_interface_t interface)
{}

static void mv88e6393x_xg_pcs_get_state(struct phylink_pcs *pcs,
					struct phylink_link_state *state)
{}

static const struct phylink_pcs_ops mv88e6393x_xg_pcs_ops =;

static int mv88e6393x_pcs_init(struct mv88e6xxx_chip *chip, int port)
{}

const struct mv88e6xxx_pcs_ops mv88e6393x_pcs_ops =;