Bug Summary

File:dev/pcmcia/if_malo.c
Warning:line 898, column 2
Value stored to 'val16' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name if_malo.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/dev/pcmcia/if_malo.c
1/* $OpenBSD: if_malo.c,v 1.97 2022/01/09 05:42:58 jsg Exp $ */
2
3/*
4 * Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include "bpfilter.h"
20
21#include <sys/param.h>
22#include <sys/systm.h>
23#include <sys/kernel.h>
24#include <sys/device.h>
25#include <sys/timeout.h>
26#include <sys/socket.h>
27#include <sys/tree.h>
28#include <sys/malloc.h>
29#include <sys/sockio.h>
30#include <sys/mbuf.h>
31
32#if NBPFILTER1 > 0
33#include <net/bpf.h>
34#endif
35
36#include <net/if.h>
37#include <net/if_dl.h>
38#include <net/if_media.h>
39#include <net/if_llc.h>
40
41#include <netinet/in.h>
42#include <netinet/if_ether.h>
43
44#include <net80211/ieee80211_var.h>
45#include <net80211/ieee80211_radiotap.h>
46
47#include <machine/bus.h>
48#include <machine/intr.h>
49
50#include <dev/pcmcia/pcmciavar.h>
51#include <dev/pcmcia/pcmciadevs.h>
52
53#include <dev/pcmcia/if_malovar.h>
54#include <dev/pcmcia/if_maloreg.h>
55
56/*
57 * Driver for the Marvell 88W8385 chip (Compact Flash).
58 */
59
60#ifdef CMALO_DEBUG
61int cmalo_d = 1;
62#define DPRINTF(l, x...) do { if ((l) <= cmalo_d) printf(x); } while (0)
63#else
64#define DPRINTF(l, x...)
65#endif
66
67int malo_pcmcia_match(struct device *, void *, void *);
68void malo_pcmcia_attach(struct device *, struct device *, void *);
69int malo_pcmcia_detach(struct device *, int);
70int malo_pcmcia_activate(struct device *, int);
71void malo_pcmcia_wakeup(struct malo_softc *);
72
73void cmalo_attach(struct device *);
74int cmalo_ioctl(struct ifnet *, u_long, caddr_t);
75int cmalo_fw_alloc(struct malo_softc *);
76void cmalo_fw_free(struct malo_softc *);
77int cmalo_fw_load_helper(struct malo_softc *);
78int cmalo_fw_load_main(struct malo_softc *);
79int cmalo_init(struct ifnet *);
80void cmalo_stop(struct malo_softc *);
81int cmalo_media_change(struct ifnet *);
82int cmalo_newstate(struct ieee80211com *, enum ieee80211_state, int);
83void cmalo_detach(void *);
84int cmalo_intr(void *);
85void cmalo_intr_mask(struct malo_softc *, int);
86void cmalo_rx(struct malo_softc *);
87void cmalo_start(struct ifnet *);
88void cmalo_watchdog(struct ifnet *);
89int cmalo_tx(struct malo_softc *, struct mbuf *);
90void cmalo_tx_done(struct malo_softc *);
91void cmalo_event(struct malo_softc *);
92void cmalo_select_network(struct malo_softc *);
93void cmalo_reflect_network(struct malo_softc *);
94int cmalo_wep(struct malo_softc *);
95int cmalo_rate2bitmap(int);
96
97void cmalo_hexdump(void *, int);
98int cmalo_cmd_get_hwspec(struct malo_softc *);
99int cmalo_cmd_rsp_hwspec(struct malo_softc *);
100int cmalo_cmd_set_reset(struct malo_softc *);
101int cmalo_cmd_set_scan(struct malo_softc *);
102int cmalo_cmd_rsp_scan(struct malo_softc *);
103int cmalo_parse_elements(struct malo_softc *, void *, int, int);
104int cmalo_cmd_set_auth(struct malo_softc *);
105int cmalo_cmd_set_wep(struct malo_softc *, uint16_t,
106 struct ieee80211_key *);
107int cmalo_cmd_set_snmp(struct malo_softc *, uint16_t);
108int cmalo_cmd_set_radio(struct malo_softc *, uint16_t);
109int cmalo_cmd_set_channel(struct malo_softc *, uint16_t);
110int cmalo_cmd_set_txpower(struct malo_softc *, int16_t);
111int cmalo_cmd_set_antenna(struct malo_softc *, uint16_t);
112int cmalo_cmd_set_macctrl(struct malo_softc *);
113int cmalo_cmd_set_macaddr(struct malo_softc *, uint8_t *);
114int cmalo_cmd_set_assoc(struct malo_softc *);
115int cmalo_cmd_rsp_assoc(struct malo_softc *);
116int cmalo_cmd_set_80211d(struct malo_softc *);
117int cmalo_cmd_set_bgscan_config(struct malo_softc *);
118int cmalo_cmd_set_bgscan_query(struct malo_softc *);
119int cmalo_cmd_set_rate(struct malo_softc *, int);
120int cmalo_cmd_request(struct malo_softc *, uint16_t, int);
121int cmalo_cmd_response(struct malo_softc *);
122
123/*
124 * PCMCIA bus.
125 */
126struct malo_pcmcia_softc {
127 struct malo_softc sc_malo;
128
129 struct pcmcia_function *sc_pf;
130 struct pcmcia_io_handle sc_pcioh;
131 int sc_io_window;
132 void *sc_ih;
133};
134
135struct cfattach malo_pcmcia_ca = {
136 sizeof(struct malo_pcmcia_softc),
137 malo_pcmcia_match,
138 malo_pcmcia_attach,
139 malo_pcmcia_detach,
140 malo_pcmcia_activate
141};
142
143int
144malo_pcmcia_match(struct device *parent, void *match, void *aux)
145{
146 struct pcmcia_attach_args *pa = aux;
147
148 if (pa->manufacturer == PCMCIA_VENDOR_AMBICOM0x02df &&
149 pa->product == PCMCIA_PRODUCT_AMBICOM_WL54CF0x8103)
150 return (1);
151
152 return (0);
153}
154
155void
156malo_pcmcia_attach(struct device *parent, struct device *self, void *aux)
157{
158 struct malo_pcmcia_softc *psc = (struct malo_pcmcia_softc *)self;
159 struct malo_softc *sc = &psc->sc_malo;
160 struct pcmcia_attach_args *pa = aux;
161 struct pcmcia_config_entry *cfe;
162 const char *intrstr = NULL((void *)0);
163
164 psc->sc_pf = pa->pf;
165 cfe = SIMPLEQ_FIRST(&pa->pf->cfe_head)((&pa->pf->cfe_head)->sqh_first);
166
167 /* enable card */
168 pcmcia_function_init(psc->sc_pf, cfe);
169 if (pcmcia_function_enable(psc->sc_pf)) {
170 printf(": can't enable function\n");
171 return;
172 }
173
174 /* allocate I/O space */
175 if (pcmcia_io_alloc(psc->sc_pf, 0,(((*((psc->sc_pf)->sc->pct)->io_alloc)((psc->sc_pf
->sc->pch), ((0)), ((cfe->iospace[0].length)), ((cfe
->iospace[0].length)), ((&psc->sc_pcioh)))))
176 cfe->iospace[0].length, cfe->iospace[0].length, &psc->sc_pcioh)(((*((psc->sc_pf)->sc->pct)->io_alloc)((psc->sc_pf
->sc->pch), ((0)), ((cfe->iospace[0].length)), ((cfe
->iospace[0].length)), ((&psc->sc_pcioh)))))
) {
177 printf(": can't allocate i/o space\n");
178 pcmcia_function_disable(psc->sc_pf);
179 return;
180 }
181
182 /* map I/O space */
183 if (pcmcia_io_map(psc->sc_pf, PCMCIA_WIDTH_IO162, 0,
184 cfe->iospace[0].length, &psc->sc_pcioh, &psc->sc_io_window)) {
185 printf(": can't map i/o space\n");
186 pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh)(((*((psc->sc_pf)->sc->pct)->io_free)(((psc->sc_pf
)->sc->pch), ((&psc->sc_pcioh)))))
;
187 pcmcia_function_disable(psc->sc_pf);
188 return;
189 }
190 sc->sc_iot = psc->sc_pcioh.iot;
191 sc->sc_ioh = psc->sc_pcioh.ioh;
192
193 printf(" port 0x%lx/%ld", psc->sc_pcioh.addr, psc->sc_pcioh.size);
194
195 /* establish interrupt */
196 psc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET0x7, cmalo_intr, sc,
197 sc->sc_dev.dv_xname);
198 if (psc->sc_ih == NULL((void *)0)) {
199 printf(": can't establish interrupt\n");
200 return;
201 }
202 intrstr = pcmcia_intr_string(psc->sc_pf, psc->sc_ih);
203 if (intrstr != NULL((void *)0)) {
204 if (*intrstr != '\0')
205 printf(", %s", intrstr);
206 }
207 printf("\n");
208
209 config_mountroot(self, cmalo_attach);
210}
211
212int
213malo_pcmcia_detach(struct device *dev, int flags)
214{
215 struct malo_pcmcia_softc *psc = (struct malo_pcmcia_softc *)dev;
216 struct malo_softc *sc = &psc->sc_malo;
217
218 cmalo_detach(sc);
219
220 pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window)(((*((psc->sc_pf)->sc->pct)->io_unmap)(((psc->
sc_pf)->sc->pch), ((psc->sc_io_window)))))
;
221 pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh)(((*((psc->sc_pf)->sc->pct)->io_free)(((psc->sc_pf
)->sc->pch), ((&psc->sc_pcioh)))))
;
222
223 return (0);
224}
225
226int
227malo_pcmcia_activate(struct device *dev, int act)
228{
229 struct malo_pcmcia_softc *psc = (struct malo_pcmcia_softc *)dev;
230 struct malo_softc *sc = &psc->sc_malo;
231 struct ieee80211com *ic = &sc->sc_ic;
232 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
233
234 switch (act) {
235 case DVACT_SUSPEND3:
236 if ((sc->sc_flags & MALO_DEVICE_ATTACHED(1 << 0)) &&
237 (ifp->if_flags & IFF_RUNNING0x40))
238 cmalo_stop(sc);
239 if (psc->sc_ih)
240 pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih);
241 psc->sc_ih = NULL((void *)0);
242 pcmcia_function_disable(psc->sc_pf);
243 break;
244 case DVACT_RESUME4:
245 pcmcia_function_enable(psc->sc_pf);
246 psc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET0x7,
247 cmalo_intr, sc, sc->sc_dev.dv_xname);
248 break;
249 case DVACT_WAKEUP5:
250 malo_pcmcia_wakeup(sc);
251 break;
252 case DVACT_DEACTIVATE1:
253 if ((sc->sc_flags & MALO_DEVICE_ATTACHED(1 << 0)) &&
254 (ifp->if_flags & IFF_RUNNING0x40))
255 cmalo_stop(sc); /* XXX tries to touch regs */
256 if (psc->sc_ih)
257 pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih);
258 psc->sc_ih = NULL((void *)0);
259 pcmcia_function_disable(psc->sc_pf);
260 break;
261 }
262 return (0);
263}
264
265void
266malo_pcmcia_wakeup(struct malo_softc *sc)
267{
268 struct ieee80211com *ic = &sc->sc_ic;
269 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
270 int s;
271
272 s = splnet()splraise(0x7);
273 while (sc->sc_flags & MALO_BUSY(1 << 3))
274 tsleep_nsec(&sc->sc_flags, 0, "malopwr", INFSLP0xffffffffffffffffULL);
275 sc->sc_flags |= MALO_BUSY(1 << 3);
276
277 cmalo_init(ifp);
278
279 sc->sc_flags &= ~MALO_BUSY(1 << 3);
280 wakeup(&sc->sc_flags);
281 splx(s)spllower(s);
282}
283
284/*
285 * Driver.
286 */
287void
288cmalo_attach(struct device *self)
289{
290 struct malo_softc *sc = (struct malo_softc *)self;
291 struct ieee80211com *ic = &sc->sc_ic;
292 struct ifnet *ifp = &sc->sc_ic.ic_ific_ac.ac_if;
293 int i;
294
295 /* disable interrupts */
296 cmalo_intr_mask(sc, 0);
297
298 /* load firmware */
299 if (cmalo_fw_alloc(sc) != 0)
300 return;
301 if (cmalo_fw_load_helper(sc) != 0)
302 return;
303 if (cmalo_fw_load_main(sc) != 0)
304 return;
305 sc->sc_flags |= MALO_FW_LOADED(1 << 1);
306
307 /* allocate command buffer */
308 sc->sc_cmd = malloc(MALO_CMD_BUFFER_SIZE256, M_DEVBUF2, M_NOWAIT0x0002);
309
310 /* allocate data buffer */
311 sc->sc_data = malloc(MCLBYTES(1 << 11), M_DEVBUF2, M_NOWAIT0x0002);
312
313 /* enable interrupts */
314 cmalo_intr_mask(sc, 1);
315
316 /* we are context save here for FW commands */
317 sc->sc_cmd_ctxsave = 1;
318
319 /* get hardware specs */
320 cmalo_cmd_get_hwspec(sc);
321
322 /* setup interface */
323 ifp->if_softc = sc;
324 ifp->if_ioctl = cmalo_ioctl;
325 ifp->if_start = cmalo_start;
326 ifp->if_watchdog = cmalo_watchdog;
327 ifp->if_flags = IFF_SIMPLEX0x800 | IFF_BROADCAST0x2 | IFF_MULTICAST0x8000;
328 strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ16);
329
330 ic->ic_opmode = IEEE80211_M_STA;
331 ic->ic_state = IEEE80211_S_INIT;
332 ic->ic_caps = IEEE80211_C_MONITOR0x00000200 | IEEE80211_C_WEP0x00000001;
333
334 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
335 ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
336
337 for (i = 0; i <= 14; i++) {
338 ic->ic_channels[i].ic_freq =
339 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ0x0080);
340 ic->ic_channels[i].ic_flags =
341 IEEE80211_CHAN_CCK0x0020 | IEEE80211_CHAN_OFDM0x0040 |
342 IEEE80211_CHAN_DYN0x0400 | IEEE80211_CHAN_2GHZ0x0080;
343 }
344
345 /* attach interface */
346 if_attach(ifp);
347 ieee80211_ifattach(ifp);
348
349 sc->sc_newstate = ic->ic_newstate;
350 ic->ic_newstate = cmalo_newstate;
351 ieee80211_media_init(ifp, cmalo_media_change, ieee80211_media_status);
352
353 /* second attach line */
354 printf("%s: address %s\n",
355 sc->sc_dev.dv_xname, ether_sprintf(ic->ic_myaddr));
356
357 /* device attached */
358 sc->sc_flags |= MALO_DEVICE_ATTACHED(1 << 0);
359}
360
361int
362cmalo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
363{
364 struct malo_softc *sc = ifp->if_softc;
365 struct ieee80211_nodereq_all *na;
366 struct ieee80211_nodereq *nr;
367 int i, j, s, error = 0;
368
369 s = splnet()splraise(0x7);
370 /*
371 * Prevent processes from entering this function while another
372 * process is tsleep'ing in it.
373 */
374 while ((sc->sc_flags & MALO_BUSY(1 << 3)) && error == 0)
375 error = tsleep_nsec(&sc->sc_flags, PCATCH0x100, "maloioc", INFSLP0xffffffffffffffffULL);
376 if (error != 0) {
377 splx(s)spllower(s);
378 return error;
379 }
380 sc->sc_flags |= MALO_BUSY(1 << 3);
381
382 switch (cmd) {
383 case SIOCSIFADDR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((12)))
:
384 ifp->if_flags |= IFF_UP0x1;
385 /* FALLTHROUGH */
386 case SIOCSIFFLAGS((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((16)))
:
387 if (ifp->if_flags & IFF_UP0x1) {
388 if ((ifp->if_flags & IFF_RUNNING0x40) == 0)
389 cmalo_init(ifp);
390 } else {
391 if (ifp->if_flags & IFF_RUNNING0x40)
392 cmalo_stop(sc);
393 }
394 break;
395 case SIOCS80211SCAN((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((210)))
:
396 cmalo_cmd_set_scan(sc);
397 break;
398 case SIOCG80211ALLNODES(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ieee80211_nodereq_all) & 0x1fff) << 16) | (
(('i')) << 8) | ((214)))
:
399 nr = NULL((void *)0);
400 na = (struct ieee80211_nodereq_all *)data;
401
402 if ((nr = malloc(sizeof(*nr), M_DEVBUF2, M_WAITOK0x0001)) == NULL((void *)0))
403 break;
404
405 for (na->na_nodes = i = j = 0; i < sc->sc_net_num &&
406 (na->na_size >= j + sizeof(struct ieee80211_nodereq));
407 i++) {
408 bzero(nr, sizeof(*nr))__builtin_bzero((nr), (sizeof(*nr)));
409
410 IEEE80211_ADDR_COPY(nr->nr_macaddr,__builtin_memcpy((nr->nr_macaddr), (sc->sc_net[i].bssid
), (6))
411 sc->sc_net[i].bssid)__builtin_memcpy((nr->nr_macaddr), (sc->sc_net[i].bssid
), (6))
;
412 IEEE80211_ADDR_COPY(nr->nr_bssid,__builtin_memcpy((nr->nr_bssid), (sc->sc_net[i].bssid),
(6))
413 sc->sc_net[i].bssid)__builtin_memcpy((nr->nr_bssid), (sc->sc_net[i].bssid),
(6))
;
414 nr->nr_channel = sc->sc_net[i].channel;
415 nr->nr_chan_flags = IEEE80211_CHAN_B(0x0080 | 0x0020); /* XXX */
416 nr->nr_rssi = sc->sc_net[i].rssi;
417 nr->nr_max_rssi = 0; /* XXX */
418 nr->nr_nwid_len = strlen(sc->sc_net[i].ssid);
419 bcopy(sc->sc_net[i].ssid, nr->nr_nwid,
420 nr->nr_nwid_len);
421 nr->nr_intval = sc->sc_net[i].beaconintvl;
422 nr->nr_capinfo = sc->sc_net[i].capinfo;
423 nr->nr_flags |= IEEE80211_NODEREQ_AP0x01;
424
425 if (copyout(nr, (caddr_t)na->na_node + j,
426 sizeof(struct ieee80211_nodereq)))
427 break;
428
429 j += sizeof(struct ieee80211_nodereq);
430 na->na_nodes++;
431 }
432
433 if (nr)
434 free(nr, M_DEVBUF2, 0);
435 break;
436 default:
437 error = ieee80211_ioctl(ifp, cmd, data);
438 break;
439 }
440
441 if (error == ENETRESET52) {
442 if (ifp->if_flags & (IFF_UP0x1 | IFF_RUNNING0x40))
443 cmalo_init(ifp);
444 error = 0;
445 }
446
447 sc->sc_flags &= ~MALO_BUSY(1 << 3);
448 wakeup(&sc->sc_flags);
449 splx(s)spllower(s);
450
451 return (error);
452}
453
454int
455cmalo_fw_alloc(struct malo_softc *sc)
456{
457 const char *name_h = "malo8385-h";
458 const char *name_m = "malo8385-m";
459 int error;
460
461 if (sc->sc_fw_h == NULL((void *)0)) {
462 /* read helper firmware image */
463 error = loadfirmware(name_h, &sc->sc_fw_h, &sc->sc_fw_h_size);
464 if (error != 0) {
465 printf("%s: error %d, could not read firmware %s\n",
466 sc->sc_dev.dv_xname, error, name_h);
467 return (EIO5);
468 }
469 }
470
471 if (sc->sc_fw_m == NULL((void *)0)) {
472 /* read main firmware image */
473 error = loadfirmware(name_m, &sc->sc_fw_m, &sc->sc_fw_m_size);
474 if (error != 0) {
475 printf("%s: error %d, could not read firmware %s\n",
476 sc->sc_dev.dv_xname, error, name_m);
477 return (EIO5);
478 }
479 }
480
481 return (0);
482}
483
484void
485cmalo_fw_free(struct malo_softc *sc)
486{
487 if (sc->sc_fw_h != NULL((void *)0)) {
488 free(sc->sc_fw_h, M_DEVBUF2, 0);
489 sc->sc_fw_h = NULL((void *)0);
490 }
491
492 if (sc->sc_fw_m != NULL((void *)0)) {
493 free(sc->sc_fw_m, M_DEVBUF2, 0);
494 sc->sc_fw_m = NULL((void *)0);
495 }
496}
497
498int
499cmalo_fw_load_helper(struct malo_softc *sc)
500{
501 uint8_t val8;
502 uint16_t bsize, *uc;
503 int offset, i;
504
505 /* verify if the card is ready for firmware download */
506 val8 = MALO_READ_1(sc, MALO_REG_SCRATCH)(((sc)->sc_iot)->read_1(((sc)->sc_ioh), ((0x3f))));
507 if (val8 == MALO_VAL_SCRATCH_FW_LOADED0x5a)
508 /* firmware already loaded */
509 return (0);
510 if (val8 != MALO_VAL_SCRATCH_READY0x00) {
511 /* bad register value */
512 printf("%s: device not ready for FW download\n",
513 sc->sc_dev.dv_xname);
514 return (EIO5);
515 }
516
517 /* download the helper firmware */
518 for (offset = 0; offset < sc->sc_fw_h_size; offset += bsize) {
519 if (sc->sc_fw_h_size - offset >= MALO_FW_HELPER_BSIZE256)
520 bsize = MALO_FW_HELPER_BSIZE256;
521 else
522 bsize = sc->sc_fw_h_size - offset;
523
524 /* send a block in words and confirm it */
525 DPRINTF(3, "%s: download helper FW block (%d bytes, %d off)\n",
526 sc->sc_dev.dv_xname, bsize, offset);
527 MALO_WRITE_2(sc, MALO_REG_CMD_WRITE_LEN, bsize)(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x18)), (
(bsize))))
;
528 uc = (uint16_t *)(sc->sc_fw_h + offset);
529 for (i = 0; i < bsize / 2; i++)
530 MALO_WRITE_2(sc, MALO_REG_CMD_WRITE, htole16(uc[i]))(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x1a)), (
(((__uint16_t)(uc[i]))))))
;
531 MALO_WRITE_1(sc, MALO_REG_HOST_STATUS, MALO_VAL_CMD_DL_OVER)(((sc)->sc_iot)->write_1(((sc)->sc_ioh), ((0x00)), (
(0x04))))
;
532 MALO_WRITE_2(sc, MALO_REG_CARD_INTR_CAUSE,(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x02)), (
(0x04))))
533 MALO_VAL_CMD_DL_OVER)(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x02)), (
(0x04))))
;
534
535 /* poll for an acknowledgement */
536 for (i = 0; i < 50; i++) {
537 if (MALO_READ_1(sc, MALO_REG_CARD_STATUS)(((sc)->sc_iot)->read_1(((sc)->sc_ioh), ((0x20)))) ==
538 MALO_VAL_CMD_DL_OVER0x04)
539 break;
540 delay(1000)(*delay_func)(1000);
541 }
542 if (i == 50) {
543 printf("%s: timeout while helper FW block download\n",
544 sc->sc_dev.dv_xname);
545 return (EIO5);
546 }
547 }
548
549 /* helper firmware download done */
550 MALO_WRITE_2(sc, MALO_REG_CMD_WRITE_LEN, 0)(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x18)), (
(0))))
;
551 MALO_WRITE_1(sc, MALO_REG_HOST_STATUS, MALO_VAL_CMD_DL_OVER)(((sc)->sc_iot)->write_1(((sc)->sc_ioh), ((0x00)), (
(0x04))))
;
552 MALO_WRITE_2(sc, MALO_REG_CARD_INTR_CAUSE, MALO_VAL_CMD_DL_OVER)(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x02)), (
(0x04))))
;
553 DPRINTF(1, "%s: helper FW downloaded\n", sc->sc_dev.dv_xname);
554
555 return (0);
556}
557
558int
559cmalo_fw_load_main(struct malo_softc *sc)
560{
561 uint16_t val16, bsize, *uc;
562 int offset, i, retry = 0;
563
564 /* verify if the helper firmware has been loaded correctly */
565 for (i = 0; i < 10; i++) {
566 if (MALO_READ_1(sc, MALO_REG_RBAL)(((sc)->sc_iot)->read_1(((sc)->sc_ioh), ((0x28)))) == MALO_FW_HELPER_LOADED0x10)
567 break;
568 delay(1000)(*delay_func)(1000);
569 }
570 if (i == 10) {
571 printf("%s: helper FW not loaded\n", sc->sc_dev.dv_xname);
572 return (EIO5);
573 }
574 DPRINTF(1, "%s: helper FW loaded successfully\n", sc->sc_dev.dv_xname);
575
576 /* download the main firmware */
577 bsize = 0; /* XXX really??? */
578 for (offset = 0; offset < sc->sc_fw_m_size; offset += bsize) {
579 val16 = MALO_READ_2(sc, MALO_REG_RBAL)(((sc)->sc_iot)->read_2(((sc)->sc_ioh), ((0x28))));
580 /*
581 * If the helper firmware serves us an odd integer then
582 * something went wrong and we retry to download the last
583 * block until we receive a good integer again, or give up.
584 */
585 if (val16 & 0x0001) {
586 if (retry > MALO_FW_MAIN_MAXRETRY20) {
587 printf("%s: main FW download failed\n",
588 sc->sc_dev.dv_xname);
589 return (EIO5);
590 }
591 retry++;
592 offset -= bsize;
593 } else {
594 retry = 0;
595 bsize = val16;
596 }
597
598 /* send a block in words and confirm it */
599 DPRINTF(3, "%s: download main FW block (%d bytes, %d off)\n",
600 sc->sc_dev.dv_xname, bsize, offset);
601 MALO_WRITE_2(sc, MALO_REG_CMD_WRITE_LEN, bsize)(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x18)), (
(bsize))))
;
602 uc = (uint16_t *)(sc->sc_fw_m + offset);
603 for (i = 0; i < bsize / 2; i++)
604 MALO_WRITE_2(sc, MALO_REG_CMD_WRITE, htole16(uc[i]))(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x1a)), (
(((__uint16_t)(uc[i]))))))
;
605 MALO_WRITE_1(sc, MALO_REG_HOST_STATUS, MALO_VAL_CMD_DL_OVER)(((sc)->sc_iot)->write_1(((sc)->sc_ioh), ((0x00)), (
(0x04))))
;
606 MALO_WRITE_2(sc, MALO_REG_CARD_INTR_CAUSE,(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x02)), (
(0x04))))
607 MALO_VAL_CMD_DL_OVER)(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x02)), (
(0x04))))
;
608
609 /* poll for an acknowledgement */
610 for (i = 0; i < 5000; i++) {
611 if (MALO_READ_1(sc, MALO_REG_CARD_STATUS)(((sc)->sc_iot)->read_1(((sc)->sc_ioh), ((0x20)))) ==
612 MALO_VAL_CMD_DL_OVER0x04)
613 break;
614 }
615 if (i == 5000) {
616 printf("%s: timeout while main FW block download\n",
617 sc->sc_dev.dv_xname);
618 return (EIO5);
619 }
620 }
621
622 DPRINTF(1, "%s: main FW downloaded\n", sc->sc_dev.dv_xname);
623
624 /* verify if the main firmware has been loaded correctly */
625 for (i = 0; i < 500; i++) {
626 if (MALO_READ_1(sc, MALO_REG_SCRATCH)(((sc)->sc_iot)->read_1(((sc)->sc_ioh), ((0x3f)))) ==
627 MALO_VAL_SCRATCH_FW_LOADED0x5a)
628 break;
629 delay(1000)(*delay_func)(1000);
630 }
631 if (i == 500) {
632 printf("%s: main FW not loaded\n", sc->sc_dev.dv_xname);
633 return (EIO5);
634 }
635
636 DPRINTF(1, "%s: main FW loaded successfully\n", sc->sc_dev.dv_xname);
637
638 return (0);
639}
640
641int
642cmalo_init(struct ifnet *ifp)
643{
644 struct malo_softc *sc = ifp->if_softc;
645 struct ieee80211com *ic = &sc->sc_ic;
646
647 /* reload the firmware if necessary */
648 if (!(sc->sc_flags & MALO_FW_LOADED(1 << 1))) {
649 /* disable interrupts */
650 cmalo_intr_mask(sc, 0);
651
652 /* load firmware */
653 if (cmalo_fw_load_helper(sc) != 0)
654 return (EIO5);
655 if (cmalo_fw_load_main(sc) != 0)
656 return (EIO5);
657 sc->sc_flags |= MALO_FW_LOADED(1 << 1);
658
659 /* enable interrupts */
660 cmalo_intr_mask(sc, 1);
661 }
662
663 /* reset association state flag */
664 sc->sc_flags &= ~MALO_ASSOC_FAILED(1 << 2);
665
666 /* get current channel */
667 ic->ic_bss->ni_chan = ic->ic_ibss_chan;
668 sc->sc_curchan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
669 DPRINTF(1, "%s: current channel is %d\n",
670 sc->sc_dev.dv_xname, sc->sc_curchan);
671
672 /* setup device */
673 if (cmalo_cmd_set_macctrl(sc) != 0)
674 return (EIO5);
675 if (cmalo_cmd_set_txpower(sc, 15) != 0)
676 return (EIO5);
677 if (cmalo_cmd_set_antenna(sc, 1) != 0)
678 return (EIO5);
679 if (cmalo_cmd_set_antenna(sc, 2) != 0)
680 return (EIO5);
681 if (cmalo_cmd_set_radio(sc, 1) != 0)
682 return (EIO5);
683 if (cmalo_cmd_set_channel(sc, sc->sc_curchan) != 0)
684 return (EIO5);
685 if (cmalo_cmd_set_rate(sc, ic->ic_fixed_rate) != 0)
686 return (EIO5);
687 if (cmalo_cmd_set_snmp(sc, MALO_OID_RTSTRESH0x05) != 0)
688 return (EIO5);
689 if (cmalo_cmd_set_snmp(sc, MALO_OID_SHORTRETRY0x06) != 0)
690 return (EIO5);
691 if (cmalo_cmd_set_snmp(sc, MALO_OID_FRAGTRESH0x08) != 0)
692 return (EIO5);
693 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))
;
694 if (cmalo_cmd_set_macaddr(sc, ic->ic_myaddr) != 0)
695 return (EIO5);
696 if (sc->sc_ic.ic_flags & IEEE80211_F_WEPON0x00000100) {
697 if (cmalo_wep(sc) != 0)
698 return (EIO5);
699 }
700
701 /* device up */
702 ifp->if_flags |= IFF_RUNNING0x40;
703 ifq_clr_oactive(&ifp->if_snd);
704
705 /* start network */
706 if (ic->ic_opmode != IEEE80211_M_MONITOR)
707 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1)(((ic)->ic_newstate)((ic), (IEEE80211_S_SCAN), (-1)));
708 if (sc->sc_flags & MALO_ASSOC_FAILED(1 << 2))
709 ieee80211_new_state(ic, IEEE80211_S_INIT, -1)(((ic)->ic_newstate)((ic), (IEEE80211_S_INIT), (-1)));
710 else
711 ieee80211_new_state(ic, IEEE80211_S_RUN, -1)(((ic)->ic_newstate)((ic), (IEEE80211_S_RUN), (-1)));
712
713 /* we are not context save anymore for FW commands */
714 sc->sc_cmd_ctxsave = 0;
715
716 return (0);
717}
718
719void
720cmalo_stop(struct malo_softc *sc)
721{
722 struct ieee80211com *ic = &sc->sc_ic;
723 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
724
725 /* device down */
726 ifp->if_flags &= ~IFF_RUNNING0x40;
727 ifq_clr_oactive(&ifp->if_snd);
728
729 /* change device back to initial state */
730 ieee80211_new_state(ic, IEEE80211_S_INIT, -1)(((ic)->ic_newstate)((ic), (IEEE80211_S_INIT), (-1)));
731
732 /* reset device */
733 cmalo_cmd_set_reset(sc);
734 sc->sc_flags &= ~MALO_FW_LOADED(1 << 1);
735 ifp->if_timer = 0;
736
737 DPRINTF(1, "%s: device down\n", sc->sc_dev.dv_xname);
738}
739
740int
741cmalo_media_change(struct ifnet *ifp)
742{
743 int error;
744
745 if ((error = ieee80211_media_change(ifp) != ENETRESET52))
746 return (error);
747
748 if (ifp->if_flags & (IFF_UP0x1 | IFF_RUNNING0x40))
749 cmalo_init(ifp);
750
751 return (0);
752}
753
754int
755cmalo_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
756{
757 struct malo_softc *sc = ic->ic_ific_ac.ac_if.if_softc;
758 enum ieee80211_state ostate;
759
760 ostate = ic->ic_state;
761
762 if (ostate == nstate)
763 goto out;
764
765 switch (nstate) {
766 case IEEE80211_S_INIT:
767 DPRINTF(1, "%s: newstate is IEEE80211_S_INIT\n",
768 sc->sc_dev.dv_xname);
769 break;
770 case IEEE80211_S_SCAN:
771 DPRINTF(1, "%s: newstate is IEEE80211_S_SCAN\n",
772 sc->sc_dev.dv_xname);
773 cmalo_cmd_set_scan(sc);
774 if (!sc->sc_net_num) {
775 /* no networks found */
776 DPRINTF(1, "%s: no networks found\n",
777 sc->sc_dev.dv_xname);
778 break;
779 }
780 cmalo_select_network(sc);
781 cmalo_cmd_set_auth(sc);
782 cmalo_cmd_set_assoc(sc);
783 break;
784 case IEEE80211_S_AUTH:
785 DPRINTF(1, "%s: newstate is IEEE80211_S_AUTH\n",
786 sc->sc_dev.dv_xname);
787 break;
788 case IEEE80211_S_ASSOC:
789 DPRINTF(1, "%s: newstate is IEEE80211_S_ASSOC\n",
790 sc->sc_dev.dv_xname);
791 break;
792 case IEEE80211_S_RUN:
793 DPRINTF(1, "%s: newstate is IEEE80211_S_RUN\n",
794 sc->sc_dev.dv_xname);
795 cmalo_reflect_network(sc);
796 break;
797 default:
798 break;
799 }
800
801out:
802 return (sc->sc_newstate(ic, nstate, arg));
803}
804
805void
806cmalo_detach(void *arg)
807{
808 struct malo_softc *sc = arg;
809 struct ieee80211com *ic = &sc->sc_ic;
810 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
811
812 if (!(sc->sc_flags & MALO_DEVICE_ATTACHED(1 << 0)))
813 /* device was not properly attached */
814 return;
815
816 /* free command buffer */
817 if (sc->sc_cmd != NULL((void *)0))
818 free(sc->sc_cmd, M_DEVBUF2, 0);
819
820 /* free data buffer */
821 if (sc->sc_data != NULL((void *)0))
822 free(sc->sc_data, M_DEVBUF2, 0);
823
824 /* free firmware */
825 cmalo_fw_free(sc);
826
827 /* detach interface */
828 ieee80211_ifdetach(ifp);
829 if_detach(ifp);
830}
831
832int
833cmalo_intr(void *arg)
834{
835 struct malo_softc *sc = arg;
836 uint16_t intr = 0;
837
838 /* read interrupt reason */
839 intr = MALO_READ_2(sc, MALO_REG_HOST_INTR_CAUSE)(((sc)->sc_iot)->read_2(((sc)->sc_ioh), ((0x22))));
840 if (intr == 0) {
841 /* interrupt not for us */
842 return (0);
843 }
844 if (intr == 0xffff) {
845 /* card has been detached */
846 return (0);
847 }
848
849 /* disable interrupts */
850 cmalo_intr_mask(sc, 0);
851
852 /* acknowledge interrupt */
853 MALO_WRITE_2(sc, MALO_REG_HOST_INTR_CAUSE,(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x22)), (
(intr & 0x001f))))
854 intr & MALO_VAL_HOST_INTR_MASK_ON)(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x22)), (
(intr & 0x001f))))
;
855
856 /* enable interrupts */
857 cmalo_intr_mask(sc, 1);
858
859 DPRINTF(2, "%s: interrupt handler called (intr = 0x%04x)\n",
860 sc->sc_dev.dv_xname, intr);
861
862 if (intr & MALO_VAL_HOST_INTR_TX(1 << 0))
863 /* TX frame sent */
864 cmalo_tx_done(sc);
865 if (intr & MALO_VAL_HOST_INTR_RX(1 << 1))
866 /* RX frame received */
867 cmalo_rx(sc);
868 if (intr & MALO_VAL_HOST_INTR_CMD(1 << 3)) {
869 /* command response */
870 wakeup(sc);
871 if (!sc->sc_cmd_ctxsave)
872 cmalo_cmd_response(sc);
873 }
874 if (intr & MALO_VAL_HOST_INTR_EVENT(1 << 4))
875 /* event */
876 cmalo_event(sc);
877
878 return (1);
879}
880
881void
882cmalo_intr_mask(struct malo_softc *sc, int enable)
883{
884 uint16_t val16;
885
886 val16 = MALO_READ_2(sc, MALO_REG_HOST_INTR_MASK)(((sc)->sc_iot)->read_2(((sc)->sc_ioh), ((0x04))));
887
888 DPRINTF(3, "%s: intr mask changed from 0x%04x ",
889 sc->sc_dev.dv_xname, val16);
890
891 if (enable)
892 MALO_WRITE_2(sc, MALO_REG_HOST_INTR_MASK,(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x04)), (
(val16 & ~0x001f))))
893 val16 & ~MALO_VAL_HOST_INTR_MASK_ON)(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x04)), (
(val16 & ~0x001f))))
;
894 else
895 MALO_WRITE_2(sc, MALO_REG_HOST_INTR_MASK,(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x04)), (
(val16 | 0x001f))))
896 val16 | MALO_VAL_HOST_INTR_MASK_ON)(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x04)), (
(val16 | 0x001f))))
;
897
898 val16 = MALO_READ_2(sc, MALO_REG_HOST_INTR_MASK)(((sc)->sc_iot)->read_2(((sc)->sc_ioh), ((0x04))));
Value stored to 'val16' is never read
899
900 DPRINTF(3, "to 0x%04x\n", val16);
901}
902
903void
904cmalo_rx(struct malo_softc *sc)
905{
906 struct ieee80211com *ic = &sc->sc_ic;
907 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
908 struct malo_rx_desc *rxdesc;
909 struct mbuf_list ml = MBUF_LIST_INITIALIZER(){ ((void *)0), ((void *)0), 0 };
910 struct mbuf *m;
911 uint8_t *data;
912 uint16_t psize;
913 int i;
914
915 splassert(IPL_NET)do { if (splassert_ctl > 0) { splassert_check(0x7, __func__
); } } while (0)
;
916
917 /* read the whole RX packet which is always 802.3 */
918 psize = MALO_READ_2(sc, MALO_REG_DATA_READ_LEN)(((sc)->sc_iot)->read_2(((sc)->sc_ioh), ((0x24))));
919 if (psize & 0x0001) {
920 MALO_READ_MULTI_2(sc, MALO_REG_DATA_READ, sc->sc_data,(((sc)->sc_iot)->read_multi_2(((sc)->sc_ioh), ((0x10
)), (u_int16_t *)((sc->sc_data)), ((psize - 1)) >> 1
))
921 psize - 1)(((sc)->sc_iot)->read_multi_2(((sc)->sc_ioh), ((0x10
)), (u_int16_t *)((sc->sc_data)), ((psize - 1)) >> 1
))
;
922 data = (uint8_t *)sc->sc_data;
923 data[psize - 1] = MALO_READ_1(sc, MALO_REG_DATA_READ)(((sc)->sc_iot)->read_1(((sc)->sc_ioh), ((0x10))));
924 } else
925 MALO_READ_MULTI_2(sc, MALO_REG_DATA_READ, sc->sc_data, psize)(((sc)->sc_iot)->read_multi_2(((sc)->sc_ioh), ((0x10
)), (u_int16_t *)((sc->sc_data)), ((psize)) >> 1))
;
926 MALO_WRITE_1(sc, MALO_REG_HOST_STATUS, MALO_VAL_RX_DL_OVER)(((sc)->sc_iot)->write_1(((sc)->sc_ioh), ((0x00)), (
(0x02))))
;
927 MALO_WRITE_2(sc, MALO_REG_CARD_INTR_CAUSE, MALO_VAL_RX_DL_OVER)(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x02)), (
(0x02))))
;
928
929 /* access RX packet descriptor */
930 rxdesc = (struct malo_rx_desc *)sc->sc_data;
931 rxdesc->status = letoh16(rxdesc->status)((__uint16_t)(rxdesc->status));
932 rxdesc->pkglen = letoh16(rxdesc->pkglen)((__uint16_t)(rxdesc->pkglen));
933 rxdesc->pkgoffset = letoh32(rxdesc->pkgoffset)((__uint32_t)(rxdesc->pkgoffset));
934
935 DPRINTF(2, "RX status=%d, pkglen=%d, pkgoffset=%d\n",
936 rxdesc->status, rxdesc->pkglen, rxdesc->pkgoffset);
937
938 if (rxdesc->status != MALO_RX_STATUS_OK0x0001)
939 /* RX packet is not OK */
940 return;
941
942 /* remove the LLC / SNAP header */
943 data = sc->sc_data + rxdesc->pkgoffset;
944 i = (ETHER_ADDR_LEN6 * 2) + sizeof(struct llc);
945 bcopy(data + i, data + (ETHER_ADDR_LEN6 * 2), rxdesc->pkglen - i);
946 rxdesc->pkglen -= sizeof(struct llc);
947
948 /* prepare mbuf */
949 m = m_devget(sc->sc_data + rxdesc->pkgoffset,
950 rxdesc->pkglen, ETHER_ALIGN2);
951 if (m == NULL((void *)0)) {
952 DPRINTF(1, "RX m_devget failed\n");
953 ifp->if_ierrorsif_data.ifi_ierrors++;
954 return;
955 }
956
957 /* push the frame up to the network stack if not in monitor mode */
958 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
959 ml_enqueue(&ml, m);
960 if_input(ifp, &ml);
961#if NBPFILTER1 > 0
962 } else {
963 if (ifp->if_bpf)
964 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN(1 << 0));
965#endif
966 }
967
968}
969
970void
971cmalo_start(struct ifnet *ifp)
972{
973 struct malo_softc *sc = ifp->if_softc;
974 struct mbuf *m;
975
976 /* don't transmit packets if interface is busy or down */
977 if (!(ifp->if_flags & IFF_RUNNING0x40) || ifq_is_oactive(&ifp->if_snd))
978 return;
979
980 m = ifq_dequeue(&ifp->if_snd);
981 if (m == NULL((void *)0))
982 return;
983
984#if NBPFILTER1 > 0
985 if (ifp->if_bpf)
986 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT(1 << 1));
987#endif
988
989 if (cmalo_tx(sc, m) != 0)
990 ifp->if_oerrorsif_data.ifi_oerrors++;
991}
992
993void
994cmalo_watchdog(struct ifnet *ifp)
995{
996 DPRINTF(2, "watchdog timeout\n");
997
998 /* accept TX packets again */
999 ifq_clr_oactive(&ifp->if_snd);
1000}
1001
1002int
1003cmalo_tx(struct malo_softc *sc, struct mbuf *m)
1004{
1005 struct ifnet *ifp = &sc->sc_ic.ic_ific_ac.ac_if;
1006 struct malo_tx_desc *txdesc = sc->sc_data;
1007 uint8_t *data;
1008 uint16_t psize;
1009
1010 splassert(IPL_NET)do { if (splassert_ctl > 0) { splassert_check(0x7, __func__
); } } while (0)
;
1011
1012 bzero(sc->sc_data, sizeof(*txdesc))__builtin_bzero((sc->sc_data), (sizeof(*txdesc)));
1013 psize = sizeof(*txdesc) + m->m_pkthdrM_dat.MH.MH_pkthdr.len;
1014 data = mtod(m, uint8_t *)((uint8_t *)((m)->m_hdr.mh_data));
1015
1016 /* prepare TX descriptor */
1017 txdesc->pkgoffset = htole32(sizeof(*txdesc))((__uint32_t)(sizeof(*txdesc)));
1018 txdesc->pkglen = htole16(m->m_pkthdr.len)((__uint16_t)(m->M_dat.MH.MH_pkthdr.len));
1019 bcopy(data, txdesc->dstaddrhigh, sizeof(txdesc->dstaddrhigh));
1020 bcopy(data + sizeof(txdesc->dstaddrhigh), txdesc->dstaddrlow,
1021 sizeof(txdesc->dstaddrlow));
1022
1023 /* copy mbuf data to the buffer */
1024 m_copydata(m, 0, m->m_pkthdrM_dat.MH.MH_pkthdr.len, sc->sc_data + sizeof(*txdesc));
1025 m_freem(m);
1026
1027 /* send TX packet to the device */
1028 MALO_WRITE_2(sc, MALO_REG_DATA_WRITE_LEN, psize)(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x14)), (
(psize))))
;
1029 if (psize & 0x0001) {
1030 MALO_WRITE_MULTI_2(sc, MALO_REG_DATA_WRITE, sc->sc_data,(((sc)->sc_iot)->write_multi_2(((sc)->sc_ioh), ((0x16
)), (const u_int16_t *)((sc->sc_data)), ((psize - 1)) >>
1))
1031 psize - 1)(((sc)->sc_iot)->write_multi_2(((sc)->sc_ioh), ((0x16
)), (const u_int16_t *)((sc->sc_data)), ((psize - 1)) >>
1))
;
1032 data = (uint8_t *)sc->sc_data;
1033 MALO_WRITE_1(sc, MALO_REG_DATA_WRITE, data[psize - 1])(((sc)->sc_iot)->write_1(((sc)->sc_ioh), ((0x16)), (
(data[psize - 1]))))
;
1034 } else
1035 MALO_WRITE_MULTI_2(sc, MALO_REG_DATA_WRITE, sc->sc_data, psize)(((sc)->sc_iot)->write_multi_2(((sc)->sc_ioh), ((0x16
)), (const u_int16_t *)((sc->sc_data)), ((psize)) >>
1))
;
1036 MALO_WRITE_1(sc, MALO_REG_HOST_STATUS, MALO_VAL_TX_DL_OVER)(((sc)->sc_iot)->write_1(((sc)->sc_ioh), ((0x00)), (
(0x01))))
;
1037 MALO_WRITE_2(sc, MALO_REG_CARD_INTR_CAUSE, MALO_VAL_TX_DL_OVER)(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x02)), (
(0x01))))
;
1038
1039 ifq_set_oactive(&ifp->if_snd);
1040 ifp->if_timer = 5;
1041
1042 DPRINTF(2, "%s: TX status=%d, pkglen=%d, pkgoffset=%d\n",
1043 sc->sc_dev.dv_xname, txdesc->status, letoh16(txdesc->pkglen),
1044 sizeof(*txdesc));
1045
1046 return (0);
1047}
1048
1049void
1050cmalo_tx_done(struct malo_softc *sc)
1051{
1052 struct ifnet *ifp = &sc->sc_ic.ic_ific_ac.ac_if;
1053
1054 splassert(IPL_NET)do { if (splassert_ctl > 0) { splassert_check(0x7, __func__
); } } while (0)
;
1055
1056 DPRINTF(2, "%s: TX done\n", sc->sc_dev.dv_xname);
1057
1058 ifq_clr_oactive(&ifp->if_snd);
1059 ifp->if_timer = 0;
1060 cmalo_start(ifp);
1061}
1062
1063void
1064cmalo_event(struct malo_softc *sc)
1065{
1066 uint16_t event;
1067
1068 /* read event reason */
1069 event = MALO_READ_2(sc, MALO_REG_CARD_STATUS)(((sc)->sc_iot)->read_2(((sc)->sc_ioh), ((0x20))));
1070 event &= MALO_VAL_CARD_STATUS_MASK0x7f00;
1071 event = event >> 8;
1072
1073 switch (event) {
1074 case MALO_EVENT_DEAUTH0x0008:
1075 DPRINTF(1, "%s: got deauthentication event (0x%04x)\n",
1076 sc->sc_dev.dv_xname, event);
1077 /* try to associate again */
1078 cmalo_cmd_set_assoc(sc);
1079 break;
1080 case MALO_EVENT_DISASSOC0x0009:
1081 DPRINTF(1, "%s: got disassociation event (0x%04x)\n",
1082 sc->sc_dev.dv_xname, event);
1083 /* try to associate again */
1084 cmalo_cmd_set_assoc(sc);
1085 break;
1086 default:
1087 DPRINTF(1, "%s: got unknown event (0x%04x)\n",
1088 sc->sc_dev.dv_xname, event);
1089 break;
1090 }
1091
1092 /* acknowledge event */
1093 MALO_WRITE_2(sc, MALO_REG_CARD_INTR_CAUSE, MALO_VAL_HOST_INTR_EVENT)(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x02)), (
((1 << 4)))))
;
1094}
1095
1096void
1097cmalo_select_network(struct malo_softc *sc)
1098{
1099 struct ieee80211com *ic = &sc->sc_ic;
1100 int i, best_rssi;
1101
1102 /* reset last selected network */
1103 sc->sc_net_cur = 0;
1104
1105 /* get desired network */
1106 if (ic->ic_des_esslen) {
1107 for (i = 0; i < sc->sc_net_num; i++) {
1108 if (!strcmp(ic->ic_des_essid, sc->sc_net[i].ssid)) {
1109 sc->sc_net_cur = i;
1110 DPRINTF(1, "%s: desired network found (%s)\n",
1111 sc->sc_dev.dv_xname, ic->ic_des_essid);
1112 return;
1113 }
1114 }
1115 DPRINTF(1, "%s: desired network not found in scan results "
1116 "(%s)\n",
1117 sc->sc_dev.dv_xname, ic->ic_des_essid);
1118 }
1119
1120 /* get network with best signal strength */
1121 best_rssi = sc->sc_net[0].rssi;
1122 for (i = 0; i < sc->sc_net_num; i++) {
1123 if (best_rssi < sc->sc_net[i].rssi) {
1124 best_rssi = sc->sc_net[i].rssi;
1125 sc->sc_net_cur = i;
1126 }
1127 }
1128 DPRINTF(1, "%s: best network found (%s)\n",
1129 sc->sc_dev.dv_xname, sc->sc_net[sc->sc_net_cur].ssid);
1130}
1131
1132void
1133cmalo_reflect_network(struct malo_softc *sc)
1134{
1135 struct ieee80211com *ic = &sc->sc_ic;
1136 uint8_t chan;
1137
1138 /* reflect active network to our 80211 stack */
1139
1140 /* BSSID */
1141 IEEE80211_ADDR_COPY(ic->ic_bss->ni_bssid,__builtin_memcpy((ic->ic_bss->ni_bssid), (sc->sc_net
[sc->sc_net_cur].bssid), (6))
1142 sc->sc_net[sc->sc_net_cur].bssid)__builtin_memcpy((ic->ic_bss->ni_bssid), (sc->sc_net
[sc->sc_net_cur].bssid), (6))
;
1143
1144 /* SSID */
1145 ic->ic_bss->ni_esslen = strlen(sc->sc_net[sc->sc_net_cur].ssid);
1146 bcopy(sc->sc_net[sc->sc_net_cur].ssid, ic->ic_bss->ni_essid,
1147 ic->ic_bss->ni_esslen);
1148
1149 /* channel */
1150 chan = sc->sc_net[sc->sc_net_cur].channel;
1151 ic->ic_bss->ni_chan = &ic->ic_channels[chan];
1152}
1153
1154int
1155cmalo_wep(struct malo_softc *sc)
1156{
1157 struct ieee80211com *ic = &sc->sc_ic;
1158 int i;
1159
1160 for (i = 0; i < IEEE80211_WEP_NKID4; i++) {
1161 struct ieee80211_key *key = &ic->ic_nw_keys[i];
1162
1163 if (!key->k_len)
1164 continue;
1165
1166 DPRINTF(1, "%s: setting wep key for index %d\n",
1167 sc->sc_dev.dv_xname, i);
1168
1169 cmalo_cmd_set_wep(sc, i, key);
1170 }
1171
1172 return (0);
1173}
1174
1175int
1176cmalo_rate2bitmap(int rate)
1177{
1178 switch (rate) {
1179 /* CCK rates */
1180 case 0: return (MALO_RATE_BITMAP_DS1(1 << 0));
1181 case 1: return (MALO_RATE_BITMAP_DS2(1 << 1));
1182 case 2: return (MALO_RATE_BITMAP_DS5(1 << 2));
1183 case 3: return (MALO_RATE_BITMAP_DS11(1 << 3));
1184
1185 /* OFDM rates */
1186 case 4: return (MALO_RATE_BITMAP_OFDM6(1 << 5));
1187 case 5: return (MALO_RATE_BITMAP_OFDM9(1 << 6));
1188 case 6: return (MALO_RATE_BITMAP_OFDM12(1 << 7));
1189 case 7: return (MALO_RATE_BITMAP_OFDM18(1 << 8));
1190 case 8: return (MALO_RATE_BITMAP_OFDM24(1 << 9));
1191 case 9: return (MALO_RATE_BITMAP_OFDM36(1 << 10));
1192 case 10: return (MALO_RATE_BITMAP_OFDM48(1 << 11));
1193 case 11: return (MALO_RATE_BITMAP_OFDM54(1 << 12));
1194
1195 /* unknown rate: should not happen */
1196 default: return (0);
1197 }
1198}
1199
1200void
1201cmalo_hexdump(void *buf, int len)
1202{
1203#ifdef CMALO_DEBUG
1204 int i;
1205
1206 if (cmalo_d >= 2) {
1207 for (i = 0; i < len; i++) {
1208 if (i % 16 == 0)
1209 printf("%s%5i:", i ? "\n" : "", i);
1210 if (i % 4 == 0)
1211 printf(" ");
1212 printf("%02x", (int)*((u_char *)buf + i));
1213 }
1214 printf("\n");
1215 }
1216#endif
1217}
1218
1219int
1220cmalo_cmd_get_hwspec(struct malo_softc *sc)
1221{
1222 struct malo_cmd_header *hdr = sc->sc_cmd;
1223 struct malo_cmd_body_spec *body;
1224 uint16_t psize;
1225
1226 bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE)__builtin_bzero((sc->sc_cmd), (256));
1227 psize = sizeof(*hdr) + sizeof(*body);
1228
1229 hdr->cmd = htole16(MALO_CMD_HWSPEC)((__uint16_t)(0x0003));
1230 hdr->size = htole16(sizeof(*body))((__uint16_t)(sizeof(*body)));
1231 hdr->seqnum = htole16(1)((__uint16_t)(1));
1232 hdr->result = 0;
1233 body = (struct malo_cmd_body_spec *)(hdr + 1);
1234
1235 /* set all bits for MAC address, otherwise we won't get one back */
1236 memset(body->macaddr, 0xff, ETHER_ADDR_LEN)__builtin_memset((body->macaddr), (0xff), (6));
1237
1238 /* process command request */
1239 if (cmalo_cmd_request(sc, psize, 0) != 0)
1240 return (EIO5);
1241
1242 /* process command response */
1243 cmalo_cmd_response(sc);
1244
1245 return (0);
1246}
1247
1248int
1249cmalo_cmd_rsp_hwspec(struct malo_softc *sc)
1250{
1251 struct ieee80211com *ic = &sc->sc_ic;
1252 struct malo_cmd_header *hdr = sc->sc_cmd;
1253 struct malo_cmd_body_spec *body;
1254 int i;
1255
1256 body = (struct malo_cmd_body_spec *)(hdr + 1);
1257
1258 /* get our MAC address */
1259 for (i = 0; i < ETHER_ADDR_LEN6; i++)
1260 ic->ic_myaddr[i] = body->macaddr[i];
1261
1262 return (0);
1263}
1264
1265int
1266cmalo_cmd_set_reset(struct malo_softc *sc)
1267{
1268 struct malo_cmd_header *hdr = sc->sc_cmd;
1269 uint16_t psize;
1270
1271 bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE)__builtin_bzero((sc->sc_cmd), (256));
1272 psize = sizeof(*hdr);
1273
1274 hdr->cmd = htole16(MALO_CMD_RESET)((__uint16_t)(0x0005));
1275 hdr->size = 0;
1276 hdr->seqnum = htole16(1)((__uint16_t)(1));
1277 hdr->result = 0;
1278
1279 /* process command request */
1280 if (cmalo_cmd_request(sc, psize, 1) != 0)
1281 return (EIO5);
1282
1283 /* give the device some time to finish the reset */
1284 delay(100)(*delay_func)(100);
1285
1286 return (0);
1287}
1288
1289int
1290cmalo_cmd_set_scan(struct malo_softc *sc)
1291{
1292 struct ieee80211com *ic = &sc->sc_ic;
1293 struct malo_cmd_header *hdr = sc->sc_cmd;
1294 struct malo_cmd_body_scan *body;
1295 struct malo_cmd_tlv_ssid *body_ssid;
1296 struct malo_cmd_tlv_chanlist *body_chanlist;
1297 struct malo_cmd_tlv_rates *body_rates;
1298 //struct malo_cmd_tlv_numprobes *body_numprobes;
1299 uint16_t psize;
1300 int i;
1301
1302 bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE)__builtin_bzero((sc->sc_cmd), (256));
1303 psize = sizeof(*hdr) + sizeof(*body);
1304
1305 hdr->cmd = htole16(MALO_CMD_SCAN)((__uint16_t)(0x0006));
1306 hdr->seqnum = htole16(1)((__uint16_t)(1));
1307 hdr->result = 0;
1308 body = (struct malo_cmd_body_scan *)(hdr + 1);
1309
1310 body->bsstype = 0x03; /* any BSS */
1311 memset(body->bssid, 0xff, ETHER_ADDR_LEN)__builtin_memset((body->bssid), (0xff), (6));
1312
1313 body_ssid = sc->sc_cmd + psize;
1314 body_ssid->type = htole16(MALO_TLV_TYPE_SSID)((__uint16_t)(0x0000));
1315 body_ssid->size = htole16(0)((__uint16_t)(0));
1316 psize += (sizeof(*body_ssid) - 1);
1317
1318 body_chanlist = sc->sc_cmd + psize;
1319 body_chanlist->type = htole16(MALO_TLV_TYPE_CHANLIST)((__uint16_t)(0x0101));
1320 body_chanlist->size = htole16(sizeof(body_chanlist->data))((__uint16_t)(sizeof(body_chanlist->data)));
1321 for (i = 0; i < CHANNELS12; i++) {
1322 body_chanlist->data[i].radiotype = 0x00;
1323 body_chanlist->data[i].channumber = (i + 1);
1324 body_chanlist->data[i].scantype = 0x00; /* active */
1325 body_chanlist->data[i].minscantime = htole16(0)((__uint16_t)(0));
1326 body_chanlist->data[i].maxscantime = htole16(100)((__uint16_t)(100));
1327 }
1328 psize += sizeof(*body_chanlist);
1329
1330 body_rates = sc->sc_cmd + psize;
1331 body_rates->type = htole16(MALO_TLV_TYPE_RATES)((__uint16_t)(0x0001));
1332 body_rates->size =
1333 htole16(ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates)((__uint16_t)(ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates
))
;
1334 bcopy(ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates, body_rates->data,
1335 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates);
1336 psize += (sizeof(*body_rates) - 1) + letoh16(body_rates->size)((__uint16_t)(body_rates->size));
1337#if 0
1338 body_numprobes = sc->sc_cmd + psize;
1339 body_numprobes->type = htole16(MALO_TLV_TYPE_NUMPROBES)((__uint16_t)(0x0102));
1340 body_numprobes->size = htole16(2)((__uint16_t)(2));
1341 body_numprobes->numprobes = htole16(1)((__uint16_t)(1));
1342 psize += sizeof(*body_numprobes);
1343#endif
1344 hdr->size = htole16(psize - sizeof(*hdr))((__uint16_t)(psize - sizeof(*hdr)));
1345
1346 /* process command request */
1347 if (cmalo_cmd_request(sc, psize, 0) != 0)
1348 return (EIO5);
1349
1350 /* process command response */
1351 cmalo_cmd_response(sc);
1352
1353 return (0);
1354}
1355
1356int
1357cmalo_cmd_rsp_scan(struct malo_softc *sc)
1358{
1359 struct malo_cmd_header *hdr = sc->sc_cmd;
1360 struct malo_cmd_body_rsp_scan *body;
1361 struct malo_cmd_body_rsp_scan_set *set;
1362 uint16_t psize;
1363 int i;
1364
1365 bzero(sc->sc_net, sizeof(sc->sc_net))__builtin_bzero((sc->sc_net), (sizeof(sc->sc_net)));
1366 psize = sizeof(*hdr) + sizeof(*body);
1367
1368 body = (struct malo_cmd_body_rsp_scan *)(hdr + 1);
1369
1370 body->bufsize = letoh16(body->bufsize)((__uint16_t)(body->bufsize));
1371
1372 DPRINTF(1, "bufsize=%d, APs=%d\n", body->bufsize, body->numofset);
1373 sc->sc_net_num = body->numofset;
1374
1375 /* cycle through found networks */
1376 for (i = 0; i < body->numofset; i++) {
1377 set = (struct malo_cmd_body_rsp_scan_set *)(sc->sc_cmd + psize);
1378
1379 set->size = letoh16(set->size)((__uint16_t)(set->size));
1380 set->beaconintvl = letoh16(set->beaconintvl)((__uint16_t)(set->beaconintvl));
1381 set->capinfo = letoh16(set->capinfo)((__uint16_t)(set->capinfo));
1382
1383 DPRINTF(1, "size=%d, bssid=%s, rssi=%d, beaconintvl=%d, "
1384 "capinfo=0x%04x\n",
1385 set->size, ether_sprintf(set->bssid), set->rssi,
1386 set->beaconintvl, set->capinfo);
1387
1388 /* save scan results */
1389 bcopy(set->bssid, sc->sc_net[i].bssid, sizeof(set->bssid));
1390 bcopy(set->timestamp, sc->sc_net[i].timestamp,
1391 sizeof(set->timestamp));
1392 sc->sc_net[i].rssi = set->rssi;
1393 sc->sc_net[i].beaconintvl = set->beaconintvl;
1394 sc->sc_net[i].capinfo = set->capinfo;
1395 cmalo_parse_elements(sc, (set + 1),
1396 set->size - (sizeof(*set) - sizeof(set->size)), i);
1397
1398 psize += (set->size + sizeof(set->size));
1399 }
1400
1401 return (0);
1402}
1403
1404int
1405cmalo_parse_elements(struct malo_softc *sc, void *buf, int size, int pos)
1406{
1407 uint8_t eid, len;
1408 int i;
1409
1410 DPRINTF(2, "element_size=%d, element_pos=%d\n", size, pos);
1411
1412 for (i = 0; i < size; ) {
1413 eid = *(uint8_t *)(buf + i);
1414 i++;
1415 len = *(uint8_t *)(buf + i);
1416 i++;
1417 DPRINTF(2, "eid=%d, len=%d, ", eid, len);
1418
1419 switch (eid) {
1420 case IEEE80211_ELEMID_SSID:
1421 bcopy(buf + i, sc->sc_net[pos].ssid, len);
1422 DPRINTF(2, "ssid=%s\n", sc->sc_net[pos].ssid);
1423 break;
1424 case IEEE80211_ELEMID_RATES:
1425 bcopy(buf + i, sc->sc_net[pos].rates, len);
1426 DPRINTF(2, "rates\n");
1427 break;
1428 case IEEE80211_ELEMID_DSPARMS:
1429 sc->sc_net[pos].channel = *(uint8_t *)(buf + i);
1430 DPRINTF(2, "chnl=%d\n", sc->sc_net[pos].channel);
1431 break;
1432 default:
1433 DPRINTF(2, "unknown\n");
1434 break;
1435 }
1436
1437 i += len;
1438 }
1439
1440 return (0);
1441}
1442
1443int
1444cmalo_cmd_set_auth(struct malo_softc *sc)
1445{
1446 struct malo_cmd_header *hdr = sc->sc_cmd;
1447 struct malo_cmd_body_auth *body;
1448 uint16_t psize;
1449
1450 bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE)__builtin_bzero((sc->sc_cmd), (256));
1451 psize = sizeof(*hdr) + sizeof(*body);
1452
1453 hdr->cmd = htole16(MALO_CMD_AUTH)((__uint16_t)(0x0011));
1454 hdr->size = htole16(sizeof(*body))((__uint16_t)(sizeof(*body)));
1455 hdr->seqnum = htole16(1)((__uint16_t)(1));
1456 hdr->result = 0;
1457 body = (struct malo_cmd_body_auth *)(hdr + 1);
1458
1459 bcopy(sc->sc_net[sc->sc_net_cur].bssid, body->peermac, ETHER_ADDR_LEN6);
1460 body->authtype = 0;
1461
1462 /* process command request */
1463 if (cmalo_cmd_request(sc, psize, 0) != 0)
1464 return (EIO5);
1465
1466 /* process command response */
1467 cmalo_cmd_response(sc);
1468
1469 return (0);
1470}
1471
1472int
1473cmalo_cmd_set_wep(struct malo_softc *sc, uint16_t index,
1474 struct ieee80211_key *key)
1475{
1476 struct malo_cmd_header *hdr = sc->sc_cmd;
1477 struct malo_cmd_body_wep *body;
1478 uint16_t psize;
1479
1480 bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE)__builtin_bzero((sc->sc_cmd), (256));
1481 psize = sizeof(*hdr) + sizeof(*body);
1482
1483 hdr->cmd = htole16(MALO_CMD_WEP)((__uint16_t)(0x0013));
1484 hdr->size = htole16(sizeof(*body))((__uint16_t)(sizeof(*body)));
1485 hdr->seqnum = htole16(1)((__uint16_t)(1));
1486 hdr->result = 0;
1487 body = (struct malo_cmd_body_wep *)(hdr + 1);
1488
1489 body->action = htole16(MALO_WEP_ACTION_TYPE_ADD)((__uint16_t)(0x02));
1490 body->key_index = htole16(index)((__uint16_t)(index));
1491
1492 if (body->key_index == 0) {
1493 if (key->k_len > 5)
1494 body->key_type_1 = MALO_WEP_KEY_TYPE_104BIT0x02;
1495 else
1496 body->key_type_1 = MALO_WEP_KEY_TYPE_40BIT0x01;
1497 bcopy(key->k_key, body->key_value_1, key->k_len);
1498 }
1499 if (body->key_index == 1) {
1500 if (key->k_len > 5)
1501 body->key_type_2 = MALO_WEP_KEY_TYPE_104BIT0x02;
1502 else
1503 body->key_type_2 = MALO_WEP_KEY_TYPE_40BIT0x01;
1504 bcopy(key->k_key, body->key_value_2, key->k_len);
1505 }
1506 if (body->key_index == 2) {
1507 if (key->k_len > 5)
1508 body->key_type_3 = MALO_WEP_KEY_TYPE_104BIT0x02;
1509 else
1510 body->key_type_3 = MALO_WEP_KEY_TYPE_40BIT0x01;
1511 bcopy(key->k_key, body->key_value_3, key->k_len);
1512 }
1513 if (body->key_index == 3) {
1514 if (key->k_len > 5)
1515 body->key_type_4 = MALO_WEP_KEY_TYPE_104BIT0x02;
1516 else
1517 body->key_type_4 = MALO_WEP_KEY_TYPE_40BIT0x01;
1518 bcopy(key->k_key, body->key_value_4, key->k_len);
1519 }
1520
1521 /* process command request */
1522 if (cmalo_cmd_request(sc, psize, 0) != 0)
1523 return (EIO5);
1524
1525 /* process command response */
1526 cmalo_cmd_response(sc);
1527
1528 return (0);
1529}
1530
1531int
1532cmalo_cmd_set_snmp(struct malo_softc *sc, uint16_t oid)
1533{
1534 struct malo_cmd_header *hdr = sc->sc_cmd;
1535 struct malo_cmd_body_snmp *body;
1536 uint16_t psize;
1537
1538 bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE)__builtin_bzero((sc->sc_cmd), (256));
1539 psize = sizeof(*hdr) + sizeof(*body);
1540
1541 hdr->cmd = htole16(MALO_CMD_SNMP)((__uint16_t)(0x0016));
1542 hdr->size = htole16(sizeof(*body))((__uint16_t)(sizeof(*body)));
1543 hdr->seqnum = htole16(1)((__uint16_t)(1));
1544 hdr->result = 0;
1545 body = (struct malo_cmd_body_snmp *)(hdr + 1);
1546
1547 body->action = htole16(1)((__uint16_t)(1));
1548
1549 switch (oid) {
1550 case MALO_OID_RTSTRESH0x05:
1551 body->oid = htole16(MALO_OID_RTSTRESH)((__uint16_t)(0x05));
1552 body->size = htole16(2)((__uint16_t)(2));
1553 *(uint16_t *)body->data = htole16(2347)((__uint16_t)(2347));
1554 break;
1555 case MALO_OID_SHORTRETRY0x06:
1556 body->oid = htole16(MALO_OID_SHORTRETRY)((__uint16_t)(0x06));
1557 body->size = htole16(2)((__uint16_t)(2));
1558 *(uint16_t *)body->data = htole16(4)((__uint16_t)(4));
1559 break;
1560 case MALO_OID_FRAGTRESH0x08:
1561 body->oid = htole16(MALO_OID_FRAGTRESH)((__uint16_t)(0x08));
1562 body->size = htole16(2)((__uint16_t)(2));
1563 *(uint16_t *)body->data = htole16(2346)((__uint16_t)(2346));
1564 break;
1565 case MALO_OID_80211D0x09:
1566 body->oid = htole16(MALO_OID_80211D)((__uint16_t)(0x09));
1567 body->size = htole16(2)((__uint16_t)(2));
1568 *(uint16_t *)body->data = htole16(1)((__uint16_t)(1));
1569 break;
1570 default:
1571 break;
1572 }
1573
1574 /* process command request */
1575 if (cmalo_cmd_request(sc, psize, 0) != 0)
1576 return (EIO5);
1577
1578 /* process command response */
1579 cmalo_cmd_response(sc);
1580
1581 return (0);
1582}
1583
1584int
1585cmalo_cmd_set_radio(struct malo_softc *sc, uint16_t control)
1586{
1587 struct malo_cmd_header *hdr = sc->sc_cmd;
1588 struct malo_cmd_body_radio *body;
1589 uint16_t psize;
1590
1591 bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE)__builtin_bzero((sc->sc_cmd), (256));
1592 psize = sizeof(*hdr) + sizeof(*body);
1593
1594 hdr->cmd = htole16(MALO_CMD_RADIO)((__uint16_t)(0x001c));
1595 hdr->size = htole16(sizeof(*body))((__uint16_t)(sizeof(*body)));
1596 hdr->seqnum = htole16(1)((__uint16_t)(1));
1597 hdr->result = 0;
1598 body = (struct malo_cmd_body_radio *)(hdr + 1);
1599
1600 body->action = htole16(1)((__uint16_t)(1));
1601
1602 if (control) {
1603 body->control = htole16(MALO_CMD_RADIO_ON)((__uint16_t)(0x0001));
1604 body->control |= htole16(MALO_CMD_RADIO_AUTO_P)((__uint16_t)(0x0004));
1605 }
1606
1607 /* process command request */
1608 if (cmalo_cmd_request(sc, psize, 0) != 0)
1609 return (EIO5);
1610
1611 /* process command response */
1612 cmalo_cmd_response(sc);
1613
1614 return (0);
1615}
1616
1617int
1618cmalo_cmd_set_channel(struct malo_softc *sc, uint16_t channel)
1619{
1620 struct malo_cmd_header *hdr = sc->sc_cmd;
1621 struct malo_cmd_body_channel *body;
1622 uint16_t psize;
1623
1624 bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE)__builtin_bzero((sc->sc_cmd), (256));
1625 psize = sizeof(*hdr) + sizeof(*body);
1626
1627 hdr->cmd = htole16(MALO_CMD_CHANNEL)((__uint16_t)(0x001d));
1628 hdr->size = htole16(sizeof(*body))((__uint16_t)(sizeof(*body)));
1629 hdr->seqnum = htole16(1)((__uint16_t)(1));
1630 hdr->result = 0;
1631 body = (struct malo_cmd_body_channel *)(hdr + 1);
1632
1633 body->action = htole16(1)((__uint16_t)(1));
1634 body->channel = htole16(channel)((__uint16_t)(channel));
1635
1636 /* process command request */
1637 if (cmalo_cmd_request(sc, psize, 0) != 0)
1638 return (EIO5);
1639
1640 /* process command response */
1641 cmalo_cmd_response(sc);
1642
1643 return (0);
1644}
1645
1646
1647int
1648cmalo_cmd_set_txpower(struct malo_softc *sc, int16_t txpower)
1649{
1650 struct malo_cmd_header *hdr = sc->sc_cmd;
1651 struct malo_cmd_body_txpower *body;
1652 uint16_t psize;
1653
1654 bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE)__builtin_bzero((sc->sc_cmd), (256));
1655 psize = sizeof(*hdr) + sizeof(*body);
1656
1657 hdr->cmd = htole16(MALO_CMD_TXPOWER)((__uint16_t)(0x001e));
1658 hdr->size = htole16(sizeof(*body))((__uint16_t)(sizeof(*body)));
1659 hdr->seqnum = htole16(1)((__uint16_t)(1));
1660 hdr->result = 0;
1661 body = (struct malo_cmd_body_txpower *)(hdr + 1);
1662
1663 body->action = htole16(1)((__uint16_t)(1));
1664 body->txpower = htole16(txpower)((__uint16_t)(txpower));
1665
1666 /* process command request */
1667 if (cmalo_cmd_request(sc, psize, 0) != 0)
1668 return (EIO5);
1669
1670 /* process command response */
1671 cmalo_cmd_response(sc);
1672
1673 return (0);
1674}
1675
1676int
1677cmalo_cmd_set_antenna(struct malo_softc *sc, uint16_t action)
1678{
1679 struct malo_cmd_header *hdr = sc->sc_cmd;
1680 struct malo_cmd_body_antenna *body;
1681 uint16_t psize;
1682
1683 bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE)__builtin_bzero((sc->sc_cmd), (256));
1684 psize = sizeof(*hdr) + sizeof(*body);
1685
1686 hdr->cmd = htole16(MALO_CMD_ANTENNA)((__uint16_t)(0x0020));
1687 hdr->size = htole16(sizeof(*body))((__uint16_t)(sizeof(*body)));
1688 hdr->seqnum = htole16(1)((__uint16_t)(1));
1689 hdr->result = 0;
1690 body = (struct malo_cmd_body_antenna *)(hdr + 1);
1691
1692 /* 1 = set RX, 2 = set TX */
1693 body->action = htole16(action)((__uint16_t)(action));
1694
1695 if (action == 1)
1696 /* set RX antenna */
1697 body->antenna_mode = htole16(0xffff)((__uint16_t)(0xffff));
1698 if (action == 2)
1699 /* set TX antenna */
1700 body->antenna_mode = htole16(2)((__uint16_t)(2));
1701
1702 /* process command request */
1703 if (cmalo_cmd_request(sc, psize, 0) != 0)
1704 return (EIO5);
1705
1706 /* process command response */
1707 cmalo_cmd_response(sc);
1708
1709 return (0);
1710}
1711
1712int
1713cmalo_cmd_set_macctrl(struct malo_softc *sc)
1714{
1715 struct ieee80211com *ic = &sc->sc_ic;
1716 struct malo_cmd_header *hdr = sc->sc_cmd;
1717 struct malo_cmd_body_macctrl *body;
1718 uint16_t psize;
1719
1720 bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE)__builtin_bzero((sc->sc_cmd), (256));
1721 psize = sizeof(*hdr) + sizeof(*body);
1722
1723 hdr->cmd = htole16(MALO_CMD_MACCTRL)((__uint16_t)(0x0028));
1724 hdr->size = htole16(sizeof(*body))((__uint16_t)(sizeof(*body)));
1725 hdr->seqnum = htole16(1)((__uint16_t)(1));
1726 hdr->result = 0;
1727 body = (struct malo_cmd_body_macctrl *)(hdr + 1);
1728
1729 body->action = htole16(MALO_CMD_MACCTRL_RX_ON)((__uint16_t)(0x0001));
1730 body->action |= htole16(MALO_CMD_MACCTRL_TX_ON)((__uint16_t)(0x0002));
1731 if (ic->ic_opmode == IEEE80211_M_MONITOR)
1732 body->action |= htole16(MALO_CMD_MACCTRL_PROMISC_ON)((__uint16_t)(0x0080));
1733
1734 /* process command request */
1735 if (cmalo_cmd_request(sc, psize, 0) != 0)
1736 return (EIO5);
1737
1738 /* process command response */
1739 cmalo_cmd_response(sc);
1740
1741 return (0);
1742}
1743
1744int
1745cmalo_cmd_set_macaddr(struct malo_softc *sc, uint8_t *macaddr)
1746{
1747 struct malo_cmd_header *hdr = sc->sc_cmd;
1748 struct malo_cmd_body_macaddr *body;
1749 uint16_t psize;
1750
1751 bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE)__builtin_bzero((sc->sc_cmd), (256));
1752 psize = sizeof(*hdr) + sizeof(*body);
1753
1754 hdr->cmd = htole16(MALO_CMD_MACADDR)((__uint16_t)(0x004d));
1755 hdr->size = htole16(sizeof(*body))((__uint16_t)(sizeof(*body)));
1756 hdr->seqnum = htole16(1)((__uint16_t)(1));
1757 hdr->result = 0;
1758 body = (struct malo_cmd_body_macaddr *)(hdr + 1);
1759
1760 body->action = htole16(1)((__uint16_t)(1));
1761 bcopy(macaddr, body->macaddr, ETHER_ADDR_LEN6);
1762
1763 /* process command request */
1764 if (cmalo_cmd_request(sc, psize, 0) != 0)
1765 return (EIO5);
1766
1767 /* process command response */
1768 cmalo_cmd_response(sc);
1769
1770 return (0);
1771}
1772
1773int
1774cmalo_cmd_set_assoc(struct malo_softc *sc)
1775{
1776 struct malo_cmd_header *hdr = sc->sc_cmd;
1777 struct malo_cmd_body_assoc *body;
1778 struct malo_cmd_tlv_ssid *body_ssid;
1779 struct malo_cmd_tlv_phy *body_phy;
1780 struct malo_cmd_tlv_cf *body_cf;
1781 struct malo_cmd_tlv_rates *body_rates;
1782 struct malo_cmd_tlv_passeid *body_passeid;
1783 uint16_t psize;
1784
1785 bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE)__builtin_bzero((sc->sc_cmd), (256));
1786 psize = sizeof(*hdr) + sizeof(*body);
1787
1788 hdr->cmd = htole16(MALO_CMD_ASSOC)((__uint16_t)(0x0050));
1789 hdr->seqnum = htole16(1)((__uint16_t)(1));
1790 hdr->result = 0;
1791 body = (struct malo_cmd_body_assoc *)(hdr + 1);
1792
1793 bcopy(sc->sc_net[sc->sc_net_cur].bssid, body->peermac, ETHER_ADDR_LEN6);
1794 body->capinfo = htole16(sc->sc_net[sc->sc_net_cur].capinfo)((__uint16_t)(sc->sc_net[sc->sc_net_cur].capinfo));
1795 body->listenintrv = htole16(10)((__uint16_t)(10));
1796
1797 body_ssid = sc->sc_cmd + psize;
1798 body_ssid->type = htole16(MALO_TLV_TYPE_SSID)((__uint16_t)(0x0000));
1799 body_ssid->size = htole16(strlen(sc->sc_net[sc->sc_net_cur].ssid))((__uint16_t)(strlen(sc->sc_net[sc->sc_net_cur].ssid)));
1800 bcopy(sc->sc_net[sc->sc_net_cur].ssid, body_ssid->data,
1801 letoh16(body_ssid->size)((__uint16_t)(body_ssid->size)));
1802 psize += (sizeof(*body_ssid) - 1) + letoh16(body_ssid->size)((__uint16_t)(body_ssid->size));
1803
1804 body_phy = sc->sc_cmd + psize;
1805 body_phy->type = htole16(MALO_TLV_TYPE_PHY)((__uint16_t)(0x0003));
1806 body_phy->size = htole16(1)((__uint16_t)(1));
1807 bcopy(&sc->sc_net[sc->sc_net_cur].channel, body_phy->data, 1);
1808 psize += sizeof(*body_phy);
1809
1810 body_cf = sc->sc_cmd + psize;
1811 body_cf->type = htole16(MALO_TLV_TYPE_CF)((__uint16_t)(0x0004));
1812 body_cf->size = htole16(0)((__uint16_t)(0));
1813 psize += (sizeof(*body_cf) - 1);
1814
1815 body_rates = sc->sc_cmd + psize;
1816 body_rates->type = htole16(MALO_TLV_TYPE_RATES)((__uint16_t)(0x0001));
1817 body_rates->size = htole16(strlen(sc->sc_net[sc->sc_net_cur].rates))((__uint16_t)(strlen(sc->sc_net[sc->sc_net_cur].rates))
)
;
1818 bcopy(sc->sc_net[sc->sc_net_cur].rates, body_rates->data,
1819 letoh16(body_rates->size)((__uint16_t)(body_rates->size)));
1820 psize += (sizeof(*body_rates) - 1) + letoh16(body_rates->size)((__uint16_t)(body_rates->size));
1821
1822 /* hack to correct FW's wrong generated rates-element-id */
1823 body_passeid = sc->sc_cmd + psize;
1824 body_passeid->type = htole16(MALO_TLV_TYPE_PASSEID)((__uint16_t)(0x010a));
1825 body_passeid->size = body_rates->size;
1826 bcopy(body_rates->data, body_passeid->data, letoh16(body_rates->size)((__uint16_t)(body_rates->size)));
1827 psize += (sizeof(*body_passeid) - 1) + letoh16(body_passeid->size)((__uint16_t)(body_passeid->size));
1828
1829 hdr->size = htole16(psize - sizeof(*hdr))((__uint16_t)(psize - sizeof(*hdr)));
1830
1831 /* process command request */
1832 if (!sc->sc_cmd_ctxsave) {
1833 if (cmalo_cmd_request(sc, psize, 1) != 0)
1834 return (EIO5);
1835 return (0);
1836 }
1837 if (cmalo_cmd_request(sc, psize, 0) != 0)
1838 return (EIO5);
1839
1840 /* process command response */
1841 cmalo_cmd_response(sc);
1842
1843 return (0);
1844}
1845
1846int
1847cmalo_cmd_rsp_assoc(struct malo_softc *sc)
1848{
1849 struct malo_cmd_header *hdr = sc->sc_cmd;
1850 struct malo_cmd_body_rsp_assoc *body;
1851
1852 body = (struct malo_cmd_body_rsp_assoc *)(hdr + 1);
1853
1854 if (body->status) {
1855 DPRINTF(1, "%s: association failed (status %d)\n",
1856 sc->sc_dev.dv_xname, body->status);
1857 sc->sc_flags |= MALO_ASSOC_FAILED(1 << 2);
1858 } else
1859 DPRINTF(1, "%s: association successful\n",
1860 sc->sc_dev.dv_xname, body->status);
1861
1862 return (0);
1863}
1864
1865int
1866cmalo_cmd_set_80211d(struct malo_softc *sc)
1867{
1868 struct malo_cmd_header *hdr = sc->sc_cmd;
1869 struct malo_cmd_body_80211d *body;
1870 struct malo_cmd_tlv_80211d *body_80211d;
1871 uint16_t psize;
1872 int i;
1873
1874 bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE)__builtin_bzero((sc->sc_cmd), (256));
1875 psize = sizeof(*hdr) + sizeof(*body);
1876
1877 hdr->cmd = htole16(MALO_CMD_80211D)((__uint16_t)(0x005b));
1878 hdr->seqnum = htole16(1)((__uint16_t)(1));
1879 hdr->result = 0;
1880 body = (struct malo_cmd_body_80211d *)(hdr + 1);
1881
1882 body->action = htole16(1)((__uint16_t)(1));
1883
1884 body_80211d = sc->sc_cmd + psize;
1885 body_80211d->type = htole16(MALO_TLV_TYPE_80211D)((__uint16_t)(0x0007));
1886 body_80211d->size = htole16(sizeof(body_80211d->data) +((__uint16_t)(sizeof(body_80211d->data) + sizeof(body_80211d
->countrycode)))
1887 sizeof(body_80211d->countrycode))((__uint16_t)(sizeof(body_80211d->data) + sizeof(body_80211d
->countrycode)))
;
1888 bcopy("EU ", body_80211d->countrycode,
1889 sizeof(body_80211d->countrycode));
1890 for (i = 0; i < CHANNELS12; i++) {
1891 body_80211d->data[i].firstchannel = 1;
1892 body_80211d->data[i].numchannels = 12;
1893 body_80211d->data[i].maxtxpower = 10;
1894 }
1895 psize += sizeof(*body_80211d);
1896
1897 hdr->size = htole16(psize - sizeof(*hdr))((__uint16_t)(psize - sizeof(*hdr)));
1898
1899 /* process command request */
1900 if (cmalo_cmd_request(sc, psize, 0) != 0)
1901 return (EIO5);
1902
1903 /* process command response */
1904 cmalo_cmd_response(sc);
1905
1906 return (0);
1907}
1908
1909int
1910cmalo_cmd_set_bgscan_config(struct malo_softc *sc)
1911{
1912 struct malo_cmd_header *hdr = sc->sc_cmd;
1913 struct malo_cmd_body_bgscan_config *body;
1914 uint16_t psize;
1915
1916 bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE)__builtin_bzero((sc->sc_cmd), (256));
1917 psize = sizeof(*hdr) + sizeof(*body);
1918
1919 hdr->cmd = htole16(MALO_CMD_BGSCAN_CONFIG)((__uint16_t)(0x006b));
1920 hdr->size = htole16(sizeof(*body))((__uint16_t)(sizeof(*body)));
1921 hdr->seqnum = htole16(1)((__uint16_t)(1));
1922 hdr->result = 0;
1923 body = (struct malo_cmd_body_bgscan_config *)(hdr + 1);
1924
1925 body->action = htole16(1)((__uint16_t)(1));
1926 body->enable = 1;
1927 body->bsstype = 0x03;
1928 body->chperscan = 12;
1929 body->scanintvl = htole32(100)((__uint32_t)(100));
1930 body->maxscanres = htole16(12)((__uint16_t)(12));
1931
1932 /* process command request */
1933 if (cmalo_cmd_request(sc, psize, 0) != 0)
1934 return (EIO5);
1935
1936 /* process command response */
1937 cmalo_cmd_response(sc);
1938
1939 return (0);
1940}
1941
1942int
1943cmalo_cmd_set_bgscan_query(struct malo_softc *sc)
1944{
1945 struct malo_cmd_header *hdr = sc->sc_cmd;
1946 struct malo_cmd_body_bgscan_query *body;
1947 uint16_t psize;
1948
1949 bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE)__builtin_bzero((sc->sc_cmd), (256));
1950 psize = sizeof(*hdr) + sizeof(*body);
1951
1952 hdr->cmd = htole16(MALO_CMD_BGSCAN_QUERY)((__uint16_t)(0x006c));
1953 hdr->size = htole16(sizeof(*body))((__uint16_t)(sizeof(*body)));
1954 hdr->seqnum = htole16(1)((__uint16_t)(1));
1955 hdr->result = 0;
1956 body = (struct malo_cmd_body_bgscan_query *)(hdr + 1);
1957
1958 body->flush = 0;
1959
1960 /* process command request */
1961 if (cmalo_cmd_request(sc, psize, 0) != 0)
1962 return (EIO5);
1963
1964 /* process command response */
1965 cmalo_cmd_response(sc);
1966
1967 return (0);
1968}
1969
1970int
1971cmalo_cmd_set_rate(struct malo_softc *sc, int rate)
1972{
1973 struct malo_cmd_header *hdr = sc->sc_cmd;
1974 struct malo_cmd_body_rate *body;
1975 uint16_t psize;
1976
1977 bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE)__builtin_bzero((sc->sc_cmd), (256));
1978 psize = sizeof(*hdr) + sizeof(*body);
1979
1980 hdr->cmd = htole16(MALO_CMD_RATE)((__uint16_t)(0x0076));
1981 hdr->size = htole16(sizeof(*body))((__uint16_t)(sizeof(*body)));
1982 hdr->seqnum = htole16(1)((__uint16_t)(1));
1983 hdr->result = 0;
1984 body = (struct malo_cmd_body_rate *)(hdr + 1);
1985
1986 body->action = htole16(1)((__uint16_t)(1));
1987 if (rate == -1) {
1988 body->hwauto = htole16(1)((__uint16_t)(1));
1989 body->ratebitmap = htole16(MALO_RATE_BITMAP_AUTO)((__uint16_t)(0x1fef));
1990 } else {
1991 body->hwauto = 0;
1992 body->ratebitmap = htole16(cmalo_rate2bitmap(rate))((__uint16_t)(cmalo_rate2bitmap(rate)));
1993 }
1994
1995 /* process command request */
1996 if (cmalo_cmd_request(sc, psize, 0) != 0)
1997 return (EIO5);
1998
1999 /* process command response */
2000 cmalo_cmd_response(sc);
2001
2002 return (0);
2003}
2004
2005int
2006cmalo_cmd_request(struct malo_softc *sc, uint16_t psize, int no_response)
2007{
2008 uint8_t *cmd;
2009
2010 cmalo_hexdump(sc->sc_cmd, psize);
2011
2012 /* send command request */
2013 MALO_WRITE_2(sc, MALO_REG_CMD_WRITE_LEN, psize)(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x18)), (
(psize))))
;
2014 if (psize & 0x0001) {
2015 MALO_WRITE_MULTI_2(sc, MALO_REG_CMD_WRITE, sc->sc_cmd,(((sc)->sc_iot)->write_multi_2(((sc)->sc_ioh), ((0x1a
)), (const u_int16_t *)((sc->sc_cmd)), ((psize - 1)) >>
1))
2016 psize - 1)(((sc)->sc_iot)->write_multi_2(((sc)->sc_ioh), ((0x1a
)), (const u_int16_t *)((sc->sc_cmd)), ((psize - 1)) >>
1))
;
2017 cmd = (uint8_t *)sc->sc_cmd;
2018 MALO_WRITE_1(sc, MALO_REG_CMD_WRITE, cmd[psize - 1])(((sc)->sc_iot)->write_1(((sc)->sc_ioh), ((0x1a)), (
(cmd[psize - 1]))))
;
2019 } else
2020 MALO_WRITE_MULTI_2(sc, MALO_REG_CMD_WRITE, sc->sc_cmd, psize)(((sc)->sc_iot)->write_multi_2(((sc)->sc_ioh), ((0x1a
)), (const u_int16_t *)((sc->sc_cmd)), ((psize)) >> 1
))
;
2021 MALO_WRITE_1(sc, MALO_REG_HOST_STATUS, MALO_VAL_CMD_DL_OVER)(((sc)->sc_iot)->write_1(((sc)->sc_ioh), ((0x00)), (
(0x04))))
;
2022 MALO_WRITE_2(sc, MALO_REG_CARD_INTR_CAUSE, MALO_VAL_CMD_DL_OVER)(((sc)->sc_iot)->write_2(((sc)->sc_ioh), ((0x02)), (
(0x04))))
;
2023
2024 if (no_response)
2025 /* we don't expect a response */
2026 return (0);
2027
2028 /* wait for the command response */
2029 if (tsleep_nsec(sc, 0, "malocmd", SEC_TO_NSEC(5))) {
2030 printf("%s: timeout while waiting for cmd response\n",
2031 sc->sc_dev.dv_xname);
2032 return (EIO5);
2033 }
2034
2035 return (0);
2036}
2037
2038int
2039cmalo_cmd_response(struct malo_softc *sc)
2040{
2041 struct malo_cmd_header *hdr = sc->sc_cmd;
2042 uint16_t psize;
2043 uint8_t *cmd;
2044 int s;
2045
2046 s = splnet()splraise(0x7);
2047
2048 bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE)__builtin_bzero((sc->sc_cmd), (256));
2049
2050 /* read the whole command response */
2051 psize = MALO_READ_2(sc, MALO_REG_CMD_READ_LEN)(((sc)->sc_iot)->read_2(((sc)->sc_ioh), ((0x30))));
2052 if (psize & 0x0001) {
2053 MALO_READ_MULTI_2(sc, MALO_REG_CMD_READ, sc->sc_cmd,(((sc)->sc_iot)->read_multi_2(((sc)->sc_ioh), ((0x12
)), (u_int16_t *)((sc->sc_cmd)), ((psize - 1)) >> 1)
)
2054 psize - 1)(((sc)->sc_iot)->read_multi_2(((sc)->sc_ioh), ((0x12
)), (u_int16_t *)((sc->sc_cmd)), ((psize - 1)) >> 1)
)
;
2055 cmd = (uint8_t *)sc->sc_cmd;
2056 cmd[psize - 1] = MALO_READ_1(sc, MALO_REG_CMD_READ)(((sc)->sc_iot)->read_1(((sc)->sc_ioh), ((0x12))));
2057 } else
2058 MALO_READ_MULTI_2(sc, MALO_REG_CMD_READ, sc->sc_cmd, psize)(((sc)->sc_iot)->read_multi_2(((sc)->sc_ioh), ((0x12
)), (u_int16_t *)((sc->sc_cmd)), ((psize)) >> 1))
;
2059
2060 cmalo_hexdump(sc->sc_cmd, psize);
2061
2062 /*
2063 * We convert the header values into the machines correct endianness,
2064 * so we don't have to letoh16() all over the code. The body is
2065 * kept in the cards order, little endian. We need to take care
2066 * about the body endianness in the corresponding response routines.
2067 */
2068 hdr->cmd = letoh16(hdr->cmd)((__uint16_t)(hdr->cmd));
2069 hdr->size = letoh16(hdr->size)((__uint16_t)(hdr->size));
2070 hdr->seqnum = letoh16(hdr->seqnum)((__uint16_t)(hdr->seqnum));
2071 hdr->result = letoh16(hdr->result)((__uint16_t)(hdr->result));
2072
2073 /* check for a valid command response */
2074 if (!(hdr->cmd & MALO_CMD_RESP0x8000)) {
2075 printf("%s: got invalid command response (0x%04x)\n",
2076 sc->sc_dev.dv_xname, hdr->cmd);
2077 splx(s)spllower(s);
2078 return (EIO5);
2079 }
2080 hdr->cmd &= ~MALO_CMD_RESP0x8000;
2081
2082 /* association cmd response is special */
2083 if (hdr->cmd == 0x0012)
2084 hdr->cmd = MALO_CMD_ASSOC0x0050;
2085
2086 /* to which command does the response belong */
2087 switch (hdr->cmd) {
2088 case MALO_CMD_HWSPEC0x0003:
2089 DPRINTF(1, "%s: got hwspec cmd response\n",
2090 sc->sc_dev.dv_xname);
2091 cmalo_cmd_rsp_hwspec(sc);
2092 break;
2093 case MALO_CMD_RESET0x0005:
2094 /* reset will not send back a response */
2095 break;
2096 case MALO_CMD_SCAN0x0006:
2097 DPRINTF(1, "%s: got scan cmd response\n",
2098 sc->sc_dev.dv_xname);
2099 cmalo_cmd_rsp_scan(sc);
2100 break;
2101 case MALO_CMD_AUTH0x0011:
2102 /* do nothing */
2103 DPRINTF(1, "%s: got auth cmd response\n",
2104 sc->sc_dev.dv_xname);
2105 break;
2106 case MALO_CMD_WEP0x0013:
2107 /* do nothing */
2108 DPRINTF(1, "%s: got wep cmd response\n",
2109 sc->sc_dev.dv_xname);
2110 break;
2111 case MALO_CMD_SNMP0x0016:
2112 /* do nothing */
2113 DPRINTF(1, "%s: got snmp cmd response\n",
2114 sc->sc_dev.dv_xname);
2115 break;
2116 case MALO_CMD_RADIO0x001c:
2117 /* do nothing */
2118 DPRINTF(1, "%s: got radio cmd response\n",
2119 sc->sc_dev.dv_xname);
2120 break;
2121 case MALO_CMD_CHANNEL0x001d:
2122 /* do nothing */
2123 DPRINTF(1, "%s: got channel cmd response\n",
2124 sc->sc_dev.dv_xname);
2125 break;
2126 case MALO_CMD_TXPOWER0x001e:
2127 /* do nothing */
2128 DPRINTF(1, "%s: got txpower cmd response\n",
2129 sc->sc_dev.dv_xname);
2130 break;
2131 case MALO_CMD_ANTENNA0x0020:
2132 /* do nothing */
2133 DPRINTF(1, "%s: got antenna cmd response\n",
2134 sc->sc_dev.dv_xname);
2135 break;
2136 case MALO_CMD_MACCTRL0x0028:
2137 /* do nothing */
2138 DPRINTF(1, "%s: got macctrl cmd response\n",
2139 sc->sc_dev.dv_xname);
2140 break;
2141 case MALO_CMD_MACADDR0x004d:
2142 /* do nothing */
2143 DPRINTF(1, "%s: got macaddr cmd response\n",
2144 sc->sc_dev.dv_xname);
2145 break;
2146 case MALO_CMD_ASSOC0x0050:
2147 /* do nothing */
2148 DPRINTF(1, "%s: got assoc cmd response\n",
2149 sc->sc_dev.dv_xname);
2150 cmalo_cmd_rsp_assoc(sc);
2151 break;
2152 case MALO_CMD_80211D0x005b:
2153 /* do nothing */
2154 DPRINTF(1, "%s: got 80211d cmd response\n",
2155 sc->sc_dev.dv_xname);
2156 break;
2157 case MALO_CMD_BGSCAN_CONFIG0x006b:
2158 /* do nothing */
2159 DPRINTF(1, "%s: got bgscan config cmd response\n",
2160 sc->sc_dev.dv_xname);
2161 break;
2162 case MALO_CMD_BGSCAN_QUERY0x006c:
2163 /* do nothing */
2164 DPRINTF(1, "%s: got bgscan query cmd response\n",
2165 sc->sc_dev.dv_xname);
2166 break;
2167 case MALO_CMD_RATE0x0076:
2168 /* do nothing */
2169 DPRINTF(1, "%s: got rate cmd response\n",
2170 sc->sc_dev.dv_xname);
2171 break;
2172 default:
2173 printf("%s: got unknown cmd response (0x%04x)\n",
2174 sc->sc_dev.dv_xname, hdr->cmd);
2175 break;
2176 }
2177
2178 splx(s)spllower(s);
2179
2180 return (0);
2181}