linux/drivers/net/ethernet/amd/ariadne.c
<<
>>
Prefs
   1/*
   2 *  Amiga Linux/m68k Ariadne Ethernet Driver
   3 *
   4 *  © Copyright 1995-2003 by Geert Uytterhoeven (geert@linux-m68k.org)
   5 *                           Peter De Schrijver (p2@mind.be)
   6 *
   7 *  ---------------------------------------------------------------------------
   8 *
   9 *  This program is based on
  10 *
  11 *      lance.c:        An AMD LANCE ethernet driver for linux.
  12 *                      Written 1993-94 by Donald Becker.
  13 *
  14 *      Am79C960:       PCnet(tm)-ISA Single-Chip Ethernet Controller
  15 *                      Advanced Micro Devices
  16 *                      Publication #16907, Rev. B, Amendment/0, May 1994
  17 *
  18 *      MC68230:        Parallel Interface/Timer (PI/T)
  19 *                      Motorola Semiconductors, December, 1983
  20 *
  21 *  ---------------------------------------------------------------------------
  22 *
  23 *  This file is subject to the terms and conditions of the GNU General Public
  24 *  License.  See the file COPYING in the main directory of the Linux
  25 *  distribution for more details.
  26 *
  27 *  ---------------------------------------------------------------------------
  28 *
  29 *  The Ariadne is a Zorro-II board made by Village Tronic. It contains:
  30 *
  31 *      - an Am79C960 PCnet-ISA Single-Chip Ethernet Controller with both
  32 *        10BASE-2 (thin coax) and 10BASE-T (UTP) connectors
  33 *
  34 *      - an MC68230 Parallel Interface/Timer configured as 2 parallel ports
  35 */
  36
  37#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  38/*#define DEBUG*/
  39
  40#include <linux/module.h>
  41#include <linux/stddef.h>
  42#include <linux/kernel.h>
  43#include <linux/string.h>
  44#include <linux/errno.h>
  45#include <linux/ioport.h>
  46#include <linux/netdevice.h>
  47#include <linux/etherdevice.h>
  48#include <linux/interrupt.h>
  49#include <linux/skbuff.h>
  50#include <linux/init.h>
  51#include <linux/zorro.h>
  52#include <linux/bitops.h>
  53
  54#include <asm/amigaints.h>
  55#include <asm/amigahw.h>
  56#include <asm/irq.h>
  57
  58#include "ariadne.h"
  59
  60#ifdef ARIADNE_DEBUG
  61int ariadne_debug = ARIADNE_DEBUG;
  62#else
  63int ariadne_debug = 1;
  64#endif
  65
  66/* Macros to Fix Endianness problems */
  67
  68/* Swap the Bytes in a WORD */
  69#define swapw(x)        (((x >> 8) & 0x00ff) | ((x << 8) & 0xff00))
  70/* Get the Low BYTE in a WORD */
  71#define lowb(x)         (x & 0xff)
  72/* Get the Swapped High WORD in a LONG */
  73#define swhighw(x)      ((((x) >> 8) & 0xff00) | (((x) >> 24) & 0x00ff))
  74/* Get the Swapped Low WORD in a LONG */
  75#define swloww(x)       ((((x) << 8) & 0xff00) | (((x) >> 8) & 0x00ff))
  76
  77/* Transmit/Receive Ring Definitions */
  78
  79#define TX_RING_SIZE    5
  80#define RX_RING_SIZE    16
  81
  82#define PKT_BUF_SIZE    1520
  83
  84/* Private Device Data */
  85
  86struct ariadne_private {
  87        volatile struct TDRE *tx_ring[TX_RING_SIZE];
  88        volatile struct RDRE *rx_ring[RX_RING_SIZE];
  89        volatile u_short *tx_buff[TX_RING_SIZE];
  90        volatile u_short *rx_buff[RX_RING_SIZE];
  91        int cur_tx, cur_rx;             /* The next free ring entry */
  92        int dirty_tx;                   /* The ring entries to be free()ed */
  93        char tx_full;
  94};
  95
  96/* Structure Created in the Ariadne's RAM Buffer */
  97
  98struct lancedata {
  99        struct TDRE tx_ring[TX_RING_SIZE];
 100        struct RDRE rx_ring[RX_RING_SIZE];
 101        u_short tx_buff[TX_RING_SIZE][PKT_BUF_SIZE / sizeof(u_short)];
 102        u_short rx_buff[RX_RING_SIZE][PKT_BUF_SIZE / sizeof(u_short)];
 103};
 104
 105static void memcpyw(volatile u_short *dest, u_short *src, int len)
 106{
 107        while (len >= 2) {
 108                *(dest++) = *(src++);
 109                len -= 2;
 110        }
 111        if (len == 1)
 112                *dest = (*(u_char *)src) << 8;
 113}
 114
 115static void ariadne_init_ring(struct net_device *dev)
 116{
 117        struct ariadne_private *priv = netdev_priv(dev);
 118        volatile struct lancedata *lancedata = (struct lancedata *)dev->mem_start;
 119        int i;
 120
 121        netif_stop_queue(dev);
 122
 123        priv->tx_full = 0;
 124        priv->cur_rx = priv->cur_tx = 0;
 125        priv->dirty_tx = 0;
 126
 127        /* Set up TX Ring */
 128        for (i = 0; i < TX_RING_SIZE; i++) {
 129                volatile struct TDRE *t = &lancedata->tx_ring[i];
 130                t->TMD0 = swloww(ARIADNE_RAM +
 131                                 offsetof(struct lancedata, tx_buff[i]));
 132                t->TMD1 = swhighw(ARIADNE_RAM +
 133                                  offsetof(struct lancedata, tx_buff[i])) |
 134                        TF_STP | TF_ENP;
 135                t->TMD2 = swapw((u_short)-PKT_BUF_SIZE);
 136                t->TMD3 = 0;
 137                priv->tx_ring[i] = &lancedata->tx_ring[i];
 138                priv->tx_buff[i] = lancedata->tx_buff[i];
 139                netdev_dbg(dev, "TX Entry %2d at %p, Buf at %p\n",
 140                           i, &lancedata->tx_ring[i], lancedata->tx_buff[i]);
 141        }
 142
 143        /* Set up RX Ring */
 144        for (i = 0; i < RX_RING_SIZE; i++) {
 145                volatile struct RDRE *r = &lancedata->rx_ring[i];
 146                r->RMD0 = swloww(ARIADNE_RAM +
 147                                 offsetof(struct lancedata, rx_buff[i]));
 148                r->RMD1 = swhighw(ARIADNE_RAM +
 149                                  offsetof(struct lancedata, rx_buff[i])) |
 150                        RF_OWN;
 151                r->RMD2 = swapw((u_short)-PKT_BUF_SIZE);
 152                r->RMD3 = 0x0000;
 153                priv->rx_ring[i] = &lancedata->rx_ring[i];
 154                priv->rx_buff[i] = lancedata->rx_buff[i];
 155                netdev_dbg(dev, "RX Entry %2d at %p, Buf at %p\n",
 156                           i, &lancedata->rx_ring[i], lancedata->rx_buff[i]);
 157        }
 158}
 159
 160static int ariadne_rx(struct net_device *dev)
 161{
 162        struct ariadne_private *priv = netdev_priv(dev);
 163        int entry = priv->cur_rx % RX_RING_SIZE;
 164        int i;
 165
 166        /* If we own the next entry, it's a new packet. Send it up */
 167        while (!(lowb(priv->rx_ring[entry]->RMD1) & RF_OWN)) {
 168                int status = lowb(priv->rx_ring[entry]->RMD1);
 169
 170                if (status != (RF_STP | RF_ENP)) {      /* There was an error */
 171                        /* There is a tricky error noted by
 172                         * John Murphy <murf@perftech.com> to Russ Nelson:
 173                         * Even with full-sized buffers it's possible for a
 174                         * jabber packet to use two buffers, with only the
 175                         * last correctly noting the error
 176                         */
 177                        /* Only count a general error at the end of a packet */
 178                        if (status & RF_ENP)
 179                                dev->stats.rx_errors++;
 180                        if (status & RF_FRAM)
 181                                dev->stats.rx_frame_errors++;
 182                        if (status & RF_OFLO)
 183                                dev->stats.rx_over_errors++;
 184                        if (status & RF_CRC)
 185                                dev->stats.rx_crc_errors++;
 186                        if (status & RF_BUFF)
 187                                dev->stats.rx_fifo_errors++;
 188                        priv->rx_ring[entry]->RMD1 &= 0xff00 | RF_STP | RF_ENP;
 189                } else {
 190                        /* Malloc up new buffer, compatible with net-3 */
 191                        short pkt_len = swapw(priv->rx_ring[entry]->RMD3);
 192                        struct sk_buff *skb;
 193
 194                        skb = netdev_alloc_skb(dev, pkt_len + 2);
 195                        if (skb == NULL) {
 196                                for (i = 0; i < RX_RING_SIZE; i++)
 197                                        if (lowb(priv->rx_ring[(entry + i) % RX_RING_SIZE]->RMD1) & RF_OWN)
 198                                                break;
 199
 200                                if (i > RX_RING_SIZE - 2) {
 201                                        dev->stats.rx_dropped++;
 202                                        priv->rx_ring[entry]->RMD1 |= RF_OWN;
 203                                        priv->cur_rx++;
 204                                }
 205                                break;
 206                        }
 207
 208
 209                        skb_reserve(skb, 2);    /* 16 byte align */
 210                        skb_put(skb, pkt_len);  /* Make room */
 211                        skb_copy_to_linear_data(skb,
 212                                                (const void *)priv->rx_buff[entry],
 213                                                pkt_len);
 214                        skb->protocol = eth_type_trans(skb, dev);
 215                        netdev_dbg(dev, "RX pkt type 0x%04x from %pM to %pM data %p len %u\n",
 216                                   ((u_short *)skb->data)[6],
 217                                   skb->data + 6, skb->data,
 218                                   skb->data, skb->len);
 219
 220                        netif_rx(skb);
 221                        dev->stats.rx_packets++;
 222                        dev->stats.rx_bytes += pkt_len;
 223                }
 224
 225                priv->rx_ring[entry]->RMD1 |= RF_OWN;
 226                entry = (++priv->cur_rx) % RX_RING_SIZE;
 227        }
 228
 229        priv->cur_rx = priv->cur_rx % RX_RING_SIZE;
 230
 231        /* We should check that at least two ring entries are free.
 232         * If not, we should free one and mark stats->rx_dropped++
 233         */
 234
 235        return 0;
 236}
 237
 238static irqreturn_t ariadne_interrupt(int irq, void *data)
 239{
 240        struct net_device *dev = (struct net_device *)data;
 241        volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr;
 242        struct ariadne_private *priv;
 243        int csr0, boguscnt;
 244        int handled = 0;
 245
 246        lance->RAP = CSR0;              /* PCnet-ISA Controller Status */
 247
 248        if (!(lance->RDP & INTR))       /* Check if any interrupt has been */
 249                return IRQ_NONE;        /* generated by the board */
 250
 251        priv = netdev_priv(dev);
 252
 253        boguscnt = 10;
 254        while ((csr0 = lance->RDP) & (ERR | RINT | TINT) && --boguscnt >= 0) {
 255                /* Acknowledge all of the current interrupt sources ASAP */
 256                lance->RDP = csr0 & ~(INEA | TDMD | STOP | STRT | INIT);
 257
 258#ifdef DEBUG
 259                if (ariadne_debug > 5) {
 260                        netdev_dbg(dev, "interrupt  csr0=%#02x new csr=%#02x [",
 261                                   csr0, lance->RDP);
 262                        if (csr0 & INTR)
 263                                pr_cont(" INTR");
 264                        if (csr0 & INEA)
 265                                pr_cont(" INEA");
 266                        if (csr0 & RXON)
 267                                pr_cont(" RXON");
 268                        if (csr0 & TXON)
 269                                pr_cont(" TXON");
 270                        if (csr0 & TDMD)
 271                                pr_cont(" TDMD");
 272                        if (csr0 & STOP)
 273                                pr_cont(" STOP");
 274                        if (csr0 & STRT)
 275                                pr_cont(" STRT");
 276                        if (csr0 & INIT)
 277                                pr_cont(" INIT");
 278                        if (csr0 & ERR)
 279                                pr_cont(" ERR");
 280                        if (csr0 & BABL)
 281                                pr_cont(" BABL");
 282                        if (csr0 & CERR)
 283                                pr_cont(" CERR");
 284                        if (csr0 & MISS)
 285                                pr_cont(" MISS");
 286                        if (csr0 & MERR)
 287                                pr_cont(" MERR");
 288                        if (csr0 & RINT)
 289                                pr_cont(" RINT");
 290                        if (csr0 & TINT)
 291                                pr_cont(" TINT");
 292                        if (csr0 & IDON)
 293                                pr_cont(" IDON");
 294                        pr_cont(" ]\n");
 295                }
 296#endif
 297
 298                if (csr0 & RINT) {      /* Rx interrupt */
 299                        handled = 1;
 300                        ariadne_rx(dev);
 301                }
 302
 303                if (csr0 & TINT) {      /* Tx-done interrupt */
 304                        int dirty_tx = priv->dirty_tx;
 305
 306                        handled = 1;
 307                        while (dirty_tx < priv->cur_tx) {
 308                                int entry = dirty_tx % TX_RING_SIZE;
 309                                int status = lowb(priv->tx_ring[entry]->TMD1);
 310
 311                                if (status & TF_OWN)
 312                                        break;  /* It still hasn't been Txed */
 313
 314                                priv->tx_ring[entry]->TMD1 &= 0xff00;
 315
 316                                if (status & TF_ERR) {
 317                                        /* There was an major error, log it */
 318                                        int err_status = priv->tx_ring[entry]->TMD3;
 319                                        dev->stats.tx_errors++;
 320                                        if (err_status & EF_RTRY)
 321                                                dev->stats.tx_aborted_errors++;
 322                                        if (err_status & EF_LCAR)
 323                                                dev->stats.tx_carrier_errors++;
 324                                        if (err_status & EF_LCOL)
 325                                                dev->stats.tx_window_errors++;
 326                                        if (err_status & EF_UFLO) {
 327                                                /* Ackk!  On FIFO errors the Tx unit is turned off! */
 328                                                dev->stats.tx_fifo_errors++;
 329                                                /* Remove this verbosity later! */
 330                                                netdev_err(dev, "Tx FIFO error! Status %04x\n",
 331                                                           csr0);
 332                                                /* Restart the chip */
 333                                                lance->RDP = STRT;
 334                                        }
 335                                } else {
 336                                        if (status & (TF_MORE | TF_ONE))
 337                                                dev->stats.collisions++;
 338                                        dev->stats.tx_packets++;
 339                                }
 340                                dirty_tx++;
 341                        }
 342
 343#ifndef final_version
 344                        if (priv->cur_tx - dirty_tx >= TX_RING_SIZE) {
 345                                netdev_err(dev, "out-of-sync dirty pointer, %d vs. %d, full=%d\n",
 346                                           dirty_tx, priv->cur_tx,
 347                                           priv->tx_full);
 348                                dirty_tx += TX_RING_SIZE;
 349                        }
 350#endif
 351
 352                        if (priv->tx_full && netif_queue_stopped(dev) &&
 353                            dirty_tx > priv->cur_tx - TX_RING_SIZE + 2) {
 354                                /* The ring is no longer full */
 355                                priv->tx_full = 0;
 356                                netif_wake_queue(dev);
 357                        }
 358
 359                        priv->dirty_tx = dirty_tx;
 360                }
 361
 362                /* Log misc errors */
 363                if (csr0 & BABL) {
 364                        handled = 1;
 365                        dev->stats.tx_errors++; /* Tx babble */
 366                }
 367                if (csr0 & MISS) {
 368                        handled = 1;
 369                        dev->stats.rx_errors++; /* Missed a Rx frame */
 370                }
 371                if (csr0 & MERR) {
 372                        handled = 1;
 373                        netdev_err(dev, "Bus master arbitration failure, status %04x\n",
 374                                   csr0);
 375                        /* Restart the chip */
 376                        lance->RDP = STRT;
 377                }
 378        }
 379
 380        /* Clear any other interrupt, and set interrupt enable */
 381        lance->RAP = CSR0;              /* PCnet-ISA Controller Status */
 382        lance->RDP = INEA | BABL | CERR | MISS | MERR | IDON;
 383
 384        if (ariadne_debug > 4)
 385                netdev_dbg(dev, "exiting interrupt, csr%d=%#04x\n",
 386                           lance->RAP, lance->RDP);
 387
 388        return IRQ_RETVAL(handled);
 389}
 390
 391static int ariadne_open(struct net_device *dev)
 392{
 393        volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr;
 394        u_short in;
 395        u_long version;
 396        int i;
 397
 398        /* Reset the LANCE */
 399        in = lance->Reset;
 400
 401        /* Stop the LANCE */
 402        lance->RAP = CSR0;              /* PCnet-ISA Controller Status */
 403        lance->RDP = STOP;
 404
 405        /* Check the LANCE version */
 406        lance->RAP = CSR88;             /* Chip ID */
 407        version = swapw(lance->RDP);
 408        lance->RAP = CSR89;             /* Chip ID */
 409        version |= swapw(lance->RDP) << 16;
 410        if ((version & 0x00000fff) != 0x00000003) {
 411                pr_warn("Couldn't find AMD Ethernet Chip\n");
 412                return -EAGAIN;
 413        }
 414        if ((version & 0x0ffff000) != 0x00003000) {
 415                pr_warn("Couldn't find Am79C960 (Wrong part number = %ld)\n",
 416                       (version & 0x0ffff000) >> 12);
 417                return -EAGAIN;
 418        }
 419
 420        netdev_dbg(dev, "Am79C960 (PCnet-ISA) Revision %ld\n",
 421                   (version & 0xf0000000) >> 28);
 422
 423        ariadne_init_ring(dev);
 424
 425        /* Miscellaneous Stuff */
 426        lance->RAP = CSR3;              /* Interrupt Masks and Deferral Control */
 427        lance->RDP = 0x0000;
 428        lance->RAP = CSR4;              /* Test and Features Control */
 429        lance->RDP = DPOLL | APAD_XMT | MFCOM | RCVCCOM | TXSTRTM | JABM;
 430
 431        /* Set the Multicast Table */
 432        lance->RAP = CSR8;              /* Logical Address Filter, LADRF[15:0] */
 433        lance->RDP = 0x0000;
 434        lance->RAP = CSR9;              /* Logical Address Filter, LADRF[31:16] */
 435        lance->RDP = 0x0000;
 436        lance->RAP = CSR10;             /* Logical Address Filter, LADRF[47:32] */
 437        lance->RDP = 0x0000;
 438        lance->RAP = CSR11;             /* Logical Address Filter, LADRF[63:48] */
 439        lance->RDP = 0x0000;
 440
 441        /* Set the Ethernet Hardware Address */
 442        lance->RAP = CSR12;             /* Physical Address Register, PADR[15:0] */
 443        lance->RDP = ((u_short *)&dev->dev_addr[0])[0];
 444        lance->RAP = CSR13;             /* Physical Address Register, PADR[31:16] */
 445        lance->RDP = ((u_short *)&dev->dev_addr[0])[1];
 446        lance->RAP = CSR14;             /* Physical Address Register, PADR[47:32] */
 447        lance->RDP = ((u_short *)&dev->dev_addr[0])[2];
 448
 449        /* Set the Init Block Mode */
 450        lance->RAP = CSR15;             /* Mode Register */
 451        lance->RDP = 0x0000;
 452
 453        /* Set the Transmit Descriptor Ring Pointer */
 454        lance->RAP = CSR30;             /* Base Address of Transmit Ring */
 455        lance->RDP = swloww(ARIADNE_RAM + offsetof(struct lancedata, tx_ring));
 456        lance->RAP = CSR31;             /* Base Address of transmit Ring */
 457        lance->RDP = swhighw(ARIADNE_RAM + offsetof(struct lancedata, tx_ring));
 458
 459        /* Set the Receive Descriptor Ring Pointer */
 460        lance->RAP = CSR24;             /* Base Address of Receive Ring */
 461        lance->RDP = swloww(ARIADNE_RAM + offsetof(struct lancedata, rx_ring));
 462        lance->RAP = CSR25;             /* Base Address of Receive Ring */
 463        lance->RDP = swhighw(ARIADNE_RAM + offsetof(struct lancedata, rx_ring));
 464
 465        /* Set the Number of RX and TX Ring Entries */
 466        lance->RAP = CSR76;             /* Receive Ring Length */
 467        lance->RDP = swapw(((u_short)-RX_RING_SIZE));
 468        lance->RAP = CSR78;             /* Transmit Ring Length */
 469        lance->RDP = swapw(((u_short)-TX_RING_SIZE));
 470
 471        /* Enable Media Interface Port Auto Select (10BASE-2/10BASE-T) */
 472        lance->RAP = ISACSR2;           /* Miscellaneous Configuration */
 473        lance->IDP = ASEL;
 474
 475        /* LED Control */
 476        lance->RAP = ISACSR5;           /* LED1 Status */
 477        lance->IDP = PSE|XMTE;
 478        lance->RAP = ISACSR6;   /* LED2 Status */
 479        lance->IDP = PSE|COLE;
 480        lance->RAP = ISACSR7;   /* LED3 Status */
 481        lance->IDP = PSE|RCVE;
 482
 483        netif_start_queue(dev);
 484
 485        i = request_irq(IRQ_AMIGA_PORTS, ariadne_interrupt, IRQF_SHARED,
 486                        dev->name, dev);
 487        if (i)
 488                return i;
 489
 490        lance->RAP = CSR0;              /* PCnet-ISA Controller Status */
 491        lance->RDP = INEA | STRT;
 492
 493        return 0;
 494}
 495
 496static int ariadne_close(struct net_device *dev)
 497{
 498        volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr;
 499
 500        netif_stop_queue(dev);
 501
 502        lance->RAP = CSR112;            /* Missed Frame Count */
 503        dev->stats.rx_missed_errors = swapw(lance->RDP);
 504        lance->RAP = CSR0;              /* PCnet-ISA Controller Status */
 505
 506        if (ariadne_debug > 1) {
 507                netdev_dbg(dev, "Shutting down ethercard, status was %02x\n",
 508                           lance->RDP);
 509                netdev_dbg(dev, "%lu packets missed\n",
 510                           dev->stats.rx_missed_errors);
 511        }
 512
 513        /* We stop the LANCE here -- it occasionally polls memory if we don't */
 514        lance->RDP = STOP;
 515
 516        free_irq(IRQ_AMIGA_PORTS, dev);
 517
 518        return 0;
 519}
 520
 521static inline void ariadne_reset(struct net_device *dev)
 522{
 523        volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr;
 524
 525        lance->RAP = CSR0;      /* PCnet-ISA Controller Status */
 526        lance->RDP = STOP;
 527        ariadne_init_ring(dev);
 528        lance->RDP = INEA | STRT;
 529        netif_start_queue(dev);
 530}
 531
 532static void ariadne_tx_timeout(struct net_device *dev)
 533{
 534        volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr;
 535
 536        netdev_err(dev, "transmit timed out, status %04x, resetting\n",
 537                   lance->RDP);
 538        ariadne_reset(dev);
 539        netif_wake_queue(dev);
 540}
 541
 542static netdev_tx_t ariadne_start_xmit(struct sk_buff *skb,
 543                                      struct net_device *dev)
 544{
 545        struct ariadne_private *priv = netdev_priv(dev);
 546        volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr;
 547        int entry;
 548        unsigned long flags;
 549        int len = skb->len;
 550
 551#if 0
 552        if (ariadne_debug > 3) {
 553                lance->RAP = CSR0;      /* PCnet-ISA Controller Status */
 554                netdev_dbg(dev, "%s: csr0 %04x\n", __func__, lance->RDP);
 555                lance->RDP = 0x0000;
 556        }
 557#endif
 558
 559        /* FIXME: is the 79C960 new enough to do its own padding right ? */
 560        if (skb->len < ETH_ZLEN) {
 561                if (skb_padto(skb, ETH_ZLEN))
 562                        return NETDEV_TX_OK;
 563                len = ETH_ZLEN;
 564        }
 565
 566        /* Fill in a Tx ring entry */
 567
 568        netdev_dbg(dev, "TX pkt type 0x%04x from %pM to %pM data %p len %u\n",
 569                   ((u_short *)skb->data)[6],
 570                   skb->data + 6, skb->data,
 571                   skb->data, skb->len);
 572
 573        local_irq_save(flags);
 574
 575        entry = priv->cur_tx % TX_RING_SIZE;
 576
 577        /* Caution: the write order is important here, set the base address with
 578           the "ownership" bits last */
 579
 580        priv->tx_ring[entry]->TMD2 = swapw((u_short)-skb->len);
 581        priv->tx_ring[entry]->TMD3 = 0x0000;
 582        memcpyw(priv->tx_buff[entry], (u_short *)skb->data, len);
 583
 584#ifdef DEBUG
 585        print_hex_dump(KERN_DEBUG, "tx_buff: ", DUMP_PREFIX_OFFSET, 16, 1,
 586                       (void *)priv->tx_buff[entry],
 587                       skb->len > 64 ? 64 : skb->len, true);
 588#endif
 589
 590        priv->tx_ring[entry]->TMD1 = (priv->tx_ring[entry]->TMD1 & 0xff00)
 591                | TF_OWN | TF_STP | TF_ENP;
 592
 593        dev_kfree_skb(skb);
 594
 595        priv->cur_tx++;
 596        if ((priv->cur_tx >= TX_RING_SIZE) &&
 597            (priv->dirty_tx >= TX_RING_SIZE)) {
 598
 599                netdev_dbg(dev, "*** Subtracting TX_RING_SIZE from cur_tx (%d) and dirty_tx (%d)\n",
 600                           priv->cur_tx, priv->dirty_tx);
 601
 602                priv->cur_tx -= TX_RING_SIZE;
 603                priv->dirty_tx -= TX_RING_SIZE;
 604        }
 605        dev->stats.tx_bytes += len;
 606
 607        /* Trigger an immediate send poll */
 608        lance->RAP = CSR0;              /* PCnet-ISA Controller Status */
 609        lance->RDP = INEA | TDMD;
 610
 611        if (lowb(priv->tx_ring[(entry + 1) % TX_RING_SIZE]->TMD1) != 0) {
 612                netif_stop_queue(dev);
 613                priv->tx_full = 1;
 614        }
 615        local_irq_restore(flags);
 616
 617        return NETDEV_TX_OK;
 618}
 619
 620static struct net_device_stats *ariadne_get_stats(struct net_device *dev)
 621{
 622        volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr;
 623        short saved_addr;
 624        unsigned long flags;
 625
 626        local_irq_save(flags);
 627        saved_addr = lance->RAP;
 628        lance->RAP = CSR112;            /* Missed Frame Count */
 629        dev->stats.rx_missed_errors = swapw(lance->RDP);
 630        lance->RAP = saved_addr;
 631        local_irq_restore(flags);
 632
 633        return &dev->stats;
 634}
 635
 636/* Set or clear the multicast filter for this adaptor.
 637 * num_addrs == -1      Promiscuous mode, receive all packets
 638 * num_addrs == 0       Normal mode, clear multicast list
 639 * num_addrs > 0        Multicast mode, receive normal and MC packets,
 640 *                      and do best-effort filtering.
 641 */
 642static void set_multicast_list(struct net_device *dev)
 643{
 644        volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr;
 645
 646        if (!netif_running(dev))
 647                return;
 648
 649        netif_stop_queue(dev);
 650
 651        /* We take the simple way out and always enable promiscuous mode */
 652        lance->RAP = CSR0;              /* PCnet-ISA Controller Status */
 653        lance->RDP = STOP;              /* Temporarily stop the lance */
 654        ariadne_init_ring(dev);
 655
 656        if (dev->flags & IFF_PROMISC) {
 657                lance->RAP = CSR15;     /* Mode Register */
 658                lance->RDP = PROM;      /* Set promiscuous mode */
 659        } else {
 660                short multicast_table[4];
 661                int num_addrs = netdev_mc_count(dev);
 662                int i;
 663                /* We don't use the multicast table,
 664                 * but rely on upper-layer filtering
 665                 */
 666                memset(multicast_table, (num_addrs == 0) ? 0 : -1,
 667                       sizeof(multicast_table));
 668                for (i = 0; i < 4; i++) {
 669                        lance->RAP = CSR8 + (i << 8);
 670                                        /* Logical Address Filter */
 671                        lance->RDP = swapw(multicast_table[i]);
 672                }
 673                lance->RAP = CSR15;     /* Mode Register */
 674                lance->RDP = 0x0000;    /* Unset promiscuous mode */
 675        }
 676
 677        lance->RAP = CSR0;              /* PCnet-ISA Controller Status */
 678        lance->RDP = INEA | STRT | IDON;/* Resume normal operation */
 679
 680        netif_wake_queue(dev);
 681}
 682
 683
 684static void ariadne_remove_one(struct zorro_dev *z)
 685{
 686        struct net_device *dev = zorro_get_drvdata(z);
 687
 688        unregister_netdev(dev);
 689        release_mem_region(ZTWO_PADDR(dev->base_addr), sizeof(struct Am79C960));
 690        release_mem_region(ZTWO_PADDR(dev->mem_start), ARIADNE_RAM_SIZE);
 691        free_netdev(dev);
 692}
 693
 694static struct zorro_device_id ariadne_zorro_tbl[] = {
 695        { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE },
 696        { 0 }
 697};
 698MODULE_DEVICE_TABLE(zorro, ariadne_zorro_tbl);
 699
 700static const struct net_device_ops ariadne_netdev_ops = {
 701        .ndo_open               = ariadne_open,
 702        .ndo_stop               = ariadne_close,
 703        .ndo_start_xmit         = ariadne_start_xmit,
 704        .ndo_tx_timeout         = ariadne_tx_timeout,
 705        .ndo_get_stats          = ariadne_get_stats,
 706        .ndo_set_rx_mode        = set_multicast_list,
 707        .ndo_validate_addr      = eth_validate_addr,
 708        .ndo_change_mtu         = eth_change_mtu,
 709        .ndo_set_mac_address    = eth_mac_addr,
 710};
 711
 712static int ariadne_init_one(struct zorro_dev *z,
 713                            const struct zorro_device_id *ent)
 714{
 715        unsigned long board = z->resource.start;
 716        unsigned long base_addr = board + ARIADNE_LANCE;
 717        unsigned long mem_start = board + ARIADNE_RAM;
 718        struct resource *r1, *r2;
 719        struct net_device *dev;
 720        struct ariadne_private *priv;
 721        int err;
 722
 723        r1 = request_mem_region(base_addr, sizeof(struct Am79C960), "Am79C960");
 724        if (!r1)
 725                return -EBUSY;
 726        r2 = request_mem_region(mem_start, ARIADNE_RAM_SIZE, "RAM");
 727        if (!r2) {
 728                release_mem_region(base_addr, sizeof(struct Am79C960));
 729                return -EBUSY;
 730        }
 731
 732        dev = alloc_etherdev(sizeof(struct ariadne_private));
 733        if (dev == NULL) {
 734                release_mem_region(base_addr, sizeof(struct Am79C960));
 735                release_mem_region(mem_start, ARIADNE_RAM_SIZE);
 736                return -ENOMEM;
 737        }
 738
 739        priv = netdev_priv(dev);
 740
 741        r1->name = dev->name;
 742        r2->name = dev->name;
 743
 744        dev->dev_addr[0] = 0x00;
 745        dev->dev_addr[1] = 0x60;
 746        dev->dev_addr[2] = 0x30;
 747        dev->dev_addr[3] = (z->rom.er_SerialNumber >> 16) & 0xff;
 748        dev->dev_addr[4] = (z->rom.er_SerialNumber >> 8) & 0xff;
 749        dev->dev_addr[5] = z->rom.er_SerialNumber & 0xff;
 750        dev->base_addr = ZTWO_VADDR(base_addr);
 751        dev->mem_start = ZTWO_VADDR(mem_start);
 752        dev->mem_end = dev->mem_start + ARIADNE_RAM_SIZE;
 753
 754        dev->netdev_ops = &ariadne_netdev_ops;
 755        dev->watchdog_timeo = 5 * HZ;
 756
 757        err = register_netdev(dev);
 758        if (err) {
 759                release_mem_region(base_addr, sizeof(struct Am79C960));
 760                release_mem_region(mem_start, ARIADNE_RAM_SIZE);
 761                free_netdev(dev);
 762                return err;
 763        }
 764        zorro_set_drvdata(z, dev);
 765
 766        netdev_info(dev, "Ariadne at 0x%08lx, Ethernet Address %pM\n",
 767                    board, dev->dev_addr);
 768
 769        return 0;
 770}
 771
 772static struct zorro_driver ariadne_driver = {
 773        .name           = "ariadne",
 774        .id_table       = ariadne_zorro_tbl,
 775        .probe          = ariadne_init_one,
 776        .remove         = ariadne_remove_one,
 777};
 778
 779static int __init ariadne_init_module(void)
 780{
 781        return zorro_register_driver(&ariadne_driver);
 782}
 783
 784static void __exit ariadne_cleanup_module(void)
 785{
 786        zorro_unregister_driver(&ariadne_driver);
 787}
 788
 789module_init(ariadne_init_module);
 790module_exit(ariadne_cleanup_module);
 791
 792MODULE_LICENSE("GPL");
 793