1177595Sweongyo/*-
2177595Sweongyo * Copyright (c) 2007 Marvell Semiconductor, Inc.
3177595Sweongyo * Copyright (c) 2007 Sam Leffler, Errno Consulting
4177595Sweongyo * Copyright (c) 2008 Weongyo Jeong <weongyo@freebsd.org>
5177595Sweongyo * All rights reserved.
6177595Sweongyo *
7177595Sweongyo * Redistribution and use in source and binary forms, with or without
8177595Sweongyo * modification, are permitted provided that the following conditions
9177595Sweongyo * are met:
10177595Sweongyo * 1. Redistributions of source code must retain the above copyright
11177595Sweongyo *    notice, this list of conditions and the following disclaimer,
12177595Sweongyo *    without modification.
13177595Sweongyo * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14177595Sweongyo *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
15177595Sweongyo *    redistribution must be conditioned upon including a substantially
16177595Sweongyo *    similar Disclaimer requirement for further binary redistribution.
17177595Sweongyo *
18177595Sweongyo * NO WARRANTY
19177595Sweongyo * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20177595Sweongyo * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21177595Sweongyo * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
22177595Sweongyo * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23177595Sweongyo * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
24177595Sweongyo * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25177595Sweongyo * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26177595Sweongyo * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27177595Sweongyo * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28177595Sweongyo * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
29177595Sweongyo * THE POSSIBILITY OF SUCH DAMAGES.
30177595Sweongyo *
31177595Sweongyo * $FreeBSD$
32177595Sweongyo */
33177595Sweongyo
34177595Sweongyo/*
35177595Sweongyo * Definitions for the Marvell 88W8335 Wireless LAN controller.
36177595Sweongyo */
37177595Sweongyo#ifndef _DEV_MALO_H
38177595Sweongyo#define _DEV_MALO_H
39177595Sweongyo
40177595Sweongyo#include <net80211/ieee80211_radiotap.h>
41177595Sweongyo#include <dev/malo/if_malohal.h>
42177595Sweongyo#include <dev/malo/if_maloioctl.h>
43177595Sweongyo
44177595Sweongyo#ifndef MALO_TXBUF
45177595Sweongyo#define MALO_TXBUF		256	/* number of TX descriptors/buffers */
46177595Sweongyo#endif
47177595Sweongyo#ifndef MALO_RXBUF
48177595Sweongyo#define MALO_RXBUF		256	/* number of RX descriptors/buffers */
49177595Sweongyo#endif
50177595Sweongyo
51177595Sweongyo#define	MALO_TXDESC		1	/* max tx descriptors/segments */
52177595Sweongyo
53177595Sweongyo#define	MALO_RXSIZE		PAGE_SIZE
54177595Sweongyo#define	MALO_RSSI_DUMMY_MARKER	127
55177595Sweongyo#define	MALO_RSSI_EP_MULTIPLIER	(1<<7)	/* pow2 to optimize out * and / */
56177595Sweongyo
57177595Sweongyo#define MALO_REG_INT_CODE			0x00000C14
58177595Sweongyo/* From host to ARM */
59177595Sweongyo#define MALO_REG_H2A_INTERRUPT_EVENTS		0x00000C18
60177595Sweongyo
61177595Sweongyo/* bit definitions for MALO_REG_H2A_INTERRUPT_CAUSE */
62177595Sweongyo#define MALO_H2ARIC_BIT_PPA_READY		0x00000001
63177595Sweongyo#define MALO_H2ARIC_BIT_DOOR_BELL		0x00000002 /* bit 1 */
64177595Sweongyo#define MALO_H2ARIC_BIT_PS			0x00000004
65177595Sweongyo#define MALO_H2ARIC_BIT_PSPOLL			0x00000008 /* bit 3 */
66177595Sweongyo
67177595Sweongyo/* From ARM to host */
68177595Sweongyo#define MALO_REG_A2H_INTERRUPT_CAUSE		0x00000C30
69177595Sweongyo#define MALO_REG_A2H_INTERRUPT_MASK		0x00000C34
70177595Sweongyo#define MALO_REG_A2H_INTERRUPT_CLEAR_SEL	0x00000C38
71177595Sweongyo#define MALO_REG_A2H_INTERRUPT_STATUS_MASK	0x00000C3C
72177595Sweongyo
73177595Sweongyo/* bit definitions for MALO_REG_A2H_INTERRUPT_CAUSE */
74177595Sweongyo#define MALO_A2HRIC_BIT_TX_DONE			0x00000001	/* bit 0 */
75177595Sweongyo#define MALO_A2HRIC_BIT_RX_RDY			0x00000002	/* bit 1 */
76177595Sweongyo#define MALO_A2HRIC_BIT_OPC_DONE		0x00000004
77177595Sweongyo#define MALO_A2HRIC_BIT_MAC_EVENT		0x00000008
78177595Sweongyo#define MALO_A2HRIC_BIT_RX_PROBLEM		0x00000010
79177595Sweongyo#define MALO_A2HRIC_BIT_RADIO_OFF		0x00000020	/* bit 5 */
80177595Sweongyo#define MALO_A2HRIC_BIT_RADIO_ON		0x00000040
81177595Sweongyo#define MALO_A2HRIC_BIT_RADAR_DETECT		0x00000080
82177595Sweongyo#define MALO_A2HRIC_BIT_ICV_ERROR		0x00000100
83177595Sweongyo#define MALO_A2HRIC_BIT_MIC_ERROR		0x00000200	/* bit 9 */
84177595Sweongyo#define MALO_A2HRIC_BIT_QUEUE_EMPTY		0x00000400
85177595Sweongyo#define MALO_A2HRIC_BIT_QUEUE_FULL		0x00000800
86177595Sweongyo#define MALO_A2HRIC_BIT_CHAN_SWITCH		0x00001000
87177595Sweongyo#define MALO_A2HRIC_BIT_TX_WATCHDOG		0x00002000
88177595Sweongyo#define MALO_A2HRIC_BIT_BA_WATCHDOG		0x00004000
89177595Sweongyo
90177595Sweongyo#define MALO_ISR_SRC_BITS			\
91177595Sweongyo	(MALO_A2HRIC_BIT_RX_RDY |		\
92177595Sweongyo	 MALO_A2HRIC_BIT_TX_DONE |		\
93177595Sweongyo	 MALO_A2HRIC_BIT_OPC_DONE |		\
94177595Sweongyo	 MALO_A2HRIC_BIT_MAC_EVENT |		\
95177595Sweongyo	 MALO_A2HRIC_BIT_MIC_ERROR |		\
96177595Sweongyo	 MALO_A2HRIC_BIT_ICV_ERROR |		\
97177595Sweongyo	 MALO_A2HRIC_BIT_RADAR_DETECT |		\
98177595Sweongyo	 MALO_A2HRIC_BIT_CHAN_SWITCH |		\
99177595Sweongyo	 MALO_A2HRIC_BIT_TX_WATCHDOG |		\
100177595Sweongyo	 MALO_A2HRIC_BIT_QUEUE_EMPTY)
101177595Sweongyo#define MALO_ISR_RESET				(1<<15)
102177595Sweongyo
103177595Sweongyo#define MALO_A2HRIC_BIT_MASK			MALO_ISR_SRC_BITS
104177595Sweongyo
105177595Sweongyo/* map to 0x80000000 on BAR1  */
106177595Sweongyo#define MALO_REG_GEN_PTR			0x00000C10
107177595Sweongyo#define MALO_REG_INT_CODE			0x00000C14
108177595Sweongyo#define MALO_REG_SCRATCH			0x00000C40
109177595Sweongyo
110177595Sweongyo/*
111177595Sweongyo * define OpMode for SoftAP/Station mode
112177595Sweongyo *
113177595Sweongyo * the following mode signature has to be written to PCI scratch register#0
114177595Sweongyo * right after successfully downloading the last block of firmware and
115177595Sweongyo * before waiting for firmware ready signature
116177595Sweongyo */
117177595Sweongyo#define MALO_HOSTCMD_STA_MODE			0x5A
118177595Sweongyo#define MALO_HOSTCMD_STA_FWRDY_SIGNATURE	0xF0F1F2F4
119177595Sweongyo
120177595Sweongyo/*
121177595Sweongyo * 16 bit host command code
122177595Sweongyo */
123177595Sweongyo#define MALO_HOSTCMD_NONE			0x0000
124177595Sweongyo#define MALO_HOSTCMD_CODE_DNLD			0x0001
125177595Sweongyo#define MALO_HOSTCMD_GET_HW_SPEC		0x0003
126177595Sweongyo#define MALO_HOSTCMD_SET_HW_SPEC		0x0004
127177595Sweongyo#define MALO_HOSTCMD_MAC_MULTICAST_ADR		0x0010
128177595Sweongyo#define MALO_HOSTCMD_SET_WEPKEY			0x0013
129177595Sweongyo#define MALO_HOSTCMD_802_11_RADIO_CONTROL	0x001c
130177595Sweongyo#define MALO_HOSTCMD_802_11_RF_TX_POWER		0x001e
131177595Sweongyo#define MALO_HOSTCMD_802_11_RF_ANTENNA		0x0020
132177595Sweongyo#define MALO_HOSTCMD_SET_PRE_SCAN		0x0107
133177595Sweongyo#define MALO_HOSTCMD_SET_POST_SCAN		0x0108
134177595Sweongyo#define MALO_HOSTCMD_SET_RF_CHANNEL		0x010a
135177595Sweongyo#define MALO_HOSTCMD_SET_AID			0x010d
136177595Sweongyo#define MALO_HOSTCMD_SET_RATE			0x0110
137177595Sweongyo#define MALO_HOSTCMD_SET_SLOT			0x0114
138177595Sweongyo/* define DFS lab commands  */
139177595Sweongyo#define MALO_HOSTCMD_SET_FIXED_RATE		0x0126
140177595Sweongyo#define MALO_HOSTCMD_SET_REGION_POWER		0x0128
141177595Sweongyo#define MALO_HOSTCMD_GET_CALTABLE		0x1134
142177595Sweongyo
143177595Sweongyo/*
144177595Sweongyo * definition of action or option for each command.
145177595Sweongyo */
146177595Sweongyo/* define general purpose action  */
147177595Sweongyo#define MALO_HOSTCMD_ACT_GEN_GET		0x0000
148177595Sweongyo#define MALO_HOSTCMD_ACT_GEN_SET		0x0001
149177595Sweongyo#define MALO_HOSTCMD_ACT_GEN_SET_LIST		0x0002
150177595Sweongyo
151177595Sweongyo/* define action or option for HostCmd_FW_USE_FIXED_RATE */
152177595Sweongyo#define MALO_HOSTCMD_ACT_USE_FIXED_RATE		0x0001
153177595Sweongyo#define MALO_HOSTCMD_ACT_NOT_USE_FIXED_RATE	0x0002
154177595Sweongyo
155177595Sweongyo/* INT code register event definition  */
156177595Sweongyo#define MALO_INT_CODE_CMD_FINISHED		0x00000005
157177595Sweongyo
158177595Sweongyostruct malo_cmd_header {
159177595Sweongyo	uint16_t		cmd;
160177595Sweongyo	uint16_t		length;
161177595Sweongyo	uint16_t		seqnum;
162177595Sweongyo	uint16_t		result;
163177595Sweongyo} __packed;
164177595Sweongyo
165177595Sweongyostruct malo_cmd_caltable {
166177595Sweongyo	struct malo_cmd_header	cmdhdr;
167177595Sweongyo	uint8_t			annex;
168177595Sweongyo	uint8_t			index;
169177595Sweongyo	uint8_t			len;
170177595Sweongyo	uint8_t			reserverd;
171177595Sweongyo#define MALO_CAL_TBL_SIZE	160
172177595Sweongyo	uint8_t			caltbl[MALO_CAL_TBL_SIZE];
173177595Sweongyo} __packed;
174177595Sweongyo
175177595Sweongyostruct malo_cmd_get_hwspec {
176177595Sweongyo	struct malo_cmd_header	cmdhdr;
177177595Sweongyo	u_int8_t		version;	/* version of the HW  */
178177595Sweongyo	u_int8_t		hostif;		/* host interface  */
179177595Sweongyo	/* Max. number of WCB FW can handle  */
180177595Sweongyo	u_int16_t		num_wcb;
181177595Sweongyo	/* MaxNbr of MC addresses FW can handle */
182177595Sweongyo	u_int16_t		num_mcastaddr;
183177595Sweongyo	/* MAC address programmed in HW */
184177595Sweongyo	u_int8_t		permaddr[6];
185177595Sweongyo	u_int16_t		regioncode;
186177595Sweongyo	/* Number of antenna used */
187177595Sweongyo	u_int16_t		num_antenna;
188177595Sweongyo	/* 4 byte of FW release number */
189177595Sweongyo	u_int32_t		fw_releasenum;
190177595Sweongyo	u_int32_t		wcbbase0;
191177595Sweongyo	u_int32_t		rxpdwr_ptr;
192177595Sweongyo	u_int32_t		rxpdrd_ptr;
193177595Sweongyo	u_int32_t		ul_fw_awakecookie;
194177595Sweongyo	u_int32_t		wcbbase1;
195177595Sweongyo	u_int32_t		wcbbase2;
196177595Sweongyo	u_int32_t		wcbbase3;
197177595Sweongyo} __packed;
198177595Sweongyo
199177595Sweongyostruct malo_cmd_set_hwspec {
200177595Sweongyo	struct malo_cmd_header	cmdhdr;
201177595Sweongyo	uint8_t			version;	/* HW revision */
202177595Sweongyo	uint8_t			hostif;		/* Host interface */
203177595Sweongyo	/* Max. number of Multicast address FW can handle */
204177595Sweongyo	uint16_t		num_mcastaddr;
205177595Sweongyo	uint8_t			permaddr[6];	/* MAC address */
206177595Sweongyo	uint16_t		regioncode;	/* Region Code */
207177595Sweongyo	/* 4 byte of FW release number */
208177595Sweongyo	uint32_t		fwreleasenum;
209177595Sweongyo	/* Firmware awake cookie */
210177595Sweongyo	uint32_t		ul_fw_awakecookie;
211177595Sweongyo	/* Device capabilities (see above) */
212177595Sweongyo	uint32_t		devicecaps;
213177595Sweongyo	uint32_t		rxpdwrptr;	/* Rx shared memory queue  */
214177595Sweongyo	/* # TX queues in WcbBase array */
215177595Sweongyo	uint32_t		num_txqueues;
216177595Sweongyo	/* TX WCB Rings */
217177595Sweongyo	uint32_t		wcbbase[MALO_MAX_TXWCB_QUEUES];
218177595Sweongyo	uint32_t		flags;
219177595Sweongyo	uint32_t		txwcbnum_per_queue;
220177595Sweongyo	uint32_t		total_rxwcb;
221177595Sweongyo} __packed;
222177595Sweongyo
223177595Sweongyo/* DS 802.11 */
224177595Sweongyostruct malo_cmd_rf_antenna {
225177595Sweongyo	struct malo_cmd_header	cmdhdr;
226177595Sweongyo	uint16_t		action;
227177595Sweongyo	/* Number of antennas or 0xffff (diversity)  */
228177595Sweongyo	uint16_t		mode;
229177595Sweongyo} __packed;
230177595Sweongyo
231177595Sweongyostruct malo_cmd_radio_control {
232177595Sweongyo	struct malo_cmd_header	cmdhdr;
233177595Sweongyo	uint16_t		action;
234177595Sweongyo	/*
235177595Sweongyo	 * bit 0 : 1 = on, 0 = off
236177595Sweongyo	 * bit 1 : 1 = long, 0 = short
237177595Sweongyo	 * bit 2 : 1 = auto, 0 = fix
238177595Sweongyo	 */
239177595Sweongyo	uint16_t		control;
240177595Sweongyo	uint16_t		radio_on;
241177595Sweongyo} __packed;
242177595Sweongyo
243177595Sweongyostruct malo_cmd_fw_set_wmmmode {
244177595Sweongyo	struct malo_cmd_header	cmdhdr;
245177595Sweongyo	uint16_t		action;	/* 0 -> unset, 1 -> set  */
246177595Sweongyo} __packed;
247177595Sweongyo
248177595Sweongyostruct malo_cmd_fw_set_rf_channel {
249177595Sweongyo	struct malo_cmd_header	cmdhdr;
250177595Sweongyo	uint16_t		action;
251177595Sweongyo	uint8_t			cur_channel;	/* channel # */
252177595Sweongyo} __packed;
253177595Sweongyo
254177595Sweongyo#define MALO_TX_POWER_LEVEL_TOTAL	8
255177595Sweongyostruct malo_cmd_rf_tx_power {
256177595Sweongyo	struct malo_cmd_header	cmdhdr;
257177595Sweongyo	uint16_t		action;
258177595Sweongyo	uint16_t		support_txpower_level;
259177595Sweongyo	uint16_t		current_txpower_level;
260177595Sweongyo	uint16_t		reserved;
261177595Sweongyo	uint16_t		power_levellist[MALO_TX_POWER_LEVEL_TOTAL];
262177595Sweongyo} __packed;
263177595Sweongyo
264177595Sweongyostruct malo_fixrate_flag {
265177595Sweongyo	/* lower rate after the retry count.  0 = legacy, 1 = HT  */
266177595Sweongyo	uint32_t		type;
267177595Sweongyo	/* 0: retry count is not valid, 1: use retry count specified  */
268177595Sweongyo	uint32_t		retrycount_valid;
269177595Sweongyo} __packed;
270177595Sweongyo
271177595Sweongyostruct malo_fixed_rate_entry {
272177595Sweongyo	struct malo_fixrate_flag typeflags;
273177595Sweongyo	/* legacy rate(not index) or an MCS code.  */
274177595Sweongyo	uint32_t		fixedrate;
275177595Sweongyo	uint32_t		retrycount;
276177595Sweongyo} __packed;
277177595Sweongyo
278177595Sweongyostruct malo_cmd_fw_use_fixed_rate {
279177595Sweongyo	struct malo_cmd_header	cmdhdr;
280177595Sweongyo	/*
281177595Sweongyo	 * MALO_HOSTCMD_ACT_GEN_GET	0x0000
282177595Sweongyo	 * MALO_HOSTCMD_ACT_GEN_SET	0x0001
283177595Sweongyo	 * MALO_HOSTCMD_ACT_NOT_USE_FIXED_RATE	0x0002
284177595Sweongyo	 */
285177595Sweongyo	uint32_t		action;
286177595Sweongyo	/* use fixed rate specified but firmware can drop to  */
287177595Sweongyo	uint32_t		allowratedrop;
288177595Sweongyo	uint32_t		entrycount;
289177595Sweongyo	struct malo_fixed_rate_entry fixedrate_table[4];
290177595Sweongyo	uint8_t			multicast_rate;
291177595Sweongyo	uint8_t			multirate_txtype;
292177595Sweongyo	uint8_t			management_rate;
293177595Sweongyo} __packed;
294177595Sweongyo
295177595Sweongyo#define MALO_RATE_INDEX_MAX_ARRAY		14
296177595Sweongyo
297177595Sweongyostruct malo_cmd_fw_set_aid {
298177595Sweongyo	struct malo_cmd_header	cmdhdr;
299177595Sweongyo	uint16_t		associd;
300177595Sweongyo	uint8_t			macaddr[6];	/* AP's Mac Address(BSSID) */
301177595Sweongyo	uint32_t		gprotection;
302177595Sweongyo	uint8_t			aprates[MALO_RATE_INDEX_MAX_ARRAY];
303177595Sweongyo} __packed;
304177595Sweongyo
305177595Sweongyostruct malo_cmd_prescan {
306177595Sweongyo	struct malo_cmd_header	cmdhdr;
307177595Sweongyo} __packed;
308177595Sweongyo
309177595Sweongyostruct malo_cmd_postscan {
310177595Sweongyo	struct malo_cmd_header	cmdhdr;
311177595Sweongyo	uint32_t		isibss;
312177595Sweongyo	uint8_t			bssid[6];
313177595Sweongyo} __packed;
314177595Sweongyo
315177595Sweongyostruct malo_cmd_fw_setslot {
316177595Sweongyo	struct malo_cmd_header	cmdhdr;
317177595Sweongyo	uint16_t		action;
318177595Sweongyo	/* slot = 0 if regular, slot = 1 if short.  */
319177595Sweongyo	uint8_t			slot;
320177595Sweongyo};
321177595Sweongyo
322177595Sweongyostruct malo_cmd_set_rate {
323177595Sweongyo	struct malo_cmd_header	cmdhdr;
324177595Sweongyo	uint8_t			dataratetype;
325177595Sweongyo	uint8_t			rateindex;
326177595Sweongyo	uint8_t			aprates[14];
327177595Sweongyo} __packed;
328177595Sweongyo
329177595Sweongyostruct malo_cmd_wepkey {
330177595Sweongyo	struct malo_cmd_header	cmdhdr;
331177595Sweongyo	uint16_t		action;
332177595Sweongyo	uint8_t			len;
333177595Sweongyo	uint8_t			flags;
334177595Sweongyo	uint16_t		index;
335177595Sweongyo	uint8_t			value[IEEE80211_KEYBUF_SIZE];
336177595Sweongyo	uint8_t			txmickey[IEEE80211_WEP_MICLEN];
337177595Sweongyo	uint8_t			rxmickey[IEEE80211_WEP_MICLEN];
338177595Sweongyo	uint64_t		rxseqctr;
339177595Sweongyo	uint64_t		txseqctr;
340177595Sweongyo} __packed;
341177595Sweongyo
342177595Sweongyostruct malo_cmd_mcast {
343177595Sweongyo	struct malo_cmd_header	cmdhdr;
344177595Sweongyo	uint16_t		action;
345177595Sweongyo	uint16_t		numaddr;
346177595Sweongyo#define	MALO_HAL_MCAST_MAX	32
347177595Sweongyo	uint8_t			maclist[6*32];
348177595Sweongyo} __packed;
349177595Sweongyo
350177595Sweongyo/*
351177595Sweongyo * DMA state for tx/rx descriptors.
352177595Sweongyo */
353177595Sweongyo
354177595Sweongyo/*
355177595Sweongyo * Common "base class" for tx/rx descriptor resources
356177595Sweongyo * allocated using the bus dma api.
357177595Sweongyo */
358177595Sweongyostruct malo_descdma {
359177595Sweongyo	const char*		dd_name;
360177595Sweongyo	void			*dd_desc;	/* descriptors */
361177595Sweongyo	bus_addr_t		dd_desc_paddr;	/* physical addr of dd_desc */
362177595Sweongyo	bus_size_t		dd_desc_len;	/* size of dd_desc */
363177595Sweongyo	bus_dma_segment_t	dd_dseg;
364177595Sweongyo	int			dd_dnseg;	/* number of segments */
365177595Sweongyo	bus_dma_tag_t		dd_dmat;	/* bus DMA tag */
366177595Sweongyo	bus_dmamap_t		dd_dmamap;	/* DMA map for descriptors */
367177595Sweongyo	void			*dd_bufptr;	/* associated buffers */
368177595Sweongyo};
369177595Sweongyo
370177595Sweongyo/*
371177595Sweongyo * Hardware tx/rx descriptors.
372177595Sweongyo *
373177595Sweongyo * NB: tx descriptor size must match f/w expected size
374177595Sweongyo * because f/w prefetch's the next descriptor linearly
375177595Sweongyo * and doesn't chase the next pointer.
376177595Sweongyo */
377177595Sweongyostruct malo_txdesc {
378177595Sweongyo	uint32_t		status;
379177595Sweongyo#define	MALO_TXD_STATUS_IDLE			0x00000000
380177595Sweongyo#define	MALO_TXD_STATUS_USED			0x00000001
381177595Sweongyo#define	MALO_TXD_STATUS_OK			0x00000001
382177595Sweongyo#define	MALO_TXD_STATUS_OK_RETRY		0x00000002
383177595Sweongyo#define	MALO_TXD_STATUS_OK_MORE_RETRY		0x00000004
384177595Sweongyo#define	MALO_TXD_STATUS_MULTICAST_TX		0x00000008
385177595Sweongyo#define	MALO_TXD_STATUS_BROADCAST_TX		0x00000010
386177595Sweongyo#define	MALO_TXD_STATUS_FAILED_LINK_ERROR	0x00000020
387177595Sweongyo#define	MALO_TXD_STATUS_FAILED_EXCEED_LIMIT	0x00000040
388177595Sweongyo#define	MALO_TXD_STATUS_FAILED_XRETRY	MALO_TXD_STATUS_FAILED_EXCEED_LIMIT
389177595Sweongyo#define	MALO_TXD_STATUS_FAILED_AGING		0x00000080
390177595Sweongyo#define	MALO_TXD_STATUS_FW_OWNED		0x80000000
391177595Sweongyo	uint8_t			datarate;
392177595Sweongyo	uint8_t			txpriority;
393177595Sweongyo	uint16_t		qosctrl;
394177595Sweongyo	uint32_t		pktptr;
395177595Sweongyo	uint16_t		pktlen;
396177595Sweongyo	uint8_t			destaddr[6];
397177595Sweongyo	uint32_t		physnext;
398177595Sweongyo	uint32_t		sap_pktinfo;
399177595Sweongyo	uint16_t		format;
400177595Sweongyo#define	MALO_TXD_FORMAT		0x0001	/* frame format/rate */
401177595Sweongyo#define	MALO_TXD_FORMAT_LEGACY	0x0000	/* legacy rate frame */
402177595Sweongyo#define	MALO_TXD_RATE		0x01f8	/* tx rate (legacy)/ MCS */
403177595Sweongyo#define	MALO_TXD_RATE_S		3
404177595Sweongyo/* NB: 3 is reserved */
405177595Sweongyo#define	MALO_TXD_ANTENNA	0x1800	/* antenna select */
406177595Sweongyo#define	MALO_TXD_ANTENNA_S	11
407177595Sweongyo	uint16_t		pad;	/* align to 4-byte boundary */
408177595Sweongyo} __packed;
409177595Sweongyo
410177595Sweongyo#define	MALO_TXDESC_SYNC(txq, ds, how) do {				\
411177595Sweongyo	bus_dmamap_sync((txq)->dma.dd_dmat, (txq)->dma.dd_dmamap, how);	\
412177595Sweongyo} while(0)
413177595Sweongyo
414177595Sweongyostruct malo_rxdesc {
415177595Sweongyo	uint8_t		rxcontrol;	/* control element */
416177595Sweongyo#define	MALO_RXD_CTRL_DRIVER_OWN		0x00
417177595Sweongyo#define	MALO_RXD_CTRL_OS_OWN			0x04
418177595Sweongyo#define	MALO_RXD_CTRL_DMA_OWN			0x80
419177595Sweongyo	uint8_t		snr;		/* signal to noise ratio */
420177595Sweongyo	uint8_t		status;		/* status field w/ USED bit */
421177595Sweongyo#define	MALO_RXD_STATUS_IDLE			0x00
422177595Sweongyo#define	MALO_RXD_STATUS_OK			0x01
423177595Sweongyo#define	MALO_RXD_STATUS_MULTICAST_RX		0x02
424177595Sweongyo#define	MALO_RXD_STATUS_BROADCAST_RX		0x04
425177595Sweongyo#define	MALO_RXD_STATUS_FRAGMENT_RX		0x08
426177595Sweongyo#define	MALO_RXD_STATUS_GENERAL_DECRYPT_ERR	0xff
427177595Sweongyo#define	MALO_RXD_STATUS_DECRYPT_ERR_MASK	0x80
428177595Sweongyo#define	MALO_RXD_STATUS_TKIP_MIC_DECRYPT_ERR	0x02
429177595Sweongyo#define	MALO_RXD_STATUS_WEP_ICV_DECRYPT_ERR	0x04
430177595Sweongyo#define	MALO_RXD_STATUS_TKIP_ICV_DECRYPT_ERR	0x08
431177595Sweongyo	uint8_t		channel;	/* channel # pkt received on */
432177595Sweongyo	uint16_t	pktlen;		/* total length of received data */
433177595Sweongyo	uint8_t		nf;		/* noise floor */
434177595Sweongyo	uint8_t		rate;		/* received data rate */
435177595Sweongyo	uint32_t	physbuffdata;	/* physical address of payload data */
436177595Sweongyo	uint32_t	physnext;	/* physical address of next RX desc */
437177595Sweongyo	uint16_t	qosctrl;	/* received QosCtrl field variable */
438177595Sweongyo	uint16_t	htsig2;		/* like name states */
439177595Sweongyo} __packed;
440177595Sweongyo
441177595Sweongyo#define	MALO_RXDESC_SYNC(sc, ds, how) do {				\
442177595Sweongyo	bus_dmamap_sync((sc)->malo_rxdma.dd_dmat,			\
443177595Sweongyo	    (sc)->malo_rxdma.dd_dmamap, how);				\
444177595Sweongyo} while (0)
445177595Sweongyo
446177595Sweongyostruct malo_rxbuf {
447177595Sweongyo	STAILQ_ENTRY(malo_rxbuf) bf_list;
448177595Sweongyo	void			*bf_desc;	/* h/w descriptor */
449177595Sweongyo	bus_addr_t		bf_daddr;	/* physical addr of desc */
450177595Sweongyo	bus_dmamap_t		bf_dmamap;
451177595Sweongyo	bus_addr_t		bf_data;	/* physical addr of rx data */
452177595Sweongyo	struct mbuf		*bf_m;		/* jumbo mbuf */
453177595Sweongyo};
454177595Sweongyotypedef STAILQ_HEAD(, malo_rxbuf) malo_rxbufhead;
455177595Sweongyo
456177595Sweongyo/*
457177595Sweongyo * Software backed version of tx/rx descriptors.  We keep
458177595Sweongyo * the software state out of the h/w descriptor structure
459177595Sweongyo * so that may be allocated in uncached memory w/o paying
460177595Sweongyo * performance hit.
461177595Sweongyo */
462177595Sweongyostruct malo_txbuf {
463177595Sweongyo	STAILQ_ENTRY(malo_txbuf) bf_list;
464177595Sweongyo	void			*bf_desc;	/* h/w descriptor */
465177595Sweongyo	bus_addr_t		bf_daddr;	/* physical addr of desc */
466177595Sweongyo	bus_dmamap_t		bf_dmamap;	/* DMA map for descriptors */
467177595Sweongyo	int			bf_nseg;
468177595Sweongyo	bus_dma_segment_t	bf_segs[MALO_TXDESC];
469177595Sweongyo	struct mbuf		*bf_m;
470177595Sweongyo	struct ieee80211_node	*bf_node;
471177595Sweongyo	struct malo_txq		*bf_txq;	/* backpointer to tx q/ring */
472177595Sweongyo};
473177595Sweongyotypedef STAILQ_HEAD(, malo_txbuf) malo_txbufhead;
474177595Sweongyo
475177595Sweongyo/*
476177595Sweongyo * TX/RX ring definitions.  There are 4 tx rings, one
477177595Sweongyo * per AC, and 1 rx ring.  Note carefully that transmit
478177595Sweongyo * descriptors are treated as a contiguous chunk and the
479177595Sweongyo * firmware pre-fetches descriptors.  This means that we
480177595Sweongyo * must preserve order when moving descriptors between
481177595Sweongyo * the active+free lists; otherwise we may stall transmit.
482177595Sweongyo */
483177595Sweongyostruct malo_txq {
484177595Sweongyo	struct malo_descdma	dma;		/* bus dma resources */
485177595Sweongyo	struct mtx		lock;		/* tx q lock */
486177595Sweongyo	char			name[12];	/* e.g. "malo0_txq4" */
487177595Sweongyo	int			qnum;		/* f/w q number */
488177595Sweongyo	int			txpri;		/* f/w tx priority */
489177595Sweongyo	int			nfree;		/* # buffers on free list */
490177595Sweongyo	malo_txbufhead		free;		/* queue of free buffers */
491177595Sweongyo	malo_txbufhead		active;		/* queue of active buffers */
492177595Sweongyo};
493177595Sweongyo
494177595Sweongyo#define	MALO_TXQ_LOCK_INIT(_sc, _tq) do { \
495177595Sweongyo	snprintf((_tq)->name, sizeof((_tq)->name), "%s_txq%u", \
496177595Sweongyo		device_get_nameunit((_sc)->malo_dev), (_tq)->qnum); \
497177595Sweongyo	mtx_init(&(_tq)->lock, (_tq)->name, NULL, MTX_DEF); \
498177595Sweongyo} while (0)
499177595Sweongyo#define	MALO_TXQ_LOCK_DESTROY(_tq)	mtx_destroy(&(_tq)->lock)
500177595Sweongyo#define	MALO_TXQ_LOCK(_tq)		mtx_lock(&(_tq)->lock)
501177595Sweongyo#define	MALO_TXQ_UNLOCK(_tq)		mtx_unlock(&(_tq)->lock)
502177595Sweongyo#define	MALO_TXQ_LOCK_ASSERT(_tq)	mtx_assert(&(_tq)->lock, MA_OWNED)
503177595Sweongyo
504177595Sweongyo/*
505177595Sweongyo * Each packet has fixed front matter: a 2-byte length
506177595Sweongyo * of the payload, followed by a 4-address 802.11 header
507177595Sweongyo * (regardless of the actual header and always w/o any
508177595Sweongyo * QoS header).  The payload then follows.
509177595Sweongyo */
510177595Sweongyostruct malo_txrec {
511177595Sweongyo	uint16_t fwlen;
512177595Sweongyo	struct ieee80211_frame_addr4 wh;
513177595Sweongyo} __packed;
514177595Sweongyo
515178354Ssamstruct malo_vap {
516178354Ssam	struct ieee80211vap malo_vap;
517178354Ssam	int			(*malo_newstate)(struct ieee80211vap *,
518178354Ssam				    enum ieee80211_state, int);
519178354Ssam};
520178354Ssam#define	MALO_VAP(vap)	((struct malo_vap *)(vap))
521178354Ssam
522177595Sweongyostruct malo_softc {
523177595Sweongyo	device_t		malo_dev;
524177595Sweongyo	struct ifnet		*malo_ifp;	/* interface common */
525177595Sweongyo	struct mtx		malo_mtx;	/* master lock (recursive) */
526177595Sweongyo	struct taskqueue	*malo_tq;	/* private task queue */
527177595Sweongyo
528177595Sweongyo	bus_dma_tag_t		malo_dmat;	/* bus DMA tag */
529177595Sweongyo	bus_space_handle_t	malo_io0h;	/* BAR 0 */
530177595Sweongyo	bus_space_tag_t		malo_io0t;
531177595Sweongyo	bus_space_handle_t	malo_io1h;	/* BAR 1 */
532177595Sweongyo	bus_space_tag_t		malo_io1t;
533177595Sweongyo
534177595Sweongyo	unsigned int		malo_invalid : 1,/* disable hardware accesses */
535177595Sweongyo				malo_recvsetup : 1,	/* recv setup */
536178354Ssam				malo_fixedrate: 1;	/* use fixed tx rate */
537177595Sweongyo
538177595Sweongyo	struct malo_hal		*malo_mh;	/* h/w access layer */
539177595Sweongyo	struct malo_hal_hwspec	malo_hwspecs;	/* h/w capabilities */
540177595Sweongyo	struct malo_hal_txrxdma	malo_hwdma;	/* h/w dma setup */
541177595Sweongyo	uint32_t		malo_imask;	/* interrupt mask copy */
542177595Sweongyo	struct malo_hal_channel	malo_curchan;
543177595Sweongyo	u_int16_t		malo_rxantenna;	/* rx antenna */
544177595Sweongyo	u_int16_t		malo_txantenna;	/* tx antenna */
545177595Sweongyo
546177595Sweongyo	struct malo_descdma	malo_rxdma;	/* rx bus dma resources */
547177595Sweongyo	malo_rxbufhead		malo_rxbuf;	/* rx buffers */
548177595Sweongyo	struct malo_rxbuf	*malo_rxnext;	/* next rx buffer to process */
549177595Sweongyo	struct task		malo_rxtask;	/* rx int processing */
550177595Sweongyo
551177595Sweongyo	struct malo_txq		malo_txq[MALO_NUM_TX_QUEUES];
552177595Sweongyo	struct task		malo_txtask;	/* tx int processing */
553199559Sjhb	struct callout	malo_watchdog_timer;
554199559Sjhb	int			malo_timer;
555177595Sweongyo
556177595Sweongyo	struct malo_tx_radiotap_header malo_tx_th;
557177595Sweongyo	struct malo_rx_radiotap_header malo_rx_th;
558177595Sweongyo
559177595Sweongyo	struct malo_stats	malo_stats;	/* interface statistics */
560177595Sweongyo	int			malo_debug;
561177595Sweongyo};
562177595Sweongyo
563177595Sweongyo#define	MALO_LOCK_INIT(_sc) \
564177595Sweongyo	mtx_init(&(_sc)->malo_mtx, device_get_nameunit((_sc)->malo_dev), \
565177595Sweongyo		 NULL, MTX_DEF | MTX_RECURSE)
566177595Sweongyo#define	MALO_LOCK_DESTROY(_sc)		mtx_destroy(&(_sc)->malo_mtx)
567177595Sweongyo#define	MALO_LOCK(_sc)			mtx_lock(&(_sc)->malo_mtx)
568177595Sweongyo#define	MALO_UNLOCK(_sc)		mtx_unlock(&(_sc)->malo_mtx)
569177595Sweongyo#define	MALO_LOCK_ASSERT(_sc)		mtx_assert(&(_sc)->malo_mtx, MA_OWNED)
570177595Sweongyo
571177595Sweongyo#define	MALO_RXFREE_INIT(_sc)						\
572177595Sweongyo	mtx_init(&(_sc)->malo_rxlock, device_get_nameunit((_sc)->malo_dev), \
573177595Sweongyo		 NULL, MTX_DEF)
574177595Sweongyo#define	MALO_RXFREE_DESTROY(_sc)	mtx_destroy(&(_sc)->malo_rxlock)
575177595Sweongyo#define	MALO_RXFREE_LOCK(_sc)		mtx_lock(&(_sc)->malo_rxlock)
576177595Sweongyo#define	MALO_RXFREE_UNLOCK(_sc)		mtx_unlock(&(_sc)->malo_rxlock)
577177595Sweongyo#define	MALO_RXFREE_ASSERT(_sc)		mtx_assert(&(_sc)->malo_rxlock, \
578177595Sweongyo	MA_OWNED)
579177595Sweongyo
580177595Sweongyoint	malo_attach(uint16_t, struct malo_softc *);
581177595Sweongyoint	malo_intr(void *);
582177595Sweongyoint	malo_detach(struct malo_softc *);
583177595Sweongyovoid	malo_shutdown(struct malo_softc *);
584177595Sweongyovoid	malo_suspend(struct malo_softc *);
585177595Sweongyovoid	malo_resume(struct malo_softc *);
586177595Sweongyo
587177595Sweongyo#endif
588