// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2017 Microchip Technology Inc. All rights reserved.
 */

#include <dm.h>
#include <malloc.h>
#include <miiphy.h>
#include <memalign.h>
#include <usb.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include "usb_ether.h"
#include "lan7x.h"

/*
 * Lan7x infrastructure commands
 */
int lan7x_write_reg(struct usb_device *udev, u32 index, u32 data)
{
	int len;
	ALLOC_CACHE_ALIGN_BUFFER(u32, tmpbuf, 1);

	cpu_to_le32s(&data);
	tmpbuf[0] = data;

	len = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
			      USB_VENDOR_REQUEST_WRITE_REGISTER,
			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
			      0, index, tmpbuf, sizeof(data),
			      USB_CTRL_SET_TIMEOUT_MS);
	if (len != sizeof(data)) {
		debug("%s failed: index=%d, data=%d, len=%d",
		      __func__, index, data, len);
		return -EIO;
	}
	return 0;
}

int lan7x_read_reg(struct usb_device *udev, u32 index, u32 *data)
{
	int len;
	ALLOC_CACHE_ALIGN_BUFFER(u32, tmpbuf, 1);

	len = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
			      USB_VENDOR_REQUEST_READ_REGISTER,
			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
			      0, index, tmpbuf, sizeof(*data),
			      USB_CTRL_GET_TIMEOUT_MS);
	*data = tmpbuf[0];
	if (len != sizeof(*data)) {
		debug("%s failed: index=%d, len=%d", __func__, index, len);
		return -EIO;
	}

	le32_to_cpus(data);
	return 0;
}

static int lan7x_phy_wait_not_busy(struct usb_device *udev)
{
	return lan7x_wait_for_bit(udev, __func__,
				  MII_ACC, MII_ACC_MII_BUSY,
				  false, 100, 0);
}

int lan7x_mdio_read(struct usb_device *udev, int phy_id, int idx)
{
	u32 val, addr;

	/* confirm MII not busy */
	if (lan7x_phy_wait_not_busy(udev)) {
		debug("MII is busy in %s\n", __func__);
		return -ETIMEDOUT;
	}

	/* set the address, index & direction (read from PHY) */
	addr = (phy_id << 11) | (idx << 6) |
		MII_ACC_MII_READ | MII_ACC_MII_BUSY;
	lan7x_write_reg(udev, MII_ACC, addr);

	if (lan7x_phy_wait_not_busy(udev)) {
		debug("Timed out reading MII reg %02X\n", idx);
		return -ETIMEDOUT;
	}

	lan7x_read_reg(udev, MII_DATA, &val);

	return val & 0xFFFF;
}

void lan7x_mdio_write(struct usb_device *udev, int phy_id, int idx, int regval)
{
	u32 addr;

	/* confirm MII not busy */
	if (lan7x_phy_wait_not_busy(udev)) {
		debug("MII is busy in %s\n", __func__);
		return;
	}

	lan7x_write_reg(udev, MII_DATA, regval);

	/* set the address, index & direction (write to PHY) */
	addr = (phy_id << 11) | (idx << 6) |
		MII_ACC_MII_WRITE | MII_ACC_MII_BUSY;
	lan7x_write_reg(udev, MII_ACC, addr);

	if (lan7x_phy_wait_not_busy(udev))
		debug("Timed out writing MII reg %02X\n", idx);
}

/*
 * Lan7x phylib wrappers
 */
static int lan7x_phylib_mdio_read(struct mii_dev *bus,
				  int addr, int devad, int reg)
{
	struct usb_device *udev = dev_get_parent_priv(bus->priv);

	return lan7x_mdio_read(udev, addr, reg);
}

static int lan7x_phylib_mdio_write(struct mii_dev *bus,
				   int addr, int devad, int reg, u16 val)
{
	struct usb_device *udev = dev_get_parent_priv(bus->priv);

	lan7x_mdio_write(udev, addr, reg, (int)val);

	return 0;
}

/*
 * Lan7x eeprom functions
 */
static int lan7x_eeprom_confirm_not_busy(struct usb_device *udev)
{
	return lan7x_wait_for_bit(udev, __func__,
				  E2P_CMD, E2P_CMD_EPC_BUSY,
				  false, 100, 0);
}

