2 * Copyright (c) 2002 Takeshi Shibagaki
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * xe pccard interface driver
28 * $FreeBSD: src/sys/dev/xe/if_xe_pccard.c,v 1.11 2003/10/14 22:51:35 rsm Exp $
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/kernel.h>
34 #include <sys/socket.h>
35 #include <sys/module.h>
39 #include <net/ethernet.h>
41 #include <net/if_arp.h>
42 #include <net/if_media.h>
43 #include <net/if_mib.h>
45 #include <bus/pccard/pccardvar.h>
46 #include <bus/pccard/pccarddevs.h>
55 #define DEVPRINTF(level, arg) if (xe_debug >= (level)) device_printf arg
57 #define DEVPRINTF(level, arg)
60 static const struct pccard_product xe_pccard_products[] = {
61 PCMCIA_CARD(COMPAQ, CPQ550, 0),
62 PCMCIA_CARD(COMPAQ2, CPQ_10_100, 0),
63 PCMCIA_CARD(INTEL, EEPRO100, 0),
64 PCMCIA_CARD(RACORE, ACCTON_EN2226, 0),
65 PCMCIA_CARD(XIRCOM, CE, 0),
66 PCMCIA_CARD(XIRCOM, CE2, 0),
67 PCMCIA_CARD(XIRCOM, CE3, 0),
68 PCMCIA_CARD(XIRCOM, CEM, 0),
69 PCMCIA_CARD(XIRCOM, CEM28, 0),
70 PCMCIA_CARD(XIRCOM, CEM33, 0),
71 PCMCIA_CARD(XIRCOM, CEM56, 0),
72 PCMCIA_CARD(XIRCOM, REM56, 0),
73 PCMCIA_CARD(XIRCOM, CNW_801, 0),
74 PCMCIA_CARD(XIRCOM, CNW_802, 0),
80 const char *vendor_desc;
82 { PCMCIA_VENDOR_XIRCOM, "Xircom" },
83 { PCMCIA_VENDOR_COMPAQ, "Compaq" },
84 { PCMCIA_VENDOR_COMPAQ2, "Compaq" },
85 { PCMCIA_VENDOR_INTEL, "Intel" },
89 #define XE_CARD_TYPE_FLAGS_NO 0x0
90 #define XE_CARD_TYPE_FLAGS_CE2 0x1
91 #define XE_CARD_TYPE_FLAGS_MOHAWK 0x2
92 #define XE_CARD_TYPE_FLAGS_DINGO 0x4
94 #define XE_PROD_UMASK 0x11000f
95 #define XE_PROD_ETHER_UMASK 0x010000
96 #define XE_PROD_MODEM_UMASK 0x100000
97 #define XE_PROD_SINGLE_ID1 0x010001
98 #define XE_PROD_SINGLE_ID2 0x010002
99 #define XE_PROD_SINGLE_ID3 0x010003
100 #define XE_PROD_MULTI_ID1 0x110001
101 #define XE_PROD_MULTI_ID2 0x110002
102 #define XE_PROD_MULTI_ID3 0x110003
103 #define XE_PROD_MULTI_ID4 0x110004
104 #define XE_PROD_MULTI_ID5 0x110005
105 #define XE_PROD_MULTI_ID6 0x110006
106 #define XE_PROD_MULTI_ID7 0x110007
108 struct xe_card_type {
110 const char *card_type_desc;
112 } xe_card_types[] = {
113 { XE_PROD_MULTI_ID1, "CEM", XE_CARD_TYPE_FLAGS_NO },
114 { XE_PROD_MULTI_ID2, "CEM2", XE_CARD_TYPE_FLAGS_CE2 },
115 { XE_PROD_MULTI_ID3, "CEM3", XE_CARD_TYPE_FLAGS_CE2 },
116 { XE_PROD_MULTI_ID4, "CEM33", XE_CARD_TYPE_FLAGS_CE2 },
117 { XE_PROD_MULTI_ID5, "CEM56M", XE_CARD_TYPE_FLAGS_MOHAWK },
118 { XE_PROD_MULTI_ID6, "CEM56", XE_CARD_TYPE_FLAGS_MOHAWK |
119 XE_CARD_TYPE_FLAGS_DINGO },
120 { XE_PROD_MULTI_ID7, "CEM56", XE_CARD_TYPE_FLAGS_MOHAWK |
121 XE_CARD_TYPE_FLAGS_DINGO },
122 { XE_PROD_SINGLE_ID1, "CE", XE_CARD_TYPE_FLAGS_NO },
123 { XE_PROD_SINGLE_ID2, "CE2", XE_CARD_TYPE_FLAGS_CE2 },
124 { XE_PROD_SINGLE_ID3, "CE3", XE_CARD_TYPE_FLAGS_MOHAWK },
128 static struct xe_vendor *xe_vendor_lookup (uint32_t);
129 static struct xe_card_type *xe_card_type_lookup (uint32_t);
131 static int xe_cemfix (device_t);
132 static int xe_pccard_probe (device_t);
133 static int xe_pccard_match (device_t);
134 static int xe_pccard_attach(device_t);
136 static device_method_t xe_pccard_methods[] = {
137 /* Device interface */
138 DEVMETHOD(device_probe, pccard_compat_probe),
139 DEVMETHOD(device_attach, pccard_compat_attach),
140 DEVMETHOD(device_detach, xe_detach),
143 DEVMETHOD(card_compat_match, xe_pccard_match),
144 DEVMETHOD(card_compat_probe, xe_pccard_probe),
145 DEVMETHOD(card_compat_attach, xe_pccard_attach),
150 static driver_t xe_pccard_driver = {
153 sizeof(struct xe_softc),
156 devclass_t xe_devclass;
157 DRIVER_MODULE(xe, pccard, xe_pccard_driver, xe_devclass, NULL, NULL);
160 * Fixing for CEM2, CEM3 and CEM56/REM56 cards. These need some magic to
161 * enable the Ethernet function, which isn't mentioned anywhere in the CIS.
162 * Despite the register names, most of this isn't Dingo-specific.
165 xe_cemfix(device_t dev)
167 struct xe_softc *sc = device_get_softc(dev);
169 bus_space_handle_t bsh;
174 device_printf(dev, "CEM I/O port 0x%0lx, size 0x%0lx\n",
175 bus_get_resource_start(dev, SYS_RES_IOPORT, sc->port_rid),
176 bus_get_resource_count(dev, SYS_RES_IOPORT, sc->port_rid));
179 r = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0,
180 ~0, 4 << 10, RF_ACTIVE);
182 device_printf(dev, "Can't map in attribute memory\n");
186 bsh = rman_get_bushandle(r);
187 bst = rman_get_bustag(r);
189 CARD_SET_RES_FLAGS(device_get_parent(dev), dev, SYS_RES_MEMORY, rid,
192 bus_space_write_1(bst, bsh, DINGO_ECOR, DINGO_ECOR_IRQ_LEVEL |
193 DINGO_ECOR_INT_ENABLE |
194 DINGO_ECOR_IOB_ENABLE |
195 DINGO_ECOR_ETH_ENABLE);
196 ioport = bus_get_resource_start(dev, SYS_RES_IOPORT, sc->port_rid);
197 bus_space_write_1(bst, bsh, DINGO_EBAR0, ioport & 0xff);
198 bus_space_write_1(bst, bsh, DINGO_EBAR1, (ioport >> 8) & 0xff);
201 bus_space_write_1(bst, bsh, DINGO_DCOR0, DINGO_DCOR0_SF_INT);
202 bus_space_write_1(bst, bsh, DINGO_DCOR1,
203 DINGO_DCOR1_INT_LEVEL | DINGO_DCOR1_EEDIO);
204 bus_space_write_1(bst, bsh, DINGO_DCOR2, 0x00);
205 bus_space_write_1(bst, bsh, DINGO_DCOR3, 0x00);
206 bus_space_write_1(bst, bsh, DINGO_DCOR4, 0x00);
209 bus_release_resource(dev, SYS_RES_MEMORY, rid, r);
215 static struct xe_vendor *
216 xe_vendor_lookup(uint32_t vendor_id)
220 for (v = xe_vendors; v->vendor_id != 0; ++v) {
221 if(v->vendor_id == vendor_id)
227 static struct xe_card_type *
228 xe_card_type_lookup(uint32_t prod)
230 struct xe_card_type *ct;
232 for (ct = xe_card_types; ct->card_type_desc != NULL; ++ct) {
233 if(ct->prod_type == (prod & XE_PROD_UMASK))
240 * PCMCIA probe routine.
241 * Identify the device. Called from the bus driver when the card is
242 * inserted or otherwise powers up.
245 xe_pccard_probe(device_t dev)
247 struct xe_softc *scp = device_get_softc(dev);
248 uint32_t vendor, product, prod;
250 const uint8_t *ether_addr;
251 const char *cis3_str=NULL;
252 struct xe_vendor *vendor_itm;
253 struct xe_card_type *card_itm;
257 const char *vendor_str = NULL;
258 const char *product_str = NULL;
259 const char *cis4_str = NULL;
261 vendor = pccard_get_vendor(dev);
262 product = pccard_get_product(dev);
263 prodext = pccard_get_prodext(dev);
264 vendor_str = pccard_get_vendor_str(dev);
265 product_str = pccard_get_product_str(dev);
266 cis3_str = pccard_get_cis3_str(dev);
267 cis4_str = pccard_get_cis4_str(dev);
269 DEVPRINTF(1, (dev, "pccard_probe\n"));
270 DEVPRINTF(1, (dev, "vendor = 0x%04x\n", vendor));
271 DEVPRINTF(1, (dev, "product = 0x%04x\n", product));
272 DEVPRINTF(1, (dev, "prodext = 0x%02x\n", prodext));
273 DEVPRINTF(1, (dev, "vendor_str = %s\n",
274 vendor_str == NULL ? "NULL" : vendor_str));
275 DEVPRINTF(1, (dev, "product_str = %s\n",
276 product_str == NULL ? "NULL" : product_str));
277 DEVPRINTF(1, (dev, "cis3_str = %s\n",
278 cis3_str == NULL ? "NULL" : cis3_str));
279 DEVPRINTF(1, (dev, "cis4_str = %s\n",
280 cis4_str == NULL ? "NULL" : cis4_str));
284 * PCCARD_CISTPL_MANFID = 0x20
286 vendor = pccard_get_vendor(dev);
287 vendor_itm = xe_vendor_lookup(vendor);
289 * We always have some vendor here, although
290 * vendor description may be "Unknown".
292 scp->vendor = vendor_itm->vendor_desc;
294 product = pccard_get_product(dev);
295 prodext = pccard_get_prodext(dev);
298 * prod(new) = rev, media, prod(old)
299 * prod(new) = (don't care), (care 0x10 bit), (care 0x0f bit)
301 prod = (product << 8) | prodext;
302 card_itm = xe_card_type_lookup(prod);
303 if (card_itm == NULL)
306 scp->card_type = card_itm->card_type_desc;
307 if (card_itm->prod_type & XE_PROD_MODEM_UMASK)
310 for (i = 1; i != XE_CARD_TYPE_FLAGS_DINGO; i = i << 1) {
311 switch(i & card_itm->flags) {
312 case XE_CARD_TYPE_FLAGS_CE2:
315 case XE_CARD_TYPE_FLAGS_MOHAWK:
318 case XE_CARD_TYPE_FLAGS_DINGO:
325 * PCCARD_CISTPL_VERS_1 = 0x15
327 * Check for certain strange CE2's that look like CE's:
328 * match 3rd version string against "CE2"
330 cis3_str = pccard_get_cis3_str(dev);
331 if (strcmp(scp->card_type, "CE") == 0)
332 if (cis3_str != NULL && strcmp(cis3_str, "PS-CE2-10") == 0)
333 scp->card_type = "CE2";
336 * PCCARD_CISTPL_FUNCE = 0x22
338 ether_addr = pccard_get_ether(dev);
339 bcopy(ether_addr, scp->arpcom.ac_enaddr, ETHER_ADDR_LEN);
341 /* Reject unsupported cards */
342 if (strcmp(scp->card_type, "CE") == 0 ||
343 strcmp(scp->card_type, "CEM") == 0) {
344 device_printf(dev, "Sorry, your %s card is not supported :(\n",
354 xe_pccard_attach(device_t dev)
356 struct xe_softc *scp = device_get_softc(dev);
359 if ((err = xe_activate(dev)) != 0)
362 /* Hack RealPorts into submission */
363 if (scp->modem && xe_cemfix(dev) < 0) {
364 device_printf(dev, "Unable to fix your %s combo card\n",
369 return xe_attach(dev);
373 xe_pccard_match(device_t dev)
375 const struct pccard_product *pp;
377 if ((pp = pccard_product_lookup(dev, xe_pccard_products,
378 sizeof(xe_pccard_products[0]), NULL)) != NULL) {
379 if (pp->pp_name != NULL)
380 device_set_desc(dev, pp->pp_name);