home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / drivers / net / de620.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-07  |  25.2 KB  |  1,005 lines

  1. /*
  2.  *    de620.c $Revision: 1.31 $ BETA
  3.  *
  4.  *
  5.  *    Linux driver for the D-Link DE-620 Ethernet pocket adapter.
  6.  *
  7.  *    Portions (C) Copyright 1993, 1994 by Bjorn Ekwall <bj0rn@blox.se>
  8.  *
  9.  *    Based on adapter information gathered from DOS packetdriver
  10.  *    sources from D-Link Inc:  (Special thanks to Henry Ngai of D-Link.)
  11.  *        Portions (C) Copyright D-Link SYSTEM Inc. 1991, 1992
  12.  *        Copyright, 1988, Russell Nelson, Crynwr Software
  13.  *
  14.  *    Adapted to the sample network driver core for linux,
  15.  *    written by: Donald Becker <becker@super.org>
  16.  *        (Now at <becker@cesdis.gsfc.nasa.gov>
  17.  *
  18.  *    Valuable assistance from:
  19.  *        J. Joshua Kopper <kopper@rtsg.mot.com>
  20.  *        Olav Kvittem <Olav.Kvittem@uninett.no>
  21.  *        Germano Caronni <caronni@nessie.cs.id.ethz.ch>
  22.  *        Jeremy Fitzhardinge <jeremy@suite.sw.oz.au>
  23.  *
  24.  *****************************************************************************/
  25. /*
  26.  *    This program is free software; you can redistribute it and/or modify
  27.  *    it under the terms of the GNU General Public License as published by
  28.  *    the Free Software Foundation; either version 2, or (at your option)
  29.  *    any later version.
  30.  *
  31.  *    This program is distributed in the hope that it will be useful,
  32.  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  33.  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  34.  *    GNU General Public License for more details.
  35.  *
  36.  *    You should have received a copy of the GNU General Public License
  37.  *    along with this program; if not, write to the Free Software
  38.  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  39.  *
  40.  *****************************************************************************/
  41. static char *version =
  42.     "de620.c: $Revision: 1.31 $,  Bjorn Ekwall <bj0rn@blox.se>\n";
  43.  
  44. /***********************************************************************
  45.  *
  46.  * "Tuning" section.
  47.  *
  48.  * Compile-time options: (see below for descriptions)
  49.  * -DDE620_IO=0x378    (lpt1)
  50.  * -DDE620_IRQ=7    (lpt1)
  51.  * -DDE602_DEBUG=...
  52.  * -DSHUTDOWN_WHEN_LOST
  53.  * -DCOUNT_LOOPS
  54.  * -DLOWSPEED
  55.  * -DREAD_DELAY
  56.  * -DWRITE_DELAY
  57.  */
  58.  
  59. /*
  60.  * If the adapter has problems with high speeds, enable this #define
  61.  * otherwise full printerport speed will be attempted.
  62.  *
  63.  * You can tune the READ_DELAY/WRITE_DELAY below if you enable LOWSPEED
  64.  *
  65. #define LOWSPEED
  66.  */
  67.  
  68. #ifndef READ_DELAY
  69. #define READ_DELAY 100    /* adapter internal read delay in 100ns units */
  70. #endif
  71.  
  72. #ifndef WRITE_DELAY
  73. #define WRITE_DELAY 100    /* adapter internal write delay in 100ns units */
  74. #endif
  75.  
  76. /*
  77.  * Enable this #define if you want the adapter to do a "ifconfig down" on
  78.  * itself when we have detected that something is possibly wrong with it.
  79.  * The default behaviour is to retry with "adapter_init()" until success.
  80.  * This should be used for debugging purposes only.
  81.  *
  82. #define SHUTDOWN_WHEN_LOST
  83.  */
  84.  
  85. /*
  86.  * Enable debugging by "-DDE620_DEBUG=3" when compiling,
  87.  * OR in "./CONFIG"
  88.  * OR by enabling the following #define
  89.  *
  90.  * use 0 for production, 1 for verification, >2 for debug
  91.  *
  92. #define DE620_DEBUG 3
  93.  */
  94.  
  95. #ifdef LOWSPEED
  96. /*
  97.  * Enable this #define if you want to see debugging output that show how long
  98.  * we have to wait before the DE-620 is ready for the next read/write/command.
  99.  *
  100. #define COUNT_LOOPS
  101.  */
  102. #endif
  103. static int bnc, utp;
  104. /*
  105.  * Force media with insmod:
  106.  *    insmod de620.o bnc=1
  107.  * or
  108.  *    insmod de620.o utp=1
  109.  */
  110.  
  111. #ifdef MODULE
  112. #include <linux/module.h>
  113. #include <linux/version.h>
  114. #endif
  115.  
  116. #include <linux/kernel.h>
  117. #include <linux/sched.h>
  118. #include <linux/types.h>
  119. #include <linux/fcntl.h>
  120. #include <linux/string.h>
  121. #include <linux/interrupt.h>
  122. #include <linux/ioport.h>
  123. #include <asm/io.h>
  124. #include <linux/in.h>
  125. #include <linux/ptrace.h>
  126. #include <asm/system.h>
  127. #include <linux/errno.h>
  128.  
  129. #include <linux/inet.h>
  130. #include <linux/netdevice.h>
  131. #include <linux/etherdevice.h>
  132. #include <linux/skbuff.h>
  133.  
  134. /* Constant definitions for the DE-620 registers, commands and bits */
  135. #include "de620.h"
  136.  
  137. #define netstats enet_statistics
  138. typedef unsigned char byte;
  139.  
  140. /*******************************************************
  141.  *                                                     *
  142.  * Definition of D-Link DE-620 Ethernet Pocket adapter *
  143.  * See also "de620.h"                                  *
  144.  *                                                     *
  145.  *******************************************************/
  146. #ifndef DE620_IO /* Compile-time configurable */
  147. #define DE620_IO 0x378
  148. #endif
  149.  
  150. #ifndef DE620_IRQ /* Compile-time configurable */
  151. #define DE620_IRQ    7
  152. #endif
  153.  
  154. #define DATA_PORT    (DE620_IO)
  155. #define STATUS_PORT    (DE620_IO + 1)
  156. #define COMMAND_PORT    (DE620_IO + 2)
  157.  
  158. #define RUNT 60        /* Too small Ethernet packet */
  159. #define GIANT 1514    /* largest legal size packet, no fcs */
  160.  
  161. #ifdef DE620_DEBUG /* Compile-time configurable */
  162. #define PRINTK(x) if (de620_debug >= 2) printk x
  163. #else
  164. #define DE620_DEBUG 0
  165. #define PRINTK(x) /**/
  166. #endif
  167.  
  168. /***********************************************
  169.  *                                             *
  170.  * Index to functions, as function prototypes. *
  171.  *                                             *
  172.  ***********************************************/
  173.  
  174. /*
  175.  * Routines used internally. (See also "convenience macros.. below")
  176.  */
  177.  
  178. /* Put in the device structure. */
  179. static int    de620_open(struct device *);
  180. static int    de620_close(struct device *);
  181. static struct netstats *get_stats(struct device *);
  182. static void    de620_set_multicast_list(struct device *, int, void *);
  183. static int    de620_start_xmit(struct sk_buff *, struct device *);
  184.  
  185. /* Dispatch from interrupts. */
  186. static void    de620_interrupt(int, struct pt_regs *);
  187. static int    de620_rx_intr(struct device *);
  188.  
  189. /* Initialization */
  190. static int    adapter_init(struct device *);
  191. int        de620_probe(struct device *);
  192. static int    read_eeprom(void);
  193.  
  194.  
  195. /*
  196.  * D-Link driver variables:
  197.  */
  198. #define SCR_DEF NIBBLEMODE |INTON | SLEEP | AUTOTX
  199. #define    TCR_DEF RXPB            /* not used: | TXSUCINT | T16INT */
  200. #define DE620_RX_START_PAGE 12        /* 12 pages (=3k) reserved for tx */
  201. #define DEF_NIC_CMD IRQEN | ICEN | DS1
  202.  
  203. unsigned int de620_debug = DE620_DEBUG;
  204.  
  205. static volatile byte    NIC_Cmd;
  206. static volatile byte    next_rx_page;
  207. static byte        first_rx_page;
  208. static byte        last_rx_page;
  209. static byte        EIPRegister;
  210.  
  211. static struct nic {
  212.     byte    NodeID[6];
  213.     byte    RAM_Size;
  214.     byte    Model;
  215.     byte    Media;
  216.     byte    SCR;
  217. } nic_data;
  218.  
  219. /**********************************************************
  220.  *                                                        *
  221.  * Convenience macros/functions for D-Link DE-620 adapter *
  222.  *                                                        *
  223.  **********************************************************/
  224. #define de620_tx_buffs() (inb(STATUS_PORT) & (TXBF0 | TXBF1))
  225. #define de620_flip_ds() NIC_Cmd ^= DS0 | DS1; outb(NIC_Cmd, COMMAND_PORT);
  226.  
  227. /* Check for ready-status, and return a nibble (high 4 bits) for data input */
  228. #ifdef COUNT_LOOPS
  229. static int tot_cnt;
  230. #endif
  231. static inline byte
  232. de620_ready(void)
  233. {
  234.     byte value;
  235.     register short int cnt = 0;
  236.  
  237.     while ((((value = inb(STATUS_PORT)) & READY) == 0) && (cnt <= 1000))
  238.         ++cnt;
  239.  
  240. #ifdef COUNT_LOOPS
  241.     tot_cnt += cnt;
  242. #endif
  243.     return value & 0xf0; /* nibble */
  244. }
  245.  
  246. static inline void
  247. de620_send_command(byte cmd)
  248. {
  249.     de620_ready();
  250.     if (cmd == W_DUMMY)
  251.         outb(NIC_Cmd, COMMAND_PORT);
  252.  
  253.     outb(cmd, DATA_PORT);
  254.  
  255.     outb(NIC_Cmd ^ CS0, COMMAND_PORT);
  256.     de620_ready();
  257.     outb(NIC_Cmd, COMMAND_PORT);
  258. }
  259.  
  260. static inline void
  261. de620_put_byte(byte value)
  262. {
  263.     /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */
  264.     de620_ready();
  265.     outb(value, DATA_PORT);
  266.     de620_flip_ds();
  267. }
  268.  
  269. static inline byte
  270. de620_read_byte(void)
  271. {
  272.     byte value;
  273.  
  274.     /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */
  275.     value = de620_ready(); /* High nibble */
  276.     de620_flip_ds();
  277.     value |= de620_ready() >> 4; /* Low nibble */
  278.     return value;
  279. }
  280.  
  281. static inline void
  282. de620_write_block(byte *buffer, int count)
  283. {
  284. #ifndef LOWSPEED
  285.     byte uflip = NIC_Cmd ^ (DS0 | DS1);
  286.     byte dflip = NIC_Cmd;
  287. #else /* LOWSPEED */
  288. #ifdef COUNT_LOOPS
  289.     int bytes = count;
  290. #endif /* COUNT_LOOPS */
  291. #endif /* LOWSPEED */
  292.  
  293. #ifdef LOWSPEED
  294. #ifdef COUNT_LOOPS
  295.     tot_cnt = 0;
  296. #endif /* COUNT_LOOPS */
  297.     /* No further optimization useful, the limit is in the adapter. */
  298.     for ( ; count > 0; --count, ++buffer) {
  299.         de620_put_byte(*buffer);
  300.     }
  301.     de620_send_command(W_DUMMY);
  302. #ifdef COUNT_LOOPS
  303.     /* trial debug output: loops per byte in de620_ready() */
  304.     printk("WRITE(%d)\n", tot_cnt/((bytes?bytes:1)));
  305. #endif /* COUNT_LOOPS */
  306. #else /* not LOWSPEED */
  307.     for ( ; count > 0; count -=2) {
  308.         outb(*buffer++, DATA_PORT);
  309.         outb(uflip, COMMAND_PORT);
  310.         outb(*buffer++, DATA_PORT);
  311.         outb(dflip, COMMAND_PORT);
  312.     }
  313.     de620_send_command(W_DUMMY);
  314. #endif /* LOWSPEED */
  315. }
  316.  
  317. static inline void
  318. de620_read_block(byte *data, int count)
  319. {
  320. #ifndef LOWSPEED
  321.     byte value;
  322.     byte uflip = NIC_Cmd ^ (DS0 | DS1);
  323.     byte dflip = NIC_Cmd;
  324. #else /* LOWSPEED */
  325. #ifdef COUNT_LOOPS
  326.     int bytes = count;
  327.  
  328.     tot_cnt = 0;
  329. #endif /* COUNT_LOOPS */
  330. #endif /* LOWSPEED */
  331.  
  332. #ifdef LOWSPEED
  333.     /* No further optimization useful, the limit is in the adapter. */
  334.     while (count-- > 0) {
  335.         *data++ = de620_read_byte();
  336.         de620_flip_ds();
  337.     }
  338. #ifdef COUNT_LOOPS
  339.     /* trial debug output: loops per byte in de620_ready() */
  340.     printk("READ(%d)\n", tot_cnt/(2*(bytes?bytes:1)));
  341. #endif /* COUNT_LOOPS */
  342. #else /* not LOWSPEED */
  343.     while (count-- > 0) {
  344.         value = inb(STATUS_PORT) & 0xf0; /* High nibble */
  345.         outb(uflip, COMMAND_PORT);
  346.         *data++ = value | inb(STATUS_PORT) >> 4; /* Low nibble */
  347.         outb(dflip , COMMAND_PORT);
  348.     }
  349. #endif /* LOWSPEED */
  350. }
  351.  
  352. static inline void
  353. de620_set_delay(void)
  354. {
  355.     de620_ready();
  356.     outb(W_DFR, DATA_PORT);
  357.     outb(NIC_Cmd ^ CS0, COMMAND_PORT);
  358.  
  359.     de620_ready();
  360. #ifdef LOWSPEED
  361.     outb(WRITE_DELAY, DATA_PORT);
  362. #else
  363.     outb(0, DATA_PORT);
  364. #endif
  365.     de620_flip_ds();
  366.  
  367.     de620_ready();
  368. #ifdef LOWSPEED
  369.     outb(READ_DELAY, DATA_PORT);
  370. #else
  371.     outb(0, DATA_PORT);
  372. #endif
  373.     de620_flip_ds();
  374. }
  375.  
  376. static inline void
  377. de620_set_register(byte reg, byte value)
  378. {
  379.     de620_ready();
  380.     outb(reg, DATA_PORT);
  381.     outb(NIC_Cmd ^ CS0, COMMAND_PORT);
  382.  
  383.     de620_put_byte(value);
  384. }
  385.  
  386. static inline byte
  387. de620_get_register(byte reg)
  388. {
  389.     byte value;
  390.  
  391.     de620_send_command(reg);
  392.     value = de620_read_byte();
  393.     de620_send_command(W_DUMMY);
  394.  
  395.     return value;
  396. }
  397.  
  398. /*********************************************************************
  399.  *
  400.  * Open/initialize the board.
  401.  *
  402.  * This routine should set everything up anew at each open, even
  403.  * registers that "should" only need to be set once at boot, so that
  404.  * there is a non-reboot way to recover if something goes wrong.
  405.  *
  406.  */
  407. static int
  408. de620_open(struct device *dev)
  409. {
  410.     if (request_irq(DE620_IRQ, de620_interrupt, 0, "de620")) {
  411.         printk ("%s: unable to get IRQ %d\n", dev->name, DE620_IRQ);
  412.         return 1;
  413.     }
  414.     irq2dev_map[DE620_IRQ] = dev;
  415.  
  416. #ifdef MODULE
  417.     MOD_INC_USE_COUNT;
  418. #endif
  419.     if (adapter_init(dev)) {
  420.         return 1;
  421.     }
  422.     dev->start = 1;
  423.     return 0;
  424. }
  425.  
  426. /************************************************
  427.  *
  428.  * The inverse routine to de620_open().
  429.  *
  430.  */
  431. static int
  432. de620_close(struct device *dev)
  433. {
  434.     /* disable recv */
  435.     de620_set_register(W_TCR, RXOFF);
  436.  
  437.     free_irq(DE620_IRQ);
  438.     irq2dev_map[DE620_IRQ] = NULL;
  439.  
  440.     dev->start = 0;
  441. #ifdef MODULE
  442.     MOD_DEC_USE_COUNT;
  443. #endif
  444.     return 0;
  445. }
  446.  
  447. /*********************************************
  448.  *
  449.  * Return current statistics
  450.  *
  451.  */
  452. static struct netstats *
  453. get_stats(struct device *dev)
  454. {
  455.     return (struct netstats *)(dev->priv);
  456. }
  457.  
  458. /*********************************************
  459.  *
  460.  * Set or clear the multicast filter for this adaptor.
  461.  * (no real multicast implemented for the DE-620, but she can be promiscuous...)
  462.  *
  463.  * num_addrs == -1    Promiscuous mode, receive all packets
  464.  * num_addrs == 0    Normal mode, clear multicast list
  465.  * num_addrs > 0    Multicast mode, receive normal and MC packets, and do
  466.  *            best-effort filtering.
  467.  */
  468. static void
  469. de620_set_multicast_list(struct device *dev, int num_addrs, void *addrs)
  470. {
  471.     if (num_addrs) { /* Enable promiscuous mode */
  472.         de620_set_register(W_TCR, (TCR_DEF & ~RXPBM) | RXALL);
  473.     }
  474.     else { /* Disable promiscuous mode, use normal mode */
  475.         de620_set_register(W_TCR, TCR_DEF);
  476.     }
  477. }
  478.  
  479. /*******************************************************
  480.  *
  481.  * Copy a buffer to the adapter transmit page memory.
  482.  * Start sending.
  483.  */
  484. static int
  485. de620_start_xmit(struct sk_buff *skb, struct device *dev)
  486. {
  487.     unsigned long flags;
  488.     int len;
  489.     int tickssofar;
  490.     byte *buffer = skb->data;
  491.     byte using_txbuf;
  492.  
  493.     /*
  494.      * If some higher layer thinks we've missed a
  495.      * tx-done interrupt we are passed NULL.
  496.      * Caution: dev_tint() handles the cli()/sti() itself.
  497.      */
  498.  
  499.     if (skb == NULL) {
  500.         dev_tint(dev);
  501.         return 0;
  502.     }
  503.  
  504.     using_txbuf = de620_tx_buffs(); /* Peek at the adapter */
  505.     dev->tbusy = (using_txbuf == (TXBF0 | TXBF1)); /* Boolean! */
  506.  
  507.     if (dev->tbusy) {    /* Do timeouts, to avoid hangs. */
  508.         tickssofar = jiffies - dev->trans_start;
  509.  
  510.         if (tickssofar < 5)
  511.             return 1;
  512.  
  513.         /* else */
  514.         printk("%s: transmit timed out (%d), %s?\n",
  515.             dev->name,
  516.             tickssofar,
  517.             "network cable problem"
  518.             );
  519.         /* Restart the adapter. */
  520.         if (adapter_init(dev)) /* maybe close it */
  521.             return 1;
  522.     }
  523.  
  524.     if ((len = skb->len) < RUNT)
  525.         len = RUNT;
  526.     if (len & 1) /* send an even number of bytes */
  527.         ++len;
  528.  
  529.     /* Start real output */
  530.     save_flags(flags);
  531.     cli();
  532.  
  533.     PRINTK(("de620_start_xmit: len=%d, bufs 0x%02x\n",
  534.         (int)skb->len, using_txbuf));
  535.  
  536.     /* select a free tx buffer. if there is one... */
  537.     switch (using_txbuf) {
  538.     default: /* both are free: use TXBF0 */
  539.     case TXBF1: /* use TXBF0 */
  540.         de620_send_command(W_CR | RW0);
  541.         using_txbuf |= TXBF0;
  542.         break;
  543.  
  544.     case TXBF0: /* use TXBF1 */
  545.         de620_send_command(W_CR | RW1);
  546.         using_txbuf |= TXBF1;
  547.         break;
  548.  
  549.     case (TXBF0 | TXBF1): /* NONE!!! */
  550.         printk("de620: Ouch! No tx-buffer available!\n");
  551.         restore_flags(flags);
  552.         return 1;
  553.         break;
  554.     }
  555.     de620_write_block(buffer, len);
  556.  
  557.     dev->trans_start = jiffies;
  558.     dev->tbusy = (using_txbuf == (TXBF0 | TXBF1)); /* Boolean! */
  559.  
  560.     ((struct netstats *)(dev->priv))->tx_packets++;
  561.     
  562.     restore_flags(flags); /* interrupts maybe back on */
  563.     
  564.     dev_kfree_skb (skb, FREE_WRITE);
  565.  
  566.     return 0;
  567. }
  568.  
  569. /*****************************************************
  570.  *
  571.  * Handle the network interface interrupts.
  572.  *
  573.  */
  574. static void
  575. de620_interrupt(int irq, struct pt_regs *regs)
  576. {
  577.     struct device *dev = irq2dev_map[irq];
  578.     byte irq_status;
  579.     int bogus_count = 0;
  580.     int again = 0;
  581.  
  582.     /* This might be deleted now, no crummy drivers present :-) Or..? */
  583.     if ((dev == NULL) || (DE620_IRQ != irq)) {
  584.         printk("%s: bogus interrupt %d\n", dev?dev->name:"DE620", irq);
  585.         return;
  586.     }
  587.  
  588.     cli();
  589.     dev->interrupt = 1;
  590.  
  591.     /* Read the status register (_not_ the status port) */
  592.     irq_status = de620_get_register(R_STS);
  593.  
  594.     PRINTK(("de620_interrupt (%2.2X)\n", irq_status));
  595.  
  596.     if (irq_status & RXGOOD) {
  597.         do {
  598.             again = de620_rx_intr(dev);
  599.             PRINTK(("again=%d\n", again));
  600.         }
  601.         while (again && (++bogus_count < 100));
  602.     }
  603.  
  604.     dev->tbusy = (de620_tx_buffs() == (TXBF0 | TXBF1)); /* Boolean! */
  605.  
  606.     dev->interrupt = 0;
  607.     sti();
  608.     return;
  609. }
  610.  
  611. /**************************************
  612.  *
  613.  * Get a packet from the adapter
  614.  *
  615.  * Send it "upstairs"
  616.  *
  617.  */
  618. static int
  619. de620_rx_intr(struct device *dev)
  620. {
  621.     struct header_buf {
  622.         byte        status;
  623.         byte        Rx_NextPage;
  624.         unsigned short    Rx_ByteCount;
  625.     } header_buf;
  626.     struct sk_buff *skb;
  627.     int size;
  628.     byte *buffer;
  629.     byte pagelink;
  630.     byte curr_page;
  631.  
  632.     PRINTK(("de620_rx_intr: next_rx_page = %d\n", next_rx_page));
  633.  
  634.     /* Tell the adapter that we are going to read data, and from where */
  635.     de620_send_command(W_CR | RRN);
  636.     de620_set_register(W_RSA1, next_rx_page);
  637.     de620_set_register(W_RSA0, 0);
  638.  
  639.     /* Deep breath, and away we goooooo */
  640.     de620_read_block((byte *)&header_buf, sizeof(struct header_buf));
  641.     PRINTK(("page status=0x%02x, nextpage=%d, packetsize=%d\n",
  642.     header_buf.status, header_buf.Rx_NextPage, header_buf.Rx_ByteCount));
  643.  
  644.     /* Plausible page header? */
  645.     pagelink = header_buf.Rx_NextPage;
  646.     if ((pagelink < first_rx_page) || (last_rx_page < pagelink)) {
  647.         /* Ouch... Forget it! Skip all and start afresh... */
  648.         printk("%s: Ring overrun? Restoring...\n", dev->name);
  649.         /* You win some, you loose some. And sometimes plenty... */
  650.         adapter_init(dev);
  651.         ((struct netstats *)(dev->priv))->rx_over_errors++;
  652.         return 0;
  653.     }
  654.  
  655.     /* OK, this look good, so far. Let's see if it's consistent... */
  656.     /* Let's compute the start of the next packet, based on where we are */
  657.     pagelink = next_rx_page +
  658.         ((header_buf.Rx_ByteCount + (4 - 1 + 0x100)) >> 8);
  659.  
  660.     /* Are we going to wrap around the page counter? */
  661.     if (pagelink > last_rx_page)
  662.         pagelink -= (last_rx_page - first_rx_page + 1);
  663.  
  664.     /* Is the _computed_ next page number equal to what the adapter says? */
  665.     if (pagelink != header_buf.Rx_NextPage) {
  666.         /* Naah, we'll skip this packet. Probably bogus data as well */
  667.         printk("%s: Page link out of sync! Restoring...\n", dev->name);
  668.         next_rx_page = header_buf.Rx_NextPage; /* at least a try... */
  669.         de620_send_command(W_DUMMY);
  670.         de620_set_register(W_NPRF, next_rx_page);
  671.         ((struct netstats *)(dev->priv))->rx_over_errors++;
  672.         return 0;
  673.     }
  674.     next_rx_page = pagelink;
  675.  
  676.     size = header_buf.Rx_ByteCount - 4;
  677.     if ((size < RUNT) || (GIANT < size)) {
  678.         printk("%s: Illegal packet size: %d!\n", dev->name, size);
  679.     }
  680.     else { /* Good packet? */
  681.         skb = alloc_skb(size, GFP_ATOMIC);
  682.         if (skb == NULL) { /* Yeah, but no place to put it... */
  683.             printk("%s: Couldn't allocate a sk_buff of size %d.\n",
  684.                 dev->name, size);
  685.             ((struct netstats *)(dev->priv))->rx_dropped++;
  686.         }
  687.         else { /* Yep! Go get it! */
  688.             skb->len = size; skb->dev = dev; skb->free = 1;
  689.             /* skb->data points to the start of sk_buff data area */
  690.             buffer = skb->data;
  691.             /* copy the packet into the buffer */
  692.             de620_read_block(buffer, size);
  693.             PRINTK(("Read %d bytes\n", size));
  694.             netif_rx(skb); /* deliver it "upstairs" */
  695.             /* count all receives */
  696.             ((struct netstats *)(dev->priv))->rx_packets++;
  697.         }
  698.     }
  699.  
  700.     /* Let's peek ahead to see if we have read the last current packet */
  701.     /* NOTE! We're _not_ checking the 'EMPTY'-flag! This seems better... */
  702.     curr_page = de620_get_register(R_CPR);
  703.     de620_set_register(W_NPRF, next_rx_page);
  704.     PRINTK(("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page));
  705.  
  706.     return (next_rx_page != curr_page); /* That was slightly tricky... */
  707. }
  708.  
  709. /*********************************************
  710.  *
  711.  * Reset the adapter to a known state
  712.  *
  713.  */
  714. static int
  715. adapter_init(struct device *dev)
  716. {
  717.     int i;
  718.     static int was_down = 0;
  719.  
  720.     if ((nic_data.Model == 3) || (nic_data.Model == 0)) { /* CT */
  721.         EIPRegister = NCTL0;
  722.         if (nic_data.Media != 1)
  723.             EIPRegister |= NIS0;    /* not BNC */
  724.     }
  725.     else if (nic_data.Model == 2) { /* UTP */
  726.         EIPRegister = NCTL0 | NIS0;
  727.     }
  728.  
  729.     if (utp)
  730.         EIPRegister = NCTL0 | NIS0;
  731.     if (bnc)
  732.         EIPRegister = NCTL0;
  733.  
  734.     de620_send_command(W_CR | RNOP | CLEAR);
  735.     de620_send_command(W_CR | RNOP);
  736.  
  737.     de620_set_register(W_SCR, SCR_DEF);
  738.     /* disable recv to wait init */
  739.     de620_set_register(W_TCR, RXOFF);
  740.  
  741.     /* Set the node ID in the adapter */
  742.     for (i = 0; i < 6; ++i) { /* W_PARn = 0xaa + n */
  743.         de620_set_register(W_PAR0 + i, dev->dev_addr[i]);
  744.     }
  745.  
  746.     de620_set_register(W_EIP, EIPRegister);
  747.  
  748.     next_rx_page = first_rx_page = DE620_RX_START_PAGE;
  749.     if (nic_data.RAM_Size)
  750.         last_rx_page = nic_data.RAM_Size - 1;
  751.     else /* 64k RAM */
  752.         last_rx_page = 255;
  753.  
  754.     de620_set_register(W_SPR, first_rx_page); /* Start Page Register */
  755.     de620_set_register(W_EPR, last_rx_page);  /* End Page Register */
  756.     de620_set_register(W_CPR, first_rx_page); /* Current Page Register */
  757.     de620_send_command(W_NPR | first_rx_page); /* Next Page Register */
  758.     de620_send_command(W_DUMMY);
  759.     de620_set_delay();
  760.  
  761.     /* Final sanity check: Anybody out there? */
  762.     /* Let's hope some bits from the statusregister make a good check */
  763. #define CHECK_MASK (  0 | TXSUC |  T16  |  0  | RXCRC | RXSHORT |  0  |  0  )
  764. #define CHECK_OK   (  0 |   0   |  0    |  0  |   0   |   0     |  0  |  0  )
  765.         /* success:   X     0      0       X      0       0        X     X  */
  766.         /* ignore:   EEDI                RXGOOD                   COLS  LNKS*/
  767.  
  768.     if (((i = de620_get_register(R_STS)) & CHECK_MASK) != CHECK_OK) {
  769.         printk("Something has happened to the DE-620!  Please check it"
  770. #ifdef SHUTDOWN_WHEN_LOST
  771.             " and do a new ifconfig"
  772. #endif
  773.             "! (%02x)\n", i);
  774. #ifdef SHUTDOWN_WHEN_LOST
  775.         /* Goodbye, cruel world... */
  776.         dev->flags &= ~IFF_UP;
  777.         de620_close(dev);
  778. #endif
  779.         was_down = 1;
  780.         return 1; /* failed */
  781.     }
  782.     if (was_down) {
  783.         printk("Thanks, I feel much better now!\n");
  784.         was_down = 0;
  785.     }
  786.  
  787.     /* All OK, go ahead... */
  788.     de620_set_register(W_TCR, TCR_DEF);
  789.  
  790.     return 0; /* all ok */
  791. }
  792.  
  793. /******************************************************************************
  794.  *
  795.  * Only start-up code below
  796.  *
  797.  */
  798. /****************************************
  799.  *
  800.  * Check if there is a DE-620 connected
  801.  */
  802. int
  803. de620_probe(struct device *dev)
  804. {
  805.     static struct netstats de620_netstats;
  806.     int i;
  807.     byte checkbyte = 0xa5;
  808.  
  809.     if (de620_debug)
  810.         printk(version);
  811.  
  812.     printk("D-Link DE-620 pocket adapter");
  813.  
  814.     /* Initially, configure basic nibble mode, so we can read the EEPROM */
  815.     NIC_Cmd = DEF_NIC_CMD;
  816.     de620_set_register(W_EIP, EIPRegister);
  817.  
  818.     /* Anybody out there? */
  819.     de620_set_register(W_CPR, checkbyte);
  820.     checkbyte = de620_get_register(R_CPR);
  821.  
  822.     if ((checkbyte != 0xa5) || (read_eeprom() != 0)) {
  823.         printk(" not identified in the printer port\n");
  824.         return ENODEV;
  825.     }
  826.  
  827. #if 0 /* Not yet */
  828.     if (check_region(DE620_IO, 3)) {
  829.         printk(", port 0x%x busy\n", DE620_IO);
  830.         return EBUSY;
  831.     }
  832. #endif
  833.     request_region(DE620_IO, 3, "de620");
  834.  
  835.     /* else, got it! */
  836.     printk(", Ethernet Address: %2.2X",
  837.         dev->dev_addr[0] = nic_data.NodeID[0]);
  838.     for (i = 1; i < ETH_ALEN; i++) {
  839.         printk(":%2.2X", dev->dev_addr[i] = nic_data.NodeID[i]);
  840.         dev->broadcast[i] = 0xff;
  841.     }
  842.  
  843.     printk(" (%dk RAM,",
  844.         (nic_data.RAM_Size) ? (nic_data.RAM_Size >> 2) : 64);
  845.  
  846.     if (nic_data.Media == 1)
  847.         printk(" BNC)\n");
  848.     else
  849.         printk(" UTP)\n");
  850.  
  851.     /* Initialize the device structure. */
  852.     /*dev->priv = kmalloc(sizeof(struct netstats), GFP_KERNEL);*/
  853.     dev->priv = &de620_netstats;
  854.  
  855.     memset(dev->priv, 0, sizeof(struct netstats));
  856.     dev->get_stats = get_stats;
  857.     dev->open = de620_open;
  858.     dev->stop = de620_close;
  859.     dev->hard_start_xmit = &de620_start_xmit;
  860.     dev->set_multicast_list = &de620_set_multicast_list;
  861.     dev->base_addr = DE620_IO;
  862.     dev->irq = DE620_IRQ;
  863.  
  864.     ether_setup(dev);
  865.     
  866.     /* dump eeprom */
  867.     if (de620_debug) {
  868.         printk("\nEEPROM contents:\n");
  869.         printk("RAM_Size = 0x%02X\n", nic_data.RAM_Size);
  870.         printk("NodeID = %02X:%02X:%02X:%02X:%02X:%02X\n",
  871.             nic_data.NodeID[0], nic_data.NodeID[1],
  872.             nic_data.NodeID[2], nic_data.NodeID[3],
  873.             nic_data.NodeID[4], nic_data.NodeID[5]);
  874.         printk("Model = %d\n", nic_data.Model);
  875.         printk("Media = %d\n", nic_data.Media);
  876.         printk("SCR = 0x%02x\n", nic_data.SCR);
  877.     }
  878.  
  879.     return 0;
  880. }
  881.  
  882. /**********************************
  883.  *
  884.  * Read info from on-board EEPROM
  885.  *
  886.  * Note: Bitwise serial I/O to/from the EEPROM vi the status _register_!
  887.  */
  888. #define sendit(data) de620_set_register(W_EIP, data | EIPRegister);
  889.  
  890. static unsigned short
  891. ReadAWord(int from)
  892. {
  893.     unsigned short data;
  894.     int nbits;
  895.  
  896.     /* cs   [__~~] SET SEND STATE */
  897.     /* di   [____]                */
  898.     /* sck  [_~~_]                */
  899.     sendit(0); sendit(1); sendit(5); sendit(4);
  900.  
  901.     /* Send the 9-bit address from where we want to read the 16-bit word */
  902.     for (nbits = 9; nbits > 0; --nbits, from <<= 1) {
  903.         if (from & 0x0100) { /* bit set? */
  904.             /* cs    [~~~~] SEND 1 */
  905.             /* di    [~~~~]        */
  906.             /* sck   [_~~_]        */
  907.             sendit(6); sendit(7); sendit(7); sendit(6);
  908.         }
  909.         else {
  910.             /* cs    [~~~~] SEND 0 */
  911.             /* di    [____]        */
  912.             /* sck   [_~~_]        */
  913.             sendit(4); sendit(5); sendit(5); sendit(4);
  914.         }
  915.     }
  916.  
  917.     /* Shift in the 16-bit word. The bits appear serially in EEDI (=0x80) */
  918.     for (data = 0, nbits = 16; nbits > 0; --nbits) {
  919.         /* cs    [~~~~] SEND 0 */
  920.         /* di    [____]        */
  921.         /* sck   [_~~_]        */
  922.         sendit(4); sendit(5); sendit(5); sendit(4);
  923.         data = (data << 1) | ((de620_get_register(R_STS) & EEDI) >> 7);
  924.     }
  925.     /* cs    [____] RESET SEND STATE */
  926.     /* di    [____]                  */
  927.     /* sck   [_~~_]                  */
  928.     sendit(0); sendit(1); sendit(1); sendit(0);
  929.  
  930.     return data;
  931. }
  932.  
  933. static int
  934. read_eeprom(void)
  935. {
  936.     unsigned short wrd;
  937.  
  938.     /* D-Link Ethernet addresses are in the series  00:80:c8:7X:XX:XX:XX */
  939.     wrd = ReadAWord(0x1aa);    /* bytes 0 + 1 of NodeID */
  940.     if (wrd != htons(0x0080)) /* Valid D-Link ether sequence? */
  941.         return -1; /* Nope, not a DE-620 */
  942.     nic_data.NodeID[0] = wrd & 0xff;
  943.     nic_data.NodeID[1] = wrd >> 8;
  944.  
  945.     wrd = ReadAWord(0x1ab);    /* bytes 2 + 3 of NodeID */
  946.     if ((wrd & 0xff) != 0xc8) /* Valid D-Link ether sequence? */
  947.         return -1; /* Nope, not a DE-620 */
  948.     nic_data.NodeID[2] = wrd & 0xff;
  949.     nic_data.NodeID[3] = wrd >> 8;
  950.  
  951.     wrd = ReadAWord(0x1ac);    /* bytes 4 + 5 of NodeID */
  952.     nic_data.NodeID[4] = wrd & 0xff;
  953.     nic_data.NodeID[5] = wrd >> 8;
  954.  
  955.     wrd = ReadAWord(0x1ad);    /* RAM size in pages (256 bytes). 0 = 64k */
  956.     nic_data.RAM_Size = (wrd >> 8);
  957.  
  958.     wrd = ReadAWord(0x1ae);    /* hardware model (CT = 3) */
  959.     nic_data.Model = (wrd & 0xff);
  960.  
  961.     wrd = ReadAWord(0x1af); /* media (indicates BNC/UTP) */
  962.     nic_data.Media = (wrd & 0xff);
  963.  
  964.     wrd = ReadAWord(0x1a8); /* System Configuration Register */
  965.     nic_data.SCR = (wrd >> 8);
  966.  
  967.     return 0; /* no errors */
  968. }
  969.  
  970. /******************************************************************************
  971.  *
  972.  * Loadable module skeleton
  973.  *
  974.  */
  975. #ifdef MODULE
  976. char kernel_version[] = UTS_RELEASE;
  977. static char nullname[8];
  978. static struct device de620_dev = {
  979.     nullname, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, de620_probe };
  980.  
  981. int
  982. init_module(void)
  983. {
  984.     if (register_netdev(&de620_dev) != 0)
  985.         return -EIO;
  986.     return 0;
  987. }
  988.  
  989. void
  990. cleanup_module(void)
  991. {
  992.     unregister_netdev(&de620_dev);
  993.     release_region(DE620_IO, 3);
  994. }
  995. #endif /* MODULE */
  996.  
  997. /*
  998.  * (add '-DMODULE' when compiling as loadable module)
  999.  *
  1000.  * compile-command:
  1001.  *    gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 \
  1002.  *     -fomit-frame-pointer -m486 \
  1003.  *    -I/usr/src/linux/include -I../../net/inet -c de620.c
  1004.  */
  1005.