// SPDX-License-Identifier: GPL-2.0+
/*
 * Cirrus Logic CS8900A Ethernet
 *
 * (C) 2009 Ben Warren , biggerbadderben@gmail.com
 *     Converted to use CONFIG_NET_MULTI API
 *
 * (C) 2003 Wolfgang Denk, wd@denx.de
 *     Extension to synchronize ethaddr environment variable
 *     against value in EEPROM
 *
 * (C) Copyright 2002
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Marius Groeger <mgroeger@sysgo.de>
 *
 * Copyright (C) 1999 Ben Williamson <benw@pobox.com>
 *
 * This program is loaded into SRAM in bootstrap mode, where it waits
 * for commands on UART1 to read and write memory, jump to code etc.
 * A design goal for this program is to be entirely independent of the
 * target board.  Anything with a CL-PS7111 or EP7211 should be able to run
 * this code in bootstrap mode.  All the board specifics can be handled on
 * the host.
 */

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

#undef DEBUG

/* packet page register access functions */

#ifdef CONFIG_CS8900_BUS32

#define REG_WRITE(v, a) writel((v),(a))
#define REG_READ(a) readl((a))

/* we don't need 16 bit initialisation on 32 bit bus */
#define get_reg_init_bus(r,d) get_reg((r),(d))

#else

#define REG_WRITE(v, a) writew((v),(a))
#define REG_READ(a) readw((a))

static u16 get_reg_init_bus(struct eth_device *dev, int regno)
{
	/* force 16 bit busmode */
	struct cs8900_priv *priv = (struct cs8900_priv *)(dev->priv);
	uint8_t volatile * const iob = (uint8_t volatile * const)dev->iobase;

	readb(iob);
	readb(iob + 1);
	readb(iob);
	readb(iob + 1);
	readb(iob);

	REG_WRITE(regno, &priv->regs->pptr);
	return REG_READ(&priv->regs->pdata);
}
#endif

static u16 get_reg(struct eth_device *dev, int regno)
{
	struct cs8900_priv *priv = (struct cs8900_priv *)(dev->priv);
	REG_WRITE(regno, &priv->regs->pptr);
	return REG_READ(&priv->regs->pdata);
}


static void put_reg(struct eth_device *dev, int regno, u16 val)
{
	struct cs8900_priv *priv = (struct cs8900_priv *)(dev->priv);
	REG_WRITE(regno, &priv->regs->pptr);
	REG_WRITE(val, &priv->regs->pdata);
}

static void cs8900_reset(struct eth_device *dev)
{
	int tmo;
	u16 us;

	/* reset NIC */
	put_reg(dev, PP_SelfCTL, get_reg(dev, PP_SelfCTL) | PP_SelfCTL_Reset);

	/* wait for 200ms */
	udelay(200000);
	/* Wait until the chip is reset */

	tmo = get_timer(0) + 1 * CONFIG_SYS_HZ;
	while ((((us = get_reg_init_bus(dev, PP_SelfSTAT)) &
		PP_SelfSTAT_InitD) == 0) && tmo < get_timer(0))
		/*NOP*/;
}

static void cs8900_reginit(struct eth_device *dev)
{
	/* receive only error free packets addressed to this card */
	put_reg(dev, PP_RxCTL,
		PP_RxCTL_IA | PP_RxCTL_Broadcast | PP_RxCTL_RxOK);
	/* do not generate any interrupts on receive operations */
	put_reg(dev, PP_RxCFG, 0);
	/* do not generate any interrupts on transmit operations */
	put_reg(dev, PP_TxCFG, 0);
	/* do not generate any interrupts on buffer operations */
	put_reg(dev, PP_BufCFG, 0);
	/* enable transmitter/receiver mode */
	put_reg(dev, PP_LineCTL, PP_LineCTL_Rx | PP_LineCTL_Tx);
}

void cs8900_get_enetaddr(struct eth_device *dev)
{
	int i;

	/* verify chip id */
	if (get_reg_init_bus(dev, PP_ChipID) != 0x630e)
		return;
	cs8900_reset(dev);
	if ((get_reg(dev, PP_SelfSTAT) &
		(PP_SelfSTAT_EEPROM | PP_SelfSTAT_EEPROM_OK)) ==
		(PP_SelfSTAT_EEPROM | PP_SelfSTAT_EEPROM_OK)) {

		/* Load the MAC from EEPROM */
		for (i = 0; i < 3; i++) {
			u32 Addr;

			Addr = get_reg(dev, PP_IA + i * 2);
			dev->enetaddr[i * 2] = Addr & 0xFF;
			dev->enetaddr[i * 2 + 1] = Addr >> 8;
		}
	}
}

void cs8900_halt(struct eth_device *dev)
{
	/* disable transmitter/receiver mode */
	put_reg(dev, PP_LineCTL, 0);

	/* "shutdown" to show ChipID or kernel wouldn't find he cs8900 ... */
	get_reg_init_bus(dev, PP_ChipID);
}

