// SPDX-License-Identifier: GPL-2.0+
/*
 * Micrel KS8851_MLL 16bit Network driver
 * Copyright (c) 2011 Roberto Cerati <roberto.cerati@bticino.it>
 */

#include <log.h>
#include <asm/io.h>
#include <common.h>
#include <command.h>
#include <malloc.h>
#include <net.h>
#include <miiphy.h>
#include <linux/delay.h>

#include "ks8851_mll.h"

#define DRIVERNAME			"ks8851_mll"

#define RX_BUF_SIZE			2000

/*
 * struct ks_net - KS8851 driver private data
 * @dev		: legacy non-DM ethernet device structure
 * @iobase	: register base
 * @bus_width	: i/o bus width.
 * @sharedbus	: Multipex(addr and data bus) mode indicator.
 * @extra_byte	: number of extra byte prepended rx pkt.
 */
struct ks_net {
#ifndef CONFIG_DM_ETH
	struct eth_device	dev;
#endif
	phys_addr_t		iobase;
	int			bus_width;
	u16			sharedbus;
	u16			rxfc;
	u8			extra_byte;
};

#define BE3             0x8000      /* Byte Enable 3 */
#define BE2             0x4000      /* Byte Enable 2 */
#define BE1             0x2000      /* Byte Enable 1 */
#define BE0             0x1000      /* Byte Enable 0 */

static u8 ks_rdreg8(struct ks_net *ks, u16 offset)
{
	u8 shift_bit = offset & 0x03;
	u8 shift_data = (offset & 1) << 3;

	writew(offset | (BE0 << shift_bit), ks->iobase + 2);

	return (u8)(readw(ks->iobase) >> shift_data);
}

static u16 ks_rdreg16(struct ks_net *ks, u16 offset)
{
	writew(offset | ((BE1 | BE0) << (offset & 0x02)), ks->iobase + 2);

	return readw(ks->iobase);
}

static void ks_wrreg16(struct ks_net *ks, u16 offset, u16 val)
{
	writew(offset | ((BE1 | BE0) << (offset & 0x02)), ks->iobase + 2);
	writew(val, ks->iobase);
}

/*
 * ks_inblk - read a block of data from QMU. This is called after sudo DMA mode
 * enabled.
 * @ks: The chip state
 * @wptr: buffer address to save data
 * @len: length in byte to read
 */
static inline void ks_inblk(struct ks_net *ks, u16 *wptr, u32 len)
{
	len >>= 1;

	while (len--)
		*wptr++ = readw(ks->iobase);
}

/*
 * ks_outblk - write data to QMU. This is called after sudo DMA mode enabled.
 * @ks: The chip information
 * @wptr: buffer address
 * @len: length in byte to write
 */
static inline void ks_outblk(struct ks_net *ks, u16 *wptr, u32 len)
{
	len >>= 1;

	while (len--)
		writew(*wptr++, ks->iobase);
}

static void ks_enable_int(struct ks_net *ks)
{
	ks_wrreg16(ks, KS_IER, IRQ_LCI | IRQ_TXI | IRQ_RXI);
}

static void ks_set_powermode(struct ks_net *ks, unsigned int pwrmode)
{
	unsigned int pmecr;

	ks_rdreg16(ks, KS_GRR);
	pmecr = ks_rdreg16(ks, KS_PMECR);
	pmecr &= ~PMECR_PM_MASK;
	pmecr |= pwrmode;

	ks_wrreg16(ks, KS_PMECR, pmecr);
}

/*
 * ks_read_config - read chip configuration of bus width.
 * @ks: The chip information
 */
static void ks_read_config(struct ks_net *ks)
{
	u16 reg_data = 0;

	/* Regardless of bus width, 8 bit read should always work. */
	reg_data = ks_rdreg8(ks, KS_CCR) & 0x00FF;
	reg_data |= ks_rdreg8(ks, KS_CCR + 1) << 8;

	/* addr/data bus are multiplexed */
	ks->sharedbus = (reg_data & CCR_SHARED) == CCR_SHARED;

	/*
	 * There are garbage data when reading data from QMU,
	 * depending on bus-width.
	 */
	if (reg_data & CCR_8BIT) {
		ks->bus_width = ENUM_BUS_8BIT;
		ks->extra_byte = 1;
	} else if (reg_data & CCR_16BIT) {
		ks->bus_width = ENUM_BUS_16BIT;
		ks->extra_byte = 2;
	} else {
		ks->bus_width = ENUM_BUS_32BIT;
		ks->extra_byte = 4;
	}
}

