// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * IDT RXS Gen.3 Serial RapidIO switch family support
 *
 * Copyright 2016 Integrated Device Technology, Inc.
 */

#include <linux/stat.h>
#include <linux/module.h>
#include <linux/rio.h>
#include <linux/rio_drv.h>
#include <linux/rio_ids.h>
#include <linux/delay.h>

#include <asm/page.h>
#include "../rio.h"

#define RIO_EM_PW_STAT		0x40020
#define RIO_PW_CTL		0x40204
#define RIO_PW_CTL_PW_TMR		0xffffff00
#define RIO_PW_ROUTE		0x40208

#define RIO_EM_DEV_INT_EN	0x40030

#define RIO_PLM_SPx_IMP_SPEC_CTL(x)	(0x10100 + (x)*0x100)
#define RIO_PLM_SPx_IMP_SPEC_CTL_SOFT_RST	0x02000000

#define RIO_PLM_SPx_PW_EN(x)	(0x10118 + (x)*0x100)
#define RIO_PLM_SPx_PW_EN_OK2U	0x40000000
#define RIO_PLM_SPx_PW_EN_LINIT 0x10000000

#define RIO_BC_L2_Gn_ENTRYx_CSR(n, x)	(0x31000 + (n)*0x400 + (x)*0x4)
#define RIO_SPx_L2_Gn_ENTRYy_CSR(x, n, y) \
				(0x51000 + (x)*0x2000 + (n)*0x400 + (y)*0x4)

static int
idtg3_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
		       u16 table, u16 route_destid, u8 route_port)
{
	u32 rval;
	u32 entry = route_port;
	int err = 0;

	pr_debug("RIO: %s t=0x%x did_%x to p_%x\n",
		 __func__, table, route_destid, entry);

	if (route_destid > 0xFF)
		return -EINVAL;

	if (route_port == RIO_INVALID_ROUTE)
		entry = RIO_RT_ENTRY_DROP_PKT;

	if (table == RIO_GLOBAL_TABLE) {
		/* Use broadcast register to update all per-port tables */
		err = rio_mport_write_config_32(mport, destid, hopcount,
				RIO_BC_L2_Gn_ENTRYx_CSR(0, route_destid),
				entry);
		return err;
	}

	/*
	 * Verify that specified port/table number is valid
	 */
	err = rio_mport_read_config_32(mport, destid, hopcount,
				       RIO_SWP_INFO_CAR, &rval);
	if (err)
		return err;

	if (table >= RIO_GET_TOTAL_PORTS(rval))
		return -EINVAL;

	err = rio_mport_write_config_32(mport, destid, hopcount,
			RIO_SPx_L2_Gn_ENTRYy_CSR(table, 0, route_destid),
			entry);
	return err;
}

static int
idtg3_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
		       u16 table, u16 route_destid, u8 *route_port)
{
	u32 rval;
	int err;

	if (route_destid > 0xFF)
		return -EINVAL;

	err = rio_mport_read_config_32(mport, destid, hopcount,
				       RIO_SWP_INFO_CAR, &rval);
	if (err)
		return err;

	/*
	 * This switch device does not have the dedicated global routing table.
	 * It is substituted by reading routing table of the ingress port of
	 * maintenance read requests.
	 */
	if (table == RIO_GLOBAL_TABLE)
		table = RIO_GET_PORT_NUM(rval);
	else if (table >= RIO_GET_TOTAL_PORTS(rval))
		return -EINVAL;

	err = rio_mport_read_config_32(mport, destid, hopcount,
			RIO_SPx_L2_Gn_ENTRYy_CSR(table, 0, route_destid),
			&rval);
	if (err)
		return err;

	if (rval == RIO_RT_ENTRY_DROP_PKT)
		*route_port = RIO_INVALID_ROUTE;
	else
		*route_port = (u8)rval;

	return 0;
}

static int
idtg3_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
		       u16 table)
{
	u32 i;
	u32 rval;
	int err;

	if (table == RIO_GLOBAL_TABLE) {
		for (i = 0; i <= 0xff; i++) {
			err = rio_mport_write_config_32(mport, destid, hopcount,
						RIO_BC_L2_Gn_ENTRYx_CSR(0, i),
						RIO_RT_ENTRY_DROP_PKT);
			if (err)
				break;
		}

		return err;
	}

	err = rio_mport_read_config_32(mport, destid, hopcount,
				       RIO_SWP_INFO_CAR, &rval);
	if (err)
		return err;

	if (table >= RIO_GET_TOTAL_PORTS(rval))
		return -EINVAL;

	for (i = 0; i <= 0xff; i++) {
		err = rio_mport_write_config_32(mport, destid, hopcount,
					RIO_SPx_L2_Gn_ENTRYy_CSR(table, 0, i),
					RIO_RT_ENTRY_DROP_PKT);
		if (err)
			break;
	}

	return err;
}

