Deleted Added
full compact
if_malo.c (283540) if_malo.c (286410)
1/*-
2 * Copyright (c) 2008 Weongyo Jeong <weongyo@freebsd.org>
3 * Copyright (c) 2007 Marvell Semiconductor, Inc.
4 * Copyright (c) 2007 Sam Leffler, Errno Consulting
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 17 unchanged lines hidden (view full) ---

26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
29 * THE POSSIBILITY OF SUCH DAMAGES.
30 */
31
32#include <sys/cdefs.h>
33#ifdef __FreeBSD__
1/*-
2 * Copyright (c) 2008 Weongyo Jeong <weongyo@freebsd.org>
3 * Copyright (c) 2007 Marvell Semiconductor, Inc.
4 * Copyright (c) 2007 Sam Leffler, Errno Consulting
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 17 unchanged lines hidden (view full) ---

26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
29 * THE POSSIBILITY OF SUCH DAMAGES.
30 */
31
32#include <sys/cdefs.h>
33#ifdef __FreeBSD__
34__FBSDID("$FreeBSD: head/sys/dev/malo/if_malo.c 283540 2015-05-25 19:53:29Z glebius $");
34__FBSDID("$FreeBSD: head/sys/dev/malo/if_malo.c 286410 2015-08-07 11:43:14Z glebius $");
35#endif
36
37#include "opt_malo.h"
38
39#include <sys/param.h>
40#include <sys/endian.h>
41#include <sys/kernel.h>
42#include <sys/socket.h>

--- 54 unchanged lines hidden (view full) ---

97 MALO_DEBUG_ANY = 0xffffffff
98};
99#define IS_BEACON(wh) \
100 ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK | \
101 IEEE80211_FC0_SUBTYPE_MASK)) == \
102 (IEEE80211_FC0_TYPE_MGT|IEEE80211_FC0_SUBTYPE_BEACON))
103#define IFF_DUMPPKTS_RECV(sc, wh) \
104 (((sc->malo_debug & MALO_DEBUG_RECV) && \
35#endif
36
37#include "opt_malo.h"
38
39#include <sys/param.h>
40#include <sys/endian.h>
41#include <sys/kernel.h>
42#include <sys/socket.h>

--- 54 unchanged lines hidden (view full) ---

97 MALO_DEBUG_ANY = 0xffffffff
98};
99#define IS_BEACON(wh) \
100 ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK | \
101 IEEE80211_FC0_SUBTYPE_MASK)) == \
102 (IEEE80211_FC0_TYPE_MGT|IEEE80211_FC0_SUBTYPE_BEACON))
103#define IFF_DUMPPKTS_RECV(sc, wh) \
104 (((sc->malo_debug & MALO_DEBUG_RECV) && \
105 ((sc->malo_debug & MALO_DEBUG_RECV_ALL) || !IS_BEACON(wh))) || \
106 (sc->malo_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == \
107 (IFF_DEBUG|IFF_LINK2))
105 ((sc->malo_debug & MALO_DEBUG_RECV_ALL) || !IS_BEACON(wh))))
108#define IFF_DUMPPKTS_XMIT(sc) \
106#define IFF_DUMPPKTS_XMIT(sc) \
109 ((sc->malo_debug & MALO_DEBUG_XMIT) || \
110 (sc->malo_ifp->if_flags & (IFF_DEBUG | IFF_LINK2)) == \
111 (IFF_DEBUG | IFF_LINK2))
107 (sc->malo_debug & MALO_DEBUG_XMIT)
112#define DPRINTF(sc, m, fmt, ...) do { \
113 if (sc->malo_debug & (m)) \
114 printf(fmt, __VA_ARGS__); \
115} while (0)
116#else
117#define DPRINTF(sc, m, fmt, ...) do { \
118 (void) sc; \
119} while (0)

--- 5 unchanged lines hidden (view full) ---

125 const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
126 const uint8_t [IEEE80211_ADDR_LEN],
127 const uint8_t [IEEE80211_ADDR_LEN]);
128static void malo_vap_delete(struct ieee80211vap *);
129static int malo_dma_setup(struct malo_softc *);
130static int malo_setup_hwdma(struct malo_softc *);
131static void malo_txq_init(struct malo_softc *, struct malo_txq *, int);
132static void malo_tx_cleanupq(struct malo_softc *, struct malo_txq *);
108#define DPRINTF(sc, m, fmt, ...) do { \
109 if (sc->malo_debug & (m)) \
110 printf(fmt, __VA_ARGS__); \
111} while (0)
112#else
113#define DPRINTF(sc, m, fmt, ...) do { \
114 (void) sc; \
115} while (0)

--- 5 unchanged lines hidden (view full) ---

