Bug Summary

File:dev/pci/if_wpi.c
Warning:line 232, column 7
Although the value stored to 'error' is used in the enclosing expression, the value is never actually read from 'error'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name if_wpi.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/dev/pci/if_wpi.c
1/* $OpenBSD: if_wpi.c,v 1.155 2020/12/12 11:48:53 jan Exp $ */
2
3/*-
4 * Copyright (c) 2006-2008
5 * Damien Bergamini <damien.bergamini@free.fr>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20/*
21 * Driver for Intel PRO/Wireless 3945ABG 802.11 network adapters.
22 */
23
24#include "bpfilter.h"
25
26#include <sys/param.h>
27#include <sys/sockio.h>
28#include <sys/mbuf.h>
29#include <sys/kernel.h>
30#include <sys/rwlock.h>
31#include <sys/socket.h>
32#include <sys/systm.h>
33#include <sys/malloc.h>
34#include <sys/conf.h>
35#include <sys/device.h>
36#include <sys/task.h>
37#include <sys/endian.h>
38
39#include <machine/bus.h>
40#include <machine/intr.h>
41
42#include <dev/pci/pcireg.h>
43#include <dev/pci/pcivar.h>
44#include <dev/pci/pcidevs.h>
45
46#if NBPFILTER1 > 0
47#include <net/bpf.h>
48#endif
49#include <net/if.h>
50#include <net/if_dl.h>
51#include <net/if_media.h>
52
53#include <netinet/in.h>
54#include <netinet/if_ether.h>
55
56#include <net80211/ieee80211_var.h>
57#include <net80211/ieee80211_amrr.h>
58#include <net80211/ieee80211_radiotap.h>
59
60#include <dev/pci/if_wpireg.h>
61#include <dev/pci/if_wpivar.h>
62
63static const struct pci_matchid wpi_devices[] = {
64 { PCI_VENDOR_INTEL0x8086, PCI_PRODUCT_INTEL_PRO_WL_3945ABG_10x4222 },
65 { PCI_VENDOR_INTEL0x8086, PCI_PRODUCT_INTEL_PRO_WL_3945ABG_20x4227 }
66};
67
68int wpi_match(struct device *, void *, void *);
69void wpi_attach(struct device *, struct device *, void *);
70#if NBPFILTER1 > 0
71void wpi_radiotap_attach(struct wpi_softc *);
72#endif
73int wpi_detach(struct device *, int);
74int wpi_activate(struct device *, int);
75void wpi_wakeup(struct wpi_softc *);
76void wpi_init_task(void *);
77int wpi_nic_lock(struct wpi_softc *);
78int wpi_read_prom_data(struct wpi_softc *, uint32_t, void *, int);
79int wpi_dma_contig_alloc(bus_dma_tag_t, struct wpi_dma_info *,
80 void **, bus_size_t, bus_size_t);
81void wpi_dma_contig_free(struct wpi_dma_info *);
82int wpi_alloc_shared(struct wpi_softc *);
83void wpi_free_shared(struct wpi_softc *);
84int wpi_alloc_fwmem(struct wpi_softc *);
85void wpi_free_fwmem(struct wpi_softc *);
86int wpi_alloc_rx_ring(struct wpi_softc *, struct wpi_rx_ring *);
87void wpi_reset_rx_ring(struct wpi_softc *, struct wpi_rx_ring *);
88void wpi_free_rx_ring(struct wpi_softc *, struct wpi_rx_ring *);
89int wpi_alloc_tx_ring(struct wpi_softc *, struct wpi_tx_ring *,
90 int);
91void wpi_reset_tx_ring(struct wpi_softc *, struct wpi_tx_ring *);
92void wpi_free_tx_ring(struct wpi_softc *, struct wpi_tx_ring *);
93int wpi_read_eeprom(struct wpi_softc *);
94void wpi_read_eeprom_channels(struct wpi_softc *, int);
95void wpi_read_eeprom_group(struct wpi_softc *, int);
96struct ieee80211_node *wpi_node_alloc(struct ieee80211com *);
97void wpi_newassoc(struct ieee80211com *, struct ieee80211_node *,
98 int);
99int wpi_media_change(struct ifnet *);
100int wpi_newstate(struct ieee80211com *, enum ieee80211_state, int);
101void wpi_iter_func(void *, struct ieee80211_node *);
102void wpi_calib_timeout(void *);
103int wpi_ccmp_decap(struct wpi_softc *, struct mbuf *,
104 struct ieee80211_key *);
105void wpi_rx_done(struct wpi_softc *, struct wpi_rx_desc *,
106 struct wpi_rx_data *, struct mbuf_list *);
107void wpi_tx_done(struct wpi_softc *, struct wpi_rx_desc *);
108void wpi_cmd_done(struct wpi_softc *, struct wpi_rx_desc *);
109void wpi_notif_intr(struct wpi_softc *);
110void wpi_fatal_intr(struct wpi_softc *);
111int wpi_intr(void *);
112int wpi_tx(struct wpi_softc *, struct mbuf *,
113 struct ieee80211_node *);
114void wpi_start(struct ifnet *);
115void wpi_watchdog(struct ifnet *);
116int wpi_ioctl(struct ifnet *, u_long, caddr_t);
117int wpi_cmd(struct wpi_softc *, int, const void *, int, int);
118int wpi_mrr_setup(struct wpi_softc *);
119void wpi_updateedca(struct ieee80211com *);
120void wpi_set_led(struct wpi_softc *, uint8_t, uint8_t, uint8_t);
121int wpi_set_timing(struct wpi_softc *, struct ieee80211_node *);
122void wpi_power_calibration(struct wpi_softc *);
123int wpi_set_txpower(struct wpi_softc *, int);
124int wpi_get_power_index(struct wpi_softc *,
125 struct wpi_power_group *, struct ieee80211_channel *, int);
126int wpi_set_pslevel(struct wpi_softc *, int, int, int);
127int wpi_config(struct wpi_softc *);
128int wpi_scan(struct wpi_softc *, uint16_t);
129int wpi_auth(struct wpi_softc *);
130int wpi_run(struct wpi_softc *);
131int wpi_set_key(struct ieee80211com *, struct ieee80211_node *,
132 struct ieee80211_key *);
133void wpi_delete_key(struct ieee80211com *, struct ieee80211_node *,
134 struct ieee80211_key *);
135int wpi_post_alive(struct wpi_softc *);
136int wpi_load_bootcode(struct wpi_softc *, const uint8_t *, int);
137int wpi_load_firmware(struct wpi_softc *);
138int wpi_read_firmware(struct wpi_softc *);
139int wpi_clock_wait(struct wpi_softc *);
140int wpi_apm_init(struct wpi_softc *);
141void wpi_apm_stop_master(struct wpi_softc *);
142void wpi_apm_stop(struct wpi_softc *);
143void wpi_nic_config(struct wpi_softc *);
144int wpi_hw_init(struct wpi_softc *);
145void wpi_hw_stop(struct wpi_softc *);
146int wpi_init(struct ifnet *);
147void wpi_stop(struct ifnet *, int);
148
149#ifdef WPI_DEBUG
150#define DPRINTF(x) do { if (wpi_debug > 0) printf x; } while (0)
151#define DPRINTFN(n, x) do { if (wpi_debug >= (n)) printf x; } while (0)
152int wpi_debug = 0;
153#else
154#define DPRINTF(x)
155#define DPRINTFN(n, x)
156#endif
157
158struct cfdriver wpi_cd = {
159 NULL((void *)0), "wpi", DV_IFNET
160};
161
162struct cfattach wpi_ca = {
163 sizeof (struct wpi_softc), wpi_match, wpi_attach, wpi_detach,
164 wpi_activate
165};
166
167int
168wpi_match(struct device *parent, void *match, void *aux)
169{
170 return pci_matchbyid((struct pci_attach_args *)aux, wpi_devices,
171 nitems(wpi_devices)(sizeof((wpi_devices)) / sizeof((wpi_devices)[0])));
172}
173
174void
175wpi_attach(struct device *parent, struct device *self, void *aux)
176{
177 struct wpi_softc *sc = (struct wpi_softc *)self;
178 struct ieee80211com *ic = &sc->sc_ic;
179 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
180 struct pci_attach_args *pa = aux;
181 const char *intrstr;
182 pci_intr_handle_t ih;
183 pcireg_t memtype, reg;
184 int i, error;
185
186 sc->sc_pct = pa->pa_pc;
187 sc->sc_pcitag = pa->pa_tag;
188 sc->sc_dmat = pa->pa_dmat;
189
190 /*
191 * Get the offset of the PCI Express Capability Structure in PCI
192 * Configuration Space (the vendor driver hard-codes it as E0h.)
193 */
194 error = pci_get_capability(sc->sc_pct, sc->sc_pcitag,
195 PCI_CAP_PCIEXPRESS0x10, &sc->sc_cap_off, NULL((void *)0));
196 if (error == 0) {
197 printf(": PCIe capability structure not found!\n");
198 return;
199 }
200
201 /* Clear device-specific "PCI retry timeout" register (41h). */
202 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
203 reg &= ~0xff00;
204 pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg);
205
206 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, WPI_PCI_BAR00x10);
207 error = pci_mapreg_map(pa, WPI_PCI_BAR00x10, memtype, 0, &sc->sc_st,
208 &sc->sc_sh, NULL((void *)0), &sc->sc_sz, 0);
209 if (error != 0) {
210 printf(": can't map mem space\n");
211 return;
212 }
213
214 /* Install interrupt handler. */
215 if (pci_intr_map_msi(pa, &ih) != 0 && pci_intr_map(pa, &ih) != 0) {
216 printf(": can't map interrupt\n");
217 return;
218 }
219 intrstr = pci_intr_string(sc->sc_pct, ih);
220 sc->sc_ih = pci_intr_establish(sc->sc_pct, ih, IPL_NET0x7, wpi_intr, sc,
221 sc->sc_dev.dv_xname);
222 if (sc->sc_ih == NULL((void *)0)) {
223 printf(": can't establish interrupt");
224 if (intrstr != NULL((void *)0))
225 printf(" at %s", intrstr);
226 printf("\n");
227 return;
228 }
229 printf(": %s", intrstr);
230
231 /* Power ON adapter. */
232 if ((error = wpi_apm_init(sc)) != 0) {
Although the value stored to 'error' is used in the enclosing expression, the value is never actually read from 'error'
233 printf(": could not power ON adapter\n");
234 return;
235 }
236
237 /* Read MAC address, channels, etc from EEPROM. */
238 if ((error = wpi_read_eeprom(sc)) != 0) {
239 printf(": could not read EEPROM\n");
240 return;
241 }
242
243 /* Allocate DMA memory for firmware transfers. */
244 if ((error = wpi_alloc_fwmem(sc)) != 0) {
245 printf(": could not allocate memory for firmware\n");
246 return;
247 }
248
249 /* Allocate shared area. */
250 if ((error = wpi_alloc_shared(sc)) != 0) {
251 printf(": could not allocate shared area\n");
252 goto fail1;
253 }
254
255 /* Allocate TX rings. */
256 for (i = 0; i < WPI_NTXQUEUES8; i++) {
257 if ((error = wpi_alloc_tx_ring(sc, &sc->txq[i], i)) != 0) {
258 printf(": could not allocate TX ring %d\n", i);
259 goto fail2;
260 }
261 }
262
263 /* Allocate RX ring. */
264 if ((error = wpi_alloc_rx_ring(sc, &sc->rxq)) != 0) {
265 printf(": could not allocate Rx ring\n");
266 goto fail2;
267 }
268
269 /* Power OFF adapter. */
270 wpi_apm_stop(sc);
271 /* Clear pending interrupts. */
272 WPI_WRITE(sc, WPI_INT, 0xffffffff)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x008)), ((
0xffffffff))))
;
273
274 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
275 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
276 ic->ic_state = IEEE80211_S_INIT;
277
278 /* Set device capabilities. */
279 ic->ic_caps =
280 IEEE80211_C_WEP0x00000001 | /* WEP */
281 IEEE80211_C_RSN0x00001000 | /* WPA/RSN */
282 IEEE80211_C_SCANALL0x00000400 | /* device scans all channels at once */
283 IEEE80211_C_SCANALLBAND0x00008000 | /* driver scans all bands at once */
284 IEEE80211_C_MONITOR0x00000200 | /* monitor mode supported */
285 IEEE80211_C_SHSLOT0x00000080 | /* short slot time supported */
286 IEEE80211_C_SHPREAMBLE0x00000100 | /* short preamble supported */
287 IEEE80211_C_PMGT0x00000004; /* power saving supported */
288
289 /* Set supported rates. */
290 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
291 ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
292 if (sc->sc_flags & WPI_FLAG_HAS_5GHZ(1 << 0)) {
293 ic->ic_sup_rates[IEEE80211_MODE_11A] =
294 ieee80211_std_rateset_11a;
295 }
296
297 /* IBSS channel undefined for now. */
298 ic->ic_ibss_chan = &ic->ic_channels[0];
299
300 ifp->if_softc = sc;
301 ifp->if_flags = IFF_BROADCAST0x2 | IFF_SIMPLEX0x800 | IFF_MULTICAST0x8000;
302 ifp->if_ioctl = wpi_ioctl;
303 ifp->if_start = wpi_start;
304 ifp->if_watchdog = wpi_watchdog;
305 memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ)__builtin_memcpy((ifp->if_xname), (sc->sc_dev.dv_xname)
, (16))
;
306
307 if_attach(ifp);
308 ieee80211_ifattach(ifp);
309 ic->ic_node_alloc = wpi_node_alloc;
310 ic->ic_newassoc = wpi_newassoc;
311 ic->ic_updateedca = wpi_updateedca;
312 ic->ic_set_key = wpi_set_key;
313 ic->ic_delete_key = wpi_delete_key;
314
315 /* Override 802.11 state transition machine. */
316 sc->sc_newstate = ic->ic_newstate;
317 ic->ic_newstate = wpi_newstate;
318 ieee80211_media_init(ifp, wpi_media_change, ieee80211_media_status);
319
320 sc->amrr.amrr_min_success_threshold = 1;
321 sc->amrr.amrr_max_success_threshold = 15;
322
323#if NBPFILTER1 > 0
324 wpi_radiotap_attach(sc);
325#endif
326 timeout_set(&sc->calib_to, wpi_calib_timeout, sc);
327 rw_init(&sc->sc_rwlock, "wpilock")_rw_init_flags(&sc->sc_rwlock, "wpilock", 0, ((void *)
0))
;
328 task_set(&sc->init_task, wpi_init_task, sc);
329 return;
330
331 /* Free allocated memory if something failed during attachment. */
332fail2: while (--i >= 0)
333 wpi_free_tx_ring(sc, &sc->txq[i]);
334 wpi_free_shared(sc);
335fail1: wpi_free_fwmem(sc);
336}
337
338#if NBPFILTER1 > 0
339/*
340 * Attach the interface to 802.11 radiotap.
341 */
342void
343wpi_radiotap_attach(struct wpi_softc *sc)
344{
345 bpfattach(&sc->sc_drvbpf, &sc->sc_ic.ic_ific_ac.ac_if, DLT_IEEE802_11_RADIO127,
346 sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN64);
347
348 sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
349 sc->sc_rxtapsc_rxtapu.th.wr_ihdr.it_len = htole16(sc->sc_rxtap_len)((__uint16_t)(sc->sc_rxtap_len));
350 sc->sc_rxtapsc_rxtapu.th.wr_ihdr.it_present = htole32(WPI_RX_RADIOTAP_PRESENT)((__uint32_t)(((1 << IEEE80211_RADIOTAP_TSFT) | (1 <<
IEEE80211_RADIOTAP_FLAGS) | (1 << IEEE80211_RADIOTAP_RATE
) | (1 << IEEE80211_RADIOTAP_CHANNEL) | (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL
) | (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | (1 <<
IEEE80211_RADIOTAP_ANTENNA))))
;
351
352 sc->sc_txtap_len = sizeof sc->sc_txtapu;
353 sc->sc_txtapsc_txtapu.th.wt_ihdr.it_len = htole16(sc->sc_txtap_len)((__uint16_t)(sc->sc_txtap_len));
354 sc->sc_txtapsc_txtapu.th.wt_ihdr.it_present = htole32(WPI_TX_RADIOTAP_PRESENT)((__uint32_t)(((1 << IEEE80211_RADIOTAP_FLAGS) | (1 <<
IEEE80211_RADIOTAP_RATE) | (1 << IEEE80211_RADIOTAP_CHANNEL
))))
;
355}
356#endif
357
358int
359wpi_detach(struct device *self, int flags)
360{
361 struct wpi_softc *sc = (struct wpi_softc *)self;
362 struct ifnet *ifp = &sc->sc_ic.ic_ific_ac.ac_if;
363 int qid;
364
365 timeout_del(&sc->calib_to);
366 task_del(systq, &sc->init_task);
367
368 /* Uninstall interrupt handler. */
369 if (sc->sc_ih != NULL((void *)0))
370 pci_intr_disestablish(sc->sc_pct, sc->sc_ih);
371
372 /* Free DMA resources. */
373 wpi_free_rx_ring(sc, &sc->rxq);
374 for (qid = 0; qid < WPI_NTXQUEUES8; qid++)
375 wpi_free_tx_ring(sc, &sc->txq[qid]);
376 wpi_free_shared(sc);
377 wpi_free_fwmem(sc);
378
379 bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_sz);
380
381 ieee80211_ifdetach(ifp);
382 if_detach(ifp);
383
384 return 0;
385}
386
387int
388wpi_activate(struct device *self, int act)
389{
390 struct wpi_softc *sc = (struct wpi_softc *)self;
391 struct ifnet *ifp = &sc->sc_ic.ic_ific_ac.ac_if;
392
393 switch (act) {
394 case DVACT_SUSPEND3:
395 if (ifp->if_flags & IFF_RUNNING0x40)
396 wpi_stop(ifp, 0);
397 break;
398 case DVACT_WAKEUP5:
399 wpi_wakeup(sc);
400 break;
401 }
402
403 return 0;
404}
405
406void
407wpi_wakeup(struct wpi_softc *sc)
408{
409 pcireg_t reg;
410
411 /* Clear device-specific "PCI retry timeout" register (41h). */
412 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
413 reg &= ~0xff00;
414 pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg);
415
416 wpi_init_task(sc);
417}
418
419void
420wpi_init_task(void *arg1)
421{
422 struct wpi_softc *sc = arg1;
423 struct ifnet *ifp = &sc->sc_ic.ic_ific_ac.ac_if;
424 int s;
425
426 rw_enter_write(&sc->sc_rwlock);
427 s = splnet()splraise(0x7);
428
429 if ((ifp->if_flags & (IFF_UP0x1 | IFF_RUNNING0x40)) == IFF_UP0x1)
430 wpi_init(ifp);
431
432 splx(s)spllower(s);
433 rw_exit_write(&sc->sc_rwlock);
434}
435
436int
437wpi_nic_lock(struct wpi_softc *sc)
438{
439 int ntries;
440
441 /* Request exclusive access to NIC. */
442 WPI_SETBITS(sc, WPI_GP_CNTRL, WPI_GP_CNTRL_MAC_ACCESS_REQ)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x024)), ((
(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x024)))) | (
(1 << 3))))))
;
443
444 /* Spin until we actually get the lock. */
445 for (ntries = 0; ntries < 1000; ntries++) {
446 if ((WPI_READ(sc, WPI_GP_CNTRL)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x024)))) &
447 (WPI_GP_CNTRL_MAC_ACCESS_ENA(1 << 0) | WPI_GP_CNTRL_SLEEP(1 << 4))) ==
448 WPI_GP_CNTRL_MAC_ACCESS_ENA(1 << 0))
449 return 0;
450 DELAY(10)(*delay_func)(10);
451 }
452 return ETIMEDOUT60;
453}
454
455static __inline void
456wpi_nic_unlock(struct wpi_softc *sc)
457{
458 WPI_CLRBITS(sc, WPI_GP_CNTRL, WPI_GP_CNTRL_MAC_ACCESS_REQ)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x024)), ((
(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x024)))) &
~((1 << 3))))))
;
459}
460
461static __inline uint32_t
462wpi_prph_read(struct wpi_softc *sc, uint32_t addr)
463{
464 WPI_WRITE(sc, WPI_PRPH_RADDR, WPI_PRPH_DWORD | addr)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x448)), ((
((sizeof (uint32_t) - 1) << 24) | addr))))
;
465 WPI_BARRIER_READ_WRITE(sc)bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, (sc)->
sc_sz, 0x01 | 0x02)
;
466 return WPI_READ(sc, WPI_PRPH_RDATA)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x450))));
467}
468
469static __inline void
470wpi_prph_write(struct wpi_softc *sc, uint32_t addr, uint32_t data)
471{
472 WPI_WRITE(sc, WPI_PRPH_WADDR, WPI_PRPH_DWORD | addr)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x444)), ((
((sizeof (uint32_t) - 1) << 24) | addr))))
;
473 WPI_BARRIER_WRITE(sc)bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, (sc)->
sc_sz, 0x02)
;
474 WPI_WRITE(sc, WPI_PRPH_WDATA, data)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x44c)), ((
data))))
;
475}
476
477static __inline void
478wpi_prph_setbits(struct wpi_softc *sc, uint32_t addr, uint32_t mask)
479{
480 wpi_prph_write(sc, addr, wpi_prph_read(sc, addr) | mask);
481}
482
483static __inline void
484wpi_prph_clrbits(struct wpi_softc *sc, uint32_t addr, uint32_t mask)
485{
486 wpi_prph_write(sc, addr, wpi_prph_read(sc, addr) & ~mask);
487}
488
489static __inline void
490wpi_prph_write_region_4(struct wpi_softc *sc, uint32_t addr,
491 const uint32_t *data, int count)
492{
493 for (; count > 0; count--, data++, addr += 4)
494 wpi_prph_write(sc, addr, *data);
495}
496
497#ifdef WPI_DEBUG
498
499static __inline uint32_t
500wpi_mem_read(struct wpi_softc *sc, uint32_t addr)
501{
502 WPI_WRITE(sc, WPI_MEM_RADDR, addr)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x40c)), ((
addr))))
;
503 WPI_BARRIER_READ_WRITE(sc)bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, (sc)->
sc_sz, 0x01 | 0x02)
;
504 return WPI_READ(sc, WPI_MEM_RDATA)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x41c))));
505}
506
507static __inline void
508wpi_mem_write(struct wpi_softc *sc, uint32_t addr, uint32_t data)
509{
510 WPI_WRITE(sc, WPI_MEM_WADDR, addr)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x410)), ((
addr))))
;
511 WPI_BARRIER_WRITE(sc)bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, (sc)->
sc_sz, 0x02)
;
512 WPI_WRITE(sc, WPI_MEM_WDATA, data)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x418)), ((
data))))
;
513}
514
515static __inline void
516wpi_mem_read_region_4(struct wpi_softc *sc, uint32_t addr, uint32_t *data,
517 int count)
518{
519 for (; count > 0; count--, addr += 4)
520 *data++ = wpi_mem_read(sc, addr);
521}
522
523#endif
524
525int
526wpi_read_prom_data(struct wpi_softc *sc, uint32_t addr, void *data, int count)
527{
528 uint8_t *out = data;
529 uint32_t val;
530 int error, ntries;
531
532 if ((error = wpi_nic_lock(sc)) != 0)
533 return error;
534
535 for (; count > 0; count -= 2, addr++) {
536 WPI_WRITE(sc, WPI_EEPROM, addr << 2)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x02c)), ((
addr << 2))))
;
537 WPI_CLRBITS(sc, WPI_EEPROM, WPI_EEPROM_CMD)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x02c)), ((
(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x02c)))) &
~((1 << 1))))))
;
538
539 for (ntries = 0; ntries < 10; ntries++) {
540 val = WPI_READ(sc, WPI_EEPROM)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x02c))));
541 if (val & WPI_EEPROM_READ_VALID(1 << 0))
542 break;
543 DELAY(5)(*delay_func)(5);
544 }
545 if (ntries == 10) {
546 printf("%s: could not read EEPROM\n",
547 sc->sc_dev.dv_xname);
548 return ETIMEDOUT60;
549 }
550 *out++ = val >> 16;
551 if (count > 1)
552 *out++ = val >> 24;
553 }
554
555 wpi_nic_unlock(sc);
556 return 0;
557}
558
559int
560wpi_dma_contig_alloc(bus_dma_tag_t tag, struct wpi_dma_info *dma, void **kvap,
561 bus_size_t size, bus_size_t alignment)
562{
563 int nsegs, error;
564
565 dma->tag = tag;
566 dma->size = size;
567
568 error = bus_dmamap_create(tag, size, 1, size, 0, BUS_DMA_NOWAIT,(*(tag)->_dmamap_create)((tag), (size), (1), (size), (0), (
0x0001), (&dma->map))
569 &dma->map)(*(tag)->_dmamap_create)((tag), (size), (1), (size), (0), (
0x0001), (&dma->map))
;
570 if (error != 0)
571 goto fail;
572
573 error = bus_dmamem_alloc(tag, size, alignment, 0, &dma->seg, 1, &nsegs,(*(tag)->_dmamem_alloc)((tag), (size), (alignment), (0), (
&dma->seg), (1), (&nsegs), (0x0001 | 0x1000))
574 BUS_DMA_NOWAIT | BUS_DMA_ZERO)(*(tag)->_dmamem_alloc)((tag), (size), (alignment), (0), (
&dma->seg), (1), (&nsegs), (0x0001 | 0x1000))
;
575 if (error != 0)
576 goto fail;
577
578 error = bus_dmamem_map(tag, &dma->seg, 1, size, &dma->vaddr,(*(tag)->_dmamem_map)((tag), (&dma->seg), (1), (size
), (&dma->vaddr), (0x0001 | 0x0004))
579 BUS_DMA_NOWAIT | BUS_DMA_COHERENT)(*(tag)->_dmamem_map)((tag), (&dma->seg), (1), (size
), (&dma->vaddr), (0x0001 | 0x0004))
;
580 if (error != 0)
581 goto fail;
582
583 error = bus_dmamap_load_raw(tag, dma->map, &dma->seg, 1, size,(*(tag)->_dmamap_load_raw)((tag), (dma->map), (&dma
->seg), (1), (size), (0x0001))
584 BUS_DMA_NOWAIT)(*(tag)->_dmamap_load_raw)((tag), (dma->map), (&dma
->seg), (1), (size), (0x0001))
;
585 if (error != 0)
586 goto fail;
587
588 bus_dmamap_sync(tag, dma->map, 0, size, BUS_DMASYNC_PREWRITE)(*(tag)->_dmamap_sync)((tag), (dma->map), (0), (size), (
0x04))
;
589
590 dma->paddr = dma->map->dm_segs[0].ds_addr;
591 if (kvap != NULL((void *)0))
592 *kvap = dma->vaddr;
593
594 return 0;
595
596fail: wpi_dma_contig_free(dma);
597 return error;
598}
599
600void
601wpi_dma_contig_free(struct wpi_dma_info *dma)
602{
603 if (dma->map != NULL((void *)0)) {
604 if (dma->vaddr != NULL((void *)0)) {
605 bus_dmamap_sync(dma->tag, dma->map, 0, dma->size,(*(dma->tag)->_dmamap_sync)((dma->tag), (dma->map
), (0), (dma->size), (0x02 | 0x08))
606 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE)(*(dma->tag)->_dmamap_sync)((dma->tag), (dma->map
), (0), (dma->size), (0x02 | 0x08))
;
607 bus_dmamap_unload(dma->tag, dma->map)(*(dma->tag)->_dmamap_unload)((dma->tag), (dma->map
))
;
608 bus_dmamem_unmap(dma->tag, dma->vaddr, dma->size)(*(dma->tag)->_dmamem_unmap)((dma->tag), (dma->vaddr
), (dma->size))
;
609 bus_dmamem_free(dma->tag, &dma->seg, 1)(*(dma->tag)->_dmamem_free)((dma->tag), (&dma->
seg), (1))
;
610 dma->vaddr = NULL((void *)0);
611 }
612 bus_dmamap_destroy(dma->tag, dma->map)(*(dma->tag)->_dmamap_destroy)((dma->tag), (dma->
map))
;
613 dma->map = NULL((void *)0);
614 }
615}
616
617int
618wpi_alloc_shared(struct wpi_softc *sc)
619{
620 /* Shared buffer must be aligned on a 4KB boundary. */
621 return wpi_dma_contig_alloc(sc->sc_dmat, &sc->shared_dma,
622 (void **)&sc->shared, sizeof (struct wpi_shared), 4096);
623}
624
625void
626wpi_free_shared(struct wpi_softc *sc)
627{
628 wpi_dma_contig_free(&sc->shared_dma);
629}
630
631int
632wpi_alloc_fwmem(struct wpi_softc *sc)
633{
634 /* Allocate enough contiguous space to store text and data. */
635 return wpi_dma_contig_alloc(sc->sc_dmat, &sc->fw_dma, NULL((void *)0),
636 WPI_FW_TEXT_MAXSZ(80 * 1024) + WPI_FW_DATA_MAXSZ(32 * 1024), 16);
637}
638
639void
640wpi_free_fwmem(struct wpi_softc *sc)
641{
642 wpi_dma_contig_free(&sc->fw_dma);
643}
644
645int
646wpi_alloc_rx_ring(struct wpi_softc *sc, struct wpi_rx_ring *ring)
647{
648 bus_size_t size;
649 int i, error;
650
651 ring->cur = 0;
652
653 /* Allocate RX descriptors (16KB aligned.) */
654 size = WPI_RX_RING_COUNT(1 << 6) * sizeof (uint32_t);
655 error = wpi_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma,
656 (void **)&ring->desc, size, 16 * 1024);
657 if (error != 0) {
658 printf("%s: could not allocate RX ring DMA memory\n",
659 sc->sc_dev.dv_xname);
660 goto fail;
661 }
662
663 /*
664 * Allocate and map RX buffers.
665 */
666 for (i = 0; i < WPI_RX_RING_COUNT(1 << 6); i++) {
667 struct wpi_rx_data *data = &ring->data[i];
668
669 error = bus_dmamap_create(sc->sc_dmat, WPI_RBUF_SIZE, 1,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((3 *
1024)), (1), ((3 * 1024)), (0), (0x0001), (&data->map
))
670 WPI_RBUF_SIZE, 0, BUS_DMA_NOWAIT, &data->map)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((3 *
1024)), (1), ((3 * 1024)), (0), (0x0001), (&data->map
))
;
671 if (error != 0) {
672 printf("%s: could not create RX buf DMA map\n",
673 sc->sc_dev.dv_xname);
674 goto fail;
675 }
676
677 data->m = MCLGETL(NULL, M_DONTWAIT, WPI_RBUF_SIZE)m_clget((((void *)0)), (0x0002), ((3 * 1024)));
678 if (data->m == NULL((void *)0)) {
679 printf("%s: could not allocate RX mbuf\n",
680 sc->sc_dev.dv_xname);
681 error = ENOBUFS55;
682 goto fail;
683 }
684
685 error = bus_dmamap_load(sc->sc_dmat, data->map,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (data->
map), (((void *)((data->m)->m_hdr.mh_data))), ((3 * 1024
)), (((void *)0)), (0x0001 | 0x0200))
686 mtod(data->m, void *), WPI_RBUF_SIZE, NULL,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (data->
map), (((void *)((data->m)->m_hdr.mh_data))), ((3 * 1024
)), (((void *)0)), (0x0001 | 0x0200))
687 BUS_DMA_NOWAIT | BUS_DMA_READ)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (data->
map), (((void *)((data->m)->m_hdr.mh_data))), ((3 * 1024
)), (((void *)0)), (0x0001 | 0x0200))
;
688 if (error != 0) {
689 printf("%s: can't map mbuf (error %d)\n",
690 sc->sc_dev.dv_xname, error);
691 goto fail;
692 }
693
694 /* Set physical address of RX buffer. */
695 ring->desc[i] = htole32(data->map->dm_segs[0].ds_addr)((__uint32_t)(data->map->dm_segs[0].ds_addr));
696 }
697
698 bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map, 0, size,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
desc_dma.map), (0), (size), (0x04))
699 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
desc_dma.map), (0), (size), (0x04))
;
700
701 return 0;
702
703fail: wpi_free_rx_ring(sc, ring);
704 return error;
705}
706
707void
708wpi_reset_rx_ring(struct wpi_softc *sc, struct wpi_rx_ring *ring)
709{
710 int ntries;
711
712 if (wpi_nic_lock(sc) == 0) {
713 WPI_WRITE(sc, WPI_FH_RX_CONFIG, 0)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xc00)), ((
0))))
;
714 for (ntries = 0; ntries < 100; ntries++) {
715 if (WPI_READ(sc, WPI_FH_RX_STATUS)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0xcc4)))) &
716 WPI_FH_RX_STATUS_IDLE(1 << 24))
717 break;
718 DELAY(10)(*delay_func)(10);
719 }
720 wpi_nic_unlock(sc);
721 }
722 ring->cur = 0;
723}
724
725void
726wpi_free_rx_ring(struct wpi_softc *sc, struct wpi_rx_ring *ring)
727{
728 int i;
729
730 wpi_dma_contig_free(&ring->desc_dma);
731
732 for (i = 0; i < WPI_RX_RING_COUNT(1 << 6); i++) {
733 struct wpi_rx_data *data = &ring->data[i];
734
735 if (data->m != NULL((void *)0)) {
736 bus_dmamap_sync(sc->sc_dmat, data->map, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x02))
737 data->map->dm_mapsize, BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x02))
;
738 bus_dmamap_unload(sc->sc_dmat, data->map)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (data
->map))
;
739 m_freem(data->m);
740 }
741 if (data->map != NULL((void *)0))
742 bus_dmamap_destroy(sc->sc_dmat, data->map)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (data
->map))
;
743 }
744}
745
746int
747wpi_alloc_tx_ring(struct wpi_softc *sc, struct wpi_tx_ring *ring, int qid)
748{
749 bus_addr_t paddr;
750 bus_size_t size;
751 int i, error;
752
753 ring->qid = qid;
754 ring->queued = 0;
755 ring->cur = 0;
756
757 /* Allocate TX descriptors (16KB aligned.) */
758 size = WPI_TX_RING_COUNT256 * sizeof (struct wpi_tx_desc);
759 error = wpi_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma,
760 (void **)&ring->desc, size, 16 * 1024);
761 if (error != 0) {
762 printf("%s: could not allocate TX ring DMA memory\n",
763 sc->sc_dev.dv_xname);
764 goto fail;
765 }
766
767 /* Update shared area with ring physical address. */
768 sc->shared->txbase[qid] = htole32(ring->desc_dma.paddr)((__uint32_t)(ring->desc_dma.paddr));
769 bus_dmamap_sync(sc->sc_dmat, sc->shared_dma.map, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
shared_dma.map), (0), (sizeof (struct wpi_shared)), (0x04))
770 sizeof (struct wpi_shared), BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
shared_dma.map), (0), (sizeof (struct wpi_shared)), (0x04))
;
771
772 /*
773 * We only use rings 0 through 4 (4 EDCA + cmd) so there is no need
774 * to allocate commands space for other rings.
775 * XXX Do we really need to allocate descriptors for other rings?
776 */
777 if (qid > 4)
778 return 0;
779
780 size = WPI_TX_RING_COUNT256 * sizeof (struct wpi_tx_cmd);
781 error = wpi_dma_contig_alloc(sc->sc_dmat, &ring->cmd_dma,
782 (void **)&ring->cmd, size, 4);
783 if (error != 0) {
784 printf("%s: could not allocate TX cmd DMA memory\n",
785 sc->sc_dev.dv_xname);
786 goto fail;
787 }
788
789 paddr = ring->cmd_dma.paddr;
790 for (i = 0; i < WPI_TX_RING_COUNT256; i++) {
791 struct wpi_tx_data *data = &ring->data[i];
792
793 data->cmd_paddr = paddr;
794 paddr += sizeof (struct wpi_tx_cmd);
795
796 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (4 - 1), ((1 << 11)), (0), (0x0001), (&data->
map))
797 WPI_MAX_SCATTER - 1, MCLBYTES, 0, BUS_DMA_NOWAIT,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (4 - 1), ((1 << 11)), (0), (0x0001), (&data->
map))
798 &data->map)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (4 - 1), ((1 << 11)), (0), (0x0001), (&data->
map))
;
799 if (error != 0) {
800 printf("%s: could not create TX buf DMA map\n",
801 sc->sc_dev.dv_xname);
802 goto fail;
803 }
804 }
805 return 0;
806
807fail: wpi_free_tx_ring(sc, ring);
808 return error;
809}
810
811void
812wpi_reset_tx_ring(struct wpi_softc *sc, struct wpi_tx_ring *ring)
813{
814 int i;
815
816 for (i = 0; i < WPI_TX_RING_COUNT256; i++) {
817 struct wpi_tx_data *data = &ring->data[i];
818
819 if (data->m != NULL((void *)0)) {
820 bus_dmamap_sync(sc->sc_dmat, data->map, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x08))
821 data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x08))
;
822 bus_dmamap_unload(sc->sc_dmat, data->map)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (data
->map))
;
823 m_freem(data->m);
824 data->m = NULL((void *)0);
825 }
826 }
827 /* Clear TX descriptors. */
828 memset(ring->desc, 0, ring->desc_dma.size)__builtin_memset((ring->desc), (0), (ring->desc_dma.size
))
;
829 sc->qfullmsk &= ~(1 << ring->qid);
830 ring->queued = 0;
831 ring->cur = 0;
832}
833
834void
835wpi_free_tx_ring(struct wpi_softc *sc, struct wpi_tx_ring *ring)
836{
837 int i;
838
839 wpi_dma_contig_free(&ring->desc_dma);
840 wpi_dma_contig_free(&ring->cmd_dma);
841
842 for (i = 0; i < WPI_TX_RING_COUNT256; i++) {
843 struct wpi_tx_data *data = &ring->data[i];
844
845 if (data->m != NULL((void *)0)) {
846 bus_dmamap_sync(sc->sc_dmat, data->map, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x08))
847 data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x08))
;
848 bus_dmamap_unload(sc->sc_dmat, data->map)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (data
->map))
;
849 m_freem(data->m);
850 }
851 if (data->map != NULL((void *)0))
852 bus_dmamap_destroy(sc->sc_dmat, data->map)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (data
->map))
;
853 }
854}
855
856int
857wpi_read_eeprom(struct wpi_softc *sc)
858{
859 struct ieee80211com *ic = &sc->sc_ic;
860 char domain[4];
861 int i;
862
863 if ((WPI_READ(sc, WPI_EEPROM_GP)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x030)))) & 0x6) == 0) {
864 printf("%s: bad EEPROM signature\n", sc->sc_dev.dv_xname);
865 return EIO5;
866 }
867 /* Clear HW ownership of EEPROM. */
868 WPI_CLRBITS(sc, WPI_EEPROM_GP, WPI_EEPROM_GP_IF_OWNER)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x030)), ((
(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x030)))) &
~(0x00000180)))))
;
869
870 wpi_read_prom_data(sc, WPI_EEPROM_CAPABILITIES0x045, &sc->cap, 1);
871 wpi_read_prom_data(sc, WPI_EEPROM_REVISION0x035, &sc->rev, 2);
872 wpi_read_prom_data(sc, WPI_EEPROM_TYPE0x04a, &sc->type, 1);
873
874 DPRINTF(("cap=%x rev=%x type=%x\n", sc->cap, letoh16(sc->rev),
875 sc->type));
876
877 /* Read and print regulatory domain (4 ASCII characters.) */
878 wpi_read_prom_data(sc, WPI_EEPROM_DOMAIN0x060, domain, 4);
879 printf(", %.4s", domain);
880
881 /* Read and print MAC address. */
882 wpi_read_prom_data(sc, WPI_EEPROM_MAC0x015, ic->ic_myaddr, 6);
883 printf(", address %s\n", ether_sprintf(ic->ic_myaddr));
884
885 /* Read the list of authorized channels. */
886 for (i = 0; i < WPI_CHAN_BANDS_COUNT5; i++)
887 wpi_read_eeprom_channels(sc, i);
888
889 /* Read the list of TX power groups. */
890 for (i = 0; i < WPI_POWER_GROUPS_COUNT5; i++)
891 wpi_read_eeprom_group(sc, i);
892
893 return 0;
894}
895
896void
897wpi_read_eeprom_channels(struct wpi_softc *sc, int n)
898{
899 struct ieee80211com *ic = &sc->sc_ic;
900 const struct wpi_chan_band *band = &wpi_bands[n];
901 struct wpi_eeprom_chan channels[WPI_MAX_CHAN_PER_BAND14];
902 int chan, i;
903
904 wpi_read_prom_data(sc, band->addr, channels,
905 band->nchan * sizeof (struct wpi_eeprom_chan));
906
907 for (i = 0; i < band->nchan; i++) {
908 if (!(channels[i].flags & WPI_EEPROM_CHAN_VALID(1 << 0)))
909 continue;
910
911 chan = band->chan[i];
912
913 if (n == 0) { /* 2GHz band */
914 ic->ic_channels[chan].ic_freq =
915 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ0x0080);
916 ic->ic_channels[chan].ic_flags =
917 IEEE80211_CHAN_CCK0x0020 | IEEE80211_CHAN_OFDM0x0040 |
918 IEEE80211_CHAN_DYN0x0400 | IEEE80211_CHAN_2GHZ0x0080;
919
920 } else { /* 5GHz band */
921 /*
922 * Some adapters support channels 7, 8, 11 and 12
923 * both in the 2GHz and 4.9GHz bands.
924 * Because of limitations in our net80211 layer,
925 * we don't support them in the 4.9GHz band.
926 */
927 if (chan <= 14)
928 continue;
929
930 ic->ic_channels[chan].ic_freq =
931 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_5GHZ0x0100);
932 ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_A(0x0100 | 0x0040);
933 /* We have at least one valid 5GHz channel. */
934 sc->sc_flags |= WPI_FLAG_HAS_5GHZ(1 << 0);
935 }
936
937 /* Is active scan allowed on this channel? */
938 if (!(channels[i].flags & WPI_EEPROM_CHAN_ACTIVE(1 << 3))) {
939 ic->ic_channels[chan].ic_flags |=
940 IEEE80211_CHAN_PASSIVE0x0200;
941 }
942
943 /* Save maximum allowed TX power for this channel. */
944 sc->maxpwr[chan] = channels[i].maxpwr;
945
946 DPRINTF(("adding chan %d flags=0x%x maxpwr=%d\n",
947 chan, channels[i].flags, sc->maxpwr[chan]));
948 }
949}
950
951void
952wpi_read_eeprom_group(struct wpi_softc *sc, int n)
953{
954 struct wpi_power_group *group = &sc->groups[n];
955 struct wpi_eeprom_group rgroup;
956 int i;
957
958 wpi_read_prom_data(sc, WPI_EEPROM_POWER_GRP0x100 + n * 32, &rgroup,
959 sizeof rgroup);
960
961 /* Save TX power group information. */
962 group->chan = rgroup.chan;
963 group->maxpwr = rgroup.maxpwr;
964 /* Retrieve temperature at which the samples were taken. */
965 group->temp = (int16_t)letoh16(rgroup.temp)((__uint16_t)(rgroup.temp));
966
967 DPRINTF(("power group %d: chan=%d maxpwr=%d temp=%d\n", n,
968 group->chan, group->maxpwr, group->temp));
969
970 for (i = 0; i < WPI_SAMPLES_COUNT5; i++) {
971 group->samples[i].index = rgroup.samples[i].index;
972 group->samples[i].power = rgroup.samples[i].power;
973
974 DPRINTF(("\tsample %d: index=%d power=%d\n", i,
975 group->samples[i].index, group->samples[i].power));
976 }
977}
978
979struct ieee80211_node *
980wpi_node_alloc(struct ieee80211com *ic)
981{
982 return malloc(sizeof (struct wpi_node), M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008);
983}
984
985void
986wpi_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
987{
988 struct wpi_softc *sc = ic->ic_ific_ac.ac_if.if_softc;
989 struct wpi_node *wn = (void *)ni;
990 uint8_t rate;
991 int ridx, i;
992
993 ieee80211_amrr_node_init(&sc->amrr, &wn->amn);
994 /* Start at lowest available bit-rate, AMRR will raise. */
995 ni->ni_txrate = 0;
996
997 for (i = 0; i < ni->ni_rates.rs_nrates; i++) {
998 rate = ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL0x7f;
999 /* Map 802.11 rate to HW rate index. */
1000 for (ridx = 0; ridx <= WPI_RIDX_MAX11; ridx++)
1001 if (wpi_rates[ridx].rate == rate)
1002 break;
1003 wn->ridx[i] = ridx;
1004 }
1005}
1006
1007int
1008wpi_media_change(struct ifnet *ifp)
1009{
1010 struct wpi_softc *sc = ifp->if_softc;
1011 struct ieee80211com *ic = &sc->sc_ic;
1012 uint8_t rate, ridx;
1013 int error;
1014
1015 error = ieee80211_media_change(ifp);
1016 if (error != ENETRESET52)
1017 return error;
1018
1019 if (ic->ic_fixed_rate != -1) {
1020 rate = ic->ic_sup_rates[ic->ic_curmode].
1021 rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL0x7f;
1022 /* Map 802.11 rate to HW rate index. */
1023 for (ridx = 0; ridx <= WPI_RIDX_MAX11; ridx++)
1024 if (wpi_rates[ridx].rate == rate)
1025 break;
1026 sc->fixed_ridx = ridx;
1027 }
1028
1029 if ((ifp->if_flags & (IFF_UP0x1 | IFF_RUNNING0x40)) ==
1030 (IFF_UP0x1 | IFF_RUNNING0x40)) {
1031 wpi_stop(ifp, 0);
1032 error = wpi_init(ifp);
1033 }
1034 return error;
1035}
1036
1037int
1038wpi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
1039{
1040 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1041 struct wpi_softc *sc = ifp->if_softc;
1042 int error;
1043
1044 timeout_del(&sc->calib_to);
1045
1046 switch (nstate) {
1047 case IEEE80211_S_SCAN:
1048 /* Make the link LED blink while we're scanning. */
1049 wpi_set_led(sc, WPI_LED_LINK2, 20, 2);
1050
1051 if ((error = wpi_scan(sc, IEEE80211_CHAN_2GHZ0x0080)) != 0) {
1052 printf("%s: could not initiate scan\n",
1053 sc->sc_dev.dv_xname);
1054 return error;
1055 }
1056 if (ifp->if_flags & IFF_DEBUG0x4)
1057 printf("%s: %s -> %s\n", ifp->if_xname,
1058 ieee80211_state_name[ic->ic_state],
1059 ieee80211_state_name[nstate]);
1060 ieee80211_set_link_state(ic, LINK_STATE_DOWN2);
1061 ieee80211_node_cleanup(ic, ic->ic_bss);
1062 ic->ic_state = nstate;
1063 return 0;
1064
1065 case IEEE80211_S_ASSOC:
1066 if (ic->ic_state != IEEE80211_S_RUN)
1067 break;
1068 /* FALLTHROUGH */
1069 case IEEE80211_S_AUTH:
1070 /* Reset state to handle reassociations correctly. */
1071 sc->rxon.associd = 0;
1072 sc->rxon.filter &= ~htole32(WPI_FILTER_BSS)((__uint32_t)((1 << 5)));
1073
1074 if ((error = wpi_auth(sc)) != 0) {
1075 printf("%s: could not move to auth state\n",
1076 sc->sc_dev.dv_xname);
1077 return error;
1078 }
1079 break;
1080
1081 case IEEE80211_S_RUN:
1082 if ((error = wpi_run(sc)) != 0) {
1083 printf("%s: could not move to run state\n",
1084 sc->sc_dev.dv_xname);
1085 return error;
1086 }
1087 break;
1088
1089 case IEEE80211_S_INIT:
1090 break;
1091 }
1092
1093 return sc->sc_newstate(ic, nstate, arg);
1094}
1095
1096void
1097wpi_iter_func(void *arg, struct ieee80211_node *ni)
1098{
1099 struct wpi_softc *sc = arg;
1100 struct wpi_node *wn = (struct wpi_node *)ni;
1101
1102 ieee80211_amrr_choose(&sc->amrr, ni, &wn->amn);
1103}
1104
1105void
1106wpi_calib_timeout(void *arg)
1107{
1108 struct wpi_softc *sc = arg;
1109 struct ieee80211com *ic = &sc->sc_ic;
1110 int s;
1111
1112 s = splnet()splraise(0x7);
1113 /* Automatic rate control triggered every 500ms. */
1114 if (ic->ic_fixed_rate == -1) {
1115 if (ic->ic_opmode == IEEE80211_M_STA)
1116 wpi_iter_func(sc, ic->ic_bss);
1117 else
1118 ieee80211_iterate_nodes(ic, wpi_iter_func, sc);
1119 }
1120
1121 /* Force automatic TX power calibration every 60 secs. */
1122 if (++sc->calib_cnt >= 120) {
1123 wpi_power_calibration(sc);
1124 sc->calib_cnt = 0;
1125 }
1126 splx(s)spllower(s);
1127
1128 /* Automatic rate control triggered every 500ms. */
1129 timeout_add_msec(&sc->calib_to, 500);
1130}
1131
1132int
1133wpi_ccmp_decap(struct wpi_softc *sc, struct mbuf *m, struct ieee80211_key *k)
1134{
1135 struct ieee80211com *ic = &sc->sc_ic;
1136 struct ieee80211_frame *wh;
1137 uint64_t pn, *prsc;
1138 uint8_t *ivp;
1139 uint8_t tid;
1140 int hdrlen;
1141
1142 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
1143 hdrlen = ieee80211_get_hdrlen(wh);
1144 ivp = (uint8_t *)wh + hdrlen;
1145
1146 /* Check that ExtIV bit is set. */
1147 if (!(ivp[3] & IEEE80211_WEP_EXTIV0x20)) {
1148 DPRINTF(("CCMP decap ExtIV not set\n"));
1149 return 1;
1150 }
1151 tid = ieee80211_has_qos(wh) ?
1152 ieee80211_get_qos(wh) & IEEE80211_QOS_TID0x000f : 0;
1153 prsc = &k->k_rsc[tid];
1154
1155 /* Extract the 48-bit PN from the CCMP header. */
1156 pn = (uint64_t)ivp[0] |
1157 (uint64_t)ivp[1] << 8 |
1158 (uint64_t)ivp[4] << 16 |
1159 (uint64_t)ivp[5] << 24 |
1160 (uint64_t)ivp[6] << 32 |
1161 (uint64_t)ivp[7] << 40;
1162 if (pn <= *prsc) {
1163 DPRINTF(("CCMP replayed\n"));
1164 ic->ic_stats.is_ccmp_replays++;
1165 return 1;
1166 }
1167 /* Last seen packet number is updated in ieee80211_inputm(). */
1168
1169 /* Strip MIC. IV will be stripped by ieee80211_inputm(). */
1170 m_adj(m, -IEEE80211_CCMP_MICLEN8);
1171 return 0;
1172}
1173
1174void
1175wpi_rx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc,
1176 struct wpi_rx_data *data, struct mbuf_list *ml)
1177{
1178 struct ieee80211com *ic = &sc->sc_ic;
1179 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1180 struct wpi_rx_ring *ring = &sc->rxq;
1181 struct wpi_rx_stat *stat;
1182 struct wpi_rx_head *head;
1183 struct wpi_rx_tail *tail;
1184 struct ieee80211_frame *wh;
1185 struct ieee80211_rxinfo rxi;
1186 struct ieee80211_node *ni;
1187 struct mbuf *m, *m1;
1188 uint32_t flags;
1189 int error;
1190
1191 bus_dmamap_sync(sc->sc_dmat, data->map, 0, WPI_RBUF_SIZE,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), ((3 * 1024)), (0x02))
1192 BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), ((3 * 1024)), (0x02))
;
1193 stat = (struct wpi_rx_stat *)(desc + 1);
1194
1195 if (stat->len > WPI_STAT_MAXLEN20) {
1196 printf("%s: invalid RX statistic header\n",
1197 sc->sc_dev.dv_xname);
1198 ifp->if_ierrorsif_data.ifi_ierrors++;
1199 return;
1200 }
1201 head = (struct wpi_rx_head *)((caddr_t)(stat + 1) + stat->len);
1202 tail = (struct wpi_rx_tail *)((caddr_t)(head + 1) + letoh16(head->len)((__uint16_t)(head->len)));
1203 flags = letoh32(tail->flags)((__uint32_t)(tail->flags));
1204
1205 /* Discard frames with a bad FCS early. */
1206 if ((flags & WPI_RX_NOERROR((1 << 0) | (1 << 1))) != WPI_RX_NOERROR((1 << 0) | (1 << 1))) {
1207 DPRINTFN(2, ("rx tail flags error %x\n", flags));
1208 ifp->if_ierrorsif_data.ifi_ierrors++;
1209 return;
1210 }
1211 /* Discard frames that are too short. */
1212 if (letoh16(head->len)((__uint16_t)(head->len)) < sizeof (*wh)) {
1213 DPRINTF(("frame too short: %d\n", letoh16(head->len)));
1214 ic->ic_stats.is_rx_tooshort++;
1215 ifp->if_ierrorsif_data.ifi_ierrors++;
1216 return;
1217 }
1218
1219 m1 = MCLGETL(NULL, M_DONTWAIT, WPI_RBUF_SIZE)m_clget((((void *)0)), (0x0002), ((3 * 1024)));
1220 if (m1 == NULL((void *)0)) {
1221 ic->ic_stats.is_rx_nombuf++;
1222 ifp->if_ierrorsif_data.ifi_ierrors++;
1223 return;
1224 }
1225 bus_dmamap_unload(sc->sc_dmat, data->map)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (data
->map))
;
1226
1227 error = bus_dmamap_load(sc->sc_dmat, data->map, mtod(m1, void *),(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (data->
map), (((void *)((m1)->m_hdr.mh_data))), ((3 * 1024)), (((
void *)0)), (0x0001 | 0x0200))
1228 WPI_RBUF_SIZE, NULL, BUS_DMA_NOWAIT | BUS_DMA_READ)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (data->
map), (((void *)((m1)->m_hdr.mh_data))), ((3 * 1024)), (((
void *)0)), (0x0001 | 0x0200))
;
1229 if (error != 0) {
1230 m_freem(m1);
1231
1232 /* Try to reload the old mbuf. */
1233 error = bus_dmamap_load(sc->sc_dmat, data->map,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (data->
map), (((void *)((data->m)->m_hdr.mh_data))), ((3 * 1024
)), (((void *)0)), (0x0001 | 0x0200))
1234 mtod(data->m, void *), WPI_RBUF_SIZE, NULL,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (data->
map), (((void *)((data->m)->m_hdr.mh_data))), ((3 * 1024
)), (((void *)0)), (0x0001 | 0x0200))
1235 BUS_DMA_NOWAIT | BUS_DMA_READ)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (data->
map), (((void *)((data->m)->m_hdr.mh_data))), ((3 * 1024
)), (((void *)0)), (0x0001 | 0x0200))
;
1236 if (error != 0) {
1237 panic("%s: could not load old RX mbuf",
1238 sc->sc_dev.dv_xname);
1239 }
1240 /* Physical address may have changed. */
1241 ring->desc[ring->cur] = htole32(data->map->dm_segs[0].ds_addr)((__uint32_t)(data->map->dm_segs[0].ds_addr));
1242 bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
desc_dma.map), (ring->cur * sizeof (uint32_t)), (sizeof (uint32_t
)), (0x04))
1243 ring->cur * sizeof (uint32_t), sizeof (uint32_t),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
desc_dma.map), (ring->cur * sizeof (uint32_t)), (sizeof (uint32_t
)), (0x04))
1244 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
desc_dma.map), (ring->cur * sizeof (uint32_t)), (sizeof (uint32_t
)), (0x04))
;
1245 ifp->if_ierrorsif_data.ifi_ierrors++;
1246 return;
1247 }
1248
1249 m = data->m;
1250 data->m = m1;
1251 /* Update RX descriptor. */
1252 ring->desc[ring->cur] = htole32(data->map->dm_segs[0].ds_addr)((__uint32_t)(data->map->dm_segs[0].ds_addr));
1253 bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
desc_dma.map), (ring->cur * sizeof (uint32_t)), (sizeof (uint32_t
)), (0x04))
1254 ring->cur * sizeof (uint32_t), sizeof (uint32_t),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
desc_dma.map), (ring->cur * sizeof (uint32_t)), (sizeof (uint32_t
)), (0x04))
1255 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
desc_dma.map), (ring->cur * sizeof (uint32_t)), (sizeof (uint32_t
)), (0x04))
;
1256
1257 /* Finalize mbuf. */
1258 m->m_datam_hdr.mh_data = (caddr_t)(head + 1);
1259 m->m_pkthdrM_dat.MH.MH_pkthdr.len = m->m_lenm_hdr.mh_len = letoh16(head->len)((__uint16_t)(head->len));
1260
1261 /* Grab a reference to the source node. */
1262 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
1263 ni = ieee80211_find_rxnode(ic, wh);
1264
1265 rxi.rxi_flags = 0;
1266 if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED0x40) &&
1267 !IEEE80211_IS_MULTICAST(wh->i_addr1)(*(wh->i_addr1) & 0x01) &&
1268 (ni->ni_flags & IEEE80211_NODE_RXPROT0x0008) &&
1269 ni->ni_pairwise_key.k_cipher == IEEE80211_CIPHER_CCMP) {
1270 if ((flags & WPI_RX_CIPHER_MASK(7 << 8)) != WPI_RX_CIPHER_CCMP(2 << 8)) {
1271 ic->ic_stats.is_ccmp_dec_errs++;
1272 ifp->if_ierrorsif_data.ifi_ierrors++;
1273 m_freem(m);
1274 ieee80211_release_node(ic, ni);
1275 return;
1276 }
1277 /* Check whether decryption was successful or not. */
1278 if ((flags & WPI_RX_DECRYPT_MASK(3 << 11)) != WPI_RX_DECRYPT_OK(3 << 11)) {
1279 DPRINTF(("CCMP decryption failed 0x%x\n", flags));
1280 ic->ic_stats.is_ccmp_dec_errs++;
1281 ifp->if_ierrorsif_data.ifi_ierrors++;
1282 m_freem(m);
1283 ieee80211_release_node(ic, ni);
1284 return;
1285 }
1286 if (wpi_ccmp_decap(sc, m, &ni->ni_pairwise_key) != 0) {
1287 ifp->if_ierrorsif_data.ifi_ierrors++;
1288 m_freem(m);
1289 ieee80211_release_node(ic, ni);
1290 return;
1291 }
1292 rxi.rxi_flags |= IEEE80211_RXI_HWDEC0x00000001;
1293 }
1294
1295#if NBPFILTER1 > 0
1296 if (sc->sc_drvbpf != NULL((void *)0)) {
1297 struct wpi_rx_radiotap_header *tap = &sc->sc_rxtapsc_rxtapu.th;
1298
1299 tap->wr_flags = 0;
1300 if (letoh16(head->flags)((__uint16_t)(head->flags)) & 0x4)
1301 tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE0x02;
1302 tap->wr_chan_freq =
1303 htole16(ic->ic_channels[head->chan].ic_freq)((__uint16_t)(ic->ic_channels[head->chan].ic_freq));
1304 tap->wr_chan_flags =
1305 htole16(ic->ic_channels[head->chan].ic_flags)((__uint16_t)(ic->ic_channels[head->chan].ic_flags));
1306 tap->wr_dbm_antsignal = (int8_t)(stat->rssi - WPI_RSSI_OFFSET95);
1307 tap->wr_dbm_antnoise = (int8_t)letoh16(stat->noise)((__uint16_t)(stat->noise));
1308 tap->wr_tsft = tail->tstamp;
1309 tap->wr_antenna = (letoh16(head->flags)((__uint16_t)(head->flags)) >> 4) & 0xf;
1310 switch (head->rate) {
1311 /* CCK rates. */
1312 case 10: tap->wr_rate = 2; break;
1313 case 20: tap->wr_rate = 4; break;
1314 case 55: tap->wr_rate = 11; break;
1315 case 110: tap->wr_rate = 22; break;
1316 /* OFDM rates. */
1317 case 0xd: tap->wr_rate = 12; break;
1318 case 0xf: tap->wr_rate = 18; break;
1319 case 0x5: tap->wr_rate = 24; break;
1320 case 0x7: tap->wr_rate = 36; break;
1321 case 0x9: tap->wr_rate = 48; break;
1322 case 0xb: tap->wr_rate = 72; break;
1323 case 0x1: tap->wr_rate = 96; break;
1324 case 0x3: tap->wr_rate = 108; break;
1325 /* Unknown rate: should not happen. */
1326 default: tap->wr_rate = 0;
1327 }
1328
1329 bpf_mtap_hdr(sc->sc_drvbpf, tap, sc->sc_rxtap_len,
1330 m, BPF_DIRECTION_IN(1 << 0));
1331 }
1332#endif
1333
1334 /* Send the frame to the 802.11 layer. */
1335 rxi.rxi_rssi = stat->rssi;
1336 rxi.rxi_tstamp = 0; /* unused */
1337 ieee80211_inputm(ifp, m, ni, &rxi, ml);
1338
1339 /* Node is no longer needed. */
1340 ieee80211_release_node(ic, ni);
1341}
1342
1343void
1344wpi_tx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc)
1345{
1346 struct ieee80211com *ic = &sc->sc_ic;
1347 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1348 struct wpi_tx_ring *ring = &sc->txq[desc->qid & 0x3];
1349 struct wpi_tx_data *data = &ring->data[desc->idx];
1350 struct wpi_tx_stat *stat = (struct wpi_tx_stat *)(desc + 1);
1351 struct wpi_node *wn = (struct wpi_node *)data->ni;
1352
1353 /* Update rate control statistics. */
1354 wn->amn.amn_txcnt++;
1355 if (stat->retrycnt > 0)
1356 wn->amn.amn_retrycnt++;
1357
1358 if ((letoh32(stat->status)((__uint32_t)(stat->status)) & 0xff) != 1)
1359 ifp->if_oerrorsif_data.ifi_oerrors++;
1360
1361 /* Unmap and free mbuf. */
1362 bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x08))
1363 BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x08))
;
1364 bus_dmamap_unload(sc->sc_dmat, data->map)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (data
->map))
;
1365 m_freem(data->m);
1366 data->m = NULL((void *)0);
1367 ieee80211_release_node(ic, data->ni);
1368 data->ni = NULL((void *)0);
1369
1370 sc->sc_tx_timer = 0;
1371 if (--ring->queued < WPI_TX_RING_LOMARK192) {
1372 sc->qfullmsk &= ~(1 << ring->qid);
1373 if (sc->qfullmsk == 0 && ifq_is_oactive(&ifp->if_snd)) {
1374 ifq_clr_oactive(&ifp->if_snd);
1375 (*ifp->if_start)(ifp);
1376 }
1377 }
1378}
1379
1380void
1381wpi_cmd_done(struct wpi_softc *sc, struct wpi_rx_desc *desc)
1382{
1383 struct wpi_tx_ring *ring = &sc->txq[4];
1384 struct wpi_tx_data *data;
1385
1386 if ((desc->qid & 7) != 4)
1387 return; /* Not a command ack. */
1388
1389 data = &ring->data[desc->idx];
1390
1391 /* If the command was mapped in an mbuf, free it. */
1392 if (data->m != NULL((void *)0)) {
1393 bus_dmamap_sync(sc->sc_dmat, data->map, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x08))
1394 data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x08))
;
1395 bus_dmamap_unload(sc->sc_dmat, data->map)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (data
->map))
;
1396 m_freem(data->m);
1397 data->m = NULL((void *)0);
1398 }
1399 wakeup(&ring->cmd[desc->idx]);
1400}
1401
1402void
1403wpi_notif_intr(struct wpi_softc *sc)
1404{
1405 struct mbuf_list ml = MBUF_LIST_INITIALIZER(){ ((void *)0), ((void *)0), 0 };
1406 struct ieee80211com *ic = &sc->sc_ic;
1407 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1408 uint32_t hw;
1409
1410 bus_dmamap_sync(sc->sc_dmat, sc->shared_dma.map, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
shared_dma.map), (0), (sizeof (struct wpi_shared)), (0x02))
1411 sizeof (struct wpi_shared), BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
shared_dma.map), (0), (sizeof (struct wpi_shared)), (0x02))
;
1412
1413 hw = letoh32(sc->shared->next)((__uint32_t)(sc->shared->next));
1414 while (sc->rxq.cur != hw) {
1415 struct wpi_rx_data *data = &sc->rxq.data[sc->rxq.cur];
1416 struct wpi_rx_desc *desc;
1417
1418 bus_dmamap_sync(sc->sc_dmat, data->map, 0, sizeof (*desc),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (sizeof (*desc)), (0x02))
1419 BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (sizeof (*desc)), (0x02))
;
1420 desc = mtod(data->m, struct wpi_rx_desc *)((struct wpi_rx_desc *)((data->m)->m_hdr.mh_data));
1421
1422 DPRINTFN(4, ("rx notification qid=%x idx=%d flags=%x type=%d "
1423 "len=%d\n", desc->qid, desc->idx, desc->flags, desc->type,
1424 letoh32(desc->len)));
1425
1426 if (!(desc->qid & 0x80)) /* Reply to a command. */
1427 wpi_cmd_done(sc, desc);
1428
1429 switch (desc->type) {
1430 case WPI_RX_DONE27:
1431 /* An 802.11 frame has been received. */
1432 wpi_rx_done(sc, desc, data, &ml);
1433 break;
1434
1435 case WPI_TX_DONE28:
1436 /* An 802.11 frame has been transmitted. */
1437 wpi_tx_done(sc, desc);
1438 break;
1439
1440 case WPI_UC_READY1:
1441 {
1442 struct wpi_ucode_info *uc =
1443 (struct wpi_ucode_info *)(desc + 1);
1444
1445 /* The microcontroller is ready. */
1446 bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (sizeof (*desc)), (sizeof (*uc)), (0x02))
1447 sizeof (*uc), BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (sizeof (*desc)), (sizeof (*uc)), (0x02))
;
1448 DPRINTF(("microcode alive notification version %x "
1449 "alive %x\n", letoh32(uc->version),
1450 letoh32(uc->valid)));
1451
1452 if (letoh32(uc->valid)((__uint32_t)(uc->valid)) != 1) {
1453 printf("%s: microcontroller initialization "
1454 "failed\n", sc->sc_dev.dv_xname);
1455 }
1456 if (uc->subtype != WPI_UCODE_INIT9) {
1457 /* Save the address of the error log. */
1458 sc->errptr = letoh32(uc->errptr)((__uint32_t)(uc->errptr));
1459 }
1460 break;
1461 }
1462 case WPI_STATE_CHANGED161:
1463 {
1464 uint32_t *status = (uint32_t *)(desc + 1);
1465
1466 /* Enabled/disabled notification. */
1467 bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (sizeof (*desc)), (sizeof (*status)), (0x02))
1468 sizeof (*status), BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (sizeof (*desc)), (sizeof (*status)), (0x02))
;
1469 DPRINTF(("state changed to %x\n", letoh32(*status)));
1470
1471 if (letoh32(*status)((__uint32_t)(*status)) & 1) {
1472 /* The radio button has to be pushed. */
1473 printf("%s: Radio transmitter is off\n",
1474 sc->sc_dev.dv_xname);
1475 /* Turn the interface down. */
1476 wpi_stop(ifp, 1);
1477 return; /* No further processing. */
1478 }
1479 break;
1480 }
1481 case WPI_START_SCAN130:
1482 {
1483 struct wpi_start_scan *scan =
1484 (struct wpi_start_scan *)(desc + 1);
1485
1486 bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (sizeof (*desc)), (sizeof (*scan)), (0x02))
1487 sizeof (*scan), BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (sizeof (*desc)), (sizeof (*scan)), (0x02))
;
1488 DPRINTFN(2, ("scanning channel %d status %x\n",
1489 scan->chan, letoh32(scan->status)));
1490
1491 /* Fix current channel. */
1492 ic->ic_bss->ni_chan = &ic->ic_channels[scan->chan];
1493 break;
1494 }
1495 case WPI_STOP_SCAN132:
1496 {
1497 struct wpi_stop_scan *scan =
1498 (struct wpi_stop_scan *)(desc + 1);
1499
1500 bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (sizeof (*desc)), (sizeof (*scan)), (0x02))
1501 sizeof (*scan), BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (sizeof (*desc)), (sizeof (*scan)), (0x02))
;
1502 DPRINTF(("scan finished nchan=%d status=%d chan=%d\n",
1503 scan->nchan, scan->status, scan->chan));
1504
1505 if (scan->status == 1 && scan->chan <= 14 &&
1506 (sc->sc_flags & WPI_FLAG_HAS_5GHZ(1 << 0))) {
1507 /*
1508 * We just finished scanning 2GHz channels,
1509 * start scanning 5GHz ones.
1510 */
1511 if (wpi_scan(sc, IEEE80211_CHAN_5GHZ0x0100) == 0)
1512 break;
1513 }
1514 ieee80211_end_scan(ifp);
1515 break;
1516 }
1517 }
1518
1519 sc->rxq.cur = (sc->rxq.cur + 1) % WPI_RX_RING_COUNT(1 << 6);
1520 }
1521 if_input(&ic->ic_ific_ac.ac_if, &ml);
1522
1523 /* Tell the firmware what we have processed. */
1524 hw = (hw == 0) ? WPI_RX_RING_COUNT(1 << 6) - 1 : hw - 1;
1525 WPI_WRITE(sc, WPI_FH_RX_WPTR, hw & ~7)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xc20)), ((
hw & ~7))))
;
1526}
1527
1528#ifdef WPI_DEBUG
1529/*
1530 * Dump the error log of the firmware when a firmware panic occurs. Although
1531 * we can't debug the firmware because it is neither open source nor free, it
1532 * can help us to identify certain classes of problems.
1533 */
1534void
1535wpi_fatal_intr(struct wpi_softc *sc)
1536{
1537#define N(a) (sizeof (a) / sizeof ((a)[0]))
1538 struct wpi_fwdump dump;
1539 uint32_t i, offset, count;
1540
1541 /* Check that the error log address is valid. */
1542 if (sc->errptr < WPI_FW_DATA_BASE0x00800000 ||
1543 sc->errptr + sizeof (dump) >
1544 WPI_FW_DATA_BASE0x00800000 + WPI_FW_DATA_MAXSZ(32 * 1024)) {
1545 printf("%s: bad firmware error log address 0x%08x\n",
1546 sc->sc_dev.dv_xname, sc->errptr);
1547 return;
1548 }
1549
1550 if (wpi_nic_lock(sc) != 0) {
1551 printf("%s: could not read firmware error log\n",
1552 sc->sc_dev.dv_xname);
1553 return;
1554 }
1555 /* Read number of entries in the log. */
1556 count = wpi_mem_read(sc, sc->errptr);
1557 if (count == 0 || count * sizeof (dump) > WPI_FW_DATA_MAXSZ(32 * 1024)) {
1558 printf("%s: invalid count field (count=%u)\n",
1559 sc->sc_dev.dv_xname, count);
1560 wpi_nic_unlock(sc);
1561 return;
1562 }
1563 /* Skip "count" field. */
1564 offset = sc->errptr + sizeof (uint32_t);
1565 printf("firmware error log (count=%u):\n", count);
1566 for (i = 0; i < count; i++) {
1567 wpi_mem_read_region_4(sc, offset, (uint32_t *)&dump,
1568 sizeof (dump) / sizeof (uint32_t));
1569
1570 printf(" error type = \"%s\" (0x%08X)\n",
1571 (dump.desc < N(wpi_fw_errmsg)) ?
1572 wpi_fw_errmsg[dump.desc] : "UNKNOWN",
1573 dump.desc);
1574 printf(" error data = 0x%08X\n",
1575 dump.data);
1576 printf(" branch link = 0x%08X%08X\n",
1577 dump.blink[0], dump.blink[1]);
1578 printf(" interrupt link = 0x%08X%08X\n",
1579 dump.ilink[0], dump.ilink[1]);
1580 printf(" time = %u\n", dump.time);
1581
1582 offset += sizeof (dump);
1583 }
1584 wpi_nic_unlock(sc);
1585 /* Dump driver status (TX and RX rings) while we're here. */
1586 printf("driver status:\n");
1587 for (i = 0; i < 6; i++) {
1588 struct wpi_tx_ring *ring = &sc->txq[i];
1589 printf(" tx ring %2d: qid=%-2d cur=%-3d queued=%-3d\n",
1590 i, ring->qid, ring->cur, ring->queued);
1591 }
1592 printf(" rx ring: cur=%d\n", sc->rxq.cur);
1593 printf(" 802.11 state %d\n", sc->sc_ic.ic_state);
1594#undef N
1595}
1596#endif
1597
1598int
1599wpi_intr(void *arg)
1600{
1601 struct wpi_softc *sc = arg;
1602 struct ifnet *ifp = &sc->sc_ic.ic_ific_ac.ac_if;
1603 uint32_t r1, r2;
1604
1605 /* Disable interrupts. */
1606 WPI_WRITE(sc, WPI_MASK, 0)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x00c)), ((
0))))
;
1607
1608 r1 = WPI_READ(sc, WPI_INT)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x008))));
1609 r2 = WPI_READ(sc, WPI_FH_INT)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x010))));
1610
1611 if (r1 == 0 && r2 == 0) {
1612 if (ifp->if_flags & IFF_UP0x1)
1613 WPI_WRITE(sc, WPI_MASK, WPI_INT_MASK)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x00c)), ((
((1U << 25) | (1U << 29) | (1U << 27) | (1U
<< 31) | (1U << 0) | (1U << 1) | (1U <<
3) | (1U << 7))))))
;
1614 return 0; /* Interrupt not for us. */
1615 }
1616 if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0)
1617 return 0; /* Hardware gone! */
1618
1619 /* Acknowledge interrupts. */
1620 WPI_WRITE(sc, WPI_INT, r1)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x008)), ((
r1))))
;
1621 WPI_WRITE(sc, WPI_FH_INT, r2)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x010)), ((
r2))))
;
1622
1623 if (r1 & (WPI_INT_SW_ERR(1U << 25) | WPI_INT_HW_ERR(1U << 29))) {
1624 printf("%s: fatal firmware error\n", sc->sc_dev.dv_xname);
1625 /* Dump firmware error log and stop. */
1626#ifdef WPI_DEBUG
1627 wpi_fatal_intr(sc);
1628#endif
1629 wpi_stop(ifp, 1);
1630 task_add(systq, &sc->init_task);
1631 return 1;
1632 }
1633 if ((r1 & (WPI_INT_FH_RX(1U << 31) | WPI_INT_SW_RX(1U << 3))) ||
1634 (r2 & WPI_FH_INT_RX((1 << ((0) + 16)) | (1 << ((1) + 16)) | (1 <<
((2) + 16)) | (1 << 30))
))
1635 wpi_notif_intr(sc);
1636
1637 if (r1 & WPI_INT_ALIVE(1U << 0))
1638 wakeup(sc); /* Firmware is alive. */
1639
1640 /* Re-enable interrupts. */
1641 if (ifp->if_flags & IFF_UP0x1)
1642 WPI_WRITE(sc, WPI_MASK, WPI_INT_MASK)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x00c)), ((
((1U << 25) | (1U << 29) | (1U << 27) | (1U
<< 31) | (1U << 0) | (1U << 1) | (1U <<
3) | (1U << 7))))))
;
1643
1644 return 1;
1645}
1646
1647int
1648wpi_tx(struct wpi_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
1649{
1650 struct ieee80211com *ic = &sc->sc_ic;
1651 struct wpi_node *wn = (void *)ni;
1652 struct wpi_tx_ring *ring;
1653 struct wpi_tx_desc *desc;
1654 struct wpi_tx_data *data;
1655 struct wpi_tx_cmd *cmd;
1656 struct wpi_cmd_data *tx;
1657 const struct wpi_rate *rinfo;
1658 struct ieee80211_frame *wh;
1659 struct ieee80211_key *k = NULL((void *)0);
1660 enum ieee80211_edca_ac ac;
1661 uint32_t flags;
1662 uint16_t qos;
1663 u_int hdrlen;
1664 uint8_t *ivp, tid, ridx, type;
1665 int i, totlen, hasqos, error;
1666
1667 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
1668 hdrlen = ieee80211_get_hdrlen(wh);
1669 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK0x0c;
1670
1671 /* Select EDCA Access Category and TX ring for this frame. */
1672 if ((hasqos = ieee80211_has_qos(wh))) {
1673 qos = ieee80211_get_qos(wh);
1674 tid = qos & IEEE80211_QOS_TID0x000f;
1675 ac = ieee80211_up_to_ac(ic, tid);
1676 } else {
1677 tid = 0;
1678 ac = EDCA_AC_BE;
1679 }
1680
1681 ring = &sc->txq[ac];
1682 desc = &ring->desc[ring->cur];
1683 data = &ring->data[ring->cur];
1684
1685 /* Choose a TX rate index. */
1686 if (IEEE80211_IS_MULTICAST(wh->i_addr1)(*(wh->i_addr1) & 0x01) ||
1687 type != IEEE80211_FC0_TYPE_DATA0x08) {
1688 ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
1689 WPI_RIDX_OFDM60 : WPI_RIDX_CCK18;
1690 } else if (ic->ic_fixed_rate != -1) {
1691 ridx = sc->fixed_ridx;
1692 } else
1693 ridx = wn->ridx[ni->ni_txrate];
1694 rinfo = &wpi_rates[ridx];
1695
1696#if NBPFILTER1 > 0
1697 if (sc->sc_drvbpf != NULL((void *)0)) {
1698 struct wpi_tx_radiotap_header *tap = &sc->sc_txtapsc_txtapu.th;
1699
1700 tap->wt_flags = 0;
1701 tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq)((__uint16_t)(ni->ni_chan->ic_freq));
1702 tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags)((__uint16_t)(ni->ni_chan->ic_flags));
1703 tap->wt_rate = rinfo->rate;
1704 if ((ic->ic_flags & IEEE80211_F_WEPON0x00000100) &&
1705 (wh->i_fc[1] & IEEE80211_FC1_PROTECTED0x40))
1706 tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP0x04;
1707
1708 bpf_mtap_hdr(sc->sc_drvbpf, tap, sc->sc_txtap_len,
1709 m, BPF_DIRECTION_OUT(1 << 1));
1710 }
1711#endif
1712
1713 totlen = m->m_pkthdrM_dat.MH.MH_pkthdr.len;
1714
1715 /* Encrypt the frame if need be. */
1716 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED0x40) {
1717 /* Retrieve key for TX. */
1718 k = ieee80211_get_txkey(ic, wh, ni);
1719 if (k->k_cipher != IEEE80211_CIPHER_CCMP) {
1720 /* Do software encryption. */
1721 if ((m = ieee80211_encrypt(ic, m, k)) == NULL((void *)0))
1722 return ENOBUFS55;
1723 /* 802.11 header may have moved. */
1724 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
1725 totlen = m->m_pkthdrM_dat.MH.MH_pkthdr.len;
1726
1727 } else /* HW appends CCMP MIC. */
1728 totlen += IEEE80211_CCMP_HDRLEN8;
1729 }
1730
1731 /* Prepare TX firmware command. */
1732 cmd = &ring->cmd[ring->cur];
1733 cmd->code = WPI_CMD_TX_DATA28;
1734 cmd->flags = 0;
1735 cmd->qid = ring->qid;
1736 cmd->idx = ring->cur;
1737
1738 tx = (struct wpi_cmd_data *)cmd->data;
1739 /* NB: No need to clear tx, all fields are reinitialized here. */
1740
1741 flags = 0;
1742 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)(*(wh->i_addr1) & 0x01)) {
1743 /* Unicast frame, check if an ACK is expected. */
1744 if (!hasqos || (qos & IEEE80211_QOS_ACK_POLICY_MASK0x0060) !=
1745 IEEE80211_QOS_ACK_POLICY_NOACK0x0020)
1746 flags |= WPI_TX_NEED_ACK(1 << 3);
1747 }
1748
1749 /* Check if frame must be protected using RTS/CTS or CTS-to-self. */
1750 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)(*(wh->i_addr1) & 0x01)) {
1751 /* NB: Group frames are sent using CCK in 802.11b/g. */
1752 if (totlen + IEEE80211_CRC_LEN4 > ic->ic_rtsthreshold) {
1753 flags |= WPI_TX_NEED_RTS(1 << 1) | WPI_TX_FULL_TXOP(1 << 7);
1754 } else if ((ic->ic_flags & IEEE80211_F_USEPROT0x00100000) &&
1755 ridx <= WPI_RIDX_OFDM547) {
1756 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
1757 flags |= WPI_TX_NEED_CTS(1 << 2) | WPI_TX_FULL_TXOP(1 << 7);
1758 else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
1759 flags |= WPI_TX_NEED_RTS(1 << 1) | WPI_TX_FULL_TXOP(1 << 7);
1760 }
1761 }
1762
1763 if (IEEE80211_IS_MULTICAST(wh->i_addr1)(*(wh->i_addr1) & 0x01) ||
1764 type != IEEE80211_FC0_TYPE_DATA0x08)
1765 tx->id = WPI_ID_BROADCAST24;
1766 else
1767 tx->id = wn->id;
1768
1769 if (type == IEEE80211_FC0_TYPE_MGT0x00) {
1770 uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK0xf0;
1771
1772#ifndef IEEE80211_STA_ONLY
1773 /* Tell HW to set timestamp in probe responses. */
1774 if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP0x50)
1775 flags |= WPI_TX_INSERT_TSTAMP(1 << 16);
1776#endif
1777 if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ0x00 ||
1778 subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ0x20)
1779 tx->timeout = htole16(3)((__uint16_t)(3));
1780 else
1781 tx->timeout = htole16(2)((__uint16_t)(2));
1782 } else
1783 tx->timeout = htole16(0)((__uint16_t)(0));
1784
1785 tx->len = htole16(totlen)((__uint16_t)(totlen));
1786 tx->tid = tid;
1787 tx->rts_ntries = 7;
1788 tx->data_ntries = 15;
1789 tx->ofdm_mask = 0xff;
1790 tx->cck_mask = 0x0f;
1791 tx->lifetime = htole32(WPI_LIFETIME_INFINITE)((__uint32_t)(0xffffffff));
1792 tx->plcp = rinfo->plcp;
1793
1794 /* Copy 802.11 header in TX command. */
1795 memcpy((uint8_t *)(tx + 1), wh, hdrlen)__builtin_memcpy(((uint8_t *)(tx + 1)), (wh), (hdrlen));
1796
1797 if (k != NULL((void *)0) && k->k_cipher == IEEE80211_CIPHER_CCMP) {
1798 /* Trim 802.11 header and prepend CCMP IV. */
1799 m_adj(m, hdrlen - IEEE80211_CCMP_HDRLEN8);
1800 ivp = mtod(m, uint8_t *)((uint8_t *)((m)->m_hdr.mh_data));
1801 k->k_tsc++;
1802 ivp[0] = k->k_tsc;
1803 ivp[1] = k->k_tsc >> 8;
1804 ivp[2] = 0;
1805 ivp[3] = k->k_id << 6 | IEEE80211_WEP_EXTIV0x20;
1806 ivp[4] = k->k_tsc >> 16;
1807 ivp[5] = k->k_tsc >> 24;
1808 ivp[6] = k->k_tsc >> 32;
1809 ivp[7] = k->k_tsc >> 40;
1810
1811 tx->security = WPI_CIPHER_CCMP2;
1812 memcpy(tx->key, k->k_key, k->k_len)__builtin_memcpy((tx->key), (k->k_key), (k->k_len));
1813 } else {
1814 /* Trim 802.11 header. */
1815 m_adj(m, hdrlen);
1816 tx->security = 0;
1817 }
1818 tx->flags = htole32(flags)((__uint32_t)(flags));
1819
1820 error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
data->map), (m), (0x0001 | 0x0400))
1821 BUS_DMA_NOWAIT | BUS_DMA_WRITE)(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
data->map), (m), (0x0001 | 0x0400))
;
1822 if (error != 0 && error != EFBIG27) {
1823 printf("%s: can't map mbuf (error %d)\n",
1824 sc->sc_dev.dv_xname, error);
1825 m_freem(m);
1826 return error;
1827 }
1828 if (error != 0) {
1829 /* Too many DMA segments, linearize mbuf. */
1830 if (m_defrag(m, M_DONTWAIT0x0002)) {
1831 m_freem(m);
1832 return ENOBUFS55;
1833 }
1834 error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
data->map), (m), (0x0001 | 0x0400))
1835 BUS_DMA_NOWAIT | BUS_DMA_WRITE)(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
data->map), (m), (0x0001 | 0x0400))
;
1836 if (error != 0) {
1837 printf("%s: can't map mbuf (error %d)\n",
1838 sc->sc_dev.dv_xname, error);
1839 m_freem(m);
1840 return error;
1841 }
1842 }
1843
1844 data->m = m;
1845 data->ni = ni;
1846
1847 DPRINTFN(4, ("sending data: qid=%d idx=%d len=%d nsegs=%d\n",
1848 ring->qid, ring->cur, m->m_pkthdr.len, data->map->dm_nsegs));
1849
1850 /* Fill TX descriptor. */
1851 desc->flags = htole32(WPI_PAD32(m->m_pkthdr.len) << 28 |((__uint32_t)(((((m->M_dat.MH.MH_pkthdr.len) + 3) & ~3
) - (m->M_dat.MH.MH_pkthdr.len)) << 28 | (1 + data->
map->dm_nsegs) << 24))
1852 (1 + data->map->dm_nsegs) << 24)((__uint32_t)(((((m->M_dat.MH.MH_pkthdr.len) + 3) & ~3
) - (m->M_dat.MH.MH_pkthdr.len)) << 28 | (1 + data->
map->dm_nsegs) << 24))
;
1853 /* First DMA segment is used by the TX command. */
1854 desc->segs[0].addr = htole32(ring->cmd_dma.paddr +((__uint32_t)(ring->cmd_dma.paddr + ring->cur * sizeof (
struct wpi_tx_cmd)))
1855 ring->cur * sizeof (struct wpi_tx_cmd))((__uint32_t)(ring->cmd_dma.paddr + ring->cur * sizeof (
struct wpi_tx_cmd)))
;
1856 desc->segs[0].len = htole32(4 + sizeof (struct wpi_cmd_data) +((__uint32_t)(4 + sizeof (struct wpi_cmd_data) + ((hdrlen + 3
) & ~3)))
1857 ((hdrlen + 3) & ~3))((__uint32_t)(4 + sizeof (struct wpi_cmd_data) + ((hdrlen + 3
) & ~3)))
;
1858 /* Other DMA segments are for data payload. */
1859 for (i = 1; i <= data->map->dm_nsegs; i++) {
1860 desc->segs[i].addr =
1861 htole32(data->map->dm_segs[i - 1].ds_addr)((__uint32_t)(data->map->dm_segs[i - 1].ds_addr));
1862 desc->segs[i].len =
1863 htole32(data->map->dm_segs[i - 1].ds_len)((__uint32_t)(data->map->dm_segs[i - 1].ds_len));
1864 }
1865
1866 bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x04))
1867 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x04))
;
1868 bus_dmamap_sync(sc->sc_dmat, ring->cmd_dma.map,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
cmd_dma.map), ((caddr_t)cmd - ring->cmd_dma.vaddr), (sizeof
(*cmd)), (0x04))
1869 (caddr_t)cmd - ring->cmd_dma.vaddr, sizeof (*cmd),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
cmd_dma.map), ((caddr_t)cmd - ring->cmd_dma.vaddr), (sizeof
(*cmd)), (0x04))
1870 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
cmd_dma.map), ((caddr_t)cmd - ring->cmd_dma.vaddr), (sizeof
(*cmd)), (0x04))
;
1871 bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
desc_dma.map), ((caddr_t)desc - ring->desc_dma.vaddr), (sizeof
(*desc)), (0x04))
1872 (caddr_t)desc - ring->desc_dma.vaddr, sizeof (*desc),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
desc_dma.map), ((caddr_t)desc - ring->desc_dma.vaddr), (sizeof
(*desc)), (0x04))
1873 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
desc_dma.map), ((caddr_t)desc - ring->desc_dma.vaddr), (sizeof
(*desc)), (0x04))
;
1874
1875 /* Kick TX ring. */
1876 ring->cur = (ring->cur + 1) % WPI_TX_RING_COUNT256;
1877 WPI_WRITE(sc, WPI_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x460)), ((
ring->qid << 8 | ring->cur))))
;
1878
1879 /* Mark TX ring as full if we reach a certain threshold. */
1880 if (++ring->queued > WPI_TX_RING_HIMARK224)
1881 sc->qfullmsk |= 1 << ring->qid;
1882
1883 return 0;
1884}
1885
1886void
1887wpi_start(struct ifnet *ifp)
1888{
1889 struct wpi_softc *sc = ifp->if_softc;
1890 struct ieee80211com *ic = &sc->sc_ic;
1891 struct ieee80211_node *ni;
1892 struct mbuf *m;
1893
1894 if (!(ifp->if_flags & IFF_RUNNING0x40) || ifq_is_oactive(&ifp->if_snd))
1895 return;
1896
1897 for (;;) {
1898 if (sc->qfullmsk != 0) {
1899 ifq_set_oactive(&ifp->if_snd);
1900 break;
1901 }
1902 /* Send pending management frames first. */
1903 m = mq_dequeue(&ic->ic_mgtq);
1904 if (m != NULL((void *)0)) {
1905 ni = m->m_pkthdrM_dat.MH.MH_pkthdr.ph_cookie;
1906 goto sendit;
1907 }
1908 if (ic->ic_state != IEEE80211_S_RUN)
1909 break;
1910
1911 /* Encapsulate and send data frames. */
1912 m = ifq_dequeue(&ifp->if_snd);
1913 if (m == NULL((void *)0))
1914 break;
1915#if NBPFILTER1 > 0
1916 if (ifp->if_bpf != NULL((void *)0))
1917 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT(1 << 1));
1918#endif
1919 if ((m = ieee80211_encap(ifp, m, &ni)) == NULL((void *)0))
1920 continue;
1921sendit:
1922#if NBPFILTER1 > 0
1923 if (ic->ic_rawbpf != NULL((void *)0))
1924 bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT(1 << 1));
1925#endif
1926 if (wpi_tx(sc, m, ni) != 0) {
1927 ieee80211_release_node(ic, ni);
1928 ifp->if_oerrorsif_data.ifi_oerrors++;
1929 continue;
1930 }
1931
1932 sc->sc_tx_timer = 5;
1933 ifp->if_timer = 1;
1934 }
1935}
1936
1937void
1938wpi_watchdog(struct ifnet *ifp)
1939{
1940 struct wpi_softc *sc = ifp->if_softc;
1941
1942 ifp->if_timer = 0;
1943
1944 if (sc->sc_tx_timer > 0) {
1945 if (--sc->sc_tx_timer == 0) {
1946 printf("%s: device timeout\n", sc->sc_dev.dv_xname);
1947 wpi_stop(ifp, 1);
1948 ifp->if_oerrorsif_data.ifi_oerrors++;
1949 return;
1950 }
1951 ifp->if_timer = 1;
1952 }
1953
1954 ieee80211_watchdog(ifp);
1955}
1956
1957int
1958wpi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1959{
1960 struct wpi_softc *sc = ifp->if_softc;
1961 struct ieee80211com *ic = &sc->sc_ic;
1962 int s, error = 0;
1963
1964 error = rw_enter(&sc->sc_rwlock, RW_WRITE0x0001UL | RW_INTR0x0010UL);
1965 if (error)
1966 return error;
1967 s = splnet()splraise(0x7);
1968
1969 switch (cmd) {
1970 case SIOCSIFADDR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((12)))
:
1971 ifp->if_flags |= IFF_UP0x1;
1972 /* FALLTHROUGH */
1973 case SIOCSIFFLAGS((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((16)))
:
1974 if (ifp->if_flags & IFF_UP0x1) {
1975 if (!(ifp->if_flags & IFF_RUNNING0x40))
1976 error = wpi_init(ifp);
1977 } else {
1978 if (ifp->if_flags & IFF_RUNNING0x40)
1979 wpi_stop(ifp, 1);
1980 }
1981 break;
1982
1983 case SIOCS80211POWER((unsigned long)0x80000000 | ((sizeof(struct ieee80211_power)
& 0x1fff) << 16) | ((('i')) << 8) | ((234)))
:
1984 error = ieee80211_ioctl(ifp, cmd, data);
1985 if (error != ENETRESET52)
1986 break;
1987 if (ic->ic_state == IEEE80211_S_RUN) {
1988 if (ic->ic_flags & IEEE80211_F_PMGTON0x00000400)
1989 error = wpi_set_pslevel(sc, 0, 3, 0);
1990 else /* back to CAM */
1991 error = wpi_set_pslevel(sc, 0, 0, 0);
1992 } else {
1993 /* Defer until transition to IEEE80211_S_RUN. */
1994 error = 0;
1995 }
1996 break;
1997
1998 default:
1999 error = ieee80211_ioctl(ifp, cmd, data);
2000 }
2001
2002 if (error == ENETRESET52) {
2003 error = 0;
2004 if ((ifp->if_flags & (IFF_UP0x1 | IFF_RUNNING0x40)) ==
2005 (IFF_UP0x1 | IFF_RUNNING0x40)) {
2006 wpi_stop(ifp, 0);
2007 error = wpi_init(ifp);
2008 }
2009 }
2010
2011 splx(s)spllower(s);
2012 rw_exit_write(&sc->sc_rwlock);
2013 return error;
2014}
2015
2016/*
2017 * Send a command to the firmware.
2018 */
2019int
2020wpi_cmd(struct wpi_softc *sc, int code, const void *buf, int size, int async)
2021{
2022 struct wpi_tx_ring *ring = &sc->txq[4];
2023 struct wpi_tx_desc *desc;
2024 struct wpi_tx_data *data;
2025 struct wpi_tx_cmd *cmd;
2026 struct mbuf *m;
2027 bus_addr_t paddr;
2028 int totlen, error;
2029
2030 desc = &ring->desc[ring->cur];
2031 data = &ring->data[ring->cur];
2032 totlen = 4 + size;
2033
2034 if (size > sizeof cmd->data) {
2035 /* Command is too large to fit in a descriptor. */
2036 if (totlen > MCLBYTES(1 << 11))
2037 return EINVAL22;
2038 MGETHDR(m, M_DONTWAIT, MT_DATA)m = m_gethdr((0x0002), (1));
2039 if (m == NULL((void *)0))
2040 return ENOMEM12;
2041 if (totlen > MHLEN((256 - sizeof(struct m_hdr)) - sizeof(struct pkthdr))) {
2042 MCLGET(m, M_DONTWAIT)(void) m_clget((m), (0x0002), (1 << 11));
2043 if (!(m->m_flagsm_hdr.mh_flags & M_EXT0x0001)) {
2044 m_freem(m);
2045 return ENOMEM12;
2046 }
2047 }
2048 cmd = mtod(m, struct wpi_tx_cmd *)((struct wpi_tx_cmd *)((m)->m_hdr.mh_data));
2049 error = bus_dmamap_load(sc->sc_dmat, data->map, cmd, totlen,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (data->
map), (cmd), (totlen), (((void *)0)), (0x0001 | 0x0400))
2050 NULL, BUS_DMA_NOWAIT | BUS_DMA_WRITE)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (data->
map), (cmd), (totlen), (((void *)0)), (0x0001 | 0x0400))
;
2051 if (error != 0) {
2052 m_freem(m);
2053 return error;
2054 }
2055 data->m = m;
2056 paddr = data->map->dm_segs[0].ds_addr;
2057 } else {
2058 cmd = &ring->cmd[ring->cur];
2059 paddr = data->cmd_paddr;
2060 }
2061
2062 cmd->code = code;
2063 cmd->flags = 0;
2064 cmd->qid = ring->qid;
2065 cmd->idx = ring->cur;
2066 memcpy(cmd->data, buf, size)__builtin_memcpy((cmd->data), (buf), (size));
2067
2068 desc->flags = htole32(WPI_PAD32(size) << 28 | 1 << 24)((__uint32_t)(((((size) + 3) & ~3) - (size)) << 28 |
1 << 24))
;
2069 desc->segs[0].addr = htole32(paddr)((__uint32_t)(paddr));
2070 desc->segs[0].len = htole32(totlen)((__uint32_t)(totlen));
2071
2072 if (size > sizeof cmd->data) {
2073 bus_dmamap_sync(sc->sc_dmat, data->map, 0, totlen,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (totlen), (0x04))
2074 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (totlen), (0x04))
;
2075 } else {
2076 bus_dmamap_sync(sc->sc_dmat, ring->cmd_dma.map,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
cmd_dma.map), ((caddr_t)cmd - ring->cmd_dma.vaddr), (totlen
), (0x04))
2077 (caddr_t)cmd - ring->cmd_dma.vaddr, totlen,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
cmd_dma.map), ((caddr_t)cmd - ring->cmd_dma.vaddr), (totlen
), (0x04))
2078 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
cmd_dma.map), ((caddr_t)cmd - ring->cmd_dma.vaddr), (totlen
), (0x04))
;
2079 }
2080 bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
desc_dma.map), ((caddr_t)desc - ring->desc_dma.vaddr), (sizeof
(*desc)), (0x04))
2081 (caddr_t)desc - ring->desc_dma.vaddr, sizeof (*desc),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
desc_dma.map), ((caddr_t)desc - ring->desc_dma.vaddr), (sizeof
(*desc)), (0x04))
2082 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
desc_dma.map), ((caddr_t)desc - ring->desc_dma.vaddr), (sizeof
(*desc)), (0x04))
;
2083
2084 /* Kick command ring. */
2085 ring->cur = (ring->cur + 1) % WPI_TX_RING_COUNT256;
2086 WPI_WRITE(sc, WPI_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x460)), ((
ring->qid << 8 | ring->cur))))
;
2087
2088 return async ? 0 : tsleep_nsec(cmd, PCATCH0x100, "wpicmd", SEC_TO_NSEC(1));
2089}
2090
2091/*
2092 * Configure HW multi-rate retries.
2093 */
2094int
2095wpi_mrr_setup(struct wpi_softc *sc)
2096{
2097 struct ieee80211com *ic = &sc->sc_ic;
2098 struct wpi_mrr_setup mrr;
2099 int i, error;
2100
2101 /* CCK rates (not used with 802.11a). */
2102 for (i = WPI_RIDX_CCK18; i <= WPI_RIDX_CCK1111; i++) {
2103 mrr.rates[i].flags = 0;
2104 mrr.rates[i].plcp = wpi_rates[i].plcp;
2105 /* Fallback to the immediate lower CCK rate (if any.) */
2106 mrr.rates[i].next =
2107 (i == WPI_RIDX_CCK18) ? WPI_RIDX_CCK18 : i - 1;
2108 /* Try one time at this rate before falling back to "next". */
2109 mrr.rates[i].ntries = 1;
2110 }
2111 /* OFDM rates (not used with 802.11b). */
2112 for (i = WPI_RIDX_OFDM60; i <= WPI_RIDX_OFDM547; i++) {
2113 mrr.rates[i].flags = 0;
2114 mrr.rates[i].plcp = wpi_rates[i].plcp;
2115 /* Fallback to the immediate lower rate (if any.) */
2116 /* We allow fallback from OFDM/6 to CCK/2 in 11b/g mode. */
2117 mrr.rates[i].next = (i == WPI_RIDX_OFDM60) ?
2118 ((ic->ic_curmode == IEEE80211_MODE_11A) ?
2119 WPI_RIDX_OFDM60 : WPI_RIDX_CCK29) :
2120 i - 1;
2121 /* Try one time at this rate before falling back to "next". */
2122 mrr.rates[i].ntries = 1;
2123 }
2124 /* Setup MRR for control frames. */
2125 mrr.which = htole32(WPI_MRR_CTL)((__uint32_t)(0));
2126 error = wpi_cmd(sc, WPI_CMD_MRR_SETUP71, &mrr, sizeof mrr, 0);
2127 if (error != 0) {
2128 printf("%s: could not setup MRR for control frames\n",
2129 sc->sc_dev.dv_xname);
2130 return error;
2131 }
2132 /* Setup MRR for data frames. */
2133 mrr.which = htole32(WPI_MRR_DATA)((__uint32_t)(1));
2134 error = wpi_cmd(sc, WPI_CMD_MRR_SETUP71, &mrr, sizeof mrr, 0);
2135 if (error != 0) {
2136 printf("%s: could not setup MRR for data frames\n",
2137 sc->sc_dev.dv_xname);
2138 return error;
2139 }
2140 return 0;
2141}
2142
2143void
2144wpi_updateedca(struct ieee80211com *ic)
2145{
2146#define WPI_EXP2(x) ((1 << (x)) - 1) /* CWmin = 2^ECWmin - 1 */
2147 struct wpi_softc *sc = ic->ic_softcic_ac.ac_if.if_softc;
2148 struct wpi_edca_params cmd;
2149 int aci;
2150
2151 memset(&cmd, 0, sizeof cmd)__builtin_memset((&cmd), (0), (sizeof cmd));
2152 cmd.flags = htole32(WPI_EDCA_UPDATE)((__uint32_t)((1 << 0)));
2153 for (aci = 0; aci < EDCA_NUM_AC4; aci++) {
2154 const struct ieee80211_edca_ac_params *ac =
2155 &ic->ic_edca_ac[aci];
2156 cmd.ac[aci].aifsn = ac->ac_aifsn;
2157 cmd.ac[aci].cwmin = htole16(WPI_EXP2(ac->ac_ecwmin))((__uint16_t)(WPI_EXP2(ac->ac_ecwmin)));
2158 cmd.ac[aci].cwmax = htole16(WPI_EXP2(ac->ac_ecwmax))((__uint16_t)(WPI_EXP2(ac->ac_ecwmax)));
2159 cmd.ac[aci].txoplimit =
2160 htole16(IEEE80211_TXOP_TO_US(ac->ac_txoplimit))((__uint16_t)(((ac->ac_txoplimit) * 32)));
2161 }
2162 (void)wpi_cmd(sc, WPI_CMD_EDCA_PARAMS19, &cmd, sizeof cmd, 1);
2163#undef WPI_EXP2
2164}
2165
2166void
2167wpi_set_led(struct wpi_softc *sc, uint8_t which, uint8_t off, uint8_t on)
2168{
2169 struct wpi_cmd_led led;
2170
2171 led.which = which;
2172 led.unit = htole32(100000)((__uint32_t)(100000)); /* on/off in unit of 100ms */
2173 led.off = off;
2174 led.on = on;
2175 (void)wpi_cmd(sc, WPI_CMD_SET_LED72, &led, sizeof led, 1);
2176}
2177
2178int
2179wpi_set_timing(struct wpi_softc *sc, struct ieee80211_node *ni)
2180{
2181 struct wpi_cmd_timing cmd;
2182 uint64_t val, mod;
2183
2184 memset(&cmd, 0, sizeof cmd)__builtin_memset((&cmd), (0), (sizeof cmd));
2185 memcpy(&cmd.tstamp, ni->ni_tstamp, sizeof (uint64_t))__builtin_memcpy((&cmd.tstamp), (ni->ni_tstamp), (sizeof
(uint64_t)))
;
2186 cmd.bintval = htole16(ni->ni_intval)((__uint16_t)(ni->ni_intval));
2187 cmd.lintval = htole16(10)((__uint16_t)(10));
2188
2189 /* Compute remaining time until next beacon. */
2190 val = (uint64_t)ni->ni_intval * 1024; /* msecs -> usecs */
2191 mod = letoh64(cmd.tstamp)((__uint64_t)(cmd.tstamp)) % val;
2192 cmd.binitval = htole32((uint32_t)(val - mod))((__uint32_t)((uint32_t)(val - mod)));
2193
2194 DPRINTF(("timing bintval=%u, tstamp=%llu, init=%u\n",
2195 ni->ni_intval, letoh64(cmd.tstamp), (uint32_t)(val - mod)));
2196
2197 return wpi_cmd(sc, WPI_CMD_TIMING20, &cmd, sizeof cmd, 1);
2198}
2199
2200/*
2201 * This function is called periodically (every minute) to adjust TX power
2202 * based on temperature variation.
2203 */
2204void
2205wpi_power_calibration(struct wpi_softc *sc)
2206{
2207 int temp;
2208
2209 temp = (int)WPI_READ(sc, WPI_UCODE_GP2)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x060))));
2210 /* Sanity-check temperature. */
2211 if (temp < -260 || temp > 25) {
2212 /* This can't be correct, ignore. */
2213 DPRINTF(("out-of-range temperature reported: %d\n", temp));
2214 return;
2215 }
2216 DPRINTF(("temperature %d->%d\n", sc->temp, temp));
2217 /* Adjust TX power if need be (delta > 6). */
2218 if (abs(temp - sc->temp) > 6) {
2219 /* Record temperature of last calibration. */
2220 sc->temp = temp;
2221 (void)wpi_set_txpower(sc, 1);
2222 }
2223}
2224
2225/*
2226 * Set TX power for current channel (each rate has its own power settings).
2227 */
2228int
2229wpi_set_txpower(struct wpi_softc *sc, int async)
2230{
2231 struct ieee80211com *ic = &sc->sc_ic;
2232 struct ieee80211_channel *ch;
2233 struct wpi_power_group *group;
2234 struct wpi_cmd_txpower cmd;
2235 u_int chan;
2236 int idx, i;
2237
2238 /* Retrieve current channel from last RXON. */
2239 chan = sc->rxon.chan;
2240 DPRINTF(("setting TX power for channel %d\n", chan));
2241 ch = &ic->ic_channels[chan];
2242
2243 /* Find the TX power group to which this channel belongs. */
2244 if (IEEE80211_IS_CHAN_5GHZ(ch)(((ch)->ic_flags & 0x0100) != 0)) {
2245 for (group = &sc->groups[1]; group < &sc->groups[4]; group++)
2246 if (chan <= group->chan)
2247 break;
2248 } else
2249 group = &sc->groups[0];
2250
2251 memset(&cmd, 0, sizeof cmd)__builtin_memset((&cmd), (0), (sizeof cmd));
2252 cmd.band = IEEE80211_IS_CHAN_5GHZ(ch)(((ch)->ic_flags & 0x0100) != 0) ? 0 : 1;
2253 cmd.chan = htole16(chan)((__uint16_t)(chan));
2254
2255 /* Set TX power for all OFDM and CCK rates. */
2256 for (i = 0; i <= WPI_RIDX_MAX11 ; i++) {
2257 /* Retrieve TX power for this channel/rate. */
2258 idx = wpi_get_power_index(sc, group, ch, i);
2259
2260 cmd.rates[i].plcp = wpi_rates[i].plcp;
2261
2262 if (IEEE80211_IS_CHAN_5GHZ(ch)(((ch)->ic_flags & 0x0100) != 0)) {
2263 cmd.rates[i].rf_gain = wpi_rf_gain_5ghz[idx];
2264 cmd.rates[i].dsp_gain = wpi_dsp_gain_5ghz[idx];
2265 } else {
2266 cmd.rates[i].rf_gain = wpi_rf_gain_2ghz[idx];
2267 cmd.rates[i].dsp_gain = wpi_dsp_gain_2ghz[idx];
2268 }
2269 DPRINTF(("chan %d/rate %d: power index %d\n", chan,
2270 wpi_rates[i].rate, idx));
2271 }
2272 return wpi_cmd(sc, WPI_CMD_TXPOWER151, &cmd, sizeof cmd, async);
2273}
2274
2275/*
2276 * Determine TX power index for a given channel/rate combination.
2277 * This takes into account the regulatory information from EEPROM and the
2278 * current temperature.
2279 */
2280int
2281wpi_get_power_index(struct wpi_softc *sc, struct wpi_power_group *group,
2282 struct ieee80211_channel *c, int ridx)
2283{
2284/* Fixed-point arithmetic division using a n-bit fractional part. */
2285#define fdivround(a, b, n) \
2286 ((((1 << n) * (a)) / (b) + (1 << n) / 2) / (1 << n))
2287
2288/* Linear interpolation. */
2289#define interpolate(x, x1, y1, x2, y2, n) \
2290 ((y1) + fdivround(((x) - (x1)) * ((y2) - (y1)), (x2) - (x1), n))
2291
2292 struct ieee80211com *ic = &sc->sc_ic;
2293 struct wpi_power_sample *sample;
2294 int pwr, idx;
2295 u_int chan;
2296
2297 /* Get channel number. */
2298 chan = ieee80211_chan2ieee(ic, c);
2299
2300 /* Default TX power is group maximum TX power minus 3dB. */
2301 pwr = group->maxpwr / 2;
2302
2303 /* Decrease TX power for highest OFDM rates to reduce distortion. */
2304 switch (ridx) {
2305 case WPI_RIDX_OFDM365:
2306 pwr -= IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0) ? 0 : 5;
2307 break;
2308 case WPI_RIDX_OFDM486:
2309 pwr -= IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0) ? 7 : 10;
2310 break;
2311 case WPI_RIDX_OFDM547:
2312 pwr -= IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0) ? 9 : 12;
2313 break;
2314 }
2315
2316 /* Never exceed the channel maximum allowed TX power. */
2317 pwr = MIN(pwr, sc->maxpwr[chan])(((pwr)<(sc->maxpwr[chan]))?(pwr):(sc->maxpwr[chan])
)
;
2318
2319 /* Retrieve TX power index into gain tables from samples. */
2320 for (sample = group->samples; sample < &group->samples[3]; sample++)
2321 if (pwr > sample[1].power)
2322 break;
2323 /* Fixed-point linear interpolation using a 19-bit fractional part. */
2324 idx = interpolate(pwr, sample[0].power, sample[0].index,
2325 sample[1].power, sample[1].index, 19);
2326
2327 /*-
2328 * Adjust power index based on current temperature:
2329 * - if cooler than factory-calibrated: decrease output power
2330 * - if warmer than factory-calibrated: increase output power
2331 */
2332 idx -= (sc->temp - group->temp) * 11 / 100;
2333
2334 /* Decrease TX power for CCK rates (-5dB). */
2335 if (ridx >= WPI_RIDX_CCK18)
2336 idx += 10;
2337
2338 /* Make sure idx stays in a valid range. */
2339 if (idx < 0)
2340 idx = 0;
2341 else if (idx > WPI_MAX_PWR_INDEX77)
2342 idx = WPI_MAX_PWR_INDEX77;
2343 return idx;
2344
2345#undef interpolate
2346#undef fdivround
2347}
2348
2349/*
2350 * Set STA mode power saving level (between 0 and 5).
2351 * Level 0 is CAM (Continuously Aware Mode), 5 is for maximum power saving.
2352 */
2353int
2354wpi_set_pslevel(struct wpi_softc *sc, int dtim, int level, int async)
2355{
2356 struct wpi_pmgt_cmd cmd;
2357 const struct wpi_pmgt *pmgt;
2358 uint32_t max, skip_dtim;
2359 pcireg_t reg;
2360 int i;
2361
2362 /* Select which PS parameters to use. */
2363 if (dtim <= 10)
2364 pmgt = &wpi_pmgt[0][level];
2365 else
2366 pmgt = &wpi_pmgt[1][level];
2367
2368 memset(&cmd, 0, sizeof cmd)__builtin_memset((&cmd), (0), (sizeof cmd));
2369 if (level != 0) /* not CAM */
2370 cmd.flags |= htole16(WPI_PS_ALLOW_SLEEP)((__uint16_t)((1 << 0)));
2371 /* Retrieve PCIe Active State Power Management (ASPM). */
2372 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag,
2373 sc->sc_cap_off + PCI_PCIE_LCSR0x10);
2374 if (!(reg & PCI_PCIE_LCSR_ASPM_L0S0x00000001)) /* L0s Entry disabled. */
2375 cmd.flags |= htole16(WPI_PS_PCI_PMGT)((__uint16_t)((1 << 3)));
2376 cmd.rxtimeout = htole32(pmgt->rxtimeout * 1024)((__uint32_t)(pmgt->rxtimeout * 1024));
2377 cmd.txtimeout = htole32(pmgt->txtimeout * 1024)((__uint32_t)(pmgt->txtimeout * 1024));
2378
2379 if (dtim == 0) {
2380 dtim = 1;
2381 skip_dtim = 0;
2382 } else
2383 skip_dtim = pmgt->skip_dtim;
2384 if (skip_dtim != 0) {
2385 cmd.flags |= htole16(WPI_PS_SLEEP_OVER_DTIM)((__uint16_t)((1 << 2)));
2386 max = pmgt->intval[4];
2387 if (max == (uint32_t)-1)
2388 max = dtim * (skip_dtim + 1);
2389 else if (max > dtim)
2390 max = (max / dtim) * dtim;
2391 } else
2392 max = dtim;
2393 for (i = 0; i < 5; i++)
2394 cmd.intval[i] = htole32(MIN(max, pmgt->intval[i]))((__uint32_t)((((max)<(pmgt->intval[i]))?(max):(pmgt->
intval[i]))))
;
2395
2396 DPRINTF(("setting power saving level to %d\n", level));
2397 return wpi_cmd(sc, WPI_CMD_SET_POWER_MODE119, &cmd, sizeof cmd, async);
2398}
2399
2400int
2401wpi_config(struct wpi_softc *sc)
2402{
2403 struct ieee80211com *ic = &sc->sc_ic;
2404 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
2405 struct wpi_bluetooth bluetooth;
2406 struct wpi_node_info node;
2407 int error;
2408
2409 /* Set power saving level to CAM during initialization. */
2410 if ((error = wpi_set_pslevel(sc, 0, 0, 0)) != 0) {
2411 printf("%s: could not set power saving level\n",
2412 sc->sc_dev.dv_xname);
2413 return error;
2414 }
2415
2416 /* Configure bluetooth coexistence. */
2417 memset(&bluetooth, 0, sizeof bluetooth)__builtin_memset((&bluetooth), (0), (sizeof bluetooth));
2418 bluetooth.flags = WPI_BT_COEX_MODE_4WIRE3;
2419 bluetooth.lead_time = WPI_BT_LEAD_TIME_DEF30;
2420 bluetooth.max_kill = WPI_BT_MAX_KILL_DEF5;
2421 error = wpi_cmd(sc, WPI_CMD_BT_COEX155, &bluetooth, sizeof bluetooth, 0);
2422 if (error != 0) {
2423 printf("%s: could not configure bluetooth coexistence\n",
2424 sc->sc_dev.dv_xname);
2425 return error;
2426 }
2427
2428 /* Configure adapter. */
2429 memset(&sc->rxon, 0, sizeof (struct wpi_rxon))__builtin_memset((&sc->rxon), (0), (sizeof (struct wpi_rxon
)))
;
2430 IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl))__builtin_memcpy((ic->ic_myaddr), (((caddr_t)((ifp->if_sadl
)->sdl_data + (ifp->if_sadl)->sdl_nlen))), (6))
;
2431 IEEE80211_ADDR_COPY(sc->rxon.myaddr, ic->ic_myaddr)__builtin_memcpy((sc->rxon.myaddr), (ic->ic_myaddr), (6
))
;
2432 /* Set default channel. */
2433 sc->rxon.chan = ieee80211_chan2ieee(ic, ic->ic_ibss_chan);
2434 sc->rxon.flags = htole32(WPI_RXON_TSF)((__uint32_t)((1 << 15)));
2435 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_ibss_chan)(((ic->ic_ibss_chan)->ic_flags & 0x0080) != 0))
2436 sc->rxon.flags |= htole32(WPI_RXON_AUTO | WPI_RXON_24GHZ)((__uint32_t)((1 << 2) | (1 << 0)));
2437 switch (ic->ic_opmode) {
2438 case IEEE80211_M_STA:
2439 sc->rxon.mode = WPI_MODE_STA3;
2440 sc->rxon.filter = htole32(WPI_FILTER_MULTICAST)((__uint32_t)((1 << 2)));
2441 break;
2442 case IEEE80211_M_MONITOR:
2443 sc->rxon.mode = WPI_MODE_MONITOR6;
2444 sc->rxon.filter = htole32(WPI_FILTER_MULTICAST |((__uint32_t)((1 << 2) | (1 << 1) | (1 << 0
)))
2445 WPI_FILTER_CTL | WPI_FILTER_PROMISC)((__uint32_t)((1 << 2) | (1 << 1) | (1 << 0
)))
;
2446 break;
2447 default:
2448 /* Should not get there. */
2449 break;
2450 }
2451 sc->rxon.cck_mask = 0x0f; /* not yet negotiated */
2452 sc->rxon.ofdm_mask = 0xff; /* not yet negotiated */
2453 DPRINTF(("setting configuration\n"));
2454 error = wpi_cmd(sc, WPI_CMD_RXON16, &sc->rxon, sizeof (struct wpi_rxon),
2455 0);
2456 if (error != 0) {
2457 printf("%s: RXON command failed\n", sc->sc_dev.dv_xname);
2458 return error;
2459 }
2460
2461 /* Configuration has changed, set TX power accordingly. */
2462 if ((error = wpi_set_txpower(sc, 0)) != 0) {
2463 printf("%s: could not set TX power\n", sc->sc_dev.dv_xname);
2464 return error;
2465 }
2466
2467 /* Add broadcast node. */
2468 memset(&node, 0, sizeof node)__builtin_memset((&node), (0), (sizeof node));
2469 IEEE80211_ADDR_COPY(node.macaddr, etherbroadcastaddr)__builtin_memcpy((node.macaddr), (etherbroadcastaddr), (6));
2470 node.id = WPI_ID_BROADCAST24;
2471 node.plcp = wpi_rates[WPI_RIDX_CCK18].plcp;
2472 node.action = htole32(WPI_ACTION_SET_RATE)((__uint32_t)((1 << 2)));
2473 node.antenna = WPI_ANTENNA_BOTH((1 << 6) | (1 << 7));
2474 error = wpi_cmd(sc, WPI_CMD_ADD_NODE24, &node, sizeof node, 0);
2475 if (error != 0) {
2476 printf("%s: could not add broadcast node\n",
2477 sc->sc_dev.dv_xname);
2478 return error;
2479 }
2480
2481 if ((error = wpi_mrr_setup(sc)) != 0) {
2482 printf("%s: could not setup MRR\n", sc->sc_dev.dv_xname);
2483 return error;
2484 }
2485 return 0;
2486}
2487
2488int
2489wpi_scan(struct wpi_softc *sc, uint16_t flags)
2490{
2491 struct ieee80211com *ic = &sc->sc_ic;
2492 struct wpi_scan_hdr *hdr;
2493 struct wpi_cmd_data *tx;
2494 struct wpi_scan_essid *essid;
2495 struct wpi_scan_chan *chan;
2496 struct ieee80211_frame *wh;
2497 struct ieee80211_rateset *rs;
2498 struct ieee80211_channel *c;
2499 uint8_t *buf, *frm;
2500 int buflen, error;
2501
2502 buf = malloc(WPI_SCAN_MAXSZ((1 << 11) - 4), M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008);
2503 if (buf == NULL((void *)0)) {
2504 printf("%s: could not allocate buffer for scan command\n",
2505 sc->sc_dev.dv_xname);
2506 return ENOMEM12;
2507 }
2508 hdr = (struct wpi_scan_hdr *)buf;
2509 /*
2510 * Move to the next channel if no frames are received within 10ms
2511 * after sending the probe request.
2512 */
2513 hdr->quiet_time = htole16(10)((__uint16_t)(10)); /* timeout in milliseconds */
2514 hdr->quiet_threshold = htole16(1)((__uint16_t)(1)); /* min # of packets */
2515
2516 tx = (struct wpi_cmd_data *)(hdr + 1);
2517 tx->flags = htole32(WPI_TX_AUTO_SEQ)((__uint32_t)((1 << 13)));
2518 tx->id = WPI_ID_BROADCAST24;
2519 tx->lifetime = htole32(WPI_LIFETIME_INFINITE)((__uint32_t)(0xffffffff));
2520
2521 if (flags & IEEE80211_CHAN_5GHZ0x0100) {
2522 hdr->crc_threshold = htole16(1)((__uint16_t)(1));
2523 /* Send probe requests at 6Mbps. */
2524 tx->plcp = wpi_rates[WPI_RIDX_OFDM60].plcp;
2525 rs = &ic->ic_sup_rates[IEEE80211_MODE_11A];
2526 } else {
2527 hdr->flags = htole32(WPI_RXON_24GHZ | WPI_RXON_AUTO)((__uint32_t)((1 << 0) | (1 << 2)));
2528 /* Send probe requests at 1Mbps. */
2529 tx->plcp = wpi_rates[WPI_RIDX_CCK18].plcp;
2530 rs = &ic->ic_sup_rates[IEEE80211_MODE_11G];
2531 }
2532
2533 essid = (struct wpi_scan_essid *)(tx + 1);
2534 if (ic->ic_des_esslen != 0) {
2535 essid[0].id = IEEE80211_ELEMID_SSID;
2536 essid[0].len = ic->ic_des_esslen;
2537 memcpy(essid[0].data, ic->ic_des_essid, ic->ic_des_esslen)__builtin_memcpy((essid[0].data), (ic->ic_des_essid), (ic->
ic_des_esslen))
;
2538 }
2539 /*
2540 * Build a probe request frame. Most of the following code is a
2541 * copy & paste of what is done in net80211.
2542 */
2543 wh = (struct ieee80211_frame *)(essid + 4);
2544 wh->i_fc[0] = IEEE80211_FC0_VERSION_00x00 | IEEE80211_FC0_TYPE_MGT0x00 |
2545 IEEE80211_FC0_SUBTYPE_PROBE_REQ0x40;
2546 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS0x00;
2547 IEEE80211_ADDR_COPY(wh->i_addr1, etherbroadcastaddr)__builtin_memcpy((wh->i_addr1), (etherbroadcastaddr), (6));
2548 IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_myaddr)__builtin_memcpy((wh->i_addr2), (ic->ic_myaddr), (6));
2549 IEEE80211_ADDR_COPY(wh->i_addr3, etherbroadcastaddr)__builtin_memcpy((wh->i_addr3), (etherbroadcastaddr), (6));
2550 *(uint16_t *)&wh->i_dur[0] = 0; /* filled by HW */
2551 *(uint16_t *)&wh->i_seq[0] = 0; /* filled by HW */
2552
2553 frm = (uint8_t *)(wh + 1);
2554 frm = ieee80211_add_ssid(frm, NULL((void *)0), 0);
2555 frm = ieee80211_add_rates(frm, rs);
2556 if (rs->rs_nrates > IEEE80211_RATE_SIZE8)
2557 frm = ieee80211_add_xrates(frm, rs);
2558
2559 /* Set length of probe request. */
2560 tx->len = htole16(frm - (uint8_t *)wh)((__uint16_t)(frm - (uint8_t *)wh));
2561
2562 chan = (struct wpi_scan_chan *)frm;
2563 for (c = &ic->ic_channels[1];
2564 c <= &ic->ic_channels[IEEE80211_CHAN_MAX255]; c++) {
2565 if ((c->ic_flags & flags) != flags)
2566 continue;
2567
2568 chan->chan = ieee80211_chan2ieee(ic, c);
2569 DPRINTFN(2, ("adding channel %d\n", chan->chan));
2570 chan->flags = 0;
2571 if (!(c->ic_flags & IEEE80211_CHAN_PASSIVE0x0200))
2572 chan->flags |= WPI_CHAN_ACTIVE(1 << 0);
2573 if (ic->ic_des_esslen != 0)
2574 chan->flags |= WPI_CHAN_NPBREQS(1)(((1 << (1)) - 1) << 1);
2575 chan->dsp_gain = 0x6e;
2576 if (IEEE80211_IS_CHAN_5GHZ(c)(((c)->ic_flags & 0x0100) != 0)) {
2577 chan->rf_gain = 0x3b;
2578 chan->active = htole16(24)((__uint16_t)(24));
2579 chan->passive = htole16(110)((__uint16_t)(110));
2580 } else {
2581 chan->rf_gain = 0x28;
2582 chan->active = htole16(36)((__uint16_t)(36));
2583 chan->passive = htole16(120)((__uint16_t)(120));
2584 }
2585 hdr->nchan++;
2586 chan++;
2587 }
2588
2589 buflen = (uint8_t *)chan - buf;
2590 hdr->len = htole16(buflen)((__uint16_t)(buflen));
2591
2592 DPRINTF(("sending scan command nchan=%d\n", hdr->nchan));
2593 error = wpi_cmd(sc, WPI_CMD_SCAN128, buf, buflen, 1);
2594 free(buf, M_DEVBUF2, WPI_SCAN_MAXSZ((1 << 11) - 4));
2595 return error;
2596}
2597
2598int
2599wpi_auth(struct wpi_softc *sc)
2600{
2601 struct ieee80211com *ic = &sc->sc_ic;
2602 struct ieee80211_node *ni = ic->ic_bss;
2603 struct wpi_node_info node;
2604 int error;
2605
2606 /* Update adapter configuration. */
2607 IEEE80211_ADDR_COPY(sc->rxon.bssid, ni->ni_bssid)__builtin_memcpy((sc->rxon.bssid), (ni->ni_bssid), (6));
2608 sc->rxon.chan = ieee80211_chan2ieee(ic, ni->ni_chan);
2609 sc->rxon.flags = htole32(WPI_RXON_TSF)((__uint32_t)((1 << 15)));
2610 if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)(((ni->ni_chan)->ic_flags & 0x0080) != 0))
2611 sc->rxon.flags |= htole32(WPI_RXON_AUTO | WPI_RXON_24GHZ)((__uint32_t)((1 << 2) | (1 << 0)));
2612 if (ic->ic_flags & IEEE80211_F_SHSLOT0x00020000)
2613 sc->rxon.flags |= htole32(WPI_RXON_SHSLOT)((__uint32_t)((1 << 4)));
2614 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE0x00040000)
2615 sc->rxon.flags |= htole32(WPI_RXON_SHPREAMBLE)((__uint32_t)((1 << 5)));
2616 switch (ic->ic_curmode) {
2617 case IEEE80211_MODE_11A:
2618 sc->rxon.cck_mask = 0;
2619 sc->rxon.ofdm_mask = 0x15;
2620 break;
2621 case IEEE80211_MODE_11B:
2622 sc->rxon.cck_mask = 0x03;
2623 sc->rxon.ofdm_mask = 0;
2624 break;
2625 default: /* Assume 802.11b/g. */
2626 sc->rxon.cck_mask = 0x0f;
2627 sc->rxon.ofdm_mask = 0x15;
2628 }
2629 DPRINTF(("rxon chan %d flags %x cck %x ofdm %x\n", sc->rxon.chan,
2630 sc->rxon.flags, sc->rxon.cck_mask, sc->rxon.ofdm_mask));
2631 error = wpi_cmd(sc, WPI_CMD_RXON16, &sc->rxon, sizeof (struct wpi_rxon),
2632 1);
2633 if (error != 0) {
2634 printf("%s: RXON command failed\n", sc->sc_dev.dv_xname);
2635 return error;
2636 }
2637
2638 /* Configuration has changed, set TX power accordingly. */
2639 if ((error = wpi_set_txpower(sc, 1)) != 0) {
2640 printf("%s: could not set TX power\n", sc->sc_dev.dv_xname);
2641 return error;
2642 }
2643 /*
2644 * Reconfiguring RXON clears the firmware nodes table so we must
2645 * add the broadcast node again.
2646 */
2647 memset(&node, 0, sizeof node)__builtin_memset((&node), (0), (sizeof node));
2648 IEEE80211_ADDR_COPY(node.macaddr, etherbroadcastaddr)__builtin_memcpy((node.macaddr), (etherbroadcastaddr), (6));
2649 node.id = WPI_ID_BROADCAST24;
2650 node.plcp = (ic->ic_curmode == IEEE80211_MODE_11A) ?
2651 wpi_rates[WPI_RIDX_OFDM60].plcp : wpi_rates[WPI_RIDX_CCK18].plcp;
2652 node.action = htole32(WPI_ACTION_SET_RATE)((__uint32_t)((1 << 2)));
2653 node.antenna = WPI_ANTENNA_BOTH((1 << 6) | (1 << 7));
2654 error = wpi_cmd(sc, WPI_CMD_ADD_NODE24, &node, sizeof node, 1);
2655 if (error != 0) {
2656 printf("%s: could not add broadcast node\n",
2657 sc->sc_dev.dv_xname);
2658 return error;
2659 }
2660 return 0;
2661}
2662
2663int
2664wpi_run(struct wpi_softc *sc)
2665{
2666 struct ieee80211com *ic = &sc->sc_ic;
2667 struct ieee80211_node *ni = ic->ic_bss;
2668 struct wpi_node_info node;
2669 int error;
2670
2671 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
2672 /* Link LED blinks while monitoring. */
2673 wpi_set_led(sc, WPI_LED_LINK2, 5, 5);
2674 return 0;
2675 }
2676 if ((error = wpi_set_timing(sc, ni)) != 0) {
2677 printf("%s: could not set timing\n", sc->sc_dev.dv_xname);
2678 return error;
2679 }
2680
2681 /* Update adapter configuration. */
2682 sc->rxon.associd = htole16(IEEE80211_AID(ni->ni_associd))((__uint16_t)(((ni->ni_associd) &~ 0xc000)));
2683 /* Short preamble and slot time are negotiated when associating. */
2684 sc->rxon.flags &= ~htole32(WPI_RXON_SHPREAMBLE | WPI_RXON_SHSLOT)((__uint32_t)((1 << 5) | (1 << 4)));
2685 if (ic->ic_flags & IEEE80211_F_SHSLOT0x00020000)
2686 sc->rxon.flags |= htole32(WPI_RXON_SHSLOT)((__uint32_t)((1 << 4)));
2687 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE0x00040000)
2688 sc->rxon.flags |= htole32(WPI_RXON_SHPREAMBLE)((__uint32_t)((1 << 5)));
2689 sc->rxon.filter |= htole32(WPI_FILTER_BSS)((__uint32_t)((1 << 5)));
2690 DPRINTF(("rxon chan %d flags %x\n", sc->rxon.chan, sc->rxon.flags));
2691 error = wpi_cmd(sc, WPI_CMD_RXON16, &sc->rxon, sizeof (struct wpi_rxon),
2692 1);
2693 if (error != 0) {
2694 printf("%s: RXON command failed\n", sc->sc_dev.dv_xname);
2695 return error;
2696 }
2697
2698 /* Configuration has changed, set TX power accordingly. */
2699 if ((error = wpi_set_txpower(sc, 1)) != 0) {
2700 printf("%s: could not set TX power\n", sc->sc_dev.dv_xname);
2701 return error;
2702 }
2703
2704 /* Fake a join to init the TX rate. */
2705 ((struct wpi_node *)ni)->id = WPI_ID_BSS0;
2706 wpi_newassoc(ic, ni, 1);
2707
2708 /* Add BSS node. */
2709 memset(&node, 0, sizeof node)__builtin_memset((&node), (0), (sizeof node));
2710 IEEE80211_ADDR_COPY(node.macaddr, ni->ni_bssid)__builtin_memcpy((node.macaddr), (ni->ni_bssid), (6));
2711 node.id = WPI_ID_BSS0;
2712 node.plcp = (ic->ic_curmode == IEEE80211_MODE_11A) ?
2713 wpi_rates[WPI_RIDX_OFDM60].plcp : wpi_rates[WPI_RIDX_CCK18].plcp;
2714 node.action = htole32(WPI_ACTION_SET_RATE)((__uint32_t)((1 << 2)));
2715 node.antenna = WPI_ANTENNA_BOTH((1 << 6) | (1 << 7));
2716 DPRINTF(("adding BSS node\n"));
2717 error = wpi_cmd(sc, WPI_CMD_ADD_NODE24, &node, sizeof node, 1);
2718 if (error != 0) {
2719 printf("%s: could not add BSS node\n", sc->sc_dev.dv_xname);
2720 return error;
2721 }
2722
2723 /* Start periodic calibration timer. */
2724 sc->calib_cnt = 0;
2725 timeout_add_msec(&sc->calib_to, 500);
2726
2727 /* Link LED always on while associated. */
2728 wpi_set_led(sc, WPI_LED_LINK2, 0, 1);
2729
2730 /* Enable power-saving mode if requested by user. */
2731 if (sc->sc_ic.ic_flags & IEEE80211_F_PMGTON0x00000400)
2732 (void)wpi_set_pslevel(sc, 0, 3, 1);
2733
2734 return 0;
2735}
2736
2737/*
2738 * We support CCMP hardware encryption/decryption of unicast frames only.
2739 * HW support for TKIP really sucks. We should let TKIP die anyway.
2740 */
2741int
2742wpi_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
2743 struct ieee80211_key *k)
2744{
2745 struct wpi_softc *sc = ic->ic_softcic_ac.ac_if.if_softc;
2746 struct wpi_node *wn = (void *)ni;
2747 struct wpi_node_info node;
2748 uint16_t kflags;
2749
2750 if ((k->k_flags & IEEE80211_KEY_GROUP0x00000001) ||
2751 k->k_cipher != IEEE80211_CIPHER_CCMP)
2752 return ieee80211_set_key(ic, ni, k);
2753
2754 kflags = WPI_KFLAG_CCMP(1 << 1) | WPI_KFLAG_KID(k->k_id)((k->k_id) << 8);
2755 memset(&node, 0, sizeof node)__builtin_memset((&node), (0), (sizeof node));
2756 node.id = wn->id;
2757 node.control = WPI_NODE_UPDATE(1 << 0);
2758 node.flags = WPI_FLAG_SET_KEY(1 << 0);
2759 node.kflags = htole16(kflags)((__uint16_t)(kflags));
2760 memcpy(node.key, k->k_key, k->k_len)__builtin_memcpy((node.key), (k->k_key), (k->k_len));
2761 DPRINTF(("set key id=%d for node %d\n", k->k_id, node.id));
2762 return wpi_cmd(sc, WPI_CMD_ADD_NODE24, &node, sizeof node, 1);
2763}
2764
2765void
2766wpi_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
2767 struct ieee80211_key *k)
2768{
2769 struct wpi_softc *sc = ic->ic_softcic_ac.ac_if.if_softc;
2770 struct wpi_node *wn = (void *)ni;
2771 struct wpi_node_info node;
2772
2773 if ((k->k_flags & IEEE80211_KEY_GROUP0x00000001) ||
2774 k->k_cipher != IEEE80211_CIPHER_CCMP) {
2775 /* See comment about other ciphers above. */
2776 ieee80211_delete_key(ic, ni, k);
2777 return;
2778 }
2779 if (ic->ic_state != IEEE80211_S_RUN)
2780 return; /* Nothing to do. */
2781 memset(&node, 0, sizeof node)__builtin_memset((&node), (0), (sizeof node));
2782 node.id = wn->id;
2783 node.control = WPI_NODE_UPDATE(1 << 0);
2784 node.flags = WPI_FLAG_SET_KEY(1 << 0);
2785 node.kflags = 0;
2786 DPRINTF(("delete keys for node %d\n", node.id));
2787 (void)wpi_cmd(sc, WPI_CMD_ADD_NODE24, &node, sizeof node, 1);
2788}
2789
2790int
2791wpi_post_alive(struct wpi_softc *sc)
2792{
2793 int ntries, error;
2794
2795 /* Check (again) that the radio is not disabled. */
2796 if ((error = wpi_nic_lock(sc)) != 0)
2797 return error;
2798 /* NB: Runtime firmware must be up and running. */
2799 if (!(wpi_prph_read(sc, WPI_APMG_RFKILL0x3014) & 1)) {
2800 printf("%s: radio is disabled by hardware switch\n",
2801 sc->sc_dev.dv_xname);
2802 wpi_nic_unlock(sc);
2803 return EPERM1; /* :-) */
2804 }
2805 wpi_nic_unlock(sc);
2806
2807 /* Wait for thermal sensor to calibrate. */
2808 for (ntries = 0; ntries < 1000; ntries++) {
2809 if ((sc->temp = (int)WPI_READ(sc, WPI_UCODE_GP2)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x060))))) != 0)
2810 break;
2811 DELAY(10)(*delay_func)(10);
2812 }
2813 if (ntries == 1000) {
2814 printf("%s: timeout waiting for thermal sensor calibration\n",
2815 sc->sc_dev.dv_xname);
2816 return ETIMEDOUT60;
2817 }
2818 DPRINTF(("temperature %d\n", sc->temp));
2819 return 0;
2820}
2821
2822/*
2823 * The firmware boot code is small and is intended to be copied directly into
2824 * the NIC internal memory (no DMA transfer.)
2825 */
2826int
2827wpi_load_bootcode(struct wpi_softc *sc, const uint8_t *ucode, int size)
2828{
2829 int error, ntries;
2830
2831 size /= sizeof (uint32_t);
2832
2833 if ((error = wpi_nic_lock(sc)) != 0)
2834 return error;
2835
2836 /* Copy microcode image into NIC memory. */
2837 wpi_prph_write_region_4(sc, WPI_BSM_SRAM_BASE0x3800,
2838 (const uint32_t *)ucode, size);
2839
2840 wpi_prph_write(sc, WPI_BSM_WR_MEM_SRC0x3404, 0);
2841 wpi_prph_write(sc, WPI_BSM_WR_MEM_DST0x3408, WPI_FW_TEXT_BASE0x00000000);
2842 wpi_prph_write(sc, WPI_BSM_WR_DWCOUNT0x340c, size);
2843
2844 /* Start boot load now. */
2845 wpi_prph_write(sc, WPI_BSM_WR_CTRL0x3400, WPI_BSM_WR_CTRL_START(1U << 31));
2846
2847 /* Wait for transfer to complete. */
2848 for (ntries = 0; ntries < 1000; ntries++) {
2849 if (!(wpi_prph_read(sc, WPI_BSM_WR_CTRL0x3400) &
2850 WPI_BSM_WR_CTRL_START(1U << 31)))
2851 break;
2852 DELAY(10)(*delay_func)(10);
2853 }
2854 if (ntries == 1000) {
2855 printf("%s: could not load boot firmware\n",
2856 sc->sc_dev.dv_xname);
2857 wpi_nic_unlock(sc);
2858 return ETIMEDOUT60;
2859 }
2860
2861 /* Enable boot after power up. */
2862 wpi_prph_write(sc, WPI_BSM_WR_CTRL0x3400, WPI_BSM_WR_CTRL_START_EN(1U << 30));
2863
2864 wpi_nic_unlock(sc);
2865 return 0;
2866}
2867
2868int
2869wpi_load_firmware(struct wpi_softc *sc)
2870{
2871 struct wpi_fw_info *fw = &sc->fw;
2872 struct wpi_dma_info *dma = &sc->fw_dma;
2873 int error;
2874
2875 /* Copy initialization sections into pre-allocated DMA-safe memory. */
2876 memcpy(dma->vaddr, fw->init.data, fw->init.datasz)__builtin_memcpy((dma->vaddr), (fw->init.data), (fw->
init.datasz))
;
2877 bus_dmamap_sync(sc->sc_dmat, dma->map, 0, fw->init.datasz,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma->
map), (0), (fw->init.datasz), (0x04))
2878 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma->
map), (0), (fw->init.datasz), (0x04))
;
2879 memcpy(dma->vaddr + WPI_FW_DATA_MAXSZ,__builtin_memcpy((dma->vaddr + (32 * 1024)), (fw->init.
text), (fw->init.textsz))
2880 fw->init.text, fw->init.textsz)__builtin_memcpy((dma->vaddr + (32 * 1024)), (fw->init.
text), (fw->init.textsz))
;
2881 bus_dmamap_sync(sc->sc_dmat, dma->map, WPI_FW_DATA_MAXSZ,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma->
map), ((32 * 1024)), (fw->init.textsz), (0x04))
2882 fw->init.textsz, BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma->
map), ((32 * 1024)), (fw->init.textsz), (0x04))
;
2883
2884 /* Tell adapter where to find initialization sections. */
2885 if ((error = wpi_nic_lock(sc)) != 0)
2886 return error;
2887 wpi_prph_write(sc, WPI_BSM_DRAM_DATA_ADDR0x3498, dma->paddr);
2888 wpi_prph_write(sc, WPI_BSM_DRAM_DATA_SIZE0x349c, fw->init.datasz);
2889 wpi_prph_write(sc, WPI_BSM_DRAM_TEXT_ADDR0x3490,
2890 dma->paddr + WPI_FW_DATA_MAXSZ(32 * 1024));
2891 wpi_prph_write(sc, WPI_BSM_DRAM_TEXT_SIZE0x3494, fw->init.textsz);
2892 wpi_nic_unlock(sc);
2893
2894 /* Load firmware boot code. */
2895 error = wpi_load_bootcode(sc, fw->boot.text, fw->boot.textsz);
2896 if (error != 0) {
2897 printf("%s: could not load boot firmware\n",
2898 sc->sc_dev.dv_xname);
2899 return error;
2900 }
2901 /* Now press "execute". */
2902 WPI_WRITE(sc, WPI_RESET, 0)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x020)), ((
0))))
;
2903
2904 /* Wait at most one second for first alive notification. */
2905 if ((error = tsleep_nsec(sc, PCATCH0x100, "wpiinit", SEC_TO_NSEC(1))) != 0) {
2906 printf("%s: timeout waiting for adapter to initialize\n",
2907 sc->sc_dev.dv_xname);
2908 return error;
2909 }
2910
2911 /* Copy runtime sections into pre-allocated DMA-safe memory. */
2912 memcpy(dma->vaddr, fw->main.data, fw->main.datasz)__builtin_memcpy((dma->vaddr), (fw->main.data), (fw->
main.datasz))
;
2913 bus_dmamap_sync(sc->sc_dmat, dma->map, 0, fw->main.datasz,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma->
map), (0), (fw->main.datasz), (0x04))
2914 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma->
map), (0), (fw->main.datasz), (0x04))
;
2915 memcpy(dma->vaddr + WPI_FW_DATA_MAXSZ,__builtin_memcpy((dma->vaddr + (32 * 1024)), (fw->main.
text), (fw->main.textsz))
2916 fw->main.text, fw->main.textsz)__builtin_memcpy((dma->vaddr + (32 * 1024)), (fw->main.
text), (fw->main.textsz))
;
2917 bus_dmamap_sync(sc->sc_dmat, dma->map, WPI_FW_DATA_MAXSZ,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma->
map), ((32 * 1024)), (fw->main.textsz), (0x04))
2918 fw->main.textsz, BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma->
map), ((32 * 1024)), (fw->main.textsz), (0x04))
;
2919
2920 /* Tell adapter where to find runtime sections. */
2921 if ((error = wpi_nic_lock(sc)) != 0)
2922 return error;
2923 wpi_prph_write(sc, WPI_BSM_DRAM_DATA_ADDR0x3498, dma->paddr);
2924 wpi_prph_write(sc, WPI_BSM_DRAM_DATA_SIZE0x349c, fw->main.datasz);
2925 wpi_prph_write(sc, WPI_BSM_DRAM_TEXT_ADDR0x3490,
2926 dma->paddr + WPI_FW_DATA_MAXSZ(32 * 1024));
2927 wpi_prph_write(sc, WPI_BSM_DRAM_TEXT_SIZE0x3494,
2928 WPI_FW_UPDATED(1U << 31) | fw->main.textsz);
2929 wpi_nic_unlock(sc);
2930
2931 return 0;
2932}
2933
2934int
2935wpi_read_firmware(struct wpi_softc *sc)
2936{
2937 struct wpi_fw_info *fw = &sc->fw;
2938 const struct wpi_firmware_hdr *hdr;
2939 int error;
2940
2941 /* Read firmware image from filesystem. */
2942 if ((error = loadfirmware("wpi-3945abg", &fw->data, &fw->datalen)) != 0) {
2943 printf("%s: error, %d, could not read firmware %s\n",
2944 sc->sc_dev.dv_xname, error, "wpi-3945abg");
2945 return error;
2946 }
2947 if (fw->datalen < sizeof (*hdr)) {
2948 printf("%s: truncated firmware header: %zu bytes\n",
2949 sc->sc_dev.dv_xname, fw->datalen);
2950 free(fw->data, M_DEVBUF2, fw->datalen);
2951 return EINVAL22;
2952 }
2953 /* Extract firmware header information. */
2954 hdr = (struct wpi_firmware_hdr *)fw->data;
2955 fw->main.textsz = letoh32(hdr->main_textsz)((__uint32_t)(hdr->main_textsz));
2956 fw->main.datasz = letoh32(hdr->main_datasz)((__uint32_t)(hdr->main_datasz));
2957 fw->init.textsz = letoh32(hdr->init_textsz)((__uint32_t)(hdr->init_textsz));
2958 fw->init.datasz = letoh32(hdr->init_datasz)((__uint32_t)(hdr->init_datasz));
2959 fw->boot.textsz = letoh32(hdr->boot_textsz)((__uint32_t)(hdr->boot_textsz));
2960 fw->boot.datasz = 0;
2961
2962 /* Sanity-check firmware header. */
2963 if (fw->main.textsz > WPI_FW_TEXT_MAXSZ(80 * 1024) ||
2964 fw->main.datasz > WPI_FW_DATA_MAXSZ(32 * 1024) ||
2965 fw->init.textsz > WPI_FW_TEXT_MAXSZ(80 * 1024) ||
2966 fw->init.datasz > WPI_FW_DATA_MAXSZ(32 * 1024) ||
2967 fw->boot.textsz > WPI_FW_BOOT_TEXT_MAXSZ1024 ||
2968 (fw->boot.textsz & 3) != 0) {
2969 printf("%s: invalid firmware header\n", sc->sc_dev.dv_xname);
2970 free(fw->data, M_DEVBUF2, fw->datalen);
2971 return EINVAL22;
2972 }
2973
2974 /* Check that all firmware sections fit. */
2975 if (fw->datalen < sizeof (*hdr) + fw->main.textsz + fw->main.datasz +
2976 fw->init.textsz + fw->init.datasz + fw->boot.textsz) {
2977 printf("%s: firmware file too short: %zu bytes\n",
2978 sc->sc_dev.dv_xname, fw->datalen);
2979 free(fw->data, M_DEVBUF2, fw->datalen);
2980 return EINVAL22;
2981 }
2982
2983 /* Get pointers to firmware sections. */
2984 fw->main.text = (const uint8_t *)(hdr + 1);
2985 fw->main.data = fw->main.text + fw->main.textsz;
2986 fw->init.text = fw->main.data + fw->main.datasz;
2987 fw->init.data = fw->init.text + fw->init.textsz;
2988 fw->boot.text = fw->init.data + fw->init.datasz;
2989
2990 return 0;
2991}
2992
2993int
2994wpi_clock_wait(struct wpi_softc *sc)
2995{
2996 int ntries;
2997
2998 /* Set "initialization complete" bit. */
2999 WPI_SETBITS(sc, WPI_GP_CNTRL, WPI_GP_CNTRL_INIT_DONE)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x024)), ((
(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x024)))) | (
(1 << 2))))))
;
3000
3001 /* Wait for clock stabilization. */
3002 for (ntries = 0; ntries < 25000; ntries++) {
3003 if (WPI_READ(sc, WPI_GP_CNTRL)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x024)))) & WPI_GP_CNTRL_MAC_CLOCK_READY(1 << 0))
3004 return 0;
3005 DELAY(100)(*delay_func)(100);
3006 }
3007 printf("%s: timeout waiting for clock stabilization\n",
3008 sc->sc_dev.dv_xname);
3009 return ETIMEDOUT60;
3010}
3011
3012int
3013wpi_apm_init(struct wpi_softc *sc)
3014{
3015 int error;
3016
3017 WPI_SETBITS(sc, WPI_ANA_PLL, WPI_ANA_PLL_INIT)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x20c)), ((
(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x20c)))) | (
(1 << 24))))))
;
3018 /* Disable L0s. */
3019 WPI_SETBITS(sc, WPI_GIO_CHICKEN, WPI_GIO_CHICKEN_L1A_NO_L0S_RX)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x100)), ((
(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x100)))) | (
(1 << 23))))))
;
3020
3021 if ((error = wpi_clock_wait(sc)) != 0)
3022 return error;
3023
3024 if ((error = wpi_nic_lock(sc)) != 0)
3025 return error;
3026 /* Enable DMA. */
3027 wpi_prph_write(sc, WPI_APMG_CLK_ENA0x3004,
3028 WPI_APMG_CLK_DMA_CLK_RQT(1 << 9) | WPI_APMG_CLK_BSM_CLK_RQT(1 << 11));
3029 DELAY(20)(*delay_func)(20);
3030 /* Disable L1. */
3031 wpi_prph_setbits(sc, WPI_APMG_PCI_STT0x3010, WPI_APMG_PCI_STT_L1A_DIS(1 << 11));
3032 wpi_nic_unlock(sc);
3033
3034 return 0;
3035}
3036
3037void
3038wpi_apm_stop_master(struct wpi_softc *sc)
3039{
3040 int ntries;
3041
3042 WPI_SETBITS(sc, WPI_RESET, WPI_RESET_STOP_MASTER)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x020)), ((
(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x020)))) | (
(1 << 9))))))
;
3043
3044 if ((WPI_READ(sc, WPI_GP_CNTRL)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x024)))) & WPI_GP_CNTRL_PS_MASK(7 << 24)) ==
3045 WPI_GP_CNTRL_MAC_PS(4 << 24))
3046 return; /* Already asleep. */
3047
3048 for (ntries = 0; ntries < 100; ntries++) {
3049 if (WPI_READ(sc, WPI_RESET)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x020)))) & WPI_RESET_MASTER_DISABLED(1 << 8))
3050 return;
3051 DELAY(10)(*delay_func)(10);
3052 }
3053 printf("%s: timeout waiting for master\n", sc->sc_dev.dv_xname);
3054}
3055
3056void
3057wpi_apm_stop(struct wpi_softc *sc)
3058{
3059 wpi_apm_stop_master(sc);
3060 WPI_SETBITS(sc, WPI_RESET, WPI_RESET_SW)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x020)), ((
(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x020)))) | (
(1 << 7))))))
;
3061}
3062
3063void
3064wpi_nic_config(struct wpi_softc *sc)
3065{
3066 pcireg_t reg;
3067 uint8_t rev;
3068
3069 /* Voodoo from the reference driver. */
3070 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_CLASS_REG0x08);
3071 rev = PCI_REVISION(reg)(((reg) >> 0) & 0xff);
3072 if ((rev & 0xc0) == 0x40)
3073 WPI_SETBITS(sc, WPI_HW_IF_CONFIG, WPI_HW_IF_CONFIG_ALM_MB)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x000)), ((
(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x000)))) | (
(1 << 8))))))
;
3074 else if (!(rev & 0x80))
3075 WPI_SETBITS(sc, WPI_HW_IF_CONFIG, WPI_HW_IF_CONFIG_ALM_MM)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x000)), ((
(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x000)))) | (
(1 << 9))))))
;
3076
3077 if (sc->cap == 0x80)
3078 WPI_SETBITS(sc, WPI_HW_IF_CONFIG, WPI_HW_IF_CONFIG_SKU_MRC)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x000)), ((
(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x000)))) | (
(1 << 10))))))
;
3079
3080 if ((letoh16(sc->rev)((__uint16_t)(sc->rev)) & 0xf0) == 0xd0)
3081 WPI_SETBITS(sc, WPI_HW_IF_CONFIG, WPI_HW_IF_CONFIG_REV_D)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x000)), ((
(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x000)))) | (
(1 << 11))))))
;
3082 else
3083 WPI_CLRBITS(sc, WPI_HW_IF_CONFIG, WPI_HW_IF_CONFIG_REV_D)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x000)), ((
(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x000)))) &
~((1 << 11))))))
;
3084
3085 if (sc->type > 1)
3086 WPI_SETBITS(sc, WPI_HW_IF_CONFIG, WPI_HW_IF_CONFIG_TYPE_B)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x000)), ((
(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x000)))) | (
(1 << 12))))))
;
3087}
3088
3089int
3090wpi_hw_init(struct wpi_softc *sc)
3091{
3092 int chnl, ntries, error;
3093
3094 /* Clear pending interrupts. */
3095 WPI_WRITE(sc, WPI_INT, 0xffffffff)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x008)), ((
0xffffffff))))
;
3096
3097 if ((error = wpi_apm_init(sc)) != 0) {
3098 printf("%s: could not power ON adapter\n",
3099 sc->sc_dev.dv_xname);
3100 return error;
3101 }
3102
3103 /* Select VMAIN power source. */
3104 if ((error = wpi_nic_lock(sc)) != 0)
3105 return error;
3106 wpi_prph_clrbits(sc, WPI_APMG_PS0x300c, WPI_APMG_PS_PWR_SRC_MASK(3 << 24));
3107 wpi_nic_unlock(sc);
3108 /* Spin until VMAIN gets selected. */
3109 for (ntries = 0; ntries < 5000; ntries++) {
3110 if (WPI_READ(sc, WPI_GPIO_IN)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x018)))) & WPI_GPIO_IN_VMAIN(1 << 9))
3111 break;
3112 DELAY(10)(*delay_func)(10);
3113 }
3114 if (ntries == 5000) {
3115 printf("%s: timeout selecting power source\n",
3116 sc->sc_dev.dv_xname);
3117 return ETIMEDOUT60;
3118 }
3119
3120 /* Perform adapter initialization. */
3121 (void)wpi_nic_config(sc);
3122
3123 /* Initialize RX ring. */
3124 if ((error = wpi_nic_lock(sc)) != 0)
3125 return error;
3126 /* Set physical address of RX ring. */
3127 WPI_WRITE(sc, WPI_FH_RX_BASE, sc->rxq.desc_dma.paddr)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xc04)), ((
sc->rxq.desc_dma.paddr))))
;
3128 /* Set physical address of RX read pointer. */
3129 WPI_WRITE(sc, WPI_FH_RX_RPTR_ADDR, sc->shared_dma.paddr +(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xc24)), ((
sc->shared_dma.paddr + __builtin_offsetof(struct wpi_shared
, next)))))
3130 offsetof(struct wpi_shared, next))(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xc24)), ((
sc->shared_dma.paddr + __builtin_offsetof(struct wpi_shared
, next)))))
;
3131 WPI_WRITE(sc, WPI_FH_RX_WPTR, 0)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xc20)), ((
0))))
;
3132 /* Enable RX. */
3133 WPI_WRITE(sc, WPI_FH_RX_CONFIG,(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xc00)), ((
(1U << 31) | (1U << 29) | (1U << 27) | (1U <<
24) | ((6) << 20) | (1U << 12) | ((1) << 4
)))))
3134 WPI_FH_RX_CONFIG_DMA_ENA |(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xc00)), ((
(1U << 31) | (1U << 29) | (1U << 27) | (1U <<
24) | ((6) << 20) | (1U << 12) | ((1) << 4
)))))
3135 WPI_FH_RX_CONFIG_RDRBD_ENA |(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xc00)), ((
(1U << 31) | (1U << 29) | (1U << 27) | (1U <<
24) | ((6) << 20) | (1U << 12) | ((1) << 4
)))))
3136 WPI_FH_RX_CONFIG_WRSTATUS_ENA |(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xc00)), ((
(1U << 31) | (1U << 29) | (1U << 27) | (1U <<
24) | ((6) << 20) | (1U << 12) | ((1) << 4
)))))
3137 WPI_FH_RX_CONFIG_MAXFRAG |(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xc00)), ((
(1U << 31) | (1U << 29) | (1U << 27) | (1U <<
24) | ((6) << 20) | (1U << 12) | ((1) << 4
)))))
3138 WPI_FH_RX_CONFIG_NRBD(WPI_RX_RING_COUNT_LOG) |(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xc00)), ((
(1U << 31) | (1U << 29) | (1U << 27) | (1U <<
24) | ((6) << 20) | (1U << 12) | ((1) << 4
)))))
3139 WPI_FH_RX_CONFIG_IRQ_DST_HOST |(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xc00)), ((
(1U << 31) | (1U << 29) | (1U << 27) | (1U <<
24) | ((6) << 20) | (1U << 12) | ((1) << 4
)))))
3140 WPI_FH_RX_CONFIG_IRQ_RBTH(1))(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xc00)), ((
(1U << 31) | (1U << 29) | (1U << 27) | (1U <<
24) | ((6) << 20) | (1U << 12) | ((1) << 4
)))))
;
3141 (void)WPI_READ(sc, WPI_FH_RSSR_TBL)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0xcc0)))); /* barrier */
3142 WPI_WRITE(sc, WPI_FH_RX_WPTR, (WPI_RX_RING_COUNT - 1) & ~7)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xc20)), ((
((1 << 6) - 1) & ~7))))
;
3143 wpi_nic_unlock(sc);
3144
3145 /* Initialize TX rings. */
3146 if ((error = wpi_nic_lock(sc)) != 0)
3147 return error;
3148 wpi_prph_write(sc, WPI_ALM_SCHED_MODE0x2e00, 2); /* bypass mode */
3149 wpi_prph_write(sc, WPI_ALM_SCHED_ARASTAT0x2e04, 1); /* enable RA0 */
3150 /* Enable all 6 TX rings. */
3151 wpi_prph_write(sc, WPI_ALM_SCHED_TXFACT0x2e10, 0x3f);
3152 wpi_prph_write(sc, WPI_ALM_SCHED_SBYPASS_MODE10x2e2c, 0x10000);
3153 wpi_prph_write(sc, WPI_ALM_SCHED_SBYPASS_MODE20x2e30, 0x30002);
3154 wpi_prph_write(sc, WPI_ALM_SCHED_TXF4MF0x2e14, 4);
3155 wpi_prph_write(sc, WPI_ALM_SCHED_TXF5MF0x2e20, 5);
3156 /* Set physical address of TX rings. */
3157 WPI_WRITE(sc, WPI_FH_TX_BASE, sc->shared_dma.paddr)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xe80)), ((
sc->shared_dma.paddr))))
;
3158 WPI_WRITE(sc, WPI_FH_MSG_CONFIG, 0xffff05a5)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xe88)), ((
0xffff05a5))))
;
3159
3160 /* Enable all DMA channels. */
3161 for (chnl = 0; chnl < WPI_NDMACHNLS6; chnl++) {
3162 WPI_WRITE(sc, WPI_FH_CBBC_CTRL(chnl), 0)(((sc)->sc_st)->write_4(((sc)->sc_sh), (((0x940 + (chnl
) * 8))), ((0))))
;
3163 WPI_WRITE(sc, WPI_FH_CBBC_BASE(chnl), 0)(((sc)->sc_st)->write_4(((sc)->sc_sh), (((0x944 + (chnl
) * 8))), ((0))))
;
3164 WPI_WRITE(sc, WPI_FH_TX_CONFIG(chnl), 0x80200008)(((sc)->sc_st)->write_4(((sc)->sc_sh), (((0xd00 + (chnl
) * 32))), ((0x80200008))))
;
3165 }
3166 wpi_nic_unlock(sc);
3167 (void)WPI_READ(sc, WPI_FH_TX_BASE)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0xe80)))); /* barrier */
3168
3169 /* Clear "radio off" and "commands blocked" bits. */
3170 WPI_WRITE(sc, WPI_UCODE_GP1_CLR, WPI_UCODE_GP1_RFKILL)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x05c)), ((
(1 << 1)))))
;
3171 WPI_WRITE(sc, WPI_UCODE_GP1_CLR, WPI_UCODE_GP1_CMD_BLOCKED)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x05c)), ((
(1 << 2)))))
;
3172
3173 /* Clear pending interrupts. */
3174 WPI_WRITE(sc, WPI_INT, 0xffffffff)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x008)), ((
0xffffffff))))
;
3175 /* Enable interrupts. */
3176 WPI_WRITE(sc, WPI_MASK, WPI_INT_MASK)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x00c)), ((
((1U << 25) | (1U << 29) | (1U << 27) | (1U
<< 31) | (1U << 0) | (1U << 1) | (1U <<
3) | (1U << 7))))))
;
3177
3178 /* _Really_ make sure "radio off" bit is cleared! */
3179 WPI_WRITE(sc, WPI_UCODE_GP1_CLR, WPI_UCODE_GP1_RFKILL)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x05c)), ((
(1 << 1)))))
;
3180 WPI_WRITE(sc, WPI_UCODE_GP1_CLR, WPI_UCODE_GP1_RFKILL)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x05c)), ((
(1 << 1)))))
;
3181
3182 if ((error = wpi_load_firmware(sc)) != 0) {
3183 printf("%s: could not load firmware\n", sc->sc_dev.dv_xname);
3184 return error;
3185 }
3186 /* Wait at most one second for firmware alive notification. */
3187 if ((error = tsleep_nsec(sc, PCATCH0x100, "wpiinit", SEC_TO_NSEC(1))) != 0) {
3188 printf("%s: timeout waiting for adapter to initialize\n",
3189 sc->sc_dev.dv_xname);
3190 return error;
3191 }
3192 /* Do post-firmware initialization. */
3193 return wpi_post_alive(sc);
3194}
3195
3196void
3197wpi_hw_stop(struct wpi_softc *sc)
3198{
3199 int chnl, qid, ntries;
3200 uint32_t tmp;
3201
3202 WPI_WRITE(sc, WPI_RESET, WPI_RESET_NEVO)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x020)), ((
(1 << 0)))))
;
3203
3204 /* Disable interrupts. */
3205 WPI_WRITE(sc, WPI_MASK, 0)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x00c)), ((
0))))
;
3206 WPI_WRITE(sc, WPI_INT, 0xffffffff)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x008)), ((
0xffffffff))))
;
3207 WPI_WRITE(sc, WPI_FH_INT, 0xffffffff)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x010)), ((
0xffffffff))))
;
3208
3209 /* Make sure we no longer hold the NIC lock. */
3210 wpi_nic_unlock(sc);
3211
3212 if (wpi_nic_lock(sc) == 0) {
3213 /* Stop TX scheduler. */
3214 wpi_prph_write(sc, WPI_ALM_SCHED_MODE0x2e00, 0);
3215 wpi_prph_write(sc, WPI_ALM_SCHED_TXFACT0x2e10, 0);
3216
3217 /* Stop all DMA channels. */
3218 for (chnl = 0; chnl < WPI_NDMACHNLS6; chnl++) {
3219 WPI_WRITE(sc, WPI_FH_TX_CONFIG(chnl), 0)(((sc)->sc_st)->write_4(((sc)->sc_sh), (((0xd00 + (chnl
) * 32))), ((0))))
;
3220 for (ntries = 0; ntries < 100; ntries++) {
3221 tmp = WPI_READ(sc, WPI_FH_TX_STATUS)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0xe90))));
3222 if ((tmp & WPI_FH_TX_STATUS_IDLE(chnl)(1 << ((chnl) + 24) | 1 << ((chnl) + 16))) ==
3223 WPI_FH_TX_STATUS_IDLE(chnl)(1 << ((chnl) + 24) | 1 << ((chnl) + 16)))
3224 break;
3225 DELAY(10)(*delay_func)(10);
3226 }
3227 }
3228 wpi_nic_unlock(sc);
3229 }
3230
3231 /* Stop RX ring. */
3232 wpi_reset_rx_ring(sc, &sc->rxq);
3233
3234 /* Reset all TX rings. */
3235 for (qid = 0; qid < WPI_NTXQUEUES8; qid++)
3236 wpi_reset_tx_ring(sc, &sc->txq[qid]);
3237
3238 if (wpi_nic_lock(sc) == 0) {
3239 wpi_prph_write(sc, WPI_APMG_CLK_DIS0x3008, WPI_APMG_CLK_DMA_CLK_RQT(1 << 9));
3240 wpi_nic_unlock(sc);
3241 }
3242 DELAY(5)(*delay_func)(5);
3243 /* Power OFF adapter. */
3244 wpi_apm_stop(sc);
3245}
3246
3247int
3248wpi_init(struct ifnet *ifp)
3249{
3250 struct wpi_softc *sc = ifp->if_softc;
3251 struct ieee80211com *ic = &sc->sc_ic;
3252 int error;
3253
3254#ifdef notyet
3255 /* Check that the radio is not disabled by hardware switch. */
3256 if (!(WPI_READ(sc, WPI_GP_CNTRL)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x024)))) & WPI_GP_CNTRL_RFKILL(1 << 27))) {
3257 printf("%s: radio is disabled by hardware switch\n",
3258 sc->sc_dev.dv_xname);
3259 error = EPERM1; /* :-) */
3260 goto fail;
3261 }
3262#endif
3263 /* Read firmware images from the filesystem. */
3264 if ((error = wpi_read_firmware(sc)) != 0) {
3265 printf("%s: could not read firmware\n", sc->sc_dev.dv_xname);
3266 goto fail;
3267 }
3268
3269 /* Initialize hardware and upload firmware. */
3270 error = wpi_hw_init(sc);
3271 free(sc->fw.data, M_DEVBUF2, sc->fw.datalen);
3272 if (error != 0) {
3273 printf("%s: could not initialize hardware\n",
3274 sc->sc_dev.dv_xname);
3275 goto fail;
3276 }
3277
3278 /* Configure adapter now that it is ready. */
3279 if ((error = wpi_config(sc)) != 0) {
3280 printf("%s: could not configure device\n",
3281 sc->sc_dev.dv_xname);
3282 goto fail;
3283 }
3284
3285 ifq_clr_oactive(&ifp->if_snd);
3286 ifp->if_flags |= IFF_RUNNING0x40;
3287
3288 if (ic->ic_opmode != IEEE80211_M_MONITOR)
3289 ieee80211_begin_scan(ifp);
3290 else
3291 ieee80211_new_state(ic, IEEE80211_S_RUN, -1)(((ic)->ic_newstate)((ic), (IEEE80211_S_RUN), (-1)));
3292
3293 return 0;
3294
3295fail: wpi_stop(ifp, 1);
3296 return error;
3297}
3298
3299void
3300wpi_stop(struct ifnet *ifp, int disable)
3301{
3302 struct wpi_softc *sc = ifp->if_softc;
3303 struct ieee80211com *ic = &sc->sc_ic;
3304
3305 ifp->if_timer = sc->sc_tx_timer = 0;
3306 ifp->if_flags &= ~IFF_RUNNING0x40;
3307 ifq_clr_oactive(&ifp->if_snd);
3308
3309 ieee80211_new_state(ic, IEEE80211_S_INIT, -1)(((ic)->ic_newstate)((ic), (IEEE80211_S_INIT), (-1)));
3310
3311 /* Power OFF hardware. */
3312 wpi_hw_stop(sc);
3313}