blob: 3d87bd2b4194972dcdaf30551245f35c61ebf71f [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* bionet.c BioNet-100 device driver for linux68k.
2 *
3 * Version: @(#)bionet.c 1.0 02/06/96
4 *
5 * Author: Hartmut Laue <laue@ifk-mp.uni-kiel.de>
6 * and Torsten Narjes <narjes@ifk-mp.uni-kiel.de>
7 *
8 * Little adaptions for integration into pl7 by Roman Hodek
9 *
10 * Some changes in bionet_poll_rx by Karl-Heinz Lohner
11 *
12 What is it ?
13 ------------
14 This driver controls the BIONET-100 LAN-Adapter which connects
15 an ATARI ST/TT via the ACSI-port to an Ethernet-based network.
16
17 This version can be compiled as a loadable module (See the
18 compile command at the bottom of this file).
19 At load time, you can optionally set the debugging level and the
20 fastest response time on the command line of 'insmod'.
21
22 'bionet_debug'
23 controls the amount of diagnostic messages:
24 0 : no messages
25 >0 : see code for meaning of printed messages
26
27 'bionet_min_poll_time' (always >=1)
28 gives the time (in jiffies) between polls. Low values
29 increase the system load (beware!)
30
31 When loaded, a net device with the name 'bio0' becomes available,
32 which can be controlled with the usual 'ifconfig' command.
33
34 It is possible to compile this driver into the kernel like other
35 (net) drivers. For this purpose, some source files (e.g. config-files
36 makefiles, Space.c) must be changed accordingly. (You may refer to
37 other drivers how to do it.) In this case, the device will be detected
38 at boot time and (probably) appear as 'eth0'.
39
40 This code is based on several sources:
41 - The driver code for a parallel port ethernet adapter by
42 Donald Becker (see file 'atp.c' from the PC linux distribution)
43 - The ACSI code by Roman Hodek for the ATARI-ACSI harddisk support
44 and DMA handling.
45 - Very limited information about moving packets in and out of the
46 BIONET-adapter from the TCP package for TOS by BioData GmbH.
47
48 Theory of Operation
49 -------------------
50 Because the ATARI DMA port is usually shared between several
51 devices (eg. harddisk, floppy) we cannot block the ACSI bus
52 while waiting for interrupts. Therefore we use a polling mechanism
53 to fetch packets from the adapter. For the same reason, we send
54 packets without checking that the previous packet has been sent to
55 the LAN. We rely on the higher levels of the networking code to detect
56 missing packets and resend them.
57
58 Before we access the ATARI DMA controller, we check if another
59 process is using the DMA. If not, we lock the DMA, perform one or
60 more packet transfers and unlock the DMA before returning.
61 We do not use 'stdma_lock' unconditionally because it is unclear
62 if the networking code can be set to sleep, which will happen if
63 another (possibly slow) device is using the DMA controller.
64
65 The polling is done via timer interrupts which periodically
66 'simulate' an interrupt from the Ethernet adapter. The time (in jiffies)
67 between polls varies depending on an estimate of the net activity.
68 The allowed range is given by the variable 'bionet_min_poll_time'
69 for the lower (fastest) limit and the constant 'MAX_POLL_TIME'
70 for the higher (slowest) limit.
71
72 Whenever a packet arrives, we switch to fastest response by setting
73 the polling time to its lowest limit. If the following poll fails,
74 because no packets have arrived, we increase the time for the next
75 poll. When the net activity is low, the polling time effectively
76 stays at its maximum value, resulting in the lowest load for the
77 machine.
78 */
79
80#define MAX_POLL_TIME 10
81
82static char version[] =
83 "bionet.c:v1.0 06-feb-96 (c) Hartmut Laue.\n";
84
85#include <linux/module.h>
86
87#include <linux/errno.h>
88#include <linux/kernel.h>
89#include <linux/jiffies.h>
90#include <linux/types.h>
91#include <linux/fcntl.h>
92#include <linux/interrupt.h>
93#include <linux/ioport.h>
94#include <linux/in.h>
95#include <linux/slab.h>
96#include <linux/string.h>
97#include <linux/delay.h>
98#include <linux/timer.h>
99#include <linux/init.h>
100#include <linux/bitops.h>
101
102#include <linux/netdevice.h>
103#include <linux/etherdevice.h>
104#include <linux/skbuff.h>
105
106#include <asm/setup.h>
107#include <asm/pgtable.h>
108#include <asm/system.h>
109#include <asm/io.h>
110#include <asm/dma.h>
111#include <asm/atarihw.h>
112#include <asm/atariints.h>
113#include <asm/atari_acsi.h>
114#include <asm/atari_stdma.h>
115
116
117/* use 0 for production, 1 for verification, >2 for debug
118 */
119#ifndef NET_DEBUG
120#define NET_DEBUG 0
121#endif
122/*
123 * Global variable 'bionet_debug'. Can be set at load time by 'insmod'
124 */
125unsigned int bionet_debug = NET_DEBUG;
Rusty Russell8d3b33f2006-03-25 03:07:05 -0800126module_param(bionet_debug, int, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127MODULE_PARM_DESC(bionet_debug, "bionet debug level (0-2)");
128MODULE_LICENSE("GPL");
129
130static unsigned int bionet_min_poll_time = 2;
131
132
133/* Information that need to be kept for each board.
134 */
135struct net_local {
136 struct net_device_stats stats;
137 long open_time; /* for debugging */
138 int poll_time; /* polling time varies with net load */
139};
140
141static struct nic_pkt_s { /* packet format */
142 unsigned char status;
143 unsigned char dummy;
144 unsigned char l_lo, l_hi;
145 unsigned char buffer[3000];
146} *nic_packet;
147unsigned char *phys_nic_packet;
148
149/* Index to functions, as function prototypes.
150 */
151static int bionet_open(struct net_device *dev);
152static int bionet_send_packet(struct sk_buff *skb, struct net_device *dev);
153static void bionet_poll_rx(struct net_device *);
154static int bionet_close(struct net_device *dev);
155static struct net_device_stats *net_get_stats(struct net_device *dev);
156static void bionet_tick(unsigned long);
157
Ingo Molnar8d06afa2005-09-09 13:10:40 -0700158static DEFINE_TIMER(bionet_timer, bionet_tick, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159
160#define STRAM_ADDR(a) (((a) & 0xff000000) == 0)
161
162/* The following routines access the ethernet board connected to the
163 * ACSI port via the st_dma chip.
164 */
165#define NODE_ADR 0x60
166
167#define C_READ 8
168#define C_WRITE 0x0a
169#define C_GETEA 0x0f
170#define C_SETCR 0x0e
171
172static int
173sendcmd(unsigned int a0, unsigned int mod, unsigned int cmd) {
174 unsigned int c;
175
176 dma_wd.dma_mode_status = (mod | ((a0) ? 2 : 0) | 0x88);
177 dma_wd.fdc_acces_seccount = cmd;
178 dma_wd.dma_mode_status = (mod | 0x8a);
179
180 if( !acsi_wait_for_IRQ(HZ/2) ) /* wait for cmd ack */
181 return -1; /* timeout */
182
183 c = dma_wd.fdc_acces_seccount;
184 return (c & 0xff);
185}
186
187
188static void
189set_status(int cr) {
190 sendcmd(0,0x100,NODE_ADR | C_SETCR); /* CMD: SET CR */
191 sendcmd(1,0x100,cr);
192
193 dma_wd.dma_mode_status = 0x80;
194}
195
196static int
197get_status(unsigned char *adr) {
198 int i,c;
199
200 DISABLE_IRQ();
201 c = sendcmd(0,0x00,NODE_ADR | C_GETEA); /* CMD: GET ETH ADR*/
202 if( c < 0 ) goto gsend;
203
204 /* now read status bytes */
205
206 for (i=0; i<6; i++) {
207 dma_wd.fdc_acces_seccount = 0; /* request next byte */
208
209 if( !acsi_wait_for_IRQ(HZ/2) ) { /* wait for cmd ack */
210 c = -1;
211 goto gsend; /* timeout */
212 }
213 c = dma_wd.fdc_acces_seccount;
214 *adr++ = (unsigned char)c;
215 }
216 c = 1;
217gsend:
218 dma_wd.dma_mode_status = 0x80;
219 return c;
220}
221
222static irqreturn_t
David Howells7d12e782006-10-05 14:55:46 +0100223bionet_intr(int irq, void *data) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224 return IRQ_HANDLED;
225}
226
227
228static int
229get_frame(unsigned long paddr, int odd) {
230 int c;
231 unsigned long flags;
232
233 DISABLE_IRQ();
234 local_irq_save(flags);
235
236 dma_wd.dma_mode_status = 0x9a;
237 dma_wd.dma_mode_status = 0x19a;
238 dma_wd.dma_mode_status = 0x9a;
239 dma_wd.fdc_acces_seccount = 0x04; /* sector count (was 5) */
240 dma_wd.dma_lo = (unsigned char)paddr;
241 paddr >>= 8;
242 dma_wd.dma_md = (unsigned char)paddr;
243 paddr >>= 8;
244 dma_wd.dma_hi = (unsigned char)paddr;
245 local_irq_restore(flags);
246
247 c = sendcmd(0,0x00,NODE_ADR | C_READ); /* CMD: READ */
248 if( c < 128 ) goto rend;
249
250 /* now read block */
251
252 c = sendcmd(1,0x00,odd); /* odd flag for address shift */
253 dma_wd.dma_mode_status = 0x0a;
254
255 if( !acsi_wait_for_IRQ(100) ) { /* wait for DMA to complete */
256 c = -1;
257 goto rend;
258 }
259 dma_wd.dma_mode_status = 0x8a;
260 dma_wd.dma_mode_status = 0x18a;
261 dma_wd.dma_mode_status = 0x8a;
262 c = dma_wd.fdc_acces_seccount;
263
264 dma_wd.dma_mode_status = 0x88;
265 c = dma_wd.fdc_acces_seccount;
266 c = 1;
267
268rend:
269 dma_wd.dma_mode_status = 0x80;
270 udelay(40);
271 acsi_wait_for_noIRQ(20);
272 return c;
273}
274
275
276static int
277hardware_send_packet(unsigned long paddr, int cnt) {
278 unsigned int c;
279 unsigned long flags;
280
281 DISABLE_IRQ();
282 local_irq_save(flags);
283
284 dma_wd.dma_mode_status = 0x19a;
285 dma_wd.dma_mode_status = 0x9a;
286 dma_wd.dma_mode_status = 0x19a;
287 dma_wd.dma_lo = (unsigned char)paddr;
288 paddr >>= 8;
289 dma_wd.dma_md = (unsigned char)paddr;
290 paddr >>= 8;
291 dma_wd.dma_hi = (unsigned char)paddr;
292
293 dma_wd.fdc_acces_seccount = 0x4; /* sector count */
294 local_irq_restore(flags);
295
296 c = sendcmd(0,0x100,NODE_ADR | C_WRITE); /* CMD: WRITE */
297 c = sendcmd(1,0x100,cnt&0xff);
298 c = sendcmd(1,0x100,cnt>>8);
299
300 /* now write block */
301
302 dma_wd.dma_mode_status = 0x10a; /* DMA enable */
303 if( !acsi_wait_for_IRQ(100) ) /* wait for DMA to complete */
304 goto end;
305
306 dma_wd.dma_mode_status = 0x19a; /* DMA disable ! */
307 c = dma_wd.fdc_acces_seccount;
308
309end:
310 c = sendcmd(1,0x100,0);
311 c = sendcmd(1,0x100,0);
312
313 dma_wd.dma_mode_status = 0x180;
314 udelay(40);
315 acsi_wait_for_noIRQ(20);
316 return( c & 0x02);
317}
318
319
320/* Check for a network adaptor of this type, and return '0' if one exists.
321 */
322struct net_device * __init bionet_probe(int unit)
323{
324 struct net_device *dev;
325 unsigned char station_addr[6];
326 static unsigned version_printed;
327 static int no_more_found; /* avoid "Probing for..." printed 4 times */
328 int i;
329 int err;
330
331 if (!MACH_IS_ATARI || no_more_found)
332 return ERR_PTR(-ENODEV);
333
334 dev = alloc_etherdev(sizeof(struct net_local));
335 if (!dev)
336 return ERR_PTR(-ENOMEM);
337 if (unit >= 0) {
338 sprintf(dev->name, "eth%d", unit);
339 netdev_boot_setup_check(dev);
340 }
341 SET_MODULE_OWNER(dev);
342
343 printk("Probing for BioNet 100 Adapter...\n");
344
345 stdma_lock(bionet_intr, NULL);
346 i = get_status(station_addr); /* Read the station address PROM. */
347 ENABLE_IRQ();
348 stdma_release();
349
350 /* Check the first three octets of the S.A. for the manufactor's code.
351 */
352
353 if( i < 0
354 || station_addr[0] != 'B'
355 || station_addr[1] != 'I'
356 || station_addr[2] != 'O' ) {
357 no_more_found = 1;
358 printk( "No BioNet 100 found.\n" );
359 free_netdev(dev);
360 return ERR_PTR(-ENODEV);
361 }
362
363 if (bionet_debug > 0 && version_printed++ == 0)
364 printk(version);
365
366 printk("%s: %s found, eth-addr: %02x-%02x-%02x:%02x-%02x-%02x.\n",
367 dev->name, "BioNet 100",
368 station_addr[0], station_addr[1], station_addr[2],
369 station_addr[3], station_addr[4], station_addr[5]);
370
371 /* Initialize the device structure. */
372
373 nic_packet = (struct nic_pkt_s *)acsi_buffer;
374 phys_nic_packet = (unsigned char *)phys_acsi_buffer;
375 if (bionet_debug > 0) {
376 printk("nic_packet at 0x%p, phys at 0x%p\n",
377 nic_packet, phys_nic_packet );
378 }
379
380 dev->open = bionet_open;
381 dev->stop = bionet_close;
382 dev->hard_start_xmit = bionet_send_packet;
383 dev->get_stats = net_get_stats;
384
385 /* Fill in the fields of the device structure with ethernet-generic
386 * values. This should be in a common file instead of per-driver.
387 */
388
389 for (i = 0; i < ETH_ALEN; i++) {
390#if 0
391 dev->broadcast[i] = 0xff;
392#endif
393 dev->dev_addr[i] = station_addr[i];
394 }
395 err = register_netdev(dev);
396 if (!err)
397 return dev;
398 free_netdev(dev);
399 return ERR_PTR(err);
400}
401
402/* Open/initialize the board. This is called (in the current kernel)
403 sometime after booting when the 'ifconfig' program is run.
404
405 This routine should set everything up anew at each open, even
406 registers that "should" only need to be set once at boot, so that
407 there is non-reboot way to recover if something goes wrong.
408 */
409static int
410bionet_open(struct net_device *dev) {
411 struct net_local *lp = netdev_priv(dev);
412
413 if (bionet_debug > 0)
414 printk("bionet_open\n");
415 stdma_lock(bionet_intr, NULL);
416
417 /* Reset the hardware here.
418 */
419 set_status(4);
420 lp->open_time = 0; /*jiffies*/
421 lp->poll_time = MAX_POLL_TIME;
422
423 dev->tbusy = 0;
424 dev->interrupt = 0;
425 dev->start = 1;
426
427 stdma_release();
428 bionet_timer.data = (long)dev;
429 bionet_timer.expires = jiffies + lp->poll_time;
430 add_timer(&bionet_timer);
431 return 0;
432}
433
434static int
435bionet_send_packet(struct sk_buff *skb, struct net_device *dev) {
436 struct net_local *lp = netdev_priv(dev);
437 unsigned long flags;
438
439 /* Block a timer-based transmit from overlapping. This could better be
440 * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
441 */
442 local_irq_save(flags);
443
444 if (stdma_islocked()) {
445 local_irq_restore(flags);
446 lp->stats.tx_errors++;
447 }
448 else {
449 int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
450 unsigned long buf = virt_to_phys(skb->data);
451 int stat;
452
453 stdma_lock(bionet_intr, NULL);
454 local_irq_restore(flags);
455 if( !STRAM_ADDR(buf+length-1) ) {
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -0300456 skb_copy_from_linear_data(skb, nic_packet->buffer,
457 length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458 buf = (unsigned long)&((struct nic_pkt_s *)phys_nic_packet)->buffer;
459 }
460
461 if (bionet_debug >1) {
462 u_char *data = nic_packet->buffer, *p;
463 int i;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400464
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465 printk( "%s: TX pkt type 0x%4x from ", dev->name,
466 ((u_short *)data)[6]);
467
468 for( p = &data[6], i = 0; i < 6; i++ )
469 printk("%02x%s", *p++,i != 5 ? ":" : "" );
470 printk(" to ");
471
472 for( p = data, i = 0; i < 6; i++ )
473 printk("%02x%s", *p++,i != 5 ? ":" : "" "\n" );
474
475 printk( "%s: ", dev->name );
476 printk(" data %02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x"
477 " %02x%02x%02x%02x len %d\n",
478 data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19],
479 data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27],
480 data[28], data[29], data[30], data[31], data[32], data[33],
481 length );
482 }
483 dma_cache_maintenance(buf, length, 1);
484
485 stat = hardware_send_packet(buf, length);
486 ENABLE_IRQ();
487 stdma_release();
488
489 dev->trans_start = jiffies;
490 dev->tbusy = 0;
491 lp->stats.tx_packets++;
492 lp->stats.tx_bytes+=length;
493 }
494 dev_kfree_skb(skb);
495
496 return 0;
497}
498
499/* We have a good packet(s), get it/them out of the buffers.
500 */
501static void
502bionet_poll_rx(struct net_device *dev) {
503 struct net_local *lp = netdev_priv(dev);
504 int boguscount = 10;
505 int pkt_len, status;
506 unsigned long flags;
507
508 local_irq_save(flags);
509 /* ++roman: Take care at locking the ST-DMA... This must be done with ints
510 * off, since otherwise an int could slip in between the question and the
511 * locking itself, and then we'd go to sleep... And locking itself is
512 * necessary to keep the floppy_change timer from working with ST-DMA
513 * registers. */
514 if (stdma_islocked()) {
515 local_irq_restore(flags);
516 return;
517 }
518 stdma_lock(bionet_intr, NULL);
519 DISABLE_IRQ();
520 local_irq_restore(flags);
521
522 if( lp->poll_time < MAX_POLL_TIME ) lp->poll_time++;
523
524 while(boguscount--) {
525 status = get_frame((unsigned long)phys_nic_packet, 0);
526
527 if( status == 0 ) break;
528
529 /* Good packet... */
530
531 dma_cache_maintenance((unsigned long)phys_nic_packet, 1520, 0);
532
533 pkt_len = (nic_packet->l_hi << 8) | nic_packet->l_lo;
534
535 lp->poll_time = bionet_min_poll_time; /* fast poll */
536 if( pkt_len >= 60 && pkt_len <= 1520 ) {
537 /* ^^^^ war 1514 KHL */
538 /* Malloc up new buffer.
539 */
540 struct sk_buff *skb = dev_alloc_skb( pkt_len + 2 );
541 if (skb == NULL) {
542 printk("%s: Memory squeeze, dropping packet.\n",
543 dev->name);
544 lp->stats.rx_dropped++;
545 break;
546 }
547
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548 skb_reserve( skb, 2 ); /* 16 Byte align */
549 skb_put( skb, pkt_len ); /* make room */
550
551 /* 'skb->data' points to the start of sk_buff data area.
552 */
Arnaldo Carvalho de Melo27d7ff42007-03-31 11:55:19 -0300553 skb_copy_to_linear_data(skb, nic_packet->buffer,
554 pkt_len);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400555 skb->protocol = eth_type_trans( skb, dev );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 netif_rx(skb);
557 dev->last_rx = jiffies;
558 lp->stats.rx_packets++;
559 lp->stats.rx_bytes+=pkt_len;
560
561 /* If any worth-while packets have been received, dev_rint()
562 has done a mark_bh(INET_BH) for us and will work on them
563 when we get to the bottom-half routine.
564 */
565
566 if (bionet_debug >1) {
567 u_char *data = nic_packet->buffer, *p;
568 int i;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400569
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 printk( "%s: RX pkt type 0x%4x from ", dev->name,
571 ((u_short *)data)[6]);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400572
573
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 for( p = &data[6], i = 0; i < 6; i++ )
575 printk("%02x%s", *p++,i != 5 ? ":" : "" );
576 printk(" to ");
577 for( p = data, i = 0; i < 6; i++ )
578 printk("%02x%s", *p++,i != 5 ? ":" : "" "\n" );
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400579
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580 printk( "%s: ", dev->name );
581 printk(" data %02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x"
582 " %02x%02x%02x%02x len %d\n",
583 data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19],
584 data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27],
585 data[28], data[29], data[30], data[31], data[32], data[33],
586 pkt_len );
587 }
588 }
589 else {
590 printk(" Packet has wrong length: %04d bytes\n", pkt_len);
591 lp->stats.rx_errors++;
592 }
593 }
594 stdma_release();
595 ENABLE_IRQ();
596 return;
597}
598
599/* bionet_tick: called by bionet_timer. Reads packets from the adapter,
600 * passes them to the higher layers and restarts the timer.
601 */
602static void
603bionet_tick(unsigned long data) {
604 struct net_device *dev = (struct net_device *)data;
605 struct net_local *lp = netdev_priv(dev);
606
607 if( bionet_debug > 0 && (lp->open_time++ & 7) == 8 )
608 printk("bionet_tick: %ld\n", lp->open_time);
609
610 if( !stdma_islocked() ) bionet_poll_rx(dev);
611
612 bionet_timer.expires = jiffies + lp->poll_time;
613 add_timer(&bionet_timer);
614}
615
616/* The inverse routine to bionet_open().
617 */
618static int
619bionet_close(struct net_device *dev) {
620 struct net_local *lp = netdev_priv(dev);
621
622 if (bionet_debug > 0)
623 printk("bionet_close, open_time=%ld\n", lp->open_time);
624 del_timer(&bionet_timer);
625 stdma_lock(bionet_intr, NULL);
626
627 set_status(0);
628 lp->open_time = 0;
629
630 dev->tbusy = 1;
631 dev->start = 0;
632
633 stdma_release();
634 return 0;
635}
636
637/* Get the current statistics.
638 This may be called with the card open or closed.
639 */
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400640static struct net_device_stats *net_get_stats(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641{
642 struct net_local *lp = netdev_priv(dev);
643 return &lp->stats;
644}
645
646
647#ifdef MODULE
648
649static struct net_device *bio_dev;
650
651int init_module(void)
652{
653 bio_dev = bionet_probe(-1);
654 if (IS_ERR(bio_dev))
655 return PTR_ERR(bio_dev);
656 return 0;
657}
658
659void cleanup_module(void)
660{
661 unregister_netdev(bio_dev);
662 free_netdev(bio_dev);
663}
664
665#endif /* MODULE */
666
667/* Local variables:
668 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include
669 -b m68k-linuxaout -Wall -Wstrict-prototypes -O2
670 -fomit-frame-pointer -pipe -DMODULE -I../../net/inet -c bionet.c"
671 * version-control: t
672 * kept-new-versions: 5
673 * tab-width: 8
674 * End:
675 */