1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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
101#include <linux/netdevice.h>
102#include <linux/etherdevice.h>
103#include <linux/skbuff.h>
104
105#include <asm/setup.h>
106#include <asm/pgtable.h>
107#include <asm/system.h>
108#include <asm/bitops.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
118
119#ifndef NET_DEBUG
120#define NET_DEBUG 0
121#endif
122
123
124
125unsigned int bionet_debug = NET_DEBUG;
126MODULE_PARM(bionet_debug, "i");
127MODULE_PARM_DESC(bionet_debug, "bionet debug level (0-2)");
128MODULE_LICENSE("GPL");
129
130static unsigned int bionet_min_poll_time = 2;
131
132
133
134
135struct net_local {
136 struct net_device_stats stats;
137 long open_time;
138 int poll_time;
139};
140
141static struct nic_pkt_s {
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
150
151extern int bionet_probe(struct net_device *dev);
152
153static int bionet_open(struct net_device *dev);
154static int bionet_send_packet(struct sk_buff *skb, struct net_device *dev);
155static void bionet_poll_rx(struct net_device *);
156static int bionet_close(struct net_device *dev);
157static struct net_device_stats *net_get_stats(struct net_device *dev);
158static void bionet_tick(unsigned long);
159
160static struct timer_list bionet_timer = TIMER_INITIALIZER(bionet_tick, 0, 0);
161
162#define STRAM_ADDR(a) (((a) & 0xff000000) == 0)
163
164
165
166
167#define NODE_ADR 0x60
168
169#define C_READ 8
170#define C_WRITE 0x0a
171#define C_GETEA 0x0f
172#define C_SETCR 0x0e
173
174static int
175sendcmd(unsigned int a0, unsigned int mod, unsigned int cmd) {
176 unsigned int c;
177
178 dma_wd.dma_mode_status = (mod | ((a0) ? 2 : 0) | 0x88);
179 dma_wd.fdc_acces_seccount = cmd;
180 dma_wd.dma_mode_status = (mod | 0x8a);
181
182 if( !acsi_wait_for_IRQ(HZ/2) )
183 return -1;
184
185 c = dma_wd.fdc_acces_seccount;
186 return (c & 0xff);
187}
188
189
190static void
191set_status(int cr) {
192 sendcmd(0,0x100,NODE_ADR | C_SETCR);
193 sendcmd(1,0x100,cr);
194
195 dma_wd.dma_mode_status = 0x80;
196}
197
198static int
199get_status(unsigned char *adr) {
200 int i,c;
201
202 DISABLE_IRQ();
203 c = sendcmd(0,0x00,NODE_ADR | C_GETEA);
204 if( c < 0 ) goto gsend;
205
206
207
208 for (i=0; i<6; i++) {
209 dma_wd.fdc_acces_seccount = 0;
210
211 if( !acsi_wait_for_IRQ(HZ/2) ) {
212 c = -1;
213 goto gsend;
214 }
215 c = dma_wd.fdc_acces_seccount;
216 *adr++ = (unsigned char)c;
217 }
218 c = 1;
219gsend:
220 dma_wd.dma_mode_status = 0x80;
221 return c;
222}
223
224static irqreturn_t
225bionet_intr(int irq, void *data, struct pt_regs *fp) {
226 return IRQ_HANDLED;
227}
228
229
230static int
231get_frame(unsigned long paddr, int odd) {
232 int c;
233 unsigned long flags;
234
235 DISABLE_IRQ();
236 local_irq_save(flags);
237
238 dma_wd.dma_mode_status = 0x9a;
239 dma_wd.dma_mode_status = 0x19a;
240 dma_wd.dma_mode_status = 0x9a;
241 dma_wd.fdc_acces_seccount = 0x04;
242 dma_wd.dma_lo = (unsigned char)paddr;
243 paddr >>= 8;
244 dma_wd.dma_md = (unsigned char)paddr;
245 paddr >>= 8;
246 dma_wd.dma_hi = (unsigned char)paddr;
247 local_irq_restore(flags);
248
249 c = sendcmd(0,0x00,NODE_ADR | C_READ);
250 if( c < 128 ) goto rend;
251
252
253
254 c = sendcmd(1,0x00,odd);
255 dma_wd.dma_mode_status = 0x0a;
256
257 if( !acsi_wait_for_IRQ(100) ) {
258 c = -1;
259 goto rend;
260 }
261 dma_wd.dma_mode_status = 0x8a;
262 dma_wd.dma_mode_status = 0x18a;
263 dma_wd.dma_mode_status = 0x8a;
264 c = dma_wd.fdc_acces_seccount;
265
266 dma_wd.dma_mode_status = 0x88;
267 c = dma_wd.fdc_acces_seccount;
268 c = 1;
269
270rend:
271 dma_wd.dma_mode_status = 0x80;
272 udelay(40);
273 acsi_wait_for_noIRQ(20);
274 return c;
275}
276
277
278static int
279hardware_send_packet(unsigned long paddr, int cnt) {
280 unsigned int c;
281 unsigned long flags;
282
283 DISABLE_IRQ();
284 local_irq_save(flags);
285
286 dma_wd.dma_mode_status = 0x19a;
287 dma_wd.dma_mode_status = 0x9a;
288 dma_wd.dma_mode_status = 0x19a;
289 dma_wd.dma_lo = (unsigned char)paddr;
290 paddr >>= 8;
291 dma_wd.dma_md = (unsigned char)paddr;
292 paddr >>= 8;
293 dma_wd.dma_hi = (unsigned char)paddr;
294
295 dma_wd.fdc_acces_seccount = 0x4;
296 local_irq_restore(flags);
297
298 c = sendcmd(0,0x100,NODE_ADR | C_WRITE);
299 c = sendcmd(1,0x100,cnt&0xff);
300 c = sendcmd(1,0x100,cnt>>8);
301
302
303
304 dma_wd.dma_mode_status = 0x10a;
305 if( !acsi_wait_for_IRQ(100) )
306 goto end;
307
308 dma_wd.dma_mode_status = 0x19a;
309 c = dma_wd.fdc_acces_seccount;
310
311end:
312 c = sendcmd(1,0x100,0);
313 c = sendcmd(1,0x100,0);
314
315 dma_wd.dma_mode_status = 0x180;
316 udelay(40);
317 acsi_wait_for_noIRQ(20);
318 return( c & 0x02);
319}
320
321
322
323
324int __init
325bionet_probe(struct net_device *dev){
326 unsigned char station_addr[6];
327 static unsigned version_printed;
328 static int no_more_found;
329 int i;
330
331 if (!MACH_IS_ATARI || no_more_found)
332 return -ENODEV;
333
334 printk("Probing for BioNet 100 Adapter...\n");
335
336 stdma_lock(bionet_intr, NULL);
337 i = get_status(station_addr);
338 ENABLE_IRQ();
339 stdma_release();
340
341
342
343
344 if( i < 0
345 || station_addr[0] != 'B'
346 || station_addr[1] != 'I'
347 || station_addr[2] != 'O' ) {
348 no_more_found = 1;
349 printk( "No BioNet 100 found.\n" );
350 return -ENODEV;
351 }
352
353 SET_MODULE_OWNER(dev);
354
355 if (bionet_debug > 0 && version_printed++ == 0)
356 printk(version);
357
358 printk("%s: %s found, eth-addr: %02x-%02x-%02x:%02x-%02x-%02x.\n",
359 dev->name, "BioNet 100",
360 station_addr[0], station_addr[1], station_addr[2],
361 station_addr[3], station_addr[4], station_addr[5]);
362
363
364
365 nic_packet = (struct nic_pkt_s *)acsi_buffer;
366 phys_nic_packet = (unsigned char *)phys_acsi_buffer;
367 if (bionet_debug > 0) {
368 printk("nic_packet at 0x%p, phys at 0x%p\n",
369 nic_packet, phys_nic_packet );
370 }
371
372 if (dev->priv == NULL)
373 dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
374 if (!dev->priv)
375 return -ENOMEM;
376 memset(dev->priv, 0, sizeof(struct net_local));
377
378 dev->open = bionet_open;
379 dev->stop = bionet_close;
380 dev->hard_start_xmit = bionet_send_packet;
381 dev->get_stats = net_get_stats;
382
383
384
385
386
387 for (i = 0; i < ETH_ALEN; i++) {
388#if 0
389 dev->broadcast[i] = 0xff;
390#endif
391 dev->dev_addr[i] = station_addr[i];
392 }
393 ether_setup(dev);
394 return 0;
395}
396
397
398
399
400
401
402
403
404static int
405bionet_open(struct net_device *dev) {
406 struct net_local *lp = (struct net_local *)dev->priv;
407
408 if (bionet_debug > 0)
409 printk("bionet_open\n");
410 stdma_lock(bionet_intr, NULL);
411
412
413
414 set_status(4);
415 lp->open_time = 0;
416 lp->poll_time = MAX_POLL_TIME;
417
418 dev->tbusy = 0;
419 dev->interrupt = 0;
420 dev->start = 1;
421
422 stdma_release();
423 bionet_timer.data = (long)dev;
424 bionet_timer.expires = jiffies + lp->poll_time;
425 add_timer(&bionet_timer);
426 return 0;
427}
428
429static int
430bionet_send_packet(struct sk_buff *skb, struct net_device *dev) {
431 struct net_local *lp = (struct net_local *)dev->priv;
432 unsigned long flags;
433
434
435
436
437 local_irq_save(flags);
438
439 if (stdma_islocked()) {
440 local_irq_restore(flags);
441 lp->stats.tx_errors++;
442 }
443 else {
444 int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
445 unsigned long buf = virt_to_phys(skb->data);
446 int stat;
447
448 stdma_lock(bionet_intr, NULL);
449 local_irq_restore(flags);
450 if( !STRAM_ADDR(buf+length-1) ) {
451 memcpy(nic_packet->buffer, skb->data, length);
452 buf = (unsigned long)&((struct nic_pkt_s *)phys_nic_packet)->buffer;
453 }
454
455 if (bionet_debug >1) {
456 u_char *data = nic_packet->buffer, *p;
457 int i;
458
459 printk( "%s: TX pkt type 0x%4x from ", dev->name,
460 ((u_short *)data)[6]);
461
462 for( p = &data[6], i = 0; i < 6; i++ )
463 printk("%02x%s", *p++,i != 5 ? ":" : "" );
464 printk(" to ");
465
466 for( p = data, i = 0; i < 6; i++ )
467 printk("%02x%s", *p++,i != 5 ? ":" : "" "\n" );
468
469 printk( "%s: ", dev->name );
470 printk(" data %02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x"
471 " %02x%02x%02x%02x len %d\n",
472 data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19],
473 data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27],
474 data[28], data[29], data[30], data[31], data[32], data[33],
475 length );
476 }
477 dma_cache_maintenance(buf, length, 1);
478
479 stat = hardware_send_packet(buf, length);
480 ENABLE_IRQ();
481 stdma_release();
482
483 dev->trans_start = jiffies;
484 dev->tbusy = 0;
485 lp->stats.tx_packets++;
486 lp->stats.tx_bytes+=length;
487 }
488 dev_kfree_skb(skb);
489
490 return 0;
491}
492
493
494
495static void
496bionet_poll_rx(struct net_device *dev) {
497 struct net_local *lp = (struct net_local *)dev->priv;
498 int boguscount = 10;
499 int pkt_len, status;
500 unsigned long flags;
501
502 local_irq_save(flags);
503
504
505
506
507
508 if (stdma_islocked()) {
509 local_irq_restore(flags);
510 return;
511 }
512 stdma_lock(bionet_intr, NULL);
513 DISABLE_IRQ();
514 local_irq_restore(flags);
515
516 if( lp->poll_time < MAX_POLL_TIME ) lp->poll_time++;
517
518 while(boguscount--) {
519 status = get_frame((unsigned long)phys_nic_packet, 0);
520
521 if( status == 0 ) break;
522
523
524
525 dma_cache_maintenance((unsigned long)phys_nic_packet, 1520, 0);
526
527 pkt_len = (nic_packet->l_hi << 8) | nic_packet->l_lo;
528
529 lp->poll_time = bionet_min_poll_time;
530 if( pkt_len >= 60 && pkt_len <= 1520 ) {
531
532
533
534 struct sk_buff *skb = dev_alloc_skb( pkt_len + 2 );
535 if (skb == NULL) {
536 printk("%s: Memory squeeze, dropping packet.\n",
537 dev->name);
538 lp->stats.rx_dropped++;
539 break;
540 }
541
542 skb->dev = dev;
543 skb_reserve( skb, 2 );
544 skb_put( skb, pkt_len );
545
546
547
548 memcpy(skb->data, nic_packet->buffer, pkt_len);
549 skb->protocol = eth_type_trans( skb, dev );
550 netif_rx(skb);
551 dev->last_rx = jiffies;
552 lp->stats.rx_packets++;
553 lp->stats.rx_bytes+=pkt_len;
554
555
556
557
558
559
560 if (bionet_debug >1) {
561 u_char *data = nic_packet->buffer, *p;
562 int i;
563
564 printk( "%s: RX pkt type 0x%4x from ", dev->name,
565 ((u_short *)data)[6]);
566
567
568 for( p = &data[6], i = 0; i < 6; i++ )
569 printk("%02x%s", *p++,i != 5 ? ":" : "" );
570 printk(" to ");
571 for( p = data, i = 0; i < 6; i++ )
572 printk("%02x%s", *p++,i != 5 ? ":" : "" "\n" );
573
574 printk( "%s: ", dev->name );
575 printk(" data %02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x"
576 " %02x%02x%02x%02x len %d\n",
577 data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19],
578 data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27],
579 data[28], data[29], data[30], data[31], data[32], data[33],
580 pkt_len );
581 }
582 }
583 else {
584 printk(" Packet has wrong length: %04d bytes\n", pkt_len);
585 lp->stats.rx_errors++;
586 }
587 }
588 stdma_release();
589 ENABLE_IRQ();
590 return;
591}
592
593
594
595
596static void
597bionet_tick(unsigned long data) {
598 struct net_device *dev = (struct net_device *)data;
599 struct net_local *lp = (struct net_local *)dev->priv;
600
601 if( bionet_debug > 0 && (lp->open_time++ & 7) == 8 )
602 printk("bionet_tick: %ld\n", lp->open_time);
603
604 if( !stdma_islocked() ) bionet_poll_rx(dev);
605
606 bionet_timer.expires = jiffies + lp->poll_time;
607 add_timer(&bionet_timer);
608}
609
610
611
612static int
613bionet_close(struct net_device *dev) {
614 struct net_local *lp = (struct net_local *)dev->priv;
615
616 if (bionet_debug > 0)
617 printk("bionet_close, open_time=%ld\n", lp->open_time);
618 del_timer(&bionet_timer);
619 stdma_lock(bionet_intr, NULL);
620
621 set_status(0);
622 lp->open_time = 0;
623
624 dev->tbusy = 1;
625 dev->start = 0;
626
627 stdma_release();
628 return 0;
629}
630
631
632
633
634static struct net_device_stats *net_get_stats(struct net_device *dev)
635{
636 struct net_local *lp = (struct net_local *)dev->priv;
637 return &lp->stats;
638}
639
640
641#ifdef MODULE
642
643static struct net_device bio_dev;
644
645int
646init_module(void) {
647 int err;
648
649 bio_dev.init = bionet_probe;
650 if ((err = register_netdev(&bio_dev))) {
651 if (err == -EEXIST) {
652 printk("BIONET: devices already present. Module not loaded.\n");
653 }
654 return err;
655 }
656 return 0;
657}
658
659void
660cleanup_module(void) {
661 unregister_netdev(&bio_dev);
662}
663
664#endif
665
666
667
668
669
670
671
672
673
674
675