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

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