Bug Summary

File:dev/pci/if_wpi.c
Warning:line 250, 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.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name if_wpi.c -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 -ffp-contract=on -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 -target-feature +retpoline-external-thunk -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/llvm16/lib/clang/16 -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/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -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/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -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/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -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 SUSPEND -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 -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 -fcf-protection=branch -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 /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/sys/dev/pci/if_wpi.c
1/* $OpenBSD: if_wpi.c,v 1.157 2022/04/21 21:03:03 stsp 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
162const struct 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_NET0x4, 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) {
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) {
Although the value stored to 'error' is used in the enclosing expression, the value is never actually read from 'error'
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(0x4);
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(0x4);
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 memset(&rxi, 0, sizeof(rxi))__builtin_memset((&rxi), (0), (sizeof(rxi)));
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 ieee80211_inputm(ifp, m, ni, &rxi, ml);
1337
1338 /* Node is no longer needed. */
1339 ieee80211_release_node(ic, ni);
1340}
1341
1342void
1343wpi_tx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc)
1344{
1345 struct ieee80211com *ic = &sc->sc_ic;
1346 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1347 struct wpi_tx_ring *ring = &sc->txq[desc->qid & 0x3];
1348 struct wpi_tx_data *data = &ring->data[desc->idx];
1349 struct wpi_tx_stat *stat = (struct wpi_tx_stat *)(desc + 1);
1350 struct wpi_node *wn = (struct wpi_node *)data->ni;
1351
1352 /* Update rate control statistics. */
1353 wn->amn.amn_txcnt++;
1354 if (stat->retrycnt > 0)
1355 wn->amn.amn_retrycnt++;
1356
1357 if ((letoh32(stat->status)((__uint32_t)(stat->status)) & 0xff) != 1)
1358 ifp->if_oerrorsif_data.ifi_oerrors++;
1359
1360 /* Unmap and free mbuf. */
1361 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))
1362 BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x08))
;
1363 bus_dmamap_unload(sc->sc_dmat, data->map)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (data
->map))
;
1364 m_freem(data->m);
1365 data->m = NULL((void *)0);
1366 ieee80211_release_node(ic, data->ni);
1367 data->ni = NULL((void *)0);
1368
1369 sc->sc_tx_timer = 0;
1370 if (--ring->queued < WPI_TX_RING_LOMARK192) {
1371 sc->qfullmsk &= ~(1 << ring->qid);
1372 if (sc->qfullmsk == 0 && ifq_is_oactive(&ifp->if_snd)) {
1373 ifq_clr_oactive(&ifp->if_snd);
1374 (*ifp->if_start)(ifp);
1375 }
1376 }
1377}
1378
1379void
1380wpi_cmd_done(struct wpi_softc *sc, struct wpi_rx_desc *desc)
1381{
1382 struct wpi_tx_ring *ring = &sc->txq[4];
1383 struct wpi_tx_data *data;
1384
1385 if ((desc->qid & 7) != 4)
1386 return; /* Not a command ack. */
1387
1388 data = &ring->data[desc->idx];
1389
1390 /* If the command was mapped in an mbuf, free it. */
1391 if (data->m != NULL((void *)0)) {
1392 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))
1393 data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x08))
;
1394 bus_dmamap_unload(sc->sc_dmat, data->map)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (data
->map))
;
1395 m_freem(data->m);
1396 data->m = NULL((void *)0);
1397 }
1398 wakeup(&ring->cmd[desc->idx]);
1399}
1400
1401void
1402wpi_notif_intr(struct wpi_softc *sc)
1403{
1404 struct mbuf_list ml = MBUF_LIST_INITIALIZER(){ ((void *)0), ((void *)0), 0 };
1405 struct ieee80211com *ic = &sc->sc_ic;
1406 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1407 uint32_t hw;
1408
1409 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))
1410 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))
;
1411
1412 hw = letoh32(sc->shared->next)((__uint32_t)(sc->shared->next));
1413 while (sc->rxq.cur != hw) {
1414 struct wpi_rx_data *data = &sc->rxq.data[sc->rxq.cur];
1415 struct wpi_rx_desc *desc;
1416
1417 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))
1418 BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (sizeof (*desc)), (0x02))
;
1419 desc = mtod(data->m, struct wpi_rx_desc *)((struct wpi_rx_desc *)((data->m)->m_hdr.mh_data));
1420
1421 DPRINTFN(4, ("rx notification qid=%x idx=%d flags=%x type=%d "
1422 "len=%d\n", desc->qid, desc->idx, desc->flags, desc->type,
1423 letoh32(desc->len)));
1424
1425 if (!(desc->qid & 0x80)) /* Reply to a command. */
1426 wpi_cmd_done(sc, desc);
1427
1428 switch (desc->type) {
1429 case WPI_RX_DONE27:
1430 /* An 802.11 frame has been received. */
1431 wpi_rx_done(sc, desc, data, &ml);
1432 break;
1433
1434 case WPI_TX_DONE28:
1435 /* An 802.11 frame has been transmitted. */
1436 wpi_tx_done(sc, desc);
1437 break;
1438
1439 case WPI_UC_READY1:
1440 {
1441 struct wpi_ucode_info *uc =
1442 (struct wpi_ucode_info *)(desc + 1);
1443
1444 /* The microcontroller is ready. */
1445 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))
1446 sizeof (*uc), BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (sizeof (*desc)), (sizeof (*uc)), (0x02))
;
1447 DPRINTF(("microcode alive notification version %x "
1448 "alive %x\n", letoh32(uc->version),
1449 letoh32(uc->valid)));
1450
1451 if (letoh32(uc->valid)((__uint32_t)(uc->valid)) != 1) {
1452 printf("%s: microcontroller initialization "
1453 "failed\n", sc->sc_dev.dv_xname);
1454 }
1455 if (uc->subtype != WPI_UCODE_INIT9) {
1456 /* Save the address of the error log. */
1457 sc->errptr = letoh32(uc->errptr)((__uint32_t)(uc->errptr));
1458 }
1459 break;
1460 }
1461 case WPI_STATE_CHANGED161:
1462 {
1463 uint32_t *status = (uint32_t *)(desc + 1);
1464
1465 /* Enabled/disabled notification. */
1466 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))
1467 sizeof (*status), BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (sizeof (*desc)), (sizeof (*status)), (0x02))
;
1468 DPRINTF(("state changed to %x\n", letoh32(*status)));
1469
1470 if (letoh32(*status)((__uint32_t)(*status)) & 1) {
1471 /* The radio button has to be pushed. */
1472 printf("%s: Radio transmitter is off\n",
1473 sc->sc_dev.dv_xname);
1474 /* Turn the interface down. */
1475 wpi_stop(ifp, 1);
1476 return; /* No further processing. */
1477 }
1478 break;
1479 }
1480 case WPI_START_SCAN130:
1481 {
1482 struct wpi_start_scan *scan =
1483 (struct wpi_start_scan *)(desc + 1);
1484
1485 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))
1486 sizeof (*scan), BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (sizeof (*desc)), (sizeof (*scan)), (0x02))
;
1487 DPRINTFN(2, ("scanning channel %d status %x\n",
1488 scan->chan, letoh32(scan->status)));
1489
1490 /* Fix current channel. */
1491 ic->ic_bss->ni_chan = &ic->ic_channels[scan->chan];
1492 break;
1493 }
1494 case WPI_STOP_SCAN132:
1495 {
1496 struct wpi_stop_scan *scan =
1497 (struct wpi_stop_scan *)(desc + 1);
1498
1499 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))
1500 sizeof (*scan), BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (sizeof (*desc)), (sizeof (*scan)), (0x02))
;
1501 DPRINTF(("scan finished nchan=%d status=%d chan=%d\n",
1502 scan->nchan, scan->status, scan->chan));
1503
1504 if (scan->status == 1 && scan->chan <= 14 &&
1505 (sc->sc_flags & WPI_FLAG_HAS_5GHZ(1 << 0))) {
1506 /*
1507 * We just finished scanning 2GHz channels,
1508 * start scanning 5GHz ones.
1509 */
1510 if (wpi_scan(sc, IEEE80211_CHAN_5GHZ0x0100) == 0)
1511 break;
1512 }
1513 ieee80211_end_scan(ifp);
1514 break;
1515 }
1516 }
1517
1518 sc->rxq.cur = (sc->rxq.cur + 1) % WPI_RX_RING_COUNT(1 << 6);
1519 }
1520 if_input(&ic->ic_ific_ac.ac_if, &ml);
1521
1522 /* Tell the firmware what we have processed. */
1523 hw = (hw == 0) ? WPI_RX_RING_COUNT(1 << 6) - 1 : hw - 1;
1524 WPI_WRITE(sc, WPI_FH_RX_WPTR, hw & ~7)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xc20)), ((
hw & ~7))))
;
1525}
1526
1527#ifdef WPI_DEBUG
1528/*
1529 * Dump the error log of the firmware when a firmware panic occurs. Although
1530 * we can't debug the firmware because it is neither open source nor free, it
1531 * can help us to identify certain classes of problems.
1532 */
1533void
1534wpi_fatal_intr(struct wpi_softc *sc)
1535{
1536#define N(a) (sizeof (a) / sizeof ((a)[0]))
1537 struct wpi_fwdump dump;
1538 uint32_t i, offset, count;
1539
1540 /* Check that the error log address is valid. */
1541 if (sc->errptr < WPI_FW_DATA_BASE0x00800000 ||
1542 sc->errptr + sizeof (dump) >
1543 WPI_FW_DATA_BASE0x00800000 + WPI_FW_DATA_MAXSZ(32 * 1024)) {
1544 printf("%s: bad firmware error log address 0x%08x\n",
1545 sc->sc_dev.dv_xname, sc->errptr);
1546 return;
1547 }
1548
1549 if (wpi_nic_lock(sc) != 0) {
1550 printf("%s: could not read firmware error log\n",
1551 sc->sc_dev.dv_xname);
1552 return;
1553 }
1554 /* Read number of entries in the log. */
1555 count = wpi_mem_read(sc, sc->errptr);
1556 if (count == 0 || count * sizeof (dump) > WPI_FW_DATA_MAXSZ(32 * 1024)) {
1557 printf("%s: invalid count field (count=%u)\n",
1558 sc->sc_dev.dv_xname, count);
1559 wpi_nic_unlock(sc);
1560 return;
1561 }
1562 /* Skip "count" field. */
1563 offset = sc->errptr + sizeof (uint32_t);
1564 printf("firmware error log (count=%u):\n", count);
1565 for (i = 0; i < count; i++) {
1566 wpi_mem_read_region_4(sc, offset, (uint32_t *)&dump,
1567 sizeof (dump) / sizeof (uint32_t));
1568
1569 printf(" error type = \"%s\" (0x%08X)\n",
1570 (dump.desc < N(wpi_fw_errmsg)) ?
1571 wpi_fw_errmsg[dump.desc] : "UNKNOWN",
1572 dump.desc);
1573 printf(" error data = 0x%08X\n",
1574 dump.data);
1575 printf(" branch link = 0x%08X%08X\n",
1576 dump.blink[0], dump.blink[1]);
1577 printf(" interrupt link = 0x%08X%08X\n",
1578 dump.ilink[0], dump.ilink[1]);
1579 printf(" time = %u\n", dump.time);
1580
1581 offset += sizeof (dump);
1582 }
1583 wpi_nic_unlock(sc);
1584 /* Dump driver status (TX and RX rings) while we're here. */
1585 printf("driver status:\n");
1586 for (i = 0; i < 6; i++) {
1587 struct wpi_tx_ring *ring = &sc->txq[i];
1588 printf(" tx ring %2d: qid=%-2d cur=%-3d queued=%-3d\n",
1589 i, ring->qid, ring->cur, ring->queued);
1590 }
1591 printf(" rx ring: cur=%d\n", sc->rxq.cur);
1592 printf(" 802.11 state %d\n", sc->sc_ic.ic_state);
1593#undef N
1594}
1595#endif
1596
1597int
1598wpi_intr(void *arg)
1599{
1600 struct wpi_softc *sc = arg;
1601 struct ifnet *ifp = &sc->sc_ic.ic_ific_ac.ac_if;
1602 uint32_t r1, r2;
1603
1604 /* Disable interrupts. */
1605 WPI_WRITE(sc, WPI_MASK, 0)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x00c)), ((
0))))
;
1606
1607 r1 = WPI_READ(sc, WPI_INT)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x008))));
1608 r2 = WPI_READ(sc, WPI_FH_INT)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x010))));
1609
1610 if (r1 == 0 && r2 == 0) {
1611 if (ifp->if_flags & IFF_UP0x1)
1612 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))))))
;
1613 return 0; /* Interrupt not for us. */
1614 }
1615 if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0)
1616 return 0; /* Hardware gone! */
1617
1618 /* Acknowledge interrupts. */
1619 WPI_WRITE(sc, WPI_INT, r1)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x008)), ((
r1))))
;
1620 WPI_WRITE(sc, WPI_FH_INT, r2)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x010)), ((
r2))))
;
1621
1622 if (r1 & (WPI_INT_SW_ERR(1U << 25) | WPI_INT_HW_ERR(1U << 29))) {
1623 printf("%s: fatal firmware error\n", sc->sc_dev.dv_xname);
1624 /* Dump firmware error log and stop. */
1625#ifdef WPI_DEBUG
1626 wpi_fatal_intr(sc);
1627#endif
1628 wpi_stop(ifp, 1);
1629 task_add(systq, &sc->init_task);
1630 return 1;
1631 }
1632 if ((r1 & (WPI_INT_FH_RX(1U << 31) | WPI_INT_SW_RX(1U << 3))) ||
1633 (r2 & WPI_FH_INT_RX((1 << ((0) + 16)) | (1 << ((1) + 16)) | (1 <<
((2) + 16)) | (1 << 30))
))
1634 wpi_notif_intr(sc);
1635
1636 if (r1 & WPI_INT_ALIVE(1U << 0))
1637 wakeup(sc); /* Firmware is alive. */
1638
1639 /* Re-enable interrupts. */
1640 if (ifp->if_flags & IFF_UP0x1)
1641 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))))))
;
1642
1643 return 1;
1644}
1645
1646int
1647wpi_tx(struct wpi_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
1648{
1649 struct ieee80211com *ic = &sc->sc_ic;
1650 struct wpi_node *wn = (void *)ni;
1651 struct wpi_tx_ring *ring;
1652 struct wpi_tx_desc *desc;
1653 struct wpi_tx_data *data;
1654 struct wpi_tx_cmd *cmd;
1655 struct wpi_cmd_data *tx;
1656 const struct wpi_rate *rinfo;
1657 struct ieee80211_frame *wh;
1658 struct ieee80211_key *k = NULL((void *)0);
1659 enum ieee80211_edca_ac ac;
1660 uint32_t flags;
1661 uint16_t qos;
1662 u_int hdrlen;
1663 uint8_t *ivp, tid, ridx, type;
1664 int i, totlen, hasqos, error;
1665
1666 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
1667 hdrlen = ieee80211_get_hdrlen(wh);
1668 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK0x0c;
1669
1670 /* Select EDCA Access Category and TX ring for this frame. */
1671 if ((hasqos = ieee80211_has_qos(wh))) {
1672 qos = ieee80211_get_qos(wh);
1673 tid = qos & IEEE80211_QOS_TID0x000f;
1674 ac = ieee80211_up_to_ac(ic, tid);
1675 } else {
1676 tid = 0;
1677 ac = EDCA_AC_BE;
1678 }
1679
1680 ring = &sc->txq[ac];
1681 desc = &ring->desc[ring->cur];
1682 data = &ring->data[ring->cur];
1683
1684 /* Choose a TX rate index. */
1685 if (IEEE80211_IS_MULTICAST(wh->i_addr1)(*(wh->i_addr1) & 0x01) ||
1686 type != IEEE80211_FC0_TYPE_DATA0x08) {
1687 ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
1688 WPI_RIDX_OFDM60 : WPI_RIDX_CCK18;
1689 } else if (ic->ic_fixed_rate != -1) {
1690 ridx = sc->fixed_ridx;
1691 } else
1692 ridx = wn->ridx[ni->ni_txrate];
1693 rinfo = &wpi_rates[ridx];
1694
1695#if NBPFILTER1 > 0
1696 if (sc->sc_drvbpf != NULL((void *)0)) {
1697 struct wpi_tx_radiotap_header *tap = &sc->sc_txtapsc_txtapu.th;
1698
1699 tap->wt_flags = 0;
1700 tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq)((__uint16_t)(ni->ni_chan->ic_freq));
1701 tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags)((__uint16_t)(ni->ni_chan->ic_flags));
1702 tap->wt_rate = rinfo->rate;
1703 if ((ic->ic_flags & IEEE80211_F_WEPON0x00000100) &&
1704 (wh->i_fc[1] & IEEE80211_FC1_PROTECTED0x40))
1705 tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP0x04;
1706
1707 bpf_mtap_hdr(sc->sc_drvbpf, tap, sc->sc_txtap_len,
1708 m, BPF_DIRECTION_OUT(1 << 1));
1709 }
1710#endif
1711
1712 totlen = m->m_pkthdrM_dat.MH.MH_pkthdr.len;
1713
1714 /* Encrypt the frame if need be. */
1715 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED0x40) {
1716 /* Retrieve key for TX. */
1717 k = ieee80211_get_txkey(ic, wh, ni);
1718 if (k->k_cipher != IEEE80211_CIPHER_CCMP) {
1719 /* Do software encryption. */
1720 if ((m = ieee80211_encrypt(ic, m, k)) == NULL((void *)0))
1721 return ENOBUFS55;
1722 /* 802.11 header may have moved. */
1723 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
1724 totlen = m->m_pkthdrM_dat.MH.MH_pkthdr.len;
1725
1726 } else /* HW appends CCMP MIC. */
1727 totlen += IEEE80211_CCMP_HDRLEN8;
1728 }
1729
1730 /* Prepare TX firmware command. */
1731 cmd = &ring->cmd[ring->cur];
1732 cmd->code = WPI_CMD_TX_DATA28;
1733 cmd->flags = 0;
1734 cmd->qid = ring->qid;
1735 cmd->idx = ring->cur;
1736
1737 tx = (struct wpi_cmd_data *)cmd->data;
1738 /* NB: No need to clear tx, all fields are reinitialized here. */
1739
1740 flags = 0;
1741 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)(*(wh->i_addr1) & 0x01)) {
1742 /* Unicast frame, check if an ACK is expected. */
1743 if (!hasqos || (qos & IEEE80211_QOS_ACK_POLICY_MASK0x0060) !=
1744 IEEE80211_QOS_ACK_POLICY_NOACK0x0020)
1745 flags |= WPI_TX_NEED_ACK(1 << 3);
1746 }
1747
1748 /* Check if frame must be protected using RTS/CTS or CTS-to-self. */
1749 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)(*(wh->i_addr1) & 0x01)) {
1750 /* NB: Group frames are sent using CCK in 802.11b/g. */
1751 if (totlen + IEEE80211_CRC_LEN4 > ic->ic_rtsthreshold) {
1752 flags |= WPI_TX_NEED_RTS(1 << 1) | WPI_TX_FULL_TXOP(1 << 7);
1753 } else if ((ic->ic_flags & IEEE80211_F_USEPROT0x00100000) &&
1754 ridx <= WPI_RIDX_OFDM547) {
1755 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
1756 flags |= WPI_TX_NEED_CTS(1 << 2) | WPI_TX_FULL_TXOP(1 << 7);
1757 else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
1758 flags |= WPI_TX_NEED_RTS(1 << 1) | WPI_TX_FULL_TXOP(1 << 7);
1759 }
1760 }
1761
1762 if (IEEE80211_IS_MULTICAST(wh->i_addr1)(*(wh->i_addr1) & 0x01) ||
1763 type != IEEE80211_FC0_TYPE_DATA0x08)
1764 tx->id = WPI_ID_BROADCAST24;
1765 else
1766 tx->id = wn->id;
1767
1768 if (type == IEEE80211_FC0_TYPE_MGT0x00) {
1769 uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK0xf0;
1770
1771#ifndef IEEE80211_STA_ONLY
1772 /* Tell HW to set timestamp in probe responses. */
1773 if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP0x50)
1774 flags |= WPI_TX_INSERT_TSTAMP(1 << 16);
1775#endif
1776 if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ0x00 ||
1777 subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ0x20)
1778 tx->timeout = htole16(3)((__uint16_t)(3));
1779 else
1780 tx->timeout = htole16(2)((__uint16_t)(2));
1781 } else
1782 tx->timeout = htole16(0)((__uint16_t)(0));
1783
1784 tx->len = htole16(totlen)((__uint16_t)(totlen));
1785 tx->tid = tid;
1786 tx->rts_ntries = 7;
1787 tx->data_ntries = 15;
1788 tx->ofdm_mask = 0xff;
1789 tx->cck_mask = 0x0f;
1790 tx->lifetime = htole32(WPI_LIFETIME_INFINITE)((__uint32_t)(0xffffffff));
1791 tx->plcp = rinfo->plcp;
1792
1793 /* Copy 802.11 header in TX command. */
1794 memcpy((uint8_t *)(tx + 1), wh, hdrlen)__builtin_memcpy(((uint8_t *)(tx + 1)), (wh), (hdrlen));
1795
1796 if (k != NULL((void *)0) && k->k_cipher == IEEE80211_CIPHER_CCMP) {
1797 /* Trim 802.11 header and prepend CCMP IV. */
1798 m_adj(m, hdrlen - IEEE80211_CCMP_HDRLEN8);
1799 ivp = mtod(m, uint8_t *)((uint8_t *)((m)->m_hdr.mh_data));
1800 k->k_tsc++;
1801 ivp[0] = k->k_tsc;
1802 ivp[1] = k->k_tsc >> 8;
1803 ivp[2] = 0;
1804 ivp[3] = k->k_id << 6 | IEEE80211_WEP_EXTIV0x20;
1805 ivp[4] = k->k_tsc >> 16;
1806 ivp[5] = k->k_tsc >> 24;
1807 ivp[6] = k->k_tsc >> 32;
1808 ivp[7] = k->k_tsc >> 40;
1809
1810 tx->security = WPI_CIPHER_CCMP2;
1811 memcpy(tx->key, k->k_key, k->k_len)__builtin_memcpy((tx->key), (k->k_key), (k->k_len));
1812 } else {
1813 /* Trim 802.11 header. */
1814 m_adj(m, hdrlen);
1815 tx->security = 0;
1816 }
1817 tx->flags = htole32(flags)((__uint32_t)(flags));
1818
1819 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))
1820 BUS_DMA_NOWAIT | BUS_DMA_WRITE)(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
data->map), (m), (0x0001 | 0x0400))
;
1821 if (error != 0 && error != EFBIG27) {
1822 printf("%s: can't map mbuf (error %d)\n",
1823 sc->sc_dev.dv_xname, error);
1824 m_freem(m);
1825 return error;
1826 }
1827 if (error != 0) {
1828 /* Too many DMA segments, linearize mbuf. */
1829 if (m_defrag(m, M_DONTWAIT0x0002)) {
1830 m_freem(m);
1831 return ENOBUFS55;
1832 }
1833 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))
1834 BUS_DMA_NOWAIT | BUS_DMA_WRITE)(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
data->map), (m), (0x0001 | 0x0400))
;
1835 if (error != 0) {
1836 printf("%s: can't map mbuf (error %d)\n",
1837 sc->sc_dev.dv_xname, error);
1838 m_freem(m);
1839 return error;
1840 }
1841 }
1842
1843 data->m = m;
1844 data->ni = ni;
1845
1846 DPRINTFN(4, ("sending data: qid=%d idx=%d len=%d nsegs=%d\n",
1847 ring->qid, ring->cur, m->m_pkthdr.len, data->map->dm_nsegs));
1848
1849 /* Fill TX descriptor. */
1850 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))
1851 (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))
;
1852 /* First DMA segment is used by the TX command. */
1853 desc->segs[0].addr = htole32(ring->cmd_dma.paddr +((__uint32_t)(ring->cmd_dma.paddr + ring->cur * sizeof (
struct wpi_tx_cmd)))
1854 ring->cur * sizeof (struct wpi_tx_cmd))((__uint32_t)(ring->cmd_dma.paddr + ring->cur * sizeof (
struct wpi_tx_cmd)))
;
1855 desc->segs[0].len = htole32(4 + sizeof (struct wpi_cmd_data) +((__uint32_t)(4 + sizeof (struct wpi_cmd_data) + ((hdrlen + 3
) & ~3)))
1856 ((hdrlen + 3) & ~3))((__uint32_t)(4 + sizeof (struct wpi_cmd_data) + ((hdrlen + 3
) & ~3)))
;
1857 /* Other DMA segments are for data payload. */
1858 for (i = 1; i <= data->map->dm_nsegs; i++) {
1859 desc->segs[i].addr =
1860 htole32(data->map->dm_segs[i - 1].ds_addr)((__uint32_t)(data->map->dm_segs[i - 1].ds_addr));
1861 desc->segs[i].len =
1862 htole32(data->map->dm_segs[i - 1].ds_len)((__uint32_t)(data->map->dm_segs[i - 1].ds_len));
1863 }
1864
1865 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))
1866 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x04))
;
1867 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))
1868 (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))
1869 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))
;
1870 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))
1871 (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))
1872 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))
;
1873
1874 /* Kick TX ring. */
1875 ring->cur = (ring->cur + 1) % WPI_TX_RING_COUNT256;
1876 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))))
;
1877
1878 /* Mark TX ring as full if we reach a certain threshold. */
1879 if (++ring->queued > WPI_TX_RING_HIMARK224)
1880 sc->qfullmsk |= 1 << ring->qid;
1881
1882 return 0;
1883}
1884
1885void
1886wpi_start(struct ifnet *ifp)
1887{
1888 struct wpi_softc *sc = ifp->if_softc;
1889 struct ieee80211com *ic = &sc->sc_ic;
1890 struct ieee80211_node *ni;
1891 struct mbuf *m;
1892
1893 if (!(ifp->if_flags & IFF_RUNNING0x40) || ifq_is_oactive(&ifp->if_snd))
1894 return;
1895
1896 for (;;) {
1897 if (sc->qfullmsk != 0) {
1898 ifq_set_oactive(&ifp->if_snd);
1899 break;
1900 }
1901 /* Send pending management frames first. */
1902 m = mq_dequeue(&ic->ic_mgtq);
1903 if (m != NULL((void *)0)) {
1904 ni = m->m_pkthdrM_dat.MH.MH_pkthdr.ph_cookie;
1905 goto sendit;
1906 }
1907 if (ic->ic_state != IEEE80211_S_RUN)
1908 break;
1909
1910 /* Encapsulate and send data frames. */
1911 m = ifq_dequeue(&ifp->if_snd);
1912 if (m == NULL((void *)0))
1913 break;
1914#if NBPFILTER1 > 0
1915 if (ifp->if_bpf != NULL((void *)0))
1916 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT(1 << 1));
1917#endif
1918 if ((m = ieee80211_encap(ifp, m, &ni)) == NULL((void *)0))
1919 continue;
1920sendit:
1921#if NBPFILTER1 > 0
1922 if (ic->ic_rawbpf != NULL((void *)0))
1923 bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT(1 << 1));
1924#endif
1925 if (wpi_tx(sc, m, ni) != 0) {
1926 ieee80211_release_node(ic, ni);
1927 ifp->if_oerrorsif_data.ifi_oerrors++;
1928 continue;
1929 }
1930
1931 sc->sc_tx_timer = 5;
1932 ifp->if_timer = 1;
1933 }
1934}
1935
1936void
1937wpi_watchdog(struct ifnet *ifp)
1938{
1939 struct wpi_softc *sc = ifp->if_softc;
1940
1941 ifp->if_timer = 0;
1942
1943 if (sc->sc_tx_timer > 0) {
1944 if (--sc->sc_tx_timer == 0) {
1945 printf("%s: device timeout\n", sc->sc_dev.dv_xname);
1946 wpi_stop(ifp, 1);
1947 ifp->if_oerrorsif_data.ifi_oerrors++;
1948 return;
1949 }
1950 ifp->if_timer = 1;
1951 }
1952
1953 ieee80211_watchdog(ifp);
1954}
1955
1956int
1957wpi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1958{
1959 struct wpi_softc *sc = ifp->if_softc;
1960 struct ieee80211com *ic = &sc->sc_ic;
1961 int s, error = 0;
1962
1963 error = rw_enter(&sc->sc_rwlock, RW_WRITE0x0001UL | RW_INTR0x0010UL);
1964 if (error)
1965 return error;
1966 s = splnet()splraise(0x4);
1967
1968 switch (cmd) {
1969 case SIOCSIFADDR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((12)))
:
1970 ifp->if_flags |= IFF_UP0x1;
1971 /* FALLTHROUGH */
1972 case SIOCSIFFLAGS((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((16)))
:
1973 if (ifp->if_flags & IFF_UP0x1) {
1974 if (!(ifp->if_flags & IFF_RUNNING0x40))
1975 error = wpi_init(ifp);
1976 } else {
1977 if (ifp->if_flags & IFF_RUNNING0x40)
1978 wpi_stop(ifp, 1);
1979 }
1980 break;
1981
1982 case SIOCS80211POWER((unsigned long)0x80000000 | ((sizeof(struct ieee80211_power)
& 0x1fff) << 16) | ((('i')) << 8) | ((234)))
:
1983 error = ieee80211_ioctl(ifp, cmd, data);
1984 if (error != ENETRESET52)
1985 break;
1986 if (ic->ic_state == IEEE80211_S_RUN) {
1987 if (ic->ic_flags & IEEE80211_F_PMGTON0x00000400)
1988 error = wpi_set_pslevel(sc, 0, 3, 0);
1989 else /* back to CAM */
1990 error = wpi_set_pslevel(sc, 0, 0, 0);
1991 } else {
1992 /* Defer until transition to IEEE80211_S_RUN. */
1993 error = 0;
1994 }
1995 break;
1996
1997 default:
1998 error = ieee80211_ioctl(ifp, cmd, data);
1999 }
2000
2001 if (error == ENETRESET52) {
2002 error = 0;
2003 if ((ifp->if_flags & (IFF_UP0x1 | IFF_RUNNING0x40)) ==
2004 (IFF_UP0x1 | IFF_RUNNING0x40)) {
2005 wpi_stop(ifp, 0);
2006 error = wpi_init(ifp);
2007 }
2008 }
2009
2010 splx(s)spllower(s);
2011 rw_exit_write(&sc->sc_rwlock);
2012 return error;
2013}
2014
2015/*
2016 * Send a command to the firmware.
2017 */
2018int
2019wpi_cmd(struct wpi_softc *sc, int code, const void *buf, int size, int async)
2020{
2021 struct wpi_tx_ring *ring = &sc->txq[4];
2022 struct wpi_tx_desc *desc;
2023 struct wpi_tx_data *data;
2024 struct wpi_tx_cmd *cmd;
2025 struct mbuf *m;
2026 bus_addr_t paddr;
2027 int totlen, error;
2028
2029 desc = &ring->desc[ring->cur];
2030 data = &ring->data[ring->cur];
2031 totlen = 4 + size;
2032
2033 if (size > sizeof cmd->data) {
2034 /* Command is too large to fit in a descriptor. */
2035 if (totlen > MCLBYTES(1 << 11))
2036 return EINVAL22;
2037 MGETHDR(m, M_DONTWAIT, MT_DATA)m = m_gethdr((0x0002), (1));
2038 if (m == NULL((void *)0))
2039 return ENOMEM12;
2040 if (totlen > MHLEN((256 - sizeof(struct m_hdr)) - sizeof(struct pkthdr))) {
2041 MCLGET(m, M_DONTWAIT)(void) m_clget((m), (0x0002), (1 << 11));
2042 if (!(m->m_flagsm_hdr.mh_flags & M_EXT0x0001)) {
2043 m_freem(m);
2044 return ENOMEM12;
2045 }
2046 }
2047 cmd = mtod(m, struct wpi_tx_cmd *)((struct wpi_tx_cmd *)((m)->m_hdr.mh_data));
2048 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))
2049 NULL, BUS_DMA_NOWAIT | BUS_DMA_WRITE)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (data->
map), (cmd), (totlen), (((void *)0)), (0x0001 | 0x0400))
;
2050 if (error != 0) {
2051 m_freem(m);
2052 return error;
2053 }
2054 data->m = m;
2055 paddr = data->map->dm_segs[0].ds_addr;
2056 } else {
2057 cmd = &ring->cmd[ring->cur];
2058 paddr = data->cmd_paddr;
2059 }
2060
2061 cmd->code = code;
2062 cmd->flags = 0;
2063 cmd->qid = ring->qid;
2064 cmd->idx = ring->cur;
2065 memcpy(cmd->data, buf, size)__builtin_memcpy((cmd->data), (buf), (size));
2066
2067 desc->flags = htole32(WPI_PAD32(size) << 28 | 1 << 24)((__uint32_t)(((((size) + 3) & ~3) - (size)) << 28 |
1 << 24))
;
2068 desc->segs[0].addr = htole32(paddr)((__uint32_t)(paddr));
2069 desc->segs[0].len = htole32(totlen)((__uint32_t)(totlen));
2070
2071 if (size > sizeof cmd->data) {
2072 bus_dmamap_sync(sc->sc_dmat, data->map, 0, totlen,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (totlen), (0x04))
2073 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (totlen), (0x04))
;
2074 } else {
2075 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))
2076 (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))
2077 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
cmd_dma.map), ((caddr_t)cmd - ring->cmd_dma.vaddr), (totlen
), (0x04))
;
2078 }
2079 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))
2080 (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))
2081 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))
;
2082
2083 /* Kick command ring. */
2084 ring->cur = (ring->cur + 1) % WPI_TX_RING_COUNT256;
2085 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))))
;
2086
2087 return async ? 0 : tsleep_nsec(cmd, PCATCH0x100, "wpicmd", SEC_TO_NSEC(1));
2088}
2089
2090/*
2091 * Configure HW multi-rate retries.
2092 */
2093int
2094wpi_mrr_setup(struct wpi_softc *sc)
2095{
2096 struct ieee80211com *ic = &sc->sc_ic;
2097 struct wpi_mrr_setup mrr;
2098 int i, error;
2099
2100 /* CCK rates (not used with 802.11a). */
2101 for (i = WPI_RIDX_CCK18; i <= WPI_RIDX_CCK1111; i++) {
2102 mrr.rates[i].flags = 0;
2103 mrr.rates[i].plcp = wpi_rates[i].plcp;
2104 /* Fallback to the immediate lower CCK rate (if any.) */
2105 mrr.rates[i].next =
2106 (i == WPI_RIDX_CCK18) ? WPI_RIDX_CCK18 : i - 1;
2107 /* Try one time at this rate before falling back to "next". */
2108 mrr.rates[i].ntries = 1;
2109 }
2110 /* OFDM rates (not used with 802.11b). */
2111 for (i = WPI_RIDX_OFDM60; i <= WPI_RIDX_OFDM547; i++) {
2112 mrr.rates[i].flags = 0;
2113 mrr.rates[i].plcp = wpi_rates[i].plcp;
2114 /* Fallback to the immediate lower rate (if any.) */
2115 /* We allow fallback from OFDM/6 to CCK/2 in 11b/g mode. */
2116 mrr.rates[i].next = (i == WPI_RIDX_OFDM60) ?
2117 ((ic->ic_curmode == IEEE80211_MODE_11A) ?
2118 WPI_RIDX_OFDM60 : WPI_RIDX_CCK29) :
2119 i - 1;
2120 /* Try one time at this rate before falling back to "next". */
2121 mrr.rates[i].ntries = 1;
2122 }
2123 /* Setup MRR for control frames. */
2124 mrr.which = htole32(WPI_MRR_CTL)((__uint32_t)(0));
2125 error = wpi_cmd(sc, WPI_CMD_MRR_SETUP71, &mrr, sizeof mrr, 0);
2126 if (error != 0) {
2127 printf("%s: could not setup MRR for control frames\n",
2128 sc->sc_dev.dv_xname);
2129 return error;
2130 }
2131 /* Setup MRR for data frames. */
2132 mrr.which = htole32(WPI_MRR_DATA)((__uint32_t)(1));
2133 error = wpi_cmd(sc, WPI_CMD_MRR_SETUP71, &mrr, sizeof mrr, 0);
2134 if (error != 0) {
2135 printf("%s: could not setup MRR for data frames\n",
2136 sc->sc_dev.dv_xname);
2137 return error;
2138 }
2139 return 0;
2140}
2141
2142void
2143wpi_updateedca(struct ieee80211com *ic)
2144{
2145#define WPI_EXP2(x) ((1 << (x)) - 1) /* CWmin = 2^ECWmin - 1 */
2146 struct wpi_softc *sc = ic->ic_softcic_ac.ac_if.if_softc;
2147 struct wpi_edca_params cmd;
2148 int aci;
2149
2150 memset(&cmd, 0, sizeof cmd)__builtin_memset((&cmd), (0), (sizeof cmd));
2151 cmd.flags = htole32(WPI_EDCA_UPDATE)((__uint32_t)((1 << 0)));
2152 for (aci = 0; aci < EDCA_NUM_AC4; aci++) {
2153 const struct ieee80211_edca_ac_params *ac =
2154 &ic->ic_edca_ac[aci];
2155 cmd.ac[aci].aifsn = ac->ac_aifsn;
2156 cmd.ac[aci].cwmin = htole16(WPI_EXP2(ac->ac_ecwmin))((__uint16_t)(WPI_EXP2(ac->ac_ecwmin)));
2157 cmd.ac[aci].cwmax = htole16(WPI_EXP2(ac->ac_ecwmax))((__uint16_t)(WPI_EXP2(ac->ac_ecwmax)));
2158 cmd.ac[aci].txoplimit =
2159 htole16(IEEE80211_TXOP_TO_US(ac->ac_txoplimit))((__uint16_t)(((ac->ac_txoplimit) * 32)));
2160 }
2161 (void)wpi_cmd(sc, WPI_CMD_EDCA_PARAMS19, &cmd, sizeof cmd, 1);
2162#undef WPI_EXP2
2163}
2164
2165void
2166wpi_set_led(struct wpi_softc *sc, uint8_t which, uint8_t off, uint8_t on)
2167{
2168 struct wpi_cmd_led led;
2169
2170 led.which = which;
2171 led.unit = htole32(100000)((__uint32_t)(100000)); /* on/off in unit of 100ms */
2172 led.off = off;
2173 led.on = on;
2174 (void)wpi_cmd(sc, WPI_CMD_SET_LED72, &led, sizeof led, 1);
2175}
2176
2177int
2178wpi_set_timing(struct wpi_softc *sc, struct ieee80211_node *ni)
2179{
2180 struct wpi_cmd_timing cmd;
2181 uint64_t val, mod;
2182
2183 memset(&cmd, 0, sizeof cmd)__builtin_memset((&cmd), (0), (sizeof cmd));
2184 memcpy(&cmd.tstamp, ni->ni_tstamp, sizeof (uint64_t))__builtin_memcpy((&cmd.tstamp), (ni->ni_tstamp), (sizeof
(uint64_t)))
;
2185 cmd.bintval = htole16(ni->ni_intval)((__uint16_t)(ni->ni_intval));
2186 cmd.lintval = htole16(10)((__uint16_t)(10));
2187
2188 /* Compute remaining time until next beacon. */
2189 val = (uint64_t)ni->ni_intval * 1024; /* msecs -> usecs */
2190 mod = letoh64(cmd.tstamp)((__uint64_t)(cmd.tstamp)) % val;
2191 cmd.binitval = htole32((uint32_t)(val - mod))((__uint32_t)((uint32_t)(val - mod)));
2192
2193 DPRINTF(("timing bintval=%u, tstamp=%llu, init=%u\n",
2194 ni->ni_intval, letoh64(cmd.tstamp), (uint32_t)(val - mod)));
2195
2196 return wpi_cmd(sc, WPI_CMD_TIMING20, &cmd, sizeof cmd, 1);
2197}
2198
2199/*
2200 * This function is called periodically (every minute) to adjust TX power
2201 * based on temperature variation.
2202 */
2203void
2204wpi_power_calibration(struct wpi_softc *sc)
2205{
2206 int temp;
2207
2208 temp = (int)WPI_READ(sc, WPI_UCODE_GP2)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x060))));
2209 /* Sanity-check temperature. */
2210 if (temp < -260 || temp > 25) {
2211 /* This can't be correct, ignore. */
2212 DPRINTF(("out-of-range temperature reported: %d\n", temp));
2213 return;
2214 }
2215 DPRINTF(("temperature %d->%d\n", sc->temp, temp));
2216 /* Adjust TX power if need be (delta > 6). */
2217 if (abs(temp - sc->temp) > 6) {
2218 /* Record temperature of last calibration. */
2219 sc->temp = temp;
2220 (void)wpi_set_txpower(sc, 1);
2221 }
2222}
2223
2224/*
2225 * Set TX power for current channel (each rate has its own power settings).
2226 */
2227int
2228wpi_set_txpower(struct wpi_softc *sc, int async)
2229{
2230 struct ieee80211com *ic = &sc->sc_ic;
2231 struct ieee80211_channel *ch;
2232 struct wpi_power_group *group;
2233 struct wpi_cmd_txpower cmd;
2234 u_int chan;
2235 int idx, i;
2236
2237 /* Retrieve current channel from last RXON. */
2238 chan = sc->rxon.chan;
2239 DPRINTF(("setting TX power for channel %d\n", chan));
2240 ch = &ic->ic_channels[chan];
2241
2242 /* Find the TX power group to which this channel belongs. */
2243 if (IEEE80211_IS_CHAN_5GHZ(ch)(((ch)->ic_flags & 0x0100) != 0)) {
2244 for (group = &sc->groups[1]; group < &sc->groups[4]; group++)
2245 if (chan <= group->chan)
2246 break;
2247 } else
2248 group = &sc->groups[0];
2249
2250 memset(&cmd, 0, sizeof cmd)__builtin_memset((&cmd), (0), (sizeof cmd));
2251 cmd.band = IEEE80211_IS_CHAN_5GHZ(ch)(((ch)->ic_flags & 0x0100) != 0) ? 0 : 1;
2252 cmd.chan = htole16(chan)((__uint16_t)(chan));
2253
2254 /* Set TX power for all OFDM and CCK rates. */
2255 for (i = 0; i <= WPI_RIDX_MAX11 ; i++) {
2256 /* Retrieve TX power for this channel/rate. */
2257 idx = wpi_get_power_index(sc, group, ch, i);
2258
2259 cmd.rates[i].plcp = wpi_rates[i].plcp;
2260
2261 if (IEEE80211_IS_CHAN_5GHZ(ch)(((ch)->ic_flags & 0x0100) != 0)) {
2262 cmd.rates[i].rf_gain = wpi_rf_gain_5ghz[idx];
2263 cmd.rates[i].dsp_gain = wpi_dsp_gain_5ghz[idx];
2264 } else {
2265 cmd.rates[i].rf_gain = wpi_rf_gain_2ghz[idx];
2266 cmd.rates[i].dsp_gain = wpi_dsp_gain_2ghz[idx];
2267 }
2268 DPRINTF(("chan %d/rate %d: power index %d\n", chan,
2269 wpi_rates[i].rate, idx));
2270 }
2271 return wpi_cmd(sc, WPI_CMD_TXPOWER151, &cmd, sizeof cmd, async);
2272}
2273
2274/*
2275 * Determine TX power index for a given channel/rate combination.
2276 * This takes into account the regulatory information from EEPROM and the
2277 * current temperature.
2278 */
2279int
2280wpi_get_power_index(struct wpi_softc *sc, struct wpi_power_group *group,
2281 struct ieee80211_channel *c, int ridx)
2282{
2283/* Fixed-point arithmetic division using a n-bit fractional part. */
2284#define fdivround(a, b, n) \
2285 ((((1 << n) * (a)) / (b) + (1 << n) / 2) / (1 << n))
2286
2287/* Linear interpolation. */
2288#define interpolate(x, x1, y1, x2, y2, n) \
2289 ((y1) + fdivround(((x) - (x1)) * ((y2) - (y1)), (x2) - (x1), n))
2290
2291 struct ieee80211com *ic = &sc->sc_ic;
2292 struct wpi_power_sample *sample;
2293 int pwr, idx;
2294 u_int chan;
2295
2296 /* Get channel number. */
2297 chan = ieee80211_chan2ieee(ic, c);
2298
2299 /* Default TX power is group maximum TX power minus 3dB. */
2300 pwr = group->maxpwr / 2;
2301
2302 /* Decrease TX power for highest OFDM rates to reduce distortion. */
2303 switch (ridx) {
2304 case WPI_RIDX_OFDM365:
2305 pwr -= IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0) ? 0 : 5;
2306 break;
2307 case WPI_RIDX_OFDM486:
2308 pwr -= IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0) ? 7 : 10;
2309 break;
2310 case WPI_RIDX_OFDM547:
2311 pwr -= IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0) ? 9 : 12;
2312 break;
2313 }
2314
2315 /* Never exceed the channel maximum allowed TX power. */
2316 pwr = MIN(pwr, sc->maxpwr[chan])(((pwr)<(sc->maxpwr[chan]))?(pwr):(sc->maxpwr[chan])
)
;
2317
2318 /* Retrieve TX power index into gain tables from samples. */
2319 for (sample = group->samples; sample < &group->samples[3]; sample++)
2320 if (pwr > sample[1].power)
2321 break;
2322 /* Fixed-point linear interpolation using a 19-bit fractional part. */
2323 idx = interpolate(pwr, sample[0].power, sample[0].index,
2324 sample[1].power, sample[1].index, 19);
2325
2326 /*-
2327 * Adjust power index based on current temperature:
2328 * - if cooler than factory-calibrated: decrease output power
2329 * - if warmer than factory-calibrated: increase output power
2330 */
2331 idx -= (sc->temp - group->temp) * 11 / 100;
2332
2333 /* Decrease TX power for CCK rates (-5dB). */
2334 if (ridx >= WPI_RIDX_CCK18)
2335 idx += 10;
2336
2337 /* Make sure idx stays in a valid range. */
2338 if (idx < 0)
2339 idx = 0;
2340 else if (idx > WPI_MAX_PWR_INDEX77)
2341 idx = WPI_MAX_PWR_INDEX77;
2342 return idx;
2343
2344#undef interpolate
2345#undef fdivround
2346}
2347
2348/*
2349 * Set STA mode power saving level (between 0 and 5).
2350 * Level 0 is CAM (Continuously Aware Mode), 5 is for maximum power saving.
2351 */
2352int
2353wpi_set_pslevel(struct wpi_softc *sc, int dtim, int level, int async)
2354{
2355 struct wpi_pmgt_cmd cmd;
2356 const struct wpi_pmgt *pmgt;
2357 uint32_t max, skip_dtim;
2358 pcireg_t reg;
2359 int i;
2360
2361 /* Select which PS parameters to use. */
2362 if (dtim <= 10)
2363 pmgt = &wpi_pmgt[0][level];
2364 else
2365 pmgt = &wpi_pmgt[1][level];
2366
2367 memset(&cmd, 0, sizeof cmd)__builtin_memset((&cmd), (0), (sizeof cmd));
2368 if (level != 0) /* not CAM */
2369 cmd.flags |= htole16(WPI_PS_ALLOW_SLEEP)((__uint16_t)((1 << 0)));
2370 /* Retrieve PCIe Active State Power Management (ASPM). */
2371 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag,
2372 sc->sc_cap_off + PCI_PCIE_LCSR0x10);
2373 if (!(reg & PCI_PCIE_LCSR_ASPM_L0S0x00000001)) /* L0s Entry disabled. */
2374 cmd.flags |= htole16(WPI_PS_PCI_PMGT)((__uint16_t)((1 << 3)));
2375 cmd.rxtimeout = htole32(pmgt->rxtimeout * 1024)((__uint32_t)(pmgt->rxtimeout * 1024));
2376 cmd.txtimeout = htole32(pmgt->txtimeout * 1024)((__uint32_t)(pmgt->txtimeout * 1024));
2377
2378 if (dtim == 0) {
2379 dtim = 1;
2380 skip_dtim = 0;
2381 } else
2382 skip_dtim = pmgt->skip_dtim;
2383 if (skip_dtim != 0) {
2384 cmd.flags |= htole16(WPI_PS_SLEEP_OVER_DTIM)((__uint16_t)((1 << 2)));
2385 max = pmgt->intval[4];
2386 if (max == (uint32_t)-1)
2387 max = dtim * (skip_dtim + 1);
2388 else if (max > dtim)
2389 max = (max / dtim) * dtim;
2390 } else
2391 max = dtim;
2392 for (i = 0; i < 5; i++)
2393 cmd.intval[i] = htole32(MIN(max, pmgt->intval[i]))((__uint32_t)((((max)<(pmgt->intval[i]))?(max):(pmgt->
intval[i]))))
;
2394
2395 DPRINTF(("setting power saving level to %d\n", level));
2396 return wpi_cmd(sc, WPI_CMD_SET_POWER_MODE119, &cmd, sizeof cmd, async);
2397}
2398
2399int
2400wpi_config(struct wpi_softc *sc)
2401{
2402 struct ieee80211com *ic = &sc->sc_ic;
2403 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
2404 struct wpi_bluetooth bluetooth;
2405 struct wpi_node_info node;
2406 int error;
2407
2408 /* Set power saving level to CAM during initialization. */
2409 if ((error = wpi_set_pslevel(sc, 0, 0, 0)) != 0) {
2410 printf("%s: could not set power saving level\n",
2411 sc->sc_dev.dv_xname);
2412 return error;
2413 }
2414
2415 /* Configure bluetooth coexistence. */
2416 memset(&bluetooth, 0, sizeof bluetooth)__builtin_memset((&bluetooth), (0), (sizeof bluetooth));
2417 bluetooth.flags = WPI_BT_COEX_MODE_4WIRE3;
2418 bluetooth.lead_time = WPI_BT_LEAD_TIME_DEF30;
2419 bluetooth.max_kill = WPI_BT_MAX_KILL_DEF5;
2420 error = wpi_cmd(sc, WPI_CMD_BT_COEX155, &bluetooth, sizeof bluetooth, 0);
2421 if (error != 0) {
2422 printf("%s: could not configure bluetooth coexistence\n",
2423 sc->sc_dev.dv_xname);
2424 return error;
2425 }
2426
2427 /* Configure adapter. */
2428 memset(&sc->rxon, 0, sizeof (struct wpi_rxon))__builtin_memset((&sc->rxon), (0), (sizeof (struct wpi_rxon
)))
;
2429 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))
;
2430 IEEE80211_ADDR_COPY(sc->rxon.myaddr, ic->ic_myaddr)__builtin_memcpy((sc->rxon.myaddr), (ic->ic_myaddr), (6
))
;
2431 /* Set default channel. */
2432 sc->rxon.chan = ieee80211_chan2ieee(ic, ic->ic_ibss_chan);
2433 sc->rxon.flags = htole32(WPI_RXON_TSF)((__uint32_t)((1 << 15)));
2434 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_ibss_chan)(((ic->ic_ibss_chan)->ic_flags & 0x0080) != 0))
2435 sc->rxon.flags |= htole32(WPI_RXON_AUTO | WPI_RXON_24GHZ)((__uint32_t)((1 << 2) | (1 << 0)));
2436 switch (ic->ic_opmode) {
2437 case IEEE80211_M_STA:
2438 sc->rxon.mode = WPI_MODE_STA3;
2439 sc->rxon.filter = htole32(WPI_FILTER_MULTICAST)((__uint32_t)((1 << 2)));
2440 break;
2441 case IEEE80211_M_MONITOR:
2442 sc->rxon.mode = WPI_MODE_MONITOR6;
2443 sc->rxon.filter = htole32(WPI_FILTER_MULTICAST |((__uint32_t)((1 << 2) | (1 << 1) | (1 << 0
)))
2444 WPI_FILTER_CTL | WPI_FILTER_PROMISC)((__uint32_t)((1 << 2) | (1 << 1) | (1 << 0
)))
;
2445 break;
2446 default:
2447 /* Should not get there. */
2448 break;
2449 }
2450 sc->rxon.cck_mask = 0x0f; /* not yet negotiated */
2451 sc->rxon.ofdm_mask = 0xff; /* not yet negotiated */
2452 DPRINTF(("setting configuration\n"));
2453 error = wpi_cmd(sc, WPI_CMD_RXON16, &sc->rxon, sizeof (struct wpi_rxon),
2454 0);
2455 if (error != 0) {
2456 printf("%s: RXON command failed\n", sc->sc_dev.dv_xname);
2457 return error;
2458 }
2459
2460 /* Configuration has changed, set TX power accordingly. */
2461 if ((error = wpi_set_txpower(sc, 0)) != 0) {
2462 printf("%s: could not set TX power\n", sc->sc_dev.dv_xname);
2463 return error;
2464 }
2465
2466 /* Add broadcast node. */
2467 memset(&node, 0, sizeof node)__builtin_memset((&node), (0), (sizeof node));
2468 IEEE80211_ADDR_COPY(node.macaddr, etherbroadcastaddr)__builtin_memcpy((node.macaddr), (etherbroadcastaddr), (6));
2469 node.id = WPI_ID_BROADCAST24;
2470 node.plcp = wpi_rates[WPI_RIDX_CCK18].plcp;
2471 node.action = htole32(WPI_ACTION_SET_RATE)((__uint32_t)((1 << 2)));
2472 node.antenna = WPI_ANTENNA_BOTH((1 << 6) | (1 << 7));
2473 error = wpi_cmd(sc, WPI_CMD_ADD_NODE24, &node, sizeof node, 0);
2474 if (error != 0) {
2475 printf("%s: could not add broadcast node\n",
2476 sc->sc_dev.dv_xname);
2477 return error;
2478 }
2479
2480 if ((error = wpi_mrr_setup(sc)) != 0) {
2481 printf("%s: could not setup MRR\n", sc->sc_dev.dv_xname);
2482 return error;
2483 }
2484 return 0;
2485}
2486
2487int
2488wpi_scan(struct wpi_softc *sc, uint16_t flags)
2489{
2490 struct ieee80211com *ic = &sc->sc_ic;
2491 struct wpi_scan_hdr *hdr;
2492 struct wpi_cmd_data *tx;
2493 struct wpi_scan_essid *essid;
2494 struct wpi_scan_chan *chan;
2495 struct ieee80211_frame *wh;
2496 struct ieee80211_rateset *rs;
2497 struct ieee80211_channel *c;
2498 uint8_t *buf, *frm;
2499 int buflen, error;
2500
2501 buf = malloc(WPI_SCAN_MAXSZ((1 << 11) - 4), M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008);
2502 if (buf == NULL((void *)0)) {
2503 printf("%s: could not allocate buffer for scan command\n",
2504 sc->sc_dev.dv_xname);
2505 return ENOMEM12;
2506 }
2507 hdr = (struct wpi_scan_hdr *)buf;
2508 /*
2509 * Move to the next channel if no frames are received within 10ms
2510 * after sending the probe request.
2511 */
2512 hdr->quiet_time = htole16(10)((__uint16_t)(10)); /* timeout in milliseconds */
2513 hdr->quiet_threshold = htole16(1)((__uint16_t)(1)); /* min # of packets */
2514
2515 tx = (struct wpi_cmd_data *)(hdr + 1);
2516 tx->flags = htole32(WPI_TX_AUTO_SEQ)((__uint32_t)((1 << 13)));
2517 tx->id = WPI_ID_BROADCAST24;
2518 tx->lifetime = htole32(WPI_LIFETIME_INFINITE)((__uint32_t)(0xffffffff));
2519
2520 if (flags & IEEE80211_CHAN_5GHZ0x0100) {
2521 hdr->crc_threshold = htole16(1)((__uint16_t)(1));
2522 /* Send probe requests at 6Mbps. */
2523 tx->plcp = wpi_rates[WPI_RIDX_OFDM60].plcp;
2524 rs = &ic->ic_sup_rates[IEEE80211_MODE_11A];
2525 } else {
2526 hdr->flags = htole32(WPI_RXON_24GHZ | WPI_RXON_AUTO)((__uint32_t)((1 << 0) | (1 << 2)));
2527 /* Send probe requests at 1Mbps. */
2528 tx->plcp = wpi_rates[WPI_RIDX_CCK18].plcp;
2529 rs = &ic->ic_sup_rates[IEEE80211_MODE_11G];
2530 }
2531
2532 essid = (struct wpi_scan_essid *)(tx + 1);
2533 if (ic->ic_des_esslen != 0) {
2534 essid[0].id = IEEE80211_ELEMID_SSID;
2535 essid[0].len = ic->ic_des_esslen;
2536 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))
;
2537 }
2538 /*
2539 * Build a probe request frame. Most of the following code is a
2540 * copy & paste of what is done in net80211.
2541 */
2542 wh = (struct ieee80211_frame *)(essid + 4);
2543 wh->i_fc[0] = IEEE80211_FC0_VERSION_00x00 | IEEE80211_FC0_TYPE_MGT0x00 |
2544 IEEE80211_FC0_SUBTYPE_PROBE_REQ0x40;
2545 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS0x00;
2546 IEEE80211_ADDR_COPY(wh->i_addr1, etherbroadcastaddr)__builtin_memcpy((wh->i_addr1), (etherbroadcastaddr), (6));
2547 IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_myaddr)__builtin_memcpy((wh->i_addr2), (ic->ic_myaddr), (6));
2548 IEEE80211_ADDR_COPY(wh->i_addr3, etherbroadcastaddr)__builtin_memcpy((wh->i_addr3), (etherbroadcastaddr), (6));
2549 *(uint16_t *)&wh->i_dur[0] = 0; /* filled by HW */
2550 *(uint16_t *)&wh->i_seq[0] = 0; /* filled by HW */
2551
2552 frm = (uint8_t *)(wh + 1);
2553 frm = ieee80211_add_ssid(frm, NULL((void *)0), 0);
2554 frm = ieee80211_add_rates(frm, rs);
2555 if (rs->rs_nrates > IEEE80211_RATE_SIZE8)
2556 frm = ieee80211_add_xrates(frm, rs);
2557
2558 /* Set length of probe request. */
2559 tx->len = htole16(frm - (uint8_t *)wh)((__uint16_t)(frm - (uint8_t *)wh));
2560
2561 chan = (struct wpi_scan_chan *)frm;
2562 for (c = &ic->ic_channels[1];
2563 c <= &ic->ic_channels[IEEE80211_CHAN_MAX255]; c++) {
2564 if ((c->ic_flags & flags) != flags)
2565 continue;
2566
2567 chan->chan = ieee80211_chan2ieee(ic, c);
2568 DPRINTFN(2, ("adding channel %d\n", chan->chan));
2569 chan->flags = 0;
2570 if (!(c->ic_flags & IEEE80211_CHAN_PASSIVE0x0200))
2571 chan->flags |= WPI_CHAN_ACTIVE(1 << 0);
2572 if (ic->ic_des_esslen != 0)
2573 chan->flags |= WPI_CHAN_NPBREQS(1)(((1 << (1)) - 1) << 1);
2574 chan->dsp_gain = 0x6e;
2575 if (IEEE80211_IS_CHAN_5GHZ(c)(((c)->ic_flags & 0x0100) != 0)) {
2576 chan->rf_gain = 0x3b;
2577 chan->active = htole16(24)((__uint16_t)(24));
2578 chan->passive = htole16(110)((__uint16_t)(110));
2579 } else {
2580 chan->rf_gain = 0x28;
2581 chan->active = htole16(36)((__uint16_t)(36));
2582 chan->passive = htole16(120)((__uint16_t)(120));
2583 }
2584 hdr->nchan++;
2585 chan++;
2586 }
2587
2588 buflen = (uint8_t *)chan - buf;
2589 hdr->len = htole16(buflen)((__uint16_t)(buflen));
2590
2591 DPRINTF(("sending scan command nchan=%d\n", hdr->nchan));
2592 error = wpi_cmd(sc, WPI_CMD_SCAN128, buf, buflen, 1);
2593 free(buf, M_DEVBUF2, WPI_SCAN_MAXSZ((1 << 11) - 4));
2594 return error;
2595}
2596
2597int
2598wpi_auth(struct wpi_softc *sc)
2599{
2600 struct ieee80211com *ic = &sc->sc_ic;
2601 struct ieee80211_node *ni = ic->ic_bss;
2602 struct wpi_node_info node;
2603 int error;
2604
2605 /* Update adapter configuration. */
2606 IEEE80211_ADDR_COPY(sc->rxon.bssid, ni->ni_bssid)__builtin_memcpy((sc->rxon.bssid), (ni->ni_bssid), (6));
2607 sc->rxon.chan = ieee80211_chan2ieee(ic, ni->ni_chan);
2608 sc->rxon.flags = htole32(WPI_RXON_TSF)((__uint32_t)((1 << 15)));
2609 if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)(((ni->ni_chan)->ic_flags & 0x0080) != 0))
2610 sc->rxon.flags |= htole32(WPI_RXON_AUTO | WPI_RXON_24GHZ)((__uint32_t)((1 << 2) | (1 << 0)));
2611 if (ic->ic_flags & IEEE80211_F_SHSLOT0x00020000)
2612 sc->rxon.flags |= htole32(WPI_RXON_SHSLOT)((__uint32_t)((1 << 4)));
2613 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE0x00040000)
2614 sc->rxon.flags |= htole32(WPI_RXON_SHPREAMBLE)((__uint32_t)((1 << 5)));
2615 switch (ic->ic_curmode) {
2616 case IEEE80211_MODE_11A:
2617 sc->rxon.cck_mask = 0;
2618 sc->rxon.ofdm_mask = 0x15;
2619 break;
2620 case IEEE80211_MODE_11B:
2621 sc->rxon.cck_mask = 0x03;
2622 sc->rxon.ofdm_mask = 0;
2623 break;
2624 default: /* Assume 802.11b/g. */
2625 sc->rxon.cck_mask = 0x0f;
2626 sc->rxon.ofdm_mask = 0x15;
2627 }
2628 DPRINTF(("rxon chan %d flags %x cck %x ofdm %x\n", sc->rxon.chan,
2629 sc->rxon.flags, sc->rxon.cck_mask, sc->rxon.ofdm_mask));
2630 error = wpi_cmd(sc, WPI_CMD_RXON16, &sc->rxon, sizeof (struct wpi_rxon),
2631 1);
2632 if (error != 0) {
2633 printf("%s: RXON command failed\n", sc->sc_dev.dv_xname);
2634 return error;
2635 }
2636
2637 /* Configuration has changed, set TX power accordingly. */
2638 if ((error = wpi_set_txpower(sc, 1)) != 0) {
2639 printf("%s: could not set TX power\n", sc->sc_dev.dv_xname);
2640 return error;
2641 }
2642 /*
2643 * Reconfiguring RXON clears the firmware nodes table so we must
2644 * add the broadcast node again.
2645 */
2646 memset(&node, 0, sizeof node)__builtin_memset((&node), (0), (sizeof node));
2647 IEEE80211_ADDR_COPY(node.macaddr, etherbroadcastaddr)__builtin_memcpy((node.macaddr), (etherbroadcastaddr), (6));
2648 node.id = WPI_ID_BROADCAST24;
2649 node.plcp = (ic->ic_curmode == IEEE80211_MODE_11A) ?
2650 wpi_rates[WPI_RIDX_OFDM60].plcp : wpi_rates[WPI_RIDX_CCK18].plcp;
2651 node.action = htole32(WPI_ACTION_SET_RATE)((__uint32_t)((1 << 2)));
2652 node.antenna = WPI_ANTENNA_BOTH((1 << 6) | (1 << 7));
2653 error = wpi_cmd(sc, WPI_CMD_ADD_NODE24, &node, sizeof node, 1);
2654 if (error != 0) {
2655 printf("%s: could not add broadcast node\n",
2656 sc->sc_dev.dv_xname);
2657 return error;
2658 }
2659 return 0;
2660}
2661
2662int
2663wpi_run(struct wpi_softc *sc)
2664{
2665 struct ieee80211com *ic = &sc->sc_ic;
2666 struct ieee80211_node *ni = ic->ic_bss;
2667 struct wpi_node_info node;
2668 int error;
2669
2670 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
2671 /* Link LED blinks while monitoring. */
2672 wpi_set_led(sc, WPI_LED_LINK2, 5, 5);
2673 return 0;
2674 }
2675 if ((error = wpi_set_timing(sc, ni)) != 0) {
2676 printf("%s: could not set timing\n", sc->sc_dev.dv_xname);
2677 return error;
2678 }
2679
2680 /* Update adapter configuration. */
2681 sc->rxon.associd = htole16(IEEE80211_AID(ni->ni_associd))((__uint16_t)(((ni->ni_associd) &~ 0xc000)));
2682 /* Short preamble and slot time are negotiated when associating. */
2683 sc->rxon.flags &= ~htole32(WPI_RXON_SHPREAMBLE | WPI_RXON_SHSLOT)((__uint32_t)((1 << 5) | (1 << 4)));
2684 if (ic->ic_flags & IEEE80211_F_SHSLOT0x00020000)
2685 sc->rxon.flags |= htole32(WPI_RXON_SHSLOT)((__uint32_t)((1 << 4)));
2686 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE0x00040000)
2687 sc->rxon.flags |= htole32(WPI_RXON_SHPREAMBLE)((__uint32_t)((1 << 5)));
2688 sc->rxon.filter |= htole32(WPI_FILTER_BSS)((__uint32_t)((1 << 5)));
2689 DPRINTF(("rxon chan %d flags %x\n", sc->rxon.chan, sc->rxon.flags));
2690 error = wpi_cmd(sc, WPI_CMD_RXON16, &sc->rxon, sizeof (struct wpi_rxon),
2691 1);
2692 if (error != 0) {
2693 printf("%s: RXON command failed\n", sc->sc_dev.dv_xname);
2694 return error;
2695 }
2696
2697 /* Configuration has changed, set TX power accordingly. */
2698 if ((error = wpi_set_txpower(sc, 1)) != 0) {
2699 printf("%s: could not set TX power\n", sc->sc_dev.dv_xname);
2700 return error;
2701 }
2702
2703 /* Fake a join to init the TX rate. */
2704 ((struct wpi_node *)ni)->id = WPI_ID_BSS0;
2705 wpi_newassoc(ic, ni, 1);
2706
2707 /* Add BSS node. */
2708 memset(&node, 0, sizeof node)__builtin_memset((&node), (0), (sizeof node));
2709 IEEE80211_ADDR_COPY(node.macaddr, ni->ni_bssid)__builtin_memcpy((node.macaddr), (ni->ni_bssid), (6));
2710 node.id = WPI_ID_BSS0;
2711 node.plcp = (ic->ic_curmode == IEEE80211_MODE_11A) ?
2712 wpi_rates[WPI_RIDX_OFDM60].plcp : wpi_rates[WPI_RIDX_CCK18].plcp;
2713 node.action = htole32(WPI_ACTION_SET_RATE)((__uint32_t)((1 << 2)));
2714 node.antenna = WPI_ANTENNA_BOTH((1 << 6) | (1 << 7));
2715 DPRINTF(("adding BSS node\n"));
2716 error = wpi_cmd(sc, WPI_CMD_ADD_NODE24, &node, sizeof node, 1);
2717 if (error != 0) {
2718 printf("%s: could not add BSS node\n", sc->sc_dev.dv_xname);
2719 return error;
2720 }
2721
2722 /* Start periodic calibration timer. */
2723 sc->calib_cnt = 0;
2724 timeout_add_msec(&sc->calib_to, 500);
2725
2726 /* Link LED always on while associated. */
2727 wpi_set_led(sc, WPI_LED_LINK2, 0, 1);
2728
2729 /* Enable power-saving mode if requested by user. */
2730 if (sc->sc_ic.ic_flags & IEEE80211_F_PMGTON0x00000400)
2731 (void)wpi_set_pslevel(sc, 0, 3, 1);
2732
2733 return 0;
2734}
2735
2736/*
2737 * We support CCMP hardware encryption/decryption of unicast frames only.
2738 * HW support for TKIP really sucks. We should let TKIP die anyway.
2739 */
2740int
2741wpi_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
2742 struct ieee80211_key *k)
2743{
2744 struct wpi_softc *sc = ic->ic_softcic_ac.ac_if.if_softc;
2745 struct wpi_node *wn = (void *)ni;
2746 struct wpi_node_info node;
2747 uint16_t kflags;
2748
2749 if ((k->k_flags & IEEE80211_KEY_GROUP0x00000001) ||
2750 k->k_cipher != IEEE80211_CIPHER_CCMP)
2751 return ieee80211_set_key(ic, ni, k);
2752
2753 kflags = WPI_KFLAG_CCMP(1 << 1) | WPI_KFLAG_KID(k->k_id)((k->k_id) << 8);
2754 memset(&node, 0, sizeof node)__builtin_memset((&node), (0), (sizeof node));
2755 node.id = wn->id;
2756 node.control = WPI_NODE_UPDATE(1 << 0);
2757 node.flags = WPI_FLAG_SET_KEY(1 << 0);
2758 node.kflags = htole16(kflags)((__uint16_t)(kflags));
2759 memcpy(node.key, k->k_key, k->k_len)__builtin_memcpy((node.key), (k->k_key), (k->k_len));
2760 DPRINTF(("set key id=%d for node %d\n", k->k_id, node.id));
2761 return wpi_cmd(sc, WPI_CMD_ADD_NODE24, &node, sizeof node, 1);
2762}
2763
2764void
2765wpi_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
2766 struct ieee80211_key *k)
2767{
2768 struct wpi_softc *sc = ic->ic_softcic_ac.ac_if.if_softc;
2769 struct wpi_node *wn = (void *)ni;
2770 struct wpi_node_info node;
2771
2772 if ((k->k_flags & IEEE80211_KEY_GROUP0x00000001) ||
2773 k->k_cipher != IEEE80211_CIPHER_CCMP) {
2774 /* See comment about other ciphers above. */
2775 ieee80211_delete_key(ic, ni, k);
2776 return;
2777 }
2778 if (ic->ic_state != IEEE80211_S_RUN)
2779 return; /* Nothing to do. */
2780 memset(&node, 0, sizeof node)__builtin_memset((&node), (0), (sizeof node));
2781 node.id = wn->id;
2782 node.control = WPI_NODE_UPDATE(1 << 0);
2783 node.flags = WPI_FLAG_SET_KEY(1 << 0);
2784 node.kflags = 0;
2785 DPRINTF(("delete keys for node %d\n", node.id));
2786 (void)wpi_cmd(sc, WPI_CMD_ADD_NODE24, &node, sizeof node, 1);
2787}
2788
2789int
2790wpi_post_alive(struct wpi_softc *sc)
2791{
2792 int ntries, error;
2793
2794 /* Check (again) that the radio is not disabled. */
2795 if ((error = wpi_nic_lock(sc)) != 0)
2796 return error;
2797 /* NB: Runtime firmware must be up and running. */
2798 if (!(wpi_prph_read(sc, WPI_APMG_RFKILL0x3014) & 1)) {
2799 printf("%s: radio is disabled by hardware switch\n",
2800 sc->sc_dev.dv_xname);
2801 wpi_nic_unlock(sc);
2802 return EPERM1; /* :-) */
2803 }
2804 wpi_nic_unlock(sc);
2805
2806 /* Wait for thermal sensor to calibrate. */
2807 for (ntries = 0; ntries < 1000; ntries++) {
2808 if ((sc->temp = (int)WPI_READ(sc, WPI_UCODE_GP2)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x060))))) != 0)
2809 break;
2810 DELAY(10)(*delay_func)(10);
2811 }
2812 if (ntries == 1000) {
2813 printf("%s: timeout waiting for thermal sensor calibration\n",
2814 sc->sc_dev.dv_xname);
2815 return ETIMEDOUT60;
2816 }
2817 DPRINTF(("temperature %d\n", sc->temp));
2818 return 0;
2819}
2820
2821/*
2822 * The firmware boot code is small and is intended to be copied directly into
2823 * the NIC internal memory (no DMA transfer.)
2824 */
2825int
2826wpi_load_bootcode(struct wpi_softc *sc, const uint8_t *ucode, int size)
2827{
2828 int error, ntries;
2829
2830 size /= sizeof (uint32_t);
2831
2832 if ((error = wpi_nic_lock(sc)) != 0)
2833 return error;
2834
2835 /* Copy microcode image into NIC memory. */
2836 wpi_prph_write_region_4(sc, WPI_BSM_SRAM_BASE0x3800,
2837 (const uint32_t *)ucode, size);
2838
2839 wpi_prph_write(sc, WPI_BSM_WR_MEM_SRC0x3404, 0);
2840 wpi_prph_write(sc, WPI_BSM_WR_MEM_DST0x3408, WPI_FW_TEXT_BASE0x00000000);
2841 wpi_prph_write(sc, WPI_BSM_WR_DWCOUNT0x340c, size);
2842
2843 /* Start boot load now. */
2844 wpi_prph_write(sc, WPI_BSM_WR_CTRL0x3400, WPI_BSM_WR_CTRL_START(1U << 31));
2845
2846 /* Wait for transfer to complete. */
2847 for (ntries = 0; ntries < 1000; ntries++) {
2848 if (!(wpi_prph_read(sc, WPI_BSM_WR_CTRL0x3400) &
2849 WPI_BSM_WR_CTRL_START(1U << 31)))
2850 break;
2851 DELAY(10)(*delay_func)(10);
2852 }
2853 if (ntries == 1000) {
2854 printf("%s: could not load boot firmware\n",
2855 sc->sc_dev.dv_xname);
2856 wpi_nic_unlock(sc);
2857 return ETIMEDOUT60;
2858 }
2859
2860 /* Enable boot after power up. */
2861 wpi_prph_write(sc, WPI_BSM_WR_CTRL0x3400, WPI_BSM_WR_CTRL_START_EN(1U << 30));
2862
2863 wpi_nic_unlock(sc);
2864 return 0;
2865}
2866
2867int
2868wpi_load_firmware(struct wpi_softc *sc)
2869{
2870 struct wpi_fw_info *fw = &sc->fw;
2871 struct wpi_dma_info *dma = &sc->fw_dma;
2872 int error;
2873
2874 /* Copy initialization sections into pre-allocated DMA-safe memory. */
2875 memcpy(dma->vaddr, fw->init.data, fw->init.datasz)__builtin_memcpy((dma->vaddr), (fw->init.data), (fw->
init.datasz))
;
2876 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))
2877 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma->
map), (0), (fw->init.datasz), (0x04))
;
2878 memcpy(dma->vaddr + WPI_FW_DATA_MAXSZ,__builtin_memcpy((dma->vaddr + (32 * 1024)), (fw->init.
text), (fw->init.textsz))
2879 fw->init.text, fw->init.textsz)__builtin_memcpy((dma->vaddr + (32 * 1024)), (fw->init.
text), (fw->init.textsz))
;
2880 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))
2881 fw->init.textsz, BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma->
map), ((32 * 1024)), (fw->init.textsz), (0x04))
;
2882
2883 /* Tell adapter where to find initialization sections. */
2884 if ((error = wpi_nic_lock(sc)) != 0)
2885 return error;
2886 wpi_prph_write(sc, WPI_BSM_DRAM_DATA_ADDR0x3498, dma->paddr);
2887 wpi_prph_write(sc, WPI_BSM_DRAM_DATA_SIZE0x349c, fw->init.datasz);
2888 wpi_prph_write(sc, WPI_BSM_DRAM_TEXT_ADDR0x3490,
2889 dma->paddr + WPI_FW_DATA_MAXSZ(32 * 1024));
2890 wpi_prph_write(sc, WPI_BSM_DRAM_TEXT_SIZE0x3494, fw->init.textsz);
2891 wpi_nic_unlock(sc);
2892
2893 /* Load firmware boot code. */
2894 error = wpi_load_bootcode(sc, fw->boot.text, fw->boot.textsz);
2895 if (error != 0) {
2896 printf("%s: could not load boot firmware\n",
2897 sc->sc_dev.dv_xname);
2898 return error;
2899 }
2900 /* Now press "execute". */
2901 WPI_WRITE(sc, WPI_RESET, 0)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x020)), ((
0))))
;
2902
2903 /* Wait at most one second for first alive notification. */
2904 if ((error = tsleep_nsec(sc, PCATCH0x100, "wpiinit", SEC_TO_NSEC(1))) != 0) {
2905 printf("%s: timeout waiting for adapter to initialize\n",
2906 sc->sc_dev.dv_xname);
2907 return error;
2908 }
2909
2910 /* Copy runtime sections into pre-allocated DMA-safe memory. */
2911 memcpy(dma->vaddr, fw->main.data, fw->main.datasz)__builtin_memcpy((dma->vaddr), (fw->main.data), (fw->
main.datasz))
;
2912 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))
2913 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma->
map), (0), (fw->main.datasz), (0x04))
;
2914 memcpy(dma->vaddr + WPI_FW_DATA_MAXSZ,__builtin_memcpy((dma->vaddr + (32 * 1024)), (fw->main.
text), (fw->main.textsz))
2915 fw->main.text, fw->main.textsz)__builtin_memcpy((dma->vaddr + (32 * 1024)), (fw->main.
text), (fw->main.textsz))
;
2916 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))
2917 fw->main.textsz, BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dma->
map), ((32 * 1024)), (fw->main.textsz), (0x04))
;
2918
2919 /* Tell adapter where to find runtime sections. */
2920 if ((error = wpi_nic_lock(sc)) != 0)
2921 return error;
2922 wpi_prph_write(sc, WPI_BSM_DRAM_DATA_ADDR0x3498, dma->paddr);
2923 wpi_prph_write(sc, WPI_BSM_DRAM_DATA_SIZE0x349c, fw->main.datasz);
2924 wpi_prph_write(sc, WPI_BSM_DRAM_TEXT_ADDR0x3490,
2925 dma->paddr + WPI_FW_DATA_MAXSZ(32 * 1024));
2926 wpi_prph_write(sc, WPI_BSM_DRAM_TEXT_SIZE0x3494,
2927 WPI_FW_UPDATED(1U << 31) | fw->main.textsz);
2928 wpi_nic_unlock(sc);
2929
2930 return 0;
2931}
2932
2933int
2934wpi_read_firmware(struct wpi_softc *sc)
2935{
2936 struct wpi_fw_info *fw = &sc->fw;
2937 const struct wpi_firmware_hdr *hdr;
2938 int error;
2939
2940 /* Read firmware image from filesystem. */
2941 if ((error = loadfirmware("wpi-3945abg", &fw->data, &fw->datalen)) != 0) {
2942 printf("%s: error, %d, could not read firmware %s\n",
2943 sc->sc_dev.dv_xname, error, "wpi-3945abg");
2944 return error;
2945 }
2946 if (fw->datalen < sizeof (*hdr)) {
2947 printf("%s: truncated firmware header: %zu bytes\n",
2948 sc->sc_dev.dv_xname, fw->datalen);
2949 free(fw->data, M_DEVBUF2, fw->datalen);
2950 return EINVAL22;
2951 }
2952 /* Extract firmware header information. */
2953 hdr = (struct wpi_firmware_hdr *)fw->data;
2954 fw->main.textsz = letoh32(hdr->main_textsz)((__uint32_t)(hdr->main_textsz));
2955 fw->main.datasz = letoh32(hdr->main_datasz)((__uint32_t)(hdr->main_datasz));
2956 fw->init.textsz = letoh32(hdr->init_textsz)((__uint32_t)(hdr->init_textsz));
2957 fw->init.datasz = letoh32(hdr->init_datasz)((__uint32_t)(hdr->init_datasz));
2958 fw->boot.textsz = letoh32(hdr->boot_textsz)((__uint32_t)(hdr->boot_textsz));
2959 fw->boot.datasz = 0;
2960
2961 /* Sanity-check firmware header. */
2962 if (fw->main.textsz > WPI_FW_TEXT_MAXSZ(80 * 1024) ||
2963 fw->main.datasz > WPI_FW_DATA_MAXSZ(32 * 1024) ||
2964 fw->init.textsz > WPI_FW_TEXT_MAXSZ(80 * 1024) ||
2965 fw->init.datasz > WPI_FW_DATA_MAXSZ(32 * 1024) ||
2966 fw->boot.textsz > WPI_FW_BOOT_TEXT_MAXSZ1024 ||
2967 (fw->boot.textsz & 3) != 0) {
2968 printf("%s: invalid firmware header\n", sc->sc_dev.dv_xname);
2969 free(fw->data, M_DEVBUF2, fw->datalen);
2970 return EINVAL22;
2971 }
2972
2973 /* Check that all firmware sections fit. */
2974 if (fw->datalen < sizeof (*hdr) + fw->main.textsz + fw->main.datasz +
2975 fw->init.textsz + fw->init.datasz + fw->boot.textsz) {
2976 printf("%s: firmware file too short: %zu bytes\n",
2977 sc->sc_dev.dv_xname, fw->datalen);
2978 free(fw->data, M_DEVBUF2, fw->datalen);
2979 return EINVAL22;
2980 }
2981
2982 /* Get pointers to firmware sections. */
2983 fw->main.text = (const uint8_t *)(hdr + 1);
2984 fw->main.data = fw->main.text + fw->main.textsz;
2985 fw->init.text = fw->main.data + fw->main.datasz;
2986 fw->init.data = fw->init.text + fw->init.textsz;
2987 fw->boot.text = fw->init.data + fw->init.datasz;
2988
2989 return 0;
2990}
2991
2992int
2993wpi_clock_wait(struct wpi_softc *sc)
2994{
2995 int ntries;
2996
2997 /* Set "initialization complete" bit. */
2998 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))))))
;
2999
3000 /* Wait for clock stabilization. */
3001 for (ntries = 0; ntries < 25000; ntries++) {
3002 if (WPI_READ(sc, WPI_GP_CNTRL)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x024)))) & WPI_GP_CNTRL_MAC_CLOCK_READY(1 << 0))
3003 return 0;
3004 DELAY(100)(*delay_func)(100);
3005 }
3006 printf("%s: timeout waiting for clock stabilization\n",
3007 sc->sc_dev.dv_xname);
3008 return ETIMEDOUT60;
3009}
3010
3011int
3012wpi_apm_init(struct wpi_softc *sc)
3013{
3014 int error;
3015
3016 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))))))
;
3017 /* Disable L0s. */
3018 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))))))
;
3019
3020 if ((error = wpi_clock_wait(sc)) != 0)
3021 return error;
3022
3023 if ((error = wpi_nic_lock(sc)) != 0)
3024 return error;
3025 /* Enable DMA. */
3026 wpi_prph_write(sc, WPI_APMG_CLK_ENA0x3004,
3027 WPI_APMG_CLK_DMA_CLK_RQT(1 << 9) | WPI_APMG_CLK_BSM_CLK_RQT(1 << 11));
3028 DELAY(20)(*delay_func)(20);
3029 /* Disable L1. */
3030 wpi_prph_setbits(sc, WPI_APMG_PCI_STT0x3010, WPI_APMG_PCI_STT_L1A_DIS(1 << 11));
3031 wpi_nic_unlock(sc);
3032
3033 return 0;
3034}
3035
3036void
3037wpi_apm_stop_master(struct wpi_softc *sc)
3038{
3039 int ntries;
3040
3041 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))))))
;
3042
3043 if ((WPI_READ(sc, WPI_GP_CNTRL)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x024)))) & WPI_GP_CNTRL_PS_MASK(7 << 24)) ==
3044 WPI_GP_CNTRL_MAC_PS(4 << 24))
3045 return; /* Already asleep. */
3046
3047 for (ntries = 0; ntries < 100; ntries++) {
3048 if (WPI_READ(sc, WPI_RESET)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x020)))) & WPI_RESET_MASTER_DISABLED(1 << 8))
3049 return;
3050 DELAY(10)(*delay_func)(10);
3051 }
3052 printf("%s: timeout waiting for master\n", sc->sc_dev.dv_xname);
3053}
3054
3055void
3056wpi_apm_stop(struct wpi_softc *sc)
3057{
3058 wpi_apm_stop_master(sc);
3059 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))))))
;
3060}
3061
3062void
3063wpi_nic_config(struct wpi_softc *sc)
3064{
3065 pcireg_t reg;
3066 uint8_t rev;
3067
3068 /* Voodoo from the reference driver. */
3069 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_CLASS_REG0x08);
3070 rev = PCI_REVISION(reg)(((reg) >> 0) & 0xff);
3071 if ((rev & 0xc0) == 0x40)
3072 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))))))
;
3073 else if (!(rev & 0x80))
3074 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))))))
;
3075
3076 if (sc->cap == 0x80)
3077 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))))))
;
3078
3079 if ((letoh16(sc->rev)((__uint16_t)(sc->rev)) & 0xf0) == 0xd0)
3080 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))))))
;
3081 else
3082 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))))))
;
3083
3084 if (sc->type > 1)
3085 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))))))
;
3086}
3087
3088int
3089wpi_hw_init(struct wpi_softc *sc)
3090{
3091 int chnl, ntries, error;
3092
3093 /* Clear pending interrupts. */
3094 WPI_WRITE(sc, WPI_INT, 0xffffffff)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x008)), ((
0xffffffff))))
;
3095
3096 if ((error = wpi_apm_init(sc)) != 0) {
3097 printf("%s: could not power ON adapter\n",
3098 sc->sc_dev.dv_xname);
3099 return error;
3100 }
3101
3102 /* Select VMAIN power source. */
3103 if ((error = wpi_nic_lock(sc)) != 0)
3104 return error;
3105 wpi_prph_clrbits(sc, WPI_APMG_PS0x300c, WPI_APMG_PS_PWR_SRC_MASK(3 << 24));
3106 wpi_nic_unlock(sc);
3107 /* Spin until VMAIN gets selected. */
3108 for (ntries = 0; ntries < 5000; ntries++) {
3109 if (WPI_READ(sc, WPI_GPIO_IN)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x018)))) & WPI_GPIO_IN_VMAIN(1 << 9))
3110 break;
3111 DELAY(10)(*delay_func)(10);
3112 }
3113 if (ntries == 5000) {
3114 printf("%s: timeout selecting power source\n",
3115 sc->sc_dev.dv_xname);
3116 return ETIMEDOUT60;
3117 }
3118
3119 /* Perform adapter initialization. */
3120 (void)wpi_nic_config(sc);
3121
3122 /* Initialize RX ring. */
3123 if ((error = wpi_nic_lock(sc)) != 0)
3124 return error;
3125 /* Set physical address of RX ring. */
3126 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))))
;
3127 /* Set physical address of RX read pointer. */
3128 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)))))
3129 offsetof(struct wpi_shared, next))(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xc24)), ((
sc->shared_dma.paddr + __builtin_offsetof(struct wpi_shared
, next)))))
;
3130 WPI_WRITE(sc, WPI_FH_RX_WPTR, 0)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xc20)), ((
0))))
;
3131 /* Enable RX. */
3132 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
)))))
3133 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
)))))
3134 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
)))))
3135 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
)))))
3136 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
)))))
3137 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
)))))
3138 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
)))))
3139 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
)))))
;
3140 (void)WPI_READ(sc, WPI_FH_RSSR_TBL)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0xcc0)))); /* barrier */
3141 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))))
;
3142 wpi_nic_unlock(sc);
3143
3144 /* Initialize TX rings. */
3145 if ((error = wpi_nic_lock(sc)) != 0)
3146 return error;
3147 wpi_prph_write(sc, WPI_ALM_SCHED_MODE0x2e00, 2); /* bypass mode */
3148 wpi_prph_write(sc, WPI_ALM_SCHED_ARASTAT0x2e04, 1); /* enable RA0 */
3149 /* Enable all 6 TX rings. */
3150 wpi_prph_write(sc, WPI_ALM_SCHED_TXFACT0x2e10, 0x3f);
3151 wpi_prph_write(sc, WPI_ALM_SCHED_SBYPASS_MODE10x2e2c, 0x10000);
3152 wpi_prph_write(sc, WPI_ALM_SCHED_SBYPASS_MODE20x2e30, 0x30002);
3153 wpi_prph_write(sc, WPI_ALM_SCHED_TXF4MF0x2e14, 4);
3154 wpi_prph_write(sc, WPI_ALM_SCHED_TXF5MF0x2e20, 5);
3155 /* Set physical address of TX rings. */
3156 WPI_WRITE(sc, WPI_FH_TX_BASE, sc->shared_dma.paddr)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xe80)), ((
sc->shared_dma.paddr))))
;
3157 WPI_WRITE(sc, WPI_FH_MSG_CONFIG, 0xffff05a5)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0xe88)), ((
0xffff05a5))))
;
3158
3159 /* Enable all DMA channels. */
3160 for (chnl = 0; chnl < WPI_NDMACHNLS6; chnl++) {
3161 WPI_WRITE(sc, WPI_FH_CBBC_CTRL(chnl), 0)(((sc)->sc_st)->write_4(((sc)->sc_sh), (((0x940 + (chnl
) * 8))), ((0))))
;
3162 WPI_WRITE(sc, WPI_FH_CBBC_BASE(chnl), 0)(((sc)->sc_st)->write_4(((sc)->sc_sh), (((0x944 + (chnl
) * 8))), ((0))))
;
3163 WPI_WRITE(sc, WPI_FH_TX_CONFIG(chnl), 0x80200008)(((sc)->sc_st)->write_4(((sc)->sc_sh), (((0xd00 + (chnl
) * 32))), ((0x80200008))))
;
3164 }
3165 wpi_nic_unlock(sc);
3166 (void)WPI_READ(sc, WPI_FH_TX_BASE)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0xe80)))); /* barrier */
3167
3168 /* Clear "radio off" and "commands blocked" bits. */
3169 WPI_WRITE(sc, WPI_UCODE_GP1_CLR, WPI_UCODE_GP1_RFKILL)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x05c)), ((
(1 << 1)))))
;
3170 WPI_WRITE(sc, WPI_UCODE_GP1_CLR, WPI_UCODE_GP1_CMD_BLOCKED)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x05c)), ((
(1 << 2)))))
;
3171
3172 /* Clear pending interrupts. */
3173 WPI_WRITE(sc, WPI_INT, 0xffffffff)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x008)), ((
0xffffffff))))
;
3174 /* Enable interrupts. */
3175 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))))))
;
3176
3177 /* _Really_ make sure "radio off" bit is cleared! */
3178 WPI_WRITE(sc, WPI_UCODE_GP1_CLR, WPI_UCODE_GP1_RFKILL)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x05c)), ((
(1 << 1)))))
;
3179 WPI_WRITE(sc, WPI_UCODE_GP1_CLR, WPI_UCODE_GP1_RFKILL)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x05c)), ((
(1 << 1)))))
;
3180
3181 if ((error = wpi_load_firmware(sc)) != 0) {
3182 printf("%s: could not load firmware\n", sc->sc_dev.dv_xname);
3183 return error;
3184 }
3185 /* Wait at most one second for firmware alive notification. */
3186 if ((error = tsleep_nsec(sc, PCATCH0x100, "wpiinit", SEC_TO_NSEC(1))) != 0) {
3187 printf("%s: timeout waiting for adapter to initialize\n",
3188 sc->sc_dev.dv_xname);
3189 return error;
3190 }
3191 /* Do post-firmware initialization. */
3192 return wpi_post_alive(sc);
3193}
3194
3195void
3196wpi_hw_stop(struct wpi_softc *sc)
3197{
3198 int chnl, qid, ntries;
3199 uint32_t tmp;
3200
3201 WPI_WRITE(sc, WPI_RESET, WPI_RESET_NEVO)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x020)), ((
(1 << 0)))))
;
3202
3203 /* Disable interrupts. */
3204 WPI_WRITE(sc, WPI_MASK, 0)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x00c)), ((
0))))
;
3205 WPI_WRITE(sc, WPI_INT, 0xffffffff)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x008)), ((
0xffffffff))))
;
3206 WPI_WRITE(sc, WPI_FH_INT, 0xffffffff)(((sc)->sc_st)->write_4(((sc)->sc_sh), ((0x010)), ((
0xffffffff))))
;
3207
3208 /* Make sure we no longer hold the NIC lock. */
3209 wpi_nic_unlock(sc);
3210
3211 if (wpi_nic_lock(sc) == 0) {
3212 /* Stop TX scheduler. */
3213 wpi_prph_write(sc, WPI_ALM_SCHED_MODE0x2e00, 0);
3214 wpi_prph_write(sc, WPI_ALM_SCHED_TXFACT0x2e10, 0);
3215
3216 /* Stop all DMA channels. */
3217 for (chnl = 0; chnl < WPI_NDMACHNLS6; chnl++) {
3218 WPI_WRITE(sc, WPI_FH_TX_CONFIG(chnl), 0)(((sc)->sc_st)->write_4(((sc)->sc_sh), (((0xd00 + (chnl
) * 32))), ((0))))
;
3219 for (ntries = 0; ntries < 100; ntries++) {
3220 tmp = WPI_READ(sc, WPI_FH_TX_STATUS)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0xe90))));
3221 if ((tmp & WPI_FH_TX_STATUS_IDLE(chnl)(1 << ((chnl) + 24) | 1 << ((chnl) + 16))) ==
3222 WPI_FH_TX_STATUS_IDLE(chnl)(1 << ((chnl) + 24) | 1 << ((chnl) + 16)))
3223 break;
3224 DELAY(10)(*delay_func)(10);
3225 }
3226 }
3227 wpi_nic_unlock(sc);
3228 }
3229
3230 /* Stop RX ring. */
3231 wpi_reset_rx_ring(sc, &sc->rxq);
3232
3233 /* Reset all TX rings. */
3234 for (qid = 0; qid < WPI_NTXQUEUES8; qid++)
3235 wpi_reset_tx_ring(sc, &sc->txq[qid]);
3236
3237 if (wpi_nic_lock(sc) == 0) {
3238 wpi_prph_write(sc, WPI_APMG_CLK_DIS0x3008, WPI_APMG_CLK_DMA_CLK_RQT(1 << 9));
3239 wpi_nic_unlock(sc);
3240 }
3241 DELAY(5)(*delay_func)(5);
3242 /* Power OFF adapter. */
3243 wpi_apm_stop(sc);
3244}
3245
3246int
3247wpi_init(struct ifnet *ifp)
3248{
3249 struct wpi_softc *sc = ifp->if_softc;
3250 struct ieee80211com *ic = &sc->sc_ic;
3251 int error;
3252
3253#ifdef notyet
3254 /* Check that the radio is not disabled by hardware switch. */
3255 if (!(WPI_READ(sc, WPI_GP_CNTRL)(((sc)->sc_st)->read_4(((sc)->sc_sh), ((0x024)))) & WPI_GP_CNTRL_RFKILL(1 << 27))) {
3256 printf("%s: radio is disabled by hardware switch\n",
3257 sc->sc_dev.dv_xname);
3258 error = EPERM1; /* :-) */
3259 goto fail;
3260 }
3261#endif
3262 /* Read firmware images from the filesystem. */
3263 if ((error = wpi_read_firmware(sc)) != 0) {
3264 printf("%s: could not read firmware\n", sc->sc_dev.dv_xname);
3265 goto fail;
3266 }
3267
3268 /* Initialize hardware and upload firmware. */
3269 error = wpi_hw_init(sc);
3270 free(sc->fw.data, M_DEVBUF2, sc->fw.datalen);
3271 if (error != 0) {
3272 printf("%s: could not initialize hardware\n",
3273 sc->sc_dev.dv_xname);
3274 goto fail;
3275 }
3276
3277 /* Configure adapter now that it is ready. */
3278 if ((error = wpi_config(sc)) != 0) {
3279 printf("%s: could not configure device\n",
3280 sc->sc_dev.dv_xname);
3281 goto fail;
3282 }
3283
3284 ifq_clr_oactive(&ifp->if_snd);
3285 ifp->if_flags |= IFF_RUNNING0x40;
3286
3287 if (ic->ic_opmode != IEEE80211_M_MONITOR)
3288 ieee80211_begin_scan(ifp);
3289 else
3290 ieee80211_new_state(ic, IEEE80211_S_RUN, -1)(((ic)->ic_newstate)((ic), (IEEE80211_S_RUN), (-1)));
3291
3292 return 0;
3293
3294fail: wpi_stop(ifp, 1);
3295 return error;
3296}
3297
3298void
3299wpi_stop(struct ifnet *ifp, int disable)
3300{
3301 struct wpi_softc *sc = ifp->if_softc;
3302 struct ieee80211com *ic = &sc->sc_ic;
3303
3304 ifp->if_timer = sc->sc_tx_timer = 0;
3305 ifp->if_flags &= ~IFF_RUNNING0x40;
3306 ifq_clr_oactive(&ifp->if_snd);
3307
3308 ieee80211_new_state(ic, IEEE80211_S_INIT, -1)(((ic)->ic_newstate)((ic), (IEEE80211_S_INIT), (-1)));
3309
3310 /* Power OFF hardware. */
3311 wpi_hw_stop(sc);
3312}