FreeBSD/Linux Kernel Cross Reference
sys/dev/owi/if_owi.c
1 /*
2 * Copyright (c) 1997, 1998, 1999
3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Bill Paul.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*
34 * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for FreeBSD.
35 *
36 * Written by Bill Paul <wpaul@ctr.columbia.edu>
37 * Electrical Engineering Department
38 * Columbia University, New York City
39 */
40
41 /*
42 * The WaveLAN/IEEE adapter is the second generation of the WaveLAN
43 * from Lucent. Unlike the older cards, the new ones are programmed
44 * entirely via a firmware-driven controller called the Hermes.
45 * Unfortunately, Lucent will not release the Hermes programming manual
46 * without an NDA (if at all). What they do release is an API library
47 * called the HCF (Hardware Control Functions) which is supposed to
48 * do the device-specific operations of a device driver for you. The
49 * publically available version of the HCF library (the 'HCF Light') is
50 * a) extremely gross, b) lacks certain features, particularly support
51 * for 802.11 frames, and c) is contaminated by the GNU Public License.
52 *
53 * This driver does not use the HCF or HCF Light at all. Instead, it
54 * programs the Hermes controller directly, using information gleaned
55 * from the HCF Light code and corresponding documentation.
56 *
57 * This driver supports the ISA, PCMCIA and PCI versions of the Lucent
58 * WaveLan cards (based on the Hermes chipset), as well as the newer
59 * Prism 2 chipsets with firmware from Intersil and Symbol.
60 */
61
62 #include <sys/param.h>
63 #include <sys/systm.h>
64 #include <sys/endian.h>
65 #include <sys/sockio.h>
66 #include <sys/mbuf.h>
67 #include <sys/proc.h>
68 #include <sys/kernel.h>
69 #include <sys/socket.h>
70 #include <sys/module.h>
71 #include <sys/bus.h>
72 #include <sys/random.h>
73 #include <sys/syslog.h>
74 #include <sys/sysctl.h>
75
76 #include <machine/bus.h>
77 #include <machine/resource.h>
78 #include <machine/clock.h>
79 #include <sys/rman.h>
80
81 #include <net/if.h>
82 #include <net/if_arp.h>
83 #include <net/ethernet.h>
84 #include <net/if_dl.h>
85 #include <net/if_media.h>
86 #include <net/if_types.h>
87 #include <dev/owi/if_ieee80211.h>
88
89 #include <netinet/in.h>
90 #include <netinet/in_systm.h>
91 #include <netinet/in_var.h>
92 #include <netinet/ip.h>
93 #include <netinet/if_ether.h>
94
95 #include <net/bpf.h>
96
97 #include <dev/wi/if_wavelan_ieee.h>
98 #include <dev/owi/if_wivar.h>
99 #include <dev/owi/if_wireg.h>
100
101 #if !defined(lint)
102 static const char rcsid[] =
103 "$FreeBSD: releng/5.3/sys/dev/owi/if_owi.c 129616 2004-05-23 16:11:53Z mux $";
104 #endif
105
106 static void wi_intr(void *);
107 static void wi_reset(struct wi_softc *);
108 static int wi_ioctl(struct ifnet *, u_long, caddr_t);
109 static void wi_init(void *);
110 static void wi_start(struct ifnet *);
111 static void wi_watchdog(struct ifnet *);
112 static void wi_rxeof(struct wi_softc *);
113 static void wi_txeof(struct wi_softc *, int);
114 static void wi_update_stats(struct wi_softc *);
115 static void wi_setmulti(struct wi_softc *);
116
117 static int wi_cmd(struct wi_softc *, int, int, int, int);
118 static int wi_read_record(struct wi_softc *, struct wi_ltv_gen *);
119 static int wi_write_record(struct wi_softc *, struct wi_ltv_gen *);
120 static int wi_read_data(struct wi_softc *, int, int, caddr_t, int);
121 static int wi_write_data(struct wi_softc *, int, int, caddr_t, int);
122 static int wi_seek(struct wi_softc *, int, int, int);
123 static int wi_alloc_nicmem(struct wi_softc *, int, int *);
124 static void wi_inquire(void *);
125 static void wi_setdef(struct wi_softc *, struct wi_req *);
126
127 #ifdef WICACHE
128 static
129 void wi_cache_store(struct wi_softc *, struct ether_header *,
130 struct mbuf *, unsigned short);
131 #endif
132
133 static int wi_get_cur_ssid(struct wi_softc *, char *, int *);
134 static int wi_media_change(struct ifnet *);
135 static void wi_media_status(struct ifnet *, struct ifmediareq *);
136
137 devclass_t owi_devclass;
138
139 struct wi_card_ident wi_card_ident[] = {
140 /* CARD_ID CARD_NAME FIRM_TYPE */
141 { WI_NIC_LUCENT_ID, WI_NIC_LUCENT_STR, WI_LUCENT },
142 { WI_NIC_SONY_ID, WI_NIC_SONY_STR, WI_LUCENT },
143 { WI_NIC_LUCENT_EMB_ID, WI_NIC_LUCENT_EMB_STR, WI_LUCENT },
144 { 0, NULL, 0 },
145 };
146
147 int
148 owi_generic_detach(dev)
149 device_t dev;
150 {
151 struct wi_softc *sc;
152 struct ifnet *ifp;
153 int s;
154
155 sc = device_get_softc(dev);
156 WI_LOCK(sc, s);
157 ifp = &sc->arpcom.ac_if;
158
159 if (sc->wi_gone) {
160 device_printf(dev, "already unloaded\n");
161 WI_UNLOCK(sc, s);
162 return(ENODEV);
163 }
164 sc->wi_gone = !bus_child_present(dev);
165
166 owi_stop(sc);
167
168 /* Delete all remaining media. */
169 ifmedia_removeall(&sc->ifmedia);
170
171 ether_ifdetach(ifp);
172 bus_teardown_intr(dev, sc->irq, sc->wi_intrhand);
173 owi_free(dev);
174 sc->wi_gone = 1;
175
176 WI_UNLOCK(sc, s);
177 mtx_destroy(&sc->wi_mtx);
178
179 return(0);
180 }
181
182 int
183 owi_generic_attach(device_t dev)
184 {
185 struct wi_softc *sc;
186 struct wi_ltv_macaddr mac;
187 struct wi_ltv_gen gen;
188 struct ifnet *ifp;
189 int error;
190 int s;
191
192 /* XXX maybe we need the splimp stuff here XXX */
193 sc = device_get_softc(dev);
194 ifp = &sc->arpcom.ac_if;
195
196 error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET,
197 wi_intr, sc, &sc->wi_intrhand);
198
199 if (error) {
200 device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
201 owi_free(dev);
202 return (error);
203 }
204
205 mtx_init(&sc->wi_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
206 MTX_DEF | MTX_RECURSE);
207 WI_LOCK(sc, s);
208
209 /* Reset the NIC. */
210 wi_reset(sc);
211
212 /*
213 * Read the station address.
214 * And do it twice. I've seen PRISM-based cards that return
215 * an error when trying to read it the first time, which causes
216 * the probe to fail.
217 */
218 mac.wi_type = WI_RID_MAC_NODE;
219 mac.wi_len = 4;
220 wi_read_record(sc, (struct wi_ltv_gen *)&mac);
221 if ((error = wi_read_record(sc, (struct wi_ltv_gen *)&mac)) != 0) {
222 device_printf(dev, "mac read failed %d\n", error);
223 owi_free(dev);
224 return (error);
225 }
226 bcopy((char *)&mac.wi_mac_addr,
227 (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
228
229 owi_get_id(sc);
230
231 if_initname(ifp, device_get_name(dev), sc->wi_unit);
232 ifp->if_softc = sc;
233 ifp->if_mtu = ETHERMTU;
234 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
235 ifp->if_ioctl = wi_ioctl;
236 ifp->if_start = wi_start;
237 ifp->if_watchdog = wi_watchdog;
238 ifp->if_init = wi_init;
239 ifp->if_baudrate = 10000000;
240 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
241
242 bzero(sc->wi_node_name, sizeof(sc->wi_node_name));
243 bcopy(WI_DEFAULT_NODENAME, sc->wi_node_name,
244 sizeof(WI_DEFAULT_NODENAME) - 1);
245
246 bzero(sc->wi_net_name, sizeof(sc->wi_net_name));
247 bcopy(WI_DEFAULT_NETNAME, sc->wi_net_name,
248 sizeof(WI_DEFAULT_NETNAME) - 1);
249
250 bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name));
251 bcopy(WI_DEFAULT_IBSS, sc->wi_ibss_name,
252 sizeof(WI_DEFAULT_IBSS) - 1);
253
254 sc->wi_portnum = WI_DEFAULT_PORT;
255 sc->wi_ptype = WI_PORTTYPE_BSS;
256 sc->wi_ap_density = WI_DEFAULT_AP_DENSITY;
257 sc->wi_rts_thresh = WI_DEFAULT_RTS_THRESH;
258 sc->wi_tx_rate = WI_DEFAULT_TX_RATE;
259 sc->wi_max_data_len = WI_DEFAULT_DATALEN;
260 sc->wi_create_ibss = WI_DEFAULT_CREATE_IBSS;
261 sc->wi_pm_enabled = WI_DEFAULT_PM_ENABLED;
262 sc->wi_max_sleep = WI_DEFAULT_MAX_SLEEP;
263 sc->wi_roaming = WI_DEFAULT_ROAMING;
264 sc->wi_authtype = WI_DEFAULT_AUTHTYPE;
265 sc->wi_authmode = IEEE80211_AUTH_OPEN;
266
267 /*
268 * Read the default channel from the NIC. This may vary
269 * depending on the country where the NIC was purchased, so
270 * we can't hard-code a default and expect it to work for
271 * everyone.
272 */
273 gen.wi_type = WI_RID_OWN_CHNL;
274 gen.wi_len = 2;
275 wi_read_record(sc, &gen);
276 sc->wi_channel = gen.wi_val;
277
278 /*
279 * Set flags based on firmware version.
280 */
281 switch (sc->sc_firmware_type) {
282 case WI_LUCENT:
283 sc->wi_flags |= WI_FLAGS_HAS_ROAMING;
284 if (sc->sc_sta_firmware_ver >= 60000)
285 sc->wi_flags |= WI_FLAGS_HAS_MOR;
286 if (sc->sc_sta_firmware_ver >= 60006) {
287 sc->wi_flags |= WI_FLAGS_HAS_IBSS;
288 sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS;
289 }
290 sc->wi_ibss_port = htole16(1);
291 break;
292 }
293
294 /*
295 * Find out if we support WEP on this card.
296 */
297 gen.wi_type = WI_RID_WEP_AVAIL;
298 gen.wi_len = 2;
299 wi_read_record(sc, &gen);
300 sc->wi_has_wep = gen.wi_val;
301
302 if (bootverbose)
303 device_printf(sc->dev, "owi_has_wep = %d\n", sc->wi_has_wep);
304
305 /*
306 * Find supported rates.
307 */
308 gen.wi_type = WI_RID_DATA_RATES;
309 gen.wi_len = 2;
310 if (wi_read_record(sc, &gen))
311 sc->wi_supprates = WI_SUPPRATES_1M | WI_SUPPRATES_2M |
312 WI_SUPPRATES_5M | WI_SUPPRATES_11M;
313 else
314 sc->wi_supprates = gen.wi_val;
315
316 bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats));
317
318 wi_init(sc);
319 owi_stop(sc);
320
321 ifmedia_init(&sc->ifmedia, 0, wi_media_change, wi_media_status);
322 #define ADD(m, c) ifmedia_add(&sc->ifmedia, (m), (c), NULL)
323 if (sc->wi_supprates & WI_SUPPRATES_1M) {
324 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 0, 0), 0);
325 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
326 IFM_IEEE80211_ADHOC, 0), 0);
327 if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
328 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
329 IFM_IEEE80211_IBSS, 0), 0);
330 if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
331 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
332 IFM_IEEE80211_IBSSMASTER, 0), 0);
333 }
334 if (sc->wi_supprates & WI_SUPPRATES_2M) {
335 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0);
336 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
337 IFM_IEEE80211_ADHOC, 0), 0);
338 if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
339 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
340 IFM_IEEE80211_IBSS, 0), 0);
341 if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
342 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
343 IFM_IEEE80211_IBSSMASTER, 0), 0);
344 }
345 if (sc->wi_supprates & WI_SUPPRATES_5M) {
346 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 0, 0), 0);
347 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
348 IFM_IEEE80211_ADHOC, 0), 0);
349 if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
350 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
351 IFM_IEEE80211_IBSS, 0), 0);
352 if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
353 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
354 IFM_IEEE80211_IBSSMASTER, 0), 0);
355 }
356 if (sc->wi_supprates & WI_SUPPRATES_11M) {
357 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0);
358 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
359 IFM_IEEE80211_ADHOC, 0), 0);
360 if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
361 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
362 IFM_IEEE80211_IBSS, 0), 0);
363 if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
364 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
365 IFM_IEEE80211_IBSSMASTER, 0), 0);
366 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_MANUAL, 0, 0), 0);
367 }
368 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_ADHOC, 0), 0);
369 if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
370 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_IBSS,
371 0), 0);
372 if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
373 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO,
374 IFM_IEEE80211_IBSSMASTER, 0), 0);
375 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0), 0);
376 #undef ADD
377 ifmedia_set(&sc->ifmedia, IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0));
378
379 /*
380 * Call MI attach routine.
381 */
382 ether_ifattach(ifp, sc->arpcom.ac_enaddr);
383 callout_handle_init(&sc->wi_stat_ch);
384 WI_UNLOCK(sc, s);
385
386 return(0);
387 }
388
389 void
390 owi_get_id(sc)
391 struct wi_softc *sc;
392 {
393 struct wi_ltv_ver ver;
394 struct wi_card_ident *id;
395
396 /* getting chip identity */
397 memset(&ver, 0, sizeof(ver));
398 ver.wi_type = WI_RID_CARD_ID;
399 ver.wi_len = 5;
400 wi_read_record(sc, (struct wi_ltv_gen *)&ver);
401 device_printf(sc->dev, "using ");
402 sc->sc_firmware_type = WI_NOTYPE;
403 for (id = wi_card_ident; id->card_name != NULL; id++) {
404 if (le16toh(ver.wi_ver[0]) == id->card_id) {
405 printf("%s", id->card_name);
406 sc->sc_firmware_type = id->firm_type;
407 break;
408 }
409 }
410 if (sc->sc_firmware_type == WI_NOTYPE) {
411 if ((le16toh(ver.wi_ver[0]) & 0x8000) == 0) {
412 printf("Unknown Lucent chip");
413 sc->sc_firmware_type = WI_LUCENT;
414 }
415 }
416
417 if (sc->sc_firmware_type != WI_LUCENT)
418 return;
419
420 /* get station firmware version */
421 memset(&ver, 0, sizeof(ver));
422 ver.wi_type = WI_RID_STA_IDENTITY;
423 ver.wi_len = 5;
424 wi_read_record(sc, (struct wi_ltv_gen *)&ver);
425 ver.wi_ver[1] = le16toh(ver.wi_ver[1]);
426 ver.wi_ver[2] = le16toh(ver.wi_ver[2]);
427 ver.wi_ver[3] = le16toh(ver.wi_ver[3]);
428 sc->sc_sta_firmware_ver = ver.wi_ver[2] * 10000 +
429 ver.wi_ver[3] * 100 + ver.wi_ver[1];
430 printf("\n");
431 device_printf(sc->dev, "Lucent Firmware: ");
432
433 printf("Station %u.%02u.%02u\n",
434 sc->sc_sta_firmware_ver / 10000, (sc->sc_sta_firmware_ver % 10000) / 100,
435 sc->sc_sta_firmware_ver % 100);
436 return;
437 }
438
439 static void
440 wi_rxeof(sc)
441 struct wi_softc *sc;
442 {
443 struct ifnet *ifp;
444 struct ether_header *eh;
445 struct mbuf *m;
446 int id;
447 int s;
448
449 WI_LOCK_ASSERT(sc);
450
451 ifp = &sc->arpcom.ac_if;
452
453 id = CSR_READ_2(sc, WI_RX_FID);
454
455 /*
456 * if we have the procframe flag set, disregard all this and just
457 * read the data from the device.
458 */
459 if (sc->wi_procframe || sc->wi_debug.wi_monitor) {
460 struct wi_frame *rx_frame;
461 int datlen, hdrlen;
462
463 /* first allocate mbuf for packet storage */
464 MGETHDR(m, M_DONTWAIT, MT_DATA);
465 if (m == NULL) {
466 ifp->if_ierrors++;
467 return;
468 }
469 MCLGET(m, M_DONTWAIT);
470 if (!(m->m_flags & M_EXT)) {
471 m_freem(m);
472 ifp->if_ierrors++;
473 return;
474 }
475
476 m->m_pkthdr.rcvif = ifp;
477
478 /* now read wi_frame first so we know how much data to read */
479 if (wi_read_data(sc, id, 0, mtod(m, caddr_t),
480 sizeof(struct wi_frame))) {
481 m_freem(m);
482 ifp->if_ierrors++;
483 return;
484 }
485
486 rx_frame = mtod(m, struct wi_frame *);
487
488 switch ((rx_frame->wi_status & WI_STAT_MAC_PORT) >> 8) {
489 case 7:
490 switch (rx_frame->wi_frame_ctl & WI_FCTL_FTYPE) {
491 case WI_FTYPE_DATA:
492 hdrlen = WI_DATA_HDRLEN;
493 datlen = rx_frame->wi_dat_len + WI_FCS_LEN;
494 break;
495 case WI_FTYPE_MGMT:
496 hdrlen = WI_MGMT_HDRLEN;
497 datlen = rx_frame->wi_dat_len + WI_FCS_LEN;
498 break;
499 case WI_FTYPE_CTL:
500 /*
501 * prism2 cards don't pass control packets
502 * down properly or consistently, so we'll only
503 * pass down the header.
504 */
505 hdrlen = WI_CTL_HDRLEN;
506 datlen = 0;
507 break;
508 default:
509 device_printf(sc->dev, "received packet of "
510 "unknown type on port 7\n");
511 m_freem(m);
512 ifp->if_ierrors++;
513 return;
514 }
515 break;
516 case 0:
517 hdrlen = WI_DATA_HDRLEN;
518 datlen = rx_frame->wi_dat_len + WI_FCS_LEN;
519 break;
520 default:
521 device_printf(sc->dev, "received packet on invalid "
522 "port (wi_status=0x%x)\n", rx_frame->wi_status);
523 m_freem(m);
524 ifp->if_ierrors++;
525 return;
526 }
527
528 if ((hdrlen + datlen + 2) > MCLBYTES) {
529 device_printf(sc->dev, "oversized packet received "
530 "(wi_dat_len=%d, wi_status=0x%x)\n",
531 datlen, rx_frame->wi_status);
532 m_freem(m);
533 ifp->if_ierrors++;
534 return;
535 }
536
537 if (wi_read_data(sc, id, hdrlen, mtod(m, caddr_t) + hdrlen,
538 datlen + 2)) {
539 m_freem(m);
540 ifp->if_ierrors++;
541 return;
542 }
543
544 m->m_pkthdr.len = m->m_len = hdrlen + datlen;
545
546 ifp->if_ipackets++;
547
548 /* Handle BPF listeners. */
549 BPF_MTAP(ifp, m);
550
551 m_freem(m);
552 } else {
553 struct wi_frame rx_frame;
554
555 /* First read in the frame header */
556 if (wi_read_data(sc, id, 0, (caddr_t)&rx_frame,
557 sizeof(rx_frame))) {
558 ifp->if_ierrors++;
559 return;
560 }
561
562 if (rx_frame.wi_status & WI_STAT_ERRSTAT) {
563 ifp->if_ierrors++;
564 return;
565 }
566
567 MGETHDR(m, M_DONTWAIT, MT_DATA);
568 if (m == NULL) {
569 ifp->if_ierrors++;
570 return;
571 }
572 MCLGET(m, M_DONTWAIT);
573 if (!(m->m_flags & M_EXT)) {
574 m_freem(m);
575 ifp->if_ierrors++;
576 return;
577 }
578
579 eh = mtod(m, struct ether_header *);
580 m->m_pkthdr.rcvif = ifp;
581
582 if (rx_frame.wi_status == WI_STAT_1042 ||
583 rx_frame.wi_status == WI_STAT_TUNNEL ||
584 rx_frame.wi_status == WI_STAT_WMP_MSG) {
585 if((rx_frame.wi_dat_len + WI_SNAPHDR_LEN) > MCLBYTES) {
586 device_printf(sc->dev,
587 "oversized packet received "
588 "(wi_dat_len=%d, wi_status=0x%x)\n",
589 rx_frame.wi_dat_len, rx_frame.wi_status);
590 m_freem(m);
591 ifp->if_ierrors++;
592 return;
593 }
594 m->m_pkthdr.len = m->m_len =
595 rx_frame.wi_dat_len + WI_SNAPHDR_LEN;
596
597 #if 0
598 bcopy((char *)&rx_frame.wi_addr1,
599 (char *)&eh->ether_dhost, ETHER_ADDR_LEN);
600 if (sc->wi_ptype == WI_PORTTYPE_ADHOC) {
601 bcopy((char *)&rx_frame.wi_addr2,
602 (char *)&eh->ether_shost, ETHER_ADDR_LEN);
603 } else {
604 bcopy((char *)&rx_frame.wi_addr3,
605 (char *)&eh->ether_shost, ETHER_ADDR_LEN);
606 }
607 #else
608 bcopy((char *)&rx_frame.wi_dst_addr,
609 (char *)&eh->ether_dhost, ETHER_ADDR_LEN);
610 bcopy((char *)&rx_frame.wi_src_addr,
611 (char *)&eh->ether_shost, ETHER_ADDR_LEN);
612 #endif
613
614 bcopy((char *)&rx_frame.wi_type,
615 (char *)&eh->ether_type, ETHER_TYPE_LEN);
616
617 if (wi_read_data(sc, id, WI_802_11_OFFSET,
618 mtod(m, caddr_t) + sizeof(struct ether_header),
619 m->m_len + 2)) {
620 m_freem(m);
621 ifp->if_ierrors++;
622 return;
623 }
624 } else {
625 if((rx_frame.wi_dat_len +
626 sizeof(struct ether_header)) > MCLBYTES) {
627 device_printf(sc->dev,
628 "oversized packet received "
629 "(wi_dat_len=%d, wi_status=0x%x)\n",
630 rx_frame.wi_dat_len, rx_frame.wi_status);
631 m_freem(m);
632 ifp->if_ierrors++;
633 return;
634 }
635 m->m_pkthdr.len = m->m_len =
636 rx_frame.wi_dat_len + sizeof(struct ether_header);
637
638 if (wi_read_data(sc, id, WI_802_3_OFFSET,
639 mtod(m, caddr_t), m->m_len + 2)) {
640 m_freem(m);
641 ifp->if_ierrors++;
642 return;
643 }
644 }
645
646 ifp->if_ipackets++;
647
648 /* Receive packet. */
649 #ifdef WICACHE
650 wi_cache_store(sc, eh, m, rx_frame.wi_q_info);
651 #endif
652 WI_UNLOCK(sc, s);
653 (*ifp->if_input)(ifp, m);
654 WI_LOCK(sc, s);
655 }
656 }
657
658 static void
659 wi_txeof(sc, status)
660 struct wi_softc *sc;
661 int status;
662 {
663 struct ifnet *ifp;
664
665 ifp = &sc->arpcom.ac_if;
666
667 ifp->if_timer = 0;
668 ifp->if_flags &= ~IFF_OACTIVE;
669
670 if (status & WI_EV_TX_EXC)
671 ifp->if_oerrors++;
672 else
673 ifp->if_opackets++;
674
675 return;
676 }
677
678 static void
679 wi_inquire(xsc)
680 void *xsc;
681 {
682 struct wi_softc *sc;
683 struct ifnet *ifp;
684 int s;
685
686 sc = xsc;
687 ifp = &sc->arpcom.ac_if;
688
689 sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60);
690
691 /* Don't do this while we're transmitting */
692 if (ifp->if_flags & IFF_OACTIVE)
693 return;
694
695 WI_LOCK(sc, s);
696 wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_COUNTERS, 0, 0);
697 WI_UNLOCK(sc, s);
698
699 return;
700 }
701
702 static void
703 wi_update_stats(sc)
704 struct wi_softc *sc;
705 {
706 struct wi_ltv_gen gen;
707 u_int16_t id;
708 struct ifnet *ifp;
709 u_int32_t *ptr;
710 int len, i;
711 u_int16_t t;
712
713 ifp = &sc->arpcom.ac_if;
714
715 id = CSR_READ_2(sc, WI_INFO_FID);
716
717 wi_read_data(sc, id, 0, (char *)&gen, 4);
718
719 /*
720 * if we just got our scan results, copy it over into the scan buffer
721 * so we can return it to anyone that asks for it. (add a little
722 * compatibility with the prism2 scanning mechanism)
723 */
724 if (gen.wi_type == WI_INFO_SCAN_RESULTS)
725 {
726 sc->wi_scanbuf_len = gen.wi_len;
727 wi_read_data(sc, id, 4, (char *)sc->wi_scanbuf,
728 sc->wi_scanbuf_len * 2);
729
730 return;
731 }
732 else if (gen.wi_type != WI_INFO_COUNTERS)
733 return;
734
735 len = (gen.wi_len - 1 < sizeof(sc->wi_stats) / 4) ?
736 gen.wi_len - 1 : sizeof(sc->wi_stats) / 4;
737 ptr = (u_int32_t *)&sc->wi_stats;
738
739 for (i = 0; i < len - 1; i++) {
740 t = CSR_READ_2(sc, WI_DATA1);
741 #ifdef WI_HERMES_STATS_WAR
742 if (t > 0xF000)
743 t = ~t & 0xFFFF;
744 #endif
745 ptr[i] += t;
746 }
747
748 ifp->if_collisions = sc->wi_stats.wi_tx_single_retries +
749 sc->wi_stats.wi_tx_multi_retries +
750 sc->wi_stats.wi_tx_retry_limit;
751
752 return;
753 }
754
755 static void
756 wi_intr(xsc)
757 void *xsc;
758 {
759 struct wi_softc *sc = xsc;
760 struct ifnet *ifp;
761 u_int16_t status;
762 int s;
763
764 WI_LOCK(sc, s);
765
766 ifp = &sc->arpcom.ac_if;
767
768 if (sc->wi_gone || !(ifp->if_flags & IFF_UP)) {
769 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
770 CSR_WRITE_2(sc, WI_INT_EN, 0);
771 WI_UNLOCK(sc, s);
772 return;
773 }
774
775 /* Disable interrupts. */
776 CSR_WRITE_2(sc, WI_INT_EN, 0);
777
778 status = CSR_READ_2(sc, WI_EVENT_STAT);
779 CSR_WRITE_2(sc, WI_EVENT_ACK, ~WI_INTRS);
780
781 if (status & WI_EV_RX) {
782 wi_rxeof(sc);
783 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
784 }
785
786 if (status & WI_EV_TX) {
787 wi_txeof(sc, status);
788 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX);
789 }
790
791 if (status & WI_EV_ALLOC) {
792 int id;
793
794 id = CSR_READ_2(sc, WI_ALLOC_FID);
795 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
796 if (id == sc->wi_tx_data_id)
797 wi_txeof(sc, status);
798 }
799
800 if (status & WI_EV_INFO) {
801 wi_update_stats(sc);
802 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO);
803 }
804
805 if (status & WI_EV_TX_EXC) {
806 wi_txeof(sc, status);
807 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX_EXC);
808 }
809
810 if (status & WI_EV_INFO_DROP) {
811 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO_DROP);
812 }
813
814 /* Re-enable interrupts. */
815 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
816
817 if (ifp->if_snd.ifq_head != NULL) {
818 wi_start(ifp);
819 }
820
821 WI_UNLOCK(sc, s);
822
823 return;
824 }
825
826 static int
827 wi_cmd(sc, cmd, val0, val1, val2)
828 struct wi_softc *sc;
829 int cmd;
830 int val0;
831 int val1;
832 int val2;
833 {
834 int i, s = 0;
835 static volatile int count = 0;
836
837 if (count > 1)
838 panic("Hey partner, hold on there!");
839 count++;
840
841 /* wait for the busy bit to clear */
842 for (i = 500; i > 0; i--) { /* 5s */
843 if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY)) {
844 break;
845 }
846 DELAY(10*1000); /* 10 m sec */
847 }
848 if (i == 0) {
849 device_printf(sc->dev, "owi_cmd: busy bit won't clear.\n" );
850 count--;
851 return(ETIMEDOUT);
852 }
853
854 CSR_WRITE_2(sc, WI_PARAM0, val0);
855 CSR_WRITE_2(sc, WI_PARAM1, val1);
856 CSR_WRITE_2(sc, WI_PARAM2, val2);
857 CSR_WRITE_2(sc, WI_COMMAND, cmd);
858
859 for (i = 0; i < WI_TIMEOUT; i++) {
860 /*
861 * Wait for 'command complete' bit to be
862 * set in the event status register.
863 */
864 s = CSR_READ_2(sc, WI_EVENT_STAT);
865 if (s & WI_EV_CMD) {
866 /* Ack the event and read result code. */
867 s = CSR_READ_2(sc, WI_STATUS);
868 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
869 #ifdef foo
870 if ((s & WI_CMD_CODE_MASK) != (cmd & WI_CMD_CODE_MASK))
871 return(EIO);
872 #endif
873 if (s & WI_STAT_CMD_RESULT) {
874 count--;
875 return(EIO);
876 }
877 break;
878 }
879 DELAY(WI_DELAY);
880 }
881
882 count--;
883 if (i == WI_TIMEOUT) {
884 device_printf(sc->dev,
885 "timeout in wi_cmd 0x%04x; event status 0x%04x\n", cmd, s);
886 return(ETIMEDOUT);
887 }
888 return(0);
889 }
890
891 static void
892 wi_reset(sc)
893 struct wi_softc *sc;
894 {
895 #define WI_INIT_TRIES 3
896 int i;
897 int tries;
898
899 tries = WI_INIT_TRIES;
900 for (i = 0; i < tries; i++) {
901 if (wi_cmd(sc, WI_CMD_INI, 0, 0, 0) == 0)
902 break;
903 DELAY(WI_DELAY * 1000);
904 }
905 sc->sc_enabled = 1;
906
907 if (i == tries) {
908 device_printf(sc->dev, "init failed\n");
909 return;
910 }
911
912 CSR_WRITE_2(sc, WI_INT_EN, 0);
913 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
914
915 /* Calibrate timer. */
916 WI_SETVAL(WI_RID_TICK_TIME, 8);
917
918 return;
919 }
920
921 /*
922 * Read an LTV record from the NIC.
923 */
924 static int
925 wi_read_record(sc, ltv)
926 struct wi_softc *sc;
927 struct wi_ltv_gen *ltv;
928 {
929 u_int16_t *ptr;
930 int i, len, code;
931 struct wi_ltv_gen *oltv;
932
933 oltv = ltv;
934
935 /* Tell the NIC to enter record read mode. */
936 if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type, 0, 0))
937 return(EIO);
938
939 /* Seek to the record. */
940 if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
941 return(EIO);
942
943 /*
944 * Read the length and record type and make sure they
945 * match what we expect (this verifies that we have enough
946 * room to hold all of the returned data).
947 */
948 len = CSR_READ_2(sc, WI_DATA1);
949 if (len > ltv->wi_len)
950 return(ENOSPC);
951 code = CSR_READ_2(sc, WI_DATA1);
952 if (code != ltv->wi_type)
953 return(EIO);
954
955 ltv->wi_len = len;
956 ltv->wi_type = code;
957
958 /* Now read the data. */
959 ptr = <v->wi_val;
960 for (i = 0; i < ltv->wi_len - 1; i++)
961 ptr[i] = CSR_READ_2(sc, WI_DATA1);
962
963 if (ltv->wi_type == WI_RID_PORTTYPE && sc->wi_ptype == WI_PORTTYPE_IBSS
964 && ltv->wi_val == sc->wi_ibss_port) {
965 /*
966 * Convert vendor IBSS port type to WI_PORTTYPE_IBSS.
967 * Since Lucent uses port type 1 for BSS *and* IBSS we
968 * have to rely on wi_ptype to distinguish this for us.
969 */
970 ltv->wi_val = htole16(WI_PORTTYPE_IBSS);
971 }
972
973 return(0);
974 }
975
976 /*
977 * Same as read, except we inject data instead of reading it.
978 */
979 static int
980 wi_write_record(sc, ltv)
981 struct wi_softc *sc;
982 struct wi_ltv_gen *ltv;
983 {
984 uint16_t *ptr;
985 int i;
986 struct wi_ltv_gen p2ltv;
987
988 if (ltv->wi_type == WI_RID_PORTTYPE &&
989 le16toh(ltv->wi_val) == WI_PORTTYPE_IBSS) {
990 /* Convert WI_PORTTYPE_IBSS to vendor IBSS port type. */
991 p2ltv.wi_type = WI_RID_PORTTYPE;
992 p2ltv.wi_len = 2;
993 p2ltv.wi_val = sc->wi_ibss_port;
994 ltv = &p2ltv;
995 } else {
996 /* LUCENT */
997 switch (ltv->wi_type) {
998 case WI_RID_TX_RATE:
999 switch (ltv->wi_val) {
1000 case 1: ltv->wi_val = 1; break; /* 1Mb/s fixed */
1001 case 2: ltv->wi_val = 2; break; /* 2Mb/s fixed */
1002 case 3: ltv->wi_val = 3; break; /* 11Mb/s auto */
1003 case 5: ltv->wi_val = 4; break; /* 5.5Mb/s fixed */
1004 case 6: ltv->wi_val = 6; break; /* 2Mb/s auto */
1005 case 7: ltv->wi_val = 7; break; /* 5.5Mb/s auto */
1006 case 11: ltv->wi_val = 5; break; /* 11Mb/s fixed */
1007 default: return EINVAL;
1008 }
1009 case WI_RID_TX_CRYPT_KEY:
1010 if (ltv->wi_val > WI_NLTV_KEYS)
1011 return (EINVAL);
1012 break;
1013 }
1014 }
1015
1016 if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
1017 return(EIO);
1018
1019 CSR_WRITE_2(sc, WI_DATA1, ltv->wi_len);
1020 CSR_WRITE_2(sc, WI_DATA1, ltv->wi_type);
1021
1022 ptr = <v->wi_val;
1023 for (i = 0; i < ltv->wi_len - 1; i++)
1024 CSR_WRITE_2(sc, WI_DATA1, ptr[i]);
1025
1026 if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_WRITE, ltv->wi_type, 0, 0))
1027 return(EIO);
1028
1029 return(0);
1030 }
1031
1032 static int
1033 wi_seek(sc, id, off, chan)
1034 struct wi_softc *sc;
1035 int id, off, chan;
1036 {
1037 int i;
1038 int selreg, offreg;
1039 int status;
1040
1041 switch (chan) {
1042 case WI_BAP0:
1043 selreg = WI_SEL0;
1044 offreg = WI_OFF0;
1045 break;
1046 case WI_BAP1:
1047 selreg = WI_SEL1;
1048 offreg = WI_OFF1;
1049 break;
1050 default:
1051 device_printf(sc->dev, "invalid data path: %x\n", chan);
1052 return(EIO);
1053 }
1054
1055 CSR_WRITE_2(sc, selreg, id);
1056 CSR_WRITE_2(sc, offreg, off);
1057
1058 for (i = 0; i < WI_TIMEOUT; i++) {
1059 status = CSR_READ_2(sc, offreg);
1060 if (!(status & (WI_OFF_BUSY|WI_OFF_ERR)))
1061 break;
1062 DELAY(WI_DELAY);
1063 }
1064
1065 if (i == WI_TIMEOUT) {
1066 device_printf(sc->dev, "timeout in wi_seek to %x/%x; last status %x\n",
1067 id, off, status);
1068 return(ETIMEDOUT);
1069 }
1070
1071 return(0);
1072 }
1073
1074 static int
1075 wi_read_data(sc, id, off, buf, len)
1076 struct wi_softc *sc;
1077 int id, off;
1078 caddr_t buf;
1079 int len;
1080 {
1081 int i;
1082 u_int16_t *ptr;
1083
1084 if (wi_seek(sc, id, off, WI_BAP1))
1085 return(EIO);
1086
1087 ptr = (u_int16_t *)buf;
1088 for (i = 0; i < len / 2; i++)
1089 ptr[i] = CSR_READ_2(sc, WI_DATA1);
1090
1091 return(0);
1092 }
1093
1094 /*
1095 * According to the comments in the HCF Light code, there is a bug in
1096 * the Hermes (or possibly in certain Hermes firmware revisions) where
1097 * the chip's internal autoincrement counter gets thrown off during
1098 * data writes: the autoincrement is missed, causing one data word to
1099 * be overwritten and subsequent words to be written to the wrong memory
1100 * locations. The end result is that we could end up transmitting bogus
1101 * frames without realizing it. The workaround for this is to write a
1102 * couple of extra guard words after the end of the transfer, then
1103 * attempt to read then back. If we fail to locate the guard words where
1104 * we expect them, we preform the transfer over again.
1105 */
1106 static int
1107 wi_write_data(sc, id, off, buf, len)
1108 struct wi_softc *sc;
1109 int id, off;
1110 caddr_t buf;
1111 int len;
1112 {
1113 int i;
1114 u_int16_t *ptr;
1115 #ifdef WI_HERMES_AUTOINC_WAR
1116 int retries;
1117
1118 retries = 512;
1119 again:
1120 #endif
1121
1122 if (wi_seek(sc, id, off, WI_BAP0))
1123 return(EIO);
1124
1125 ptr = (u_int16_t *)buf;
1126 for (i = 0; i < (len / 2); i++)
1127 CSR_WRITE_2(sc, WI_DATA0, ptr[i]);
1128
1129 #ifdef WI_HERMES_AUTOINC_WAR
1130 CSR_WRITE_2(sc, WI_DATA0, 0x1234);
1131 CSR_WRITE_2(sc, WI_DATA0, 0x5678);
1132
1133 if (wi_seek(sc, id, off + len, WI_BAP0))
1134 return(EIO);
1135
1136 if (CSR_READ_2(sc, WI_DATA0) != 0x1234 ||
1137 CSR_READ_2(sc, WI_DATA0) != 0x5678) {
1138 if (--retries >= 0)
1139 goto again;
1140 device_printf(sc->dev, "owi_write_data device timeout\n");
1141 return (EIO);
1142 }
1143 #endif
1144
1145 return(0);
1146 }
1147
1148 /*
1149 * Allocate a region of memory inside the NIC and zero
1150 * it out.
1151 */
1152 static int
1153 wi_alloc_nicmem(sc, len, id)
1154 struct wi_softc *sc;
1155 int len;
1156 int *id;
1157 {
1158 int i;
1159
1160 if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len, 0, 0)) {
1161 device_printf(sc->dev,
1162 "failed to allocate %d bytes on NIC\n", len);
1163 return(ENOMEM);
1164 }
1165
1166 for (i = 0; i < WI_TIMEOUT; i++) {
1167 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC)
1168 break;
1169 DELAY(WI_DELAY);
1170 }
1171
1172 if (i == WI_TIMEOUT) {
1173 device_printf(sc->dev, "time out allocating memory on card\n");
1174 return(ETIMEDOUT);
1175 }
1176
1177 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
1178 *id = CSR_READ_2(sc, WI_ALLOC_FID);
1179
1180 if (wi_seek(sc, *id, 0, WI_BAP0)) {
1181 device_printf(sc->dev, "seek failed while allocating memory on card\n");
1182 return(EIO);
1183 }
1184
1185 for (i = 0; i < len / 2; i++)
1186 CSR_WRITE_2(sc, WI_DATA0, 0);
1187
1188 return(0);
1189 }
1190
1191 static void
1192 wi_setmulti(sc)
1193 struct wi_softc *sc;
1194 {
1195 struct ifnet *ifp;
1196 int i = 0;
1197 struct ifmultiaddr *ifma;
1198 struct wi_ltv_mcast mcast;
1199
1200 ifp = &sc->arpcom.ac_if;
1201
1202 bzero((char *)&mcast, sizeof(mcast));
1203
1204 mcast.wi_type = WI_RID_MCAST_LIST;
1205 mcast.wi_len = (3 * 16) + 1;
1206
1207 if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
1208 wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
1209 return;
1210 }
1211
1212 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1213 if (ifma->ifma_addr->sa_family != AF_LINK)
1214 continue;
1215 if (i < 16) {
1216 bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
1217 (char *)&mcast.wi_mcast[i], ETHER_ADDR_LEN);
1218 i++;
1219 } else {
1220 bzero((char *)&mcast, sizeof(mcast));
1221 break;
1222 }
1223 }
1224
1225 mcast.wi_len = (i * 3) + 1;
1226 wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
1227
1228 return;
1229 }
1230
1231 static void
1232 wi_setdef(sc, wreq)
1233 struct wi_softc *sc;
1234 struct wi_req *wreq;
1235 {
1236 struct sockaddr_dl *sdl;
1237 struct ifaddr *ifa;
1238 struct ifnet *ifp;
1239
1240 ifp = &sc->arpcom.ac_if;
1241
1242 switch(wreq->wi_type) {
1243 case WI_RID_MAC_NODE:
1244 ifa = ifaddr_byindex(ifp->if_index);
1245 sdl = (struct sockaddr_dl *)ifa->ifa_addr;
1246 bcopy((char *)&wreq->wi_val, (char *)&sc->arpcom.ac_enaddr,
1247 ETHER_ADDR_LEN);
1248 bcopy((char *)&wreq->wi_val, LLADDR(sdl), ETHER_ADDR_LEN);
1249 break;
1250 case WI_RID_PORTTYPE:
1251 sc->wi_ptype = le16toh(wreq->wi_val[0]);
1252 break;
1253 case WI_RID_TX_RATE:
1254 sc->wi_tx_rate = le16toh(wreq->wi_val[0]);
1255 break;
1256 case WI_RID_MAX_DATALEN:
1257 sc->wi_max_data_len = le16toh(wreq->wi_val[0]);
1258 break;
1259 case WI_RID_RTS_THRESH:
1260 sc->wi_rts_thresh = le16toh(wreq->wi_val[0]);
1261 break;
1262 case WI_RID_SYSTEM_SCALE:
1263 sc->wi_ap_density = le16toh(wreq->wi_val[0]);
1264 break;
1265 case WI_RID_CREATE_IBSS:
1266 sc->wi_create_ibss = le16toh(wreq->wi_val[0]);
1267 break;
1268 case WI_RID_OWN_CHNL:
1269 sc->wi_channel = le16toh(wreq->wi_val[0]);
1270 break;
1271 case WI_RID_NODENAME:
1272 bzero(sc->wi_node_name, sizeof(sc->wi_node_name));
1273 bcopy((char *)&wreq->wi_val[1], sc->wi_node_name, 30);
1274 break;
1275 case WI_RID_DESIRED_SSID:
1276 bzero(sc->wi_net_name, sizeof(sc->wi_net_name));
1277 bcopy((char *)&wreq->wi_val[1], sc->wi_net_name, 30);
1278 break;
1279 case WI_RID_OWN_SSID:
1280 bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name));
1281 bcopy((char *)&wreq->wi_val[1], sc->wi_ibss_name, 30);
1282 break;
1283 case WI_RID_PM_ENABLED:
1284 sc->wi_pm_enabled = le16toh(wreq->wi_val[0]);
1285 break;
1286 case WI_RID_MICROWAVE_OVEN:
1287 sc->wi_mor_enabled = le16toh(wreq->wi_val[0]);
1288 break;
1289 case WI_RID_MAX_SLEEP:
1290 sc->wi_max_sleep = le16toh(wreq->wi_val[0]);
1291 break;
1292 case WI_RID_CNFAUTHMODE:
1293 sc->wi_authtype = le16toh(wreq->wi_val[0]);
1294 break;
1295 case WI_RID_ROAMING_MODE:
1296 sc->wi_roaming = le16toh(wreq->wi_val[0]);
1297 break;
1298 case WI_RID_ENCRYPTION:
1299 sc->wi_use_wep = le16toh(wreq->wi_val[0]);
1300 break;
1301 case WI_RID_TX_CRYPT_KEY:
1302 sc->wi_tx_key = le16toh(wreq->wi_val[0]);
1303 break;
1304 case WI_RID_DEFLT_CRYPT_KEYS:
1305 bcopy((char *)wreq, (char *)&sc->wi_keys,
1306 sizeof(struct wi_ltv_keys));
1307 break;
1308 default:
1309 break;
1310 }
1311
1312 /* Reinitialize WaveLAN. */
1313 wi_init(sc);
1314
1315 return;
1316 }
1317
1318 static int
1319 wi_ioctl(ifp, command, data)
1320 struct ifnet *ifp;
1321 u_long command;
1322 caddr_t data;
1323 {
1324 int error = 0;
1325 int len;
1326 int s;
1327 uint16_t mif;
1328 uint16_t val;
1329 u_int8_t tmpkey[14];
1330 char tmpssid[IEEE80211_NWID_LEN];
1331 struct wi_softc *sc;
1332 struct wi_req wreq;
1333 struct ifreq *ifr;
1334 struct ieee80211req *ireq;
1335 struct thread *td = curthread;
1336
1337 sc = ifp->if_softc;
1338 WI_LOCK(sc, s);
1339 ifr = (struct ifreq *)data;
1340 ireq = (struct ieee80211req *)data;
1341
1342 if (sc->wi_gone) {
1343 error = ENODEV;
1344 goto out;
1345 }
1346
1347 switch(command) {
1348 case SIOCSIFFLAGS:
1349 /*
1350 * Can't do promisc and hostap at the same time. If all that's
1351 * changing is the promisc flag, try to short-circuit a call to
1352 * wi_init() by just setting PROMISC in the hardware.
1353 */
1354 if (ifp->if_flags & IFF_UP) {
1355 if (ifp->if_flags & IFF_RUNNING) {
1356 if (ifp->if_flags & IFF_PROMISC &&
1357 !(sc->wi_if_flags & IFF_PROMISC)) {
1358 WI_SETVAL(WI_RID_PROMISC, 1);
1359 } else if (!(ifp->if_flags & IFF_PROMISC) &&
1360 sc->wi_if_flags & IFF_PROMISC) {
1361 WI_SETVAL(WI_RID_PROMISC, 0);
1362 } else {
1363 wi_init(sc);
1364 }
1365 } else {
1366 wi_init(sc);
1367 }
1368 } else {
1369 if (ifp->if_flags & IFF_RUNNING) {
1370 owi_stop(sc);
1371 }
1372 }
1373 sc->wi_if_flags = ifp->if_flags;
1374 error = 0;
1375 break;
1376 case SIOCSIFMEDIA:
1377 case SIOCGIFMEDIA:
1378 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);
1379 break;
1380 case SIOCADDMULTI:
1381 case SIOCDELMULTI:
1382 wi_setmulti(sc);
1383 error = 0;
1384 break;
1385 case SIOCGWAVELAN:
1386 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1387 if (error)
1388 break;
1389 if (wreq.wi_len > WI_MAX_DATALEN) {
1390 error = EINVAL;
1391 break;
1392 }
1393 /* Don't show WEP keys to non-root users. */
1394 if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS && suser(td))
1395 break;
1396 if (wreq.wi_type == WI_RID_IFACE_STATS) {
1397 bcopy((char *)&sc->wi_stats, (char *)&wreq.wi_val,
1398 sizeof(sc->wi_stats));
1399 wreq.wi_len = (sizeof(sc->wi_stats) / 2) + 1;
1400 } else if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS) {
1401 bcopy((char *)&sc->wi_keys, (char *)&wreq,
1402 sizeof(struct wi_ltv_keys));
1403 }
1404 #ifdef WICACHE
1405 else if (wreq.wi_type == WI_RID_ZERO_CACHE) {
1406 error = suser(td);
1407 if (error)
1408 break;
1409 sc->wi_sigitems = sc->wi_nextitem = 0;
1410 } else if (wreq.wi_type == WI_RID_READ_CACHE) {
1411 char *pt = (char *)&wreq.wi_val;
1412 bcopy((char *)&sc->wi_sigitems,
1413 (char *)pt, sizeof(int));
1414 pt += (sizeof (int));
1415 wreq.wi_len = sizeof(int) / 2;
1416 bcopy((char *)&sc->wi_sigcache, (char *)pt,
1417 sizeof(struct wi_sigcache) * sc->wi_sigitems);
1418 wreq.wi_len += ((sizeof(struct wi_sigcache) *
1419 sc->wi_sigitems) / 2) + 1;
1420 }
1421 #endif
1422 else if (wreq.wi_type == WI_RID_PROCFRAME) {
1423 wreq.wi_len = 2;
1424 wreq.wi_val[0] = sc->wi_procframe;
1425 } else if (wreq.wi_type == WI_RID_SCAN_RES) {
1426 memcpy((char *)wreq.wi_val, (char *)sc->wi_scanbuf,
1427 sc->wi_scanbuf_len * 2);
1428 wreq.wi_len = sc->wi_scanbuf_len;
1429 } else if (wreq.wi_type == WI_RID_MIF) {
1430 mif = wreq.wi_val[0];
1431 error = wi_cmd(sc, WI_CMD_READMIF, mif, 0, 0);
1432 val = CSR_READ_2(sc, WI_RESP0);
1433 wreq.wi_len = 2;
1434 wreq.wi_val[0] = val;
1435 } else {
1436 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) {
1437 error = EINVAL;
1438 break;
1439 }
1440 }
1441 error = copyout(&wreq, ifr->ifr_data, sizeof(wreq));
1442 break;
1443 case SIOCSWAVELAN:
1444 if ((error = suser(td)))
1445 goto out;
1446 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1447 if (error)
1448 break;
1449 if (wreq.wi_len > WI_MAX_DATALEN) {
1450 error = EINVAL;
1451 break;
1452 }
1453 if (wreq.wi_type == WI_RID_IFACE_STATS) {
1454 error = EINVAL;
1455 break;
1456 } else if (wreq.wi_type == WI_RID_PROCFRAME) {
1457 sc->wi_procframe = wreq.wi_val[0];
1458 /*
1459 * if we're getting a scan request from a wavelan card
1460 * (non-prism2), send out a cmd_inquire to the card to scan
1461 * results for the scan will be received through the info
1462 * interrupt handler. otherwise the scan request can be
1463 * directly handled by a prism2 card's rid interface.
1464 */
1465 } else if (wreq.wi_type == WI_RID_SCAN_REQ) {
1466 wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS, 0, 0);
1467 } else if (wreq.wi_type == WI_RID_MIF) {
1468 mif = wreq.wi_val[0];
1469 val = wreq.wi_val[1];
1470 error = wi_cmd(sc, WI_CMD_WRITEMIF, mif, val, 0);
1471 } else {
1472 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
1473 if (!error)
1474 wi_setdef(sc, &wreq);
1475 }
1476 break;
1477 case SIOCG80211:
1478 switch(ireq->i_type) {
1479 case IEEE80211_IOC_SSID:
1480 if(ireq->i_val == -1) {
1481 bzero(tmpssid, IEEE80211_NWID_LEN);
1482 error = wi_get_cur_ssid(sc, tmpssid, &len);
1483 if (error != 0)
1484 break;
1485 error = copyout(tmpssid, ireq->i_data,
1486 IEEE80211_NWID_LEN);
1487 ireq->i_len = len;
1488 } else if (ireq->i_val == 0) {
1489 error = copyout(sc->wi_net_name,
1490 ireq->i_data,
1491 IEEE80211_NWID_LEN);
1492 ireq->i_len = IEEE80211_NWID_LEN;
1493 } else
1494 error = EINVAL;
1495 break;
1496 case IEEE80211_IOC_NUMSSIDS:
1497 ireq->i_val = 1;
1498 break;
1499 case IEEE80211_IOC_WEP:
1500 if(!sc->wi_has_wep) {
1501 ireq->i_val = IEEE80211_WEP_NOSUP;
1502 } else {
1503 if(sc->wi_use_wep) {
1504 ireq->i_val =
1505 IEEE80211_WEP_MIXED;
1506 } else {
1507 ireq->i_val =
1508 IEEE80211_WEP_OFF;
1509 }
1510 }
1511 break;
1512 case IEEE80211_IOC_WEPKEY:
1513 if(!sc->wi_has_wep ||
1514 ireq->i_val < 0 || ireq->i_val > 3) {
1515 error = EINVAL;
1516 break;
1517 }
1518 len = sc->wi_keys.wi_keys[ireq->i_val].wi_keylen;
1519 if (suser(td))
1520 bcopy(sc->wi_keys.wi_keys[ireq->i_val].wi_keydat,
1521 tmpkey, len);
1522 else
1523 bzero(tmpkey, len);
1524
1525 ireq->i_len = len;
1526 error = copyout(tmpkey, ireq->i_data, len);
1527
1528 break;
1529 case IEEE80211_IOC_NUMWEPKEYS:
1530 if(!sc->wi_has_wep)
1531 error = EINVAL;
1532 else
1533 ireq->i_val = 4;
1534 break;
1535 case IEEE80211_IOC_WEPTXKEY:
1536 if(!sc->wi_has_wep)
1537 error = EINVAL;
1538 else
1539 ireq->i_val = sc->wi_tx_key;
1540 break;
1541 case IEEE80211_IOC_AUTHMODE:
1542 ireq->i_val = sc->wi_authmode;
1543 break;
1544 case IEEE80211_IOC_STATIONNAME:
1545 error = copyout(sc->wi_node_name,
1546 ireq->i_data, IEEE80211_NWID_LEN);
1547 ireq->i_len = IEEE80211_NWID_LEN;
1548 break;
1549 case IEEE80211_IOC_CHANNEL:
1550 wreq.wi_type = WI_RID_CURRENT_CHAN;
1551 wreq.wi_len = WI_MAX_DATALEN;
1552 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq))
1553 error = EINVAL;
1554 else {
1555 ireq->i_val = wreq.wi_val[0];
1556 }
1557 break;
1558 case IEEE80211_IOC_POWERSAVE:
1559 if(sc->wi_pm_enabled)
1560 ireq->i_val = IEEE80211_POWERSAVE_ON;
1561 else
1562 ireq->i_val = IEEE80211_POWERSAVE_OFF;
1563 break;
1564 case IEEE80211_IOC_POWERSAVESLEEP:
1565 ireq->i_val = sc->wi_max_sleep;
1566 break;
1567 default:
1568 error = EINVAL;
1569 }
1570 break;
1571 case SIOCS80211:
1572 if ((error = suser(td)))
1573 goto out;
1574 switch(ireq->i_type) {
1575 case IEEE80211_IOC_SSID:
1576 if (ireq->i_val != 0 ||
1577 ireq->i_len > IEEE80211_NWID_LEN) {
1578 error = EINVAL;
1579 break;
1580 }
1581 /* We set both of them */
1582 bzero(sc->wi_net_name, IEEE80211_NWID_LEN);
1583 error = copyin(ireq->i_data,
1584 sc->wi_net_name, ireq->i_len);
1585 bcopy(sc->wi_net_name, sc->wi_ibss_name, IEEE80211_NWID_LEN);
1586 break;
1587 case IEEE80211_IOC_WEP:
1588 /*
1589 * These cards only support one mode so
1590 * we just turn wep on what ever is
1591 * passed in if it's not OFF.
1592 */
1593 if (ireq->i_val == IEEE80211_WEP_OFF) {
1594 sc->wi_use_wep = 0;
1595 } else {
1596 sc->wi_use_wep = 1;
1597 }
1598 break;
1599 case IEEE80211_IOC_WEPKEY:
1600 if (ireq->i_val < 0 || ireq->i_val > 3 ||
1601 ireq->i_len > 13) {
1602 error = EINVAL;
1603 break;
1604 }
1605 bzero(sc->wi_keys.wi_keys[ireq->i_val].wi_keydat, 13);
1606 error = copyin(ireq->i_data,
1607 sc->wi_keys.wi_keys[ireq->i_val].wi_keydat,
1608 ireq->i_len);
1609 if(error)
1610 break;
1611 sc->wi_keys.wi_keys[ireq->i_val].wi_keylen =
1612 ireq->i_len;
1613 break;
1614 case IEEE80211_IOC_WEPTXKEY:
1615 if (ireq->i_val < 0 || ireq->i_val > 3) {
1616 error = EINVAL;
1617 break;
1618 }
1619 sc->wi_tx_key = ireq->i_val;
1620 break;
1621 case IEEE80211_IOC_AUTHMODE:
1622 sc->wi_authmode = ireq->i_val;
1623 break;
1624 case IEEE80211_IOC_STATIONNAME:
1625 if (ireq->i_len > 32) {
1626 error = EINVAL;
1627 break;
1628 }
1629 bzero(sc->wi_node_name, 32);
1630 error = copyin(ireq->i_data,
1631 sc->wi_node_name, ireq->i_len);
1632 break;
1633 case IEEE80211_IOC_CHANNEL:
1634 /*
1635 * The actual range is 1-14, but if you
1636 * set it to 0 you get the default. So
1637 * we let that work too.
1638 */
1639 if (ireq->i_val < 0 || ireq->i_val > 14) {
1640 error = EINVAL;
1641 break;
1642 }
1643 sc->wi_channel = ireq->i_val;
1644 break;
1645 case IEEE80211_IOC_POWERSAVE:
1646 switch (ireq->i_val) {
1647 case IEEE80211_POWERSAVE_OFF:
1648 sc->wi_pm_enabled = 0;
1649 break;
1650 case IEEE80211_POWERSAVE_ON:
1651 sc->wi_pm_enabled = 1;
1652 break;
1653 default:
1654 error = EINVAL;
1655 break;
1656 }
1657 break;
1658 case IEEE80211_IOC_POWERSAVESLEEP:
1659 if (ireq->i_val < 0) {
1660 error = EINVAL;
1661 break;
1662 }
1663 sc->wi_max_sleep = ireq->i_val;
1664 break;
1665 default:
1666 error = EINVAL;
1667 break;
1668 }
1669
1670 /* Reinitialize WaveLAN. */
1671 wi_init(sc);
1672
1673 break;
1674 default:
1675 error = ether_ioctl(ifp, command, data);
1676 break;
1677 }
1678 out:
1679 WI_UNLOCK(sc, s);
1680
1681 return(error);
1682 }
1683
1684 static void
1685 wi_init(xsc)
1686 void *xsc;
1687 {
1688 struct wi_softc *sc = xsc;
1689 struct ifnet *ifp = &sc->arpcom.ac_if;
1690 struct wi_ltv_macaddr mac;
1691 int id = 0;
1692 int s;
1693
1694 WI_LOCK(sc, s);
1695
1696 if (sc->wi_gone) {
1697 WI_UNLOCK(sc, s);
1698 return;
1699 }
1700
1701 if (ifp->if_flags & IFF_RUNNING)
1702 owi_stop(sc);
1703
1704 wi_reset(sc);
1705
1706 /* Program max data length. */
1707 WI_SETVAL(WI_RID_MAX_DATALEN, sc->wi_max_data_len);
1708
1709 /* Set the port type. */
1710 WI_SETVAL(WI_RID_PORTTYPE, sc->wi_ptype);
1711
1712 /* Enable/disable IBSS creation. */
1713 WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss);
1714
1715 /* Program the RTS/CTS threshold. */
1716 WI_SETVAL(WI_RID_RTS_THRESH, sc->wi_rts_thresh);
1717
1718 /* Program the TX rate */
1719 WI_SETVAL(WI_RID_TX_RATE, sc->wi_tx_rate);
1720
1721 /* Access point density */
1722 WI_SETVAL(WI_RID_SYSTEM_SCALE, sc->wi_ap_density);
1723
1724 /* Power Management Enabled */
1725 WI_SETVAL(WI_RID_PM_ENABLED, sc->wi_pm_enabled);
1726
1727 /* Power Managment Max Sleep */
1728 WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep);
1729
1730 /* Roaming type */
1731 WI_SETVAL(WI_RID_ROAMING_MODE, sc->wi_roaming);
1732
1733 /* Specify the IBSS name */
1734 WI_SETSTR(WI_RID_OWN_SSID, sc->wi_ibss_name);
1735
1736 /* Specify the network name */
1737 WI_SETSTR(WI_RID_DESIRED_SSID, sc->wi_net_name);
1738
1739 /* Specify the frequency to use */
1740 WI_SETVAL(WI_RID_OWN_CHNL, sc->wi_channel);
1741
1742 /* Program the nodename. */
1743 WI_SETSTR(WI_RID_NODENAME, sc->wi_node_name);
1744
1745 /* Specify the authentication mode. */
1746 WI_SETVAL(WI_RID_CNFAUTHMODE, sc->wi_authmode);
1747
1748 /* Set our MAC address. */
1749 mac.wi_len = 4;
1750 mac.wi_type = WI_RID_MAC_NODE;
1751 bcopy((char *)&sc->arpcom.ac_enaddr,
1752 (char *)&mac.wi_mac_addr, ETHER_ADDR_LEN);
1753 wi_write_record(sc, (struct wi_ltv_gen *)&mac);
1754
1755 /*
1756 * Initialize promisc mode.
1757 */
1758 if (ifp->if_flags & IFF_PROMISC)
1759 WI_SETVAL(WI_RID_PROMISC, 1);
1760 else
1761 WI_SETVAL(WI_RID_PROMISC, 0);
1762
1763 /* Configure WEP. */
1764 if (sc->wi_has_wep) {
1765 WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep);
1766 WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key);
1767 sc->wi_keys.wi_len = (sizeof(struct wi_ltv_keys) / 2) + 1;
1768 sc->wi_keys.wi_type = WI_RID_DEFLT_CRYPT_KEYS;
1769 wi_write_record(sc, (struct wi_ltv_gen *)&sc->wi_keys);
1770 }
1771
1772 /* Set multicast filter. */
1773 wi_setmulti(sc);
1774
1775 /* Enable desired port */
1776 wi_cmd(sc, WI_CMD_ENABLE | sc->wi_portnum, 0, 0, 0);
1777
1778 if (wi_alloc_nicmem(sc, ETHER_MAX_LEN + sizeof(struct wi_frame) + 8, &id))
1779 device_printf(sc->dev, "tx buffer allocation failed\n");
1780 sc->wi_tx_data_id = id;
1781
1782 if (wi_alloc_nicmem(sc, ETHER_MAX_LEN + sizeof(struct wi_frame) + 8, &id))
1783 device_printf(sc->dev, "mgmt. buffer allocation failed\n");
1784 sc->wi_tx_mgmt_id = id;
1785
1786 /* enable interrupts */
1787 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
1788
1789 ifp->if_flags |= IFF_RUNNING;
1790 ifp->if_flags &= ~IFF_OACTIVE;
1791
1792 sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60);
1793 WI_UNLOCK(sc, s);
1794
1795 return;
1796 }
1797
1798 static void
1799 wi_start(ifp)
1800 struct ifnet *ifp;
1801 {
1802 struct wi_softc *sc;
1803 struct mbuf *m0;
1804 struct wi_frame tx_frame;
1805 struct ether_header *eh;
1806 int id;
1807 int s;
1808
1809 sc = ifp->if_softc;
1810 WI_LOCK(sc, s);
1811
1812 if (sc->wi_gone) {
1813 WI_UNLOCK(sc, s);
1814 return;
1815 }
1816
1817 if (ifp->if_flags & IFF_OACTIVE) {
1818 WI_UNLOCK(sc, s);
1819 return;
1820 }
1821
1822 IF_DEQUEUE(&ifp->if_snd, m0);
1823 if (m0 == NULL) {
1824 WI_UNLOCK(sc, s);
1825 return;
1826 }
1827
1828 bzero((char *)&tx_frame, sizeof(tx_frame));
1829 tx_frame.wi_frame_ctl = htole16(WI_FTYPE_DATA);
1830 id = sc->wi_tx_data_id;
1831 eh = mtod(m0, struct ether_header *);
1832
1833 /*
1834 * Use RFC1042 encoding for IP and ARP datagrams,
1835 * 802.3 for anything else.
1836 */
1837 if (ntohs(eh->ether_type) > ETHER_MAX_LEN) {
1838 bcopy((char *)&eh->ether_dhost,
1839 (char *)&tx_frame.wi_addr1, ETHER_ADDR_LEN);
1840 bcopy((char *)&eh->ether_shost,
1841 (char *)&tx_frame.wi_addr2, ETHER_ADDR_LEN);
1842 bcopy((char *)&eh->ether_dhost,
1843 (char *)&tx_frame.wi_dst_addr, ETHER_ADDR_LEN);
1844 bcopy((char *)&eh->ether_shost,
1845 (char *)&tx_frame.wi_src_addr, ETHER_ADDR_LEN);
1846
1847 tx_frame.wi_dat_len = m0->m_pkthdr.len - WI_SNAPHDR_LEN;
1848 tx_frame.wi_dat[0] = htons(WI_SNAP_WORD0);
1849 tx_frame.wi_dat[1] = htons(WI_SNAP_WORD1);
1850 tx_frame.wi_len = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN);
1851 tx_frame.wi_type = eh->ether_type;
1852
1853 m_copydata(m0, sizeof(struct ether_header),
1854 m0->m_pkthdr.len - sizeof(struct ether_header),
1855 (caddr_t)&sc->wi_txbuf);
1856 wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
1857 sizeof(struct wi_frame));
1858 wi_write_data(sc, id, WI_802_11_OFFSET,
1859 (caddr_t)&sc->wi_txbuf, (m0->m_pkthdr.len -
1860 sizeof(struct ether_header)) + 2);
1861 } else {
1862 tx_frame.wi_dat_len = m0->m_pkthdr.len;
1863
1864 eh->ether_type = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN);
1865 m_copydata(m0, 0, m0->m_pkthdr.len, (caddr_t)&sc->wi_txbuf);
1866 wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
1867 sizeof(struct wi_frame));
1868 wi_write_data(sc, id, WI_802_3_OFFSET,
1869 (caddr_t)&sc->wi_txbuf, m0->m_pkthdr.len + 2);
1870 }
1871
1872 /*
1873 * If there's a BPF listner, bounce a copy of
1874 * this frame to him. Also, don't send this to the bpf sniffer
1875 * if we're in procframe or monitor sniffing mode.
1876 */
1877 if (!(sc->wi_procframe || sc->wi_debug.wi_monitor))
1878 BPF_MTAP(ifp, m0);
1879
1880 m_freem(m0);
1881
1882 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id, 0, 0))
1883 device_printf(sc->dev, "xmit failed\n");
1884
1885 ifp->if_flags |= IFF_OACTIVE;
1886
1887 /*
1888 * Set a timeout in case the chip goes out to lunch.
1889 */
1890 ifp->if_timer = 5;
1891
1892 WI_UNLOCK(sc, s);
1893 return;
1894 }
1895
1896 void
1897 owi_stop(sc)
1898 struct wi_softc *sc;
1899 {
1900 struct ifnet *ifp;
1901 int s;
1902
1903 WI_LOCK(sc, s);
1904
1905 untimeout(wi_inquire, sc, sc->wi_stat_ch);
1906
1907 if (sc->wi_gone) {
1908 WI_UNLOCK(sc, s);
1909 return;
1910 }
1911
1912 ifp = &sc->arpcom.ac_if;
1913
1914 /*
1915 * If the card is gone and the memory port isn't mapped, we will
1916 * (hopefully) get 0xffff back from the status read, which is not
1917 * a valid status value.
1918 */
1919 if (CSR_READ_2(sc, WI_STATUS) != 0xffff) {
1920 CSR_WRITE_2(sc, WI_INT_EN, 0);
1921 wi_cmd(sc, WI_CMD_DISABLE|sc->wi_portnum, 0, 0, 0);
1922 }
1923
1924 ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
1925
1926 WI_UNLOCK(sc, s);
1927 return;
1928 }
1929
1930 static void
1931 wi_watchdog(ifp)
1932 struct ifnet *ifp;
1933 {
1934 struct wi_softc *sc;
1935
1936 sc = ifp->if_softc;
1937
1938 device_printf(sc->dev, "watchdog timeout\n");
1939
1940 wi_init(sc);
1941
1942 ifp->if_oerrors++;
1943
1944 return;
1945 }
1946
1947 int
1948 owi_alloc(dev, rid)
1949 device_t dev;
1950 int rid;
1951 {
1952 struct wi_softc *sc = device_get_softc(dev);
1953
1954 if (sc->wi_bus_type != WI_BUS_PCI_NATIVE) {
1955 sc->iobase_rid = rid;
1956 sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT,
1957 &sc->iobase_rid, 0, ~0, (1 << 6),
1958 rman_make_alignment_flags(1 << 6) | RF_ACTIVE);
1959 if (!sc->iobase) {
1960 device_printf(dev, "No I/O space?!\n");
1961 return (ENXIO);
1962 }
1963
1964 sc->wi_io_addr = rman_get_start(sc->iobase);
1965 sc->wi_btag = rman_get_bustag(sc->iobase);
1966 sc->wi_bhandle = rman_get_bushandle(sc->iobase);
1967 } else {
1968 sc->mem_rid = rid;
1969 sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
1970 &sc->mem_rid, RF_ACTIVE);
1971
1972 if (!sc->mem) {
1973 device_printf(dev, "No Mem space on prism2.5?\n");
1974 return (ENXIO);
1975 }
1976
1977 sc->wi_btag = rman_get_bustag(sc->mem);
1978 sc->wi_bhandle = rman_get_bushandle(sc->mem);
1979 }
1980
1981
1982 sc->irq_rid = 0;
1983 sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
1984 RF_ACTIVE |
1985 ((sc->wi_bus_type == WI_BUS_PCCARD) ? 0 : RF_SHAREABLE));
1986
1987 if (!sc->irq) {
1988 owi_free(dev);
1989 device_printf(dev, "No irq?!\n");
1990 return (ENXIO);
1991 }
1992
1993 sc->dev = dev;
1994 sc->wi_unit = device_get_unit(dev);
1995
1996 return (0);
1997 }
1998
1999 void
2000 owi_free(dev)
2001 device_t dev;
2002 {
2003 struct wi_softc *sc = device_get_softc(dev);
2004
2005 if (sc->iobase != NULL) {
2006 bus_release_resource(dev, SYS_RES_IOPORT, sc->iobase_rid, sc->iobase);
2007 sc->iobase = NULL;
2008 }
2009 if (sc->irq != NULL) {
2010 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
2011 sc->irq = NULL;
2012 }
2013 if (sc->mem != NULL) {
2014 bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
2015 sc->mem = NULL;
2016 }
2017
2018 return;
2019 }
2020
2021 void
2022 owi_shutdown(dev)
2023 device_t dev;
2024 {
2025 struct wi_softc *sc;
2026
2027 sc = device_get_softc(dev);
2028 owi_stop(sc);
2029
2030 return;
2031 }
2032
2033 #ifdef WICACHE
2034 /* wavelan signal strength cache code.
2035 * store signal/noise/quality on per MAC src basis in
2036 * a small fixed cache. The cache wraps if > MAX slots
2037 * used. The cache may be zeroed out to start over.
2038 * Two simple filters exist to reduce computation:
2039 * 1. ip only (literally 0x800) which may be used
2040 * to ignore some packets. It defaults to ip only.
2041 * it could be used to focus on broadcast, non-IP 802.11 beacons.
2042 * 2. multicast/broadcast only. This may be used to
2043 * ignore unicast packets and only cache signal strength
2044 * for multicast/broadcast packets (beacons); e.g., Mobile-IP
2045 * beacons and not unicast traffic.
2046 *
2047 * The cache stores (MAC src(index), IP src (major clue), signal,
2048 * quality, noise)
2049 *
2050 * No apologies for storing IP src here. It's easy and saves much
2051 * trouble elsewhere. The cache is assumed to be INET dependent,
2052 * although it need not be.
2053 */
2054
2055 #ifdef documentation
2056
2057 int wi_sigitems; /* number of cached entries */
2058 struct wi_sigcache wi_sigcache[MAXWICACHE]; /* array of cache entries */
2059 int wi_nextitem; /* index/# of entries */
2060
2061
2062 #endif
2063
2064 /* control variables for cache filtering. Basic idea is
2065 * to reduce cost (e.g., to only Mobile-IP agent beacons
2066 * which are broadcast or multicast). Still you might
2067 * want to measure signal strength with unicast ping packets
2068 * on a pt. to pt. ant. setup.
2069 */
2070 /* set true if you want to limit cache items to broadcast/mcast
2071 * only packets (not unicast). Useful for mobile-ip beacons which
2072 * are broadcast/multicast at network layer. Default is all packets
2073 * so ping/unicast will work say with pt. to pt. antennae setup.
2074 */
2075 static int wi_cache_mcastonly = 0;
2076 SYSCTL_INT(_machdep, OID_AUTO, wi_cache_mcastonly, CTLFLAG_RW,
2077 &wi_cache_mcastonly, 0, "");
2078
2079 /* set true if you want to limit cache items to IP packets only
2080 */
2081 static int wi_cache_iponly = 1;
2082 SYSCTL_INT(_machdep, OID_AUTO, wi_cache_iponly, CTLFLAG_RW,
2083 &wi_cache_iponly, 0, "");
2084
2085 /*
2086 * Original comments:
2087 * -----------------
2088 * wi_cache_store, per rx packet store signal
2089 * strength in MAC (src) indexed cache.
2090 *
2091 * follows linux driver in how signal strength is computed.
2092 * In ad hoc mode, we use the rx_quality field.
2093 * signal and noise are trimmed to fit in the range from 47..138.
2094 * rx_quality field MSB is signal strength.
2095 * rx_quality field LSB is noise.
2096 * "quality" is (signal - noise) as is log value.
2097 * note: quality CAN be negative.
2098 *
2099 * In BSS mode, we use the RID for communication quality.
2100 * TBD: BSS mode is currently untested.
2101 *
2102 * Bill's comments:
2103 * ---------------
2104 * Actually, we use the rx_quality field all the time for both "ad-hoc"
2105 * and BSS modes. Why? Because reading an RID is really, really expensive:
2106 * there's a bunch of PIO operations that have to be done to read a record
2107 * from the NIC, and reading the comms quality RID each time a packet is
2108 * received can really hurt performance. We don't have to do this anyway:
2109 * the comms quality field only reflects the values in the rx_quality field
2110 * anyway. The comms quality RID is only meaningful in infrastructure mode,
2111 * but the values it contains are updated based on the rx_quality from
2112 * frames received from the access point.
2113 *
2114 * Also, according to Lucent, the signal strength and noise level values
2115 * can be converted to dBms by subtracting 149, so I've modified the code
2116 * to do that instead of the scaling it did originally.
2117 */
2118 static void
2119 wi_cache_store(struct wi_softc *sc, struct ether_header *eh,
2120 struct mbuf *m, unsigned short rx_quality)
2121 {
2122 struct ip *ip = 0;
2123 int i;
2124 static int cache_slot = 0; /* use this cache entry */
2125 static int wrapindex = 0; /* next "free" cache entry */
2126 int sig, noise;
2127 int sawip=0;
2128
2129 /*
2130 * filters:
2131 * 1. ip only
2132 * 2. configurable filter to throw out unicast packets,
2133 * keep multicast only.
2134 */
2135
2136 if ((ntohs(eh->ether_type) == ETHERTYPE_IP)) {
2137 sawip = 1;
2138 }
2139
2140 /*
2141 * filter for ip packets only
2142 */
2143 if (wi_cache_iponly && !sawip) {
2144 return;
2145 }
2146
2147 /*
2148 * filter for broadcast/multicast only
2149 */
2150 if (wi_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) {
2151 return;
2152 }
2153
2154 #ifdef SIGDEBUG
2155 printf("owi%d: q value %x (MSB=0x%x, LSB=0x%x) \n", sc->wi_unit,
2156 rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff);
2157 #endif
2158
2159 /*
2160 * find the ip header. we want to store the ip_src
2161 * address.
2162 */
2163 if (sawip)
2164 ip = mtod(m, struct ip *);
2165
2166 /*
2167 * do a linear search for a matching MAC address
2168 * in the cache table
2169 * . MAC address is 6 bytes,
2170 * . var w_nextitem holds total number of entries already cached
2171 */
2172 for(i = 0; i < sc->wi_nextitem; i++) {
2173 if (! bcmp(eh->ether_shost , sc->wi_sigcache[i].macsrc, 6 )) {
2174 /*
2175 * Match!,
2176 * so we already have this entry,
2177 * update the data
2178 */
2179 break;
2180 }
2181 }
2182
2183 /*
2184 * did we find a matching mac address?
2185 * if yes, then overwrite a previously existing cache entry
2186 */
2187 if (i < sc->wi_nextitem ) {
2188 cache_slot = i;
2189 }
2190 /*
2191 * else, have a new address entry,so
2192 * add this new entry,
2193 * if table full, then we need to replace LRU entry
2194 */
2195 else {
2196
2197 /*
2198 * check for space in cache table
2199 * note: wi_nextitem also holds number of entries
2200 * added in the cache table
2201 */
2202 if ( sc->wi_nextitem < MAXWICACHE ) {
2203 cache_slot = sc->wi_nextitem;
2204 sc->wi_nextitem++;
2205 sc->wi_sigitems = sc->wi_nextitem;
2206 }
2207 /* no space found, so simply wrap with wrap index
2208 * and "zap" the next entry
2209 */
2210 else {
2211 if (wrapindex == MAXWICACHE) {
2212 wrapindex = 0;
2213 }
2214 cache_slot = wrapindex++;
2215 }
2216 }
2217
2218 /*
2219 * invariant: cache_slot now points at some slot
2220 * in cache.
2221 */
2222 if (cache_slot < 0 || cache_slot >= MAXWICACHE) {
2223 log(LOG_ERR, "owi_cache_store, bad index: %d of "
2224 "[0..%d], gross cache error\n",
2225 cache_slot, MAXWICACHE);
2226 return;
2227 }
2228
2229 /*
2230 * store items in cache
2231 * .ip source address
2232 * .mac src
2233 * .signal, etc.
2234 */
2235 if (sawip)
2236 sc->wi_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr;
2237 bcopy( eh->ether_shost, sc->wi_sigcache[cache_slot].macsrc, 6);
2238
2239 sig = (rx_quality >> 8) & 0xFF;
2240 noise = rx_quality & 0xFF;
2241
2242 /*
2243 * -149 is Lucent specific to convert to dBm. Prism2 cards do
2244 * things differently, sometimes don't have a noise measurement,
2245 * and is firmware dependent :-(
2246 */
2247 sc->wi_sigcache[cache_slot].signal = sig - 149;
2248 sc->wi_sigcache[cache_slot].noise = noise - 149;
2249 sc->wi_sigcache[cache_slot].quality = sig - noise;
2250
2251 return;
2252 }
2253 #endif
2254
2255 static int
2256 wi_get_cur_ssid(sc, ssid, len)
2257 struct wi_softc *sc;
2258 char *ssid;
2259 int *len;
2260 {
2261 int error = 0;
2262 struct wi_req wreq;
2263
2264 wreq.wi_len = WI_MAX_DATALEN;
2265 switch (sc->wi_ptype) {
2266 case WI_PORTTYPE_IBSS:
2267 case WI_PORTTYPE_ADHOC:
2268 wreq.wi_type = WI_RID_CURRENT_SSID;
2269 error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq);
2270 if (error != 0)
2271 break;
2272 if (wreq.wi_val[0] > IEEE80211_NWID_LEN) {
2273 error = EINVAL;
2274 break;
2275 }
2276 *len = wreq.wi_val[0];
2277 bcopy(&wreq.wi_val[1], ssid, IEEE80211_NWID_LEN);
2278 break;
2279 case WI_PORTTYPE_BSS:
2280 wreq.wi_type = WI_RID_COMMQUAL;
2281 error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq);
2282 if (error != 0)
2283 break;
2284 if (wreq.wi_val[0] != 0) /* associated */ {
2285 wreq.wi_type = WI_RID_CURRENT_SSID;
2286 wreq.wi_len = WI_MAX_DATALEN;
2287 error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq);
2288 if (error != 0)
2289 break;
2290 if (wreq.wi_val[0] > IEEE80211_NWID_LEN) {
2291 error = EINVAL;
2292 break;
2293 }
2294 *len = wreq.wi_val[0];
2295 bcopy(&wreq.wi_val[1], ssid, IEEE80211_NWID_LEN);
2296 } else {
2297 *len = IEEE80211_NWID_LEN;
2298 bcopy(sc->wi_net_name, ssid, IEEE80211_NWID_LEN);
2299 }
2300 break;
2301 default:
2302 error = EINVAL;
2303 break;
2304 }
2305
2306 return error;
2307 }
2308
2309 static int
2310 wi_media_change(ifp)
2311 struct ifnet *ifp;
2312 {
2313 struct wi_softc *sc = ifp->if_softc;
2314 int otype = sc->wi_ptype;
2315 int orate = sc->wi_tx_rate;
2316 int ocreate_ibss = sc->wi_create_ibss;
2317
2318 sc->wi_create_ibss = 0;
2319
2320 switch (sc->ifmedia.ifm_cur->ifm_media & IFM_OMASK) {
2321 case 0:
2322 sc->wi_ptype = WI_PORTTYPE_BSS;
2323 break;
2324 case IFM_IEEE80211_ADHOC:
2325 sc->wi_ptype = WI_PORTTYPE_ADHOC;
2326 break;
2327 case IFM_IEEE80211_IBSSMASTER:
2328 case IFM_IEEE80211_IBSSMASTER|IFM_IEEE80211_IBSS:
2329 if (!(sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS))
2330 return (EINVAL);
2331 sc->wi_create_ibss = 1;
2332 /* FALLTHROUGH */
2333 case IFM_IEEE80211_IBSS:
2334 sc->wi_ptype = WI_PORTTYPE_IBSS;
2335 break;
2336 default:
2337 /* Invalid combination. */
2338 return (EINVAL);
2339 }
2340
2341 switch (IFM_SUBTYPE(sc->ifmedia.ifm_cur->ifm_media)) {
2342 case IFM_IEEE80211_DS1:
2343 sc->wi_tx_rate = 1;
2344 break;
2345 case IFM_IEEE80211_DS2:
2346 sc->wi_tx_rate = 2;
2347 break;
2348 case IFM_IEEE80211_DS5:
2349 sc->wi_tx_rate = 5;
2350 break;
2351 case IFM_IEEE80211_DS11:
2352 sc->wi_tx_rate = 11;
2353 break;
2354 case IFM_AUTO:
2355 sc->wi_tx_rate = 3;
2356 break;
2357 }
2358
2359 if (ocreate_ibss != sc->wi_create_ibss || otype != sc->wi_ptype ||
2360 orate != sc->wi_tx_rate)
2361 wi_init(sc);
2362
2363 return(0);
2364 }
2365
2366 static void
2367 wi_media_status(ifp, imr)
2368 struct ifnet *ifp;
2369 struct ifmediareq *imr;
2370 {
2371 struct wi_req wreq;
2372 struct wi_softc *sc = ifp->if_softc;
2373
2374 if (sc->wi_tx_rate == 3) {
2375 imr->ifm_active = IFM_IEEE80211|IFM_AUTO;
2376 if (sc->wi_ptype == WI_PORTTYPE_ADHOC)
2377 imr->ifm_active |= IFM_IEEE80211_ADHOC;
2378 else if (sc->wi_ptype == WI_PORTTYPE_IBSS) {
2379 if (sc->wi_create_ibss)
2380 imr->ifm_active |= IFM_IEEE80211_IBSSMASTER;
2381 else
2382 imr->ifm_active |= IFM_IEEE80211_IBSS;
2383 }
2384 wreq.wi_type = WI_RID_CUR_TX_RATE;
2385 wreq.wi_len = WI_MAX_DATALEN;
2386 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) == 0) {
2387 switch(wreq.wi_val[0]) {
2388 case 1:
2389 imr->ifm_active |= IFM_IEEE80211_DS1;
2390 break;
2391 case 2:
2392 imr->ifm_active |= IFM_IEEE80211_DS2;
2393 break;
2394 case 6:
2395 imr->ifm_active |= IFM_IEEE80211_DS5;
2396 break;
2397 case 11:
2398 imr->ifm_active |= IFM_IEEE80211_DS11;
2399 break;
2400 }
2401 }
2402 } else {
2403 imr->ifm_active = sc->ifmedia.ifm_cur->ifm_media;
2404 }
2405
2406 imr->ifm_status = IFM_AVALID;
2407 if (sc->wi_ptype == WI_PORTTYPE_ADHOC ||
2408 sc->wi_ptype == WI_PORTTYPE_IBSS)
2409 /*
2410 * XXX: It would be nice if we could give some actually
2411 * useful status like whether we joined another IBSS or
2412 * created one ourselves.
2413 */
2414 imr->ifm_status |= IFM_ACTIVE;
2415 else {
2416 wreq.wi_type = WI_RID_COMMQUAL;
2417 wreq.wi_len = WI_MAX_DATALEN;
2418 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) == 0 &&
2419 wreq.wi_val[0] != 0)
2420 imr->ifm_status |= IFM_ACTIVE;
2421 }
2422 }
Cache object: 4d3a4f6cae784411a162ea1f5aade8c5
|