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

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

/* LAN78xx specific register/bit defines */
#define LAN78XX_HW_CFG_LED1_EN		BIT(21) /* Muxed with EEDO */
#define LAN78XX_HW_CFG_LED0_EN		BIT(20) /* Muxed with EECLK */

#define LAN78XX_USB_CFG0		0x080
#define LAN78XX_USB_CFG0_BIR		BIT(6)

#define LAN78XX_BURST_CAP		0x090

#define LAN78XX_BULK_IN_DLY		0x094

#define LAN78XX_RFE_CTL			0x0B0

#define LAN78XX_FCT_RX_CTL		0x0C0

#define LAN78XX_FCT_TX_CTL		0x0C4

#define LAN78XX_FCT_RX_FIFO_END		0x0C8

#define LAN78XX_FCT_TX_FIFO_END		0x0CC

#define LAN78XX_FCT_FLOW		0x0D0

#define LAN78XX_MAF_BASE		0x400
#define LAN78XX_MAF_HIX			0x00
#define LAN78XX_MAF_LOX			0x04
#define LAN78XX_MAF_HI_BEGIN		(LAN78XX_MAF_BASE + LAN78XX_MAF_HIX)
#define LAN78XX_MAF_LO_BEGIN		(LAN78XX_MAF_BASE + LAN78XX_MAF_LOX)
#define LAN78XX_MAF_HI(index)		(LAN78XX_MAF_BASE + (8 * (index)) + \
					LAN78XX_MAF_HIX)
#define LAN78XX_MAF_LO(index)		(LAN78XX_MAF_BASE + (8 * (index)) + \
					LAN78XX_MAF_LOX)
#define LAN78XX_MAF_HI_VALID		BIT(31)

/* OTP registers */
#define LAN78XX_OTP_BASE_ADDR		0x00001000

#define LAN78XX_OTP_PWR_DN		(LAN78XX_OTP_BASE_ADDR + 4 * 0x00)
#define LAN78XX_OTP_PWR_DN_PWRDN_N	BIT(0)

#define LAN78XX_OTP_ADDR1		(LAN78XX_OTP_BASE_ADDR + 4 * 0x01)
#define LAN78XX_OTP_ADDR1_15_11		0x1F

#define LAN78XX_OTP_ADDR2		(LAN78XX_OTP_BASE_ADDR + 4 * 0x02)
#define LAN78XX_OTP_ADDR2_10_3		0xFF

#define LAN78XX_OTP_RD_DATA		(LAN78XX_OTP_BASE_ADDR + 4 * 0x06)

#define LAN78XX_OTP_FUNC_CMD		(LAN78XX_OTP_BASE_ADDR + 4 * 0x08)
#define LAN78XX_OTP_FUNC_CMD_READ	BIT(0)

#define LAN78XX_OTP_CMD_GO		(LAN78XX_OTP_BASE_ADDR + 4 * 0x0A)
#define LAN78XX_OTP_CMD_GO_GO		BIT(0)

#define LAN78XX_OTP_STATUS		(LAN78XX_OTP_BASE_ADDR + 4 * 0x0C)
#define LAN78XX_OTP_STATUS_BUSY		BIT(0)

#define LAN78XX_OTP_INDICATOR_1		0xF3
#define LAN78XX_OTP_INDICATOR_2		0xF7

/*
 * Lan78xx infrastructure commands
 */
