root/drivers/net/8390.c

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

DEFINITIONS

This source file includes following definitions.
  1. ei_open
  2. ei_start_xmit
  3. ei_interrupt
  4. ei_tx_intr
  5. ei_receive
  6. ei_rx_overrun
  7. get_stats
  8. set_multicast_list
  9. ethdev_init
  10. NS8390_init
  11. NS8390_trigger_send
  12. init_module
  13. cleanup_module

   1 /* 8390.c: A general NS8390 ethernet driver core for linux. */
   2 /*
   3         Written 1992-94 by Donald Becker.
   4   
   5         Copyright 1993 United States Government as represented by the
   6         Director, National Security Agency.
   7 
   8         This software may be used and distributed according to the terms
   9         of the GNU Public License, incorporated herein by reference.
  10 
  11         The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
  12         Center of Excellence in Space Data and Information Sciences
  13            Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
  14   
  15   This is the chip-specific code for many 8390-based ethernet adaptors.
  16   This is not a complete driver, it must be combined with board-specific
  17   code such as ne.c, wd.c, 3c503.c, etc.
  18 
  19   Changelog:
  20 
  21   Paul Gortmaker        : remove set_bit lock, other cleanups.
  22 
  23   */
  24 
  25 static char *version =
  26     "8390.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
  27 
  28 /*
  29   Braindamage remaining:
  30   Much of this code should have been cleaned up, but every attempt 
  31   has broken some clone part.
  32   
  33   Sources:
  34   The National Semiconductor LAN Databook, and the 3Com 3c503 databook.
  35   */
  36 
  37 #ifdef MODULE
  38 #include <linux/module.h>
  39 #include <linux/version.h>
  40 #endif
  41 
  42 #include <linux/kernel.h>
  43 #include <linux/sched.h>
  44 #include <linux/fs.h>
  45 #include <linux/types.h>
  46 #include <linux/ptrace.h>
  47 #include <linux/string.h>
  48 #include <asm/system.h>
  49 #include <asm/segment.h>
  50 #include <asm/bitops.h>
  51 #include <asm/io.h>
  52 #include <linux/errno.h>
  53 #include <linux/fcntl.h>
  54 #include <linux/in.h>
  55 #include <linux/interrupt.h>
  56 
  57 #include <linux/netdevice.h>
  58 #include <linux/etherdevice.h>
  59 #include <linux/skbuff.h>
  60 
  61 #include "8390.h"
  62 
  63 /* These are the operational function interfaces to board-specific
  64    routines.
  65         void reset_8390(struct device *dev)
  66                 Resets the board associated with DEV, including a hardware reset of
  67                 the 8390.  This is only called when there is a transmit timeout, and
  68                 it is always followed by 8390_init().
  69         void block_output(struct device *dev, int count, const unsigned char *buf,
  70                                           int start_page)
  71                 Write the COUNT bytes of BUF to the packet buffer at START_PAGE.  The
  72                 "page" value uses the 8390's 256-byte pages.
  73         int block_input(struct device *dev, int count, char *buf, int ring_offset)
  74                 Read COUNT bytes from the packet buffer into BUF.  Start reading from
  75                 RING_OFFSET, the address as the 8390 sees it.  The first read will
  76                 always be the 4 byte, page aligned 8390 header.  *If* there is a
  77                 subsequent read, it will be of the rest of the packet.
  78 */
  79 #define ei_reset_8390 (ei_local->reset_8390)
  80 #define ei_block_output (ei_local->block_output)
  81 #define ei_block_input (ei_local->block_input)
  82 
  83 /* use 0 for production, 1 for verification, >2 for debug */
  84 #ifdef EI_DEBUG
  85 int ei_debug = EI_DEBUG;
  86 #else
  87 int ei_debug = 1;
  88 #endif
  89 
  90 /* Max number of packets received at one Intr.
  91    Currently this may only be examined by a kernel debugger. */
  92 static int high_water_mark = 0;
  93 
  94 /* Index to functions. */
  95 static void ei_tx_intr(struct device *dev);
  96 static void ei_receive(struct device *dev);
  97 static void ei_rx_overrun(struct device *dev);
  98 
  99 /* Routines generic to NS8390-based boards. */
 100 static void NS8390_trigger_send(struct device *dev, unsigned int length,
 101                                                                 int start_page);
 102 #ifdef HAVE_MULTICAST
 103 static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
 104 #endif
 105 
 106 
 107 /* Open/initialize the board.  This routine goes all-out, setting everything
 108    up anew at each open, even though many of these registers should only
 109    need to be set once at boot.
 110    */
 111 int ei_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 112 {
 113     struct ei_device *ei_local = (struct ei_device *) dev->priv;
 114     
 115     if ( ! ei_local) {
 116                 printk("%s: Opening a non-existent physical device\n", dev->name);
 117                 return ENXIO;
 118     }
 119     
 120     irq2dev_map[dev->irq] = dev;
 121     NS8390_init(dev, 1);
 122     dev->start = 1;
 123     ei_local->irqlock = 0;
 124     return 0;
 125 }
 126 
 127 static int ei_start_xmit(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 128 {
 129     int e8390_base = dev->base_addr;
 130     struct ei_device *ei_local = (struct ei_device *) dev->priv;
 131     int length, send_length;
 132     
 133 /*
 134  *  We normally shouldn't be called if dev->tbusy is set, but the
 135  *  existing code does anyway. If it has been too long since the
 136  *  last Tx, we assume the board has died and kick it.
 137  */
 138  
 139     if (dev->tbusy) {   /* Do timeouts, just like the 8003 driver. */
 140                 int txsr = inb(e8390_base+EN0_TSR), isr;
 141                 int tickssofar = jiffies - dev->trans_start;
 142                 if (tickssofar < TX_TIMEOUT ||  (tickssofar < (TX_TIMEOUT+5) && ! (txsr & ENTSR_PTX))) {
 143                         return 1;
 144                 }
 145                 isr = inb(e8390_base+EN0_ISR);
 146                 if (dev->start == 0) {
 147                         printk("%s: xmit on stopped card\n", dev->name);
 148                         return 1;
 149                 }
 150                 printk(KERN_DEBUG "%s: transmit timed out, TX status %#2x, ISR %#2x.\n",
 151                            dev->name, txsr, isr);
 152                 /* Does the 8390 thinks it has posted an interrupt? */
 153                 if (isr)
 154                         printk(KERN_DEBUG "%s: Possible IRQ conflict on IRQ%d?\n", dev->name, dev->irq);
 155                 else {
 156                         /* The 8390 probably hasn't gotten on the cable yet. */
 157                         printk(KERN_DEBUG "%s: Possible network cable problem?\n", dev->name);
 158                         if(ei_local->stat.tx_packets==0)
 159                                 ei_local->interface_num ^= 1;   /* Try a different xcvr.  */
 160                 }
 161                 /* Try to restart the card.  Perhaps the user has fixed something. */
 162                 ei_reset_8390(dev);
 163                 NS8390_init(dev, 1);
 164                 dev->trans_start = jiffies;
 165     }
 166     
 167     /* Sending a NULL skb means some higher layer thinks we've missed an
 168        tx-done interrupt. Caution: dev_tint() handles the cli()/sti()
 169        itself. */
 170     if (skb == NULL) {
 171                 dev_tint(dev);
 172                 return 0;
 173     }
 174     
 175     length = skb->len;
 176     if (skb->len <= 0)
 177                 return 0;
 178 
 179     /* Mask interrupts from the ethercard. */
 180     outb_p(0x00, e8390_base + EN0_IMR);
 181     if (dev->interrupt) {
 182         printk("%s: Tx request while isr active.\n",dev->name);
 183         outb_p(ENISR_ALL, e8390_base + EN0_IMR);
 184         return 1;
 185     }
 186     ei_local->irqlock = 1;
 187 
 188     send_length = ETH_ZLEN < length ? length : ETH_ZLEN;
 189 
 190     if (ei_local->pingpong) {
 191                 int output_page;
 192                 if (ei_local->tx1 == 0) {
 193                         output_page = ei_local->tx_start_page;
 194                         ei_local->tx1 = send_length;
 195                         if (ei_debug  &&  ei_local->tx2 > 0)
 196                                 printk("%s: idle transmitter tx2=%d, lasttx=%d, txing=%d.\n",
 197                                            dev->name, ei_local->tx2, ei_local->lasttx,
 198                                            ei_local->txing);
 199                 } else if (ei_local->tx2 == 0) {
 200                         output_page = ei_local->tx_start_page + 6;
 201                         ei_local->tx2 = send_length;
 202                         if (ei_debug  &&  ei_local->tx1 > 0)
 203                                 printk("%s: idle transmitter, tx1=%d, lasttx=%d, txing=%d.\n",
 204                                            dev->name, ei_local->tx1, ei_local->lasttx,
 205                                            ei_local->txing);
 206                 } else {        /* We should never get here. */
 207                         if (ei_debug)
 208                                 printk("%s: No Tx buffers free. irq=%d tx1=%d tx2=%d last=%d\n",
 209                                         dev->name, dev->interrupt, ei_local->tx1, 
 210                                         ei_local->tx2, ei_local->lasttx);
 211                         ei_local->irqlock = 0;
 212                         dev->tbusy = 1;
 213                         outb_p(ENISR_ALL, e8390_base + EN0_IMR);
 214                         return 1;
 215                 }
 216                 ei_block_output(dev, length, skb->data, output_page);
 217                 if (! ei_local->txing) {
 218                         ei_local->txing = 1;
 219                         NS8390_trigger_send(dev, send_length, output_page);
 220                         dev->trans_start = jiffies;
 221                         if (output_page == ei_local->tx_start_page)
 222                                 ei_local->tx1 = -1, ei_local->lasttx = -1;
 223                         else
 224                                 ei_local->tx2 = -1, ei_local->lasttx = -2;
 225                 } else
 226                         ei_local->txqueue++;
 227 
 228                 dev->tbusy = (ei_local->tx1  &&  ei_local->tx2);
 229     } else {  /* No pingpong, just a single Tx buffer. */
 230                 ei_block_output(dev, length, skb->data, ei_local->tx_start_page);
 231                 ei_local->txing = 1;
 232                 NS8390_trigger_send(dev, send_length, ei_local->tx_start_page);
 233                 dev->trans_start = jiffies;
 234                 dev->tbusy = 1;
 235     }
 236     
 237     /* Turn 8390 interrupts back on. */
 238     ei_local->irqlock = 0;
 239     outb_p(ENISR_ALL, e8390_base + EN0_IMR);
 240 
 241     dev_kfree_skb (skb, FREE_WRITE);
 242     
 243     return 0;
 244 }
 245 
 246 /* The typical workload of the driver:
 247    Handle the ether interface interrupts. */
 248 void ei_interrupt(int irq, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 249 {
 250     struct device *dev = (struct device *)(irq2dev_map[irq]);
 251     int e8390_base;
 252     int interrupts, nr_serviced = 0;
 253     struct ei_device *ei_local;
 254     
 255     if (dev == NULL) {
 256                 printk ("net_interrupt(): irq %d for unknown device.\n", irq);
 257                 return;
 258     }
 259     e8390_base = dev->base_addr;
 260     ei_local = (struct ei_device *) dev->priv;
 261     if (dev->interrupt || ei_local->irqlock) {
 262                 /* The "irqlock" check is only for testing. */
 263                 printk(ei_local->irqlock
 264                            ? "%s: Interrupted while interrupts are masked! isr=%#2x imr=%#2x.\n"
 265                            : "%s: Reentering the interrupt handler! isr=%#2x imr=%#2x.\n",
 266                            dev->name, inb_p(e8390_base + EN0_ISR),
 267                            inb_p(e8390_base + EN0_IMR));
 268                 return;
 269     }
 270     
 271     dev->interrupt = 1;
 272     
 273     /* Change to page 0 and read the intr status reg. */
 274     outb_p(E8390_NODMA+E8390_PAGE0, e8390_base + E8390_CMD);
 275     if (ei_debug > 3)
 276                 printk("%s: interrupt(isr=%#2.2x).\n", dev->name,
 277                            inb_p(e8390_base + EN0_ISR));
 278     
 279     /* !!Assumption!! -- we stay in page 0.      Don't break this. */
 280     while ((interrupts = inb_p(e8390_base + EN0_ISR)) != 0
 281                    && ++nr_serviced < MAX_SERVICE) {
 282                 if (dev->start == 0) {
 283                         printk("%s: interrupt from stopped card\n", dev->name);
 284                         interrupts = 0;
 285                         break;
 286                 }
 287                 if (interrupts & ENISR_OVER) {
 288                         ei_rx_overrun(dev);
 289                 } else if (interrupts & (ENISR_RX+ENISR_RX_ERR)) {
 290                         /* Got a good (?) packet. */
 291                         ei_receive(dev);
 292                 }
 293                 /* Push the next to-transmit packet through. */
 294                 if (interrupts & ENISR_TX) {
 295                         ei_tx_intr(dev);
 296                 } else if (interrupts & ENISR_COUNTERS) {
 297                         ei_local->stat.rx_frame_errors += inb_p(e8390_base + EN0_COUNTER0);
 298                         ei_local->stat.rx_crc_errors   += inb_p(e8390_base + EN0_COUNTER1);
 299                         ei_local->stat.rx_missed_errors+= inb_p(e8390_base + EN0_COUNTER2);
 300                         outb_p(ENISR_COUNTERS, e8390_base + EN0_ISR); /* Ack intr. */
 301                 }
 302                 
 303                 /* Ignore the transmit errs and reset intr for now. */
 304                 if (interrupts & ENISR_TX_ERR) {
 305                         outb_p(ENISR_TX_ERR, e8390_base + EN0_ISR); /* Ack intr. */
 306                 }
 307 
 308                 /* Ignore any RDC interrupts that make it back to here. */
 309                 if (interrupts & ENISR_RDC) {
 310                                 outb_p(ENISR_RDC, e8390_base + EN0_ISR);
 311                 }
 312 
 313                 outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD);
 314     }
 315     
 316     if (interrupts && ei_debug) {
 317                 outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD);
 318                 if (nr_serviced >= MAX_SERVICE) {
 319                         printk("%s: Too much work at interrupt, status %#2.2x\n",
 320                                    dev->name, interrupts);
 321                         outb_p(ENISR_ALL, e8390_base + EN0_ISR); /* Ack. most intrs. */
 322                 } else {
 323                         printk("%s: unknown interrupt %#2x\n", dev->name, interrupts);
 324                         outb_p(0xff, e8390_base + EN0_ISR); /* Ack. all intrs. */
 325                 }
 326     }
 327     dev->interrupt = 0;
 328     return;
 329 }
 330 
 331 /* We have finished a transmit: check for errors and then trigger the next
 332    packet to be sent. */
 333 static void ei_tx_intr(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 334 {
 335     int e8390_base = dev->base_addr;
 336     int status = inb(e8390_base + EN0_TSR);
 337     struct ei_device *ei_local = (struct ei_device *) dev->priv;
 338     
 339     outb_p(ENISR_TX, e8390_base + EN0_ISR); /* Ack intr. */
 340     
 341     if (ei_local->pingpong) {
 342                 ei_local->txqueue--;
 343                 if (ei_local->tx1 < 0) {
 344                         if (ei_local->lasttx != 1 && ei_local->lasttx != -1)
 345                                 printk("%s: bogus last_tx_buffer %d, tx1=%d.\n",
 346                                            ei_local->name, ei_local->lasttx, ei_local->tx1);
 347                         ei_local->tx1 = 0;
 348                         dev->tbusy = 0;
 349                         if (ei_local->tx2 > 0) {
 350                                 ei_local->txing = 1;
 351                                 NS8390_trigger_send(dev, ei_local->tx2, ei_local->tx_start_page + 6);
 352                                 dev->trans_start = jiffies;
 353                                 ei_local->tx2 = -1,
 354                                 ei_local->lasttx = 2;
 355                         } else
 356                                 ei_local->lasttx = 20, ei_local->txing = 0;
 357                 } else if (ei_local->tx2 < 0) {
 358                         if (ei_local->lasttx != 2  &&  ei_local->lasttx != -2)
 359                                 printk("%s: bogus last_tx_buffer %d, tx2=%d.\n",
 360                                            ei_local->name, ei_local->lasttx, ei_local->tx2);
 361                         ei_local->tx2 = 0;
 362                         dev->tbusy = 0;
 363                         if (ei_local->tx1 > 0) {
 364                                 ei_local->txing = 1;
 365                                 NS8390_trigger_send(dev, ei_local->tx1, ei_local->tx_start_page);
 366                                 dev->trans_start = jiffies;
 367                                 ei_local->tx1 = -1;
 368                                 ei_local->lasttx = 1;
 369                         } else
 370                                 ei_local->lasttx = 10, ei_local->txing = 0;
 371                 } else
 372                         printk("%s: unexpected TX-done interrupt, lasttx=%d.\n",
 373                                    dev->name, ei_local->lasttx);
 374     } else {
 375                 ei_local->txing = 0;
 376                 dev->tbusy = 0;
 377     }
 378 
 379     /* Minimize Tx latency: update the statistics after we restart TXing. */
 380         if (status & ENTSR_COL) ei_local->stat.collisions++;
 381     if (status & ENTSR_PTX)
 382                 ei_local->stat.tx_packets++;
 383     else {
 384                 ei_local->stat.tx_errors++;
 385                 if (status & ENTSR_ABT) ei_local->stat.tx_aborted_errors++;
 386                 if (status & ENTSR_CRS) ei_local->stat.tx_carrier_errors++;
 387                 if (status & ENTSR_FU)  ei_local->stat.tx_fifo_errors++;
 388                 if (status & ENTSR_CDH) ei_local->stat.tx_heartbeat_errors++;
 389                 if (status & ENTSR_OWC) ei_local->stat.tx_window_errors++;
 390         }
 391     
 392     mark_bh (NET_BH);
 393 }
 394 
 395 /* We have a good packet(s), get it/them out of the buffers. */
 396 
 397 static void ei_receive(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 398 {
 399     int e8390_base = dev->base_addr;
 400     struct ei_device *ei_local = (struct ei_device *) dev->priv;
 401     int rxing_page, this_frame, next_frame, current_offset;
 402     int rx_pkt_count = 0;
 403     struct e8390_pkt_hdr rx_frame;
 404     int num_rx_pages = ei_local->stop_page-ei_local->rx_start_page;
 405     
 406     while (++rx_pkt_count < 10) {
 407                 int pkt_len;
 408                 
 409                 /* Get the rx page (incoming packet pointer). */
 410                 outb_p(E8390_NODMA+E8390_PAGE1, e8390_base + E8390_CMD);
 411                 rxing_page = inb_p(e8390_base + EN1_CURPAG);
 412                 outb_p(E8390_NODMA+E8390_PAGE0, e8390_base + E8390_CMD);
 413                 
 414                 /* Remove one frame from the ring.  Boundary is always a page behind. */
 415                 this_frame = inb_p(e8390_base + EN0_BOUNDARY) + 1;
 416                 if (this_frame >= ei_local->stop_page)
 417                         this_frame = ei_local->rx_start_page;
 418                 
 419                 /* Someday we'll omit the previous, iff we never get this message.
 420                    (There is at least one clone claimed to have a problem.)  */
 421                 if (ei_debug > 0  &&  this_frame != ei_local->current_page)
 422                         printk("%s: mismatched read page pointers %2x vs %2x.\n",
 423                                    dev->name, this_frame, ei_local->current_page);
 424                 
 425                 if (this_frame == rxing_page)   /* Read all the frames? */
 426                         break;                          /* Done for now */
 427                 
 428                 current_offset = this_frame << 8;
 429                 ei_block_input(dev, sizeof(rx_frame), (char *)&rx_frame,
 430                                            current_offset);
 431                 
 432                 pkt_len = rx_frame.count - sizeof(rx_frame);
 433                 
 434                 next_frame = this_frame + 1 + ((pkt_len+4)>>8);
 435                 
 436                 /* Check for bogosity warned by 3c503 book: the status byte is never
 437                    written.  This happened a lot during testing! This code should be
 438                    cleaned up someday. */
 439                 if (rx_frame.next != next_frame
 440                         && rx_frame.next != next_frame + 1
 441                         && rx_frame.next != next_frame - num_rx_pages
 442                         && rx_frame.next != next_frame + 1 - num_rx_pages) {
 443                         ei_local->current_page = rxing_page;
 444                         outb(ei_local->current_page-1, e8390_base+EN0_BOUNDARY);
 445                         ei_local->stat.rx_errors++;
 446                         continue;
 447                 }
 448 
 449                 if (pkt_len < 60  ||  pkt_len > 1518) {
 450                         if (ei_debug)
 451                                 printk("%s: bogus packet size: %d, status=%#2x nxpg=%#2x.\n",
 452                                            dev->name, rx_frame.count, rx_frame.status,
 453                                            rx_frame.next);
 454                         ei_local->stat.rx_errors++;
 455                 } else if ((rx_frame.status & 0x0F) == ENRSR_RXOK) {
 456                         struct sk_buff *skb;
 457                         
 458                         skb = alloc_skb(pkt_len, GFP_ATOMIC);
 459                         if (skb == NULL) {
 460                                 if (ei_debug > 1)
 461                                         printk("%s: Couldn't allocate a sk_buff of size %d.\n",
 462                                                    dev->name, pkt_len);
 463                                 ei_local->stat.rx_dropped++;
 464                                 break;
 465                         } else {
 466                                 skb->len = pkt_len;
 467                                 skb->dev = dev;
 468                                 
 469                                 ei_block_input(dev, pkt_len, (char *) skb->data,
 470                                                            current_offset + sizeof(rx_frame));
 471                                 skb->protocol=eth_type_trans(skb,dev);
 472                                 netif_rx(skb);
 473                                 ei_local->stat.rx_packets++;
 474                         }
 475                 } else {
 476                         int errs = rx_frame.status;
 477                         if (ei_debug)
 478                                 printk("%s: bogus packet: status=%#2x nxpg=%#2x size=%d\n",
 479                                            dev->name, rx_frame.status, rx_frame.next,
 480                                            rx_frame.count);
 481                         if (errs & ENRSR_FO)
 482                                 ei_local->stat.rx_fifo_errors++;
 483                 }
 484                 next_frame = rx_frame.next;
 485                 
 486                 /* This _should_ never happen: it's here for avoiding bad clones. */
 487                 if (next_frame >= ei_local->stop_page) {
 488                         printk("%s: next frame inconsistency, %#2x\n", dev->name,
 489                                    next_frame);
 490                         next_frame = ei_local->rx_start_page;
 491                 }
 492                 ei_local->current_page = next_frame;
 493                 outb_p(next_frame-1, e8390_base+EN0_BOUNDARY);
 494     }
 495     /* If any worth-while packets have been received, netif_rx()
 496        has done a mark_bh(NET_BH) for us and will work on them
 497        when we get to the bottom-half routine. */
 498 
 499         /* Record the maximum Rx packet queue. */
 500         if (rx_pkt_count > high_water_mark)
 501                 high_water_mark = rx_pkt_count;
 502 
 503     /* Bug alert!  Reset ENISR_OVER to avoid spurious overruns! */
 504     outb_p(ENISR_RX+ENISR_RX_ERR+ENISR_OVER, e8390_base+EN0_ISR);
 505     return;
 506 }
 507 
 508 /* We have a receiver overrun: we have to kick the 8390 to get it started
 509    again.*/
 510 static void ei_rx_overrun(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 511 {
 512     int e8390_base = dev->base_addr;
 513     int reset_start_time = jiffies;
 514     struct ei_device *ei_local = (struct ei_device *) dev->priv;
 515     
 516     /* We should already be stopped and in page0.  Remove after testing. */
 517     outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD);
 518     
 519     if (ei_debug > 1)
 520                 printk("%s: Receiver overrun.\n", dev->name);
 521     ei_local->stat.rx_over_errors++;
 522     
 523     /* The old Biro driver does dummy = inb_p( RBCR[01] ); at this point.
 524        It might mean something -- magic to speed up a reset?  A 8390 bug?*/
 525     
 526     /* Wait for the reset to complete.  This should happen almost instantly,
 527            but could take up to 1.5msec in certain rare instances.  There is no
 528            easy way of timing something in that range, so we use 'jiffies' as
 529            a sanity check. */
 530     while ((inb_p(e8390_base+EN0_ISR) & ENISR_RESET) == 0)
 531                 if (jiffies - reset_start_time > 1) {
 532                         printk("%s: reset did not complete at ei_rx_overrun.\n",
 533                                    dev->name);
 534                         NS8390_init(dev, 1);
 535                         return;
 536                 }
 537     
 538     /* Remove packets right away. */
 539     ei_receive(dev);
 540     
 541     outb_p(0xff, e8390_base+EN0_ISR);
 542     /* Generic 8390 insns to start up again, same as in open_8390(). */
 543     outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START, e8390_base + E8390_CMD);
 544     outb_p(E8390_TXCONFIG, e8390_base + EN0_TXCR); /* xmit on. */
 545 }
 546 
 547 static struct enet_statistics *get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 548 {
 549     short ioaddr = dev->base_addr;
 550     struct ei_device *ei_local = (struct ei_device *) dev->priv;
 551     
 552     /* If the card is stopped, just return the present stats. */
 553     if (dev->start == 0) return &ei_local->stat;
 554 
 555     /* Read the counter registers, assuming we are in page 0. */
 556     ei_local->stat.rx_frame_errors += inb_p(ioaddr + EN0_COUNTER0);
 557     ei_local->stat.rx_crc_errors   += inb_p(ioaddr + EN0_COUNTER1);
 558     ei_local->stat.rx_missed_errors+= inb_p(ioaddr + EN0_COUNTER2);
 559     
 560     return &ei_local->stat;
 561 }
 562 
 563 #ifdef HAVE_MULTICAST
 564 /* Set or clear the multicast filter for this adaptor.
 565    num_addrs == -1      Promiscuous mode, receive all packets
 566    num_addrs == 0       Normal mode, clear multicast list
 567    num_addrs > 0        Multicast mode, receive normal and MC packets, and do
 568    .                            best-effort filtering.
 569    */
 570 static void set_multicast_list(struct device *dev, int num_addrs, void *addrs)
     /* [previous][next][first][last][top][bottom][index][help] */
 571 {
 572     short ioaddr = dev->base_addr;
 573     
 574     if (num_addrs > 0) {
 575                 /* The multicast-accept list is initialized to accept-all, and we
 576                    rely on higher-level filtering for now. */
 577                 outb_p(E8390_RXCONFIG | 0x08, ioaddr + EN0_RXCR);
 578     } else if (num_addrs < 0)
 579                 outb_p(E8390_RXCONFIG | 0x18, ioaddr + EN0_RXCR);
 580     else
 581                 outb_p(E8390_RXCONFIG, ioaddr + EN0_RXCR);
 582 }
 583 #endif
 584 
 585 /* Initialize the rest of the 8390 device structure. */
 586 int ethdev_init(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 587 {
 588     if (ei_debug > 1)
 589                 printk(version);
 590     
 591     if (dev->priv == NULL) {
 592                 struct ei_device *ei_local;
 593                 
 594                 dev->priv = kmalloc(sizeof(struct ei_device), GFP_KERNEL);
 595                 memset(dev->priv, 0, sizeof(struct ei_device));
 596                 ei_local = (struct ei_device *)dev->priv;
 597 #ifndef NO_PINGPONG
 598                 ei_local->pingpong = 1;
 599 #endif
 600     }
 601     
 602     /* The open call may be overridden by the card-specific code. */
 603     if (dev->open == NULL)
 604                 dev->open = &ei_open;
 605     /* We should have a dev->stop entry also. */
 606     dev->hard_start_xmit = &ei_start_xmit;
 607     dev->get_stats      = get_stats;
 608 #ifdef HAVE_MULTICAST
 609     dev->set_multicast_list = &set_multicast_list;
 610 #endif
 611 
 612     ether_setup(dev);
 613         
 614     return 0;
 615 }
 616 
 617 
 618 /* This page of functions should be 8390 generic */
 619 /* Follow National Semi's recommendations for initializing the "NIC". */
 620 void NS8390_init(struct device *dev, int startp)
     /* [previous][next][first][last][top][bottom][index][help] */
 621 {
 622     int e8390_base = dev->base_addr;
 623     struct ei_device *ei_local = (struct ei_device *) dev->priv;
 624     int i;
 625     int endcfg = ei_local->word16 ? (0x48 | ENDCFG_WTS) : 0x48;
 626     unsigned long flags;
 627     
 628     /* Follow National Semi's recommendations for initing the DP83902. */
 629     outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base); /* 0x21 */
 630     outb_p(endcfg, e8390_base + EN0_DCFG);      /* 0x48 or 0x49 */
 631     /* Clear the remote byte count registers. */
 632     outb_p(0x00,  e8390_base + EN0_RCNTLO);
 633     outb_p(0x00,  e8390_base + EN0_RCNTHI);
 634     /* Set to monitor and loopback mode -- this is vital!. */
 635     outb_p(E8390_RXOFF, e8390_base + EN0_RXCR); /* 0x20 */
 636     outb_p(E8390_TXOFF, e8390_base + EN0_TXCR); /* 0x02 */
 637     /* Set the transmit page and receive ring. */
 638     outb_p(ei_local->tx_start_page,      e8390_base + EN0_TPSR);
 639     ei_local->tx1 = ei_local->tx2 = 0;
 640     outb_p(ei_local->rx_start_page,      e8390_base + EN0_STARTPG);
 641     outb_p(ei_local->stop_page-1, e8390_base + EN0_BOUNDARY); /* 3c503 says 0x3f,NS0x26*/
 642     ei_local->current_page = ei_local->rx_start_page;           /* assert boundary+1 */
 643     outb_p(ei_local->stop_page,   e8390_base + EN0_STOPPG);
 644     /* Clear the pending interrupts and mask. */
 645     outb_p(0xFF, e8390_base + EN0_ISR);
 646     outb_p(0x00,  e8390_base + EN0_IMR);
 647     
 648     /* Copy the station address into the DS8390 registers,
 649        and set the multicast hash bitmap to receive all multicasts. */
 650     save_flags(flags);
 651     cli();
 652     outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP, e8390_base); /* 0x61 */
 653     for(i = 0; i < 6; i++) {
 654                 outb_p(dev->dev_addr[i], e8390_base + EN1_PHYS + i);
 655     }
 656     /* Initialize the multicast list to accept-all.  If we enable multicast
 657        the higher levels can do the filtering. */
 658     for(i = 0; i < 8; i++)
 659                 outb_p(0xff, e8390_base + EN1_MULT + i);
 660     
 661     outb_p(ei_local->rx_start_page,      e8390_base + EN1_CURPAG);
 662     outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base);
 663     restore_flags(flags);
 664     dev->tbusy = 0;
 665     dev->interrupt = 0;
 666     ei_local->tx1 = ei_local->tx2 = 0;
 667     ei_local->txing = 0;
 668     if (startp) {
 669                 outb_p(0xff,  e8390_base + EN0_ISR);
 670                 outb_p(ENISR_ALL,  e8390_base + EN0_IMR);
 671                 outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base);
 672                 outb_p(E8390_TXCONFIG, e8390_base + EN0_TXCR); /* xmit on. */
 673                 /* 3c503 TechMan says rxconfig only after the NIC is started. */
 674                 outb_p(E8390_RXCONFIG,  e8390_base + EN0_RXCR); /* rx on,  */
 675     }
 676     return;
 677 }
 678 
 679 /* Trigger a transmit start, assuming the length is valid. */
 680 static void NS8390_trigger_send(struct device *dev, unsigned int length,
     /* [previous][next][first][last][top][bottom][index][help] */
 681                                                                 int start_page)
 682 {
 683     int e8390_base = dev->base_addr;
 684     
 685     outb_p(E8390_NODMA+E8390_PAGE0, e8390_base);
 686     
 687     if (inb_p(e8390_base) & E8390_TRANS) {
 688                 printk("%s: trigger_send() called with the transmitter busy.\n",
 689                            dev->name);
 690                 return;
 691     }
 692     outb_p(length & 0xff, e8390_base + EN0_TCNTLO);
 693     outb_p(length >> 8, e8390_base + EN0_TCNTHI);
 694     outb_p(start_page, e8390_base + EN0_TPSR);
 695     outb_p(E8390_NODMA+E8390_TRANS+E8390_START, e8390_base);
 696     return;
 697 }
 698 
 699 #ifdef MODULE
 700 char kernel_version[] = UTS_RELEASE;
 701 
 702 int init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 703 {
 704      return 0;
 705 }
 706 
 707 void
 708 cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 709 {
 710 }
 711 #endif /* MODULE */
 712 
 713 /*
 714  * Local variables:
 715  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c 8390.c"
 716  *  version-control: t
 717  *  kept-new-versions: 5
 718  *  c-indent-level: 4
 719  *  tab-width: 4
 720  * End:
 721  */

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