Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
/*-
 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
 *
 * Copyright (c) 2007 Marvell Semiconductor, Inc.
 * Copyright (c) 2007 Sam Leffler, Errno Consulting
 * Copyright (c) 2008 Weongyo Jeong <weongyo@freebsd.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
 *    redistribution must be conditioned upon including a substantially
 *    similar Disclaimer requirement for further binary redistribution.
 *
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGES.
 *
 * $FreeBSD$
 */

/*
 * Definitions for the Marvell 88W8335 Wireless LAN controller.
 */
#ifndef _DEV_MALO_H
#define _DEV_MALO_H

#include <net80211/ieee80211_radiotap.h>
#include <dev/malo/if_malohal.h>
#include <dev/malo/if_maloioctl.h>

#ifndef MALO_TXBUF
#define MALO_TXBUF		256	/* number of TX descriptors/buffers */
#endif
#ifndef MALO_RXBUF
#define MALO_RXBUF		256	/* number of RX descriptors/buffers */
#endif

#define	MALO_TXDESC		1	/* max tx descriptors/segments */

#define	MALO_RXSIZE		PAGE_SIZE
#define	MALO_RSSI_DUMMY_MARKER	127
#define	MALO_RSSI_EP_MULTIPLIER	(1<<7)	/* pow2 to optimize out * and / */

#define MALO_REG_INT_CODE			0x00000C14
/* From host to ARM */
#define MALO_REG_H2A_INTERRUPT_EVENTS		0x00000C18

/* bit definitions for MALO_REG_H2A_INTERRUPT_CAUSE */
#define MALO_H2ARIC_BIT_PPA_READY		0x00000001
#define MALO_H2ARIC_BIT_DOOR_BELL		0x00000002 /* bit 1 */
#define MALO_H2ARIC_BIT_PS			0x00000004
#define MALO_H2ARIC_BIT_PSPOLL			0x00000008 /* bit 3 */

/* From ARM to host */
#define MALO_REG_A2H_INTERRUPT_CAUSE		0x00000C30
#define MALO_REG_A2H_INTERRUPT_MASK		0x00000C34
#define MALO_REG_A2H_INTERRUPT_CLEAR_SEL	0x00000C38
#define MALO_REG_A2H_INTERRUPT_STATUS_MASK	0x00000C3C

/* bit definitions for MALO_REG_A2H_INTERRUPT_CAUSE */
#define MALO_A2HRIC_BIT_TX_DONE			0x00000001	/* bit 0 */
#define MALO_A2HRIC_BIT_RX_RDY			0x00000002	/* bit 1 */
#define MALO_A2HRIC_BIT_OPC_DONE		0x00000004
#define MALO_A2HRIC_BIT_MAC_EVENT		0x00000008
#define MALO_A2HRIC_BIT_RX_PROBLEM		0x00000010
#define MALO_A2HRIC_BIT_RADIO_OFF		0x00000020	/* bit 5 */
#define MALO_A2HRIC_BIT_RADIO_ON		0x00000040
#define MALO_A2HRIC_BIT_RADAR_DETECT		0x00000080
#define MALO_A2HRIC_BIT_ICV_ERROR		0x00000100
#define MALO_A2HRIC_BIT_MIC_ERROR		0x00000200	/* bit 9 */
#define MALO_A2HRIC_BIT_QUEUE_EMPTY		0x00000400
#define MALO_A2HRIC_BIT_QUEUE_FULL		0x00000800
#define MALO_A2HRIC_BIT_CHAN_SWITCH		0x00001000
#define MALO_A2HRIC_BIT_TX_WATCHDOG		0x00002000
#define MALO_A2HRIC_BIT_BA_WATCHDOG		0x00004000

#define MALO_ISR_SRC_BITS			\
	(MALO_A2HRIC_BIT_RX_RDY |		\
	 MALO_A2HRIC_BIT_TX_DONE |		\
	 MALO_A2HRIC_BIT_OPC_DONE |		\
	 MALO_A2HRIC_BIT_MAC_EVENT |		\
	 MALO_A2HRIC_BIT_MIC_ERROR |		\
	 MALO_A2HRIC_BIT_ICV_ERROR |		\
	 MALO_A2HRIC_BIT_RADAR_DETECT |		\
	 MALO_A2HRIC_BIT_CHAN_SWITCH |		\
	 MALO_A2HRIC_BIT_TX_WATCHDOG |		\
	 MALO_A2HRIC_BIT_QUEUE_EMPTY)
