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