121 const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
122 const uint8_t [IEEE80211_ADDR_LEN],
123 const uint8_t [IEEE80211_ADDR_LEN]);
124static void malo_vap_delete(struct ieee80211vap *);
125static int malo_dma_setup(struct malo_softc *);
126static int malo_setup_hwdma(struct malo_softc *);
127static void malo_txq_init(struct malo_softc *, struct malo_txq *, int);
128static void malo_tx_cleanupq(struct malo_softc *, struct malo_txq *);
133static void malo_start(struct ifnet *);
129static void malo_parent(struct ieee80211com *);
130static int malo_transmit(struct ieee80211com *, struct mbuf *);
131static void malo_start(struct malo_softc *);
134static void malo_watchdog(void *);
132static void malo_watchdog(void *);
135static int malo_ioctl(struct ifnet *, u_long, caddr_t);
136static void malo_updateslot(struct ieee80211com *);
137static int malo_newstate(struct ieee80211vap *, enum ieee80211_state, int);
138static void malo_scan_start(struct ieee80211com *);
139static void malo_scan_end(struct ieee80211com *);
140static void malo_set_channel(struct ieee80211com *);
141static int malo_raw_xmit(struct ieee80211_node *, struct mbuf *,
142 const struct ieee80211_bpf_params *);
143static void malo_sysctlattach(struct malo_softc *);
144static void malo_announce(struct malo_softc *);
145static void malo_dma_cleanup(struct malo_softc *);
133static void malo_updateslot(struct ieee80211com *);
134static int malo_newstate(struct ieee80211vap *, enum ieee80211_state, int);
135static void malo_scan_start(struct ieee80211com *);
136static void malo_scan_end(struct ieee80211com *);
137static void malo_set_channel(struct ieee80211com *);
138static int malo_raw_xmit(struct ieee80211_node *, struct mbuf *,
139 const struct ieee80211_bpf_params *);
140static void malo_sysctlattach(struct malo_softc *);
141static void malo_announce(struct malo_softc *);
142static void malo_dma_cleanup(struct malo_softc *);
146static void malo_stop_locked(struct ifnet *, int);
143static void malo_stop(struct malo_softc *);
147static int malo_chan_set(struct malo_softc *, struct ieee80211_channel *);
148static int malo_mode_init(struct malo_softc *);
149static void malo_tx_proc(void *, int);
150static void malo_rx_proc(void *, int);
151static void malo_init(void *);
152
153/*
154 * Read/Write shorthands for accesses to BAR 0. Note that all BAR 1

--- 13 unchanged lines hidden (view full) ---

168 __func__, (uintmax_t)off, val);
169
170 bus_space_write_4(sc->malo_io0t, sc->malo_io0h, off, val);
171}
172
173int
174malo_attach(uint16_t devid, struct malo_softc *sc)
175{
144static int malo_chan_set(struct malo_softc *, struct ieee80211_channel *);
145static int malo_mode_init(struct malo_softc *);
146static void malo_tx_proc(void *, int);
147static void malo_rx_proc(void *, int);
148static void malo_init(void *);
149
150/*
151 * Read/Write shorthands for accesses to BAR 0. Note that all BAR 1

--- 13 unchanged lines hidden (view full) ---

165 __func__, (uintmax_t)off, val);
166
167 bus_space_write_4(sc->malo_io0t, sc->malo_io0h, off, val);
168}
169
170int
171malo_attach(uint16_t devid, struct malo_softc *sc)
172{
176 int error;
177 struct ieee80211com *ic;
178 struct ifnet *ifp;
173 struct ieee80211com *ic = &sc->malo_ic;
179 struct malo_hal *mh;
174 struct malo_hal *mh;
175 int error;
180 uint8_t bands;
181
176 uint8_t bands;
177
182 ifp = sc->malo_ifp = if_alloc(IFT_IEEE80211);
183 if (ifp == NULL) {
184 device_printf(sc->malo_dev, "can not if_alloc()\n");
185 return ENOSPC;
186 }
187 ic = ifp->if_l2com;
188
189 MALO_LOCK_INIT(sc);
190 callout_init_mtx(&sc->malo_watchdog_timer, &sc->malo_mtx, 0);
178 MALO_LOCK_INIT(sc);
179 callout_init_mtx(&sc->malo_watchdog_timer, &sc->malo_mtx, 0);
180 mbufq_init(&sc->malo_snd, ifqmaxlen);
191
181
192 /* set these up early for if_printf use */
193 if_initname(ifp, device_get_name(sc->malo_dev),
194 device_get_unit(sc->malo_dev));
195
196 mh = malo_hal_attach(sc->malo_dev, devid,
197 sc->malo_io1h, sc->malo_io1t, sc->malo_dmat);
198 if (mh == NULL) {
182 mh = malo_hal_attach(sc->malo_dev, devid,
183 sc->malo_io1h, sc->malo_io1t, sc->malo_dmat);
184 if (mh == NULL) {
199 if_printf(ifp, "unable to attach HAL\n");
185 device_printf(sc->malo_dev, "unable to attach HAL\n");
200 error = EIO;
201 goto bad;
202 }
203 sc->malo_mh = mh;
204
205 /*
206 * Load firmware so we can get setup. We arbitrarily pick station
207 * firmware; we'll re-load firmware as needed so setting up
208 * the wrong mode isn't a big deal.
209 */
210 error = malo_hal_fwload(mh, "malo8335-h", "malo8335-m");
211 if (error != 0) {
186 error = EIO;
187 goto bad;
188 }
189 sc->malo_mh = mh;
190
191 /*
192 * Load firmware so we can get setup. We arbitrarily pick station
193 * firmware; we'll re-load firmware as needed so setting up
194 * the wrong mode isn't a big deal.
195 */
196 error = malo_hal_fwload(mh, "malo8335-h", "malo8335-m");
197 if (error != 0) {
212 if_printf(ifp, "unable to setup firmware\n");
198 device_printf(sc->malo_dev, "unable to setup firmware\n");
213 goto bad1;
214 }
215 /* XXX gethwspecs() extracts correct informations? not maybe! */
216 error = malo_hal_gethwspecs(mh, &sc->malo_hwspecs);
217 if (error != 0) {
199 goto bad1;
200 }
201 /* XXX gethwspecs() extracts correct informations? not maybe! */
202 error = malo_hal_gethwspecs(mh, &sc->malo_hwspecs);
203 if (error != 0) {
218 if_printf(ifp, "unable to fetch h/w specs\n");
204 device_printf(sc->malo_dev, "unable to fetch h/w specs\n");
219 goto bad1;
220 }
221
222 DPRINTF(sc, MALO_DEBUG_FW,
223 "malo_hal_gethwspecs: hwversion 0x%x hostif 0x%x"
224 "maxnum_wcb 0x%x maxnum_mcaddr 0x%x maxnum_tx_wcb 0x%x"
225 "regioncode 0x%x num_antenna 0x%x fw_releasenum 0x%x"
226 "wcbbase0 0x%x rxdesc_read 0x%x rxdesc_write 0x%x"

--- 19 unchanged lines hidden (view full) ---

246
247 /*
248 * Allocate tx + rx descriptors and populate the lists.
249 * We immediately push the information to the firmware
250 * as otherwise it gets upset.
251 */
252 error = malo_dma_setup(sc);
253 if (error != 0) {
205 goto bad1;
206 }
207
208 DPRINTF(sc, MALO_DEBUG_FW,
209 "malo_hal_gethwspecs: hwversion 0x%x hostif 0x%x"
210 "maxnum_wcb 0x%x maxnum_mcaddr 0x%x maxnum_tx_wcb 0x%x"
211 "regioncode 0x%x num_antenna 0x%x fw_releasenum 0x%x"
212 "wcbbase0 0x%x rxdesc_read 0x%x rxdesc_write 0x%x"

--- 19 unchanged lines hidden (view full) ---

232
233 /*
234 * Allocate tx + rx descriptors and populate the lists.
235 * We immediately push the information to the firmware
236 * as otherwise it gets upset.
237 */
238 error = malo_dma_setup(sc);
239 if (error != 0) {
254 if_printf(ifp, "failed to setup descriptors: %d\n", error);
240 device_printf(sc->malo_dev,
241 "failed to setup descriptors: %d\n", error);
255 goto bad1;
256 }
257 error = malo_setup_hwdma(sc); /* push to firmware */
258 if (error != 0) /* NB: malo_setupdma prints msg */
259 goto bad2;
260
261 sc->malo_tq = taskqueue_create_fast("malo_taskq", M_NOWAIT,
262 taskqueue_thread_enqueue, &sc->malo_tq);
263 taskqueue_start_threads(&sc->malo_tq, 1, PI_NET,
242 goto bad1;
243 }
244 error = malo_setup_hwdma(sc); /* push to firmware */
245 if (error != 0) /* NB: malo_setupdma prints msg */
246 goto bad2;
247
248 sc->malo_tq = taskqueue_create_fast("malo_taskq", M_NOWAIT,
249 taskqueue_thread_enqueue, &sc->malo_tq);
250 taskqueue_start_threads(&sc->malo_tq, 1, PI_NET,
264 "%s taskq", ifp->if_xname);
251 "%s taskq", device_get_nameunit(sc->malo_dev));
265
266 TASK_INIT(&sc->malo_rxtask, 0, malo_rx_proc, sc);
267 TASK_INIT(&sc->malo_txtask, 0, malo_tx_proc, sc);
268
252
253 TASK_INIT(&sc->malo_rxtask, 0, malo_rx_proc, sc);
254 TASK_INIT(&sc->malo_txtask, 0, malo_tx_proc, sc);
255
269 ifp->if_softc = sc;
270 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
271 ifp->if_start = malo_start;
272 ifp->if_ioctl = malo_ioctl;
273 ifp->if_init = malo_init;
274 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
275 ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
276 IFQ_SET_READY(&ifp->if_snd);
277
278 ic->ic_ifp = ifp;
279 ic->ic_softc = sc;
280 ic->ic_name = device_get_nameunit(sc->malo_dev);
281 /* XXX not right but it's not used anywhere important */
282 ic->ic_phytype = IEEE80211_T_OFDM;
283 ic->ic_opmode = IEEE80211_M_STA;
284 ic->ic_caps =
285 IEEE80211_C_STA /* station mode supported */
286 | IEEE80211_C_BGSCAN /* capable of bg scanning */
287 | IEEE80211_C_MONITOR /* monitor mode */
288 | IEEE80211_C_SHPREAMBLE /* short preamble supported */
289 | IEEE80211_C_SHSLOT /* short slot time supported */
290 | IEEE80211_C_TXPMGT /* capable of txpow mgt */
291 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */
292 ;
256 ic->ic_softc = sc;
257 ic->ic_name = device_get_nameunit(sc->malo_dev);
258 /* XXX not right but it's not used anywhere important */
259 ic->ic_phytype = IEEE80211_T_OFDM;
260 ic->ic_opmode = IEEE80211_M_STA;
261 ic->ic_caps =
262 IEEE80211_C_STA /* station mode supported */
263 | IEEE80211_C_BGSCAN /* capable of bg scanning */
264 | IEEE80211_C_MONITOR /* monitor mode */
265 | IEEE80211_C_SHPREAMBLE /* short preamble supported */
266 | IEEE80211_C_SHSLOT /* short slot time supported */
267 | IEEE80211_C_TXPMGT /* capable of txpow mgt */
268 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */
269 ;
270 IEEE80211_ADDR_COPY(ic->ic_macaddr, sc->malo_hwspecs.macaddr);
293
294 /*
295 * Transmit requires space in the packet for a special format transmit
296 * record and optional padding between this record and the payload.
297 * Ask the net80211 layer to arrange this when encapsulating
298 * packets so we can add it efficiently.
299 */
300 ic->ic_headroom = sizeof(struct malo_txrec) -
301 sizeof(struct ieee80211_frame);
302
303 /* call MI attach routine. */
271
272 /*
273 * Transmit requires space in the packet for a special format transmit
274 * record and optional padding between this record and the payload.
275 * Ask the net80211 layer to arrange this when encapsulating
276 * packets so we can add it efficiently.
277 */
278 ic->ic_headroom = sizeof(struct malo_txrec) -
279 sizeof(struct ieee80211_frame);
280
281 /* call MI attach routine. */
304 ieee80211_ifattach(ic, sc->malo_hwspecs.macaddr);
282 ieee80211_ifattach(ic);
305 /* override default methods */
306 ic->ic_vap_create = malo_vap_create;
307 ic->ic_vap_delete = malo_vap_delete;
308 ic->ic_raw_xmit = malo_raw_xmit;
309 ic->ic_updateslot = malo_updateslot;
283 /* override default methods */
284 ic->ic_vap_create = malo_vap_create;
285 ic->ic_vap_delete = malo_vap_delete;
286 ic->ic_raw_xmit = malo_raw_xmit;
287 ic->ic_updateslot = malo_updateslot;
310
311 ic->ic_scan_start = malo_scan_start;
312 ic->ic_scan_end = malo_scan_end;
313 ic->ic_set_channel = malo_set_channel;
288 ic->ic_scan_start = malo_scan_start;
289 ic->ic_scan_end = malo_scan_end;
290 ic->ic_set_channel = malo_set_channel;
291 ic->ic_parent = malo_parent;
292 ic->ic_transmit = malo_transmit;
314
315 sc->malo_invalid = 0; /* ready to go, enable int handling */
316
317 ieee80211_radiotap_attach(ic,
318 &sc->malo_tx_th.wt_ihdr, sizeof(sc->malo_tx_th),
319 MALO_TX_RADIOTAP_PRESENT,
320 &sc->malo_rx_th.wr_ihdr, sizeof(sc->malo_rx_th),
321 MALO_RX_RADIOTAP_PRESENT);

--- 8 unchanged lines hidden (view full) ---

330 malo_announce(sc);
331
332 return 0;
333bad2:
334 malo_dma_cleanup(sc);
335bad1:
336 malo_hal_detach(mh);
337bad:
293
294 sc->malo_invalid = 0; /* ready to go, enable int handling */
295
296 ieee80211_radiotap_attach(ic,
297 &sc->malo_tx_th.wt_ihdr, sizeof(sc->malo_tx_th),
298 MALO_TX_RADIOTAP_PRESENT,
299 &sc->malo_rx_th.wr_ihdr, sizeof(sc->malo_rx_th),
300 MALO_RX_RADIOTAP_PRESENT);

--- 8 unchanged lines hidden (view full) ---

309 malo_announce(sc);
310
311 return 0;
312bad2:
313 malo_dma_cleanup(sc);
314bad1:
315 malo_hal_detach(mh);
316bad:
338 if_free(ifp);
339 sc->malo_invalid = 1;
340
341 return error;
342}
343
344static struct ieee80211vap *
345malo_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
346 enum ieee80211_opmode opmode, int flags,
347 const uint8_t bssid[IEEE80211_ADDR_LEN],
348 const uint8_t mac[IEEE80211_ADDR_LEN])
349{
317 sc->malo_invalid = 1;
318
319 return error;
320}
321
322static struct ieee80211vap *
323malo_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
324 enum ieee80211_opmode opmode, int flags,
325 const uint8_t bssid[IEEE80211_ADDR_LEN],
326 const uint8_t mac[IEEE80211_ADDR_LEN])
327{
350 struct ifnet *ifp = ic->ic_ifp;
328 struct malo_softc *sc = ic->ic_softc;
351 struct malo_vap *mvp;
352 struct ieee80211vap *vap;
353
354 if (!TAILQ_EMPTY(&ic->ic_vaps)) {
329 struct malo_vap *mvp;
330 struct ieee80211vap *vap;
331
332 if (!TAILQ_EMPTY(&ic->ic_vaps)) {
355 if_printf(ifp, "multiple vaps not supported\n");
333 device_printf(sc->malo_dev, "multiple vaps not supported\n");
356 return NULL;
357 }
358 switch (opmode) {
359 case IEEE80211_M_STA:
360 if (opmode == IEEE80211_M_STA)
361 flags |= IEEE80211_CLONE_NOBEACONS;
362 /* fall thru... */
363 case IEEE80211_M_MONITOR:
364 break;
365 default:
334 return NULL;
335 }
336 switch (opmode) {
337 case IEEE80211_M_STA:
338 if (opmode == IEEE80211_M_STA)
339 flags |= IEEE80211_CLONE_NOBEACONS;
340 /* fall thru... */
341 case IEEE80211_M_MONITOR:
342 break;
343 default:
366 if_printf(ifp, "%s mode not supported\n",
344 device_printf(sc->malo_dev, "%s mode not supported\n",
367 ieee80211_opmode_name[opmode]);
368 return NULL; /* unsupported */
369 }
345 ieee80211_opmode_name[opmode]);
346 return NULL; /* unsupported */
347 }
370 mvp = (struct malo_vap *) malloc(sizeof(struct malo_vap),
371 M_80211_VAP, M_NOWAIT | M_ZERO);
372 if (mvp == NULL) {
373 if_printf(ifp, "cannot allocate vap state block\n");
374 return NULL;
375 }
348 mvp = malloc(sizeof(struct malo_vap), M_80211_VAP, M_WAITOK | M_ZERO);
376 vap = &mvp->malo_vap;
349 vap = &mvp->malo_vap;
377 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
350 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
378
379 /* override state transition machine */
380 mvp->malo_newstate = vap->iv_newstate;
381 vap->iv_newstate = malo_newstate;
382
383 /* complete setup */
384 ieee80211_vap_attach(vap,
351
352 /* override state transition machine */
353 mvp->malo_newstate = vap->iv_newstate;
354 vap->iv_newstate = malo_newstate;
355
356 /* complete setup */
357 ieee80211_vap_attach(vap,
385 ieee80211_media_change, ieee80211_media_status);
358 ieee80211_media_change, ieee80211_media_status, mac);
386 ic->ic_opmode = opmode;
387 return vap;
388}
389
390static void
391malo_vap_delete(struct ieee80211vap *vap)
392{
393 struct malo_vap *mvp = MALO_VAP(vap);

--- 62 unchanged lines hidden (view full) ---

456}
457
458static int
459malo_desc_setup(struct malo_softc *sc, const char *name,
460 struct malo_descdma *dd,
461 int nbuf, size_t bufsize, int ndesc, size_t descsize)
462{
463 int error;
359 ic->ic_opmode = opmode;
360 return vap;
361}
362
363static void
364malo_vap_delete(struct ieee80211vap *vap)
365{
366 struct malo_vap *mvp = MALO_VAP(vap);

--- 62 unchanged lines hidden (view full) ---

429}
430
431static int
432malo_desc_setup(struct malo_softc *sc, const char *name,
433 struct malo_descdma *dd,
434 int nbuf, size_t bufsize, int ndesc, size_t descsize)
435{
436 int error;
464 struct ifnet *ifp = sc->malo_ifp;
465 uint8_t *ds;
466
467 DPRINTF(sc, MALO_DEBUG_RESET,
468 "%s: %s DMA: %u bufs (%ju) %u desc/buf (%ju)\n",
469 __func__, name, nbuf, (uintmax_t) bufsize,
470 ndesc, (uintmax_t) descsize);
471
472 dd->dd_name = name;

--- 10 unchanged lines hidden (view full) ---

483 dd->dd_desc_len, /* maxsize */
484 1, /* nsegments */
485 dd->dd_desc_len, /* maxsegsize */
486 BUS_DMA_ALLOCNOW, /* flags */
487 NULL, /* lockfunc */
488 NULL, /* lockarg */
489 &dd->dd_dmat);
490 if (error != 0) {
437 uint8_t *ds;
438
439 DPRINTF(sc, MALO_DEBUG_RESET,
440 "%s: %s DMA: %u bufs (%ju) %u desc/buf (%ju)\n",
441 __func__, name, nbuf, (uintmax_t) bufsize,
442 ndesc, (uintmax_t) descsize);
443
444 dd->dd_name = name;

--- 10 unchanged lines hidden (view full) ---

455 dd->dd_desc_len, /* maxsize */
456 1, /* nsegments */
457 dd->dd_desc_len, /* maxsegsize */
458 BUS_DMA_ALLOCNOW, /* flags */
459 NULL, /* lockfunc */
460 NULL, /* lockarg */
461 &dd->dd_dmat);
462 if (error != 0) {
491 if_printf(ifp, "cannot allocate %s DMA tag\n", dd->dd_name);
463 device_printf(sc->malo_dev, "cannot allocate %s DMA tag\n",
464 dd->dd_name);
492 return error;
493 }
494
495 /* allocate descriptors */
496 error = bus_dmamem_alloc(dd->dd_dmat, (void**) &dd->dd_desc,
497 BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &dd->dd_dmamap);
498 if (error != 0) {
465 return error;
466 }
467
468 /* allocate descriptors */
469 error = bus_dmamem_alloc(dd->dd_dmat, (void**) &dd->dd_desc,
470 BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &dd->dd_dmamap);
471 if (error != 0) {
499 if_printf(ifp, "unable to alloc memory for %u %s descriptors, "
472 device_printf(sc->malo_dev,
473 "unable to alloc memory for %u %s descriptors, "
500 "error %u\n", nbuf * ndesc, dd->dd_name, error);
501 goto fail1;
502 }
503
504 error = bus_dmamap_load(dd->dd_dmat, dd->dd_dmamap,
505 dd->dd_desc, dd->dd_desc_len,
506 malo_load_cb, &dd->dd_desc_paddr, BUS_DMA_NOWAIT);
507 if (error != 0) {
474 "error %u\n", nbuf * ndesc, dd->dd_name, error);
475 goto fail1;
476 }
477
478 error = bus_dmamap_load(dd->dd_dmat, dd->dd_dmamap,
479 dd->dd_desc, dd->dd_desc_len,
480 malo_load_cb, &dd->dd_desc_paddr, BUS_DMA_NOWAIT);
481 if (error != 0) {
508 if_printf(ifp, "unable to map %s descriptors, error %u\n",
482 device_printf(sc->malo_dev,
483 "unable to map %s descriptors, error %u\n",
509 dd->dd_name, error);
510 goto fail2;
511 }
512
513 ds = dd->dd_desc;
514 memset(ds, 0, dd->dd_desc_len);
515 DPRINTF(sc, MALO_DEBUG_RESET,
516 "%s: %s DMA map: %p (%lu) -> 0x%jx (%lu)\n",

--- 10 unchanged lines hidden (view full) ---

527}
528
529#define DS2PHYS(_dd, _ds) \
530 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
531
532static int
533malo_rxdma_setup(struct malo_softc *sc)
534{
484 dd->dd_name, error);
485 goto fail2;
486 }
487
488 ds = dd->dd_desc;
489 memset(ds, 0, dd->dd_desc_len);
490 DPRINTF(sc, MALO_DEBUG_RESET,
491 "%s: %s DMA map: %p (%lu) -> 0x%jx (%lu)\n",

--- 10 unchanged lines hidden (view full) ---

502}
503
504#define DS2PHYS(_dd, _ds) \
505 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
506
507static int
508malo_rxdma_setup(struct malo_softc *sc)
509{
535 struct ifnet *ifp = sc->malo_ifp;
536 int error, bsize, i;
537 struct malo_rxbuf *bf;
538 struct malo_rxdesc *ds;
539
540 error = malo_desc_setup(sc, "rx", &sc->malo_rxdma,
541 malo_rxbuf, sizeof(struct malo_rxbuf),
542 1, sizeof(struct malo_rxdesc));
543 if (error != 0)
544 return error;
545
546 /*
547 * Allocate rx buffers and set them up.
548 */
549 bsize = malo_rxbuf * sizeof(struct malo_rxbuf);
550 bf = malloc(bsize, M_MALODEV, M_NOWAIT | M_ZERO);
551 if (bf == NULL) {
510 int error, bsize, i;
511 struct malo_rxbuf *bf;
512 struct malo_rxdesc *ds;
513
514 error = malo_desc_setup(sc, "rx", &sc->malo_rxdma,
515 malo_rxbuf, sizeof(struct malo_rxbuf),
516 1, sizeof(struct malo_rxdesc));
517 if (error != 0)
518 return error;
519
520 /*
521 * Allocate rx buffers and set them up.
522 */
523 bsize = malo_rxbuf * sizeof(struct malo_rxbuf);
524 bf = malloc(bsize, M_MALODEV, M_NOWAIT | M_ZERO);
525 if (bf == NULL) {
552 if_printf(ifp, "malloc of %u rx buffers failed\n", bsize);
526 device_printf(sc->malo_dev,
527 "malloc of %u rx buffers failed\n", bsize);
553 return error;
554 }
555 sc->malo_rxdma.dd_bufptr = bf;
556
557 STAILQ_INIT(&sc->malo_rxbuf);
558 ds = sc->malo_rxdma.dd_desc;
559 for (i = 0; i < malo_rxbuf; i++, bf++, ds++) {
560 bf->bf_desc = ds;
561 bf->bf_daddr = DS2PHYS(&sc->malo_rxdma, ds);
562 error = bus_dmamap_create(sc->malo_dmat, BUS_DMA_NOWAIT,
563 &bf->bf_dmamap);
564 if (error != 0) {
528 return error;
529 }
530 sc->malo_rxdma.dd_bufptr = bf;
531
532 STAILQ_INIT(&sc->malo_rxbuf);
533 ds = sc->malo_rxdma.dd_desc;
534 for (i = 0; i < malo_rxbuf; i++, bf++, ds++) {
535 bf->bf_desc = ds;
536 bf->bf_daddr = DS2PHYS(&sc->malo_rxdma, ds);
537 error = bus_dmamap_create(sc->malo_dmat, BUS_DMA_NOWAIT,
538 &bf->bf_dmamap);
539 if (error != 0) {
565 if_printf(ifp, "%s: unable to dmamap for rx buffer, "
566 "error %d\n", __func__, error);
540 device_printf(sc->malo_dev,
541 "%s: unable to dmamap for rx buffer, error %d\n",
542 __func__, error);
567 return error;
568 }
569 /* NB: tail is intentional to preserve descriptor order */
570 STAILQ_INSERT_TAIL(&sc->malo_rxbuf, bf, bf_list);
571 }
572 return 0;
573}
574
575static int
576malo_txdma_setup(struct malo_softc *sc, struct malo_txq *txq)
577{
543 return error;
544 }
545 /* NB: tail is intentional to preserve descriptor order */
546 STAILQ_INSERT_TAIL(&sc->malo_rxbuf, bf, bf_list);
547 }
548 return 0;
549}
550
551static int
552malo_txdma_setup(struct malo_softc *sc, struct malo_txq *txq)
553{
578 struct ifnet *ifp = sc->malo_ifp;
579 int error, bsize, i;
580 struct malo_txbuf *bf;
581 struct malo_txdesc *ds;
582
583 error = malo_desc_setup(sc, "tx", &txq->dma,
584 malo_txbuf, sizeof(struct malo_txbuf),
585 MALO_TXDESC, sizeof(struct malo_txdesc));
586 if (error != 0)
587 return error;
588
589 /* allocate and setup tx buffers */
590 bsize = malo_txbuf * sizeof(struct malo_txbuf);
591 bf = malloc(bsize, M_MALODEV, M_NOWAIT | M_ZERO);
592 if (bf == NULL) {
554 int error, bsize, i;
555 struct malo_txbuf *bf;
556 struct malo_txdesc *ds;
557
558 error = malo_desc_setup(sc, "tx", &txq->dma,
559 malo_txbuf, sizeof(struct malo_txbuf),
560 MALO_TXDESC, sizeof(struct malo_txdesc));
561 if (error != 0)
562 return error;
563
564 /* allocate and setup tx buffers */
565 bsize = malo_txbuf * sizeof(struct malo_txbuf);
566 bf = malloc(bsize, M_MALODEV, M_NOWAIT | M_ZERO);
567 if (bf == NULL) {
593 if_printf(ifp, "malloc of %u tx buffers failed\n",
568 device_printf(sc->malo_dev, "malloc of %u tx buffers failed\n",
594 malo_txbuf);
595 return ENOMEM;
596 }
597 txq->dma.dd_bufptr = bf;
598
599 STAILQ_INIT(&txq->free);
600 txq->nfree = 0;
601 ds = txq->dma.dd_desc;
602 for (i = 0; i < malo_txbuf; i++, bf++, ds += MALO_TXDESC) {
603 bf->bf_desc = ds;
604 bf->bf_daddr = DS2PHYS(&txq->dma, ds);
605 error = bus_dmamap_create(sc->malo_dmat, BUS_DMA_NOWAIT,
606 &bf->bf_dmamap);
607 if (error != 0) {
569 malo_txbuf);
570 return ENOMEM;
571 }
572 txq->dma.dd_bufptr = bf;
573
574 STAILQ_INIT(&txq->free);
575 txq->nfree = 0;
576 ds = txq->dma.dd_desc;
577 for (i = 0; i < malo_txbuf; i++, bf++, ds += MALO_TXDESC) {
578 bf->bf_desc = ds;
579 bf->bf_daddr = DS2PHYS(&txq->dma, ds);
580 error = bus_dmamap_create(sc->malo_dmat, BUS_DMA_NOWAIT,
581 &bf->bf_dmamap);
582 if (error != 0) {
608 if_printf(ifp, "unable to create dmamap for tx "
583 device_printf(sc->malo_dev,
584 "unable to create dmamap for tx "
609 "buffer %u, error %u\n", i, error);
610 return error;
611 }
612 STAILQ_INSERT_TAIL(&txq->free, bf, bf_list);
613 txq->nfree++;
614 }
615
616 return 0;

--- 382 unchanged lines hidden (view full) ---

999 } else {
1000 if (status & MALO_TXD_STATUS_FAILED_LINK_ERROR)
1001 sc->malo_stats.mst_tx_linkerror++;
1002 if (status & MALO_TXD_STATUS_FAILED_XRETRY)
1003 sc->malo_stats.mst_tx_xretries++;
1004 if (status & MALO_TXD_STATUS_FAILED_AGING)
1005 sc->malo_stats.mst_tx_aging++;
1006 }
585 "buffer %u, error %u\n", i, error);
586 return error;
587 }
588 STAILQ_INSERT_TAIL(&txq->free, bf, bf_list);
589 txq->nfree++;
590 }
591
592 return 0;

