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

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