#define MALO_ISR_RESET				(1<<15)

#define MALO_A2HRIC_BIT_MASK			MALO_ISR_SRC_BITS

/* map to 0x80000000 on BAR1  */
#define MALO_REG_GEN_PTR			0x00000C10
#define MALO_REG_INT_CODE			0x00000C14
#define MALO_REG_SCRATCH			0x00000C40

/*
 * define OpMode for SoftAP/Station mode
 *
 * the following mode signature has to be written to PCI scratch register#0
 * right after successfully downloading the last block of firmware and
 * before waiting for firmware ready signature
 */
#define MALO_HOSTCMD_STA_MODE			0x5A
#define MALO_HOSTCMD_STA_FWRDY_SIGNATURE	0xF0F1F2F4

/*
 * 16 bit host command code
 */
#define MALO_HOSTCMD_NONE			0x0000
#define MALO_HOSTCMD_CODE_DNLD			0x0001
#define MALO_HOSTCMD_GET_HW_SPEC		0x0003
#define MALO_HOSTCMD_SET_HW_SPEC		0x0004
#define MALO_HOSTCMD_MAC_MULTICAST_ADR		0x0010
#define MALO_HOSTCMD_SET_WEPKEY			0x0013
#define MALO_HOSTCMD_802_11_RADIO_CONTROL	0x001c
#define MALO_HOSTCMD_802_11_RF_TX_POWER		0x001e
#define MALO_HOSTCMD_802_11_RF_ANTENNA		0x0020
#define MALO_HOSTCMD_SET_PRE_SCAN		0x0107
#define MALO_HOSTCMD_SET_POST_SCAN		0x0108
#define MALO_HOSTCMD_SET_RF_CHANNEL		0x010a
#define MALO_HOSTCMD_SET_AID			0x010d
#define MALO_HOSTCMD_SET_RATE			0x0110
#define MALO_HOSTCMD_SET_SLOT			0x0114
/* define DFS lab commands  */
#define MALO_HOSTCMD_SET_FIXED_RATE		0x0126 
#define MALO_HOSTCMD_SET_REGION_POWER		0x0128
#define MALO_HOSTCMD_GET_CALTABLE		0x1134

/*
 * definition of action or option for each command.
 */
/* define general purpose action  */
#define MALO_HOSTCMD_ACT_GEN_GET		0x0000
#define MALO_HOSTCMD_ACT_GEN_SET		0x0001
#define MALO_HOSTCMD_ACT_GEN_SET_LIST		0x0002

/* define action or option for HostCmd_FW_USE_FIXED_RATE */
#define MALO_HOSTCMD_ACT_USE_FIXED_RATE		0x0001
#define MALO_HOSTCMD_ACT_NOT_USE_FIXED_RATE	0x0002

/* INT code register event definition  */
#define MALO_INT_CODE_CMD_FINISHED		0x00000005

struct malo_cmd_header {
	uint16_t		cmd;
	uint16_t		length;
	uint16_t		seqnum;
	uint16_t		result; 
} __packed;  

struct malo_cmd_caltable {
	struct malo_cmd_header	cmdhdr;
	uint8_t			annex; 
	uint8_t			index;
	uint8_t			len;
	uint8_t			reserverd; 
#define MALO_CAL_TBL_SIZE	160
	uint8_t			caltbl[MALO_CAL_TBL_SIZE];
} __packed;

struct malo_cmd_get_hwspec {
	struct malo_cmd_header	cmdhdr;
	u_int8_t		version;	/* version of the HW  */
	u_int8_t		hostif;		/* host interface  */
	/* Max. number of WCB FW can handle  */
	u_int16_t		num_wcb;
	/* MaxNbr of MC addresses FW can handle */
	u_int16_t		num_mcastaddr;
	/* MAC address programmed in HW */
	u_int8_t		permaddr[6];
	u_int16_t		regioncode;
	/* Number of antenna used */
	u_int16_t		num_antenna;
	/* 4 byte of FW release number */
	u_int32_t		fw_releasenum;
	u_int32_t		wcbbase0;
	u_int32_t		rxpdwr_ptr;
	u_int32_t		rxpdrd_ptr;
	u_int32_t		ul_fw_awakecookie;
	u_int32_t		wcbbase1;
	u_int32_t		wcbbase2;
	u_int32_t		wcbbase3;
} __packed;

