~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/net/atari_pamsnet.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.