/*
 * ks_soft_reset - issue one of the soft reset to the device
 * @ks: The device state.
 * @op: The bit(s) to set in the GRR
 *
 * Issue the relevant soft-reset command to the device's GRR register
 * specified by @op.
 *
 * Note, the delays are in there as a caution to ensure that the reset
 * has time to take effect and then complete. Since the datasheet does
 * not currently specify the exact sequence, we have chosen something
 * that seems to work with our device.
 */
static void ks_soft_reset(struct ks_net *ks, unsigned int op)
{
	/* Disable interrupt first */
	ks_wrreg16(ks, KS_IER, 0x0000);
	ks_wrreg16(ks, KS_GRR, op);
	mdelay(10);	/* wait a short time to effect reset */
	ks_wrreg16(ks, KS_GRR, 0);
	mdelay(1);	/* wait for condition to clear */
}

void ks_enable_qmu(struct ks_net *ks)
{
	u16 w;

	w = ks_rdreg16(ks, KS_TXCR);

	/* Enables QMU Transmit (TXCR). */
	ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE);

	/* Enable RX Frame Count Threshold and Auto-Dequeue RXQ Frame */
	w = ks_rdreg16(ks, KS_RXQCR);
	ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE);

	/* Enables QMU Receive (RXCR1). */
	w = ks_rdreg16(ks, KS_RXCR1);
	ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE);
}

static void ks_disable_qmu(struct ks_net *ks)
{
	u16 w;

	w = ks_rdreg16(ks, KS_TXCR);

	/* Disables QMU Transmit (TXCR). */
	w &= ~TXCR_TXE;
	ks_wrreg16(ks, KS_TXCR, w);

	/* Disables QMU Receive (RXCR1). */
	w = ks_rdreg16(ks, KS_RXCR1);
	w &= ~RXCR1_RXE;
	ks_wrreg16(ks, KS_RXCR1, w);
}

static inline void ks_read_qmu(struct ks_net *ks, u16 *buf, u32 len)
{
	u32 r = ks->extra_byte & 0x1;
	u32 w = ks->extra_byte - r;

	/* 1. set sudo DMA mode */
	ks_wrreg16(ks, KS_RXFDPR, RXFDPR_RXFPAI);
	ks_wrreg16(ks, KS_RXQCR, RXQCR_CMD_CNTL | RXQCR_SDA);

	/*
	 * 2. read prepend data
	 *
	 * read 4 + extra bytes and discard them.
	 * extra bytes for dummy, 2 for status, 2 for len
	 */

	if (r)
		ks_rdreg8(ks, 0);

	ks_inblk(ks, buf, w + 2 + 2);

	/* 3. read pkt data */
	ks_inblk(ks, buf, ALIGN(len, 4));

	/* 4. reset sudo DMA Mode */
	ks_wrreg16(ks, KS_RXQCR, RXQCR_CMD_CNTL);
}

static int ks_rcv(struct ks_net *ks, uchar *data)
{
	u16 sts, len;

	if (!ks->rxfc)
		ks->rxfc = ks_rdreg16(ks, KS_RXFCTR) >> 8;

	if (!ks->rxfc)
		return 0;

	/* Checking Received packet status */
	sts = ks_rdreg16(ks, KS_RXFHSR);
	/* Get packet len from hardware */
	len = ks_rdreg16(ks, KS_RXFHBCR);

	if ((sts & RXFSHR_RXFV) && len && (len < RX_BUF_SIZE)) {
		/* read data block including CRC 4 bytes */
		ks_read_qmu(ks, (u16 *)data, len);
		ks->rxfc--;
		return len - 4;
	}

	ks_wrreg16(ks, KS_RXQCR, RXQCR_CMD_CNTL | RXQCR_RRXEF);
	printf(DRIVERNAME ": bad packet\n");
	return 0;
}

/*
 * ks_read_selftest - read the selftest memory info.
 * @ks: The device state
 *
 * Read and check the TX/RX memory selftest information.
 */