static int lan78xx_read_raw_otp(struct usb_device *udev, u32 offset,
				u32 length, u8 *data)
{
	int i;
	int ret;
	u32 buf;

	ret = lan7x_read_reg(udev, LAN78XX_OTP_PWR_DN, &buf);
	if (ret)
		return ret;

	if (buf & LAN78XX_OTP_PWR_DN_PWRDN_N) {
		/* clear it and wait to be cleared */
		ret = lan7x_write_reg(udev, LAN78XX_OTP_PWR_DN, 0);
		if (ret)
			return ret;

		ret = lan7x_wait_for_bit(udev, "LAN78XX_OTP_PWR_DN_PWRDN_N",
					 LAN78XX_OTP_PWR_DN,
					 LAN78XX_OTP_PWR_DN_PWRDN_N,
					 false, 1000, 0);
		if (ret)
			return ret;
	}

	for (i = 0; i < length; i++) {
		ret = lan7x_write_reg(udev, LAN78XX_OTP_ADDR1,
				      ((offset + i) >> 8) &
				      LAN78XX_OTP_ADDR1_15_11);
		if (ret)
			return ret;
		ret = lan7x_write_reg(udev, LAN78XX_OTP_ADDR2,
				      ((offset + i) & LAN78XX_OTP_ADDR2_10_3));
		if (ret)
			return ret;

		ret = lan7x_write_reg(udev, LAN78XX_OTP_FUNC_CMD,
				      LAN78XX_OTP_FUNC_CMD_READ);
		if (ret)
			return ret;
		ret = lan7x_write_reg(udev, LAN78XX_OTP_CMD_GO,
				      LAN78XX_OTP_CMD_GO_GO);

		if (ret)
			return ret;

		ret = lan7x_wait_for_bit(udev, "LAN78XX_OTP_STATUS_BUSY",
					 LAN78XX_OTP_STATUS,
					 LAN78XX_OTP_STATUS_BUSY,
					 false, 1000, 0);
		if (ret)
			return ret;

		ret = lan7x_read_reg(udev, LAN78XX_OTP_RD_DATA, &buf);
		if (ret)
			return ret;

		data[i] = (u8)(buf & 0xFF);
	}

	return 0;
}

static int lan78xx_read_otp(struct usb_device *udev, u32 offset,
			    u32 length, u8 *data)
{
	u8 sig;
	int ret;

	ret = lan78xx_read_raw_otp(udev, 0, 1, &sig);

	if (!ret) {
		if (sig == LAN78XX_OTP_INDICATOR_2)
			offset += 0x100;
		else if (sig != LAN78XX_OTP_INDICATOR_1)
			return -EINVAL;
		ret = lan78xx_read_raw_otp(udev, offset, length, data);
		if (ret)
			return ret;
	}
	debug("LAN78x: MAC address from OTP = %pM\n", data);

	return ret;
}

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

	memset(enetaddr, 0, 6);

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

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

static int lan78xx_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, LAN78XX_FCT_FLOW, fct_flow);
	if (ret)
		return ret;
	return lan7x_write_reg(udev, FLOW, flow);
}

static int lan78xx_read_mac(unsigned char *enetaddr,
			    struct usb_device *udev,
			    struct lan7x_private *priv)
{
	u32 val;
	int ret;
	int saved = 0, done = 0;

	/*
	 * Depends on chip, some EEPROM pins are muxed with LED function.
	 * disable & restore LED function to access EEPROM.
	 */
	if ((priv->chipid == ID_REV_CHIP_ID_7800) ||
	    (priv->chipid == ID_REV_CHIP_ID_7850)) {
		ret = lan7x_read_reg(udev, HW_CFG, &val);
		if (ret)
			return ret;
		saved = val;
		val &= ~(LAN78XX_HW_CFG_LED1_EN | LAN78XX_HW_CFG_LED0_EN);
		ret = lan7x_write_reg(udev, HW_CFG, val);
		if (ret)
			goto restore;
	}

	/*
	 * Refer to the doc/README.enetaddr and doc/README.usb for
	 * the U-Boot MAC address policy
	 */
	/* try reading mac address from EEPROM, then from OTP */
	ret = lan7x_read_eeprom_mac(enetaddr, udev);
	if (!ret)
		done = 1;

restore:
	if ((priv->chipid == ID_REV_CHIP_ID_7800) ||
	    (priv->chipid == ID_REV_CHIP_ID_7850)) {
		ret = lan7x_write_reg(udev, HW_CFG, saved);
		if (ret)
			return ret;
	}
	/* if the EEPROM mac address is good, then exit */
	if (done)
		return 0;