static int lan7x_wait_eeprom(struct usb_device *udev)
{
	return lan7x_wait_for_bit(udev, __func__,
				  E2P_CMD,
				  (E2P_CMD_EPC_BUSY | E2P_CMD_EPC_TIMEOUT),
				  false, 100, 0);
}

static int lan7x_read_eeprom(struct usb_device *udev,
			     u32 offset, u32 length, u8 *data)
{
	u32 val;
	int i, ret;

	ret = lan7x_eeprom_confirm_not_busy(udev);
	if (ret)
		return ret;

	for (i = 0; i < length; i++) {
		val = E2P_CMD_EPC_BUSY | E2P_CMD_EPC_CMD_READ |
			(offset & E2P_CMD_EPC_ADDR_MASK);
		lan7x_write_reg(udev, E2P_CMD, val);

		ret = lan7x_wait_eeprom(udev);
		if (ret)
			return ret;

		lan7x_read_reg(udev, E2P_DATA, &val);
		data[i] = val & 0xFF;
		offset++;
	}
	return ret;
}

/*
 * Lan7x phylib functions
 */
int lan7x_phylib_register(struct udevice *udev)
{
	struct usb_device *usbdev = dev_get_parent_priv(udev);
	struct lan7x_private *priv = dev_get_priv(udev);
	int ret;

	priv->mdiobus = mdio_alloc();
	if (!priv->mdiobus) {
		printf("mdio_alloc failed\n");
		return -ENOMEM;
	}
	priv->mdiobus->read = lan7x_phylib_mdio_read;
	priv->mdiobus->write = lan7x_phylib_mdio_write;
	sprintf(priv->mdiobus->name,
		"lan7x_mdiobus-d%hu-p%hu", usbdev->devnum, usbdev->portnr);
	priv->mdiobus->priv = (void *)udev;

	ret = mdio_register(priv->mdiobus);
	if (ret) {
		printf("mdio_register failed\n");
		free(priv->mdiobus);
		return -ENOMEM;
	}

	return 0;
}

int lan7x_eth_phylib_connect(struct udevice *udev, struct ueth_data *dev)
{
	struct lan7x_private *priv = dev_get_priv(udev);

	priv->phydev = phy_connect(priv->mdiobus, dev->phy_id,
			     udev, PHY_INTERFACE_MODE_MII);

	if (!priv->phydev) {
		printf("phy_connect failed\n");
		return -ENODEV;
	}
	return 0;
}

int lan7x_eth_phylib_config_start(struct udevice *udev)
{
	struct lan7x_private *priv = dev_get_priv(udev);
	int ret;

	/* configure supported modes */
	priv->phydev->supported = PHY_BASIC_FEATURES |
				  SUPPORTED_1000baseT_Full |
				  SUPPORTED_Pause |
				  SUPPORTED_Asym_Pause;

	priv->phydev->advertising = ADVERTISED_10baseT_Half |
				    ADVERTISED_10baseT_Full |
				    ADVERTISED_100baseT_Half |
				    ADVERTISED_100baseT_Full |
				    ADVERTISED_1000baseT_Full |
				    ADVERTISED_Pause |
				    ADVERTISED_Asym_Pause |
				    ADVERTISED_Autoneg;

	priv->phydev->autoneg = AUTONEG_ENABLE;

	ret = genphy_config_aneg(priv->phydev);
	if (ret) {
		printf("genphy_config_aneg failed\n");
		return ret;
	}
	ret = phy_startup(priv->phydev);
	if (ret) {
		printf("phy_startup failed\n");
		return ret;
	}

	debug("** %s() speed %i duplex %i adv %X supp %X\n", __func__,
	      priv->phydev->speed, priv->phydev->duplex,
	      priv->phydev->advertising, priv->phydev->supported);

	return 0;
}

