1 | /* |
2 | * Linux ARCnet driver - "RIM I" (entirely mem-mapped) cards |
3 | * |
4 | * Written 1994-1999 by Avery Pennarun. |
5 | * Written 1999-2000 by Martin Mares <mj@ucw.cz>. |
6 | * Derived from skeleton.c by Donald Becker. |
7 | * |
8 | * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com) |
9 | * for sponsoring the further development of this driver. |
10 | * |
11 | * ********************** |
12 | * |
13 | * The original copyright of skeleton.c was as follows: |
14 | * |
15 | * skeleton.c Written 1993 by Donald Becker. |
16 | * Copyright 1993 United States Government as represented by the |
17 | * Director, National Security Agency. This software may only be used |
18 | * and distributed according to the terms of the GNU General Public License as |
19 | * modified by SRC, incorporated herein by reference. |
20 | * |
21 | * ********************** |
22 | * |
23 | * For more details, see drivers/net/arcnet.c |
24 | * |
25 | * ********************** |
26 | */ |
27 | |
28 | #define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt |
29 | |
30 | #include <linux/kernel.h> |
31 | #include <linux/module.h> |
32 | #include <linux/moduleparam.h> |
33 | #include <linux/ioport.h> |
34 | #include <linux/delay.h> |
35 | #include <linux/netdevice.h> |
36 | #include <linux/memblock.h> |
37 | #include <linux/init.h> |
38 | #include <linux/interrupt.h> |
39 | #include <linux/io.h> |
40 | |
41 | #include "arcdevice.h" |
42 | #include "com9026.h" |
43 | |
44 | /* Internal function declarations */ |
45 | |
46 | static int arcrimi_probe(struct net_device *dev); |
47 | static int arcrimi_found(struct net_device *dev); |
48 | static void arcrimi_command(struct net_device *dev, int command); |
49 | static int arcrimi_status(struct net_device *dev); |
50 | static void arcrimi_setmask(struct net_device *dev, int mask); |
51 | static int arcrimi_reset(struct net_device *dev, int really_reset); |
52 | static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset, |
53 | void *buf, int count); |
54 | static void arcrimi_copy_from_card(struct net_device *dev, int bufnum, |
55 | int offset, void *buf, int count); |
56 | |
57 | /* Handy defines for ARCnet specific stuff */ |
58 | |
59 | /* Amount of I/O memory used by the card */ |
60 | #define BUFFER_SIZE (512) |
61 | #define MIRROR_SIZE (BUFFER_SIZE * 4) |
62 | |
63 | /* We cannot probe for a RIM I card; one reason is I don't know how to reset |
64 | * them. In fact, we can't even get their node ID automatically. So, we |
65 | * need to be passed a specific shmem address, IRQ, and node ID. |
66 | */ |
67 | static int __init arcrimi_probe(struct net_device *dev) |
68 | { |
69 | if (BUGLVL(D_NORMAL)) { |
70 | pr_info("%s\n" , "RIM I (entirely mem-mapped) support" ); |
71 | pr_info("E-mail me if you actually test the RIM I driver, please!\n" ); |
72 | pr_info("Given: node %02Xh, shmem %lXh, irq %d\n" , |
73 | dev->dev_addr[0], dev->mem_start, dev->irq); |
74 | } |
75 | |
76 | if (dev->mem_start <= 0 || dev->irq <= 0) { |
77 | if (BUGLVL(D_NORMAL)) |
78 | pr_err("No autoprobe for RIM I; you must specify the shmem and irq!\n" ); |
79 | return -ENODEV; |
80 | } |
81 | if (dev->dev_addr[0] == 0) { |
82 | if (BUGLVL(D_NORMAL)) |
83 | pr_err("You need to specify your card's station ID!\n" ); |
84 | return -ENODEV; |
85 | } |
86 | /* Grab the memory region at mem_start for MIRROR_SIZE bytes. |
87 | * Later in arcrimi_found() the real size will be determined |
88 | * and this reserve will be released and the correct size |
89 | * will be taken. |
90 | */ |
91 | if (!request_mem_region(dev->mem_start, MIRROR_SIZE, "arcnet (90xx)" )) { |
92 | if (BUGLVL(D_NORMAL)) |
93 | pr_notice("Card memory already allocated\n" ); |
94 | return -ENODEV; |
95 | } |
96 | return arcrimi_found(dev); |
97 | } |
98 | |
99 | static int check_mirror(unsigned long addr, size_t size) |
100 | { |
101 | void __iomem *p; |
102 | int res = -1; |
103 | |
104 | if (!request_mem_region(addr, size, "arcnet (90xx)" )) |
105 | return -1; |
106 | |
107 | p = ioremap(offset: addr, size); |
108 | if (p) { |
109 | if (arcnet_readb(p, COM9026_REG_R_STATUS) == TESTvalue) |
110 | res = 1; |
111 | else |
112 | res = 0; |
113 | iounmap(addr: p); |
114 | } |
115 | |
116 | release_mem_region(addr, size); |
117 | return res; |
118 | } |
119 | |
120 | /* Set up the struct net_device associated with this card. |
121 | * Called after probing succeeds. |
122 | */ |
123 | static int __init arcrimi_found(struct net_device *dev) |
124 | { |
125 | struct arcnet_local *lp; |
126 | unsigned long first_mirror, last_mirror, shmem; |
127 | void __iomem *p; |
128 | int mirror_size; |
129 | int err; |
130 | |
131 | p = ioremap(offset: dev->mem_start, MIRROR_SIZE); |
132 | if (!p) { |
133 | release_mem_region(dev->mem_start, MIRROR_SIZE); |
134 | arc_printk(D_NORMAL, dev, "Can't ioremap\n" ); |
135 | return -ENODEV; |
136 | } |
137 | |
138 | /* reserve the irq */ |
139 | if (request_irq(irq: dev->irq, handler: arcnet_interrupt, flags: 0, name: "arcnet (RIM I)" , dev)) { |
140 | iounmap(addr: p); |
141 | release_mem_region(dev->mem_start, MIRROR_SIZE); |
142 | arc_printk(D_NORMAL, dev, "Can't get IRQ %d!\n" , dev->irq); |
143 | return -ENODEV; |
144 | } |
145 | |
146 | shmem = dev->mem_start; |
147 | arcnet_writeb(TESTvalue, p, COM9026_REG_W_INTMASK); |
148 | arcnet_writeb(TESTvalue, p, COM9026_REG_W_COMMAND); |
149 | /* actually the station/node ID */ |
150 | |
151 | /* find the real shared memory start/end points, including mirrors */ |
152 | |
153 | /* guess the actual size of one "memory mirror" - the number of |
154 | * bytes between copies of the shared memory. On most cards, it's |
155 | * 2k (or there are no mirrors at all) but on some, it's 4k. |
156 | */ |
157 | mirror_size = MIRROR_SIZE; |
158 | if (arcnet_readb(p, COM9026_REG_R_STATUS) == TESTvalue && |
159 | check_mirror(addr: shmem - MIRROR_SIZE, MIRROR_SIZE) == 0 && |
160 | check_mirror(addr: shmem - 2 * MIRROR_SIZE, MIRROR_SIZE) == 1) |
161 | mirror_size = 2 * MIRROR_SIZE; |
162 | |
163 | first_mirror = shmem - mirror_size; |
164 | while (check_mirror(addr: first_mirror, size: mirror_size) == 1) |
165 | first_mirror -= mirror_size; |
166 | first_mirror += mirror_size; |
167 | |
168 | last_mirror = shmem + mirror_size; |
169 | while (check_mirror(addr: last_mirror, size: mirror_size) == 1) |
170 | last_mirror += mirror_size; |
171 | last_mirror -= mirror_size; |
172 | |
173 | dev->mem_start = first_mirror; |
174 | dev->mem_end = last_mirror + MIRROR_SIZE - 1; |
175 | |
176 | /* initialize the rest of the device structure. */ |
177 | |
178 | lp = netdev_priv(dev); |
179 | lp->card_name = "RIM I" ; |
180 | lp->hw.command = arcrimi_command; |
181 | lp->hw.status = arcrimi_status; |
182 | lp->hw.intmask = arcrimi_setmask; |
183 | lp->hw.reset = arcrimi_reset; |
184 | lp->hw.owner = THIS_MODULE; |
185 | lp->hw.copy_to_card = arcrimi_copy_to_card; |
186 | lp->hw.copy_from_card = arcrimi_copy_from_card; |
187 | |
188 | /* re-reserve the memory region - arcrimi_probe() alloced this reqion |
189 | * but didn't know the real size. Free that region and then re-get |
190 | * with the correct size. There is a VERY slim chance this could |
191 | * fail. |
192 | */ |
193 | iounmap(addr: p); |
194 | release_mem_region(shmem, MIRROR_SIZE); |
195 | if (!request_mem_region(dev->mem_start, |
196 | dev->mem_end - dev->mem_start + 1, |
197 | "arcnet (90xx)" )) { |
198 | arc_printk(D_NORMAL, dev, "Card memory already allocated\n" ); |
199 | goto err_free_irq; |
200 | } |
201 | |
202 | lp->mem_start = ioremap(offset: dev->mem_start, |
203 | size: dev->mem_end - dev->mem_start + 1); |
204 | if (!lp->mem_start) { |
205 | arc_printk(D_NORMAL, dev, "Can't remap device memory!\n" ); |
206 | goto err_release_mem; |
207 | } |
208 | |
209 | /* get and check the station ID from offset 1 in shmem */ |
210 | arcnet_set_addr(dev, arcnet_readb(lp->mem_start, |
211 | COM9026_REG_R_STATION)); |
212 | |
213 | arc_printk(D_NORMAL, dev, "ARCnet RIM I: station %02Xh found at IRQ %d, ShMem %lXh (%ld*%d bytes)\n" , |
214 | dev->dev_addr[0], |
215 | dev->irq, dev->mem_start, |
216 | (dev->mem_end - dev->mem_start + 1) / mirror_size, |
217 | mirror_size); |
218 | |
219 | err = register_netdev(dev); |
220 | if (err) |
221 | goto err_unmap; |
222 | |
223 | return 0; |
224 | |
225 | err_unmap: |
226 | iounmap(addr: lp->mem_start); |
227 | err_release_mem: |
228 | release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1); |
229 | err_free_irq: |
230 | free_irq(dev->irq, dev); |
231 | return -EIO; |
232 | } |
233 | |
234 | /* Do a hardware reset on the card, and set up necessary registers. |
235 | * |
236 | * This should be called as little as possible, because it disrupts the |
237 | * token on the network (causes a RECON) and requires a significant delay. |
238 | * |
239 | * However, it does make sure the card is in a defined state. |
240 | */ |
241 | static int arcrimi_reset(struct net_device *dev, int really_reset) |
242 | { |
243 | struct arcnet_local *lp = netdev_priv(dev); |
244 | void __iomem *ioaddr = lp->mem_start + 0x800; |
245 | |
246 | arc_printk(D_INIT, dev, "Resetting %s (status=%02Xh)\n" , |
247 | dev->name, arcnet_readb(ioaddr, COM9026_REG_R_STATUS)); |
248 | |
249 | if (really_reset) { |
250 | arcnet_writeb(TESTvalue, ioaddr, -0x800); /* fake reset */ |
251 | return 0; |
252 | } |
253 | /* clear flags & end reset */ |
254 | arcnet_writeb(CFLAGScmd | RESETclear, ioaddr, COM9026_REG_W_COMMAND); |
255 | arcnet_writeb(CFLAGScmd | CONFIGclear, ioaddr, COM9026_REG_W_COMMAND); |
256 | |
257 | /* enable extended (512-byte) packets */ |
258 | arcnet_writeb(CONFIGcmd | EXTconf, ioaddr, COM9026_REG_W_COMMAND); |
259 | |
260 | /* done! return success. */ |
261 | return 0; |
262 | } |
263 | |
264 | static void arcrimi_setmask(struct net_device *dev, int mask) |
265 | { |
266 | struct arcnet_local *lp = netdev_priv(dev); |
267 | void __iomem *ioaddr = lp->mem_start + 0x800; |
268 | |
269 | arcnet_writeb(mask, ioaddr, COM9026_REG_W_INTMASK); |
270 | } |
271 | |
272 | static int arcrimi_status(struct net_device *dev) |
273 | { |
274 | struct arcnet_local *lp = netdev_priv(dev); |
275 | void __iomem *ioaddr = lp->mem_start + 0x800; |
276 | |
277 | return arcnet_readb(ioaddr, COM9026_REG_R_STATUS); |
278 | } |
279 | |
280 | static void arcrimi_command(struct net_device *dev, int cmd) |
281 | { |
282 | struct arcnet_local *lp = netdev_priv(dev); |
283 | void __iomem *ioaddr = lp->mem_start + 0x800; |
284 | |
285 | arcnet_writeb(cmd, ioaddr, COM9026_REG_W_COMMAND); |
286 | } |
287 | |
288 | static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset, |
289 | void *buf, int count) |
290 | { |
291 | struct arcnet_local *lp = netdev_priv(dev); |
292 | void __iomem *memaddr = lp->mem_start + 0x800 + bufnum * 512 + offset; |
293 | |
294 | TIME(dev, "memcpy_toio" , count, memcpy_toio(memaddr, buf, count)); |
295 | } |
296 | |
297 | static void arcrimi_copy_from_card(struct net_device *dev, int bufnum, |
298 | int offset, void *buf, int count) |
299 | { |
300 | struct arcnet_local *lp = netdev_priv(dev); |
301 | void __iomem *memaddr = lp->mem_start + 0x800 + bufnum * 512 + offset; |
302 | |
303 | TIME(dev, "memcpy_fromio" , count, memcpy_fromio(buf, memaddr, count)); |
304 | } |
305 | |
306 | static int node; |
307 | static int io; /* use the insmod io= irq= node= options */ |
308 | static int irq; |
309 | static char device[9]; /* use eg. device=arc1 to change name */ |
310 | |
311 | module_param(node, int, 0); |
312 | module_param(io, int, 0); |
313 | module_param(irq, int, 0); |
314 | module_param_string(device, device, sizeof(device), 0); |
315 | MODULE_LICENSE("GPL" ); |
316 | |
317 | static struct net_device *my_dev; |
318 | |
319 | static int __init arc_rimi_init(void) |
320 | { |
321 | struct net_device *dev; |
322 | |
323 | dev = alloc_arcdev(name: device); |
324 | if (!dev) |
325 | return -ENOMEM; |
326 | |
327 | if (node && node != 0xff) |
328 | arcnet_set_addr(dev, addr: node); |
329 | |
330 | dev->mem_start = io; |
331 | dev->irq = irq; |
332 | if (dev->irq == 2) |
333 | dev->irq = 9; |
334 | |
335 | if (arcrimi_probe(dev)) { |
336 | free_arcdev(dev); |
337 | return -EIO; |
338 | } |
339 | |
340 | my_dev = dev; |
341 | return 0; |
342 | } |
343 | |
344 | static void __exit arc_rimi_exit(void) |
345 | { |
346 | struct net_device *dev = my_dev; |
347 | struct arcnet_local *lp = netdev_priv(dev); |
348 | |
349 | unregister_netdev(dev); |
350 | iounmap(addr: lp->mem_start); |
351 | release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1); |
352 | free_irq(dev->irq, dev); |
353 | free_arcdev(dev); |
354 | } |
355 | |
356 | #ifndef MODULE |
357 | static int __init arcrimi_setup(char *s) |
358 | { |
359 | int ints[8]; |
360 | |
361 | s = get_options(str: s, nints: 8, ints); |
362 | if (!ints[0]) |
363 | return 1; |
364 | switch (ints[0]) { |
365 | default: /* ERROR */ |
366 | pr_err("Too many arguments\n" ); |
367 | fallthrough; |
368 | case 3: /* Node ID */ |
369 | node = ints[3]; |
370 | fallthrough; |
371 | case 2: /* IRQ */ |
372 | irq = ints[2]; |
373 | fallthrough; |
374 | case 1: /* IO address */ |
375 | io = ints[1]; |
376 | } |
377 | if (*s) |
378 | snprintf(buf: device, size: sizeof(device), fmt: "%s" , s); |
379 | return 1; |
380 | } |
381 | __setup("arcrimi=" , arcrimi_setup); |
382 | #endif /* MODULE */ |
383 | |
384 | module_init(arc_rimi_init) |
385 | module_exit(arc_rimi_exit) |
386 | |