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