/*
 * This routine performs device-specific initialization only.
 * All standard EM configuration should be performed at upper level.
 */
static int
idtg3_em_init(struct rio_dev *rdev)
{
	int i, tmp;
	u32 rval;

	pr_debug("RIO: %s [%d:%d]\n", __func__, rdev->destid, rdev->hopcount);

	/* Disable assertion of interrupt signal */
	rio_write_config_32(rdev, RIO_EM_DEV_INT_EN, 0);

	/* Disable port-write event notifications during initialization */
	rio_write_config_32(rdev, rdev->em_efptr + RIO_EM_PW_TX_CTRL,
			    RIO_EM_PW_TX_CTRL_PW_DIS);

	/* Configure Port-Write notifications for hot-swap events */
	tmp = RIO_GET_TOTAL_PORTS(rdev->swpinfo);
	for (i = 0; i < tmp; i++) {

		rio_read_config_32(rdev,
			RIO_DEV_PORT_N_ERR_STS_CSR(rdev, i),
			&rval);
		if (rval & RIO_PORT_N_ERR_STS_PORT_UA)
			continue;

		/* Clear events signaled before enabling notification */
		rio_write_config_32(rdev,
			rdev->em_efptr + RIO_EM_PN_ERR_DETECT(i), 0);

		/* Enable event notifications */
		rio_write_config_32(rdev,
			rdev->em_efptr + RIO_EM_PN_ERRRATE_EN(i),
			RIO_EM_PN_ERRRATE_EN_OK2U | RIO_EM_PN_ERRRATE_EN_U2OK);
		/* Enable port-write generation on events */
		rio_write_config_32(rdev, RIO_PLM_SPx_PW_EN(i),
			RIO_PLM_SPx_PW_EN_OK2U | RIO_PLM_SPx_PW_EN_LINIT);

	}

	/* Set Port-Write destination port */
	tmp = RIO_GET_PORT_NUM(rdev->swpinfo);
	rio_write_config_32(rdev, RIO_PW_ROUTE, 1 << tmp);


	/* Enable sending port-write event notifications */
	rio_write_config_32(rdev, rdev->em_efptr + RIO_EM_PW_TX_CTRL, 0);

	/* set TVAL = ~50us */
	rio_write_config_32(rdev,
		rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8);
	return 0;
}


/*
 * idtg3_em_handler - device-specific error handler
 *
 * If the link is down (PORT_UNINIT) does nothing - this is considered
 * as link partner removal from the port.
 *
 * If the link is up (PORT_OK) - situation is handled as *new* device insertion.
 * In this case ERR_STOP bits are cleared by issuing soft reset command to the
 * reporting port. Inbound and outbound ackIDs are cleared by the reset as well.
 * This way the port is synchronized with freshly inserted device (assuming it
 * was reset/powered-up on insertion).
 *
 * TODO: This is not sufficient in a situation when a link between two devices
 * was down and up again (e.g. cable disconnect). For that situation full ackID
 * realignment process has to be implemented.
 */
static int
idtg3_em_handler(struct rio_dev *rdev, u8 pnum)
{
	u32 err_status;
	u32 rval;

	rio_read_config_32(rdev,
			RIO_DEV_PORT_N_ERR_STS_CSR(rdev, pnum),
			&err_status);

	/* Do nothing for device/link removal */
	if (err_status & RIO_PORT_N_ERR_STS_PORT_UNINIT)
		return 0;

	/* When link is OK we have a device insertion.
	 * Request port soft reset to clear errors if they present.
	 * Inbound and outbound ackIDs will be 0 after reset.
	 */
	if (err_status & (RIO_PORT_N_ERR_STS_OUT_ES |
				RIO_PORT_N_ERR_STS_INP_ES)) {
		rio_read_config_32(rdev, RIO_PLM_SPx_IMP_SPEC_CTL(pnum), &rval);
		rio_write_config_32(rdev, RIO_PLM_SPx_IMP_SPEC_CTL(pnum),
				    rval | RIO_PLM_SPx_IMP_SPEC_CTL_SOFT_RST);
		udelay(10);
		rio_write_config_32(rdev, RIO_PLM_SPx_IMP_SPEC_CTL(pnum), rval);
		msleep(500);
	}

	return 0;
}

