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
121#include <linux/kernel.h>
122#include <linux/sched.h>
123#include <linux/types.h>
124#include <linux/fcntl.h>
125#include <linux/string.h>
126#include <linux/interrupt.h>
127#include <linux/ioport.h>
128#include <asm/io.h>
129#include <linux/in.h>
130#include <asm/system.h>
131#include <linux/errno.h>
132#include <linux/init.h>
133
134#include <linux/inet.h>
135#include <linux/netdevice.h>
136#include <linux/etherdevice.h>
137#include <linux/skbuff.h>
138
139
140#include "de620.h"
141
142typedef unsigned char byte;
143
144
145
146
147
148
149
150#ifndef DE620_IO
151#define DE620_IO 0x378
152#endif
153
154#ifndef DE620_IRQ
155#define DE620_IRQ 7
156#endif
157
158#define DATA_PORT (dev->base_addr)
159#define STATUS_PORT (dev->base_addr + 1)
160#define COMMAND_PORT (dev->base_addr + 2)
161
162#define RUNT 60
163#define GIANT 1514
164
165#ifdef DE620_DEBUG
166#define PRINTK(x) if (de620_debug >= 2) printk x
167#else
168#define DE620_DEBUG 0
169#define PRINTK(x)
170#endif
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185static int bnc;
186static int utp;
187static int io = DE620_IO;
188static int irq = DE620_IRQ;
189static int clone = DE620_CLONE;
190
191static unsigned int de620_debug = DE620_DEBUG;
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 void 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)
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 de620_send_command(dev,W_DUMMY);
338#ifdef COUNT_LOOPS
339
340 printk("WRITE(%d)\n", tot_cnt/((bytes?bytes:1)));
341#endif
342#else
343 for ( ; count > 0; count -=2) {
344 outb(*buffer++, DATA_PORT);
345 outb(uflip, COMMAND_PORT);
346 outb(*buffer++, DATA_PORT);
347 outb(dflip, COMMAND_PORT);
348 }
349 de620_send_command(dev,W_DUMMY);
350#endif
351}
352
353static inline void
354de620_read_block(struct net_device *dev, byte *data, int count)
355{
356#ifndef LOWSPEED
357 byte value;
358 byte uflip = NIC_Cmd ^ (DS0 | DS1);
359 byte dflip = NIC_Cmd;
360#else
361#ifdef COUNT_LOOPS
362 int bytes = count;
363
364 tot_cnt = 0;
365#endif
366#endif
367
368#ifdef LOWSPEED
369
370 while (count-- > 0) {
371 *data++ = de620_read_byte(dev);
372 de620_flip_ds(dev);
373 }
374#ifdef COUNT_LOOPS
375
376 printk("READ(%d)\n", tot_cnt/(2*(bytes?bytes:1)));
377#endif
378#else
379 while (count-- > 0) {
380 value = inb(STATUS_PORT) & 0xf0;
381 outb(uflip, COMMAND_PORT);
382 *data++ = value | inb(STATUS_PORT) >> 4;
383 outb(dflip , COMMAND_PORT);
384 }
385#endif
386}
387
388static inline void
389de620_set_delay(struct net_device *dev)
390{
391 de620_ready(dev);
392 outb(W_DFR, DATA_PORT);
393 outb(NIC_Cmd ^ CS0, COMMAND_PORT);
394
395 de620_ready(dev);
396#ifdef LOWSPEED
397 outb(WRITE_DELAY, DATA_PORT);
398#else
399 outb(0, DATA_PORT);
400#endif
401 de620_flip_ds(dev);
402
403 de620_ready(dev);
404#ifdef LOWSPEED
405 outb(READ_DELAY, DATA_PORT);
406#else
407 outb(0, DATA_PORT);
408#endif
409 de620_flip_ds(dev);
410}
411
412static inline void
413de620_set_register(struct net_device *dev, byte reg, byte value)
414{
415 de620_ready(dev);
416 outb(reg, DATA_PORT);
417 outb(NIC_Cmd ^ CS0, COMMAND_PORT);
418
419 de620_put_byte(dev, value);
420}
421
422static inline byte
423de620_get_register(struct net_device *dev, byte reg)
424{
425 byte value;
426
427 de620_send_command(dev,reg);
428 value = de620_read_byte(dev);
429 de620_send_command(dev,W_DUMMY);
430
431 return value;
432}
433
434
435
436
437
438
439
440
441
442
443static int de620_open(struct net_device *dev)
444{
445 int ret = request_irq(dev->irq, de620_interrupt, 0, dev->name, dev);
446 if (ret) {
447 printk (KERN_ERR "%s: unable to get IRQ %d\n", dev->name, dev->irq);
448 return ret;
449 }
450
451 if (adapter_init(dev)) {
452 ret = -EIO;
453 goto out_free_irq;
454 }
455
456 netif_start_queue(dev);
457 return 0;
458
459out_free_irq:
460 free_irq(dev->irq, dev);
461 return ret;
462}
463
464
465
466
467
468
469
470static int de620_close(struct net_device *dev)
471{
472 netif_stop_queue(dev);
473
474 de620_set_register(dev, W_TCR, RXOFF);
475 free_irq(dev->irq, dev);
476 return 0;
477}
478
479
480
481
482
483
484static struct net_device_stats *get_stats(struct net_device *dev)
485{
486 return (struct net_device_stats *)(dev->priv);
487}
488
489
490
491
492
493
494
495
496static void de620_set_multicast_list(struct net_device *dev)
497{
498 if (dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
499 {
500
501
502
503
504
505 dev->flags|=IFF_PROMISC;
506
507 de620_set_register(dev, W_TCR, (TCR_DEF & ~RXPBM) | RXALL);
508 }
509 else
510 {
511 de620_set_register(dev, W_TCR, TCR_DEF);
512 }
513}
514
515
516
517
518
519
520static void de620_timeout(struct net_device *dev)
521{
522 printk("%s: transmit timed out, %s?\n",
523 dev->name,
524 "network cable problem"
525 );
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 save_flags(flags);
555 cli();
556
557 PRINTK(("de620_start_xmit: len=%d, bufs 0x%02x\n",
558 (int)skb->len, using_txbuf));
559
560
561 switch (using_txbuf) {
562 default:
563 case TXBF1:
564 de620_send_command(dev,W_CR | RW0);
565 using_txbuf |= TXBF0;
566 break;
567
568 case TXBF0:
569 de620_send_command(dev,W_CR | RW1);
570 using_txbuf |= TXBF1;
571 break;
572
573 case (TXBF0 | TXBF1):
574 printk(KERN_WARNING "%s: No tx-buffer available!\n", dev->name);
575 restore_flags(flags);
576 return 1;
577 }
578 de620_write_block(dev, buffer, len);
579
580 dev->trans_start = jiffies;
581 if(!(using_txbuf == (TXBF0 | TXBF1)))
582 netif_wake_queue(dev);
583
584 ((struct net_device_stats *)(dev->priv))->tx_packets++;
585 restore_flags(flags);
586 dev_kfree_skb (skb);
587 return 0;
588}
589
590
591
592
593
594
595static void de620_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
603 if ((dev == NULL) || (irq != irq_in)) {
604 printk("%s: bogus interrupt %d\n", dev?dev->name:"de620", irq_in);
605 return;
606 }
607
608
609 irq_status = de620_get_register(dev, R_STS);
610
611 PRINTK(("de620_interrupt (%2.2X)\n", irq_status));
612
613 if (irq_status & RXGOOD) {
614 do {
615 again = de620_rx_intr(dev);
616 PRINTK(("again=%d\n", again));
617 }
618 while (again && (++bogus_count < 100));
619 }
620
621 if(de620_tx_buffs(dev) != (TXBF0 | TXBF1))
622 netif_wake_queue(dev);
623}
624
625
626
627
628
629
630
631
632static int de620_rx_intr(struct net_device *dev)
633{
634 struct header_buf {
635 byte status;
636 byte Rx_NextPage;
637 unsigned short Rx_ByteCount;
638 } header_buf;
639 struct sk_buff *skb;
640 int size;
641 byte *buffer;
642 byte pagelink;
643 byte curr_page;
644
645 PRINTK(("de620_rx_intr: next_rx_page = %d\n", next_rx_page));
646
647
648 de620_send_command(dev, W_CR | RRN);
649 de620_set_register(dev, W_RSA1, next_rx_page);
650 de620_set_register(dev, W_RSA0, 0);
651
652
653 de620_read_block(dev, (byte *)&header_buf, sizeof(struct header_buf));
654 PRINTK(("page status=0x%02x, nextpage=%d, packetsize=%d\n",
655 header_buf.status, header_buf.Rx_NextPage, header_buf.Rx_ByteCount));
656
657
658 pagelink = header_buf.Rx_NextPage;
659 if ((pagelink < first_rx_page) || (last_rx_page < pagelink)) {
660
661 printk(KERN_WARNING "%s: Ring overrun? Restoring...\n", dev->name);
662
663 adapter_init(dev);
664 netif_wake_queue(dev);
665 ((struct net_device_stats *)(dev->priv))->rx_over_errors++;
666 return 0;
667 }
668
669
670
671 pagelink = next_rx_page +
672 ((header_buf.Rx_ByteCount + (4 - 1 + 0x100)) >> 8);
673
674
675 if (pagelink > last_rx_page)
676 pagelink -= (last_rx_page - first_rx_page + 1);
677
678
679 if (pagelink != header_buf.Rx_NextPage) {
680
681 printk(KERN_WARNING "%s: Page link out of sync! Restoring...\n", dev->name);
682 next_rx_page = header_buf.Rx_NextPage;
683 de620_send_command(dev, W_DUMMY);
684 de620_set_register(dev, W_NPRF, next_rx_page);
685 ((struct net_device_stats *)(dev->priv))->rx_over_errors++;
686 return 0;
687 }
688 next_rx_page = pagelink;
689
690 size = header_buf.Rx_ByteCount - 4;
691 if ((size < RUNT) || (GIANT < size)) {
692 printk(KERN_WARNING "%s: Illegal packet size: %d!\n", dev->name, size);
693 }
694 else {
695 skb = dev_alloc_skb(size+2);
696 if (skb == NULL) {
697 printk(KERN_WARNING "%s: Couldn't allocate a sk_buff of size %d.\n",
698 dev->name, size);
699 ((struct net_device_stats *)(dev->priv))->rx_dropped++;
700 }
701 else {
702 skb_reserve(skb,2);
703 skb->dev = dev;
704
705 buffer = skb_put(skb,size);
706
707 de620_read_block(dev, buffer, size);
708 PRINTK(("Read %d bytes\n", size));
709 skb->protocol=eth_type_trans(skb,dev);
710 netif_rx(skb);
711 dev->last_rx = jiffies;
712
713 ((struct net_device_stats *)(dev->priv))->rx_packets++;
714 ((struct net_device_stats *)(dev->priv))->rx_bytes += size;
715 }
716 }
717
718
719
720 curr_page = de620_get_register(dev, R_CPR);
721 de620_set_register(dev, W_NPRF, next_rx_page);
722 PRINTK(("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page));
723
724 return (next_rx_page != curr_page);
725}
726
727
728
729
730
731
732static int adapter_init(struct net_device *dev)
733{
734 int i;
735 static int was_down;
736
737 if ((nic_data.Model == 3) || (nic_data.Model == 0)) {
738 EIPRegister = NCTL0;
739 if (nic_data.Media != 1)
740 EIPRegister |= NIS0;
741 }
742 else if (nic_data.Model == 2) {
743 EIPRegister = NCTL0 | NIS0;
744 }
745
746 if (utp)
747 EIPRegister = NCTL0 | NIS0;
748 if (bnc)
749 EIPRegister = NCTL0;
750
751 de620_send_command(dev, W_CR | RNOP | CLEAR);
752 de620_send_command(dev, W_CR | RNOP);
753
754 de620_set_register(dev, W_SCR, SCR_DEF);
755
756 de620_set_register(dev, W_TCR, RXOFF);
757
758
759 for (i = 0; i < 6; ++i) {
760 de620_set_register(dev, W_PAR0 + i, dev->dev_addr[i]);
761 }
762
763 de620_set_register(dev, W_EIP, EIPRegister);
764
765 next_rx_page = first_rx_page = DE620_RX_START_PAGE;
766 if (nic_data.RAM_Size)
767 last_rx_page = nic_data.RAM_Size - 1;
768 else
769 last_rx_page = 255;
770
771 de620_set_register(dev, W_SPR, first_rx_page);
772 de620_set_register(dev, W_EPR, last_rx_page);
773 de620_set_register(dev, W_CPR, first_rx_page);
774 de620_send_command(dev, W_NPR | first_rx_page);
775 de620_send_command(dev, W_DUMMY);
776 de620_set_delay(dev);
777
778
779
780#define CHECK_MASK ( 0 | TXSUC | T16 | 0 | RXCRC | RXSHORT | 0 | 0 )
781#define CHECK_OK ( 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 )
782
783
784
785 if (((i = de620_get_register(dev, R_STS)) & CHECK_MASK) != CHECK_OK) {
786 printk(KERN_ERR "%s: Something has happened to the DE-620! Please check it"
787#ifdef SHUTDOWN_WHEN_LOST
788 " and do a new ifconfig"
789#endif
790 "! (%02x)\n", dev->name, i);
791#ifdef SHUTDOWN_WHEN_LOST
792
793 dev->flags &= ~IFF_UP;
794 de620_close(dev);
795#endif
796 was_down = 1;
797 return 1;
798 }
799 if (was_down) {
800 printk(KERN_WARNING "%s: Thanks, I feel much better now!\n", dev->name);
801 was_down = 0;
802 }
803
804
805 de620_set_register(dev, W_TCR, TCR_DEF);
806
807 return 0;
808}
809
810
811
812
813
814
815
816
817
818
819int __init de620_probe(struct net_device *dev)
820{
821 static struct net_device_stats de620_netstats;
822 int i;
823 byte checkbyte = 0xa5;
824
825 SET_MODULE_OWNER(dev);
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 0
853 if (check_region(dev->base_addr, 3)) {
854 printk(", port 0x%x busy\n", dev->base_addr);
855 return -EBUSY;
856 }
857#endif
858 if (!request_region(dev->base_addr, 3, "de620")) {
859 printk(KERN_ERR "io 0x%3lX, which is busy.\n", dev->base_addr);
860 return -EBUSY;
861 }
862
863
864 printk(", Ethernet Address: %2.2X",
865 dev->dev_addr[0] = nic_data.NodeID[0]);
866 for (i = 1; i < ETH_ALEN; i++) {
867 printk(":%2.2X", dev->dev_addr[i] = nic_data.NodeID[i]);
868 dev->broadcast[i] = 0xff;
869 }
870
871 printk(" (%dk RAM,",
872 (nic_data.RAM_Size) ? (nic_data.RAM_Size >> 2) : 64);
873
874 if (nic_data.Media == 1)
875 printk(" BNC)\n");
876 else
877 printk(" UTP)\n");
878
879
880 dev->priv = &de620_netstats;
881
882 memset(dev->priv, 0, sizeof(struct net_device_stats));
883 dev->get_stats = get_stats;
884 dev->open = de620_open;
885 dev->stop = de620_close;
886 dev->hard_start_xmit = de620_start_xmit;
887 dev->tx_timeout = de620_timeout;
888 dev->watchdog_timeo = HZ*2;
889 dev->set_multicast_list = de620_set_multicast_list;
890
891
892
893 ether_setup(dev);
894
895
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 }
907
908 return 0;
909}
910
911
912
913
914
915
916
917#define sendit(dev,data) de620_set_register(dev, W_EIP, data | EIPRegister);
918
919static unsigned short __init ReadAWord(struct net_device *dev, int from)
920{
921 unsigned short data;
922 int nbits;
923
924
925
926
927 sendit(dev, 0); sendit(dev, 1); sendit(dev, 5); sendit(dev, 4);
928
929
930 for (nbits = 9; nbits > 0; --nbits, from <<= 1) {
931 if (from & 0x0100) {
932
933
934
935 sendit(dev, 6); sendit(dev, 7); sendit(dev, 7); sendit(dev, 6);
936 }
937 else {
938
939
940
941 sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4);
942 }
943 }
944
945
946 for (data = 0, nbits = 16; nbits > 0; --nbits) {
947
948
949
950 sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4);
951 data = (data << 1) | ((de620_get_register(dev, R_STS) & EEDI) >> 7);
952 }
953
954
955
956 sendit(dev, 0); sendit(dev, 1); sendit(dev, 1); sendit(dev, 0);
957
958 return data;
959}
960
961static int __init read_eeprom(struct net_device *dev)
962{
963 unsigned short wrd;
964
965
966 wrd = ReadAWord(dev, 0x1aa);
967 if (!clone && (wrd != htons(0x0080)))
968 return -1;
969 nic_data.NodeID[0] = wrd & 0xff;
970 nic_data.NodeID[1] = wrd >> 8;
971
972 wrd = ReadAWord(dev, 0x1ab);
973 if (!clone && ((wrd & 0xff) != 0xc8))
974 return -1;
975 nic_data.NodeID[2] = wrd & 0xff;
976 nic_data.NodeID[3] = wrd >> 8;
977
978 wrd = ReadAWord(dev, 0x1ac);
979 nic_data.NodeID[4] = wrd & 0xff;
980 nic_data.NodeID[5] = wrd >> 8;
981
982 wrd = ReadAWord(dev, 0x1ad);
983 nic_data.RAM_Size = (wrd >> 8);
984
985 wrd = ReadAWord(dev, 0x1ae);
986 nic_data.Model = (wrd & 0xff);
987
988 wrd = ReadAWord(dev, 0x1af);
989 nic_data.Media = (wrd & 0xff);
990
991 wrd = ReadAWord(dev, 0x1a8);
992 nic_data.SCR = (wrd >> 8);
993
994 return 0;
995}
996
997
998
999
1000
1001
1002#ifdef MODULE
1003static struct net_device de620_dev;
1004
1005int init_module(void)
1006{
1007 de620_dev.init = de620_probe;
1008 if (register_netdev(&de620_dev) != 0)
1009 return -EIO;
1010 return 0;
1011}
1012
1013void cleanup_module(void)
1014{
1015 unregister_netdev(&de620_dev);
1016 release_region(de620_dev.base_addr, 3);
1017}
1018#endif
1019MODULE_LICENSE("GPL");
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037