struct malo_cmd_set_hwspec {
	struct malo_cmd_header	cmdhdr;
	uint8_t			version;	/* HW revision */
	uint8_t			hostif;		/* Host interface */
	/* Max. number of Multicast address FW can handle */
	uint16_t		num_mcastaddr;
	uint8_t			permaddr[6];	/* MAC address */
	uint16_t		regioncode;	/* Region Code */
	/* 4 byte of FW release number */
	uint32_t		fwreleasenum;
	/* Firmware awake cookie */
	uint32_t		ul_fw_awakecookie;
	/* Device capabilities (see above) */
	uint32_t		devicecaps;
	uint32_t		rxpdwrptr;	/* Rx shared memory queue  */
	/* # TX queues in WcbBase array */
	uint32_t		num_txqueues;
	/* TX WCB Rings */
	uint32_t		wcbbase[MALO_MAX_TXWCB_QUEUES];
	uint32_t		flags;
	uint32_t		txwcbnum_per_queue;
	uint32_t		total_rxwcb;
} __packed;

/* DS 802.11 */
struct malo_cmd_rf_antenna {
	struct malo_cmd_header	cmdhdr;
	uint16_t		action;
	/* Number of antennas or 0xffff (diversity)  */
	uint16_t		mode;
} __packed;

struct malo_cmd_radio_control {
	struct malo_cmd_header	cmdhdr;
	uint16_t		action;                   
	/*
	 * bit 0 : 1 = on, 0 = off
	 * bit 1 : 1 = long, 0 = short
	 * bit 2 : 1 = auto, 0 = fix
	 */
	uint16_t		control;
	uint16_t		radio_on;
} __packed;

struct malo_cmd_fw_set_wmmmode {
	struct malo_cmd_header	cmdhdr;
	uint16_t		action;	/* 0 -> unset, 1 -> set  */
} __packed;

struct malo_cmd_fw_set_rf_channel {
	struct malo_cmd_header	cmdhdr;
	uint16_t		action;
	uint8_t			cur_channel;	/* channel # */
} __packed;

#define MALO_TX_POWER_LEVEL_TOTAL	8
struct malo_cmd_rf_tx_power {
	struct malo_cmd_header	cmdhdr;
	uint16_t		action;
	uint16_t		support_txpower_level;
	uint16_t		current_txpower_level;
	uint16_t		reserved;
	uint16_t		power_levellist[MALO_TX_POWER_LEVEL_TOTAL];
} __packed;

struct malo_fixrate_flag {
	/* lower rate after the retry count.  0 = legacy, 1 = HT  */
	uint32_t		type;
	/* 0: retry count is not valid, 1: use retry count specified  */
	uint32_t		retrycount_valid;
} __packed;

struct malo_fixed_rate_entry {
	struct malo_fixrate_flag typeflags;
	/* legacy rate(not index) or an MCS code.  */
	uint32_t		fixedrate;
	uint32_t		retrycount;
} __packed;

struct malo_cmd_fw_use_fixed_rate {
	struct malo_cmd_header	cmdhdr;
	/*
	 * MALO_HOSTCMD_ACT_GEN_GET	0x0000
	 * MALO_HOSTCMD_ACT_GEN_SET	0x0001
	 * MALO_HOSTCMD_ACT_NOT_USE_FIXED_RATE	0x0002
	 */
	uint32_t		action;
	/* use fixed rate specified but firmware can drop to  */
	uint32_t		allowratedrop;
	uint32_t		entrycount;
	struct malo_fixed_rate_entry fixedrate_table[4];
	uint8_t			multicast_rate;
	uint8_t			multirate_txtype;
	uint8_t			management_rate;
} __packed;

#define MALO_RATE_INDEX_MAX_ARRAY		14

struct malo_cmd_fw_set_aid {
	struct malo_cmd_header	cmdhdr;
	uint16_t		associd;
	uint8_t			macaddr[6];	/* AP's Mac Address(BSSID) */
	uint32_t		gprotection;
	uint8_t			aprates[MALO_RATE_INDEX_MAX_ARRAY];
} __packed;

struct malo_cmd_prescan {
	struct malo_cmd_header	cmdhdr;
} __packed;

struct malo_cmd_postscan {
	struct malo_cmd_header	cmdhdr;
	uint32_t		isibss;
	uint8_t			bssid[6];
} __packed;

struct malo_cmd_fw_setslot {
	struct malo_cmd_header	cmdhdr;
	uint16_t		action;
	/* slot = 0 if regular, slot = 1 if short.  */
	uint8_t			slot;
};