int lan7x_update_flowcontrol(struct usb_device *udev,
			     struct ueth_data *dev,
			     uint32_t *flow, uint32_t *fct_flow)
{
	uint32_t lcladv, rmtadv;
	u8 cap = 0;
	struct lan7x_private *priv = dev_get_priv(udev->dev);

	debug("** %s()\n", __func__);
	debug("** %s() priv->phydev->speed %i duplex %i\n", __func__,
	      priv->phydev->speed, priv->phydev->duplex);

	if (priv->phydev->duplex == DUPLEX_FULL) {
		lcladv = lan7x_mdio_read(udev, dev->phy_id, MII_ADVERTISE);
		rmtadv = lan7x_mdio_read(udev, dev->phy_id, MII_LPA);
		cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv);

		debug("TX Flow ");
		if (cap & FLOW_CTRL_TX) {
			*flow = (FLOW_CR_TX_FCEN | 0xFFFF);
			/* set fct_flow thresholds to 20% and 80% */
			*fct_flow = ((MAX_RX_FIFO_SIZE * 2) / (10 * 512))
					& 0x7FUL;
			*fct_flow <<= 8UL;
			*fct_flow |= ((MAX_RX_FIFO_SIZE * 8) / (10 * 512))
					& 0x7FUL;
			debug("EN ");
		} else {
			debug("DIS ");
		}
		debug("RX Flow ");
		if (cap & FLOW_CTRL_RX) {
			*flow |= FLOW_CR_RX_FCEN;
			debug("EN");
		} else {
			debug("DIS");
		}
	}
	debug("\n");
	return 0;
}

int lan7x_read_eeprom_mac(unsigned char *enetaddr, struct usb_device *udev)
{
	int ret;

	memset(enetaddr, 0, 6);

	ret = lan7x_read_eeprom(udev, 0, 1, enetaddr);

	if ((ret == 0) && (enetaddr[0] == EEPROM_INDICATOR)) {
		ret = lan7x_read_eeprom(udev,
					EEPROM_MAC_OFFSET, ETH_ALEN,
					enetaddr);
		if ((ret == 0) && is_valid_ethaddr(enetaddr)) {
			/* eeprom values are valid so use them */
			debug("MAC address read from EEPROM %pM\n",
			      enetaddr);
			return 0;
		}
	}
	debug("MAC address read from EEPROM invalid %pM\n", enetaddr);

	memset(enetaddr, 0, 6);
	return -EINVAL;
}

int lan7x_pmt_phy_reset(struct usb_device *udev,
			struct ueth_data *dev)
{
	int ret;
	u32 data;

	ret = lan7x_read_reg(udev, PMT_CTL, &data);
	if (ret)
		return ret;
	ret = lan7x_write_reg(udev, PMT_CTL, data | PMT_CTL_PHY_RST);
	if (ret)
		return ret;

	/* for LAN7x, we need to check PMT_CTL_READY asserted */
	ret = lan7x_wait_for_bit(udev, "PMT_CTL_PHY_RST",
				 PMT_CTL, PMT_CTL_PHY_RST,
				 false, 1000, 0); /* could take over 125mS */
	if (ret)
		return ret;

	return lan7x_wait_for_bit(udev, "PMT_CTL_READY",
				 PMT_CTL, PMT_CTL_READY,
				 true, 1000, 0);
}

int lan7x_basic_reset(struct usb_device *udev,
		      struct ueth_data *dev)
{
	int ret;

	dev->phy_id = LAN7X_INTERNAL_PHY_ID; /* fixed phy id */

	ret = lan7x_write_reg(udev, HW_CFG, HW_CFG_LRST);
	if (ret)
		return ret;

	ret = lan7x_wait_for_bit(udev, "HW_CFG_LRST",
				 HW_CFG, HW_CFG_LRST,
				 false, 1000, 0);
	if (ret)
		return ret;

	debug("USB devnum %d portnr %d\n", udev->devnum, udev->portnr);

	return lan7x_pmt_phy_reset(udev, dev);
}

void lan7x_eth_stop(struct udevice *dev)
{
	debug("** %s()\n", __func__);
}

