1 /* bionet.c BioNet-100 device driver for linux68k. 3 * Version: @(#)bionet.c 1.0 02/06/96 5 * Author: Hartmut Laue <laue@ifk-mp.uni-kiel.de> 6 * and Torsten Narjes <narjes@ifk-mp.uni-kiel.de> 8 * Little adaptions for integration into pl7 by Roman Hodek 10 * Some changes in bionet_poll_rx by Karl-Heinz Lohner 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. 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'. 23 controls the amount of diagnostic messages: 25 >0 : see code for meaning of printed messages 27 'bionet_min_poll_time' (always >=1) 28 gives the time (in jiffies) between polls. Low values 29 increase the system load (beware!) 31 When loaded, a net device with the name 'bio0' becomes available, 32 which can be controlled with the usual 'ifconfig' command. 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'. 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 45 - Very limited information about moving packets in and out of the 46 BIONET-adapter from the TCP package for TOS by BioData GmbH. 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. 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. 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. 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 80 #define MAX_POLL_TIME 10 83 "bionet.c:v1.0 06-feb-96 (c) Hartmut Laue.\n"; 85 #include <linux/module.h> 87 #include <linux/errno.h> 88 #include <linux/kernel.h> 89 #include <linux/sched.h> 90 #include <linux/types.h> 91 #include <linux/fcntl.h> 92 #include <linux/interrupt.h> 93 #include <linux/ptrace.h> 94 #include <linux/ioport.h> 96 #include <linux/malloc.h> 97 #include <linux/string.h> 98 #include <linux/delay.h> 99 #include <linux/timer.h> 100 #include <linux/init.h> 102 #include <linux/netdevice.h> 103 #include <linux/etherdevice.h> 104 #include <linux/skbuff.h> 106 #include <asm/setup.h> 107 #include <asm/pgtable.h> 108 #include <asm/system.h> 109 #include <asm/bitops.h> 112 #include <asm/atarihw.h> 113 #include <asm/atariints.h> 114 #include <asm/atari_acsi.h> 115 #include <asm/atari_stdma.h> 118 externstruct net_device
*init_etherdev(struct net_device
*dev
,int sizeof_private
); 120 /* use 0 for production, 1 for verification, >2 for debug 126 * Global variable 'bionet_debug'. Can be set at load time by 'insmod' 128 unsigned int bionet_debug
= NET_DEBUG
; 129 MODULE_PARM(bionet_debug
,"i"); 131 static unsigned int bionet_min_poll_time
=2; 134 /* Information that need to be kept for each board. 137 struct net_device_stats stats
; 138 long open_time
;/* for debugging */ 139 int poll_time
;/* polling time varies with net load */ 142 static struct nic_pkt_s
{/* packet format */ 143 unsigned char status
; 145 unsigned char l_lo
, l_hi
; 146 unsigned char buffer
[3000]; 148 unsigned char*phys_nic_packet
; 150 /* Index to functions, as function prototypes. 152 externintbionet_probe(struct net_device
*dev
); 154 static intbionet_open(struct net_device
*dev
); 155 static intbionet_send_packet(struct sk_buff
*skb
,struct net_device
*dev
); 156 static voidbionet_poll_rx(struct net_device
*); 157 static intbionet_close(struct net_device
*dev
); 158 static struct net_device_stats
*net_get_stats(struct net_device
*dev
); 159 static voidbionet_tick(unsigned long); 161 static struct timer_list bionet_timer
= { function
: bionet_tick
}; 163 #define STRAM_ADDR(a) (((a) & 0xff000000) == 0) 165 /* The following routines access the ethernet board connected to the 166 * ACSI port via the st_dma chip. 168 #define NODE_ADR 0x60 176 sendcmd(unsigned int a0
,unsigned int mod
,unsigned int cmd
) { 179 dma_wd
.dma_mode_status
= (mod
| ((a0
) ?2:0) |0x88); 180 dma_wd
.fdc_acces_seccount
= cmd
; 181 dma_wd
.dma_mode_status
= (mod
|0x8a); 183 if( !acsi_wait_for_IRQ(HZ
/2) )/* wait for cmd ack */ 184 return-1;/* timeout */ 186 c
= dma_wd
.fdc_acces_seccount
; 193 sendcmd(0,0x100,NODE_ADR
| C_SETCR
);/* CMD: SET CR */ 196 dma_wd
.dma_mode_status
=0x80; 200 get_status(unsigned char*adr
) { 204 c
=sendcmd(0,0x00,NODE_ADR
| C_GETEA
);/* CMD: GET ETH ADR*/ 207 /* now read status bytes */ 210 dma_wd
.fdc_acces_seccount
=0;/* request next byte */ 212 if( !acsi_wait_for_IRQ(HZ
/2) ) {/* wait for cmd ack */ 214 goto gsend
;/* timeout */ 216 c
= dma_wd
.fdc_acces_seccount
; 217 *adr
++ = (unsigned char)c
; 221 dma_wd
.dma_mode_status
=0x80; 226 bionet_intr(int irq
,void*data
,struct pt_regs
*fp
) { 232 get_frame(unsigned long paddr
,int odd
) { 240 dma_wd
.dma_mode_status
=0x9a; 241 dma_wd
.dma_mode_status
=0x19a; 242 dma_wd
.dma_mode_status
=0x9a; 243 dma_wd
.fdc_acces_seccount
=0x04;/* sector count (was 5) */ 244 dma_wd
.dma_lo
= (unsigned char)paddr
; 246 dma_wd
.dma_md
= (unsigned char)paddr
; 248 dma_wd
.dma_hi
= (unsigned char)paddr
; 249 restore_flags(flags
); 251 c
=sendcmd(0,0x00,NODE_ADR
| C_READ
);/* CMD: READ */ 252 if( c
<128)goto rend
; 256 c
=sendcmd(1,0x00,odd
);/* odd flag for address shift */ 257 dma_wd
.dma_mode_status
=0x0a; 259 if( !acsi_wait_for_IRQ(100) ) {/* wait for DMA to complete */ 263 dma_wd
.dma_mode_status
=0x8a; 264 dma_wd
.dma_mode_status
=0x18a; 265 dma_wd
.dma_mode_status
=0x8a; 266 c
= dma_wd
.fdc_acces_seccount
; 268 dma_wd
.dma_mode_status
=0x88; 269 c
= dma_wd
.fdc_acces_seccount
; 273 dma_wd
.dma_mode_status
=0x80; 275 acsi_wait_for_noIRQ(20); 281 hardware_send_packet(unsigned long paddr
,int cnt
) { 289 dma_wd
.dma_mode_status
=0x19a; 290 dma_wd
.dma_mode_status
=0x9a; 291 dma_wd
.dma_mode_status
=0x19a; 292 dma_wd
.dma_lo
= (unsigned char)paddr
; 294 dma_wd
.dma_md
= (unsigned char)paddr
; 296 dma_wd
.dma_hi
= (unsigned char)paddr
; 298 dma_wd
.fdc_acces_seccount
=0x4;/* sector count */ 299 restore_flags(flags
); 301 c
=sendcmd(0,0x100,NODE_ADR
| C_WRITE
);/* CMD: WRITE */ 302 c
=sendcmd(1,0x100,cnt
&0xff); 303 c
=sendcmd(1,0x100,cnt
>>8); 305 /* now write block */ 307 dma_wd
.dma_mode_status
=0x10a;/* DMA enable */ 308 if( !acsi_wait_for_IRQ(100) )/* wait for DMA to complete */ 311 dma_wd
.dma_mode_status
=0x19a;/* DMA disable ! */ 312 c
= dma_wd
.fdc_acces_seccount
; 315 c
=sendcmd(1,0x100,0); 316 c
=sendcmd(1,0x100,0); 318 dma_wd
.dma_mode_status
=0x180; 320 acsi_wait_for_noIRQ(20); 325 /* Check for a network adaptor of this type, and return '0' if one exists. 328 bionet_probe(struct net_device
*dev
){ 329 unsigned char station_addr
[6]; 330 static unsigned version_printed
=0; 331 static int no_more_found
=0;/* avoid "Probing for..." printed 4 times */ 334 if(!MACH_IS_ATARI
|| no_more_found
) 337 printk("Probing for BioNet 100 Adapter...\n"); 339 stdma_lock(bionet_intr
, NULL
); 340 i
=get_status(station_addr
);/* Read the station address PROM. */ 344 /* Check the first three octets of the S.A. for the manufactor's code. 348 || station_addr
[0] !='B' 349 || station_addr
[1] !='I' 350 || station_addr
[2] !='O') { 352 printk("No BioNet 100 found.\n"); 356 SET_MODULE_OWNER(dev
); 358 if(bionet_debug
>0&& version_printed
++ ==0) 361 printk("%s: %s found, eth-addr: %02x-%02x-%02x:%02x-%02x-%02x.\n", 362 dev
->name
,"BioNet 100", 363 station_addr
[0], station_addr
[1], station_addr
[2], 364 station_addr
[3], station_addr
[4], station_addr
[5]); 366 /* Initialize the device structure. */ 368 nic_packet
= (struct nic_pkt_s
*)acsi_buffer
; 369 phys_nic_packet
= (unsigned char*)phys_acsi_buffer
; 370 if(bionet_debug
>0) { 371 printk("nic_packet at 0x%p, phys at 0x%p\n", 372 nic_packet
, phys_nic_packet
); 375 if(dev
->priv
== NULL
) 376 dev
->priv
=kmalloc(sizeof(struct net_local
), GFP_KERNEL
); 377 memset(dev
->priv
,0,sizeof(struct net_local
)); 379 dev
->open
= bionet_open
; 380 dev
->stop
= bionet_close
; 381 dev
->hard_start_xmit
= bionet_send_packet
; 382 dev
->get_stats
= net_get_stats
; 384 /* Fill in the fields of the device structure with ethernet-generic 385 * values. This should be in a common file instead of per-driver. 388 for(i
=0; i
< ETH_ALEN
; i
++) { 390 dev
->broadcast
[i
] =0xff; 392 dev
->dev_addr
[i
] = station_addr
[i
]; 398 /* Open/initialize the board. This is called (in the current kernel) 399 sometime after booting when the 'ifconfig' program is run. 401 This routine should set everything up anew at each open, even 402 registers that "should" only need to be set once at boot, so that 403 there is non-reboot way to recover if something goes wrong. 406 bionet_open(struct net_device
*dev
) { 407 struct net_local
*lp
= (struct net_local
*)dev
->priv
; 410 printk("bionet_open\n"); 411 stdma_lock(bionet_intr
, NULL
); 413 /* Reset the hardware here. 416 lp
->open_time
=0;/*jiffies*/ 417 lp
->poll_time
= MAX_POLL_TIME
; 424 bionet_timer
.data
= (long)dev
; 425 bionet_timer
.expires
= jiffies
+ lp
->poll_time
; 426 add_timer(&bionet_timer
); 431 bionet_send_packet(struct sk_buff
*skb
,struct net_device
*dev
) { 432 struct net_local
*lp
= (struct net_local
*)dev
->priv
; 435 /* Block a timer-based transmit from overlapping. This could better be 436 * done with atomic_swap(1, dev->tbusy), but set_bit() works as well. 441 if(stdma_islocked()) { 442 restore_flags(flags
); 443 lp
->stats
.tx_errors
++; 446 int length
= ETH_ZLEN
< skb
->len
? skb
->len
: ETH_ZLEN
; 447 unsigned long buf
=virt_to_phys(skb
->data
); 450 stdma_lock(bionet_intr
, NULL
); 451 restore_flags(flags
); 452 if( !STRAM_ADDR(buf
+length
-1) ) { 453 memcpy(nic_packet
->buffer
, skb
->data
, length
); 454 buf
= (unsigned long)&((struct nic_pkt_s
*)phys_nic_packet
)->buffer
; 457 if(bionet_debug
>1) { 458 u_char
*data
= nic_packet
->buffer
, *p
; 461 printk("%s: TX pkt type 0x%4x from ", dev
->name
, 462 ((u_short
*)data
)[6]); 464 for( p
= &data
[6], i
=0; i
<6; i
++ ) 465 printk("%02x%s", *p
++,i
!=5?":":""); 468 for( p
= data
, i
=0; i
<6; i
++ ) 469 printk("%02x%s", *p
++,i
!=5?":":"""\n"); 471 printk("%s: ", dev
->name
); 472 printk(" data %02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x" 473 " %02x%02x%02x%02x len %d\n", 474 data
[12], data
[13], data
[14], data
[15], data
[16], data
[17], data
[18], data
[19], 475 data
[20], data
[21], data
[22], data
[23], data
[24], data
[25], data
[26], data
[27], 476 data
[28], data
[29], data
[30], data
[31], data
[32], data
[33], 479 dma_cache_maintenance(buf
, length
,1); 481 stat
=hardware_send_packet(buf
, length
); 485 dev
->trans_start
= jiffies
; 487 lp
->stats
.tx_packets
++; 488 lp
->stats
.tx_bytes
+=length
; 495 /* We have a good packet(s), get it/them out of the buffers. 498 bionet_poll_rx(struct net_device
*dev
) { 499 struct net_local
*lp
= (struct net_local
*)dev
->priv
; 506 /* ++roman: Take care at locking the ST-DMA... This must be done with ints 507 * off, since otherwise an int could slip in between the question and the 508 * locking itself, and then we'd go to sleep... And locking itself is 509 * necessary to keep the floppy_change timer from working with ST-DMA 511 if(stdma_islocked()) { 512 restore_flags(flags
); 515 stdma_lock(bionet_intr
, NULL
); 517 restore_flags(flags
); 519 if( lp
->poll_time
< MAX_POLL_TIME
) lp
->poll_time
++; 521 while(boguscount
--) { 522 status
=get_frame((unsigned long)phys_nic_packet
,0); 524 if( status
==0)break; 528 dma_cache_maintenance((unsigned long)phys_nic_packet
,1520,0); 530 pkt_len
= (nic_packet
->l_hi
<<8) | nic_packet
->l_lo
; 532 lp
->poll_time
= bionet_min_poll_time
;/* fast poll */ 533 if( pkt_len
>=60&& pkt_len
<=1520) { 534 /* ^^^^ war 1514 KHL */ 535 /* Malloc up new buffer. 537 struct sk_buff
*skb
=dev_alloc_skb( pkt_len
+2); 539 printk("%s: Memory squeeze, dropping packet.\n", 541 lp
->stats
.rx_dropped
++; 546 skb_reserve( skb
,2);/* 16 Byte align */ 547 skb_put( skb
, pkt_len
);/* make room */ 549 /* 'skb->data' points to the start of sk_buff data area. 551 memcpy(skb
->data
, nic_packet
->buffer
, pkt_len
); 552 skb
->protocol
=eth_type_trans( skb
, dev
); 554 lp
->stats
.rx_packets
++; 555 lp
->stats
.rx_bytes
+=pkt_len
; 557 /* If any worth-while packets have been received, dev_rint() 558 has done a mark_bh(INET_BH) for us and will work on them 559 when we get to the bottom-half routine. 562 if(bionet_debug
>1) { 563 u_char
*data
= nic_packet
->buffer
, *p
; 566 printk("%s: RX pkt type 0x%4x from ", dev
->name
, 567 ((u_short
*)data
)[6]); 570 for( p
= &data
[6], i
=0; i
<6; i
++ ) 571 printk("%02x%s", *p
++,i
!=5?":":""); 573 for( p
= data
, i
=0; i
<6; i
++ ) 574 printk("%02x%s", *p
++,i
!=5?":":"""\n"); 576 printk("%s: ", dev
->name
); 577 printk(" data %02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x" 578 " %02x%02x%02x%02x len %d\n", 579 data
[12], data
[13], data
[14], data
[15], data
[16], data
[17], data
[18], data
[19], 580 data
[20], data
[21], data
[22], data
[23], data
[24], data
[25], data
[26], data
[27], 581 data
[28], data
[29], data
[30], data
[31], data
[32], data
[33], 586 printk(" Packet has wrong length: %04d bytes\n", pkt_len
); 587 lp
->stats
.rx_errors
++; 595 /* bionet_tick: called by bionet_timer. Reads packets from the adapter, 596 * passes them to the higher layers and restarts the timer. 599 bionet_tick(unsigned long data
) { 600 struct net_device
*dev
= (struct net_device
*)data
; 601 struct net_local
*lp
= (struct net_local
*)dev
->priv
; 603 if( bionet_debug
>0&& (lp
->open_time
++ &7) ==8) 604 printk("bionet_tick: %ld\n", lp
->open_time
); 606 if( !stdma_islocked() )bionet_poll_rx(dev
); 608 bionet_timer
.expires
= jiffies
+ lp
->poll_time
; 609 add_timer(&bionet_timer
); 612 /* The inverse routine to bionet_open(). 615 bionet_close(struct net_device
*dev
) { 616 struct net_local
*lp
= (struct net_local
*)dev
->priv
; 619 printk("bionet_close, open_time=%ld\n", lp
->open_time
); 620 del_timer(&bionet_timer
); 621 stdma_lock(bionet_intr
, NULL
); 633 /* Get the current statistics. 634 This may be called with the card open or closed. 636 static struct net_device_stats
*net_get_stats(struct net_device
*dev
) 638 struct net_local
*lp
= (struct net_local
*)dev
->priv
; 645 static struct net_device bio_dev
; 651 bio_dev
.init
= bionet_probe
; 652 if((err
=register_netdev(&bio_dev
))) { 654 printk("BIONET: devices already present. Module not loaded.\n"); 662 cleanup_module(void) { 663 unregister_netdev(&bio_dev
); 669 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include 670 -b m68k-linuxaout -Wall -Wstrict-prototypes -O2 671 -fomit-frame-pointer -pipe -DMODULE -I../../net/inet -c bionet.c" 673 * kept-new-versions: 5