--- 382 unchanged lines hidden (view full) ---

975 } else {
976 if (status & MALO_TXD_STATUS_FAILED_LINK_ERROR)
977 sc->malo_stats.mst_tx_linkerror++;
978 if (status & MALO_TXD_STATUS_FAILED_XRETRY)
979 sc->malo_stats.mst_tx_xretries++;
980 if (status & MALO_TXD_STATUS_FAILED_AGING)
981 sc->malo_stats.mst_tx_aging++;
982 }
1007 /*
1008 * Do any tx complete callback. Note this must
1009 * be done before releasing the node reference.
1010 * XXX no way to figure out if frame was ACK'd
1011 */
1012 if (bf->bf_m->m_flags & M_TXCB) {
1013 /* XXX strip fw len in case header inspected */
1014 m_adj(bf->bf_m, sizeof(uint16_t));
1015 ieee80211_process_callback(ni, bf->bf_m,
1016 (status & MALO_TXD_STATUS_OK) == 0);
1017 }
1018 /*
1019 * Reclaim reference to node.
1020 *
1021 * NB: the node may be reclaimed here if, for example
1022 * this is a DEAUTH message that was sent and the
1023 * node was timed out due to inactivity.
1024 */
1025 ieee80211_free_node(ni);
1026 }
983 /* XXX strip fw len in case header inspected */
984 m_adj(bf->bf_m, sizeof(uint16_t));
985 ieee80211_tx_complete(ni, bf->bf_m,
986 (status & MALO_TXD_STATUS_OK) == 0);
987 } else
988 m_freem(bf->bf_m);
989
1027 ds->status = htole32(MALO_TXD_STATUS_IDLE);
1028 ds->pktlen = htole32(0);
1029
1030 bus_dmamap_sync(sc->malo_dmat, bf->bf_dmamap,
1031 BUS_DMASYNC_POSTWRITE);
1032 bus_dmamap_unload(sc->malo_dmat, bf->bf_dmamap);
990 ds->status = htole32(MALO_TXD_STATUS_IDLE);
991 ds->pktlen = htole32(0);
992
993 bus_dmamap_sync(sc->malo_dmat, bf->bf_dmamap,
994 BUS_DMASYNC_POSTWRITE);
995 bus_dmamap_unload(sc->malo_dmat, bf->bf_dmamap);
1033 m_freem(bf->bf_m);
1034 bf->bf_m = NULL;
1035 bf->bf_node = NULL;
1036
1037 MALO_TXQ_LOCK(txq);
1038 STAILQ_INSERT_TAIL(&txq->free, bf, bf_list);
1039 txq->nfree++;
1040 MALO_TXQ_UNLOCK(txq);
1041 }
1042 return nreaped;
1043}
1044
1045/*
1046 * Deferred processing of transmit interrupt.
1047 */
1048static void
1049malo_tx_proc(void *arg, int npending)
1050{
1051 struct malo_softc *sc = arg;
996 bf->bf_m = NULL;
997 bf->bf_node = NULL;
998
999 MALO_TXQ_LOCK(txq);
1000 STAILQ_INSERT_TAIL(&txq->free, bf, bf_list);
1001 txq->nfree++;
1002 MALO_TXQ_UNLOCK(txq);
1003 }
1004 return nreaped;
1005}
1006
1007/*
1008 * Deferred processing of transmit interrupt.
1009 */
1010static void
1011malo_tx_proc(void *arg, int npending)
1012{
1013 struct malo_softc *sc = arg;
1052 struct ifnet *ifp = sc->malo_ifp;
1053 int i, nreaped;
1054
1055 /*
1056 * Process each active queue.
1057 */
1058 nreaped = 0;
1014 int i, nreaped;
1015
1016 /*
1017 * Process each active queue.
1018 */
1019 nreaped = 0;
1020 MALO_LOCK(sc);
1059 for (i = 0; i < MALO_NUM_TX_QUEUES; i++) {
1060 if (!STAILQ_EMPTY(&sc->malo_txq[i].active))
1061 nreaped += malo_tx_processq(sc, &sc->malo_txq[i]);
1062 }
1063
1064 if (nreaped != 0) {
1021 for (i = 0; i < MALO_NUM_TX_QUEUES; i++) {
1022 if (!STAILQ_EMPTY(&sc->malo_txq[i].active))
1023 nreaped += malo_tx_processq(sc, &sc->malo_txq[i]);
1024 }
1025
1026 if (nreaped != 0) {
1065 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1066 sc->malo_timer = 0;
1027 sc->malo_timer = 0;
1067 malo_start(ifp);
1028 malo_start(sc);
1068 }
1029 }
1030 MALO_UNLOCK(sc);
1069}
1070
1071static int
1072malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni,
1073 struct malo_txbuf *bf, struct mbuf *m0)
1074{
1075#define IEEE80211_DIR_DSTODS(wh) \
1076 ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
1077#define IS_DATA_FRAME(wh) \
1078 ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK)) == IEEE80211_FC0_TYPE_DATA)
1079 int error, ismcast, iswep;
1080 int copyhdrlen, hdrlen, pktlen;
1081 struct ieee80211_frame *wh;
1031}
1032
1033static int
1034malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni,
1035 struct malo_txbuf *bf, struct mbuf *m0)
1036{
1037#define IEEE80211_DIR_DSTODS(wh) \
1038 ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
1039#define IS_DATA_FRAME(wh) \
1040 ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK)) == IEEE80211_FC0_TYPE_DATA)
1041 int error, ismcast, iswep;
1042 int copyhdrlen, hdrlen, pktlen;
1043 struct ieee80211_frame *wh;
1082 struct ifnet *ifp = sc->malo_ifp;
1083 struct ieee80211com *ic = ifp->if_l2com;
1044 struct ieee80211com *ic = &sc->malo_ic;
1084 struct ieee80211vap *vap = ni->ni_vap;
1085 struct malo_txdesc *ds;
1086 struct malo_txrec *tr;
1087 struct malo_txq *txq;
1088 uint16_t qos;
1089
1090 wh = mtod(m0, struct ieee80211_frame *);
1091 iswep = wh->i_fc[1] & IEEE80211_FC1_PROTECTED;

