root/drivers/net/de600.c

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

DEFINITIONS

This source file includes following definitions.
  1. de600_read_status
  2. de600_read_byte
  3. de600_open
  4. de600_close
  5. get_stats
  6. trigger_interrupt
  7. de600_start_xmit
  8. de600_interrupt
  9. de600_tx_intr
  10. de600_rx_intr
  11. de600_probe
  12. adapter_init
  13. de600_rspace
  14. init_module
  15. cleanup_module

   1 static const char *version =
   2         "de600.c: $Revision: 1.40 $,  Bjorn Ekwall (bj0rn@blox.se)\n";
   3 /*
   4  *      de600.c
   5  *
   6  *      Linux driver for the D-Link DE-600 Ethernet pocket adapter.
   7  *
   8  *      Portions (C) Copyright 1993, 1994 by Bjorn Ekwall
   9  *      The Author may be reached as bj0rn@blox.se
  10  *
  11  *      Based on adapter information gathered from DE600.ASM by D-Link Inc.,
  12  *      as included on disk C in the v.2.11 of PC/TCP from FTP Software.
  13  *      For DE600.asm:
  14  *              Portions (C) Copyright 1990 D-Link, Inc.
  15  *              Copyright, 1988-1992, Russell Nelson, Crynwr Software
  16  *
  17  *      Adapted to the sample network driver core for linux,
  18  *      written by: Donald Becker <becker@super.org>
  19  *      C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
  20  *
  21  *      compile-command:
  22  *      "gcc -D__KERNEL__  -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer \
  23  *       -m486 -c de600.c
  24  *
  25  **************************************************************/
  26 /*
  27  *      This program is free software; you can redistribute it and/or modify
  28  *      it under the terms of the GNU General Public License as published by
  29  *      the Free Software Foundation; either version 2, or (at your option)
  30  *      any later version.
  31  *
  32  *      This program is distributed in the hope that it will be useful,
  33  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  34  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  35  *      GNU General Public License for more details.
  36  *
  37  *      You should have received a copy of the GNU General Public License
  38  *      along with this program; if not, write to the Free Software
  39  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  40  *
  41  **************************************************************/
  42 /* Add another "; SLOW_DOWN_IO" here if your adapter won't work OK: */
  43 #define DE600_SLOW_DOWN SLOW_DOWN_IO; SLOW_DOWN_IO; SLOW_DOWN_IO
  44 
  45  /*
  46  * If you still have trouble reading/writing to the adapter,
  47  * modify the following "#define": (see <asm/io.h> for more info)
  48 #define REALLY_SLOW_IO
  49  */
  50 #define SLOW_IO_BY_JUMPING /* Looks "better" than dummy write to port 0x80 :-) */
  51 
  52 /*
  53  * If you want to enable automatic continuous checking for the DE600,
  54  * keep this #define enabled.
  55  * It doesn't cost much per packet, so I think it is worth it!
  56  * If you disagree, comment away the #define, and live with it...
  57  *
  58  */
  59 #define CHECK_LOST_DE600
  60 
  61 /*
  62  * Enable this #define if you want the adapter to do a "ifconfig down" on
  63  * itself when we have detected that something is possibly wrong with it.
  64  * The default behaviour is to retry with "adapter_init()" until success.
  65  * This should be used for debugging purposes only.
  66  * (Depends on the CHECK_LOST_DE600 above)
  67  *
  68  */
  69 #define SHUTDOWN_WHEN_LOST
  70 
  71 /*
  72  * See comment at "de600_rspace()"!
  73  * This is an *ugly* hack, but for now it achieves its goal of
  74  * faking a TCP flow-control that will not flood the poor DE600.
  75  *
  76  * Tricks TCP to announce a small max window (max 2 fast packets please :-)
  77  *
  78  * Comment away at your own risk!
  79  *
  80  * Update: Use the more general per-device maxwindow parameter instead.
  81  */
  82 #undef FAKE_SMALL_MAX
  83 
  84 /* use 0 for production, 1 for verification, >2 for debug */
  85 #ifdef DE600_DEBUG
  86 #define PRINTK(x) if (de600_debug >= 2) printk x
  87 #else
  88 #define DE600_DEBUG 0
  89 #define PRINTK(x) /**/
  90 #endif
  91 unsigned int de600_debug = DE600_DEBUG;
  92 
  93 #ifdef MODULE
  94 #include <linux/module.h>
  95 #include <linux/version.h>
  96 #endif
  97 
  98 #include <linux/kernel.h>
  99 #include <linux/sched.h>
 100 #include <linux/types.h>
 101 #include <linux/fcntl.h>
 102 #include <linux/string.h>
 103 #include <linux/interrupt.h>
 104 #include <linux/ioport.h>
 105 #include <asm/io.h>
 106 #include <linux/in.h>
 107 #include <linux/ptrace.h>
 108 #include <asm/system.h>
 109 #include <linux/errno.h>
 110 
 111 #include <linux/inet.h>
 112 #include <linux/netdevice.h>
 113 #include <linux/etherdevice.h>
 114 #include <linux/skbuff.h>
 115 
 116 #ifdef FAKE_SMALL_MAX
 117 static unsigned long de600_rspace(struct sock *sk);
 118 #include <net/sock.h>
 119 #endif
 120 
 121 #define netstats enet_statistics
 122 typedef unsigned char byte;
 123 
 124 /**************************************************
 125  *                                                *
 126  * Definition of D-Link Ethernet Pocket adapter   *
 127  *                                                *
 128  **************************************************/
 129 /*
 130  * D-Link Ethernet pocket adapter ports
 131  */
 132 /*
 133  * OK, so I'm cheating, but there are an awful lot of
 134  * reads and writes in order to get anything in and out
 135  * of the DE-600 with 4 bits at a time in the parallel port,
 136  * so every saved instruction really helps :-)
 137  *
 138  * That is, I don't care what the device struct says
 139  * but hope that Space.c will keep the rest of the drivers happy.
 140  */
 141 #ifndef DE600_IO
 142 #define DE600_IO 0x378
 143 #endif
 144 
 145 #define DATA_PORT       (DE600_IO)
 146 #define STATUS_PORT     (DE600_IO + 1)
 147 #define COMMAND_PORT    (DE600_IO + 2)
 148 
 149 #ifndef DE600_IRQ
 150 #define DE600_IRQ       7
 151 #endif
 152 /*
 153  * It really should look like this, and autoprobing as well...
 154  *
 155 #define DATA_PORT       (dev->base_addr + 0)
 156 #define STATUS_PORT     (dev->base_addr + 1)
 157 #define COMMAND_PORT    (dev->base_addr + 2)
 158 #define DE600_IRQ       dev->irq
 159  */
 160 
 161 /*
 162  * D-Link COMMAND_PORT commands
 163  */
 164 #define SELECT_NIC      0x04 /* select Network Interface Card */
 165 #define SELECT_PRN      0x1c /* select Printer */
 166 #define NML_PRN         0xec /* normal Printer situation */
 167 #define IRQEN           0x10 /* enable IRQ line */
 168 
 169 /*
 170  * D-Link STATUS_PORT
 171  */
 172 #define RX_BUSY         0x80
 173 #define RX_GOOD         0x40
 174 #define TX_FAILED16     0x10
 175 #define TX_BUSY         0x08
 176 
 177 /*
 178  * D-Link DATA_PORT commands
 179  * command in low 4 bits
 180  * data in high 4 bits
 181  * select current data nibble with HI_NIBBLE bit
 182  */
 183 #define WRITE_DATA      0x00 /* write memory */
 184 #define READ_DATA       0x01 /* read memory */
 185 #define STATUS          0x02 /* read  status register */
 186 #define COMMAND         0x03 /* write command register (see COMMAND below) */
 187 #define NULL_COMMAND    0x04 /* null command */
 188 #define RX_LEN          0x05 /* read  received packet length */
 189 #define TX_ADDR         0x06 /* set adapter transmit memory address */
 190 #define RW_ADDR         0x07 /* set adapter read/write memory address */
 191 #define HI_NIBBLE       0x08 /* read/write the high nibble of data,
 192                                 or-ed with rest of command */
 193 
 194 /*
 195  * command register, accessed through DATA_PORT with low bits = COMMAND
 196  */
 197 #define RX_ALL          0x01 /* PROMISCUOUS */
 198 #define RX_BP           0x02 /* default: BROADCAST & PHYSICAL ADDRESS */
 199 #define RX_MBP          0x03 /* MULTICAST, BROADCAST & PHYSICAL ADDRESS */
 200 
 201 #define TX_ENABLE       0x04 /* bit 2 */
 202 #define RX_ENABLE       0x08 /* bit 3 */
 203 
 204 #define RESET           0x80 /* set bit 7 high */
 205 #define STOP_RESET      0x00 /* set bit 7 low */
 206 
 207 /*
 208  * data to command register
 209  * (high 4 bits in write to DATA_PORT)
 210  */
 211 #define RX_PAGE2_SELECT 0x10 /* bit 4, only 2 pages to select */
 212 #define RX_BASE_PAGE    0x20 /* bit 5, always set when specifying RX_ADDR */
 213 #define FLIP_IRQ        0x40 /* bit 6 */
 214 
 215 /*
 216  * D-Link adapter internal memory:
 217  *
 218  * 0-2K 1:st transmit page (send from pointer up to 2K)
 219  * 2-4K 2:nd transmit page (send from pointer up to 4K)
 220  *
 221  * 4-6K 1:st receive page (data from 4K upwards)
 222  * 6-8K 2:nd receive page (data from 6K upwards)
 223  *
 224  * 8K+  Adapter ROM (contains magic code and last 3 bytes of Ethernet address)
 225  */
 226 #define MEM_2K          0x0800 /* 2048 */
 227 #define MEM_4K          0x1000 /* 4096 */
 228 #define MEM_6K          0x1800 /* 6144 */
 229 #define NODE_ADDRESS    0x2000 /* 8192 */
 230 
 231 #define RUNT 60         /* Too small Ethernet packet */
 232 
 233 /**************************************************
 234  *                                                *
 235  *             End of definition                  *
 236  *                                                *
 237  **************************************************/
 238 
 239 /*
 240  * Index to functions, as function prototypes.
 241  */
 242 /* Routines used internally. (See "convenience macros") */
 243 static byte     de600_read_status(struct device *dev);
 244 static byte     de600_read_byte(unsigned char type, struct device *dev);
 245 
 246 /* Put in the device structure. */
 247 static int      de600_open(struct device *dev);
 248 static int      de600_close(struct device *dev);
 249 static struct netstats *get_stats(struct device *dev);
 250 static int      de600_start_xmit(struct sk_buff *skb, struct device *dev);
 251 
 252 /* Dispatch from interrupts. */
 253 static void     de600_interrupt(int irq, struct pt_regs *regs);
 254 static int      de600_tx_intr(struct device *dev, int irq_status);
 255 static void     de600_rx_intr(struct device *dev);
 256 
 257 /* Initialization */
 258 static void     trigger_interrupt(struct device *dev);
 259 int             de600_probe(struct device *dev);
 260 static int      adapter_init(struct device *dev);
 261 
 262 /*
 263  * D-Link driver variables:
 264  */
 265 static volatile int             rx_page         = 0;
 266 
 267 #define TX_PAGES 2
 268 static volatile int             tx_fifo[TX_PAGES];
 269 static volatile int             tx_fifo_in = 0;
 270 static volatile int             tx_fifo_out = 0;
 271 static volatile int             free_tx_pages = TX_PAGES;
 272 static int                      was_down = 0;
 273 
 274 /*
 275  * Convenience macros/functions for D-Link adapter
 276  */
 277 
 278 #define select_prn() outb_p(SELECT_PRN, COMMAND_PORT); DE600_SLOW_DOWN
 279 #define select_nic() outb_p(SELECT_NIC, COMMAND_PORT); DE600_SLOW_DOWN
 280 
 281 /* Thanks for hints from Mark Burton <markb@ordern.demon.co.uk> */
 282 #define de600_put_byte(data) ( \
 283         outb_p(((data) << 4)   | WRITE_DATA            , DATA_PORT), \
 284         outb_p(((data) & 0xf0) | WRITE_DATA | HI_NIBBLE, DATA_PORT))
 285 
 286 /*
 287  * The first two outb_p()'s below could perhaps be deleted if there
 288  * would be more delay in the last two. Not certain about it yet...
 289  */
 290 #define de600_put_command(cmd) ( \
 291         outb_p(( rx_page        << 4)   | COMMAND            , DATA_PORT), \
 292         outb_p(( rx_page        & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT), \
 293         outb_p(((rx_page | cmd) << 4)   | COMMAND            , DATA_PORT), \
 294         outb_p(((rx_page | cmd) & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT))
 295 
 296 #define de600_setup_address(addr,type) ( \
 297         outb_p((((addr) << 4) & 0xf0) | type            , DATA_PORT), \
 298         outb_p(( (addr)       & 0xf0) | type | HI_NIBBLE, DATA_PORT), \
 299         outb_p((((addr) >> 4) & 0xf0) | type            , DATA_PORT), \
 300         outb_p((((addr) >> 8) & 0xf0) | type | HI_NIBBLE, DATA_PORT))
 301 
 302 #define rx_page_adr() ((rx_page & RX_PAGE2_SELECT)?(MEM_6K):(MEM_4K))
 303 
 304 /* Flip bit, only 2 pages */
 305 #define next_rx_page() (rx_page ^= RX_PAGE2_SELECT)
 306 
 307 #define tx_page_adr(a) (((a) + 1) * MEM_2K)
 308 
 309 static inline byte
 310 de600_read_status(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 311 {
 312         byte status;
 313 
 314         outb_p(STATUS, DATA_PORT);
 315         status = inb(STATUS_PORT);
 316         outb_p(NULL_COMMAND | HI_NIBBLE, DATA_PORT);
 317 
 318         return status;
 319 }
 320 
 321 static inline byte
 322 de600_read_byte(unsigned char type, struct device *dev) { /* dev used by macros */
     /* [previous][next][first][last][top][bottom][index][help] */
 323         byte lo;
 324 
 325         (void)outb_p((type), DATA_PORT);
 326         lo = ((unsigned char)inb(STATUS_PORT)) >> 4;
 327         (void)outb_p((type) | HI_NIBBLE, DATA_PORT);
 328         return ((unsigned char)inb(STATUS_PORT) & (unsigned char)0xf0) | lo;
 329 }
 330 
 331 /*
 332  * Open/initialize the board.  This is called (in the current kernel)
 333  * after booting when 'ifconfig <dev->name> $IP_ADDR' is run (in rc.inet1).
 334  *
 335  * This routine should set everything up anew at each open, even
 336  * registers that "should" only need to be set once at boot, so that
 337  * there is a non-reboot way to recover if something goes wrong.
 338  */
 339 static int
 340 de600_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 341 {
 342         if (request_irq(DE600_IRQ, de600_interrupt, 0, "de600")) {
 343                 printk ("%s: unable to get IRQ %d\n", dev->name, DE600_IRQ);
 344                 return 1;
 345         }
 346         irq2dev_map[DE600_IRQ] = dev;
 347 
 348 #ifdef MODULE
 349         MOD_INC_USE_COUNT;
 350 #endif
 351         dev->start = 1;
 352         if (adapter_init(dev)) {
 353                 return 1;
 354         }
 355 
 356         return 0;
 357 }
 358 
 359 /*
 360  * The inverse routine to de600_open().
 361  */
 362 static int
 363 de600_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 364 {
 365         select_nic();
 366         rx_page = 0;
 367         de600_put_command(RESET);
 368         de600_put_command(STOP_RESET);
 369         de600_put_command(0);
 370         select_prn();
 371 
 372         if (dev->start) {
 373                 free_irq(DE600_IRQ);
 374                 irq2dev_map[DE600_IRQ] = NULL;
 375                 dev->start = 0;
 376 #ifdef MODULE
 377                 MOD_DEC_USE_COUNT;
 378 #endif
 379         }
 380         return 0;
 381 }
 382 
 383 static struct netstats *
 384 get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 385 {
 386     return (struct netstats *)(dev->priv);
 387 }
 388 
 389 static inline void
 390 trigger_interrupt(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 391 {
 392         de600_put_command(FLIP_IRQ);
 393         select_prn();
 394         DE600_SLOW_DOWN;
 395         select_nic();
 396         de600_put_command(0);
 397 }
 398 
 399 /*
 400  * Copy a buffer to the adapter transmit page memory.
 401  * Start sending.
 402  */
 403 static int
 404 de600_start_xmit(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 405 {
 406         int     transmit_from;
 407         int     len;
 408         int     tickssofar;
 409         byte    *buffer = skb->data;
 410 
 411         /*
 412          * If some higher layer thinks we've missed a
 413          * tx-done interrupt we are passed NULL.
 414          * Caution: dev_tint() handles the cli()/sti() itself.
 415          */
 416 
 417         if (skb == NULL) {
 418                 dev_tint(dev);
 419                 return 0;
 420         }
 421 
 422         if (free_tx_pages <= 0) {       /* Do timeouts, to avoid hangs. */
 423                 tickssofar = jiffies - dev->trans_start;
 424 
 425                 if (tickssofar < 5)
 426                         return 1;
 427 
 428                 /* else */
 429                 printk("%s: transmit timed out (%d), %s?\n",
 430                         dev->name,
 431                         tickssofar,
 432                         "network cable problem"
 433                         );
 434                 /* Restart the adapter. */
 435                 if (adapter_init(dev)) {
 436                         return 1;
 437                 }
 438         }
 439 
 440         /* Start real output */
 441         PRINTK(("de600_start_xmit:len=%d, page %d/%d\n", skb->len, tx_fifo_in, free_tx_pages));
 442 
 443         if ((len = skb->len) < RUNT)
 444                 len = RUNT;
 445 
 446         cli();
 447         select_nic();
 448         tx_fifo[tx_fifo_in] = transmit_from = tx_page_adr(tx_fifo_in) - len;
 449         tx_fifo_in = (tx_fifo_in + 1) % TX_PAGES; /* Next free tx page */
 450 
 451 #ifdef CHECK_LOST_DE600
 452         /* This costs about 40 instructions per packet... */
 453         de600_setup_address(NODE_ADDRESS, RW_ADDR);
 454         de600_read_byte(READ_DATA, dev);
 455         if (was_down || (de600_read_byte(READ_DATA, dev) != 0xde)) {
 456                 if (adapter_init(dev)) {
 457                         sti();
 458                         return 1;
 459                 }
 460         }
 461 #endif
 462 
 463         de600_setup_address(transmit_from, RW_ADDR);
 464         for ( ; len > 0; --len, ++buffer)
 465                 de600_put_byte(*buffer);
 466 
 467         if (free_tx_pages-- == TX_PAGES) { /* No transmission going on */
 468                 dev->trans_start = jiffies;
 469                 dev->tbusy = 0; /* allow more packets into adapter */
 470                 /* Send page and generate a faked interrupt */
 471                 de600_setup_address(transmit_from, TX_ADDR);
 472                 de600_put_command(TX_ENABLE);
 473         }
 474         else {
 475                 dev->tbusy = !free_tx_pages;
 476                 select_prn();
 477         }
 478         
 479         sti(); /* interrupts back on */
 480         
 481 #ifdef FAKE_SMALL_MAX
 482         /* This will "patch" the socket TCP proto at an early moment */
 483         if (skb->sk && (skb->sk->protocol == IPPROTO_TCP) &&
 484                 (skb->sk->prot->rspace != &de600_rspace))
 485                 skb->sk->prot->rspace = de600_rspace; /* Ugh! */
 486 #endif
 487 
 488         dev_kfree_skb (skb, FREE_WRITE);
 489 
 490         return 0;
 491 }
 492 
 493 /*
 494  * The typical workload of the driver:
 495  * Handle the network interface interrupts.
 496  */
 497 static void
 498 de600_interrupt(int irq, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 499 {
 500         struct device   *dev = irq2dev_map[irq];
 501         byte            irq_status;
 502         int             retrig = 0;
 503         int             boguscount = 0;
 504 
 505         /* This might just as well be deleted now, no crummy drivers present :-) */
 506         if ((dev == NULL) || (dev->start == 0) || (DE600_IRQ != irq)) {
 507                 printk("%s: bogus interrupt %d\n", dev?dev->name:"DE-600", irq);
 508                 return;
 509         }
 510 
 511         dev->interrupt = 1;
 512         select_nic();
 513         irq_status = de600_read_status(dev);
 514 
 515         do {
 516                 PRINTK(("de600_interrupt (%02X)\n", irq_status));
 517 
 518                 if (irq_status & RX_GOOD)
 519                         de600_rx_intr(dev);
 520                 else if (!(irq_status & RX_BUSY))
 521                         de600_put_command(RX_ENABLE);
 522 
 523                 /* Any transmission in progress? */
 524                 if (free_tx_pages < TX_PAGES)
 525                         retrig = de600_tx_intr(dev, irq_status);
 526                 else
 527                         retrig = 0;
 528 
 529                 irq_status = de600_read_status(dev);
 530         } while ( (irq_status & RX_GOOD) || ((++boguscount < 100) && retrig) );
 531         /*
 532          * Yeah, it _looks_ like busy waiting, smells like busy waiting
 533          * and I know it's not PC, but please, it will only occur once
 534          * in a while and then only for a loop or so (< 1ms for sure!)
 535          */
 536 
 537         /* Enable adapter interrupts */
 538         dev->interrupt = 0;
 539         select_prn();
 540 
 541         if (retrig)
 542                 trigger_interrupt(dev);
 543 
 544         sti();
 545         return;
 546 }
 547 
 548 static int
 549 de600_tx_intr(struct device *dev, int irq_status)
     /* [previous][next][first][last][top][bottom][index][help] */
 550 {
 551         /*
 552          * Returns 1 if tx still not done
 553          */
 554 
 555         mark_bh(NET_BH);
 556         /* Check if current transmission is done yet */
 557         if (irq_status & TX_BUSY)
 558                 return 1; /* tx not done, try again */
 559 
 560         /* else */
 561         /* If last transmission OK then bump fifo index */
 562         if (!(irq_status & TX_FAILED16)) {
 563                 tx_fifo_out = (tx_fifo_out + 1) % TX_PAGES;
 564                 ++free_tx_pages;
 565                 ((struct netstats *)(dev->priv))->tx_packets++;
 566                 dev->tbusy = 0;
 567         }
 568 
 569         /* More to send, or resend last packet? */
 570         if ((free_tx_pages < TX_PAGES) || (irq_status & TX_FAILED16)) {
 571                 dev->trans_start = jiffies;
 572                 de600_setup_address(tx_fifo[tx_fifo_out], TX_ADDR);
 573                 de600_put_command(TX_ENABLE);
 574                 return 1;
 575         }
 576         /* else */
 577 
 578         return 0;
 579 }
 580 
 581 /*
 582  * We have a good packet, get it out of the adapter.
 583  */
 584 static void
 585 de600_rx_intr(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 586 {
 587         struct sk_buff  *skb;
 588         int             i;
 589         int             read_from;
 590         int             size;
 591         register unsigned char  *buffer;
 592 
 593         cli();
 594         /* Get size of received packet */
 595         size = de600_read_byte(RX_LEN, dev);    /* low byte */
 596         size += (de600_read_byte(RX_LEN, dev) << 8);    /* high byte */
 597         size -= 4;      /* Ignore trailing 4 CRC-bytes */
 598 
 599         /* Tell adapter where to store next incoming packet, enable receiver */
 600         read_from = rx_page_adr();
 601         next_rx_page();
 602         de600_put_command(RX_ENABLE);
 603         sti();
 604 
 605         if ((size < 32)  ||  (size > 1535)) {
 606                 printk("%s: Bogus packet size %d.\n", dev->name, size);
 607                 if (size > 10000)
 608                         adapter_init(dev);
 609                 return;
 610         }
 611 
 612         skb = dev_alloc_skb(size+2);
 613         sti();
 614         if (skb == NULL) {
 615                 printk("%s: Couldn't allocate a sk_buff of size %d.\n",
 616                         dev->name, size);
 617                 return;
 618         }
 619         /* else */
 620 
 621         skb->dev = dev;
 622         skb_reserve(skb,2);     /* Align */
 623         
 624         /* 'skb->data' points to the start of sk_buff data area. */
 625         buffer = skb_put(skb,size);
 626 
 627         /* copy the packet into the buffer */
 628         de600_setup_address(read_from, RW_ADDR);
 629         for (i = size; i > 0; --i, ++buffer)
 630                 *buffer = de600_read_byte(READ_DATA, dev);
 631         
 632         ((struct netstats *)(dev->priv))->rx_packets++; /* count all receives */
 633 
 634         skb->protocol=eth_type_trans(skb,dev);
 635         
 636         netif_rx(skb);
 637         /*
 638          * If any worth-while packets have been received, netif_rx()
 639          * has done a mark_bh(INET_BH) for us and will work on them
 640          * when we get to the bottom-half routine.
 641          */
 642 }
 643 
 644 int
 645 de600_probe(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 646 {
 647         int     i;
 648         static struct netstats de600_netstats;
 649         /*dev->priv = kmalloc(sizeof(struct netstats), GFP_KERNEL);*/
 650 
 651         printk("%s: D-Link DE-600 pocket adapter", dev->name);
 652         /* Alpha testers must have the version number to report bugs. */
 653         if (de600_debug > 1)
 654                 printk(version);
 655 
 656         /* probe for adapter */
 657         rx_page = 0;
 658         select_nic();
 659         (void)de600_read_status(dev);
 660         de600_put_command(RESET);
 661         de600_put_command(STOP_RESET);
 662         if (de600_read_status(dev) & 0xf0) {
 663                 printk(": not at I/O %#3x.\n", DATA_PORT);
 664                 return ENODEV;
 665         }
 666 
 667         /*
 668          * Maybe we found one,
 669          * have to check if it is a D-Link DE-600 adapter...
 670          */
 671 
 672         /* Get the adapter ethernet address from the ROM */
 673         de600_setup_address(NODE_ADDRESS, RW_ADDR);
 674         for (i = 0; i < ETH_ALEN; i++) {
 675                 dev->dev_addr[i] = de600_read_byte(READ_DATA, dev);
 676                 dev->broadcast[i] = 0xff;
 677         }
 678 
 679         /* Check magic code */
 680         if ((dev->dev_addr[1] == 0xde) && (dev->dev_addr[2] == 0x15)) {
 681                 /* OK, install real address */
 682                 dev->dev_addr[0] = 0x00;
 683                 dev->dev_addr[1] = 0x80;
 684                 dev->dev_addr[2] = 0xc8;
 685                 dev->dev_addr[3] &= 0x0f;
 686                 dev->dev_addr[3] |= 0x70;
 687         } else {
 688                 printk(" not identified in the printer port\n");
 689                 return ENODEV;
 690         }
 691 
 692 #if 0 /* Not yet */
 693         if (check_region(DE600_IO, 3)) {
 694                 printk(", port 0x%x busy\n", DE600_IO);
 695                 return EBUSY;
 696         }
 697 #endif
 698         request_region(DE600_IO, 3, "de600");
 699 
 700         printk(", Ethernet Address: %02X", dev->dev_addr[0]);
 701         for (i = 1; i < ETH_ALEN; i++)
 702                 printk(":%02X",dev->dev_addr[i]);
 703         printk("\n");
 704 
 705         /* Initialize the device structure. */
 706         /*dev->priv = kmalloc(sizeof(struct netstats), GFP_KERNEL);*/
 707         dev->priv = &de600_netstats;
 708 
 709         memset(dev->priv, 0, sizeof(struct netstats));
 710         dev->get_stats = get_stats;
 711 
 712         dev->open = de600_open;
 713         dev->stop = de600_close;
 714         dev->hard_start_xmit = &de600_start_xmit;
 715 
 716         ether_setup(dev);
 717         
 718         select_prn();
 719         return 0;
 720 }
 721 
 722 static int
 723 adapter_init(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 724 {
 725         int     i;
 726         long flags;
 727 
 728         save_flags(flags);
 729         cli();
 730 
 731         select_nic();
 732         rx_page = 0; /* used by RESET */
 733         de600_put_command(RESET);
 734         de600_put_command(STOP_RESET);
 735 #ifdef CHECK_LOST_DE600
 736         /* Check if it is still there... */
 737         /* Get the some bytes of the adapter ethernet address from the ROM */
 738         de600_setup_address(NODE_ADDRESS, RW_ADDR);
 739         de600_read_byte(READ_DATA, dev);
 740         if ((de600_read_byte(READ_DATA, dev) != 0xde) ||
 741             (de600_read_byte(READ_DATA, dev) != 0x15)) {
 742         /* was: if (de600_read_status(dev) & 0xf0) { */
 743                 printk("Something has happened to the DE-600!  Please check it"
 744 #ifdef SHUTDOWN_WHEN_LOST
 745                         " and do a new ifconfig"
 746 #endif /* SHUTDOWN_WHEN_LOST */
 747                         "!\n");
 748 #ifdef SHUTDOWN_WHEN_LOST
 749                 /* Goodbye, cruel world... */
 750                 dev->flags &= ~IFF_UP;
 751                 de600_close(dev);
 752 #endif /* SHUTDOWN_WHEN_LOST */
 753                 was_down = 1;
 754                 dev->tbusy = 1;         /* Transmit busy...  */
 755                 return 1; /* failed */
 756         }
 757 #endif /* CHECK_LOST_DE600 */
 758         if (was_down) {
 759                 printk("Thanks, I feel much better now!\n");
 760                 was_down = 0;
 761         }
 762 
 763         dev->tbusy = 0;         /* Transmit busy...  */
 764         dev->interrupt = 0;
 765         tx_fifo_in = 0;
 766         tx_fifo_out = 0;
 767         free_tx_pages = TX_PAGES;
 768 
 769         /* set the ether address. */
 770         de600_setup_address(NODE_ADDRESS, RW_ADDR);
 771         for (i = 0; i < ETH_ALEN; i++)
 772                 de600_put_byte(dev->dev_addr[i]);
 773 
 774         /* where to start saving incoming packets */
 775         rx_page = RX_BP | RX_BASE_PAGE;
 776         de600_setup_address(MEM_4K, RW_ADDR);
 777         /* Enable receiver */
 778         de600_put_command(RX_ENABLE);
 779         select_prn();
 780         restore_flags(flags);
 781 
 782         return 0; /* OK */
 783 }
 784 
 785 #ifdef FAKE_SMALL_MAX
 786 /*
 787  *      The new router code (coming soon 8-) ) will fix this properly.
 788  */
 789 #define DE600_MIN_WINDOW 1024
 790 #define DE600_MAX_WINDOW 2048
 791 #define DE600_TCP_WINDOW_DIFF 1024
 792 /*
 793  * Copied from "net/inet/sock.c"
 794  *
 795  * Sets a lower max receive window in order to achieve <= 2
 796  * packets arriving at the adapter in fast succession.
 797  * (No way that a DE-600 can keep up with a net saturated
 798  *  with packets homing in on it :-( )
 799  *
 800  * Since there are only 2 receive buffers in the DE-600
 801  * and it takes some time to copy from the adapter,
 802  * this is absolutely necessary for any TCP performance whatsoever!
 803  *
 804  * Note that the returned window info will never be smaller than
 805  * DE600_MIN_WINDOW, i.e. 1024
 806  * This differs from the standard function, that can return an
 807  * arbitrarily small window!
 808  */
 809 #define min(a,b)        ((a)<(b)?(a):(b))
 810 static unsigned long
 811 de600_rspace(struct sock *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 812 {
 813   int amt;
 814 
 815   if (sk != NULL) {
 816 /*
 817  * Hack! You might want to play with commenting away the following line,
 818  * if you know what you do!
 819         sk->max_unacked = DE600_MAX_WINDOW - DE600_TCP_WINDOW_DIFF;
 820  */
 821 
 822         if (sk->rmem_alloc >= sk->rcvbuf-2*DE600_MIN_WINDOW) return(0);
 823         amt = min((sk->rcvbuf-sk->rmem_alloc)/2/*-DE600_MIN_WINDOW*/, DE600_MAX_WINDOW);
 824         if (amt < 0) return(0);
 825         return(amt);
 826   }
 827   return(0);
 828 }
 829 #endif
 830 
 831 #ifdef MODULE
 832 char kernel_version[] = UTS_RELEASE;
 833 static char nullname[8];
 834 static struct device de600_dev = {
 835         nullname, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, de600_probe };
 836 
 837 int
 838 init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 839 {
 840         if (register_netdev(&de600_dev) != 0)
 841                 return -EIO;
 842         return 0;
 843 }
 844 
 845 void
 846 cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 847 {
 848         unregister_netdev(&de600_dev);
 849         release_region(DE600_IO, 3);
 850 }
 851 #endif /* MODULE */
 852 /*
 853  * Local variables:
 854  *  kernel-compile-command: "gcc -D__KERNEL__ -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c"
 855  *  module-compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c"
 856  *  compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c"
 857  * End:
 858  */

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