static struct rio_switch_ops idtg3_switch_ops = {
	.owner = THIS_MODULE,
	.add_entry = idtg3_route_add_entry,
	.get_entry = idtg3_route_get_entry,
	.clr_table = idtg3_route_clr_table,
	.em_init   = idtg3_em_init,
	.em_handle = idtg3_em_handler,
};

static int idtg3_probe(struct rio_dev *rdev, const struct rio_device_id *id)
{
	pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));

	spin_lock(&rdev->rswitch->lock);

	if (rdev->rswitch->ops) {
		spin_unlock(&rdev->rswitch->lock);
		return -EINVAL;
	}

	rdev->rswitch->ops = &idtg3_switch_ops;

	if (rdev->do_enum) {
		/* Disable hierarchical routing support: Existing fabric
		 * enumeration/discovery process (see rio-scan.c) uses 8-bit
		 * flat destination ID routing only.
		 */
		rio_write_config_32(rdev, 0x5000 + RIO_BC_RT_CTL_CSR, 0);
	}

	spin_unlock(&rdev->rswitch->lock);

	return 0;
}

static void idtg3_remove(struct rio_dev *rdev)
{
	pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
	spin_lock(&rdev->rswitch->lock);
	if (rdev->rswitch->ops == &idtg3_switch_ops)
		rdev->rswitch->ops = NULL;
	spin_unlock(&rdev->rswitch->lock);
}

/*
 * Gen3 switches repeat sending PW messages until a corresponding event flag
 * is cleared. Use shutdown notification to disable generation of port-write
 * messages if their destination node is shut down.
 */
static void idtg3_shutdown(struct rio_dev *rdev)
{
	int i;
	u32 rval;
	u16 destid;

	/* Currently the enumerator node acts also as PW handler */
	if (!rdev->do_enum)
		return;

	pr_debug("RIO: %s(%s)\n", __func__, rio_name(rdev));

	rio_read_config_32(rdev, RIO_PW_ROUTE, &rval);
	i = RIO_GET_PORT_NUM(rdev->swpinfo);

	/* Check port-write destination port */
	if (!((1 << i) & rval))
		return;

	/* Disable sending port-write event notifications if PW destID
	 * matches to one of the enumerator node
	 */
	rio_read_config_32(rdev, rdev->em_efptr + RIO_EM_PW_TGT_DEVID, &rval);

	if (rval & RIO_EM_PW_TGT_DEVID_DEV16)
		destid = rval >> 16;
	else
		destid = ((rval & RIO_EM_PW_TGT_DEVID_D8) >> 16);

	if (rdev->net->hport->host_deviceid == destid) {
		rio_write_config_32(rdev,
				    rdev->em_efptr + RIO_EM_PW_TX_CTRL, 0);
		pr_debug("RIO: %s(%s) PW transmission disabled\n",
			 __func__, rio_name(rdev));
	}
}

static const struct rio_device_id idtg3_id_table[] = {
	{RIO_DEVICE(RIO_DID_IDTRXS1632, RIO_VID_IDT)},
	{RIO_DEVICE(RIO_DID_IDTRXS2448, RIO_VID_IDT)},
	{ 0, }	/* terminate list */
};

static struct rio_driver idtg3_driver = {
	.name = "idt_gen3",
	.id_table = idtg3_id_table,
	.probe = idtg3_probe,
	.remove = idtg3_remove,
	.shutdown = idtg3_shutdown,
};

static int __init idtg3_init(void)
{
	return rio_register_driver(&idtg3_driver);
}

static void __exit idtg3_exit(void)
{
	pr_debug("RIO: %s\n", __func__);
	rio_unregister_driver(&idtg3_driver);
	pr_debug("RIO: %s done\n", __func__);
}

device_initcall(idtg3_init);
module_exit(idtg3_exit);

MODULE_DESCRIPTION("IDT RXS Gen.3 Serial RapidIO switch family driver");
MODULE_AUTHOR("Integrated Device Technology, Inc.");
MODULE_LICENSE("GPL");