static int ks_read_selftest(struct ks_net *ks)
{
	u16 both_done = MBIR_TXMBF | MBIR_RXMBF;
	u16 mbir;
	int ret = 0;

	mbir = ks_rdreg16(ks, KS_MBIR);

	if ((mbir & both_done) != both_done) {
		printf(DRIVERNAME ": Memory selftest not finished\n");
		return 0;
	}

	if (mbir & MBIR_TXMBFA) {
		printf(DRIVERNAME ": TX memory selftest fails\n");
		ret |= 1;
	}

	if (mbir & MBIR_RXMBFA) {
		printf(DRIVERNAME ": RX memory selftest fails\n");
		ret |= 2;
	}

	debug(DRIVERNAME ": the selftest passes\n");

	return ret;
}

static void ks_setup(struct ks_net *ks)
{
	u16 w;

	/* Setup Transmit Frame Data Pointer Auto-Increment (TXFDPR) */
	ks_wrreg16(ks, KS_TXFDPR, TXFDPR_TXFPAI);

	/* Setup Receive Frame Data Pointer Auto-Increment */
	ks_wrreg16(ks, KS_RXFDPR, RXFDPR_RXFPAI);

	/* Setup Receive Frame Threshold - 1 frame (RXFCTFC) */
	ks_wrreg16(ks, KS_RXFCTR, 1 & RXFCTR_THRESHOLD_MASK);

	/* Setup RxQ Command Control (RXQCR) */
	ks_wrreg16(ks, KS_RXQCR, RXQCR_CMD_CNTL);

	/*
	 * set the force mode to half duplex, default is full duplex
	 * because if the auto-negotiation fails, most switch uses
	 * half-duplex.
	 */
	w = ks_rdreg16(ks, KS_P1MBCR);
	w &= ~P1MBCR_FORCE_FDX;
	ks_wrreg16(ks, KS_P1MBCR, w);

	w = TXCR_TXFCE | TXCR_TXPE | TXCR_TXCRC | TXCR_TCGIP;
	ks_wrreg16(ks, KS_TXCR, w);

	w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE | RXCR1_RXME | RXCR1_RXIPFCC;

	/* Normal mode */
	w |= RXCR1_RXPAFMA;

	ks_wrreg16(ks, KS_RXCR1, w);
}

static void ks_setup_int(struct ks_net *ks)
{
	/* Clear the interrupts status of the hardware. */
	ks_wrreg16(ks, KS_ISR, 0xffff);
}

static int ks8851_mll_detect_chip(struct ks_net *ks)
{
	unsigned short val;

	ks_read_config(ks);

	val = ks_rdreg16(ks, KS_CIDER);

	if (val == 0xffff) {
		/* Special case -- no chip present */
		printf(DRIVERNAME ":  is chip mounted ?\n");
		return -1;
	} else if ((val & 0xfff0) != CIDER_ID) {
		printf(DRIVERNAME ": Invalid chip id 0x%04x\n", val);
		return -1;
	}

	debug("Read back KS8851 id 0x%x\n", val);

	if ((val & 0xfff0) != CIDER_ID) {
		printf(DRIVERNAME ": Unknown chip ID %04x\n", val);
		return -1;
	}

	return 0;
}

static void ks8851_mll_reset(struct ks_net *ks)
{
	/* wake up powermode to normal mode */
	ks_set_powermode(ks, PMECR_PM_NORMAL);
	mdelay(1);	/* wait for normal mode to take effect */

	/* Disable interrupt and reset */
	ks_soft_reset(ks, GRR_GSR);

	/* turn off the IRQs and ack any outstanding */
	ks_wrreg16(ks, KS_IER, 0x0000);
	ks_wrreg16(ks, KS_ISR, 0xffff);

	/* shutdown RX/TX QMU */
	ks_disable_qmu(ks);
}

static void ks8851_mll_phy_configure(struct ks_net *ks)
{
	u16 data;

	ks_setup(ks);
	ks_setup_int(ks);

	/* Probing the phy */
	data = ks_rdreg16(ks, KS_OBCR);
	ks_wrreg16(ks, KS_OBCR, data | OBCR_ODS_16MA);

	debug(DRIVERNAME ": phy initialized\n");
}

static void ks8851_mll_enable(struct ks_net *ks)
{
	ks_wrreg16(ks, KS_ISR, 0xffff);
	ks_enable_int(ks);
	ks_enable_qmu(ks);
}