--- 128 unchanged lines hidden (view full) ---

1220 /* fall thru... */
1221 case IEEE80211_FC0_TYPE_CTL:
1222 ds->txpriority = 1;
1223 break;
1224 case IEEE80211_FC0_TYPE_DATA:
1225 ds->txpriority = txq->qnum;
1226 break;
1227 default:
1045 struct ieee80211vap *vap = ni->ni_vap;
1046 struct malo_txdesc *ds;
1047 struct malo_txrec *tr;
1048 struct malo_txq *txq;
1049 uint16_t qos;
1050
1051 wh = mtod(m0, struct ieee80211_frame *);
1052 iswep = wh->i_fc[1] & IEEE80211_FC1_PROTECTED;

--- 128 unchanged lines hidden (view full) ---

1181 /* fall thru... */
1182 case IEEE80211_FC0_TYPE_CTL:
1183 ds->txpriority = 1;
1184 break;
1185 case IEEE80211_FC0_TYPE_DATA:
1186 ds->txpriority = txq->qnum;
1187 break;
1188 default:
1228 if_printf(ifp, "bogus frame type 0x%x (%s)\n",
1189 device_printf(sc->malo_dev, "bogus frame type 0x%x (%s)\n",
1229 wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__);
1230 /* XXX statistic */
1231 m_freem(m0);
1232 return EIO;
1233 }
1234
1235#ifdef MALO_DEBUG
1236 if (IFF_DUMPPKTS_XMIT(sc))

--- 4 unchanged lines hidden (view full) ---

1241
1242 MALO_TXQ_LOCK(txq);
1243 if (!IS_DATA_FRAME(wh))
1244 ds->status |= htole32(1);
1245 ds->status |= htole32(MALO_TXD_STATUS_FW_OWNED);
1246 STAILQ_INSERT_TAIL(&txq->active, bf, bf_list);
1247 MALO_TXDESC_SYNC(txq, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1248
1190 wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__);
1191 /* XXX statistic */
1192 m_freem(m0);
1193 return EIO;
1194 }
1195
1196#ifdef MALO_DEBUG
1197 if (IFF_DUMPPKTS_XMIT(sc))

--- 4 unchanged lines hidden (view full) ---

1202
1203 MALO_TXQ_LOCK(txq);
1204 if (!IS_DATA_FRAME(wh))
1205 ds->status |= htole32(1);
1206 ds->status |= htole32(MALO_TXD_STATUS_FW_OWNED);
1207 STAILQ_INSERT_TAIL(&txq->active, bf, bf_list);
1208 MALO_TXDESC_SYNC(txq, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1209
1249 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
1250 sc->malo_timer = 5;
1251 MALO_TXQ_UNLOCK(txq);
1252 return 0;
1253#undef IEEE80211_DIR_DSTODS
1254}
1255
1210 sc->malo_timer = 5;
1211 MALO_TXQ_UNLOCK(txq);
1212 return 0;
1213#undef IEEE80211_DIR_DSTODS
1214}
1215
1216static int
1217malo_transmit(struct ieee80211com *ic, struct mbuf *m)
1218{
1219 struct malo_softc *sc = ic->ic_softc;
1220 int error;
1221
1222 MALO_LOCK(sc);
1223 if (!sc->malo_running) {
1224 MALO_UNLOCK(sc);
1225 return (ENXIO);
1226 }
1227 error = mbufq_enqueue(&sc->malo_snd, m);
1228 if (error) {
1229 MALO_UNLOCK(sc);
1230 return (error);
1231 }
1232 malo_start(sc);
1233 MALO_UNLOCK(sc);
1234 return (0);
1235}
1236
1256static void
1237static void
1257malo_start(struct ifnet *ifp)
1238malo_start(struct malo_softc *sc)
1258{
1239{
1259 struct malo_softc *sc = ifp->if_softc;
1260 struct ieee80211_node *ni;
1261 struct malo_txq *txq = &sc->malo_txq[0];
1262 struct malo_txbuf *bf = NULL;
1263 struct mbuf *m;
1264 int nqueued = 0;
1265
1240 struct ieee80211_node *ni;
1241 struct malo_txq *txq = &sc->malo_txq[0];
1242 struct malo_txbuf *bf = NULL;
1243 struct mbuf *m;
1244 int nqueued = 0;
1245
1266 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->malo_invalid)
1246 MALO_LOCK_ASSERT(sc);
1247
1248 if (!sc->malo_running || sc->malo_invalid)
1267 return;
1268
1249 return;
1250
1269 for (;;) {
1270 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
1271 if (m == NULL)
1272 break;
1251 while ((m = mbufq_dequeue(&sc->malo_snd)) != NULL) {
1273 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1274 bf = malo_getbuf(sc, txq);
1275 if (bf == NULL) {
1252 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1253 bf = malo_getbuf(sc, txq);
1254 if (bf == NULL) {
1276 IFQ_DRV_PREPEND(&ifp->if_snd, m);
1277
1278 /* XXX blocks other traffic */
1279 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1255 mbufq_prepend(&sc->malo_snd, m);
1280 sc->malo_stats.mst_tx_qstop++;
1281 break;
1282 }
1283 /*
1284 * Pass the frame to the h/w for transmission.
1285 */
1286 if (malo_tx_start(sc, ni, bf, m)) {
1256 sc->malo_stats.mst_tx_qstop++;
1257 break;
1258 }
1259 /*
1260 * Pass the frame to the h/w for transmission.
1261 */
1262 if (malo_tx_start(sc, ni, bf, m)) {
1287 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
1263 if_inc_counter(ni->ni_vap->iv_ifp,
1264 IFCOUNTER_OERRORS, 1);
1288 if (bf != NULL) {
1289 bf->bf_m = NULL;
1290 bf->bf_node = NULL;
1291 MALO_TXQ_LOCK(txq);
1292 STAILQ_INSERT_HEAD(&txq->free, bf, bf_list);
1293 MALO_TXQ_UNLOCK(txq);
1294 }
1295 ieee80211_free_node(ni);

--- 27 unchanged lines hidden (view full) ---

1323 */
1324 malo_hal_txstart(sc->malo_mh, 0/*XXX*/);
1325 }
1326}
1327
1328static void
1329malo_watchdog(void *arg)
1330{
1265 if (bf != NULL) {
1266 bf->bf_m = NULL;
1267 bf->bf_node = NULL;
1268 MALO_TXQ_LOCK(txq);
1269 STAILQ_INSERT_HEAD(&txq->free, bf, bf_list);
1270 MALO_TXQ_UNLOCK(txq);
1271 }
1272 ieee80211_free_node(ni);

--- 27 unchanged lines hidden (view full) ---

1300 */
1301 malo_hal_txstart(sc->malo_mh, 0/*XXX*/);
1302 }
1303}
1304
1305static void
1306malo_watchdog(void *arg)
1307{
1331 struct malo_softc *sc;
1332 struct ifnet *ifp;
1308 struct malo_softc *sc = arg;
1333
1309
1334 sc = arg;
1335 callout_reset(&sc->malo_watchdog_timer, hz, malo_watchdog, sc);
1336 if (sc->malo_timer == 0 || --sc->malo_timer > 0)
1337 return;
1338
1310 callout_reset(&sc->malo_watchdog_timer, hz, malo_watchdog, sc);
1311 if (sc->malo_timer == 0 || --sc->malo_timer > 0)
1312 return;
1313
1339 ifp = sc->malo_ifp;
1340 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && !sc->malo_invalid) {
1341 if_printf(ifp, "watchdog timeout\n");
1314 if (sc->malo_running && !sc->malo_invalid) {
1315 device_printf(sc->malo_dev, "watchdog timeout\n");
1342
1343 /* XXX no way to reset h/w. now */
1344
1316
1317 /* XXX no way to reset h/w. now */
1318
1345 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
1319 counter_u64_add(sc->malo_ic.ic_oerrors, 1);
1346 sc->malo_stats.mst_watchdog++;
1347 }
1348}
1349
1350static int
1351malo_hal_reset(struct malo_softc *sc)
1352{
1353 static int first = 0;
1320 sc->malo_stats.mst_watchdog++;
1321 }
1322}
1323
1324static int
1325malo_hal_reset(struct malo_softc *sc)
1326{
1327 static int first = 0;
1354 struct ifnet *ifp = sc->malo_ifp;
1355 struct ieee80211com *ic = ifp->if_l2com;
1328 struct ieee80211com *ic = &sc->malo_ic;
1356 struct malo_hal *mh = sc->malo_mh;
1357
1358 if (first == 0) {
1359 /*
1360 * NB: when the device firstly is initialized, sometimes
1361 * firmware could override rx/tx dma registers so we re-set
1362 * these values once.
1363 */

--- 23 unchanged lines hidden (view full) ---

1387 if (m == NULL) {
1388 sc->malo_stats.mst_rx_nombuf++; /* XXX */
1389 return NULL;
1390 }
1391 error = bus_dmamap_load(sc->malo_dmat, bf->bf_dmamap,
1392 mtod(m, caddr_t), MJUMPAGESIZE,
1393 malo_load_cb, &paddr, BUS_DMA_NOWAIT);
1394 if (error != 0) {
1329 struct malo_hal *mh = sc->malo_mh;
1330
1331 if (first == 0) {
1332 /*
1333 * NB: when the device firstly is initialized, sometimes
1334 * firmware could override rx/tx dma registers so we re-set
1335 * these values once.
1336 */

--- 23 unchanged lines hidden (view full) ---

1360 if (m == NULL) {
1361 sc->malo_stats.mst_rx_nombuf++; /* XXX */
1362 return NULL;
1363 }
1364 error = bus_dmamap_load(sc->malo_dmat, bf->bf_dmamap,
1365 mtod(m, caddr_t), MJUMPAGESIZE,
1366 malo_load_cb, &paddr, BUS_DMA_NOWAIT);
1367 if (error != 0) {
1395 if_printf(sc->malo_ifp,
1368 device_printf(sc->malo_dev,
1396 "%s: bus_dmamap_load failed, error %d\n", __func__, error);
1397 m_freem(m);
1398 return NULL;
1399 }
1400 bf->bf_data = paddr;
1401 bus_dmamap_sync(sc->malo_dmat, bf->bf_dmamap, BUS_DMASYNC_PREWRITE);
1402
1403 return m;

--- 74 unchanged lines hidden (view full) ---

1478 malo_mode_init(sc); /* set filters, etc. */
1479
1480 return 0;
1481}
1482
1483static void
1484malo_init_locked(struct malo_softc *sc)
1485{
1369 "%s: bus_dmamap_load failed, error %d\n", __func__, error);
1370 m_freem(m);
1371 return NULL;
1372 }
1373 bf->bf_data = paddr;
1374 bus_dmamap_sync(sc->malo_dmat, bf->bf_dmamap, BUS_DMASYNC_PREWRITE);
1375
1376 return m;

--- 74 unchanged lines hidden (view full) ---

1451 malo_mode_init(sc); /* set filters, etc. */
1452
1453 return 0;
1454}
1455
1456static void
1457malo_init_locked(struct malo_softc *sc)
1458{
1486 struct ifnet *ifp = sc->malo_ifp;
1487 struct malo_hal *mh = sc->malo_mh;
1488 int error;
1489
1459 struct malo_hal *mh = sc->malo_mh;
1460 int error;
1461
1490 DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags 0x%x\n",
1491 __func__, ifp->if_flags);
1492
1493 MALO_LOCK_ASSERT(sc);
1494
1495 /*
1496 * Stop anything previously setup. This is safe whether this is
1497 * the first time through or not.
1498 */
1462 MALO_LOCK_ASSERT(sc);
1463
1464 /*
1465 * Stop anything previously setup. This is safe whether this is
1466 * the first time through or not.
1467 */
1499 malo_stop_locked(ifp, 0);
1468 malo_stop(sc);
1500
1501 /*
1502 * Push state to the firmware.
1503 */
1504 if (!malo_hal_reset(sc)) {
1469
1470 /*
1471 * Push state to the firmware.
1472 */
1473 if (!malo_hal_reset(sc)) {
1505 if_printf(ifp, "%s: unable to reset hardware\n", __func__);
1474 device_printf(sc->malo_dev,
1475 "%s: unable to reset hardware\n", __func__);
1506 return;
1507 }
1508
1509 /*
1510 * Setup recv (once); transmit is already good to go.
1511 */
1512 error = malo_startrecv(sc);
1513 if (error != 0) {
1476 return;
1477 }
1478
1479 /*
1480 * Setup recv (once); transmit is already good to go.
1481 */
1482 error = malo_startrecv(sc);
1483 if (error != 0) {
1514 if_printf(ifp, "%s: unable to start recv logic, error %d\n",
1484 device_printf(sc->malo_dev,
1485 "%s: unable to start recv logic, error %d\n",
1515 __func__, error);
1516 return;
1517 }
1518
1519 /*
1520 * Enable interrupts.
1521 */
1522 sc->malo_imask = MALO_A2HRIC_BIT_RX_RDY
1523 | MALO_A2HRIC_BIT_TX_DONE
1524 | MALO_A2HRIC_BIT_OPC_DONE
1525 | MALO_A2HRIC_BIT_MAC_EVENT
1526 | MALO_A2HRIC_BIT_RX_PROBLEM
1527 | MALO_A2HRIC_BIT_ICV_ERROR
1528 | MALO_A2HRIC_BIT_RADAR_DETECT
1529 | MALO_A2HRIC_BIT_CHAN_SWITCH;
1530
1486 __func__, error);
1487 return;
1488 }
1489
1490 /*
1491 * Enable interrupts.
1492 */
1493 sc->malo_imask = MALO_A2HRIC_BIT_RX_RDY
1494 | MALO_A2HRIC_BIT_TX_DONE
1495 | MALO_A2HRIC_BIT_OPC_DONE
1496 | MALO_A2HRIC_BIT_MAC_EVENT
1497 | MALO_A2HRIC_BIT_RX_PROBLEM
1498 | MALO_A2HRIC_BIT_ICV_ERROR
1499 | MALO_A2HRIC_BIT_RADAR_DETECT
1500 | MALO_A2HRIC_BIT_CHAN_SWITCH;
1501
1531 ifp->if_drv_flags |= IFF_DRV_RUNNING;
1502 sc->malo_running = 1;
1532 malo_hal_intrset(mh, sc->malo_imask);
1533 callout_reset(&sc->malo_watchdog_timer, hz, malo_watchdog, sc);
1534}
1535
1536static void
1537malo_init(void *arg)
1538{
1539 struct malo_softc *sc = (struct malo_softc *) arg;
1503 malo_hal_intrset(mh, sc->malo_imask);
1504 callout_reset(&sc->malo_watchdog_timer, hz, malo_watchdog, sc);
1505}
1506
1507static void
1508malo_init(void *arg)
1509{
1510 struct malo_softc *sc = (struct malo_softc *) arg;
1540 struct ifnet *ifp = sc->malo_ifp;
1541 struct ieee80211com *ic = ifp->if_l2com;
1511 struct ieee80211com *ic = &sc->malo_ic;
1542
1512
1543 DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags 0x%x\n",
1544 __func__, ifp->if_flags);
1545
1546 MALO_LOCK(sc);
1547 malo_init_locked(sc);
1513 MALO_LOCK(sc);
1514 malo_init_locked(sc);
1548
1549 MALO_UNLOCK(sc);
1550
1515 MALO_UNLOCK(sc);
1516
1551 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1517 if (sc->malo_running)
1552 ieee80211_start_all(ic); /* start all vap's */
1553}
1554
1555/*
1556 * Set the multicast filter contents into the hardware.
1557 */
1558static void
1559malo_setmcastfilter(struct malo_softc *sc)
1560{
1518 ieee80211_start_all(ic); /* start all vap's */
1519}
1520
1521/*
1522 * Set the multicast filter contents into the hardware.
1523 */
1524static void
1525malo_setmcastfilter(struct malo_softc *sc)
1526{
1561 struct ifnet *ifp = sc->malo_ifp;
1562 struct ieee80211com *ic = ifp->if_l2com;
1563 struct ifmultiaddr *ifma;
1527 struct ieee80211com *ic = &sc->malo_ic;
1528 struct ieee80211vap *vap;
1564 uint8_t macs[IEEE80211_ADDR_LEN * MALO_HAL_MCAST_MAX];
1565 uint8_t *mp;
1566 int nmc;
1567
1568 mp = macs;
1569 nmc = 0;
1570
1529 uint8_t macs[IEEE80211_ADDR_LEN * MALO_HAL_MCAST_MAX];
1530 uint8_t *mp;
1531 int nmc;
1532
1533 mp = macs;
1534 nmc = 0;
1535
1571 if (ic->ic_opmode == IEEE80211_M_MONITOR ||
1572 (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)))
1536 if (ic->ic_opmode == IEEE80211_M_MONITOR || ic->ic_allmulti > 0 ||
1537 ic->ic_promisc > 0)
1573 goto all;
1538 goto all;
1574
1575 if_maddr_rlock(ifp);
1576 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1577 if (ifma->ifma_addr->sa_family != AF_LINK)
1578 continue;
1579
1539
1580 if (nmc == MALO_HAL_MCAST_MAX) {
1581 ifp->if_flags |= IFF_ALLMULTI;
1582 if_maddr_runlock(ifp);
1583 goto all;
1584 }
1585 IEEE80211_ADDR_COPY(mp,
1586 LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
1540 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
1541 struct ifnet *ifp;
1542 struct ifmultiaddr *ifma;
1587
1543
1588 mp += IEEE80211_ADDR_LEN, nmc++;
1544 ifp = vap->iv_ifp;
1545 if_maddr_rlock(ifp);
1546 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1547 if (ifma->ifma_addr->sa_family != AF_LINK)
1548 continue;
1549
1550 if (nmc == MALO_HAL_MCAST_MAX) {
1551 ifp->if_flags |= IFF_ALLMULTI;
1552 if_maddr_runlock(ifp);
1553 goto all;
1554 }
1555 IEEE80211_ADDR_COPY(mp,
1556 LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
1557
1558 mp += IEEE80211_ADDR_LEN, nmc++;
1559 }
1560 if_maddr_runlock(ifp);
1589 }
1561 }
1590 if_maddr_runlock(ifp);
1591
1592 malo_hal_setmcast(sc->malo_mh, nmc, macs);
1593
1594all:
1595 /*
1596 * XXX we don't know how to set the f/w for supporting
1597 * IFF_ALLMULTI | IFF_PROMISC cases
1598 */
1599 return;
1600}
1601
1602static int
1603malo_mode_init(struct malo_softc *sc)
1604{
1562
1563 malo_hal_setmcast(sc->malo_mh, nmc, macs);
1564
1565all:
1566 /*
1567 * XXX we don't know how to set the f/w for supporting
1568 * IFF_ALLMULTI | IFF_PROMISC cases
1569 */
1570 return;
1571}
1572
1573static int
1574malo_mode_init(struct malo_softc *sc)
1575{
1605 struct ifnet *ifp = sc->malo_ifp;
1606 struct ieee80211com *ic = ifp->if_l2com;
1576 struct ieee80211com *ic = &sc->malo_ic;
1607 struct malo_hal *mh = sc->malo_mh;
1608
1609 /*
1610 * NB: Ignore promisc in hostap mode; it's set by the
1611 * bridge. This is wrong but we have no way to
1612 * identify internal requests (from the bridge)
1613 * versus external requests such as for tcpdump.
1614 */
1577 struct malo_hal *mh = sc->malo_mh;
1578
1579 /*
1580 * NB: Ignore promisc in hostap mode; it's set by the
1581 * bridge. This is wrong but we have no way to
1582 * identify internal requests (from the bridge)
1583 * versus external requests such as for tcpdump.
1584 */
1615 malo_hal_setpromisc(mh, (ifp->if_flags & IFF_PROMISC) &&
1585 malo_hal_setpromisc(mh, ic->ic_promisc > 0 &&
1616 ic->ic_opmode != IEEE80211_M_HOSTAP);
1617 malo_setmcastfilter(sc);
1618
1619 return ENXIO;
1620}
1621
1622static void
1623malo_tx_draintxq(struct malo_softc *sc, struct malo_txq *txq)

--- 12 unchanged lines hidden (view full) ---

1636 if (bf == NULL) {
1637 MALO_TXQ_UNLOCK(txq);
1638 break;
1639 }
1640 STAILQ_REMOVE_HEAD(&txq->active, bf_list);
1641 MALO_TXQ_UNLOCK(txq);
1642#ifdef MALO_DEBUG
1643 if (sc->malo_debug & MALO_DEBUG_RESET) {
1586 ic->ic_opmode != IEEE80211_M_HOSTAP);
1587 malo_setmcastfilter(sc);
1588
1589 return ENXIO;
1590}
1591
1592static void
1593malo_tx_draintxq(struct malo_softc *sc, struct malo_txq *txq)

