Bug Summary

File:dev/ic/malo.c
Warning:line 1385, column 2
Value stored to 'wh' 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 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/ic/malo.c
1/* $OpenBSD: malo.c,v 1.122 2022/01/09 05:42:38 jsg Exp $ */
2
3/*
4 * Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
5 * Copyright (c) 2006 Marcus Glocker <mglocker@openbsd.org>
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#include "bpfilter.h"
21
22#include <sys/param.h>
23
24#include <sys/device.h>
25#include <sys/kernel.h>
26#include <sys/malloc.h>
27#include <sys/mbuf.h>
28#include <sys/socket.h>
29#include <sys/sockio.h>
30#include <sys/systm.h>
31#include <sys/endian.h>
32
33#include <machine/bus.h>
34#include <machine/intr.h>
35
36#include <net/if.h>
37#include <net/if_media.h>
38
39#if NBPFILTER1 > 0
40#include <net/bpf.h>
41#endif
42
43#include <netinet/in.h>
44#include <netinet/if_ether.h>
45
46#include <net80211/ieee80211_var.h>
47#include <net80211/ieee80211_radiotap.h>
48
49#include <dev/ic/malo.h>
50
51#ifdef MALO_DEBUG
52int malo_d = 1;
53#define DPRINTF(l, x...) do { if ((l) <= malo_d) printf(x); } while (0)
54#else
55#define DPRINTF(l, x...)
56#endif
57
58/* internal structures and defines */
59struct malo_node {
60 struct ieee80211_node ni;
61};
62
63struct malo_rx_data {
64 bus_dmamap_t map;
65 struct mbuf *m;
66};
67
68struct malo_tx_data {
69 bus_dmamap_t map;
70 struct mbuf *m;
71 uint32_t softstat;
72 struct ieee80211_node *ni;
73};
74
75/* RX descriptor used by HW */
76struct malo_rx_desc {
77 uint8_t rxctrl;
78 uint8_t rssi;
79 uint8_t status;
80 uint8_t channel;
81 uint16_t len;
82 uint8_t reserved1; /* actually unused */
83 uint8_t datarate;
84 uint32_t physdata; /* DMA address of data */
85 uint32_t physnext; /* DMA address of next control block */
86 uint16_t qosctrl;
87 uint16_t reserved2;
88} __packed__attribute__((__packed__));
89
90/* TX descriptor used by HW */
91struct malo_tx_desc {
92 uint32_t status;
93 uint8_t datarate;
94 uint8_t txpriority;
95 uint16_t qosctrl;
96 uint32_t physdata; /* DMA address of data */
97 uint16_t len;
98 uint8_t destaddr[6];
99 uint32_t physnext; /* DMA address of next control block */
100 uint32_t reserved1; /* SAP packet info ??? */
101 uint32_t reserved2;
102} __packed__attribute__((__packed__));
103
104#define MALO_RX_RING_COUNT256 256
105#define MALO_TX_RING_COUNT256 256
106#define MALO_MAX_SCATTER8 8 /* XXX unknown, wild guess */
107#define MALO_CMD_TIMEOUT50 50 /* MALO_CMD_TIMEOUT * 100us */
108
109/*
110 * Firmware commands
111 */
112#define MALO_CMD_GET_HW_SPEC0x0003 0x0003
113#define MALO_CMD_SET_RADIO0x001c 0x001c
114#define MALO_CMD_SET_AID0x010d 0x010d
115#define MALO_CMD_SET_TXPOWER0x001e 0x001e
116#define MALO_CMD_SET_ANTENNA0x0020 0x0020
117#define MALO_CMD_SET_PRESCAN0x0107 0x0107
118#define MALO_CMD_SET_POSTSCAN0x0108 0x0108
119#define MALO_CMD_SET_RATE0x0110 0x0110
120#define MALO_CMD_SET_CHANNEL0x010a 0x010a
121#define MALO_CMD_SET_RTS0x0113 0x0113
122#define MALO_CMD_SET_SLOT0x0114 0x0114
123#define MALO_CMD_RESPONSE0x8000 0x8000
124
125#define MALO_CMD_RESULT_OK0x0000 0x0000 /* everything is fine */
126#define MALO_CMD_RESULT_ERROR0x0001 0x0001 /* general error */
127#define MALO_CMD_RESULT_NOSUPPORT0x0002 0x0002 /* command not valid */
128#define MALO_CMD_RESULT_PENDING0x0003 0x0003 /* will be processed */
129#define MALO_CMD_RESULT_BUSY0x0004 0x0004 /* command ignored */
130#define MALO_CMD_RESULT_PARTIALDATA0x0005 0x0005 /* buffer too small */
131
132struct malo_cmdheader {
133 uint16_t cmd;
134 uint16_t size; /* size of the command, incl. header */
135 uint16_t seqnum; /* seems not to matter that much */
136 uint16_t result; /* set to 0 on request */
137 /* following the data payload, up to 256 bytes */
138};
139
140struct malo_hw_spec {
141 uint16_t HwVersion;
142 uint16_t NumOfWCB;
143 uint16_t NumOfMCastAdr;
144 uint8_t PermanentAddress[6];
145 uint16_t RegionCode;
146 uint16_t NumberOfAntenna;
147 uint32_t FWReleaseNumber;
148 uint32_t WcbBase0;
149 uint32_t RxPdWrPtr;
150 uint32_t RxPdRdPtr;
151 uint32_t CookiePtr;
152 uint32_t WcbBase1;
153 uint32_t WcbBase2;
154 uint32_t WcbBase3;
155} __packed__attribute__((__packed__));
156
157struct malo_cmd_radio {
158 uint16_t action;
159 uint16_t preamble_mode;
160 uint16_t enable;
161} __packed__attribute__((__packed__));
162
163struct malo_cmd_aid {
164 uint16_t associd;
165 uint8_t macaddr[6];
166 uint32_t gprotection;
167 uint8_t aprates[14];
168} __packed__attribute__((__packed__));
169
170struct malo_cmd_txpower {
171 uint16_t action;
172 uint16_t supportpowerlvl;
173 uint16_t currentpowerlvl;
174 uint16_t reserved;
175 uint16_t powerlvllist[8];
176} __packed__attribute__((__packed__));
177
178struct malo_cmd_antenna {
179 uint16_t action;
180 uint16_t mode;
181} __packed__attribute__((__packed__));
182
183struct malo_cmd_postscan {
184 uint32_t isibss;
185 uint8_t bssid[6];
186} __packed__attribute__((__packed__));
187
188struct malo_cmd_channel {
189 uint16_t action;
190 uint8_t channel;
191} __packed__attribute__((__packed__));
192
193struct malo_cmd_rate {
194 uint8_t dataratetype;
195 uint8_t rateindex;
196 uint8_t aprates[14];
197} __packed__attribute__((__packed__));
198
199struct malo_cmd_rts {
200 uint16_t action;
201 uint32_t threshold;
202} __packed__attribute__((__packed__));
203
204struct malo_cmd_slot {
205 uint16_t action;
206 uint8_t slot;
207} __packed__attribute__((__packed__));
208
209#define malo_mem_write4(sc, off, x)(((sc)->sc_mem1_bt)->write_4(((sc)->sc_mem1_bh), ((off
)), ((x))))
\
210 bus_space_write_4((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off), (x))(((sc)->sc_mem1_bt)->write_4(((sc)->sc_mem1_bh), ((off
)), ((x))))
211#define malo_mem_write2(sc, off, x)(((sc)->sc_mem1_bt)->write_2(((sc)->sc_mem1_bh), ((off
)), ((x))))
\
212 bus_space_write_2((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off), (x))(((sc)->sc_mem1_bt)->write_2(((sc)->sc_mem1_bh), ((off
)), ((x))))
213#define malo_mem_write1(sc, off, x)(((sc)->sc_mem1_bt)->write_1(((sc)->sc_mem1_bh), ((off
)), ((x))))
\
214 bus_space_write_1((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off), (x))(((sc)->sc_mem1_bt)->write_1(((sc)->sc_mem1_bh), ((off
)), ((x))))
215
216#define malo_mem_read4(sc, off)(((sc)->sc_mem1_bt)->read_4(((sc)->sc_mem1_bh), ((off
))))
\
217 bus_space_read_4((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off))(((sc)->sc_mem1_bt)->read_4(((sc)->sc_mem1_bh), ((off
))))
218#define malo_mem_read1(sc, off)(((sc)->sc_mem1_bt)->read_1(((sc)->sc_mem1_bh), ((off
))))
\
219 bus_space_read_1((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off))(((sc)->sc_mem1_bt)->read_1(((sc)->sc_mem1_bh), ((off
))))
220
221#define malo_ctl_write4(sc, off, x)(((sc)->sc_mem2_bt)->write_4(((sc)->sc_mem2_bh), ((off
)), ((x))))
\
222 bus_space_write_4((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, (off), (x))(((sc)->sc_mem2_bt)->write_4(((sc)->sc_mem2_bh), ((off
)), ((x))))
223#define malo_ctl_read4(sc, off)(((sc)->sc_mem2_bt)->read_4(((sc)->sc_mem2_bh), ((off
))))
\
224 bus_space_read_4((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, (off))(((sc)->sc_mem2_bt)->read_4(((sc)->sc_mem2_bh), ((off
))))
225#define malo_ctl_read1(sc, off)(((sc)->sc_mem2_bt)->read_1(((sc)->sc_mem2_bh), ((off
))))
\
226 bus_space_read_1((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, (off))(((sc)->sc_mem2_bt)->read_1(((sc)->sc_mem2_bh), ((off
))))
227
228#define malo_ctl_barrier(sc, t)bus_space_barrier((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, 0x0c00
, 0xff, (t))
\
229 bus_space_barrier((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, 0x0c00, 0xff, (t))
230
231struct cfdriver malo_cd = {
232 NULL((void *)0), "malo", DV_IFNET
233};
234
235int malo_alloc_cmd(struct malo_softc *sc);
236void malo_free_cmd(struct malo_softc *sc);
237void malo_send_cmd(struct malo_softc *sc, bus_addr_t addr);
238int malo_send_cmd_dma(struct malo_softc *sc, bus_addr_t addr);
239int malo_alloc_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring,
240 int count);
241void malo_reset_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring);
242void malo_free_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring);
243int malo_alloc_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring,
244 int count);
245void malo_reset_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring);
246void malo_free_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring);
247int malo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
248void malo_start(struct ifnet *ifp);
249void malo_watchdog(struct ifnet *ifp);
250int malo_newstate(struct ieee80211com *ic, enum ieee80211_state nstate,
251 int arg);
252void malo_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni,
253 int isnew);
254struct ieee80211_node *
255 malo_node_alloc(struct ieee80211com *ic);
256int malo_media_change(struct ifnet *ifp);
257void malo_media_status(struct ifnet *ifp, struct ifmediareq *imr);
258int malo_chip2rate(int chip_rate);
259int malo_fix2rate(int fix_rate);
260void malo_next_scan(void *arg);
261void malo_tx_intr(struct malo_softc *sc);
262int malo_tx_mgt(struct malo_softc *sc, struct mbuf *m0,
263 struct ieee80211_node *ni);
264int malo_tx_data(struct malo_softc *sc, struct mbuf *m0,
265 struct ieee80211_node *ni);
266void malo_tx_setup_desc(struct malo_softc *sc, struct malo_tx_desc *desc,
267 int len, int rate, const bus_dma_segment_t *segs, int nsegs);
268void malo_rx_intr(struct malo_softc *sc);
269int malo_load_bootimg(struct malo_softc *sc);
270int malo_load_firmware(struct malo_softc *sc);
271
272int malo_set_slot(struct malo_softc *sc);
273void malo_update_slot(struct ieee80211com *ic);
274#ifdef MALO_DEBUG
275void malo_hexdump(void *buf, int len);
276#endif
277static char *
278 malo_cmd_string(uint16_t cmd);
279static char *
280 malo_cmd_string_result(uint16_t result);
281int malo_cmd_get_spec(struct malo_softc *sc);
282int malo_cmd_set_prescan(struct malo_softc *sc);
283int malo_cmd_set_postscan(struct malo_softc *sc, uint8_t *macaddr,
284 uint8_t ibsson);
285int malo_cmd_set_channel(struct malo_softc *sc, uint8_t channel);
286int malo_cmd_set_antenna(struct malo_softc *sc, uint16_t antenna_type);
287int malo_cmd_set_radio(struct malo_softc *sc, uint16_t mode,
288 uint16_t preamble);
289int malo_cmd_set_aid(struct malo_softc *sc, uint8_t *bssid,
290 uint16_t associd);
291int malo_cmd_set_txpower(struct malo_softc *sc, unsigned int powerlevel);
292int malo_cmd_set_rts(struct malo_softc *sc, uint32_t threshold);
293int malo_cmd_set_slot(struct malo_softc *sc, uint8_t slot);
294int malo_cmd_set_rate(struct malo_softc *sc, uint8_t rate);
295void malo_cmd_response(struct malo_softc *sc);
296
297int
298malo_intr(void *arg)
299{
300 struct malo_softc *sc = arg;
301 uint32_t status;
302
303 status = malo_ctl_read4(sc, 0x0c30)(((sc)->sc_mem2_bt)->read_4(((sc)->sc_mem2_bh), ((0x0c30
))))
;
304 if (status == 0xffffffff || status == 0)
305 /* not for us */
306 return (0);
307
308 if (status & 0x1)
309 malo_tx_intr(sc);
310 if (status & 0x2)
311 malo_rx_intr(sc);
312 if (status & 0x4) {
313 /* XXX cmd done interrupt handling doesn't work yet */
314 DPRINTF(1, "%s: got cmd done interrupt\n", sc->sc_dev.dv_xname);
315 //malo_cmd_response(sc);
316 }
317
318 if (status & ~0x7)
319 DPRINTF(1, "%s: unknown interrupt %x\n",
320 sc->sc_dev.dv_xname, status);
321
322 /* just ack the interrupt */
323 malo_ctl_write4(sc, 0x0c30, 0)(((sc)->sc_mem2_bt)->write_4(((sc)->sc_mem2_bh), ((0x0c30
)), ((0))))
;
324
325 return (1);
326}
327
328int
329malo_attach(struct malo_softc *sc)
330{
331 struct ieee80211com *ic = &sc->sc_ic;
332 struct ifnet *ifp = &sc->sc_ic.ic_ific_ac.ac_if;
333 int i;
334
335 /* initialize channel scanning timer */
336 timeout_set(&sc->sc_scan_to, malo_next_scan, sc);
337
338 /* allocate DMA structures */
339 malo_alloc_cmd(sc);
340 malo_alloc_rx_ring(sc, &sc->sc_rxring, MALO_RX_RING_COUNT256);
341 malo_alloc_tx_ring(sc, &sc->sc_txring, MALO_TX_RING_COUNT256);
342
343 /* setup interface */
344 ifp->if_softc = sc;
345 ifp->if_ioctl = malo_ioctl;
346 ifp->if_start = malo_start;
347 ifp->if_watchdog = malo_watchdog;
348 ifp->if_flags = IFF_SIMPLEX0x800 | IFF_BROADCAST0x2 | IFF_MULTICAST0x8000;
349 strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ16);
350 ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN)((&ifp->if_snd)->ifq_maxlen = (256));
351
352 /* set supported rates */
353 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
354 ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
355 sc->sc_last_txrate = -1;
356
357 /* set channels */
358 for (i = 1; i <= 14; i++) {
359 ic->ic_channels[i].ic_freq =
360 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ0x0080);
361 ic->ic_channels[i].ic_flags =
362 IEEE80211_CHAN_PUREG(0x0080 | 0x0040) |
363 IEEE80211_CHAN_B(0x0080 | 0x0020) |
364 IEEE80211_CHAN_G(0x0080 | 0x0400);
365 }
366
367 /* set the rest */
368 ic->ic_caps =
369 IEEE80211_C_IBSS0x00000002 |
370 IEEE80211_C_MONITOR0x00000200 |
371 IEEE80211_C_SHPREAMBLE0x00000100 |
372 IEEE80211_C_SHSLOT0x00000080 |
373 IEEE80211_C_WEP0x00000001 |
374 IEEE80211_C_RSN0x00001000;
375 ic->ic_opmode = IEEE80211_M_STA;
376 ic->ic_state = IEEE80211_S_INIT;
377 ic->ic_max_rssi = 75;
378 for (i = 0; i < 6; i++)
379 ic->ic_myaddr[i] = malo_ctl_read1(sc, 0xa528 + i)(((sc)->sc_mem2_bt)->read_1(((sc)->sc_mem2_bh), ((0xa528
+ i))))
;
380
381 /* show our mac address */
382 printf(", address %s\n", ether_sprintf(ic->ic_myaddr));
383
384 /* attach interface */
385 if_attach(ifp);
386 ieee80211_ifattach(ifp);
387
388 /* post attach vector functions */
389 sc->sc_newstate = ic->ic_newstate;
390 ic->ic_newstate = malo_newstate;
391 ic->ic_newassoc = malo_newassoc;
392 ic->ic_node_alloc = malo_node_alloc;
393 ic->ic_updateslot = malo_update_slot;
394
395 ieee80211_media_init(ifp, malo_media_change, malo_media_status);
396
397#if NBPFILTER1 > 0
398 bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO127,
399 sizeof(struct ieee80211_frame) + 64);
400
401 sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
402 sc->sc_rxtapsc_rxtapu.th.wr_ihdr.it_len = htole16(sc->sc_rxtap_len)((__uint16_t)(sc->sc_rxtap_len));
403 sc->sc_rxtapsc_rxtapu.th.wr_ihdr.it_present = htole32(MALO_RX_RADIOTAP_PRESENT)((__uint32_t)(((1 << IEEE80211_RADIOTAP_FLAGS) | (1 <<
IEEE80211_RADIOTAP_CHANNEL) | (1 << IEEE80211_RADIOTAP_RSSI
))))
;
404
405 sc->sc_txtap_len = sizeof(sc->sc_txtapu);
406 sc->sc_txtapsc_txtapu.th.wt_ihdr.it_len = htole16(sc->sc_txtap_len)((__uint16_t)(sc->sc_txtap_len));
407 sc->sc_txtapsc_txtapu.th.wt_ihdr.it_present = htole32(MALO_TX_RADIOTAP_PRESENT)((__uint32_t)(((1 << IEEE80211_RADIOTAP_FLAGS) | (1 <<
IEEE80211_RADIOTAP_RATE) | (1 << IEEE80211_RADIOTAP_CHANNEL
))))
;
408#endif
409
410 return (0);
411}
412
413int
414malo_detach(void *arg)
415{
416 struct malo_softc *sc = arg;
417 struct ieee80211com *ic = &sc->sc_ic;
418 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
419
420 /* remove channel scanning timer */
421 timeout_del(&sc->sc_scan_to);
422
423 malo_stop(sc);
424 ieee80211_ifdetach(ifp);
425 if_detach(ifp);
426 malo_free_cmd(sc);
427 malo_free_rx_ring(sc, &sc->sc_rxring);
428 malo_free_tx_ring(sc, &sc->sc_txring);
429
430 return (0);
431}
432
433int
434malo_alloc_cmd(struct malo_softc *sc)
435{
436 int error, nsegs;
437
438 error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
12)), (1), ((1 << 12)), (0), (0x0002), (&sc->sc_cmd_dmam
))
439 PAGE_SIZE, 0, BUS_DMA_ALLOCNOW, &sc->sc_cmd_dmam)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
12)), (1), ((1 << 12)), (0), (0x0002), (&sc->sc_cmd_dmam
))
;
440 if (error != 0) {
441 printf("%s: can not create DMA tag\n", sc->sc_dev.dv_xname);
442 return (-1);
443 }
444
445 error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE,(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), ((1 <<
12)), ((1 << 12)), (0), (&sc->sc_cmd_dmas), (1)
, (&nsegs), (0x0000))
446 0, &sc->sc_cmd_dmas, 1, &nsegs, BUS_DMA_WAITOK)(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), ((1 <<
12)), ((1 << 12)), (0), (&sc->sc_cmd_dmas), (1)
, (&nsegs), (0x0000))
;
447 if (error != 0) {
448 printf("%s: error alloc dma memory\n", sc->sc_dev.dv_xname);
449 return (-1);
450 }
451
452 error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cmd_dmas, nsegs,(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&sc
->sc_cmd_dmas), (nsegs), ((1 << 12)), ((caddr_t *)&
sc->sc_cmd_mem), (0x0000))
453 PAGE_SIZE, (caddr_t *)&sc->sc_cmd_mem, BUS_DMA_WAITOK)(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&sc
->sc_cmd_dmas), (nsegs), ((1 << 12)), ((caddr_t *)&
sc->sc_cmd_mem), (0x0000))
;
454 if (error != 0) {
455 printf("%s: error map dma memory\n", sc->sc_dev.dv_xname);
456 return (-1);
457 }
458
459 error = bus_dmamap_load(sc->sc_dmat, sc->sc_cmd_dmam,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (sc->
sc_cmd_dmam), (sc->sc_cmd_mem), ((1 << 12)), (((void
*)0)), (0x0001))
460 sc->sc_cmd_mem, PAGE_SIZE, NULL, BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (sc->
sc_cmd_dmam), (sc->sc_cmd_mem), ((1 << 12)), (((void
*)0)), (0x0001))
;
461 if (error != 0) {
462 printf("%s: error load dma memory\n", sc->sc_dev.dv_xname);
463 bus_dmamem_free(sc->sc_dmat, &sc->sc_cmd_dmas, nsegs)(*(sc->sc_dmat)->_dmamem_free)((sc->sc_dmat), (&
sc->sc_cmd_dmas), (nsegs))
;
464 return (-1);
465 }
466
467 sc->sc_cookie = sc->sc_cmd_mem;
468 *sc->sc_cookie = htole32(0xaa55aa55)((__uint32_t)(0xaa55aa55));
469 sc->sc_cmd_mem = (caddr_t)sc->sc_cmd_mem + sizeof(uint32_t);
470 sc->sc_cookie_dmaaddr = sc->sc_cmd_dmam->dm_segs[0].ds_addr;
471 sc->sc_cmd_dmaaddr = sc->sc_cmd_dmam->dm_segs[0].ds_addr +
472 sizeof(uint32_t);
473
474 return (0);
475}
476
477void
478malo_free_cmd(struct malo_softc *sc)
479{
480 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x08))
481 BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x08))
;
482 bus_dmamap_unload(sc->sc_dmat, sc->sc_cmd_dmam)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (sc->
sc_cmd_dmam))
;
483 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_cookie, PAGE_SIZE)(*(sc->sc_dmat)->_dmamem_unmap)((sc->sc_dmat), ((caddr_t
)sc->sc_cookie), ((1 << 12)))
;
484 bus_dmamem_free(sc->sc_dmat, &sc->sc_cmd_dmas, 1)(*(sc->sc_dmat)->_dmamem_free)((sc->sc_dmat), (&
sc->sc_cmd_dmas), (1))
;
485}
486
487void
488malo_send_cmd(struct malo_softc *sc, bus_addr_t addr)
489{
490 malo_ctl_write4(sc, 0x0c10, (uint32_t)addr)(((sc)->sc_mem2_bt)->write_4(((sc)->sc_mem2_bh), ((0x0c10
)), (((uint32_t)addr))))
;
491 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE)bus_space_barrier((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, 0x0c00
, 0xff, (0x02))
;
492 malo_ctl_write4(sc, 0x0c18, 2)(((sc)->sc_mem2_bt)->write_4(((sc)->sc_mem2_bh), ((0x0c18
)), ((2))))
; /* CPU_TRANSFER_CMD */
493 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE)bus_space_barrier((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, 0x0c00
, 0xff, (0x02))
;
494}
495
496int
497malo_send_cmd_dma(struct malo_softc *sc, bus_addr_t addr)
498{
499 int i;
500 struct malo_cmdheader *hdr = sc->sc_cmd_mem;
501
502 malo_ctl_write4(sc, 0x0c10, (uint32_t)addr)(((sc)->sc_mem2_bt)->write_4(((sc)->sc_mem2_bh), ((0x0c10
)), (((uint32_t)addr))))
;
503 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE)bus_space_barrier((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, 0x0c00
, 0xff, (0x02))
;
504 malo_ctl_write4(sc, 0x0c18, 2)(((sc)->sc_mem2_bt)->write_4(((sc)->sc_mem2_bh), ((0x0c18
)), ((2))))
; /* CPU_TRANSFER_CMD */
505 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE)bus_space_barrier((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, 0x0c00
, 0xff, (0x02))
;
506
507 for (i = 0; i < MALO_CMD_TIMEOUT50; i++) {
508 delay(100)(*delay_func)(100);
509 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x08 | 0x02))
510 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x08 | 0x02))
;
511 if (hdr->cmd & htole16(0x8000)((__uint16_t)(0x8000)))
512 break;
513 }
514 if (i == MALO_CMD_TIMEOUT50) {
515 printf("%s: timeout while waiting for cmd response!\n",
516 sc->sc_dev.dv_xname);
517 return (ETIMEDOUT60);
518 }
519
520 malo_cmd_response(sc);
521
522 return (0);
523}
524
525int
526malo_alloc_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring, int count)
527{
528 struct malo_rx_desc *desc;
529 struct malo_rx_data *data;
530 int i, nsegs, error;
531
532 ring->count = count;
533 ring->cur = ring->next = 0;
534
535 error = bus_dmamap_create(sc->sc_dmat,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (count
* sizeof(struct malo_rx_desc)), (1), (count * sizeof(struct malo_rx_desc
)), (0), (0x0001), (&ring->map))
536 count * sizeof(struct malo_rx_desc), 1,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (count
* sizeof(struct malo_rx_desc)), (1), (count * sizeof(struct malo_rx_desc
)), (0), (0x0001), (&ring->map))
537 count * sizeof(struct malo_rx_desc), 0,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (count
* sizeof(struct malo_rx_desc)), (1), (count * sizeof(struct malo_rx_desc
)), (0), (0x0001), (&ring->map))
538 BUS_DMA_NOWAIT, &ring->map)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (count
* sizeof(struct malo_rx_desc)), (1), (count * sizeof(struct malo_rx_desc
)), (0), (0x0001), (&ring->map))
;
539 if (error != 0) {
540 printf("%s: could not create desc DMA map\n",
541 sc->sc_dev.dv_xname);
542 goto fail;
543 }
544
545 error = bus_dmamem_alloc(sc->sc_dmat,(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (count
* sizeof(struct malo_rx_desc)), ((1 << 12)), (0), (&
ring->seg), (1), (&nsegs), (0x0001 | 0x1000))
546 count * sizeof(struct malo_rx_desc),(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (count
* sizeof(struct malo_rx_desc)), ((1 << 12)), (0), (&
ring->seg), (1), (&nsegs), (0x0001 | 0x1000))
547 PAGE_SIZE, 0, &ring->seg, 1, &nsegs,(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (count
* sizeof(struct malo_rx_desc)), ((1 << 12)), (0), (&
ring->seg), (1), (&nsegs), (0x0001 | 0x1000))
548 BUS_DMA_NOWAIT | BUS_DMA_ZERO)(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (count
* sizeof(struct malo_rx_desc)), ((1 << 12)), (0), (&
ring->seg), (1), (&nsegs), (0x0001 | 0x1000))
;
549 if (error != 0) {
550 printf("%s: could not allocate DMA memory\n",
551 sc->sc_dev.dv_xname);
552 goto fail;
553 }
554
555 error = bus_dmamem_map(sc->sc_dmat, &ring->seg, nsegs,(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&ring
->seg), (nsegs), (count * sizeof(struct malo_rx_desc)), ((
caddr_t *)&ring->desc), (0x0001))
556 count * sizeof(struct malo_rx_desc), (caddr_t *)&ring->desc,(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&ring
->seg), (nsegs), (count * sizeof(struct malo_rx_desc)), ((
caddr_t *)&ring->desc), (0x0001))
557 BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&ring
->seg), (nsegs), (count * sizeof(struct malo_rx_desc)), ((
caddr_t *)&ring->desc), (0x0001))
;
558 if (error != 0) {
559 printf("%s: can't map desc DMA memory\n",
560 sc->sc_dev.dv_xname);
561 goto fail;
562 }
563
564 error = bus_dmamap_load(sc->sc_dmat, ring->map, ring->desc,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (ring->
map), (ring->desc), (count * sizeof(struct malo_rx_desc)),
(((void *)0)), (0x0001))
565 count * sizeof(struct malo_rx_desc), NULL, BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (ring->
map), (ring->desc), (count * sizeof(struct malo_rx_desc)),
(((void *)0)), (0x0001))
;
566 if (error != 0) {
567 printf("%s: could not load desc DMA map\n",
568 sc->sc_dev.dv_xname);
569 goto fail;
570 }
571
572 ring->physaddr = ring->map->dm_segs->ds_addr;
573
574 ring->data = mallocarray(count, sizeof (struct malo_rx_data),
575 M_DEVBUF2, M_NOWAIT0x0002);
576 if (ring->data == NULL((void *)0)) {
577 printf("%s: could not allocate soft data\n",
578 sc->sc_dev.dv_xname);
579 error = ENOMEM12;
580 goto fail;
581 }
582
583 /*
584 * Pre-allocate Rx buffers and populate Rx ring.
585 */
586 bzero(ring->data, count * sizeof (struct malo_rx_data))__builtin_bzero((ring->data), (count * sizeof (struct malo_rx_data
)))
;
587 for (i = 0; i < count; i++) {
588 desc = &ring->desc[i];
589 data = &ring->data[i];
590
591 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (1), ((1 << 11)), (0), (0x0001), (&data->
map))
592 0, BUS_DMA_NOWAIT, &data->map)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (1), ((1 << 11)), (0), (0x0001), (&data->
map))
;
593 if (error != 0) {
594 printf("%s: could not create DMA map\n",
595 sc->sc_dev.dv_xname);
596 goto fail;
597 }
598
599 MGETHDR(data->m, M_DONTWAIT, MT_DATA)data->m = m_gethdr((0x0002), (1));
600 if (data->m == NULL((void *)0)) {
601 printf("%s: could not allocate rx mbuf\n",
602 sc->sc_dev.dv_xname);
603 error = ENOMEM12;
604 goto fail;
605 }
606
607 MCLGET(data->m, M_DONTWAIT)(void) m_clget((data->m), (0x0002), (1 << 11));
608 if (!(data->m->m_flagsm_hdr.mh_flags & M_EXT0x0001)) {
609 printf("%s: could not allocate rx mbuf cluster\n",
610 sc->sc_dev.dv_xname);
611 error = ENOMEM12;
612 goto fail;
613 }
614
615 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))), ((1 <<
11)), (((void *)0)), (0x0001))
616 mtod(data->m, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (data->
map), (((void *)((data->m)->m_hdr.mh_data))), ((1 <<
11)), (((void *)0)), (0x0001))
;
617 if (error != 0) {
618 printf("%s: could not load rx buf DMA map",
619 sc->sc_dev.dv_xname);
620 goto fail;
621 }
622
623 desc->status = 1;
624 desc->physdata = htole32(data->map->dm_segs->ds_addr)((__uint32_t)(data->map->dm_segs->ds_addr));
625 desc->physnext = htole32(ring->physaddr +((__uint32_t)(ring->physaddr + (i + 1) % count * sizeof(struct
malo_rx_desc)))
626 (i + 1) % count * sizeof(struct malo_rx_desc))((__uint32_t)(ring->physaddr + (i + 1) % count * sizeof(struct
malo_rx_desc)))
;
627 }
628
629 bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
map), (0), (ring->map->dm_mapsize), (0x04))
630 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
map), (0), (ring->map->dm_mapsize), (0x04))
;
631
632 return (0);
633
634fail: malo_free_rx_ring(sc, ring);
635 return (error);
636}
637
638void
639malo_reset_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring)
640{
641 int i;
642
643 for (i = 0; i < ring->count; i++)
644 ring->desc[i].status = 0;
645
646 bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
map), (0), (ring->map->dm_mapsize), (0x04))
647 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
map), (0), (ring->map->dm_mapsize), (0x04))
;
648
649 ring->cur = ring->next = 0;
650}
651
652void
653malo_free_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring)
654{
655 struct malo_rx_data *data;
656 int i;
657
658 if (ring->desc != NULL((void *)0)) {
659 bus_dmamap_sync(sc->sc_dmat, ring->map, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
map), (0), (ring->map->dm_mapsize), (0x08))
660 ring->map->dm_mapsize, BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
map), (0), (ring->map->dm_mapsize), (0x08))
;
661 bus_dmamap_unload(sc->sc_dmat, ring->map)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (ring
->map))
;
662 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc,(*(sc->sc_dmat)->_dmamem_unmap)((sc->sc_dmat), ((caddr_t
)ring->desc), (ring->count * sizeof(struct malo_rx_desc
)))
663 ring->count * sizeof(struct malo_rx_desc))(*(sc->sc_dmat)->_dmamem_unmap)((sc->sc_dmat), ((caddr_t
)ring->desc), (ring->count * sizeof(struct malo_rx_desc
)))
;
664 bus_dmamem_free(sc->sc_dmat, &ring->seg, 1)(*(sc->sc_dmat)->_dmamem_free)((sc->sc_dmat), (&
ring->seg), (1))
;
665 }
666
667 if (ring->data != NULL((void *)0)) {
668 for (i = 0; i < ring->count; i++) {
669 data = &ring->data[i];
670
671 if (data->m != NULL((void *)0)) {
672 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))
673 data->map->dm_mapsize,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x02))
674 BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x02))
;
675 bus_dmamap_unload(sc->sc_dmat, data->map)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (data
->map))
;
676 m_freem(data->m);
677 }
678
679 if (data->map != NULL((void *)0))
680 bus_dmamap_destroy(sc->sc_dmat, data->map)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (data
->map))
;
681 }
682 free(ring->data, M_DEVBUF2, 0);
683 }
684}
685
686int
687malo_alloc_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring,
688 int count)
689{
690 int i, nsegs, error;
691
692 ring->count = count;
693 ring->queued = 0;
694 ring->cur = ring->next = ring->stat = 0;
695
696 error = bus_dmamap_create(sc->sc_dmat,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (count
* sizeof(struct malo_tx_desc)), (1), (count * sizeof(struct malo_tx_desc
)), (0), (0x0001), (&ring->map))
697 count * sizeof(struct malo_tx_desc), 1,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (count
* sizeof(struct malo_tx_desc)), (1), (count * sizeof(struct malo_tx_desc
)), (0), (0x0001), (&ring->map))
698 count * sizeof(struct malo_tx_desc), 0, BUS_DMA_NOWAIT, &ring->map)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (count
* sizeof(struct malo_tx_desc)), (1), (count * sizeof(struct malo_tx_desc
)), (0), (0x0001), (&ring->map))
;
699 if (error != 0) {
700 printf("%s: could not create desc DMA map\n",
701 sc->sc_dev.dv_xname);
702 goto fail;
703 }
704
705 error = bus_dmamem_alloc(sc->sc_dmat,(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (count
* sizeof(struct malo_tx_desc)), ((1 << 12)), (0), (&
ring->seg), (1), (&nsegs), (0x0001 | 0x1000))
706 count * sizeof(struct malo_tx_desc), PAGE_SIZE, 0,(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (count
* sizeof(struct malo_tx_desc)), ((1 << 12)), (0), (&
ring->seg), (1), (&nsegs), (0x0001 | 0x1000))
707 &ring->seg, 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO)(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (count
* sizeof(struct malo_tx_desc)), ((1 << 12)), (0), (&
ring->seg), (1), (&nsegs), (0x0001 | 0x1000))
;
708 if (error != 0) {
709 printf("%s: could not allocate DMA memory\n",
710 sc->sc_dev.dv_xname);
711 goto fail;
712 }
713
714 error = bus_dmamem_map(sc->sc_dmat, &ring->seg, nsegs,(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&ring
->seg), (nsegs), (count * sizeof(struct malo_tx_desc)), ((
caddr_t *)&ring->desc), (0x0001))
715 count * sizeof(struct malo_tx_desc), (caddr_t *)&ring->desc,(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&ring
->seg), (nsegs), (count * sizeof(struct malo_tx_desc)), ((
caddr_t *)&ring->desc), (0x0001))
716 BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&ring
->seg), (nsegs), (count * sizeof(struct malo_tx_desc)), ((
caddr_t *)&ring->desc), (0x0001))
;
717 if (error != 0) {
718 printf("%s: can't map desc DMA memory\n",
719 sc->sc_dev.dv_xname);
720 goto fail;
721 }
722
723 error = bus_dmamap_load(sc->sc_dmat, ring->map, ring->desc,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (ring->
map), (ring->desc), (count * sizeof(struct malo_tx_desc)),
(((void *)0)), (0x0001))
724 count * sizeof(struct malo_tx_desc), NULL, BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (ring->
map), (ring->desc), (count * sizeof(struct malo_tx_desc)),
(((void *)0)), (0x0001))
;
725 if (error != 0) {
726 printf("%s: could not load desc DMA map\n",
727 sc->sc_dev.dv_xname);
728 goto fail;
729 }
730
731 ring->physaddr = ring->map->dm_segs->ds_addr;
732
733 ring->data = mallocarray(count, sizeof(struct malo_tx_data),
734 M_DEVBUF2, M_NOWAIT0x0002);
735 if (ring->data == NULL((void *)0)) {
736 printf("%s: could not allocate soft data\n",
737 sc->sc_dev.dv_xname);
738 error = ENOMEM12;
739 goto fail;
740 }
741
742 memset(ring->data, 0, count * sizeof(struct malo_tx_data))__builtin_memset((ring->data), (0), (count * sizeof(struct
malo_tx_data)))
;
743 for (i = 0; i < count; i++) {
744 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (8), ((1 << 11)), (0), (0x0001), (&ring->
data[i].map))
745 MALO_MAX_SCATTER, MCLBYTES, 0, BUS_DMA_NOWAIT,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (8), ((1 << 11)), (0), (0x0001), (&ring->
data[i].map))
746 &ring->data[i].map)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (8), ((1 << 11)), (0), (0x0001), (&ring->
data[i].map))
;
747 if (error != 0) {
748 printf("%s: could not create DMA map\n",
749 sc->sc_dev.dv_xname);
750 goto fail;
751 }
752 ring->desc[i].physnext = htole32(ring->physaddr +((__uint32_t)(ring->physaddr + (i + 1) % count * sizeof(struct
malo_tx_desc)))
753 (i + 1) % count * sizeof(struct malo_tx_desc))((__uint32_t)(ring->physaddr + (i + 1) % count * sizeof(struct
malo_tx_desc)))
;
754 }
755
756 return (0);
757
758fail: malo_free_tx_ring(sc, ring);
759 return (error);
760}
761
762void
763malo_reset_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring)
764{
765 struct malo_tx_desc *desc;
766 struct malo_tx_data *data;
767 int i;
768
769 for (i = 0; i < ring->count; i++) {
770 desc = &ring->desc[i];
771 data = &ring->data[i];
772
773 if (data->m != NULL((void *)0)) {
774 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))
775 data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x08))
;
776 bus_dmamap_unload(sc->sc_dmat, data->map)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (data
->map))
;
777 m_freem(data->m);
778 data->m = NULL((void *)0);
779 }
780
781 /*
782 * The node has already been freed at that point so don't call
783 * ieee80211_release_node() here.
784 */
785 data->ni = NULL((void *)0);
786
787 desc->status = 0;
788 }
789
790 bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
map), (0), (ring->map->dm_mapsize), (0x04))
791 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
map), (0), (ring->map->dm_mapsize), (0x04))
;
792
793 ring->queued = 0;
794 ring->cur = ring->next = ring->stat = 0;
795}
796
797void
798malo_free_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring)
799{
800 struct malo_tx_data *data;
801 int i;
802
803 if (ring->desc != NULL((void *)0)) {
804 bus_dmamap_sync(sc->sc_dmat, ring->map, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
map), (0), (ring->map->dm_mapsize), (0x08))
805 ring->map->dm_mapsize, BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ring->
map), (0), (ring->map->dm_mapsize), (0x08))
;
806 bus_dmamap_unload(sc->sc_dmat, ring->map)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (ring
->map))
;
807 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc,(*(sc->sc_dmat)->_dmamem_unmap)((sc->sc_dmat), ((caddr_t
)ring->desc), (ring->count * sizeof(struct malo_tx_desc
)))
808 ring->count * sizeof(struct malo_tx_desc))(*(sc->sc_dmat)->_dmamem_unmap)((sc->sc_dmat), ((caddr_t
)ring->desc), (ring->count * sizeof(struct malo_tx_desc
)))
;
809 bus_dmamem_free(sc->sc_dmat, &ring->seg, 1)(*(sc->sc_dmat)->_dmamem_free)((sc->sc_dmat), (&
ring->seg), (1))
;
810 }
811
812 if (ring->data != NULL((void *)0)) {
813 for (i = 0; i < ring->count; i++) {
814 data = &ring->data[i];
815
816 if (data->m != NULL((void *)0)) {
817 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))
818 data->map->dm_mapsize,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x08))
819 BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x08))
;
820 bus_dmamap_unload(sc->sc_dmat, data->map)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (data
->map))
;
821 m_freem(data->m);
822 }
823
824 /*
825 * The node has already been freed at that point so
826 * don't call ieee80211_release_node() here.
827 */
828 data->ni = NULL((void *)0);
829
830 if (data->map != NULL((void *)0))
831 bus_dmamap_destroy(sc->sc_dmat, data->map)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (data
->map))
;
832 }
833 free(ring->data, M_DEVBUF2, 0);
834 }
835}
836
837int
838malo_init(struct ifnet *ifp)
839{
840 struct malo_softc *sc = ifp->if_softc;
841 struct ieee80211com *ic = &sc->sc_ic;
842 uint8_t chan;
843 int error;
844
845 DPRINTF(1, "%s: %s\n", ifp->if_xname, __func__);
846
847 /* if interface already runs stop it first */
848 if (ifp->if_flags & IFF_RUNNING0x40)
849 malo_stop(sc);
850
851 /* power on cardbus socket */
852 if (sc->sc_enable)
853 sc->sc_enable(sc);
854
855 /* disable interrupts */
856 malo_ctl_read4(sc, 0x0c30)(((sc)->sc_mem2_bt)->read_4(((sc)->sc_mem2_bh), ((0x0c30
))))
;
857 malo_ctl_write4(sc, 0x0c30, 0)(((sc)->sc_mem2_bt)->write_4(((sc)->sc_mem2_bh), ((0x0c30
)), ((0))))
;
858 malo_ctl_write4(sc, 0x0c34, 0)(((sc)->sc_mem2_bt)->write_4(((sc)->sc_mem2_bh), ((0x0c34
)), ((0))))
;
859 malo_ctl_write4(sc, 0x0c3c, 0)(((sc)->sc_mem2_bt)->write_4(((sc)->sc_mem2_bh), ((0x0c3c
)), ((0))))
;
860
861 /* load firmware */
862 if ((error = malo_load_bootimg(sc)))
863 goto fail;
864 if ((error = malo_load_firmware(sc)))
865 goto fail;
866
867 /* enable interrupts */
868 malo_ctl_write4(sc, 0x0c34, 0x1f)(((sc)->sc_mem2_bt)->write_4(((sc)->sc_mem2_bh), ((0x0c34
)), ((0x1f))))
;
869 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE)bus_space_barrier((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, 0x0c00
, 0xff, (0x02))
;
870 malo_ctl_write4(sc, 0x0c3c, 0x1f)(((sc)->sc_mem2_bt)->write_4(((sc)->sc_mem2_bh), ((0x0c3c
)), ((0x1f))))
;
871 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE)bus_space_barrier((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, 0x0c00
, 0xff, (0x02))
;
872
873 if ((error = malo_cmd_get_spec(sc)))
874 goto fail;
875
876 /* select default channel */
877 ic->ic_bss->ni_chan = ic->ic_ibss_chan;
878 chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
879
880 /* initialize hardware */
881 if ((error = malo_cmd_set_channel(sc, chan))) {
882 printf("%s: setting channel failed!\n",
883 sc->sc_dev.dv_xname);
884 goto fail;
885 }
886 if ((error = malo_cmd_set_antenna(sc, 1))) {
887 printf("%s: setting RX antenna failed!\n",
888 sc->sc_dev.dv_xname);
889 goto fail;
890 }
891 if ((error = malo_cmd_set_antenna(sc, 2))) {
892 printf("%s: setting TX antenna failed!\n",
893 sc->sc_dev.dv_xname);
894 goto fail;
895 }
896 if ((error = malo_cmd_set_radio(sc, 1, 5))) {
897 printf("%s: turn radio on failed!\n",
898 sc->sc_dev.dv_xname);
899 goto fail;
900 }
901 if ((error = malo_cmd_set_txpower(sc, 100))) {
902 printf("%s: setting TX power failed!\n",
903 sc->sc_dev.dv_xname);
904 goto fail;
905 }
906 if ((error = malo_cmd_set_rts(sc, IEEE80211_RTS_MAX(2300 + 4 + (3 + 1 + 4))))) {
907 printf("%s: setting RTS failed!\n",
908 sc->sc_dev.dv_xname);
909 goto fail;
910 }
911
912 ifp->if_flags |= IFF_RUNNING0x40;
913
914 if (ic->ic_opmode != IEEE80211_M_MONITOR)
915 /* start background scanning */
916 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1)(((ic)->ic_newstate)((ic), (IEEE80211_S_SCAN), (-1)));
917 else
918 /* in monitor mode change directly into run state */
919 ieee80211_new_state(ic, IEEE80211_S_RUN, -1)(((ic)->ic_newstate)((ic), (IEEE80211_S_RUN), (-1)));
920
921 return (0);
922
923fail:
924 /* reset adapter */
925 DPRINTF(1, "%s: malo_init failed, resetting card\n",
926 sc->sc_dev.dv_xname);
927 malo_stop(sc);
928 return (error);
929}
930
931int
932malo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
933{
934 struct malo_softc *sc = ifp->if_softc;
935 struct ieee80211com *ic = &sc->sc_ic;
936 int s, error = 0;
937 uint8_t chan;
938
939 s = splnet()splraise(0x7);
940
941 switch (cmd) {
942 case SIOCSIFADDR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((12)))
:
943 ifp->if_flags |= IFF_UP0x1;
944 /* FALLTHROUGH */
945 case SIOCSIFFLAGS((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((16)))
:
946 if (ifp->if_flags & IFF_UP0x1) {
947 if ((ifp->if_flags & IFF_RUNNING0x40) == 0)
948 malo_init(ifp);
949 } else {
950 if (ifp->if_flags & IFF_RUNNING0x40)
951 malo_stop(sc);
952 }
953 break;
954 case SIOCS80211CHANNEL((unsigned long)0x80000000 | ((sizeof(struct ieee80211chanreq
) & 0x1fff) << 16) | ((('i')) << 8) | ((238))
)
:
955 /* allow fast channel switching in monitor mode */
956 error = ieee80211_ioctl(ifp, cmd, data);
957 if (error == ENETRESET52 &&
958 ic->ic_opmode == IEEE80211_M_MONITOR) {
959 if ((ifp->if_flags & (IFF_UP0x1 | IFF_RUNNING0x40)) ==
960 (IFF_UP0x1 | IFF_RUNNING0x40)) {
961 ic->ic_bss->ni_chan = ic->ic_ibss_chan;
962 chan = ieee80211_chan2ieee(ic,
963 ic->ic_bss->ni_chan);
964 malo_cmd_set_channel(sc, chan);
965 }
966 error = 0;
967 }
968 break;
969 default:
970 error = ieee80211_ioctl(ifp, cmd, data);
971 break;
972 }
973
974 if (error == ENETRESET52) {
975 if ((ifp->if_flags & (IFF_UP0x1 | IFF_RUNNING0x40)) ==
976 (IFF_UP0x1 | IFF_RUNNING0x40))
977 malo_init(ifp);
978 error = 0;
979 }
980
981 splx(s)spllower(s);
982
983 return (error);
984}
985
986void
987malo_start(struct ifnet *ifp)
988{
989 struct malo_softc *sc = ifp->if_softc;
990 struct ieee80211com *ic = &sc->sc_ic;
991 struct mbuf *m0;
992 struct ieee80211_node *ni;
993
994 DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
995
996 if (!(ifp->if_flags & IFF_RUNNING0x40) || ifq_is_oactive(&ifp->if_snd))
997 return;
998
999 for (;;) {
1000 if (sc->sc_txring.queued >= MALO_TX_RING_COUNT256 - 1) {
1001 ifq_set_oactive(&ifp->if_snd);
1002 break;
1003 }
1004
1005 m0 = mq_dequeue(&ic->ic_mgtq);
1006 if (m0 != NULL((void *)0)) {
1007 ni = m0->m_pkthdrM_dat.MH.MH_pkthdr.ph_cookie;
1008#if NBPFILTER1 > 0
1009 if (ic->ic_rawbpf != NULL((void *)0))
1010 bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT(1 << 1));
1011#endif
1012 if (malo_tx_mgt(sc, m0, ni) != 0)
1013 break;
1014 } else {
1015 if (ic->ic_state != IEEE80211_S_RUN)
1016 break;
1017
1018 m0 = ifq_dequeue(&ifp->if_snd);
1019 if (m0 == NULL((void *)0))
1020 break;
1021#if NBPFILTER1 > 0
1022 if (ifp->if_bpf != NULL((void *)0))
1023 bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT(1 << 1));
1024#endif
1025 m0 = ieee80211_encap(ifp, m0, &ni);
1026 if (m0 == NULL((void *)0))
1027 continue;
1028#if NBPFILTER1 > 0
1029 if (ic->ic_rawbpf != NULL((void *)0))
1030 bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT(1 << 1));
1031#endif
1032 if (malo_tx_data(sc, m0, ni) != 0) {
1033 if (ni != NULL((void *)0))
1034 ieee80211_release_node(ic, ni);
1035 ifp->if_oerrorsif_data.ifi_oerrors++;
1036 break;
1037 }
1038 }
1039 }
1040}
1041
1042void
1043malo_stop(struct malo_softc *sc)
1044{
1045 struct ieee80211com *ic = &sc->sc_ic;
1046 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1047
1048 DPRINTF(1, "%s: %s\n", ifp->if_xname, __func__);
1049
1050 /* reset adapter */
1051 if (ifp->if_flags & IFF_RUNNING0x40)
1052 malo_ctl_write4(sc, 0x0c18, (1 << 15))(((sc)->sc_mem2_bt)->write_4(((sc)->sc_mem2_bh), ((0x0c18
)), (((1 << 15)))))
;
1053
1054 /* device is not running anymore */
1055 ifp->if_flags &= ~IFF_RUNNING0x40;
1056 ifq_clr_oactive(&ifp->if_snd);
1057
1058 /* change back to initial state */
1059 ieee80211_new_state(ic, IEEE80211_S_INIT, -1)(((ic)->ic_newstate)((ic), (IEEE80211_S_INIT), (-1)));
1060
1061 /* reset RX / TX rings */
1062 malo_reset_tx_ring(sc, &sc->sc_txring);
1063 malo_reset_rx_ring(sc, &sc->sc_rxring);
1064
1065 /* set initial rate */
1066 sc->sc_last_txrate = -1;
1067
1068 /* power off cardbus socket */
1069 if (sc->sc_disable)
1070 sc->sc_disable(sc);
1071}
1072
1073void
1074malo_watchdog(struct ifnet *ifp)
1075{
1076
1077}
1078
1079int
1080malo_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
1081{
1082 struct malo_softc *sc = ic->ic_ific_ac.ac_if.if_softc;
1083 enum ieee80211_state ostate;
1084 uint8_t chan;
1085 int rate;
1086
1087 DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
1088
1089 ostate = ic->ic_state;
1090 timeout_del(&sc->sc_scan_to);
1091
1092 switch (nstate) {
1093 case IEEE80211_S_INIT:
1094 break;
1095 case IEEE80211_S_SCAN:
1096 if (ostate == IEEE80211_S_INIT) {
1097 if (malo_cmd_set_prescan(sc) != 0)
1098 DPRINTF(1, "%s: can't set prescan\n",
1099 sc->sc_dev.dv_xname);
1100 } else {
1101 chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
1102
1103 malo_cmd_set_channel(sc, chan);
1104 }
1105 timeout_add_msec(&sc->sc_scan_to, 500);
1106 break;
1107 case IEEE80211_S_AUTH:
1108 DPRINTF(1, "%s: newstate AUTH\n", sc->sc_dev.dv_xname);
1109 malo_cmd_set_postscan(sc, ic->ic_myaddr, 1);
1110 chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
1111 malo_cmd_set_channel(sc, chan);
1112 break;
1113 case IEEE80211_S_ASSOC:
1114 DPRINTF(1, "%s: newstate ASSOC\n", sc->sc_dev.dv_xname);
1115 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE0x00040000)
1116 malo_cmd_set_radio(sc, 1, 3); /* short preamble */
1117 else
1118 malo_cmd_set_radio(sc, 1, 1); /* long preamble */
1119
1120 malo_cmd_set_aid(sc, ic->ic_bss->ni_bssid,
1121 ic->ic_bss->ni_associd);
1122
1123 if (ic->ic_fixed_rate == -1)
1124 /* automatic rate adaption */
1125 malo_cmd_set_rate(sc, 0);
1126 else {
1127 /* fixed rate */
1128 rate = malo_fix2rate(ic->ic_fixed_rate);
1129 malo_cmd_set_rate(sc, rate);
1130 }
1131
1132 malo_set_slot(sc);
1133 break;
1134 case IEEE80211_S_RUN:
1135 DPRINTF(1, "%s: newstate RUN\n", sc->sc_dev.dv_xname);
1136 break;
1137 default:
1138 break;
1139 }
1140
1141 return (sc->sc_newstate(ic, nstate, arg));
1142}
1143
1144void
1145malo_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
1146{
1147
1148}
1149
1150struct ieee80211_node *
1151malo_node_alloc(struct ieee80211com *ic)
1152{
1153 struct malo_node *wn;
1154
1155 wn = malloc(sizeof(*wn), M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008);
1156 if (wn == NULL((void *)0))
1157 return (NULL((void *)0));
1158
1159 return ((struct ieee80211_node *)wn);
1160}
1161
1162int
1163malo_media_change(struct ifnet *ifp)
1164{
1165 int error;
1166
1167 DPRINTF(1, "%s: %s\n", ifp->if_xname, __func__);
1168
1169 error = ieee80211_media_change(ifp);
1170 if (error != ENETRESET52)
1171 return (error);
1172
1173 if ((ifp->if_flags & (IFF_UP0x1 | IFF_RUNNING0x40)) == (IFF_UP0x1 | IFF_RUNNING0x40))
1174 malo_init(ifp);
1175
1176 return (0);
1177}
1178
1179void
1180malo_media_status(struct ifnet *ifp, struct ifmediareq *imr)
1181{
1182 struct malo_softc *sc = ifp->if_softc;
1183 struct ieee80211com *ic = &sc->sc_ic;
1184
1185 imr->ifm_status = IFM_AVALID0x0000000000000001ULL;
1186 imr->ifm_active = IFM_IEEE802110x0000000000000400ULL;
1187 if (ic->ic_state == IEEE80211_S_RUN)
1188 imr->ifm_status |= IFM_ACTIVE0x0000000000000002ULL;
1189
1190 /* report last TX rate used by chip */
1191 imr->ifm_active |= ieee80211_rate2media(ic, sc->sc_last_txrate,
1192 ic->ic_curmode);
1193
1194 switch (ic->ic_opmode) {
1195 case IEEE80211_M_STA:
1196 break;
1197#ifndef IEEE80211_STA_ONLY
1198 case IEEE80211_M_IBSS:
1199 imr->ifm_active |= IFM_IEEE80211_ADHOC0x0000000000010000ULL;
1200 break;
1201 case IEEE80211_M_AHDEMO:
1202 break;
1203 case IEEE80211_M_HOSTAP:
1204 break;
1205#endif
1206 case IEEE80211_M_MONITOR:
1207 imr->ifm_active |= IFM_IEEE80211_MONITOR0x0000000000100000ULL;
1208 break;
1209 default:
1210 break;
1211 }
1212
1213 switch (ic->ic_curmode) {
1214 case IEEE80211_MODE_11B:
1215 imr->ifm_active |= IFM_IEEE80211_11B0x0000000200000000ULL;
1216 break;
1217 case IEEE80211_MODE_11G:
1218 imr->ifm_active |= IFM_IEEE80211_11G0x0000000300000000ULL;
1219 break;
1220 }
1221}
1222
1223int
1224malo_chip2rate(int chip_rate)
1225{
1226 switch (chip_rate) {
1227 /* CCK rates */
1228 case 0: return (2);
1229 case 1: return (4);
1230 case 2: return (11);
1231 case 3: return (22);
1232
1233 /* OFDM rates */
1234 case 4: return (0); /* reserved */
1235 case 5: return (12);
1236 case 6: return (18);
1237 case 7: return (24);
1238 case 8: return (36);
1239 case 9: return (48);
1240 case 10: return (72);
1241 case 11: return (96);
1242 case 12: return (108);
1243
1244 /* no rate select yet or unknown rate */
1245 default: return (-1);
1246 }
1247}
1248
1249int
1250malo_fix2rate(int fix_rate)
1251{
1252 switch (fix_rate) {
1253 /* CCK rates */
1254 case 0: return (2);
1255 case 1: return (4);
1256 case 2: return (11);
1257 case 3: return (22);
1258
1259 /* OFDM rates */
1260 case 4: return (12);
1261 case 5: return (18);
1262 case 6: return (24);
1263 case 7: return (36);
1264 case 8: return (48);
1265 case 9: return (72);
1266 case 10: return (96);
1267 case 11: return (108);
1268
1269 /* unknown rate: should not happen */
1270 default: return (0);
1271 }
1272}
1273
1274void
1275malo_next_scan(void *arg)
1276{
1277 struct malo_softc *sc = arg;
1278 struct ieee80211com *ic = &sc->sc_ic;
1279 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1280 int s;
1281
1282 DPRINTF(1, "%s: %s\n", ifp->if_xname, __func__);
1283
1284 s = splnet()splraise(0x7);
1285
1286 if (ic->ic_state == IEEE80211_S_SCAN)
1287 ieee80211_next_scan(ifp);
1288
1289 splx(s)spllower(s);
1290}
1291
1292void
1293malo_tx_intr(struct malo_softc *sc)
1294{
1295 struct ieee80211com *ic = &sc->sc_ic;
1296 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1297 struct malo_tx_desc *desc;
1298 struct malo_tx_data *data;
1299 struct malo_node *rn;
1300 int stat;
1301
1302 DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
1303
1304 stat = sc->sc_txring.stat;
1305 for (;;) {
1306 desc = &sc->sc_txring.desc[sc->sc_txring.stat];
1307 data = &sc->sc_txring.data[sc->sc_txring.stat];
1308 rn = (struct malo_node *)data->ni;
1309
1310 /* check if TX descriptor is not owned by FW anymore */
1311 if ((letoh32(desc->status)((__uint32_t)(desc->status)) & 0x80000000) ||
1312 !(letoh32(data->softstat)((__uint32_t)(data->softstat)) & 0x80))
1313 break;
1314
1315 /* if no frame has been sent, ignore */
1316 if (rn == NULL((void *)0))
1317 goto next;
1318
1319 /* check TX state */
1320 switch (letoh32(desc->status)((__uint32_t)(desc->status)) & 0x1) {
1321 case 0x1:
1322 DPRINTF(2, "%s: data frame was sent successfully\n",
1323 sc->sc_dev.dv_xname);
1324 break;
1325 default:
1326 DPRINTF(1, "%s: data frame sending error\n",
1327 sc->sc_dev.dv_xname);
1328 ifp->if_oerrorsif_data.ifi_oerrors++;
1329 break;
1330 }
1331
1332 /* save last used TX rate */
1333 sc->sc_last_txrate = malo_chip2rate(desc->datarate);
1334
1335 /* cleanup TX data and TX descriptor */
1336 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))
1337 data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x08))
;
1338 bus_dmamap_unload(sc->sc_dmat, data->map)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (data
->map))
;
1339 m_freem(data->m);
1340 ieee80211_release_node(ic, data->ni);
1341 data->m = NULL((void *)0);
1342 data->ni = NULL((void *)0);
1343 data->softstat &= htole32(~0x80)((__uint32_t)(~0x80));
1344 desc->status = 0;
1345 desc->len = 0;
1346
1347 DPRINTF(2, "%s: tx done idx=%d\n",
1348 sc->sc_dev.dv_xname, sc->sc_txring.stat);
1349
1350 sc->sc_txring.queued--;
1351next:
1352 if (++sc->sc_txring.stat >= sc->sc_txring.count)
1353 sc->sc_txring.stat = 0;
1354 if (sc->sc_txring.stat == stat)
1355 break;
1356 }
1357
1358 sc->sc_tx_timer = 0;
1359 ifq_clr_oactive(&ifp->if_snd);
1360 malo_start(ifp);
1361}
1362
1363int
1364malo_tx_mgt(struct malo_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
1365{
1366 struct ieee80211com *ic = &sc->sc_ic;
1367 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1368 struct malo_tx_desc *desc;
1369 struct malo_tx_data *data;
1370 struct ieee80211_frame *wh;
1371 int error;
1372
1373 DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
1374
1375 desc = &sc->sc_txring.desc[sc->sc_txring.cur];
1376 data = &sc->sc_txring.data[sc->sc_txring.cur];
1377
1378 if (m0->m_lenm_hdr.mh_len < sizeof(struct ieee80211_frame)) {
1379 m0 = m_pullup(m0, sizeof(struct ieee80211_frame));
1380 if (m0 == NULL((void *)0)) {
1381 ifp->if_ierrorsif_data.ifi_ierrors++;
1382 return (ENOBUFS55);
1383 }
1384 }
1385 wh = mtod(m0, struct ieee80211_frame *)((struct ieee80211_frame *)((m0)->m_hdr.mh_data));
Value stored to 'wh' is never read
1386
1387#if NBPFILTER1 > 0
1388 if (sc->sc_drvbpf != NULL((void *)0)) {
1389 struct mbuf mb;
1390 struct malo_tx_radiotap_hdr *tap = &sc->sc_txtapsc_txtapu.th;
1391
1392 tap->wt_flags = 0;
1393 tap->wt_rate = sc->sc_last_txrate;
1394 tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq)((__uint16_t)(ic->ic_bss->ni_chan->ic_freq));
1395 tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags)((__uint16_t)(ic->ic_bss->ni_chan->ic_flags));
1396
1397 mb.m_datam_hdr.mh_data = (caddr_t)tap;
1398 mb.m_lenm_hdr.mh_len = sc->sc_txtap_len;
1399 mb.m_nextm_hdr.mh_next = m0;
1400 mb.m_nextpktm_hdr.mh_nextpkt = NULL((void *)0);
1401 mb.m_typem_hdr.mh_type = 0;
1402 mb.m_flagsm_hdr.mh_flags = 0;
1403 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT(1 << 1));
1404 }
1405#endif
1406 /*
1407 * inject FW specific fields into the 802.11 frame
1408 *
1409 * 2 bytes FW len (inject)
1410 * 24 bytes 802.11 frame header
1411 * 6 bytes addr4 (inject)
1412 * n bytes 802.11 frame body
1413 */
1414 if (m_leadingspace(m0) < 8) {
1415 if (m_trailingspace(m0) < 8)
1416 panic("%s: not enough space for mbuf dance",
1417 sc->sc_dev.dv_xname);
1418 bcopy(m0->m_datam_hdr.mh_data, m0->m_datam_hdr.mh_data + 8, m0->m_lenm_hdr.mh_len);
1419 m0->m_datam_hdr.mh_data += 8;
1420 }
1421
1422 /* move frame header */
1423 bcopy(m0->m_datam_hdr.mh_data, m0->m_datam_hdr.mh_data - 6, sizeof(*wh));
1424 m0->m_datam_hdr.mh_data -= 8;
1425 m0->m_lenm_hdr.mh_len += 8;
1426 m0->m_pkthdrM_dat.MH.MH_pkthdr.len += 8;
1427 *mtod(m0, uint16_t *)((uint16_t *)((m0)->m_hdr.mh_data)) = htole16(m0->m_len - 32)((__uint16_t)(m0->m_hdr.mh_len - 32)); /* FW len */
1428
1429 error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
data->map), (m0), (0x0001))
1430 BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
data->map), (m0), (0x0001))
;
1431 if (error != 0) {
1432 printf("%s: can't map mbuf (error %d)\n",
1433 sc->sc_dev.dv_xname, error);
1434 m_freem(m0);
1435 return (error);
1436 }
1437
1438 data->m = m0;
1439 data->ni = ni;
1440 data->softstat |= htole32(0x80)((__uint32_t)(0x80));
1441
1442 malo_tx_setup_desc(sc, desc, m0->m_pkthdrM_dat.MH.MH_pkthdr.len, 0,
1443 data->map->dm_segs, data->map->dm_nsegs);
1444
1445 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))
1446 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x04))
;
1447 bus_dmamap_sync(sc->sc_dmat, sc->sc_txring.map,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_txring.map), (sc->sc_txring.cur * sizeof(struct malo_tx_desc
)), (sizeof(struct malo_tx_desc)), (0x04))
1448 sc->sc_txring.cur * sizeof(struct malo_tx_desc),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_txring.map), (sc->sc_txring.cur * sizeof(struct malo_tx_desc
)), (sizeof(struct malo_tx_desc)), (0x04))
1449 sizeof(struct malo_tx_desc), BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_txring.map), (sc->sc_txring.cur * sizeof(struct malo_tx_desc
)), (sizeof(struct malo_tx_desc)), (0x04))
;
1450
1451 DPRINTF(2, "%s: sending mgmt frame, pktlen=%u, idx=%u\n",
1452 sc->sc_dev.dv_xname, m0->m_pkthdr.len, sc->sc_txring.cur);
1453
1454 sc->sc_txring.queued++;
1455 sc->sc_txring.cur = (sc->sc_txring.cur + 1) % MALO_TX_RING_COUNT256;
1456
1457 /* kick mgmt TX */
1458 malo_ctl_write4(sc, 0x0c18, 1)(((sc)->sc_mem2_bt)->write_4(((sc)->sc_mem2_bh), ((0x0c18
)), ((1))))
;
1459 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE)bus_space_barrier((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, 0x0c00
, 0xff, (0x02))
;
1460
1461 return (0);
1462}
1463
1464int
1465malo_tx_data(struct malo_softc *sc, struct mbuf *m0,
1466 struct ieee80211_node *ni)
1467{
1468 struct ieee80211com *ic = &sc->sc_ic;
1469 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1470 struct malo_tx_desc *desc;
1471 struct malo_tx_data *data;
1472 struct ieee80211_frame *wh;
1473 struct ieee80211_key *k;
1474 struct mbuf *mnew;
1475 int error;
1476
1477 DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
1478
1479 desc = &sc->sc_txring.desc[sc->sc_txring.cur];
1480 data = &sc->sc_txring.data[sc->sc_txring.cur];
1481
1482 if (m0->m_lenm_hdr.mh_len < sizeof(struct ieee80211_frame)) {
1483 m0 = m_pullup(m0, sizeof(struct ieee80211_frame));
1484 if (m0 == NULL((void *)0)) {
1485 ifp->if_ierrorsif_data.ifi_ierrors++;
1486 return (ENOBUFS55);
1487 }
1488 }
1489 wh = mtod(m0, struct ieee80211_frame *)((struct ieee80211_frame *)((m0)->m_hdr.mh_data));
1490
1491 if (wh->i_fc[1] & IEEE80211_FC1_WEP0x40) {
1492 k = ieee80211_get_txkey(ic, wh, ni);
1493 if ((m0 = ieee80211_encrypt(ic, m0, k)) == NULL((void *)0))
1494 return (ENOBUFS55);
1495
1496 /* packet header may have moved, reset our local pointer */
1497 wh = mtod(m0, struct ieee80211_frame *)((struct ieee80211_frame *)((m0)->m_hdr.mh_data));
1498 }
1499
1500#if NBPFILTER1 > 0
1501 if (sc->sc_drvbpf != NULL((void *)0)) {
1502 struct mbuf mb;
1503 struct malo_tx_radiotap_hdr *tap = &sc->sc_txtapsc_txtapu.th;
1504
1505 tap->wt_flags = 0;
1506 tap->wt_rate = sc->sc_last_txrate;
1507 tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq)((__uint16_t)(ic->ic_bss->ni_chan->ic_freq));
1508 tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags)((__uint16_t)(ic->ic_bss->ni_chan->ic_flags));
1509
1510 mb.m_datam_hdr.mh_data = (caddr_t)tap;
1511 mb.m_lenm_hdr.mh_len = sc->sc_txtap_len;
1512 mb.m_nextm_hdr.mh_next = m0;
1513 mb.m_nextpktm_hdr.mh_nextpkt = NULL((void *)0);
1514 mb.m_typem_hdr.mh_type = 0;
1515 mb.m_flagsm_hdr.mh_flags = 0;
1516 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT(1 << 1));
1517 }
1518#endif
1519
1520 /*
1521 * inject FW specific fields into the 802.11 frame
1522 *
1523 * 2 bytes FW len (inject)
1524 * 24 bytes 802.11 frame header
1525 * 6 bytes addr4 (inject)
1526 * n bytes 802.11 frame body
1527 *
1528 * For now copy all into a new mcluster.
1529 */
1530 MGETHDR(mnew, M_DONTWAIT, MT_DATA)mnew = m_gethdr((0x0002), (1));
1531 if (mnew == NULL((void *)0))
1532 return (ENOBUFS55);
1533 MCLGET(mnew, M_DONTWAIT)(void) m_clget((mnew), (0x0002), (1 << 11));
1534 if (!(mnew->m_flagsm_hdr.mh_flags & M_EXT0x0001)) {
1535 m_free(mnew);
1536 return (ENOBUFS55);
1537 }
1538
1539 *mtod(mnew, uint16_t *)((uint16_t *)((mnew)->m_hdr.mh_data)) = htole16(m0->m_pkthdr.len - 24)((__uint16_t)(m0->M_dat.MH.MH_pkthdr.len - 24)); /* FW len */
1540 bcopy(wh, mtod(mnew, caddr_t)((caddr_t)((mnew)->m_hdr.mh_data)) + 2, sizeof(*wh));
1541 bzero(mtod(mnew, caddr_t) + 26, 6)__builtin_bzero((((caddr_t)((mnew)->m_hdr.mh_data)) + 26),
(6))
;
1542 m_copydata(m0, sizeof(*wh), m0->m_pkthdrM_dat.MH.MH_pkthdr.len - sizeof(*wh),
1543 mtod(mnew, caddr_t)((caddr_t)((mnew)->m_hdr.mh_data)) + 32);
1544 mnew->m_pkthdrM_dat.MH.MH_pkthdr.len = mnew->m_lenm_hdr.mh_len = m0->m_pkthdrM_dat.MH.MH_pkthdr.len + 8;
1545 m_freem(m0);
1546 m0 = mnew;
1547
1548 error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
data->map), (m0), (0x0001))
1549 BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
data->map), (m0), (0x0001))
;
1550 if (error != 0) {
1551 printf("%s: can't map mbuf (error %d)\n",
1552 sc->sc_dev.dv_xname, error);
1553 m_freem(m0);
1554 return (error);
1555 }
1556
1557 data->m = m0;
1558 data->ni = ni;
1559 data->softstat |= htole32(0x80)((__uint32_t)(0x80));
1560
1561 malo_tx_setup_desc(sc, desc, m0->m_pkthdrM_dat.MH.MH_pkthdr.len, 1,
1562 data->map->dm_segs, data->map->dm_nsegs);
1563
1564 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))
1565 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x04))
;
1566 bus_dmamap_sync(sc->sc_dmat, sc->sc_txring.map,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_txring.map), (sc->sc_txring.cur * sizeof(struct malo_tx_desc
)), (sizeof(struct malo_tx_desc)), (0x04))
1567 sc->sc_txring.cur * sizeof(struct malo_tx_desc),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_txring.map), (sc->sc_txring.cur * sizeof(struct malo_tx_desc
)), (sizeof(struct malo_tx_desc)), (0x04))
1568 sizeof(struct malo_tx_desc), BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_txring.map), (sc->sc_txring.cur * sizeof(struct malo_tx_desc
)), (sizeof(struct malo_tx_desc)), (0x04))
;
1569
1570 DPRINTF(2, "%s: sending data frame, pktlen=%u, idx=%u\n",
1571 sc->sc_dev.dv_xname, m0->m_pkthdr.len, sc->sc_txring.cur);
1572
1573 sc->sc_txring.queued++;
1574 sc->sc_txring.cur = (sc->sc_txring.cur + 1) % MALO_TX_RING_COUNT256;
1575
1576 /* kick data TX */
1577 malo_ctl_write4(sc, 0x0c18, 1)(((sc)->sc_mem2_bt)->write_4(((sc)->sc_mem2_bh), ((0x0c18
)), ((1))))
;
1578 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE)bus_space_barrier((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, 0x0c00
, 0xff, (0x02))
;
1579
1580 return (0);
1581}
1582
1583void
1584malo_tx_setup_desc(struct malo_softc *sc, struct malo_tx_desc *desc,
1585 int len, int rate, const bus_dma_segment_t *segs, int nsegs)
1586{
1587 desc->len = htole16(segs[0].ds_len)((__uint16_t)(segs[0].ds_len));
1588 desc->datarate = rate; /* 0 = mgmt frame, 1 = data frame */
1589 desc->physdata = htole32(segs[0].ds_addr)((__uint32_t)(segs[0].ds_addr));
1590 desc->status = htole32(0x00000001 | 0x80000000)((__uint32_t)(0x00000001 | 0x80000000));
1591}
1592
1593void
1594malo_rx_intr(struct malo_softc *sc)
1595{
1596 struct mbuf_list ml = MBUF_LIST_INITIALIZER(){ ((void *)0), ((void *)0), 0 };
1597 struct ieee80211com *ic = &sc->sc_ic;
1598 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1599 struct malo_rx_desc *desc;
1600 struct malo_rx_data *data;
1601 struct ieee80211_frame *wh;
1602 struct ieee80211_rxinfo rxi;
1603 struct ieee80211_node *ni;
1604 struct mbuf *mnew, *m;
1605 uint32_t rxRdPtr, rxWrPtr;
1606 int error, i;
1607
1608 rxRdPtr = malo_mem_read4(sc, sc->sc_RxPdRdPtr)(((sc)->sc_mem1_bt)->read_4(((sc)->sc_mem1_bh), ((sc
->sc_RxPdRdPtr))))
;
1609 rxWrPtr = malo_mem_read4(sc, sc->sc_RxPdWrPtr)(((sc)->sc_mem1_bt)->read_4(((sc)->sc_mem1_bh), ((sc
->sc_RxPdWrPtr))))
;
1610
1611 for (i = 0; i < MALO_RX_RING_COUNT256 && rxRdPtr != rxWrPtr; i++) {
1612 desc = &sc->sc_rxring.desc[sc->sc_rxring.cur];
1613 data = &sc->sc_rxring.data[sc->sc_rxring.cur];
1614
1615 bus_dmamap_sync(sc->sc_dmat, sc->sc_rxring.map,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_rxring.map), (sc->sc_rxring.cur * sizeof(struct malo_rx_desc
)), (sizeof(struct malo_rx_desc)), (0x02))
1616 sc->sc_rxring.cur * sizeof(struct malo_rx_desc),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_rxring.map), (sc->sc_rxring.cur * sizeof(struct malo_rx_desc
)), (sizeof(struct malo_rx_desc)), (0x02))
1617 sizeof(struct malo_rx_desc), BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_rxring.map), (sc->sc_rxring.cur * sizeof(struct malo_rx_desc
)), (sizeof(struct malo_rx_desc)), (0x02))
;
1618
1619 DPRINTF(3, "%s: rx intr idx=%d, rxctrl=0x%02x, rssi=%d, "
1620 "status=0x%02x, channel=%d, len=%d, res1=%02x, rate=%d, "
1621 "physdata=0x%04x, physnext=0x%04x, qosctrl=%02x, res2=%d\n",
1622 sc->sc_dev.dv_xname,
1623 sc->sc_rxring.cur, desc->rxctrl, desc->rssi, desc->status,
1624 desc->channel, letoh16(desc->len), desc->reserved1,
1625 desc->datarate, letoh32(desc->physdata),
1626 letoh32(desc->physnext), desc->qosctrl, desc->reserved2);
1627
1628 if ((desc->rxctrl & 0x80) == 0)
1629 break;
1630
1631 MGETHDR(mnew, M_DONTWAIT, MT_DATA)mnew = m_gethdr((0x0002), (1));
1632 if (mnew == NULL((void *)0)) {
1633 ifp->if_ierrorsif_data.ifi_ierrors++;
1634 goto skip;
1635 }
1636
1637 MCLGET(mnew, M_DONTWAIT)(void) m_clget((mnew), (0x0002), (1 << 11));
1638 if (!(mnew->m_flagsm_hdr.mh_flags & M_EXT0x0001)) {
1639 m_freem(mnew);
1640 ifp->if_ierrorsif_data.ifi_ierrors++;
1641 goto skip;
1642 }
1643
1644 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))
1645 data->map->dm_mapsize, BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (data->
map), (0), (data->map->dm_mapsize), (0x02))
;
1646 bus_dmamap_unload(sc->sc_dmat, data->map)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (data
->map))
;
1647
1648 error = bus_dmamap_load(sc->sc_dmat, data->map,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (data->
map), (((void *)((mnew)->m_hdr.mh_data))), ((1 << 11
)), (((void *)0)), (0x0001))
1649 mtod(mnew, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (data->
map), (((void *)((mnew)->m_hdr.mh_data))), ((1 << 11
)), (((void *)0)), (0x0001))
;
1650 if (error != 0) {
1651 m_freem(mnew);
1652
1653 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))), ((1 <<
11)), (((void *)0)), (0x0001))
1654 mtod(data->m, void *), MCLBYTES, NULL,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (data->
map), (((void *)((data->m)->m_hdr.mh_data))), ((1 <<
11)), (((void *)0)), (0x0001))
1655 BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (data->
map), (((void *)((data->m)->m_hdr.mh_data))), ((1 <<
11)), (((void *)0)), (0x0001))
;
1656 if (error != 0) {
1657 panic("%s: could not load old rx mbuf",
1658 sc->sc_dev.dv_xname);
1659 }
1660 ifp->if_ierrorsif_data.ifi_ierrors++;
1661 goto skip;
1662 }
1663
1664 /*
1665 * New mbuf mbuf successfully loaded
1666 */
1667 m = data->m;
1668 data->m = mnew;
1669 desc->physdata = htole32(data->map->dm_segs->ds_addr)((__uint32_t)(data->map->dm_segs->ds_addr));
1670
1671 /* finalize mbuf */
1672 m->m_pkthdrM_dat.MH.MH_pkthdr.len = m->m_lenm_hdr.mh_len = letoh16(desc->len)((__uint16_t)(desc->len));
1673
1674 /*
1675 * cut out FW specific fields from the 802.11 frame
1676 *
1677 * 2 bytes FW len (cut out)
1678 * 24 bytes 802.11 frame header
1679 * 6 bytes addr4 (cut out)
1680 * n bytes 802.11 frame data
1681 */
1682 bcopy(m->m_datam_hdr.mh_data, m->m_datam_hdr.mh_data + 6, 26);
1683 m_adj(m, 8);
1684
1685#if NBPFILTER1 > 0
1686 if (sc->sc_drvbpf != NULL((void *)0)) {
1687 struct mbuf mb;
1688 struct malo_rx_radiotap_hdr *tap = &sc->sc_rxtapsc_rxtapu.th;
1689
1690 tap->wr_flags = 0;
1691 tap->wr_chan_freq =
1692 htole16(ic->ic_bss->ni_chan->ic_freq)((__uint16_t)(ic->ic_bss->ni_chan->ic_freq));
1693 tap->wr_chan_flags =
1694 htole16(ic->ic_bss->ni_chan->ic_flags)((__uint16_t)(ic->ic_bss->ni_chan->ic_flags));
1695 tap->wr_rssi = desc->rssi;
1696 tap->wr_max_rssi = ic->ic_max_rssi;
1697
1698 mb.m_datam_hdr.mh_data = (caddr_t)tap;
1699 mb.m_lenm_hdr.mh_len = sc->sc_rxtap_len;
1700 mb.m_nextm_hdr.mh_next = m;
1701 mb.m_nextpktm_hdr.mh_nextpkt = NULL((void *)0);
1702 mb.m_typem_hdr.mh_type = 0;
1703 mb.m_flagsm_hdr.mh_flags = 0;
1704 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN(1 << 0));
1705 }
1706#endif
1707
1708 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
1709 ni = ieee80211_find_rxnode(ic, wh);
1710
1711 /* send the frame to the 802.11 layer */
1712 rxi.rxi_flags = 0;
1713 rxi.rxi_rssi = desc->rssi;
1714 rxi.rxi_tstamp = 0; /* unused */
1715 ieee80211_inputm(ifp, m, ni, &rxi, &ml);
1716
1717 /* node is no longer needed */
1718 ieee80211_release_node(ic, ni);
1719
1720skip:
1721 desc->rxctrl = 0;
1722 rxRdPtr = letoh32(desc->physnext)((__uint32_t)(desc->physnext));
1723
1724 bus_dmamap_sync(sc->sc_dmat, sc->sc_rxring.map,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_rxring.map), (sc->sc_rxring.cur * sizeof(struct malo_rx_desc
)), (sizeof(struct malo_rx_desc)), (0x04))
1725 sc->sc_rxring.cur * sizeof(struct malo_rx_desc),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_rxring.map), (sc->sc_rxring.cur * sizeof(struct malo_rx_desc
)), (sizeof(struct malo_rx_desc)), (0x04))
1726 sizeof(struct malo_rx_desc), BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_rxring.map), (sc->sc_rxring.cur * sizeof(struct malo_rx_desc
)), (sizeof(struct malo_rx_desc)), (0x04))
;
1727
1728 sc->sc_rxring.cur = (sc->sc_rxring.cur + 1) %
1729 MALO_RX_RING_COUNT256;
1730 }
1731 if_input(ifp, &ml);
1732
1733 malo_mem_write4(sc, sc->sc_RxPdRdPtr, rxRdPtr)(((sc)->sc_mem1_bt)->write_4(((sc)->sc_mem1_bh), ((sc
->sc_RxPdRdPtr)), ((rxRdPtr))))
;
1734}
1735
1736int
1737malo_load_bootimg(struct malo_softc *sc)
1738{
1739 char *name = "malo8335-h";
1740 uint8_t *ucode;
1741 size_t usize;
1742 int error, i;
1743
1744 /* load boot firmware */
1745 if ((error = loadfirmware(name, &ucode, &usize)) != 0) {
1746 printf("%s: error %d, could not read firmware %s\n",
1747 sc->sc_dev.dv_xname, error, name);
1748 return (EIO5);
1749 }
1750
1751 /*
1752 * It seems we are putting this code directly onto the stack of
1753 * the ARM cpu. I don't know why we need to instruct the DMA
1754 * engine to move the code. This is a big riddle without docu.
1755 */
1756 DPRINTF(1, "%s: loading boot firmware\n", sc->sc_dev.dv_xname);
1757 malo_mem_write2(sc, 0xbef8, 0x001)(((sc)->sc_mem1_bt)->write_2(((sc)->sc_mem1_bh), ((0xbef8
)), ((0x001))))
;
1758 malo_mem_write2(sc, 0xbefa, usize)(((sc)->sc_mem1_bt)->write_2(((sc)->sc_mem1_bh), ((0xbefa
)), ((usize))))
;
1759 malo_mem_write4(sc, 0xbefc, 0)(((sc)->sc_mem1_bt)->write_4(((sc)->sc_mem1_bh), ((0xbefc
)), ((0))))
;
1760
1761 bus_space_write_region_1(sc->sc_mem1_bt, sc->sc_mem1_bh, 0xbf00,((sc->sc_mem1_bt)->write_region_1((sc->sc_mem1_bh), (
0xbf00), (ucode), (usize)))
1762 ucode, usize)((sc->sc_mem1_bt)->write_region_1((sc->sc_mem1_bh), (
0xbf00), (ucode), (usize)))
;
1763
1764 /*
1765 * we loaded the firmware into card memory now tell the CPU
1766 * to fetch the code and execute it. The memory mapped via the
1767 * first bar is internally mapped to 0xc0000000.
1768 */
1769 malo_send_cmd(sc, 0xc000bef8);
1770
1771 /* wait for the device to go into FW loading mode */
1772 for (i = 0; i < 10; i++) {
1773 delay(50)(*delay_func)(50);
1774 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_READ)bus_space_barrier((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, 0x0c00
, 0xff, (0x01))
;
1775 if (malo_ctl_read4(sc, 0x0c14)(((sc)->sc_mem2_bt)->read_4(((sc)->sc_mem2_bh), ((0x0c14
))))
== 0x5)
1776 break;
1777 }
1778 if (i == 10) {
1779 printf("%s: timeout at boot firmware load!\n",
1780 sc->sc_dev.dv_xname);
1781 free(ucode, M_DEVBUF2, usize);
1782 return (ETIMEDOUT60);
1783 }
1784 free(ucode, M_DEVBUF2, usize);
1785
1786 /* tell the card we're done and... */
1787 malo_mem_write2(sc, 0xbef8, 0x001)(((sc)->sc_mem1_bt)->write_2(((sc)->sc_mem1_bh), ((0xbef8
)), ((0x001))))
;
1788 malo_mem_write2(sc, 0xbefa, 0)(((sc)->sc_mem1_bt)->write_2(((sc)->sc_mem1_bh), ((0xbefa
)), ((0))))
;
1789 malo_mem_write4(sc, 0xbefc, 0)(((sc)->sc_mem1_bt)->write_4(((sc)->sc_mem1_bh), ((0xbefc
)), ((0))))
;
1790 malo_send_cmd(sc, 0xc000bef8);
1791
1792 DPRINTF(1, "%s: boot firmware loaded\n", sc->sc_dev.dv_xname);
1793
1794 return (0);
1795}
1796
1797int
1798malo_load_firmware(struct malo_softc *sc)
1799{
1800 struct malo_cmdheader *hdr;
1801 char *name = "malo8335-m";
1802 void *data;
1803 uint8_t *ucode;
1804 size_t size, count, bsize;
1805 int i, sn, error;
1806
1807 /* load real firmware now */
1808 if ((error = loadfirmware(name, &ucode, &size)) != 0) {
1809 printf("%s: error %d, could not read firmware %s\n",
1810 sc->sc_dev.dv_xname, error, name);
1811 return (EIO5);
1812 }
1813
1814 DPRINTF(1, "%s: uploading firmware\n", sc->sc_dev.dv_xname);
1815
1816 hdr = sc->sc_cmd_mem;
1817 data = hdr + 1;
1818 sn = 1;
1819 for (count = 0; count < size; count += bsize) {
1820 bsize = MIN(256, size - count)(((256)<(size - count))?(256):(size - count));
1821
1822 hdr->cmd = htole16(0x0001)((__uint16_t)(0x0001));
1823 hdr->size = htole16(bsize)((__uint16_t)(bsize));
1824 hdr->seqnum = htole16(sn++)((__uint16_t)(sn++));
1825 hdr->result = 0;
1826
1827 bcopy(ucode + count, data, bsize);
1828
1829 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04))
1830 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04))
;
1831 malo_send_cmd(sc, sc->sc_cmd_dmaaddr);
1832 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x08))
1833 BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x08))
;
1834 delay(500)(*delay_func)(500);
1835 }
1836 free(ucode, M_DEVBUF2, size);
1837
1838 DPRINTF(1, "%s: firmware upload finished\n", sc->sc_dev.dv_xname);
1839
1840 /*
1841 * send a command with size 0 to tell that the firmware has been
1842 * uploaded
1843 */
1844 hdr->cmd = htole16(0x0001)((__uint16_t)(0x0001));
1845 hdr->size = 0;
1846 hdr->seqnum = htole16(sn++)((__uint16_t)(sn++));
1847 hdr->result = 0;
1848
1849 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04))
1850 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04))
;
1851 malo_send_cmd(sc, sc->sc_cmd_dmaaddr);
1852 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x08))
1853 BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x08))
;
1854 delay(100)(*delay_func)(100);
1855
1856 DPRINTF(1, "%s: loading firmware\n", sc->sc_dev.dv_xname);
1857
1858 /* wait until firmware has been loaded */
1859 for (i = 0; i < 200; i++) {
1860 malo_ctl_write4(sc, 0x0c10, 0x5a)(((sc)->sc_mem2_bt)->write_4(((sc)->sc_mem2_bh), ((0x0c10
)), ((0x5a))))
;
1861 delay(500)(*delay_func)(500);
1862 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE |bus_space_barrier((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, 0x0c00
, 0xff, (0x02 | 0x01))
1863 BUS_SPACE_BARRIER_READ)bus_space_barrier((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, 0x0c00
, 0xff, (0x02 | 0x01))
;
1864 if (malo_ctl_read4(sc, 0x0c14)(((sc)->sc_mem2_bt)->read_4(((sc)->sc_mem2_bh), ((0x0c14
))))
== 0xf0f1f2f4)
1865 break;
1866 }
1867 if (i == 200) {
1868 printf("%s: timeout at firmware load!\n", sc->sc_dev.dv_xname);
1869 return (ETIMEDOUT60);
1870 }
1871
1872 DPRINTF(1, "%s: firmware loaded\n", sc->sc_dev.dv_xname);
1873
1874 return (0);
1875}
1876
1877int
1878malo_set_slot(struct malo_softc *sc)
1879{
1880 struct ieee80211com *ic = &sc->sc_ic;
1881
1882 if (ic->ic_flags & IEEE80211_F_SHSLOT0x00020000) {
1883 /* set short slot */
1884 if (malo_cmd_set_slot(sc, 1)) {
1885 printf("%s: setting short slot failed\n",
1886 sc->sc_dev.dv_xname);
1887 return (ENXIO6);
1888 }
1889 } else {
1890 /* set long slot */
1891 if (malo_cmd_set_slot(sc, 0)) {
1892 printf("%s: setting long slot failed\n",
1893 sc->sc_dev.dv_xname);
1894 return (ENXIO6);
1895 }
1896 }
1897
1898 return (0);
1899}
1900
1901void
1902malo_update_slot(struct ieee80211com *ic)
1903{
1904 struct malo_softc *sc = ic->ic_ific_ac.ac_if.if_softc;
1905
1906 malo_set_slot(sc);
1907
1908#ifndef IEEE80211_STA_ONLY
1909 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
1910 /* TODO */
1911 }
1912#endif
1913}
1914
1915#ifdef MALO_DEBUG
1916void
1917malo_hexdump(void *buf, int len)
1918{
1919 u_char b[16];
1920 int i, j, l;
1921
1922 for (i = 0; i < len; i += l) {
1923 printf("%4i:", i);
1924 l = min(sizeof(b), len - i);
1925 bcopy(buf + i, b, l);
1926
1927 for (j = 0; j < sizeof(b); j++) {
1928 if (j % 2 == 0)
1929 printf(" ");
1930 if (j % 8 == 0)
1931 printf(" ");
1932 if (j < l)
1933 printf("%02x", (int)b[j]);
1934 else
1935 printf(" ");
1936 }
1937 printf(" |");
1938 for (j = 0; j < l; j++) {
1939 if (b[j] >= 0x20 && b[j] <= 0x7e)
1940 printf("%c", b[j]);
1941 else
1942 printf(".");
1943 }
1944 printf("|\n");
1945 }
1946}
1947#endif
1948
1949static char *
1950malo_cmd_string(uint16_t cmd)
1951{
1952 int i;
1953 static char cmd_buf[16];
1954 static const struct {
1955 uint16_t cmd_code;
1956 char *cmd_string;
1957 } cmds[] = {
1958 { MALO_CMD_GET_HW_SPEC0x0003, "GetHwSpecifications" },
1959 { MALO_CMD_SET_RADIO0x001c, "SetRadio" },
1960 { MALO_CMD_SET_AID0x010d, "SetAid" },
1961 { MALO_CMD_SET_TXPOWER0x001e, "SetTxPower" },
1962 { MALO_CMD_SET_ANTENNA0x0020, "SetAntenna" },
1963 { MALO_CMD_SET_PRESCAN0x0107, "SetPrescan" },
1964 { MALO_CMD_SET_POSTSCAN0x0108, "SetPostscan" },
1965 { MALO_CMD_SET_RATE0x0110, "SetRate" },
1966 { MALO_CMD_SET_CHANNEL0x010a, "SetChannel" },
1967 { MALO_CMD_SET_RTS0x0113, "SetRTS" },
1968 { MALO_CMD_SET_SLOT0x0114, "SetSlot" },
1969 };
1970
1971 for (i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++)
1972 if ((letoh16(cmd)((__uint16_t)(cmd)) & 0x7fff) == cmds[i].cmd_code)
1973 return (cmds[i].cmd_string);
1974
1975 snprintf(cmd_buf, sizeof(cmd_buf), "unknown %#x", cmd);
1976 return (cmd_buf);
1977}
1978
1979static char *
1980malo_cmd_string_result(uint16_t result)
1981{
1982 int i;
1983 static const struct {
1984 uint16_t result_code;
1985 char *result_string;
1986 } results[] = {
1987 { MALO_CMD_RESULT_OK0x0000, "OK" },
1988 { MALO_CMD_RESULT_ERROR0x0001, "general error" },
1989 { MALO_CMD_RESULT_NOSUPPORT0x0002, "not supported" },
1990 { MALO_CMD_RESULT_PENDING0x0003, "pending" },
1991 { MALO_CMD_RESULT_BUSY0x0004, "ignored" },
1992 { MALO_CMD_RESULT_PARTIALDATA0x0005, "incomplete" },
1993 };
1994
1995 for (i = 0; i < sizeof(results) / sizeof(results[0]); i++)
1996 if (letoh16(result)((__uint16_t)(result)) == results[i].result_code)
1997 return (results[i].result_string);
1998
1999 return ("unknown");
2000}
2001
2002int
2003malo_cmd_get_spec(struct malo_softc *sc)
2004{
2005 struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2006 struct malo_hw_spec *spec;
2007
2008 hdr->cmd = htole16(MALO_CMD_GET_HW_SPEC)((__uint16_t)(0x0003));
2009 hdr->size = htole16(sizeof(*hdr) + sizeof(*spec))((__uint16_t)(sizeof(*hdr) + sizeof(*spec)));
2010 hdr->seqnum = htole16(42)((__uint16_t)(42)); /* the one and only */
2011 hdr->result = 0;
2012 spec = (struct malo_hw_spec *)(hdr + 1);
2013
2014 bzero(spec, sizeof(*spec))__builtin_bzero((spec), (sizeof(*spec)));
2015 memset(spec->PermanentAddress, 0xff, ETHER_ADDR_LEN)__builtin_memset((spec->PermanentAddress), (0xff), (6));
2016 spec->CookiePtr = htole32(sc->sc_cookie_dmaaddr)((__uint32_t)(sc->sc_cookie_dmaaddr));
2017
2018 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04|0x01))
2019 BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04|0x01))
;
2020
2021 if (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr) != 0)
2022 return (ETIMEDOUT60);
2023
2024 /* get the data from the buffer */
2025 DPRINTF(1, "%s: get_hw_spec: V%x R%x, #WCB %d, #Mcast %d, Regcode %d, "
2026 "#Ant %d\n", sc->sc_dev.dv_xname, htole16(spec->HwVersion),
2027 htole32(spec->FWReleaseNumber), htole16(spec->NumOfWCB),
2028 htole16(spec->NumOfMCastAdr), htole16(spec->RegionCode),
2029 htole16(spec->NumberOfAntenna));
2030
2031 /* tell the DMA engine where our rings are */
2032 malo_mem_write4(sc, letoh32(spec->RxPdRdPtr) & 0xffff,(((sc)->sc_mem1_bt)->write_4(((sc)->sc_mem1_bh), (((
(__uint32_t)(spec->RxPdRdPtr)) & 0xffff)), ((sc->sc_rxring
.physaddr))))
2033 sc->sc_rxring.physaddr)(((sc)->sc_mem1_bt)->write_4(((sc)->sc_mem1_bh), (((
(__uint32_t)(spec->RxPdRdPtr)) & 0xffff)), ((sc->sc_rxring
.physaddr))))
;
2034 malo_mem_write4(sc, letoh32(spec->RxPdWrPtr) & 0xffff,(((sc)->sc_mem1_bt)->write_4(((sc)->sc_mem1_bh), (((
(__uint32_t)(spec->RxPdWrPtr)) & 0xffff)), ((sc->sc_rxring
.physaddr))))
2035 sc->sc_rxring.physaddr)(((sc)->sc_mem1_bt)->write_4(((sc)->sc_mem1_bh), (((
(__uint32_t)(spec->RxPdWrPtr)) & 0xffff)), ((sc->sc_rxring
.physaddr))))
;
2036 malo_mem_write4(sc, letoh32(spec->WcbBase0) & 0xffff,(((sc)->sc_mem1_bt)->write_4(((sc)->sc_mem1_bh), (((
(__uint32_t)(spec->WcbBase0)) & 0xffff)), ((sc->sc_txring
.physaddr))))
2037 sc->sc_txring.physaddr)(((sc)->sc_mem1_bt)->write_4(((sc)->sc_mem1_bh), (((
(__uint32_t)(spec->WcbBase0)) & 0xffff)), ((sc->sc_txring
.physaddr))))
;
2038
2039 /* save DMA RX pointers for later use */
2040 sc->sc_RxPdRdPtr = letoh32(spec->RxPdRdPtr)((__uint32_t)(spec->RxPdRdPtr)) & 0xffff;
2041 sc->sc_RxPdWrPtr = letoh32(spec->RxPdWrPtr)((__uint32_t)(spec->RxPdWrPtr)) & 0xffff;
2042
2043 return (0);
2044}
2045
2046int
2047malo_cmd_set_prescan(struct malo_softc *sc)
2048{
2049 struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2050
2051 hdr->cmd = htole16(MALO_CMD_SET_PRESCAN)((__uint16_t)(0x0107));
2052 hdr->size = htole16(sizeof(*hdr))((__uint16_t)(sizeof(*hdr)));
2053 hdr->seqnum = 1;
2054 hdr->result = 0;
2055
2056 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04 | 0x01))
2057 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04 | 0x01))
;
2058
2059 return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
2060}
2061
2062int
2063malo_cmd_set_postscan(struct malo_softc *sc, uint8_t *macaddr, uint8_t ibsson)
2064{
2065 struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2066 struct malo_cmd_postscan *body;
2067
2068 hdr->cmd = htole16(MALO_CMD_SET_POSTSCAN)((__uint16_t)(0x0108));
2069 hdr->size = htole16(sizeof(*hdr) + sizeof(*body))((__uint16_t)(sizeof(*hdr) + sizeof(*body)));
2070 hdr->seqnum = 1;
2071 hdr->result = 0;
2072 body = (struct malo_cmd_postscan *)(hdr + 1);
2073
2074 bzero(body, sizeof(*body))__builtin_bzero((body), (sizeof(*body)));
2075 memcpy(&body->bssid, macaddr, ETHER_ADDR_LEN)__builtin_memcpy((&body->bssid), (macaddr), (6));
2076 body->isibss = htole32(ibsson)((__uint32_t)(ibsson));
2077
2078 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04 | 0x01))
2079 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04 | 0x01))
;
2080
2081 return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
2082}
2083
2084int
2085malo_cmd_set_channel(struct malo_softc *sc, uint8_t channel)
2086{
2087 struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2088 struct malo_cmd_channel *body;
2089
2090 hdr->cmd = htole16(MALO_CMD_SET_CHANNEL)((__uint16_t)(0x010a));
2091 hdr->size = htole16(sizeof(*hdr) + sizeof(*body))((__uint16_t)(sizeof(*hdr) + sizeof(*body)));
2092 hdr->seqnum = 1;
2093 hdr->result = 0;
2094 body = (struct malo_cmd_channel *)(hdr + 1);
2095
2096 bzero(body, sizeof(*body))__builtin_bzero((body), (sizeof(*body)));
2097 body->action = htole16(1)((__uint16_t)(1));
2098 body->channel = channel;
2099
2100 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04 | 0x01))
2101 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04 | 0x01))
;
2102
2103 return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
2104}
2105
2106int
2107malo_cmd_set_antenna(struct malo_softc *sc, uint16_t antenna)
2108{
2109 struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2110 struct malo_cmd_antenna *body;
2111
2112 hdr->cmd = htole16(MALO_CMD_SET_ANTENNA)((__uint16_t)(0x0020));
2113 hdr->size = htole16(sizeof(*hdr) + sizeof(*body))((__uint16_t)(sizeof(*hdr) + sizeof(*body)));
2114 hdr->seqnum = 1;
2115 hdr->result = 0;
2116 body = (struct malo_cmd_antenna *)(hdr + 1);
2117
2118 bzero(body, sizeof(*body))__builtin_bzero((body), (sizeof(*body)));
2119 body->action = htole16(antenna)((__uint16_t)(antenna));
2120 if (antenna == 1)
2121 body->mode = htole16(0xffff)((__uint16_t)(0xffff));
2122 else
2123 body->mode = htole16(2)((__uint16_t)(2));
2124
2125 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04 | 0x01))
2126 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04 | 0x01))
;
2127
2128 return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
2129}
2130
2131int
2132malo_cmd_set_radio(struct malo_softc *sc, uint16_t enable,
2133 uint16_t preamble_mode)
2134{
2135 struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2136 struct malo_cmd_radio *body;
2137
2138 hdr->cmd = htole16(MALO_CMD_SET_RADIO)((__uint16_t)(0x001c));
2139 hdr->size = htole16(sizeof(*hdr) + sizeof(*body))((__uint16_t)(sizeof(*hdr) + sizeof(*body)));
2140 hdr->seqnum = 1;
2141 hdr->result = 0;
2142 body = (struct malo_cmd_radio *)(hdr + 1);
2143
2144 bzero(body, sizeof(*body))__builtin_bzero((body), (sizeof(*body)));
2145 body->action = htole16(1)((__uint16_t)(1));
2146 body->preamble_mode = htole16(preamble_mode)((__uint16_t)(preamble_mode));
2147 body->enable = htole16(enable)((__uint16_t)(enable));
2148
2149 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04 | 0x01))
2150 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04 | 0x01))
;
2151
2152 return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
2153}
2154
2155int
2156malo_cmd_set_aid(struct malo_softc *sc, uint8_t *bssid, uint16_t associd)
2157{
2158 struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2159 struct malo_cmd_aid *body;
2160
2161 hdr->cmd = htole16(MALO_CMD_SET_AID)((__uint16_t)(0x010d));
2162 hdr->size = htole16(sizeof(*hdr) + sizeof(*body))((__uint16_t)(sizeof(*hdr) + sizeof(*body)));
2163 hdr->seqnum = 1;
2164 hdr->result = 0;
2165 body = (struct malo_cmd_aid *)(hdr + 1);
2166
2167 bzero(body, sizeof(*body))__builtin_bzero((body), (sizeof(*body)));
2168 body->associd = htole16(associd)((__uint16_t)(associd));
2169 memcpy(&body->macaddr[0], bssid, IEEE80211_ADDR_LEN)__builtin_memcpy((&body->macaddr[0]), (bssid), (6));
2170
2171 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04 | 0x01))
2172 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04 | 0x01))
;
2173
2174 return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
2175}
2176
2177int
2178malo_cmd_set_txpower(struct malo_softc *sc, unsigned int powerlevel)
2179{
2180 struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2181 struct malo_cmd_txpower *body;
2182
2183 hdr->cmd = htole16(MALO_CMD_SET_TXPOWER)((__uint16_t)(0x001e));
2184 hdr->size = htole16(sizeof(*hdr) + sizeof(*body))((__uint16_t)(sizeof(*hdr) + sizeof(*body)));
2185 hdr->seqnum = 1;
2186 hdr->result = 0;
2187 body = (struct malo_cmd_txpower *)(hdr + 1);
2188
2189 bzero(body, sizeof(*body))__builtin_bzero((body), (sizeof(*body)));
2190 body->action = htole16(1)((__uint16_t)(1));
2191 if (powerlevel < 30)
2192 body->supportpowerlvl = htole16(5)((__uint16_t)(5)); /* LOW */
2193 else if (powerlevel >= 30 && powerlevel < 60)
2194 body->supportpowerlvl = htole16(10)((__uint16_t)(10)); /* MEDIUM */
2195 else
2196 body->supportpowerlvl = htole16(15)((__uint16_t)(15)); /* HIGH */
2197
2198 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04 | 0x01))
2199 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04 | 0x01))
;
2200
2201 return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
2202}
2203
2204int
2205malo_cmd_set_rts(struct malo_softc *sc, uint32_t threshold)
2206{
2207 struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2208 struct malo_cmd_rts *body;
2209
2210 hdr->cmd = htole16(MALO_CMD_SET_RTS)((__uint16_t)(0x0113));
2211 hdr->size = htole16(sizeof(*hdr) + sizeof(*body))((__uint16_t)(sizeof(*hdr) + sizeof(*body)));
2212 hdr->seqnum = 1;
2213 hdr->result = 0;
2214 body = (struct malo_cmd_rts *)(hdr + 1);
2215
2216 bzero(body, sizeof(*body))__builtin_bzero((body), (sizeof(*body)));
2217 body->action = htole16(1)((__uint16_t)(1));
2218 body->threshold = htole32(threshold)((__uint32_t)(threshold));
2219
2220 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04 | 0x01))
2221 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04 | 0x01))
;
2222
2223 return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
2224}
2225
2226int
2227malo_cmd_set_slot(struct malo_softc *sc, uint8_t slot)
2228{
2229 struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2230 struct malo_cmd_slot *body;
2231
2232 hdr->cmd = htole16(MALO_CMD_SET_SLOT)((__uint16_t)(0x0114));
2233 hdr->size = htole16(sizeof(*hdr) + sizeof(*body))((__uint16_t)(sizeof(*hdr) + sizeof(*body)));
2234 hdr->seqnum = 1;
2235 hdr->result = 0;
2236 body = (struct malo_cmd_slot *)(hdr + 1);
2237
2238 bzero(body, sizeof(*body))__builtin_bzero((body), (sizeof(*body)));
2239 body->action = htole16(1)((__uint16_t)(1));
2240 body->slot = slot;
2241
2242 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04 | 0x01))
2243 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04 | 0x01))
;
2244
2245 return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
2246}
2247
2248int
2249malo_cmd_set_rate(struct malo_softc *sc, uint8_t rate)
2250{
2251 struct ieee80211com *ic = &sc->sc_ic;
2252 struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2253 struct malo_cmd_rate *body;
2254 int i;
2255
2256 hdr->cmd = htole16(MALO_CMD_SET_RATE)((__uint16_t)(0x0110));
2257 hdr->size = htole16(sizeof(*hdr) + sizeof(*body))((__uint16_t)(sizeof(*hdr) + sizeof(*body)));
2258 hdr->seqnum = 1;
2259 hdr->result = 0;
2260 body = (struct malo_cmd_rate *)(hdr + 1);
2261
2262 bzero(body, sizeof(*body))__builtin_bzero((body), (sizeof(*body)));
2263
2264#ifndef IEEE80211_STA_ONLY
2265 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
2266 /* TODO */
2267 } else
2268#endif
2269 {
2270 body->aprates[0] = 2;
2271 body->aprates[1] = 4;
2272 body->aprates[2] = 11;
2273 body->aprates[3] = 22;
2274 if (ic->ic_curmode == IEEE80211_MODE_11G) {
2275 body->aprates[4] = 0;
2276 body->aprates[5] = 12;
2277 body->aprates[6] = 18;
2278 body->aprates[7] = 24;
2279 body->aprates[8] = 36;
2280 body->aprates[9] = 48;
2281 body->aprates[10] = 72;
2282 body->aprates[11] = 96;
2283 body->aprates[12] = 108;
2284 }
2285 }
2286
2287 if (rate != 0) {
2288 /* fixed rate */
2289 for (i = 0; i < 13; i++) {
2290 if (body->aprates[i] == rate) {
2291 body->rateindex = i;
2292 body->dataratetype = 1;
2293 break;
2294 }
2295 }
2296 }
2297
2298 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04 | 0x01))
2299 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_cmd_dmam), (0), ((1 << 12)), (0x04 | 0x01))
;
2300
2301 return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
2302}
2303
2304void
2305malo_cmd_response(struct malo_softc *sc)
2306{
2307 struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2308
2309 if (letoh16(hdr->result)((__uint16_t)(hdr->result)) != MALO_CMD_RESULT_OK0x0000) {
2310 printf("%s: firmware cmd %s failed with %s\n",
2311 sc->sc_dev.dv_xname,
2312 malo_cmd_string(hdr->cmd),
2313 malo_cmd_string_result(hdr->result));
2314 }
2315
2316#ifdef MALO_DEBUG
2317 printf("%s: cmd answer for %s=%s\n",
2318 sc->sc_dev.dv_xname,
2319 malo_cmd_string(hdr->cmd),
2320 malo_cmd_string_result(hdr->result));
2321
2322 if (malo_d > 2)
2323 malo_hexdump(hdr, letoh16(hdr->size)((__uint16_t)(hdr->size)));
2324#endif
2325}