2 vender-specific information definition for NEC PC-9800
6 (C)1998,1999 KITAGWA Takurou & Linux/98 project
9 #include <linux/config.h>
12 #define NE_RESET EI_SHIFT(0x11) /* Issue a read to reset, a write to clear. */
14 #ifdef CONFIG_NE2K_CBUS_CNET98EL
15 #ifndef CONFIG_NE2K_CBUS_CNET98EL_IO_BASE
16 #warning CONFIG_NE2K_CBUS_CNET98EL_IO_BASE is not defined(config error?)
17 #warning use 0xaaed as default
18 #define CONFIG_NE2K_CBUS_CNET98EL_IO_BASE 0xaaed /* or 0x55ed */
20 #define CNET98EL_START_PG 0x00
21 #define CNET98EL_STOP_PG 0x40
24 /* Hardware type definition (derived from *BSD) */
25 #define NE2K_CBUS_HARDWARE_TYPE_MASK 0xff
27 /* 0: reserved for auto-detect */
29 Allied Telesis CentreCom LA-98-T */
30 #define NE2K_CBUS_HARDWARE_TYPE_ATLA98 1
34 PLANET SMART COM 98 EN-2298-C
36 #define NE2K_CBUS_HARDWARE_TYPE_BDN 2
39 Contec C-NET(98)E*A/L*A,C-NET(98)P */
40 #define NE2K_CBUS_HARDWARE_TYPE_EGY98 3
42 Melco LGY-98,IND-SP,IND-SS
44 #define NE2K_CBUS_HARDWARE_TYPE_LGY98 4
46 ICM DT-ET-25,DT-ET-T5,IF-2766ET,IF-2771ET
47 PLANET SMART COM 98 EN-2298-T,EN-2298P-T
48 D-Link DE-298PT,DE-298PCAT
49 ELECOM Laneed LD-98P */
50 #define NE2K_CBUS_HARDWARE_TYPE_ICM 5
51 /* 6: (reserved for SIC-98, which is not supported in this driver.) */
52 /* 7: (unused in *BSD?)
53 <Original NE2000 compatible>
54 <for PCI/PCMCIA cards>
56 #define NE2K_CBUS_HARDWARE_TYPE_NE2K 7
59 #define NE2K_CBUS_HARDWARE_TYPE_NEC108 8
61 I-O DATA LA-98,LA/T-98 */
62 #define NE2K_CBUS_HARDWARE_TYPE_IOLA98 9
63 /* 10: (reserved for C-NET(98), which is not supported in this driver.) */
65 Contec C-NET(98)E,L */
66 #define NE2K_CBUS_HARDWARE_TYPE_CNET98EL 11
68 #define NE2K_CBUS_HARDWARE_TYPE_MAX 11
70 /* HARDWARE TYPE ID 12-31: reserved */
72 struct ne2k_cbus_offsetinfo
{
74 unsigned short offset8
; /* +0x8 - +0xf */
75 unsigned short offset10
; /* +0x10 */
76 unsigned short offset1f
; /* +0x1f */
79 struct ne2k_cbus_region
{
84 struct ne2k_cbus_hwinfo
{
85 const unsigned short hwtype
;
86 const unsigned char *hwident
;
88 const unsigned short *portlist
;
90 const struct ne2k_cbus_offsetinfo
*offsetinfo
;
91 const struct ne2k_cbus_region
*regionlist
;
94 #ifdef CONFIG_NE2K_CBUS_ATLA98
96 static unsigned short atla98_portlist
[] __initdata
= {
101 #define atla98_offsetinfo ne2k_offsetinfo
102 #define atla98_regionlist ne2k_regionlist
103 #endif /* CONFIG_NE2K_CBUS_ATLA98 */
105 #ifdef CONFIG_NE2K_CBUS_BDN
107 static unsigned short bdn_portlist
[] __initdata
= {
112 static struct ne2k_cbus_offsetinfo bdn_offsetinfo __initdata
= {
114 /* comes from FreeBSD(98) ed98.h */
115 0x1000, 0x8000, 0x100, 0xc200 /* ??? */
117 /* comes from NetBSD/pc98 if_ne_isa.c */
118 0x1000, 0x8000, 0x100, 0x7f00 /* ??? */
121 static struct ne2k_cbus_region bdn_regionlist
[] __initdata
= {
122 {0x0, 1}, {0x1000, 1}, {0x2000, 1}, {0x3000,1},
123 {0x4000, 1}, {0x5000, 1}, {0x6000, 1}, {0x7000, 1},
124 {0x8000, 1}, {0x9000, 1}, {0xa000, 1}, {0xb000, 1},
125 {0xc000, 1}, {0xd000, 1}, {0xe000, 1}, {0xf000, 1},
126 {0x100, 1}, {0x7f00, 1},
129 #endif /* CONFIG_NE2K_CBUS_BDN */
131 #ifdef CONFIG_NE2K_CBUS_EGY98
133 static unsigned short egy98_portlist
[] __initdata
= {
138 static struct ne2k_cbus_offsetinfo egy98_offsetinfo __initdata
= {
139 0x02, 0x100, 0x200, 0x300
141 static struct ne2k_cbus_region egy98_regionlist
[] __initdata
= {
142 {0x0, 1}, {0x2, 1}, {0x4, 1}, {0x6, 1},
143 {0x8, 1}, {0xa, 1}, {0xc, 1}, {0xe, 1},
144 {0x100, 1}, {0x102, 1}, {0x104, 1}, {0x106, 1},
145 {0x108, 1}, {0x10a, 1}, {0x10c, 1}, {0x10e, 1},
146 {0x200, 1}, {0x300, 1},
149 #endif /* CONFIG_NE2K_CBUS_EGY98 */
151 #ifdef CONFIG_NE2K_CBUS_LGY98
153 static unsigned short lgy98_portlist
[] __initdata
= {
154 0xd0, 0x10d0, 0x20d0, 0x30d0, 0x40d0, 0x50d0, 0x60d0, 0x70d0,
158 static struct ne2k_cbus_offsetinfo lgy98_offsetinfo __initdata
= {
159 0x01, 0x08, 0x200, 0x300
161 static struct ne2k_cbus_region lgy98_regionlist
[] __initdata
= {
162 {0x0, 16}, {0x200, 1}, {0x300, 1},
165 #endif /* CONFIG_NE2K_CBUS_LGY98 */
167 #ifdef CONFIG_NE2K_CBUS_ICM
169 static unsigned short icm_portlist
[] __initdata
= {
173 0x46d0, 0x66d0, 0x76d0, 0x86d0, 0x96d0, 0xa6d0, 0xb6d0, 0xc6d0,
177 static struct ne2k_cbus_offsetinfo icm_offsetinfo __initdata
= {
178 0x01, 0x08, 0x100, 0x10f
180 static struct ne2k_cbus_region icm_regionlist
[] __initdata
= {
181 {0x0, 16}, {0x100, 16},
184 #endif /* CONFIG_NE2K_CBUS_ICM */
186 #if defined(CONFIG_NE2K_CBUS_NE2K) && !defined(MODULE)
187 static unsigned short ne2k_portlist
[] __initdata
= {
188 0xd0, 0x300, 0x280, 0x320, 0x340, 0x360, 0x380,
192 #if defined(CONFIG_NE2K_CBUS_NE2K) || defined(CONFIG_NE2K_CBUS_ATLA98)
193 static struct ne2k_cbus_offsetinfo ne2k_offsetinfo __initdata
= {
194 0x01, 0x08, 0x10, 0x1f
196 static struct ne2k_cbus_region ne2k_regionlist
[] __initdata
= {
202 #ifdef CONFIG_NE2K_CBUS_NEC108
204 static unsigned short nec108_portlist
[] __initdata
= {
205 0x770, 0x2770, 0x4770, 0x6770,
209 static struct ne2k_cbus_offsetinfo nec108_offsetinfo __initdata
= {
210 0x02, 0x1000, 0x888, 0x88a
212 static struct ne2k_cbus_region nec108_regionlist
[] __initdata
= {
213 {0x0, 1}, {0x2, 1}, {0x4, 1}, {0x6, 1},
214 {0x8, 1}, {0xa, 1}, {0xc, 1}, {0xe, 1},
215 {0x1000, 1}, {0x1002, 1}, {0x1004, 1}, {0x1006, 1},
216 {0x1008, 1}, {0x100a, 1}, {0x100c, 1}, {0x100e, 1},
217 {0x888, 1}, {0x88a, 1}, {0x88c, 1}, {0x88e, 1},
222 #ifdef CONFIG_NE2K_CBUS_IOLA98
224 static unsigned short iola98_portlist
[] __initdata
= {
225 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
229 static struct ne2k_cbus_offsetinfo iola98_offsetinfo __initdata
= {
230 0x1000, 0x8000, 0x100, 0xf100
232 static struct ne2k_cbus_region iola98_regionlist
[] __initdata
= {
233 {0x0, 1}, {0x1000, 1}, {0x2000, 1}, {0x3000, 1},
234 {0x4000, 1}, {0x5000, 1}, {0x6000, 1}, {0x7000, 1},
235 {0x8000, 1}, {0x9000, 1}, {0xa000, 1}, {0xb000, 1},
236 {0xc000, 1}, {0xd000, 1}, {0xe000, 1}, {0xf000, 1},
237 {0x100, 1}, {0xf100, 1},
240 #endif /* CONFIG_NE2K_CBUS_IOLA98 */
242 #ifdef CONFIG_NE2K_CBUS_CNET98EL
244 static unsigned short cnet98el_portlist
[] __initdata
= {
245 0x3d0, 0x13d0, 0x23d0, 0x33d0, 0x43d0, 0x53d0, 0x60d0, 0x70d0,
249 static struct ne2k_cbus_offsetinfo cnet98el_offsetinfo __initdata
= {
250 0x01, 0x08, 0x40e, 0x400
252 static struct ne2k_cbus_region cnet98el_regionlist
[] __initdata
= {
253 {0x0, 16}, {0x400, 16},
259 /* port information table (for ne.c initialize/probe process) */
261 static struct ne2k_cbus_hwinfo ne2k_cbus_hwinfo_list
[] __initdata
= {
262 #ifdef CONFIG_NE2K_CBUS_ATLA98
265 NE2K_CBUS_HARDWARE_TYPE_ATLA98
,
270 &atla98_offsetinfo
, atla98_regionlist
273 #ifdef CONFIG_NE2K_CBUS_BDN
276 NE2K_CBUS_HARDWARE_TYPE_BDN
,
281 &bdn_offsetinfo
, bdn_regionlist
284 #ifdef CONFIG_NE2K_CBUS_ICM
286 NE2K_CBUS_HARDWARE_TYPE_ICM
,
291 &icm_offsetinfo
, icm_regionlist
294 #ifdef CONFIG_NE2K_CBUS_NE2K
296 NE2K_CBUS_HARDWARE_TYPE_NE2K
,
301 &ne2k_offsetinfo
, ne2k_regionlist
304 #ifdef CONFIG_NE2K_CBUS_NEC108
306 NE2K_CBUS_HARDWARE_TYPE_NEC108
,
311 &nec108_offsetinfo
, nec108_regionlist
314 #ifdef CONFIG_NE2K_CBUS_IOLA98
316 NE2K_CBUS_HARDWARE_TYPE_IOLA98
,
321 &iola98_offsetinfo
, iola98_regionlist
324 #ifdef CONFIG_NE2K_CBUS_CNET98EL
326 NE2K_CBUS_HARDWARE_TYPE_CNET98EL
,
331 &cnet98el_offsetinfo
, cnet98el_regionlist
334 /* NOTE: LGY98 must be probed before EGY98, or system stalled!? */
335 #ifdef CONFIG_NE2K_CBUS_LGY98
337 NE2K_CBUS_HARDWARE_TYPE_LGY98
,
342 &lgy98_offsetinfo
, lgy98_regionlist
345 #ifdef CONFIG_NE2K_CBUS_EGY98
347 NE2K_CBUS_HARDWARE_TYPE_EGY98
,
352 &egy98_offsetinfo
, egy98_regionlist
357 "unsupported hardware",
365 static int __init
ne2k_cbus_init(struct net_device
*dev
)
367 struct ei_device
*ei_local
;
368 if (dev
->priv
== NULL
) {
369 ei_local
= kmalloc(sizeof(struct ei_device
), GFP_KERNEL
);
370 if (ei_local
== NULL
)
372 memset(ei_local
, 0, sizeof(struct ei_device
));
373 ei_local
->reg_offset
= kmalloc(sizeof(typeof(*ei_local
->reg_offset
))*18, GFP_KERNEL
);
374 if (ei_local
->reg_offset
== NULL
) {
378 spin_lock_init(&ei_local
->page_lock
);
379 dev
->priv
= ei_local
;
384 static void ne2k_cbus_destroy(struct net_device
*dev
)
386 struct ei_device
*ei_local
= (struct ei_device
*)(dev
->priv
);
387 if (ei_local
!= NULL
) {
388 if (ei_local
->reg_offset
)
389 kfree(ei_local
->reg_offset
);
395 static const struct ne2k_cbus_hwinfo
* __init
ne2k_cbus_get_hwinfo(int hwtype
)
397 const struct ne2k_cbus_hwinfo
*hw
;
399 for (hw
= &ne2k_cbus_hwinfo_list
[0]; hw
->hwtype
; hw
++) {
400 if (hw
->hwtype
== hwtype
) break;
405 static void __init
ne2k_cbus_set_hwtype(struct net_device
*dev
, const struct ne2k_cbus_hwinfo
*hw
, int ioaddr
)
407 struct ei_device
*ei_local
= (struct ei_device
*)(dev
->priv
);
409 int hwtype_old
= dev
->mem_start
& NE2K_CBUS_HARDWARE_TYPE_MASK
;
412 panic("Gieee! ei_local == NULL!! (from %p)",
413 __builtin_return_address(0));
415 dev
->mem_start
&= ~NE2K_CBUS_HARDWARE_TYPE_MASK
;
416 dev
->mem_start
|= hw
->hwtype
& NE2K_CBUS_HARDWARE_TYPE_MASK
;
419 printk(KERN_DEBUG
"hwtype changed: %d -> %d\n",hwtype_old
,(int)(dev
->mem_start
& NE2K_CBUS_HARDWARE_TYPE_MASK
));
422 if (hw
->offsetinfo
) {
423 for (i
= 0; i
< 8; i
++) {
424 ei_local
->reg_offset
[i
] = hw
->offsetinfo
->skip
* i
;
426 for (i
= 8; i
< 16; i
++) {
427 ei_local
->reg_offset
[i
] =
428 hw
->offsetinfo
->skip
*(i
-8) + hw
->offsetinfo
->offset8
;
430 #ifdef CONFIG_NE2K_CBUS_NEC108
431 if (hw
->hwtype
== NE2K_CBUS_HARDWARE_TYPE_NEC108
) {
432 int adj
= (ioaddr
& 0xf000) /2;
433 ei_local
->reg_offset
[16] =
434 (hw
->offsetinfo
->offset10
| adj
) - ioaddr
;
435 ei_local
->reg_offset
[17] =
436 (hw
->offsetinfo
->offset1f
| adj
) - ioaddr
;
438 #endif /* CONFIG_NE2K_CBUS_NEC108 */
439 ei_local
->reg_offset
[16] = hw
->offsetinfo
->offset10
;
440 ei_local
->reg_offset
[17] = hw
->offsetinfo
->offset1f
;
441 #ifdef CONFIG_NE2K_CBUS_NEC108
445 /* make dummmy offset list */
446 for (i
= 0; i
< 16; i
++) {
447 ei_local
->reg_offset
[i
] = i
;
449 ei_local
->reg_offset
[16] = 0x10;
450 ei_local
->reg_offset
[17] = 0x1f;
454 #if defined(CONFIG_NE2K_CBUS_ICM) || defined(CONFIG_NE2K_CBUS_CNET98EL)
455 static void __init
ne2k_cbus_readmem(struct net_device
*dev
, int ioaddr
, unsigned short memaddr
, char *buf
, unsigned short len
)
457 struct ei_device
*ei_local
= (struct ei_device
*)(dev
->priv
);
458 outb_p(E8390_NODMA
| E8390_START
, ioaddr
+E8390_CMD
);
459 outb_p(len
& 0xff, ioaddr
+EN0_RCNTLO
);
460 outb_p(len
>> 8, ioaddr
+EN0_RCNTHI
);
461 outb_p(memaddr
& 0xff, ioaddr
+EN0_RSARLO
);
462 outb_p(memaddr
>> 8, ioaddr
+EN0_RSARHI
);
463 outb_p(E8390_RREAD
| E8390_START
, ioaddr
+E8390_CMD
);
464 insw(ioaddr
+NE_DATAPORT
, buf
, len
>> 1);
466 static void __init
ne2k_cbus_writemem(struct net_device
*dev
, int ioaddr
, unsigned short memaddr
, const char *buf
, unsigned short len
)
468 struct ei_device
*ei_local
= (struct ei_device
*)(dev
->priv
);
469 outb_p(E8390_NODMA
| E8390_START
, ioaddr
+E8390_CMD
);
470 outb_p(ENISR_RDC
, ioaddr
+EN0_ISR
);
471 outb_p(len
& 0xff, ioaddr
+EN0_RCNTLO
);
472 outb_p(len
>> 8, ioaddr
+EN0_RCNTHI
);
473 outb_p(memaddr
& 0xff, ioaddr
+EN0_RSARLO
);
474 outb_p(memaddr
>> 8, ioaddr
+EN0_RSARHI
);
475 outb_p(E8390_RWRITE
| E8390_START
, ioaddr
+E8390_CMD
);
476 outsw(ioaddr
+NE_DATAPORT
, buf
, len
>> 1);
480 static int ne_probe_cbus(struct net_device
*dev
, const struct ne2k_cbus_hwinfo
*hw
, int ioaddr
);
481 /* End of ne2k_cbus.h */