--- 12 unchanged lines hidden (view full) ---

1606 if (bf == NULL) {
1607 MALO_TXQ_UNLOCK(txq);
1608 break;
1609 }
1610 STAILQ_REMOVE_HEAD(&txq->active, bf_list);
1611 MALO_TXQ_UNLOCK(txq);
1612#ifdef MALO_DEBUG
1613 if (sc->malo_debug & MALO_DEBUG_RESET) {
1644 struct ifnet *ifp = sc->malo_ifp;
1645 struct ieee80211com *ic = ifp->if_l2com;
1614 struct ieee80211com *ic = &sc->malo_ic;
1646 const struct malo_txrec *tr =
1647 mtod(bf->bf_m, const struct malo_txrec *);
1648 malo_printtxbuf(bf, txq->qnum, ix);
1649 ieee80211_dump_pkt(ic, (const uint8_t *)&tr->wh,
1650 bf->bf_m->m_len - sizeof(tr->fwlen), 0, -1);
1651 }
1652#endif /* MALO_DEBUG */
1653 bus_dmamap_unload(sc->malo_dmat, bf->bf_dmamap);

--- 11 unchanged lines hidden (view full) ---

1665 MALO_TXQ_LOCK(txq);
1666 STAILQ_INSERT_TAIL(&txq->free, bf, bf_list);
1667 txq->nfree++;
1668 MALO_TXQ_UNLOCK(txq);
1669 }
1670}
1671
1672static void
1615 const struct malo_txrec *tr =
1616 mtod(bf->bf_m, const struct malo_txrec *);
1617 malo_printtxbuf(bf, txq->qnum, ix);
1618 ieee80211_dump_pkt(ic, (const uint8_t *)&tr->wh,
1619 bf->bf_m->m_len - sizeof(tr->fwlen), 0, -1);
1620 }
1621#endif /* MALO_DEBUG */
1622 bus_dmamap_unload(sc->malo_dmat, bf->bf_dmamap);

--- 11 unchanged lines hidden (view full) ---

