Linux 2.6.20.7
[linux/fpc-iii.git] / drivers / net / atari_pamsnet.c
blob3b543614928606cae76a4bcfc7a661723c1f6668
1 /* atari_pamsnet.c PAMsNet device driver for linux68k.
3 * Version: @(#)PAMsNet.c 0.2ß 03/31/96
5 * Author: Torsten Lang <Torsten.Lang@ap.physik.uni-giessen.de>
6 * <Torsten.Lang@jung.de>
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>
13 * Little adaptions for integration into pl7 by Roman Hodek
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.
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'.
25 'pamsnet_debug'
26 controls the amount of diagnostic messages:
27 0 : no messages
28 >0 : see code for meaning of printed messages
30 'pamsnet_min_poll_time' (always >=1)
31 gives the time (in jiffies) between polls. Low values
32 increase the system load (beware!)
34 When loaded, a net device with the name 'eth?' becomes available,
35 which can be controlled with the usual 'ifconfig' command.
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'.
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.
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.
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.
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.
75 #define MAX_POLL_TIME 10
77 static char *version =
78 "pamsnet.c:v0.2beta 30-mar-96 (c) Torsten Lang.\n";
80 #include <linux/module.h>
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>
102 #include <linux/delay.h>
103 #include <linux/timer.h>
104 #include <linux/init.h>
106 #include <linux/netdevice.h>
107 #include <linux/etherdevice.h>
108 #include <linux/skbuff.h>
110 #undef READ
111 #undef WRITE
113 /* use 0 for production, 1 for verification, >2 for debug
115 #ifndef NET_DEBUG
116 #define NET_DEBUG 0
117 #endif
119 * Global variable 'pamsnet_debug'. Can be set at load time by 'insmod'
121 unsigned int pamsnet_debug = NET_DEBUG;
122 module_param(pamsnet_debug, int, 0);
123 MODULE_PARM_DESC(pamsnet_debug, "pamsnet debug enable (0-1)");
124 MODULE_LICENSE("GPL");
126 static unsigned int pamsnet_min_poll_time = 2;
129 /* Information that need to be kept for each board.
131 struct net_local {
132 struct net_device_stats stats;
133 long open_time; /* for debugging */
134 int poll_time; /* polling time varies with net load */
137 static struct nic_pkt_s { /* packet format */
138 unsigned char buffer[2048];
139 } *nic_packet = 0;
140 unsigned char *phys_nic_packet;
142 typedef unsigned char HADDR[6]; /* 6-byte hardware address of lance */
144 /* Index to functions, as function prototypes.
146 static void start (int target);
147 static int stop (int target);
148 static int testpkt (int target);
149 static int sendpkt (int target, unsigned char *buffer, int length);
150 static int receivepkt (int target, unsigned char *buffer);
151 static int inquiry (int target, unsigned char *buffer);
152 static HADDR *read_hw_addr(int target, unsigned char *buffer);
153 static void setup_dma (void *address, unsigned rw_flag, int num_blocks);
154 static int send_first (int target, unsigned char byte);
155 static int send_1_5 (int lun, unsigned char *command, int dma);
156 static int get_status (void);
157 static int calc_received (void *start_address);
159 static int pamsnet_open(struct net_device *dev);
160 static int pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev);
161 static void pamsnet_poll_rx(struct net_device *);
162 static int pamsnet_close(struct net_device *dev);
163 static struct net_device_stats *net_get_stats(struct net_device *dev);
164 static void pamsnet_tick(unsigned long);
166 static irqreturn_t pamsnet_intr(int irq, void *data);
168 static DEFINE_TIMER(pamsnet_timer, pamsnet_tick, 0, 0);
170 #define STRAM_ADDR(a) (((a) & 0xff000000) == 0)
172 typedef struct
174 unsigned char reserved1[0x38];
175 HADDR hwaddr;
176 unsigned char reserved2[0x1c2];
177 } DMAHWADDR;
180 * Definitions of commands understood by the PAMs DMA adaptor.
182 * In general the DMA adaptor uses LUN 0, 5, 6 and 7 on one ID changeable
183 * by the PAM's Net software.
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.
192 * Some commands like the INQUIRY command work identical on all used LUNs.
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.
227 enum {UNKNOWN1=3, READPKT=8, UNKNOWN2, WRITEPKT=10, INQUIRY=18, START,
228 NUMPKTS=22, UNKNOWN3, UNKNOWN4, UNKNOWN5, DESELECT, STOP};
230 #define READSECTOR READPKT
231 #define WRITESECTOR WRITEPKT
233 u_char *inquire8="MV PAM's NET/GK";
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
240 #define MFP_GPIP mfp.par_dt_reg
242 /* Some useful functions */
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; \
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; \
257 /* Definitions for DMODE */
259 #define READ 0x000
260 #define WRITE 0x100
262 #define DMA_FDC 0x080
263 #define DMA_ACSI 0x000
265 #define DMA_DISABLE 0x040
267 #define SEC_COUNT 0x010
268 #define DMA_WINDOW 0x000
270 #define REG_ACSI 0x008
271 #define REG_FDC 0x000
273 #define A1 0x002
275 /* Timeout constants */
277 #define TIMEOUTCMD HZ/2 /* ca. 500ms */
278 #define TIMEOUTDMA HZ /* ca. 1s */
279 #define COMMAND_DELAY 500 /* ca. 0.5ms */
281 unsigned rw;
282 int lance_target = -1;
283 int if_up = 0;
285 /* The following routines access the ethernet board connected to the
286 * ACSI port via the st_dma chip.
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
295 /* Setup the DMA counter */
297 static void
298 setup_dma (address, rw_flag, num_blocks)
299 void *address;
300 unsigned rw_flag;
301 int num_blocks;
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;
317 /* Send the first byte of an command block */
319 static int
320 send_first (target, byte)
321 int target;
322 unsigned char byte;
324 rw = READ;
325 acsi_delay_end(COMMAND_DELAY);
327 * wake up ACSI
329 WRITEMODE(DMA_FDC | DMA_WINDOW | REG_ACSI);
331 * write command byte
333 WRITEBOTH((target << 5) | (byte & 0x1F), DMA_FDC |
334 DMA_WINDOW | REG_ACSI | A1);
335 return (!acsi_wait_for_IRQ(TIMEOUTCMD));
338 /* Send the rest of an command block */
340 static int
341 send_1_5 (lun, command, dma)
342 int lun;
343 unsigned char *command;
344 int dma;
346 int i, j;
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);
358 return (0);
361 /* Read a status byte */
363 static int
364 get_status (void)
366 WRITEMODE(DMA_FDC | DMA_WINDOW | REG_ACSI | A1);
367 acsi_delay_start();
368 return ((int)(DACCESS & 0xFF));
371 /* Calculate the number of received bytes */
373 static int
374 calc_received (start_address)
375 void *start_address;
377 return (int)(
378 (((unsigned long)DMAHIGH << 16) | ((unsigned)DMAMID << 8) | DMALOW)
379 - (unsigned long)start_address);
382 /* The following midlevel routines still work on physical addresses ... */
384 /* start() starts the PAM's DMA adaptor */
386 static void
387 start (target)
388 int target;
390 send_first(target, START);
393 /* stop() stops the PAM's DMA adaptor and returns a value of zero in case of success */
395 static int
396 stop (target)
397 int target;
399 int ret = -1;
400 unsigned char cmd_buffer[5];
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;
411 bad:
412 return (ret);
415 /* testpkt() returns the number of received packets waiting in the queue */
417 static int
418 testpkt(target)
419 int target;
421 int ret = -1;
423 if (send_first(target, NUMPKTS))
424 goto bad;
425 ret = get_status();
426 bad:
427 return (ret);
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! */
433 static int
434 inquiry (target, buffer)
435 int target;
436 unsigned char *buffer;
438 int ret = -1;
439 unsigned char *vbuffer = phys_to_virt((unsigned long)buffer);
440 unsigned char cmd_buffer[5];
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;
457 bad:
458 if (!!NET_DEBUG) {
459 vbuffer[8+20]=0;
460 printk("inquiry of target %d: %s\n", target, vbuffer+8);
462 return (ret);
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
470 static HADDR
471 *read_hw_addr(target, buffer)
472 int target;
473 unsigned char *buffer;
475 HADDR *ret = 0;
476 unsigned char cmd_buffer[5];
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);
489 bad:
490 return (ret);
493 static irqreturn_t
494 pamsnet_intr(irq, data, fp)
495 int irq;
496 void *data;
498 return IRQ_HANDLED;
501 /* receivepkt() loads a packet to a given buffer and returns its length */
503 static int
504 receivepkt (target, buffer)
505 int target;
506 unsigned char *buffer;
508 int ret = -1;
509 unsigned char cmd_buffer[5];
511 if (send_first(target, READPKT))
512 goto bad;
513 setup_dma(buffer, READ, 3);
514 cmd_buffer[0] = cmd_buffer[1] = cmd_buffer[2] = cmd_buffer[4] = 0;
515 cmd_buffer[3] = 3;
516 if (send_1_5(7, cmd_buffer, 1) ||
517 !acsi_wait_for_IRQ(TIMEOUTDMA) ||
518 get_status())
519 goto bad;
520 ret = calc_received(buffer);
521 bad:
522 return (ret);
525 /* sendpkt() sends a packet and returns a value of zero when the packet was sent
526 successfully */
528 static int
529 sendpkt (target, buffer, length)
530 int target;
531 unsigned char *buffer;
532 int length;
534 int ret = -1;
535 unsigned char cmd_buffer[5];
537 if (send_first(target, WRITEPKT))
538 goto bad;
539 setup_dma(buffer, WRITE, 3);
540 cmd_buffer[0] = cmd_buffer[1] = cmd_buffer[4] = 0;
541 cmd_buffer[2] = length >> 8;
542 cmd_buffer[3] = length & 0xFF;
543 if (send_1_5(7, cmd_buffer, 1) ||
544 !acsi_wait_for_IRQ(TIMEOUTDMA) ||
545 get_status())
546 goto bad;
547 ret = 0;
548 bad:
549 return (ret);
552 /* The following higher level routines work on virtual addresses and convert them to
553 * physical addresses when passed to the lowlevel routines. It's up to the higher level
554 * routines to copy data from Alternate RAM to ST RAM if neccesary!
557 /* Check for a network adaptor of this type, and return '0' if one exists.
560 struct net_device * __init pamsnet_probe (int unit)
562 struct net_device *dev;
563 int i;
564 HADDR *hwaddr;
565 int err;
567 unsigned char station_addr[6];
568 static unsigned version_printed;
569 /* avoid "Probing for..." printed 4 times - the driver is supporting only one adapter now! */
570 static int no_more_found;
572 if (no_more_found)
573 return ERR_PTR(-ENODEV);
574 no_more_found = 1;
576 dev = alloc_etherdev(sizeof(struct net_local));
577 if (!dev)
578 return ERR_PTR(-ENOMEM);
579 if (unit >= 0) {
580 sprintf(dev->name, "eth%d", unit);
581 netdev_boot_setup_check(dev);
583 SET_MODULE_OWNER(dev);
585 printk("Probing for PAM's Net/GK Adapter...\n");
587 /* Allocate the DMA buffer here since we need it for probing! */
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 );
596 stdma_lock(pamsnet_intr, NULL);
597 DISABLE_IRQ();
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;
609 if (!!NET_DEBUG)
610 printk("ID: %d\n",i);
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);
619 ENABLE_IRQ();
620 stdma_release();
622 if (lance_target < 0) {
623 printk("No PAM's Net/GK found.\n");
624 free_netdev(dev);
625 return ERR_PTR(-ENODEV);
628 if (pamsnet_debug > 0 && version_printed++ == 0)
629 printk(version);
631 printk("%s: %s found on target %01d, eth-addr: %02x:%02x:%02x:%02x:%02x:%02x.\n",
632 dev->name, "PAM's Net/GK", lance_target,
633 station_addr[0], station_addr[1], station_addr[2],
634 station_addr[3], station_addr[4], station_addr[5]);
636 /* Initialize the device structure. */
637 dev->open = pamsnet_open;
638 dev->stop = pamsnet_close;
639 dev->hard_start_xmit = pamsnet_send_packet;
640 dev->get_stats = net_get_stats;
642 /* Fill in the fields of the device structure with ethernet-generic
643 * values. This should be in a common file instead of per-driver.
646 for (i = 0; i < ETH_ALEN; i++) {
647 #if 0
648 dev->broadcast[i] = 0xff;
649 #endif
650 dev->dev_addr[i] = station_addr[i];
652 err = register_netdev(dev);
653 if (!err)
654 return dev;
656 free_netdev(dev);
657 return ERR_PTR(err);
660 /* Open/initialize the board. This is called (in the current kernel)
661 sometime after booting when the 'ifconfig' program is run.
663 This routine should set everything up anew at each open, even
664 registers that "should" only need to be set once at boot, so that
665 there is non-reboot way to recover if something goes wrong.
667 static int
668 pamsnet_open(struct net_device *dev) {
669 struct net_local *lp = netdev_priv(dev);
671 if (pamsnet_debug > 0)
672 printk("pamsnet_open\n");
673 stdma_lock(pamsnet_intr, NULL);
674 DISABLE_IRQ();
676 /* Reset the hardware here.
678 if (!if_up)
679 start(lance_target);
680 if_up = 1;
681 lp->open_time = 0; /*jiffies*/
682 lp->poll_time = MAX_POLL_TIME;
684 dev->tbusy = 0;
685 dev->interrupt = 0;
686 dev->start = 1;
688 ENABLE_IRQ();
689 stdma_release();
690 pamsnet_timer.data = (long)dev;
691 pamsnet_timer.expires = jiffies + lp->poll_time;
692 add_timer(&pamsnet_timer);
693 return 0;
696 static int
697 pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev) {
698 struct net_local *lp = netdev_priv(dev);
699 unsigned long flags;
701 /* Block a timer-based transmit from overlapping. This could better be
702 * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
704 local_irq_save(flags);
706 if (stdma_islocked()) {
707 local_irq_restore(flags);
708 lp->stats.tx_errors++;
710 else {
711 int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
712 unsigned long buf = virt_to_phys(skb->data);
713 int stat;
715 stdma_lock(pamsnet_intr, NULL);
716 DISABLE_IRQ();
718 local_irq_restore(flags);
719 if( !STRAM_ADDR(buf+length-1) ) {
720 memcpy(nic_packet->buffer, skb->data, length);
721 buf = (unsigned long)phys_nic_packet;
724 dma_cache_maintenance(buf, length, 1);
726 stat = sendpkt(lance_target, (unsigned char *)buf, length);
727 ENABLE_IRQ();
728 stdma_release();
730 dev->trans_start = jiffies;
731 dev->tbusy = 0;
732 lp->stats.tx_packets++;
733 lp->stats.tx_bytes+=length;
735 dev_kfree_skb(skb);
737 return 0;
740 /* We have a good packet(s), get it/them out of the buffers.
742 static void
743 pamsnet_poll_rx(struct net_device *dev) {
744 struct net_local *lp = netdev_priv(dev);
745 int boguscount;
746 int pkt_len;
747 struct sk_buff *skb;
748 unsigned long flags;
750 local_irq_save(flags);
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 local_irq_restore(flags);
758 return;
760 stdma_lock(pamsnet_intr, NULL);
761 DISABLE_IRQ();
762 local_irq_restore(flags);
764 boguscount = testpkt(lance_target);
765 if( lp->poll_time < MAX_POLL_TIME ) lp->poll_time++;
767 while(boguscount--) {
768 pkt_len = receivepkt(lance_target, phys_nic_packet);
770 if( pkt_len < 60 ) break;
772 /* Good packet... */
774 dma_cache_maintenance((unsigned long)phys_nic_packet, pkt_len, 0);
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;
781 /* Malloc up new buffer.
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;
790 skb->len = pkt_len;
791 skb->dev = dev;
793 /* 'skb->data' points to the start of sk_buff data area.
795 memcpy(skb->data, nic_packet->buffer, pkt_len);
796 netif_rx(skb);
797 dev->last_rx = jiffies;
798 lp->stats.rx_packets++;
799 lp->stats.rx_bytes+=pkt_len;
803 /* If any worth-while packets have been received, dev_rint()
804 has done a mark_bh(INET_BH) for us and will work on them
805 when we get to the bottom-half routine.
808 ENABLE_IRQ();
809 stdma_release();
810 return;
813 /* pamsnet_tick: called by pamsnet_timer. Reads packets from the adapter,
814 * passes them to the higher layers and restarts the timer.
816 static void
817 pamsnet_tick(unsigned long data) {
818 struct net_device *dev = (struct net_device *)data;
819 struct net_local *lp = netdev_priv(dev);
821 if( pamsnet_debug > 0 && (lp->open_time++ & 7) == 8 )
822 printk("pamsnet_tick: %ld\n", lp->open_time);
824 pamsnet_poll_rx(dev);
826 pamsnet_timer.expires = jiffies + lp->poll_time;
827 add_timer(&pamsnet_timer);
830 /* The inverse routine to pamsnet_open().
832 static int
833 pamsnet_close(struct net_device *dev) {
834 struct net_local *lp = netdev_priv(dev);
836 if (pamsnet_debug > 0)
837 printk("pamsnet_close, open_time=%ld\n", lp->open_time);
838 del_timer(&pamsnet_timer);
839 stdma_lock(pamsnet_intr, NULL);
840 DISABLE_IRQ();
842 if (if_up)
843 stop(lance_target);
844 if_up = 0;
846 lp->open_time = 0;
848 dev->tbusy = 1;
849 dev->start = 0;
851 ENABLE_IRQ();
852 stdma_release();
853 return 0;
856 /* Get the current statistics.
857 This may be called with the card open or closed.
859 static struct net_device_stats *net_get_stats(struct net_device *dev)
861 struct net_local *lp = netdev_priv(dev);
862 return &lp->stats;
866 #ifdef MODULE
868 static struct net_device *pam_dev;
870 int init_module(void)
872 pam_dev = pamsnet_probe(-1);
873 if (IS_ERR(pam_dev))
874 return PTR_ERR(pam_dev);
875 return 0;
878 void cleanup_module(void)
880 unregister_netdev(pam_dev);
881 free_netdev(pam_dev);
884 #endif /* MODULE */
886 /* Local variables:
887 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include
888 -b m68k-linuxaout -Wall -Wstrict-prototypes -O2
889 -fomit-frame-pointer -pipe -DMODULE -I../../net/inet -c atari_pamsnet.c"
890 * version-control: t
891 * kept-new-versions: 5
892 * tab-width: 8
893 * End: