cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

idt_gen2.c (12534B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * IDT CPS Gen.2 Serial RapidIO switch family support
      4 *
      5 * Copyright 2010 Integrated Device Technology, Inc.
      6 * Alexandre Bounine <alexandre.bounine@idt.com>
      7 */
      8
      9#include <linux/stat.h>
     10#include <linux/module.h>
     11#include <linux/rio.h>
     12#include <linux/rio_drv.h>
     13#include <linux/rio_ids.h>
     14#include <linux/delay.h>
     15
     16#include <asm/page.h>
     17#include "../rio.h"
     18
     19#define LOCAL_RTE_CONF_DESTID_SEL	0x010070
     20#define LOCAL_RTE_CONF_DESTID_SEL_PSEL	0x0000001f
     21
     22#define IDT_LT_ERR_REPORT_EN	0x03100c
     23
     24#define IDT_PORT_ERR_REPORT_EN(n)	(0x031044 + (n)*0x40)
     25#define IDT_PORT_ERR_REPORT_EN_BC	0x03ff04
     26
     27#define IDT_PORT_ISERR_REPORT_EN(n)	(0x03104C + (n)*0x40)
     28#define IDT_PORT_ISERR_REPORT_EN_BC	0x03ff0c
     29#define IDT_PORT_INIT_TX_ACQUIRED	0x00000020
     30
     31#define IDT_LANE_ERR_REPORT_EN(n)	(0x038010 + (n)*0x100)
     32#define IDT_LANE_ERR_REPORT_EN_BC	0x03ff10
     33
     34#define IDT_DEV_CTRL_1		0xf2000c
     35#define IDT_DEV_CTRL_1_GENPW		0x02000000
     36#define IDT_DEV_CTRL_1_PRSTBEH		0x00000001
     37
     38#define IDT_CFGBLK_ERR_CAPTURE_EN	0x020008
     39#define IDT_CFGBLK_ERR_REPORT		0xf20014
     40#define IDT_CFGBLK_ERR_REPORT_GENPW		0x00000002
     41
     42#define IDT_AUX_PORT_ERR_CAP_EN	0x020000
     43#define IDT_AUX_ERR_REPORT_EN	0xf20018
     44#define IDT_AUX_PORT_ERR_LOG_I2C	0x00000002
     45#define IDT_AUX_PORT_ERR_LOG_JTAG	0x00000001
     46
     47#define	IDT_ISLTL_ADDRESS_CAP	0x021014
     48
     49#define IDT_RIO_DOMAIN		0xf20020
     50#define IDT_RIO_DOMAIN_MASK		0x000000ff
     51
     52#define IDT_PW_INFO_CSR		0xf20024
     53
     54#define IDT_SOFT_RESET		0xf20040
     55#define IDT_SOFT_RESET_REQ		0x00030097
     56
     57#define IDT_I2C_MCTRL		0xf20050
     58#define IDT_I2C_MCTRL_GENPW		0x04000000
     59
     60#define IDT_JTAG_CTRL		0xf2005c
     61#define IDT_JTAG_CTRL_GENPW		0x00000002
     62
     63#define IDT_LANE_CTRL(n)	(0xff8000 + (n)*0x100)
     64#define IDT_LANE_CTRL_BC	0xffff00
     65#define IDT_LANE_CTRL_GENPW		0x00200000
     66#define IDT_LANE_DFE_1_BC	0xffff18
     67#define IDT_LANE_DFE_2_BC	0xffff1c
     68
     69#define IDT_PORT_OPS(n)		(0xf40004 + (n)*0x100)
     70#define IDT_PORT_OPS_GENPW		0x08000000
     71#define IDT_PORT_OPS_PL_ELOG		0x00000040
     72#define IDT_PORT_OPS_LL_ELOG		0x00000020
     73#define IDT_PORT_OPS_LT_ELOG		0x00000010
     74#define IDT_PORT_OPS_BC		0xf4ff04
     75
     76#define IDT_PORT_ISERR_DET(n)	(0xf40008 + (n)*0x100)
     77
     78#define IDT_ERR_CAP		0xfd0000
     79#define IDT_ERR_CAP_LOG_OVERWR		0x00000004
     80
     81#define IDT_ERR_RD		0xfd0004
     82
     83#define IDT_DEFAULT_ROUTE	0xde
     84#define IDT_NO_ROUTE		0xdf
     85
     86static int
     87idtg2_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
     88		       u16 table, u16 route_destid, u8 route_port)
     89{
     90	/*
     91	 * Select routing table to update
     92	 */
     93	if (table == RIO_GLOBAL_TABLE)
     94		table = 0;
     95	else
     96		table++;
     97
     98	if (route_port == RIO_INVALID_ROUTE)
     99		route_port = IDT_DEFAULT_ROUTE;
    100
    101	rio_mport_write_config_32(mport, destid, hopcount,
    102				  LOCAL_RTE_CONF_DESTID_SEL, table);
    103
    104	/*
    105	 * Program destination port for the specified destID
    106	 */
    107	rio_mport_write_config_32(mport, destid, hopcount,
    108				  RIO_STD_RTE_CONF_DESTID_SEL_CSR,
    109				  (u32)route_destid);
    110
    111	rio_mport_write_config_32(mport, destid, hopcount,
    112				  RIO_STD_RTE_CONF_PORT_SEL_CSR,
    113				  (u32)route_port);
    114	udelay(10);
    115
    116	return 0;
    117}
    118
    119static int
    120idtg2_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
    121		       u16 table, u16 route_destid, u8 *route_port)
    122{
    123	u32 result;
    124
    125	/*
    126	 * Select routing table to read
    127	 */
    128	if (table == RIO_GLOBAL_TABLE)
    129		table = 0;
    130	else
    131		table++;
    132
    133	rio_mport_write_config_32(mport, destid, hopcount,
    134				  LOCAL_RTE_CONF_DESTID_SEL, table);
    135
    136	rio_mport_write_config_32(mport, destid, hopcount,
    137				  RIO_STD_RTE_CONF_DESTID_SEL_CSR,
    138				  route_destid);
    139
    140	rio_mport_read_config_32(mport, destid, hopcount,
    141				 RIO_STD_RTE_CONF_PORT_SEL_CSR, &result);
    142
    143	if (IDT_DEFAULT_ROUTE == (u8)result || IDT_NO_ROUTE == (u8)result)
    144		*route_port = RIO_INVALID_ROUTE;
    145	else
    146		*route_port = (u8)result;
    147
    148	return 0;
    149}
    150
    151static int
    152idtg2_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
    153		       u16 table)
    154{
    155	u32 i;
    156
    157	/*
    158	 * Select routing table to read
    159	 */
    160	if (table == RIO_GLOBAL_TABLE)
    161		table = 0;
    162	else
    163		table++;
    164
    165	rio_mport_write_config_32(mport, destid, hopcount,
    166				  LOCAL_RTE_CONF_DESTID_SEL, table);
    167
    168	for (i = RIO_STD_RTE_CONF_EXTCFGEN;
    169	     i <= (RIO_STD_RTE_CONF_EXTCFGEN | 0xff);) {
    170		rio_mport_write_config_32(mport, destid, hopcount,
    171			RIO_STD_RTE_CONF_DESTID_SEL_CSR, i);
    172		rio_mport_write_config_32(mport, destid, hopcount,
    173			RIO_STD_RTE_CONF_PORT_SEL_CSR,
    174			(IDT_DEFAULT_ROUTE << 24) | (IDT_DEFAULT_ROUTE << 16) |
    175			(IDT_DEFAULT_ROUTE << 8) | IDT_DEFAULT_ROUTE);
    176		i += 4;
    177	}
    178
    179	return 0;
    180}
    181
    182
    183static int
    184idtg2_set_domain(struct rio_mport *mport, u16 destid, u8 hopcount,
    185		       u8 sw_domain)
    186{
    187	/*
    188	 * Switch domain configuration operates only at global level
    189	 */
    190	rio_mport_write_config_32(mport, destid, hopcount,
    191				  IDT_RIO_DOMAIN, (u32)sw_domain);
    192	return 0;
    193}
    194
    195static int
    196idtg2_get_domain(struct rio_mport *mport, u16 destid, u8 hopcount,
    197		       u8 *sw_domain)
    198{
    199	u32 regval;
    200
    201	/*
    202	 * Switch domain configuration operates only at global level
    203	 */
    204	rio_mport_read_config_32(mport, destid, hopcount,
    205				IDT_RIO_DOMAIN, &regval);
    206
    207	*sw_domain = (u8)(regval & 0xff);
    208
    209	return 0;
    210}
    211
    212static int
    213idtg2_em_init(struct rio_dev *rdev)
    214{
    215	u32 regval;
    216	int i, tmp;
    217
    218	/*
    219	 * This routine performs device-specific initialization only.
    220	 * All standard EM configuration should be performed at upper level.
    221	 */
    222
    223	pr_debug("RIO: %s [%d:%d]\n", __func__, rdev->destid, rdev->hopcount);
    224
    225	/* Set Port-Write info CSR: PRIO=3 and CRF=1 */
    226	rio_write_config_32(rdev, IDT_PW_INFO_CSR, 0x0000e000);
    227
    228	/*
    229	 * Configure LT LAYER error reporting.
    230	 */
    231
    232	/* Enable standard (RIO.p8) error reporting */
    233	rio_write_config_32(rdev, IDT_LT_ERR_REPORT_EN,
    234			REM_LTL_ERR_ILLTRAN | REM_LTL_ERR_UNSOLR |
    235			REM_LTL_ERR_UNSUPTR);
    236
    237	/* Use Port-Writes for LT layer error reporting.
    238	 * Enable per-port reset
    239	 */
    240	rio_read_config_32(rdev, IDT_DEV_CTRL_1, &regval);
    241	rio_write_config_32(rdev, IDT_DEV_CTRL_1,
    242			regval | IDT_DEV_CTRL_1_GENPW | IDT_DEV_CTRL_1_PRSTBEH);
    243
    244	/*
    245	 * Configure PORT error reporting.
    246	 */
    247
    248	/* Report all RIO.p8 errors supported by device */
    249	rio_write_config_32(rdev, IDT_PORT_ERR_REPORT_EN_BC, 0x807e8037);
    250
    251	/* Configure reporting of implementation specific errors/events */
    252	rio_write_config_32(rdev, IDT_PORT_ISERR_REPORT_EN_BC,
    253			    IDT_PORT_INIT_TX_ACQUIRED);
    254
    255	/* Use Port-Writes for port error reporting and enable error logging */
    256	tmp = RIO_GET_TOTAL_PORTS(rdev->swpinfo);
    257	for (i = 0; i < tmp; i++) {
    258		rio_read_config_32(rdev, IDT_PORT_OPS(i), &regval);
    259		rio_write_config_32(rdev,
    260				IDT_PORT_OPS(i), regval | IDT_PORT_OPS_GENPW |
    261				IDT_PORT_OPS_PL_ELOG |
    262				IDT_PORT_OPS_LL_ELOG |
    263				IDT_PORT_OPS_LT_ELOG);
    264	}
    265	/* Overwrite error log if full */
    266	rio_write_config_32(rdev, IDT_ERR_CAP, IDT_ERR_CAP_LOG_OVERWR);
    267
    268	/*
    269	 * Configure LANE error reporting.
    270	 */
    271
    272	/* Disable line error reporting */
    273	rio_write_config_32(rdev, IDT_LANE_ERR_REPORT_EN_BC, 0);
    274
    275	/* Use Port-Writes for lane error reporting (when enabled)
    276	 * (do per-lane update because lanes may have different configuration)
    277	 */
    278	tmp = (rdev->did == RIO_DID_IDTCPS1848) ? 48 : 16;
    279	for (i = 0; i < tmp; i++) {
    280		rio_read_config_32(rdev, IDT_LANE_CTRL(i), &regval);
    281		rio_write_config_32(rdev, IDT_LANE_CTRL(i),
    282				    regval | IDT_LANE_CTRL_GENPW);
    283	}
    284
    285	/*
    286	 * Configure AUX error reporting.
    287	 */
    288
    289	/* Disable JTAG and I2C Error capture */
    290	rio_write_config_32(rdev, IDT_AUX_PORT_ERR_CAP_EN, 0);
    291
    292	/* Disable JTAG and I2C Error reporting/logging */
    293	rio_write_config_32(rdev, IDT_AUX_ERR_REPORT_EN, 0);
    294
    295	/* Disable Port-Write notification from JTAG */
    296	rio_write_config_32(rdev, IDT_JTAG_CTRL, 0);
    297
    298	/* Disable Port-Write notification from I2C */
    299	rio_read_config_32(rdev, IDT_I2C_MCTRL, &regval);
    300	rio_write_config_32(rdev, IDT_I2C_MCTRL, regval & ~IDT_I2C_MCTRL_GENPW);
    301
    302	/*
    303	 * Configure CFG_BLK error reporting.
    304	 */
    305
    306	/* Disable Configuration Block error capture */
    307	rio_write_config_32(rdev, IDT_CFGBLK_ERR_CAPTURE_EN, 0);
    308
    309	/* Disable Port-Writes for Configuration Block error reporting */
    310	rio_read_config_32(rdev, IDT_CFGBLK_ERR_REPORT, &regval);
    311	rio_write_config_32(rdev, IDT_CFGBLK_ERR_REPORT,
    312			    regval & ~IDT_CFGBLK_ERR_REPORT_GENPW);
    313
    314	/* set TVAL = ~50us */
    315	rio_write_config_32(rdev,
    316		rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8);
    317
    318	return 0;
    319}
    320
    321static int
    322idtg2_em_handler(struct rio_dev *rdev, u8 portnum)
    323{
    324	u32 regval, em_perrdet, em_ltlerrdet;
    325
    326	rio_read_config_32(rdev,
    327		rdev->em_efptr + RIO_EM_LTL_ERR_DETECT, &em_ltlerrdet);
    328	if (em_ltlerrdet) {
    329		/* Service Logical/Transport Layer Error(s) */
    330		if (em_ltlerrdet & REM_LTL_ERR_IMPSPEC) {
    331			/* Implementation specific error reported */
    332			rio_read_config_32(rdev,
    333					IDT_ISLTL_ADDRESS_CAP, &regval);
    334
    335			pr_debug("RIO: %s Implementation Specific LTL errors" \
    336				 " 0x%x @(0x%x)\n",
    337				 rio_name(rdev), em_ltlerrdet, regval);
    338
    339			/* Clear implementation specific address capture CSR */
    340			rio_write_config_32(rdev, IDT_ISLTL_ADDRESS_CAP, 0);
    341
    342		}
    343	}
    344
    345	rio_read_config_32(rdev,
    346		rdev->em_efptr + RIO_EM_PN_ERR_DETECT(portnum), &em_perrdet);
    347	if (em_perrdet) {
    348		/* Service Port-Level Error(s) */
    349		if (em_perrdet & REM_PED_IMPL_SPEC) {
    350			/* Implementation Specific port error reported */
    351
    352			/* Get IS errors reported */
    353			rio_read_config_32(rdev,
    354					IDT_PORT_ISERR_DET(portnum), &regval);
    355
    356			pr_debug("RIO: %s Implementation Specific Port" \
    357				 " errors 0x%x\n", rio_name(rdev), regval);
    358
    359			/* Clear all implementation specific events */
    360			rio_write_config_32(rdev,
    361					IDT_PORT_ISERR_DET(portnum), 0);
    362		}
    363	}
    364
    365	return 0;
    366}
    367
    368static ssize_t
    369idtg2_show_errlog(struct device *dev, struct device_attribute *attr, char *buf)
    370{
    371	struct rio_dev *rdev = to_rio_dev(dev);
    372	ssize_t len = 0;
    373	u32 regval;
    374
    375	while (!rio_read_config_32(rdev, IDT_ERR_RD, &regval)) {
    376		if (!regval)    /* 0 = end of log */
    377			break;
    378		len += snprintf(buf + len, PAGE_SIZE - len,
    379					"%08x\n", regval);
    380		if (len >= (PAGE_SIZE - 10))
    381			break;
    382	}
    383
    384	return len;
    385}
    386
    387static DEVICE_ATTR(errlog, S_IRUGO, idtg2_show_errlog, NULL);
    388
    389static int idtg2_sysfs(struct rio_dev *rdev, bool create)
    390{
    391	struct device *dev = &rdev->dev;
    392	int err = 0;
    393
    394	if (create) {
    395		/* Initialize sysfs entries */
    396		err = device_create_file(dev, &dev_attr_errlog);
    397		if (err)
    398			dev_err(dev, "Unable create sysfs errlog file\n");
    399	} else
    400		device_remove_file(dev, &dev_attr_errlog);
    401
    402	return err;
    403}
    404
    405static struct rio_switch_ops idtg2_switch_ops = {
    406	.owner = THIS_MODULE,
    407	.add_entry = idtg2_route_add_entry,
    408	.get_entry = idtg2_route_get_entry,
    409	.clr_table = idtg2_route_clr_table,
    410	.set_domain = idtg2_set_domain,
    411	.get_domain = idtg2_get_domain,
    412	.em_init = idtg2_em_init,
    413	.em_handle = idtg2_em_handler,
    414};
    415
    416static int idtg2_probe(struct rio_dev *rdev, const struct rio_device_id *id)
    417{
    418	pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
    419
    420	spin_lock(&rdev->rswitch->lock);
    421
    422	if (rdev->rswitch->ops) {
    423		spin_unlock(&rdev->rswitch->lock);
    424		return -EINVAL;
    425	}
    426
    427	rdev->rswitch->ops = &idtg2_switch_ops;
    428
    429	if (rdev->do_enum) {
    430		/* Ensure that default routing is disabled on startup */
    431		rio_write_config_32(rdev,
    432				    RIO_STD_RTE_DEFAULT_PORT, IDT_NO_ROUTE);
    433	}
    434
    435	spin_unlock(&rdev->rswitch->lock);
    436
    437	/* Create device-specific sysfs attributes */
    438	idtg2_sysfs(rdev, true);
    439
    440	return 0;
    441}
    442
    443static void idtg2_remove(struct rio_dev *rdev)
    444{
    445	pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
    446	spin_lock(&rdev->rswitch->lock);
    447	if (rdev->rswitch->ops != &idtg2_switch_ops) {
    448		spin_unlock(&rdev->rswitch->lock);
    449		return;
    450	}
    451	rdev->rswitch->ops = NULL;
    452	spin_unlock(&rdev->rswitch->lock);
    453	/* Remove device-specific sysfs attributes */
    454	idtg2_sysfs(rdev, false);
    455}
    456
    457static const struct rio_device_id idtg2_id_table[] = {
    458	{RIO_DEVICE(RIO_DID_IDTCPS1848, RIO_VID_IDT)},
    459	{RIO_DEVICE(RIO_DID_IDTCPS1616, RIO_VID_IDT)},
    460	{RIO_DEVICE(RIO_DID_IDTVPS1616, RIO_VID_IDT)},
    461	{RIO_DEVICE(RIO_DID_IDTSPS1616, RIO_VID_IDT)},
    462	{RIO_DEVICE(RIO_DID_IDTCPS1432, RIO_VID_IDT)},
    463	{ 0, }	/* terminate list */
    464};
    465
    466static struct rio_driver idtg2_driver = {
    467	.name = "idt_gen2",
    468	.id_table = idtg2_id_table,
    469	.probe = idtg2_probe,
    470	.remove = idtg2_remove,
    471};
    472
    473static int __init idtg2_init(void)
    474{
    475	return rio_register_driver(&idtg2_driver);
    476}
    477
    478static void __exit idtg2_exit(void)
    479{
    480	pr_debug("RIO: %s\n", __func__);
    481	rio_unregister_driver(&idtg2_driver);
    482	pr_debug("RIO: %s done\n", __func__);
    483}
    484
    485device_initcall(idtg2_init);
    486module_exit(idtg2_exit);
    487
    488MODULE_DESCRIPTION("IDT CPS Gen.2 Serial RapidIO switch family driver");
    489MODULE_AUTHOR("Integrated Device Technology, Inc.");
    490MODULE_LICENSE("GPL");