// 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, struct bd_info * 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;
}
