1 /* atari_pamsnet.c PAMsNet device driver for linux68k.
2 *
3 * Version: @(#)PAMsNet.c 0.2� 03/31/96
4 *
5 * Author: Torsten Lang <Torsten.Lang@ap.physik.uni-giessen.de>
6 * <Torsten.Lang@jung.de>
7 *
8 * This driver is based on my driver PAMSDMA.c for MiNT-Net and
9 * on the driver bionet.c written by
10 * Hartmut Laue <laue@ifk-mp.uni-kiel.de>
11 * and Torsten Narjes <narjes@ifk-mp.uni-kiel.de>
12 *
13 * Little adaptions for integration into pl7 by Roman Hodek
14 *
15 What is it ?
16 ------------
17 This driver controls the PAMsNet LAN-Adapter which connects
18 an ATARI ST/TT via the ACSI-port to an Ethernet-based network.
19
20 This version can be compiled as a loadable module (See the
21 compile command at the bottom of this file).
22 At load time, you can optionally set the debugging level and the
23 fastest response time on the command line of 'insmod'.
24
25 'pamsnet_debug'
26 controls the amount of diagnostic messages:
27 0 : no messages
28 >0 : see code for meaning of printed messages
29
30 'pamsnet_min_poll_time' (always >=1)
31 gives the time (in jiffies) between polls. Low values
32 increase the system load (beware!)
33
34 When loaded, a net device with the name 'eth?' becomes available,
35 which can be controlled with the usual 'ifconfig' command.
36
37 It is possible to compile this driver into the kernel like other
38 (net) drivers. For this purpose, some source files (e.g. config-files
39 makefiles, Space.c) must be changed accordingly. (You may refer to
40 other drivers how to do it.) In this case, the device will be detected
41 at boot time and (probably) appear as 'eth0'.
42
43 Theory of Operation
44 -------------------
45 Because the ATARI DMA port is usually shared between several
46 devices (eg. harddisk, floppy) we cannot block the ACSI bus
47 while waiting for interrupts. Therefore we use a polling mechanism
48 to fetch packets from the adapter. For the same reason, we send
49 packets without checking that the previous packet has been sent to
50 the LAN. We rely on the higher levels of the networking code to detect
51 missing packets and resend them.
52
53 Before we access the ATARI DMA controller, we check if another
54 process is using the DMA. If not, we lock the DMA, perform one or
55 more packet transfers and unlock the DMA before returning.
56 We do not use 'stdma_lock' unconditionally because it is unclear
57 if the networking code can be set to sleep, which will happen if
58 another (possibly slow) device is using the DMA controller.
59
60 The polling is done via timer interrupts which periodically
61 'simulate' an interrupt from the Ethernet adapter. The time (in jiffies)
62 between polls varies depending on an estimate of the net activity.
63 The allowed range is given by the variable 'bionet_min_poll_time'
64 for the lower (fastest) limit and the constant 'MAX_POLL_TIME'
65 for the higher (slowest) limit.
66
67 Whenever a packet arrives, we switch to fastest response by setting
68 the polling time to its lowest limit. If the following poll fails,
69 because no packets have arrived, we increase the time for the next
70 poll. When the net activity is low, the polling time effectively
71 stays at its maximum value, resulting in the lowest load for the
72 machine.
73 */
74
75 #define MAX_POLL_TIME 10
76
77 static char *version =
78 "pamsnet.c:v0.2beta 30-mar-96 (c) Torsten Lang.\n";
79
80 #include <linux/module.h>
81
82 #include <linux/kernel.h>
83 #include <linux/sched.h>
84 #include <linux/types.h>
85 #include <linux/fcntl.h>
86 #include <linux/interrupt.h>
87 #include <linux/ptrace.h>
88 #include <linux/ioport.h>
89 #include <linux/in.h>
90 #include <linux/slab.h>
91 #include <linux/string.h>
92 #include <asm/system.h>
93 #include <asm/pgtable.h>
94 #include <asm/bitops.h>
95 #include <asm/io.h>
96 #include <asm/dma.h>
97 #include <linux/errno.h>
98 #include <asm/atarihw.h>
99 #include <asm/atariints.h>
100 #include <asm/atari_stdma.h>
101 #include <asm/atari_acsi.h>
102
103 #include <linux/delay.h>
104 #include <linux/timer.h>
105 #include <linux/init.h>
106
107 #include <linux/netdevice.h>
108 #include <linux/etherdevice.h>
109 #include <linux/skbuff.h>
110
111 #undef READ
112 #undef WRITE
113
114 extern struct net_device *init_etherdev(struct net_device *dev, int sizeof_private);
115
116 /* use 0 for production, 1 for verification, >2 for debug
117 */
118 #ifndef NET_DEBUG
119 #define NET_DEBUG 0
120 #endif
121 /*
122 * Global variable 'pamsnet_debug'. Can be set at load time by 'insmod'
123 */
124 unsigned int pamsnet_debug = NET_DEBUG;
125 MODULE_PARM(pamsnet_debug, "i");
126 MODULE_PARM_DESC(pamsnet_debug, "pamsnet debug enable (0-1)");
127 MODULE_LICENSE("GPL");
128
129 static unsigned int pamsnet_min_poll_time = 2;
130
131
132 /* Information that need to be kept for each board.
133 */
134 struct net_local {
135 struct net_device_stats stats;
136 long open_time; /* for debugging */
137 int poll_time; /* polling time varies with net load */
138 };
139
140 static struct nic_pkt_s { /* packet format */
141 unsigned char buffer[2048];
142 } *nic_packet = 0;
143 unsigned char *phys_nic_packet;
144
145 typedef unsigned char HADDR[6]; /* 6-byte hardware address of lance */
146
147 /* Index to functions, as function prototypes.
148 */
149 static void start (int target);
150 static int stop (int target);
151 static int testpkt (int target);
152 static int sendpkt (int target, unsigned char *buffer, int length);
153 static int receivepkt (int target, unsigned char *buffer);
154 static int inquiry (int target, unsigned char *buffer);
155 static HADDR *read_hw_addr(int target, unsigned char *buffer);
156 static void setup_dma (void *address, unsigned rw_flag, int num_blocks);
157 static int send_first (int target, unsigned char byte);
158 static int send_1_5 (int lun, unsigned char *command, int dma);
159 static int get_status (void);
160 static int calc_received (void *start_address);
161
162 extern int pamsnet_probe(struct net_device *dev);
163
164 static int pamsnet_open(struct net_device *dev);
165 static int pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev);
166 static void pamsnet_poll_rx(struct net_device *);
167 static int pamsnet_close(struct net_device *dev);
168 static struct net_device_stats *net_get_stats(struct net_device *dev);
169 static void pamsnet_tick(unsigned long);
170
171 static void pamsnet_intr(int irq, void *data, struct pt_regs *fp);
172
173 static struct timer_list pamsnet_timer = { function: pamsnet_tick };
174
175 #define STRAM_ADDR(a) (((a) & 0xff000000) == 0)
176
177 typedef struct
178 {
179 unsigned char reserved1[0x38];
180 HADDR hwaddr;
181 unsigned char reserved2[0x1c2];
182 } DMAHWADDR;
183
184 /*
185 * Definitions of commands understood by the PAMs DMA adaptor.
186 *
187 * In general the DMA adaptor uses LUN 0, 5, 6 and 7 on one ID changeable
188 * by the PAM's Net software.
189 *
190 * LUN 0 works as a harddisk. You can boot the PAM's Net driver there.
191 * LUN 5 works as a harddisk and lets you access the RAM and some I/O HW
192 * area. In sector 0, bytes 0x38-0x3d you find the ethernet HW address
193 * of the adaptor.
194 * LUN 6 works as a harddisk and lets you access the firmware ROM.
195 * LUN 7 lets you send and receive packets.
196 *
197 * Some commands like the INQUIRY command work identical on all used LUNs.
198 *
199 * UNKNOWN1 seems to read some data.
200 * Command length is 6 bytes.
201 * UNKNOWN2 seems to read some data (command byte 1 must be !=0). The
202 * following bytes seem to be something like an allocation length.
203 * Command length is 6 bytes.
204 * READPKT reads a packet received by the DMA adaptor.
205 * Command length is 6 bytes.
206 * WRITEPKT sends a packet transferred by the following DMA phase. The length
207 * of the packet is transferred in command bytes 3 and 4.
208 * The adaptor automatically replaces the src hw address in an ethernet
209 * packet by its own hw address.
210 * Command length is 6 bytes.
211 * INQUIRY has the same function as the INQUIRY command supported by harddisks
212 * and other SCSI devices. It lets you detect which device you found
213 * at a given address.
214 * Command length is 6 bytes.
215 * START initializes the DMA adaptor. After this command it is able to send
216 * and receive packets. There is no status byte returned!
217 * Command length is 1 byte.
218 * NUMPKTS gives back the number of received packets waiting in the queue in
219 * the status byte.
220 * Command length is 1 byte.
221 * UNKNOWN3
222 * UNKNOWN4 Function of these three commands is unknown.
223 * UNKNOWN5 The command length of these three commands is 1 byte.
224 * DESELECT immediately deselects the DMA adaptor. May important with interrupt
225 * driven operation.
226 * Command length is 1 byte.
227 * STOP resets the DMA adaptor. After this command packets can no longer
228 * be received or transferred.
229 * Command length is 6 byte.
230 */
231
232 enum {UNKNOWN1=3, READPKT=8, UNKNOWN2, WRITEPKT=10, INQUIRY=18, START,
233 NUMPKTS=22, UNKNOWN3, UNKNOWN4, UNKNOWN5, DESELECT, STOP};
234
235 #define READSECTOR READPKT
236 #define WRITESECTOR WRITEPKT
237
238 u_char *inquire8="MV PAM's NET/GK";
239
240 #define DMALOW dma_wd.dma_lo
241 #define DMAMID dma_wd.dma_md
242 #define DMAHIGH dma_wd.dma_hi
243 #define DACCESS dma_wd.fdc_acces_seccount
244
245 #define MFP_GPIP mfp.par_dt_reg
246
247 /* Some useful functions */
248
249 #define INT (!(MFP_GPIP & 0x20))
250 #define DELAY ({MFP_GPIP; MFP_GPIP; MFP_GPIP;})
251 #define WRITEMODE(value) \
252 ({ u_short dummy = value; \
253 __asm__ volatile("movew %0, 0xFFFF8606" : : "d"(dummy)); \
254 DELAY; \
255 })
256 #define WRITEBOTH(value1, value2) \
257 ({ u_long dummy = (u_long)(value1)<<16 | (u_short)(value2); \
258 __asm__ volatile("movel %0, 0xFFFF8604" : : "d"(dummy)); \
259 DELAY; \
260 })
261
262 /* Definitions for DMODE */
263
264 #define READ 0x000
265 #define WRITE 0x100
266
267 #define DMA_FDC 0x080
268 #define DMA_ACSI 0x000
269
270 #define DMA_DISABLE 0x040
271
272 #define SEC_COUNT 0x010
273 #define DMA_WINDOW 0x000
274
275 #define REG_ACSI 0x008
276 #define REG_FDC 0x000
277
278 #define A1 0x002
279
280 /* Timeout constants */
281
282 #define TIMEOUTCMD HZ/2 /* ca. 500ms */
283 #define TIMEOUTDMA HZ /* ca. 1s */
284 #define COMMAND_DELAY 500 /* ca. 0.5ms */
285
286 unsigned rw;
287 int lance_target = -1;
288 int if_up = 0;
289
290 /* The following routines access the ethernet board connected to the
291 * ACSI port via the st_dma chip.
292 */
293
294 /* The following lowlevel routines work on physical addresses only and assume
295 * that eventually needed buffers are
296 * - completely located in ST RAM
297 * - are contigous in the physical address space
298 */
299
300 /* Setup the DMA counter */
301
302 static void
setup_dma(address,rw_flag,num_blocks)303 setup_dma (address, rw_flag, num_blocks)
304 void *address;
305 unsigned rw_flag;
306 int num_blocks;
307 {
308 WRITEMODE((unsigned) rw_flag | DMA_FDC | SEC_COUNT | REG_ACSI |
309 A1);
310 WRITEMODE((unsigned)(rw_flag ^ WRITE) | DMA_FDC | SEC_COUNT | REG_ACSI |
311 A1);
312 WRITEMODE((unsigned) rw_flag | DMA_FDC | SEC_COUNT | REG_ACSI |
313 A1);
314 DMALOW = (unsigned char)((unsigned long)address & 0xFF);
315 DMAMID = (unsigned char)(((unsigned long)address >> 8) & 0xFF);
316 DMAHIGH = (unsigned char)(((unsigned long)address >> 16) & 0xFF);
317 WRITEBOTH((unsigned)num_blocks & 0xFF,
318 rw_flag | DMA_FDC | DMA_WINDOW | REG_ACSI | A1);
319 rw = rw_flag;
320 }
321
322 /* Send the first byte of an command block */
323
324 static int
send_first(target,byte)325 send_first (target, byte)
326 int target;
327 unsigned char byte;
328 {
329 rw = READ;
330 acsi_delay_end(COMMAND_DELAY);
331 /*
332 * wake up ACSI
333 */
334 WRITEMODE(DMA_FDC | DMA_WINDOW | REG_ACSI);
335 /*
336 * write command byte
337 */
338 WRITEBOTH((target << 5) | (byte & 0x1F), DMA_FDC |
339 DMA_WINDOW | REG_ACSI | A1);
340 return (!acsi_wait_for_IRQ(TIMEOUTCMD));
341 }
342
343 /* Send the rest of an command block */
344
345 static int
send_1_5(lun,command,dma)346 send_1_5 (lun, command, dma)
347 int lun;
348 unsigned char *command;
349 int dma;
350 {
351 int i, j;
352
353 for (i=0; i<5; i++) {
354 WRITEBOTH((!i ? (((lun & 0x7) << 5) | (command[i] & 0x1F))
355 : command[i]),
356 rw | REG_ACSI | DMA_WINDOW |
357 ((i < 4) ? DMA_FDC
358 : (dma ? DMA_ACSI
359 : DMA_FDC)) | A1);
360 if (i < 4 && (j = !acsi_wait_for_IRQ(TIMEOUTCMD)))
361 return (j);
362 }
363 return (0);
364 }
365
366 /* Read a status byte */
367
368 static int
get_status(void)369 get_status (void)
370 {
371 WRITEMODE(DMA_FDC | DMA_WINDOW | REG_ACSI | A1);
372 acsi_delay_start();
373 return ((int)(DACCESS & 0xFF));
374 }
375
376 /* Calculate the number of received bytes */
377
378 static int
calc_received(start_address)379 calc_received (start_address)
380 void *start_address;
381 {
382 return (int)(
383 (((unsigned long)DMAHIGH << 16) | ((unsigned)DMAMID << 8) | DMALOW)
384 - (unsigned long)start_address);
385 }
386
387 /* The following midlevel routines still work on physical addresses ... */
388
389 /* start() starts the PAM's DMA adaptor */
390
391 static void
start(target)392 start (target)
393 int target;
394 {
395 send_first(target, START);
396 }
397
398 /* stop() stops the PAM's DMA adaptor and returns a value of zero in case of success */
399
400 static int
stop(target)401 stop (target)
402 int target;
403 {
404 int ret = -1;
405 unsigned char cmd_buffer[5];
406
407 if (send_first(target, STOP))
408 goto bad;
409 cmd_buffer[0] = cmd_buffer[1] = cmd_buffer[2] =
410 cmd_buffer[3] = cmd_buffer[4] = 0;
411 if (send_1_5(7, cmd_buffer, 0) ||
412 !acsi_wait_for_IRQ(TIMEOUTDMA) ||
413 get_status())
414 goto bad;
415 ret = 0;
416 bad:
417 return (ret);
418 }
419
420 /* testpkt() returns the number of received packets waiting in the queue */
421
422 static int
testpkt(target)423 testpkt(target)
424 int target;
425 {
426 int ret = -1;
427
428 if (send_first(target, NUMPKTS))
429 goto bad;
430 ret = get_status();
431 bad:
432 return (ret);
433 }
434
435 /* inquiry() returns 0 when PAM's DMA found, -1 when timeout, -2 otherwise */
436 /* Please note: The buffer is for internal use only but must be defined! */
437
438 static int
inquiry(target,buffer)439 inquiry (target, buffer)
440 int target;
441 unsigned char *buffer;
442 {
443 int ret = -1;
444 unsigned char *vbuffer = phys_to_virt((unsigned long)buffer);
445 unsigned char cmd_buffer[5];
446
447 if (send_first(target, INQUIRY))
448 goto bad;
449 setup_dma(buffer, READ, 1);
450 vbuffer[8] = vbuffer[27] = 0; /* Avoid confusion with previous read data */
451 cmd_buffer[0] = cmd_buffer[1] = cmd_buffer[2] = cmd_buffer[4] = 0;
452 cmd_buffer[3] = 48;
453 if (send_1_5(5, cmd_buffer, 1) ||
454 !acsi_wait_for_IRQ(TIMEOUTDMA) ||
455 get_status() ||
456 (calc_received(buffer) < 32))
457 goto bad;
458 dma_cache_maintenance((unsigned long)(buffer+8), 20, 0);
459 if (memcmp(inquire8, vbuffer+8, 20))
460 goto bad;
461 ret = 0;
462 bad:
463 if (!!NET_DEBUG) {
464 vbuffer[8+20]=0;
465 printk("inquiry of target %d: %s\n", target, vbuffer+8);
466 }
467 return (ret);
468 }
469
470 /*
471 * read_hw_addr() reads the sector containing the hwaddr and returns
472 * a pointer to it (virtual address!) or 0 in case of an error
473 */
474
475 static HADDR
read_hw_addr(target,buffer)476 *read_hw_addr(target, buffer)
477 int target;
478 unsigned char *buffer;
479 {
480 HADDR *ret = 0;
481 unsigned char cmd_buffer[5];
482
483 if (send_first(target, READSECTOR))
484 goto bad;
485 setup_dma(buffer, READ, 1);
486 cmd_buffer[0] = cmd_buffer[1] = cmd_buffer[2] = cmd_buffer[4] = 0;
487 cmd_buffer[3] = 1;
488 if (send_1_5(5, cmd_buffer, 1) ||
489 !acsi_wait_for_IRQ(TIMEOUTDMA) ||
490 get_status())
491 goto bad;
492 ret = phys_to_virt(&(((DMAHWADDR *)buffer)->hwaddr));
493 dma_cache_maintenance((unsigned long)buffer, 512, 0);
494 bad:
495 return (ret);
496 }
497
498 static void
pamsnet_intr(irq,data,fp)499 pamsnet_intr(irq, data, fp)
500 int irq;
501 void *data;
502 struct pt_regs *fp;
503 {
504 return;
505 }
506
507 /* receivepkt() loads a packet to a given buffer and returns its length */
508
509 static int
receivepkt(target,buffer)510 receivepkt (target, buffer)
511 int target;
512 unsigned char *buffer;
513 {
514 int ret = -1;
515 unsigned char cmd_buffer[5];
516
517 if (send_first(target, READPKT))
518 goto bad;
519 setup_dma(buffer, READ, 3);
520 cmd_buffer[0] = cmd_buffer[1] = cmd_buffer[2] = cmd_buffer[4] = 0;
521 cmd_buffer[3] = 3;
522 if (send_1_5(7, cmd_buffer, 1) ||
523 !acsi_wait_for_IRQ(TIMEOUTDMA) ||
524 get_status())
525 goto bad;
526 ret = calc_received(buffer);
527 bad:
528 return (ret);
529 }
530
531 /* sendpkt() sends a packet and returns a value of zero when the packet was sent
532 successfully */
533
534 static int
sendpkt(target,buffer,length)535 sendpkt (target, buffer, length)
536 int target;
537 unsigned char *buffer;
538 int length;
539 {
540 int ret = -1;
541 unsigned char cmd_buffer[5];
542
543 if (send_first(target, WRITEPKT))
544 goto bad;
545 setup_dma(buffer, WRITE, 3);
546 cmd_buffer[0] = cmd_buffer[1] = cmd_buffer[4] = 0;
547 cmd_buffer[2] = length >> 8;
548 cmd_buffer[3] = length & 0xFF;
549 if (send_1_5(7, cmd_buffer, 1) ||
550 !acsi_wait_for_IRQ(TIMEOUTDMA) ||
551 get_status())
552 goto bad;
553 ret = 0;
554 bad:
555 return (ret);
556 }
557
558 /* The following higher level routines work on virtual addresses and convert them to
559 * physical addresses when passed to the lowlevel routines. It's up to the higher level
560 * routines to copy data from Alternate RAM to ST RAM if neccesary!
561 */
562
563 /* Check for a network adaptor of this type, and return '0' if one exists.
564 */
565
566 int __init
pamsnet_probe(dev)567 pamsnet_probe (dev)
568 struct net_device *dev;
569 {
570 int i;
571 HADDR *hwaddr;
572
573 unsigned char station_addr[6];
574 static unsigned version_printed;
575 /* avoid "Probing for..." printed 4 times - the driver is supporting only one adapter now! */
576 static int no_more_found;
577
578 if (no_more_found)
579 return -ENODEV;
580
581 SET_MODULE_OWNER(dev);
582
583 no_more_found = 1;
584
585 printk("Probing for PAM's Net/GK Adapter...\n");
586
587 /* Allocate the DMA buffer here since we need it for probing! */
588
589 nic_packet = (struct nic_pkt_s *)acsi_buffer;
590 phys_nic_packet = (unsigned char *)phys_acsi_buffer;
591 if (pamsnet_debug > 0) {
592 printk("nic_packet at 0x%p, phys at 0x%p\n",
593 nic_packet, phys_nic_packet );
594 }
595
596 stdma_lock(pamsnet_intr, NULL);
597 DISABLE_IRQ();
598
599 for (i=0; i<8; i++) {
600 /* Do two inquiries to cover cases with strange equipment on previous ID */
601 /* blocking the ACSI bus (like the SLMC804 laser printer controller... */
602 inquiry(i, phys_nic_packet);
603 if (!inquiry(i, phys_nic_packet)) {
604 lance_target = i;
605 break;
606 }
607 }
608
609 if (!!NET_DEBUG)
610 printk("ID: %d\n",i);
611
612 if (lance_target >= 0) {
613 if (!(hwaddr = read_hw_addr(lance_target, phys_nic_packet)))
614 lance_target = -1;
615 else
616 memcpy (station_addr, hwaddr, ETH_ALEN);
617 }
618
619 ENABLE_IRQ();
620 stdma_release();
621
622 if (lance_target < 0)
623 printk("No PAM's Net/GK found.\n");
624
625 if ((dev == NULL) || (lance_target < 0))
626 return -ENODEV;
627 if (pamsnet_debug > 0 && version_printed++ == 0)
628 printk(version);
629
630 printk("%s: %s found on target %01d, eth-addr: %02x:%02x:%02x:%02x:%02x:%02x.\n",
631 dev->name, "PAM's Net/GK", lance_target,
632 station_addr[0], station_addr[1], station_addr[2],
633 station_addr[3], station_addr[4], station_addr[5]);
634
635 /* Initialize the device structure. */
636 if (dev->priv == NULL)
637 dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
638 if (!dev->priv)
639 return -ENOMEM;
640 memset(dev->priv, 0, sizeof(struct net_local));
641
642 dev->open = pamsnet_open;
643 dev->stop = pamsnet_close;
644 dev->hard_start_xmit = pamsnet_send_packet;
645 dev->get_stats = net_get_stats;
646
647 /* Fill in the fields of the device structure with ethernet-generic
648 * values. This should be in a common file instead of per-driver.
649 */
650
651 for (i = 0; i < ETH_ALEN; i++) {
652 #if 0
653 dev->broadcast[i] = 0xff;
654 #endif
655 dev->dev_addr[i] = station_addr[i];
656 }
657 ether_setup(dev);
658
659 return(0);
660 }
661
662 /* Open/initialize the board. This is called (in the current kernel)
663 sometime after booting when the 'ifconfig' program is run.
664
665 This routine should set everything up anew at each open, even
666 registers that "should" only need to be set once at boot, so that
667 there is non-reboot way to recover if something goes wrong.
668 */
669 static int
pamsnet_open(struct net_device * dev)670 pamsnet_open(struct net_device *dev) {
671 struct net_local *lp = (struct net_local *)dev->priv;
672
673 if (pamsnet_debug > 0)
674 printk("pamsnet_open\n");
675 stdma_lock(pamsnet_intr, NULL);
676 DISABLE_IRQ();
677
678 /* Reset the hardware here.
679 */
680 if (!if_up)
681 start(lance_target);
682 if_up = 1;
683 lp->open_time = 0; /*jiffies*/
684 lp->poll_time = MAX_POLL_TIME;
685
686 dev->tbusy = 0;
687 dev->interrupt = 0;
688 dev->start = 1;
689
690 ENABLE_IRQ();
691 stdma_release();
692 pamsnet_timer.data = (long)dev;
693 pamsnet_timer.expires = jiffies + lp->poll_time;
694 add_timer(&pamsnet_timer);
695 return 0;
696 }
697
698 static int
pamsnet_send_packet(struct sk_buff * skb,struct net_device * dev)699 pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev) {
700 struct net_local *lp = (struct net_local *)dev->priv;
701 unsigned long flags;
702
703 /* Block a timer-based transmit from overlapping. This could better be
704 * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
705 */
706 save_flags(flags);
707 cli();
708
709 if (stdma_islocked()) {
710 restore_flags(flags);
711 lp->stats.tx_errors++;
712 }
713 else {
714 int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
715 unsigned long buf = virt_to_phys(skb->data);
716 int stat;
717
718 stdma_lock(pamsnet_intr, NULL);
719 DISABLE_IRQ();
720
721 restore_flags(flags);
722 if( !STRAM_ADDR(buf+length-1) ) {
723 memcpy(nic_packet->buffer, skb->data, length);
724 buf = (unsigned long)phys_nic_packet;
725 }
726
727 dma_cache_maintenance(buf, length, 1);
728
729 stat = sendpkt(lance_target, (unsigned char *)buf, length);
730 ENABLE_IRQ();
731 stdma_release();
732
733 dev->trans_start = jiffies;
734 dev->tbusy = 0;
735 lp->stats.tx_packets++;
736 lp->stats.tx_bytes+=length;
737 }
738 dev_kfree_skb(skb);
739
740 return 0;
741 }
742
743 /* We have a good packet(s), get it/them out of the buffers.
744 */
745 static void
pamsnet_poll_rx(struct net_device * dev)746 pamsnet_poll_rx(struct net_device *dev) {
747 struct net_local *lp = (struct net_local *)dev->priv;
748 int boguscount;
749 int pkt_len;
750 struct sk_buff *skb;
751 unsigned long flags;
752
753 save_flags(flags);
754 cli();
755 /* ++roman: Take care at locking the ST-DMA... This must be done with ints
756 * off, since otherwise an int could slip in between the question and the
757 * locking itself, and then we'd go to sleep... And locking itself is
758 * necessary to keep the floppy_change timer from working with ST-DMA
759 * registers. */
760 if (stdma_islocked()) {
761 restore_flags(flags);
762 return;
763 }
764 stdma_lock(pamsnet_intr, NULL);
765 DISABLE_IRQ();
766 restore_flags(flags);
767
768 boguscount = testpkt(lance_target);
769 if( lp->poll_time < MAX_POLL_TIME ) lp->poll_time++;
770
771 while(boguscount--) {
772 pkt_len = receivepkt(lance_target, phys_nic_packet);
773
774 if( pkt_len < 60 ) break;
775
776 /* Good packet... */
777
778 dma_cache_maintenance((unsigned long)phys_nic_packet, pkt_len, 0);
779
780 lp->poll_time = pamsnet_min_poll_time; /* fast poll */
781 if( pkt_len >= 60 && pkt_len <= 2048 ) {
782 if (pkt_len > 1514)
783 pkt_len = 1514;
784
785 /* Malloc up new buffer.
786 */
787 skb = alloc_skb(pkt_len, GFP_ATOMIC);
788 if (skb == NULL) {
789 printk("%s: Memory squeeze, dropping packet.\n",
790 dev->name);
791 lp->stats.rx_dropped++;
792 break;
793 }
794 skb->len = pkt_len;
795 skb->dev = dev;
796
797 /* 'skb->data' points to the start of sk_buff data area.
798 */
799 memcpy(skb->data, nic_packet->buffer, pkt_len);
800 netif_rx(skb);
801 dev->last_rx = jiffies;
802 lp->stats.rx_packets++;
803 lp->stats.rx_bytes+=pkt_len;
804 }
805 }
806
807 /* If any worth-while packets have been received, dev_rint()
808 has done a mark_bh(INET_BH) for us and will work on them
809 when we get to the bottom-half routine.
810 */
811
812 ENABLE_IRQ();
813 stdma_release();
814 return;
815 }
816
817 /* pamsnet_tick: called by pamsnet_timer. Reads packets from the adapter,
818 * passes them to the higher layers and restarts the timer.
819 */
820 static void
pamsnet_tick(unsigned long data)821 pamsnet_tick(unsigned long data) {
822 struct net_device *dev = (struct net_device *)data;
823 struct net_local *lp = (struct net_local *)dev->priv;
824
825 if( pamsnet_debug > 0 && (lp->open_time++ & 7) == 8 )
826 printk("pamsnet_tick: %ld\n", lp->open_time);
827
828 pamsnet_poll_rx(dev);
829
830 pamsnet_timer.expires = jiffies + lp->poll_time;
831 add_timer(&pamsnet_timer);
832 }
833
834 /* The inverse routine to pamsnet_open().
835 */
836 static int
pamsnet_close(struct net_device * dev)837 pamsnet_close(struct net_device *dev) {
838 struct net_local *lp = (struct net_local *)dev->priv;
839
840 if (pamsnet_debug > 0)
841 printk("pamsnet_close, open_time=%ld\n", lp->open_time);
842 del_timer(&pamsnet_timer);
843 stdma_lock(pamsnet_intr, NULL);
844 DISABLE_IRQ();
845
846 if (if_up)
847 stop(lance_target);
848 if_up = 0;
849
850 lp->open_time = 0;
851
852 dev->tbusy = 1;
853 dev->start = 0;
854
855 ENABLE_IRQ();
856 stdma_release();
857 return 0;
858 }
859
860 /* Get the current statistics.
861 This may be called with the card open or closed.
862 */
net_get_stats(struct net_device * dev)863 static struct net_device_stats *net_get_stats(struct net_device *dev)
864 {
865 struct net_local *lp = (struct net_local *)dev->priv;
866 return &lp->stats;
867 }
868
869
870 #ifdef MODULE
871
872 static struct net_device pam_dev;
873
874 int
init_module(void)875 init_module(void) {
876 int err;
877
878 pam_dev.init = pamsnet_probe;
879 if ((err = register_netdev(&pam_dev))) {
880 if (err == -EEXIST) {
881 printk("PAM's Net/GK: devices already present. Module not loaded.\n");
882 }
883 return err;
884 }
885 return 0;
886 }
887
888 void
cleanup_module(void)889 cleanup_module(void) {
890 unregister_netdev(&pam_dev);
891 }
892
893 #endif /* MODULE */
894
895 /* Local variables:
896 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include
897 -b m68k-linuxaout -Wall -Wstrict-prototypes -O2
898 -fomit-frame-pointer -pipe -DMODULE -I../../net/inet -c atari_pamsnet.c"
899 * version-control: t
900 * kept-new-versions: 5
901 * tab-width: 8
902 * End:
903 */
904