struct malo_cmd_set_rate {
	struct malo_cmd_header	cmdhdr;
	uint8_t			dataratetype;
	uint8_t			rateindex;
	uint8_t			aprates[14];
} __packed;

struct malo_cmd_wepkey {
	struct malo_cmd_header	cmdhdr;
	uint16_t		action;
	uint8_t			len;
	uint8_t			flags;
	uint16_t		index;
	uint8_t			value[IEEE80211_KEYBUF_SIZE];
	uint8_t			txmickey[IEEE80211_WEP_MICLEN];
	uint8_t			rxmickey[IEEE80211_WEP_MICLEN];
	uint64_t		rxseqctr;
	uint64_t		txseqctr;
} __packed;

struct malo_cmd_mcast {
	struct malo_cmd_header	cmdhdr;
	uint16_t		action;
	uint16_t		numaddr;
#define	MALO_HAL_MCAST_MAX	32
	uint8_t			maclist[6*32];
} __packed;

/*
 * DMA state for tx/rx descriptors.
 */

/*
 * Common "base class" for tx/rx descriptor resources
 * allocated using the bus dma api.
 */
struct malo_descdma {
	const char*		dd_name;
	void			*dd_desc;	/* descriptors */
	bus_addr_t		dd_desc_paddr;	/* physical addr of dd_desc */
	bus_size_t		dd_desc_len;	/* size of dd_desc */
	bus_dma_segment_t	dd_dseg;
	int			dd_dnseg;	/* number of segments */
	bus_dma_tag_t		dd_dmat;	/* bus DMA tag */
	bus_dmamap_t		dd_dmamap;	/* DMA map for descriptors */
	void			*dd_bufptr;	/* associated buffers */
};

/*
 * Hardware tx/rx descriptors.
 *
 * NB: tx descriptor size must match f/w expected size
 * because f/w prefetch's the next descriptor linearly
 * and doesn't chase the next pointer.
 */
struct malo_txdesc {
	uint32_t		status;
#define	MALO_TXD_STATUS_IDLE			0x00000000
#define	MALO_TXD_STATUS_USED			0x00000001 
#define	MALO_TXD_STATUS_OK			0x00000001
#define	MALO_TXD_STATUS_OK_RETRY		0x00000002
#define	MALO_TXD_STATUS_OK_MORE_RETRY		0x00000004
#define	MALO_TXD_STATUS_MULTICAST_TX		0x00000008
#define	MALO_TXD_STATUS_BROADCAST_TX		0x00000010
#define	MALO_TXD_STATUS_FAILED_LINK_ERROR	0x00000020
#define	MALO_TXD_STATUS_FAILED_EXCEED_LIMIT	0x00000040
#define	MALO_TXD_STATUS_FAILED_XRETRY	MALO_TXD_STATUS_FAILED_EXCEED_LIMIT
#define	MALO_TXD_STATUS_FAILED_AGING		0x00000080
#define	MALO_TXD_STATUS_FW_OWNED		0x80000000
	uint8_t			datarate;
	uint8_t			txpriority;
	uint16_t		qosctrl;
	uint32_t		pktptr;
	uint16_t		pktlen;
	uint8_t			destaddr[6];
	uint32_t		physnext;
	uint32_t		sap_pktinfo;
	uint16_t		format;
#define	MALO_TXD_FORMAT		0x0001	/* frame format/rate */
#define	MALO_TXD_FORMAT_LEGACY	0x0000	/* legacy rate frame */
#define	MALO_TXD_RATE		0x01f8	/* tx rate (legacy)/ MCS */
#define	MALO_TXD_RATE_S		3
/* NB: 3 is reserved */
#define	MALO_TXD_ANTENNA	0x1800	/* antenna select */
#define	MALO_TXD_ANTENNA_S	11
	uint16_t		pad;	/* align to 4-byte boundary */
} __packed;

#define	MALO_TXDESC_SYNC(txq, ds, how) do {				\
	bus_dmamap_sync((txq)->dma.dd_dmat, (txq)->dma.dd_dmamap, how);	\
} while(0)

