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