static int cs8900_init(struct eth_device *dev, bd_t * bd)
{
	uchar *enetaddr = dev->enetaddr;
	u16 id;

	/* verify chip id */
	id = get_reg_init_bus(dev, PP_ChipID);
	if (id != 0x630e) {
		printf ("CS8900 Ethernet chip not found: "
			"ID=0x%04x instead 0x%04x\n", id, 0x630e);
		return 1;
	}

	cs8900_reset (dev);
	/* set the ethernet address */
	put_reg(dev, PP_IA + 0, enetaddr[0] | (enetaddr[1] << 8));
	put_reg(dev, PP_IA + 2, enetaddr[2] | (enetaddr[3] << 8));
	put_reg(dev, PP_IA + 4, enetaddr[4] | (enetaddr[5] << 8));

	cs8900_reginit(dev);
	return 0;
}

/* Get a data block via Ethernet */
static int cs8900_recv(struct eth_device *dev)
{
	int i;
	u16 rxlen;
	u16 *addr;
	u16 status;

	struct cs8900_priv *priv = (struct cs8900_priv *)(dev->priv);

	status = get_reg(dev, PP_RER);

	if ((status & PP_RER_RxOK) == 0)
		return 0;

	status = REG_READ(&priv->regs->rtdata);
	rxlen = REG_READ(&priv->regs->rtdata);

	if (rxlen > PKTSIZE_ALIGN + PKTALIGN)
		debug("packet too big!\n");
	for (addr = (u16 *)net_rx_packets[0], i = rxlen >> 1; i > 0; i--)
		*addr++ = REG_READ(&priv->regs->rtdata);
	if (rxlen & 1)
		*addr++ = REG_READ(&priv->regs->rtdata);

	/* Pass the packet up to the protocol layers. */
	net_process_received_packet(net_rx_packets[0], rxlen);
	return rxlen;
}

/* Send a data block via Ethernet. */
static int cs8900_send(struct eth_device *dev, void *packet, int length)
{
	volatile u16 *addr;
	int tmo;
	u16 s;
	struct cs8900_priv *priv = (struct cs8900_priv *)(dev->priv);

retry:
	/* initiate a transmit sequence */
	REG_WRITE(PP_TxCmd_TxStart_Full, &priv->regs->txcmd);
	REG_WRITE(length, &priv->regs->txlen);

	/* Test to see if the chip has allocated memory for the packet */
	if ((get_reg(dev, PP_BusSTAT) & PP_BusSTAT_TxRDY) == 0) {
		/* Oops... this should not happen! */
		debug("cs: unable to send packet; retrying...\n");
		for (tmo = get_timer(0) + 5 * CONFIG_SYS_HZ;
			get_timer(0) < tmo;)
			/*NOP*/;
		cs8900_reset(dev);
		cs8900_reginit(dev);
		goto retry;
	}

	/* Write the contents of the packet */
	/* assume even number of bytes */
	for (addr = packet; length > 0; length -= 2)
		REG_WRITE(*addr++, &priv->regs->rtdata);

	/* wait for transfer to succeed */
	tmo = get_timer(0) + 5 * CONFIG_SYS_HZ;
	while ((s = get_reg(dev, PP_TER) & ~0x1F) == 0) {
		if (get_timer(0) >= tmo)
			break;
	}

	/* nothing */ ;
	if((s & (PP_TER_CRS | PP_TER_TxOK)) != PP_TER_TxOK) {
		debug("\ntransmission error %#x\n", s);
	}

	return 0;
}

static void cs8900_e2prom_ready(struct eth_device *dev)
{
	while (get_reg(dev, PP_SelfSTAT) & SI_BUSY)
		;
}

/***********************************************************/
/* read a 16-bit word out of the EEPROM                    */
/***********************************************************/

int cs8900_e2prom_read(struct eth_device *dev,
			u8 addr, u16 *value)
{
	cs8900_e2prom_ready(dev);
	put_reg(dev, PP_EECMD, EEPROM_READ_CMD | addr);
	cs8900_e2prom_ready(dev);
	*value = get_reg(dev, PP_EEData);

	return 0;
}


/***********************************************************/
/* write a 16-bit word into the EEPROM                     */
/***********************************************************/

int cs8900_e2prom_write(struct eth_device *dev, u8 addr, u16 value)
{
	cs8900_e2prom_ready(dev);
	put_reg(dev, PP_EECMD, EEPROM_WRITE_EN);
	cs8900_e2prom_ready(dev);
	put_reg(dev, PP_EEData, value);
	put_reg(dev, PP_EECMD, EEPROM_WRITE_CMD | addr);
	cs8900_e2prom_ready(dev);
	put_reg(dev, PP_EECMD, EEPROM_WRITE_DIS);
	cs8900_e2prom_ready(dev);

	return 0;
}

int cs8900_initialize(u8 dev_num, int base_addr)
{
	struct eth_device *dev;
	struct cs8900_priv *priv;

	dev = malloc(sizeof(*dev));
	if (!dev) {
		return 0;
	}
	memset(dev, 0, sizeof(*dev));

	priv = malloc(sizeof(*priv));
	if (!priv) {
		free(dev);
		return 0;
	}
	memset(priv, 0, sizeof(*priv));
	priv->regs = (struct cs8900_regs *)base_addr;

	dev->iobase = base_addr;
	dev->priv = priv;
	dev->init = cs8900_init;
	dev->halt = cs8900_halt;
	dev->send = cs8900_send;
	dev->recv = cs8900_recv;

	/* Load MAC address from EEPROM */
	cs8900_get_enetaddr(dev);

	sprintf(dev->name, "%s-%hu", CS8900_DRIVERNAME, dev_num);

	eth_register(dev);
	return 0;
}