struct malo_rxdesc {
	uint8_t		rxcontrol;	/* control element */
#define	MALO_RXD_CTRL_DRIVER_OWN		0x00
#define	MALO_RXD_CTRL_OS_OWN			0x04
#define	MALO_RXD_CTRL_DMA_OWN			0x80
	uint8_t		snr;		/* signal to noise ratio */
	uint8_t		status;		/* status field w/ USED bit */
#define	MALO_RXD_STATUS_IDLE			0x00
#define	MALO_RXD_STATUS_OK			0x01
#define	MALO_RXD_STATUS_MULTICAST_RX		0x02
#define	MALO_RXD_STATUS_BROADCAST_RX		0x04
#define	MALO_RXD_STATUS_FRAGMENT_RX		0x08
#define	MALO_RXD_STATUS_GENERAL_DECRYPT_ERR	0xff
#define	MALO_RXD_STATUS_DECRYPT_ERR_MASK	0x80
#define	MALO_RXD_STATUS_TKIP_MIC_DECRYPT_ERR	0x02
#define	MALO_RXD_STATUS_WEP_ICV_DECRYPT_ERR	0x04
#define	MALO_RXD_STATUS_TKIP_ICV_DECRYPT_ERR	0x08
	uint8_t		channel;	/* channel # pkt received on */
	uint16_t	pktlen;		/* total length of received data */
	uint8_t		nf;		/* noise floor */
	uint8_t		rate;		/* received data rate */
	uint32_t	physbuffdata;	/* physical address of payload data */
	uint32_t	physnext;	/* physical address of next RX desc */ 
	uint16_t	qosctrl;	/* received QosCtrl field variable */
	uint16_t	htsig2;		/* like name states */
} __packed;

#define	MALO_RXDESC_SYNC(sc, ds, how) do {				\
	bus_dmamap_sync((sc)->malo_rxdma.dd_dmat,			\
	    (sc)->malo_rxdma.dd_dmamap, how);				\
} while (0)

struct malo_rxbuf {
	STAILQ_ENTRY(malo_rxbuf) bf_list;
	void			*bf_desc;	/* h/w descriptor */
	bus_addr_t		bf_daddr;	/* physical addr of desc */
	bus_dmamap_t		bf_dmamap;
	bus_addr_t		bf_data;	/* physical addr of rx data */
	struct mbuf		*bf_m;		/* jumbo mbuf */
};
typedef STAILQ_HEAD(, malo_rxbuf) malo_rxbufhead;

/*
 * Software backed version of tx/rx descriptors.  We keep
 * the software state out of the h/w descriptor structure
 * so that may be allocated in uncached memory w/o paying
 * performance hit.
 */
struct malo_txbuf {
	STAILQ_ENTRY(malo_txbuf) bf_list;
	void			*bf_desc;	/* h/w descriptor */
	bus_addr_t		bf_daddr;	/* physical addr of desc */
	bus_dmamap_t		bf_dmamap;	/* DMA map for descriptors */
	int			bf_nseg;
	bus_dma_segment_t	bf_segs[MALO_TXDESC];
	struct mbuf		*bf_m;
	struct ieee80211_node	*bf_node;
	struct malo_txq		*bf_txq;	/* backpointer to tx q/ring */
};
typedef STAILQ_HEAD(, malo_txbuf) malo_txbufhead;

/*
 * TX/RX ring definitions.  There are 4 tx rings, one
 * per AC, and 1 rx ring.  Note carefully that transmit
 * descriptors are treated as a contiguous chunk and the
 * firmware pre-fetches descriptors.  This means that we
 * must preserve order when moving descriptors between
 * the active+free lists; otherwise we may stall transmit.
 */
struct malo_txq {
	struct malo_descdma	dma;		/* bus dma resources */
	struct mtx		lock;		/* tx q lock */
	char			name[12];	/* e.g. "malo0_txq4" */
	int			qnum;		/* f/w q number */
	int			txpri;		/* f/w tx priority */
	int			nfree;		/* # buffers on free list */
	malo_txbufhead		free;		/* queue of free buffers */
	malo_txbufhead		active;		/* queue of active buffers */
};

#define	MALO_TXQ_LOCK_INIT(_sc, _tq) do { \
	snprintf((_tq)->name, sizeof((_tq)->name), "%s_txq%u", \
		device_get_nameunit((_sc)->malo_dev), (_tq)->qnum); \
	mtx_init(&(_tq)->lock, (_tq)->name, NULL, MTX_DEF); \
} while (0)
#define	MALO_TXQ_LOCK_DESTROY(_tq)	mtx_destroy(&(_tq)->lock)
#define	MALO_TXQ_LOCK(_tq)		mtx_lock(&(_tq)->lock)
#define	MALO_TXQ_UNLOCK(_tq)		mtx_unlock(&(_tq)->lock)
#define	MALO_TXQ_LOCK_ASSERT(_tq)	mtx_assert(&(_tq)->lock, MA_OWNED)