static int ks8851_mll_init_common(struct ks_net *ks)
{
	if (ks_read_selftest(ks)) {
		printf(DRIVERNAME ": Selftest failed\n");
		return -1;
	}

	ks8851_mll_reset(ks);

	/* Configure the PHY, initialize the link state */
	ks8851_mll_phy_configure(ks);

	ks->rxfc = 0;

	/* Turn on Tx + Rx */
	ks8851_mll_enable(ks);

	return 0;
}

static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len)
{
	__le16 txw[2];
	/* start header at txb[0] to align txw entries */
	txw[0] = 0;
	txw[1] = cpu_to_le16(len);

	/* 1. set sudo-DMA mode */
	ks_wrreg16(ks, KS_TXFDPR, TXFDPR_TXFPAI);
	ks_wrreg16(ks, KS_RXQCR, RXQCR_CMD_CNTL | RXQCR_SDA);
	/* 2. write status/length info */
	ks_outblk(ks, txw, 4);
	/* 3. write pkt data */
	ks_outblk(ks, (u16 *)pdata, ALIGN(len, 4));
	/* 4. reset sudo-DMA mode */
	ks_wrreg16(ks, KS_RXQCR, RXQCR_CMD_CNTL);
	/* 5. Enqueue Tx(move the pkt from TX buffer into TXQ) */
	ks_wrreg16(ks, KS_TXQCR, TXQCR_METFE);
	/* 6. wait until TXQCR_METFE is auto-cleared */
	do { } while (ks_rdreg16(ks, KS_TXQCR) & TXQCR_METFE);
}

static int ks8851_mll_send_common(struct ks_net *ks, void *packet, int length)
{
	u8 *data = (u8 *)packet;
	u16 tmplen = (u16)length;
	u16 retv;

	/*
	 * Extra space are required:
	 * 4 byte for alignment, 4 for status/length, 4 for CRC
	 */
	retv = ks_rdreg16(ks, KS_TXMIR) & 0x1fff;
	if (retv >= tmplen + 12) {
		ks_write_qmu(ks, data, tmplen);
		return 0;
	}

	printf(DRIVERNAME ": failed to send packet: No buffer\n");
	return -1;
}

static void ks8851_mll_halt_common(struct ks_net *ks)
{
	ks8851_mll_reset(ks);
}

/*
 * Maximum receive ring size; that is, the number of packets
 * we can buffer before overflow happens. Basically, this just
 * needs to be enough to prevent a packet being discarded while
 * we are processing the previous one.
 */
static int ks8851_mll_recv_common(struct ks_net *ks, uchar *data)
{
	u16 status;
	int ret = 0;

	status = ks_rdreg16(ks, KS_ISR);

	ks_wrreg16(ks, KS_ISR, status);

	if (ks->rxfc || (status & IRQ_RXI))
		ret = ks_rcv(ks, data);

	if (status & IRQ_LDI) {
		u16 pmecr = ks_rdreg16(ks, KS_PMECR);

		pmecr &= ~PMECR_WKEVT_MASK;
		ks_wrreg16(ks, KS_PMECR, pmecr | PMECR_WKEVT_LINK);
	}

	return ret;
}

static void ks8851_mll_write_hwaddr_common(struct ks_net *ks, u8 enetaddr[6])
{
	u16 addrl, addrm, addrh;

	addrh = (enetaddr[0] << 8) | enetaddr[1];
	addrm = (enetaddr[2] << 8) | enetaddr[3];
	addrl = (enetaddr[4] << 8) | enetaddr[5];

	ks_wrreg16(ks, KS_MARH, addrh);
	ks_wrreg16(ks, KS_MARM, addrm);
	ks_wrreg16(ks, KS_MARL, addrl);
}

#ifndef CONFIG_DM_ETH
static int ks8851_mll_init(struct eth_device *dev, bd_t *bd)
{
	struct ks_net *ks = container_of(dev, struct ks_net, dev);

	return ks8851_mll_init_common(ks);
}

static void ks8851_mll_halt(struct eth_device *dev)
{
	struct ks_net *ks = container_of(dev, struct ks_net, dev);

	ks8851_mll_halt_common(ks);
}

static int ks8851_mll_send(struct eth_device *dev, void *packet, int length)
{
	struct ks_net *ks = container_of(dev, struct ks_net, dev);

	return ks8851_mll_send_common(ks, packet, length);
}

