ia64/linux-2.6.18-xen.hg

view drivers/net/de620.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
line source
1 /*
2 * de620.c $Revision: 1.40 $ 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@scyld.com>)
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 const char version[] =
42 "de620.c: $Revision: 1.40 $, Bjorn Ekwall <bj0rn@blox.se>\n";
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 */
59 /*
60 * This driver assumes that the printer port is a "normal",
61 * dumb, uni-directional port!
62 * If your port is "fancy" in any way, please try to set it to "normal"
63 * with your BIOS setup. I have no access to machines with bi-directional
64 * ports, so I can't test such a driver :-(
65 * (Yes, I _know_ it is possible to use DE620 with bidirectional ports...)
66 *
67 * There are some clones of DE620 out there, with different names.
68 * If the current driver does not recognize a clone, try to change
69 * the following #define to:
70 *
71 * #define DE620_CLONE 1
72 */
73 #define DE620_CLONE 0
75 /*
76 * If the adapter has problems with high speeds, enable this #define
77 * otherwise full printerport speed will be attempted.
78 *
79 * You can tune the READ_DELAY/WRITE_DELAY below if you enable LOWSPEED
80 *
81 #define LOWSPEED
82 */
84 #ifndef READ_DELAY
85 #define READ_DELAY 100 /* adapter internal read delay in 100ns units */
86 #endif
88 #ifndef WRITE_DELAY
89 #define WRITE_DELAY 100 /* adapter internal write delay in 100ns units */
90 #endif
92 /*
93 * Enable this #define if you want the adapter to do a "ifconfig down" on
94 * itself when we have detected that something is possibly wrong with it.
95 * The default behaviour is to retry with "adapter_init()" until success.
96 * This should be used for debugging purposes only.
97 *
98 #define SHUTDOWN_WHEN_LOST
99 */
101 /*
102 * Enable debugging by "-DDE620_DEBUG=3" when compiling,
103 * OR by enabling the following #define
104 *
105 * use 0 for production, 1 for verification, >2 for debug
106 *
107 #define DE620_DEBUG 3
108 */
110 #ifdef LOWSPEED
111 /*
112 * Enable this #define if you want to see debugging output that show how long
113 * we have to wait before the DE-620 is ready for the next read/write/command.
114 *
115 #define COUNT_LOOPS
116 */
117 #endif
119 #include <linux/module.h>
120 #include <linux/kernel.h>
121 #include <linux/types.h>
122 #include <linux/fcntl.h>
123 #include <linux/string.h>
124 #include <linux/interrupt.h>
125 #include <linux/ioport.h>
126 #include <linux/in.h>
127 #include <linux/errno.h>
128 #include <linux/init.h>
129 #include <linux/inet.h>
130 #include <linux/netdevice.h>
131 #include <linux/etherdevice.h>
132 #include <linux/skbuff.h>
134 #include <asm/io.h>
135 #include <asm/system.h>
137 /* Constant definitions for the DE-620 registers, commands and bits */
138 #include "de620.h"
140 typedef unsigned char byte;
142 /*******************************************************
143 * *
144 * Definition of D-Link DE-620 Ethernet Pocket adapter *
145 * See also "de620.h" *
146 * *
147 *******************************************************/
148 #ifndef DE620_IO /* Compile-time configurable */
149 #define DE620_IO 0x378
150 #endif
152 #ifndef DE620_IRQ /* Compile-time configurable */
153 #define DE620_IRQ 7
154 #endif
156 #define DATA_PORT (dev->base_addr)
157 #define STATUS_PORT (dev->base_addr + 1)
158 #define COMMAND_PORT (dev->base_addr + 2)
160 #define RUNT 60 /* Too small Ethernet packet */
161 #define GIANT 1514 /* largest legal size packet, no fcs */
163 #ifdef DE620_DEBUG /* Compile-time configurable */
164 #define PRINTK(x) if (de620_debug >= 2) printk x
165 #else
166 #define DE620_DEBUG 0
167 #define PRINTK(x) /**/
168 #endif
171 /*
172 * Force media with insmod:
173 * insmod de620.o bnc=1
174 * or
175 * insmod de620.o utp=1
176 *
177 * Force io and/or irq with insmod:
178 * insmod de620.o io=0x378 irq=7
179 *
180 * Make a clone skip the Ethernet-address range check:
181 * insmod de620.o clone=1
182 */
183 static int bnc;
184 static int utp;
185 static int io = DE620_IO;
186 static int irq = DE620_IRQ;
187 static int clone = DE620_CLONE;
189 static unsigned int de620_debug = DE620_DEBUG;
191 static spinlock_t de620_lock;
193 module_param(bnc, int, 0);
194 module_param(utp, int, 0);
195 module_param(io, int, 0);
196 module_param(irq, int, 0);
197 module_param(clone, int, 0);
198 module_param(de620_debug, int, 0);
199 MODULE_PARM_DESC(bnc, "DE-620 set BNC medium (0-1)");
200 MODULE_PARM_DESC(utp, "DE-620 set UTP medium (0-1)");
201 MODULE_PARM_DESC(io, "DE-620 I/O base address,required");
202 MODULE_PARM_DESC(irq, "DE-620 IRQ number,required");
203 MODULE_PARM_DESC(clone, "Check also for non-D-Link DE-620 clones (0-1)");
204 MODULE_PARM_DESC(de620_debug, "DE-620 debug level (0-2)");
206 /***********************************************
207 * *
208 * Index to functions, as function prototypes. *
209 * *
210 ***********************************************/
212 /*
213 * Routines used internally. (See also "convenience macros.. below")
214 */
216 /* Put in the device structure. */
217 static int de620_open(struct net_device *);
218 static int de620_close(struct net_device *);
219 static struct net_device_stats *get_stats(struct net_device *);
220 static void de620_set_multicast_list(struct net_device *);
221 static int de620_start_xmit(struct sk_buff *, struct net_device *);
223 /* Dispatch from interrupts. */
224 static irqreturn_t de620_interrupt(int, void *, struct pt_regs *);
225 static int de620_rx_intr(struct net_device *);
227 /* Initialization */
228 static int adapter_init(struct net_device *);
229 static int read_eeprom(struct net_device *);
232 /*
233 * D-Link driver variables:
234 */
235 #define SCR_DEF NIBBLEMODE |INTON | SLEEP | AUTOTX
236 #define TCR_DEF RXPB /* not used: | TXSUCINT | T16INT */
237 #define DE620_RX_START_PAGE 12 /* 12 pages (=3k) reserved for tx */
238 #define DEF_NIC_CMD IRQEN | ICEN | DS1
240 static volatile byte NIC_Cmd;
241 static volatile byte next_rx_page;
242 static byte first_rx_page;
243 static byte last_rx_page;
244 static byte EIPRegister;
246 static struct nic {
247 byte NodeID[6];
248 byte RAM_Size;
249 byte Model;
250 byte Media;
251 byte SCR;
252 } nic_data;
254 /**********************************************************
255 * *
256 * Convenience macros/functions for D-Link DE-620 adapter *
257 * *
258 **********************************************************/
259 #define de620_tx_buffs(dd) (inb(STATUS_PORT) & (TXBF0 | TXBF1))
260 #define de620_flip_ds(dd) NIC_Cmd ^= DS0 | DS1; outb(NIC_Cmd, COMMAND_PORT);
262 /* Check for ready-status, and return a nibble (high 4 bits) for data input */
263 #ifdef COUNT_LOOPS
264 static int tot_cnt;
265 #endif
266 static inline byte
267 de620_ready(struct net_device *dev)
268 {
269 byte value;
270 register short int cnt = 0;
272 while ((((value = inb(STATUS_PORT)) & READY) == 0) && (cnt <= 1000))
273 ++cnt;
275 #ifdef COUNT_LOOPS
276 tot_cnt += cnt;
277 #endif
278 return value & 0xf0; /* nibble */
279 }
281 static inline void
282 de620_send_command(struct net_device *dev, byte cmd)
283 {
284 de620_ready(dev);
285 if (cmd == W_DUMMY)
286 outb(NIC_Cmd, COMMAND_PORT);
288 outb(cmd, DATA_PORT);
290 outb(NIC_Cmd ^ CS0, COMMAND_PORT);
291 de620_ready(dev);
292 outb(NIC_Cmd, COMMAND_PORT);
293 }
295 static inline void
296 de620_put_byte(struct net_device *dev, byte value)
297 {
298 /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */
299 de620_ready(dev);
300 outb(value, DATA_PORT);
301 de620_flip_ds(dev);
302 }
304 static inline byte
305 de620_read_byte(struct net_device *dev)
306 {
307 byte value;
309 /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */
310 value = de620_ready(dev); /* High nibble */
311 de620_flip_ds(dev);
312 value |= de620_ready(dev) >> 4; /* Low nibble */
313 return value;
314 }
316 static inline void
317 de620_write_block(struct net_device *dev, byte *buffer, int count, int pad)
318 {
319 #ifndef LOWSPEED
320 byte uflip = NIC_Cmd ^ (DS0 | DS1);
321 byte dflip = NIC_Cmd;
322 #else /* LOWSPEED */
323 #ifdef COUNT_LOOPS
324 int bytes = count;
325 #endif /* COUNT_LOOPS */
326 #endif /* LOWSPEED */
328 #ifdef LOWSPEED
329 #ifdef COUNT_LOOPS
330 tot_cnt = 0;
331 #endif /* COUNT_LOOPS */
332 /* No further optimization useful, the limit is in the adapter. */
333 for ( ; count > 0; --count, ++buffer) {
334 de620_put_byte(dev,*buffer);
335 }
336 for ( count = pad ; count > 0; --count, ++buffer) {
337 de620_put_byte(dev, 0);
338 }
339 de620_send_command(dev,W_DUMMY);
340 #ifdef COUNT_LOOPS
341 /* trial debug output: loops per byte in de620_ready() */
342 printk("WRITE(%d)\n", tot_cnt/((bytes?bytes:1)));
343 #endif /* COUNT_LOOPS */
344 #else /* not LOWSPEED */
345 for ( ; count > 0; count -=2) {
346 outb(*buffer++, DATA_PORT);
347 outb(uflip, COMMAND_PORT);
348 outb(*buffer++, DATA_PORT);
349 outb(dflip, COMMAND_PORT);
350 }
351 de620_send_command(dev,W_DUMMY);
352 #endif /* LOWSPEED */
353 }
355 static inline void
356 de620_read_block(struct net_device *dev, byte *data, int count)
357 {
358 #ifndef LOWSPEED
359 byte value;
360 byte uflip = NIC_Cmd ^ (DS0 | DS1);
361 byte dflip = NIC_Cmd;
362 #else /* LOWSPEED */
363 #ifdef COUNT_LOOPS
364 int bytes = count;
366 tot_cnt = 0;
367 #endif /* COUNT_LOOPS */
368 #endif /* LOWSPEED */
370 #ifdef LOWSPEED
371 /* No further optimization useful, the limit is in the adapter. */
372 while (count-- > 0) {
373 *data++ = de620_read_byte(dev);
374 de620_flip_ds(dev);
375 }
376 #ifdef COUNT_LOOPS
377 /* trial debug output: loops per byte in de620_ready() */
378 printk("READ(%d)\n", tot_cnt/(2*(bytes?bytes:1)));
379 #endif /* COUNT_LOOPS */
380 #else /* not LOWSPEED */
381 while (count-- > 0) {
382 value = inb(STATUS_PORT) & 0xf0; /* High nibble */
383 outb(uflip, COMMAND_PORT);
384 *data++ = value | inb(STATUS_PORT) >> 4; /* Low nibble */
385 outb(dflip , COMMAND_PORT);
386 }
387 #endif /* LOWSPEED */
388 }
390 static inline void
391 de620_set_delay(struct net_device *dev)
392 {
393 de620_ready(dev);
394 outb(W_DFR, DATA_PORT);
395 outb(NIC_Cmd ^ CS0, COMMAND_PORT);
397 de620_ready(dev);
398 #ifdef LOWSPEED
399 outb(WRITE_DELAY, DATA_PORT);
400 #else
401 outb(0, DATA_PORT);
402 #endif
403 de620_flip_ds(dev);
405 de620_ready(dev);
406 #ifdef LOWSPEED
407 outb(READ_DELAY, DATA_PORT);
408 #else
409 outb(0, DATA_PORT);
410 #endif
411 de620_flip_ds(dev);
412 }
414 static inline void
415 de620_set_register(struct net_device *dev, byte reg, byte value)
416 {
417 de620_ready(dev);
418 outb(reg, DATA_PORT);
419 outb(NIC_Cmd ^ CS0, COMMAND_PORT);
421 de620_put_byte(dev, value);
422 }
424 static inline byte
425 de620_get_register(struct net_device *dev, byte reg)
426 {
427 byte value;
429 de620_send_command(dev,reg);
430 value = de620_read_byte(dev);
431 de620_send_command(dev,W_DUMMY);
433 return value;
434 }
436 /*********************************************************************
437 *
438 * Open/initialize the board.
439 *
440 * This routine should set everything up anew at each open, even
441 * registers that "should" only need to be set once at boot, so that
442 * there is a non-reboot way to recover if something goes wrong.
443 *
444 */
445 static int de620_open(struct net_device *dev)
446 {
447 int ret = request_irq(dev->irq, de620_interrupt, 0, dev->name, dev);
448 if (ret) {
449 printk (KERN_ERR "%s: unable to get IRQ %d\n", dev->name, dev->irq);
450 return ret;
451 }
453 if (adapter_init(dev)) {
454 ret = -EIO;
455 goto out_free_irq;
456 }
458 netif_start_queue(dev);
459 return 0;
461 out_free_irq:
462 free_irq(dev->irq, dev);
463 return ret;
464 }
466 /************************************************
467 *
468 * The inverse routine to de620_open().
469 *
470 */
472 static int de620_close(struct net_device *dev)
473 {
474 netif_stop_queue(dev);
475 /* disable recv */
476 de620_set_register(dev, W_TCR, RXOFF);
477 free_irq(dev->irq, dev);
478 return 0;
479 }
481 /*********************************************
482 *
483 * Return current statistics
484 *
485 */
486 static struct net_device_stats *get_stats(struct net_device *dev)
487 {
488 return (struct net_device_stats *)(dev->priv);
489 }
491 /*********************************************
492 *
493 * Set or clear the multicast filter for this adaptor.
494 * (no real multicast implemented for the DE-620, but she can be promiscuous...)
495 *
496 */
498 static void de620_set_multicast_list(struct net_device *dev)
499 {
500 if (dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
501 { /* Enable promiscuous mode */
502 /*
503 * We must make the kernel realise we had to move
504 * into promisc mode or we start all out war on
505 * the cable. - AC
506 */
507 dev->flags|=IFF_PROMISC;
509 de620_set_register(dev, W_TCR, (TCR_DEF & ~RXPBM) | RXALL);
510 }
511 else
512 { /* Disable promiscuous mode, use normal mode */
513 de620_set_register(dev, W_TCR, TCR_DEF);
514 }
515 }
517 /*******************************************************
518 *
519 * Handle timeouts on transmit
520 */
522 static void de620_timeout(struct net_device *dev)
523 {
524 printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, "network cable problem");
525 /* Restart the adapter. */
526 if (!adapter_init(dev)) /* maybe close it */
527 netif_wake_queue(dev);
528 }
530 /*******************************************************
531 *
532 * Copy a buffer to the adapter transmit page memory.
533 * Start sending.
534 */
535 static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev)
536 {
537 unsigned long flags;
538 int len;
539 byte *buffer = skb->data;
540 byte using_txbuf;
542 using_txbuf = de620_tx_buffs(dev); /* Peek at the adapter */
544 netif_stop_queue(dev);
547 if ((len = skb->len) < RUNT)
548 len = RUNT;
549 if (len & 1) /* send an even number of bytes */
550 ++len;
552 /* Start real output */
554 spin_lock_irqsave(&de620_lock, flags)
555 PRINTK(("de620_start_xmit: len=%d, bufs 0x%02x\n",
556 (int)skb->len, using_txbuf));
558 /* select a free tx buffer. if there is one... */
559 switch (using_txbuf) {
560 default: /* both are free: use TXBF0 */
561 case TXBF1: /* use TXBF0 */
562 de620_send_command(dev,W_CR | RW0);
563 using_txbuf |= TXBF0;
564 break;
566 case TXBF0: /* use TXBF1 */
567 de620_send_command(dev,W_CR | RW1);
568 using_txbuf |= TXBF1;
569 break;
571 case (TXBF0 | TXBF1): /* NONE!!! */
572 printk(KERN_WARNING "%s: No tx-buffer available!\n", dev->name);
573 spin_unlock_irqrestore(&de620_lock, flags);
574 return 1;
575 }
576 de620_write_block(dev, buffer, skb->len, len-skb->len);
578 dev->trans_start = jiffies;
579 if(!(using_txbuf == (TXBF0 | TXBF1)))
580 netif_wake_queue(dev);
582 ((struct net_device_stats *)(dev->priv))->tx_packets++;
583 spin_unlock_irqrestore(&de620_lock, flags);
584 dev_kfree_skb (skb);
585 return 0;
586 }
588 /*****************************************************
589 *
590 * Handle the network interface interrupts.
591 *
592 */
593 static irqreturn_t
594 de620_interrupt(int irq_in, void *dev_id, struct pt_regs *regs)
595 {
596 struct net_device *dev = dev_id;
597 byte irq_status;
598 int bogus_count = 0;
599 int again = 0;
601 spin_lock(&de620_lock);
603 /* Read the status register (_not_ the status port) */
604 irq_status = de620_get_register(dev, R_STS);
606 PRINTK(("de620_interrupt (%2.2X)\n", irq_status));
608 if (irq_status & RXGOOD) {
609 do {
610 again = de620_rx_intr(dev);
611 PRINTK(("again=%d\n", again));
612 }
613 while (again && (++bogus_count < 100));
614 }
616 if(de620_tx_buffs(dev) != (TXBF0 | TXBF1))
617 netif_wake_queue(dev);
619 spin_unlock(&de620_lock);
620 return IRQ_HANDLED;
621 }
623 /**************************************
624 *
625 * Get a packet from the adapter
626 *
627 * Send it "upstairs"
628 *
629 */
630 static int de620_rx_intr(struct net_device *dev)
631 {
632 struct header_buf {
633 byte status;
634 byte Rx_NextPage;
635 unsigned short Rx_ByteCount;
636 } header_buf;
637 struct sk_buff *skb;
638 int size;
639 byte *buffer;
640 byte pagelink;
641 byte curr_page;
643 PRINTK(("de620_rx_intr: next_rx_page = %d\n", next_rx_page));
645 /* Tell the adapter that we are going to read data, and from where */
646 de620_send_command(dev, W_CR | RRN);
647 de620_set_register(dev, W_RSA1, next_rx_page);
648 de620_set_register(dev, W_RSA0, 0);
650 /* Deep breath, and away we goooooo */
651 de620_read_block(dev, (byte *)&header_buf, sizeof(struct header_buf));
652 PRINTK(("page status=0x%02x, nextpage=%d, packetsize=%d\n",
653 header_buf.status, header_buf.Rx_NextPage, header_buf.Rx_ByteCount));
655 /* Plausible page header? */
656 pagelink = header_buf.Rx_NextPage;
657 if ((pagelink < first_rx_page) || (last_rx_page < pagelink)) {
658 /* Ouch... Forget it! Skip all and start afresh... */
659 printk(KERN_WARNING "%s: Ring overrun? Restoring...\n", dev->name);
660 /* You win some, you lose some. And sometimes plenty... */
661 adapter_init(dev);
662 netif_wake_queue(dev);
663 ((struct net_device_stats *)(dev->priv))->rx_over_errors++;
664 return 0;
665 }
667 /* OK, this look good, so far. Let's see if it's consistent... */
668 /* Let's compute the start of the next packet, based on where we are */
669 pagelink = next_rx_page +
670 ((header_buf.Rx_ByteCount + (4 - 1 + 0x100)) >> 8);
672 /* Are we going to wrap around the page counter? */
673 if (pagelink > last_rx_page)
674 pagelink -= (last_rx_page - first_rx_page + 1);
676 /* Is the _computed_ next page number equal to what the adapter says? */
677 if (pagelink != header_buf.Rx_NextPage) {
678 /* Naah, we'll skip this packet. Probably bogus data as well */
679 printk(KERN_WARNING "%s: Page link out of sync! Restoring...\n", dev->name);
680 next_rx_page = header_buf.Rx_NextPage; /* at least a try... */
681 de620_send_command(dev, W_DUMMY);
682 de620_set_register(dev, W_NPRF, next_rx_page);
683 ((struct net_device_stats *)(dev->priv))->rx_over_errors++;
684 return 0;
685 }
686 next_rx_page = pagelink;
688 size = header_buf.Rx_ByteCount - 4;
689 if ((size < RUNT) || (GIANT < size)) {
690 printk(KERN_WARNING "%s: Illegal packet size: %d!\n", dev->name, size);
691 }
692 else { /* Good packet? */
693 skb = dev_alloc_skb(size+2);
694 if (skb == NULL) { /* Yeah, but no place to put it... */
695 printk(KERN_WARNING "%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size);
696 ((struct net_device_stats *)(dev->priv))->rx_dropped++;
697 }
698 else { /* Yep! Go get it! */
699 skb_reserve(skb,2); /* Align */
700 skb->dev = dev;
701 /* skb->data points to the start of sk_buff data area */
702 buffer = skb_put(skb,size);
703 /* copy the packet into the buffer */
704 de620_read_block(dev, buffer, size);
705 PRINTK(("Read %d bytes\n", size));
706 skb->protocol=eth_type_trans(skb,dev);
707 netif_rx(skb); /* deliver it "upstairs" */
708 dev->last_rx = jiffies;
709 /* count all receives */
710 ((struct net_device_stats *)(dev->priv))->rx_packets++;
711 ((struct net_device_stats *)(dev->priv))->rx_bytes += size;
712 }
713 }
715 /* Let's peek ahead to see if we have read the last current packet */
716 /* NOTE! We're _not_ checking the 'EMPTY'-flag! This seems better... */
717 curr_page = de620_get_register(dev, R_CPR);
718 de620_set_register(dev, W_NPRF, next_rx_page);
719 PRINTK(("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page));
721 return (next_rx_page != curr_page); /* That was slightly tricky... */
722 }
724 /*********************************************
725 *
726 * Reset the adapter to a known state
727 *
728 */
729 static int adapter_init(struct net_device *dev)
730 {
731 int i;
732 static int was_down;
734 if ((nic_data.Model == 3) || (nic_data.Model == 0)) { /* CT */
735 EIPRegister = NCTL0;
736 if (nic_data.Media != 1)
737 EIPRegister |= NIS0; /* not BNC */
738 }
739 else if (nic_data.Model == 2) { /* UTP */
740 EIPRegister = NCTL0 | NIS0;
741 }
743 if (utp)
744 EIPRegister = NCTL0 | NIS0;
745 if (bnc)
746 EIPRegister = NCTL0;
748 de620_send_command(dev, W_CR | RNOP | CLEAR);
749 de620_send_command(dev, W_CR | RNOP);
751 de620_set_register(dev, W_SCR, SCR_DEF);
752 /* disable recv to wait init */
753 de620_set_register(dev, W_TCR, RXOFF);
755 /* Set the node ID in the adapter */
756 for (i = 0; i < 6; ++i) { /* W_PARn = 0xaa + n */
757 de620_set_register(dev, W_PAR0 + i, dev->dev_addr[i]);
758 }
760 de620_set_register(dev, W_EIP, EIPRegister);
762 next_rx_page = first_rx_page = DE620_RX_START_PAGE;
763 if (nic_data.RAM_Size)
764 last_rx_page = nic_data.RAM_Size - 1;
765 else /* 64k RAM */
766 last_rx_page = 255;
768 de620_set_register(dev, W_SPR, first_rx_page); /* Start Page Register*/
769 de620_set_register(dev, W_EPR, last_rx_page); /* End Page Register */
770 de620_set_register(dev, W_CPR, first_rx_page);/*Current Page Register*/
771 de620_send_command(dev, W_NPR | first_rx_page); /* Next Page Register*/
772 de620_send_command(dev, W_DUMMY);
773 de620_set_delay(dev);
775 /* Final sanity check: Anybody out there? */
776 /* Let's hope some bits from the statusregister make a good check */
777 #define CHECK_MASK ( 0 | TXSUC | T16 | 0 | RXCRC | RXSHORT | 0 | 0 )
778 #define CHECK_OK ( 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 )
779 /* success: X 0 0 X 0 0 X X */
780 /* ignore: EEDI RXGOOD COLS LNKS*/
782 if (((i = de620_get_register(dev, R_STS)) & CHECK_MASK) != CHECK_OK) {
783 printk(KERN_ERR "%s: Something has happened to the DE-620! Please check it"
784 #ifdef SHUTDOWN_WHEN_LOST
785 " and do a new ifconfig"
786 #endif
787 "! (%02x)\n", dev->name, i);
788 #ifdef SHUTDOWN_WHEN_LOST
789 /* Goodbye, cruel world... */
790 dev->flags &= ~IFF_UP;
791 de620_close(dev);
792 #endif
793 was_down = 1;
794 return 1; /* failed */
795 }
796 if (was_down) {
797 printk(KERN_WARNING "%s: Thanks, I feel much better now!\n", dev->name);
798 was_down = 0;
799 }
801 /* All OK, go ahead... */
802 de620_set_register(dev, W_TCR, TCR_DEF);
804 return 0; /* all ok */
805 }
807 /******************************************************************************
808 *
809 * Only start-up code below
810 *
811 */
812 /****************************************
813 *
814 * Check if there is a DE-620 connected
815 */
816 struct net_device * __init de620_probe(int unit)
817 {
818 byte checkbyte = 0xa5;
819 struct net_device *dev;
820 int err = -ENOMEM;
821 int i;
823 dev = alloc_etherdev(sizeof(struct net_device_stats));
824 if (!dev)
825 goto out;
827 SET_MODULE_OWNER(dev);
829 spin_lock_init(&de620_lock);
831 /*
832 * This is where the base_addr and irq gets set.
833 * Tunable at compile-time and insmod-time
834 */
835 dev->base_addr = io;
836 dev->irq = irq;
838 /* allow overriding parameters on command line */
839 if (unit >= 0) {
840 sprintf(dev->name, "eth%d", unit);
841 netdev_boot_setup_check(dev);
842 }
844 if (de620_debug)
845 printk(version);
847 printk(KERN_INFO "D-Link DE-620 pocket adapter");
849 if (!request_region(dev->base_addr, 3, "de620")) {
850 printk(" io 0x%3lX, which is busy.\n", dev->base_addr);
851 err = -EBUSY;
852 goto out1;
853 }
855 /* Initially, configure basic nibble mode, so we can read the EEPROM */
856 NIC_Cmd = DEF_NIC_CMD;
857 de620_set_register(dev, W_EIP, EIPRegister);
859 /* Anybody out there? */
860 de620_set_register(dev, W_CPR, checkbyte);
861 checkbyte = de620_get_register(dev, R_CPR);
863 if ((checkbyte != 0xa5) || (read_eeprom(dev) != 0)) {
864 printk(" not identified in the printer port\n");
865 err = -ENODEV;
866 goto out2;
867 }
869 /* else, got it! */
870 printk(", Ethernet Address: %2.2X",
871 dev->dev_addr[0] = nic_data.NodeID[0]);
872 for (i = 1; i < ETH_ALEN; i++) {
873 printk(":%2.2X", dev->dev_addr[i] = nic_data.NodeID[i]);
874 dev->broadcast[i] = 0xff;
875 }
877 printk(" (%dk RAM,",
878 (nic_data.RAM_Size) ? (nic_data.RAM_Size >> 2) : 64);
880 if (nic_data.Media == 1)
881 printk(" BNC)\n");
882 else
883 printk(" UTP)\n");
885 dev->get_stats = get_stats;
886 dev->open = de620_open;
887 dev->stop = de620_close;
888 dev->hard_start_xmit = de620_start_xmit;
889 dev->tx_timeout = de620_timeout;
890 dev->watchdog_timeo = HZ*2;
891 dev->set_multicast_list = de620_set_multicast_list;
893 /* base_addr and irq are already set, see above! */
895 /* dump eeprom */
896 if (de620_debug) {
897 printk("\nEEPROM contents:\n");
898 printk("RAM_Size = 0x%02X\n", nic_data.RAM_Size);
899 printk("NodeID = %02X:%02X:%02X:%02X:%02X:%02X\n",
900 nic_data.NodeID[0], nic_data.NodeID[1],
901 nic_data.NodeID[2], nic_data.NodeID[3],
902 nic_data.NodeID[4], nic_data.NodeID[5]);
903 printk("Model = %d\n", nic_data.Model);
904 printk("Media = %d\n", nic_data.Media);
905 printk("SCR = 0x%02x\n", nic_data.SCR);
906 }
908 err = register_netdev(dev);
909 if (err)
910 goto out2;
911 return dev;
913 out2:
914 release_region(dev->base_addr, 3);
915 out1:
916 free_netdev(dev);
917 out:
918 return ERR_PTR(err);
919 }
921 /**********************************
922 *
923 * Read info from on-board EEPROM
924 *
925 * Note: Bitwise serial I/O to/from the EEPROM vi the status _register_!
926 */
927 #define sendit(dev,data) de620_set_register(dev, W_EIP, data | EIPRegister);
929 static unsigned short __init ReadAWord(struct net_device *dev, int from)
930 {
931 unsigned short data;
932 int nbits;
934 /* cs [__~~] SET SEND STATE */
935 /* di [____] */
936 /* sck [_~~_] */
937 sendit(dev, 0); sendit(dev, 1); sendit(dev, 5); sendit(dev, 4);
939 /* Send the 9-bit address from where we want to read the 16-bit word */
940 for (nbits = 9; nbits > 0; --nbits, from <<= 1) {
941 if (from & 0x0100) { /* bit set? */
942 /* cs [~~~~] SEND 1 */
943 /* di [~~~~] */
944 /* sck [_~~_] */
945 sendit(dev, 6); sendit(dev, 7); sendit(dev, 7); sendit(dev, 6);
946 }
947 else {
948 /* cs [~~~~] SEND 0 */
949 /* di [____] */
950 /* sck [_~~_] */
951 sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4);
952 }
953 }
955 /* Shift in the 16-bit word. The bits appear serially in EEDI (=0x80) */
956 for (data = 0, nbits = 16; nbits > 0; --nbits) {
957 /* cs [~~~~] SEND 0 */
958 /* di [____] */
959 /* sck [_~~_] */
960 sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4);
961 data = (data << 1) | ((de620_get_register(dev, R_STS) & EEDI) >> 7);
962 }
963 /* cs [____] RESET SEND STATE */
964 /* di [____] */
965 /* sck [_~~_] */
966 sendit(dev, 0); sendit(dev, 1); sendit(dev, 1); sendit(dev, 0);
968 return data;
969 }
971 static int __init read_eeprom(struct net_device *dev)
972 {
973 unsigned short wrd;
975 /* D-Link Ethernet addresses are in the series 00:80:c8:7X:XX:XX:XX */
976 wrd = ReadAWord(dev, 0x1aa); /* bytes 0 + 1 of NodeID */
977 if (!clone && (wrd != htons(0x0080))) /* Valid D-Link ether sequence? */
978 return -1; /* Nope, not a DE-620 */
979 nic_data.NodeID[0] = wrd & 0xff;
980 nic_data.NodeID[1] = wrd >> 8;
982 wrd = ReadAWord(dev, 0x1ab); /* bytes 2 + 3 of NodeID */
983 if (!clone && ((wrd & 0xff) != 0xc8)) /* Valid D-Link ether sequence? */
984 return -1; /* Nope, not a DE-620 */
985 nic_data.NodeID[2] = wrd & 0xff;
986 nic_data.NodeID[3] = wrd >> 8;
988 wrd = ReadAWord(dev, 0x1ac); /* bytes 4 + 5 of NodeID */
989 nic_data.NodeID[4] = wrd & 0xff;
990 nic_data.NodeID[5] = wrd >> 8;
992 wrd = ReadAWord(dev, 0x1ad); /* RAM size in pages (256 bytes). 0 = 64k */
993 nic_data.RAM_Size = (wrd >> 8);
995 wrd = ReadAWord(dev, 0x1ae); /* hardware model (CT = 3) */
996 nic_data.Model = (wrd & 0xff);
998 wrd = ReadAWord(dev, 0x1af); /* media (indicates BNC/UTP) */
999 nic_data.Media = (wrd & 0xff);
1001 wrd = ReadAWord(dev, 0x1a8); /* System Configuration Register */
1002 nic_data.SCR = (wrd >> 8);
1004 return 0; /* no errors */
1007 /******************************************************************************
1009 * Loadable module skeleton
1011 */
1012 #ifdef MODULE
1013 static struct net_device *de620_dev;
1015 int __init init_module(void)
1017 de620_dev = de620_probe(-1);
1018 if (IS_ERR(de620_dev))
1019 return PTR_ERR(de620_dev);
1020 return 0;
1023 void cleanup_module(void)
1025 unregister_netdev(de620_dev);
1026 release_region(de620_dev->base_addr, 3);
1027 free_netdev(de620_dev);
1029 #endif /* MODULE */
1030 MODULE_LICENSE("GPL");
1033 /*
1034 * (add '-DMODULE' when compiling as loadable module)
1036 * compile-command:
1037 * gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 \
1038 * -fomit-frame-pointer -m486 \
1039 * -I/usr/src/linux/include -I../../net/inet -c de620.c
1040 */
1041 /*
1042 * Local variables:
1043 * kernel-compile-command: "gcc -D__KERNEL__ -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c"
1044 * module-compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c"
1045 * compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c"
1046 * End:
1047 */