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

#include <dm.h>
#include <log.h>
#include <usb.h>
#include <linux/mii.h>
#include "usb_ether.h"
#include "lan7x.h"

/* LAN75xx specific register/bit defines */
#define LAN75XX_HW_CFG_BIR		BIT(7)

#define LAN75XX_BURST_CAP		0x034

#define LAN75XX_BULK_IN_DLY		0x03C

#define LAN75XX_RFE_CTL			0x060

#define LAN75XX_FCT_RX_CTL		0x090

#define LAN75XX_FCT_TX_CTL		0x094

#define LAN75XX_FCT_RX_FIFO_END		0x098

#define LAN75XX_FCT_TX_FIFO_END		0x09C

#define LAN75XX_FCT_FLOW		0x0A0

/* MAC ADDRESS PERFECT FILTER For LAN75xx */
#define LAN75XX_ADDR_FILTX		0x300
#define LAN75XX_ADDR_FILTX_FB_VALID	BIT(31)

/*
 * Lan75xx infrastructure commands
 */
static int lan75xx_phy_gig_workaround(struct usb_device *udev,
				      struct ueth_data *dev)
{
	int ret = 0;

	/* Only internal phy */
	/* Set the phy in Gig loopback */
	lan7x_mdio_write(udev, dev->phy_id, MII_BMCR,
			 (BMCR_LOOPBACK | BMCR_SPEED1000));

	/* Wait for the link up */
	ret = lan7x_mdio_wait_for_bit(udev, "BMSR_LSTATUS",
				      dev->phy_id, MII_BMSR, BMSR_LSTATUS,
				      true, PHY_CONNECT_TIMEOUT_MS, 1);
	if (ret)
		return ret;

	/* phy reset */
	return lan7x_pmt_phy_reset(udev, dev);
}

static int lan75xx_update_flowcontrol(struct usb_device *udev,
				      struct ueth_data *dev)
{
	uint32_t flow = 0, fct_flow = 0;
	int ret;

	ret = lan7x_update_flowcontrol(udev, dev, &flow, &fct_flow);
	if (ret)
		return ret;

	ret = lan7x_write_reg(udev, LAN75XX_FCT_FLOW, fct_flow);
	if (ret)
		return ret;
	return lan7x_write_reg(udev, FLOW, flow);
}

static int lan75xx_set_receive_filter(struct usb_device *udev)
{
	/* No multicast in u-boot */
	return lan7x_write_reg(udev, LAN75XX_RFE_CTL,
			       RFE_CTL_BCAST_EN | RFE_CTL_DA_PERFECT);
}

/* starts the TX path */
static void lan75xx_start_tx_path(struct usb_device *udev)
{
	/* Enable Tx at MAC */
	lan7x_write_reg(udev, MAC_TX, MAC_TX_TXEN);

	/* Enable Tx at SCSRs */
	lan7x_write_reg(udev, LAN75XX_FCT_TX_CTL, FCT_TX_CTL_EN);
}

/* Starts the Receive path */
static void lan75xx_start_rx_path(struct usb_device *udev)
{
	/* Enable Rx at MAC */
	lan7x_write_reg(udev, MAC_RX,
			LAN7X_MAC_RX_MAX_SIZE_DEFAULT |
			MAC_RX_FCS_STRIP | MAC_RX_RXEN);

	/* Enable Rx at SCSRs */
	lan7x_write_reg(udev, LAN75XX_FCT_RX_CTL, FCT_RX_CTL_EN);
}

static int lan75xx_basic_reset(struct usb_device *udev,
			       struct ueth_data *dev,
			       struct lan7x_private *priv)
{
	int ret;
	u32 val;

	ret = lan7x_basic_reset(udev, dev);
	if (ret)
		return ret;

	/* Keep the chip ID */
	ret = lan7x_read_reg(udev, ID_REV, &val);
	if (ret)
		return ret;
	debug("LAN75xx ID_REV = 0x%08x\n", val);

	priv->chipid = (val & ID_REV_CHIP_ID_MASK) >> 16;

	/* Respond to the IN token with a NAK */
	ret = lan7x_read_reg(udev, HW_CFG, &val);
	if (ret)
		return ret;
	val |= LAN75XX_HW_CFG_BIR;
	return lan7x_write_reg(udev, HW_CFG, val);
}

int lan75xx_write_hwaddr(struct udevice *dev)
{
	struct usb_device *udev = dev_get_parent_priv(dev);
	struct eth_pdata *pdata = dev_get_platdata(dev);
	unsigned char *enetaddr = pdata->enetaddr;
	u32 addr_lo = get_unaligned_le32(&enetaddr[0]);
	u32 addr_hi = (u32)get_unaligned_le16(&enetaddr[4]);
	int ret;

	/* set hardware address */
	ret = lan7x_write_reg(udev, RX_ADDRL, addr_lo);
	if (ret)
		return ret;

	ret = lan7x_write_reg(udev, RX_ADDRH, addr_hi);
	if (ret)
		return ret;

	ret = lan7x_write_reg(udev, LAN75XX_ADDR_FILTX + 4, addr_lo);
	if (ret)
		return ret;

	addr_hi |= LAN75XX_ADDR_FILTX_FB_VALID;
	ret = lan7x_write_reg(udev, LAN75XX_ADDR_FILTX, addr_hi);
	if (ret)
		return ret;

	debug("MAC addr %pM written\n", enetaddr);

	return 0;
}

