// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Marvell 88E6185 family SERDES PCS support
 *
 * Copyright (c) 2008 Marvell Semiconductor
 *
 * Copyright (c) 2017 Andrew Lunn <andrew@lunn.ch>
 */
#include <linux/phylink.h>

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

struct mv88e6185_pcs {
	struct phylink_pcs phylink_pcs;
	unsigned int irq;
	char name[64];

	struct mv88e6xxx_chip *chip;
	int port;
};

static struct mv88e6185_pcs *pcs_to_mv88e6185_pcs(struct phylink_pcs *pcs)
{
	return container_of(pcs, struct mv88e6185_pcs, phylink_pcs);
}

static irqreturn_t mv88e6185_pcs_handle_irq(int irq, void *dev_id)
{
	struct mv88e6185_pcs *mpcs = dev_id;
	struct mv88e6xxx_chip *chip;
	irqreturn_t ret = IRQ_NONE;
	bool link_up;
	u16 status;
	int port;
	int err;

	chip = mpcs->chip;
	port = mpcs->port;

	mv88e6xxx_reg_lock(chip);
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status);
	mv88e6xxx_reg_unlock(chip);

	if (!err) {
		link_up = !!(status & MV88E6XXX_PORT_STS_LINK);

		phylink_pcs_change(&mpcs->phylink_pcs, link_up);

		ret = IRQ_HANDLED;
	}

	return ret;
}

static void mv88e6185_pcs_get_state(struct phylink_pcs *pcs,
				    struct phylink_link_state *state)
{
	struct mv88e6185_pcs *mpcs = pcs_to_mv88e6185_pcs(pcs);
	struct mv88e6xxx_chip *chip = mpcs->chip;
	int port = mpcs->port;
	u16 status;
	int err;

	mv88e6xxx_reg_lock(chip);
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status);
	mv88e6xxx_reg_unlock(chip);

	if (err)
		status = 0;

	state->link = !!(status & MV88E6XXX_PORT_STS_LINK);
	if (state->link) {
		state->duplex = status & MV88E6XXX_PORT_STS_DUPLEX ?
			DUPLEX_FULL : DUPLEX_HALF;

		switch (status & MV88E6XXX_PORT_STS_SPEED_MASK) {
		case MV88E6XXX_PORT_STS_SPEED_1000:
			state->speed = SPEED_1000;
			break;

		case MV88E6XXX_PORT_STS_SPEED_100:
			state->speed = SPEED_100;
			break;

		case MV88E6XXX_PORT_STS_SPEED_10:
			state->speed = SPEED_10;
			break;

		default:
			state->link = false;
			break;
		}
	}
}

static int mv88e6185_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
				phy_interface_t interface,
				const unsigned long *advertising,
				bool permit_pause_to_mac)
{
	return 0;
}

static void mv88e6185_pcs_an_restart(struct phylink_pcs *pcs)
{
}

static const struct phylink_pcs_ops mv88e6185_phylink_pcs_ops = {
	.pcs_get_state = mv88e6185_pcs_get_state,
	.pcs_config = mv88e6185_pcs_config,
	.pcs_an_restart = mv88e6185_pcs_an_restart,
};

static int mv88e6185_pcs_init(struct mv88e6xxx_chip *chip, int port)
{
	struct mv88e6185_pcs *mpcs;
	struct device *dev;
	unsigned int irq;
	int err;

	/* There are no configurable serdes lanes on this switch chip, so
	 * we use the static cmode configuration to determine whether we
	 * have a PCS or not.
	 */
	if (chip->ports[port].cmode != MV88E6185_PORT_STS_CMODE_SERDES &&
	    chip->ports[port].cmode != MV88E6185_PORT_STS_CMODE_1000BASE_X)
		return 0;

	dev = chip->dev;

	mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL);
	if (!mpcs)
		return -ENOMEM;

	mpcs->chip = chip;
	mpcs->port = port;
	mpcs->phylink_pcs.ops = &mv88e6185_phylink_pcs_ops;

	irq = mv88e6xxx_serdes_irq_mapping(chip, port);
	if (irq) {
		snprintf(mpcs->name, sizeof(mpcs->name),
			 "mv88e6xxx-%s-serdes-%d", dev_name(dev), port);

		err = request_threaded_irq(irq, NULL, mv88e6185_pcs_handle_irq,
					   IRQF_ONESHOT, mpcs->name, mpcs);
		if (err) {
			kfree(mpcs);
			return err;
		}

		mpcs->irq = irq;
	} else {
		mpcs->phylink_pcs.poll = true;
	}

	chip->ports[port].pcs_private = &mpcs->phylink_pcs;

	return 0;
}

static void mv88e6185_pcs_teardown(struct mv88e6xxx_chip *chip, int port)
{
	struct mv88e6185_pcs *mpcs;

	mpcs = chip->ports[port].pcs_private;
	if (!mpcs)
		return;

	if (mpcs->irq)
		free_irq(mpcs->irq, mpcs);

	kfree(mpcs);

	chip->ports[port].pcs_private = NULL;
}

static struct phylink_pcs *mv88e6185_pcs_select(struct mv88e6xxx_chip *chip,
						int port,
						phy_interface_t interface)
{
	return chip->ports[port].pcs_private;
}

const struct mv88e6xxx_pcs_ops mv88e6185_pcs_ops = {
	.pcs_init = mv88e6185_pcs_init,
	.pcs_teardown = mv88e6185_pcs_teardown,
	.pcs_select = mv88e6185_pcs_select,
};
