1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41static const char version[] =
42 "de620.c: $Revision: 1.40 $, Bjorn Ekwall <bj0rn@blox.se>\n";
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73#define DE620_CLONE 0
74
75
76
77
78
79
80
81
82
83
84#ifndef READ_DELAY
85#define READ_DELAY 100
86#endif
87
88#ifndef WRITE_DELAY
89#define WRITE_DELAY 100
90#endif
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110#ifdef LOWSPEED
111
112
113
114
115
116
117#endif
118
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>
133
134#include <asm/io.h>
135#include <asm/system.h>
136
137
138#include "de620.h"
139
140typedef unsigned char byte;
141
142
143
144
145
146
147
148#ifndef DE620_IO
149#define DE620_IO 0x378
150#endif
151
152#ifndef DE620_IRQ
153#define DE620_IRQ 7
154#endif
155
156#define DATA_PORT (dev->base_addr)
157#define STATUS_PORT (dev->base_addr + 1)
158#define COMMAND_PORT (dev->base_addr + 2)
159
160#define RUNT 60
161#define GIANT 1514
162
163#ifdef DE620_DEBUG
164#define PRINTK(x) if (de620_debug >= 2) printk x
165#else
166#define DE620_DEBUG 0
167#define PRINTK(x)
168#endif
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183static int bnc;
184static int utp;
185static int io = DE620_IO;
186static int irq = DE620_IRQ;
187static int clone = DE620_CLONE;
188
189static unsigned int de620_debug = DE620_DEBUG;
190
191static spinlock_t de620_lock;
192
193MODULE_PARM(bnc, "i");
194MODULE_PARM(utp, "i");
195MODULE_PARM(io, "i");
196MODULE_PARM(irq, "i");
197MODULE_PARM(clone, "i");
198MODULE_PARM(de620_debug, "i");
199MODULE_PARM_DESC(bnc, "DE-620 set BNC medium (0-1)");
200MODULE_PARM_DESC(utp, "DE-620 set UTP medium (0-1)");
201MODULE_PARM_DESC(io, "DE-620 I/O base address,required");
202MODULE_PARM_DESC(irq, "DE-620 IRQ number,required");
203MODULE_PARM_DESC(clone, "Check also for non-D-Link DE-620 clones (0-1)");
204MODULE_PARM_DESC(de620_debug, "DE-620 debug level (0-2)");
205
206
207
208
209
210
211
212
213
214
215
216
217static int de620_open(struct net_device *);
218static int de620_close(struct net_device *);
219static struct net_device_stats *get_stats(struct net_device *);
220static void de620_set_multicast_list(struct net_device *);
221static int de620_start_xmit(struct sk_buff *, struct net_device *);
222
223
224static irqreturn_t de620_interrupt(int, void *, struct pt_regs *);
225static int de620_rx_intr(struct net_device *);
226
227
228static int adapter_init(struct net_device *);
229int de620_probe(struct net_device *);
230static int read_eeprom(struct net_device *);
231
232
233
234
235
236#define SCR_DEF NIBBLEMODE |INTON | SLEEP | AUTOTX
237#define TCR_DEF RXPB
238#define DE620_RX_START_PAGE 12
239#define DEF_NIC_CMD IRQEN | ICEN | DS1
240
241static volatile byte NIC_Cmd;
242static volatile byte next_rx_page;
243static byte first_rx_page;
244static byte last_rx_page;
245static byte EIPRegister;
246
247static struct nic {
248 byte NodeID[6];
249 byte RAM_Size;
250 byte Model;
251 byte Media;
252 byte SCR;
253} nic_data;
254
255
256
257
258
259
260#define de620_tx_buffs(dd) (inb(STATUS_PORT) & (TXBF0 | TXBF1))
261#define de620_flip_ds(dd) NIC_Cmd ^= DS0 | DS1; outb(NIC_Cmd, COMMAND_PORT);
262
263
264#ifdef COUNT_LOOPS
265static int tot_cnt;
266#endif
267static inline byte
268de620_ready(struct net_device *dev)
269{
270 byte value;
271 register short int cnt = 0;
272
273 while ((((value = inb(STATUS_PORT)) & READY) == 0) && (cnt <= 1000))
274 ++cnt;
275
276#ifdef COUNT_LOOPS
277 tot_cnt += cnt;
278#endif
279 return value & 0xf0;
280}
281
282static inline void
283de620_send_command(struct net_device *dev, byte cmd)
284{
285 de620_ready(dev);
286 if (cmd == W_DUMMY)
287 outb(NIC_Cmd, COMMAND_PORT);
288
289 outb(cmd, DATA_PORT);
290
291 outb(NIC_Cmd ^ CS0, COMMAND_PORT);
292 de620_ready(dev);
293 outb(NIC_Cmd, COMMAND_PORT);
294}
295
296static inline void
297de620_put_byte(struct net_device *dev, byte value)
298{
299
300 de620_ready(dev);
301 outb(value, DATA_PORT);
302 de620_flip_ds(dev);
303}
304
305static inline byte
306de620_read_byte(struct net_device *dev)
307{
308 byte value;
309
310
311 value = de620_ready(dev);
312 de620_flip_ds(dev);
313 value |= de620_ready(dev) >> 4;
314 return value;
315}
316
317static inline void
318de620_write_block(struct net_device *dev, byte *buffer, int count, int pad)
319{
320#ifndef LOWSPEED
321 byte uflip = NIC_Cmd ^ (DS0 | DS1);
322 byte dflip = NIC_Cmd;
323#else
324#ifdef COUNT_LOOPS
325 int bytes = count;
326#endif
327#endif
328
329#ifdef LOWSPEED
330#ifdef COUNT_LOOPS
331 tot_cnt = 0;
332#endif
333
334 for ( ; count > 0; --count, ++buffer) {
335 de620_put_byte(dev,*buffer);
336 }
337 for ( count = pad ; count > 0; --count, ++buffer) {
338 de620_put_byte(dev, 0);
339 }
340 de620_send_command(dev,W_DUMMY);
341#ifdef COUNT_LOOPS
342
343 printk("WRITE(%d)\n", tot_cnt/((bytes?bytes:1)));
344#endif
345#else
346 for ( ; count > 0; count -=2) {
347 outb(*buffer++, DATA_PORT);
348 outb(uflip, COMMAND_PORT);
349 outb(*buffer++, DATA_PORT);
350 outb(dflip, COMMAND_PORT);
351 }
352 de620_send_command(dev,W_DUMMY);
353#endif
354}
355
356static inline void
357de620_read_block(struct net_device *dev, byte *data, int count)
358{
359#ifndef LOWSPEED
360 byte value;
361 byte uflip = NIC_Cmd ^ (DS0 | DS1);
362 byte dflip = NIC_Cmd;
363#else
364#ifdef COUNT_LOOPS
365 int bytes = count;
366
367 tot_cnt = 0;
368#endif
369#endif
370
371#ifdef LOWSPEED
372
373 while (count-- > 0) {
374 *data++ = de620_read_byte(dev);
375 de620_flip_ds(dev);
376 }
377#ifdef COUNT_LOOPS
378
379 printk("READ(%d)\n", tot_cnt/(2*(bytes?bytes:1)));
380#endif
381#else
382 while (count-- > 0) {
383 value = inb(STATUS_PORT) & 0xf0;
384 outb(uflip, COMMAND_PORT);
385 *data++ = value | inb(STATUS_PORT) >> 4;
386 outb(dflip , COMMAND_PORT);
387 }
388#endif
389}
390
391static inline void
392de620_set_delay(struct net_device *dev)
393{
394 de620_ready(dev);
395 outb(W_DFR, DATA_PORT);
396 outb(NIC_Cmd ^ CS0, COMMAND_PORT);
397
398 de620_ready(dev);
399#ifdef LOWSPEED
400 outb(WRITE_DELAY, DATA_PORT);
401#else
402 outb(0, DATA_PORT);
403#endif
404 de620_flip_ds(dev);
405
406 de620_ready(dev);
407#ifdef LOWSPEED
408 outb(READ_DELAY, DATA_PORT);
409#else
410 outb(0, DATA_PORT);
411#endif
412 de620_flip_ds(dev);
413}
414
415static inline void
416de620_set_register(struct net_device *dev, byte reg, byte value)
417{
418 de620_ready(dev);
419 outb(reg, DATA_PORT);
420 outb(NIC_Cmd ^ CS0, COMMAND_PORT);
421
422 de620_put_byte(dev, value);
423}
424
425static inline byte
426de620_get_register(struct net_device *dev, byte reg)
427{
428 byte value;
429
430 de620_send_command(dev,reg);
431 value = de620_read_byte(dev);
432 de620_send_command(dev,W_DUMMY);
433
434 return value;
435}
436
437
438
439
440
441
442
443
444
445
446static int de620_open(struct net_device *dev)
447{
448 int ret = request_irq(dev->irq, de620_interrupt, 0, dev->name, dev);
449 if (ret) {
450 printk (KERN_ERR "%s: unable to get IRQ %d\n", dev->name, dev->irq);
451 return ret;
452 }
453
454 if (adapter_init(dev)) {
455 ret = -EIO;
456 goto out_free_irq;
457 }
458
459 netif_start_queue(dev);
460 return 0;
461
462out_free_irq:
463 free_irq(dev->irq, dev);
464 return ret;
465}
466
467
468
469
470
471
472
473static int de620_close(struct net_device *dev)
474{
475 netif_stop_queue(dev);
476
477 de620_set_register(dev, W_TCR, RXOFF);
478 free_irq(dev->irq, dev);
479 return 0;
480}
481
482
483
484
485
486
487static struct net_device_stats *get_stats(struct net_device *dev)
488{
489 return (struct net_device_stats *)(dev->priv);
490}
491
492
493
494
495
496
497
498
499static void de620_set_multicast_list(struct net_device *dev)
500{
501 if (dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
502 {
503
504
505
506
507
508 dev->flags|=IFF_PROMISC;
509
510 de620_set_register(dev, W_TCR, (TCR_DEF & ~RXPBM) | RXALL);
511 }
512 else
513 {
514 de620_set_register(dev, W_TCR, TCR_DEF);
515 }
516}
517
518
519
520
521
522
523static void de620_timeout(struct net_device *dev)
524{
525 printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, "network cable problem");
526
527 if (!adapter_init(dev))
528 netif_wake_queue(dev);
529}
530
531
532
533
534
535
536static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev)
537{
538 unsigned long flags;
539 int len;
540 byte *buffer = skb->data;
541 byte using_txbuf;
542
543 using_txbuf = de620_tx_buffs(dev);
544
545 netif_stop_queue(dev);
546
547
548 if ((len = skb->len) < RUNT)
549 len = RUNT;
550 if (len & 1)
551 ++len;
552
553
554
555 spin_lock_irqsave(&de620_lock, flags)
556 PRINTK(("de620_start_xmit: len=%d, bufs 0x%02x\n",
557 (int)skb->len, using_txbuf));
558
559
560 switch (using_txbuf) {
561 default:
562 case TXBF1:
563 de620_send_command(dev,W_CR | RW0);
564 using_txbuf |= TXBF0;
565 break;
566
567 case TXBF0:
568 de620_send_command(dev,W_CR | RW1);
569 using_txbuf |= TXBF1;
570 break;
571
572 case (TXBF0 | TXBF1):
573 printk(KERN_WARNING "%s: No tx-buffer available!\n", dev->name);
574 spin_unlock_irqrestore(&de620_lock, flags);
575 return 1;
576 }
577 de620_write_block(dev, buffer, skb->len, len-skb->len);
578
579 dev->trans_start = jiffies;
580 if(!(using_txbuf == (TXBF0 | TXBF1)))
581 netif_wake_queue(dev);
582
583 ((struct net_device_stats *)(dev->priv))->tx_packets++;
584 spin_unlock_irqrestore(&de620_lock, flags);
585 dev_kfree_skb (skb);
586 return 0;
587}
588
589
590
591
592
593
594static irqreturn_t
595de620_interrupt(int irq_in, void *dev_id, struct pt_regs *regs)
596{
597 struct net_device *dev = dev_id;
598 byte irq_status;
599 int bogus_count = 0;
600 int again = 0;
601
602 spin_lock(&de620_lock);
603
604
605 irq_status = de620_get_register(dev, R_STS);
606
607 PRINTK(("de620_interrupt (%2.2X)\n", irq_status));
608
609 if (irq_status & RXGOOD) {
610 do {
611 again = de620_rx_intr(dev);
612 PRINTK(("again=%d\n", again));
613 }
614 while (again && (++bogus_count < 100));
615 }
616
617 if(de620_tx_buffs(dev) != (TXBF0 | TXBF1))
618 netif_wake_queue(dev);
619
620 spin_unlock(&de620_lock);
621 return IRQ_HANDLED;
622}
623
624
625
626
627
628
629
630
631static int de620_rx_intr(struct net_device *dev)
632{
633 struct header_buf {
634 byte status;
635 byte Rx_NextPage;
636 unsigned short Rx_ByteCount;
637 } header_buf;
638 struct sk_buff *skb;
639 int size;
640 byte *buffer;
641 byte pagelink;
642 byte curr_page;
643
644 PRINTK(("de620_rx_intr: next_rx_page = %d\n", next_rx_page));
645
646
647 de620_send_command(dev, W_CR | RRN);
648 de620_set_register(dev, W_RSA1, next_rx_page);
649 de620_set_register(dev, W_RSA0, 0);
650
651
652 de620_read_block(dev, (byte *)&header_buf, sizeof(struct header_buf));
653 PRINTK(("page status=0x%02x, nextpage=%d, packetsize=%d\n",
654 header_buf.status, header_buf.Rx_NextPage, header_buf.Rx_ByteCount));
655
656
657 pagelink = header_buf.Rx_NextPage;
658 if ((pagelink < first_rx_page) || (last_rx_page < pagelink)) {
659
660 printk(KERN_WARNING "%s: Ring overrun? Restoring...\n", dev->name);
661
662 adapter_init(dev);
663 netif_wake_queue(dev);
664 ((struct net_device_stats *)(dev->priv))->rx_over_errors++;
665 return 0;
666 }
667
668
669
670 pagelink = next_rx_page +
671 ((header_buf.Rx_ByteCount + (4 - 1 + 0x100)) >> 8);
672
673
674 if (pagelink > last_rx_page)
675 pagelink -= (last_rx_page - first_rx_page + 1);
676
677
678 if (pagelink != header_buf.Rx_NextPage) {
679
680 printk(KERN_WARNING "%s: Page link out of sync! Restoring...\n", dev->name);
681 next_rx_page = header_buf.Rx_NextPage;
682 de620_send_command(dev, W_DUMMY);
683 de620_set_register(dev, W_NPRF, next_rx_page);
684 ((struct net_device_stats *)(dev->priv))->rx_over_errors++;
685 return 0;
686 }
687 next_rx_page = pagelink;
688
689 size = header_buf.Rx_ByteCount - 4;
690 if ((size < RUNT) || (GIANT < size)) {
691 printk(KERN_WARNING "%s: Illegal packet size: %d!\n", dev->name, size);
692 }
693 else {
694 skb = dev_alloc_skb(size+2);
695 if (skb == NULL) {
696 printk(KERN_WARNING "%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size);
697 ((struct net_device_stats *)(dev->priv))->rx_dropped++;
698 }
699 else {
700 skb_reserve(skb,2);
701 skb->dev = dev;
702
703 buffer = skb_put(skb,size);
704
705 de620_read_block(dev, buffer, size);
706 PRINTK(("Read %d bytes\n", size));
707 skb->protocol=eth_type_trans(skb,dev);
708 netif_rx(skb);
709 dev->last_rx = jiffies;
710
711 ((struct net_device_stats *)(dev->priv))->rx_packets++;
712 ((struct net_device_stats *)(dev->priv))->rx_bytes += size;
713 }
714 }
715
716
717
718 curr_page = de620_get_register(dev, R_CPR);
719 de620_set_register(dev, W_NPRF, next_rx_page);
720 PRINTK(("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page));
721
722 return (next_rx_page != curr_page);
723}
724
725
726
727
728
729
730static int adapter_init(struct net_device *dev)
731{
732 int i;
733 static int was_down;
734
735 if ((nic_data.Model == 3) || (nic_data.Model == 0)) {
736 EIPRegister = NCTL0;
737 if (nic_data.Media != 1)
738 EIPRegister |= NIS0;
739 }
740 else if (nic_data.Model == 2) {
741 EIPRegister = NCTL0 | NIS0;
742 }
743
744 if (utp)
745 EIPRegister = NCTL0 | NIS0;
746 if (bnc)
747 EIPRegister = NCTL0;
748
749 de620_send_command(dev, W_CR | RNOP | CLEAR);
750 de620_send_command(dev, W_CR | RNOP);
751
752 de620_set_register(dev, W_SCR, SCR_DEF);
753
754 de620_set_register(dev, W_TCR, RXOFF);
755
756
757 for (i = 0; i < 6; ++i) {
758 de620_set_register(dev, W_PAR0 + i, dev->dev_addr[i]);
759 }
760
761 de620_set_register(dev, W_EIP, EIPRegister);
762
763 next_rx_page = first_rx_page = DE620_RX_START_PAGE;
764 if (nic_data.RAM_Size)
765 last_rx_page = nic_data.RAM_Size - 1;
766 else
767 last_rx_page = 255;
768
769 de620_set_register(dev, W_SPR, first_rx_page);
770 de620_set_register(dev, W_EPR, last_rx_page);
771 de620_set_register(dev, W_CPR, first_rx_page);
772 de620_send_command(dev, W_NPR | first_rx_page);
773 de620_send_command(dev, W_DUMMY);
774 de620_set_delay(dev);
775
776
777
778#define CHECK_MASK ( 0 | TXSUC | T16 | 0 | RXCRC | RXSHORT | 0 | 0 )
779#define CHECK_OK ( 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 )
780
781
782
783 if (((i = de620_get_register(dev, R_STS)) & CHECK_MASK) != CHECK_OK) {
784 printk(KERN_ERR "%s: Something has happened to the DE-620! Please check it"
785#ifdef SHUTDOWN_WHEN_LOST
786 " and do a new ifconfig"
787#endif
788 "! (%02x)\n", dev->name, i);
789#ifdef SHUTDOWN_WHEN_LOST
790
791 dev->flags &= ~IFF_UP;
792 de620_close(dev);
793#endif
794 was_down = 1;
795 return 1;
796 }
797 if (was_down) {
798 printk(KERN_WARNING "%s: Thanks, I feel much better now!\n", dev->name);
799 was_down = 0;
800 }
801
802
803 de620_set_register(dev, W_TCR, TCR_DEF);
804
805 return 0;
806}
807
808
809
810
811
812
813
814
815
816
817int __init de620_probe(struct net_device *dev)
818{
819 static struct net_device_stats de620_netstats;
820 int i;
821 byte checkbyte = 0xa5;
822
823 SET_MODULE_OWNER(dev);
824
825 spin_lock_init(&de620_lock);
826
827
828
829
830
831 dev->base_addr = io;
832 dev->irq = irq;
833
834 if (de620_debug)
835 printk(version);
836
837 printk(KERN_INFO "D-Link DE-620 pocket adapter");
838
839
840 NIC_Cmd = DEF_NIC_CMD;
841 de620_set_register(dev, W_EIP, EIPRegister);
842
843
844 de620_set_register(dev, W_CPR, checkbyte);
845 checkbyte = de620_get_register(dev, R_CPR);
846
847 if ((checkbyte != 0xa5) || (read_eeprom(dev) != 0)) {
848 printk(" not identified in the printer port\n");
849 return -ENODEV;
850 }
851
852 if (!request_region(dev->base_addr, 3, "de620")) {
853 printk(KERN_ERR "io 0x%3lX, which is busy.\n", dev->base_addr);
854 return -EBUSY;
855 }
856
857
858 printk(", Ethernet Address: %2.2X",
859 dev->dev_addr[0] = nic_data.NodeID[0]);
860 for (i = 1; i < ETH_ALEN; i++) {
861 printk(":%2.2X", dev->dev_addr[i] = nic_data.NodeID[i]);
862 dev->broadcast[i] = 0xff;
863 }
864
865 printk(" (%dk RAM,",
866 (nic_data.RAM_Size) ? (nic_data.RAM_Size >> 2) : 64);
867
868 if (nic_data.Media == 1)
869 printk(" BNC)\n");
870 else
871 printk(" UTP)\n");
872
873
874 dev->priv = &de620_netstats;
875
876 memset(dev->priv, 0, sizeof(struct net_device_stats));
877 dev->get_stats = get_stats;
878 dev->open = de620_open;
879 dev->stop = de620_close;
880 dev->hard_start_xmit = de620_start_xmit;
881 dev->tx_timeout = de620_timeout;
882 dev->watchdog_timeo = HZ*2;
883 dev->set_multicast_list = de620_set_multicast_list;
884
885
886
887 ether_setup(dev);
888
889
890 if (de620_debug) {
891 printk("\nEEPROM contents:\n");
892 printk("RAM_Size = 0x%02X\n", nic_data.RAM_Size);
893 printk("NodeID = %02X:%02X:%02X:%02X:%02X:%02X\n",
894 nic_data.NodeID[0], nic_data.NodeID[1],
895 nic_data.NodeID[2], nic_data.NodeID[3],
896 nic_data.NodeID[4], nic_data.NodeID[5]);
897 printk("Model = %d\n", nic_data.Model);
898 printk("Media = %d\n", nic_data.Media);
899 printk("SCR = 0x%02x\n", nic_data.SCR);
900 }
901
902 return 0;
903}
904
905
906
907
908
909
910
911#define sendit(dev,data) de620_set_register(dev, W_EIP, data | EIPRegister);
912
913static unsigned short __init ReadAWord(struct net_device *dev, int from)
914{
915 unsigned short data;
916 int nbits;
917
918
919
920
921 sendit(dev, 0); sendit(dev, 1); sendit(dev, 5); sendit(dev, 4);
922
923
924 for (nbits = 9; nbits > 0; --nbits, from <<= 1) {
925 if (from & 0x0100) {
926
927
928
929 sendit(dev, 6); sendit(dev, 7); sendit(dev, 7); sendit(dev, 6);
930 }
931 else {
932
933
934
935 sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4);
936 }
937 }
938
939
940 for (data = 0, nbits = 16; nbits > 0; --nbits) {
941
942
943
944 sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4);
945 data = (data << 1) | ((de620_get_register(dev, R_STS) & EEDI) >> 7);
946 }
947
948
949
950 sendit(dev, 0); sendit(dev, 1); sendit(dev, 1); sendit(dev, 0);
951
952 return data;
953}
954
955static int __init read_eeprom(struct net_device *dev)
956{
957 unsigned short wrd;
958
959
960 wrd = ReadAWord(dev, 0x1aa);
961 if (!clone && (wrd != htons(0x0080)))
962 return -1;
963 nic_data.NodeID[0] = wrd & 0xff;
964 nic_data.NodeID[1] = wrd >> 8;
965
966 wrd = ReadAWord(dev, 0x1ab);
967 if (!clone && ((wrd & 0xff) != 0xc8))
968 return -1;
969 nic_data.NodeID[2] = wrd & 0xff;
970 nic_data.NodeID[3] = wrd >> 8;
971
972 wrd = ReadAWord(dev, 0x1ac);
973 nic_data.NodeID[4] = wrd & 0xff;
974 nic_data.NodeID[5] = wrd >> 8;
975
976 wrd = ReadAWord(dev, 0x1ad);
977 nic_data.RAM_Size = (wrd >> 8);
978
979 wrd = ReadAWord(dev, 0x1ae);
980 nic_data.Model = (wrd & 0xff);
981
982 wrd = ReadAWord(dev, 0x1af);
983 nic_data.Media = (wrd & 0xff);
984
985 wrd = ReadAWord(dev, 0x1a8);
986 nic_data.SCR = (wrd >> 8);
987
988 return 0;
989}
990
991
992
993
994
995
996#ifdef MODULE
997static struct net_device de620_dev;
998
999int init_module(void)
1000{
1001 de620_dev.init = de620_probe;
1002 if (register_netdev(&de620_dev) != 0)
1003 return -EIO;
1004 return 0;
1005}
1006
1007void cleanup_module(void)
1008{
1009 unregister_netdev(&de620_dev);
1010 release_region(de620_dev.base_addr, 3);
1011}
1012#endif
1013MODULE_LICENSE("GPL");
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031