linux/drivers/net/seeq8005.c
<<
>>
Prefs
   1/* seeq8005.c: A network driver for linux. */
   2/*
   3        Based on skeleton.c,
   4        Written 1993-94 by Donald Becker.
   5        See the skeleton.c file for further copyright information.
   6
   7        This software may be used and distributed according to the terms
   8        of the GNU General Public License, incorporated herein by reference.
   9
  10        The author may be reached as hamish@zot.apana.org.au
  11
  12        This file is a network device driver for the SEEQ 8005 chipset and
  13        the Linux operating system.
  14
  15*/
  16
  17static const char version[] =
  18        "seeq8005.c:v1.00 8/07/95 Hamish Coleman (hamish@zot.apana.org.au)\n";
  19
  20/*
  21  Sources:
  22        SEEQ 8005 databook
  23
  24  Version history:
  25        1.00    Public release. cosmetic changes (no warnings now)
  26        0.68    Turning per- packet,interrupt debug messages off - testing for release.
  27        0.67    timing problems/bad buffer reads seem to be fixed now
  28        0.63    *!@$ protocol=eth_type_trans -- now packets flow
  29        0.56    Send working
  30        0.48    Receive working
  31*/
  32
  33#include <linux/module.h>
  34#include <linux/kernel.h>
  35#include <linux/types.h>
  36#include <linux/fcntl.h>
  37#include <linux/interrupt.h>
  38#include <linux/ioport.h>
  39#include <linux/in.h>
  40#include <linux/slab.h>
  41#include <linux/string.h>
  42#include <linux/init.h>
  43#include <linux/delay.h>
  44#include <linux/errno.h>
  45#include <linux/netdevice.h>
  46#include <linux/etherdevice.h>
  47#include <linux/skbuff.h>
  48#include <linux/bitops.h>
  49#include <linux/jiffies.h>
  50
  51#include <asm/system.h>
  52#include <asm/io.h>
  53#include <asm/dma.h>
  54
  55#include "seeq8005.h"
  56
  57/* First, a few definitions that the brave might change. */
  58/* A zero-terminated list of I/O addresses to be probed. */
  59static unsigned int seeq8005_portlist[] __initdata =
  60   { 0x300, 0x320, 0x340, 0x360, 0};
  61
  62/* use 0 for production, 1 for verification, >2 for debug */
  63#ifndef NET_DEBUG
  64#define NET_DEBUG 1
  65#endif
  66static unsigned int net_debug = NET_DEBUG;
  67
  68/* Information that need to be kept for each board. */
  69struct net_local {
  70        unsigned short receive_ptr;             /* What address in packet memory do we expect a recv_pkt_header? */
  71        long open_time;                         /* Useless example local info. */
  72};
  73
  74/* The station (ethernet) address prefix, used for IDing the board. */
  75#define SA_ADDR0 0x00
  76#define SA_ADDR1 0x80
  77#define SA_ADDR2 0x4b
  78
  79/* Index to functions, as function prototypes. */
  80
  81static int seeq8005_probe1(struct net_device *dev, int ioaddr);
  82static int seeq8005_open(struct net_device *dev);
  83static void seeq8005_timeout(struct net_device *dev);
  84static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev);
  85static irqreturn_t seeq8005_interrupt(int irq, void *dev_id);
  86static void seeq8005_rx(struct net_device *dev);
  87static int seeq8005_close(struct net_device *dev);
  88static void set_multicast_list(struct net_device *dev);
  89
  90/* Example routines you must write ;->. */
  91#define tx_done(dev)    (inw(SEEQ_STATUS) & SEEQSTAT_TX_ON)
  92static void hardware_send_packet(struct net_device *dev, char *buf, int length);
  93extern void seeq8005_init(struct net_device *dev, int startp);
  94static inline void wait_for_buffer(struct net_device *dev);
  95
  96
  97/* Check for a network adaptor of this type, and return '0' iff one exists.
  98   If dev->base_addr == 0, probe all likely locations.
  99   If dev->base_addr == 1, always return failure.
 100   */
 101
 102static int io = 0x320;
 103static int irq = 10;
 104
 105struct net_device * __init seeq8005_probe(int unit)
 106{
 107        struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
 108        unsigned *port;
 109        int err = 0;
 110
 111        if (!dev)
 112                return ERR_PTR(-ENODEV);
 113
 114        if (unit >= 0) {
 115                sprintf(dev->name, "eth%d", unit);
 116                netdev_boot_setup_check(dev);
 117                io = dev->base_addr;
 118                irq = dev->irq;
 119        }
 120
 121        if (io > 0x1ff) {       /* Check a single specified location. */
 122                err = seeq8005_probe1(dev, io);
 123        } else if (io != 0) {   /* Don't probe at all. */
 124                err = -ENXIO;
 125        } else {
 126                for (port = seeq8005_portlist; *port; port++) {
 127                        if (seeq8005_probe1(dev, *port) == 0)
 128                                break;
 129                }
 130                if (!*port)
 131                        err = -ENODEV;
 132        }
 133        if (err)
 134                goto out;
 135        err = register_netdev(dev);
 136        if (err)
 137                goto out1;
 138        return dev;
 139out1:
 140        release_region(dev->base_addr, SEEQ8005_IO_EXTENT);
 141out:
 142        free_netdev(dev);
 143        return ERR_PTR(err);
 144}
 145
 146/* This is the real probe routine.  Linux has a history of friendly device
 147   probes on the ISA bus.  A good device probes avoids doing writes, and
 148   verifies that the correct device exists and functions.  */
 149
 150static int __init seeq8005_probe1(struct net_device *dev, int ioaddr)
 151{
 152        static unsigned version_printed;
 153        int i,j;
 154        unsigned char SA_prom[32];
 155        int old_cfg1;
 156        int old_cfg2;
 157        int old_stat;
 158        int old_dmaar;
 159        int old_rear;
 160        int retval;
 161        DECLARE_MAC_BUF(mac);
 162
 163        if (!request_region(ioaddr, SEEQ8005_IO_EXTENT, "seeq8005"))
 164                return -ENODEV;
 165
 166        if (net_debug>1)
 167                printk("seeq8005: probing at 0x%x\n",ioaddr);
 168
 169        old_stat = inw(SEEQ_STATUS);                                    /* read status register */
 170        if (old_stat == 0xffff) {
 171                retval = -ENODEV;
 172                goto out;                                               /* assume that 0xffff == no device */
 173        }
 174        if ( (old_stat & 0x1800) != 0x1800 ) {                          /* assume that unused bits are 1, as my manual says */
 175                if (net_debug>1) {
 176                        printk("seeq8005: reserved stat bits != 0x1800\n");
 177                        printk("          == 0x%04x\n",old_stat);
 178                }
 179                retval = -ENODEV;
 180                goto out;
 181        }
 182
 183        old_rear = inw(SEEQ_REA);
 184        if (old_rear == 0xffff) {
 185                outw(0,SEEQ_REA);
 186                if (inw(SEEQ_REA) == 0xffff) {                          /* assume that 0xffff == no device */
 187                        retval = -ENODEV;
 188                        goto out;
 189                }
 190        } else if ((old_rear & 0xff00) != 0xff00) {                     /* assume that unused bits are 1 */
 191                if (net_debug>1) {
 192                        printk("seeq8005: unused rear bits != 0xff00\n");
 193                        printk("          == 0x%04x\n",old_rear);
 194                }
 195                retval = -ENODEV;
 196                goto out;
 197        }
 198
 199        old_cfg2 = inw(SEEQ_CFG2);                                      /* read CFG2 register */
 200        old_cfg1 = inw(SEEQ_CFG1);
 201        old_dmaar = inw(SEEQ_DMAAR);
 202
 203        if (net_debug>4) {
 204                printk("seeq8005: stat = 0x%04x\n",old_stat);
 205                printk("seeq8005: cfg1 = 0x%04x\n",old_cfg1);
 206                printk("seeq8005: cfg2 = 0x%04x\n",old_cfg2);
 207                printk("seeq8005: raer = 0x%04x\n",old_rear);
 208                printk("seeq8005: dmaar= 0x%04x\n",old_dmaar);
 209        }
 210
 211        outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);      /* setup for reading PROM */
 212        outw( 0, SEEQ_DMAAR);                                           /* set starting PROM address */
 213        outw( SEEQCFG1_BUFFER_PROM, SEEQ_CFG1);                         /* set buffer to look at PROM */
 214
 215
 216        j=0;
 217        for(i=0; i <32; i++) {
 218                j+= SA_prom[i] = inw(SEEQ_BUFFER) & 0xff;
 219        }
 220
 221#if 0
 222        /* untested because I only have the one card */
 223        if ( (j&0xff) != 0 ) {                                          /* checksum appears to be 8bit = 0 */
 224                if (net_debug>1) {                                      /* check this before deciding that we have a card */
 225                        printk("seeq8005: prom sum error\n");
 226                }
 227                outw( old_stat, SEEQ_STATUS);
 228                outw( old_dmaar, SEEQ_DMAAR);
 229                outw( old_cfg1, SEEQ_CFG1);
 230                retval = -ENODEV;
 231                goto out;
 232        }
 233#endif
 234
 235        outw( SEEQCFG2_RESET, SEEQ_CFG2);                               /* reset the card */
 236        udelay(5);
 237        outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
 238
 239        if (net_debug) {
 240                printk("seeq8005: prom sum = 0x%08x\n",j);
 241                for(j=0; j<32; j+=16) {
 242                        printk("seeq8005: prom %02x: ",j);
 243                        for(i=0;i<16;i++) {
 244                                printk("%02x ",SA_prom[j|i]);
 245                        }
 246                        printk(" ");
 247                        for(i=0;i<16;i++) {
 248                                if ((SA_prom[j|i]>31)&&(SA_prom[j|i]<127)) {
 249                                        printk("%c", SA_prom[j|i]);
 250                                } else {
 251                                        printk(" ");
 252                                }
 253                        }
 254                        printk("\n");
 255                }
 256        }
 257
 258#if 0
 259        /*
 260         * testing the packet buffer memory doesn't work yet
 261         * but all other buffer accesses do
 262         *                      - fixing is not a priority
 263         */
 264        if (net_debug>1) {                                      /* test packet buffer memory */
 265                printk("seeq8005: testing packet buffer ... ");
 266                outw( SEEQCFG1_BUFFER_BUFFER, SEEQ_CFG1);
 267                outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
 268                outw( 0 , SEEQ_DMAAR);
 269                for(i=0;i<32768;i++) {
 270                        outw(0x5a5a, SEEQ_BUFFER);
 271                }
 272                j=jiffies+HZ;
 273                while ( ((inw(SEEQ_STATUS) & SEEQSTAT_FIFO_EMPTY) != SEEQSTAT_FIFO_EMPTY) && time_before(jiffies, j) )
 274                        mb();
 275                outw( 0 , SEEQ_DMAAR);
 276                while ( ((inw(SEEQ_STATUS) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && time_before(jiffies, j+HZ))
 277                        mb();
 278                if ( (inw(SEEQ_STATUS) & SEEQSTAT_WINDOW_INT) == SEEQSTAT_WINDOW_INT)
 279                        outw( SEEQCMD_WINDOW_INT_ACK | (inw(SEEQ_STATUS)& SEEQCMD_INT_MASK), SEEQ_CMD);
 280                outw( SEEQCMD_FIFO_READ | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
 281                j=0;
 282                for(i=0;i<32768;i++) {
 283                        if (inw(SEEQ_BUFFER) != 0x5a5a)
 284                                j++;
 285                }
 286                if (j) {
 287                        printk("%i\n",j);
 288                } else {
 289                        printk("ok.\n");
 290                }
 291        }
 292#endif
 293
 294        if (net_debug  &&  version_printed++ == 0)
 295                printk(version);
 296
 297        printk("%s: %s found at %#3x, ", dev->name, "seeq8005", ioaddr);
 298
 299        /* Fill in the 'dev' fields. */
 300        dev->base_addr = ioaddr;
 301        dev->irq = irq;
 302
 303        /* Retrieve and print the ethernet address. */
 304        for (i = 0; i < 6; i++)
 305                dev->dev_addr[i] = SA_prom[i+6];
 306        printk("%s", print_mac(mac, dev->dev_addr));
 307
 308        if (dev->irq == 0xff)
 309                ;                       /* Do nothing: a user-level program will set it. */
 310        else if (dev->irq < 2) {        /* "Auto-IRQ" */
 311                unsigned long cookie = probe_irq_on();
 312
 313                outw( SEEQCMD_RX_INT_EN | SEEQCMD_SET_RX_ON | SEEQCMD_SET_RX_OFF, SEEQ_CMD );
 314
 315                dev->irq = probe_irq_off(cookie);
 316
 317                if (net_debug >= 2)
 318                        printk(" autoirq is %d\n", dev->irq);
 319        } else if (dev->irq == 2)
 320          /* Fixup for users that don't know that IRQ 2 is really IRQ 9,
 321           * or don't know which one to set.
 322           */
 323          dev->irq = 9;
 324
 325#if 0
 326        {
 327                 int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005", dev);
 328                 if (irqval) {
 329                         printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
 330                                         dev->irq, irqval);
 331                         retval = -EAGAIN;
 332                         goto out;
 333                 }
 334        }
 335#endif
 336        dev->open               = seeq8005_open;
 337        dev->stop               = seeq8005_close;
 338        dev->hard_start_xmit    = seeq8005_send_packet;
 339        dev->tx_timeout         = seeq8005_timeout;
 340        dev->watchdog_timeo     = HZ/20;
 341        dev->set_multicast_list = set_multicast_list;
 342        dev->flags &= ~IFF_MULTICAST;
 343
 344        return 0;
 345out:
 346        release_region(ioaddr, SEEQ8005_IO_EXTENT);
 347        return retval;
 348}
 349
 350
 351/* Open/initialize the board.  This is called (in the current kernel)
 352   sometime after booting when the 'ifconfig' program is run.
 353
 354   This routine should set everything up anew at each open, even
 355   registers that "should" only need to be set once at boot, so that
 356   there is non-reboot way to recover if something goes wrong.
 357   */
 358static int seeq8005_open(struct net_device *dev)
 359{
 360        struct net_local *lp = netdev_priv(dev);
 361
 362        {
 363                 int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005", dev);
 364                 if (irqval) {
 365                         printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
 366                                         dev->irq, irqval);
 367                         return -EAGAIN;
 368                 }
 369        }
 370
 371        /* Reset the hardware here.  Don't forget to set the station address. */
 372        seeq8005_init(dev, 1);
 373
 374        lp->open_time = jiffies;
 375
 376        netif_start_queue(dev);
 377        return 0;
 378}
 379
 380static void seeq8005_timeout(struct net_device *dev)
 381{
 382        int ioaddr = dev->base_addr;
 383        printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
 384                   tx_done(dev) ? "IRQ conflict" : "network cable problem");
 385        /* Try to restart the adaptor. */
 386        seeq8005_init(dev, 1);
 387        dev->trans_start = jiffies;
 388        netif_wake_queue(dev);
 389}
 390
 391static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev)
 392{
 393        short length = skb->len;
 394        unsigned char *buf;
 395
 396        if (length < ETH_ZLEN) {
 397                if (skb_padto(skb, ETH_ZLEN))
 398                        return 0;
 399                length = ETH_ZLEN;
 400        }
 401        buf = skb->data;
 402
 403        /* Block a timer-based transmit from overlapping */
 404        netif_stop_queue(dev);
 405
 406        hardware_send_packet(dev, buf, length);
 407        dev->trans_start = jiffies;
 408        dev->stats.tx_bytes += length;
 409        dev_kfree_skb (skb);
 410        /* You might need to clean up and record Tx statistics here. */
 411
 412        return 0;
 413}
 414
 415/*
 416 * wait_for_buffer
 417 *
 418 * This routine waits for the SEEQ chip to assert that the FIFO is ready
 419 * by checking for a window interrupt, and then clearing it. This has to
 420 * occur in the interrupt handler!
 421 */
 422inline void wait_for_buffer(struct net_device * dev)
 423{
 424        int ioaddr = dev->base_addr;
 425        unsigned long tmp;
 426        int status;
 427
 428        tmp = jiffies + HZ;
 429        while ( ( ((status=inw(SEEQ_STATUS)) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && time_before(jiffies, tmp))
 430                cpu_relax();
 431
 432        if ( (status & SEEQSTAT_WINDOW_INT) == SEEQSTAT_WINDOW_INT)
 433                outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
 434}
 435
 436/* The typical workload of the driver:
 437   Handle the network interface interrupts. */
 438static irqreturn_t seeq8005_interrupt(int irq, void *dev_id)
 439{
 440        struct net_device *dev = dev_id;
 441        struct net_local *lp;
 442        int ioaddr, status, boguscount = 0;
 443        int handled = 0;
 444
 445        ioaddr = dev->base_addr;
 446        lp = netdev_priv(dev);
 447
 448        status = inw(SEEQ_STATUS);
 449        do {
 450                if (net_debug >2) {
 451                        printk("%s: int, status=0x%04x\n",dev->name,status);
 452                }
 453
 454                if (status & SEEQSTAT_WINDOW_INT) {
 455                        handled = 1;
 456                        outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
 457                        if (net_debug) {
 458                                printk("%s: window int!\n",dev->name);
 459                        }
 460                }
 461                if (status & SEEQSTAT_TX_INT) {
 462                        handled = 1;
 463                        outw( SEEQCMD_TX_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
 464                        dev->stats.tx_packets++;
 465                        netif_wake_queue(dev);  /* Inform upper layers. */
 466                }
 467                if (status & SEEQSTAT_RX_INT) {
 468                        handled = 1;
 469                        /* Got a packet(s). */
 470                        seeq8005_rx(dev);
 471                }
 472                status = inw(SEEQ_STATUS);
 473        } while ( (++boguscount < 10) && (status & SEEQSTAT_ANY_INT)) ;
 474
 475        if(net_debug>2) {
 476                printk("%s: eoi\n",dev->name);
 477        }
 478        return IRQ_RETVAL(handled);
 479}
 480
 481/* We have a good packet(s), get it/them out of the buffers. */
 482static void seeq8005_rx(struct net_device *dev)
 483{
 484        struct net_local *lp = netdev_priv(dev);
 485        int boguscount = 10;
 486        int pkt_hdr;
 487        int ioaddr = dev->base_addr;
 488
 489        do {
 490                int next_packet;
 491                int pkt_len;
 492                int i;
 493                int status;
 494
 495                status = inw(SEEQ_STATUS);
 496                outw( lp->receive_ptr, SEEQ_DMAAR);
 497                outw(SEEQCMD_FIFO_READ | SEEQCMD_RX_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
 498                wait_for_buffer(dev);
 499                next_packet = ntohs(inw(SEEQ_BUFFER));
 500                pkt_hdr = inw(SEEQ_BUFFER);
 501
 502                if (net_debug>2) {
 503                        printk("%s: 0x%04x recv next=0x%04x, hdr=0x%04x\n",dev->name,lp->receive_ptr,next_packet,pkt_hdr);
 504                }
 505
 506                if ((next_packet == 0) || ((pkt_hdr & SEEQPKTH_CHAIN)==0)) {    /* Read all the frames? */
 507                        return;                                                 /* Done for now */
 508                }
 509
 510                if ((pkt_hdr & SEEQPKTS_DONE)==0)
 511                        break;
 512
 513                if (next_packet < lp->receive_ptr) {
 514                        pkt_len = (next_packet + 0x10000 - ((DEFAULT_TEA+1)<<8)) - lp->receive_ptr - 4;
 515                } else {
 516                        pkt_len = next_packet - lp->receive_ptr - 4;
 517                }
 518
 519                if (next_packet < ((DEFAULT_TEA+1)<<8)) {                       /* is the next_packet address sane? */
 520                        printk("%s: recv packet ring corrupt, resetting board\n",dev->name);
 521                        seeq8005_init(dev,1);
 522                        return;
 523                }
 524
 525                lp->receive_ptr = next_packet;
 526
 527                if (net_debug>2) {
 528                        printk("%s: recv len=0x%04x\n",dev->name,pkt_len);
 529                }
 530
 531                if (pkt_hdr & SEEQPKTS_ANY_ERROR) {                             /* There was an error. */
 532                        dev->stats.rx_errors++;
 533                        if (pkt_hdr & SEEQPKTS_SHORT) dev->stats.rx_frame_errors++;
 534                        if (pkt_hdr & SEEQPKTS_DRIB) dev->stats.rx_frame_errors++;
 535                        if (pkt_hdr & SEEQPKTS_OVERSIZE) dev->stats.rx_over_errors++;
 536                        if (pkt_hdr & SEEQPKTS_CRC_ERR) dev->stats.rx_crc_errors++;
 537                        /* skip over this packet */
 538                        outw( SEEQCMD_FIFO_WRITE | SEEQCMD_DMA_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
 539                        outw( (lp->receive_ptr & 0xff00)>>8, SEEQ_REA);
 540                } else {
 541                        /* Malloc up new buffer. */
 542                        struct sk_buff *skb;
 543                        unsigned char *buf;
 544
 545                        skb = dev_alloc_skb(pkt_len);
 546                        if (skb == NULL) {
 547                                printk("%s: Memory squeeze, dropping packet.\n", dev->name);
 548                                dev->stats.rx_dropped++;
 549                                break;
 550                        }
 551                        skb_reserve(skb, 2);    /* align data on 16 byte */
 552                        buf = skb_put(skb,pkt_len);
 553
 554                        insw(SEEQ_BUFFER, buf, (pkt_len + 1) >> 1);
 555
 556                        if (net_debug>2) {
 557                                char * p = buf;
 558                                printk("%s: recv ",dev->name);
 559                                for(i=0;i<14;i++) {
 560                                        printk("%02x ",*(p++)&0xff);
 561                                }
 562                                printk("\n");
 563                        }
 564
 565                        skb->protocol=eth_type_trans(skb,dev);
 566                        netif_rx(skb);
 567                        dev->last_rx = jiffies;
 568                        dev->stats.rx_packets++;
 569                        dev->stats.rx_bytes += pkt_len;
 570                }
 571        } while ((--boguscount) && (pkt_hdr & SEEQPKTH_CHAIN));
 572
 573        /* If any worth-while packets have been received, netif_rx()
 574           has done a mark_bh(NET_BH) for us and will work on them
 575           when we get to the bottom-half routine. */
 576        return;
 577}
 578
 579/* The inverse routine to net_open(). */
 580static int seeq8005_close(struct net_device *dev)
 581{
 582        struct net_local *lp = netdev_priv(dev);
 583        int ioaddr = dev->base_addr;
 584
 585        lp->open_time = 0;
 586
 587        netif_stop_queue(dev);
 588
 589        /* Flush the Tx and disable Rx here. */
 590        outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
 591
 592        free_irq(dev->irq, dev);
 593
 594        /* Update the statistics here. */
 595
 596        return 0;
 597
 598}
 599
 600/* Set or clear the multicast filter for this adaptor.
 601   num_addrs == -1      Promiscuous mode, receive all packets
 602   num_addrs == 0       Normal mode, clear multicast list
 603   num_addrs > 0        Multicast mode, receive normal and MC packets, and do
 604                        best-effort filtering.
 605 */
 606static void set_multicast_list(struct net_device *dev)
 607{
 608/*
 609 * I _could_ do up to 6 addresses here, but won't (yet?)
 610 */
 611
 612#if 0
 613        int ioaddr = dev->base_addr;
 614/*
 615 * hmm, not even sure if my matching works _anyway_ - seem to be receiving
 616 * _everything_ . . .
 617 */
 618
 619        if (num_addrs) {                        /* Enable promiscuous mode */
 620                outw( (inw(SEEQ_CFG1) & ~SEEQCFG1_MATCH_MASK)| SEEQCFG1_MATCH_ALL,  SEEQ_CFG1);
 621                dev->flags|=IFF_PROMISC;
 622        } else {                                /* Disable promiscuous mode, use normal mode */
 623                outw( (inw(SEEQ_CFG1) & ~SEEQCFG1_MATCH_MASK)| SEEQCFG1_MATCH_BROAD, SEEQ_CFG1);
 624        }
 625#endif
 626}
 627
 628void seeq8005_init(struct net_device *dev, int startp)
 629{
 630        struct net_local *lp = netdev_priv(dev);
 631        int ioaddr = dev->base_addr;
 632        int i;
 633
 634        outw(SEEQCFG2_RESET, SEEQ_CFG2);        /* reset device */
 635        udelay(5);
 636
 637        outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
 638        outw( 0, SEEQ_DMAAR);                   /* load start address into both low and high byte */
 639/*      wait_for_buffer(dev); */                /* I think that you only need a wait for memory buffer */
 640        outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1);
 641
 642        for(i=0;i<6;i++) {                      /* set Station address */
 643                outb(dev->dev_addr[i], SEEQ_BUFFER);
 644                udelay(2);
 645        }
 646
 647        outw( SEEQCFG1_BUFFER_TEA, SEEQ_CFG1);  /* set xmit end area pointer to 16K */
 648        outb( DEFAULT_TEA, SEEQ_BUFFER);        /* this gives us 16K of send buffer and 48K of recv buffer */
 649
 650        lp->receive_ptr = (DEFAULT_TEA+1)<<8;   /* so we can find our packet_header */
 651        outw( lp->receive_ptr, SEEQ_RPR);       /* Receive Pointer Register is set to recv buffer memory */
 652
 653        outw( 0x00ff, SEEQ_REA);                /* Receive Area End */
 654
 655        if (net_debug>4) {
 656                printk("%s: SA0 = ",dev->name);
 657
 658                outw( SEEQCMD_FIFO_READ | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
 659                outw( 0, SEEQ_DMAAR);
 660                outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1);
 661
 662                for(i=0;i<6;i++) {
 663                        printk("%02x ",inb(SEEQ_BUFFER));
 664                }
 665                printk("\n");
 666        }
 667
 668        outw( SEEQCFG1_MAC0_EN | SEEQCFG1_MATCH_BROAD | SEEQCFG1_BUFFER_BUFFER, SEEQ_CFG1);
 669        outw( SEEQCFG2_AUTO_REA | SEEQCFG2_CTRLO, SEEQ_CFG2);
 670        outw( SEEQCMD_SET_RX_ON | SEEQCMD_TX_INT_EN | SEEQCMD_RX_INT_EN, SEEQ_CMD);
 671
 672        if (net_debug>4) {
 673                int old_cfg1;
 674                old_cfg1 = inw(SEEQ_CFG1);
 675                printk("%s: stat = 0x%04x\n",dev->name,inw(SEEQ_STATUS));
 676                printk("%s: cfg1 = 0x%04x\n",dev->name,old_cfg1);
 677                printk("%s: cfg2 = 0x%04x\n",dev->name,inw(SEEQ_CFG2));
 678                printk("%s: raer = 0x%04x\n",dev->name,inw(SEEQ_REA));
 679                printk("%s: dmaar= 0x%04x\n",dev->name,inw(SEEQ_DMAAR));
 680
 681        }
 682}
 683
 684
 685static void hardware_send_packet(struct net_device * dev, char *buf, int length)
 686{
 687        int ioaddr = dev->base_addr;
 688        int status = inw(SEEQ_STATUS);
 689        int transmit_ptr = 0;
 690        unsigned long tmp;
 691
 692        if (net_debug>4) {
 693                printk("%s: send 0x%04x\n",dev->name,length);
 694        }
 695
 696        /* Set FIFO to writemode and set packet-buffer address */
 697        outw( SEEQCMD_FIFO_WRITE | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
 698        outw( transmit_ptr, SEEQ_DMAAR);
 699
 700        /* output SEEQ Packet header barfage */
 701        outw( htons(length + 4), SEEQ_BUFFER);
 702        outw( SEEQPKTH_XMIT | SEEQPKTH_DATA_FOLLOWS | SEEQPKTH_XMIT_INT_EN, SEEQ_BUFFER );
 703
 704        /* blat the buffer */
 705        outsw( SEEQ_BUFFER, buf, (length +1) >> 1);
 706        /* paranoia !! */
 707        outw( 0, SEEQ_BUFFER);
 708        outw( 0, SEEQ_BUFFER);
 709
 710        /* set address of start of transmit chain */
 711        outw( transmit_ptr, SEEQ_TPR);
 712
 713        /* drain FIFO */
 714        tmp = jiffies;
 715        while ( (((status=inw(SEEQ_STATUS)) & SEEQSTAT_FIFO_EMPTY) == 0) && time_before(jiffies, tmp + HZ))
 716                mb();
 717
 718        /* doit ! */
 719        outw( SEEQCMD_WINDOW_INT_ACK | SEEQCMD_SET_TX_ON | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
 720
 721}
 722
 723
 724#ifdef MODULE
 725
 726static struct net_device *dev_seeq;
 727MODULE_LICENSE("GPL");
 728module_param(io, int, 0);
 729module_param(irq, int, 0);
 730MODULE_PARM_DESC(io, "SEEQ 8005 I/O base address");
 731MODULE_PARM_DESC(irq, "SEEQ 8005 IRQ number");
 732
 733int __init init_module(void)
 734{
 735        dev_seeq = seeq8005_probe(-1);
 736        if (IS_ERR(dev_seeq))
 737                return PTR_ERR(dev_seeq);
 738        return 0;
 739}
 740
 741void __exit cleanup_module(void)
 742{
 743        unregister_netdev(dev_seeq);
 744        release_region(dev_seeq->base_addr, SEEQ8005_IO_EXTENT);
 745        free_netdev(dev_seeq);
 746}
 747
 748#endif /* MODULE */
 749
 750/*
 751 * Local variables:
 752 *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c skeleton.c"
 753 *  version-control: t
 754 *  kept-new-versions: 5
 755 *  tab-width: 4
 756 * End:
 757 */
 758
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.