if_wi_pcmcia.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. /* $OpenBSD: if_wi_pcmcia.c,v 1.73 2014/12/22 02:28:52 tedu Exp $ */
  2. /* $NetBSD: if_wi_pcmcia.c,v 1.14 2001/11/26 04:34:56 ichiro Exp $ */
  3. /*
  4. * Copyright (c) 1997, 1998, 1999
  5. * Bill Paul <wpaul@ctr.columbia.edu>. 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 Bill Paul.
  18. * 4. Neither the name of the author nor the names of any co-contributors
  19. * may be used to endorse or promote products derived from this software
  20. * without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
  23. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25. * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
  26. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  27. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  28. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  29. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  30. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  31. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  32. * THE POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. * From: if_wi.c,v 1.7 1999/07/04 14:40:22 wpaul Exp $
  35. */
  36. /*
  37. * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for OpenBSD.
  38. *
  39. * Originally written by Bill Paul <wpaul@ctr.columbia.edu>
  40. * Electrical Engineering Department
  41. * Columbia University, New York City
  42. */
  43. #include <sys/param.h>
  44. #include <sys/systm.h>
  45. #include <sys/timeout.h>
  46. #include <sys/socket.h>
  47. #include <sys/device.h>
  48. #include <sys/tree.h>
  49. #include <net/if.h>
  50. #include <net/if_dl.h>
  51. #include <net/if_media.h>
  52. #include <netinet/in.h>
  53. #include <netinet/if_ether.h>
  54. #include <net80211/ieee80211_var.h>
  55. #include <net80211/ieee80211_ioctl.h>
  56. #include <machine/bus.h>
  57. #include <dev/pcmcia/pcmciareg.h>
  58. #include <dev/pcmcia/pcmciavar.h>
  59. #include <dev/pcmcia/pcmciadevs.h>
  60. #include <dev/ic/if_wireg.h>
  61. #include <dev/ic/if_wi_ieee.h>
  62. #include <dev/ic/if_wivar.h>
  63. int wi_pcmcia_match(struct device *, void *, void *);
  64. void wi_pcmcia_attach(struct device *, struct device *, void *);
  65. int wi_pcmcia_detach(struct device *, int);
  66. int wi_pcmcia_activate(struct device *, int);
  67. void wi_pcmcia_wakeup(struct wi_softc *);
  68. struct wi_pcmcia_softc {
  69. struct wi_softc sc_wi;
  70. struct pcmcia_io_handle sc_pcioh;
  71. int sc_io_window;
  72. struct pcmcia_function *sc_pf;
  73. };
  74. struct cfattach wi_pcmcia_ca = {
  75. sizeof (struct wi_pcmcia_softc), wi_pcmcia_match, wi_pcmcia_attach,
  76. wi_pcmcia_detach, wi_pcmcia_activate
  77. };
  78. static const struct wi_pcmcia_product {
  79. u_int16_t pp_vendor;
  80. u_int16_t pp_product;
  81. const char *pp_cisinfo[4];
  82. } wi_pcmcia_products[] = {
  83. { PCMCIA_VENDOR_LUCENT,
  84. PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE,
  85. PCMCIA_CIS_LUCENT_WAVELAN_IEEE
  86. },
  87. { PCMCIA_VENDOR_3COM,
  88. PCMCIA_PRODUCT_3COM_3CRWE737A,
  89. PCMCIA_CIS_3COM_3CRWE737A
  90. },
  91. { PCMCIA_VENDOR_3COM,
  92. PCMCIA_PRODUCT_3COM_3CRWE777A,
  93. PCMCIA_CIS_3COM_3CRWE777A
  94. },
  95. { PCMCIA_VENDOR_COREGA,
  96. PCMCIA_PRODUCT_COREGA_WIRELESS_LAN_PCC_11,
  97. PCMCIA_CIS_COREGA_WIRELESS_LAN_PCC_11
  98. },
  99. { PCMCIA_VENDOR_COREGA,
  100. PCMCIA_PRODUCT_COREGA_WIRELESS_LAN_PCCA_11,
  101. PCMCIA_CIS_COREGA_WIRELESS_LAN_PCCA_11
  102. },
  103. { PCMCIA_VENDOR_COREGA,
  104. PCMCIA_PRODUCT_COREGA_WIRELESS_LAN_PCCB_11,
  105. PCMCIA_CIS_COREGA_WIRELESS_LAN_PCCB_11
  106. },
  107. { PCMCIA_VENDOR_COREGA,
  108. PCMCIA_PRODUCT_COREGA_WIRELESS_LAN_PCCL_11,
  109. PCMCIA_CIS_COREGA_WIRELESS_LAN_PCCL_11
  110. },
  111. { PCMCIA_VENDOR_COREGA,
  112. PCMCIA_PRODUCT_COREGA_WIRELESS_LAN_WLCFL_11,
  113. PCMCIA_CIS_COREGA_WIRELESS_LAN_WLCFL_11
  114. },
  115. { PCMCIA_VENDOR_INTEL,
  116. PCMCIA_PRODUCT_INTEL_PRO_WLAN_2011,
  117. PCMCIA_CIS_INTEL_PRO_WLAN_2011
  118. },
  119. { PCMCIA_VENDOR_INTERSIL,
  120. PCMCIA_PRODUCT_INTERSIL_PRISM2,
  121. PCMCIA_CIS_INTERSIL_PRISM2
  122. },
  123. { PCMCIA_VENDOR_SAMSUNG,
  124. PCMCIA_PRODUCT_SAMSUNG_SWL_2000N,
  125. PCMCIA_CIS_SAMSUNG_SWL_2000N
  126. },
  127. { PCMCIA_VENDOR_LINKSYS2,
  128. PCMCIA_PRODUCT_LINKSYS2_IWN,
  129. PCMCIA_CIS_LINKSYS2_IWN
  130. },
  131. { PCMCIA_VENDOR_LINKSYS2,
  132. PCMCIA_PRODUCT_LINKSYS2_IWN2,
  133. PCMCIA_CIS_LINKSYS2_IWN2
  134. },
  135. { PCMCIA_VENDOR_LINKSYS2,
  136. PCMCIA_PRODUCT_LINKSYS2_WCF11,
  137. PCMCIA_CIS_LINKSYS2_WCF11
  138. },
  139. { PCMCIA_VENDOR_LUCENT,
  140. PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE,
  141. PCMCIA_CIS_SMC_2632W
  142. },
  143. { PCMCIA_VENDOR_LUCENT,
  144. PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE,
  145. PCMCIA_CIS_NANOSPEED_PRISM2
  146. },
  147. { PCMCIA_VENDOR_ELSA,
  148. PCMCIA_PRODUCT_ELSA_XI300_IEEE,
  149. PCMCIA_CIS_ELSA_XI300_IEEE
  150. },
  151. { PCMCIA_VENDOR_ELSA,
  152. PCMCIA_PRODUCT_ELSA_XI325_IEEE,
  153. PCMCIA_CIS_ELSA_XI325_IEEE
  154. },
  155. { PCMCIA_VENDOR_ELSA,
  156. PCMCIA_PRODUCT_ELSA_WNB11CFZ,
  157. PCMCIA_CIS_ELSA_WNB11CFZ
  158. },
  159. { PCMCIA_VENDOR_COMPAQ,
  160. PCMCIA_PRODUCT_COMPAQ_NC5004,
  161. PCMCIA_CIS_COMPAQ_NC5004
  162. },
  163. { PCMCIA_VENDOR_CONTEC,
  164. PCMCIA_PRODUCT_CONTEC_FX_DS110_PCC,
  165. PCMCIA_CIS_CONTEC_FX_DS110_PCC
  166. },
  167. { PCMCIA_VENDOR_TDK,
  168. PCMCIA_PRODUCT_TDK_LAK_CD011WL,
  169. PCMCIA_CIS_TDK_LAK_CD011WL
  170. },
  171. { PCMCIA_VENDOR_LUCENT,
  172. PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE,
  173. PCMCIA_CIS_NEC_CMZ_RT_WP
  174. },
  175. { PCMCIA_VENDOR_LUCENT,
  176. PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE,
  177. PCMCIA_CIS_NTT_ME_WLAN
  178. },
  179. { PCMCIA_VENDOR_ADDTRON,
  180. PCMCIA_PRODUCT_ADDTRON_AWP100,
  181. PCMCIA_CIS_ADDTRON_AWP100
  182. },
  183. { PCMCIA_VENDOR_LUCENT,
  184. PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE,
  185. PCMCIA_CIS_CABLETRON_ROAMABOUT
  186. },
  187. { PCMCIA_VENDOR_IODATA2,
  188. PCMCIA_PRODUCT_IODATA2_WCF12,
  189. PCMCIA_CIS_IODATA2_WCF12
  190. },
  191. { PCMCIA_VENDOR_IODATA2,
  192. PCMCIA_PRODUCT_IODATA2_WNB11PCM,
  193. PCMCIA_CIS_IODATA2_WNB11PCM
  194. },
  195. { PCMCIA_VENDOR_GEMTEK,
  196. PCMCIA_PRODUCT_GEMTEK_WLAN,
  197. PCMCIA_CIS_GEMTEK_WLAN
  198. },
  199. { PCMCIA_VENDOR_ELSA,
  200. PCMCIA_PRODUCT_ELSA_XI800_IEEE,
  201. PCMCIA_CIS_ELSA_XI800_IEEE
  202. },
  203. { PCMCIA_VENDOR_BUFFALO,
  204. PCMCIA_PRODUCT_BUFFALO_WLI_PCM_S11,
  205. PCMCIA_CIS_BUFFALO_WLI_PCM_S11
  206. },
  207. { PCMCIA_VENDOR_BUFFALO,
  208. PCMCIA_PRODUCT_BUFFALO_WLI_CF_S11G,
  209. PCMCIA_CIS_BUFFALO_WLI_CF_S11G
  210. },
  211. { PCMCIA_VENDOR_EMTAC,
  212. PCMCIA_PRODUCT_EMTAC_WLAN,
  213. PCMCIA_CIS_EMTAC_WLAN
  214. },
  215. { PCMCIA_VENDOR_SIMPLETECH,
  216. PCMCIA_PRODUCT_SIMPLETECH_SPECTRUM24_ALT,
  217. PCMCIA_CIS_SIMPLETECH_SPECTRUM24_ALT
  218. },
  219. { PCMCIA_VENDOR_ERICSSON,
  220. PCMCIA_PRODUCT_ERICSSON_WIRELESSLAN,
  221. PCMCIA_CIS_ERICSSON_WIRELESSLAN
  222. },
  223. { PCMCIA_VENDOR_PROXIM,
  224. PCMCIA_PRODUCT_PROXIM_RANGELANDS_8430,
  225. PCMCIA_CIS_PROXIM_RANGELANDS_8430
  226. },
  227. { PCMCIA_VENDOR_ACTIONTEC,
  228. PCMCIA_PRODUCT_ACTIONTEC_HWC01170,
  229. PCMCIA_CIS_ACTIONTEC_HWC01170
  230. },
  231. { PCMCIA_VENDOR_NOKIA,
  232. PCMCIA_PRODUCT_NOKIA_C020_WLAN,
  233. PCMCIA_CIS_NOKIA_C020_WLAN
  234. },
  235. { PCMCIA_VENDOR_NOKIA,
  236. PCMCIA_PRODUCT_NOKIA_C110_WLAN,
  237. PCMCIA_CIS_NOKIA_C110_WLAN
  238. },
  239. { PCMCIA_VENDOR_NETGEAR2,
  240. PCMCIA_PRODUCT_NETGEAR2_MA401RA,
  241. PCMCIA_CIS_NETGEAR2_MA401RA
  242. },
  243. { PCMCIA_VENDOR_NETGEAR2,
  244. PCMCIA_PRODUCT_NETGEAR2_DWL650,
  245. PCMCIA_CIS_NETGEAR2_DWL650
  246. },
  247. { PCMCIA_VENDOR_AIRVAST,
  248. PCMCIA_PRODUCT_AIRVAST_WN_100,
  249. PCMCIA_CIS_AIRVAST_WN_100
  250. },
  251. { PCMCIA_VENDOR_SIEMENS,
  252. PCMCIA_PRODUCT_SIEMENS_SS1021,
  253. PCMCIA_CIS_SIEMENS_SS1021
  254. },
  255. { PCMCIA_VENDOR_PROXIM,
  256. PCMCIA_PRODUCT_PROXIM_HARMONY_80211B,
  257. PCMCIA_CIS_PROXIM_HARMONY_80211B
  258. },
  259. { PCMCIA_VENDOR_MICROSOFT,
  260. PCMCIA_PRODUCT_MICROSOFT_MN520,
  261. PCMCIA_CIS_MICROSOFT_MN520
  262. },
  263. { PCMCIA_VENDOR_ADAPTEC2,
  264. PCMCIA_PRODUCT_ADAPTEC2_AWN8030,
  265. PCMCIA_CIS_ADAPTEC2_AWN8030
  266. },
  267. { PCMCIA_VENDOR_ASUS,
  268. PCMCIA_PRODUCT_ASUS_WL_100,
  269. PCMCIA_CIS_ASUS_WL_100
  270. },
  271. { PCMCIA_VENDOR_SENAO,
  272. PCMCIA_PRODUCT_SENAO_EL2511CD2EM,
  273. PCMCIA_CIS_SENAO_EL2511CD2EM
  274. },
  275. { PCMCIA_VENDOR_ARTEM,
  276. PCMCIA_PRODUCT_ARTEM_ONAIR,
  277. PCMCIA_CIS_ARTEM_ONAIR
  278. },
  279. { PCMCIA_VENDOR_PLANEX,
  280. PCMCIA_PRODUCT_PLANEX_GWNS11H,
  281. PCMCIA_CIS_PLANEX_GWNS11H
  282. },
  283. { PCMCIA_VENDOR_SYMBOL,
  284. PCMCIA_PRODUCT_SYMBOL_LA4100,
  285. PCMCIA_CIS_SYMBOL_LA4100
  286. },
  287. { PCMCIA_VENDOR_BAY,
  288. PCMCIA_PRODUCT_BAY_EMOBILITY_11B,
  289. PCMCIA_CIS_BAY_EMOBILITY_11B
  290. },
  291. { PCMCIA_VENDOR_GREYCELL,
  292. PCMCIA_PRODUCT_GREYCELL_DWL650H,
  293. PCMCIA_CIS_GREYCELL_DWL650H
  294. },
  295. { PCMCIA_VENDOR_FUJITSU,
  296. PCMCIA_PRODUCT_FUJITSU_WL110,
  297. PCMCIA_CIS_FUJITSU_WL110
  298. },
  299. { PCMCIA_VENDOR_ALLIEDTELESIS,
  300. PCMCIA_PRODUCT_ALLIEDTELESIS_WR211PCM,
  301. PCMCIA_CIS_ALLIEDTELESIS_WR211PCM
  302. },
  303. { PCMCIA_VENDOR_HWN,
  304. PCMCIA_PRODUCT_HWN_AIRWAY80211,
  305. PCMCIA_CIS_HWN_AIRWAY80211
  306. },
  307. { PCMCIA_VENDOR_SOCKET,
  308. PCMCIA_PRODUCT_SOCKET_LP_WLAN_CF,
  309. PCMCIA_CIS_SOCKET_LP_WLAN_CF
  310. }
  311. };
  312. static const struct wi_pcmcia_product *wi_lookup(struct pcmcia_attach_args *pa);
  313. const struct wi_pcmcia_product *
  314. wi_lookup(struct pcmcia_attach_args *pa)
  315. {
  316. const struct wi_pcmcia_product *pp;
  317. const struct wi_pcmcia_product *epp = wi_pcmcia_products +
  318. sizeof(wi_pcmcia_products) / sizeof(wi_pcmcia_products[0]);
  319. /*
  320. * Several PRISM II-based cards use the Lucent WaveLAN vendor
  321. * and product IDs so we match by CIS information first.
  322. */
  323. for (pp = wi_pcmcia_products; pp < epp; pp++) {
  324. if (pa->card->cis1_info[0] != NULL &&
  325. pp->pp_cisinfo[0] != NULL &&
  326. strcmp(pa->card->cis1_info[0], pp->pp_cisinfo[0]) == 0 &&
  327. pa->card->cis1_info[1] != NULL &&
  328. pp->pp_cisinfo[1] != NULL &&
  329. strcmp(pa->card->cis1_info[1], pp->pp_cisinfo[1]) == 0)
  330. return (pp);
  331. }
  332. /* Match by vendor/product ID. */
  333. for (pp = wi_pcmcia_products; pp < epp; pp++) {
  334. if (pa->manufacturer != PCMCIA_VENDOR_INVALID &&
  335. pa->manufacturer == pp->pp_vendor &&
  336. pa->product != PCMCIA_PRODUCT_INVALID &&
  337. pa->product == pp->pp_product)
  338. return (pp);
  339. }
  340. return (NULL);
  341. }
  342. int
  343. wi_pcmcia_match(struct device *parent, void *match, void *aux)
  344. {
  345. struct pcmcia_attach_args *pa = aux;
  346. if (wi_lookup(pa) != NULL)
  347. return (1);
  348. return (0);
  349. }
  350. void
  351. wi_pcmcia_attach(struct device *parent, struct device *self, void *aux)
  352. {
  353. struct wi_pcmcia_softc *psc = (struct wi_pcmcia_softc *)self;
  354. struct wi_softc *sc = &psc->sc_wi;
  355. struct pcmcia_attach_args *pa = aux;
  356. struct pcmcia_function *pf = pa->pf;
  357. struct pcmcia_config_entry *cfe = SIMPLEQ_FIRST(&pf->cfe_head);
  358. const char *intrstr;
  359. int state = 0;
  360. psc->sc_pf = pf;
  361. /* Enable the card. */
  362. pcmcia_function_init(pf, cfe);
  363. if (pcmcia_function_enable(pf)) {
  364. printf(": function enable failed\n");
  365. goto bad;
  366. }
  367. state++;
  368. if (pcmcia_io_alloc(pf, 0, WI_IOSIZ, WI_IOSIZ, &psc->sc_pcioh)) {
  369. printf(": can't alloc i/o space\n");
  370. goto bad;
  371. }
  372. state++;
  373. if (pcmcia_io_map(pf, PCMCIA_WIDTH_IO16, 0, WI_IOSIZ,
  374. &psc->sc_pcioh, &psc->sc_io_window)) {
  375. printf(": can't map i/o space\n");
  376. goto bad;
  377. }
  378. state++;
  379. printf(" port 0x%lx/%lu", psc->sc_pcioh.addr,
  380. (u_long)psc->sc_pcioh.size);
  381. sc->wi_ltag = sc->wi_btag = psc->sc_pcioh.iot;
  382. sc->wi_lhandle = sc->wi_bhandle = psc->sc_pcioh.ioh;
  383. sc->wi_cor_offset = WI_COR_OFFSET;
  384. sc->wi_flags |= WI_FLAGS_BUS_PCMCIA;
  385. /* Make sure interrupts are disabled. */
  386. CSR_WRITE_2(sc, WI_INT_EN, 0);
  387. CSR_WRITE_2(sc, WI_EVENT_ACK, 0xffff);
  388. /* Establish the interrupt. */
  389. sc->sc_ih = pcmcia_intr_establish(pa->pf, IPL_NET, wi_intr, psc,
  390. sc->sc_dev.dv_xname);
  391. if (sc->sc_ih == NULL) {
  392. printf("%s: can't establish interrupt\n",
  393. sc->sc_dev.dv_xname);
  394. goto bad;
  395. }
  396. intrstr = pcmcia_intr_string(psc->sc_pf, sc->sc_ih);
  397. printf("%s%s\n", *intrstr ? ", " : "", intrstr);
  398. if (wi_attach(sc, &wi_func_io) == 0)
  399. return;
  400. /* wi_attach() failed, do some cleanup */
  401. pcmcia_intr_disestablish(psc->sc_pf, sc->sc_ih);
  402. sc->sc_ih = NULL;
  403. bad:
  404. if (state > 2)
  405. pcmcia_io_unmap(pf, psc->sc_io_window);
  406. if (state > 1)
  407. pcmcia_io_free(pf, &psc->sc_pcioh);
  408. if (state > 0)
  409. pcmcia_function_disable(pf);
  410. }
  411. int
  412. wi_pcmcia_detach(struct device *dev, int flags)
  413. {
  414. struct wi_pcmcia_softc *psc = (struct wi_pcmcia_softc *)dev;
  415. struct wi_softc *sc = &psc->sc_wi;
  416. struct ifnet *ifp = &sc->sc_ic.ic_if;
  417. if (!(sc->wi_flags & WI_FLAGS_ATTACHED))
  418. return (0);
  419. wi_detach(sc);
  420. sc->wi_flags = 0;
  421. pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
  422. pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
  423. ether_ifdetach(ifp);
  424. if_detach(ifp);
  425. return (0);
  426. }
  427. int
  428. wi_pcmcia_activate(struct device *dev, int act)
  429. {
  430. struct wi_pcmcia_softc *psc = (struct wi_pcmcia_softc *)dev;
  431. struct wi_softc *sc = &psc->sc_wi;
  432. struct ifnet *ifp = &sc->sc_ic.ic_if;
  433. switch (act) {
  434. case DVACT_SUSPEND:
  435. ifp->if_timer = 0;
  436. if (ifp->if_flags & IFF_RUNNING)
  437. wi_stop(sc);
  438. sc->wi_flags &= ~WI_FLAGS_INITIALIZED;
  439. if (sc->sc_ih != NULL)
  440. pcmcia_intr_disestablish(psc->sc_pf, sc->sc_ih);
  441. sc->sc_ih = NULL;
  442. pcmcia_function_disable(psc->sc_pf);
  443. break;
  444. case DVACT_RESUME:
  445. pcmcia_function_enable(psc->sc_pf);
  446. sc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET,
  447. wi_intr, sc, sc->sc_dev.dv_xname);
  448. break;
  449. case DVACT_WAKEUP:
  450. wi_pcmcia_wakeup(sc);
  451. break;
  452. case DVACT_DEACTIVATE:
  453. if (sc->sc_ih != NULL)
  454. pcmcia_intr_disestablish(psc->sc_pf, sc->sc_ih);
  455. sc->sc_ih = NULL;
  456. pcmcia_function_disable(psc->sc_pf);
  457. break;
  458. }
  459. return (0);
  460. }
  461. void
  462. wi_pcmcia_wakeup(struct wi_softc *sc)
  463. {
  464. int s;
  465. s = splnet();
  466. while (sc->wi_flags & WI_FLAGS_BUSY)
  467. tsleep(&sc->wi_flags, 0, "wipwr", 0);
  468. sc->wi_flags |= WI_FLAGS_BUSY;
  469. wi_cor_reset(sc);
  470. wi_init(sc);
  471. sc->wi_flags &= ~WI_FLAGS_BUSY;
  472. wakeup(&sc->wi_flags);
  473. splx(s);
  474. }