static int lan75xx_eth_start(struct udevice *dev)
{
	struct usb_device *udev = dev_get_parent_priv(dev);
	struct lan7x_private *priv = dev_get_priv(dev);
	struct ueth_data *ueth = &priv->ueth;
	int ret;
	u32 write_buf;

	/* Reset and read Mac addr were done in probe() */
	ret = lan75xx_write_hwaddr(dev);
	if (ret)
		return ret;

	ret = lan7x_write_reg(udev, INT_STS, 0xFFFFFFFF);
	if (ret)
		return ret;

	ret = lan7x_write_reg(udev, LAN75XX_BURST_CAP, 0);
	if (ret)
		return ret;

	ret = lan7x_write_reg(udev, LAN75XX_BULK_IN_DLY, DEFAULT_BULK_IN_DELAY);
	if (ret)
		return ret;

	/* set FIFO sizes */
	write_buf = (MAX_RX_FIFO_SIZE - 512) / 512;
	ret = lan7x_write_reg(udev, LAN75XX_FCT_RX_FIFO_END, write_buf);
	if (ret)
		return ret;

	write_buf = (MAX_TX_FIFO_SIZE - 512) / 512;
	ret = lan7x_write_reg(udev, LAN75XX_FCT_TX_FIFO_END, write_buf);
	if (ret)
		return ret;

	/* Init Tx */
	ret = lan7x_write_reg(udev, FLOW, 0);
	if (ret)
		return ret;

	/* Init Rx. Set Vlan, keep default for VLAN on 75xx */
	ret = lan75xx_set_receive_filter(udev);
	if (ret)
		return ret;

	/* phy workaround for gig link */
	ret = lan75xx_phy_gig_workaround(udev, ueth);
	if (ret)
		return ret;

	/* Init PHY, autonego, and link */
	ret = lan7x_eth_phylib_connect(dev, &priv->ueth);
	if (ret)
		return ret;
	ret = lan7x_eth_phylib_config_start(dev);
	if (ret)
		return ret;

	/*
	 * MAC_CR has to be set after PHY init.
	 * MAC will auto detect the PHY speed.
	 */
	ret = lan7x_read_reg(udev, MAC_CR, &write_buf);
	if (ret)
		return ret;
	write_buf |= MAC_CR_AUTO_DUPLEX | MAC_CR_AUTO_SPEED | MAC_CR_ADP;
	ret = lan7x_write_reg(udev, MAC_CR, write_buf);
	if (ret)
		return ret;

	lan75xx_start_tx_path(udev);
	lan75xx_start_rx_path(udev);

	return lan75xx_update_flowcontrol(udev, ueth);
}

int lan75xx_read_rom_hwaddr(struct udevice *dev)
{
	struct usb_device *udev = dev_get_parent_priv(dev);
	struct eth_pdata *pdata = dev_get_platdata(dev);
	int ret;

	/*
	 * Refer to the doc/README.enetaddr and doc/README.usb for
	 * the U-Boot MAC address policy
	 */
	ret = lan7x_read_eeprom_mac(pdata->enetaddr, udev);
	if (ret)
		memset(pdata->enetaddr, 0, 6);

	return 0;
}

static int lan75xx_eth_probe(struct udevice *dev)
{
	struct usb_device *udev = dev_get_parent_priv(dev);
	struct lan7x_private *priv = dev_get_priv(dev);
	struct ueth_data *ueth = &priv->ueth;
	struct eth_pdata *pdata = dev_get_platdata(dev);
	int ret;

	/* Do a reset in order to get the MAC address from HW */
	if (lan75xx_basic_reset(udev, ueth, priv))
		return 0;

	/* Get the MAC address */
	/*
	 * We must set the eth->enetaddr from HW because the upper layer
	 * will force to use the environmental var (usbethaddr) or random if
	 * there is no valid MAC address in eth->enetaddr.
	 *
	 * Refer to the doc/README.enetaddr and doc/README.usb for
	 * the U-Boot MAC address policy
	 */
	lan7x_read_eeprom_mac(pdata->enetaddr, udev);
	/* Do not return 0 for not finding MAC addr in HW */

	ret = usb_ether_register(dev, ueth, RX_URB_SIZE);
	if (ret)
		return ret;

	/* Register phylib */
	return lan7x_phylib_register(dev);
}

static const struct eth_ops lan75xx_eth_ops = {
	.start	= lan75xx_eth_start,
	.send	= lan7x_eth_send,
	.recv	= lan7x_eth_recv,
	.free_pkt = lan7x_free_pkt,
	.stop	= lan7x_eth_stop,
	.write_hwaddr = lan75xx_write_hwaddr,
	.read_rom_hwaddr = lan75xx_read_rom_hwaddr,
};

U_BOOT_DRIVER(lan75xx_eth) = {
	.name	= "lan75xx_eth",
	.id	= UCLASS_ETH,
	.probe	= lan75xx_eth_probe,
	.remove	= lan7x_eth_remove,
	.ops	= &lan75xx_eth_ops,
	.priv_auto_alloc_size = sizeof(struct lan7x_private),
	.platdata_auto_alloc_size = sizeof(struct eth_pdata),
};

static const struct usb_device_id lan75xx_eth_id_table[] = {
	{ USB_DEVICE(0x0424, 0x7500) },	/* LAN7500 USB Ethernet */
	{ }		/* Terminating entry */
};

U_BOOT_USB_DEVICE(lan75xx_eth, lan75xx_eth_id_table);
