Annotation of sys/dev/pcmcia/if_ne_pcmcia.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: if_ne_pcmcia.c,v 1.90 2007/05/08 18:50:06 deraadt Exp $ */
2: /* $NetBSD: if_ne_pcmcia.c,v 1.17 1998/08/15 19:00:04 thorpej Exp $ */
3:
4: /*
5: * Copyright (c) 1997 Marc Horowitz. All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: * 3. All advertising materials mentioning features or use of this software
16: * must display the following acknowledgement:
17: * This product includes software developed by Marc Horowitz.
18: * 4. The name of the author may not be used to endorse or promote products
19: * derived from this software without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31: */
32:
33: #include <sys/param.h>
34: #include <sys/systm.h>
35: #include <sys/selinfo.h>
36: #include <sys/device.h>
37: #include <sys/socket.h>
38:
39: #include <net/if_types.h>
40: #include <net/if.h>
41: #include <net/if_media.h>
42: #include <netinet/in.h>
43: #include <netinet/if_ether.h>
44:
45: #include <machine/bus.h>
46:
47: #include <dev/pcmcia/pcmciareg.h>
48: #include <dev/pcmcia/pcmciavar.h>
49: #include <dev/pcmcia/pcmciadevs.h>
50:
51: #include <dev/mii/miivar.h>
52: #include <dev/mii/mii_bitbang.h>
53:
54: #include <dev/ic/dp8390reg.h>
55: #include <dev/ic/dp8390var.h>
56:
57: #include <dev/ic/ne2000reg.h>
58: #include <dev/ic/ne2000var.h>
59:
60: #include <dev/ic/dl10019reg.h>
61: #include <dev/ic/dl10019var.h>
62:
63: #include <dev/ic/rtl80x9reg.h>
64: #include <dev/ic/rtl80x9var.h>
65:
66: #include <dev/ic/ax88190reg.h>
67: #include <dev/ic/ax88190var.h>
68:
69: int ne_pcmcia_match(struct device *, void *, void *);
70: void ne_pcmcia_attach(struct device *, struct device *, void *);
71: int ne_pcmcia_detach(struct device *, int);
72: int ne_pcmcia_activate(struct device *, enum devact);
73:
74: int ne_pcmcia_enable(struct dp8390_softc *);
75: void ne_pcmcia_disable(struct dp8390_softc *);
76:
77: struct ne_pcmcia_softc {
78: struct ne2000_softc sc_ne2000; /* real "ne2000" softc */
79:
80: /* PCMCIA-specific goo */
81: struct pcmcia_io_handle sc_pcioh; /* PCMCIA i/o information */
82: int sc_asic_io_window; /* i/o window for ASIC */
83: int sc_nic_io_window; /* i/o window for NIC */
84: struct pcmcia_function *sc_pf; /* our PCMCIA function */
85: void *sc_ih; /* interrupt handle */
86: };
87:
88: u_int8_t *
89: ne_pcmcia_get_enaddr(struct ne_pcmcia_softc *, int,
90: u_int8_t[ETHER_ADDR_LEN]);
91: u_int8_t *
92: ne_pcmcia_dl10019_get_enaddr(struct ne_pcmcia_softc *,
93: u_int8_t[ETHER_ADDR_LEN]);
94: int ne_pcmcia_ax88190_set_iobase(struct ne_pcmcia_softc *);
95:
96: struct cfattach ne_pcmcia_ca = {
97: sizeof(struct ne_pcmcia_softc), ne_pcmcia_match, ne_pcmcia_attach,
98: ne_pcmcia_detach, ne_pcmcia_activate
99: };
100:
101: const struct ne2000dev {
102: u_int16_t manufacturer;
103: u_int16_t product;
104: char *cis_info[4];
105: int function;
106: int enet_maddr;
107: unsigned char enet_vendor[3];
108: int flags;
109: #define NE2000DVF_AX88190 0x0002 /* chip is ASIX AX88190 */
110: } ne2000devs[] = {
111: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
112: PCMCIA_CIS_AMBICOM_AMB8002T,
113: 0, -1, { 0x00, 0x10, 0x7a } },
114:
115: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
116: PCMCIA_CIS_PREMAX_PE200,
117: 0, 0x07f0, { 0x00, 0x20, 0xe0 } },
118:
119: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
120: PCMCIA_CIS_DIGITAL_DEPCMXX,
121: 0, 0x0ff0, { 0x00, 0x00, 0xe8 } },
122:
123: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
124: PCMCIA_CIS_PLANET_SMARTCOM2000,
125: 0, 0x0ff0, { 0x00, 0x00, 0xe8 } },
126:
127: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
128: PCMCIA_CIS_DLINK_DE660,
129: 0, -1, { 0x00, 0x80, 0xc8 } },
130:
131: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
132: PCMCIA_CIS_DLINK_DE660PLUS,
133: 0, -1, { 0x00, 0x80, 0xc8 } },
134:
135: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
136: PCMCIA_CIS_RPTI_EP400,
137: 0, -1, { 0x00, 0x40, 0x95 } },
138:
139: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
140: PCMCIA_CIS_RPTI_EP401,
141: 0, -1, { 0x00, 0x40, 0x95 } },
142:
143: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
144: PCMCIA_CIS_ACCTON_EN2212,
145: 0, 0x0ff0, { 0x00, 0x00, 0xe8 } },
146:
147: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
148: PCMCIA_CIS_ADDTRON_W89C926,
149: 0, -1, { 0x00, 0x40, 0x33 } },
150:
151: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
152: PCMCIA_CIS_SVEC_COMBOCARD,
153: 0, -1, { 0x00, 0xe0, 0x98 } },
154:
155: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
156: PCMCIA_CIS_SVEC_LANCARD,
157: 0, 0x07f0, { 0x00, 0xc0, 0x6c } },
158:
159: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_EPSON_EEN10B,
160: PCMCIA_CIS_EPSON_EEN10B,
161: 0, 0x0ff0, { 0x00, 0x00, 0x48 } },
162:
163: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
164: PCMCIA_CIS_EDIMAX_NE2000,
165: 0, -1, { 0x00, 0x00, 0xb4 } },
166:
167: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
168: PCMCIA_CIS_CNET_NE2000,
169: 0, -1, { 0x00, 0x80, 0xad } },
170:
171: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_CNET_CNF301,
172: PCMCIA_CIS_CNET_CNF301,
173: 0, -1, { 0x00, 0x10, 0x60 } },
174:
175: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
176: PCMCIA_CIS_BILLIONTON_LNT10TN,
177: 0, -1, { 0x00, 0x00, 0x00 } },
178:
179: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
180: PCMCIA_CIS_NDC_ND5100_E,
181: 0, -1, { 0x00, 0x80, 0xc6 } },
182:
183: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
184: PCMCIA_CIS_SYNERGY21_S21810,
185: 0, -1, { 0x00, 0x48, 0x54 } },
186:
187: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
188: PCMCIA_CIS_TAMARACK_NE2000,
189: 0, -1, { 0x00, 0x47, 0x43 } },
190:
191: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
192: PCMCIA_CIS_GVC_NIC2000P,
193: 0, 0x0ff0, { 0x00, 0x00, 0xe8 } },
194:
195: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
196: PCMCIA_CIS_WISECOM_T210CT,
197: 0, -1, { 0x00, 0x20, 0x18 } },
198:
199: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
200: PCMCIA_CIS_WISECOM_IPORT,
201: 0, -1, { 0x00, 0x02, 0xdd } },
202:
203: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
204: PCMCIA_CIS_AROWANA_FE,
205: 0, -1, { 0x00, 0x48, 0x54 }, NE2000DVF_AX88190 },
206:
207: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
208: PCMCIA_CIS_GVC_NP0335,
209: 0, -1, { 0x00, 0x40, 0x05 } },
210:
211: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
212: PCMCIA_CIS_RELIA_RE2408T,
213: 0, -1, { 0x00, 0xc0, 0x0c } },
214:
215: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
216: PCMCIA_CIS_BILLIONTON_CFLT2,
217: 0, -1, { 0x00, 0x10, 0x60 } },
218:
219: /*
220: * You have to add new entries which contains
221: * PCMCIA_VENDOR_INVALID and/or PCMCIA_PRODUCT_INVALID
222: * in front of this comment.
223: *
224: * There are cards which use a generic vendor and product id but needs
225: * a different handling depending on the cis_info, so ne2000_match
226: * needs a table where the exceptions comes first and then the normal
227: * product and vendor entries.
228: */
229:
230: { PCMCIA_VENDOR_GREYCELL, PCMCIA_PRODUCT_GREYCELL_GCS2000,
231: PCMCIA_CIS_GREYCELL_GCS2000,
232: 0, -1, { 0x00, 0x47, 0x43 } },
233:
234: { PCMCIA_VENDOR_IBM, PCMCIA_PRODUCT_IBM_INFOMOVER,
235: PCMCIA_CIS_IBM_INFOMOVER,
236: 0, 0x0ff0, { 0x08, 0x00, 0x5a } },
237:
238: { PCMCIA_VENDOR_IBM, PCMCIA_PRODUCT_IBM_INFOMOVER,
239: PCMCIA_CIS_IBM_INFOMOVER,
240: 0, 0x0ff0, { 0x00, 0x04, 0xac } },
241:
242: { PCMCIA_VENDOR_IBM, PCMCIA_PRODUCT_IBM_INFOMOVER,
243: PCMCIA_CIS_IBM_INFOMOVER,
244: 0, 0x0ff0, { 0x00, 0x06, 0x29 } },
245:
246: { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_ECARD_1,
247: PCMCIA_CIS_LINKSYS_ECARD_1,
248: 0, -1, { 0x00, 0x80, 0xc8 } },
249:
250: { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_PCM100,
251: PCMCIA_CIS_LINKSYS_PCM100,
252: 0, -1, { 0x00, 0x04, 0x5a } },
253:
254: { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_COMBO_ECARD,
255: PCMCIA_CIS_LINKSYS_COMBO_ECARD,
256: 0, -1, { 0x00, 0x04, 0x5a }, NE2000DVF_AX88190 },
257:
258: { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_COMBO_ECARD,
259: PCMCIA_CIS_LINKSYS_COMBO_ECARD,
260: 0, -1, { 0x00, 0x80, 0xc8 } },
261:
262: { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_COMBO_ECARD,
263: PCMCIA_CIS_PLANEX_FNW3600T,
264: 0, -1, { 0x00, 0x90, 0xcc } },
265:
266: { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_COMBO_ECARD,
267: PCMCIA_CIS_SVEC_PN650TX,
268: 0, -1, { 0x00, 0xe0, 0x98 } },
269:
270: { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_COMBO_ECARD,
271: PCMCIA_CIS_TRENDNET_TECF100,
272: 0, -1, { 0x00, 0x12, 0x0e } },
273:
274: /*
275: * This entry should be here so that above two cards doesn't
276: * match with this. FNW-3700T won't match above entries due to
277: * MAC address check.
278: */
279: { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_COMBO_ECARD,
280: PCMCIA_CIS_PLANEX_FNW3700T,
281: 0, -1, { 0x00, 0x90, 0xcc }, NE2000DVF_AX88190 },
282:
283: { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_ETHERFAST,
284: PCMCIA_CIS_LINKSYS_ETHERFAST,
285: 0, -1, { 0x00, 0x80, 0xc8 } },
286:
287: { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_ETHERFAST,
288: PCMCIA_CIS_LINKSYS_ETHERFAST,
289: 0, -1, { 0x00, 0x50, 0xba } },
290:
291: { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_ETHERFAST,
292: PCMCIA_CIS_DLINK_DE650,
293: 0, -1, { 0x00, 0xe0, 0x98 } },
294:
295: { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_NETGEAR_FA410TXC,
296: PCMCIA_CIS_DLINK_DFE670TXD,
297: 0, -1, { 0x00, 0x05, 0x5d } },
298:
299: { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_NETGEAR_FA410TXC,
300: PCMCIA_CIS_DLINK_DFE670TXD,
301: 0, -1, { 0x00, 0x50, 0xba } },
302:
303: { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_TRUST_COMBO_ECARD,
304: PCMCIA_CIS_LINKSYS_TRUST_COMBO_ECARD,
305: 0, 0x0120, { 0x20, 0x04, 0x49 } },
306:
307: /* Although the comments above say to put VENDOR/PRODUCT INVALID IDs
308: above this list, we need to keep this one below the ECARD_1, or else
309: both will match the same more-generic entry rather than the more
310: specific one above with proper vendor and product IDs. */
311: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
312: PCMCIA_CIS_LINKSYS_ECARD_2,
313: 0, -1, { 0x00, 0x80, 0xc8 } },
314:
315: /*
316: * D-Link DE-650 has many minor versions:
317: *
318: * CIS information Manufacturer Product Note
319: * 1 "D-Link, DE-650" INVALID INVALID white card
320: * 2 "D-Link, DE-650, Ver 01.00" INVALID INVALID became bare metal
321: * 3 "D-Link, DE-650, Ver 01.00" 0x149 0x265 minor change in look
322: * 4 "D-Link, DE-650, Ver 01.00" 0x149 0x265 collision LED added
323: *
324: * While the 1st and the 2nd types should use the "D-Link DE-650" entry,
325: * the 3rd and the 4th types should use the "Linksys EtherCard" entry.
326: * Therefore, this entry must be below the LINKSYS_ECARD_1. --itohy
327: */
328: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
329: PCMCIA_CIS_DLINK_DE650,
330: 0, 0x0040, { 0x00, 0x80, 0xc8 } },
331:
332: /*
333: * IO-DATA PCLA/TE and later version of PCLA/T has valid
334: * vendor/product ID and it is possible to read MAC address
335: * using standard I/O ports. It also read from CIS offset 0x01c0.
336: * On the other hand, earlier version of PCLA/T doesn't have valid
337: * vendor/product ID and MAC address must be read from CIS offset
338: * 0x0ff0 (i.e., usual ne2000 way to read it doesn't work).
339: * And CIS information of earlier and later version of PCLA/T are
340: * same except fourth element. So, for now, we place the entry for
341: * PCLA/TE (and later version of PCLA/T) followed by entry
342: * for the earlier version of PCLA/T (or, modify to match all CIS
343: * information and have three or more individual entries).
344: */
345: { PCMCIA_VENDOR_IODATA, PCMCIA_PRODUCT_IODATA_PCLATE,
346: PCMCIA_CIS_IODATA_PCLATE,
347: 0, -1, { 0x00, 0xa0, 0xb0 } },
348:
349: /*
350: * This entry should be placed after above PCLA-TE entry.
351: * See above comments for detail.
352: */
353: { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
354: PCMCIA_CIS_IODATA_PCLAT,
355: 0, 0x0ff0, { 0x00, 0xa0, 0xb0 } },
356:
357: { PCMCIA_VENDOR_DAYNA, PCMCIA_PRODUCT_DAYNA_COMMUNICARD_E_1,
358: PCMCIA_CIS_DAYNA_COMMUNICARD_E_1,
359: 0, 0x0110, { 0x00, 0x80, 0x19 } },
360:
361: { PCMCIA_VENDOR_DAYNA, PCMCIA_PRODUCT_DAYNA_COMMUNICARD_E_2,
362: PCMCIA_CIS_DAYNA_COMMUNICARD_E_2,
363: 0, -1, { 0x00, 0x80, 0x19 } },
364:
365: { PCMCIA_VENDOR_COREGA, PCMCIA_PRODUCT_COREGA_ETHER_PCC_T,
366: PCMCIA_CIS_COREGA_ETHER_PCC_T,
367: 0, -1, { 0x00, 0x00, 0xf4 } },
368:
369: { PCMCIA_VENDOR_COREGA, PCMCIA_PRODUCT_COREGA_ETHER_PCC_TD,
370: PCMCIA_CIS_COREGA_ETHER_PCC_TD,
371: 0, -1, { 0x00, 0x00, 0xf4 } },
372:
373: { PCMCIA_VENDOR_COREGA, PCMCIA_PRODUCT_COREGA_ETHER_II_PCC_T,
374: PCMCIA_CIS_COREGA_ETHER_II_PCC_T,
375: 0, -1, { 0x00, 0x00, 0xf4 } },
376:
377: { PCMCIA_VENDOR_COREGA, PCMCIA_PRODUCT_COREGA_ETHER_II_PCC_TD,
378: PCMCIA_CIS_COREGA_ETHER_II_PCC_TD,
379: 0, -1, { 0x00, 0x00, 0xf4 } },
380:
381: { PCMCIA_VENDOR_COREGA, PCMCIA_PRODUCT_COREGA_FAST_ETHER_PCC_TX,
382: PCMCIA_CIS_COREGA_FAST_ETHER_PCC_TX,
383: 0, -1, { 0x00, 0x00, 0xf4 } },
384:
385: { PCMCIA_VENDOR_COREGA, PCMCIA_PRODUCT_COREGA_FETHER_PCC_TXF,
386: PCMCIA_CIS_COREGA_FETHER_PCC_TXF,
387: 0, -1, { 0x00, 0x90, 0x99 } },
388:
389: { PCMCIA_VENDOR_COREGA, PCMCIA_PRODUCT_COREGA_FETHER_PCC_TXD,
390: PCMCIA_CIS_COREGA_FETHER_PCC_TXD,
391: 0, -1, { 0x00, 0x90, 0x99 } },
392:
393: { PCMCIA_VENDOR_COMPEX, PCMCIA_PRODUCT_COMPEX_LINKPORT_ENET_B,
394: PCMCIA_CIS_COMPEX_LINKPORT_ENET_B,
395: 0, 0x01c0, { 0x00, 0xa0, 0x0c } },
396:
397: { PCMCIA_VENDOR_SMC, PCMCIA_PRODUCT_SMC_EZCARD,
398: PCMCIA_CIS_SMC_EZCARD,
399: 0, 0x01c0, { 0x00, 0xe0, 0x29 } },
400:
401: { PCMCIA_VENDOR_IODATA, PCMCIA_PRODUCT_IODATA_8041TX,
402: PCMCIA_CIS_IODATA_8041TX,
403: 0, -1, { 0x00, 0x04, 0xe2 } },
404:
405: { PCMCIA_VENDOR_SMC, PCMCIA_PRODUCT_SMC_8041,
406: PCMCIA_CIS_SMC_8041,
407: 0, -1, { 0x00, 0x04, 0xe2 } },
408:
409: { PCMCIA_VENDOR_SOCKET, PCMCIA_PRODUCT_SOCKET_LP_ETHER_CF,
410: PCMCIA_CIS_SOCKET_LP_ETHER_CF,
411: 0, -1, { 0x00, 0xc0, 0x1b} },
412:
413: { PCMCIA_VENDOR_SOCKET, PCMCIA_PRODUCT_SOCKET_LP_ETHER,
414: PCMCIA_CIS_SOCKET_LP_ETHER,
415: 0, -1, { 0x00, 0xc0, 0x1b } },
416:
417: { PCMCIA_VENDOR_SOCKET, PCMCIA_PRODUCT_SOCKET_ETHER_CF_10_100,
418: PCMCIA_CIS_SOCKET_ETHER_CF_10_100,
419: 0, -1, { 0x00, 0x12, 0x0e } },
420:
421: { PCMCIA_VENDOR_SOCKET, PCMCIA_PRODUCT_SOCKET_ETHER_CF_10_100,
422: PCMCIA_CIS_SOCKET_ETHER_CF_10_100,
423: 0, -1, { 0x00, 0xe0, 0x98 } },
424:
425: { PCMCIA_VENDOR_XIRCOM, PCMCIA_PRODUCT_XIRCOM_CFE_10,
426: PCMCIA_CIS_XIRCOM_CFE_10,
427: 0, -1, { 0x00, 0x10, 0xa4 } },
428:
429: { PCMCIA_VENDOR_MELCO, PCMCIA_PRODUCT_MELCO_LPC3_TX,
430: PCMCIA_CIS_MELCO_LPC3_TX,
431: 0, -1, { 0x00, 0x40, 0x26 }, NE2000DVF_AX88190 },
432:
433: { PCMCIA_VENDOR_BUFFALO, PCMCIA_PRODUCT_BUFFALO_LPC_CF_CLT,
434: PCMCIA_CIS_INVALID,
435: 0, -1, { 0x00, 0x07, 0x40 } },
436:
437: { PCMCIA_VENDOR_BUFFALO, PCMCIA_PRODUCT_BUFFALO_LPC3_CLT,
438: PCMCIA_CIS_INVALID,
439: 0, -1, { 0x00, 0x07, 0x40 } },
440:
441: { PCMCIA_VENDOR_BUFFALO, PCMCIA_PRODUCT_BUFFALO_LPC4_CLX,
442: PCMCIA_CIS_INVALID,
443: 0, -1, { 0x00, 0x40, 0xfa }, NE2000DVF_AX88190 },
444:
445: { PCMCIA_VENDOR_DUAL, PCMCIA_PRODUCT_DUAL_NE2000,
446: PCMCIA_CIS_DUAL_NE2000,
447: 0, 0x0ff0, { 0x00, 0xa0, 0x0c } },
448:
449: { PCMCIA_VENDOR_ALLIEDTELESIS, PCMCIA_PRODUCT_ALLIEDTELESIS_LA_PCM,
450: PCMCIA_CIS_ALLIEDTELESIS_LA_PCM,
451: 0, 0x0ff0, { 0x00, 0x00, 0xf4 } },
452:
453: { PCMCIA_VENDOR_KINGSTON, PCMCIA_PRODUCT_KINGSTON_KNE_PCM,
454: PCMCIA_CIS_KINGSTON_KNE_PCM,
455: 0, 0x0ff0, { 0xe2, 0x0c, 0x0f } },
456:
457: { PCMCIA_VENDOR_KINGSTON, PCMCIA_PRODUCT_KINGSTON_KNE_PC2,
458: PCMCIA_CIS_KINGSTON_KNE_PC2,
459: 0, 0x0180, { 0x00, 0xc0, 0xf0 } },
460:
461: { PCMCIA_VENDOR_TELECOMDEVICE, PCMCIA_PRODUCT_TELECOMDEVICE_TCD_HPC100,
462: PCMCIA_CIS_TELECOMDEVICE_TCD_HPC100,
463: 0, -1, { 0x00, 0x40, 0x26 }, NE2000DVF_AX88190 },
464:
465: { PCMCIA_VENDOR_MACNICA, PCMCIA_PRODUCT_MACNICA_ME1_JEIDA,
466: PCMCIA_CIS_MACNICA_ME1_JEIDA,
467: 0, 0x00b8, { 0x08, 0x00, 0x42 } },
468:
469: { PCMCIA_VENDOR_NETGEAR, PCMCIA_PRODUCT_NETGEAR_FA410TXC,
470: PCMCIA_CIS_NETGEAR_FA410TXC,
471: 0, -1, { 0x00, 0x40, 0xf4 } },
472:
473: { PCMCIA_VENDOR_NETGEAR, PCMCIA_PRODUCT_NETGEAR_FA410TXC,
474: PCMCIA_CIS_NETGEAR_FA410TXC,
475: 0, -1, { 0x00, 0x48, 0x54 } },
476:
477: { PCMCIA_VENDOR_NETGEAR, PCMCIA_PRODUCT_NETGEAR_FA410TXC,
478: PCMCIA_CIS_DLINK_DFE670TXD,
479: 0, -1, { 0x00, 0x40, 0x05 } },
480:
481: { PCMCIA_VENDOR_NETGEAR, PCMCIA_PRODUCT_NETGEAR_FA410TXC,
482: PCMCIA_CIS_DLINK_DFE670TXD,
483: 0, -1, { 0x00, 0x11, 0x95 } },
484:
485: { PCMCIA_VENDOR_NETGEAR, PCMCIA_PRODUCT_NETGEAR_FA410TXC,
486: PCMCIA_CIS_DLINK_DFE670TXD,
487: 0, -1, { 0x00, 0x0d, 0x88 } },
488:
489: { PCMCIA_VENDOR_NETGEAR, PCMCIA_PRODUCT_NETGEAR_FA411,
490: PCMCIA_CIS_NETGEAR_FA411,
491: 0, -1, { 0x00, 0x40, 0xf4 } },
492:
493: { PCMCIA_VENDOR_BELKIN, PCMCIA_PRODUCT_BELKIN_F5D5020,
494: PCMCIA_CIS_BELKIN_F5D5020,
495: 0, -1, { 0x00, 0x30, 0xbd } },
496:
497: #if 0
498: /* the rest of these are stolen from the linux pcnet pcmcia device
499: driver. Since I don't know the manfid or cis info strings for
500: any of them, they're not compiled in until I do. */
501: { "APEX MultiCard",
502: 0x0000, 0x0000, NULL, NULL, 0,
503: 0x03f4, { 0x00, 0x20, 0xe5 } },
504: { "ASANTE FriendlyNet",
505: 0x0000, 0x0000, NULL, NULL, 0,
506: 0x4910, { 0x00, 0x00, 0x94 } },
507: { "Danpex EN-6200P2",
508: 0x0000, 0x0000, NULL, NULL, 0,
509: 0x0110, { 0x00, 0x40, 0xc7 } },
510: { "DataTrek NetCard",
511: 0x0000, 0x0000, NULL, NULL, 0,
512: 0x0ff0, { 0x00, 0x20, 0xe8 } },
513: { "EP-210 Ethernet",
514: 0x0000, 0x0000, NULL, NULL, 0,
515: 0x0110, { 0x00, 0x40, 0x33 } },
516: { "ELECOM Laneed LD-CDWA",
517: 0x0000, 0x0000, NULL, NULL, 0,
518: 0x00b8, { 0x08, 0x00, 0x42 } },
519: { "Grey Cell GCS2220",
520: 0x0000, 0x0000, NULL, NULL, 0,
521: 0x0000, { 0x00, 0x47, 0x43 } },
522: { "Hypertec Ethernet",
523: 0x0000, 0x0000, NULL, NULL, 0,
524: 0x01c0, { 0x00, 0x40, 0x4c } },
525: { "IBM FME",
526: 0x0000, 0x0000, NULL, NULL, 0,
527: 0x0374, { 0x00, 0x04, 0xac } },
528: { "IBM FME",
529: 0x0000, 0x0000, NULL, NULL, 0,
530: 0x0374, { 0x08, 0x00, 0x5a } },
531: { "Katron PE-520",
532: 0x0000, 0x0000, NULL, NULL, 0,
533: 0x0110, { 0x00, 0x40, 0xf6 } },
534: { "Kingston KNE-PCM/x",
535: 0x0000, 0x0000, NULL, NULL, 0,
536: 0x0ff0, { 0x00, 0xc0, 0xf0 } },
537: { "Longshine LCS-8534",
538: 0x0000, 0x0000, NULL, NULL, 0,
539: 0x0000, { 0x08, 0x00, 0x00 } },
540: { "Maxtech PCN2000",
541: 0x0000, 0x0000, NULL, NULL, 0,
542: 0x5000, { 0x00, 0x00, 0xe8 } },
543: { "NDC Instant-Link",
544: 0x0000, 0x0000, NULL, NULL, 0,
545: 0x003a, { 0x00, 0x80, 0xc6 } },
546: { "Network General Sniffer",
547: 0x0000, 0x0000, NULL, NULL, 0,
548: 0x0ff0, { 0x00, 0x00, 0x65 } },
549: { "Panasonic VEL211",
550: 0x0000, 0x0000, NULL, NULL, 0,
551: 0x0ff0, { 0x00, 0x80, 0x45 } },
552: { "SCM Ethernet",
553: 0x0000, 0x0000, NULL, NULL, 0,
554: 0x0ff0, { 0x00, 0x20, 0xcb } },
555: { "Socket EA",
556: 0x0000, 0x0000, NULL, NULL, 0,
557: 0x4000, { 0x00, 0xc0, 0x1b } },
558: { "Volktek NPL-402CT",
559: 0x0000, 0x0000, NULL, NULL, 0,
560: 0x0060, { 0x00, 0x40, 0x05 } },
561: #endif
562: };
563:
564: #define NE2000_NDEVS (sizeof(ne2000devs) / sizeof(ne2000devs[0]))
565:
566: #define ne2000_match(card, fct, n) \
567: ((((((card)->manufacturer != PCMCIA_VENDOR_INVALID) && \
568: ((card)->manufacturer == ne2000devs[(n)].manufacturer) && \
569: ((card)->product != PCMCIA_PRODUCT_INVALID) && \
570: ((card)->product == ne2000devs[(n)].product)) || \
571: ((ne2000devs[(n)].cis_info[0]) && (ne2000devs[(n)].cis_info[1]) && \
572: ((card)->cis1_info[0]) && ((card)->cis1_info[1]) && \
573: (strcmp((card)->cis1_info[0], ne2000devs[(n)].cis_info[0]) == 0) && \
574: (strcmp((card)->cis1_info[1], ne2000devs[(n)].cis_info[1]) == 0))) && \
575: ((fct) == ne2000devs[(n)].function))? \
576: &ne2000devs[(n)]:NULL)
577:
578: int
579: ne_pcmcia_match(parent, match, aux)
580: struct device *parent;
581: void *match, *aux;
582: {
583: struct pcmcia_attach_args *pa = aux;
584: int i;
585:
586: for (i = 0; i < NE2000_NDEVS; i++) {
587: if (ne2000_match(pa->card, pa->pf->number, i))
588: return (1);
589: }
590:
591: return (0);
592: }
593:
594: void
595: ne_pcmcia_attach(parent, self, aux)
596: struct device *parent, *self;
597: void *aux;
598: {
599: struct ne_pcmcia_softc *psc = (void *) self;
600: struct ne2000_softc *nsc = &psc->sc_ne2000;
601: struct dp8390_softc *dsc = &nsc->sc_dp8390;
602: struct pcmcia_attach_args *pa = aux;
603: struct pcmcia_config_entry *cfe;
604: const struct ne2000dev *ne_dev;
605: const char *intrstr;
606: int i;
607: u_int8_t myea[6], *enaddr;
608:
609: psc->sc_pf = pa->pf;
610:
611: for (cfe = SIMPLEQ_FIRST(&pa->pf->cfe_head); cfe != NULL;
612: cfe = SIMPLEQ_NEXT(cfe, cfe_list)) {
613: #if 0
614: /*
615: * Some ne2000 driver's claim to have memory; others don't.
616: * Since I don't care, I don't check.
617: */
618:
619: if (cfe->num_memspace != 1) {
620: printf(": unexpected number of memory spaces, "
621: " %d should be 1\n", cfe->num_memspace);
622: return;
623: }
624: #endif
625:
626: if (cfe->num_iospace == 1) {
627: if (cfe->iospace[0].length != NE2000_NPORTS) {
628: printf(": unexpected I/O space "
629: "configuration\n");
630: continue;
631: }
632: } else if (cfe->num_iospace == 2) {
633: /*
634: * Some cards report a separate space for NIC and ASIC.
635: * This make some sense, but we must allocate a single
636: * NE2000_NPORTS-sized chunk, due to brain damaged
637: * address decoders on some of these cards.
638: */
639: if (cfe->iospace[0].length + cfe->iospace[1].length !=
640: NE2000_NPORTS) {
641: #ifdef DIAGNOSTIC
642: printf(": unexpected I/O space "
643: "configuration\n");
644: #endif
645: continue;
646: }
647: } else {
648: #ifdef DIAGNOSTIC
649: printf(": unexpected number of i/o spaces %d"
650: " should be 1 or 2\n", cfe->num_iospace);
651: #endif
652: continue;
653: }
654:
655: if (pcmcia_io_alloc(pa->pf, cfe->iospace[0].start,
656: NE2000_NPORTS, NE2000_NPORTS, &psc->sc_pcioh)) {
657: #ifdef DIAGNOSTIC
658: printf(": can't allocate I/O space\n");
659: #endif
660: continue;
661: }
662:
663: break;
664: }
665:
666: if (cfe == NULL) {
667: printf(": no suitable config entry\n");
668: goto fail_1;
669: }
670:
671: dsc->sc_regt = psc->sc_pcioh.iot;
672: dsc->sc_regh = psc->sc_pcioh.ioh;
673:
674: nsc->sc_asict = psc->sc_pcioh.iot;
675: if (bus_space_subregion(dsc->sc_regt, dsc->sc_regh,
676: NE2000_ASIC_OFFSET, NE2000_ASIC_NPORTS, &nsc->sc_asich)) {
677: printf(": can't get subregion for asic\n");
678: goto fail_2;
679: }
680:
681: #ifdef notyet
682: /* Set up power management hooks. */
683: dsc->sc_enable = ne_pcmcia_enable;
684: dsc->sc_disable = ne_pcmcia_disable;
685: #endif
686:
687: /* Enable the card. */
688: pcmcia_function_init(pa->pf, cfe);
689: if (pcmcia_function_enable(pa->pf)) {
690: printf(": function enable failed\n");
691: goto fail_2;
692: }
693:
694: dsc->sc_enabled = 1;
695:
696: /* some cards claim to be io16, but they're lying. */
697: if (pcmcia_io_map(pa->pf, PCMCIA_WIDTH_IO8, NE2000_NIC_OFFSET,
698: NE2000_NIC_NPORTS, &psc->sc_pcioh, &psc->sc_nic_io_window)) {
699: printf(": can't map NIC I/O space\n");
700: goto fail_3;
701: }
702:
703: if (pcmcia_io_map(pa->pf, PCMCIA_WIDTH_IO16, NE2000_ASIC_OFFSET,
704: NE2000_ASIC_NPORTS, &psc->sc_pcioh, &psc->sc_asic_io_window)) {
705: printf(": can't map ASIC I/O space\n");
706: goto fail_4;
707: }
708:
709: printf(" port 0x%lx/%d", psc->sc_pcioh.addr, NE2000_NPORTS);
710:
711: /*
712: * Read the station address from the board.
713: */
714: i = 0;
715: again:
716: enaddr = NULL; /* Ask ASIC by default */
717: for (; i < NE2000_NDEVS; i++) {
718: ne_dev = ne2000_match(pa->card, pa->pf->number, i);
719: if (ne_dev != NULL) {
720: if (ne_dev->enet_maddr >= 0) {
721: enaddr = ne_pcmcia_get_enaddr(psc,
722: ne_dev->enet_maddr, myea);
723: if (enaddr == NULL)
724: continue;
725: } else {
726: enaddr = ne_pcmcia_dl10019_get_enaddr(psc,
727: myea);
728: }
729: break;
730: }
731: }
732: if (i == NE2000_NDEVS) {
733: printf(": can't match ethernet vendor code\n");
734: goto fail_5;
735: }
736:
737: if (enaddr != NULL) {
738: /*
739: * Make sure this is what we expect.
740: */
741: if (enaddr[0] != ne_dev->enet_vendor[0] ||
742: enaddr[1] != ne_dev->enet_vendor[1] ||
743: enaddr[2] != ne_dev->enet_vendor[2]) {
744: ++i;
745: goto again;
746: }
747: }
748:
749: if ((ne_dev->flags & NE2000DVF_AX88190) != 0) {
750: if (ne_pcmcia_ax88190_set_iobase(psc))
751: goto fail_5;
752:
753: dsc->sc_mediachange = ax88190_mediachange;
754: dsc->sc_mediastatus = ax88190_mediastatus;
755: dsc->init_card = ax88190_init_card;
756: dsc->stop_card = ax88190_stop_card;
757: dsc->sc_media_init = ax88190_media_init;
758: dsc->sc_media_fini = ax88190_media_fini;
759:
760: nsc->sc_type = NE2000_TYPE_AX88190;
761: }
762:
763: /*
764: * Check for a RealTek 8019.
765: */
766: bus_space_write_1(dsc->sc_regt, dsc->sc_regh, ED_P0_CR,
767: ED_CR_PAGE_0 | ED_CR_STP);
768: if (bus_space_read_1(dsc->sc_regt, dsc->sc_regh, NERTL_RTL0_8019ID0)
769: == RTL0_8019ID0 &&
770: bus_space_read_1(dsc->sc_regt, dsc->sc_regh, NERTL_RTL0_8019ID1)
771: == RTL0_8019ID1) {
772: dsc->sc_mediachange = rtl80x9_mediachange;
773: dsc->sc_mediastatus = rtl80x9_mediastatus;
774: dsc->init_card = rtl80x9_init_card;
775: dsc->sc_media_init = rtl80x9_media_init;
776: }
777:
778: if (nsc->sc_type == NE2000_TYPE_DL10019 ||
779: nsc->sc_type == NE2000_TYPE_DL10022) {
780: dsc->sc_mediachange = dl10019_mediachange;
781: dsc->sc_mediastatus = dl10019_mediastatus;
782: dsc->init_card = dl10019_init_card;
783: dsc->stop_card = dl10019_stop_card;
784: dsc->sc_media_init = dl10019_media_init;
785: dsc->sc_media_fini = dl10019_media_fini;
786: }
787:
788: /* set up the interrupt */
789: psc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET, dp8390_intr,
790: dsc, dsc->sc_dev.dv_xname);
791: intrstr = pcmcia_intr_string(psc->sc_pf, psc->sc_ih);
792: if (*intrstr)
793: printf(", %s", intrstr);
794:
795: if (ne2000_attach(nsc, enaddr))
796: goto fail_5;
797:
798: #if notyet
799: pcmcia_function_disable(pa->pf);
800: #endif
801: return;
802:
803: fail_5:
804: /* Unmap ASIC I/O windows. */
805: pcmcia_io_unmap(psc->sc_pf, psc->sc_asic_io_window);
806:
807: fail_4:
808: /* Unmap NIC I/O windows. */
809: pcmcia_io_unmap(psc->sc_pf, psc->sc_nic_io_window);
810:
811: fail_3:
812: pcmcia_function_disable(pa->pf);
813:
814: fail_2:
815: /* Free our I/O space. */
816: pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
817:
818: fail_1:
819: psc->sc_nic_io_window = -1;
820: }
821:
822: int
823: ne_pcmcia_detach(dev, flags)
824: struct device *dev;
825: int flags;
826: {
827: struct ne_pcmcia_softc *psc = (struct ne_pcmcia_softc *)dev;
828: int error;
829:
830: if (psc->sc_nic_io_window == -1)
831: /* Nothing to detach. */
832: return (0);
833:
834: error = ne2000_detach(&psc->sc_ne2000, flags);
835: if (error != 0)
836: return (error);
837:
838: /* Unmap our i/o windows. */
839: pcmcia_io_unmap(psc->sc_pf, psc->sc_asic_io_window);
840: pcmcia_io_unmap(psc->sc_pf, psc->sc_nic_io_window);
841:
842: /* Free our i/o space. */
843: pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
844:
845: return (0);
846: }
847:
848: int
849: ne_pcmcia_activate(dev, act)
850: struct device *dev;
851: enum devact act;
852: {
853: struct ne_pcmcia_softc *sc = (struct ne_pcmcia_softc *)dev;
854: struct dp8390_softc *esc = &sc->sc_ne2000.sc_dp8390;
855: struct ifnet *ifp = &esc->sc_arpcom.ac_if;
856: int s;
857:
858: s = splnet();
859: switch (act) {
860: case DVACT_ACTIVATE:
861: pcmcia_function_enable(sc->sc_pf);
862: sc->sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_NET,
863: dp8390_intr, sc, esc->sc_dev.dv_xname);
864: dp8390_init(esc);
865: break;
866:
867: case DVACT_DEACTIVATE:
868: ifp->if_timer = 0;
869: if (ifp->if_flags & IFF_RUNNING)
870: dp8390_stop(esc);
871: if (sc->sc_ih != NULL) {
872: pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
873: sc->sc_ih = NULL;
874: }
875: pcmcia_function_disable(sc->sc_pf);
876: break;
877: }
878: splx(s);
879: return (0);
880: }
881:
882: #ifdef notyet
883: int
884: ne_pcmcia_enable(dsc)
885: struct dp8390_softc *dsc;
886: {
887: struct ne_pcmcia_softc *psc = (struct ne_pcmcia_softc *)dsc;
888:
889: /* set up the interrupt */
890: psc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET, dp8390_intr,
891: dsc, dsc->sc_dev.dv_xname);
892: if (psc->sc_ih == NULL) {
893: printf("%s: couldn't establish interrupt\n",
894: dsc->sc_dev.dv_xname);
895: return (1);
896: }
897:
898: return (pcmcia_function_enable(psc->sc_pf));
899: }
900:
901: void
902: ne_pcmcia_disable(dsc)
903: struct dp8390_softc *dsc;
904: {
905: struct ne_pcmcia_softc *psc = (struct ne_pcmcia_softc *)dsc;
906:
907: pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih);
908: pcmcia_function_disable(psc->sc_pf);
909: }
910: #endif
911:
912: u_int8_t *
913: ne_pcmcia_get_enaddr(psc, maddr, myea)
914: struct ne_pcmcia_softc *psc;
915: int maddr;
916: u_int8_t myea[ETHER_ADDR_LEN];
917: {
918: struct ne2000_softc *nsc = &psc->sc_ne2000;
919: struct dp8390_softc *dsc = &nsc->sc_dp8390;
920: struct pcmcia_mem_handle pcmh;
921: bus_size_t offset;
922: u_int8_t *enaddr = NULL;
923: int j, mwindow;
924:
925: if (maddr < 0)
926: return (NULL);
927:
928: if (pcmcia_mem_alloc(psc->sc_pf, ETHER_ADDR_LEN * 2, &pcmh)) {
929: printf("%s: can't alloc mem for enet addr\n",
930: dsc->sc_dev.dv_xname);
931: goto fail_1;
932: }
933: if (pcmcia_mem_map(psc->sc_pf, PCMCIA_MEM_ATTR, maddr,
934: ETHER_ADDR_LEN * 2, &pcmh, &offset, &mwindow)) {
935: printf("%s: can't map mem for enet addr\n",
936: dsc->sc_dev.dv_xname);
937: goto fail_2;
938: }
939: for (j = 0; j < ETHER_ADDR_LEN; j++)
940: myea[j] = bus_space_read_1(pcmh.memt, pcmh.memh,
941: offset + (j * 2));
942: enaddr = myea;
943:
944: pcmcia_mem_unmap(psc->sc_pf, mwindow);
945: fail_2:
946: pcmcia_mem_free(psc->sc_pf, &pcmh);
947: fail_1:
948: return (enaddr);
949: }
950:
951: u_int8_t *
952: ne_pcmcia_dl10019_get_enaddr(psc, myea)
953: struct ne_pcmcia_softc *psc;
954: u_int8_t myea[ETHER_ADDR_LEN];
955: {
956: struct ne2000_softc *nsc = &psc->sc_ne2000;
957: u_int8_t sum;
958: int j, type;
959:
960: for (j = 0, sum = 0; j < 8; j++) {
961: sum += bus_space_read_1(nsc->sc_asict, nsc->sc_asich,
962: 0x04 + j);
963: }
964: if (sum != 0xff)
965: return (NULL);
966:
967: for (j = 0; j < ETHER_ADDR_LEN; j++) {
968: myea[j] = bus_space_read_1(nsc->sc_asict,
969: nsc->sc_asich, 0x04 + j);
970: }
971:
972: /* XXX - magic values from Linux */
973: type = bus_space_read_1(nsc->sc_asict, nsc->sc_asich, 0x0f);
974: if (type == 0x91 || type == 0x99)
975: nsc->sc_type = NE2000_TYPE_DL10022;
976: else
977: nsc->sc_type = NE2000_TYPE_DL10019;
978:
979: return (myea);
980: }
981:
982: int
983: ne_pcmcia_ax88190_set_iobase(psc)
984: struct ne_pcmcia_softc *psc;
985: {
986: struct ne2000_softc *nsc = &psc->sc_ne2000;
987: struct dp8390_softc *dsc = &nsc->sc_dp8390;
988: struct pcmcia_mem_handle pcmh;
989: bus_size_t offset;
990: int rv = 1, mwindow;
991:
992: if (pcmcia_mem_alloc(psc->sc_pf, AX88190_LAN_IOSIZE, &pcmh)) {
993: printf("%s: can't alloc mem for LAN iobase\n",
994: dsc->sc_dev.dv_xname);
995: goto fail_1;
996: }
997: if (pcmcia_mem_map(psc->sc_pf, PCMCIA_MEM_ATTR,
998: AX88190_LAN_IOBASE, AX88190_LAN_IOSIZE, &pcmh, &offset,
999: &mwindow)) {
1000: printf("%s: can't map mem for LAN iobase\n",
1001: dsc->sc_dev.dv_xname);
1002: goto fail_2;
1003: }
1004:
1005: #ifdef NE_DEBUG
1006: printf(": LAN iobase 0x%x (0x%x) ->",
1007: bus_space_read_1(pcmh.memt, pcmh.memh, offset + 0) |
1008: bus_space_read_1(pcmh.memt, pcmh.memh, offset + 2) << 8,
1009: (u_int)psc->sc_pcioh.addr);
1010: #endif
1011: bus_space_write_1(pcmh.memt, pcmh.memh, offset,
1012: psc->sc_pcioh.addr & 0xff);
1013: bus_space_write_1(pcmh.memt, pcmh.memh, offset + 2,
1014: psc->sc_pcioh.addr >> 8);
1015: #ifdef NE_DEBUG
1016: printf(" 0x%x", bus_space_read_1(pcmh.memt, pcmh.memh, offset + 0) |
1017: bus_space_read_1(pcmh.memt, pcmh.memh, offset + 2) << 8);
1018: #endif
1019: rv = 0;
1020:
1021: pcmcia_mem_unmap(psc->sc_pf, mwindow);
1022: fail_2:
1023: pcmcia_mem_free(psc->sc_pf, &pcmh);
1024: fail_1:
1025: return (rv);
1026: }
CVSweb