	/* try reading mac address from OTP if the device is LAN78xx */
	return lan78xx_read_otp_mac(enetaddr, udev);
}

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

/* starts the TX path */
static void lan78xx_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, LAN78XX_FCT_TX_CTL, FCT_TX_CTL_EN);
}

/* Starts the Receive path */
static void lan78xx_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, LAN78XX_FCT_RX_CTL, FCT_RX_CTL_EN);
}

static int lan78xx_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("LAN78xx 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, LAN78XX_USB_CFG0, &val);
	if (ret)
		return ret;
	val &= ~LAN78XX_USB_CFG0_BIR;
	return lan7x_write_reg(udev, LAN78XX_USB_CFG0, val);
}

int lan78xx_write_hwaddr(struct udevice *dev)
{
	struct usb_device *udev = dev_get_parent_priv(dev);
	struct eth_pdata *pdata = dev_get_plat(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, LAN78XX_MAF_LO(0), addr_lo);
	if (ret)
		return ret;

	ret = lan7x_write_reg(udev, LAN78XX_MAF_HI(0),
			      addr_hi | LAN78XX_MAF_HI_VALID);
	if (ret)
		return ret;

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

	return 0;
}

static int lan78xx_eth_start(struct udevice *dev)
{
	struct usb_device *udev = dev_get_parent_priv(dev);
	struct lan7x_private *priv = dev_get_priv(dev);

	int ret;
	u32 write_buf;

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

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

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

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

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

	ret = lan7x_write_reg(udev, LAN78XX_FCT_TX_FIFO_END,
			      (MAX_TX_FIFO_SIZE - 512) / 512);
	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 78xx */
	ret = lan78xx_set_receive_filter(udev);
	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;

	lan78xx_start_tx_path(udev);
	lan78xx_start_rx_path(udev);

	return lan78xx_update_flowcontrol(udev, &priv->ueth);
}

int lan78xx_read_rom_hwaddr(struct udevice *dev)
{
	struct usb_device *udev = dev_get_parent_priv(dev);
	struct eth_pdata *pdata = dev_get_plat(dev);
	struct lan7x_private *priv = dev_get_priv(dev);
	int ret;

	ret = lan78xx_read_mac(pdata->enetaddr, udev, priv);
	if (ret)
		memset(pdata->enetaddr, 0, 6);

	return 0;
}

static int lan78xx_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_plat(dev);
	int ret;

	/* Do a reset in order to get the MAC address from HW */
	if (lan78xx_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.
	 */
	lan78xx_read_mac(pdata->enetaddr, udev, priv);
	/* 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 lan78xx_eth_ops = {
	.start	= lan78xx_eth_start,
	.send	= lan7x_eth_send,
	.recv	= lan7x_eth_recv,
	.free_pkt = lan7x_free_pkt,
	.stop	= lan7x_eth_stop,
	.write_hwaddr = lan78xx_write_hwaddr,
	.read_rom_hwaddr = lan78xx_read_rom_hwaddr,
};

U_BOOT_DRIVER(lan78xx_eth) = {
	.name	= "lan78xx_eth",
	.id	= UCLASS_ETH,
	.probe	= lan78xx_eth_probe,
	.remove	= lan7x_eth_remove,
	.ops	= &lan78xx_eth_ops,
	.priv_auto	= sizeof(struct lan7x_private),
	.plat_auto	= sizeof(struct eth_pdata),
};

static const struct usb_device_id lan78xx_eth_id_table[] = {
	{ USB_DEVICE(0x0424, 0x7800) },	/* LAN7800 USB Ethernet */
	{ USB_DEVICE(0x0424, 0x7850) },	/* LAN7850 USB Ethernet */
	{ }		/* Terminating entry */
};

U_BOOT_USB_DEVICE(lan78xx_eth, lan78xx_eth_id_table);
