root/drivers/net/hydra.c

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

DEFINITIONS

This source file includes following definitions.
  1. memcpyw
  2. memcpyw
  3. hydra_probe
  4. hydra_open
  5. hydra_close
  6. hydra_interrupt
  7. hydra_start_xmit
  8. hydra_rx
  9. hydra_get_stats
  10. set_multicast_list

   1 /* Linux/68k Hydra Amiganet board driver v2.1 BETA                          */
   2 /* copyleft by Topi Kanerva (topi@susanna.oulu.fi)                          */
   3 /* also some code & lots of fixes by Timo Rossi (trossi@cc.jyu.fi)          */
   4 
   5 /* The code is mostly based on the linux/68k Ariadne driver                 */
   6 /* copyrighted by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be) */
   7 /* and Peter De Schrijver (Peter.DeSchrijver@linux.cc.kuleuven.ac.be)       */
   8 
   9 /* This file is subject to the terms and conditions of the GNU General      */
  10 /* Public License.  See the file README.legal in the main directory of the  */
  11 /* Linux/68k distribution for more details.                                 */
  12 
  13 /* The Amiganet is a Zorro-II board made by Hydra Systems. It contains a    */
  14 /* NS8390 NIC (network interface controller) clone, 16 or 64K on-board RAM  */
  15 /* and 10BASE-2 (thin coax) and AUI connectors.                             */
  16 
  17 
  18 #include <linux/kernel.h>
  19 #include <linux/sched.h>
  20 #include <linux/string.h>
  21 #include <linux/ptrace.h>
  22 #include <linux/errno.h>
  23 #include <linux/ioport.h>
  24 #include <linux/malloc.h>
  25 #include <linux/interrupt.h>
  26 #include <linux/netdevice.h>
  27 #include <linux/skbuff.h>
  28 
  29 #include <asm/bitops.h>
  30 #include <asm/io.h>
  31 #include <asm/irq.h>
  32 
  33 #include <asm/bootinfo.h>
  34 #include <asm/amigaints.h>
  35 #include <asm/amigahw.h>
  36 #include <asm/zorro.h>
  37 
  38 #include "hydra.h"
  39 
  40 
  41 #define HYDRA_DEBUG
  42 #undef HAVE_MULTICAST
  43 
  44 #define HYDRA_VERSION "v2.1 BETA"
  45 
  46 struct device *init_etherdev(struct device *dev, int sizeof_private, unsigned long *mem_startp);
  47 
  48 #undef HYDRA_DEBUG        /* define this for (lots of) debugging information */
  49 
  50 #if 0                         /* currently hardwired to one transmit buffer */
  51  #define TX_RING_SIZE   5
  52  #define RX_RING_SIZE   16
  53 #else
  54  #define TX_RING_SIZE 1
  55  #define RX_RING_SIZE 8
  56 #endif
  57 
  58 #define ETHER_MIN_LEN 64
  59 #define ETHER_MAX_LEN 1518
  60 #define ETHER_ADDR_LEN 6
  61 
  62 
  63 /*
  64  *   let's define here nice macros for writing and reading NIC registers
  65  *
  66  * the CIA accesses here are uses to make sure the minimum time
  67  * requirement between NIC chip selects is met.
  68  */
  69 #define WRITE_REG(reg, val) (ciaa.pra, ((u_char)(*(nicbase+(reg))=val)))
  70 #define READ_REG(reg) (ciaa.pra, ((u_char)(*(nicbase+(reg)))))
  71 
  72 /* mask value for the interrupts we use */
  73 #define NIC_INTS (ISR_PRX | ISR_PTX | ISR_RXE | ISR_TXE | ISR_OVW | ISR_CNT)
  74 
  75 /* only broadcasts, no promiscuous mode for now */
  76 #define NIC_RCRBITS (0)
  77 
  78 /*
  79  *   Private Device Data
  80  */
  81 struct hydra_private
  82     {
  83     u_char *hydra_base;
  84     u_char *hydra_nic_base;
  85     u_short tx_page_start;
  86     u_short rx_page_start;
  87     u_short rx_page_stop;
  88     u_short next_pkt;
  89     struct enet_statistics stats;
  90     };
  91 
  92 static int hydra_open(struct device *dev);
  93 static int hydra_start_xmit(struct sk_buff *skb, struct device *dev);
  94 static void hydra_interrupt(int irq, struct pt_regs *fp, void *data);
  95 static void __inline__ hydra_rx(struct device *dev, struct hydra_private *priv, u_char *nicbase);
  96 static int hydra_close(struct device *dev);
  97 static struct enet_statistics *hydra_get_stats(struct device *dev);
  98 #ifdef HAVE_MULTICAST
  99 static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
 100 #endif
 101 
 102 
 103 /* this is now coherent to the C version below, */
 104 /* compile the source with -D__USE_ASM__ if you */
 105 /* want it - it'll only be some 10% faster thou */
 106 
 107 #if defined (__GNUC__) && defined (__mc68000__) && defined (USE_ASM)
 108 
 109 static __inline__ void *memcpyw(u_short *dest, u_short *src, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 110     {
 111     __asm__("   move.l %0,%/a1; move.l %1,%/a0; move.l %2,%/d0 \n\t"
 112             "   cmpi.l #2,%/d0 \n\t"
 113             "1: bcs.s  2f \n\t"
 114             "   move.w %/a0@+,%/a1@+ \n\t"
 115             "   subq.l #2,%/d0 \n\t"
 116             "   bra.s  1b \n\t"
 117             "2: cmpi.l #1,%/d0 \n\t"
 118             "   bne.s  3f \n\t"
 119             "   move.w %/a0@,%/d0 \n\t"
 120             "   swap.w %/d0 \n\t"
 121             "   move.b %/d0,%/a1@ \n\t"
 122             "3: moveq  #0,%/d0 \n\t"
 123           :
 124           : "g" (dest), "g" (src), "g" (len)
 125           : "a1", "a0", "d0");
 126     return;
 127 }
 128 
 129 #else
 130 
 131 /* hydra memory can only be read or written as words or longwords.  */
 132 /* that will mean that we'll have to write a special memcpy for it. */
 133 /* this one here relies on the fact that _writes_ to hydra memory   */
 134 /* are guaranteed to be of even length. (reads can be arbitrary)    */
 135 
 136 static void memcpyw(u_short *dest, u_short *src, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 137 {
 138   if(len & 1)
 139     len++;
 140 
 141   while (len >= 2) {
 142     *(dest++) = *(src++);
 143     len -= 2;
 144   }
 145     
 146 }
 147 
 148 #endif
 149 
 150 unsigned long hydra_probe(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 151     {
 152     struct hydra_private *priv;
 153     u_long board;
 154     int key;
 155     struct ConfigDev *cd;
 156     int j;
 157 
 158 #ifdef HYDRA_DEBUG
 159  printk("hydra_probe(%x)\n", dev);
 160 #endif
 161 
 162     if ((key = zorro_find(MANUF_HYDRA_SYSTEMS, PROD_AMIGANET, 0, 0))) {
 163         cd = zorro_get_board(key);
 164         if((board = (u_long) cd->cd_BoardAddr))
 165             {
 166             for(j = 0; j < ETHER_ADDR_LEN; j++)
 167                 dev->dev_addr[j] = *((u_char *)ZTWO_VADDR(board + HYDRA_ADDRPROM + 2*j));
 168             
 169             printk("%s: hydra at 0x%08x, address %02x:%02x:%02x:%02x:%02x:%02x (hydra.c " HYDRA_VERSION ")\n",
 170                    dev->name, (int)board, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
 171                    dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
 172 
 173             init_etherdev(dev, 0, NULL);
 174             
 175             dev->priv = kmalloc(sizeof(struct hydra_private), GFP_KERNEL);
 176             priv = (struct hydra_private *)dev->priv;
 177             memset(priv, 0, sizeof(struct hydra_private));
 178             
 179             priv->hydra_base = (u_char *) ZTWO_VADDR(board);
 180             priv->hydra_nic_base = (u_char *) ZTWO_VADDR(board) + HYDRA_NIC_BASE;
 181             
 182             dev->open = &hydra_open;
 183             dev->stop = &hydra_close;
 184             dev->hard_start_xmit = &hydra_start_xmit;
 185             dev->get_stats = &hydra_get_stats;
 186 #ifdef HAVE_MULTICAST
 187             dev->set_multicast_list = &hydra_set_multicast_list;
 188 #endif
 189             zorro_config_board(key, 0);
 190             return(0);
 191             }
 192         }
 193     return(ENODEV);
 194     }
 195 
 196 
 197 static int hydra_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 198   {
 199     struct hydra_private *priv = (struct hydra_private *)dev->priv;
 200     static int interruptinstalled = 0;
 201     u_char volatile *nicbase = priv->hydra_nic_base;
 202 #ifdef HAVE_MULTICAST
 203     int i;
 204 #endif
 205     
 206 #ifdef HYDRA_DEBUG
 207  printk("hydra_open(0x%x)\n", dev);
 208 #endif
 209 
 210     /* first, initialize the private structure */
 211     priv->tx_page_start = 0;   /* these are 256 byte buffers for NS8390 */
 212     priv->rx_page_start = 6;
 213     priv->rx_page_stop  = 62;  /* these values are hard coded for now */
 214 
 215     /* Reset the NS8390 NIC */
 216     WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_STOP);
 217 
 218     /* be sure that the NIC is in stopped state */
 219     while(!(READ_REG(NIC_ISR) & ISR_RST));
 220 
 221     /* word transfer, big endian bytes, loopback, FIFO threshold 4 bytes */
 222     WRITE_REG(NIC_DCR, DCR_WTS | DCR_BOS | DCR_LS | DCR_FT0);
 223 
 224     /* clear remote byte count registers */
 225     WRITE_REG(NIC_RBCR0, 0);
 226     WRITE_REG(NIC_RBCR1, 0);
 227 
 228     /* accept packets addressed to this card and also broadcast packets */
 229     WRITE_REG(NIC_RCR, NIC_RCRBITS);
 230 
 231     /* enable loopback mode 1 */
 232     WRITE_REG(NIC_TCR, TCR_LB1);
 233 
 234     /* initialize receive buffer ring */
 235     WRITE_REG(NIC_PSTART, priv->rx_page_start);
 236     WRITE_REG(NIC_PSTOP, priv->rx_page_stop);
 237     WRITE_REG(NIC_BNDRY, priv->rx_page_start);
 238 
 239     /* clear interrupts */
 240     WRITE_REG(NIC_ISR, 0xff);
 241 
 242     /* enable interrupts */
 243     WRITE_REG(NIC_IMR, NIC_INTS);
 244 
 245     /* set the ethernet hardware address */
 246     WRITE_REG(NIC_CR, CR_PAGE1 | CR_NODMA | CR_STOP); /* goto page 1 */
 247 
 248     WRITE_REG(NIC_PAR0, dev->dev_addr[0]);
 249     WRITE_REG(NIC_PAR1, dev->dev_addr[1]);
 250     WRITE_REG(NIC_PAR2, dev->dev_addr[2]);
 251     WRITE_REG(NIC_PAR3, dev->dev_addr[3]);
 252     WRITE_REG(NIC_PAR4, dev->dev_addr[4]);
 253     WRITE_REG(NIC_PAR5, dev->dev_addr[5]);
 254 
 255 #ifdef HAVE_MULTICAST
 256     /* clear multicast hash table */
 257     for(i = 0; i < 8; i++)
 258       WRITE_REG(NIC_MAR0 + 2*i, 0);
 259 #endif
 260 
 261     priv->next_pkt = priv->rx_page_start+1; /* init our s/w variable */
 262     WRITE_REG(NIC_CURR, priv->next_pkt);    /* set the next buf for current */
 263 
 264     /* goto page 0, start NIC */
 265     WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_START);
 266 
 267     /* take interface out of loopback */
 268     WRITE_REG(NIC_TCR, 0);
 269 
 270     dev->tbusy = 0;
 271     dev->interrupt = 0;
 272     dev->start = 1;
 273     
 274     if(!interruptinstalled) {
 275       if(!add_isr(IRQ_AMIGA_PORTS, hydra_interrupt, 0, dev,
 276                                   "Hydra Ethernet"))
 277         return(-EAGAIN);
 278       interruptinstalled = 1;
 279     }
 280 
 281     return(0);
 282   }
 283 
 284 
 285 static int hydra_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 286 {
 287   struct hydra_private *priv = (struct hydra_private *)dev->priv;
 288   u_char volatile *nicbase = priv->hydra_nic_base;
 289   int n = 5000;
 290 
 291   dev->start = 0;
 292   dev->tbusy = 1;
 293 
 294 #ifdef HYDRA_DEBUG
 295   printk("%s: Shutting down ethercard\n", dev->name);
 296   printk("%s: %d packets missed\n", dev->name, priv->stats.rx_missed_errors);
 297 #endif
 298 
 299   WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_STOP);
 300 
 301   /* wait for NIC to stop (what a nice timeout..) */
 302   while(((READ_REG(NIC_ISR) & ISR_RST) == 0) && --n);
 303     
 304   return(0);
 305 }
 306 
 307 
 308 static void hydra_interrupt(int irq, struct pt_regs *fp, void *data)
     /* [previous][next][first][last][top][bottom][index][help] */
 309     {
 310     u_char volatile *nicbase;
 311   
 312     struct device *dev = (struct device *) data;
 313     struct hydra_private *priv;
 314     u_short intbits;
 315 
 316     if(dev == NULL)
 317         {
 318         printk("hydra_interrupt(): irq for unknown device\n");
 319         return;
 320         }
 321 
 322 /* this is not likely a problem - i think */
 323     if(dev->interrupt)
 324         printk("%s: re-entering the interrupt handler\n", dev->name);
 325 
 326     dev->interrupt = 1;
 327 
 328     priv = (struct hydra_private *) dev->priv;
 329     nicbase = (u_char *) priv->hydra_nic_base;
 330 
 331     /* select page 0 */
 332     WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA);
 333 
 334     intbits = READ_REG(NIC_ISR) & NIC_INTS;
 335     if(intbits == 0)
 336         {
 337         dev->interrupt = 0;
 338         return;
 339         }
 340 
 341         /* acknowledge all interrupts, by clearing the interrupt flag */
 342         WRITE_REG(NIC_ISR, intbits);
 343 
 344         if((intbits & ISR_PTX) && !(intbits & ISR_TXE))
 345             {
 346             dev->tbusy = 0;
 347             mark_bh(NET_BH);
 348             }
 349         
 350         if((intbits & ISR_PRX) && !(intbits & ISR_RXE))/* packet received OK */
 351               hydra_rx(dev, priv, nicbase);
 352 
 353         if(intbits & ISR_TXE)
 354             priv->stats.tx_errors++;
 355 
 356         if(intbits & ISR_RXE)
 357             priv->stats.rx_errors++;
 358 
 359         if(intbits & ISR_CNT) {
 360           /*
 361            * read the tally counters and (currently) ignore the values
 362            * might be useful because of bugs of some versions of the 8390 NIC
 363            */
 364 #ifdef HYDRA_DEBUG
 365           printk("hydra_interrupt(): ISR_CNT\n");
 366 #endif
 367           (void)READ_REG(NIC_CNTR0);
 368           (void)READ_REG(NIC_CNTR1);
 369           (void)READ_REG(NIC_CNTR2);
 370         }
 371         
 372         if(intbits & ISR_OVW)
 373             {
 374             #ifdef HYDRA_DEBUG
 375             WRITE_REG(NIC_CR, CR_PAGE1 | CR_START | CR_NODMA);
 376 /* another one just too much for me to comprehend - basically this could  */
 377 /* only occur because of invalid access to hydra ram, thus invalidating  */
 378 /* the interrupt bits read - in average usage these do not occur at all */
 379             printk("hydra_interrupt(): overwrite warning, NIC_ISR %02x, NIC_CURR %02x\n",
 380                  intbits, READ_REG(NIC_CURR));
 381             WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA);
 382             #endif
 383             
 384 
 385             /* overwrite warning occured, stop NIC & check the BOUNDARY pointer */
 386             /* FIXME - real overwrite handling needed !! */
 387 
 388             printk("hydra_interrupt(): overwrite warning, resetting NIC\n");
 389             WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_STOP);
 390             while(!(READ_REG(NIC_ISR) & ISR_RST));
 391             /* wait for NIC to reset */
 392             WRITE_REG(NIC_DCR, DCR_WTS | DCR_BOS | DCR_LS | DCR_FT0);
 393             WRITE_REG(NIC_RBCR0, 0);
 394             WRITE_REG(NIC_RBCR1, 0);
 395             WRITE_REG(NIC_RCR, NIC_RCRBITS);
 396             WRITE_REG(NIC_TCR, TCR_LB1);
 397             WRITE_REG(NIC_PSTART, priv->rx_page_start);
 398             WRITE_REG(NIC_PSTOP, priv->rx_page_stop);
 399             WRITE_REG(NIC_BNDRY, priv->rx_page_start);
 400             WRITE_REG(NIC_ISR, 0xff);
 401             WRITE_REG(NIC_IMR, NIC_INTS);
 402 /* currently this _won't_ reset my hydra, even though it is */
 403 /* basically the same code as in the board init - any ideas? */
 404 
 405             priv->next_pkt = priv->rx_page_start+1; /* init our s/w variable */
 406             WRITE_REG(NIC_CURR, priv->next_pkt);    /* set the next buf for current */
 407             
 408             WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_START);
 409             
 410             WRITE_REG(NIC_TCR, 0);
 411             }
 412 
 413     dev->interrupt = 0;
 414     return;
 415     }
 416 
 417 
 418 /*
 419  * packet transmit routine
 420  */
 421 static int hydra_start_xmit(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 422     {
 423     struct hydra_private *priv = (struct hydra_private *)dev->priv;
 424     u_char volatile *nicbase = priv->hydra_nic_base;
 425     int len, len1;
 426 
 427         /* Transmitter timeout, serious problems. */
 428 
 429     if(dev->tbusy)
 430         {
 431         int tickssofar = jiffies - dev->trans_start;
 432         if(tickssofar < 20)
 433             return(1);
 434         WRITE_REG(NIC_CR, CR_STOP);
 435         printk("%s: transmit timed out, status %4.4x, resetting.\n", dev->name, 0);
 436         priv->stats.tx_errors++;
 437 
 438 
 439         dev->tbusy = 0;
 440         dev->trans_start = jiffies;
 441 
 442         return(0);
 443         }
 444 
 445 
 446     if(skb == NULL)
 447         {
 448         dev_tint(dev);
 449         return(0);
 450         }
 451 
 452     if((len = skb->len) <= 0)
 453         return(0);
 454 
 455     /* fill in a tx ring entry */
 456     
 457 #ifdef HYDRA_DEBUG
 458  printk("TX pkt type 0x%04x from ", ((u_short *)skb->data)[6]);
 459         {
 460                 int i;
 461                 u_char *ptr = &((u_char *)skb->data)[6];
 462                 for (i = 0; i < 6; i++)
 463                         printk("%02x", ptr[i]);
 464         }
 465         printk(" to ");
 466         {
 467                 int i;
 468                 u_char *ptr = (u_char *)skb->data;
 469                 for (i = 0; i < 6; i++)
 470                         printk("%02x", ptr[i]);
 471         }
 472         printk(" data 0x%08x len %d\n", (int)skb->data, len);
 473 #endif
 474 
 475     /*
 476      * make sure that the packet size is at least the minimum
 477      * allowed ethernet packet length.
 478      * (possibly should also clear the unused space...)
 479      * note: minimum packet length is 64, including CRC
 480      */
 481     len1 = len;
 482     if(len < (ETHER_MIN_LEN-4))
 483         len = (ETHER_MIN_LEN-1);
 484 
 485     /* make sure we've got an even number of bytes to copy to hydra's mem */
 486     if(len & 1) len++;
 487 
 488     if((u_long)(priv->hydra_base + (priv->tx_page_start << 8)) < 0x80000000)
 489       printk("weirdness: memcpyw(txbuf, skbdata, len): txbuf = %0x\n", (priv->hydra_base+(priv->tx_page_start<<8)));
 490 
 491     /* copy the packet data to the transmit buffer
 492        in the ethernet card RAM */
 493     memcpyw((u_short *)(priv->hydra_base + (priv->tx_page_start << 8)),
 494             (u_short *)skb->data, len);
 495     /* clear the unused space */
 496 /*    for(; len1<len; len1++)
 497       (u_short)*(priv->hydra_base + (priv->tx_page_start<<8) + len1) = 0;
 498 */
 499     dev_kfree_skb(skb, FREE_WRITE);
 500 
 501     priv->stats.tx_packets++;
 502 
 503     cli();
 504     /* make sure we are on the correct page */
 505     WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_START);
 506 
 507     /* here we configure the transmit page start register etc */
 508     /* notice that this code is hardwired to one transmit buffer */
 509     WRITE_REG(NIC_TPSR, priv->tx_page_start);
 510     WRITE_REG(NIC_TBCR0, len & 0xff);
 511     WRITE_REG(NIC_TBCR1, len >> 8);
 512 
 513     /* commit the packet to the wire */
 514     WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA | CR_TXP);
 515     sti();
 516 
 517     dev->trans_start = jiffies;
 518 
 519     return(0);
 520     }
 521 
 522 
 523 static void __inline__ hydra_rx(struct device *dev, struct hydra_private *priv, u_char *nicbase)
     /* [previous][next][first][last][top][bottom][index][help] */
 524     {
 525     u_short volatile *board_ram_ptr;
 526     struct sk_buff *skb;
 527     int hdr_next_pkt, pkt_len, len1, boundary;
 528 
 529 
 530     /* remove packet(s) from the ring and commit them to TCP layer */
 531     WRITE_REG(NIC_CR, CR_PAGE1 | CR_NODMA | CR_START); /* page 1 */
 532     while(priv->next_pkt != READ_REG(NIC_CURR)) /* should read this only once? */
 533       {
 534         board_ram_ptr = (u_short *)(priv->hydra_base + (priv->next_pkt << 8));
 535         
 536 #ifdef HYDRA_DEBUG
 537         printk("next_pkt = 0x%x, board_ram_ptr = 0x%x\n", priv->next_pkt, board_ram_ptr);
 538 #endif
 539         
 540         /* the following must be done with two steps, or
 541            GCC optimizes it to a byte access to Hydra memory,
 542            which doesn't work... */
 543         hdr_next_pkt = board_ram_ptr[0];
 544         hdr_next_pkt >>= 8;
 545         
 546         pkt_len = board_ram_ptr[1];
 547         pkt_len = ((pkt_len >> 8) | ((pkt_len & 0xff) << 8));
 548         
 549 #ifdef HYDRA_DEBUG
 550         printk("hydra_interrupt(): hdr_next_pkt = 0x%02x, len = %d\n", hdr_next_pkt, pkt_len);
 551 #endif
 552         
 553         if(pkt_len >= ETHER_MIN_LEN && pkt_len <= ETHER_MAX_LEN)
 554           {
 555             /* note that board_ram_ptr is u_short */
 556             /* CRC is not included in the packet length */
 557             
 558             pkt_len -= 4;
 559             skb = dev_alloc_skb(pkt_len+2);
 560             if(skb == NULL)
 561               {
 562                 printk("%s: memory squeeze, dropping packet.\n", dev->name);
 563                 priv->stats.rx_dropped++;
 564               }
 565             else
 566               {
 567                 skb->dev = dev;
 568                 skb_reserve(skb, 2);
 569                 
 570                 if(hdr_next_pkt < priv->next_pkt && hdr_next_pkt != priv->rx_page_start)
 571                   {
 572                     /* here, the packet is wrapped */
 573                     len1 = ((priv->rx_page_stop - priv->next_pkt)<<8)-4;
 574                     
 575                     memcpyw((u_short *)skb_put(skb, len1), (u_short *)(board_ram_ptr+2), len1);
 576                     memcpyw((u_short *)skb_put(skb, pkt_len-len1),  (u_short *)(priv->hydra_base+(priv->rx_page_start<<8)), pkt_len-len1);
 577                     
 578 #ifdef HYDRA_DEBUG
 579                     printk("wrapped packet: %d/%d bytes\n", len1, pkt_len-len1);
 580 #endif
 581                   }  /* ... here, packet is not wrapped */
 582                 else memcpyw((u_short *) skb_put(skb, pkt_len), (u_short *)(board_ram_ptr+2), pkt_len);
 583               }
 584             /* if(skb == NULL) ... */
 585           }
 586         else
 587           {
 588             WRITE_REG(NIC_CR, CR_PAGE1 | CR_START | CR_NODMA);
 589             printk("hydra_interrupt(): invalid packet len: %d, NIC_CURR = %02x\n", pkt_len, READ_REG(NIC_CURR));
 590 /*
 591 this is the error i kept getting until i switched to 0.9.10. it still doesn't
 592 mean that the bug would have gone away - so be alarmed. the packet is likely
 593 being fetched from a wrong memory location - but why - dunno
 594    
 595 note-for-v2.1: not really problem anymore. hasn't been for a long time.
 596 */
 597             
 598             WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA);
 599             /* should probably reset the NIC here ?? */
 600             
 601             hydra_open(dev);  /* FIXME - i shouldn't really be doing this. */
 602             return;
 603           }
 604         
 605         /* now, update the next_pkt pointer */
 606         if(hdr_next_pkt < priv->rx_page_stop) priv->next_pkt = hdr_next_pkt;
 607         else printk("hydra_interrupt(): invalid next_pkt pointer %d\n", hdr_next_pkt);
 608         
 609         /* update the boundary pointer */
 610         boundary = priv->next_pkt - 1;
 611         if(boundary < priv->rx_page_start)
 612           boundary = priv->rx_page_stop - 1;
 613         
 614         /* set NIC to page 0 to update the NIC_BNDRY register */
 615         WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA);
 616         WRITE_REG(NIC_BNDRY, boundary);
 617         
 618         /* select page1 to access the NIC_CURR register */
 619         WRITE_REG(NIC_CR, CR_PAGE1 | CR_START | CR_NODMA);
 620         
 621         
 622         skb->protocol = eth_type_trans(skb, dev);
 623         netif_rx(skb);
 624         priv->stats.rx_packets++;
 625         
 626       }
 627     return;
 628     }
 629     
 630 
 631 static struct enet_statistics *hydra_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 632 {
 633         struct hydra_private *priv = (struct hydra_private *)dev->priv;
 634 #if 0
 635         u_char *board = priv->hydra_base; 
 636 
 637         short saved_addr;
 638 #endif
 639 /* currently does nothing :) i'll finish this later */
 640 
 641         return(&priv->stats);
 642 }
 643 
 644 #ifdef HAVE_MULTICAST
 645 static void set_multicast_list(struct device *dev, int num_addrs, void *addrs)
     /* [previous][next][first][last][top][bottom][index][help] */
 646     {
 647     struct hydra_private *priv = (struct hydra_private *)dev->priv;
 648     u_char *board = priv->hydra_base;
 649 
 650     /* yes, this code is also waiting for someone to complete.. :) */
 651     /* (personally i don't care about multicasts at all :) */
 652     return;
 653     }
 654 #endif
 655 

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