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