wi.c revision 1.17.2.6 1 /* $NetBSD: wi.c,v 1.17.2.6 2001/11/15 17:43:57 thorpej Exp $ */
2
3 /*
4 * Copyright (c) 1997, 1998, 1999
5 * Bill Paul <wpaul (at) 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
35 /*
36 * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for NetBSD.
37 *
38 * Original FreeBSD driver written by Bill Paul <wpaul (at) ctr.columbia.edu>
39 * Electrical Engineering Department
40 * Columbia University, New York City
41 */
42
43 /*
44 * The WaveLAN/IEEE adapter is the second generation of the WaveLAN
45 * from Lucent. Unlike the older cards, the new ones are programmed
46 * entirely via a firmware-driven controller called the Hermes.
47 * Unfortunately, Lucent will not release the Hermes programming manual
48 * without an NDA (if at all). What they do release is an API library
49 * called the HCF (Hardware Control Functions) which is supposed to
50 * do the device-specific operations of a device driver for you. The
51 * publically available version of the HCF library (the 'HCF Light') is
52 * a) extremely gross, b) lacks certain features, particularly support
53 * for 802.11 frames, and c) is contaminated by the GNU Public License.
54 *
55 * This driver does not use the HCF or HCF Light at all. Instead, it
56 * programs the Hermes controller directly, using information gleaned
57 * from the HCF Light code and corresponding documentation.
58 *
59 * This driver supports both the PCMCIA and ISA versions of the
60 * WaveLAN/IEEE cards. Note however that the ISA card isn't really
61 * anything of the sort: it's actually a PCMCIA bridge adapter
62 * that fits into an ISA slot, into which a PCMCIA WaveLAN card is
63 * inserted. Consequently, you need to use the pccard support for
64 * both the ISA and PCMCIA adapters.
65 */
66
67 /*
68 * FreeBSD driver ported to NetBSD by Bill Sommerfeld in the back of the
69 * Oslo IETF plenary meeting.
70 */
71
72 #include <sys/cdefs.h>
73 __KERNEL_RCSID(0, "$NetBSD: wi.c,v 1.17.2.6 2001/11/15 17:43:57 thorpej Exp $");
74
75 #define WI_HERMES_AUTOINC_WAR /* Work around data write autoinc bug. */
76 #define WI_HERMES_STATS_WAR /* Work around stats counter bug. */
77
78 #include "bpfilter.h"
79
80 #include <sys/param.h>
81 #include <sys/systm.h>
82 #include <sys/callout.h>
83 #include <sys/device.h>
84 #include <sys/socket.h>
85 #include <sys/mbuf.h>
86 #include <sys/ioctl.h>
87 #include <sys/kernel.h> /* for hz */
88 #include <sys/lwp.h>
89 #include <sys/proc.h>
90
91 #include <net/if.h>
92 #include <net/if_dl.h>
93 #include <net/if_media.h>
94 #include <net/if_ether.h>
95 #include <net/if_ieee80211.h>
96
97 #if NBPFILTER > 0
98 #include <net/bpf.h>
99 #include <net/bpfdesc.h>
100 #endif
101
102 #include <machine/bus.h>
103
104 #include <dev/ic/wi_ieee.h>
105 #include <dev/ic/wireg.h>
106 #include <dev/ic/wivar.h>
107
108 #define STATS_FREQUENCY (60 * hz) /* collect stats every 60 seconds */
109
110 static void wi_reset __P((struct wi_softc *));
111 static int wi_ioctl __P((struct ifnet *, u_long, caddr_t));
112 static void wi_start __P((struct ifnet *));
113 static void wi_watchdog __P((struct ifnet *));
114 static int wi_init __P((struct ifnet *));
115 static void wi_stop __P((struct ifnet *, int));
116 static void wi_rxeof __P((struct wi_softc *));
117 static void wi_txeof __P((struct wi_softc *, int));
118 static void wi_update_stats __P((struct wi_softc *));
119 static void wi_setmulti __P((struct wi_softc *));
120
121 static int wi_cmd __P((struct wi_softc *, int, int));
122 static int wi_read_record __P((struct wi_softc *, struct wi_ltv_gen *));
123 static int wi_write_record __P((struct wi_softc *, struct wi_ltv_gen *));
124 static int wi_read_data __P((struct wi_softc *, int,
125 int, caddr_t, int));
126 static int wi_write_data __P((struct wi_softc *, int,
127 int, caddr_t, int));
128 static int wi_seek __P((struct wi_softc *, int, int, int));
129 static int wi_alloc_nicmem __P((struct wi_softc *, int, int *));
130 static void wi_inquire_stats __P((void *));
131 static void wi_inquire_scan __P((void *));
132 static int wi_setdef __P((struct wi_softc *, struct wi_req *));
133 static int wi_getdef __P((struct wi_softc *, struct wi_req *));
134 static int wi_mgmt_xmit __P((struct wi_softc *, caddr_t, int));
135
136 static int wi_media_change __P((struct ifnet *));
137 static void wi_media_status __P((struct ifnet *, struct ifmediareq *));
138
139 static void wi_get_id __P((struct wi_softc *));
140
141 static int wi_set_ssid __P((struct ieee80211_nwid *, u_int8_t *, int));
142 static void wi_request_fill_ssid __P((struct wi_req *,
143 struct ieee80211_nwid *));
144 static int wi_write_ssid __P((struct wi_softc *, int, struct wi_req *,
145 struct ieee80211_nwid *));
146 static int wi_set_nwkey __P((struct wi_softc *, struct ieee80211_nwkey *));
147 static int wi_get_nwkey __P((struct wi_softc *, struct ieee80211_nwkey *));
148 static int wi_sync_media __P((struct wi_softc *, int, int));
149 static int wi_set_pm(struct wi_softc *, struct ieee80211_power *);
150 static int wi_get_pm(struct wi_softc *, struct ieee80211_power *);
151
152 int
153 wi_attach(sc)
154 struct wi_softc *sc;
155 {
156 struct ifnet *ifp = sc->sc_ifp;
157 struct wi_ltv_macaddr mac;
158 struct wi_ltv_gen gen;
159 static const u_int8_t empty_macaddr[ETHER_ADDR_LEN] = {
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
161 };
162 int s;
163
164 s = splnet();
165
166 callout_init(&sc->wi_stats_ch);
167 callout_init(&sc->wi_scan_ch);
168
169 /* Make sure interrupts are disabled. */
170 CSR_WRITE_2(sc, WI_INT_EN, 0);
171 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
172
173 /* Reset the NIC. */
174 wi_reset(sc);
175
176 memset(&mac, 0, sizeof(mac));
177 /* Read the station address. */
178 mac.wi_type = WI_RID_MAC_NODE;
179 mac.wi_len = 4;
180 wi_read_record(sc, (struct wi_ltv_gen *)&mac);
181 memcpy(sc->sc_macaddr, mac.wi_mac_addr, ETHER_ADDR_LEN);
182
183 /*
184 * Check if we got anything meaningful.
185 *
186 * Is it really enough just checking against null ethernet address?
187 * Or, check against possible vendor? XXX.
188 */
189 if (memcmp(sc->sc_macaddr, empty_macaddr, ETHER_ADDR_LEN) == 0) {
190 printf("%s: could not get mac address, attach failed\n",
191 sc->sc_dev.dv_xname);
192 return 1;
193 }
194
195 printf(" 802.11 address %s\n", ether_sprintf(sc->sc_macaddr));
196
197 /* Read NIC identification */
198 wi_get_id(sc);
199
200 memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
201 ifp->if_softc = sc;
202 ifp->if_start = wi_start;
203 ifp->if_ioctl = wi_ioctl;
204 ifp->if_watchdog = wi_watchdog;
205 ifp->if_init = wi_init;
206 ifp->if_stop = wi_stop;
207 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
208 #ifdef IFF_NOTRAILERS
209 ifp->if_flags |= IFF_NOTRAILERS;
210 #endif
211 IFQ_SET_READY(&ifp->if_snd);
212
213 (void)wi_set_ssid(&sc->wi_nodeid, WI_DEFAULT_NODENAME,
214 sizeof(WI_DEFAULT_NODENAME) - 1);
215 (void)wi_set_ssid(&sc->wi_netid, WI_DEFAULT_NETNAME,
216 sizeof(WI_DEFAULT_NETNAME) - 1);
217 (void)wi_set_ssid(&sc->wi_ibssid, WI_DEFAULT_IBSS,
218 sizeof(WI_DEFAULT_IBSS) - 1);
219
220 sc->wi_portnum = WI_DEFAULT_PORT;
221 sc->wi_ptype = WI_PORTTYPE_BSS;
222 sc->wi_ap_density = WI_DEFAULT_AP_DENSITY;
223 sc->wi_rts_thresh = WI_DEFAULT_RTS_THRESH;
224 sc->wi_tx_rate = WI_DEFAULT_TX_RATE;
225 sc->wi_max_data_len = WI_DEFAULT_DATALEN;
226 sc->wi_create_ibss = WI_DEFAULT_CREATE_IBSS;
227 sc->wi_pm_enabled = WI_DEFAULT_PM_ENABLED;
228 sc->wi_max_sleep = WI_DEFAULT_MAX_SLEEP;
229 sc->wi_roaming = WI_DEFAULT_ROAMING;
230 sc->wi_authtype = WI_DEFAULT_AUTHTYPE;
231
232 memset(&sc->wi_results, 0, sizeof (sc->wi_results));
233
234 /*
235 * Read the default channel from the NIC. This may vary
236 * depending on the country where the NIC was purchased, so
237 * we can't hard-code a default and expect it to work for
238 * everyone.
239 */
240 gen.wi_type = WI_RID_OWN_CHNL;
241 gen.wi_len = 2;
242 wi_read_record(sc, &gen);
243 sc->wi_channel = le16toh(gen.wi_val);
244
245 memset((char *)&sc->wi_stats, 0, sizeof(sc->wi_stats));
246
247 /*
248 * Find out if we support WEP on this card.
249 */
250 gen.wi_type = WI_RID_WEP_AVAIL;
251 gen.wi_len = 2;
252 wi_read_record(sc, &gen);
253 sc->wi_has_wep = le16toh(gen.wi_val);
254
255 ifmedia_init(&sc->sc_media, 0, wi_media_change, wi_media_status);
256 #define IFM_AUTOADHOC \
257 IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_ADHOC, 0)
258 #define ADD(m, c) ifmedia_add(&sc->sc_media, (m), (c), NULL)
259 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0), 0);
260 ADD(IFM_AUTOADHOC, 0);
261 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 0, 0), 0);
262 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
263 IFM_IEEE80211_ADHOC, 0), 0);
264 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0);
265 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
266 IFM_IEEE80211_ADHOC, 0), 0);
267 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0);
268 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
269 IFM_IEEE80211_ADHOC, 0), 0);
270 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_MANUAL, 0, 0), 0);
271 #undef ADD
272 ifmedia_set(&sc->sc_media, IFM_AUTOADHOC);
273
274 /*
275 * Call MI attach routines.
276 */
277 if_attach(ifp);
278 ether_ifattach(ifp, mac.wi_mac_addr);
279
280 ifp->if_baudrate = IF_Mbps(2);
281
282 /* Attach is successful. */
283 sc->sc_attached = 1;
284
285 splx(s);
286 return 0;
287 }
288
289 static void wi_rxeof(sc)
290 struct wi_softc *sc;
291 {
292 struct ifnet *ifp;
293 struct ether_header *eh;
294 struct wi_frame rx_frame;
295 struct mbuf *m;
296 int id;
297 u_int16_t msg_type;
298 u_int16_t status;
299 u_int16_t frame_ctl;
300 u_int16_t port;
301
302 ifp = sc->sc_ifp;
303
304 id = CSR_READ_2(sc, WI_RX_FID);
305
306 /* First read in the frame header */
307 if (wi_read_data(sc, id, 0, (caddr_t)&rx_frame, sizeof(rx_frame))) {
308 ifp->if_ierrors++;
309 return;
310 }
311
312 status = le16toh(rx_frame.wi_status);
313 frame_ctl = le16toh(rx_frame.wi_frame_ctl);
314 port = (status >> 8) & 0x07;
315 msg_type = status & WI_RXSTAT_MSG_TYPE;
316
317 /*
318 * Drop packets with CRC errors here. We may want the others,
319 * since we may be doing interesting things with undecryptable
320 * packets, like analyzing them in userland.
321 */
322 if (status & WI_STAT_BADCRC) {
323 ifp->if_ierrors++;
324 return;
325 }
326
327 if (port == 7) {
328 if ((le16toh(rx_frame.wi_dat_len) + 60) > MCLBYTES)
329 return;
330
331 MGETHDR(m, M_DONTWAIT, MT_DATA);
332 if (m == NULL) {
333 ifp->if_ierrors++;
334 return;
335 }
336 MCLGET(m, M_DONTWAIT);
337 if (!(m->m_flags & M_EXT)) {
338 m_freem(m);
339 ifp->if_ierrors++;
340 return;
341 }
342
343 memcpy(mtod(m, caddr_t), &rx_frame, 60);
344 m->m_pkthdr.rcvif = ifp;
345
346 m->m_pkthdr.len = m->m_len =
347 le16toh(rx_frame.wi_dat_len) + 60;
348
349 if (wi_read_data(sc, id, 60, mtod(m, caddr_t) + 60,
350 m->m_len - 60)) {
351 m_freem(m);
352 ifp->if_ierrors++;
353 return;
354 }
355
356 #if NBPFILTER > 0
357 if (ifp->if_bpf)
358 bpf_mtap(ifp->if_bpf, m);
359 #endif
360 m_freem(m);
361 return;
362 }
363
364 /*
365 * Drop undecryptable or packets with receive errors here
366 */
367 if (status & WI_STAT_ERRSTAT) {
368 ifp->if_ierrors++;
369 return;
370 }
371
372 MGETHDR(m, M_DONTWAIT, MT_DATA);
373 if (m == NULL) {
374 ifp->if_ierrors++;
375 return;
376 }
377 MCLGET(m, M_DONTWAIT);
378 if (!(m->m_flags & M_EXT)) {
379 m_freem(m);
380 ifp->if_ierrors++;
381 return;
382 }
383
384 /* Align the data after the ethernet header */
385 m->m_data = (caddr_t) ALIGN(m->m_data + sizeof(struct ether_header))
386 - sizeof(struct ether_header);
387
388 eh = mtod(m, struct ether_header *);
389 m->m_pkthdr.rcvif = ifp;
390
391 if (le16toh(rx_frame.wi_status) == WI_STAT_1042 ||
392 le16toh(rx_frame.wi_status) == WI_STAT_TUNNEL ||
393 le16toh(rx_frame.wi_status) == WI_STAT_WMP_MSG) {
394 if ((le16toh(rx_frame.wi_dat_len) + WI_SNAPHDR_LEN) > MCLBYTES) {
395 printf("%s: oversized packet received "
396 "(wi_dat_len=%d, wi_status=0x%x)\n",
397 sc->sc_dev.dv_xname,
398 le16toh(rx_frame.wi_dat_len), le16toh(rx_frame.wi_status));
399 m_freem(m);
400 ifp->if_ierrors++;
401 return;
402 }
403 m->m_pkthdr.len = m->m_len =
404 le16toh(rx_frame.wi_dat_len) + WI_SNAPHDR_LEN;
405
406 memcpy((char *)&eh->ether_dhost, (char *)&rx_frame.wi_dst_addr,
407 ETHER_ADDR_LEN);
408 memcpy((char *)&eh->ether_shost, (char *)&rx_frame.wi_src_addr,
409 ETHER_ADDR_LEN);
410 memcpy((char *)&eh->ether_type, (char *)&rx_frame.wi_type,
411 sizeof(u_int16_t));
412
413 if (wi_read_data(sc, id, WI_802_11_OFFSET,
414 mtod(m, caddr_t) + sizeof(struct ether_header),
415 m->m_len + 2)) {
416 m_freem(m);
417 ifp->if_ierrors++;
418 return;
419 }
420 } else {
421 if ((le16toh(rx_frame.wi_dat_len) +
422 sizeof(struct ether_header)) > MCLBYTES) {
423 printf("%s: oversized packet received "
424 "(wi_dat_len=%d, wi_status=0x%x)\n",
425 sc->sc_dev.dv_xname,
426 le16toh(rx_frame.wi_dat_len), le16toh(rx_frame.wi_status));
427 m_freem(m);
428 ifp->if_ierrors++;
429 return;
430 }
431 m->m_pkthdr.len = m->m_len =
432 le16toh(rx_frame.wi_dat_len) + sizeof(struct ether_header);
433
434 if (wi_read_data(sc, id, WI_802_3_OFFSET,
435 mtod(m, caddr_t), m->m_len + 2)) {
436 m_freem(m);
437 ifp->if_ierrors++;
438 return;
439 }
440 }
441
442 ifp->if_ipackets++;
443
444 #if NBPFILTER > 0
445 /* Handle BPF listeners. */
446 if (ifp->if_bpf)
447 bpf_mtap(ifp->if_bpf, m);
448 #endif
449
450 /*
451 * Discard packets which are not data packets
452 */
453 if (WLAN_FC_GET_TYPE(frame_ctl) != WLAN_FC_TYPE_DATA) {
454 m_freem(m);
455 return;
456 }
457
458 /* Receive packet. */
459 (*ifp->if_input)(ifp, m);
460 }
461
462 static void wi_txeof(sc, status)
463 struct wi_softc *sc;
464 int status;
465 {
466 struct ifnet *ifp = sc->sc_ifp;
467
468 ifp->if_timer = 0;
469 ifp->if_flags &= ~IFF_OACTIVE;
470
471 if (status & WI_EV_TX_EXC)
472 ifp->if_oerrors++;
473 else
474 ifp->if_opackets++;
475
476 return;
477 }
478
479 void wi_inquire_stats(xsc)
480 void *xsc;
481 {
482 struct wi_softc *sc;
483 struct ifnet *ifp;
484
485 sc = xsc;
486 ifp = &sc->sc_ethercom.ec_if;
487
488 if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
489 return;
490
491 callout_reset(&sc->wi_stats_ch, STATS_FREQUENCY, wi_inquire_stats, sc);
492
493 /* Don't do this while we're transmitting */
494 if (ifp->if_flags & IFF_OACTIVE)
495 return;
496
497 wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_COUNTERS);
498 }
499
500 void wi_inquire_scan(xsc)
501 void *xsc;
502 {
503 struct wi_softc *sc;
504 struct ifnet *ifp;
505
506 sc = xsc;
507 ifp = &sc->sc_ethercom.ec_if;
508
509 if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
510 return;
511
512 if (sc->wi_results.scanning > 0)
513 callout_reset(&sc->wi_scan_ch, sc->wi_results.scanning,
514 wi_inquire_scan, sc);
515 else
516 callout_stop(&sc->wi_scan_ch);
517
518 /* Don't do this while we're transmitting */
519 if (ifp->if_flags & IFF_OACTIVE)
520 return;
521
522 wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS);
523 }
524
525 void wi_update_stats(sc)
526 struct wi_softc *sc;
527 {
528 struct wi_ltv_gen gen;
529 u_int16_t id;
530 struct ifnet *ifp;
531 u_int32_t *ptr;
532 int len, i;
533 u_int16_t t;
534
535 ifp = &sc->sc_ethercom.ec_if;
536
537 id = CSR_READ_2(sc, WI_INFO_FID);
538
539 wi_read_data(sc, id, 0, (char *)&gen, 4);
540
541 switch (gen.wi_type) {
542 case WI_INFO_COUNTERS:
543 /* some card versions have a larger stats structure */
544 len = (gen.wi_len - 1 < sizeof(sc->wi_stats) / 4) ?
545 gen.wi_len - 1 : sizeof(sc->wi_stats) / 4;
546 ptr = (u_int32_t *)&sc->wi_stats;
547
548 for (i = 0; i < len; i++) {
549 t = CSR_READ_2(sc, WI_DATA1);
550 #ifdef WI_HERMES_STATS_WAR
551 if (t > 0xF000)
552 t = ~t & 0xFFFF;
553 #endif
554 ptr[i] += t;
555 }
556
557 ifp->if_collisions = sc->wi_stats.wi_tx_single_retries +
558 sc->wi_stats.wi_tx_multi_retries +
559 sc->wi_stats.wi_tx_retry_limit;
560 break;
561
562 case WI_INFO_SCAN_RESULTS:
563 microtime(&sc->wi_results.lastscan);
564 for (i = 0 ; i < gen.wi_len - 1 ; i++) {
565 t = CSR_READ_2(sc, WI_DATA1);
566 if (i < WI_SCAN_RESULTS_MAXLEN)
567 sc->wi_results.scan_results[i] = t;
568 }
569 if (gen.wi_len - 1 <= WI_SCAN_RESULTS_MAXLEN) {
570 sc->wi_results.len = gen.wi_len - 1;
571 sc->wi_results.truncated = 0;
572 } else {
573 sc->wi_results.len = WI_SCAN_RESULTS_MAXLEN;
574 sc->wi_results.truncated = 1;
575 }
576 break;
577
578 default:
579 #if 0
580 printf("Got info type: %04x\n", gen.wi_type);
581 #endif
582 for (i = 0; i < gen.wi_len; i++) {
583 t = CSR_READ_2(sc, WI_DATA1);
584 #if 0
585 printf("[0x%02x] = 0x%04x\n", i, t);
586 #endif
587 }
588 break;
589 }
590 }
591
592 int wi_intr(arg)
593 void *arg;
594 {
595 struct wi_softc *sc = arg;
596 struct ifnet *ifp;
597 u_int16_t status;
598
599 if (sc->sc_enabled == 0 ||
600 (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0 ||
601 (sc->sc_ethercom.ec_if.if_flags & IFF_RUNNING) == 0)
602 return (0);
603
604 ifp = &sc->sc_ethercom.ec_if;
605
606 if (!(ifp->if_flags & IFF_UP)) {
607 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
608 CSR_WRITE_2(sc, WI_INT_EN, 0);
609 return 1;
610 }
611
612 /* Disable interrupts. */
613 CSR_WRITE_2(sc, WI_INT_EN, 0);
614
615 status = CSR_READ_2(sc, WI_EVENT_STAT);
616 CSR_WRITE_2(sc, WI_EVENT_ACK, ~WI_INTRS);
617
618 if (status & WI_EV_RX) {
619 wi_rxeof(sc);
620 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
621 }
622
623 if (status & WI_EV_TX) {
624 wi_txeof(sc, status);
625 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX);
626 }
627
628 if (status & WI_EV_ALLOC) {
629 int id;
630 id = CSR_READ_2(sc, WI_ALLOC_FID);
631 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
632 if (id == sc->wi_tx_data_id)
633 wi_txeof(sc, status);
634 }
635
636 if (status & WI_EV_INFO) {
637 wi_update_stats(sc);
638 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO);
639 }
640
641 if (status & WI_EV_TX_EXC) {
642 wi_txeof(sc, status);
643 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX_EXC);
644 }
645
646 if (status & WI_EV_INFO_DROP) {
647 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO_DROP);
648 }
649
650 /* Re-enable interrupts. */
651 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
652
653 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
654 wi_start(ifp);
655
656 return 1;
657 }
658
659 static int
660 wi_cmd(sc, cmd, val)
661 struct wi_softc *sc;
662 int cmd;
663 int val;
664 {
665 int i, s = 0;
666
667 /* wait for the busy bit to clear */
668 for (i = 0; i < WI_TIMEOUT; i++) {
669 if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY))
670 break;
671 }
672
673 CSR_WRITE_2(sc, WI_PARAM0, val);
674 CSR_WRITE_2(sc, WI_PARAM1, 0);
675 CSR_WRITE_2(sc, WI_PARAM2, 0);
676 CSR_WRITE_2(sc, WI_COMMAND, cmd);
677
678 /* wait for the cmd completed bit */
679 for (i = 0; i < WI_TIMEOUT; i++) {
680 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_CMD)
681 break;
682 DELAY(1);
683 }
684
685 /* Ack the command */
686 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
687
688 s = CSR_READ_2(sc, WI_STATUS);
689 if (s & WI_STAT_CMD_RESULT)
690 return(EIO);
691
692 if (i == WI_TIMEOUT)
693 return(ETIMEDOUT);
694
695 return(0);
696 }
697
698 static void
699 wi_reset(sc)
700 struct wi_softc *sc;
701 {
702 DELAY(100*1000); /* 100 m sec */
703 if (wi_cmd(sc, WI_CMD_INI, 0))
704 printf("%s: init failed\n", sc->sc_dev.dv_xname);
705 CSR_WRITE_2(sc, WI_INT_EN, 0);
706 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
707
708 /* Calibrate timer. */
709 WI_SETVAL(WI_RID_TICK_TIME, 8);
710
711 return;
712 }
713
714 void
715 wi_pci_reset(sc)
716 struct wi_softc *sc;
717 {
718 bus_space_write_2(sc->sc_iot, sc->sc_ioh,
719 WI_PCI_COR, WI_PCI_SOFT_RESET);
720 DELAY(100*1000); /* 100 m sec */
721
722 bus_space_write_2(sc->sc_iot, sc->sc_ioh, WI_PCI_COR, 0x0);
723 DELAY(100*1000); /* 100 m sec */
724
725 return;
726 }
727
728 /*
729 * Read an LTV record from the NIC.
730 */
731 static int wi_read_record(sc, ltv)
732 struct wi_softc *sc;
733 struct wi_ltv_gen *ltv;
734 {
735 u_int16_t *ptr;
736 int len, code;
737 struct wi_ltv_gen *oltv, p2ltv;
738
739 if (sc->sc_prism2) {
740 oltv = ltv;
741 switch (ltv->wi_type) {
742 case WI_RID_ENCRYPTION:
743 p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
744 p2ltv.wi_len = 2;
745 ltv = &p2ltv;
746 break;
747 case WI_RID_TX_CRYPT_KEY:
748 p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
749 p2ltv.wi_len = 2;
750 ltv = &p2ltv;
751 break;
752 }
753 }
754
755 /* Tell the NIC to enter record read mode. */
756 if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type))
757 return(EIO);
758
759 /* Seek to the record. */
760 if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
761 return(EIO);
762
763 /*
764 * Read the length and record type and make sure they
765 * match what we expect (this verifies that we have enough
766 * room to hold all of the returned data).
767 */
768 len = CSR_READ_2(sc, WI_DATA1);
769 if (len > ltv->wi_len)
770 return(ENOSPC);
771 code = CSR_READ_2(sc, WI_DATA1);
772 if (code != ltv->wi_type)
773 return(EIO);
774
775 ltv->wi_len = len;
776 ltv->wi_type = code;
777
778 /* Now read the data. */
779 ptr = <v->wi_val;
780 if (ltv->wi_len > 1)
781 CSR_READ_MULTI_STREAM_2(sc, WI_DATA1, ptr, ltv->wi_len - 1);
782
783 if (sc->sc_prism2) {
784 int v;
785
786 switch (oltv->wi_type) {
787 case WI_RID_TX_RATE:
788 case WI_RID_CUR_TX_RATE:
789 switch (le16toh(ltv->wi_val)) {
790 case 1: v = 1; break;
791 case 2: v = 2; break;
792 case 3: v = 6; break;
793 case 4: v = 5; break;
794 case 7: v = 7; break;
795 case 8: v = 11; break;
796 case 15: v = 3; break;
797 default: v = 0x100 + le16toh(ltv->wi_val); break;
798 }
799 oltv->wi_val = htole16(v);
800 break;
801 case WI_RID_ENCRYPTION:
802 oltv->wi_len = 2;
803 if (le16toh(ltv->wi_val) & 0x01)
804 oltv->wi_val = htole16(1);
805 else
806 oltv->wi_val = htole16(0);
807 break;
808 case WI_RID_TX_CRYPT_KEY:
809 oltv->wi_len = 2;
810 oltv->wi_val = ltv->wi_val;
811 break;
812 case WI_RID_AUTH_CNTL:
813 oltv->wi_len = 2;
814 if (le16toh(ltv->wi_val) & 0x01)
815 oltv->wi_val = htole16(1);
816 else if (le16toh(ltv->wi_val) & 0x02)
817 oltv->wi_val = htole16(2);
818 break;
819 }
820 }
821
822 return(0);
823 }
824
825 /*
826 * Same as read, except we inject data instead of reading it.
827 */
828 static int wi_write_record(sc, ltv)
829 struct wi_softc *sc;
830 struct wi_ltv_gen *ltv;
831 {
832 u_int16_t *ptr;
833 int i;
834 struct wi_ltv_gen p2ltv;
835
836 if (sc->sc_prism2) {
837 int v;
838
839 switch (ltv->wi_type) {
840 case WI_RID_TX_RATE:
841 p2ltv.wi_type = WI_RID_TX_RATE;
842 p2ltv.wi_len = 2;
843 switch (le16toh(ltv->wi_val)) {
844 case 1: v = 1; break;
845 case 2: v = 2; break;
846 case 3: v = 15; break;
847 case 5: v = 4; break;
848 case 6: v = 3; break;
849 case 7: v = 7; break;
850 case 11: v = 8; break;
851 default: return EINVAL;
852 }
853 p2ltv.wi_val = htole16(v);
854 ltv = &p2ltv;
855 break;
856 case WI_RID_ENCRYPTION:
857 p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
858 p2ltv.wi_len = 2;
859 if (le16toh(ltv->wi_val))
860 p2ltv.wi_val = htole16(0x03);
861 else
862 p2ltv.wi_val = htole16(0x90);
863 ltv = &p2ltv;
864 break;
865 case WI_RID_TX_CRYPT_KEY:
866 p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
867 p2ltv.wi_len = 2;
868 p2ltv.wi_val = ltv->wi_val;
869 ltv = &p2ltv;
870 break;
871 case WI_RID_DEFLT_CRYPT_KEYS:
872 {
873 int error;
874 struct wi_ltv_str ws;
875 struct wi_ltv_keys *wk = (struct wi_ltv_keys *)ltv;
876 for (i = 0; i < 4; i++) {
877 ws.wi_len = 4;
878 ws.wi_type = WI_RID_P2_CRYPT_KEY0 + i;
879 memcpy(ws.wi_str, &wk->wi_keys[i].wi_keydat, 5);
880 ws.wi_str[5] = '\0';
881 error = wi_write_record(sc,
882 (struct wi_ltv_gen *)&ws);
883 if (error)
884 return error;
885 }
886 return 0;
887 }
888 case WI_RID_AUTH_CNTL:
889 p2ltv.wi_type = WI_RID_AUTH_CNTL;
890 p2ltv.wi_len = 2;
891 if (le16toh(ltv->wi_val) == 1)
892 p2ltv.wi_val = htole16(0x01);
893 else if (le16toh(ltv->wi_val) == 2)
894 p2ltv.wi_val = htole16(0x02);
895 ltv = &p2ltv;
896 break;
897 }
898 }
899
900 if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
901 return(EIO);
902
903 CSR_WRITE_2(sc, WI_DATA1, ltv->wi_len);
904 CSR_WRITE_2(sc, WI_DATA1, ltv->wi_type);
905
906 /* Write data */
907 ptr = <v->wi_val;
908 if (ltv->wi_len > 1)
909 CSR_WRITE_MULTI_STREAM_2(sc, WI_DATA1, ptr, ltv->wi_len - 1);
910
911 if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_WRITE, ltv->wi_type))
912 return(EIO);
913
914 return(0);
915 }
916
917 static int wi_seek(sc, id, off, chan)
918 struct wi_softc *sc;
919 int id, off, chan;
920 {
921 int i;
922 int selreg, offreg;
923 int status;
924
925 switch (chan) {
926 case WI_BAP0:
927 selreg = WI_SEL0;
928 offreg = WI_OFF0;
929 break;
930 case WI_BAP1:
931 selreg = WI_SEL1;
932 offreg = WI_OFF1;
933 break;
934 default:
935 printf("%s: invalid data path: %x\n",
936 sc->sc_dev.dv_xname, chan);
937 return(EIO);
938 }
939
940 CSR_WRITE_2(sc, selreg, id);
941 CSR_WRITE_2(sc, offreg, off);
942
943 for (i = 0; i < WI_TIMEOUT; i++) {
944 status = CSR_READ_2(sc, offreg);
945 if (!(status & (WI_OFF_BUSY|WI_OFF_ERR)))
946 break;
947 }
948
949 if (i == WI_TIMEOUT) {
950 printf("%s: timeout in wi_seek to %x/%x; last status %x\n",
951 sc->sc_dev.dv_xname, id, off, status);
952 return(ETIMEDOUT);
953 }
954 return(0);
955 }
956
957 static int wi_read_data(sc, id, off, buf, len)
958 struct wi_softc *sc;
959 int id, off;
960 caddr_t buf;
961 int len;
962 {
963 u_int16_t *ptr;
964
965 if (wi_seek(sc, id, off, WI_BAP1))
966 return(EIO);
967
968 ptr = (u_int16_t *)buf;
969 CSR_READ_MULTI_STREAM_2(sc, WI_DATA1, ptr, len / 2);
970
971 return(0);
972 }
973
974 /*
975 * According to the comments in the HCF Light code, there is a bug in
976 * the Hermes (or possibly in certain Hermes firmware revisions) where
977 * the chip's internal autoincrement counter gets thrown off during
978 * data writes: the autoincrement is missed, causing one data word to
979 * be overwritten and subsequent words to be written to the wrong memory
980 * locations. The end result is that we could end up transmitting bogus
981 * frames without realizing it. The workaround for this is to write a
982 * couple of extra guard words after the end of the transfer, then
983 * attempt to read then back. If we fail to locate the guard words where
984 * we expect them, we preform the transfer over again.
985 */
986 static int wi_write_data(sc, id, off, buf, len)
987 struct wi_softc *sc;
988 int id, off;
989 caddr_t buf;
990 int len;
991 {
992 u_int16_t *ptr;
993
994 #ifdef WI_HERMES_AUTOINC_WAR
995 again:
996 #endif
997
998 if (wi_seek(sc, id, off, WI_BAP0))
999 return(EIO);
1000
1001 ptr = (u_int16_t *)buf;
1002 CSR_WRITE_MULTI_STREAM_2(sc, WI_DATA0, ptr, len / 2);
1003
1004 #ifdef WI_HERMES_AUTOINC_WAR
1005 CSR_WRITE_2(sc, WI_DATA0, 0x1234);
1006 CSR_WRITE_2(sc, WI_DATA0, 0x5678);
1007
1008 if (wi_seek(sc, id, off + len, WI_BAP0))
1009 return(EIO);
1010
1011 if (CSR_READ_2(sc, WI_DATA0) != 0x1234 ||
1012 CSR_READ_2(sc, WI_DATA0) != 0x5678)
1013 goto again;
1014 #endif
1015
1016 return(0);
1017 }
1018
1019 /*
1020 * Allocate a region of memory inside the NIC and zero
1021 * it out.
1022 */
1023 static int wi_alloc_nicmem(sc, len, id)
1024 struct wi_softc *sc;
1025 int len;
1026 int *id;
1027 {
1028 int i;
1029
1030 if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len)) {
1031 printf("%s: failed to allocate %d bytes on NIC\n",
1032 sc->sc_dev.dv_xname, len);
1033 return(ENOMEM);
1034 }
1035
1036 for (i = 0; i < WI_TIMEOUT; i++) {
1037 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC)
1038 break;
1039 }
1040
1041 if (i == WI_TIMEOUT) {
1042 printf("%s: TIMED OUT in alloc\n", sc->sc_dev.dv_xname);
1043 return(ETIMEDOUT);
1044 }
1045
1046 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
1047 *id = CSR_READ_2(sc, WI_ALLOC_FID);
1048
1049 if (wi_seek(sc, *id, 0, WI_BAP0)) {
1050 printf("%s: seek failed in alloc\n", sc->sc_dev.dv_xname);
1051 return(EIO);
1052 }
1053
1054 for (i = 0; i < len / 2; i++)
1055 CSR_WRITE_2(sc, WI_DATA0, 0);
1056
1057 return(0);
1058 }
1059
1060 static void wi_setmulti(sc)
1061 struct wi_softc *sc;
1062 {
1063 struct ifnet *ifp;
1064 int i = 0;
1065 struct wi_ltv_mcast mcast;
1066 struct ether_multi *enm;
1067 struct ether_multistep estep;
1068 struct ethercom *ec = &sc->sc_ethercom;
1069
1070 ifp = &sc->sc_ethercom.ec_if;
1071
1072 if ((ifp->if_flags & IFF_PROMISC) != 0) {
1073 allmulti:
1074 ifp->if_flags |= IFF_ALLMULTI;
1075 memset((char *)&mcast, 0, sizeof(mcast));
1076 mcast.wi_type = WI_RID_MCAST_LIST;
1077 mcast.wi_len = ((ETHER_ADDR_LEN / 2) * 16) + 1;
1078
1079 wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
1080 return;
1081 }
1082
1083 i = 0;
1084 ETHER_FIRST_MULTI(estep, ec, enm);
1085 while (enm != NULL) {
1086 /* Punt on ranges or too many multicast addresses. */
1087 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
1088 ETHER_ADDR_LEN) != 0 ||
1089 i >= 16)
1090 goto allmulti;
1091
1092 memcpy((char *)&mcast.wi_mcast[i], enm->enm_addrlo,
1093 ETHER_ADDR_LEN);
1094 i++;
1095 ETHER_NEXT_MULTI(estep, enm);
1096 }
1097
1098 ifp->if_flags &= ~IFF_ALLMULTI;
1099 mcast.wi_type = WI_RID_MCAST_LIST;
1100 mcast.wi_len = ((ETHER_ADDR_LEN / 2) * i) + 1;
1101 wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
1102 }
1103
1104 static int
1105 wi_setdef(sc, wreq)
1106 struct wi_softc *sc;
1107 struct wi_req *wreq;
1108 {
1109 struct sockaddr_dl *sdl;
1110 struct ifnet *ifp;
1111 int error = 0;
1112
1113 ifp = &sc->sc_ethercom.ec_if;
1114
1115 switch(wreq->wi_type) {
1116 case WI_RID_MAC_NODE:
1117 sdl = (struct sockaddr_dl *)ifp->if_sadl;
1118 memcpy((char *)&sc->sc_macaddr, (char *)&wreq->wi_val,
1119 ETHER_ADDR_LEN);
1120 memcpy(LLADDR(sdl), (char *)&wreq->wi_val, ETHER_ADDR_LEN);
1121 break;
1122 case WI_RID_PORTTYPE:
1123 error = wi_sync_media(sc, le16toh(wreq->wi_val[0]), sc->wi_tx_rate);
1124 break;
1125 case WI_RID_TX_RATE:
1126 error = wi_sync_media(sc, sc->wi_ptype, le16toh(wreq->wi_val[0]));
1127 break;
1128 case WI_RID_MAX_DATALEN:
1129 sc->wi_max_data_len = le16toh(wreq->wi_val[0]);
1130 break;
1131 case WI_RID_RTS_THRESH:
1132 sc->wi_rts_thresh = le16toh(wreq->wi_val[0]);
1133 break;
1134 case WI_RID_SYSTEM_SCALE:
1135 sc->wi_ap_density = le16toh(wreq->wi_val[0]);
1136 break;
1137 case WI_RID_CREATE_IBSS:
1138 sc->wi_create_ibss = le16toh(wreq->wi_val[0]);
1139 break;
1140 case WI_RID_OWN_CHNL:
1141 sc->wi_channel = le16toh(wreq->wi_val[0]);
1142 break;
1143 case WI_RID_NODENAME:
1144 error = wi_set_ssid(&sc->wi_nodeid,
1145 (u_int8_t *)&wreq->wi_val[1], le16toh(wreq->wi_val[0]));
1146 break;
1147 case WI_RID_DESIRED_SSID:
1148 error = wi_set_ssid(&sc->wi_netid,
1149 (u_int8_t *)&wreq->wi_val[1], le16toh(wreq->wi_val[0]));
1150 break;
1151 case WI_RID_OWN_SSID:
1152 error = wi_set_ssid(&sc->wi_ibssid,
1153 (u_int8_t *)&wreq->wi_val[1], le16toh(wreq->wi_val[0]));
1154 break;
1155 case WI_RID_PM_ENABLED:
1156 sc->wi_pm_enabled = le16toh(wreq->wi_val[0]);
1157 break;
1158 case WI_RID_MICROWAVE_OVEN:
1159 sc->wi_mor_enabled = le16toh(wreq->wi_val[0]);
1160 break;
1161 case WI_RID_MAX_SLEEP:
1162 sc->wi_max_sleep = le16toh(wreq->wi_val[0]);
1163 break;
1164 case WI_RID_AUTH_CNTL:
1165 sc->wi_authtype = le16toh(wreq->wi_val[0]);
1166 break;
1167 case WI_RID_ROAMING_MODE:
1168 sc->wi_roaming = le16toh(wreq->wi_val[0]);
1169 break;
1170 case WI_RID_ENCRYPTION:
1171 sc->wi_use_wep = le16toh(wreq->wi_val[0]);
1172 break;
1173 case WI_RID_TX_CRYPT_KEY:
1174 sc->wi_tx_key = le16toh(wreq->wi_val[0]);
1175 break;
1176 case WI_RID_DEFLT_CRYPT_KEYS:
1177 memcpy((char *)&sc->wi_keys, (char *)wreq,
1178 sizeof(struct wi_ltv_keys));
1179 break;
1180 default:
1181 error = EINVAL;
1182 break;
1183 }
1184
1185 return (error);
1186 }
1187
1188 static int
1189 wi_getdef(sc, wreq)
1190 struct wi_softc *sc;
1191 struct wi_req *wreq;
1192 {
1193 struct sockaddr_dl *sdl;
1194 struct ifnet *ifp;
1195 int error = 0;
1196
1197 ifp = &sc->sc_ethercom.ec_if;
1198
1199 wreq->wi_len = 2; /* XXX */
1200 switch (wreq->wi_type) {
1201 case WI_RID_MAC_NODE:
1202 wreq->wi_len += ETHER_ADDR_LEN / 2 - 1;
1203 sdl = (struct sockaddr_dl *)ifp->if_sadl;
1204 memcpy(&wreq->wi_val, &sc->sc_macaddr, ETHER_ADDR_LEN);
1205 memcpy(&wreq->wi_val, LLADDR(sdl), ETHER_ADDR_LEN);
1206 break;
1207 case WI_RID_PORTTYPE:
1208 wreq->wi_val[0] = htole16(sc->wi_ptype);
1209 break;
1210 case WI_RID_TX_RATE:
1211 wreq->wi_val[0] = htole16(sc->wi_tx_rate);
1212 break;
1213 case WI_RID_MAX_DATALEN:
1214 wreq->wi_val[0] = htole16(sc->wi_max_data_len);
1215 break;
1216 case WI_RID_RTS_THRESH:
1217 wreq->wi_val[0] = htole16(sc->wi_rts_thresh);
1218 break;
1219 case WI_RID_SYSTEM_SCALE:
1220 wreq->wi_val[0] = htole16(sc->wi_ap_density);
1221 break;
1222 case WI_RID_CREATE_IBSS:
1223 wreq->wi_val[0] = htole16(sc->wi_create_ibss);
1224 break;
1225 case WI_RID_OWN_CHNL:
1226 wreq->wi_val[0] = htole16(sc->wi_channel);
1227 break;
1228 case WI_RID_NODENAME:
1229 wi_request_fill_ssid(wreq, &sc->wi_nodeid);
1230 break;
1231 case WI_RID_DESIRED_SSID:
1232 wi_request_fill_ssid(wreq, &sc->wi_netid);
1233 break;
1234 case WI_RID_OWN_SSID:
1235 wi_request_fill_ssid(wreq, &sc->wi_ibssid);
1236 break;
1237 case WI_RID_PM_ENABLED:
1238 wreq->wi_val[0] = htole16(sc->wi_pm_enabled);
1239 break;
1240 case WI_RID_MICROWAVE_OVEN:
1241 wreq->wi_val[0] = htole16(sc->wi_mor_enabled);
1242 break;
1243 case WI_RID_MAX_SLEEP:
1244 wreq->wi_val[0] = htole16(sc->wi_max_sleep);
1245 break;
1246 case WI_RID_AUTH_CNTL:
1247 wreq->wi_val[0] = htole16(sc->wi_authtype);
1248 break;
1249 case WI_RID_ROAMING_MODE:
1250 wreq->wi_val[0] = htole16(sc->wi_roaming);
1251 break;
1252 case WI_RID_WEP_AVAIL:
1253 wreq->wi_val[0] = htole16(sc->wi_has_wep);
1254 break;
1255 case WI_RID_ENCRYPTION:
1256 wreq->wi_val[0] = htole16(sc->wi_use_wep);
1257 break;
1258 case WI_RID_TX_CRYPT_KEY:
1259 wreq->wi_val[0] = htole16(sc->wi_tx_key);
1260 break;
1261 case WI_RID_DEFLT_CRYPT_KEYS:
1262 wreq->wi_len += sizeof(struct wi_ltv_keys) / 2 - 1;
1263 memcpy(wreq, &sc->wi_keys, sizeof(struct wi_ltv_keys));
1264 break;
1265 default:
1266 #if 0
1267 error = EIO;
1268 #else
1269 #ifdef WI_DEBUG
1270 printf("%s: wi_getdef: unknown request %d\n",
1271 sc->sc_dev.dv_xname, wreq->wi_type);
1272 #endif
1273 #endif
1274 break;
1275 }
1276
1277 return (error);
1278 }
1279
1280 static int
1281 wi_ioctl(ifp, command, data)
1282 struct ifnet *ifp;
1283 u_long command;
1284 caddr_t data;
1285 {
1286 int i, s, error = 0;
1287 struct wi_softc *sc = ifp->if_softc;
1288 struct wi_req wreq;
1289 struct ifreq *ifr;
1290 struct ifdrv *ifd;
1291 struct proc *p = curproc->l_proc;
1292 struct ieee80211_nwid nwid;
1293
1294 if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
1295 return (ENXIO);
1296
1297 s = splnet();
1298
1299 ifr = (struct ifreq *)data;
1300 switch (command) {
1301 case SIOCSIFADDR:
1302 case SIOCGIFADDR:
1303 case SIOCSIFMTU:
1304 error = ether_ioctl(ifp, command, data);
1305 break;
1306 case SIOCSIFFLAGS:
1307 if (ifp->if_flags & IFF_UP) {
1308 if (ifp->if_flags & IFF_RUNNING &&
1309 ifp->if_flags & IFF_PROMISC &&
1310 !(sc->wi_if_flags & IFF_PROMISC)) {
1311 WI_SETVAL(WI_RID_PROMISC, 1);
1312 } else if (ifp->if_flags & IFF_RUNNING &&
1313 !(ifp->if_flags & IFF_PROMISC) &&
1314 sc->wi_if_flags & IFF_PROMISC) {
1315 WI_SETVAL(WI_RID_PROMISC, 0);
1316 }
1317 wi_init(ifp);
1318 } else {
1319 if (ifp->if_flags & IFF_RUNNING) {
1320 wi_stop(ifp, 0);
1321 }
1322 }
1323 sc->wi_if_flags = ifp->if_flags;
1324
1325 if (!(ifp->if_flags & IFF_UP)) {
1326 if (sc->sc_enabled) {
1327 if (sc->sc_disable)
1328 (*sc->sc_disable)(sc);
1329 sc->sc_enabled = 0;
1330 ifp->if_flags &= ~IFF_RUNNING;
1331 }
1332 }
1333 error = 0;
1334 break;
1335 case SIOCADDMULTI:
1336 case SIOCDELMULTI:
1337 error = (command == SIOCADDMULTI) ?
1338 ether_addmulti(ifr, &sc->sc_ethercom) :
1339 ether_delmulti(ifr, &sc->sc_ethercom);
1340 if (error == ENETRESET) {
1341 if (sc->sc_enabled != 0) {
1342 /*
1343 * Multicast list has changed. Set the
1344 * hardware filter accordingly.
1345 */
1346 wi_setmulti(sc);
1347 }
1348 error = 0;
1349 }
1350 break;
1351 case SIOCSIFMEDIA:
1352 case SIOCGIFMEDIA:
1353 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, command);
1354 break;
1355 case SIOCGWAVELAN:
1356 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1357 if (error)
1358 break;
1359 switch (wreq.wi_type) {
1360 case WI_RID_IFACE_STATS:
1361 /* XXX native byte order */
1362 memcpy((char *)&wreq.wi_val, (char *)&sc->wi_stats,
1363 sizeof(sc->wi_stats));
1364 wreq.wi_len = (sizeof(sc->wi_stats) / 2) + 1;
1365 break;
1366 case WI_RID_DEFLT_CRYPT_KEYS:
1367 /* For non-root user, return all-zeroes keys */
1368 if (suser(p->p_ucred, &p->p_acflag))
1369 memset((char *)&wreq, 0,
1370 sizeof(struct wi_ltv_keys));
1371 else
1372 memcpy((char *)&wreq, (char *)&sc->wi_keys,
1373 sizeof(struct wi_ltv_keys));
1374 break;
1375 default:
1376 if (sc->sc_enabled == 0)
1377 error = wi_getdef(sc, &wreq);
1378 else if (wi_read_record(sc,
1379 (struct wi_ltv_gen *)&wreq))
1380 error = EINVAL;
1381 break;
1382 }
1383 if (error == 0)
1384 error = copyout(&wreq, ifr->ifr_data, sizeof(wreq));
1385 break;
1386
1387 case SIOCSWAVELAN:
1388 error = suser(p->p_ucred, &p->p_acflag);
1389 if (error)
1390 break;
1391 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1392 if (error)
1393 break;
1394 switch (wreq.wi_type) {
1395 case WI_RID_IFACE_STATS:
1396 error = EINVAL;
1397 break;
1398 case WI_RID_MGMT_XMIT:
1399 error = wi_mgmt_xmit(sc, (caddr_t)&wreq.wi_val,
1400 wreq.wi_len);
1401 break;
1402
1403 default:
1404 if (sc->sc_enabled != 0)
1405 error = wi_write_record(sc,
1406 (struct wi_ltv_gen *)&wreq);
1407 if (error == 0)
1408 error = wi_setdef(sc, &wreq);
1409 if (error == 0 && sc->sc_enabled != 0)
1410 /* Reinitialize WaveLAN. */
1411 wi_init(ifp);
1412 break;
1413 }
1414 break;
1415
1416 case SIOCSDRVSPEC:
1417 error = suser(p->p_ucred, &p->p_acflag);
1418 if (error)
1419 break;
1420 ifd = (struct ifdrv *)data;
1421 switch (ifd->ifd_cmd) {
1422 case WI_IOCTL_SET_SCAN:
1423 error = copyin(ifd->ifd_data, &i, sizeof (i));
1424 if (error)
1425 break;
1426
1427 sc->wi_results.scanning = i;
1428 if (sc->wi_results.scanning > 0)
1429 callout_reset(&sc->wi_scan_ch,
1430 sc->wi_results.scanning,
1431 wi_inquire_scan, sc);
1432 else
1433 callout_stop(&sc->wi_scan_ch);
1434 break;
1435
1436 /*
1437 * Experimental XXXMLG
1438 */
1439 case WI_IOCTL_SET_TESTMODE:
1440 error = copyin(ifd->ifd_data, &i, sizeof (i));
1441 if (error)
1442 break;
1443 if (i) {
1444 wi_cmd(sc, WI_CMD_TEST | WI_TEST_MONITOR << 8,
1445 0);
1446 printf("wi test mode enabled\n");
1447 } else {
1448 wi_cmd(sc, WI_CMD_TEST | WI_TEST_STOP << 8, 0);
1449 printf("wi test mode disabled\n");
1450 }
1451 break;
1452
1453 default:
1454 error = EINVAL;
1455 break;
1456 }
1457 break;
1458
1459 case SIOCGDRVSPEC:
1460 ifd = (struct ifdrv *)data;
1461 switch (ifd->ifd_cmd) {
1462 case WI_IOCTL_GET_SCAN_RESULTS:
1463 error = copyout(&sc->wi_results, ifd->ifd_data,
1464 sizeof(struct wi_scan_results));
1465 break;
1466
1467 default:
1468 error = EINVAL;
1469 break;
1470 }
1471 break;
1472
1473 case SIOCG80211NWID:
1474 if (sc->sc_enabled == 0) {
1475 /* Return the desired ID */
1476 error = copyout(&sc->wi_netid, ifr->ifr_data,
1477 sizeof(sc->wi_netid));
1478 } else {
1479 wreq.wi_type = WI_RID_CURRENT_SSID;
1480 wreq.wi_len = WI_MAX_DATALEN;
1481 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) ||
1482 le16toh(wreq.wi_val[0]) > IEEE80211_NWID_LEN)
1483 error = EINVAL;
1484 else {
1485 wi_set_ssid(&nwid, (u_int8_t *)&wreq.wi_val[1],
1486 le16toh(wreq.wi_val[0]));
1487 error = copyout(&nwid, ifr->ifr_data,
1488 sizeof(nwid));
1489 }
1490 }
1491 break;
1492 case SIOCS80211NWID:
1493 error = copyin(ifr->ifr_data, &nwid, sizeof(nwid));
1494 if (error != 0)
1495 break;
1496 if (nwid.i_len > IEEE80211_NWID_LEN) {
1497 error = EINVAL;
1498 break;
1499 }
1500 if (sc->wi_netid.i_len == nwid.i_len &&
1501 memcmp(sc->wi_netid.i_nwid, nwid.i_nwid, nwid.i_len) == 0)
1502 break;
1503 wi_set_ssid(&sc->wi_netid, nwid.i_nwid, nwid.i_len);
1504 if (sc->sc_enabled != 0)
1505 /* Reinitialize WaveLAN. */
1506 wi_init(ifp);
1507 break;
1508 case SIOCS80211NWKEY:
1509 error = wi_set_nwkey(sc, (struct ieee80211_nwkey *)data);
1510 break;
1511 case SIOCG80211NWKEY:
1512 error = wi_get_nwkey(sc, (struct ieee80211_nwkey *)data);
1513 break;
1514 case SIOCS80211POWER:
1515 error = wi_set_pm(sc, (struct ieee80211_power *)data);
1516 break;
1517 case SIOCG80211POWER:
1518 error = wi_get_pm(sc, (struct ieee80211_power *)data);
1519 break;
1520
1521 default:
1522 error = EINVAL;
1523 break;
1524 }
1525
1526 splx(s);
1527 return (error);
1528 }
1529
1530 static int
1531 wi_init(ifp)
1532 struct ifnet *ifp;
1533 {
1534 struct wi_softc *sc = ifp->if_softc;
1535 struct wi_req wreq;
1536 struct wi_ltv_macaddr mac;
1537 int error, id = 0;
1538
1539 if (!sc->sc_enabled) {
1540 if ((error = (*sc->sc_enable)(sc)) != 0)
1541 goto out;
1542 sc->sc_enabled = 1;
1543 }
1544
1545 wi_stop(ifp, 0);
1546 wi_reset(sc);
1547
1548 /* Program max data length. */
1549 WI_SETVAL(WI_RID_MAX_DATALEN, sc->wi_max_data_len);
1550
1551 /* Enable/disable IBSS creation. */
1552 WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss);
1553
1554 /* Set the port type. */
1555 WI_SETVAL(WI_RID_PORTTYPE, sc->wi_ptype);
1556
1557 /* Program the RTS/CTS threshold. */
1558 WI_SETVAL(WI_RID_RTS_THRESH, sc->wi_rts_thresh);
1559
1560 /* Program the TX rate */
1561 WI_SETVAL(WI_RID_TX_RATE, sc->wi_tx_rate);
1562
1563 /* Access point density */
1564 WI_SETVAL(WI_RID_SYSTEM_SCALE, sc->wi_ap_density);
1565
1566 /* Power Management Enabled */
1567 WI_SETVAL(WI_RID_PM_ENABLED, sc->wi_pm_enabled);
1568
1569 /* Power Managment Max Sleep */
1570 WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep);
1571
1572 /* Roaming type */
1573 WI_SETVAL(WI_RID_ROAMING_MODE, sc->wi_roaming);
1574
1575 /* Specify the IBSS name */
1576 wi_write_ssid(sc, WI_RID_OWN_SSID, &wreq, &sc->wi_ibssid);
1577
1578 /* Specify the network name */
1579 wi_write_ssid(sc, WI_RID_DESIRED_SSID, &wreq, &sc->wi_netid);
1580
1581 /* Specify the frequency to use */
1582 WI_SETVAL(WI_RID_OWN_CHNL, sc->wi_channel);
1583
1584 /* Program the nodename. */
1585 wi_write_ssid(sc, WI_RID_NODENAME, &wreq, &sc->wi_nodeid);
1586
1587 /* Set our MAC address. */
1588 mac.wi_len = 4;
1589 mac.wi_type = WI_RID_MAC_NODE;
1590 memcpy(&mac.wi_mac_addr, sc->sc_macaddr, ETHER_ADDR_LEN);
1591 wi_write_record(sc, (struct wi_ltv_gen *)&mac);
1592
1593 /* Initialize promisc mode. */
1594 if (ifp->if_flags & IFF_PROMISC) {
1595 WI_SETVAL(WI_RID_PROMISC, 1);
1596 } else {
1597 WI_SETVAL(WI_RID_PROMISC, 0);
1598 }
1599
1600 /* Configure WEP. */
1601 if (sc->wi_has_wep) {
1602 WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep);
1603 WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key);
1604 sc->wi_keys.wi_len = (sizeof(struct wi_ltv_keys) / 2) + 1;
1605 sc->wi_keys.wi_type = WI_RID_DEFLT_CRYPT_KEYS;
1606 wi_write_record(sc, (struct wi_ltv_gen *)&sc->wi_keys);
1607 if (sc->sc_prism2 && sc->wi_use_wep) {
1608 /*
1609 * ONLY HWB3163 EVAL-CARD Firmware version
1610 * less than 0.8 variant3
1611 *
1612 * If promiscuous mode disable, Prism2 chip
1613 * does not work with WEP .
1614 * It is under investigation for details.
1615 * (ichiro (at) netbsd.org)
1616 */
1617 if (sc->sc_prism2_ver < 83 ) {
1618 /* firm ver < 0.8 variant 3 */
1619 WI_SETVAL(WI_RID_PROMISC, 1);
1620 }
1621 WI_SETVAL(WI_RID_AUTH_CNTL, sc->wi_authtype);
1622 }
1623 }
1624
1625 /* Set multicast filter. */
1626 wi_setmulti(sc);
1627
1628 /* Enable desired port */
1629 wi_cmd(sc, WI_CMD_ENABLE | sc->wi_portnum, 0);
1630
1631 if ((error = wi_alloc_nicmem(sc,
1632 1518 + sizeof(struct wi_frame) + 8, &id)) != 0) {
1633 printf("%s: tx buffer allocation failed\n",
1634 sc->sc_dev.dv_xname);
1635 goto out;
1636 }
1637 sc->wi_tx_data_id = id;
1638
1639 if ((error = wi_alloc_nicmem(sc,
1640 1518 + sizeof(struct wi_frame) + 8, &id)) != 0) {
1641 printf("%s: mgmt. buffer allocation failed\n",
1642 sc->sc_dev.dv_xname);
1643 goto out;
1644 }
1645 sc->wi_tx_mgmt_id = id;
1646
1647 /* Enable interrupts */
1648 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
1649
1650 ifp->if_flags |= IFF_RUNNING;
1651 ifp->if_flags &= ~IFF_OACTIVE;
1652
1653 callout_reset(&sc->wi_stats_ch, STATS_FREQUENCY, wi_inquire_stats, sc);
1654
1655 out:
1656 if (error) {
1657 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1658 ifp->if_timer = 0;
1659 printf("%s: interface not running\n", sc->sc_dev.dv_xname);
1660 }
1661 return (error);
1662 }
1663
1664 static void
1665 wi_start(ifp)
1666 struct ifnet *ifp;
1667 {
1668 struct wi_softc *sc;
1669 struct mbuf *m0;
1670 struct wi_frame tx_frame;
1671 struct ether_header *eh;
1672 int id;
1673
1674 sc = ifp->if_softc;
1675
1676 if (ifp->if_flags & IFF_OACTIVE)
1677 return;
1678
1679 IFQ_DEQUEUE(&ifp->if_snd, m0);
1680 if (m0 == NULL)
1681 return;
1682
1683 memset((char *)&tx_frame, 0, sizeof(tx_frame));
1684 id = sc->wi_tx_data_id;
1685 eh = mtod(m0, struct ether_header *);
1686
1687 /*
1688 * Use RFC1042 encoding for IP and ARP datagrams,
1689 * 802.3 for anything else.
1690 */
1691 if (ntohs(eh->ether_type) == ETHERTYPE_IP ||
1692 ntohs(eh->ether_type) == ETHERTYPE_ARP ||
1693 ntohs(eh->ether_type) == ETHERTYPE_REVARP ||
1694 ntohs(eh->ether_type) == ETHERTYPE_IPV6) {
1695 memcpy((char *)&tx_frame.wi_addr1, (char *)&eh->ether_dhost,
1696 ETHER_ADDR_LEN);
1697 memcpy((char *)&tx_frame.wi_addr2, (char *)&eh->ether_shost,
1698 ETHER_ADDR_LEN);
1699 memcpy((char *)&tx_frame.wi_dst_addr, (char *)&eh->ether_dhost,
1700 ETHER_ADDR_LEN);
1701 memcpy((char *)&tx_frame.wi_src_addr, (char *)&eh->ether_shost,
1702 ETHER_ADDR_LEN);
1703
1704 tx_frame.wi_dat_len = htole16(m0->m_pkthdr.len - WI_SNAPHDR_LEN);
1705 tx_frame.wi_frame_ctl = htole16(WI_FTYPE_DATA);
1706 tx_frame.wi_dat[0] = htons(WI_SNAP_WORD0);
1707 tx_frame.wi_dat[1] = htons(WI_SNAP_WORD1);
1708 tx_frame.wi_len = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN);
1709 tx_frame.wi_type = eh->ether_type;
1710
1711 m_copydata(m0, sizeof(struct ether_header),
1712 m0->m_pkthdr.len - sizeof(struct ether_header),
1713 (caddr_t)&sc->wi_txbuf);
1714
1715 wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
1716 sizeof(struct wi_frame));
1717 wi_write_data(sc, id, WI_802_11_OFFSET, (caddr_t)&sc->wi_txbuf,
1718 (m0->m_pkthdr.len - sizeof(struct ether_header)) + 2);
1719 } else {
1720 tx_frame.wi_dat_len = htole16(m0->m_pkthdr.len);
1721
1722 m_copydata(m0, 0, m0->m_pkthdr.len, (caddr_t)&sc->wi_txbuf);
1723
1724 wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
1725 sizeof(struct wi_frame));
1726 wi_write_data(sc, id, WI_802_3_OFFSET, (caddr_t)&sc->wi_txbuf,
1727 m0->m_pkthdr.len + 2);
1728 }
1729
1730 #if NBPFILTER > 0
1731 /*
1732 * If there's a BPF listener, bounce a copy of
1733 * this frame to him.
1734 */
1735 if (ifp->if_bpf)
1736 bpf_mtap(ifp->if_bpf, m0);
1737 #endif
1738
1739 m_freem(m0);
1740
1741 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id))
1742 printf("%s: xmit failed\n", sc->sc_dev.dv_xname);
1743
1744 ifp->if_flags |= IFF_OACTIVE;
1745
1746 /*
1747 * Set a timeout in case the chip goes out to lunch.
1748 */
1749 ifp->if_timer = 5;
1750
1751 return;
1752 }
1753
1754 static int
1755 wi_mgmt_xmit(sc, data, len)
1756 struct wi_softc *sc;
1757 caddr_t data;
1758 int len;
1759 {
1760 struct wi_frame tx_frame;
1761 int id;
1762 struct wi_80211_hdr *hdr;
1763 caddr_t dptr;
1764
1765 hdr = (struct wi_80211_hdr *)data;
1766 dptr = data + sizeof(struct wi_80211_hdr);
1767
1768 memset((char *)&tx_frame, 0, sizeof(tx_frame));
1769 id = sc->wi_tx_mgmt_id;
1770
1771 memcpy((char *)&tx_frame.wi_frame_ctl, (char *)hdr,
1772 sizeof(struct wi_80211_hdr));
1773
1774 tx_frame.wi_dat_len = htole16(len - WI_SNAPHDR_LEN);
1775 tx_frame.wi_len = htons(len - WI_SNAPHDR_LEN);
1776
1777 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, sizeof(struct wi_frame));
1778 wi_write_data(sc, id, WI_802_11_OFFSET_RAW, dptr,
1779 (len - sizeof(struct wi_80211_hdr)) + 2);
1780
1781 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id)) {
1782 printf("%s: xmit failed\n", sc->sc_dev.dv_xname);
1783 return(EIO);
1784 }
1785
1786 return(0);
1787 }
1788
1789 static void
1790 wi_stop(ifp, disable)
1791 struct ifnet *ifp;
1792 {
1793 struct wi_softc *sc = ifp->if_softc;
1794
1795 CSR_WRITE_2(sc, WI_INT_EN, 0);
1796 wi_cmd(sc, WI_CMD_DISABLE|sc->wi_portnum, 0);
1797
1798 callout_stop(&sc->wi_stats_ch);
1799 callout_stop(&sc->wi_scan_ch);
1800
1801 if (disable) {
1802 if (sc->sc_enabled) {
1803 if (sc->sc_disable)
1804 (*sc->sc_disable)(sc);
1805 sc->sc_enabled = 0;
1806 }
1807 }
1808
1809 ifp->if_flags &= ~(IFF_OACTIVE | IFF_RUNNING);
1810 ifp->if_timer = 0;
1811 }
1812
1813 static void
1814 wi_watchdog(ifp)
1815 struct ifnet *ifp;
1816 {
1817 struct wi_softc *sc;
1818
1819 sc = ifp->if_softc;
1820
1821 printf("%s: device timeout\n", sc->sc_dev.dv_xname);
1822
1823 wi_init(ifp);
1824
1825 ifp->if_oerrors++;
1826
1827 return;
1828 }
1829
1830 void
1831 wi_shutdown(sc)
1832 struct wi_softc *sc;
1833 {
1834 int s;
1835
1836 s = splnet();
1837 if (sc->sc_enabled) {
1838 if (sc->sc_disable)
1839 (*sc->sc_disable)(sc);
1840 sc->sc_enabled = 0;
1841 }
1842 splx(s);
1843 }
1844
1845 int
1846 wi_activate(self, act)
1847 struct device *self;
1848 enum devact act;
1849 {
1850 struct wi_softc *sc = (struct wi_softc *)self;
1851 int rv = 0, s;
1852
1853 s = splnet();
1854 switch (act) {
1855 case DVACT_ACTIVATE:
1856 rv = EOPNOTSUPP;
1857 break;
1858
1859 case DVACT_DEACTIVATE:
1860 if_deactivate(&sc->sc_ethercom.ec_if);
1861 break;
1862 }
1863 splx(s);
1864 return (rv);
1865 }
1866
1867 static void
1868 wi_get_id(sc)
1869 struct wi_softc *sc;
1870 {
1871 struct wi_ltv_ver ver;
1872
1873 /* getting chip identity */
1874 memset(&ver, 0, sizeof(ver));
1875 ver.wi_type = WI_RID_CARD_ID;
1876 ver.wi_len = 5;
1877 wi_read_record(sc, (struct wi_ltv_gen *)&ver);
1878 printf("%s: using ", sc->sc_dev.dv_xname);
1879 switch (le16toh(ver.wi_ver[0])) {
1880 case WI_NIC_EVB2:
1881 printf("RF:PRISM2 MAC:HFA3841");
1882 sc->sc_prism2 = 1;
1883 break;
1884 case WI_NIC_HWB3763:
1885 printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3763 rev.B");
1886 sc->sc_prism2 = 1;
1887 break;
1888 case WI_NIC_HWB3163:
1889 printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163 rev.A");
1890 sc->sc_prism2 = 1;
1891 break;
1892 case WI_NIC_HWB3163B:
1893 printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163 rev.B");
1894 sc->sc_prism2 = 1;
1895 break;
1896 case WI_NIC_EVB3:
1897 printf("RF:PRISM2 MAC:HFA3842");
1898 sc->sc_prism2 = 1;
1899 break;
1900 case WI_NIC_HWB1153:
1901 printf("RF:PRISM1 MAC:HFA3841 CARD:HWB1153");
1902 sc->sc_prism2 = 1;
1903 break;
1904 case WI_NIC_P2_SST:
1905 printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163-SST-flash");
1906 sc->sc_prism2 = 1;
1907 break;
1908 case WI_NIC_PRISM2_5:
1909 printf("RF:PRISM2.5 MAC:ISL3873");
1910 sc->sc_prism2 = 1;
1911 break;
1912 case WI_NIC_3874A:
1913 printf("RF:PRISM2.5 MAC:ISL3874A(PCI)");
1914 sc->sc_prism2 = 1;
1915 break;
1916 default:
1917 printf("Lucent chip or unknown chip\n");
1918 sc->sc_prism2 = 0;
1919 break;
1920 }
1921
1922 if (sc->sc_prism2) {
1923 /* try to get prism2 firm version */
1924 memset(&ver, 0, sizeof(ver));
1925 ver.wi_type = WI_RID_STA_IDENTITY;
1926 ver.wi_len = 5;
1927 wi_read_record(sc, (struct wi_ltv_gen *)&ver);
1928 LE16TOH(ver.wi_ver[1]);
1929 LE16TOH(ver.wi_ver[2]);
1930 LE16TOH(ver.wi_ver[3]);
1931 printf(", Firmware: %i.%i variant %i\n", ver.wi_ver[2],
1932 ver.wi_ver[3], ver.wi_ver[1]);
1933 sc->sc_prism2_ver = ver.wi_ver[2] * 100 +
1934 ver.wi_ver[3] * 10 + ver.wi_ver[1];
1935 }
1936
1937 return;
1938 }
1939
1940 int
1941 wi_detach(sc)
1942 struct wi_softc *sc;
1943 {
1944 struct ifnet *ifp = sc->sc_ifp;
1945 int s;
1946
1947 if (!sc->sc_attached)
1948 return (0);
1949
1950 s = splnet();
1951 callout_stop(&sc->wi_stats_ch);
1952 callout_stop(&sc->wi_scan_ch);
1953
1954 /* Delete all remaining media. */
1955 ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
1956
1957 ether_ifdetach(ifp);
1958 if_detach(ifp);
1959 if (sc->sc_enabled) {
1960 if (sc->sc_disable)
1961 (*sc->sc_disable)(sc);
1962 sc->sc_enabled = 0;
1963 }
1964 splx(s);
1965 return (0);
1966 }
1967
1968 void
1969 wi_power(sc, why)
1970 struct wi_softc *sc;
1971 int why;
1972 {
1973 int s;
1974
1975 if (!sc->sc_enabled)
1976 return;
1977
1978 s = splnet();
1979 switch (why) {
1980 case PWR_SUSPEND:
1981 case PWR_STANDBY:
1982 wi_stop(sc->sc_ifp, 0);
1983 if (sc->sc_enabled) {
1984 if (sc->sc_disable)
1985 (*sc->sc_disable)(sc);
1986 }
1987 break;
1988 case PWR_RESUME:
1989 sc->sc_enabled = 0;
1990 wi_init(sc->sc_ifp);
1991 (void)wi_intr(sc);
1992 break;
1993 case PWR_SOFTSUSPEND:
1994 case PWR_SOFTSTANDBY:
1995 case PWR_SOFTRESUME:
1996 break;
1997 }
1998 splx(s);
1999 }
2000
2001 static int
2002 wi_set_ssid(ws, id, len)
2003 struct ieee80211_nwid *ws;
2004 u_int8_t *id;
2005 int len;
2006 {
2007
2008 if (len > IEEE80211_NWID_LEN)
2009 return (EINVAL);
2010 ws->i_len = len;
2011 memcpy(ws->i_nwid, id, len);
2012 return (0);
2013 }
2014
2015 static void
2016 wi_request_fill_ssid(wreq, ws)
2017 struct wi_req *wreq;
2018 struct ieee80211_nwid *ws;
2019 {
2020 int len = ws->i_len;
2021
2022 memset(&wreq->wi_val[0], 0, sizeof(wreq->wi_val));
2023 wreq->wi_val[0] = htole16(len);
2024 wreq->wi_len = roundup(len, 2) / 2 + 2;
2025 memcpy(&wreq->wi_val[1], ws->i_nwid, len);
2026 }
2027
2028 static int
2029 wi_write_ssid(sc, type, wreq, ws)
2030 struct wi_softc *sc;
2031 int type;
2032 struct wi_req *wreq;
2033 struct ieee80211_nwid *ws;
2034 {
2035
2036 wreq->wi_type = type;
2037 wi_request_fill_ssid(wreq, ws);
2038 return (wi_write_record(sc, (struct wi_ltv_gen *)wreq));
2039 }
2040
2041 static int
2042 wi_sync_media(sc, ptype, txrate)
2043 struct wi_softc *sc;
2044 int ptype;
2045 int txrate;
2046 {
2047 int media = sc->sc_media.ifm_cur->ifm_media;
2048 int options = IFM_OPTIONS(media);
2049 int subtype;
2050
2051 switch (txrate) {
2052 case 1:
2053 subtype = IFM_IEEE80211_DS1;
2054 break;
2055 case 2:
2056 subtype = IFM_IEEE80211_DS2;
2057 break;
2058 case 3:
2059 subtype = IFM_AUTO;
2060 break;
2061 case 11:
2062 subtype = IFM_IEEE80211_DS11;
2063 break;
2064 default:
2065 subtype = IFM_MANUAL; /* Unable to represent */
2066 break;
2067 }
2068 switch (ptype) {
2069 case WI_PORTTYPE_ADHOC:
2070 options |= IFM_IEEE80211_ADHOC;
2071 break;
2072 case WI_PORTTYPE_BSS:
2073 options &= ~IFM_IEEE80211_ADHOC;
2074 break;
2075 default:
2076 subtype = IFM_MANUAL; /* Unable to represent */
2077 break;
2078 }
2079 media = IFM_MAKEWORD(IFM_TYPE(media), subtype, options,
2080 IFM_INST(media));
2081 if (ifmedia_match(&sc->sc_media, media, sc->sc_media.ifm_mask) == NULL)
2082 return (EINVAL);
2083 ifmedia_set(&sc->sc_media, media);
2084 sc->wi_ptype = ptype;
2085 sc->wi_tx_rate = txrate;
2086 return (0);
2087 }
2088
2089 static int
2090 wi_media_change(ifp)
2091 struct ifnet *ifp;
2092 {
2093 struct wi_softc *sc = ifp->if_softc;
2094 int otype = sc->wi_ptype;
2095 int orate = sc->wi_tx_rate;
2096
2097 if ((sc->sc_media.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC) != 0)
2098 sc->wi_ptype = WI_PORTTYPE_ADHOC;
2099 else
2100 sc->wi_ptype = WI_PORTTYPE_BSS;
2101
2102 switch (IFM_SUBTYPE(sc->sc_media.ifm_cur->ifm_media)) {
2103 case IFM_IEEE80211_DS1:
2104 sc->wi_tx_rate = 1;
2105 break;
2106 case IFM_IEEE80211_DS2:
2107 sc->wi_tx_rate = 2;
2108 break;
2109 case IFM_AUTO:
2110 sc->wi_tx_rate = 3;
2111 break;
2112 case IFM_IEEE80211_DS11:
2113 sc->wi_tx_rate = 11;
2114 break;
2115 }
2116
2117 if (sc->sc_enabled != 0) {
2118 if (otype != sc->wi_ptype ||
2119 orate != sc->wi_tx_rate)
2120 wi_init(ifp);
2121 }
2122
2123 ifp->if_baudrate = ifmedia_baudrate(sc->sc_media.ifm_cur->ifm_media);
2124
2125 return (0);
2126 }
2127
2128 static void
2129 wi_media_status(ifp, imr)
2130 struct ifnet *ifp;
2131 struct ifmediareq *imr;
2132 {
2133 struct wi_softc *sc = ifp->if_softc;
2134
2135 if (sc->sc_enabled == 0) {
2136 imr->ifm_active = IFM_IEEE80211|IFM_NONE;
2137 imr->ifm_status = 0;
2138 return;
2139 }
2140
2141 imr->ifm_active = sc->sc_media.ifm_cur->ifm_media;
2142 imr->ifm_status = IFM_AVALID|IFM_ACTIVE;
2143 }
2144
2145 static int
2146 wi_set_nwkey(sc, nwkey)
2147 struct wi_softc *sc;
2148 struct ieee80211_nwkey *nwkey;
2149 {
2150 int i, error;
2151 size_t len;
2152 struct wi_req wreq;
2153 struct wi_ltv_keys *wk = (struct wi_ltv_keys *)&wreq;
2154
2155 if (!sc->wi_has_wep)
2156 return ENODEV;
2157 if (nwkey->i_defkid <= 0 ||
2158 nwkey->i_defkid > IEEE80211_WEP_NKID)
2159 return EINVAL;
2160 memcpy(wk, &sc->wi_keys, sizeof(*wk));
2161 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2162 if (nwkey->i_key[i].i_keydat == NULL)
2163 continue;
2164 len = nwkey->i_key[i].i_keylen;
2165 if (len > sizeof(wk->wi_keys[i].wi_keydat))
2166 return EINVAL;
2167 error = copyin(nwkey->i_key[i].i_keydat,
2168 wk->wi_keys[i].wi_keydat, len);
2169 if (error)
2170 return error;
2171 wk->wi_keys[i].wi_keylen = htole16(len);
2172 }
2173
2174 wk->wi_len = (sizeof(*wk) / 2) + 1;
2175 wk->wi_type = WI_RID_DEFLT_CRYPT_KEYS;
2176 if (sc->sc_enabled != 0) {
2177 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
2178 if (error)
2179 return error;
2180 }
2181 error = wi_setdef(sc, &wreq);
2182 if (error)
2183 return error;
2184
2185 wreq.wi_len = 2;
2186 wreq.wi_type = WI_RID_TX_CRYPT_KEY;
2187 wreq.wi_val[0] = htole16(nwkey->i_defkid - 1);
2188 if (sc->sc_enabled != 0) {
2189 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
2190 if (error)
2191 return error;
2192 }
2193 error = wi_setdef(sc, &wreq);
2194 if (error)
2195 return error;
2196
2197 wreq.wi_type = WI_RID_ENCRYPTION;
2198 wreq.wi_val[0] = htole16(nwkey->i_wepon);
2199 if (sc->sc_enabled != 0) {
2200 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
2201 if (error)
2202 return error;
2203 }
2204 error = wi_setdef(sc, &wreq);
2205 if (error)
2206 return error;
2207
2208 if (sc->sc_enabled != 0)
2209 wi_init(&sc->sc_ethercom.ec_if);
2210 return 0;
2211 }
2212
2213 static int
2214 wi_get_nwkey(sc, nwkey)
2215 struct wi_softc *sc;
2216 struct ieee80211_nwkey *nwkey;
2217 {
2218 int i, len, error;
2219 struct wi_ltv_keys *wk = &sc->wi_keys;
2220
2221 if (!sc->wi_has_wep)
2222 return ENODEV;
2223 nwkey->i_wepon = sc->wi_use_wep;
2224 nwkey->i_defkid = sc->wi_tx_key + 1;
2225
2226 /* do not show any keys to non-root user */
2227 error = suser(curproc->l_proc->p_ucred, &curproc->l_proc->p_acflag);
2228 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2229 if (nwkey->i_key[i].i_keydat == NULL)
2230 continue;
2231 /* error holds results of suser() for the first time */
2232 if (error)
2233 return error;
2234 len = le16toh(wk->wi_keys[i].wi_keylen);
2235 if (nwkey->i_key[i].i_keylen < len)
2236 return ENOSPC;
2237 nwkey->i_key[i].i_keylen = len;
2238 error = copyout(wk->wi_keys[i].wi_keydat,
2239 nwkey->i_key[i].i_keydat, len);
2240 if (error)
2241 return error;
2242 }
2243 return 0;
2244 }
2245
2246 static int
2247 wi_set_pm(struct wi_softc *sc, struct ieee80211_power *power)
2248 {
2249
2250 sc->wi_pm_enabled = power->i_enabled;
2251 sc->wi_max_sleep = power->i_maxsleep;
2252
2253 if (sc->sc_enabled)
2254 return (wi_init(&sc->sc_ethercom.ec_if));
2255
2256 return (0);
2257 }
2258
2259 static int
2260 wi_get_pm(struct wi_softc *sc, struct ieee80211_power *power)
2261 {
2262
2263 power->i_enabled = sc->wi_pm_enabled;
2264 power->i_maxsleep = sc->wi_max_sleep;
2265
2266 return (0);
2267 }
2268