root/net/inet/d_link.c

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

DEFINITIONS

This source file includes following definitions.
  1. d_link_read_status
  2. d_link_read_byte
  3. d_link_open
  4. d_link_close
  5. d_link_start_xmit
  6. d_link_interrupt
  7. d_link_tx_intr
  8. d_link_rx_intr
  9. d_link_init
  10. adapter_init

   1 /*
   2  *      d_link.c
   3  *
   4  *      Portions (C) Copyright 1993 by Bjorn Ekwall
   5  *      The Author may be reached as bj0rn@blox.se
   6  *
   7  *      Linux driver for the D-Link Ethernet pocket adapter.
   8  *      Based on sources from linux 0.99pl5
   9  *      and on a sample network driver core for linux.
  10  *
  11  *      Sample driver written 1993 by Donald Becker <becker@super.org>
  12  *      C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
  13  *
  14  *      compile-command:
  15  *      "gcc -DKERNEL -Wall -O6 -fomit-frame-pointer -c d_link.c"
  16  */
  17 /*************************************************************
  18  * If you have trouble reading/writing to the adapter,
  19  * uncomment the following "#define":
  20 #define REALLY_SLOW_IO
  21  */
  22 
  23 /* $Id: d_link.c,v 0.21 1993/06/02 19:41:00 waltje Exp $ */
  24 /* $Log: d_link.c,v $
  25  * Revision 0.21  1993/06/02  19:41:00 waltje
  26  * Applied multi-IRQ fix from Bjorn Ekwall and increaded version
  27  * number to 0.21.
  28  *
  29  * Revision 0.20  1993/03/26  11:43:53  root
  30  * Changed version number to indicate "alpha+" (almost beta :-)
  31  *
  32  * Revision 0.16  1993/03/26  11:26:46  root
  33  * Last ALPHA-minus version.
  34  * REALLY_SLOW_IO choice included (at line 20)
  35  * SLOW_DOWN_IO added anyway in convenience macros/functions
  36  * Test of D_LINK_FIFO included (not completely debugged)
  37  *
  38  * Revision 0.15  1993/03/24  14:00:49  root
  39  * Modified the interrupt handling considerably.
  40  * (The .asm source had me fooled in how it _really_ works :-)
  41  *
  42  * Revision 0.14  1993/03/21  01:57:25  root
  43  * Modified the interrupthandler for more robustness (hopefully :-)
  44  *
  45  * Revision 0.13  1993/03/19  11:45:09  root
  46  * Re-write of ALPHA release using Don Beckers skeleton (still works, kind of ...:-)
  47  *
  48  * Revision 0.12  1993/03/16  13:22:21  root
  49  * working ALPHA-release
  50  *
  51  */
  52 
  53 static char *version =
  54         "d_link.c: $Revision: 0.21 $,  Bjorn Ekwall (bj0rn@blox.se)\n";
  55 
  56 /*
  57  *      Based on adapter information gathered from DE600.ASM by D-Link Inc.,
  58  *      as included on disk C in the v.2.11 of PC/TCP from FTP Software.
  59  *
  60  *      For DE600.asm:
  61  *              Portions (C) Copyright 1990 D-Link, Inc.
  62  *              Copyright, 1988-1992, Russell Nelson, Crynwr Software
  63  *
  64  *      This program is free software; you can redistribute it and/or modify
  65  *      it under the terms of the GNU General Public License as published by
  66  *      the Free Software Foundation; either version 2, or (at your option)
  67  *      any later version.
  68  *
  69  *      This program is distributed in the hope that it will be useful,
  70  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  71  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  72  *      GNU General Public License for more details.
  73  *
  74  *      You should have received a copy of the GNU General Public License
  75  *      along with this program; if not, write to the Free Software
  76  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  77  *
  78  */
  79 
  80 #include <linux/config.h>
  81 #include <linux/kernel.h>
  82 #include <linux/sched.h>
  83 #include <linux/types.h>
  84 #include <linux/fcntl.h>
  85 #include <linux/string.h>
  86 #include <linux/interrupt.h>
  87 #include <asm/io.h>
  88 #include <netinet/in.h>
  89 #include <linux/ptrace.h>
  90 #include <asm/system.h>
  91 #include <errno.h>
  92 
  93 #include "inet.h"
  94 #include "dev.h"
  95 #include "eth.h"
  96 #include "ip.h"
  97 #include "route.h"
  98 #include "protocol.h"
  99 #include "tcp.h"
 100 #include "skbuff.h"
 101 #include "sock.h"
 102 #include "arp.h"
 103 
 104 
 105 /* use 0 for production, 1 for verification, >2 for debug */
 106 #ifndef D_LINK_DEBUG
 107 #define D_LINK_DEBUG 0
 108 #endif
 109 static unsigned int d_link_debug = D_LINK_DEBUG;
 110 
 111 #ifdef D_LINK_DEBUG
 112 #define PRINTK(x) if (d_link_debug >= 2) printk x
 113 #else
 114 #define PRINTK(x) /**/
 115 #endif
 116 
 117 /**************************************************
 118  *                                                *
 119  * Definition of D-Link Ethernet Pocket adapter   *
 120  *                                                *
 121  **************************************************/
 122 /*
 123  * D-Link Ethernet pocket adapter ports
 124  */
 125 #define DATA_PORT       (dev->base_addr + 0)
 126 #define STATUS_PORT     (dev->base_addr + 1)
 127 #define COMMAND_PORT    (dev->base_addr + 2)
 128 
 129 /*
 130  * D-Link COMMAND_PORT commands
 131  */
 132 #define SELECT_NIC      0x04 /* select Network Interface Card */
 133 #define SELECT_PRN      0x1c /* select Printer */
 134 #define NML_PRN         0xec /* normal Printer situation */
 135 #define IRQEN           0x10 /* enable IRQ line */
 136 
 137 /*
 138  * D-Link STATUS_PORT
 139  */
 140 #define TX_INTR         0x88
 141 #define RX_INTR         0x40
 142 
 143 #define OTHER_INTR      0x00 /* dummy, always false */
 144 
 145 /*
 146  * D-Link DATA_PORT commands
 147  * command in low 4 bits
 148  * data in high 4 bits
 149  * select current data nibble with HI_NIBBLE bit
 150  */
 151 #define WRITE_DATA      0x00 /* write memory */
 152 #define READ_DATA       0x01 /* read memory */
 153 #define STATUS          0x02 /* read  status register */
 154 #define COMMAND         0x03 /* write command register (see COMMAND below) */
 155 #define NULL_COMMAND    0x04 /* null command */
 156 #define RX_LEN          0x05 /* read  received packet length */
 157 #define TX_ADDR         0x06 /* set adapter transmit memory address */
 158 #define RW_ADDR         0x07 /* set adapter read/write memory address */
 159 #define HI_NIBBLE       0x08 /* read/write the high nibble of data,
 160                                 or-ed with rest of command */
 161 
 162 /*
 163  * command register, (I don't know all about these bits...)
 164  * accessed through DATA_PORT with low bits = COMMAND
 165  */
 166 #define RX_ALL          0x01 /* bit 0,1 = 01 */
 167 #define RX_BP           0x02 /* bit 0,1 = 10 */
 168 #define RX_MBP          0x03 /* bit 0,1 = 11 */
 169 
 170 #define TX_ENABLE       0x04 /* bit 2 */
 171 #define RX_ENABLE       0x08 /* bit 3 */
 172 
 173 #define RESET           0x80 /* set bit 7 high */
 174 #define STOP_RESET      0x00 /* set bit 7 low */
 175 
 176 /*
 177  * data to command register
 178  * (high 4 bits in write to DATA_PORT)
 179  */
 180 #define RX_PAGE2_SELECT 0x10 /* bit 4, only 2 pages to select */
 181 #define RX_BASE_PAGE    0x20 /* bit 5, always set when specifying RX_ADDR */
 182 #define FLIP_IRQ        0x40 /* bit 6 */
 183 
 184 /* Convenience definition, transmitter page 2 */
 185 #define TX_PAGE2_SELECT 0x02
 186 
 187 /*
 188  * D-Link adapter internal memory:
 189  *
 190  * 0-2K 1:st transmit page (send from pointer up to 2K)
 191  * 2-4K 2:nd transmit page (send from pointer up to 4K)
 192  *
 193  * 4-6K 1:st receive page (data from 4K upwards)
 194  * 6-8K 2:nd receive page (data from 6K upwards)
 195  *
 196  * 8K+  Adapter ROM (contains magic code and last 3 bytes of Ethernet address)
 197  */
 198 #define MEM_2K          0x0800 /* 2048 */
 199 #define MEM_4K          0x1000 /* 4096 */
 200 #define NODE_ADDRESS    0x2000 /* 8192 */
 201 
 202 #define RUNT 64 /*56*/ /* Too small Ethernet packet */
 203 
 204 /**************************************************
 205  *                                                *
 206  *             End of definition                  *
 207  *                                                *
 208  **************************************************/
 209 
 210 /* Common network statistics -- these will be in *.h someday. */
 211 struct netstats {
 212         int     tx_packets;
 213         int     rx_packets;
 214         int     tx_errors;
 215         int     rx_errors;
 216         int     missed_packets;
 217         int     soft_tx_errors;
 218         int     soft_rx_errors;
 219         int     soft_trx_err_bits;
 220 };
 221 static struct netstats  *localstats;
 222 
 223 /*
 224  * Index to functions, as function prototypes.
 225  */
 226 
 227 /* Routines used internally. (See "convenience macros" also) */
 228 static int              d_link_read_status(struct device *dev);
 229 static unsigned char    d_link_read_byte(int type, struct device *dev);
 230 
 231 /* Put in the device structure. */
 232 static int      d_link_open(struct device *dev);
 233 static int      d_link_close(struct device *dev);
 234 static int      d_link_start_xmit(struct sk_buff *skb, struct device *dev);
 235 
 236 /* Dispatch from interrupts. */
 237 static void     d_link_interrupt(int reg_ptr);
 238 static void     d_link_tx_intr(struct device *dev);
 239 static void     d_link_rx_intr(struct device *dev);
 240 
 241 /* Initialization */
 242 int             d_link_init(struct device *dev);
 243 static void     adapter_init(struct device *dev, int startp);
 244 
 245 /* Passed to sigaction() to register the interrupt handler. */
 246 static struct sigaction d_link_sigaction = {
 247         &d_link_interrupt,
 248         0,
 249         0,
 250         NULL,
 251         };
 252 
 253 /*
 254  * D-Link driver variables:
 255  */
 256 static volatile int             rx_page         = 0;
 257 static struct device            *realdev;
 258 #ifdef D_LINK_FIFO
 259 static volatile int             free_tx_page = 0x03;    /* 2 pages = 0000 0011 */
 260 static volatile unsigned int    busy_tx_page = 0x00;    /* 2 pages = 0000 0000 */
 261 static volatile int             transmit_next_from;
 262 #endif
 263 
 264 /*
 265  * Convenience macros/functions for D-Link adapter
 266  *
 267  * If you are having trouble reading/writing correctly,
 268  * try to uncomment the line "#define REALLY_SLOW_IO" (near line 20)
 269  */
 270 
 271 #define select_prn() \
 272         outb_p(SELECT_PRN, COMMAND_PORT)
 273 
 274 #define select_nic() \
 275         outb_p(SELECT_NIC, COMMAND_PORT)
 276 
 277 #define d_link_put_byte(data) \
 278         outb_p(((data) << 4)   | WRITE_DATA            , DATA_PORT); \
 279         outb_p(((data) & 0xf0) | WRITE_DATA | HI_NIBBLE, DATA_PORT)
 280 
 281 /*
 282  * The first two outb_p()'s below could perhaps be deleted if there
 283  * would be more delay in the last two. Not certain about it yet...
 284  */
 285 #define d_link_put_command(cmd) \
 286         outb_p(( rx_page        << 4)   | COMMAND            , DATA_PORT); \
 287         outb_p(( rx_page        & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT); \
 288         outb_p(((rx_page | cmd) << 4)   | COMMAND            , DATA_PORT); \
 289         outb_p(((rx_page | cmd) & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT)
 290 
 291 #define d_link_setup_address(addr,type) \
 292         outb_p((((addr) << 4) & 0xf0) | type            , DATA_PORT); \
 293         outb_p(( (addr)       & 0xf0) | type | HI_NIBBLE, DATA_PORT); \
 294         outb_p((((addr) >> 4) & 0xf0) | type            , DATA_PORT); \
 295         outb_p((((addr) >> 8) & 0xf0) | type | HI_NIBBLE, DATA_PORT)
 296 
 297 static int
 298 d_link_read_status(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 299 {
 300         int     status;
 301 
 302         select_nic();
 303         outb_p(STATUS, DATA_PORT);
 304         SLOW_DOWN_IO; /* See comment line 20 */
 305         status = inb_p(STATUS_PORT);
 306         outb_p(NULL_COMMAND, DATA_PORT);
 307         outb_p(NULL_COMMAND | HI_NIBBLE, DATA_PORT);
 308 
 309         return status;
 310 }
 311 
 312 static unsigned char
 313 d_link_read_byte(int type, struct device *dev) { /* dev used by macros */
     /* [previous][next][first][last][top][bottom][index][help] */
 314         unsigned char   lo;
 315 
 316         outb_p((type), DATA_PORT);
 317         SLOW_DOWN_IO; /* See comment line 20 */
 318         lo = inb_p(STATUS_PORT);
 319         outb_p((type) | HI_NIBBLE, DATA_PORT);
 320         SLOW_DOWN_IO; /* See comment line 20 */
 321         return ((lo & 0xf0) >> 4) | (inb_p(STATUS_PORT) & 0xf0);
 322 }
 323 
 324 #ifdef D_LINK_FIFO
 325         /* Handle a "fifo" in an int (= busy_tx_page) */
 326 # define AT_FIFO_OUTPUT (busy_tx_page & 0x0f)
 327 # define ANY_QUEUED_IN_FIFO (busy_tx_page & 0xf0)
 328 
 329 # define PULL_FROM_FIFO { busy_tx_page >>= 4;}
 330 # define PUSH_INTO_FIFO(page) { \
 331         if (busy_tx_page)       /* there already is a transmit in progress */ \
 332                 busy_tx_page |= (page << 4); \
 333         else \
 334                 busy_tx_page = page; \
 335         }
 336 #endif
 337 
 338 /*
 339  * Open/initialize the board.  This is called (in the current kernel)
 340  * sometime after booting when the 'config <dev->name>' program is run.
 341  *
 342  * This routine should set everything up anew at each open, even
 343  * registers that "should" only need to be set once at boot, so that
 344  * there is a non-reboot way to recover if something goes wrong.
 345  */
 346 static int
 347 d_link_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 348 {
 349         adapter_init(dev, 1);
 350         dev->tbusy = 0;         /* Transmit busy...  */
 351         dev->interrupt = 0;
 352         dev->start = 1;
 353         return 0;
 354 }
 355 
 356 /*
 357  * The inverse routine to d_link_open().
 358  */
 359 static int
 360 d_link_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 361 {
 362         dev->start = 0;
 363 
 364         adapter_init(dev, 0);
 365 
 366         irqaction(dev->irq, NULL);
 367 
 368         return 0;
 369 }
 370 
 371 /*
 372  * Copy a buffer to the adapter transmit page memory.
 373  * Start sending.
 374  */
 375 static int
 376 d_link_start_xmit(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 377 {
 378         static int      tx_page = 0;
 379         int             transmit_from;
 380         int             len;
 381         int             tickssofar;
 382         unsigned char   *buffer = (unsigned char *)(skb + 1);
 383 
 384         /*
 385          * If some higher layer thinks we've missed a
 386          * tx-done interrupt * we are passed NULL.
 387          * Caution: dev_tint() handles the cli()/sti() itself.
 388          */
 389 
 390         if (skb == NULL) {
 391                 dev_tint(dev);
 392                 return 0;
 393         }
 394 
 395         /* For ethernet, fill in the header (hardware addresses) with an arp. */
 396         if (!skb->arp  &&  dev->rebuild_header(skb + 1, dev)) {
 397                 skb->dev = dev;
 398                 arp_queue (skb);
 399                 return 0;
 400         }
 401 
 402 #ifdef D_LINK_FIFO
 403         if (free_tx_page == 0) {        /* Do timeouts, to avoid hangs. */
 404 #else
 405         if (dev->tbusy) {       /* Do timeouts, to avoid hangs. */
 406 #endif
 407                 tickssofar = jiffies - dev->trans_start;
 408 
 409                 if (tickssofar < 5) {
 410                         return 1;
 411                 }
 412 
 413                 /* else */
 414                 printk("%s: transmit timed out (%d), %s?\n",
 415                         dev->name,
 416                         tickssofar,
 417                         "network cable problem"
 418                         );
 419                 /* Try to restart the adapter. */
 420                 /* Maybe in next release... :-)
 421                 adapter_init(dev, 1);
 422                 */
 423         }
 424 
 425         /* Start real output */
 426         PRINTK(("d_link_start_xmit:len=%d\n", skb->len));
 427         cli();
 428         select_nic();
 429 
 430 #ifdef D_LINK_FIFO
 431         /* magic code selects the least significant bit in free_tx_page */
 432         tx_page = free_tx_page & (-free_tx_page);
 433 
 434         free_tx_page &= ~tx_page;
 435         dev->tbusy = !free_tx_page; /* any more free pages? */
 436 
 437         PUSH_INTO_FIFO(tx_page);
 438 #else
 439         tx_page ^= TX_PAGE2_SELECT;     /* Flip page, only 2 pages */
 440 #endif
 441 
 442         if ((len = skb->len) < RUNT) /*&& Hmm...? */
 443                 len = RUNT;
 444 
 445         if (tx_page & TX_PAGE2_SELECT)
 446                 transmit_from = MEM_4K - len;
 447         else
 448                 transmit_from = MEM_2K - len;
 449 
 450         d_link_setup_address(transmit_from, RW_ADDR);
 451 
 452         for ( ; len > 0; --len, ++buffer) {
 453                 d_link_put_byte(*buffer); /* macro! watch out for side effects! */
 454         }
 455 
 456 #ifdef D_LINK_FIFO
 457         if (ANY_QUEUED_IN_FIFO == 0)    { /* there is no transmit in progress */
 458                 d_link_setup_address(transmit_from, TX_ADDR);
 459                 d_link_put_command(TX_ENABLE);
 460                 dev->trans_start = jiffies;
 461         } else {
 462                 transmit_next_from = transmit_from;
 463         }
 464 #else
 465         d_link_setup_address(transmit_from, TX_ADDR);
 466         d_link_put_command(TX_ENABLE);
 467         dev->trans_start = jiffies;
 468 #endif
 469 
 470         sti(); /* interrupts back on */
 471         
 472         if (skb->free) {
 473                 kfree_skb (skb, FREE_WRITE);
 474         }
 475 
 476         return 0;
 477 }
 478 
 479 /*
 480  * The typical workload of the driver:
 481  * Handle the network interface interrupts.
 482  */
 483 static void
 484 d_link_interrupt(int reg_ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
 485 {
 486         int             irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
 487         struct device   *dev = realdev;
 488         int             interrupts;
 489 
 490         /* Get corresponding device */
 491 /*
 492         for (dev = dev_base; dev != NULL; dev = dev->next) {
 493                 if (dev->irq == irq)
 494                         break;
 495         }
 496 */
 497         if (dev == NULL) {
 498                 printk ("d_link_interrupt(): irq %d for unknown device.\n", irq);
 499                 return;
 500         }
 501 
 502         if (dev->start == 0) {
 503                 return; /*&& bogus interrupt at boot!?!?!? */
 504         }
 505 
 506         cli();
 507         dev->interrupt = 1;
 508         sti();  /* Allow other interrupts. */
 509 
 510         localstats = (struct netstats*) dev->priv;
 511 
 512         interrupts = d_link_read_status(dev);
 513 
 514         PRINTK(("d_link_interrupt (%2.2X)\n", interrupts));
 515 
 516         /*
 517          * Interrupts have been observed to be:
 518          *
 519          * Value        My interpretation
 520          * -----        -----------------
 521          * 0x47         Normal receive interrupt
 522          * 0x4F         Receive AND transmit interrupt simultaneously
 523          * 0x87         Normal transmit interrupt (? I treat it as such...)
 524          * 0x8F         Normal transmit interrupt
 525          */
 526 
 527         /*
 528          * Take care of TX interrupts first, in case there is an extra
 529          * page to transmit (keep the adapter busy while we work).
 530          */
 531         if (interrupts & TX_INTR) { /* 1xxx 1xxx */
 532                 d_link_tx_intr(dev);
 533         }
 534 
 535         if (interrupts & RX_INTR) { /* x1xx xxxx */
 536                 d_link_rx_intr(dev);
 537         }
 538 
 539         /* I'm not sure if there are any other interrupts from D-Link... */
 540         if (d_link_debug && (interrupts & OTHER_INTR)) {
 541                 printk("%s: unknown interrupt %#2x\n", dev->name, interrupts);
 542         }
 543 
 544         /* Check comment near line 20! */
 545         if (    (interrupts != 0x47) &&
 546                 (interrupts != 0x87) &&
 547                 (interrupts != 0x4F) &&
 548                 (interrupts != 0x8F)
 549                 )
 550                 printk("Strange d_link_interrupt: <%2.2X>\n", interrupts);
 551 
 552         cli();
 553         dev->interrupt = 0;
 554 
 555         /* Enable adapter interrupts */
 556         select_prn();
 557         return;
 558 }
 559 
 560 /*
 561  * Do internal handshake: Transmitter done (of this page).
 562  * Also handle the case of a pending transmit page.
 563  */
 564 static void
 565 d_link_tx_intr(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 566 {
 567         localstats->tx_packets++;
 568 
 569         cli();
 570         dev->tbusy = 0;
 571 
 572 #ifdef D_LINK_FIFO
 573         free_tx_page |= AT_FIFO_OUTPUT;
 574         PULL_FROM_FIFO;
 575 
 576         if (AT_FIFO_OUTPUT != 0) { /* more in queue! */
 577                 d_link_setup_address(transmit_next_from, TX_ADDR);
 578                 d_link_put_command(TX_ENABLE);
 579                 dev->trans_start = jiffies;
 580         }
 581 #endif
 582 
 583         mark_bh(INET_BH);
 584         sti();
 585 }
 586 
 587 /*
 588  * We have a good packet(s), get it/them out of the buffers.
 589  */
 590 static void
 591 d_link_rx_intr(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 592 {
 593         struct sk_buff  *skb;
 594         int             i;
 595         int             size;
 596         int             sksize;
 597         unsigned char   *buffer;
 598 
 599         /* Get size of received packet */
 600         /* Ignore trailing 4 CRC-bytes */
 601         size = d_link_read_byte(RX_LEN, dev); /* low byte */
 602         size = size + (d_link_read_byte(RX_LEN, dev) << 8) - 4;
 603 
 604         /* Tell adapter where to store next incoming packet, enable receiver */
 605         rx_page ^= RX_PAGE2_SELECT;     /* Flip bit, only 2 pages */
 606         d_link_put_command(RX_ENABLE);
 607 
 608         if (size == 0)          /* Read all the frames? */
 609                 return;                 /* Done for now */
 610 
 611         if ((size < 32  ||  size > 1535) && d_link_debug)
 612                 printk("%s: Bogus packet size %d.\n", dev->name, size);
 613 
 614         sksize = sizeof(struct sk_buff) + size;
 615         if ((skb = (struct sk_buff *) kmalloc(sksize, GFP_ATOMIC)) == NULL) {
 616                 if (d_link_debug) {
 617                                 printk("%s: Couldn't allocate a sk_buff of size %d.\n",
 618                                         dev->name, sksize);
 619                 }
 620                 return;
 621         }
 622         /* else */
 623 
 624         skb->lock = 0;
 625         skb->mem_len = sksize;
 626         skb->mem_addr = skb;
 627         /* 'skb + 1' points to the start of sk_buff data area. */
 628         buffer = (unsigned char *)(skb + 1);
 629 
 630         /* Get packet */
 631 
 632         /* Tell adapter from where we want to read this packet */
 633         if (rx_page & RX_PAGE2_SELECT) {
 634                 d_link_setup_address(MEM_4K, RW_ADDR);
 635         } else {
 636                 d_link_setup_address(MEM_4K + MEM_2K, RW_ADDR);
 637         }
 638 
 639         /* copy the packet into the buffer */
 640         for (i = size; i > 0; --i) {
 641                 *buffer++ = d_link_read_byte(READ_DATA, dev);
 642         }
 643         
 644         localstats->rx_packets++; /* count all receives */
 645 
 646         if(dev_rint((unsigned char *)skb, size, IN_SKBUFF, dev)) {
 647                 printk("%s: receive buffers full.\n", dev->name);
 648                 return;
 649         }
 650 
 651         /*
 652          * If any worth-while packets have been received, dev_rint()
 653          * has done a mark_bh(INET_BH) for us and will work on them
 654          * when we get to the bottom-half routine.
 655          */
 656         return;
 657 }
 658 
 659 int
 660 d_link_init(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 661 {
 662         int     i;
 663 
 664         printk("%s: D-Link pocket adapter", dev->name);
 665         /* Alpha testers must have the version number to report bugs. */
 666         if (d_link_debug > 1)
 667                 printk(version);
 668 
 669         /* probe for adapter */
 670         rx_page = 0;
 671         (void)d_link_read_status(dev);
 672         d_link_put_command(RESET);
 673         d_link_put_command(STOP_RESET);
 674         if (d_link_read_status(dev) & 0xf0) {
 675                 printk(": probe failed at %#3x.\n", dev->base_addr);
 676                 return ENODEV;
 677         }
 678 
 679         /*
 680          * Maybe we found one,
 681          * have to check if it is a D-Link adapter...
 682          */
 683 
 684         /* Get the adapter ethernet address from the ROM */
 685         d_link_setup_address(NODE_ADDRESS, RW_ADDR);
 686         for (i = 0; i < ETH_ALEN; i++) {
 687                 dev->dev_addr[i] = d_link_read_byte(READ_DATA, dev);
 688                 dev->broadcast[i] = 0xff;
 689         }
 690 
 691         /* Check magic code */
 692         if ((dev->dev_addr[1] == 0xde) && (dev->dev_addr[2] == 0x15)) {
 693                 /* OK, install real address */
 694                 dev->dev_addr[0] = 0x00;
 695                 dev->dev_addr[1] = 0x80;
 696                 dev->dev_addr[2] = 0xc8;
 697                 dev->dev_addr[3] &= 0x0f;
 698                 dev->dev_addr[3] |= 0x70;
 699         } else {
 700                 printk(", not found in printer port!\n");
 701                 return ENODEV;
 702         }
 703 
 704         /* Initialize the device structure. */
 705         dev->priv = kmalloc(sizeof(struct netstats), GFP_KERNEL);
 706         memset(dev->priv, 0, sizeof(struct netstats));
 707 
 708         for (i = 0; i < DEV_NUMBUFFS; i++)
 709                 dev->buffs[i] = NULL;
 710 
 711         dev->hard_header = eth_header;
 712         dev->add_arp = eth_add_arp;
 713         dev->queue_xmit = dev_queue_xmit;
 714         dev->rebuild_header = eth_rebuild_header;
 715         dev->type_trans = eth_type_trans;
 716 
 717         dev->open = &d_link_open;
 718         dev->stop = &d_link_close;
 719         dev->hard_start_xmit = &d_link_start_xmit;
 720 
 721         /* These are ethernet specific. */
 722         dev->type = ARPHRD_ETHER;
 723         dev->hard_header_len = ETH_HLEN;
 724         dev->mtu = 1500; /* eth_mtu */
 725         dev->addr_len   = ETH_ALEN;
 726 
 727         /* New-style flags. */
 728         dev->flags = IFF_BROADCAST;
 729         dev->family = AF_INET;
 730         dev->pa_addr = 0;
 731         dev->pa_brdaddr = 0;
 732         dev->pa_mask = 0;
 733         dev->pa_alen = sizeof(unsigned long);
 734 
 735         if (irqaction (dev->irq, &d_link_sigaction)) {
 736                 printk (": unable to get IRQ %d\n", dev->irq);
 737                 return 0;
 738         }
 739 
 740         printk(", Ethernet Address: %2.2X", dev->dev_addr[0]);
 741         for (i = 1; i < ETH_ALEN; i++)
 742                 printk(":%2.2X",dev->dev_addr[i]);
 743         printk("\n");
 744 
 745         return 0;
 746 }
 747 
 748 static void
 749 adapter_init(struct device *dev, int startp)
     /* [previous][next][first][last][top][bottom][index][help] */
 750 {
 751         int     i;
 752 
 753         cli(); /* no interrupts yet, please */
 754 
 755         select_nic();
 756         rx_page = 0;
 757         d_link_put_command(RESET);
 758         d_link_put_command(STOP_RESET);
 759 
 760         if (startp) {
 761                 irqaction (dev->irq, &d_link_sigaction);
 762                 realdev = dev;
 763 #ifdef D_LINK_FIFO
 764                 free_tx_page = 0x03;    /* 2 pages = 0000 0011 */
 765                 busy_tx_page = 0x00;    /* 2 pages = 0000 0000 */
 766 #endif
 767                 /* set the ether address. */
 768                 d_link_setup_address(NODE_ADDRESS, RW_ADDR);
 769                 for (i = 0; i < ETH_ALEN; i++) {
 770                         d_link_put_byte(dev->dev_addr[i]);
 771                 }
 772 
 773                 /* where to start saving incoming packets */
 774                 rx_page = 0 | RX_BP | RX_BASE_PAGE;
 775                 d_link_setup_address(MEM_4K, RW_ADDR);
 776                 /* Enable receiver */
 777                 d_link_put_command(RX_ENABLE);
 778         }
 779         else
 780                 d_link_put_command(0);
 781 
 782         select_prn();
 783 
 784         sti();
 785 }

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