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