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>
9 #define ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF100 \
10 ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x64, 0)
12 #define XS100_IRQSTATUS_BASE 0x40
13 #define XS100_8390_BASE 0x800
15 /* Longword-access area. Translated to 2 16-bit access cycles by the
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
25 #define __NS8390_init ax_NS8390_init
27 /* force unsigned long back to 'void __iomem *' */
28 #define ax_convert_addr(_a) ((void __force __iomem *)(_a))
30 #define ei_inb(_a) z_readb(ax_convert_addr(_a))
31 #define ei_outb(_v, _a) z_writeb(_v, ax_convert_addr(_a))
33 #define ei_inw(_a) z_readw(ax_convert_addr(_a))
34 #define ei_outw(_v, _a) z_writew(_v, ax_convert_addr(_a))
36 #define ei_inb_p(_a) ei_inb(_a)
37 #define ei_outb_p(_v, _a) ei_outb(_v, _a)
39 /* define EI_SHIFT() to take into account our register offsets */
40 #define EI_SHIFT(x) (ei_local->reg_offset[(x)])
42 /* Ensure we have our RCR base value */
43 #define AX88796_PLATFORM
45 static unsigned char version
[] =
46 "ax88796.c: Copyright 2005,2007 Simtec Electronics\n";
51 #define NE_CMD EI_SHIFT(0x00)
52 #define NE_RESET EI_SHIFT(0x1f)
53 #define NE_DATAPORT EI_SHIFT(0x10)
55 struct xsurf100_ax_plat_data
{
56 struct ax_plat_data ax
;
57 void __iomem
*base_regs
;
58 void __iomem
*data_area
;
61 static int is_xsurf100_network_irq(struct platform_device
*pdev
)
63 struct xsurf100_ax_plat_data
*xs100
= dev_get_platdata(&pdev
->dev
);
65 return (readw(xs100
->base_regs
+ XS100_IRQSTATUS_BASE
) & 0xaaaa) != 0;
68 /* These functions guarantee that the iomem is accessed with 32 bit
69 * cycles only. z_memcpy_fromio / z_memcpy_toio don't
71 static void z_memcpy_fromio32(void *dst
, const void __iomem
*src
, size_t bytes
)
75 ("movem.l (%0)+,%%d0-%%d7\n"
76 "movem.l %%d0-%%d7,(%1)\n"
77 "adda.l #32,%1" : "=a"(src
), "=a"(dst
)
78 : "0"(src
), "1"(dst
) : "d0", "d1", "d2", "d3", "d4",
79 "d5", "d6", "d7", "memory");
83 *(uint32_t *)dst
= z_readl(src
);
90 static void z_memcpy_toio32(void __iomem
*dst
, const void *src
, size_t bytes
)
93 z_writel(*(const uint32_t *)src
, dst
);
100 static void xs100_write(struct net_device
*dev
, const void *src
,
103 struct ei_device
*ei_local
= netdev_priv(dev
);
104 struct platform_device
*pdev
= to_platform_device(dev
->dev
.parent
);
105 struct xsurf100_ax_plat_data
*xs100
= dev_get_platdata(&pdev
->dev
);
107 /* copy whole blocks */
108 while (count
> XS100_8390_DATA_AREA_SIZE
) {
109 z_memcpy_toio32(xs100
->data_area
+
110 XS100_8390_DATA_WRITE32_BASE
, src
,
111 XS100_8390_DATA_AREA_SIZE
);
112 src
+= XS100_8390_DATA_AREA_SIZE
;
113 count
-= XS100_8390_DATA_AREA_SIZE
;
115 /* copy whole dwords */
116 z_memcpy_toio32(xs100
->data_area
+ XS100_8390_DATA_WRITE32_BASE
,
120 ei_outw(*(uint16_t *)src
, ei_local
->mem
+ NE_DATAPORT
);
124 ei_outb(*(uint8_t *)src
, ei_local
->mem
+ NE_DATAPORT
);
127 static void xs100_read(struct net_device
*dev
, void *dst
, unsigned int count
)
129 struct ei_device
*ei_local
= netdev_priv(dev
);
130 struct platform_device
*pdev
= to_platform_device(dev
->dev
.parent
);
131 struct xsurf100_ax_plat_data
*xs100
= dev_get_platdata(&pdev
->dev
);
133 /* copy whole blocks */
134 while (count
> XS100_8390_DATA_AREA_SIZE
) {
135 z_memcpy_fromio32(dst
, xs100
->data_area
+
136 XS100_8390_DATA_READ32_BASE
,
137 XS100_8390_DATA_AREA_SIZE
);
138 dst
+= XS100_8390_DATA_AREA_SIZE
;
139 count
-= XS100_8390_DATA_AREA_SIZE
;
141 /* copy whole dwords */
142 z_memcpy_fromio32(dst
, xs100
->data_area
+ XS100_8390_DATA_READ32_BASE
,
146 *(uint16_t *)dst
= ei_inw(ei_local
->mem
+ NE_DATAPORT
);
150 *(uint8_t *)dst
= ei_inb(ei_local
->mem
+ NE_DATAPORT
);
153 /* Block input and output, similar to the Crynwr packet driver. If
154 * you are porting to a new ethercard, look at the packet driver
155 * source for hints. The NEx000 doesn't share the on-board packet
156 * memory -- you have to put the packet out through the "remote DMA"
157 * dataport using ei_outb.
159 static void xs100_block_input(struct net_device
*dev
, int count
,
160 struct sk_buff
*skb
, int ring_offset
)
162 struct ei_device
*ei_local
= netdev_priv(dev
);
163 void __iomem
*nic_base
= ei_local
->mem
;
164 char *buf
= skb
->data
;
166 if (ei_local
->dmaing
) {
168 "DMAing conflict in %s [DMAstat:%d][irqlock:%d]\n",
170 ei_local
->dmaing
, ei_local
->irqlock
);
174 ei_local
->dmaing
|= 0x01;
176 ei_outb(E8390_NODMA
+ E8390_PAGE0
+ E8390_START
, nic_base
+ NE_CMD
);
177 ei_outb(count
& 0xff, nic_base
+ EN0_RCNTLO
);
178 ei_outb(count
>> 8, nic_base
+ EN0_RCNTHI
);
179 ei_outb(ring_offset
& 0xff, nic_base
+ EN0_RSARLO
);
180 ei_outb(ring_offset
>> 8, nic_base
+ EN0_RSARHI
);
181 ei_outb(E8390_RREAD
+ E8390_START
, nic_base
+ NE_CMD
);
183 xs100_read(dev
, buf
, count
);
185 ei_local
->dmaing
&= ~1;
188 static void xs100_block_output(struct net_device
*dev
, int count
,
189 const unsigned char *buf
, const int start_page
)
191 struct ei_device
*ei_local
= netdev_priv(dev
);
192 void __iomem
*nic_base
= ei_local
->mem
;
193 unsigned long dma_start
;
195 /* Round the count up for word writes. Do we need to do this?
196 * What effect will an odd byte count have on the 8390? I
197 * should check someday.
199 if (ei_local
->word16
&& (count
& 0x01))
202 /* This *shouldn't* happen. If it does, it's the last thing
205 if (ei_local
->dmaing
) {
207 "DMAing conflict in %s [DMAstat:%d][irqlock:%d]\n",
209 ei_local
->dmaing
, ei_local
->irqlock
);
213 ei_local
->dmaing
|= 0x01;
214 /* We should already be in page 0, but to be safe... */
215 ei_outb(E8390_PAGE0
+ E8390_START
+ E8390_NODMA
, nic_base
+ NE_CMD
);
217 ei_outb(ENISR_RDC
, nic_base
+ EN0_ISR
);
219 /* Now the normal output. */
220 ei_outb(count
& 0xff, nic_base
+ EN0_RCNTLO
);
221 ei_outb(count
>> 8, nic_base
+ EN0_RCNTHI
);
222 ei_outb(0x00, nic_base
+ EN0_RSARLO
);
223 ei_outb(start_page
, nic_base
+ EN0_RSARHI
);
225 ei_outb(E8390_RWRITE
+ E8390_START
, nic_base
+ NE_CMD
);
227 xs100_write(dev
, buf
, count
);
231 while ((ei_inb(nic_base
+ EN0_ISR
) & ENISR_RDC
) == 0) {
232 if (jiffies
- dma_start
> 2 * HZ
/ 100) { /* 20ms */
233 netdev_warn(dev
, "timeout waiting for Tx RDC.\n");
234 ei_local
->reset_8390(dev
);
235 ax_NS8390_init(dev
, 1);
240 ei_outb(ENISR_RDC
, nic_base
+ EN0_ISR
); /* Ack intr. */
241 ei_local
->dmaing
&= ~0x01;
244 static int xsurf100_probe(struct zorro_dev
*zdev
,
245 const struct zorro_device_id
*ent
)
247 struct platform_device
*pdev
;
248 struct xsurf100_ax_plat_data ax88796_data
;
249 struct resource res
[2] = {
250 DEFINE_RES_NAMED(IRQ_AMIGA_PORTS
, 1, NULL
,
251 IORESOURCE_IRQ
| IORESOURCE_IRQ_SHAREABLE
),
252 DEFINE_RES_MEM(zdev
->resource
.start
+ XS100_8390_BASE
,
256 /* This table is referenced in the device structure, so it must
257 * outlive the scope of xsurf100_probe.
259 static u32 reg_offsets
[32];
262 /* X-Surf 100 control and 32 bit ring buffer data access areas.
263 * These resources are not used by the ax88796 driver, so must
264 * be requested here and passed via platform data.
267 if (!request_mem_region(zdev
->resource
.start
, 0x100, zdev
->name
)) {
268 dev_err(&zdev
->dev
, "cannot reserve X-Surf 100 control registers\n");
272 if (!request_mem_region(zdev
->resource
.start
+
273 XS100_8390_DATA32_BASE
,
274 XS100_8390_DATA32_SIZE
,
275 "X-Surf 100 32-bit data access")) {
276 dev_err(&zdev
->dev
, "cannot reserve 32-bit area\n");
281 for (reg
= 0; reg
< 0x20; reg
++)
282 reg_offsets
[reg
] = 4 * reg
;
284 memset(&ax88796_data
, 0, sizeof(ax88796_data
));
285 ax88796_data
.ax
.flags
= AXFLG_HAS_EEPROM
;
286 ax88796_data
.ax
.wordlength
= 2;
287 ax88796_data
.ax
.dcr_val
= 0x48;
288 ax88796_data
.ax
.rcr_val
= 0x40;
289 ax88796_data
.ax
.reg_offsets
= reg_offsets
;
290 ax88796_data
.ax
.check_irq
= is_xsurf100_network_irq
;
291 ax88796_data
.base_regs
= ioremap(zdev
->resource
.start
, 0x100);
293 /* error handling for ioremap regs */
294 if (!ax88796_data
.base_regs
) {
295 dev_err(&zdev
->dev
, "Cannot ioremap area %pR (registers)\n",
302 ax88796_data
.data_area
= ioremap(zdev
->resource
.start
+
303 XS100_8390_DATA32_BASE
, XS100_8390_DATA32_SIZE
);
305 /* error handling for ioremap data */
306 if (!ax88796_data
.data_area
) {
308 "Cannot ioremap area %pR offset %x (32-bit access)\n",
309 &zdev
->resource
, XS100_8390_DATA32_BASE
);
315 ax88796_data
.ax
.block_output
= xs100_block_output
;
316 ax88796_data
.ax
.block_input
= xs100_block_input
;
318 pdev
= platform_device_register_resndata(&zdev
->dev
, "ax88796",
319 zdev
->slotaddr
, res
, 2,
321 sizeof(ax88796_data
));
324 dev_err(&zdev
->dev
, "cannot register platform device\n");
329 zorro_set_drvdata(zdev
, pdev
);
335 iounmap(ax88796_data
.data_area
);
338 iounmap(ax88796_data
.base_regs
);
341 release_mem_region(zdev
->resource
.start
+ XS100_8390_DATA32_BASE
,
342 XS100_8390_DATA32_SIZE
);
345 release_mem_region(zdev
->resource
.start
, 0x100);
350 static void xsurf100_remove(struct zorro_dev
*zdev
)
352 struct platform_device
*pdev
= zorro_get_drvdata(zdev
);
353 struct xsurf100_ax_plat_data
*xs100
= dev_get_platdata(&pdev
->dev
);
355 platform_device_unregister(pdev
);
357 iounmap(xs100
->base_regs
);
358 release_mem_region(zdev
->resource
.start
, 0x100);
359 iounmap(xs100
->data_area
);
360 release_mem_region(zdev
->resource
.start
+ XS100_8390_DATA32_BASE
,
361 XS100_8390_DATA32_SIZE
);
364 static const struct zorro_device_id xsurf100_zorro_tbl
[] = {
365 { ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF100
, },
369 MODULE_DEVICE_TABLE(zorro
, xsurf100_zorro_tbl
);
371 static struct zorro_driver xsurf100_driver
= {
373 .id_table
= xsurf100_zorro_tbl
,
374 .probe
= xsurf100_probe
,
375 .remove
= xsurf100_remove
,
378 module_driver(xsurf100_driver
, zorro_register_driver
, zorro_unregister_driver
);
380 MODULE_DESCRIPTION("X-Surf 100 driver");
381 MODULE_AUTHOR("Michael Karcher <kernel@mkarcher.dialup.fu-berlin.de>");
382 MODULE_LICENSE("GPL v2");