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