root/drivers/net/seeq8005.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. seeq8005_probe
  2. seeq8005_probe1
  3. seeq8005_open
  4. seeq8005_send_packet
  5. seeq8005_interrupt
  6. seeq8005_rx
  7. seeq8005_close
  8. seeq8005_get_stats
  9. set_multicast_list
  10. seeq8005_init
  11. hardware_send_packet
  12. wait_for_buffer

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

/* [previous][next][first][last][top][bottom][index][help] */