/*
 * Each packet has fixed front matter: a 2-byte length
 * of the payload, followed by a 4-address 802.11 header
 * (regardless of the actual header and always w/o any
 * QoS header).  The payload then follows.
 */
struct malo_txrec {
	uint16_t fwlen;
	struct ieee80211_frame_addr4 wh;
} __packed;

struct malo_vap {
	struct ieee80211vap malo_vap;
	int			(*malo_newstate)(struct ieee80211vap *,
				    enum ieee80211_state, int);
};
#define	MALO_VAP(vap)	((struct malo_vap *)(vap))

struct malo_softc {
	struct ieee80211com	malo_ic;
	struct mbufq		malo_snd;
	device_t		malo_dev;
	struct mtx		malo_mtx;	/* master lock (recursive) */
	struct taskqueue	*malo_tq;	/* private task queue */

	bus_dma_tag_t		malo_dmat;	/* bus DMA tag */
	bus_space_handle_t	malo_io0h;	/* BAR 0 */
	bus_space_tag_t		malo_io0t;
	bus_space_handle_t	malo_io1h;	/* BAR 1 */
	bus_space_tag_t		malo_io1t;

	unsigned int		malo_invalid: 1,/* disable hardware accesses */
				malo_recvsetup: 1,	/* recv setup */
				malo_fixedrate: 1,	/* use fixed tx rate */
				malo_running: 1;

	struct malo_hal		*malo_mh;	/* h/w access layer */
	struct malo_hal_hwspec	malo_hwspecs;	/* h/w capabilities */
	struct malo_hal_txrxdma	malo_hwdma;	/* h/w dma setup */
	uint32_t		malo_imask;	/* interrupt mask copy */
	struct malo_hal_channel	malo_curchan;
	u_int16_t		malo_rxantenna;	/* rx antenna */
	u_int16_t		malo_txantenna;	/* tx antenna */

	struct malo_descdma	malo_rxdma;	/* rx bus dma resources */
	malo_rxbufhead		malo_rxbuf;	/* rx buffers */
	struct malo_rxbuf	*malo_rxnext;	/* next rx buffer to process */
	struct task		malo_rxtask;	/* rx int processing */

	struct malo_txq		malo_txq[MALO_NUM_TX_QUEUES];
	struct task		malo_txtask;	/* tx int processing */
	struct callout	malo_watchdog_timer;
	int			malo_timer;

	struct malo_tx_radiotap_header malo_tx_th;
	struct malo_rx_radiotap_header malo_rx_th;

	struct malo_stats	malo_stats;	/* interface statistics */
	int			malo_debug;
};

#define	MALO_LOCK_INIT(_sc) \
	mtx_init(&(_sc)->malo_mtx, device_get_nameunit((_sc)->malo_dev), \
		 NULL, MTX_DEF | MTX_RECURSE)
#define	MALO_LOCK_DESTROY(_sc)		mtx_destroy(&(_sc)->malo_mtx)
#define	MALO_LOCK(_sc)			mtx_lock(&(_sc)->malo_mtx)
#define	MALO_UNLOCK(_sc)		mtx_unlock(&(_sc)->malo_mtx)
#define	MALO_LOCK_ASSERT(_sc)		mtx_assert(&(_sc)->malo_mtx, MA_OWNED)

#define	MALO_RXFREE_INIT(_sc)						\
	mtx_init(&(_sc)->malo_rxlock, device_get_nameunit((_sc)->malo_dev), \
		 NULL, MTX_DEF)
#define	MALO_RXFREE_DESTROY(_sc)	mtx_destroy(&(_sc)->malo_rxlock)
#define	MALO_RXFREE_LOCK(_sc)		mtx_lock(&(_sc)->malo_rxlock)
#define	MALO_RXFREE_UNLOCK(_sc)		mtx_unlock(&(_sc)->malo_rxlock)
#define	MALO_RXFREE_ASSERT(_sc)		mtx_assert(&(_sc)->malo_rxlock, \
	MA_OWNED)

int	malo_attach(uint16_t, struct malo_softc *);
int	malo_intr(void *);
int	malo_detach(struct malo_softc *);
void	malo_shutdown(struct malo_softc *);
void	malo_suspend(struct malo_softc *);
void	malo_resume(struct malo_softc *);

#endif