diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/net/appletalk |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/net/appletalk')
-rw-r--r-- | drivers/net/appletalk/Kconfig | 98 | ||||
-rw-r--r-- | drivers/net/appletalk/Makefile | 7 | ||||
-rw-r--r-- | drivers/net/appletalk/cops.c | 1059 | ||||
-rw-r--r-- | drivers/net/appletalk/cops.h | 60 | ||||
-rw-r--r-- | drivers/net/appletalk/cops_ffdrv.h | 533 | ||||
-rw-r--r-- | drivers/net/appletalk/cops_ltdrv.h | 242 | ||||
-rw-r--r-- | drivers/net/appletalk/ipddp.c | 317 | ||||
-rw-r--r-- | drivers/net/appletalk/ipddp.h | 27 | ||||
-rw-r--r-- | drivers/net/appletalk/ltpc.c | 1313 | ||||
-rw-r--r-- | drivers/net/appletalk/ltpc.h | 73 |
10 files changed, 3729 insertions, 0 deletions
diff --git a/drivers/net/appletalk/Kconfig b/drivers/net/appletalk/Kconfig new file mode 100644 index 000000000000..60b19679ca5c --- /dev/null +++ b/drivers/net/appletalk/Kconfig | |||
@@ -0,0 +1,98 @@ | |||
1 | # | ||
2 | # Appletalk driver configuration | ||
3 | # | ||
4 | config DEV_APPLETALK | ||
5 | bool "Appletalk interfaces support" | ||
6 | depends on ATALK | ||
7 | help | ||
8 | AppleTalk is the protocol that Apple computers can use to communicate | ||
9 | on a network. If your Linux box is connected to such a network, and wish | ||
10 | to do IP over it, or you have a LocalTalk card and wish to use it to | ||
11 | connect to the AppleTalk network, say Y. | ||
12 | |||
13 | |||
14 | config LTPC | ||
15 | tristate "Apple/Farallon LocalTalk PC support" | ||
16 | depends on DEV_APPLETALK && (ISA || EISA) | ||
17 | help | ||
18 | This allows you to use the AppleTalk PC card to connect to LocalTalk | ||
19 | networks. The card is also known as the Farallon PhoneNet PC card. | ||
20 | If you are in doubt, this card is the one with the 65C02 chip on it. | ||
21 | You also need version 1.3.3 or later of the netatalk package. | ||
22 | This driver is experimental, which means that it may not work. | ||
23 | See the file <file:Documentation/networking/ltpc.txt>. | ||
24 | |||
25 | config COPS | ||
26 | tristate "COPS LocalTalk PC support" | ||
27 | depends on DEV_APPLETALK && (ISA || EISA) | ||
28 | help | ||
29 | This allows you to use COPS AppleTalk cards to connect to LocalTalk | ||
30 | networks. You also need version 1.3.3 or later of the netatalk | ||
31 | package. This driver is experimental, which means that it may not | ||
32 | work. This driver will only work if you choose "AppleTalk DDP" | ||
33 | networking support, above. | ||
34 | Please read the file <file:Documentation/networking/cops.txt>. | ||
35 | |||
36 | config COPS_DAYNA | ||
37 | bool "Dayna firmware support" | ||
38 | depends on COPS | ||
39 | help | ||
40 | Support COPS compatible cards with Dayna style firmware (Dayna | ||
41 | DL2000/ Daynatalk/PC (half length), COPS LT-95, Farallon PhoneNET PC | ||
42 | III, Farallon PhoneNET PC II). | ||
43 | |||
44 | config COPS_TANGENT | ||
45 | bool "Tangent firmware support" | ||
46 | depends on COPS | ||
47 | help | ||
48 | Support COPS compatible cards with Tangent style firmware (Tangent | ||
49 | ATB_II, Novell NL-1000, Daystar Digital LT-200. | ||
50 | |||
51 | config IPDDP | ||
52 | tristate "Appletalk-IP driver support" | ||
53 | depends on DEV_APPLETALK && ATALK | ||
54 | ---help--- | ||
55 | This allows IP networking for users who only have AppleTalk | ||
56 | networking available. This feature is experimental. With this | ||
57 | driver, you can encapsulate IP inside AppleTalk (e.g. if your Linux | ||
58 | box is stuck on an AppleTalk only network) or decapsulate (e.g. if | ||
59 | you want your Linux box to act as an Internet gateway for a zoo of | ||
60 | AppleTalk connected Macs). Please see the file | ||
61 | <file:Documentation/networking/ipddp.txt> for more information. | ||
62 | |||
63 | If you say Y here, the AppleTalk-IP support will be compiled into | ||
64 | the kernel. In this case, you can either use encapsulation or | ||
65 | decapsulation, but not both. With the following two questions, you | ||
66 | decide which one you want. | ||
67 | |||
68 | To compile the AppleTalk-IP support as a module, choose M here: the | ||
69 | module will be called ipddp. | ||
70 | In this case, you will be able to use both encapsulation and | ||
71 | decapsulation simultaneously, by loading two copies of the module | ||
72 | and specifying different values for the module option ipddp_mode. | ||
73 | |||
74 | config IPDDP_ENCAP | ||
75 | bool "IP to Appletalk-IP Encapsulation support" | ||
76 | depends on IPDDP | ||
77 | help | ||
78 | If you say Y here, the AppleTalk-IP code will be able to encapsulate | ||
79 | IP packets inside AppleTalk frames; this is useful if your Linux box | ||
80 | is stuck on an AppleTalk network (which hopefully contains a | ||
81 | decapsulator somewhere). Please see | ||
82 | <file:Documentation/networking/ipddp.txt> for more information. If | ||
83 | you said Y to "AppleTalk-IP driver support" above and you say Y | ||
84 | here, then you cannot say Y to "AppleTalk-IP to IP Decapsulation | ||
85 | support", below. | ||
86 | |||
87 | config IPDDP_DECAP | ||
88 | bool "Appletalk-IP to IP Decapsulation support" | ||
89 | depends on IPDDP | ||
90 | help | ||
91 | If you say Y here, the AppleTalk-IP code will be able to decapsulate | ||
92 | AppleTalk-IP frames to IP packets; this is useful if you want your | ||
93 | Linux box to act as an Internet gateway for an AppleTalk network. | ||
94 | Please see <file:Documentation/networking/ipddp.txt> for more | ||
95 | information. If you said Y to "AppleTalk-IP driver support" above | ||
96 | and you say Y here, then you cannot say Y to "IP to AppleTalk-IP | ||
97 | Encapsulation support", above. | ||
98 | |||
diff --git a/drivers/net/appletalk/Makefile b/drivers/net/appletalk/Makefile new file mode 100644 index 000000000000..6cfc705f7c5c --- /dev/null +++ b/drivers/net/appletalk/Makefile | |||
@@ -0,0 +1,7 @@ | |||
1 | # | ||
2 | # Makefile for drivers/net/appletalk | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_IPDDP) += ipddp.o | ||
6 | obj-$(CONFIG_COPS) += cops.o | ||
7 | obj-$(CONFIG_LTPC) += ltpc.o | ||
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c new file mode 100644 index 000000000000..2161c2d585f0 --- /dev/null +++ b/drivers/net/appletalk/cops.c | |||
@@ -0,0 +1,1059 @@ | |||
1 | /* cops.c: LocalTalk driver for Linux. | ||
2 | * | ||
3 | * Authors: | ||
4 | * - Jay Schulist <jschlst@samba.org> | ||
5 | * | ||
6 | * With more than a little help from; | ||
7 | * - Alan Cox <Alan.Cox@linux.org> | ||
8 | * | ||
9 | * Derived from: | ||
10 | * - skeleton.c: A network driver outline for linux. | ||
11 | * Written 1993-94 by Donald Becker. | ||
12 | * - ltpc.c: A driver for the LocalTalk PC card. | ||
13 | * Written by Bradford W. Johnson. | ||
14 | * | ||
15 | * Copyright 1993 United States Government as represented by the | ||
16 | * Director, National Security Agency. | ||
17 | * | ||
18 | * This software may be used and distributed according to the terms | ||
19 | * of the GNU General Public License, incorporated herein by reference. | ||
20 | * | ||
21 | * Changes: | ||
22 | * 19970608 Alan Cox Allowed dual card type support | ||
23 | * Can set board type in insmod | ||
24 | * Hooks for cops_setup routine | ||
25 | * (not yet implemented). | ||
26 | * 19971101 Jay Schulist Fixes for multiple lt* devices. | ||
27 | * 19980607 Steven Hirsch Fixed the badly broken support | ||
28 | * for Tangent type cards. Only | ||
29 | * tested on Daystar LT200. Some | ||
30 | * cleanup of formatting and program | ||
31 | * logic. Added emacs 'local-vars' | ||
32 | * setup for Jay's brace style. | ||
33 | * 20000211 Alan Cox Cleaned up for softnet | ||
34 | */ | ||
35 | |||
36 | static const char *version = | ||
37 | "cops.c:v0.04 6/7/98 Jay Schulist <jschlst@samba.org>\n"; | ||
38 | /* | ||
39 | * Sources: | ||
40 | * COPS Localtalk SDK. This provides almost all of the information | ||
41 | * needed. | ||
42 | */ | ||
43 | |||
44 | /* | ||
45 | * insmod/modprobe configurable stuff. | ||
46 | * - IO Port, choose one your card supports or 0 if you dare. | ||
47 | * - IRQ, also choose one your card supports or nothing and let | ||
48 | * the driver figure it out. | ||
49 | */ | ||
50 | |||
51 | #include <linux/config.h> | ||
52 | #include <linux/module.h> | ||
53 | #include <linux/kernel.h> | ||
54 | #include <linux/types.h> | ||
55 | #include <linux/fcntl.h> | ||
56 | #include <linux/interrupt.h> | ||
57 | #include <linux/ptrace.h> | ||
58 | #include <linux/ioport.h> | ||
59 | #include <linux/in.h> | ||
60 | #include <linux/slab.h> | ||
61 | #include <linux/string.h> | ||
62 | #include <linux/errno.h> | ||
63 | #include <linux/init.h> | ||
64 | #include <linux/netdevice.h> | ||
65 | #include <linux/etherdevice.h> | ||
66 | #include <linux/skbuff.h> | ||
67 | #include <linux/if_arp.h> | ||
68 | #include <linux/if_ltalk.h> /* For ltalk_setup() */ | ||
69 | #include <linux/delay.h> /* For udelay() */ | ||
70 | #include <linux/atalk.h> | ||
71 | #include <linux/spinlock.h> | ||
72 | #include <linux/bitops.h> | ||
73 | |||
74 | #include <asm/system.h> | ||
75 | #include <asm/io.h> | ||
76 | #include <asm/dma.h> | ||
77 | |||
78 | #include "cops.h" /* Our Stuff */ | ||
79 | #include "cops_ltdrv.h" /* Firmware code for Tangent type cards. */ | ||
80 | #include "cops_ffdrv.h" /* Firmware code for Dayna type cards. */ | ||
81 | |||
82 | /* | ||
83 | * The name of the card. Is used for messages and in the requests for | ||
84 | * io regions, irqs and dma channels | ||
85 | */ | ||
86 | |||
87 | static const char *cardname = "cops"; | ||
88 | |||
89 | #ifdef CONFIG_COPS_DAYNA | ||
90 | static int board_type = DAYNA; /* Module exported */ | ||
91 | #else | ||
92 | static int board_type = TANGENT; | ||
93 | #endif | ||
94 | |||
95 | static int io = 0x240; /* Default IO for Dayna */ | ||
96 | static int irq = 5; /* Default IRQ */ | ||
97 | |||
98 | /* | ||
99 | * COPS Autoprobe information. | ||
100 | * Right now if port address is right but IRQ is not 5 this will | ||
101 | * return a 5 no matter what since we will still get a status response. | ||
102 | * Need one more additional check to narrow down after we have gotten | ||
103 | * the ioaddr. But since only other possible IRQs is 3 and 4 so no real | ||
104 | * hurry on this. I *STRONGLY* recommend using IRQ 5 for your card with | ||
105 | * this driver. | ||
106 | * | ||
107 | * This driver has 2 modes and they are: Dayna mode and Tangent mode. | ||
108 | * Each mode corresponds with the type of card. It has been found | ||
109 | * that there are 2 main types of cards and all other cards are | ||
110 | * the same and just have different names or only have minor differences | ||
111 | * such as more IO ports. As this driver is tested it will | ||
112 | * become more clear on exactly what cards are supported. The driver | ||
113 | * defaults to using Dayna mode. To change the drivers mode, simply | ||
114 | * select Dayna or Tangent mode when configuring the kernel. | ||
115 | * | ||
116 | * This driver should support: | ||
117 | * TANGENT driver mode: | ||
118 | * Tangent ATB-II, Novell NL-1000, Daystar Digital LT-200, | ||
119 | * COPS LT-1 | ||
120 | * DAYNA driver mode: | ||
121 | * Dayna DL2000/DaynaTalk PC (Half Length), COPS LT-95, | ||
122 | * Farallon PhoneNET PC III, Farallon PhoneNET PC II | ||
123 | * Other cards possibly supported mode unkown though: | ||
124 | * Dayna DL2000 (Full length), COPS LT/M (Micro-Channel) | ||
125 | * | ||
126 | * Cards NOT supported by this driver but supported by the ltpc.c | ||
127 | * driver written by Bradford W. Johnson <johns393@maroon.tc.umn.edu> | ||
128 | * Farallon PhoneNET PC | ||
129 | * Original Apple LocalTalk PC card | ||
130 | * | ||
131 | * N.B. | ||
132 | * | ||
133 | * The Daystar Digital LT200 boards do not support interrupt-driven | ||
134 | * IO. You must specify 'irq=0xff' as a module parameter to invoke | ||
135 | * polled mode. I also believe that the port probing logic is quite | ||
136 | * dangerous at best and certainly hopeless for a polled card. Best to | ||
137 | * specify both. - Steve H. | ||
138 | * | ||
139 | */ | ||
140 | |||
141 | /* | ||
142 | * Zero terminated list of IO ports to probe. | ||
143 | */ | ||
144 | |||
145 | static unsigned int ports[] = { | ||
146 | 0x240, 0x340, 0x200, 0x210, 0x220, 0x230, 0x260, | ||
147 | 0x2A0, 0x300, 0x310, 0x320, 0x330, 0x350, 0x360, | ||
148 | 0 | ||
149 | }; | ||
150 | |||
151 | /* | ||
152 | * Zero terminated list of IRQ ports to probe. | ||
153 | */ | ||
154 | |||
155 | static int cops_irqlist[] = { | ||
156 | 5, 4, 3, 0 | ||
157 | }; | ||
158 | |||
159 | static struct timer_list cops_timer; | ||
160 | |||
161 | /* use 0 for production, 1 for verification, 2 for debug, 3 for verbose debug */ | ||
162 | #ifndef COPS_DEBUG | ||
163 | #define COPS_DEBUG 1 | ||
164 | #endif | ||
165 | static unsigned int cops_debug = COPS_DEBUG; | ||
166 | |||
167 | /* The number of low I/O ports used by the card. */ | ||
168 | #define COPS_IO_EXTENT 8 | ||
169 | |||
170 | /* Information that needs to be kept for each board. */ | ||
171 | |||
172 | struct cops_local | ||
173 | { | ||
174 | struct net_device_stats stats; | ||
175 | int board; /* Holds what board type is. */ | ||
176 | int nodeid; /* Set to 1 once have nodeid. */ | ||
177 | unsigned char node_acquire; /* Node ID when acquired. */ | ||
178 | struct atalk_addr node_addr; /* Full node address */ | ||
179 | spinlock_t lock; /* RX/TX lock */ | ||
180 | }; | ||
181 | |||
182 | /* Index to functions, as function prototypes. */ | ||
183 | static int cops_probe1 (struct net_device *dev, int ioaddr); | ||
184 | static int cops_irq (int ioaddr, int board); | ||
185 | |||
186 | static int cops_open (struct net_device *dev); | ||
187 | static int cops_jumpstart (struct net_device *dev); | ||
188 | static void cops_reset (struct net_device *dev, int sleep); | ||
189 | static void cops_load (struct net_device *dev); | ||
190 | static int cops_nodeid (struct net_device *dev, int nodeid); | ||
191 | |||
192 | static irqreturn_t cops_interrupt (int irq, void *dev_id, struct pt_regs *regs); | ||
193 | static void cops_poll (unsigned long ltdev); | ||
194 | static void cops_timeout(struct net_device *dev); | ||
195 | static void cops_rx (struct net_device *dev); | ||
196 | static int cops_send_packet (struct sk_buff *skb, struct net_device *dev); | ||
197 | static void set_multicast_list (struct net_device *dev); | ||
198 | static int cops_hard_header (struct sk_buff *skb, struct net_device *dev, | ||
199 | unsigned short type, void *daddr, void *saddr, | ||
200 | unsigned len); | ||
201 | |||
202 | static int cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); | ||
203 | static int cops_close (struct net_device *dev); | ||
204 | static struct net_device_stats *cops_get_stats (struct net_device *dev); | ||
205 | |||
206 | static void cleanup_card(struct net_device *dev) | ||
207 | { | ||
208 | if (dev->irq) | ||
209 | free_irq(dev->irq, dev); | ||
210 | release_region(dev->base_addr, COPS_IO_EXTENT); | ||
211 | } | ||
212 | |||
213 | /* | ||
214 | * Check for a network adaptor of this type, and return '0' iff one exists. | ||
215 | * If dev->base_addr == 0, probe all likely locations. | ||
216 | * If dev->base_addr in [1..0x1ff], always return failure. | ||
217 | * otherwise go with what we pass in. | ||
218 | */ | ||
219 | struct net_device * __init cops_probe(int unit) | ||
220 | { | ||
221 | struct net_device *dev; | ||
222 | unsigned *port; | ||
223 | int base_addr; | ||
224 | int err = 0; | ||
225 | |||
226 | dev = alloc_netdev(sizeof(struct cops_local), "lt%d", ltalk_setup); | ||
227 | if (!dev) | ||
228 | return ERR_PTR(-ENOMEM); | ||
229 | |||
230 | if (unit >= 0) { | ||
231 | sprintf(dev->name, "lt%d", unit); | ||
232 | netdev_boot_setup_check(dev); | ||
233 | irq = dev->irq; | ||
234 | base_addr = dev->base_addr; | ||
235 | } else { | ||
236 | base_addr = dev->base_addr = io; | ||
237 | } | ||
238 | |||
239 | SET_MODULE_OWNER(dev); | ||
240 | |||
241 | if (base_addr > 0x1ff) { /* Check a single specified location. */ | ||
242 | err = cops_probe1(dev, base_addr); | ||
243 | } else if (base_addr != 0) { /* Don't probe at all. */ | ||
244 | err = -ENXIO; | ||
245 | } else { | ||
246 | /* FIXME Does this really work for cards which generate irq? | ||
247 | * It's definitely N.G. for polled Tangent. sh | ||
248 | * Dayna cards don't autoprobe well at all, but if your card is | ||
249 | * at IRQ 5 & IO 0x240 we find it every time. ;) JS | ||
250 | */ | ||
251 | for (port = ports; *port && cops_probe1(dev, *port) < 0; port++) | ||
252 | ; | ||
253 | if (!*port) | ||
254 | err = -ENODEV; | ||
255 | } | ||
256 | if (err) | ||
257 | goto out; | ||
258 | err = register_netdev(dev); | ||
259 | if (err) | ||
260 | goto out1; | ||
261 | return dev; | ||
262 | out1: | ||
263 | cleanup_card(dev); | ||
264 | out: | ||
265 | free_netdev(dev); | ||
266 | return ERR_PTR(err); | ||
267 | } | ||
268 | |||
269 | /* | ||
270 | * This is the real probe routine. Linux has a history of friendly device | ||
271 | * probes on the ISA bus. A good device probes avoids doing writes, and | ||
272 | * verifies that the correct device exists and functions. | ||
273 | */ | ||
274 | static int __init cops_probe1(struct net_device *dev, int ioaddr) | ||
275 | { | ||
276 | struct cops_local *lp; | ||
277 | static unsigned version_printed; | ||
278 | int board = board_type; | ||
279 | int retval; | ||
280 | |||
281 | if(cops_debug && version_printed++ == 0) | ||
282 | printk("%s", version); | ||
283 | |||
284 | /* Grab the region so no one else tries to probe our ioports. */ | ||
285 | if (!request_region(ioaddr, COPS_IO_EXTENT, dev->name)) | ||
286 | return -EBUSY; | ||
287 | |||
288 | /* | ||
289 | * Since this board has jumpered interrupts, allocate the interrupt | ||
290 | * vector now. There is no point in waiting since no other device | ||
291 | * can use the interrupt, and this marks the irq as busy. Jumpered | ||
292 | * interrupts are typically not reported by the boards, and we must | ||
293 | * used AutoIRQ to find them. | ||
294 | */ | ||
295 | dev->irq = irq; | ||
296 | switch (dev->irq) | ||
297 | { | ||
298 | case 0: | ||
299 | /* COPS AutoIRQ routine */ | ||
300 | dev->irq = cops_irq(ioaddr, board); | ||
301 | if (dev->irq) | ||
302 | break; | ||
303 | /* No IRQ found on this port, fallthrough */ | ||
304 | case 1: | ||
305 | retval = -EINVAL; | ||
306 | goto err_out; | ||
307 | |||
308 | /* Fixup for users that don't know that IRQ 2 is really | ||
309 | * IRQ 9, or don't know which one to set. | ||
310 | */ | ||
311 | case 2: | ||
312 | dev->irq = 9; | ||
313 | break; | ||
314 | |||
315 | /* Polled operation requested. Although irq of zero passed as | ||
316 | * a parameter tells the init routines to probe, we'll | ||
317 | * overload it to denote polled operation at runtime. | ||
318 | */ | ||
319 | case 0xff: | ||
320 | dev->irq = 0; | ||
321 | break; | ||
322 | |||
323 | default: | ||
324 | break; | ||
325 | } | ||
326 | |||
327 | /* Reserve any actual interrupt. */ | ||
328 | if (dev->irq) { | ||
329 | retval = request_irq(dev->irq, &cops_interrupt, 0, dev->name, dev); | ||
330 | if (retval) | ||
331 | goto err_out; | ||
332 | } | ||
333 | |||
334 | dev->base_addr = ioaddr; | ||
335 | |||
336 | lp = netdev_priv(dev); | ||
337 | memset(lp, 0, sizeof(struct cops_local)); | ||
338 | spin_lock_init(&lp->lock); | ||
339 | |||
340 | /* Copy local board variable to lp struct. */ | ||
341 | lp->board = board; | ||
342 | |||
343 | dev->hard_start_xmit = cops_send_packet; | ||
344 | dev->tx_timeout = cops_timeout; | ||
345 | dev->watchdog_timeo = HZ * 2; | ||
346 | dev->hard_header = cops_hard_header; | ||
347 | dev->get_stats = cops_get_stats; | ||
348 | dev->open = cops_open; | ||
349 | dev->stop = cops_close; | ||
350 | dev->do_ioctl = cops_ioctl; | ||
351 | dev->set_multicast_list = set_multicast_list; | ||
352 | dev->mc_list = NULL; | ||
353 | |||
354 | /* Tell the user where the card is and what mode we're in. */ | ||
355 | if(board==DAYNA) | ||
356 | printk("%s: %s at %#3x, using IRQ %d, in Dayna mode.\n", | ||
357 | dev->name, cardname, ioaddr, dev->irq); | ||
358 | if(board==TANGENT) { | ||
359 | if(dev->irq) | ||
360 | printk("%s: %s at %#3x, IRQ %d, in Tangent mode\n", | ||
361 | dev->name, cardname, ioaddr, dev->irq); | ||
362 | else | ||
363 | printk("%s: %s at %#3x, using polled IO, in Tangent mode.\n", | ||
364 | dev->name, cardname, ioaddr); | ||
365 | |||
366 | } | ||
367 | return 0; | ||
368 | |||
369 | err_out: | ||
370 | release_region(ioaddr, COPS_IO_EXTENT); | ||
371 | return retval; | ||
372 | } | ||
373 | |||
374 | static int __init cops_irq (int ioaddr, int board) | ||
375 | { /* | ||
376 | * This does not use the IRQ to determine where the IRQ is. We just | ||
377 | * assume that when we get a correct status response that it's the IRQ. | ||
378 | * This really just verifies the IO port but since we only have access | ||
379 | * to such a small number of IRQs (5, 4, 3) this is not bad. | ||
380 | * This will probably not work for more than one card. | ||
381 | */ | ||
382 | int irqaddr=0; | ||
383 | int i, x, status; | ||
384 | |||
385 | if(board==DAYNA) | ||
386 | { | ||
387 | outb(0, ioaddr+DAYNA_RESET); | ||
388 | inb(ioaddr+DAYNA_RESET); | ||
389 | mdelay(333); | ||
390 | } | ||
391 | if(board==TANGENT) | ||
392 | { | ||
393 | inb(ioaddr); | ||
394 | outb(0, ioaddr); | ||
395 | outb(0, ioaddr+TANG_RESET); | ||
396 | } | ||
397 | |||
398 | for(i=0; cops_irqlist[i] !=0; i++) | ||
399 | { | ||
400 | irqaddr = cops_irqlist[i]; | ||
401 | for(x = 0xFFFF; x>0; x --) /* wait for response */ | ||
402 | { | ||
403 | if(board==DAYNA) | ||
404 | { | ||
405 | status = (inb(ioaddr+DAYNA_CARD_STATUS)&3); | ||
406 | if(status == 1) | ||
407 | return irqaddr; | ||
408 | } | ||
409 | if(board==TANGENT) | ||
410 | { | ||
411 | if((inb(ioaddr+TANG_CARD_STATUS)& TANG_TX_READY) !=0) | ||
412 | return irqaddr; | ||
413 | } | ||
414 | } | ||
415 | } | ||
416 | return 0; /* no IRQ found */ | ||
417 | } | ||
418 | |||
419 | /* | ||
420 | * Open/initialize the board. This is called (in the current kernel) | ||
421 | * sometime after booting when the 'ifconfig' program is run. | ||
422 | */ | ||
423 | static int cops_open(struct net_device *dev) | ||
424 | { | ||
425 | struct cops_local *lp = netdev_priv(dev); | ||
426 | |||
427 | if(dev->irq==0) | ||
428 | { | ||
429 | /* | ||
430 | * I don't know if the Dayna-style boards support polled | ||
431 | * operation. For now, only allow it for Tangent. | ||
432 | */ | ||
433 | if(lp->board==TANGENT) /* Poll 20 times per second */ | ||
434 | { | ||
435 | init_timer(&cops_timer); | ||
436 | cops_timer.function = cops_poll; | ||
437 | cops_timer.data = (unsigned long)dev; | ||
438 | cops_timer.expires = jiffies + HZ/20; | ||
439 | add_timer(&cops_timer); | ||
440 | } | ||
441 | else | ||
442 | { | ||
443 | printk(KERN_WARNING "%s: No irq line set\n", dev->name); | ||
444 | return -EAGAIN; | ||
445 | } | ||
446 | } | ||
447 | |||
448 | cops_jumpstart(dev); /* Start the card up. */ | ||
449 | |||
450 | netif_start_queue(dev); | ||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | /* | ||
455 | * This allows for a dynamic start/restart of the entire card. | ||
456 | */ | ||
457 | static int cops_jumpstart(struct net_device *dev) | ||
458 | { | ||
459 | struct cops_local *lp = netdev_priv(dev); | ||
460 | |||
461 | /* | ||
462 | * Once the card has the firmware loaded and has acquired | ||
463 | * the nodeid, if it is reset it will lose it all. | ||
464 | */ | ||
465 | cops_reset(dev,1); /* Need to reset card before load firmware. */ | ||
466 | cops_load(dev); /* Load the firmware. */ | ||
467 | |||
468 | /* | ||
469 | * If atalkd already gave us a nodeid we will use that | ||
470 | * one again, else we wait for atalkd to give us a nodeid | ||
471 | * in cops_ioctl. This may cause a problem if someone steals | ||
472 | * our nodeid while we are resetting. | ||
473 | */ | ||
474 | if(lp->nodeid == 1) | ||
475 | cops_nodeid(dev,lp->node_acquire); | ||
476 | |||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | static void tangent_wait_reset(int ioaddr) | ||
481 | { | ||
482 | int timeout=0; | ||
483 | |||
484 | while(timeout++ < 5 && (inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0) | ||
485 | mdelay(1); /* Wait 1 second */ | ||
486 | } | ||
487 | |||
488 | /* | ||
489 | * Reset the LocalTalk board. | ||
490 | */ | ||
491 | static void cops_reset(struct net_device *dev, int sleep) | ||
492 | { | ||
493 | struct cops_local *lp = netdev_priv(dev); | ||
494 | int ioaddr=dev->base_addr; | ||
495 | |||
496 | if(lp->board==TANGENT) | ||
497 | { | ||
498 | inb(ioaddr); /* Clear request latch. */ | ||
499 | outb(0,ioaddr); /* Clear the TANG_TX_READY flop. */ | ||
500 | outb(0, ioaddr+TANG_RESET); /* Reset the adapter. */ | ||
501 | |||
502 | tangent_wait_reset(ioaddr); | ||
503 | outb(0, ioaddr+TANG_CLEAR_INT); | ||
504 | } | ||
505 | if(lp->board==DAYNA) | ||
506 | { | ||
507 | outb(0, ioaddr+DAYNA_RESET); /* Assert the reset port */ | ||
508 | inb(ioaddr+DAYNA_RESET); /* Clear the reset */ | ||
509 | if(sleep) | ||
510 | { | ||
511 | long snap=jiffies; | ||
512 | |||
513 | /* Let card finish initializing, about 1/3 second */ | ||
514 | while(jiffies-snap<HZ/3) | ||
515 | schedule(); | ||
516 | } | ||
517 | else | ||
518 | mdelay(333); | ||
519 | } | ||
520 | netif_wake_queue(dev); | ||
521 | return; | ||
522 | } | ||
523 | |||
524 | static void cops_load (struct net_device *dev) | ||
525 | { | ||
526 | struct ifreq ifr; | ||
527 | struct ltfirmware *ltf= (struct ltfirmware *)&ifr.ifr_ifru; | ||
528 | struct cops_local *lp = netdev_priv(dev); | ||
529 | int ioaddr=dev->base_addr; | ||
530 | int length, i = 0; | ||
531 | |||
532 | strcpy(ifr.ifr_name,"lt0"); | ||
533 | |||
534 | /* Get card's firmware code and do some checks on it. */ | ||
535 | #ifdef CONFIG_COPS_DAYNA | ||
536 | if(lp->board==DAYNA) | ||
537 | { | ||
538 | ltf->length=sizeof(ffdrv_code); | ||
539 | ltf->data=ffdrv_code; | ||
540 | } | ||
541 | else | ||
542 | #endif | ||
543 | #ifdef CONFIG_COPS_TANGENT | ||
544 | if(lp->board==TANGENT) | ||
545 | { | ||
546 | ltf->length=sizeof(ltdrv_code); | ||
547 | ltf->data=ltdrv_code; | ||
548 | } | ||
549 | else | ||
550 | #endif | ||
551 | { | ||
552 | printk(KERN_INFO "%s; unsupported board type.\n", dev->name); | ||
553 | return; | ||
554 | } | ||
555 | |||
556 | /* Check to make sure firmware is correct length. */ | ||
557 | if(lp->board==DAYNA && ltf->length!=5983) | ||
558 | { | ||
559 | printk(KERN_WARNING "%s: Firmware is not length of FFDRV.BIN.\n", dev->name); | ||
560 | return; | ||
561 | } | ||
562 | if(lp->board==TANGENT && ltf->length!=2501) | ||
563 | { | ||
564 | printk(KERN_WARNING "%s: Firmware is not length of DRVCODE.BIN.\n", dev->name); | ||
565 | return; | ||
566 | } | ||
567 | |||
568 | if(lp->board==DAYNA) | ||
569 | { | ||
570 | /* | ||
571 | * We must wait for a status response | ||
572 | * with the DAYNA board. | ||
573 | */ | ||
574 | while(++i<65536) | ||
575 | { | ||
576 | if((inb(ioaddr+DAYNA_CARD_STATUS)&3)==1) | ||
577 | break; | ||
578 | } | ||
579 | |||
580 | if(i==65536) | ||
581 | return; | ||
582 | } | ||
583 | |||
584 | /* | ||
585 | * Upload the firmware and kick. Byte-by-byte works nicely here. | ||
586 | */ | ||
587 | i=0; | ||
588 | length = ltf->length; | ||
589 | while(length--) | ||
590 | { | ||
591 | outb(ltf->data[i], ioaddr); | ||
592 | i++; | ||
593 | } | ||
594 | |||
595 | if(cops_debug > 1) | ||
596 | printk("%s: Uploaded firmware - %d bytes of %d bytes.\n", | ||
597 | dev->name, i, ltf->length); | ||
598 | |||
599 | if(lp->board==DAYNA) /* Tell Dayna to run the firmware code. */ | ||
600 | outb(1, ioaddr+DAYNA_INT_CARD); | ||
601 | else /* Tell Tang to run the firmware code. */ | ||
602 | inb(ioaddr); | ||
603 | |||
604 | if(lp->board==TANGENT) | ||
605 | { | ||
606 | tangent_wait_reset(ioaddr); | ||
607 | inb(ioaddr); /* Clear initial ready signal. */ | ||
608 | } | ||
609 | |||
610 | return; | ||
611 | } | ||
612 | |||
613 | /* | ||
614 | * Get the LocalTalk Nodeid from the card. We can suggest | ||
615 | * any nodeid 1-254. The card will try and get that exact | ||
616 | * address else we can specify 0 as the nodeid and the card | ||
617 | * will autoprobe for a nodeid. | ||
618 | */ | ||
619 | static int cops_nodeid (struct net_device *dev, int nodeid) | ||
620 | { | ||
621 | struct cops_local *lp = netdev_priv(dev); | ||
622 | int ioaddr = dev->base_addr; | ||
623 | |||
624 | if(lp->board == DAYNA) | ||
625 | { | ||
626 | /* Empty any pending adapter responses. */ | ||
627 | while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0) | ||
628 | { | ||
629 | outb(0, ioaddr+COPS_CLEAR_INT); /* Clear interrupts. */ | ||
630 | if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST) | ||
631 | cops_rx(dev); /* Kick any packets waiting. */ | ||
632 | schedule(); | ||
633 | } | ||
634 | |||
635 | outb(2, ioaddr); /* Output command packet length as 2. */ | ||
636 | outb(0, ioaddr); | ||
637 | outb(LAP_INIT, ioaddr); /* Send LAP_INIT command byte. */ | ||
638 | outb(nodeid, ioaddr); /* Suggest node address. */ | ||
639 | } | ||
640 | |||
641 | if(lp->board == TANGENT) | ||
642 | { | ||
643 | /* Empty any pending adapter responses. */ | ||
644 | while(inb(ioaddr+TANG_CARD_STATUS)&TANG_RX_READY) | ||
645 | { | ||
646 | outb(0, ioaddr+COPS_CLEAR_INT); /* Clear interrupt. */ | ||
647 | cops_rx(dev); /* Kick out packets waiting. */ | ||
648 | schedule(); | ||
649 | } | ||
650 | |||
651 | /* Not sure what Tangent does if nodeid picked is used. */ | ||
652 | if(nodeid == 0) /* Seed. */ | ||
653 | nodeid = jiffies&0xFF; /* Get a random try */ | ||
654 | outb(2, ioaddr); /* Command length LSB */ | ||
655 | outb(0, ioaddr); /* Command length MSB */ | ||
656 | outb(LAP_INIT, ioaddr); /* Send LAP_INIT byte */ | ||
657 | outb(nodeid, ioaddr); /* LAP address hint. */ | ||
658 | outb(0xFF, ioaddr); /* Int. level to use */ | ||
659 | } | ||
660 | |||
661 | lp->node_acquire=0; /* Set nodeid holder to 0. */ | ||
662 | while(lp->node_acquire==0) /* Get *True* nodeid finally. */ | ||
663 | { | ||
664 | outb(0, ioaddr+COPS_CLEAR_INT); /* Clear any interrupt. */ | ||
665 | |||
666 | if(lp->board == DAYNA) | ||
667 | { | ||
668 | if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST) | ||
669 | cops_rx(dev); /* Grab the nodeid put in lp->node_acquire. */ | ||
670 | } | ||
671 | if(lp->board == TANGENT) | ||
672 | { | ||
673 | if(inb(ioaddr+TANG_CARD_STATUS)&TANG_RX_READY) | ||
674 | cops_rx(dev); /* Grab the nodeid put in lp->node_acquire. */ | ||
675 | } | ||
676 | schedule(); | ||
677 | } | ||
678 | |||
679 | if(cops_debug > 1) | ||
680 | printk(KERN_DEBUG "%s: Node ID %d has been acquired.\n", | ||
681 | dev->name, lp->node_acquire); | ||
682 | |||
683 | lp->nodeid=1; /* Set got nodeid to 1. */ | ||
684 | |||
685 | return 0; | ||
686 | } | ||
687 | |||
688 | /* | ||
689 | * Poll the Tangent type cards to see if we have work. | ||
690 | */ | ||
691 | |||
692 | static void cops_poll(unsigned long ltdev) | ||
693 | { | ||
694 | int ioaddr, status; | ||
695 | int boguscount = 0; | ||
696 | |||
697 | struct net_device *dev = (struct net_device *)ltdev; | ||
698 | |||
699 | del_timer(&cops_timer); | ||
700 | |||
701 | if(dev == NULL) | ||
702 | return; /* We've been downed */ | ||
703 | |||
704 | ioaddr = dev->base_addr; | ||
705 | do { | ||
706 | status=inb(ioaddr+TANG_CARD_STATUS); | ||
707 | if(status & TANG_RX_READY) | ||
708 | cops_rx(dev); | ||
709 | if(status & TANG_TX_READY) | ||
710 | netif_wake_queue(dev); | ||
711 | status = inb(ioaddr+TANG_CARD_STATUS); | ||
712 | } while((++boguscount < 20) && (status&(TANG_RX_READY|TANG_TX_READY))); | ||
713 | |||
714 | /* poll 20 times per second */ | ||
715 | cops_timer.expires = jiffies + HZ/20; | ||
716 | add_timer(&cops_timer); | ||
717 | |||
718 | return; | ||
719 | } | ||
720 | |||
721 | /* | ||
722 | * The typical workload of the driver: | ||
723 | * Handle the network interface interrupts. | ||
724 | */ | ||
725 | static irqreturn_t cops_interrupt(int irq, void *dev_id, struct pt_regs * regs) | ||
726 | { | ||
727 | struct net_device *dev = dev_id; | ||
728 | struct cops_local *lp; | ||
729 | int ioaddr, status; | ||
730 | int boguscount = 0; | ||
731 | |||
732 | ioaddr = dev->base_addr; | ||
733 | lp = netdev_priv(dev); | ||
734 | |||
735 | if(lp->board==DAYNA) | ||
736 | { | ||
737 | do { | ||
738 | outb(0, ioaddr + COPS_CLEAR_INT); | ||
739 | status=inb(ioaddr+DAYNA_CARD_STATUS); | ||
740 | if((status&0x03)==DAYNA_RX_REQUEST) | ||
741 | cops_rx(dev); | ||
742 | netif_wake_queue(dev); | ||
743 | } while(++boguscount < 20); | ||
744 | } | ||
745 | else | ||
746 | { | ||
747 | do { | ||
748 | status=inb(ioaddr+TANG_CARD_STATUS); | ||
749 | if(status & TANG_RX_READY) | ||
750 | cops_rx(dev); | ||
751 | if(status & TANG_TX_READY) | ||
752 | netif_wake_queue(dev); | ||
753 | status=inb(ioaddr+TANG_CARD_STATUS); | ||
754 | } while((++boguscount < 20) && (status&(TANG_RX_READY|TANG_TX_READY))); | ||
755 | } | ||
756 | |||
757 | return IRQ_HANDLED; | ||
758 | } | ||
759 | |||
760 | /* | ||
761 | * We have a good packet(s), get it/them out of the buffers. | ||
762 | */ | ||
763 | static void cops_rx(struct net_device *dev) | ||
764 | { | ||
765 | int pkt_len = 0; | ||
766 | int rsp_type = 0; | ||
767 | struct sk_buff *skb = NULL; | ||
768 | struct cops_local *lp = netdev_priv(dev); | ||
769 | int ioaddr = dev->base_addr; | ||
770 | int boguscount = 0; | ||
771 | unsigned long flags; | ||
772 | |||
773 | |||
774 | spin_lock_irqsave(&lp->lock, flags); | ||
775 | |||
776 | if(lp->board==DAYNA) | ||
777 | { | ||
778 | outb(0, ioaddr); /* Send out Zero length. */ | ||
779 | outb(0, ioaddr); | ||
780 | outb(DATA_READ, ioaddr); /* Send read command out. */ | ||
781 | |||
782 | /* Wait for DMA to turn around. */ | ||
783 | while(++boguscount<1000000) | ||
784 | { | ||
785 | barrier(); | ||
786 | if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_READY) | ||
787 | break; | ||
788 | } | ||
789 | |||
790 | if(boguscount==1000000) | ||
791 | { | ||
792 | printk(KERN_WARNING "%s: DMA timed out.\n",dev->name); | ||
793 | spin_unlock_irqrestore(&lp->lock, flags); | ||
794 | return; | ||
795 | } | ||
796 | } | ||
797 | |||
798 | /* Get response length. */ | ||
799 | if(lp->board==DAYNA) | ||
800 | pkt_len = inb(ioaddr) & 0xFF; | ||
801 | else | ||
802 | pkt_len = inb(ioaddr) & 0x00FF; | ||
803 | pkt_len |= (inb(ioaddr) << 8); | ||
804 | /* Input IO code. */ | ||
805 | rsp_type=inb(ioaddr); | ||
806 | |||
807 | /* Malloc up new buffer. */ | ||
808 | skb = dev_alloc_skb(pkt_len); | ||
809 | if(skb == NULL) | ||
810 | { | ||
811 | printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", | ||
812 | dev->name); | ||
813 | lp->stats.rx_dropped++; | ||
814 | while(pkt_len--) /* Discard packet */ | ||
815 | inb(ioaddr); | ||
816 | spin_unlock_irqrestore(&lp->lock, flags); | ||
817 | return; | ||
818 | } | ||
819 | skb->dev = dev; | ||
820 | skb_put(skb, pkt_len); | ||
821 | skb->protocol = htons(ETH_P_LOCALTALK); | ||
822 | |||
823 | insb(ioaddr, skb->data, pkt_len); /* Eat the Data */ | ||
824 | |||
825 | if(lp->board==DAYNA) | ||
826 | outb(1, ioaddr+DAYNA_INT_CARD); /* Interrupt the card */ | ||
827 | |||
828 | spin_unlock_irqrestore(&lp->lock, flags); /* Restore interrupts. */ | ||
829 | |||
830 | /* Check for bad response length */ | ||
831 | if(pkt_len < 0 || pkt_len > MAX_LLAP_SIZE) | ||
832 | { | ||
833 | printk(KERN_WARNING "%s: Bad packet length of %d bytes.\n", | ||
834 | dev->name, pkt_len); | ||
835 | lp->stats.tx_errors++; | ||
836 | dev_kfree_skb_any(skb); | ||
837 | return; | ||
838 | } | ||
839 | |||
840 | /* Set nodeid and then get out. */ | ||
841 | if(rsp_type == LAP_INIT_RSP) | ||
842 | { /* Nodeid taken from received packet. */ | ||
843 | lp->node_acquire = skb->data[0]; | ||
844 | dev_kfree_skb_any(skb); | ||
845 | return; | ||
846 | } | ||
847 | |||
848 | /* One last check to make sure we have a good packet. */ | ||
849 | if(rsp_type != LAP_RESPONSE) | ||
850 | { | ||
851 | printk(KERN_WARNING "%s: Bad packet type %d.\n", dev->name, rsp_type); | ||
852 | lp->stats.tx_errors++; | ||
853 | dev_kfree_skb_any(skb); | ||
854 | return; | ||
855 | } | ||
856 | |||
857 | skb->mac.raw = skb->data; /* Point to entire packet. */ | ||
858 | skb_pull(skb,3); | ||
859 | skb->h.raw = skb->data; /* Point to data (Skip header). */ | ||
860 | |||
861 | /* Update the counters. */ | ||
862 | lp->stats.rx_packets++; | ||
863 | lp->stats.rx_bytes += skb->len; | ||
864 | |||
865 | /* Send packet to a higher place. */ | ||
866 | netif_rx(skb); | ||
867 | dev->last_rx = jiffies; | ||
868 | } | ||
869 | |||
870 | static void cops_timeout(struct net_device *dev) | ||
871 | { | ||
872 | struct cops_local *lp = netdev_priv(dev); | ||
873 | int ioaddr = dev->base_addr; | ||
874 | |||
875 | lp->stats.tx_errors++; | ||
876 | if(lp->board==TANGENT) | ||
877 | { | ||
878 | if((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0) | ||
879 | printk(KERN_WARNING "%s: No TX complete interrupt.\n", dev->name); | ||
880 | } | ||
881 | printk(KERN_WARNING "%s: Transmit timed out.\n", dev->name); | ||
882 | cops_jumpstart(dev); /* Restart the card. */ | ||
883 | dev->trans_start = jiffies; | ||
884 | netif_wake_queue(dev); | ||
885 | } | ||
886 | |||
887 | |||
888 | /* | ||
889 | * Make the card transmit a LocalTalk packet. | ||
890 | */ | ||
891 | |||
892 | static int cops_send_packet(struct sk_buff *skb, struct net_device *dev) | ||
893 | { | ||
894 | struct cops_local *lp = netdev_priv(dev); | ||
895 | int ioaddr = dev->base_addr; | ||
896 | unsigned long flags; | ||
897 | |||
898 | /* | ||
899 | * Block a timer-based transmit from overlapping. | ||
900 | */ | ||
901 | |||
902 | netif_stop_queue(dev); | ||
903 | |||
904 | spin_lock_irqsave(&lp->lock, flags); | ||
905 | if(lp->board == DAYNA) /* Wait for adapter transmit buffer. */ | ||
906 | while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0) | ||
907 | cpu_relax(); | ||
908 | if(lp->board == TANGENT) /* Wait for adapter transmit buffer. */ | ||
909 | while((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0) | ||
910 | cpu_relax(); | ||
911 | |||
912 | /* Output IO length. */ | ||
913 | outb(skb->len, ioaddr); | ||
914 | if(lp->board == DAYNA) | ||
915 | outb(skb->len >> 8, ioaddr); | ||
916 | else | ||
917 | outb((skb->len >> 8)&0x0FF, ioaddr); | ||
918 | |||
919 | /* Output IO code. */ | ||
920 | outb(LAP_WRITE, ioaddr); | ||
921 | |||
922 | if(lp->board == DAYNA) /* Check the transmit buffer again. */ | ||
923 | while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0); | ||
924 | |||
925 | outsb(ioaddr, skb->data, skb->len); /* Send out the data. */ | ||
926 | |||
927 | if(lp->board==DAYNA) /* Dayna requires you kick the card */ | ||
928 | outb(1, ioaddr+DAYNA_INT_CARD); | ||
929 | |||
930 | spin_unlock_irqrestore(&lp->lock, flags); /* Restore interrupts. */ | ||
931 | |||
932 | /* Done sending packet, update counters and cleanup. */ | ||
933 | lp->stats.tx_packets++; | ||
934 | lp->stats.tx_bytes += skb->len; | ||
935 | dev->trans_start = jiffies; | ||
936 | dev_kfree_skb (skb); | ||
937 | return 0; | ||
938 | } | ||
939 | |||
940 | /* | ||
941 | * Dummy function to keep the Appletalk layer happy. | ||
942 | */ | ||
943 | |||
944 | static void set_multicast_list(struct net_device *dev) | ||
945 | { | ||
946 | if(cops_debug >= 3) | ||
947 | printk("%s: set_multicast_list executed\n", dev->name); | ||
948 | } | ||
949 | |||
950 | /* | ||
951 | * Another Dummy function to keep the Appletalk layer happy. | ||
952 | */ | ||
953 | |||
954 | static int cops_hard_header(struct sk_buff *skb, struct net_device *dev, | ||
955 | unsigned short type, void *daddr, void *saddr, | ||
956 | unsigned len) | ||
957 | { | ||
958 | if(cops_debug >= 3) | ||
959 | printk("%s: cops_hard_header executed. Wow!\n", dev->name); | ||
960 | return 0; | ||
961 | } | ||
962 | |||
963 | /* | ||
964 | * System ioctls for the COPS LocalTalk card. | ||
965 | */ | ||
966 | |||
967 | static int cops_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | ||
968 | { | ||
969 | struct cops_local *lp = netdev_priv(dev); | ||
970 | struct sockaddr_at *sa = (struct sockaddr_at *)&ifr->ifr_addr; | ||
971 | struct atalk_addr *aa = (struct atalk_addr *)&lp->node_addr; | ||
972 | |||
973 | switch(cmd) | ||
974 | { | ||
975 | case SIOCSIFADDR: | ||
976 | /* Get and set the nodeid and network # atalkd wants. */ | ||
977 | cops_nodeid(dev, sa->sat_addr.s_node); | ||
978 | aa->s_net = sa->sat_addr.s_net; | ||
979 | aa->s_node = lp->node_acquire; | ||
980 | |||
981 | /* Set broardcast address. */ | ||
982 | dev->broadcast[0] = 0xFF; | ||
983 | |||
984 | /* Set hardware address. */ | ||
985 | dev->dev_addr[0] = aa->s_node; | ||
986 | dev->addr_len = 1; | ||
987 | return 0; | ||
988 | |||
989 | case SIOCGIFADDR: | ||
990 | sa->sat_addr.s_net = aa->s_net; | ||
991 | sa->sat_addr.s_node = aa->s_node; | ||
992 | return 0; | ||
993 | |||
994 | default: | ||
995 | return -EOPNOTSUPP; | ||
996 | } | ||
997 | } | ||
998 | |||
999 | /* | ||
1000 | * The inverse routine to cops_open(). | ||
1001 | */ | ||
1002 | |||
1003 | static int cops_close(struct net_device *dev) | ||
1004 | { | ||
1005 | struct cops_local *lp = netdev_priv(dev); | ||
1006 | |||
1007 | /* If we were running polled, yank the timer. | ||
1008 | */ | ||
1009 | if(lp->board==TANGENT && dev->irq==0) | ||
1010 | del_timer(&cops_timer); | ||
1011 | |||
1012 | netif_stop_queue(dev); | ||
1013 | return 0; | ||
1014 | } | ||
1015 | |||
1016 | /* | ||
1017 | * Get the current statistics. | ||
1018 | * This may be called with the card open or closed. | ||
1019 | */ | ||
1020 | static struct net_device_stats *cops_get_stats(struct net_device *dev) | ||
1021 | { | ||
1022 | struct cops_local *lp = netdev_priv(dev); | ||
1023 | return &lp->stats; | ||
1024 | } | ||
1025 | |||
1026 | #ifdef MODULE | ||
1027 | static struct net_device *cops_dev; | ||
1028 | |||
1029 | MODULE_LICENSE("GPL"); | ||
1030 | module_param(io, int, 0); | ||
1031 | module_param(irq, int, 0); | ||
1032 | module_param(board_type, int, 0); | ||
1033 | |||
1034 | int init_module(void) | ||
1035 | { | ||
1036 | if (io == 0) | ||
1037 | printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n", | ||
1038 | cardname); | ||
1039 | cops_dev = cops_probe(-1); | ||
1040 | if (IS_ERR(cops_dev)) | ||
1041 | return PTR_ERR(cops_dev); | ||
1042 | return 0; | ||
1043 | } | ||
1044 | |||
1045 | void cleanup_module(void) | ||
1046 | { | ||
1047 | unregister_netdev(cops_dev); | ||
1048 | cleanup_card(cops_dev); | ||
1049 | free_netdev(cops_dev); | ||
1050 | } | ||
1051 | #endif /* MODULE */ | ||
1052 | |||
1053 | /* | ||
1054 | * Local variables: | ||
1055 | * compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -c cops.c" | ||
1056 | * c-basic-offset: 4 | ||
1057 | * c-file-offsets: ((substatement-open . 0)) | ||
1058 | * End: | ||
1059 | */ | ||
diff --git a/drivers/net/appletalk/cops.h b/drivers/net/appletalk/cops.h new file mode 100644 index 000000000000..c68ba9c2ef46 --- /dev/null +++ b/drivers/net/appletalk/cops.h | |||
@@ -0,0 +1,60 @@ | |||
1 | /* cops.h: LocalTalk driver for Linux. | ||
2 | * | ||
3 | * Authors: | ||
4 | * - Jay Schulist <jschlst@samba.org> | ||
5 | */ | ||
6 | |||
7 | #ifndef __LINUX_COPSLTALK_H | ||
8 | #define __LINUX_COPSLTALK_H | ||
9 | |||
10 | #ifdef __KERNEL__ | ||
11 | |||
12 | /* Max LLAP size we will accept. */ | ||
13 | #define MAX_LLAP_SIZE 603 | ||
14 | |||
15 | /* Tangent */ | ||
16 | #define TANG_CARD_STATUS 1 | ||
17 | #define TANG_CLEAR_INT 1 | ||
18 | #define TANG_RESET 3 | ||
19 | |||
20 | #define TANG_TX_READY 1 | ||
21 | #define TANG_RX_READY 2 | ||
22 | |||
23 | /* Dayna */ | ||
24 | #define DAYNA_CMD_DATA 0 | ||
25 | #define DAYNA_CLEAR_INT 1 | ||
26 | #define DAYNA_CARD_STATUS 2 | ||
27 | #define DAYNA_INT_CARD 3 | ||
28 | #define DAYNA_RESET 4 | ||
29 | |||
30 | #define DAYNA_RX_READY 0 | ||
31 | #define DAYNA_TX_READY 1 | ||
32 | #define DAYNA_RX_REQUEST 3 | ||
33 | |||
34 | /* Same on both card types */ | ||
35 | #define COPS_CLEAR_INT 1 | ||
36 | |||
37 | /* LAP response codes received from the cards. */ | ||
38 | #define LAP_INIT 1 /* Init cmd */ | ||
39 | #define LAP_INIT_RSP 2 /* Init response */ | ||
40 | #define LAP_WRITE 3 /* Write cmd */ | ||
41 | #define DATA_READ 4 /* Data read */ | ||
42 | #define LAP_RESPONSE 4 /* Received ALAP frame response */ | ||
43 | #define LAP_GETSTAT 5 /* Get LAP and HW status */ | ||
44 | #define LAP_RSPSTAT 6 /* Status response */ | ||
45 | |||
46 | #endif | ||
47 | |||
48 | /* | ||
49 | * Structure to hold the firmware information. | ||
50 | */ | ||
51 | struct ltfirmware | ||
52 | { | ||
53 | unsigned int length; | ||
54 | unsigned char * data; | ||
55 | }; | ||
56 | |||
57 | #define DAYNA 1 | ||
58 | #define TANGENT 2 | ||
59 | |||
60 | #endif | ||
diff --git a/drivers/net/appletalk/cops_ffdrv.h b/drivers/net/appletalk/cops_ffdrv.h new file mode 100644 index 000000000000..4131b4a7a65b --- /dev/null +++ b/drivers/net/appletalk/cops_ffdrv.h | |||
@@ -0,0 +1,533 @@ | |||
1 | |||
2 | /* | ||
3 | * The firmware this driver downloads into the Localtalk card is a | ||
4 | * separate program and is not GPL'd source code, even though the Linux | ||
5 | * side driver and the routine that loads this data into the card are. | ||
6 | * | ||
7 | * It is taken from the COPS SDK and is under the following license | ||
8 | * | ||
9 | * This material is licensed to you strictly for use in conjunction with | ||
10 | * the use of COPS LocalTalk adapters. | ||
11 | * There is no charge for this SDK. And no waranty express or implied | ||
12 | * about its fitness for any purpose. However, we will cheerefully | ||
13 | * refund every penny you paid for this SDK... | ||
14 | * Regards, | ||
15 | * | ||
16 | * Thomas F. Divine | ||
17 | * Chief Scientist | ||
18 | */ | ||
19 | |||
20 | |||
21 | /* cops_ffdrv.h: LocalTalk driver firmware dump for Linux. | ||
22 | * | ||
23 | * Authors: | ||
24 | * - Jay Schulist <jschlst@samba.org> | ||
25 | */ | ||
26 | |||
27 | #include <linux/config.h> | ||
28 | |||
29 | #ifdef CONFIG_COPS_DAYNA | ||
30 | |||
31 | unsigned char ffdrv_code[] = { | ||
32 | 58,3,0,50,228,149,33,255,255,34,226,149, | ||
33 | 249,17,40,152,33,202,154,183,237,82,77,68, | ||
34 | 11,107,98,19,54,0,237,176,175,50,80,0, | ||
35 | 62,128,237,71,62,32,237,57,51,62,12,237, | ||
36 | 57,50,237,57,54,62,6,237,57,52,62,12, | ||
37 | 237,57,49,33,107,137,34,32,128,33,83,130, | ||
38 | 34,40,128,33,86,130,34,42,128,33,112,130, | ||
39 | 34,36,128,33,211,130,34,38,128,62,0,237, | ||
40 | 57,16,33,63,148,34,34,128,237,94,205,15, | ||
41 | 130,251,205,168,145,24,141,67,111,112,121,114, | ||
42 | 105,103,104,116,32,40,67,41,32,49,57,56, | ||
43 | 56,32,45,32,68,97,121,110,97,32,67,111, | ||
44 | 109,109,117,110,105,99,97,116,105,111,110,115, | ||
45 | 32,32,32,65,108,108,32,114,105,103,104,116, | ||
46 | 115,32,114,101,115,101,114,118,101,100,46,32, | ||
47 | 32,40,68,40,68,7,16,8,34,7,22,6, | ||
48 | 16,5,12,4,8,3,6,140,0,16,39,128, | ||
49 | 0,4,96,10,224,6,0,7,126,2,64,11, | ||
50 | 118,12,6,13,0,14,193,15,0,5,96,3, | ||
51 | 192,1,64,9,8,62,9,211,66,62,192,211, | ||
52 | 66,62,100,61,32,253,6,28,33,205,129,14, | ||
53 | 66,237,163,194,253,129,6,28,33,205,129,14, | ||
54 | 64,237,163,194,9,130,201,62,47,50,71,152, | ||
55 | 62,47,211,68,58,203,129,237,57,20,58,204, | ||
56 | 129,237,57,21,33,77,152,54,132,205,233,129, | ||
57 | 58,228,149,254,209,40,6,56,4,62,0,24, | ||
58 | 2,219,96,33,233,149,119,230,62,33,232,149, | ||
59 | 119,213,33,8,152,17,7,0,25,119,19,25, | ||
60 | 119,209,201,251,237,77,245,197,213,229,221,229, | ||
61 | 205,233,129,62,1,50,106,137,205,158,139,221, | ||
62 | 225,225,209,193,241,251,237,77,245,197,213,219, | ||
63 | 72,237,56,16,230,46,237,57,16,237,56,12, | ||
64 | 58,72,152,183,32,26,6,20,17,128,2,237, | ||
65 | 56,46,187,32,35,237,56,47,186,32,29,219, | ||
66 | 72,230,1,32,3,5,32,232,175,50,72,152, | ||
67 | 229,221,229,62,1,50,106,137,205,158,139,221, | ||
68 | 225,225,24,25,62,1,50,72,152,58,201,129, | ||
69 | 237,57,12,58,202,129,237,57,13,237,56,16, | ||
70 | 246,17,237,57,16,209,193,241,251,237,77,245, | ||
71 | 197,229,213,221,229,237,56,16,230,17,237,57, | ||
72 | 16,237,56,20,58,34,152,246,16,246,8,211, | ||
73 | 68,62,6,61,32,253,58,34,152,246,8,211, | ||
74 | 68,58,203,129,237,57,20,58,204,129,237,57, | ||
75 | 21,237,56,16,246,34,237,57,16,221,225,209, | ||
76 | 225,193,241,251,237,77,33,2,0,57,126,230, | ||
77 | 3,237,100,1,40,2,246,128,230,130,245,62, | ||
78 | 5,211,64,241,211,64,201,229,213,243,237,56, | ||
79 | 16,230,46,237,57,16,237,56,12,251,70,35, | ||
80 | 35,126,254,175,202,77,133,254,129,202,15,133, | ||
81 | 230,128,194,191,132,43,58,44,152,119,33,76, | ||
82 | 152,119,35,62,132,119,120,254,255,40,4,58, | ||
83 | 49,152,119,219,72,43,43,112,17,3,0,237, | ||
84 | 56,52,230,248,237,57,52,219,72,230,1,194, | ||
85 | 141,131,209,225,237,56,52,246,6,237,57,52, | ||
86 | 62,1,55,251,201,62,3,211,66,62,192,211, | ||
87 | 66,62,48,211,66,0,0,219,66,230,1,40, | ||
88 | 4,219,67,24,240,205,203,135,58,75,152,254, | ||
89 | 255,202,128,132,58,49,152,254,161,250,207,131, | ||
90 | 58,34,152,211,68,62,10,211,66,62,128,211, | ||
91 | 66,62,11,211,66,62,6,211,66,24,0,62, | ||
92 | 14,211,66,62,33,211,66,62,1,211,66,62, | ||
93 | 64,211,66,62,3,211,66,62,209,211,66,62, | ||
94 | 100,71,219,66,230,1,32,6,5,32,247,195, | ||
95 | 248,132,219,67,71,58,44,152,184,194,248,132, | ||
96 | 62,100,71,219,66,230,1,32,6,5,32,247, | ||
97 | 195,248,132,219,67,62,100,71,219,66,230,1, | ||
98 | 32,6,5,32,247,195,248,132,219,67,254,133, | ||
99 | 32,7,62,0,50,74,152,24,17,254,173,32, | ||
100 | 7,62,1,50,74,152,24,6,254,141,194,248, | ||
101 | 132,71,209,225,58,49,152,254,132,32,10,62, | ||
102 | 50,205,2,134,205,144,135,24,27,254,140,32, | ||
103 | 15,62,110,205,2,134,62,141,184,32,5,205, | ||
104 | 144,135,24,8,62,10,205,2,134,205,8,134, | ||
105 | 62,1,50,106,137,205,158,139,237,56,52,246, | ||
106 | 6,237,57,52,175,183,251,201,62,20,135,237, | ||
107 | 57,20,175,237,57,21,237,56,16,246,2,237, | ||
108 | 57,16,237,56,20,95,237,56,21,123,254,10, | ||
109 | 48,244,237,56,16,230,17,237,57,16,209,225, | ||
110 | 205,144,135,62,1,50,106,137,205,158,139,237, | ||
111 | 56,52,246,6,237,57,52,175,183,251,201,209, | ||
112 | 225,243,219,72,230,1,40,13,62,10,211,66, | ||
113 | 0,0,219,66,230,192,202,226,132,237,56,52, | ||
114 | 246,6,237,57,52,62,1,55,251,201,205,203, | ||
115 | 135,62,1,50,106,137,205,158,139,237,56,52, | ||
116 | 246,6,237,57,52,183,251,201,209,225,62,1, | ||
117 | 50,106,137,205,158,139,237,56,52,246,6,237, | ||
118 | 57,52,62,2,55,251,201,209,225,243,219,72, | ||
119 | 230,1,202,213,132,62,10,211,66,0,0,219, | ||
120 | 66,230,192,194,213,132,229,62,1,50,106,137, | ||
121 | 42,40,152,205,65,143,225,17,3,0,205,111, | ||
122 | 136,62,6,211,66,58,44,152,211,66,237,56, | ||
123 | 52,246,6,237,57,52,183,251,201,209,197,237, | ||
124 | 56,52,230,248,237,57,52,219,72,230,1,32, | ||
125 | 15,193,225,237,56,52,246,6,237,57,52,62, | ||
126 | 1,55,251,201,14,23,58,37,152,254,0,40, | ||
127 | 14,14,2,254,1,32,5,62,140,119,24,3, | ||
128 | 62,132,119,43,43,197,205,203,135,193,62,1, | ||
129 | 211,66,62,64,211,66,62,3,211,66,62,193, | ||
130 | 211,66,62,100,203,39,71,219,66,230,1,32, | ||
131 | 6,5,32,247,195,229,133,33,238,151,219,67, | ||
132 | 71,58,44,152,184,194,229,133,119,62,100,71, | ||
133 | 219,66,230,1,32,6,5,32,247,195,229,133, | ||
134 | 219,67,35,119,13,32,234,193,225,62,1,50, | ||
135 | 106,137,205,158,139,237,56,52,246,6,237,57, | ||
136 | 52,175,183,251,201,33,234,151,35,35,62,255, | ||
137 | 119,193,225,62,1,50,106,137,205,158,139,237, | ||
138 | 56,52,246,6,237,57,52,175,251,201,243,61, | ||
139 | 32,253,251,201,62,3,211,66,62,192,211,66, | ||
140 | 58,49,152,254,140,32,19,197,229,213,17,181, | ||
141 | 129,33,185,129,1,2,0,237,176,209,225,193, | ||
142 | 24,27,229,213,33,187,129,58,49,152,230,15, | ||
143 | 87,30,2,237,92,25,17,181,129,126,18,19, | ||
144 | 35,126,18,209,225,58,34,152,246,8,211,68, | ||
145 | 58,49,152,254,165,40,14,254,164,40,10,62, | ||
146 | 10,211,66,62,224,211,66,24,25,58,74,152, | ||
147 | 254,0,40,10,62,10,211,66,62,160,211,66, | ||
148 | 24,8,62,10,211,66,62,128,211,66,62,11, | ||
149 | 211,66,62,6,211,66,205,147,143,62,5,211, | ||
150 | 66,62,224,211,66,62,5,211,66,62,96,211, | ||
151 | 66,62,5,61,32,253,62,5,211,66,62,224, | ||
152 | 211,66,62,14,61,32,253,62,5,211,66,62, | ||
153 | 233,211,66,62,128,211,66,58,181,129,61,32, | ||
154 | 253,62,1,211,66,62,192,211,66,1,254,19, | ||
155 | 237,56,46,187,32,6,13,32,247,195,226,134, | ||
156 | 62,192,211,66,0,0,219,66,203,119,40,250, | ||
157 | 219,66,203,87,40,250,243,237,56,16,230,17, | ||
158 | 237,57,16,237,56,20,251,62,5,211,66,62, | ||
159 | 224,211,66,58,182,129,61,32,253,229,33,181, | ||
160 | 129,58,183,129,203,63,119,35,58,184,129,119, | ||
161 | 225,62,10,211,66,62,224,211,66,62,11,211, | ||
162 | 66,62,118,211,66,62,47,211,68,62,5,211, | ||
163 | 66,62,233,211,66,58,181,129,61,32,253,62, | ||
164 | 5,211,66,62,224,211,66,58,182,129,61,32, | ||
165 | 253,62,5,211,66,62,96,211,66,201,229,213, | ||
166 | 58,50,152,230,15,87,30,2,237,92,33,187, | ||
167 | 129,25,17,181,129,126,18,35,19,126,18,209, | ||
168 | 225,58,71,152,246,8,211,68,58,50,152,254, | ||
169 | 165,40,14,254,164,40,10,62,10,211,66,62, | ||
170 | 224,211,66,24,8,62,10,211,66,62,128,211, | ||
171 | 66,62,11,211,66,62,6,211,66,195,248,135, | ||
172 | 62,3,211,66,62,192,211,66,197,229,213,17, | ||
173 | 181,129,33,183,129,1,2,0,237,176,209,225, | ||
174 | 193,62,47,211,68,62,10,211,66,62,224,211, | ||
175 | 66,62,11,211,66,62,118,211,66,62,1,211, | ||
176 | 66,62,0,211,66,205,147,143,195,16,136,62, | ||
177 | 3,211,66,62,192,211,66,197,229,213,17,181, | ||
178 | 129,33,183,129,1,2,0,237,176,209,225,193, | ||
179 | 62,47,211,68,62,10,211,66,62,224,211,66, | ||
180 | 62,11,211,66,62,118,211,66,205,147,143,62, | ||
181 | 5,211,66,62,224,211,66,62,5,211,66,62, | ||
182 | 96,211,66,62,5,61,32,253,62,5,211,66, | ||
183 | 62,224,211,66,62,14,61,32,253,62,5,211, | ||
184 | 66,62,233,211,66,62,128,211,66,58,181,129, | ||
185 | 61,32,253,62,1,211,66,62,192,211,66,1, | ||
186 | 254,19,237,56,46,187,32,6,13,32,247,195, | ||
187 | 88,136,62,192,211,66,0,0,219,66,203,119, | ||
188 | 40,250,219,66,203,87,40,250,62,5,211,66, | ||
189 | 62,224,211,66,58,182,129,61,32,253,62,5, | ||
190 | 211,66,62,96,211,66,201,197,14,67,6,0, | ||
191 | 62,3,211,66,62,192,211,66,62,48,211,66, | ||
192 | 0,0,219,66,230,1,40,4,219,67,24,240, | ||
193 | 62,5,211,66,62,233,211,66,62,128,211,66, | ||
194 | 58,181,129,61,32,253,237,163,29,62,192,211, | ||
195 | 66,219,66,230,4,40,250,237,163,29,32,245, | ||
196 | 219,66,230,4,40,250,62,255,71,219,66,230, | ||
197 | 4,40,3,5,32,247,219,66,230,4,40,250, | ||
198 | 62,5,211,66,62,224,211,66,58,182,129,61, | ||
199 | 32,253,62,5,211,66,62,96,211,66,58,71, | ||
200 | 152,254,1,202,18,137,62,16,211,66,62,56, | ||
201 | 211,66,62,14,211,66,62,33,211,66,62,1, | ||
202 | 211,66,62,248,211,66,237,56,48,246,153,230, | ||
203 | 207,237,57,48,62,3,211,66,62,221,211,66, | ||
204 | 193,201,58,71,152,211,68,62,10,211,66,62, | ||
205 | 128,211,66,62,11,211,66,62,6,211,66,62, | ||
206 | 6,211,66,58,44,152,211,66,62,16,211,66, | ||
207 | 62,56,211,66,62,48,211,66,0,0,62,14, | ||
208 | 211,66,62,33,211,66,62,1,211,66,62,248, | ||
209 | 211,66,237,56,48,246,145,246,8,230,207,237, | ||
210 | 57,48,62,3,211,66,62,221,211,66,193,201, | ||
211 | 44,3,1,0,70,69,1,245,197,213,229,175, | ||
212 | 50,72,152,237,56,16,230,46,237,57,16,237, | ||
213 | 56,12,62,1,211,66,0,0,219,66,95,230, | ||
214 | 160,32,3,195,20,139,123,230,96,194,72,139, | ||
215 | 62,48,211,66,62,1,211,66,62,64,211,66, | ||
216 | 237,91,40,152,205,207,143,25,43,55,237,82, | ||
217 | 218,70,139,34,42,152,98,107,58,44,152,190, | ||
218 | 194,210,138,35,35,62,130,190,194,200,137,62, | ||
219 | 1,50,48,152,62,175,190,202,82,139,62,132, | ||
220 | 190,32,44,50,50,152,62,47,50,71,152,229, | ||
221 | 175,50,106,137,42,40,152,205,65,143,225,54, | ||
222 | 133,43,70,58,44,152,119,43,112,17,3,0, | ||
223 | 62,10,205,2,134,205,111,136,195,158,138,62, | ||
224 | 140,190,32,19,50,50,152,58,233,149,230,4, | ||
225 | 202,222,138,62,1,50,71,152,195,219,137,126, | ||
226 | 254,160,250,185,138,254,166,242,185,138,50,50, | ||
227 | 152,43,126,35,229,213,33,234,149,95,22,0, | ||
228 | 25,126,254,132,40,18,254,140,40,14,58,50, | ||
229 | 152,230,15,87,126,31,21,242,65,138,56,2, | ||
230 | 175,119,58,50,152,230,15,87,58,233,149,230, | ||
231 | 62,31,21,242,85,138,218,98,138,209,225,195, | ||
232 | 20,139,58,50,152,33,100,137,230,15,95,22, | ||
233 | 0,25,126,50,71,152,209,225,58,50,152,254, | ||
234 | 164,250,135,138,58,73,152,254,0,40,4,54, | ||
235 | 173,24,2,54,133,43,70,58,44,152,119,43, | ||
236 | 112,17,3,0,205,70,135,175,50,106,137,205, | ||
237 | 208,139,58,199,129,237,57,12,58,200,129,237, | ||
238 | 57,13,237,56,16,246,17,237,57,16,225,209, | ||
239 | 193,241,251,237,77,62,129,190,194,227,138,54, | ||
240 | 130,43,70,58,44,152,119,43,112,17,3,0, | ||
241 | 205,144,135,195,20,139,35,35,126,254,132,194, | ||
242 | 227,138,175,50,106,137,205,158,139,24,42,58, | ||
243 | 201,154,254,1,40,7,62,1,50,106,137,24, | ||
244 | 237,58,106,137,254,1,202,222,138,62,128,166, | ||
245 | 194,222,138,221,229,221,33,67,152,205,127,142, | ||
246 | 205,109,144,221,225,225,209,193,241,251,237,77, | ||
247 | 58,106,137,254,1,202,44,139,58,50,152,254, | ||
248 | 164,250,44,139,58,73,152,238,1,50,73,152, | ||
249 | 221,229,221,33,51,152,205,127,142,221,225,62, | ||
250 | 1,50,106,137,205,158,139,195,13,139,24,208, | ||
251 | 24,206,24,204,230,64,40,3,195,20,139,195, | ||
252 | 20,139,43,126,33,8,152,119,35,58,44,152, | ||
253 | 119,43,237,91,35,152,205,203,135,205,158,139, | ||
254 | 195,13,139,175,50,78,152,62,3,211,66,62, | ||
255 | 192,211,66,201,197,33,4,0,57,126,35,102, | ||
256 | 111,62,1,50,106,137,219,72,205,141,139,193, | ||
257 | 201,62,1,50,78,152,34,40,152,54,0,35, | ||
258 | 35,54,0,195,163,139,58,78,152,183,200,229, | ||
259 | 33,181,129,58,183,129,119,35,58,184,129,119, | ||
260 | 225,62,47,211,68,62,14,211,66,62,193,211, | ||
261 | 66,62,10,211,66,62,224,211,66,62,11,211, | ||
262 | 66,62,118,211,66,195,3,140,58,78,152,183, | ||
263 | 200,58,71,152,211,68,254,69,40,4,254,70, | ||
264 | 32,17,58,73,152,254,0,40,10,62,10,211, | ||
265 | 66,62,160,211,66,24,8,62,10,211,66,62, | ||
266 | 128,211,66,62,11,211,66,62,6,211,66,62, | ||
267 | 6,211,66,58,44,152,211,66,62,16,211,66, | ||
268 | 62,56,211,66,62,48,211,66,0,0,219,66, | ||
269 | 230,1,40,4,219,67,24,240,62,14,211,66, | ||
270 | 62,33,211,66,42,40,152,205,65,143,62,1, | ||
271 | 211,66,62,248,211,66,237,56,48,246,145,246, | ||
272 | 8,230,207,237,57,48,62,3,211,66,62,221, | ||
273 | 211,66,201,62,16,211,66,62,56,211,66,62, | ||
274 | 48,211,66,0,0,219,66,230,1,40,4,219, | ||
275 | 67,24,240,62,14,211,66,62,33,211,66,62, | ||
276 | 1,211,66,62,248,211,66,237,56,48,246,153, | ||
277 | 230,207,237,57,48,62,3,211,66,62,221,211, | ||
278 | 66,201,229,213,33,234,149,95,22,0,25,126, | ||
279 | 254,132,40,4,254,140,32,2,175,119,123,209, | ||
280 | 225,201,6,8,14,0,31,48,1,12,16,250, | ||
281 | 121,201,33,4,0,57,94,35,86,33,2,0, | ||
282 | 57,126,35,102,111,221,229,34,89,152,237,83, | ||
283 | 91,152,221,33,63,152,205,127,142,58,81,152, | ||
284 | 50,82,152,58,80,152,135,50,80,152,205,162, | ||
285 | 140,254,3,56,16,58,81,152,135,60,230,15, | ||
286 | 50,81,152,175,50,80,152,24,23,58,79,152, | ||
287 | 205,162,140,254,3,48,13,58,81,152,203,63, | ||
288 | 50,81,152,62,255,50,79,152,58,81,152,50, | ||
289 | 82,152,58,79,152,135,50,79,152,62,32,50, | ||
290 | 83,152,50,84,152,237,56,16,230,17,237,57, | ||
291 | 16,219,72,62,192,50,93,152,62,93,50,94, | ||
292 | 152,58,93,152,61,50,93,152,32,9,58,94, | ||
293 | 152,61,50,94,152,40,44,62,170,237,57,20, | ||
294 | 175,237,57,21,237,56,16,246,2,237,57,16, | ||
295 | 219,72,230,1,202,29,141,237,56,20,71,237, | ||
296 | 56,21,120,254,10,48,237,237,56,16,230,17, | ||
297 | 237,57,16,243,62,14,211,66,62,65,211,66, | ||
298 | 251,58,39,152,23,23,60,50,39,152,71,58, | ||
299 | 82,152,160,230,15,40,22,71,14,10,219,66, | ||
300 | 230,16,202,186,141,219,72,230,1,202,186,141, | ||
301 | 13,32,239,16,235,42,89,152,237,91,91,152, | ||
302 | 205,47,131,48,7,61,202,186,141,195,227,141, | ||
303 | 221,225,33,0,0,201,221,33,55,152,205,127, | ||
304 | 142,58,84,152,61,50,84,152,40,19,58,82, | ||
305 | 152,246,1,50,82,152,58,79,152,246,1,50, | ||
306 | 79,152,195,29,141,221,225,33,1,0,201,221, | ||
307 | 33,59,152,205,127,142,58,80,152,246,1,50, | ||
308 | 80,152,58,82,152,135,246,1,50,82,152,58, | ||
309 | 83,152,61,50,83,152,194,29,141,221,225,33, | ||
310 | 2,0,201,221,229,33,0,0,57,17,4,0, | ||
311 | 25,126,50,44,152,230,128,50,85,152,58,85, | ||
312 | 152,183,40,6,221,33,88,2,24,4,221,33, | ||
313 | 150,0,58,44,152,183,40,53,60,40,50,60, | ||
314 | 40,47,61,61,33,86,152,119,35,119,35,54, | ||
315 | 129,175,50,48,152,221,43,221,229,225,124,181, | ||
316 | 40,42,33,86,152,17,3,0,205,189,140,17, | ||
317 | 232,3,27,123,178,32,251,58,48,152,183,40, | ||
318 | 224,58,44,152,71,62,7,128,230,127,71,58, | ||
319 | 85,152,176,50,44,152,24,162,221,225,201,183, | ||
320 | 221,52,0,192,221,52,1,192,221,52,2,192, | ||
321 | 221,52,3,192,55,201,245,62,1,211,100,241, | ||
322 | 201,245,62,1,211,96,241,201,33,2,0,57, | ||
323 | 126,35,102,111,237,56,48,230,175,237,57,48, | ||
324 | 62,48,237,57,49,125,237,57,32,124,237,57, | ||
325 | 33,62,0,237,57,34,62,88,237,57,35,62, | ||
326 | 0,237,57,36,237,57,37,33,128,2,125,237, | ||
327 | 57,38,124,237,57,39,237,56,48,246,97,230, | ||
328 | 207,237,57,48,62,0,237,57,0,62,0,211, | ||
329 | 96,211,100,201,33,2,0,57,126,35,102,111, | ||
330 | 237,56,48,230,175,237,57,48,62,12,237,57, | ||
331 | 49,62,76,237,57,32,62,0,237,57,33,237, | ||
332 | 57,34,125,237,57,35,124,237,57,36,62,0, | ||
333 | 237,57,37,33,128,2,125,237,57,38,124,237, | ||
334 | 57,39,237,56,48,246,97,230,207,237,57,48, | ||
335 | 62,1,211,96,201,33,2,0,57,126,35,102, | ||
336 | 111,229,237,56,48,230,87,237,57,48,125,237, | ||
337 | 57,40,124,237,57,41,62,0,237,57,42,62, | ||
338 | 67,237,57,43,62,0,237,57,44,58,106,137, | ||
339 | 254,1,32,5,33,6,0,24,3,33,128,2, | ||
340 | 125,237,57,46,124,237,57,47,237,56,50,230, | ||
341 | 252,246,2,237,57,50,225,201,33,4,0,57, | ||
342 | 94,35,86,33,2,0,57,126,35,102,111,237, | ||
343 | 56,48,230,87,237,57,48,125,237,57,40,124, | ||
344 | 237,57,41,62,0,237,57,42,62,67,237,57, | ||
345 | 43,62,0,237,57,44,123,237,57,46,122,237, | ||
346 | 57,47,237,56,50,230,244,246,0,237,57,50, | ||
347 | 237,56,48,246,145,230,207,237,57,48,201,213, | ||
348 | 237,56,46,95,237,56,47,87,237,56,46,111, | ||
349 | 237,56,47,103,183,237,82,32,235,33,128,2, | ||
350 | 183,237,82,209,201,213,237,56,38,95,237,56, | ||
351 | 39,87,237,56,38,111,237,56,39,103,183,237, | ||
352 | 82,32,235,33,128,2,183,237,82,209,201,245, | ||
353 | 197,1,52,0,237,120,230,253,237,121,193,241, | ||
354 | 201,245,197,1,52,0,237,120,246,2,237,121, | ||
355 | 193,241,201,33,2,0,57,126,35,102,111,126, | ||
356 | 35,110,103,201,33,0,0,34,102,152,34,96, | ||
357 | 152,34,98,152,33,202,154,34,104,152,237,91, | ||
358 | 104,152,42,226,149,183,237,82,17,0,255,25, | ||
359 | 34,100,152,203,124,40,6,33,0,125,34,100, | ||
360 | 152,42,104,152,35,35,35,229,205,120,139,193, | ||
361 | 201,205,186,149,229,42,40,152,35,35,35,229, | ||
362 | 205,39,144,193,124,230,3,103,221,117,254,221, | ||
363 | 116,255,237,91,42,152,35,35,35,183,237,82, | ||
364 | 32,12,17,5,0,42,42,152,205,171,149,242, | ||
365 | 169,144,42,40,152,229,205,120,139,193,195,198, | ||
366 | 149,237,91,42,152,42,98,152,25,34,98,152, | ||
367 | 19,19,19,42,102,152,25,34,102,152,237,91, | ||
368 | 100,152,33,158,253,25,237,91,102,152,205,171, | ||
369 | 149,242,214,144,33,0,0,34,102,152,62,1, | ||
370 | 50,95,152,205,225,144,195,198,149,58,95,152, | ||
371 | 183,200,237,91,96,152,42,102,152,205,171,149, | ||
372 | 242,5,145,237,91,102,152,33,98,2,25,237, | ||
373 | 91,96,152,205,171,149,250,37,145,237,91,96, | ||
374 | 152,42,102,152,183,237,82,32,7,42,98,152, | ||
375 | 125,180,40,13,237,91,102,152,42,96,152,205, | ||
376 | 171,149,242,58,145,237,91,104,152,42,102,152, | ||
377 | 25,35,35,35,229,205,120,139,193,175,50,95, | ||
378 | 152,201,195,107,139,205,206,149,250,255,243,205, | ||
379 | 225,144,251,58,230,149,183,194,198,149,17,1, | ||
380 | 0,42,98,152,205,171,149,250,198,149,62,1, | ||
381 | 50,230,149,237,91,96,152,42,104,152,25,221, | ||
382 | 117,252,221,116,253,237,91,104,152,42,96,152, | ||
383 | 25,35,35,35,221,117,254,221,116,255,35,35, | ||
384 | 35,229,205,39,144,124,230,3,103,35,35,35, | ||
385 | 221,117,250,221,116,251,235,221,110,252,221,102, | ||
386 | 253,115,35,114,35,54,4,62,1,211,100,211, | ||
387 | 84,195,198,149,33,0,0,34,102,152,34,96, | ||
388 | 152,34,98,152,33,202,154,34,104,152,237,91, | ||
389 | 104,152,42,226,149,183,237,82,17,0,255,25, | ||
390 | 34,100,152,33,109,152,54,0,33,107,152,229, | ||
391 | 205,240,142,193,62,47,50,34,152,62,132,50, | ||
392 | 49,152,205,241,145,205,61,145,58,39,152,60, | ||
393 | 50,39,152,24,241,205,206,149,251,255,33,109, | ||
394 | 152,126,183,202,198,149,110,221,117,251,33,109, | ||
395 | 152,54,0,221,126,251,254,1,40,28,254,3, | ||
396 | 40,101,254,4,202,190,147,254,5,202,147,147, | ||
397 | 254,8,40,87,33,107,152,229,205,240,142,195, | ||
398 | 198,149,58,201,154,183,32,21,33,111,152,126, | ||
399 | 50,229,149,205,52,144,33,110,152,110,38,0, | ||
400 | 229,205,11,142,193,237,91,96,152,42,104,152, | ||
401 | 25,221,117,254,221,116,255,35,35,54,2,17, | ||
402 | 2,0,43,43,115,35,114,58,44,152,35,35, | ||
403 | 119,58,228,149,35,119,62,1,211,100,211,84, | ||
404 | 62,1,50,201,154,24,169,205,153,142,58,231, | ||
405 | 149,183,40,250,175,50,231,149,33,110,152,126, | ||
406 | 254,255,40,91,58,233,149,230,63,183,40,83, | ||
407 | 94,22,0,33,234,149,25,126,183,40,13,33, | ||
408 | 110,152,94,33,234,150,25,126,254,3,32,36, | ||
409 | 205,81,148,125,180,33,110,152,94,22,0,40, | ||
410 | 17,33,234,149,25,54,0,33,107,152,229,205, | ||
411 | 240,142,193,195,198,149,33,234,150,25,54,0, | ||
412 | 33,110,152,94,22,0,33,234,149,25,126,50, | ||
413 | 49,152,254,132,32,37,62,47,50,34,152,42, | ||
414 | 107,152,229,33,110,152,229,205,174,140,193,193, | ||
415 | 125,180,33,110,152,94,22,0,33,234,150,202, | ||
416 | 117,147,25,52,195,120,147,58,49,152,254,140, | ||
417 | 32,7,62,1,50,34,152,24,210,62,32,50, | ||
418 | 106,152,24,19,58,49,152,95,58,106,152,163, | ||
419 | 183,58,106,152,32,11,203,63,50,106,152,58, | ||
420 | 106,152,183,32,231,254,2,40,51,254,4,40, | ||
421 | 38,254,8,40,26,254,16,40,13,254,32,32, | ||
422 | 158,62,165,50,49,152,62,69,24,190,62,164, | ||
423 | 50,49,152,62,70,24,181,62,163,50,49,152, | ||
424 | 175,24,173,62,162,50,49,152,62,1,24,164, | ||
425 | 62,161,50,49,152,62,3,24,155,25,54,0, | ||
426 | 221,126,251,254,8,40,7,58,230,149,183,202, | ||
427 | 32,146,33,107,152,229,205,240,142,193,211,84, | ||
428 | 195,198,149,237,91,96,152,42,104,152,25,221, | ||
429 | 117,254,221,116,255,35,35,54,6,17,2,0, | ||
430 | 43,43,115,35,114,58,228,149,35,35,119,58, | ||
431 | 233,149,35,119,205,146,142,195,32,146,237,91, | ||
432 | 96,152,42,104,152,25,229,205,160,142,193,58, | ||
433 | 231,149,183,40,250,175,50,231,149,243,237,91, | ||
434 | 96,152,42,104,152,25,221,117,254,221,116,255, | ||
435 | 78,35,70,221,113,252,221,112,253,89,80,42, | ||
436 | 98,152,183,237,82,34,98,152,203,124,40,19, | ||
437 | 33,0,0,34,98,152,34,102,152,34,96,152, | ||
438 | 62,1,50,95,152,24,40,221,94,252,221,86, | ||
439 | 253,19,19,19,42,96,152,25,34,96,152,237, | ||
440 | 91,100,152,33,158,253,25,237,91,96,152,205, | ||
441 | 171,149,242,55,148,33,0,0,34,96,152,175, | ||
442 | 50,230,149,251,195,32,146,245,62,1,50,231, | ||
443 | 149,62,16,237,57,0,211,80,241,251,237,77, | ||
444 | 201,205,186,149,229,229,33,0,0,34,37,152, | ||
445 | 33,110,152,126,50,234,151,58,44,152,33,235, | ||
446 | 151,119,221,54,253,0,221,54,254,0,195,230, | ||
447 | 148,33,236,151,54,175,33,3,0,229,33,234, | ||
448 | 151,229,205,174,140,193,193,33,236,151,126,254, | ||
449 | 255,40,74,33,245,151,110,221,117,255,33,249, | ||
450 | 151,126,221,166,255,221,119,255,33,253,151,126, | ||
451 | 221,166,255,221,119,255,58,232,149,95,221,126, | ||
452 | 255,163,221,119,255,183,40,15,230,191,33,110, | ||
453 | 152,94,22,0,33,234,149,25,119,24,12,33, | ||
454 | 110,152,94,22,0,33,234,149,25,54,132,33, | ||
455 | 0,0,195,198,149,221,110,253,221,102,254,35, | ||
456 | 221,117,253,221,116,254,17,32,0,221,110,253, | ||
457 | 221,102,254,205,171,149,250,117,148,58,233,149, | ||
458 | 203,87,40,84,33,1,0,34,37,152,221,54, | ||
459 | 253,0,221,54,254,0,24,53,33,236,151,54, | ||
460 | 175,33,3,0,229,33,234,151,229,205,174,140, | ||
461 | 193,193,33,236,151,126,254,255,40,14,33,110, | ||
462 | 152,94,22,0,33,234,149,25,54,140,24,159, | ||
463 | 221,110,253,221,102,254,35,221,117,253,221,116, | ||
464 | 254,17,32,0,221,110,253,221,102,254,205,171, | ||
465 | 149,250,12,149,33,2,0,34,37,152,221,54, | ||
466 | 253,0,221,54,254,0,24,54,33,236,151,54, | ||
467 | 175,33,3,0,229,33,234,151,229,205,174,140, | ||
468 | 193,193,33,236,151,126,254,255,40,15,33,110, | ||
469 | 152,94,22,0,33,234,149,25,54,132,195,211, | ||
470 | 148,221,110,253,221,102,254,35,221,117,253,221, | ||
471 | 116,254,17,32,0,221,110,253,221,102,254,205, | ||
472 | 171,149,250,96,149,33,1,0,195,198,149,124, | ||
473 | 170,250,179,149,237,82,201,124,230,128,237,82, | ||
474 | 60,201,225,253,229,221,229,221,33,0,0,221, | ||
475 | 57,233,221,249,221,225,253,225,201,233,225,253, | ||
476 | 229,221,229,221,33,0,0,221,57,94,35,86, | ||
477 | 35,235,57,249,235,233,0,0,0,0,0,0, | ||
478 | 62,0,0,0,0,0,0,0,0,0,0,0, | ||
479 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
480 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
481 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
482 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
483 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
484 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
485 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
486 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
487 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
488 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
489 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
490 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
491 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
492 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
493 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
494 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
495 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
496 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
497 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
498 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
499 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
500 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
501 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
502 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
503 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
504 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
505 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
506 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
507 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
508 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
509 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
510 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
511 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
512 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
513 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
514 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
515 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
516 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
517 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
518 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
519 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
520 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
521 | 175,0,0,0,0,0,0,0,0,0,0,0, | ||
522 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
523 | 0,0,0,0,0,0,133,1,0,0,0,63, | ||
524 | 255,255,255,255,0,0,0,63,0,0,0,0, | ||
525 | 0,0,0,0,0,0,0,24,0,0,0,0, | ||
526 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
527 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
528 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
529 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
530 | 0,0,0,0,0,0,0 | ||
531 | } ; | ||
532 | |||
533 | #endif | ||
diff --git a/drivers/net/appletalk/cops_ltdrv.h b/drivers/net/appletalk/cops_ltdrv.h new file mode 100644 index 000000000000..05de66dd9206 --- /dev/null +++ b/drivers/net/appletalk/cops_ltdrv.h | |||
@@ -0,0 +1,242 @@ | |||
1 | /* | ||
2 | * The firmware this driver downloads into the Localtalk card is a | ||
3 | * separate program and is not GPL'd source code, even though the Linux | ||
4 | * side driver and the routine that loads this data into the card are. | ||
5 | * | ||
6 | * It is taken from the COPS SDK and is under the following license | ||
7 | * | ||
8 | * This material is licensed to you strictly for use in conjunction with | ||
9 | * the use of COPS LocalTalk adapters. | ||
10 | * There is no charge for this SDK. And no waranty express or implied | ||
11 | * about its fitness for any purpose. However, we will cheerefully | ||
12 | * refund every penny you paid for this SDK... | ||
13 | * Regards, | ||
14 | * | ||
15 | * Thomas F. Divine | ||
16 | * Chief Scientist | ||
17 | */ | ||
18 | |||
19 | |||
20 | /* cops_ltdrv.h: LocalTalk driver firmware dump for Linux. | ||
21 | * | ||
22 | * Authors: | ||
23 | * - Jay Schulist <jschlst@samba.org> | ||
24 | */ | ||
25 | |||
26 | #include <linux/config.h> | ||
27 | |||
28 | #ifdef CONFIG_COPS_TANGENT | ||
29 | |||
30 | unsigned char ltdrv_code[] = { | ||
31 | 58,3,0,50,148,10,33,143,15,62,85,119, | ||
32 | 190,32,9,62,170,119,190,32,3,35,24,241, | ||
33 | 34,146,10,249,17,150,10,33,143,15,183,237, | ||
34 | 82,77,68,11,107,98,19,54,0,237,176,62, | ||
35 | 16,237,57,51,62,0,237,57,50,237,57,54, | ||
36 | 62,12,237,57,49,62,195,33,39,2,50,56, | ||
37 | 0,34,57,0,237,86,205,30,2,251,205,60, | ||
38 | 10,24,169,67,111,112,121,114,105,103,104,116, | ||
39 | 32,40,99,41,32,49,57,56,56,45,49,57, | ||
40 | 57,50,44,32,80,114,105,110,116,105,110,103, | ||
41 | 32,67,111,109,109,117,110,105,99,97,116,105, | ||
42 | 111,110,115,32,65,115,115,111,99,105,97,116, | ||
43 | 101,115,44,32,73,110,99,46,65,108,108,32, | ||
44 | 114,105,103,104,116,115,32,114,101,115,101,114, | ||
45 | 118,101,100,46,32,32,4,4,22,40,255,60, | ||
46 | 4,96,10,224,6,0,7,126,2,64,11,246, | ||
47 | 12,6,13,0,14,193,15,0,5,96,3,192, | ||
48 | 1,0,9,8,62,3,211,82,62,192,211,82, | ||
49 | 201,62,3,211,82,62,213,211,82,201,62,5, | ||
50 | 211,82,62,224,211,82,201,62,5,211,82,62, | ||
51 | 224,211,82,201,62,5,211,82,62,96,211,82, | ||
52 | 201,6,28,33,180,1,14,82,237,163,194,4, | ||
53 | 2,33,39,2,34,64,0,58,3,0,230,1, | ||
54 | 192,62,11,237,121,62,118,237,121,201,33,182, | ||
55 | 10,54,132,205,253,1,201,245,197,213,229,42, | ||
56 | 150,10,14,83,17,98,2,67,20,237,162,58, | ||
57 | 179,1,95,219,82,230,1,32,6,29,32,247, | ||
58 | 195,17,3,62,1,211,82,219,82,95,230,160, | ||
59 | 32,10,237,162,32,225,21,32,222,195,15,3, | ||
60 | 237,162,123,230,96,194,21,3,62,48,211,82, | ||
61 | 62,1,211,82,175,211,82,237,91,150,10,43, | ||
62 | 55,237,82,218,19,3,34,152,10,98,107,58, | ||
63 | 154,10,190,32,81,62,1,50,158,10,35,35, | ||
64 | 62,132,190,32,44,54,133,43,70,58,154,10, | ||
65 | 119,43,112,17,3,0,205,137,3,62,16,211, | ||
66 | 82,62,56,211,82,205,217,1,42,150,10,14, | ||
67 | 83,17,98,2,67,20,58,178,1,95,195,59, | ||
68 | 2,62,129,190,194,227,2,54,130,43,70,58, | ||
69 | 154,10,119,43,112,17,3,0,205,137,3,195, | ||
70 | 254,2,35,35,126,254,132,194,227,2,205,61, | ||
71 | 3,24,20,62,128,166,194,222,2,221,229,221, | ||
72 | 33,175,10,205,93,6,205,144,7,221,225,225, | ||
73 | 209,193,241,251,237,77,221,229,221,33,159,10, | ||
74 | 205,93,6,221,225,205,61,3,195,247,2,24, | ||
75 | 237,24,235,24,233,230,64,40,2,24,227,24, | ||
76 | 225,175,50,179,10,205,208,1,201,197,33,4, | ||
77 | 0,57,126,35,102,111,205,51,3,193,201,62, | ||
78 | 1,50,179,10,34,150,10,54,0,58,179,10, | ||
79 | 183,200,62,14,211,82,62,193,211,82,62,10, | ||
80 | 211,82,62,224,211,82,62,6,211,82,58,154, | ||
81 | 10,211,82,62,16,211,82,62,56,211,82,62, | ||
82 | 48,211,82,219,82,230,1,40,4,219,83,24, | ||
83 | 242,62,14,211,82,62,33,211,82,62,1,211, | ||
84 | 82,62,9,211,82,62,32,211,82,205,217,1, | ||
85 | 201,14,83,205,208,1,24,23,14,83,205,208, | ||
86 | 1,205,226,1,58,174,1,61,32,253,205,244, | ||
87 | 1,58,174,1,61,32,253,205,226,1,58,175, | ||
88 | 1,61,32,253,62,5,211,82,62,233,211,82, | ||
89 | 62,128,211,82,58,176,1,61,32,253,237,163, | ||
90 | 27,62,192,211,82,219,82,230,4,40,250,237, | ||
91 | 163,27,122,179,32,243,219,82,230,4,40,250, | ||
92 | 58,178,1,71,219,82,230,4,40,3,5,32, | ||
93 | 247,219,82,230,4,40,250,205,235,1,58,177, | ||
94 | 1,61,32,253,205,244,1,201,229,213,35,35, | ||
95 | 126,230,128,194,145,4,43,58,154,10,119,43, | ||
96 | 70,33,181,10,119,43,112,17,3,0,243,62, | ||
97 | 10,211,82,219,82,230,128,202,41,4,209,225, | ||
98 | 62,1,55,251,201,205,144,3,58,180,10,254, | ||
99 | 255,202,127,4,205,217,1,58,178,1,71,219, | ||
100 | 82,230,1,32,6,5,32,247,195,173,4,219, | ||
101 | 83,71,58,154,10,184,194,173,4,58,178,1, | ||
102 | 71,219,82,230,1,32,6,5,32,247,195,173, | ||
103 | 4,219,83,58,178,1,71,219,82,230,1,32, | ||
104 | 6,5,32,247,195,173,4,219,83,254,133,194, | ||
105 | 173,4,58,179,1,24,4,58,179,1,135,61, | ||
106 | 32,253,209,225,205,137,3,205,61,3,183,251, | ||
107 | 201,209,225,243,62,10,211,82,219,82,230,128, | ||
108 | 202,164,4,62,1,55,251,201,205,144,3,205, | ||
109 | 61,3,183,251,201,209,225,62,2,55,251,201, | ||
110 | 243,62,14,211,82,62,33,211,82,251,201,33, | ||
111 | 4,0,57,94,35,86,33,2,0,57,126,35, | ||
112 | 102,111,221,229,34,193,10,237,83,195,10,221, | ||
113 | 33,171,10,205,93,6,58,185,10,50,186,10, | ||
114 | 58,184,10,135,50,184,10,205,112,6,254,3, | ||
115 | 56,16,58,185,10,135,60,230,15,50,185,10, | ||
116 | 175,50,184,10,24,23,58,183,10,205,112,6, | ||
117 | 254,3,48,13,58,185,10,203,63,50,185,10, | ||
118 | 62,255,50,183,10,58,185,10,50,186,10,58, | ||
119 | 183,10,135,50,183,10,62,32,50,187,10,50, | ||
120 | 188,10,6,255,219,82,230,16,32,3,5,32, | ||
121 | 247,205,180,4,6,40,219,82,230,16,40,3, | ||
122 | 5,32,247,62,10,211,82,219,82,230,128,194, | ||
123 | 46,5,219,82,230,16,40,214,237,95,71,58, | ||
124 | 186,10,160,230,15,40,32,71,14,10,62,10, | ||
125 | 211,82,219,82,230,128,202,119,5,205,180,4, | ||
126 | 195,156,5,219,82,230,16,202,156,5,13,32, | ||
127 | 229,16,225,42,193,10,237,91,195,10,205,252, | ||
128 | 3,48,7,61,202,156,5,195,197,5,221,225, | ||
129 | 33,0,0,201,221,33,163,10,205,93,6,58, | ||
130 | 188,10,61,50,188,10,40,19,58,186,10,246, | ||
131 | 1,50,186,10,58,183,10,246,1,50,183,10, | ||
132 | 195,46,5,221,225,33,1,0,201,221,33,167, | ||
133 | 10,205,93,6,58,184,10,246,1,50,184,10, | ||
134 | 58,186,10,135,246,1,50,186,10,58,187,10, | ||
135 | 61,50,187,10,194,46,5,221,225,33,2,0, | ||
136 | 201,221,229,33,0,0,57,17,4,0,25,126, | ||
137 | 50,154,10,230,128,50,189,10,58,189,10,183, | ||
138 | 40,6,221,33,88,2,24,4,221,33,150,0, | ||
139 | 58,154,10,183,40,49,60,40,46,61,33,190, | ||
140 | 10,119,35,119,35,54,129,175,50,158,10,221, | ||
141 | 43,221,229,225,124,181,40,42,33,190,10,17, | ||
142 | 3,0,205,206,4,17,232,3,27,123,178,32, | ||
143 | 251,58,158,10,183,40,224,58,154,10,71,62, | ||
144 | 7,128,230,127,71,58,189,10,176,50,154,10, | ||
145 | 24,166,221,225,201,183,221,52,0,192,221,52, | ||
146 | 1,192,221,52,2,192,221,52,3,192,55,201, | ||
147 | 6,8,14,0,31,48,1,12,16,250,121,201, | ||
148 | 33,2,0,57,94,35,86,35,78,35,70,35, | ||
149 | 126,35,102,105,79,120,68,103,237,176,201,33, | ||
150 | 2,0,57,126,35,102,111,62,17,237,57,48, | ||
151 | 125,237,57,40,124,237,57,41,62,0,237,57, | ||
152 | 42,62,64,237,57,43,62,0,237,57,44,33, | ||
153 | 128,2,125,237,57,46,124,237,57,47,62,145, | ||
154 | 237,57,48,211,68,58,149,10,211,66,201,33, | ||
155 | 2,0,57,126,35,102,111,62,33,237,57,48, | ||
156 | 62,64,237,57,32,62,0,237,57,33,237,57, | ||
157 | 34,125,237,57,35,124,237,57,36,62,0,237, | ||
158 | 57,37,33,128,2,125,237,57,38,124,237,57, | ||
159 | 39,62,97,237,57,48,211,67,58,149,10,211, | ||
160 | 66,201,237,56,46,95,237,56,47,87,237,56, | ||
161 | 46,111,237,56,47,103,183,237,82,32,235,33, | ||
162 | 128,2,183,237,82,201,237,56,38,95,237,56, | ||
163 | 39,87,237,56,38,111,237,56,39,103,183,237, | ||
164 | 82,32,235,33,128,2,183,237,82,201,205,106, | ||
165 | 10,221,110,6,221,102,7,126,35,110,103,195, | ||
166 | 118,10,205,106,10,33,0,0,34,205,10,34, | ||
167 | 198,10,34,200,10,33,143,15,34,207,10,237, | ||
168 | 91,207,10,42,146,10,183,237,82,17,0,255, | ||
169 | 25,34,203,10,203,124,40,6,33,0,125,34, | ||
170 | 203,10,42,207,10,229,205,37,3,195,118,10, | ||
171 | 205,106,10,229,42,150,10,35,35,35,229,205, | ||
172 | 70,7,193,124,230,3,103,221,117,254,221,116, | ||
173 | 255,237,91,152,10,35,35,35,183,237,82,32, | ||
174 | 12,17,5,0,42,152,10,205,91,10,242,203, | ||
175 | 7,42,150,10,229,205,37,3,195,118,10,237, | ||
176 | 91,152,10,42,200,10,25,34,200,10,42,205, | ||
177 | 10,25,34,205,10,237,91,203,10,33,158,253, | ||
178 | 25,237,91,205,10,205,91,10,242,245,7,33, | ||
179 | 0,0,34,205,10,62,1,50,197,10,205,5, | ||
180 | 8,33,0,0,57,249,195,118,10,205,106,10, | ||
181 | 58,197,10,183,202,118,10,237,91,198,10,42, | ||
182 | 205,10,205,91,10,242,46,8,237,91,205,10, | ||
183 | 33,98,2,25,237,91,198,10,205,91,10,250, | ||
184 | 78,8,237,91,198,10,42,205,10,183,237,82, | ||
185 | 32,7,42,200,10,125,180,40,13,237,91,205, | ||
186 | 10,42,198,10,205,91,10,242,97,8,237,91, | ||
187 | 207,10,42,205,10,25,229,205,37,3,175,50, | ||
188 | 197,10,195,118,10,205,29,3,33,0,0,57, | ||
189 | 249,195,118,10,205,106,10,58,202,10,183,40, | ||
190 | 22,205,14,7,237,91,209,10,19,19,19,205, | ||
191 | 91,10,242,139,8,33,1,0,195,118,10,33, | ||
192 | 0,0,195,118,10,205,126,10,252,255,205,108, | ||
193 | 8,125,180,194,118,10,237,91,200,10,33,0, | ||
194 | 0,205,91,10,242,118,10,237,91,207,10,42, | ||
195 | 198,10,25,221,117,254,221,116,255,35,35,35, | ||
196 | 229,205,70,7,193,124,230,3,103,35,35,35, | ||
197 | 221,117,252,221,116,253,229,221,110,254,221,102, | ||
198 | 255,229,33,212,10,229,205,124,6,193,193,221, | ||
199 | 110,252,221,102,253,34,209,10,33,211,10,54, | ||
200 | 4,33,209,10,227,205,147,6,193,62,1,50, | ||
201 | 202,10,243,221,94,252,221,86,253,42,200,10, | ||
202 | 183,237,82,34,200,10,203,124,40,17,33,0, | ||
203 | 0,34,200,10,34,205,10,34,198,10,50,197, | ||
204 | 10,24,37,221,94,252,221,86,253,42,198,10, | ||
205 | 25,34,198,10,237,91,203,10,33,158,253,25, | ||
206 | 237,91,198,10,205,91,10,242,68,9,33,0, | ||
207 | 0,34,198,10,205,5,8,33,0,0,57,249, | ||
208 | 251,195,118,10,205,106,10,33,49,13,126,183, | ||
209 | 40,16,205,42,7,237,91,47,13,19,19,19, | ||
210 | 205,91,10,242,117,9,58,142,15,198,1,50, | ||
211 | 142,15,195,118,10,33,49,13,126,254,1,40, | ||
212 | 25,254,3,202,7,10,254,5,202,21,10,33, | ||
213 | 49,13,54,0,33,47,13,229,205,207,6,195, | ||
214 | 118,10,58,141,15,183,32,72,33,51,13,126, | ||
215 | 50,149,10,205,86,7,33,50,13,126,230,127, | ||
216 | 183,32,40,58,142,15,230,127,50,142,15,183, | ||
217 | 32,5,198,1,50,142,15,33,50,13,126,111, | ||
218 | 23,159,103,203,125,58,142,15,40,5,198,128, | ||
219 | 50,142,15,33,50,13,119,33,50,13,126,111, | ||
220 | 23,159,103,229,205,237,5,193,33,211,10,54, | ||
221 | 2,33,2,0,34,209,10,58,154,10,33,212, | ||
222 | 10,119,58,148,10,33,213,10,119,33,209,10, | ||
223 | 229,205,147,6,193,24,128,42,47,13,229,33, | ||
224 | 50,13,229,205,191,4,193,24,239,33,211,10, | ||
225 | 54,6,33,3,0,34,209,10,58,154,10,33, | ||
226 | 212,10,119,58,148,10,33,213,10,119,33,214, | ||
227 | 10,54,5,33,209,10,229,205,147,6,24,200, | ||
228 | 205,106,10,33,49,13,54,0,33,47,13,229, | ||
229 | 205,207,6,33,209,10,227,205,147,6,193,205, | ||
230 | 80,9,205,145,8,24,248,124,170,250,99,10, | ||
231 | 237,82,201,124,230,128,237,82,60,201,225,253, | ||
232 | 229,221,229,221,33,0,0,221,57,233,221,249, | ||
233 | 221,225,253,225,201,233,225,253,229,221,229,221, | ||
234 | 33,0,0,221,57,94,35,86,35,235,57,249, | ||
235 | 235,233,0,0,0,0,0,0,0,0,0,0, | ||
236 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
237 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
238 | 0,0,0,0,0,0,0,0,0,0,0,0, | ||
239 | 0,0,0,0,0 | ||
240 | } ; | ||
241 | |||
242 | #endif | ||
diff --git a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c new file mode 100644 index 000000000000..1a44a79ed064 --- /dev/null +++ b/drivers/net/appletalk/ipddp.c | |||
@@ -0,0 +1,317 @@ | |||
1 | /* | ||
2 | * ipddp.c: IP to Appletalk-IP Encapsulation driver for Linux | ||
3 | * Appletalk-IP to IP Decapsulation driver for Linux | ||
4 | * | ||
5 | * Authors: | ||
6 | * - DDP-IP Encap by: Bradford W. Johnson <johns393@maroon.tc.umn.edu> | ||
7 | * - DDP-IP Decap by: Jay Schulist <jschlst@samba.org> | ||
8 | * | ||
9 | * Derived from: | ||
10 | * - Almost all code already existed in net/appletalk/ddp.c I just | ||
11 | * moved/reorginized it into a driver file. Original IP-over-DDP code | ||
12 | * was done by Bradford W. Johnson <johns393@maroon.tc.umn.edu> | ||
13 | * - skeleton.c: A network driver outline for linux. | ||
14 | * Written 1993-94 by Donald Becker. | ||
15 | * - dummy.c: A dummy net driver. By Nick Holloway. | ||
16 | * - MacGate: A user space Daemon for Appletalk-IP Decap for | ||
17 | * Linux by Jay Schulist <jschlst@samba.org> | ||
18 | * | ||
19 | * Copyright 1993 United States Government as represented by the | ||
20 | * Director, National Security Agency. | ||
21 | * | ||
22 | * This software may be used and distributed according to the terms | ||
23 | * of the GNU General Public License, incorporated herein by reference. | ||
24 | */ | ||
25 | |||
26 | #include <linux/config.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/netdevice.h> | ||
31 | #include <linux/etherdevice.h> | ||
32 | #include <linux/ip.h> | ||
33 | #include <linux/atalk.h> | ||
34 | #include <linux/if_arp.h> | ||
35 | #include <net/route.h> | ||
36 | #include <asm/uaccess.h> | ||
37 | |||
38 | #include "ipddp.h" /* Our stuff */ | ||
39 | |||
40 | static const char version[] = KERN_INFO "ipddp.c:v0.01 8/28/97 Bradford W. Johnson <johns393@maroon.tc.umn.edu>\n"; | ||
41 | |||
42 | static struct ipddp_route *ipddp_route_list; | ||
43 | |||
44 | #ifdef CONFIG_IPDDP_ENCAP | ||
45 | static int ipddp_mode = IPDDP_ENCAP; | ||
46 | #else | ||
47 | static int ipddp_mode = IPDDP_DECAP; | ||
48 | #endif | ||
49 | |||
50 | /* Index to functions, as function prototypes. */ | ||
51 | static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev); | ||
52 | static struct net_device_stats *ipddp_get_stats(struct net_device *dev); | ||
53 | static int ipddp_create(struct ipddp_route *new_rt); | ||
54 | static int ipddp_delete(struct ipddp_route *rt); | ||
55 | static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt); | ||
56 | static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); | ||
57 | |||
58 | |||
59 | static struct net_device * __init ipddp_init(void) | ||
60 | { | ||
61 | static unsigned version_printed; | ||
62 | struct net_device *dev; | ||
63 | int err; | ||
64 | |||
65 | dev = alloc_etherdev(sizeof(struct net_device_stats)); | ||
66 | if (!dev) | ||
67 | return ERR_PTR(-ENOMEM); | ||
68 | |||
69 | SET_MODULE_OWNER(dev); | ||
70 | strcpy(dev->name, "ipddp%d"); | ||
71 | |||
72 | if (version_printed++ == 0) | ||
73 | printk(version); | ||
74 | |||
75 | /* Initalize the device structure. */ | ||
76 | dev->hard_start_xmit = ipddp_xmit; | ||
77 | dev->get_stats = ipddp_get_stats; | ||
78 | dev->do_ioctl = ipddp_ioctl; | ||
79 | |||
80 | dev->type = ARPHRD_IPDDP; /* IP over DDP tunnel */ | ||
81 | dev->mtu = 585; | ||
82 | dev->flags |= IFF_NOARP; | ||
83 | |||
84 | /* | ||
85 | * The worst case header we will need is currently a | ||
86 | * ethernet header (14 bytes) and a ddp header (sizeof ddpehdr+1) | ||
87 | * We send over SNAP so that takes another 8 bytes. | ||
88 | */ | ||
89 | dev->hard_header_len = 14+8+sizeof(struct ddpehdr)+1; | ||
90 | |||
91 | err = register_netdev(dev); | ||
92 | if (err) { | ||
93 | free_netdev(dev); | ||
94 | return ERR_PTR(err); | ||
95 | } | ||
96 | |||
97 | /* Let the user now what mode we are in */ | ||
98 | if(ipddp_mode == IPDDP_ENCAP) | ||
99 | printk("%s: Appletalk-IP Encap. mode by Bradford W. Johnson <johns393@maroon.tc.umn.edu>\n", | ||
100 | dev->name); | ||
101 | if(ipddp_mode == IPDDP_DECAP) | ||
102 | printk("%s: Appletalk-IP Decap. mode by Jay Schulist <jschlst@samba.org>\n", | ||
103 | dev->name); | ||
104 | |||
105 | return dev; | ||
106 | } | ||
107 | |||
108 | /* | ||
109 | * Get the current statistics. This may be called with the card open or closed. | ||
110 | */ | ||
111 | static struct net_device_stats *ipddp_get_stats(struct net_device *dev) | ||
112 | { | ||
113 | return dev->priv; | ||
114 | } | ||
115 | |||
116 | /* | ||
117 | * Transmit LLAP/ELAP frame using aarp_send_ddp. | ||
118 | */ | ||
119 | static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev) | ||
120 | { | ||
121 | u32 paddr = ((struct rtable*)skb->dst)->rt_gateway; | ||
122 | struct ddpehdr *ddp; | ||
123 | struct ipddp_route *rt; | ||
124 | struct atalk_addr *our_addr; | ||
125 | |||
126 | /* | ||
127 | * Find appropriate route to use, based only on IP number. | ||
128 | */ | ||
129 | for(rt = ipddp_route_list; rt != NULL; rt = rt->next) | ||
130 | { | ||
131 | if(rt->ip == paddr) | ||
132 | break; | ||
133 | } | ||
134 | if(rt == NULL) | ||
135 | return 0; | ||
136 | |||
137 | our_addr = atalk_find_dev_addr(rt->dev); | ||
138 | |||
139 | if(ipddp_mode == IPDDP_DECAP) | ||
140 | /* | ||
141 | * Pull off the excess room that should not be there. | ||
142 | * This is due to a hard-header problem. This is the | ||
143 | * quick fix for now though, till it breaks. | ||
144 | */ | ||
145 | skb_pull(skb, 35-(sizeof(struct ddpehdr)+1)); | ||
146 | |||
147 | /* Create the Extended DDP header */ | ||
148 | ddp = (struct ddpehdr *)skb->data; | ||
149 | ddp->deh_len = skb->len; | ||
150 | ddp->deh_hops = 1; | ||
151 | ddp->deh_pad = 0; | ||
152 | ddp->deh_sum = 0; | ||
153 | |||
154 | /* | ||
155 | * For Localtalk we need aarp_send_ddp to strip the | ||
156 | * long DDP header and place a shot DDP header on it. | ||
157 | */ | ||
158 | if(rt->dev->type == ARPHRD_LOCALTLK) | ||
159 | { | ||
160 | ddp->deh_dnet = 0; /* FIXME more hops?? */ | ||
161 | ddp->deh_snet = 0; | ||
162 | } | ||
163 | else | ||
164 | { | ||
165 | ddp->deh_dnet = rt->at.s_net; /* FIXME more hops?? */ | ||
166 | ddp->deh_snet = our_addr->s_net; | ||
167 | } | ||
168 | ddp->deh_dnode = rt->at.s_node; | ||
169 | ddp->deh_snode = our_addr->s_node; | ||
170 | ddp->deh_dport = 72; | ||
171 | ddp->deh_sport = 72; | ||
172 | |||
173 | *((__u8 *)(ddp+1)) = 22; /* ddp type = IP */ | ||
174 | *((__u16 *)ddp)=ntohs(*((__u16 *)ddp)); /* fix up length field */ | ||
175 | |||
176 | skb->protocol = htons(ETH_P_ATALK); /* Protocol has changed */ | ||
177 | |||
178 | ((struct net_device_stats *) dev->priv)->tx_packets++; | ||
179 | ((struct net_device_stats *) dev->priv)->tx_bytes+=skb->len; | ||
180 | |||
181 | if(aarp_send_ddp(rt->dev, skb, &rt->at, NULL) < 0) | ||
182 | dev_kfree_skb(skb); | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | /* | ||
188 | * Create a routing entry. We first verify that the | ||
189 | * record does not already exist. If it does we return -EEXIST | ||
190 | */ | ||
191 | static int ipddp_create(struct ipddp_route *new_rt) | ||
192 | { | ||
193 | struct ipddp_route *rt =(struct ipddp_route*) kmalloc(sizeof(*rt), GFP_KERNEL); | ||
194 | |||
195 | if (rt == NULL) | ||
196 | return -ENOMEM; | ||
197 | |||
198 | rt->ip = new_rt->ip; | ||
199 | rt->at = new_rt->at; | ||
200 | rt->next = NULL; | ||
201 | if ((rt->dev = atrtr_get_dev(&rt->at)) == NULL) { | ||
202 | kfree(rt); | ||
203 | return -ENETUNREACH; | ||
204 | } | ||
205 | |||
206 | if (ipddp_find_route(rt)) { | ||
207 | kfree(rt); | ||
208 | return -EEXIST; | ||
209 | } | ||
210 | |||
211 | rt->next = ipddp_route_list; | ||
212 | ipddp_route_list = rt; | ||
213 | |||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | /* | ||
218 | * Delete a route, we only delete a FULL match. | ||
219 | * If route does not exist we return -ENOENT. | ||
220 | */ | ||
221 | static int ipddp_delete(struct ipddp_route *rt) | ||
222 | { | ||
223 | struct ipddp_route **r = &ipddp_route_list; | ||
224 | struct ipddp_route *tmp; | ||
225 | |||
226 | while((tmp = *r) != NULL) | ||
227 | { | ||
228 | if(tmp->ip == rt->ip | ||
229 | && tmp->at.s_net == rt->at.s_net | ||
230 | && tmp->at.s_node == rt->at.s_node) | ||
231 | { | ||
232 | *r = tmp->next; | ||
233 | kfree(tmp); | ||
234 | return 0; | ||
235 | } | ||
236 | r = &tmp->next; | ||
237 | } | ||
238 | |||
239 | return (-ENOENT); | ||
240 | } | ||
241 | |||
242 | /* | ||
243 | * Find a routing entry, we only return a FULL match | ||
244 | */ | ||
245 | static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt) | ||
246 | { | ||
247 | struct ipddp_route *f; | ||
248 | |||
249 | for(f = ipddp_route_list; f != NULL; f = f->next) | ||
250 | { | ||
251 | if(f->ip == rt->ip | ||
252 | && f->at.s_net == rt->at.s_net | ||
253 | && f->at.s_node == rt->at.s_node) | ||
254 | return (f); | ||
255 | } | ||
256 | |||
257 | return (NULL); | ||
258 | } | ||
259 | |||
260 | static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | ||
261 | { | ||
262 | struct ipddp_route __user *rt = ifr->ifr_data; | ||
263 | struct ipddp_route rcp; | ||
264 | |||
265 | if(!capable(CAP_NET_ADMIN)) | ||
266 | return -EPERM; | ||
267 | |||
268 | if(copy_from_user(&rcp, rt, sizeof(rcp))) | ||
269 | return -EFAULT; | ||
270 | |||
271 | switch(cmd) | ||
272 | { | ||
273 | case SIOCADDIPDDPRT: | ||
274 | return (ipddp_create(&rcp)); | ||
275 | |||
276 | case SIOCFINDIPDDPRT: | ||
277 | if(copy_to_user(rt, ipddp_find_route(&rcp), sizeof(struct ipddp_route))) | ||
278 | return -EFAULT; | ||
279 | return 0; | ||
280 | |||
281 | case SIOCDELIPDDPRT: | ||
282 | return (ipddp_delete(&rcp)); | ||
283 | |||
284 | default: | ||
285 | return -EINVAL; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | static struct net_device *dev_ipddp; | ||
290 | |||
291 | MODULE_LICENSE("GPL"); | ||
292 | module_param(ipddp_mode, int, 0); | ||
293 | |||
294 | static int __init ipddp_init_module(void) | ||
295 | { | ||
296 | dev_ipddp = ipddp_init(); | ||
297 | if (IS_ERR(dev_ipddp)) | ||
298 | return PTR_ERR(dev_ipddp); | ||
299 | return 0; | ||
300 | } | ||
301 | |||
302 | static void __exit ipddp_cleanup_module(void) | ||
303 | { | ||
304 | struct ipddp_route *p; | ||
305 | |||
306 | unregister_netdev(dev_ipddp); | ||
307 | free_netdev(dev_ipddp); | ||
308 | |||
309 | while (ipddp_route_list) { | ||
310 | p = ipddp_route_list->next; | ||
311 | kfree(ipddp_route_list); | ||
312 | ipddp_route_list = p; | ||
313 | } | ||
314 | } | ||
315 | |||
316 | module_init(ipddp_init_module); | ||
317 | module_exit(ipddp_cleanup_module); | ||
diff --git a/drivers/net/appletalk/ipddp.h b/drivers/net/appletalk/ipddp.h new file mode 100644 index 000000000000..52072fb0c610 --- /dev/null +++ b/drivers/net/appletalk/ipddp.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * ipddp.h: Header for IP-over-DDP driver for Linux. | ||
3 | */ | ||
4 | |||
5 | #ifndef __LINUX_IPDDP_H | ||
6 | #define __LINUX_IPDDP_H | ||
7 | |||
8 | #ifdef __KERNEL__ | ||
9 | |||
10 | #define SIOCADDIPDDPRT (SIOCDEVPRIVATE) | ||
11 | #define SIOCDELIPDDPRT (SIOCDEVPRIVATE+1) | ||
12 | #define SIOCFINDIPDDPRT (SIOCDEVPRIVATE+2) | ||
13 | |||
14 | struct ipddp_route | ||
15 | { | ||
16 | struct net_device *dev; /* Carrier device */ | ||
17 | __u32 ip; /* IP address */ | ||
18 | struct atalk_addr at; /* Gateway appletalk address */ | ||
19 | int flags; | ||
20 | struct ipddp_route *next; | ||
21 | }; | ||
22 | |||
23 | #define IPDDP_ENCAP 1 | ||
24 | #define IPDDP_DECAP 2 | ||
25 | |||
26 | #endif /* __KERNEL__ */ | ||
27 | #endif /* __LINUX_IPDDP_H */ | ||
diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c new file mode 100644 index 000000000000..ad8e943231a1 --- /dev/null +++ b/drivers/net/appletalk/ltpc.c | |||
@@ -0,0 +1,1313 @@ | |||
1 | /*** ltpc.c -- a driver for the LocalTalk PC card. | ||
2 | * | ||
3 | * Copyright (c) 1995,1996 Bradford W. Johnson <johns393@maroon.tc.umn.edu> | ||
4 | * | ||
5 | * This software may be used and distributed according to the terms | ||
6 | * of the GNU General Public License, incorporated herein by reference. | ||
7 | * | ||
8 | * This is ALPHA code at best. It may not work for you. It may | ||
9 | * damage your equipment. It may damage your relations with other | ||
10 | * users of your network. Use it at your own risk! | ||
11 | * | ||
12 | * Based in part on: | ||
13 | * skeleton.c by Donald Becker | ||
14 | * dummy.c by Nick Holloway and Alan Cox | ||
15 | * loopback.c by Ross Biro, Fred van Kampen, Donald Becker | ||
16 | * the netatalk source code (UMICH) | ||
17 | * lots of work on the card... | ||
18 | * | ||
19 | * I do not have access to the (proprietary) SDK that goes with the card. | ||
20 | * If you do, I don't want to know about it, and you can probably write | ||
21 | * a better driver yourself anyway. This does mean that the pieces that | ||
22 | * talk to the card are guesswork on my part, so use at your own risk! | ||
23 | * | ||
24 | * This is my first try at writing Linux networking code, and is also | ||
25 | * guesswork. Again, use at your own risk! (Although on this part, I'd | ||
26 | * welcome suggestions) | ||
27 | * | ||
28 | * This is a loadable kernel module which seems to work at my site | ||
29 | * consisting of a 1.2.13 linux box running netatalk 1.3.3, and with | ||
30 | * the kernel support from 1.3.3b2 including patches routing.patch | ||
31 | * and ddp.disappears.from.chooser. In order to run it, you will need | ||
32 | * to patch ddp.c and aarp.c in the kernel, but only a little... | ||
33 | * | ||
34 | * I'm fairly confident that while this is arguably badly written, the | ||
35 | * problems that people experience will be "higher level", that is, with | ||
36 | * complications in the netatalk code. The driver itself doesn't do | ||
37 | * anything terribly complicated -- it pretends to be an ether device | ||
38 | * as far as netatalk is concerned, strips the DDP data out of the ether | ||
39 | * frame and builds a LLAP packet to send out the card. In the other | ||
40 | * direction, it receives LLAP frames from the card and builds a fake | ||
41 | * ether packet that it then tosses up to the networking code. You can | ||
42 | * argue (correctly) that this is an ugly way to do things, but it | ||
43 | * requires a minimal amount of fooling with the code in ddp.c and aarp.c. | ||
44 | * | ||
45 | * The card will do a lot more than is used here -- I *think* it has the | ||
46 | * layers up through ATP. Even if you knew how that part works (which I | ||
47 | * don't) it would be a big job to carve up the kernel ddp code to insert | ||
48 | * things at a higher level, and probably a bad idea... | ||
49 | * | ||
50 | * There are a number of other cards that do LocalTalk on the PC. If | ||
51 | * nobody finds any insurmountable (at the netatalk level) problems | ||
52 | * here, this driver should encourage people to put some work into the | ||
53 | * other cards (some of which I gather are still commercially available) | ||
54 | * and also to put hooks for LocalTalk into the official ddp code. | ||
55 | * | ||
56 | * I welcome comments and suggestions. This is my first try at Linux | ||
57 | * networking stuff, and there are probably lots of things that I did | ||
58 | * suboptimally. | ||
59 | * | ||
60 | ***/ | ||
61 | |||
62 | /*** | ||
63 | * | ||
64 | * $Log: ltpc.c,v $ | ||
65 | * Revision 1.1.2.1 2000/03/01 05:35:07 jgarzik | ||
66 | * at and tr cleanup | ||
67 | * | ||
68 | * Revision 1.8 1997/01/28 05:44:54 bradford | ||
69 | * Clean up for non-module a little. | ||
70 | * Hacked about a bit to clean things up - Alan Cox | ||
71 | * Probably broken it from the origina 1.8 | ||
72 | * | ||
73 | |||
74 | * 1998/11/09: David Huggins-Daines <dhd@debian.org> | ||
75 | * Cleaned up the initialization code to use the standard autoirq methods, | ||
76 | and to probe for things in the standard order of i/o, irq, dma. This | ||
77 | removes the "reset the reset" hack, because I couldn't figure out an | ||
78 | easy way to get the card to trigger an interrupt after it. | ||
79 | * Added support for passing configuration parameters on the kernel command | ||
80 | line and through insmod | ||
81 | * Changed the device name from "ltalk0" to "lt0", both to conform with the | ||
82 | other localtalk driver, and to clear up the inconsistency between the | ||
83 | module and the non-module versions of the driver :-) | ||
84 | * Added a bunch of comments (I was going to make some enums for the state | ||
85 | codes and the register offsets, but I'm still not sure exactly what their | ||
86 | semantics are) | ||
87 | * Don't poll anymore in interrupt-driven mode | ||
88 | * It seems to work as a module now (as of 2.1.127), but I don't think | ||
89 | I'm responsible for that... | ||
90 | |||
91 | * | ||
92 | * Revision 1.7 1996/12/12 03:42:33 bradford | ||
93 | * DMA alloc cribbed from 3c505.c. | ||
94 | * | ||
95 | * Revision 1.6 1996/12/12 03:18:58 bradford | ||
96 | * Added virt_to_bus; works in 2.1.13. | ||
97 | * | ||
98 | * Revision 1.5 1996/12/12 03:13:22 root | ||
99 | * xmitQel initialization -- think through better though. | ||
100 | * | ||
101 | * Revision 1.4 1996/06/18 14:55:55 root | ||
102 | * Change names to ltpc. Tabs. Took a shot at dma alloc, | ||
103 | * although more needs to be done eventually. | ||
104 | * | ||
105 | * Revision 1.3 1996/05/22 14:59:39 root | ||
106 | * Change dev->open, dev->close to track dummy.c in 1.99.(around 7) | ||
107 | * | ||
108 | * Revision 1.2 1996/05/22 14:58:24 root | ||
109 | * Change tabs mostly. | ||
110 | * | ||
111 | * Revision 1.1 1996/04/23 04:45:09 root | ||
112 | * Initial revision | ||
113 | * | ||
114 | * Revision 0.16 1996/03/05 15:59:56 root | ||
115 | * Change ARPHRD_LOCALTLK definition to the "real" one. | ||
116 | * | ||
117 | * Revision 0.15 1996/03/05 06:28:30 root | ||
118 | * Changes for kernel 1.3.70. Still need a few patches to kernel, but | ||
119 | * it's getting closer. | ||
120 | * | ||
121 | * Revision 0.14 1996/02/25 17:38:32 root | ||
122 | * More cleanups. Removed query to card on get_stats. | ||
123 | * | ||
124 | * Revision 0.13 1996/02/21 16:27:40 root | ||
125 | * Refix debug_print_skb. Fix mac.raw gotcha that appeared in 1.3.65. | ||
126 | * Clean up receive code a little. | ||
127 | * | ||
128 | * Revision 0.12 1996/02/19 16:34:53 root | ||
129 | * Fix debug_print_skb. Kludge outgoing snet to 0 when using startup | ||
130 | * range. Change debug to mask: 1 for verbose, 2 for higher level stuff | ||
131 | * including packet printing, 4 for lower level (card i/o) stuff. | ||
132 | * | ||
133 | * Revision 0.11 1996/02/12 15:53:38 root | ||
134 | * Added router sends (requires new aarp.c patch) | ||
135 | * | ||
136 | * Revision 0.10 1996/02/11 00:19:35 root | ||
137 | * Change source LTALK_LOGGING debug switch to insmod ... debug=2. | ||
138 | * | ||
139 | * Revision 0.9 1996/02/10 23:59:35 root | ||
140 | * Fixed those fixes for 1.2 -- DANGER! The at.h that comes with netatalk | ||
141 | * has a *different* definition of struct sockaddr_at than the Linux kernel | ||
142 | * does. This is an "insidious and invidious" bug... | ||
143 | * (Actually the preceding comment is false -- it's the atalk.h in the | ||
144 | * ancient atalk-0.06 that's the problem) | ||
145 | * | ||
146 | * Revision 0.8 1996/02/10 19:09:00 root | ||
147 | * Merge 1.3 changes. Tested OK under 1.3.60. | ||
148 | * | ||
149 | * Revision 0.7 1996/02/10 17:56:56 root | ||
150 | * Added debug=1 parameter on insmod for debugging prints. Tried | ||
151 | * to fix timer unload on rmmod, but I don't think that's the problem. | ||
152 | * | ||
153 | * Revision 0.6 1995/12/31 19:01:09 root | ||
154 | * Clean up rmmod, irq comments per feedback from Corin Anderson (Thanks Corey!) | ||
155 | * Clean up initial probing -- sometimes the card wakes up latched in reset. | ||
156 | * | ||
157 | * Revision 0.5 1995/12/22 06:03:44 root | ||
158 | * Added comments in front and cleaned up a bit. | ||
159 | * This version sent out to people. | ||
160 | * | ||
161 | * Revision 0.4 1995/12/18 03:46:44 root | ||
162 | * Return shortDDP to longDDP fake to 0/0. Added command structs. | ||
163 | * | ||
164 | ***/ | ||
165 | |||
166 | /* ltpc jumpers are: | ||
167 | * | ||
168 | * Interrupts -- set at most one. If none are set, the driver uses | ||
169 | * polled mode. Because the card was developed in the XT era, the | ||
170 | * original documentation refers to IRQ2. Since you'll be running | ||
171 | * this on an AT (or later) class machine, that really means IRQ9. | ||
172 | * | ||
173 | * SW1 IRQ 4 | ||
174 | * SW2 IRQ 3 | ||
175 | * SW3 IRQ 9 (2 in original card documentation only applies to XT) | ||
176 | * | ||
177 | * | ||
178 | * DMA -- choose DMA 1 or 3, and set both corresponding switches. | ||
179 | * | ||
180 | * SW4 DMA 3 | ||
181 | * SW5 DMA 1 | ||
182 | * SW6 DMA 3 | ||
183 | * SW7 DMA 1 | ||
184 | * | ||
185 | * | ||
186 | * I/O address -- choose one. | ||
187 | * | ||
188 | * SW8 220 / 240 | ||
189 | */ | ||
190 | |||
191 | /* To have some stuff logged, do | ||
192 | * insmod ltpc.o debug=1 | ||
193 | * | ||
194 | * For a whole bunch of stuff, use higher numbers. | ||
195 | * | ||
196 | * The default is 0, i.e. no messages except for the probe results. | ||
197 | */ | ||
198 | |||
199 | /* insmod-tweakable variables */ | ||
200 | static int debug; | ||
201 | #define DEBUG_VERBOSE 1 | ||
202 | #define DEBUG_UPPER 2 | ||
203 | #define DEBUG_LOWER 4 | ||
204 | |||
205 | static int io; | ||
206 | static int irq; | ||
207 | static int dma; | ||
208 | |||
209 | #include <linux/module.h> | ||
210 | #include <linux/kernel.h> | ||
211 | #include <linux/types.h> | ||
212 | #include <linux/fcntl.h> | ||
213 | #include <linux/interrupt.h> | ||
214 | #include <linux/ptrace.h> | ||
215 | #include <linux/ioport.h> | ||
216 | #include <linux/spinlock.h> | ||
217 | #include <linux/in.h> | ||
218 | #include <linux/slab.h> | ||
219 | #include <linux/string.h> | ||
220 | #include <linux/errno.h> | ||
221 | #include <linux/init.h> | ||
222 | #include <linux/netdevice.h> | ||
223 | #include <linux/etherdevice.h> | ||
224 | #include <linux/skbuff.h> | ||
225 | #include <linux/if_arp.h> | ||
226 | #include <linux/if_ltalk.h> | ||
227 | #include <linux/delay.h> | ||
228 | #include <linux/timer.h> | ||
229 | #include <linux/atalk.h> | ||
230 | #include <linux/bitops.h> | ||
231 | |||
232 | #include <asm/system.h> | ||
233 | #include <asm/dma.h> | ||
234 | #include <asm/io.h> | ||
235 | |||
236 | /* our stuff */ | ||
237 | #include "ltpc.h" | ||
238 | |||
239 | static DEFINE_SPINLOCK(txqueue_lock); | ||
240 | static DEFINE_SPINLOCK(mbox_lock); | ||
241 | |||
242 | /* function prototypes */ | ||
243 | static int do_read(struct net_device *dev, void *cbuf, int cbuflen, | ||
244 | void *dbuf, int dbuflen); | ||
245 | static int sendup_buffer (struct net_device *dev); | ||
246 | |||
247 | /* Dma Memory related stuff, cribbed directly from 3c505.c */ | ||
248 | |||
249 | static unsigned long dma_mem_alloc(int size) | ||
250 | { | ||
251 | int order = get_order(size); | ||
252 | |||
253 | return __get_dma_pages(GFP_KERNEL, order); | ||
254 | } | ||
255 | |||
256 | /* DMA data buffer, DMA command buffer */ | ||
257 | static unsigned char *ltdmabuf; | ||
258 | static unsigned char *ltdmacbuf; | ||
259 | |||
260 | /* private struct, holds our appletalk address */ | ||
261 | |||
262 | struct ltpc_private | ||
263 | { | ||
264 | struct net_device_stats stats; | ||
265 | struct atalk_addr my_addr; | ||
266 | }; | ||
267 | |||
268 | /* transmit queue element struct */ | ||
269 | |||
270 | struct xmitQel { | ||
271 | struct xmitQel *next; | ||
272 | /* command buffer */ | ||
273 | unsigned char *cbuf; | ||
274 | short cbuflen; | ||
275 | /* data buffer */ | ||
276 | unsigned char *dbuf; | ||
277 | short dbuflen; | ||
278 | unsigned char QWrite; /* read or write data */ | ||
279 | unsigned char mailbox; | ||
280 | }; | ||
281 | |||
282 | /* the transmit queue itself */ | ||
283 | |||
284 | static struct xmitQel *xmQhd, *xmQtl; | ||
285 | |||
286 | static void enQ(struct xmitQel *qel) | ||
287 | { | ||
288 | unsigned long flags; | ||
289 | qel->next = NULL; | ||
290 | |||
291 | spin_lock_irqsave(&txqueue_lock, flags); | ||
292 | if (xmQtl) { | ||
293 | xmQtl->next = qel; | ||
294 | } else { | ||
295 | xmQhd = qel; | ||
296 | } | ||
297 | xmQtl = qel; | ||
298 | spin_unlock_irqrestore(&txqueue_lock, flags); | ||
299 | |||
300 | if (debug & DEBUG_LOWER) | ||
301 | printk("enqueued a 0x%02x command\n",qel->cbuf[0]); | ||
302 | } | ||
303 | |||
304 | static struct xmitQel *deQ(void) | ||
305 | { | ||
306 | unsigned long flags; | ||
307 | int i; | ||
308 | struct xmitQel *qel=NULL; | ||
309 | |||
310 | spin_lock_irqsave(&txqueue_lock, flags); | ||
311 | if (xmQhd) { | ||
312 | qel = xmQhd; | ||
313 | xmQhd = qel->next; | ||
314 | if(!xmQhd) xmQtl = NULL; | ||
315 | } | ||
316 | spin_unlock_irqrestore(&txqueue_lock, flags); | ||
317 | |||
318 | if ((debug & DEBUG_LOWER) && qel) { | ||
319 | int n; | ||
320 | printk(KERN_DEBUG "ltpc: dequeued command "); | ||
321 | n = qel->cbuflen; | ||
322 | if (n>100) n=100; | ||
323 | for(i=0;i<n;i++) printk("%02x ",qel->cbuf[i]); | ||
324 | printk("\n"); | ||
325 | } | ||
326 | |||
327 | return qel; | ||
328 | } | ||
329 | |||
330 | /* and... the queue elements we'll be using */ | ||
331 | static struct xmitQel qels[16]; | ||
332 | |||
333 | /* and their corresponding mailboxes */ | ||
334 | static unsigned char mailbox[16]; | ||
335 | static unsigned char mboxinuse[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; | ||
336 | |||
337 | static int wait_timeout(struct net_device *dev, int c) | ||
338 | { | ||
339 | /* returns true if it stayed c */ | ||
340 | /* this uses base+6, but it's ok */ | ||
341 | int i; | ||
342 | |||
343 | /* twenty second or so total */ | ||
344 | |||
345 | for(i=0;i<200000;i++) { | ||
346 | if ( c != inb_p(dev->base_addr+6) ) return 0; | ||
347 | udelay(100); | ||
348 | } | ||
349 | return 1; /* timed out */ | ||
350 | } | ||
351 | |||
352 | /* get the first free mailbox */ | ||
353 | |||
354 | static int getmbox(void) | ||
355 | { | ||
356 | unsigned long flags; | ||
357 | int i; | ||
358 | |||
359 | spin_lock_irqsave(&mbox_lock, flags); | ||
360 | for(i=1;i<16;i++) if(!mboxinuse[i]) { | ||
361 | mboxinuse[i]=1; | ||
362 | spin_unlock_irqrestore(&mbox_lock, flags); | ||
363 | return i; | ||
364 | } | ||
365 | spin_unlock_irqrestore(&mbox_lock, flags); | ||
366 | return 0; | ||
367 | } | ||
368 | |||
369 | /* read a command from the card */ | ||
370 | static void handlefc(struct net_device *dev) | ||
371 | { | ||
372 | /* called *only* from idle, non-reentrant */ | ||
373 | int dma = dev->dma; | ||
374 | int base = dev->base_addr; | ||
375 | unsigned long flags; | ||
376 | |||
377 | |||
378 | flags=claim_dma_lock(); | ||
379 | disable_dma(dma); | ||
380 | clear_dma_ff(dma); | ||
381 | set_dma_mode(dma,DMA_MODE_READ); | ||
382 | set_dma_addr(dma,virt_to_bus(ltdmacbuf)); | ||
383 | set_dma_count(dma,50); | ||
384 | enable_dma(dma); | ||
385 | release_dma_lock(flags); | ||
386 | |||
387 | inb_p(base+3); | ||
388 | inb_p(base+2); | ||
389 | |||
390 | if ( wait_timeout(dev,0xfc) ) printk("timed out in handlefc\n"); | ||
391 | } | ||
392 | |||
393 | /* read data from the card */ | ||
394 | static void handlefd(struct net_device *dev) | ||
395 | { | ||
396 | int dma = dev->dma; | ||
397 | int base = dev->base_addr; | ||
398 | unsigned long flags; | ||
399 | |||
400 | flags=claim_dma_lock(); | ||
401 | disable_dma(dma); | ||
402 | clear_dma_ff(dma); | ||
403 | set_dma_mode(dma,DMA_MODE_READ); | ||
404 | set_dma_addr(dma,virt_to_bus(ltdmabuf)); | ||
405 | set_dma_count(dma,800); | ||
406 | enable_dma(dma); | ||
407 | release_dma_lock(flags); | ||
408 | |||
409 | inb_p(base+3); | ||
410 | inb_p(base+2); | ||
411 | |||
412 | if ( wait_timeout(dev,0xfd) ) printk("timed out in handlefd\n"); | ||
413 | sendup_buffer(dev); | ||
414 | } | ||
415 | |||
416 | static void handlewrite(struct net_device *dev) | ||
417 | { | ||
418 | /* called *only* from idle, non-reentrant */ | ||
419 | /* on entry, 0xfb and ltdmabuf holds data */ | ||
420 | int dma = dev->dma; | ||
421 | int base = dev->base_addr; | ||
422 | unsigned long flags; | ||
423 | |||
424 | flags=claim_dma_lock(); | ||
425 | disable_dma(dma); | ||
426 | clear_dma_ff(dma); | ||
427 | set_dma_mode(dma,DMA_MODE_WRITE); | ||
428 | set_dma_addr(dma,virt_to_bus(ltdmabuf)); | ||
429 | set_dma_count(dma,800); | ||
430 | enable_dma(dma); | ||
431 | release_dma_lock(flags); | ||
432 | |||
433 | inb_p(base+3); | ||
434 | inb_p(base+2); | ||
435 | |||
436 | if ( wait_timeout(dev,0xfb) ) { | ||
437 | flags=claim_dma_lock(); | ||
438 | printk("timed out in handlewrite, dma res %d\n", | ||
439 | get_dma_residue(dev->dma) ); | ||
440 | release_dma_lock(flags); | ||
441 | } | ||
442 | } | ||
443 | |||
444 | static void handleread(struct net_device *dev) | ||
445 | { | ||
446 | /* on entry, 0xfb */ | ||
447 | /* on exit, ltdmabuf holds data */ | ||
448 | int dma = dev->dma; | ||
449 | int base = dev->base_addr; | ||
450 | unsigned long flags; | ||
451 | |||
452 | |||
453 | flags=claim_dma_lock(); | ||
454 | disable_dma(dma); | ||
455 | clear_dma_ff(dma); | ||
456 | set_dma_mode(dma,DMA_MODE_READ); | ||
457 | set_dma_addr(dma,virt_to_bus(ltdmabuf)); | ||
458 | set_dma_count(dma,800); | ||
459 | enable_dma(dma); | ||
460 | release_dma_lock(flags); | ||
461 | |||
462 | inb_p(base+3); | ||
463 | inb_p(base+2); | ||
464 | if ( wait_timeout(dev,0xfb) ) printk("timed out in handleread\n"); | ||
465 | } | ||
466 | |||
467 | static void handlecommand(struct net_device *dev) | ||
468 | { | ||
469 | /* on entry, 0xfa and ltdmacbuf holds command */ | ||
470 | int dma = dev->dma; | ||
471 | int base = dev->base_addr; | ||
472 | unsigned long flags; | ||
473 | |||
474 | flags=claim_dma_lock(); | ||
475 | disable_dma(dma); | ||
476 | clear_dma_ff(dma); | ||
477 | set_dma_mode(dma,DMA_MODE_WRITE); | ||
478 | set_dma_addr(dma,virt_to_bus(ltdmacbuf)); | ||
479 | set_dma_count(dma,50); | ||
480 | enable_dma(dma); | ||
481 | release_dma_lock(flags); | ||
482 | inb_p(base+3); | ||
483 | inb_p(base+2); | ||
484 | if ( wait_timeout(dev,0xfa) ) printk("timed out in handlecommand\n"); | ||
485 | } | ||
486 | |||
487 | /* ready made command for getting the result from the card */ | ||
488 | static unsigned char rescbuf[2] = {LT_GETRESULT,0}; | ||
489 | static unsigned char resdbuf[2]; | ||
490 | |||
491 | static int QInIdle; | ||
492 | |||
493 | /* idle expects to be called with the IRQ line high -- either because of | ||
494 | * an interrupt, or because the line is tri-stated | ||
495 | */ | ||
496 | |||
497 | static void idle(struct net_device *dev) | ||
498 | { | ||
499 | unsigned long flags; | ||
500 | int state; | ||
501 | /* FIXME This is initialized to shut the warning up, but I need to | ||
502 | * think this through again. | ||
503 | */ | ||
504 | struct xmitQel *q = NULL; | ||
505 | int oops; | ||
506 | int i; | ||
507 | int base = dev->base_addr; | ||
508 | |||
509 | spin_lock_irqsave(&txqueue_lock, flags); | ||
510 | if(QInIdle) { | ||
511 | spin_unlock_irqrestore(&txqueue_lock, flags); | ||
512 | return; | ||
513 | } | ||
514 | QInIdle = 1; | ||
515 | spin_unlock_irqrestore(&txqueue_lock, flags); | ||
516 | |||
517 | /* this tri-states the IRQ line */ | ||
518 | (void) inb_p(base+6); | ||
519 | |||
520 | oops = 100; | ||
521 | |||
522 | loop: | ||
523 | if (0>oops--) { | ||
524 | printk("idle: looped too many times\n"); | ||
525 | goto done; | ||
526 | } | ||
527 | |||
528 | state = inb_p(base+6); | ||
529 | if (state != inb_p(base+6)) goto loop; | ||
530 | |||
531 | switch(state) { | ||
532 | case 0xfc: | ||
533 | /* incoming command */ | ||
534 | if (debug & DEBUG_LOWER) printk("idle: fc\n"); | ||
535 | handlefc(dev); | ||
536 | break; | ||
537 | case 0xfd: | ||
538 | /* incoming data */ | ||
539 | if(debug & DEBUG_LOWER) printk("idle: fd\n"); | ||
540 | handlefd(dev); | ||
541 | break; | ||
542 | case 0xf9: | ||
543 | /* result ready */ | ||
544 | if (debug & DEBUG_LOWER) printk("idle: f9\n"); | ||
545 | if(!mboxinuse[0]) { | ||
546 | mboxinuse[0] = 1; | ||
547 | qels[0].cbuf = rescbuf; | ||
548 | qels[0].cbuflen = 2; | ||
549 | qels[0].dbuf = resdbuf; | ||
550 | qels[0].dbuflen = 2; | ||
551 | qels[0].QWrite = 0; | ||
552 | qels[0].mailbox = 0; | ||
553 | enQ(&qels[0]); | ||
554 | } | ||
555 | inb_p(dev->base_addr+1); | ||
556 | inb_p(dev->base_addr+0); | ||
557 | if( wait_timeout(dev,0xf9) ) | ||
558 | printk("timed out idle f9\n"); | ||
559 | break; | ||
560 | case 0xf8: | ||
561 | /* ?? */ | ||
562 | if (xmQhd) { | ||
563 | inb_p(dev->base_addr+1); | ||
564 | inb_p(dev->base_addr+0); | ||
565 | if(wait_timeout(dev,0xf8) ) | ||
566 | printk("timed out idle f8\n"); | ||
567 | } else { | ||
568 | goto done; | ||
569 | } | ||
570 | break; | ||
571 | case 0xfa: | ||
572 | /* waiting for command */ | ||
573 | if(debug & DEBUG_LOWER) printk("idle: fa\n"); | ||
574 | if (xmQhd) { | ||
575 | q=deQ(); | ||
576 | memcpy(ltdmacbuf,q->cbuf,q->cbuflen); | ||
577 | ltdmacbuf[1] = q->mailbox; | ||
578 | if (debug>1) { | ||
579 | int n; | ||
580 | printk("ltpc: sent command "); | ||
581 | n = q->cbuflen; | ||
582 | if (n>100) n=100; | ||
583 | for(i=0;i<n;i++) | ||
584 | printk("%02x ",ltdmacbuf[i]); | ||
585 | printk("\n"); | ||
586 | } | ||
587 | handlecommand(dev); | ||
588 | if(0xfa==inb_p(base+6)) { | ||
589 | /* we timed out, so return */ | ||
590 | goto done; | ||
591 | } | ||
592 | } else { | ||
593 | /* we don't seem to have a command */ | ||
594 | if (!mboxinuse[0]) { | ||
595 | mboxinuse[0] = 1; | ||
596 | qels[0].cbuf = rescbuf; | ||
597 | qels[0].cbuflen = 2; | ||
598 | qels[0].dbuf = resdbuf; | ||
599 | qels[0].dbuflen = 2; | ||
600 | qels[0].QWrite = 0; | ||
601 | qels[0].mailbox = 0; | ||
602 | enQ(&qels[0]); | ||
603 | } else { | ||
604 | printk("trouble: response command already queued\n"); | ||
605 | goto done; | ||
606 | } | ||
607 | } | ||
608 | break; | ||
609 | case 0Xfb: | ||
610 | /* data transfer ready */ | ||
611 | if(debug & DEBUG_LOWER) printk("idle: fb\n"); | ||
612 | if(q->QWrite) { | ||
613 | memcpy(ltdmabuf,q->dbuf,q->dbuflen); | ||
614 | handlewrite(dev); | ||
615 | } else { | ||
616 | handleread(dev); | ||
617 | /* non-zero mailbox numbers are for | ||
618 | commmands, 0 is for GETRESULT | ||
619 | requests */ | ||
620 | if(q->mailbox) { | ||
621 | memcpy(q->dbuf,ltdmabuf,q->dbuflen); | ||
622 | } else { | ||
623 | /* this was a result */ | ||
624 | mailbox[ 0x0f & ltdmabuf[0] ] = ltdmabuf[1]; | ||
625 | mboxinuse[0]=0; | ||
626 | } | ||
627 | } | ||
628 | break; | ||
629 | } | ||
630 | goto loop; | ||
631 | |||
632 | done: | ||
633 | QInIdle=0; | ||
634 | |||
635 | /* now set the interrupts back as appropriate */ | ||
636 | /* the first read takes it out of tri-state (but still high) */ | ||
637 | /* the second resets it */ | ||
638 | /* note that after this point, any read of base+6 will | ||
639 | trigger an interrupt */ | ||
640 | |||
641 | if (dev->irq) { | ||
642 | inb_p(base+7); | ||
643 | inb_p(base+7); | ||
644 | } | ||
645 | return; | ||
646 | } | ||
647 | |||
648 | |||
649 | static int do_write(struct net_device *dev, void *cbuf, int cbuflen, | ||
650 | void *dbuf, int dbuflen) | ||
651 | { | ||
652 | |||
653 | int i = getmbox(); | ||
654 | int ret; | ||
655 | |||
656 | if(i) { | ||
657 | qels[i].cbuf = (unsigned char *) cbuf; | ||
658 | qels[i].cbuflen = cbuflen; | ||
659 | qels[i].dbuf = (unsigned char *) dbuf; | ||
660 | qels[i].dbuflen = dbuflen; | ||
661 | qels[i].QWrite = 1; | ||
662 | qels[i].mailbox = i; /* this should be initted rather */ | ||
663 | enQ(&qels[i]); | ||
664 | idle(dev); | ||
665 | ret = mailbox[i]; | ||
666 | mboxinuse[i]=0; | ||
667 | return ret; | ||
668 | } | ||
669 | printk("ltpc: could not allocate mbox\n"); | ||
670 | return -1; | ||
671 | } | ||
672 | |||
673 | static int do_read(struct net_device *dev, void *cbuf, int cbuflen, | ||
674 | void *dbuf, int dbuflen) | ||
675 | { | ||
676 | |||
677 | int i = getmbox(); | ||
678 | int ret; | ||
679 | |||
680 | if(i) { | ||
681 | qels[i].cbuf = (unsigned char *) cbuf; | ||
682 | qels[i].cbuflen = cbuflen; | ||
683 | qels[i].dbuf = (unsigned char *) dbuf; | ||
684 | qels[i].dbuflen = dbuflen; | ||
685 | qels[i].QWrite = 0; | ||
686 | qels[i].mailbox = i; /* this should be initted rather */ | ||
687 | enQ(&qels[i]); | ||
688 | idle(dev); | ||
689 | ret = mailbox[i]; | ||
690 | mboxinuse[i]=0; | ||
691 | return ret; | ||
692 | } | ||
693 | printk("ltpc: could not allocate mbox\n"); | ||
694 | return -1; | ||
695 | } | ||
696 | |||
697 | /* end of idle handlers -- what should be seen is do_read, do_write */ | ||
698 | |||
699 | static struct timer_list ltpc_timer; | ||
700 | |||
701 | static int ltpc_xmit(struct sk_buff *skb, struct net_device *dev); | ||
702 | static struct net_device_stats *ltpc_get_stats(struct net_device *dev); | ||
703 | |||
704 | static int read_30 ( struct net_device *dev) | ||
705 | { | ||
706 | lt_command c; | ||
707 | c.getflags.command = LT_GETFLAGS; | ||
708 | return do_read(dev, &c, sizeof(c.getflags),&c,0); | ||
709 | } | ||
710 | |||
711 | static int set_30 (struct net_device *dev,int x) | ||
712 | { | ||
713 | lt_command c; | ||
714 | c.setflags.command = LT_SETFLAGS; | ||
715 | c.setflags.flags = x; | ||
716 | return do_write(dev, &c, sizeof(c.setflags),&c,0); | ||
717 | } | ||
718 | |||
719 | /* LLAP to DDP translation */ | ||
720 | |||
721 | static int sendup_buffer (struct net_device *dev) | ||
722 | { | ||
723 | /* on entry, command is in ltdmacbuf, data in ltdmabuf */ | ||
724 | /* called from idle, non-reentrant */ | ||
725 | |||
726 | int dnode, snode, llaptype, len; | ||
727 | int sklen; | ||
728 | struct sk_buff *skb; | ||
729 | struct net_device_stats *stats = &((struct ltpc_private *)dev->priv)->stats; | ||
730 | struct lt_rcvlap *ltc = (struct lt_rcvlap *) ltdmacbuf; | ||
731 | |||
732 | if (ltc->command != LT_RCVLAP) { | ||
733 | printk("unknown command 0x%02x from ltpc card\n",ltc->command); | ||
734 | return(-1); | ||
735 | } | ||
736 | dnode = ltc->dnode; | ||
737 | snode = ltc->snode; | ||
738 | llaptype = ltc->laptype; | ||
739 | len = ltc->length; | ||
740 | |||
741 | sklen = len; | ||
742 | if (llaptype == 1) | ||
743 | sklen += 8; /* correct for short ddp */ | ||
744 | if(sklen > 800) { | ||
745 | printk(KERN_INFO "%s: nonsense length in ltpc command 0x14: 0x%08x\n", | ||
746 | dev->name,sklen); | ||
747 | return -1; | ||
748 | } | ||
749 | |||
750 | if ( (llaptype==0) || (llaptype>2) ) { | ||
751 | printk(KERN_INFO "%s: unknown LLAP type: %d\n",dev->name,llaptype); | ||
752 | return -1; | ||
753 | } | ||
754 | |||
755 | |||
756 | skb = dev_alloc_skb(3+sklen); | ||
757 | if (skb == NULL) | ||
758 | { | ||
759 | printk("%s: dropping packet due to memory squeeze.\n", | ||
760 | dev->name); | ||
761 | return -1; | ||
762 | } | ||
763 | skb->dev = dev; | ||
764 | |||
765 | if (sklen > len) | ||
766 | skb_reserve(skb,8); | ||
767 | skb_put(skb,len+3); | ||
768 | skb->protocol = htons(ETH_P_LOCALTALK); | ||
769 | /* add LLAP header */ | ||
770 | skb->data[0] = dnode; | ||
771 | skb->data[1] = snode; | ||
772 | skb->data[2] = llaptype; | ||
773 | skb->mac.raw = skb->data; /* save pointer to llap header */ | ||
774 | skb_pull(skb,3); | ||
775 | |||
776 | /* copy ddp(s,e)hdr + contents */ | ||
777 | memcpy(skb->data,(void*)ltdmabuf,len); | ||
778 | |||
779 | skb->h.raw = skb->data; | ||
780 | |||
781 | stats->rx_packets++; | ||
782 | stats->rx_bytes+=skb->len; | ||
783 | |||
784 | /* toss it onwards */ | ||
785 | netif_rx(skb); | ||
786 | dev->last_rx = jiffies; | ||
787 | return 0; | ||
788 | } | ||
789 | |||
790 | /* the handler for the board interrupt */ | ||
791 | |||
792 | static irqreturn_t | ||
793 | ltpc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr) | ||
794 | { | ||
795 | struct net_device *dev = dev_id; | ||
796 | |||
797 | if (dev==NULL) { | ||
798 | printk("ltpc_interrupt: unknown device.\n"); | ||
799 | return IRQ_NONE; | ||
800 | } | ||
801 | |||
802 | inb_p(dev->base_addr+6); /* disable further interrupts from board */ | ||
803 | |||
804 | idle(dev); /* handle whatever is coming in */ | ||
805 | |||
806 | /* idle re-enables interrupts from board */ | ||
807 | |||
808 | return IRQ_HANDLED; | ||
809 | } | ||
810 | |||
811 | /*** | ||
812 | * | ||
813 | * The ioctls that the driver responds to are: | ||
814 | * | ||
815 | * SIOCSIFADDR -- do probe using the passed node hint. | ||
816 | * SIOCGIFADDR -- return net, node. | ||
817 | * | ||
818 | * some of this stuff should be done elsewhere. | ||
819 | * | ||
820 | ***/ | ||
821 | |||
822 | static int ltpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | ||
823 | { | ||
824 | struct sockaddr_at *sa = (struct sockaddr_at *) &ifr->ifr_addr; | ||
825 | /* we'll keep the localtalk node address in dev->pa_addr */ | ||
826 | struct atalk_addr *aa = &((struct ltpc_private *)dev->priv)->my_addr; | ||
827 | struct lt_init c; | ||
828 | int ltflags; | ||
829 | |||
830 | if(debug & DEBUG_VERBOSE) printk("ltpc_ioctl called\n"); | ||
831 | |||
832 | switch(cmd) { | ||
833 | case SIOCSIFADDR: | ||
834 | |||
835 | aa->s_net = sa->sat_addr.s_net; | ||
836 | |||
837 | /* this does the probe and returns the node addr */ | ||
838 | c.command = LT_INIT; | ||
839 | c.hint = sa->sat_addr.s_node; | ||
840 | |||
841 | aa->s_node = do_read(dev,&c,sizeof(c),&c,0); | ||
842 | |||
843 | /* get all llap frames raw */ | ||
844 | ltflags = read_30(dev); | ||
845 | ltflags |= LT_FLAG_ALLLAP; | ||
846 | set_30 (dev,ltflags); | ||
847 | |||
848 | dev->broadcast[0] = 0xFF; | ||
849 | dev->dev_addr[0] = aa->s_node; | ||
850 | |||
851 | dev->addr_len=1; | ||
852 | |||
853 | return 0; | ||
854 | |||
855 | case SIOCGIFADDR: | ||
856 | |||
857 | sa->sat_addr.s_net = aa->s_net; | ||
858 | sa->sat_addr.s_node = aa->s_node; | ||
859 | |||
860 | return 0; | ||
861 | |||
862 | default: | ||
863 | return -EINVAL; | ||
864 | } | ||
865 | } | ||
866 | |||
867 | static void set_multicast_list(struct net_device *dev) | ||
868 | { | ||
869 | /* This needs to be present to keep netatalk happy. */ | ||
870 | /* Actually netatalk needs fixing! */ | ||
871 | } | ||
872 | |||
873 | static int ltpc_hard_header (struct sk_buff *skb, struct net_device *dev, | ||
874 | unsigned short type, void *daddr, void *saddr, unsigned len) | ||
875 | { | ||
876 | if(debug & DEBUG_VERBOSE) | ||
877 | printk("ltpc_hard_header called for device %s\n", | ||
878 | dev->name); | ||
879 | return 0; | ||
880 | } | ||
881 | |||
882 | static int ltpc_poll_counter; | ||
883 | |||
884 | static void ltpc_poll(unsigned long l) | ||
885 | { | ||
886 | struct net_device *dev = (struct net_device *) l; | ||
887 | |||
888 | del_timer(<pc_timer); | ||
889 | |||
890 | if(debug & DEBUG_VERBOSE) { | ||
891 | if (!ltpc_poll_counter) { | ||
892 | ltpc_poll_counter = 50; | ||
893 | printk("ltpc poll is alive\n"); | ||
894 | } | ||
895 | ltpc_poll_counter--; | ||
896 | } | ||
897 | |||
898 | if (!dev) | ||
899 | return; /* we've been downed */ | ||
900 | |||
901 | /* poll 20 times per second */ | ||
902 | idle(dev); | ||
903 | ltpc_timer.expires = jiffies + HZ/20; | ||
904 | |||
905 | add_timer(<pc_timer); | ||
906 | } | ||
907 | |||
908 | /* DDP to LLAP translation */ | ||
909 | |||
910 | static int ltpc_xmit(struct sk_buff *skb, struct net_device *dev) | ||
911 | { | ||
912 | /* in kernel 1.3.xx, on entry skb->data points to ddp header, | ||
913 | * and skb->len is the length of the ddp data + ddp header | ||
914 | */ | ||
915 | |||
916 | struct net_device_stats *stats = &((struct ltpc_private *)dev->priv)->stats; | ||
917 | |||
918 | int i; | ||
919 | struct lt_sendlap cbuf; | ||
920 | |||
921 | cbuf.command = LT_SENDLAP; | ||
922 | cbuf.dnode = skb->data[0]; | ||
923 | cbuf.laptype = skb->data[2]; | ||
924 | skb_pull(skb,3); /* skip past LLAP header */ | ||
925 | cbuf.length = skb->len; /* this is host order */ | ||
926 | skb->h.raw=skb->data; | ||
927 | |||
928 | if(debug & DEBUG_UPPER) { | ||
929 | printk("command "); | ||
930 | for(i=0;i<6;i++) | ||
931 | printk("%02x ",((unsigned char *)&cbuf)[i]); | ||
932 | printk("\n"); | ||
933 | } | ||
934 | |||
935 | do_write(dev,&cbuf,sizeof(cbuf),skb->h.raw,skb->len); | ||
936 | |||
937 | if(debug & DEBUG_UPPER) { | ||
938 | printk("sent %d ddp bytes\n",skb->len); | ||
939 | for(i=0;i<skb->len;i++) printk("%02x ",skb->h.raw[i]); | ||
940 | printk("\n"); | ||
941 | } | ||
942 | |||
943 | stats->tx_packets++; | ||
944 | stats->tx_bytes+=skb->len; | ||
945 | |||
946 | dev_kfree_skb(skb); | ||
947 | return 0; | ||
948 | } | ||
949 | |||
950 | static struct net_device_stats *ltpc_get_stats(struct net_device *dev) | ||
951 | { | ||
952 | struct net_device_stats *stats = &((struct ltpc_private *) dev->priv)->stats; | ||
953 | return stats; | ||
954 | } | ||
955 | |||
956 | /* initialization stuff */ | ||
957 | |||
958 | static int __init ltpc_probe_dma(int base, int dma) | ||
959 | { | ||
960 | int want = (dma == 3) ? 2 : (dma == 1) ? 1 : 3; | ||
961 | unsigned long timeout; | ||
962 | unsigned long f; | ||
963 | |||
964 | if (want & 1) { | ||
965 | if (request_dma(1,"ltpc")) { | ||
966 | want &= ~1; | ||
967 | } else { | ||
968 | f=claim_dma_lock(); | ||
969 | disable_dma(1); | ||
970 | clear_dma_ff(1); | ||
971 | set_dma_mode(1,DMA_MODE_WRITE); | ||
972 | set_dma_addr(1,virt_to_bus(ltdmabuf)); | ||
973 | set_dma_count(1,sizeof(struct lt_mem)); | ||
974 | enable_dma(1); | ||
975 | release_dma_lock(f); | ||
976 | } | ||
977 | } | ||
978 | if (want & 2) { | ||
979 | if (request_dma(3,"ltpc")) { | ||
980 | want &= ~2; | ||
981 | } else { | ||
982 | f=claim_dma_lock(); | ||
983 | disable_dma(3); | ||
984 | clear_dma_ff(3); | ||
985 | set_dma_mode(3,DMA_MODE_WRITE); | ||
986 | set_dma_addr(3,virt_to_bus(ltdmabuf)); | ||
987 | set_dma_count(3,sizeof(struct lt_mem)); | ||
988 | enable_dma(3); | ||
989 | release_dma_lock(f); | ||
990 | } | ||
991 | } | ||
992 | /* set up request */ | ||
993 | |||
994 | /* FIXME -- do timings better! */ | ||
995 | |||
996 | ltdmabuf[0] = LT_READMEM; | ||
997 | ltdmabuf[1] = 1; /* mailbox */ | ||
998 | ltdmabuf[2] = 0; ltdmabuf[3] = 0; /* address */ | ||
999 | ltdmabuf[4] = 0; ltdmabuf[5] = 1; /* read 0x0100 bytes */ | ||
1000 | ltdmabuf[6] = 0; /* dunno if this is necessary */ | ||
1001 | |||
1002 | inb_p(io+1); | ||
1003 | inb_p(io+0); | ||
1004 | timeout = jiffies+100*HZ/100; | ||
1005 | while(time_before(jiffies, timeout)) { | ||
1006 | if ( 0xfa == inb_p(io+6) ) break; | ||
1007 | } | ||
1008 | |||
1009 | inb_p(io+3); | ||
1010 | inb_p(io+2); | ||
1011 | while(time_before(jiffies, timeout)) { | ||
1012 | if ( 0xfb == inb_p(io+6) ) break; | ||
1013 | } | ||
1014 | |||
1015 | /* release the other dma channel (if we opened both of them) */ | ||
1016 | |||
1017 | if ((want & 2) && (get_dma_residue(3)==sizeof(struct lt_mem))) { | ||
1018 | want &= ~2; | ||
1019 | free_dma(3); | ||
1020 | } | ||
1021 | |||
1022 | if ((want & 1) && (get_dma_residue(1)==sizeof(struct lt_mem))) { | ||
1023 | want &= ~1; | ||
1024 | free_dma(1); | ||
1025 | } | ||
1026 | |||
1027 | if (!want) | ||
1028 | return 0; | ||
1029 | |||
1030 | return (want & 2) ? 3 : 1; | ||
1031 | } | ||
1032 | |||
1033 | struct net_device * __init ltpc_probe(void) | ||
1034 | { | ||
1035 | struct net_device *dev; | ||
1036 | int err = -ENOMEM; | ||
1037 | int x=0,y=0; | ||
1038 | int autoirq; | ||
1039 | unsigned long f; | ||
1040 | unsigned long timeout; | ||
1041 | |||
1042 | dev = alloc_netdev(sizeof(struct ltpc_private), "lt%d", ltalk_setup); | ||
1043 | if (!dev) | ||
1044 | goto out; | ||
1045 | |||
1046 | SET_MODULE_OWNER(dev); | ||
1047 | |||
1048 | /* probe for the I/O port address */ | ||
1049 | |||
1050 | if (io != 0x240 && request_region(0x220,8,"ltpc")) { | ||
1051 | x = inb_p(0x220+6); | ||
1052 | if ( (x!=0xff) && (x>=0xf0) ) { | ||
1053 | io = 0x220; | ||
1054 | goto got_port; | ||
1055 | } | ||
1056 | release_region(0x220,8); | ||
1057 | } | ||
1058 | if (io != 0x220 && request_region(0x240,8,"ltpc")) { | ||
1059 | y = inb_p(0x240+6); | ||
1060 | if ( (y!=0xff) && (y>=0xf0) ){ | ||
1061 | io = 0x240; | ||
1062 | goto got_port; | ||
1063 | } | ||
1064 | release_region(0x240,8); | ||
1065 | } | ||
1066 | |||
1067 | /* give up in despair */ | ||
1068 | printk(KERN_ERR "LocalTalk card not found; 220 = %02x, 240 = %02x.\n", x,y); | ||
1069 | err = -ENODEV; | ||
1070 | goto out1; | ||
1071 | |||
1072 | got_port: | ||
1073 | /* probe for the IRQ line */ | ||
1074 | if (irq < 2) { | ||
1075 | unsigned long irq_mask; | ||
1076 | |||
1077 | irq_mask = probe_irq_on(); | ||
1078 | /* reset the interrupt line */ | ||
1079 | inb_p(io+7); | ||
1080 | inb_p(io+7); | ||
1081 | /* trigger an interrupt (I hope) */ | ||
1082 | inb_p(io+6); | ||
1083 | mdelay(2); | ||
1084 | autoirq = probe_irq_off(irq_mask); | ||
1085 | |||
1086 | if (autoirq == 0) { | ||
1087 | printk(KERN_ERR "ltpc: probe at %#x failed to detect IRQ line.\n", io); | ||
1088 | } else { | ||
1089 | irq = autoirq; | ||
1090 | } | ||
1091 | } | ||
1092 | |||
1093 | /* allocate a DMA buffer */ | ||
1094 | ltdmabuf = (unsigned char *) dma_mem_alloc(1000); | ||
1095 | if (!ltdmabuf) { | ||
1096 | printk(KERN_ERR "ltpc: mem alloc failed\n"); | ||
1097 | err = -ENOMEM; | ||
1098 | goto out2; | ||
1099 | } | ||
1100 | |||
1101 | ltdmacbuf = <dmabuf[800]; | ||
1102 | |||
1103 | if(debug & DEBUG_VERBOSE) { | ||
1104 | printk("ltdmabuf pointer %08lx\n",(unsigned long) ltdmabuf); | ||
1105 | } | ||
1106 | |||
1107 | /* reset the card */ | ||
1108 | |||
1109 | inb_p(io+1); | ||
1110 | inb_p(io+3); | ||
1111 | |||
1112 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
1113 | schedule_timeout(2*HZ/100); | ||
1114 | |||
1115 | inb_p(io+0); | ||
1116 | inb_p(io+2); | ||
1117 | inb_p(io+7); /* clear reset */ | ||
1118 | inb_p(io+4); | ||
1119 | inb_p(io+5); | ||
1120 | inb_p(io+5); /* enable dma */ | ||
1121 | inb_p(io+6); /* tri-state interrupt line */ | ||
1122 | |||
1123 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
1124 | schedule_timeout(HZ); | ||
1125 | |||
1126 | /* now, figure out which dma channel we're using, unless it's | ||
1127 | already been specified */ | ||
1128 | /* well, 0 is a legal DMA channel, but the LTPC card doesn't | ||
1129 | use it... */ | ||
1130 | dma = ltpc_probe_dma(io, dma); | ||
1131 | if (!dma) { /* no dma channel */ | ||
1132 | printk(KERN_ERR "No DMA channel found on ltpc card.\n"); | ||
1133 | err = -ENODEV; | ||
1134 | goto out3; | ||
1135 | } | ||
1136 | |||
1137 | /* print out friendly message */ | ||
1138 | if(irq) | ||
1139 | printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, IR%d, DMA%d.\n",io,irq,dma); | ||
1140 | else | ||
1141 | printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, DMA%d. Using polled mode.\n",io,dma); | ||
1142 | |||
1143 | /* Fill in the fields of the device structure with ethernet-generic values. */ | ||
1144 | dev->hard_start_xmit = ltpc_xmit; | ||
1145 | dev->hard_header = ltpc_hard_header; | ||
1146 | dev->get_stats = ltpc_get_stats; | ||
1147 | |||
1148 | /* add the ltpc-specific things */ | ||
1149 | dev->do_ioctl = <pc_ioctl; | ||
1150 | |||
1151 | dev->set_multicast_list = &set_multicast_list; | ||
1152 | dev->mc_list = NULL; | ||
1153 | dev->base_addr = io; | ||
1154 | dev->irq = irq; | ||
1155 | dev->dma = dma; | ||
1156 | |||
1157 | /* the card will want to send a result at this point */ | ||
1158 | /* (I think... leaving out this part makes the kernel crash, | ||
1159 | so I put it back in...) */ | ||
1160 | |||
1161 | f=claim_dma_lock(); | ||
1162 | disable_dma(dma); | ||
1163 | clear_dma_ff(dma); | ||
1164 | set_dma_mode(dma,DMA_MODE_READ); | ||
1165 | set_dma_addr(dma,virt_to_bus(ltdmabuf)); | ||
1166 | set_dma_count(dma,0x100); | ||
1167 | enable_dma(dma); | ||
1168 | release_dma_lock(f); | ||
1169 | |||
1170 | (void) inb_p(io+3); | ||
1171 | (void) inb_p(io+2); | ||
1172 | timeout = jiffies+100*HZ/100; | ||
1173 | |||
1174 | while(time_before(jiffies, timeout)) { | ||
1175 | if( 0xf9 == inb_p(io+6)) | ||
1176 | break; | ||
1177 | schedule(); | ||
1178 | } | ||
1179 | |||
1180 | if(debug & DEBUG_VERBOSE) { | ||
1181 | printk("setting up timer and irq\n"); | ||
1182 | } | ||
1183 | |||
1184 | /* grab it and don't let go :-) */ | ||
1185 | if (irq && request_irq( irq, <pc_interrupt, 0, "ltpc", dev) >= 0) | ||
1186 | { | ||
1187 | (void) inb_p(io+7); /* enable interrupts from board */ | ||
1188 | (void) inb_p(io+7); /* and reset irq line */ | ||
1189 | } else { | ||
1190 | if( irq ) | ||
1191 | printk(KERN_ERR "ltpc: IRQ already in use, using polled mode.\n"); | ||
1192 | dev->irq = 0; | ||
1193 | /* polled mode -- 20 times per second */ | ||
1194 | /* this is really, really slow... should it poll more often? */ | ||
1195 | init_timer(<pc_timer); | ||
1196 | ltpc_timer.function=ltpc_poll; | ||
1197 | ltpc_timer.data = (unsigned long) dev; | ||
1198 | |||
1199 | ltpc_timer.expires = jiffies + HZ/20; | ||
1200 | add_timer(<pc_timer); | ||
1201 | } | ||
1202 | err = register_netdev(dev); | ||
1203 | if (err) | ||
1204 | goto out4; | ||
1205 | |||
1206 | return NULL; | ||
1207 | out4: | ||
1208 | del_timer_sync(<pc_timer); | ||
1209 | if (dev->irq) | ||
1210 | free_irq(dev->irq, dev); | ||
1211 | out3: | ||
1212 | free_pages((unsigned long)ltdmabuf, get_order(1000)); | ||
1213 | out2: | ||
1214 | release_region(io, 8); | ||
1215 | out1: | ||
1216 | free_netdev(dev); | ||
1217 | out: | ||
1218 | return ERR_PTR(err); | ||
1219 | } | ||
1220 | |||
1221 | #ifndef MODULE | ||
1222 | /* handles "ltpc=io,irq,dma" kernel command lines */ | ||
1223 | static int __init ltpc_setup(char *str) | ||
1224 | { | ||
1225 | int ints[5]; | ||
1226 | |||
1227 | str = get_options(str, ARRAY_SIZE(ints), ints); | ||
1228 | |||
1229 | if (ints[0] == 0) { | ||
1230 | if (str && !strncmp(str, "auto", 4)) { | ||
1231 | /* do nothing :-) */ | ||
1232 | } | ||
1233 | else { | ||
1234 | /* usage message */ | ||
1235 | printk (KERN_ERR | ||
1236 | "ltpc: usage: ltpc=auto|iobase[,irq[,dma]]\n"); | ||
1237 | return 0; | ||
1238 | } | ||
1239 | } else { | ||
1240 | io = ints[1]; | ||
1241 | if (ints[0] > 1) { | ||
1242 | irq = ints[2]; | ||
1243 | } | ||
1244 | if (ints[0] > 2) { | ||
1245 | dma = ints[3]; | ||
1246 | } | ||
1247 | /* ignore any other paramters */ | ||
1248 | } | ||
1249 | return 1; | ||
1250 | } | ||
1251 | |||
1252 | __setup("ltpc=", ltpc_setup); | ||
1253 | #endif /* MODULE */ | ||
1254 | |||
1255 | static struct net_device *dev_ltpc; | ||
1256 | |||
1257 | #ifdef MODULE | ||
1258 | |||
1259 | MODULE_LICENSE("GPL"); | ||
1260 | module_param(debug, int, 0); | ||
1261 | module_param(io, int, 0); | ||
1262 | module_param(irq, int, 0); | ||
1263 | module_param(dma, int, 0); | ||
1264 | |||
1265 | |||
1266 | int __init init_module(void) | ||
1267 | { | ||
1268 | if(io == 0) | ||
1269 | printk(KERN_NOTICE | ||
1270 | "ltpc: Autoprobing is not recommended for modules\n"); | ||
1271 | |||
1272 | dev_ltpc = ltpc_probe(); | ||
1273 | if (IS_ERR(dev_ltpc)) | ||
1274 | return PTR_ERR(dev_ltpc); | ||
1275 | return 0; | ||
1276 | } | ||
1277 | #endif | ||
1278 | |||
1279 | static void __exit ltpc_cleanup(void) | ||
1280 | { | ||
1281 | |||
1282 | if(debug & DEBUG_VERBOSE) printk("unregister_netdev\n"); | ||
1283 | unregister_netdev(dev_ltpc); | ||
1284 | |||
1285 | ltpc_timer.data = 0; /* signal the poll routine that we're done */ | ||
1286 | |||
1287 | del_timer_sync(<pc_timer); | ||
1288 | |||
1289 | if(debug & DEBUG_VERBOSE) printk("freeing irq\n"); | ||
1290 | |||
1291 | if (dev_ltpc->irq) | ||
1292 | free_irq(dev_ltpc->irq, dev_ltpc); | ||
1293 | |||
1294 | if(debug & DEBUG_VERBOSE) printk("freeing dma\n"); | ||
1295 | |||
1296 | if (dev_ltpc->dma) | ||
1297 | free_dma(dev_ltpc->dma); | ||
1298 | |||
1299 | if(debug & DEBUG_VERBOSE) printk("freeing ioaddr\n"); | ||
1300 | |||
1301 | if (dev_ltpc->base_addr) | ||
1302 | release_region(dev_ltpc->base_addr,8); | ||
1303 | |||
1304 | free_netdev(dev_ltpc); | ||
1305 | |||
1306 | if(debug & DEBUG_VERBOSE) printk("free_pages\n"); | ||
1307 | |||
1308 | free_pages( (unsigned long) ltdmabuf, get_order(1000)); | ||
1309 | |||
1310 | if(debug & DEBUG_VERBOSE) printk("returning from cleanup_module\n"); | ||
1311 | } | ||
1312 | |||
1313 | module_exit(ltpc_cleanup); | ||
diff --git a/drivers/net/appletalk/ltpc.h b/drivers/net/appletalk/ltpc.h new file mode 100644 index 000000000000..cd30544a3729 --- /dev/null +++ b/drivers/net/appletalk/ltpc.h | |||
@@ -0,0 +1,73 @@ | |||
1 | /*** ltpc.h | ||
2 | * | ||
3 | * | ||
4 | ***/ | ||
5 | |||
6 | #define LT_GETRESULT 0x00 | ||
7 | #define LT_WRITEMEM 0x01 | ||
8 | #define LT_READMEM 0x02 | ||
9 | #define LT_GETFLAGS 0x04 | ||
10 | #define LT_SETFLAGS 0x05 | ||
11 | #define LT_INIT 0x10 | ||
12 | #define LT_SENDLAP 0x13 | ||
13 | #define LT_RCVLAP 0x14 | ||
14 | |||
15 | /* the flag that we care about */ | ||
16 | #define LT_FLAG_ALLLAP 0x04 | ||
17 | |||
18 | struct lt_getresult { | ||
19 | unsigned char command; | ||
20 | unsigned char mailbox; | ||
21 | }; | ||
22 | |||
23 | struct lt_mem { | ||
24 | unsigned char command; | ||
25 | unsigned char mailbox; | ||
26 | unsigned short addr; /* host order */ | ||
27 | unsigned short length; /* host order */ | ||
28 | }; | ||
29 | |||
30 | struct lt_setflags { | ||
31 | unsigned char command; | ||
32 | unsigned char mailbox; | ||
33 | unsigned char flags; | ||
34 | }; | ||
35 | |||
36 | struct lt_getflags { | ||
37 | unsigned char command; | ||
38 | unsigned char mailbox; | ||
39 | }; | ||
40 | |||
41 | struct lt_init { | ||
42 | unsigned char command; | ||
43 | unsigned char mailbox; | ||
44 | unsigned char hint; | ||
45 | }; | ||
46 | |||
47 | struct lt_sendlap { | ||
48 | unsigned char command; | ||
49 | unsigned char mailbox; | ||
50 | unsigned char dnode; | ||
51 | unsigned char laptype; | ||
52 | unsigned short length; /* host order */ | ||
53 | }; | ||
54 | |||
55 | struct lt_rcvlap { | ||
56 | unsigned char command; | ||
57 | unsigned char dnode; | ||
58 | unsigned char snode; | ||
59 | unsigned char laptype; | ||
60 | unsigned short length; /* host order */ | ||
61 | }; | ||
62 | |||
63 | union lt_command { | ||
64 | struct lt_getresult getresult; | ||
65 | struct lt_mem mem; | ||
66 | struct lt_setflags setflags; | ||
67 | struct lt_getflags getflags; | ||
68 | struct lt_init init; | ||
69 | struct lt_sendlap sendlap; | ||
70 | struct lt_rcvlap rcvlap; | ||
71 | }; | ||
72 | typedef union lt_command lt_command; | ||
73 | |||