1634 MALO_TXQ_LOCK(txq);
1635 STAILQ_INSERT_TAIL(&txq->free, bf, bf_list);
1636 txq->nfree++;
1637 MALO_TXQ_UNLOCK(txq);
1638 }
1639}
1640
1641static void
1673malo_stop_locked(struct ifnet *ifp, int disable)
1642malo_stop(struct malo_softc *sc)
1674{
1643{
1675 struct malo_softc *sc = ifp->if_softc;
1676 struct malo_hal *mh = sc->malo_mh;
1677 int i;
1678
1644 struct malo_hal *mh = sc->malo_mh;
1645 int i;
1646
1679 DPRINTF(sc, MALO_DEBUG_ANY, "%s: invalid %u if_flags 0x%x\n",
1680 __func__, sc->malo_invalid, ifp->if_flags);
1647 DPRINTF(sc, MALO_DEBUG_ANY, "%s: invalid %u running %u\n",
1648 __func__, sc->malo_invalid, sc->malo_running);
1681
1682 MALO_LOCK_ASSERT(sc);
1683
1649
1650 MALO_LOCK_ASSERT(sc);
1651
1684 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
1652 if (!sc->malo_running)
1685 return;
1686
1687 /*
1688 * Shutdown the hardware and driver:
1689 * disable interrupts
1690 * turn off the radio
1691 * drain and release tx queues
1692 *
1693 * Note that some of this work is not possible if the hardware
1694 * is gone (invalid).
1695 */
1653 return;
1654
1655 /*
1656 * Shutdown the hardware and driver:
1657 * disable interrupts
1658 * turn off the radio
1659 * drain and release tx queues
1660 *
1661 * Note that some of this work is not possible if the hardware
1662 * is gone (invalid).
1663 */
1696 ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
1664 sc->malo_running = 0;
1697 callout_stop(&sc->malo_watchdog_timer);
1698 sc->malo_timer = 0;
1665 callout_stop(&sc->malo_watchdog_timer);
1666 sc->malo_timer = 0;
1699 /* diable interrupt. */
1667 /* disable interrupt. */
1700 malo_hal_intrset(mh, 0);
1701 /* turn off the radio. */
1702 malo_hal_setradio(mh, 0, MHP_AUTO_PREAMBLE);
1703
1704 /* drain and release tx queues. */
1705 for (i = 0; i < MALO_NUM_TX_QUEUES; i++)
1706 malo_tx_draintxq(sc, &sc->malo_txq[i]);
1707}
1708
1668 malo_hal_intrset(mh, 0);
1669 /* turn off the radio. */
1670 malo_hal_setradio(mh, 0, MHP_AUTO_PREAMBLE);
1671
1672 /* drain and release tx queues. */
1673 for (i = 0; i < MALO_NUM_TX_QUEUES; i++)
1674 malo_tx_draintxq(sc, &sc->malo_txq[i]);
1675}
1676
1709static int
1710malo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1677static void
1678malo_parent(struct ieee80211com *ic)
1711{
1679{
1712#define MALO_IS_RUNNING(ifp) \
1713 ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
1714 struct malo_softc *sc = ifp->if_softc;
1715 struct ieee80211com *ic = ifp->if_l2com;
1716 struct ifreq *ifr = (struct ifreq *) data;
1717 int error = 0, startall = 0;
1680 struct malo_softc *sc = ic->ic_softc;
1681 int startall = 0;
1718
1719 MALO_LOCK(sc);
1682
1683 MALO_LOCK(sc);
1720 switch (cmd) {
1721 case SIOCSIFFLAGS:
1722 if (MALO_IS_RUNNING(ifp)) {
1723 /*
1724 * To avoid rescanning another access point,
1725 * do not call malo_init() here. Instead,
1726 * only reflect promisc mode settings.
1727 */
1728 malo_mode_init(sc);
1729 } else if (ifp->if_flags & IFF_UP) {
1730 /*
1731 * Beware of being called during attach/detach
1732 * to reset promiscuous mode. In that case we
1733 * will still be marked UP but not RUNNING.
1734 * However trying to re-init the interface
1735 * is the wrong thing to do as we've already
1736 * torn down much of our state. There's
1737 * probably a better way to deal with this.
1738 */
1739 if (!sc->malo_invalid) {
1740 malo_init_locked(sc);
1741 startall = 1;
1742 }
1743 } else
1744 malo_stop_locked(ifp, 1);
1745 break;
1746 case SIOCGIFMEDIA:
1747 case SIOCSIFMEDIA:
1748 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1749 break;
1750 default:
1751 error = ether_ioctl(ifp, cmd, data);
1752 break;
1753 }
1684 if (ic->ic_nrunning > 0) {
1685 /*
1686 * Beware of being called during attach/detach
1687 * to reset promiscuous mode. In that case we
1688 * will still be marked UP but not RUNNING.
1689 * However trying to re-init the interface
1690 * is the wrong thing to do as we've already
1691 * torn down much of our state. There's
1692 * probably a better way to deal with this.
1693 */
1694 if (!sc->malo_running && !sc->malo_invalid) {
1695 malo_init(sc);
1696 startall = 1;
1697 }
1698 /*
1699 * To avoid rescanning another access point,
1700 * do not call malo_init() here. Instead,
1701 * only reflect promisc mode settings.
1702 */
1703 malo_mode_init(sc);
1704 } else if (sc->malo_running)
1705 malo_stop(sc);
1754 MALO_UNLOCK(sc);
1706 MALO_UNLOCK(sc);
1755
1756 if (startall)
1757 ieee80211_start_all(ic);
1707 if (startall)
1708 ieee80211_start_all(ic);
1758 return error;
1759#undef MALO_IS_RUNNING
1760}
1761
1762/*
1763 * Callback from the 802.11 layer to update the slot time
1764 * based on the current setting. We use it to notify the
1765 * firmware of ERP changes and the f/w takes care of things
1766 * like slot time and preamble.
1767 */
1768static void
1769malo_updateslot(struct ieee80211com *ic)
1770{
1771 struct malo_softc *sc = ic->ic_softc;
1772 struct malo_hal *mh = sc->malo_mh;
1773 int error;
1774
1775 /* NB: can be called early; suppress needless cmds */
1709}
1710
1711/*
1712 * Callback from the 802.11 layer to update the slot time
1713 * based on the current setting. We use it to notify the
1714 * firmware of ERP changes and the f/w takes care of things
1715 * like slot time and preamble.
1716 */
1717static void
1718malo_updateslot(struct ieee80211com *ic)
1719{
1720 struct malo_softc *sc = ic->ic_softc;
1721 struct malo_hal *mh = sc->malo_mh;
1722 int error;
1723
1724 /* NB: can be called early; suppress needless cmds */
1776 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
1725 if (!sc->malo_running)
1777 return;
1778
1779 DPRINTF(sc, MALO_DEBUG_RESET,
1780 "%s: chan %u MHz/flags 0x%x %s slot, (ic_flags 0x%x)\n",
1781 __func__, ic->ic_curchan->ic_freq, ic->ic_curchan->ic_flags,
1782 ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long", ic->ic_flags);
1783
1784 if (ic->ic_flags & IEEE80211_F_SHSLOT)

--- 5 unchanged lines hidden (view full) ---

1790 device_printf(sc->malo_dev, "setting %s slot failed\n",
1791 ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long");
1792}
1793
1794static int
1795malo_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
1796{
1797 struct ieee80211com *ic = vap->iv_ic;
1726 return;
1727
1728 DPRINTF(sc, MALO_DEBUG_RESET,
1729 "%s: chan %u MHz/flags 0x%x %s slot, (ic_flags 0x%x)\n",
1730 __func__, ic->ic_curchan->ic_freq, ic->ic_curchan->ic_flags,
1731 ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long", ic->ic_flags);
1732
1733 if (ic->ic_flags & IEEE80211_F_SHSLOT)

--- 5 unchanged lines hidden (view full) ---

1739 device_printf(sc->malo_dev, "setting %s slot failed\n",
1740 ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long");
1741}
1742
1743static int
1744malo_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
1745{
1746 struct ieee80211com *ic = vap->iv_ic;
1798 struct malo_softc *sc = ic->ic_ifp->if_softc;
1747 struct malo_softc *sc = ic->ic_softc;
1799 struct malo_hal *mh = sc->malo_mh;
1800 int error;
1801
1802 DPRINTF(sc, MALO_DEBUG_STATE, "%s: %s -> %s\n", __func__,
1803 ieee80211_state_name[vap->iv_state],
1804 ieee80211_state_name[nstate]);
1805
1806 /*

--- 27 unchanged lines hidden (view full) ---

1834 return 0;
1835}
1836
1837static int
1838malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
1839 const struct ieee80211_bpf_params *params)
1840{
1841 struct ieee80211com *ic = ni->ni_ic;
1748 struct malo_hal *mh = sc->malo_mh;
1749 int error;
1750
1751 DPRINTF(sc, MALO_DEBUG_STATE, "%s: %s -> %s\n", __func__,
1752 ieee80211_state_name[vap->iv_state],
1753 ieee80211_state_name[nstate]);
1754
1755 /*

--- 27 unchanged lines hidden (view full) ---

1783 return 0;
1784}
1785
1786static int
1787malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
1788 const struct ieee80211_bpf_params *params)
1789{
1790 struct ieee80211com *ic = ni->ni_ic;
1842 struct ifnet *ifp = ic->ic_ifp;
1843 struct malo_softc *sc = ifp->if_softc;
1791 struct malo_softc *sc = ic->ic_softc;
1844 struct malo_txbuf *bf;
1845 struct malo_txq *txq;
1846
1792 struct malo_txbuf *bf;
1793 struct malo_txq *txq;
1794
1847 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->malo_invalid) {
1795 if (!sc->malo_running || sc->malo_invalid) {
1848 ieee80211_free_node(ni);
1849 m_freem(m);
1850 return ENETDOWN;
1851 }
1852
1853 /*
1854 * Grab a TX buffer and associated resources. Note that we depend
1855 * on the classification by the 802.11 layer to get to the right h/w
1856 * queue. Management frames must ALWAYS go on queue 1 but we
1857 * cannot just force that here because we may receive non-mgt frames.
1858 */
1859 txq = &sc->malo_txq[0];
1860 bf = malo_getbuf(sc, txq);
1861 if (bf == NULL) {
1796 ieee80211_free_node(ni);
1797 m_freem(m);
1798 return ENETDOWN;
1799 }
1800
1801 /*
1802 * Grab a TX buffer and associated resources. Note that we depend
1803 * on the classification by the 802.11 layer to get to the right h/w
1804 * queue. Management frames must ALWAYS go on queue 1 but we
1805 * cannot just force that here because we may receive non-mgt frames.
1806 */
1807 txq = &sc->malo_txq[0];
1808 bf = malo_getbuf(sc, txq);
1809 if (bf == NULL) {
1862 /* XXX blocks other traffic */
1863 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1864 ieee80211_free_node(ni);
1865 m_freem(m);
1866 return ENOBUFS;
1867 }
1868
1869 /*
1870 * Pass the frame to the h/w for transmission.
1871 */
1872 if (malo_tx_start(sc, ni, bf, m) != 0) {
1810 ieee80211_free_node(ni);
1811 m_freem(m);
1812 return ENOBUFS;
1813 }
1814
1815 /*
1816 * Pass the frame to the h/w for transmission.
1817 */
1818 if (malo_tx_start(sc, ni, bf, m) != 0) {
1873 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
1874 bf->bf_m = NULL;
1875 bf->bf_node = NULL;
1876 MALO_TXQ_LOCK(txq);
1877 STAILQ_INSERT_HEAD(&txq->free, bf, bf_list);
1878 txq->nfree++;
1879 MALO_TXQ_UNLOCK(txq);
1880
1881 ieee80211_free_node(ni);

--- 28 unchanged lines hidden (view full) ---

1910 "debug", CTLFLAG_RW, &sc->malo_debug, 0,
1911 "control debugging printfs");
1912#endif
1913}
1914
1915static void
1916malo_announce(struct malo_softc *sc)
1917{
1819 bf->bf_m = NULL;
1820 bf->bf_node = NULL;
1821 MALO_TXQ_LOCK(txq);
1822 STAILQ_INSERT_HEAD(&txq->free, bf, bf_list);
1823 txq->nfree++;
1824 MALO_TXQ_UNLOCK(txq);
1825
1826 ieee80211_free_node(ni);

--- 28 unchanged lines hidden (view full) ---

1855 "debug", CTLFLAG_RW, &sc->malo_debug, 0,
1856 "control debugging printfs");
1857#endif
1858}
1859
1860static void
1861malo_announce(struct malo_softc *sc)
1862{
1918 struct ifnet *ifp = sc->malo_ifp;
1919
1863
1920 if_printf(ifp, "versions [hw %d fw %d.%d.%d.%d] (regioncode %d)\n",
1864 device_printf(sc->malo_dev,
1865 "versions [hw %d fw %d.%d.%d.%d] (regioncode %d)\n",
1921 sc->malo_hwspecs.hwversion,
1922 (sc->malo_hwspecs.fw_releasenum >> 24) & 0xff,
1923 (sc->malo_hwspecs.fw_releasenum >> 16) & 0xff,
1924 (sc->malo_hwspecs.fw_releasenum >> 8) & 0xff,
1925 (sc->malo_hwspecs.fw_releasenum >> 0) & 0xff,
1926 sc->malo_hwspecs.regioncode);
1927
1928 if (bootverbose || malo_rxbuf != MALO_RXBUF)
1866 sc->malo_hwspecs.hwversion,
1867 (sc->malo_hwspecs.fw_releasenum >> 24) & 0xff,
1868 (sc->malo_hwspecs.fw_releasenum >> 16) & 0xff,
1869 (sc->malo_hwspecs.fw_releasenum >> 8) & 0xff,
1870 (sc->malo_hwspecs.fw_releasenum >> 0) & 0xff,
1871 sc->malo_hwspecs.regioncode);
1872
1873 if (bootverbose || malo_rxbuf != MALO_RXBUF)
1929 if_printf(ifp, "using %u rx buffers\n", malo_rxbuf);
1874 device_printf(sc->malo_dev,
1875 "using %u rx buffers\n", malo_rxbuf);
1930 if (bootverbose || malo_txbuf != MALO_TXBUF)
1876 if (bootverbose || malo_txbuf != MALO_TXBUF)
1931 if_printf(ifp, "using %u tx buffers\n", malo_txbuf);
1877 device_printf(sc->malo_dev,
1878 "using %u tx buffers\n", malo_txbuf);
1932}
1933
1934/*
1935 * Convert net80211 channel to a HAL channel.
1936 */
1937static void
1938malo_mapchan(struct malo_hal_channel *hc, const struct ieee80211_channel *chan)
1939{

--- 44 unchanged lines hidden (view full) ---

1984 malo_hal_intrset(mh, sc->malo_imask);
1985
1986 return 0;
1987}
1988
1989static void
1990malo_scan_start(struct ieee80211com *ic)
1991{
1879}
1880
1881/*
1882 * Convert net80211 channel to a HAL channel.
1883 */
1884static void
1885malo_mapchan(struct malo_hal_channel *hc, const struct ieee80211_channel *chan)
1886{

--- 44 unchanged lines hidden (view full) ---

1931 malo_hal_intrset(mh, sc->malo_imask);
1932
1933 return 0;
1934}
1935
1936static void
1937malo_scan_start(struct ieee80211com *ic)
1938{
1992 struct ifnet *ifp = ic->ic_ifp;
1993 struct malo_softc *sc = ifp->if_softc;
1939 struct malo_softc *sc = ic->ic_softc;
1994
1995 DPRINTF(sc, MALO_DEBUG_STATE, "%s\n", __func__);
1996}
1997
1998static void
1999malo_scan_end(struct ieee80211com *ic)
2000{
1940
1941 DPRINTF(sc, MALO_DEBUG_STATE, "%s\n", __func__);
1942}
1943
1944static void
1945malo_scan_end(struct ieee80211com *ic)
1946{
2001 struct ifnet *ifp = ic->ic_ifp;
2002 struct malo_softc *sc = ifp->if_softc;
1947 struct malo_softc *sc = ic->ic_softc;
2003
2004 DPRINTF(sc, MALO_DEBUG_STATE, "%s\n", __func__);
2005}
2006
2007static void
2008malo_set_channel(struct ieee80211com *ic)
2009{
1948
1949 DPRINTF(sc, MALO_DEBUG_STATE, "%s\n", __func__);
1950}
1951
1952static void
1953malo_set_channel(struct ieee80211com *ic)
1954{
2010 struct ifnet *ifp = ic->ic_ifp;
2011 struct malo_softc *sc = ifp->if_softc;
1955 struct malo_softc *sc = ic->ic_softc;
2012
2013 (void) malo_chan_set(sc, ic->ic_curchan);
2014}
2015
2016static void
2017malo_rx_proc(void *arg, int npending)
2018{
2019#define IEEE80211_DIR_DSTODS(wh) \
2020 ((((const struct ieee80211_frame *)wh)->i_fc[1] & \
2021 IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
2022 struct malo_softc *sc = arg;
1956
1957 (void) malo_chan_set(sc, ic->ic_curchan);
1958}
1959
1960static void
1961malo_rx_proc(void *arg, int npending)
1962{
1963#define IEEE80211_DIR_DSTODS(wh) \
1964 ((((const struct ieee80211_frame *)wh)->i_fc[1] & \
1965 IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
1966 struct malo_softc *sc = arg;
2023 struct ifnet *ifp = sc->malo_ifp;
2024 struct ieee80211com *ic = ifp->if_l2com;
1967 struct ieee80211com *ic = &sc->malo_ic;
2025 struct malo_rxbuf *bf;
2026 struct malo_rxdesc *ds;
2027 struct mbuf *m, *mnew;
2028 struct ieee80211_qosframe *wh;
2029 struct ieee80211_qosframe_addr4 *wh4;
2030 struct ieee80211_node *ni;
2031 int off, len, hdrlen, pktlen, rssi, ntodo;
2032 uint8_t *data, status;

--- 40 unchanged lines hidden (view full) ---

2073 readptr = le32toh(ds->physnext);
2074
2075#ifdef MALO_DEBUG
2076 if (sc->malo_debug & MALO_DEBUG_RECV_DESC)
2077 malo_printrxbuf(bf, 0);
2078#endif
2079 status = ds->status;
2080 if (status & MALO_RXD_STATUS_DECRYPT_ERR_MASK) {
1968 struct malo_rxbuf *bf;
1969 struct malo_rxdesc *ds;
1970 struct mbuf *m, *mnew;
1971 struct ieee80211_qosframe *wh;
1972 struct ieee80211_qosframe_addr4 *wh4;
1973 struct ieee80211_node *ni;
1974 int off, len, hdrlen, pktlen, rssi, ntodo;
1975 uint8_t *data, status;

--- 40 unchanged lines hidden (view full) ---

2016 readptr = le32toh(ds->physnext);
2017
2018#ifdef MALO_DEBUG
2019 if (sc->malo_debug & MALO_DEBUG_RECV_DESC)
2020 malo_printrxbuf(bf, 0);
2021#endif
2022 status = ds->status;
2023 if (status & MALO_RXD_STATUS_DECRYPT_ERR_MASK) {
2081 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
2024 counter_u64_add(ic->ic_ierrors, 1);
2082 goto rx_next;
2083 }
2084 /*
2085 * Sync the data buffer.
2086 */
2087 len = le16toh(ds->pktlen);
2088 bus_dmamap_sync(sc->malo_dmat, bf->bf_dmamap,
2089 BUS_DMASYNC_POSTREAD);

--- 22 unchanged lines hidden (view full) ---

2112 * the front. Hence there's no need to vet the packet length.
2113 * If the frame in fact is too small it should be discarded
2114 * at the net80211 layer.
2115 */
2116
2117 /* XXX don't need mbuf, just dma buffer */
2118 mnew = malo_getrxmbuf(sc, bf);
2119 if (mnew == NULL) {
2025 goto rx_next;
2026 }
2027 /*
2028 * Sync the data buffer.
2029 */
2030 len = le16toh(ds->pktlen);
2031 bus_dmamap_sync(sc->malo_dmat, bf->bf_dmamap,
2032 BUS_DMASYNC_POSTREAD);

--- 22 unchanged lines hidden (view full) ---

2055 * the front. Hence there's no need to vet the packet length.
2056 * If the frame in fact is too small it should be discarded
2057 * at the net80211 layer.
2058 */
2059
2060 /* XXX don't need mbuf, just dma buffer */
2061 mnew = malo_getrxmbuf(sc, bf);
2062 if (mnew == NULL) {
2120 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
2063 counter_u64_add(ic->ic_ierrors, 1);
2121 goto rx_next;
2122 }
2123 /*
2124 * Attach the dma buffer to the mbuf; malo_rxbuf_init will
2125 * re-setup the rx descriptor using the replacement dma
2126 * buffer we just installed above.
2127 */
2128 bf->bf_m = mnew;
2129 m->m_data += off - hdrlen;
2130 m->m_pkthdr.len = m->m_len = pktlen;
2064 goto rx_next;
2065 }
2066 /*
2067 * Attach the dma buffer to the mbuf; malo_rxbuf_init will
2068 * re-setup the rx descriptor using the replacement dma
2069 * buffer we just installed above.
2070 */
2071 bf->bf_m = mnew;
2072 m->m_data += off - hdrlen;
2073 m->m_pkthdr.len = m->m_len = pktlen;
2131 m->m_pkthdr.rcvif = ifp;
2132
2133 /*
2134 * Piece 802.11 header together.
2135 */
2136 wh = mtod(m, struct ieee80211_qosframe *);
2137 /* NB: don't need to do this sometimes but ... */
2138 /* XXX special case so we can memcpy after m_devget? */
2139 ovbcopy(data + sizeof(uint16_t), wh, hdrlen);

--- 13 unchanged lines hidden (view full) ---

2153 sc->malo_rx_th.wr_antnoise = ds->nf;
2154 }
2155#ifdef MALO_DEBUG
2156 if (IFF_DUMPPKTS_RECV(sc, wh)) {
2157 ieee80211_dump_pkt(ic, mtod(m, caddr_t),
2158 len, ds->rate, rssi);
2159 }
2160#endif
2074
2075 /*
2076 * Piece 802.11 header together.
2077 */
2078 wh = mtod(m, struct ieee80211_qosframe *);
2079 /* NB: don't need to do this sometimes but ... */
2080 /* XXX special case so we can memcpy after m_devget? */
2081 ovbcopy(data + sizeof(uint16_t), wh, hdrlen);

--- 13 unchanged lines hidden (view full) ---

2095 sc->malo_rx_th.wr_antnoise = ds->nf;
2096 }
2097#ifdef MALO_DEBUG
2098 if (IFF_DUMPPKTS_RECV(sc, wh)) {
2099 ieee80211_dump_pkt(ic, mtod(m, caddr_t),
2100 len, ds->rate, rssi);
2101 }
2102#endif
2161 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
2162
2163 /* dispatch */
2164 ni = ieee80211_find_rxnode(ic,
2165 (struct ieee80211_frame_min *)wh);
2166 if (ni != NULL) {
2167 (void) ieee80211_input(ni, m, rssi, ds->nf);
2168 ieee80211_free_node(ni);
2169 } else
2170 (void) ieee80211_input_all(ic, m, rssi, ds->nf);
2171rx_next:
2172 /* NB: ignore ENOMEM so we process more descriptors */
2173 (void) malo_rxbuf_init(sc, bf);
2174 bf = STAILQ_NEXT(bf, bf_list);
2175 }
2176
2177 malo_bar0_write4(sc, sc->malo_hwspecs.rxdesc_read, readptr);
2178 sc->malo_rxnext = bf;
2179
2103 /* dispatch */
2104 ni = ieee80211_find_rxnode(ic,
2105 (struct ieee80211_frame_min *)wh);
2106 if (ni != NULL) {
2107 (void) ieee80211_input(ni, m, rssi, ds->nf);
2108 ieee80211_free_node(ni);
2109 } else
2110 (void) ieee80211_input_all(ic, m, rssi, ds->nf);
2111rx_next:
2112 /* NB: ignore ENOMEM so we process more descriptors */
2113 (void) malo_rxbuf_init(sc, bf);
2114 bf = STAILQ_NEXT(bf, bf_list);
2115 }
2116
2117 malo_bar0_write4(sc, sc->malo_hwspecs.rxdesc_read, readptr);
2118 sc->malo_rxnext = bf;
2119
2180 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 &&
2181 !IFQ_IS_EMPTY(&ifp->if_snd))
2182 malo_start(ifp);
2120 if (mbufq_first(&sc->malo_snd) != NULL)
2121 malo_start(sc);
2183#undef IEEE80211_DIR_DSTODS
2184}
2185
2122#undef IEEE80211_DIR_DSTODS
2123}
2124
2186static void
2187malo_stop(struct ifnet *ifp, int disable)
2188{
2189 struct malo_softc *sc = ifp->if_softc;
2190
2191 MALO_LOCK(sc);
2192 malo_stop_locked(ifp, disable);
2193 MALO_UNLOCK(sc);
2194}
2195
2196/*
2197 * Reclaim all tx queue resources.
2198 */
2199static void
2200malo_tx_cleanup(struct malo_softc *sc)
2201{
2202 int i;
2203
2204 for (i = 0; i < MALO_NUM_TX_QUEUES; i++)
2205 malo_tx_cleanupq(sc, &sc->malo_txq[i]);
2206}
2207
2208int
2209malo_detach(struct malo_softc *sc)
2210{
2125/*
2126 * Reclaim all tx queue resources.
2127 */
2128static void
2129malo_tx_cleanup(struct malo_softc *sc)
2130{
2131 int i;
2132
2133 for (i = 0; i < MALO_NUM_TX_QUEUES; i++)
2134 malo_tx_cleanupq(sc, &sc->malo_txq[i]);
2135}
2136
2137int
2138malo_detach(struct malo_softc *sc)
2139{
2211 struct ifnet *ifp = sc->malo_ifp;
2212 struct ieee80211com *ic = ifp->if_l2com;
2140 struct ieee80211com *ic = &sc->malo_ic;
2213
2141
2214 DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags %x\n",
2215 __func__, ifp->if_flags);
2142 malo_stop(sc);
2216
2143
2217 malo_stop(ifp, 1);
2218
2219 if (sc->malo_tq != NULL) {
2220 taskqueue_drain(sc->malo_tq, &sc->malo_rxtask);
2221 taskqueue_drain(sc->malo_tq, &sc->malo_txtask);
2222 taskqueue_free(sc->malo_tq);
2223 sc->malo_tq = NULL;
2224 }
2225
2226 /*

--- 8 unchanged lines hidden (view full) ---

2235 * it last
2236 * Other than that, it's straightforward...
2237 */
2238 ieee80211_ifdetach(ic);
2239 callout_drain(&sc->malo_watchdog_timer);
2240 malo_dma_cleanup(sc);
2241 malo_tx_cleanup(sc);
2242 malo_hal_detach(sc->malo_mh);
2144 if (sc->malo_tq != NULL) {
2145 taskqueue_drain(sc->malo_tq, &sc->malo_rxtask);
2146 taskqueue_drain(sc->malo_tq, &sc->malo_txtask);
2147 taskqueue_free(sc->malo_tq);
2148 sc->malo_tq = NULL;
2149 }
2150
2151 /*

--- 8 unchanged lines hidden (view full) ---

2160 * it last
2161 * Other than that, it's straightforward...
2162 */
2163 ieee80211_ifdetach(ic);
2164 callout_drain(&sc->malo_watchdog_timer);
2165 malo_dma_cleanup(sc);
2166 malo_tx_cleanup(sc);
2167 malo_hal_detach(sc->malo_mh);
2243 if_free(ifp);
2244
2168 mbufq_drain(&sc->malo_snd);
2245 MALO_LOCK_DESTROY(sc);
2246
2247 return 0;
2248}
2249
2250void
2251malo_shutdown(struct malo_softc *sc)
2252{
2169 MALO_LOCK_DESTROY(sc);
2170
2171 return 0;
2172}
2173
2174void
2175malo_shutdown(struct malo_softc *sc)
2176{
2253 malo_stop(sc->malo_ifp, 1);
2177
2178 malo_stop(sc);
2254}
2255
2256void
2257malo_suspend(struct malo_softc *sc)
2258{
2179}
2180
2181void
2182malo_suspend(struct malo_softc *sc)
2183{
2259 struct ifnet *ifp = sc->malo_ifp;
2260
2184
2261 DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags %x\n",
2262 __func__, ifp->if_flags);
2263
2264 malo_stop(ifp, 1);
2185 malo_stop(sc);
2265}
2266
2267void
2268malo_resume(struct malo_softc *sc)
2269{
2186}
2187
2188void
2189malo_resume(struct malo_softc *sc)
2190{
2270 struct ifnet *ifp = sc->malo_ifp;
2271
2191
2272 DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags %x\n",
2273 __func__, ifp->if_flags);
2274
2275 if (ifp->if_flags & IFF_UP)
2192 if (sc->malo_ic.ic_nrunning > 0)
2276 malo_init(sc);
2277}
2193 malo_init(sc);
2194}