int lan7x_eth_send(struct udevice *dev, void *packet, int length)
{
	struct lan7x_private *priv = dev_get_priv(dev);
	struct ueth_data *ueth = &priv->ueth;
	int err;
	int actual_len;
	u32 tx_cmd_a;
	u32 tx_cmd_b;
	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, msg,
				 PKTSIZE + sizeof(tx_cmd_a) + sizeof(tx_cmd_b));

	debug("** %s(), len %d, buf %#x\n", __func__, length,
	      (unsigned int)(ulong) msg);
	if (length > PKTSIZE)
		return -ENOSPC;

	/* LAN7x disable all TX offload features for u-boot */
	tx_cmd_a = (u32) (length & TX_CMD_A_LEN_MASK) | TX_CMD_A_FCS;
	tx_cmd_b = 0;
	cpu_to_le32s(&tx_cmd_a);
	cpu_to_le32s(&tx_cmd_b);

	/* prepend cmd_a and cmd_b */
	memcpy(msg, &tx_cmd_a, sizeof(tx_cmd_a));
	memcpy(msg + sizeof(tx_cmd_a), &tx_cmd_b, sizeof(tx_cmd_b));
	memcpy(msg + sizeof(tx_cmd_a) + sizeof(tx_cmd_b), (void *)packet,
	       length);
	err = usb_bulk_msg(ueth->pusb_dev,
			   usb_sndbulkpipe(ueth->pusb_dev, ueth->ep_out),
			   (void *)msg,
			   length + sizeof(tx_cmd_a) +
			   sizeof(tx_cmd_b),
			   &actual_len, USB_BULK_SEND_TIMEOUT_MS);
	debug("Tx: len = %u, actual = %u, err = %d\n",
	      (unsigned int)(length + sizeof(tx_cmd_a) + sizeof(tx_cmd_b)),
	      (unsigned int)actual_len, err);

	return err;
}

int lan7x_eth_recv(struct udevice *dev, int flags, uchar **packetp)
{
	struct lan7x_private *priv = dev_get_priv(dev);
	struct ueth_data *ueth = &priv->ueth;
	uint8_t *ptr;
	int ret, len;
	u32 packet_len = 0;
	u32 rx_cmd_a = 0;

	len = usb_ether_get_rx_bytes(ueth, &ptr);
	debug("%s: first try, len=%d\n", __func__, len);
	if (!len) {
		if (!(flags & ETH_RECV_CHECK_DEVICE))
			return -EAGAIN;
		ret = usb_ether_receive(ueth, RX_URB_SIZE);
		if (ret == -EAGAIN)
			return ret;

		len = usb_ether_get_rx_bytes(ueth, &ptr);
		debug("%s: second try, len=%d\n", __func__, len);
	}

	/*
	 * 1st 4 bytes contain the length of the actual data plus error info.
	 * Extract data length.
	 */
	if (len < sizeof(packet_len)) {
		debug("Rx: incomplete packet length\n");
		goto err;
	}
	memcpy(&rx_cmd_a, ptr, sizeof(rx_cmd_a));
	le32_to_cpus(&rx_cmd_a);
	if (rx_cmd_a & RX_CMD_A_RXE) {
		debug("Rx: Error header=%#x", rx_cmd_a);
		goto err;
	}
	packet_len = (u16) (rx_cmd_a & RX_CMD_A_LEN_MASK);

	if (packet_len > len - sizeof(packet_len)) {
		debug("Rx: too large packet: %d\n", packet_len);
		goto err;
	}

	/*
	 * For LAN7x, the length in command A does not
	 * include command A, B, and C length.
	 * So use it as is.
	 */

	*packetp = ptr + 10;
	return packet_len;

err:
	usb_ether_advance_rxbuf(ueth, -1);
	return -EINVAL;
}

int lan7x_free_pkt(struct udevice *dev, uchar *packet, int packet_len)
{
	struct lan7x_private *priv = dev_get_priv(dev);

	packet_len = ALIGN(packet_len, 4);
	usb_ether_advance_rxbuf(&priv->ueth, sizeof(u32) + packet_len);

	return 0;
}

int lan7x_eth_remove(struct udevice *dev)
{
	struct lan7x_private *priv = dev_get_priv(dev);

	debug("** %s()\n", __func__);
	free(priv->phydev);
	mdio_unregister(priv->mdiobus);
	mdio_free(priv->mdiobus);

	return 0;
}
