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

xsurf100.c (10646B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <linux/module.h>
      3#include <linux/netdevice.h>
      4#include <linux/platform_device.h>
      5#include <linux/zorro.h>
      6#include <net/ax88796.h>
      7#include <asm/amigaints.h>
      8
      9#define ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF100 \
     10		ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x64, 0)
     11
     12#define XS100_IRQSTATUS_BASE 0x40
     13#define XS100_8390_BASE 0x800
     14
     15/* Longword-access area. Translated to 2 16-bit access cycles by the
     16 * X-Surf 100 FPGA
     17 */
     18#define XS100_8390_DATA32_BASE 0x8000
     19#define XS100_8390_DATA32_SIZE 0x2000
     20/* Sub-Areas for fast data register access; addresses relative to area begin */
     21#define XS100_8390_DATA_READ32_BASE 0x0880
     22#define XS100_8390_DATA_WRITE32_BASE 0x0C80
     23#define XS100_8390_DATA_AREA_SIZE 0x80
     24
     25/* force unsigned long back to 'void __iomem *' */
     26#define ax_convert_addr(_a) ((void __force __iomem *)(_a))
     27
     28#define ei_inb(_a) z_readb(ax_convert_addr(_a))
     29#define ei_outb(_v, _a) z_writeb(_v, ax_convert_addr(_a))
     30
     31#define ei_inw(_a) z_readw(ax_convert_addr(_a))
     32#define ei_outw(_v, _a) z_writew(_v, ax_convert_addr(_a))
     33
     34#define ei_inb_p(_a) ei_inb(_a)
     35#define ei_outb_p(_v, _a) ei_outb(_v, _a)
     36
     37/* define EI_SHIFT() to take into account our register offsets */
     38#define EI_SHIFT(x) (ei_local->reg_offset[(x)])
     39
     40/* Ensure we have our RCR base value */
     41#define AX88796_PLATFORM
     42
     43#include "8390.h"
     44
     45/* from ne.c */
     46#define NE_CMD		EI_SHIFT(0x00)
     47#define NE_RESET	EI_SHIFT(0x1f)
     48#define NE_DATAPORT	EI_SHIFT(0x10)
     49
     50struct xsurf100_ax_plat_data {
     51	struct ax_plat_data ax;
     52	void __iomem *base_regs;
     53	void __iomem *data_area;
     54};
     55
     56static int is_xsurf100_network_irq(struct platform_device *pdev)
     57{
     58	struct xsurf100_ax_plat_data *xs100 = dev_get_platdata(&pdev->dev);
     59
     60	return (readw(xs100->base_regs + XS100_IRQSTATUS_BASE) & 0xaaaa) != 0;
     61}
     62
     63/* These functions guarantee that the iomem is accessed with 32 bit
     64 * cycles only. z_memcpy_fromio / z_memcpy_toio don't
     65 */
     66static void z_memcpy_fromio32(void *dst, const void __iomem *src, size_t bytes)
     67{
     68	while (bytes > 32) {
     69		asm __volatile__
     70		   ("movem.l (%0)+,%%d0-%%d7\n"
     71		    "movem.l %%d0-%%d7,(%1)\n"
     72		    "adda.l #32,%1" : "=a"(src), "=a"(dst)
     73		    : "0"(src), "1"(dst) : "d0", "d1", "d2", "d3", "d4",
     74					   "d5", "d6", "d7", "memory");
     75		bytes -= 32;
     76	}
     77	while (bytes) {
     78		*(uint32_t *)dst = z_readl(src);
     79		src += 4;
     80		dst += 4;
     81		bytes -= 4;
     82	}
     83}
     84
     85static void z_memcpy_toio32(void __iomem *dst, const void *src, size_t bytes)
     86{
     87	while (bytes) {
     88		z_writel(*(const uint32_t *)src, dst);
     89		src += 4;
     90		dst += 4;
     91		bytes -= 4;
     92	}
     93}
     94
     95static void xs100_write(struct net_device *dev, const void *src,
     96			unsigned int count)
     97{
     98	struct ei_device *ei_local = netdev_priv(dev);
     99	struct platform_device *pdev = to_platform_device(dev->dev.parent);
    100	struct xsurf100_ax_plat_data *xs100 = dev_get_platdata(&pdev->dev);
    101
    102	/* copy whole blocks */
    103	while (count > XS100_8390_DATA_AREA_SIZE) {
    104		z_memcpy_toio32(xs100->data_area +
    105				XS100_8390_DATA_WRITE32_BASE, src,
    106				XS100_8390_DATA_AREA_SIZE);
    107		src += XS100_8390_DATA_AREA_SIZE;
    108		count -= XS100_8390_DATA_AREA_SIZE;
    109	}
    110	/* copy whole dwords */
    111	z_memcpy_toio32(xs100->data_area + XS100_8390_DATA_WRITE32_BASE,
    112			src, count & ~3);
    113	src += count & ~3;
    114	if (count & 2) {
    115		ei_outw(*(uint16_t *)src, ei_local->mem + NE_DATAPORT);
    116		src += 2;
    117	}
    118	if (count & 1)
    119		ei_outb(*(uint8_t *)src, ei_local->mem + NE_DATAPORT);
    120}
    121
    122static void xs100_read(struct net_device *dev, void *dst, unsigned int count)
    123{
    124	struct ei_device *ei_local = netdev_priv(dev);
    125	struct platform_device *pdev = to_platform_device(dev->dev.parent);
    126	struct xsurf100_ax_plat_data *xs100 = dev_get_platdata(&pdev->dev);
    127
    128	/* copy whole blocks */
    129	while (count > XS100_8390_DATA_AREA_SIZE) {
    130		z_memcpy_fromio32(dst, xs100->data_area +
    131				  XS100_8390_DATA_READ32_BASE,
    132				  XS100_8390_DATA_AREA_SIZE);
    133		dst += XS100_8390_DATA_AREA_SIZE;
    134		count -= XS100_8390_DATA_AREA_SIZE;
    135	}
    136	/* copy whole dwords */
    137	z_memcpy_fromio32(dst, xs100->data_area + XS100_8390_DATA_READ32_BASE,
    138			  count & ~3);
    139	dst += count & ~3;
    140	if (count & 2) {
    141		*(uint16_t *)dst = ei_inw(ei_local->mem + NE_DATAPORT);
    142		dst += 2;
    143	}
    144	if (count & 1)
    145		*(uint8_t *)dst = ei_inb(ei_local->mem + NE_DATAPORT);
    146}
    147
    148/* Block input and output, similar to the Crynwr packet driver. If
    149 * you are porting to a new ethercard, look at the packet driver
    150 * source for hints. The NEx000 doesn't share the on-board packet
    151 * memory -- you have to put the packet out through the "remote DMA"
    152 * dataport using ei_outb.
    153 */
    154static void xs100_block_input(struct net_device *dev, int count,
    155			      struct sk_buff *skb, int ring_offset)
    156{
    157	struct ei_device *ei_local = netdev_priv(dev);
    158	void __iomem *nic_base = ei_local->mem;
    159	char *buf = skb->data;
    160
    161	if (ei_local->dmaing) {
    162		netdev_err(dev,
    163			   "DMAing conflict in %s [DMAstat:%d][irqlock:%d]\n",
    164			   __func__,
    165			   ei_local->dmaing, ei_local->irqlock);
    166		return;
    167	}
    168
    169	ei_local->dmaing |= 0x01;
    170
    171	ei_outb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD);
    172	ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
    173	ei_outb(count >> 8, nic_base + EN0_RCNTHI);
    174	ei_outb(ring_offset & 0xff, nic_base + EN0_RSARLO);
    175	ei_outb(ring_offset >> 8, nic_base + EN0_RSARHI);
    176	ei_outb(E8390_RREAD + E8390_START, nic_base + NE_CMD);
    177
    178	xs100_read(dev, buf, count);
    179
    180	ei_local->dmaing &= ~1;
    181}
    182
    183static void xs100_block_output(struct net_device *dev, int count,
    184			       const unsigned char *buf, const int start_page)
    185{
    186	struct ei_device *ei_local = netdev_priv(dev);
    187	void __iomem *nic_base = ei_local->mem;
    188	unsigned long dma_start;
    189
    190	/* Round the count up for word writes. Do we need to do this?
    191	 * What effect will an odd byte count have on the 8390?  I
    192	 * should check someday.
    193	 */
    194	if (ei_local->word16 && (count & 0x01))
    195		count++;
    196
    197	/* This *shouldn't* happen. If it does, it's the last thing
    198	 * you'll see
    199	 */
    200	if (ei_local->dmaing) {
    201		netdev_err(dev,
    202			   "DMAing conflict in %s [DMAstat:%d][irqlock:%d]\n",
    203			   __func__,
    204			   ei_local->dmaing, ei_local->irqlock);
    205		return;
    206	}
    207
    208	ei_local->dmaing |= 0x01;
    209	/* We should already be in page 0, but to be safe... */
    210	ei_outb(E8390_PAGE0 + E8390_START + E8390_NODMA, nic_base + NE_CMD);
    211
    212	ei_outb(ENISR_RDC, nic_base + EN0_ISR);
    213
    214	/* Now the normal output. */
    215	ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
    216	ei_outb(count >> 8, nic_base + EN0_RCNTHI);
    217	ei_outb(0x00, nic_base + EN0_RSARLO);
    218	ei_outb(start_page, nic_base + EN0_RSARHI);
    219
    220	ei_outb(E8390_RWRITE + E8390_START, nic_base + NE_CMD);
    221
    222	xs100_write(dev, buf, count);
    223
    224	dma_start = jiffies;
    225
    226	while ((ei_inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) {
    227		if (jiffies - dma_start > 2 * HZ / 100) {	/* 20ms */
    228			netdev_warn(dev, "timeout waiting for Tx RDC.\n");
    229			ei_local->reset_8390(dev);
    230			ax_NS8390_reinit(dev);
    231			break;
    232		}
    233	}
    234
    235	ei_outb(ENISR_RDC, nic_base + EN0_ISR);	/* Ack intr. */
    236	ei_local->dmaing &= ~0x01;
    237}
    238
    239static int xsurf100_probe(struct zorro_dev *zdev,
    240			  const struct zorro_device_id *ent)
    241{
    242	struct platform_device *pdev;
    243	struct xsurf100_ax_plat_data ax88796_data;
    244	struct resource res[2] = {
    245		DEFINE_RES_NAMED(IRQ_AMIGA_PORTS, 1, NULL,
    246				 IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE),
    247		DEFINE_RES_MEM(zdev->resource.start + XS100_8390_BASE,
    248			       4 * 0x20)
    249	};
    250	int reg;
    251	/* This table is referenced in the device structure, so it must
    252	 * outlive the scope of xsurf100_probe.
    253	 */
    254	static u32 reg_offsets[32];
    255	int ret = 0;
    256
    257	/* X-Surf 100 control and 32 bit ring buffer data access areas.
    258	 * These resources are not used by the ax88796 driver, so must
    259	 * be requested here and passed via platform data.
    260	 */
    261
    262	if (!request_mem_region(zdev->resource.start, 0x100, zdev->name)) {
    263		dev_err(&zdev->dev, "cannot reserve X-Surf 100 control registers\n");
    264		return -ENXIO;
    265	}
    266
    267	if (!request_mem_region(zdev->resource.start +
    268				XS100_8390_DATA32_BASE,
    269				XS100_8390_DATA32_SIZE,
    270				"X-Surf 100 32-bit data access")) {
    271		dev_err(&zdev->dev, "cannot reserve 32-bit area\n");
    272		ret = -ENXIO;
    273		goto exit_req;
    274	}
    275
    276	for (reg = 0; reg < 0x20; reg++)
    277		reg_offsets[reg] = 4 * reg;
    278
    279	memset(&ax88796_data, 0, sizeof(ax88796_data));
    280	ax88796_data.ax.flags = AXFLG_HAS_EEPROM;
    281	ax88796_data.ax.wordlength = 2;
    282	ax88796_data.ax.dcr_val = 0x48;
    283	ax88796_data.ax.rcr_val = 0x40;
    284	ax88796_data.ax.reg_offsets = reg_offsets;
    285	ax88796_data.ax.check_irq = is_xsurf100_network_irq;
    286	ax88796_data.base_regs = ioremap(zdev->resource.start, 0x100);
    287
    288	/* error handling for ioremap regs */
    289	if (!ax88796_data.base_regs) {
    290		dev_err(&zdev->dev, "Cannot ioremap area %pR (registers)\n",
    291			&zdev->resource);
    292
    293		ret = -ENXIO;
    294		goto exit_req2;
    295	}
    296
    297	ax88796_data.data_area = ioremap(zdev->resource.start +
    298			XS100_8390_DATA32_BASE, XS100_8390_DATA32_SIZE);
    299
    300	/* error handling for ioremap data */
    301	if (!ax88796_data.data_area) {
    302		dev_err(&zdev->dev,
    303			"Cannot ioremap area %pR offset %x (32-bit access)\n",
    304			&zdev->resource,  XS100_8390_DATA32_BASE);
    305
    306		ret = -ENXIO;
    307		goto exit_mem;
    308	}
    309
    310	ax88796_data.ax.block_output = xs100_block_output;
    311	ax88796_data.ax.block_input = xs100_block_input;
    312
    313	pdev = platform_device_register_resndata(&zdev->dev, "ax88796",
    314						 zdev->slotaddr, res, 2,
    315						 &ax88796_data,
    316						 sizeof(ax88796_data));
    317
    318	if (IS_ERR(pdev)) {
    319		dev_err(&zdev->dev, "cannot register platform device\n");
    320		ret = -ENXIO;
    321		goto exit_mem2;
    322	}
    323
    324	zorro_set_drvdata(zdev, pdev);
    325
    326	if (!ret)
    327		return 0;
    328
    329 exit_mem2:
    330	iounmap(ax88796_data.data_area);
    331
    332 exit_mem:
    333	iounmap(ax88796_data.base_regs);
    334
    335 exit_req2:
    336	release_mem_region(zdev->resource.start + XS100_8390_DATA32_BASE,
    337			   XS100_8390_DATA32_SIZE);
    338
    339 exit_req:
    340	release_mem_region(zdev->resource.start, 0x100);
    341
    342	return ret;
    343}
    344
    345static void xsurf100_remove(struct zorro_dev *zdev)
    346{
    347	struct platform_device *pdev = zorro_get_drvdata(zdev);
    348	struct xsurf100_ax_plat_data *xs100 = dev_get_platdata(&pdev->dev);
    349
    350	platform_device_unregister(pdev);
    351
    352	iounmap(xs100->base_regs);
    353	release_mem_region(zdev->resource.start, 0x100);
    354	iounmap(xs100->data_area);
    355	release_mem_region(zdev->resource.start + XS100_8390_DATA32_BASE,
    356			   XS100_8390_DATA32_SIZE);
    357}
    358
    359static const struct zorro_device_id xsurf100_zorro_tbl[] = {
    360	{ ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF100, },
    361	{ 0 }
    362};
    363
    364MODULE_DEVICE_TABLE(zorro, xsurf100_zorro_tbl);
    365
    366static struct zorro_driver xsurf100_driver = {
    367	.name           = "xsurf100",
    368	.id_table       = xsurf100_zorro_tbl,
    369	.probe          = xsurf100_probe,
    370	.remove         = xsurf100_remove,
    371};
    372
    373module_driver(xsurf100_driver, zorro_register_driver, zorro_unregister_driver);
    374
    375MODULE_DESCRIPTION("X-Surf 100 driver");
    376MODULE_AUTHOR("Michael Karcher <kernel@mkarcher.dialup.fu-berlin.de>");
    377MODULE_LICENSE("GPL v2");