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 extern struct device *init_etherdev(struct device *dev, int sizeof_private,
  58                                                                         unsigned long *mem_startp);
  59 
  60 /* First, a few definitions that the brave might change. */
  61 /* A zero-terminated list of I/O addresses to be probed. */
  62 static unsigned int seeq8005_portlist[] =
  63    { 0x300, 0x320, 0x340, 0x360, 0};
  64 
  65 /* use 0 for production, 1 for verification, >2 for debug */
  66 #ifndef NET_DEBUG
  67 #define NET_DEBUG 1
  68 #endif
  69 static unsigned int net_debug = NET_DEBUG;
  70 
  71 /* Information that need to be kept for each board. */
  72 struct net_local {
  73         struct enet_statistics stats;
  74         unsigned short receive_ptr;             /* What address in packet memory do we expect a recv_pkt_header? */
  75         long open_time;                         /* Useless example local info. */
  76 };
  77 
  78 /* The station (ethernet) address prefix, used for IDing the board. */
  79 #define SA_ADDR0 0x00
  80 #define SA_ADDR1 0x80
  81 #define SA_ADDR2 0x4b
  82 
  83 /* Index to functions, as function prototypes. */
  84 
  85 extern int seeq8005_probe(struct device *dev);
  86 
  87 static int seeq8005_probe1(struct device *dev, int ioaddr);
  88 static int seeq8005_open(struct device *dev);
  89 static int seeq8005_send_packet(struct sk_buff *skb, struct device *dev);
  90 static void seeq8005_interrupt(int irq, struct pt_regs *regs);
  91 static void seeq8005_rx(struct device *dev);
  92 static int seeq8005_close(struct device *dev);
  93 static struct enet_statistics *seeq8005_get_stats(struct device *dev);
  94 static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
  95 
  96 /* Example routines you must write ;->. */
  97 #define tx_done(dev)    (inw(SEEQ_STATUS) & SEEQSTAT_TX_ON)
  98 extern void hardware_send_packet(struct device *dev, char *buf, int length);
  99 extern void seeq8005_init(struct device *dev, int startp);
 100 inline void wait_for_buffer(struct device *dev);
 101 
 102 
 103 /* Check for a network adaptor of this type, and return '0' iff one exists.
 104    If dev->base_addr == 0, probe all likely locations.
 105    If dev->base_addr == 1, always return failure.
 106    If dev->base_addr == 2, allocate space for the device and return success
 107    (detachable devices only).
 108    */
 109 #ifdef HAVE_DEVLIST
 110 /* Support for a alternate probe manager, which will eliminate the
 111    boilerplate below. */
 112 struct netdev_entry seeq8005_drv =
 113 {"seeq8005", seeq8005_probe1, SEEQ8005_IO_EXTENT, seeq8005_portlist};
 114 #else
 115 int
 116 seeq8005_probe(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 117 {
 118         int i;
 119         int base_addr = dev ? dev->base_addr : 0;
 120 
 121         if (base_addr > 0x1ff)          /* Check a single specified location. */
 122                 return seeq8005_probe1(dev, base_addr);
 123         else if (base_addr != 0)        /* Don't probe at all. */
 124                 return ENXIO;
 125 
 126         for (i = 0; seeq8005_portlist[i]; i++) {
 127                 int ioaddr = seeq8005_portlist[i];
 128                 if (check_region(ioaddr, SEEQ8005_IO_EXTENT))
 129                         continue;
 130                 if (seeq8005_probe1(dev, ioaddr) == 0)
 131                         return 0;
 132         }
 133 
 134         return ENODEV;
 135 }
 136 #endif
 137 
 138 /* This is the real probe routine.  Linux has a history of friendly device
 139    probes on the ISA bus.  A good device probes avoids doing writes, and
 140    verifies that the correct device exists and functions.  */
 141 
 142 static int seeq8005_probe1(struct device *dev, int ioaddr)
     /* [previous][next][first][last][top][bottom][index][help] */
 143 {
 144         static unsigned version_printed = 0;
 145         int i,j;
 146         unsigned char SA_prom[32];
 147         int old_cfg1;
 148         int old_cfg2;
 149         int old_stat;
 150         int old_dmaar;
 151         int old_rear;
 152 
 153         if (net_debug>1)
 154                 printk("seeq8005: probing at 0x%x\n",ioaddr);
 155 
 156         old_stat = inw(SEEQ_STATUS);                                    /* read status register */
 157         if (old_stat == 0xffff)
 158                 return ENODEV;                                          /* assume that 0xffff == no device */
 159         if ( (old_stat & 0x1800) != 0x1800 ) {                          /* assume that unused bits are 1, as my manual says */
 160                 if (net_debug>1) {
 161                         printk("seeq8005: reserved stat bits != 0x1800\n");
 162                         printk("          == 0x%04x\n",old_stat);
 163                 }
 164                 return ENODEV;
 165         }
 166 
 167         old_rear = inw(SEEQ_REA);
 168         if (old_rear == 0xffff) {
 169                 outw(0,SEEQ_REA);
 170                 if (inw(SEEQ_REA) == 0xffff) {                          /* assume that 0xffff == no device */
 171                         return ENODEV;
 172                 }
 173         } else if ((old_rear & 0xff00) != 0xff00) {                     /* assume that unused bits are 1 */
 174                 if (net_debug>1) {
 175                         printk("seeq8005: unused rear bits != 0xff00\n");
 176                         printk("          == 0x%04x\n",old_rear);
 177                 }
 178                 return ENODEV;
 179         }
 180         
 181         old_cfg2 = inw(SEEQ_CFG2);                                      /* read CFG2 register */
 182         old_cfg1 = inw(SEEQ_CFG1);
 183         old_dmaar = inw(SEEQ_DMAAR);
 184         
 185         if (net_debug>4) {
 186                 printk("seeq8005: stat = 0x%04x\n",old_stat);
 187                 printk("seeq8005: cfg1 = 0x%04x\n",old_cfg1);
 188                 printk("seeq8005: cfg2 = 0x%04x\n",old_cfg2);
 189                 printk("seeq8005: raer = 0x%04x\n",old_rear);
 190                 printk("seeq8005: dmaar= 0x%04x\n",old_dmaar);
 191         }
 192         
 193         outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);      /* setup for reading PROM */
 194         outw( 0, SEEQ_DMAAR);                                           /* set starting PROM address */
 195         outw( SEEQCFG1_BUFFER_PROM, SEEQ_CFG1);                         /* set buffer to look at PROM */
 196         
 197         
 198         j=0;
 199         for(i=0; i <32; i++) {
 200                 j+= SA_prom[i] = inw(SEEQ_BUFFER) & 0xff;
 201         }
 202 
 203 #if 0
 204         /* untested because I only have the one card */
 205         if ( (j&0xff) != 0 ) {                                          /* checksum appears to be 8bit = 0 */
 206                 if (net_debug>1) {                                      /* check this before deciding that we have a card */
 207                         printk("seeq8005: prom sum error\n");
 208                 }
 209                 outw( old_stat, SEEQ_STATUS);
 210                 outw( old_dmaar, SEEQ_DMAAR);
 211                 outw( old_cfg1, SEEQ_CFG1);
 212                 return ENODEV;
 213         }
 214 #endif
 215 
 216         outw( SEEQCFG2_RESET, SEEQ_CFG2);                               /* reset the card */
 217         SLOW_DOWN_IO;                                                   /* have to wait 4us after a reset - should be fixed */
 218         SLOW_DOWN_IO;
 219         SLOW_DOWN_IO;
 220         SLOW_DOWN_IO;
 221         outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
 222         
 223         if (net_debug) {
 224                 printk("seeq8005: prom sum = 0x%08x\n",j);
 225                 for(j=0; j<32; j+=16) {
 226                         printk("seeq8005: prom %02x: ",j);
 227                         for(i=0;i<16;i++) {
 228                                 printk("%02x ",SA_prom[j|i]);
 229                         }
 230                         printk(" ");
 231                         for(i=0;i<16;i++) {
 232                                 if ((SA_prom[j|i]>31)&&(SA_prom[j|i]<127)) {
 233                                         printk("%c", SA_prom[j|i]);
 234                                 } else {
 235                                         printk(" ");
 236                                 }
 237                         }
 238                         printk("\n");
 239                 }
 240         }
 241 
 242 #if 0   
 243         /* 
 244          * testing the packet buffer memory doesnt work yet
 245          * but all other buffer accesses do 
 246          *                      - fixing is not a priority
 247          */
 248         if (net_debug>1) {                                      /* test packet buffer memory */
 249                 printk("seeq8005: testing packet buffer ... ");
 250                 outw( SEEQCFG1_BUFFER_BUFFER, SEEQ_CFG1);
 251                 outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
 252                 outw( 0 , SEEQ_DMAAR);
 253                 for(i=0;i<32768;i++) {
 254                         outw(0x5a5a, SEEQ_BUFFER);
 255                 }
 256                 j=jiffies+HZ;
 257                 while ( ((inw(SEEQ_STATUS) & SEEQSTAT_FIFO_EMPTY) != SEEQSTAT_FIFO_EMPTY) && jiffies < j )
 258                         mb();
 259                 outw( 0 , SEEQ_DMAAR);
 260                 while ( ((inw(SEEQ_STATUS) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && jiffies < j+HZ)
 261                         mb();
 262                 if ( (inw(SEEQ_STATUS) & SEEQSTAT_WINDOW_INT) == SEEQSTAT_WINDOW_INT)
 263                         outw( SEEQCMD_WINDOW_INT_ACK | (inw(SEEQ_STATUS)& SEEQCMD_INT_MASK), SEEQ_CMD);
 264                 outw( SEEQCMD_FIFO_READ | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
 265                 j=0;
 266                 for(i=0;i<32768;i++) {
 267                         if (inw(SEEQ_BUFFER) != 0x5a5a)
 268                                 j++;
 269                 }
 270                 if (j) {
 271                         printk("%i\n",j);
 272                 } else {
 273                         printk("ok.\n");
 274                 }
 275         }
 276 #endif
 277 
 278         /* Allocate a new 'dev' if needed. */
 279         if (dev == NULL)
 280                 dev = init_etherdev(0, sizeof(struct net_local), 0);
 281 
 282         if (net_debug  &&  version_printed++ == 0)
 283                 printk(version);
 284 
 285         printk("%s: %s found at %#3x, ", dev->name, "seeq8005", ioaddr);
 286 
 287         /* Fill in the 'dev' fields. */
 288         dev->base_addr = ioaddr;
 289 
 290         /* Retrieve and print the ethernet address. */
 291         for (i = 0; i < 6; i++)
 292                 printk(" %2.2x", dev->dev_addr[i] = SA_prom[i+6]);
 293 
 294         if (dev->irq == 0xff)
 295                 ;                       /* Do nothing: a user-level program will set it. */
 296         else if (dev->irq < 2) {        /* "Auto-IRQ" */
 297                 autoirq_setup(0);
 298                 
 299                 outw( SEEQCMD_RX_INT_EN | SEEQCMD_SET_RX_ON | SEEQCMD_SET_RX_OFF, SEEQ_CMD );
 300 
 301                 dev->irq = autoirq_report(0);
 302                 
 303                 if (net_debug >= 2)
 304                         printk(" autoirq is %d\n", dev->irq);
 305         } else if (dev->irq == 2)
 306           /* Fixup for users that don't know that IRQ 2 is really IRQ 9,
 307            * or don't know which one to set. 
 308            */
 309           dev->irq = 9;
 310 
 311 #if 0
 312         {
 313                  int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005");
 314                  if (irqval) {
 315                          printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
 316                                          dev->irq, irqval);
 317                          return EAGAIN;
 318                  }
 319         }
 320 #endif
 321 
 322         /* Grab the region so we can find another board if autoIRQ fails. */
 323         request_region(ioaddr, SEEQ8005_IO_EXTENT,"seeq8005");
 324 
 325         /* Initialize the device structure. */
 326         dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
 327         if (dev->priv == NULL)
 328                 return -ENOMEM;
 329         memset(dev->priv, 0, sizeof(struct net_local));
 330 
 331         dev->open               = seeq8005_open;
 332         dev->stop               = seeq8005_close;
 333         dev->hard_start_xmit = seeq8005_send_packet;
 334         dev->get_stats  = seeq8005_get_stats;
 335         dev->set_multicast_list = &set_multicast_list;
 336 
 337         /* Fill in the fields of the device structure with ethernet values. */
 338         ether_setup(dev);
 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] */