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