This source file includes following definitions.
- wi_lookup
- wi_pcmcia_match
- wi_pcmcia_attach
- wi_pcmcia_detach
- wi_pcmcia_activate
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
41
42
43
44
45
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/timeout.h>
49 #include <sys/socket.h>
50 #include <sys/device.h>
51 #include <sys/tree.h>
52
53 #include <net/if.h>
54 #include <net/if_dl.h>
55 #include <net/if_media.h>
56
57 #ifdef INET
58 #include <netinet/in.h>
59 #include <netinet/if_ether.h>
60 #endif
61
62 #include <net80211/ieee80211_var.h>
63 #include <net80211/ieee80211_ioctl.h>
64
65 #include <machine/bus.h>
66
67 #include <dev/pcmcia/pcmciareg.h>
68 #include <dev/pcmcia/pcmciavar.h>
69 #include <dev/pcmcia/pcmciadevs.h>
70
71 #include <dev/ic/if_wireg.h>
72 #include <dev/ic/if_wi_ieee.h>
73 #include <dev/ic/if_wivar.h>
74
75 int wi_pcmcia_match(struct device *, void *, void *);
76 void wi_pcmcia_attach(struct device *, struct device *, void *);
77 int wi_pcmcia_detach(struct device *, int);
78 int wi_pcmcia_activate(struct device *, enum devact);
79
80 struct wi_pcmcia_softc {
81 struct wi_softc sc_wi;
82
83 struct pcmcia_io_handle sc_pcioh;
84 int sc_io_window;
85 struct pcmcia_function *sc_pf;
86 };
87
88 struct cfattach wi_pcmcia_ca = {
89 sizeof (struct wi_pcmcia_softc), wi_pcmcia_match, wi_pcmcia_attach,
90 wi_pcmcia_detach, wi_pcmcia_activate
91 };
92
93 static const struct wi_pcmcia_product {
94 u_int16_t pp_vendor;
95 u_int16_t pp_product;
96 const char *pp_cisinfo[4];
97 } wi_pcmcia_products[] = {
98 { PCMCIA_VENDOR_LUCENT,
99 PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE,
100 PCMCIA_CIS_LUCENT_WAVELAN_IEEE
101 },
102 { PCMCIA_VENDOR_3COM,
103 PCMCIA_PRODUCT_3COM_3CRWE737A,
104 PCMCIA_CIS_3COM_3CRWE737A
105 },
106 { PCMCIA_VENDOR_3COM,
107 PCMCIA_PRODUCT_3COM_3CRWE777A,
108 PCMCIA_CIS_3COM_3CRWE777A
109 },
110 { PCMCIA_VENDOR_COREGA,
111 PCMCIA_PRODUCT_COREGA_WIRELESS_LAN_PCC_11,
112 PCMCIA_CIS_COREGA_WIRELESS_LAN_PCC_11
113 },
114 { PCMCIA_VENDOR_COREGA,
115 PCMCIA_PRODUCT_COREGA_WIRELESS_LAN_PCCA_11,
116 PCMCIA_CIS_COREGA_WIRELESS_LAN_PCCA_11
117 },
118 { PCMCIA_VENDOR_COREGA,
119 PCMCIA_PRODUCT_COREGA_WIRELESS_LAN_PCCB_11,
120 PCMCIA_CIS_COREGA_WIRELESS_LAN_PCCB_11
121 },
122 { PCMCIA_VENDOR_COREGA,
123 PCMCIA_PRODUCT_COREGA_WIRELESS_LAN_PCCL_11,
124 PCMCIA_CIS_COREGA_WIRELESS_LAN_PCCL_11
125 },
126 { PCMCIA_VENDOR_COREGA,
127 PCMCIA_PRODUCT_COREGA_WIRELESS_LAN_WLCFL_11,
128 PCMCIA_CIS_COREGA_WIRELESS_LAN_WLCFL_11
129 },
130 { PCMCIA_VENDOR_INTEL,
131 PCMCIA_PRODUCT_INTEL_PRO_WLAN_2011,
132 PCMCIA_CIS_INTEL_PRO_WLAN_2011
133 },
134 { PCMCIA_VENDOR_INTERSIL,
135 PCMCIA_PRODUCT_INTERSIL_PRISM2,
136 PCMCIA_CIS_INTERSIL_PRISM2
137 },
138 { PCMCIA_VENDOR_SAMSUNG,
139 PCMCIA_PRODUCT_SAMSUNG_SWL_2000N,
140 PCMCIA_CIS_SAMSUNG_SWL_2000N
141 },
142 { PCMCIA_VENDOR_LINKSYS2,
143 PCMCIA_PRODUCT_LINKSYS2_IWN,
144 PCMCIA_CIS_LINKSYS2_IWN
145 },
146 { PCMCIA_VENDOR_LINKSYS2,
147 PCMCIA_PRODUCT_LINKSYS2_IWN2,
148 PCMCIA_CIS_LINKSYS2_IWN2
149 },
150 { PCMCIA_VENDOR_LINKSYS2,
151 PCMCIA_PRODUCT_LINKSYS2_WCF11,
152 PCMCIA_CIS_LINKSYS2_WCF11
153 },
154 { PCMCIA_VENDOR_LUCENT,
155 PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE,
156 PCMCIA_CIS_SMC_2632W
157 },
158 { PCMCIA_VENDOR_LUCENT,
159 PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE,
160 PCMCIA_CIS_NANOSPEED_PRISM2
161 },
162 { PCMCIA_VENDOR_ELSA,
163 PCMCIA_PRODUCT_ELSA_XI300_IEEE,
164 PCMCIA_CIS_ELSA_XI300_IEEE
165 },
166 { PCMCIA_VENDOR_ELSA,
167 PCMCIA_PRODUCT_ELSA_XI325_IEEE,
168 PCMCIA_CIS_ELSA_XI325_IEEE
169 },
170 { PCMCIA_VENDOR_ELSA,
171 PCMCIA_PRODUCT_ELSA_WNB11CFZ,
172 PCMCIA_CIS_ELSA_WNB11CFZ
173 },
174 { PCMCIA_VENDOR_COMPAQ,
175 PCMCIA_PRODUCT_COMPAQ_NC5004,
176 PCMCIA_CIS_COMPAQ_NC5004
177 },
178 { PCMCIA_VENDOR_CONTEC,
179 PCMCIA_PRODUCT_CONTEC_FX_DS110_PCC,
180 PCMCIA_CIS_CONTEC_FX_DS110_PCC
181 },
182 { PCMCIA_VENDOR_TDK,
183 PCMCIA_PRODUCT_TDK_LAK_CD011WL,
184 PCMCIA_CIS_TDK_LAK_CD011WL
185 },
186 { PCMCIA_VENDOR_LUCENT,
187 PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE,
188 PCMCIA_CIS_NEC_CMZ_RT_WP
189 },
190 { PCMCIA_VENDOR_LUCENT,
191 PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE,
192 PCMCIA_CIS_NTT_ME_WLAN
193 },
194 { PCMCIA_VENDOR_ADDTRON,
195 PCMCIA_PRODUCT_ADDTRON_AWP100,
196 PCMCIA_CIS_ADDTRON_AWP100
197 },
198 { PCMCIA_VENDOR_LUCENT,
199 PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE,
200 PCMCIA_CIS_CABLETRON_ROAMABOUT
201 },
202 { PCMCIA_VENDOR_IODATA2,
203 PCMCIA_PRODUCT_IODATA2_WCF12,
204 PCMCIA_CIS_IODATA2_WCF12
205 },
206 { PCMCIA_VENDOR_IODATA2,
207 PCMCIA_PRODUCT_IODATA2_WNB11PCM,
208 PCMCIA_CIS_IODATA2_WNB11PCM
209 },
210 { PCMCIA_VENDOR_GEMTEK,
211 PCMCIA_PRODUCT_GEMTEK_WLAN,
212 PCMCIA_CIS_GEMTEK_WLAN
213 },
214 { PCMCIA_VENDOR_ELSA,
215 PCMCIA_PRODUCT_ELSA_XI800_IEEE,
216 PCMCIA_CIS_ELSA_XI800_IEEE
217 },
218 { PCMCIA_VENDOR_BUFFALO,
219 PCMCIA_PRODUCT_BUFFALO_WLI_PCM_S11,
220 PCMCIA_CIS_BUFFALO_WLI_PCM_S11
221 },
222 { PCMCIA_VENDOR_BUFFALO,
223 PCMCIA_PRODUCT_BUFFALO_WLI_CF_S11G,
224 PCMCIA_CIS_BUFFALO_WLI_CF_S11G
225 },
226 { PCMCIA_VENDOR_EMTAC,
227 PCMCIA_PRODUCT_EMTAC_WLAN,
228 PCMCIA_CIS_EMTAC_WLAN
229 },
230 { PCMCIA_VENDOR_SIMPLETECH,
231 PCMCIA_PRODUCT_SIMPLETECH_SPECTRUM24_ALT,
232 PCMCIA_CIS_SIMPLETECH_SPECTRUM24_ALT
233 },
234 { PCMCIA_VENDOR_ERICSSON,
235 PCMCIA_PRODUCT_ERICSSON_WIRELESSLAN,
236 PCMCIA_CIS_ERICSSON_WIRELESSLAN
237 },
238 { PCMCIA_VENDOR_PROXIM,
239 PCMCIA_PRODUCT_PROXIM_RANGELANDS_8430,
240 PCMCIA_CIS_PROXIM_RANGELANDS_8430
241 },
242 { PCMCIA_VENDOR_ACTIONTEC,
243 PCMCIA_PRODUCT_ACTIONTEC_HWC01170,
244 PCMCIA_CIS_ACTIONTEC_HWC01170
245 },
246 { PCMCIA_VENDOR_NOKIA,
247 PCMCIA_PRODUCT_NOKIA_C020_WLAN,
248 PCMCIA_CIS_NOKIA_C020_WLAN
249 },
250 { PCMCIA_VENDOR_NOKIA,
251 PCMCIA_PRODUCT_NOKIA_C110_WLAN,
252 PCMCIA_CIS_NOKIA_C110_WLAN
253 },
254 { PCMCIA_VENDOR_NETGEAR2,
255 PCMCIA_PRODUCT_NETGEAR2_MA401RA,
256 PCMCIA_CIS_NETGEAR2_MA401RA
257 },
258 { PCMCIA_VENDOR_NETGEAR2,
259 PCMCIA_PRODUCT_NETGEAR2_DWL650,
260 PCMCIA_CIS_NETGEAR2_DWL650
261 },
262 { PCMCIA_VENDOR_AIRVAST,
263 PCMCIA_PRODUCT_AIRVAST_WN_100,
264 PCMCIA_CIS_AIRVAST_WN_100
265 },
266 { PCMCIA_VENDOR_SIEMENS,
267 PCMCIA_PRODUCT_SIEMENS_SS1021,
268 PCMCIA_CIS_SIEMENS_SS1021
269 },
270 { PCMCIA_VENDOR_PROXIM,
271 PCMCIA_PRODUCT_PROXIM_HARMONY_80211B,
272 PCMCIA_CIS_PROXIM_HARMONY_80211B
273 },
274 { PCMCIA_VENDOR_MICROSOFT,
275 PCMCIA_PRODUCT_MICROSOFT_MN520,
276 PCMCIA_CIS_MICROSOFT_MN520
277 },
278 { PCMCIA_VENDOR_ADAPTEC2,
279 PCMCIA_PRODUCT_ADAPTEC2_AWN8030,
280 PCMCIA_CIS_ADAPTEC2_AWN8030
281 },
282 { PCMCIA_VENDOR_ASUS,
283 PCMCIA_PRODUCT_ASUS_WL_100,
284 PCMCIA_CIS_ASUS_WL_100
285 },
286 { PCMCIA_VENDOR_SENAO,
287 PCMCIA_PRODUCT_SENAO_EL2511CD2EM,
288 PCMCIA_CIS_SENAO_EL2511CD2EM
289 },
290 { PCMCIA_VENDOR_ARTEM,
291 PCMCIA_PRODUCT_ARTEM_ONAIR,
292 PCMCIA_CIS_ARTEM_ONAIR
293 },
294 { PCMCIA_VENDOR_PLANEX,
295 PCMCIA_PRODUCT_PLANEX_GWNS11H,
296 PCMCIA_CIS_PLANEX_GWNS11H
297 },
298 { PCMCIA_VENDOR_SYMBOL,
299 PCMCIA_PRODUCT_SYMBOL_LA4100,
300 PCMCIA_CIS_SYMBOL_LA4100
301 },
302 { PCMCIA_VENDOR_BAY,
303 PCMCIA_PRODUCT_BAY_EMOBILITY_11B,
304 PCMCIA_CIS_BAY_EMOBILITY_11B
305 },
306 { PCMCIA_VENDOR_GREYCELL,
307 PCMCIA_PRODUCT_GREYCELL_DWL650H,
308 PCMCIA_CIS_GREYCELL_DWL650H
309 },
310 { PCMCIA_VENDOR_FUJITSU,
311 PCMCIA_PRODUCT_FUJITSU_WL110,
312 PCMCIA_CIS_FUJITSU_WL110
313 },
314 { PCMCIA_VENDOR_ALLIEDTELESIS,
315 PCMCIA_PRODUCT_ALLIEDTELESIS_WR211PCM,
316 PCMCIA_CIS_ALLIEDTELESIS_WR211PCM
317 },
318 { PCMCIA_VENDOR_HWN,
319 PCMCIA_PRODUCT_HWN_AIRWAY80211,
320 PCMCIA_CIS_HWN_AIRWAY80211
321 },
322 { PCMCIA_VENDOR_SOCKET,
323 PCMCIA_PRODUCT_SOCKET_LP_WLAN_CF,
324 PCMCIA_CIS_SOCKET_LP_WLAN_CF
325 }
326 };
327
328 static const struct wi_pcmcia_product *wi_lookup(struct pcmcia_attach_args *pa);
329
330 const struct wi_pcmcia_product *
331 wi_lookup(struct pcmcia_attach_args *pa)
332 {
333 const struct wi_pcmcia_product *pp;
334 const struct wi_pcmcia_product *epp = wi_pcmcia_products +
335 sizeof(wi_pcmcia_products) / sizeof(wi_pcmcia_products[0]);
336
337
338
339
340
341 for (pp = wi_pcmcia_products; pp < epp; pp++) {
342 if (pa->card->cis1_info[0] != NULL &&
343 pp->pp_cisinfo[0] != NULL &&
344 strcmp(pa->card->cis1_info[0], pp->pp_cisinfo[0]) == 0 &&
345 pa->card->cis1_info[1] != NULL &&
346 pp->pp_cisinfo[1] != NULL &&
347 strcmp(pa->card->cis1_info[1], pp->pp_cisinfo[1]) == 0)
348 return (pp);
349 }
350
351
352 for (pp = wi_pcmcia_products; pp < epp; pp++) {
353 if (pa->manufacturer != PCMCIA_VENDOR_INVALID &&
354 pa->manufacturer == pp->pp_vendor &&
355 pa->product != PCMCIA_PRODUCT_INVALID &&
356 pa->product == pp->pp_product)
357 return (pp);
358 }
359
360 return (NULL);
361 }
362
363 int
364 wi_pcmcia_match(struct device *parent, void *match, void *aux)
365 {
366 struct pcmcia_attach_args *pa = aux;
367
368 if (wi_lookup(pa) != NULL)
369 return (1);
370 return (0);
371 }
372
373 void
374 wi_pcmcia_attach(struct device *parent, struct device *self, void *aux)
375 {
376 struct wi_pcmcia_softc *psc = (struct wi_pcmcia_softc *)self;
377 struct wi_softc *sc = &psc->sc_wi;
378 struct pcmcia_attach_args *pa = aux;
379 struct pcmcia_function *pf = pa->pf;
380 struct pcmcia_config_entry *cfe = SIMPLEQ_FIRST(&pf->cfe_head);
381 const char *intrstr;
382 int state = 0;
383
384 psc->sc_pf = pf;
385
386
387 pcmcia_function_init(pf, cfe);
388 if (pcmcia_function_enable(pf)) {
389 printf(": function enable failed\n");
390 goto bad;
391 }
392 state++;
393
394 if (pcmcia_io_alloc(pf, 0, WI_IOSIZ, WI_IOSIZ, &psc->sc_pcioh)) {
395 printf(": can't alloc i/o space\n");
396 goto bad;
397 }
398 state++;
399
400 if (pcmcia_io_map(pf, PCMCIA_WIDTH_IO16, 0, WI_IOSIZ,
401 &psc->sc_pcioh, &psc->sc_io_window)) {
402 printf(": can't map io space\n");
403 goto bad;
404 }
405 state++;
406
407 printf(" port 0x%lx/%lu", psc->sc_pcioh.addr,
408 (u_long)psc->sc_pcioh.size);
409
410 sc->wi_ltag = sc->wi_btag = psc->sc_pcioh.iot;
411 sc->wi_lhandle = sc->wi_bhandle = psc->sc_pcioh.ioh;
412 sc->wi_cor_offset = WI_COR_OFFSET;
413 sc->wi_flags |= WI_FLAGS_BUS_PCMCIA;
414
415
416 CSR_WRITE_2(sc, WI_INT_EN, 0);
417 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xffff);
418
419
420 sc->sc_ih = pcmcia_intr_establish(pa->pf, IPL_NET, wi_intr, psc,
421 sc->sc_dev.dv_xname);
422 if (sc->sc_ih == NULL) {
423 printf("%s: couldn't establish interrupt\n",
424 sc->sc_dev.dv_xname);
425 goto bad;
426 }
427
428 intrstr = pcmcia_intr_string(psc->sc_pf, sc->sc_ih);
429 printf("%s%s\n", *intrstr ? ", " : "", intrstr);
430 if (wi_attach(sc, &wi_func_io) == 0)
431 return;
432
433
434 pcmcia_intr_disestablish(psc->sc_pf, sc->sc_ih);
435 sc->sc_ih = NULL;
436
437 bad:
438 if (state > 2)
439 pcmcia_io_unmap(pf, psc->sc_io_window);
440 if (state > 1)
441 pcmcia_io_free(pf, &psc->sc_pcioh);
442 if (state > 0)
443 pcmcia_function_disable(pf);
444 }
445
446 int
447 wi_pcmcia_detach(struct device *dev, int flags)
448 {
449 struct wi_pcmcia_softc *psc = (struct wi_pcmcia_softc *)dev;
450 struct wi_softc *sc = &psc->sc_wi;
451 struct ifnet *ifp = &sc->sc_ic.ic_if;
452
453 if (!(sc->wi_flags & WI_FLAGS_ATTACHED))
454 return (0);
455
456 wi_detach(sc);
457
458 sc->wi_flags = 0;
459
460 pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
461 pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
462
463 ether_ifdetach(ifp);
464 if_detach(ifp);
465
466 return (0);
467 }
468
469 int
470 wi_pcmcia_activate(struct device *dev, enum devact act)
471 {
472 struct wi_pcmcia_softc *psc = (struct wi_pcmcia_softc *)dev;
473 struct wi_softc *sc = &psc->sc_wi;
474 struct ifnet *ifp = &sc->sc_ic.ic_if;
475 int s;
476
477 s = splnet();
478 switch (act) {
479 case DVACT_ACTIVATE:
480 pcmcia_function_enable(psc->sc_pf);
481 sc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET,
482 wi_intr, sc, sc->sc_dev.dv_xname);
483 wi_cor_reset(sc);
484 wi_init(sc);
485 break;
486
487 case DVACT_DEACTIVATE:
488 ifp->if_timer = 0;
489 if (ifp->if_flags & IFF_RUNNING)
490 wi_stop(sc);
491 sc->wi_flags &= ~WI_FLAGS_INITIALIZED;
492 if (sc->sc_ih != NULL)
493 pcmcia_intr_disestablish(psc->sc_pf, sc->sc_ih);
494 pcmcia_function_disable(psc->sc_pf);
495 break;
496 }
497 splx(s);
498 return (0);
499 }