// SPDX-License-Identifier: GPL-2.0+
/* Microchip Sparx5 Switch driver
 *
 * Copyright (c) 2021 Microchip Technology Inc. and its subsidiaries.
 */

#include <linux/module.h>
#include <linux/phylink.h>
#include <linux/device.h>
#include <linux/netdevice.h>
#include <linux/sfp.h>

#include "sparx5_main_regs.h"
#include "sparx5_main.h"
#include "sparx5_port.h"

static bool port_conf_has_changed(struct sparx5_port_config *a, struct sparx5_port_config *b)
{
	if (a->speed != b->speed ||
	    a->portmode != b->portmode ||
	    a->autoneg != b->autoneg ||
	    a->pause_adv != b->pause_adv ||
	    a->power_down != b->power_down ||
	    a->media != b->media)
		return true;
	return false;
}

static struct phylink_pcs *
sparx5_phylink_mac_select_pcs(struct phylink_config *config,
			      phy_interface_t interface)
{
	struct sparx5_port *port = netdev_priv(to_net_dev(config->dev));

	return &port->phylink_pcs;
}

static void sparx5_phylink_mac_config(struct phylink_config *config,
				      unsigned int mode,
				      const struct phylink_link_state *state)
{
	/* Currently not used */
}

static void sparx5_phylink_mac_link_up(struct phylink_config *config,
				       struct phy_device *phy,
				       unsigned int mode,
				       phy_interface_t interface,
				       int speed, int duplex,
				       bool tx_pause, bool rx_pause)
{
	struct sparx5_port *port = netdev_priv(to_net_dev(config->dev));
	struct sparx5_port_config conf;
	int err;

	conf = port->conf;
	conf.duplex = duplex;
	conf.pause = 0;
	conf.pause |= tx_pause ? MLO_PAUSE_TX : 0;
	conf.pause |= rx_pause ? MLO_PAUSE_RX : 0;
	conf.speed = speed;
	/* Configure the port to speed/duplex/pause */
	err = sparx5_port_config(port->sparx5, port, &conf);
	if (err)
		netdev_err(port->ndev, "port config failed: %d\n", err);
}

static void sparx5_phylink_mac_link_down(struct phylink_config *config,
					 unsigned int mode,
					 phy_interface_t interface)
{
	/* Currently not used */
}

static struct sparx5_port *sparx5_pcs_to_port(struct phylink_pcs *pcs)
{
	return container_of(pcs, struct sparx5_port, phylink_pcs);
}

static void sparx5_pcs_get_state(struct phylink_pcs *pcs,
				 struct phylink_link_state *state)
{
	struct sparx5_port *port = sparx5_pcs_to_port(pcs);
	struct sparx5_port_status status;

	sparx5_get_port_status(port->sparx5, port, &status);
	state->link = status.link && !status.link_down;
	state->an_complete = status.an_complete;
	state->speed = status.speed;
	state->duplex = status.duplex;
	state->pause = status.pause;
}

static int sparx5_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
			     phy_interface_t interface,
			     const unsigned long *advertising,
			     bool permit_pause_to_mac)
{
	struct sparx5_port *port = sparx5_pcs_to_port(pcs);
	struct sparx5_port_config conf;
	int ret = 0;

	conf = port->conf;
	conf.power_down = false;
	conf.portmode = interface;
	conf.inband = neg_mode == PHYLINK_PCS_NEG_INBAND_DISABLED ||
		      neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED;
	conf.autoneg = neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED;
	conf.pause_adv = 0;
	if (phylink_test(advertising, Pause))
		conf.pause_adv |= ADVERTISE_1000XPAUSE;
	if (phylink_test(advertising, Asym_Pause))
		conf.pause_adv |= ADVERTISE_1000XPSE_ASYM;
	if (sparx5_is_baser(interface)) {
		if (phylink_test(advertising, FIBRE))
			conf.media = PHY_MEDIA_SR;
		else
			conf.media = PHY_MEDIA_DAC;
	}
	if (!port_conf_has_changed(&port->conf, &conf))
		return ret;
	/* Enable the PCS matching this interface type */
	ret = sparx5_port_pcs_set(port->sparx5, port, &conf);
	if (ret)
		netdev_err(port->ndev, "port PCS config failed: %d\n", ret);
	return ret;
}

static void sparx5_pcs_aneg_restart(struct phylink_pcs *pcs)
{
	/* Currently not used */
}

const struct phylink_pcs_ops sparx5_phylink_pcs_ops = {
	.pcs_get_state = sparx5_pcs_get_state,
	.pcs_config = sparx5_pcs_config,
	.pcs_an_restart = sparx5_pcs_aneg_restart,
};

const struct phylink_mac_ops sparx5_phylink_mac_ops = {
	.mac_select_pcs = sparx5_phylink_mac_select_pcs,
	.mac_config = sparx5_phylink_mac_config,
	.mac_link_down = sparx5_phylink_mac_link_down,
	.mac_link_up = sparx5_phylink_mac_link_up,
};