static int ks8851_mll_recv(struct eth_device *dev)
{
	struct ks_net *ks = container_of(dev, struct ks_net, dev);
	int ret;

	ret = ks8851_mll_recv_common(ks, net_rx_packets[0]);
	if (ret)
		net_process_received_packet(net_rx_packets[0], ret);

	return ret;
}

static int ks8851_mll_write_hwaddr(struct eth_device *dev)
{
	struct ks_net *ks = container_of(dev, struct ks_net, dev);

	ks8851_mll_write_hwaddr_common(ks, ks->dev.enetaddr);

	return 0;
}

int ks8851_mll_initialize(u8 dev_num, int base_addr)
{
	struct ks_net *ks;

	ks = calloc(1, sizeof(*ks));
	if (!ks)
		return -ENOMEM;

	ks->iobase = base_addr;

	/* Try to detect chip. Will fail if not present. */
	if (ks8851_mll_detect_chip(ks)) {
		free(ks);
		return -1;
	}

	ks->dev.init = ks8851_mll_init;
	ks->dev.halt = ks8851_mll_halt;
	ks->dev.send = ks8851_mll_send;
	ks->dev.recv = ks8851_mll_recv;
	ks->dev.write_hwaddr = ks8851_mll_write_hwaddr;
	sprintf(ks->dev.name, "%s-%hu", DRIVERNAME, dev_num);

	eth_register(&ks->dev);

	return 0;
}
#else	/* ifdef CONFIG_DM_ETH */
static int ks8851_start(struct udevice *dev)
{
	struct ks_net *ks = dev_get_priv(dev);

	return ks8851_mll_init_common(ks);
}

static void ks8851_stop(struct udevice *dev)
{
	struct ks_net *ks = dev_get_priv(dev);

	ks8851_mll_halt_common(ks);
}

static int ks8851_send(struct udevice *dev, void *packet, int length)
{
	struct ks_net *ks = dev_get_priv(dev);
	int ret;

	ret = ks8851_mll_send_common(ks, packet, length);

	return ret ? 0 : -ETIMEDOUT;
}

static int ks8851_recv(struct udevice *dev, int flags, uchar **packetp)
{
	struct ks_net *ks = dev_get_priv(dev);
	uchar *data = net_rx_packets[0];
	int ret;

	ret = ks8851_mll_recv_common(ks, data);
	if (ret)
		*packetp = (void *)data;

	return ret ? ret : -EAGAIN;
}

static int ks8851_write_hwaddr(struct udevice *dev)
{
	struct ks_net *ks = dev_get_priv(dev);
	struct eth_pdata *pdata = dev_get_platdata(dev);

	ks8851_mll_write_hwaddr_common(ks, pdata->enetaddr);

	return 0;
}

static int ks8851_bind(struct udevice *dev)
{
	return device_set_name(dev, dev->name);
}

static int ks8851_probe(struct udevice *dev)
{
	struct ks_net *ks = dev_get_priv(dev);

	/* Try to detect chip. Will fail if not present. */
	ks8851_mll_detect_chip(ks);

	return 0;
}

static int ks8851_ofdata_to_platdata(struct udevice *dev)
{
	struct ks_net *ks = dev_get_priv(dev);
	struct eth_pdata *pdata = dev_get_platdata(dev);

	pdata->iobase = devfdt_get_addr(dev);
	ks->iobase = pdata->iobase;

	return 0;
}

static const struct eth_ops ks8851_ops = {
	.start		= ks8851_start,
	.stop		= ks8851_stop,
	.send		= ks8851_send,
	.recv		= ks8851_recv,
	.write_hwaddr	= ks8851_write_hwaddr,
};

static const struct udevice_id ks8851_ids[] = {
	{ .compatible = "micrel,ks8851-mll" },
	{ }
};

U_BOOT_DRIVER(ks8851) = {
	.name		= "eth_ks8851",
	.id		= UCLASS_ETH,
	.of_match	= ks8851_ids,
	.bind		= ks8851_bind,
	.ofdata_to_platdata = ks8851_ofdata_to_platdata,
	.probe		= ks8851_probe,
	.ops		= &ks8851_ops,
	.priv_auto_alloc_size = sizeof(struct ks_net),
	.platdata_auto_alloc_size = sizeof(struct eth_pdata),
	.flags		= DM_FLAG_ALLOC_PRIV_DMA,
};
#endif
