// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2019 - 2022 Beijing WangXun Technology Co., Ltd. */

#include <linux/ethtool.h>
#include <linux/iopoll.h>
#include <linux/pci.h>
#include <linux/phy.h>

#include "../libwx/wx_type.h"
#include "../libwx/wx_hw.h"
#include "ngbe_type.h"
#include "ngbe_mdio.h"

static int ngbe_phy_read_reg_internal(struct mii_bus *bus, int phy_addr, int regnum)
{
	struct wx *wx = bus->priv;

	if (phy_addr != 0)
		return 0xffff;
	return (u16)rd32(wx, NGBE_PHY_CONFIG(regnum));
}

static int ngbe_phy_write_reg_internal(struct mii_bus *bus, int phy_addr, int regnum, u16 value)
{
	struct wx *wx = bus->priv;

	if (phy_addr == 0)
		wr32(wx, NGBE_PHY_CONFIG(regnum), value);
	return 0;
}

static int ngbe_phy_read_reg_c22(struct mii_bus *bus, int phy_addr, int regnum)
{
	struct wx *wx = bus->priv;
	u16 phy_data;

	if (wx->mac_type == em_mac_type_mdi)
		phy_data = ngbe_phy_read_reg_internal(bus, phy_addr, regnum);
	else
		phy_data = wx_phy_read_reg_mdi_c22(bus, phy_addr, regnum);

	return phy_data;
}

static int ngbe_phy_write_reg_c22(struct mii_bus *bus, int phy_addr,
				  int regnum, u16 value)
{
	struct wx *wx = bus->priv;
	int ret;

	if (wx->mac_type == em_mac_type_mdi)
		ret = ngbe_phy_write_reg_internal(bus, phy_addr, regnum, value);
	else
		ret = wx_phy_write_reg_mdi_c22(bus, phy_addr, regnum, value);

	return ret;
}

static void ngbe_mac_config(struct phylink_config *config, unsigned int mode,
			    const struct phylink_link_state *state)
{
}

static void ngbe_mac_link_down(struct phylink_config *config,
			       unsigned int mode, phy_interface_t interface)
{
}

static void ngbe_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 wx *wx = phylink_to_wx(config);
	u32 lan_speed, reg;

	wx_fc_enable(wx, tx_pause, rx_pause);

	switch (speed) {
	case SPEED_10:
		lan_speed = 0;
		break;
	case SPEED_100:
		lan_speed = 1;
		break;
	case SPEED_1000:
	default:
		lan_speed = 2;
		break;
	}

	wr32m(wx, NGBE_CFG_LAN_SPEED, 0x3, lan_speed);

	reg = rd32(wx, WX_MAC_TX_CFG);
	reg &= ~WX_MAC_TX_CFG_SPEED_MASK;
	reg |= WX_MAC_TX_CFG_SPEED_1G | WX_MAC_TX_CFG_TE;
	wr32(wx, WX_MAC_TX_CFG, reg);

	/* Re configure MAC Rx */
	reg = rd32(wx, WX_MAC_RX_CFG);
	wr32(wx, WX_MAC_RX_CFG, reg);
	wr32(wx, WX_MAC_PKT_FLT, WX_MAC_PKT_FLT_PR);
	reg = rd32(wx, WX_MAC_WDG_TIMEOUT);
	wr32(wx, WX_MAC_WDG_TIMEOUT, reg);
}

static const struct phylink_mac_ops ngbe_mac_ops = {
	.mac_config = ngbe_mac_config,
	.mac_link_down = ngbe_mac_link_down,
	.mac_link_up = ngbe_mac_link_up,
};

static int ngbe_phylink_init(struct wx *wx)
{
	struct phylink_config *config;
	phy_interface_t phy_mode;
	struct phylink *phylink;

	config = &wx->phylink_config;
	config->dev = &wx->netdev->dev;
	config->type = PHYLINK_NETDEV;
	config->mac_capabilities = MAC_1000FD | MAC_100FD | MAC_10FD |
				   MAC_SYM_PAUSE | MAC_ASYM_PAUSE;
	config->mac_managed_pm = true;

	/* The MAC only has add the Tx delay and it can not be modified.
	 * So just disable TX delay in PHY, and it is does not matter to
	 * internal phy.
	 */
	phy_mode = PHY_INTERFACE_MODE_RGMII_RXID;
	__set_bit(PHY_INTERFACE_MODE_RGMII_RXID, config->supported_interfaces);

	phylink = phylink_create(config, NULL, phy_mode, &ngbe_mac_ops);
	if (IS_ERR(phylink))
		return PTR_ERR(phylink);

	wx->phylink = phylink;

	return 0;
}

int ngbe_mdio_init(struct wx *wx)
{
	struct pci_dev *pdev = wx->pdev;
	struct mii_bus *mii_bus;
	int ret;

	mii_bus = devm_mdiobus_alloc(&pdev->dev);
	if (!mii_bus)
		return -ENOMEM;

	mii_bus->name = "ngbe_mii_bus";
	mii_bus->read = ngbe_phy_read_reg_c22;
	mii_bus->write = ngbe_phy_write_reg_c22;
	mii_bus->phy_mask = GENMASK(31, 4);
	mii_bus->parent = &pdev->dev;
	mii_bus->priv = wx;

	if (wx->mac_type == em_mac_type_rgmii) {
		mii_bus->read_c45 = wx_phy_read_reg_mdi_c45;
		mii_bus->write_c45 = wx_phy_write_reg_mdi_c45;
	}

	snprintf(mii_bus->id, MII_BUS_ID_SIZE, "ngbe-%x", pci_dev_id(pdev));
	ret = devm_mdiobus_register(&pdev->dev, mii_bus);
	if (ret)
		return ret;

	wx->phydev = phy_find_first(mii_bus);
	if (!wx->phydev)
		return -ENODEV;

	phy_attached_info(wx->phydev);

	wx->link = 0;
	wx->speed = 0;
	wx->duplex = 0;

	ret = ngbe_phylink_init(wx);
	if (ret) {
		wx_err(wx, "failed to init phylink: %d\n", ret);
		return ret;
	}

	return 0;
}
