ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / net / ne2k_cbus.h
1 /* ne2k_cbus.h: 
2    vender-specific information definition for NEC PC-9800
3    C-bus Ethernet Cards
4    Used in ne.c 
5
6    (C)1998,1999 KITAGWA Takurou & Linux/98 project
7 */
8
9 #include <linux/config.h>
10
11 #undef NE_RESET
12 #define NE_RESET EI_SHIFT(0x11) /* Issue a read to reset, a write to clear. */
13
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 */
19 #endif
20 #define CNET98EL_START_PG 0x00
21 #define CNET98EL_STOP_PG 0x40
22 #endif
23
24 /* Hardware type definition (derived from *BSD) */
25 #define NE2K_CBUS_HARDWARE_TYPE_MASK 0xff
26
27 /* 0: reserved for auto-detect */
28 /* 1: (not tested)
29    Allied Telesis CentreCom LA-98-T */
30 #define NE2K_CBUS_HARDWARE_TYPE_ATLA98 1
31 /* 2: (not tested)
32    ELECOM Laneed
33    LD-BDN[123]A
34    PLANET SMART COM 98 EN-2298-C
35    MACNICA ME98 */
36 #define NE2K_CBUS_HARDWARE_TYPE_BDN 2
37 /* 3:
38    Melco EGY-98
39    Contec C-NET(98)E*A/L*A,C-NET(98)P */
40 #define NE2K_CBUS_HARDWARE_TYPE_EGY98 3
41 /* 4:
42    Melco LGY-98,IND-SP,IND-SS
43    MACNICA NE2098 */
44 #define NE2K_CBUS_HARDWARE_TYPE_LGY98 4
45 /* 5:
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>
55 */
56 #define NE2K_CBUS_HARDWARE_TYPE_NE2K 7
57 /* 8:
58    NEC PC-9801-108 */
59 #define NE2K_CBUS_HARDWARE_TYPE_NEC108 8
60 /* 9:
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.) */
64 /* 11:
65    Contec C-NET(98)E,L */
66 #define NE2K_CBUS_HARDWARE_TYPE_CNET98EL 11
67
68 #define NE2K_CBUS_HARDWARE_TYPE_MAX 11
69
70 /* HARDWARE TYPE ID 12-31: reserved */
71
72 struct ne2k_cbus_offsetinfo {
73         unsigned short skip;
74         unsigned short offset8; /* +0x8 - +0xf */
75         unsigned short offset10; /* +0x10 */
76         unsigned short offset1f; /* +0x1f */
77 };
78
79 struct ne2k_cbus_region {
80         unsigned short start;
81         short range;
82 };
83
84 struct ne2k_cbus_hwinfo {
85         const unsigned short hwtype;
86         const unsigned char *hwident;
87 #ifndef MODULE
88         const unsigned short *portlist;
89 #endif
90         const struct ne2k_cbus_offsetinfo *offsetinfo;
91         const struct ne2k_cbus_region *regionlist;
92 };
93
94 #ifdef CONFIG_NE2K_CBUS_ATLA98
95 #ifndef MODULE
96 static unsigned short atla98_portlist[] __initdata = {
97         0xd0,
98         0
99 };
100 #endif
101 #define atla98_offsetinfo ne2k_offsetinfo
102 #define atla98_regionlist ne2k_regionlist
103 #endif /* CONFIG_NE2K_CBUS_ATLA98 */
104
105 #ifdef CONFIG_NE2K_CBUS_BDN
106 #ifndef MODULE
107 static unsigned short bdn_portlist[] __initdata = {
108         0xd0,
109         0
110 };
111 #endif
112 static struct ne2k_cbus_offsetinfo bdn_offsetinfo __initdata = {
113 #if 0
114         /* comes from FreeBSD(98) ed98.h */
115         0x1000, 0x8000, 0x100, 0xc200 /* ??? */
116 #else
117         /* comes from NetBSD/pc98 if_ne_isa.c */
118         0x1000, 0x8000, 0x100, 0x7f00 /* ??? */
119 #endif
120 };
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},
127         {0x0, 0}
128 };
129 #endif /* CONFIG_NE2K_CBUS_BDN */
130
131 #ifdef CONFIG_NE2K_CBUS_EGY98
132 #ifndef MODULE
133 static unsigned short egy98_portlist[] __initdata = {
134         0xd0,
135         0
136 };
137 #endif
138 static struct ne2k_cbus_offsetinfo egy98_offsetinfo __initdata = {
139         0x02, 0x100, 0x200, 0x300
140 };
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},
147         {0x0, 0}
148 };
149 #endif /* CONFIG_NE2K_CBUS_EGY98 */
150
151 #ifdef CONFIG_NE2K_CBUS_LGY98
152 #ifndef MODULE
153 static unsigned short lgy98_portlist[] __initdata = {
154         0xd0, 0x10d0, 0x20d0, 0x30d0, 0x40d0, 0x50d0, 0x60d0, 0x70d0,
155         0
156 };
157 #endif
158 static struct ne2k_cbus_offsetinfo lgy98_offsetinfo __initdata = {
159         0x01, 0x08, 0x200, 0x300
160 };
161 static struct ne2k_cbus_region lgy98_regionlist[] __initdata = {
162         {0x0, 16}, {0x200, 1}, {0x300, 1},
163         {0x0, 0}
164 };
165 #endif /* CONFIG_NE2K_CBUS_LGY98 */
166
167 #ifdef CONFIG_NE2K_CBUS_ICM
168 #ifndef MODULE
169 static unsigned short icm_portlist[] __initdata = {
170         /* ICM */
171         0x56d0,
172         /* LD-98PT */
173         0x46d0, 0x66d0, 0x76d0, 0x86d0, 0x96d0, 0xa6d0, 0xb6d0, 0xc6d0,
174         0
175 };
176 #endif
177 static struct ne2k_cbus_offsetinfo icm_offsetinfo __initdata = {
178         0x01, 0x08, 0x100, 0x10f
179 };
180 static struct ne2k_cbus_region icm_regionlist[] __initdata = {
181         {0x0, 16}, {0x100, 16},
182         {0x0, 0}
183 };
184 #endif /* CONFIG_NE2K_CBUS_ICM */
185
186 #if defined(CONFIG_NE2K_CBUS_NE2K) && !defined(MODULE)
187 static unsigned short ne2k_portlist[] __initdata = {
188         0xd0, 0x300, 0x280, 0x320, 0x340, 0x360, 0x380,
189         0
190 };
191 #endif
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
195 };
196 static struct ne2k_cbus_region ne2k_regionlist[] __initdata = {
197         {0x0, 32},
198         {0x0, 0}
199 };
200 #endif
201
202 #ifdef CONFIG_NE2K_CBUS_NEC108
203 #ifndef MODULE
204 static unsigned short nec108_portlist[] __initdata = {
205         0x770, 0x2770, 0x4770, 0x6770,
206         0
207 };
208 #endif
209 static struct ne2k_cbus_offsetinfo nec108_offsetinfo __initdata = {
210         0x02, 0x1000, 0x888, 0x88a
211 };
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},
218         {0x0, 0}
219 };
220 #endif
221
222 #ifdef CONFIG_NE2K_CBUS_IOLA98
223 #ifndef MODULE
224 static unsigned short iola98_portlist[] __initdata = {
225         0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
226         0
227 };
228 #endif
229 static struct ne2k_cbus_offsetinfo iola98_offsetinfo __initdata = {
230         0x1000, 0x8000, 0x100, 0xf100
231 };
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},
238         {0x0,0}
239 };
240 #endif /* CONFIG_NE2K_CBUS_IOLA98 */
241
242 #ifdef CONFIG_NE2K_CBUS_CNET98EL
243 #ifndef MODULE
244 static unsigned short cnet98el_portlist[] __initdata = {
245         0x3d0, 0x13d0, 0x23d0, 0x33d0, 0x43d0, 0x53d0, 0x60d0, 0x70d0,
246         0
247 };
248 #endif
249 static struct ne2k_cbus_offsetinfo cnet98el_offsetinfo __initdata = {
250         0x01, 0x08, 0x40e, 0x400
251 };
252 static struct ne2k_cbus_region cnet98el_regionlist[] __initdata = {
253         {0x0, 16}, {0x400, 16},
254         {0x0, 0}
255 };
256 #endif
257
258
259 /* port information table (for ne.c initialize/probe process) */
260
261 static struct ne2k_cbus_hwinfo ne2k_cbus_hwinfo_list[] __initdata = {
262 #ifdef CONFIG_NE2K_CBUS_ATLA98
263 /* NOT TESTED */
264         {
265                 NE2K_CBUS_HARDWARE_TYPE_ATLA98,
266                 "LA-98-T",
267 #ifndef MODULE
268                 atla98_portlist,
269 #endif
270                 &atla98_offsetinfo, atla98_regionlist
271         },
272 #endif
273 #ifdef CONFIG_NE2K_CBUS_BDN
274 /* NOT TESTED */
275         {
276                 NE2K_CBUS_HARDWARE_TYPE_BDN,
277                 "LD-BDN[123]A",
278 #ifndef MODULE
279                 bdn_portlist,
280 #endif
281                 &bdn_offsetinfo, bdn_regionlist
282         },
283 #endif
284 #ifdef CONFIG_NE2K_CBUS_ICM
285         {
286                 NE2K_CBUS_HARDWARE_TYPE_ICM,
287                 "IF-27xxET",
288 #ifndef MODULE
289                 icm_portlist,
290 #endif
291                 &icm_offsetinfo, icm_regionlist
292         },
293 #endif
294 #ifdef CONFIG_NE2K_CBUS_NE2K
295         {
296                 NE2K_CBUS_HARDWARE_TYPE_NE2K,
297                 "NE2000 compat.",
298 #ifndef MODULE
299                 ne2k_portlist,
300 #endif
301                 &ne2k_offsetinfo, ne2k_regionlist
302         },
303 #endif
304 #ifdef CONFIG_NE2K_CBUS_NEC108
305         {
306                 NE2K_CBUS_HARDWARE_TYPE_NEC108,
307                 "PC-9801-108",
308 #ifndef MODULE
309                 nec108_portlist,
310 #endif
311                 &nec108_offsetinfo, nec108_regionlist
312         },
313 #endif
314 #ifdef CONFIG_NE2K_CBUS_IOLA98
315         {
316                 NE2K_CBUS_HARDWARE_TYPE_IOLA98,
317                 "LA-98",
318 #ifndef MODULE
319                 iola98_portlist,
320 #endif
321                 &iola98_offsetinfo, iola98_regionlist
322         },
323 #endif
324 #ifdef CONFIG_NE2K_CBUS_CNET98EL
325         {
326                 NE2K_CBUS_HARDWARE_TYPE_CNET98EL,
327                 "C-NET(98)E/L",
328 #ifndef MODULE
329                 cnet98el_portlist,
330 #endif
331                 &cnet98el_offsetinfo, cnet98el_regionlist
332         },
333 #endif
334 /* NOTE: LGY98 must be probed before EGY98, or system stalled!? */
335 #ifdef CONFIG_NE2K_CBUS_LGY98
336         {
337                 NE2K_CBUS_HARDWARE_TYPE_LGY98,
338                 "LGY-98",
339 #ifndef MODULE
340                 lgy98_portlist,
341 #endif
342                 &lgy98_offsetinfo, lgy98_regionlist
343         },
344 #endif
345 #ifdef CONFIG_NE2K_CBUS_EGY98
346         {
347                 NE2K_CBUS_HARDWARE_TYPE_EGY98,
348                 "EGY-98",
349 #ifndef MODULE
350                 egy98_portlist,
351 #endif
352                 &egy98_offsetinfo, egy98_regionlist
353         },
354 #endif
355         {
356                 0,
357                 "unsupported hardware",
358 #ifndef MODULE
359                 NULL,
360 #endif
361                 NULL, NULL
362         }
363 };
364
365 static int __init ne2k_cbus_init(struct net_device *dev)
366 {
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)
371                         return -ENOMEM;
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) {
375                         kfree(ei_local);
376                         return -ENOMEM;
377                 }
378                 spin_lock_init(&ei_local->page_lock);
379                 dev->priv = ei_local;
380         }
381         return 0;
382 }
383
384 static void ne2k_cbus_destroy(struct net_device *dev)
385 {
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);
390                 kfree(dev->priv);
391                 dev->priv = NULL;
392         }
393 }
394
395 static const struct ne2k_cbus_hwinfo * __init ne2k_cbus_get_hwinfo(int hwtype)
396 {
397         const struct ne2k_cbus_hwinfo *hw;
398
399         for (hw = &ne2k_cbus_hwinfo_list[0]; hw->hwtype; hw++) {
400                 if (hw->hwtype == hwtype) break;
401         }
402         return hw;
403 }
404
405 static void __init ne2k_cbus_set_hwtype(struct net_device *dev, const struct ne2k_cbus_hwinfo *hw, int ioaddr)
406 {
407         struct ei_device *ei_local = (struct ei_device *)(dev->priv);
408         int i;
409         int hwtype_old = dev->mem_start & NE2K_CBUS_HARDWARE_TYPE_MASK;
410
411         if (!ei_local)
412                 panic("Gieee! ei_local == NULL!! (from %p)",
413                        __builtin_return_address(0));
414
415         dev->mem_start &= ~NE2K_CBUS_HARDWARE_TYPE_MASK;
416         dev->mem_start |= hw->hwtype & NE2K_CBUS_HARDWARE_TYPE_MASK;
417
418         if (ei_debug > 2) {
419                 printk(KERN_DEBUG "hwtype changed: %d -> %d\n",hwtype_old,(int)(dev->mem_start & NE2K_CBUS_HARDWARE_TYPE_MASK));
420         }
421
422         if (hw->offsetinfo) {
423                 for (i = 0; i < 8; i++) {
424                         ei_local->reg_offset[i] = hw->offsetinfo->skip * i;
425                 }
426                 for (i = 8; i < 16; i++) {
427                         ei_local->reg_offset[i] =
428                                 hw->offsetinfo->skip*(i-8) + hw->offsetinfo->offset8;
429                 }
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;
437                 } else {
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
442                 }
443 #endif
444         } else {
445                 /* make dummmy offset list */
446                 for (i = 0; i < 16; i++) {
447                         ei_local->reg_offset[i] = i;
448                 }
449                 ei_local->reg_offset[16] = 0x10;
450                 ei_local->reg_offset[17] = 0x1f;
451         }
452 }
453
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)
456 {
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);
465 }
466 static void __init ne2k_cbus_writemem(struct net_device *dev, int ioaddr, unsigned short memaddr, const char *buf, unsigned short len)
467 {
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);
477 }
478 #endif
479
480 static int ne_probe_cbus(struct net_device *dev, const struct ne2k_cbus_hwinfo *hw, int ioaddr, int irq);
481 /* End of ne2k_cbus.h */