xref: /freebsd/sys/dev/usb/wlan/if_upgtvar.h (revision 786ac7035f938bf3764ec6d5ee2f0e50b5d959b6)
1879f0effSWeongyo Jeong /*	$OpenBSD: if_upgtvar.h,v 1.14 2008/02/02 13:48:44 mglocker Exp $ */
2879f0effSWeongyo Jeong /*	$FreeBSD$ */
3879f0effSWeongyo Jeong 
4879f0effSWeongyo Jeong /*
5879f0effSWeongyo Jeong  * Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
6879f0effSWeongyo Jeong  *
7879f0effSWeongyo Jeong  * Permission to use, copy, modify, and distribute this software for any
8879f0effSWeongyo Jeong  * purpose with or without fee is hereby granted, provided that the above
9879f0effSWeongyo Jeong  * copyright notice and this permission notice appear in all copies.
10879f0effSWeongyo Jeong  *
11879f0effSWeongyo Jeong  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12879f0effSWeongyo Jeong  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13879f0effSWeongyo Jeong  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14879f0effSWeongyo Jeong  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15879f0effSWeongyo Jeong  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16879f0effSWeongyo Jeong  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17879f0effSWeongyo Jeong  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18879f0effSWeongyo Jeong  */
19879f0effSWeongyo Jeong 
20879f0effSWeongyo Jeong struct upgt_softc;
21879f0effSWeongyo Jeong 
22879f0effSWeongyo Jeong /*
23879f0effSWeongyo Jeong  * General values.
24879f0effSWeongyo Jeong  */
25879f0effSWeongyo Jeong enum {
26879f0effSWeongyo Jeong 	UPGT_BULK_RX,
27879f0effSWeongyo Jeong 	UPGT_BULK_TX,
28879f0effSWeongyo Jeong 	UPGT_N_XFERS = 2,
29879f0effSWeongyo Jeong };
30879f0effSWeongyo Jeong 
31879f0effSWeongyo Jeong #define UPGT_CONFIG_INDEX		0
32879f0effSWeongyo Jeong #define UPGT_IFACE_INDEX		0
33879f0effSWeongyo Jeong #define UPGT_USB_TIMEOUT		1000
34879f0effSWeongyo Jeong #define UPGT_FIRMWARE_TIMEOUT		10
35879f0effSWeongyo Jeong 
36879f0effSWeongyo Jeong #define UPGT_MEMADDR_FIRMWARE_START	0x00020000	/* 512 bytes large */
37879f0effSWeongyo Jeong #define UPGT_MEMSIZE_FRAME_HEAD		0x0070
38879f0effSWeongyo Jeong #define UPGT_MEMSIZE_RX			0x3500
39879f0effSWeongyo Jeong 
40879f0effSWeongyo Jeong #define	UPGT_RX_MAXCOUNT		6
41879f0effSWeongyo Jeong #define	UPGT_TX_MAXCOUNT		128
42879f0effSWeongyo Jeong #define	UPGT_TX_STAT_INTERVAL		5
43879f0effSWeongyo Jeong #define	UPGT_RX_MINSZ			(sizeof(struct upgt_lmac_header) + 4)
44879f0effSWeongyo Jeong 
45879f0effSWeongyo Jeong /* device flags */
46879f0effSWeongyo Jeong #define UPGT_DEVICE_ATTACHED		(1 << 0)
47879f0effSWeongyo Jeong 
48879f0effSWeongyo Jeong /* leds */
49879f0effSWeongyo Jeong #define UPGT_LED_OFF			0
50879f0effSWeongyo Jeong #define UPGT_LED_ON			1
51879f0effSWeongyo Jeong #define UPGT_LED_BLINK			2
52879f0effSWeongyo Jeong 
53879f0effSWeongyo Jeong /*
54879f0effSWeongyo Jeong  * Firmware.
55879f0effSWeongyo Jeong  */
56879f0effSWeongyo Jeong #define UPGT_FW_BLOCK_SIZE		256
57879f0effSWeongyo Jeong 
58879f0effSWeongyo Jeong #define UPGT_BRA_FWTYPE_SIZE		4
59879f0effSWeongyo Jeong #define UPGT_BRA_FWTYPE_LM86		"LM86"
60879f0effSWeongyo Jeong #define UPGT_BRA_FWTYPE_LM87		"LM87"
61879f0effSWeongyo Jeong enum upgt_fw_type {
62879f0effSWeongyo Jeong 	UPGT_FWTYPE_LM86,
63879f0effSWeongyo Jeong 	UPGT_FWTYPE_LM87
64879f0effSWeongyo Jeong };
65879f0effSWeongyo Jeong 
66879f0effSWeongyo Jeong #define UPGT_BRA_TYPE_FW		0x80000001
67879f0effSWeongyo Jeong #define UPGT_BRA_TYPE_VERSION		0x80000002
68879f0effSWeongyo Jeong #define UPGT_BRA_TYPE_DEPIF		0x80000003
69879f0effSWeongyo Jeong #define UPGT_BRA_TYPE_EXPIF		0x80000004
70879f0effSWeongyo Jeong #define UPGT_BRA_TYPE_DESCR		0x80000101
71879f0effSWeongyo Jeong #define UPGT_BRA_TYPE_END		0xff0000ff
72879f0effSWeongyo Jeong struct upgt_fw_bra_option {
73879f0effSWeongyo Jeong 	uint32_t			type;
74879f0effSWeongyo Jeong 	uint32_t			len;
75879f0effSWeongyo Jeong 	uint8_t				data[];
76879f0effSWeongyo Jeong } __packed;
77879f0effSWeongyo Jeong 
78879f0effSWeongyo Jeong struct upgt_fw_bra_descr {
79879f0effSWeongyo Jeong 	uint32_t			unknown1;
80879f0effSWeongyo Jeong 	uint32_t			memaddr_space_start;
81879f0effSWeongyo Jeong 	uint32_t			memaddr_space_end;
82879f0effSWeongyo Jeong 	uint32_t			unknown2;
83879f0effSWeongyo Jeong 	uint32_t			unknown3;
84879f0effSWeongyo Jeong 	uint8_t				rates[20];
85879f0effSWeongyo Jeong } __packed;
86879f0effSWeongyo Jeong 
87879f0effSWeongyo Jeong #define UPGT_X2_SIGNATURE_SIZE		4
88879f0effSWeongyo Jeong #define UPGT_X2_SIGNATURE		"x2  "
89879f0effSWeongyo Jeong struct upgt_fw_x2_header {
90879f0effSWeongyo Jeong 	uint8_t				signature[4];
91879f0effSWeongyo Jeong 	uint32_t			startaddr;
92879f0effSWeongyo Jeong 	uint32_t			len;
93879f0effSWeongyo Jeong 	uint32_t			crc;
94879f0effSWeongyo Jeong } __packed;
95879f0effSWeongyo Jeong 
96879f0effSWeongyo Jeong /*
97879f0effSWeongyo Jeong  * EEPROM.
98879f0effSWeongyo Jeong  */
99879f0effSWeongyo Jeong #define UPGT_EEPROM_SIZE		8192
100879f0effSWeongyo Jeong #define UPGT_EEPROM_BLOCK_SIZE		1020
101879f0effSWeongyo Jeong 
102879f0effSWeongyo Jeong struct upgt_eeprom_header {
103879f0effSWeongyo Jeong 	/* 14 bytes */
104879f0effSWeongyo Jeong 	uint32_t			magic;
105879f0effSWeongyo Jeong 	uint16_t			pad1;
106879f0effSWeongyo Jeong 	uint16_t			preamble_len;
107879f0effSWeongyo Jeong 	uint32_t			pad2;
108879f0effSWeongyo Jeong 	/* data */
109879f0effSWeongyo Jeong } __packed;
110879f0effSWeongyo Jeong 
111879f0effSWeongyo Jeong #define UPGT_EEPROM_TYPE_END		0x0000
112879f0effSWeongyo Jeong #define UPGT_EEPROM_TYPE_NAME		0x0001
113879f0effSWeongyo Jeong #define UPGT_EEPROM_TYPE_SERIAL		0x0003
114879f0effSWeongyo Jeong #define UPGT_EEPROM_TYPE_MAC		0x0101
115879f0effSWeongyo Jeong #define UPGT_EEPROM_TYPE_HWRX		0x1001
116879f0effSWeongyo Jeong #define UPGT_EEPROM_TYPE_CHIP		0x1002
117879f0effSWeongyo Jeong #define UPGT_EEPROM_TYPE_FREQ3		0x1903
118879f0effSWeongyo Jeong #define UPGT_EEPROM_TYPE_FREQ4		0x1904
119879f0effSWeongyo Jeong #define UPGT_EEPROM_TYPE_FREQ5		0x1905
120879f0effSWeongyo Jeong #define UPGT_EEPROM_TYPE_FREQ6		0x1906
121879f0effSWeongyo Jeong #define UPGT_EEPROM_TYPE_OFF		0xffff
122879f0effSWeongyo Jeong struct upgt_eeprom_option {
123879f0effSWeongyo Jeong 	uint16_t			len;
124879f0effSWeongyo Jeong 	uint16_t			type;
125879f0effSWeongyo Jeong 	uint8_t				data[];
126879f0effSWeongyo Jeong 	/* data */
127879f0effSWeongyo Jeong } __packed;
128879f0effSWeongyo Jeong 
129879f0effSWeongyo Jeong #define UPGT_EEPROM_RX_CONST		0x88
130879f0effSWeongyo Jeong struct upgt_eeprom_option_hwrx {
131879f0effSWeongyo Jeong 	uint32_t			pad1;
132879f0effSWeongyo Jeong 	uint8_t				rxfilter;
133879f0effSWeongyo Jeong 	uint8_t				pad2[15];
134879f0effSWeongyo Jeong } __packed;
135879f0effSWeongyo Jeong 
136879f0effSWeongyo Jeong struct upgt_eeprom_freq3_header {
137879f0effSWeongyo Jeong 	uint8_t				flags;
138879f0effSWeongyo Jeong 	uint8_t				elements;
139879f0effSWeongyo Jeong } __packed;
140879f0effSWeongyo Jeong 
141879f0effSWeongyo Jeong struct upgt_eeprom_freq4_header {
142879f0effSWeongyo Jeong 	uint8_t				flags;
143879f0effSWeongyo Jeong 	uint8_t				elements;
144879f0effSWeongyo Jeong 	uint8_t				settings;
145879f0effSWeongyo Jeong 	uint8_t				type;
146879f0effSWeongyo Jeong } __packed;
147879f0effSWeongyo Jeong 
148879f0effSWeongyo Jeong struct upgt_eeprom_freq4_1 {
149879f0effSWeongyo Jeong 	uint16_t			freq;
150879f0effSWeongyo Jeong 	uint8_t				data[50];
151879f0effSWeongyo Jeong } __packed;
152879f0effSWeongyo Jeong 
153879f0effSWeongyo Jeong struct upgt_eeprom_freq4_2 {
154879f0effSWeongyo Jeong 	uint16_t			head;
155879f0effSWeongyo Jeong 	uint8_t				subtails[4];
156879f0effSWeongyo Jeong 	uint8_t				tail;
157879f0effSWeongyo Jeong } __packed;
158879f0effSWeongyo Jeong 
159879f0effSWeongyo Jeong /*
160879f0effSWeongyo Jeong  * LMAC protocol.
161879f0effSWeongyo Jeong  */
162879f0effSWeongyo Jeong struct upgt_lmac_mem {
163879f0effSWeongyo Jeong 	uint32_t			addr;
164879f0effSWeongyo Jeong 	uint32_t			chksum;
165879f0effSWeongyo Jeong } __packed;
166879f0effSWeongyo Jeong 
167879f0effSWeongyo Jeong #define UPGT_H1_FLAGS_TX_MGMT		0x00	/* for TX: mgmt frame */
168879f0effSWeongyo Jeong #define UPGT_H1_FLAGS_TX_NO_CALLBACK	0x01	/* for TX: no USB callback */
169879f0effSWeongyo Jeong #define UPGT_H1_FLAGS_TX_DATA		0x10	/* for TX: data frame */
170879f0effSWeongyo Jeong #define UPGT_H1_TYPE_RX_DATA		0x00	/* 802.11 RX data frame */
171879f0effSWeongyo Jeong #define UPGT_H1_TYPE_RX_DATA_MGMT	0x04	/* 802.11 RX mgmt frame */
172879f0effSWeongyo Jeong #define UPGT_H1_TYPE_TX_DATA		0x40	/* 802.11 TX data frame */
173879f0effSWeongyo Jeong #define UPGT_H1_TYPE_CTRL		0x80	/* control frame */
174879f0effSWeongyo Jeong struct upgt_lmac_h1 {
175879f0effSWeongyo Jeong 	/* 4 bytes */
176879f0effSWeongyo Jeong 	uint8_t				flags;
177879f0effSWeongyo Jeong 	uint8_t				type;
178879f0effSWeongyo Jeong 	uint16_t			len;
179879f0effSWeongyo Jeong } __packed;
180879f0effSWeongyo Jeong 
181879f0effSWeongyo Jeong #define UPGT_H2_TYPE_TX_ACK_NO		0x0000
182879f0effSWeongyo Jeong #define UPGT_H2_TYPE_TX_ACK_YES		0x0001
183879f0effSWeongyo Jeong #define UPGT_H2_TYPE_MACFILTER		0x0000
184879f0effSWeongyo Jeong #define UPGT_H2_TYPE_CHANNEL		0x0001
185879f0effSWeongyo Jeong #define UPGT_H2_TYPE_TX_DONE		0x0008
186879f0effSWeongyo Jeong #define UPGT_H2_TYPE_STATS		0x000a
187879f0effSWeongyo Jeong #define UPGT_H2_TYPE_EEPROM		0x000c
188879f0effSWeongyo Jeong #define UPGT_H2_TYPE_LED		0x000d
189879f0effSWeongyo Jeong #define UPGT_H2_FLAGS_TX_ACK_NO		0x0101
190879f0effSWeongyo Jeong #define UPGT_H2_FLAGS_TX_ACK_YES	0x0707
191879f0effSWeongyo Jeong struct upgt_lmac_h2 {
192879f0effSWeongyo Jeong 	/* 8 bytes */
193879f0effSWeongyo Jeong 	uint32_t			reqid;
194879f0effSWeongyo Jeong 	uint16_t			type;
195879f0effSWeongyo Jeong 	uint16_t			flags;
196879f0effSWeongyo Jeong } __packed;
197879f0effSWeongyo Jeong 
198879f0effSWeongyo Jeong struct upgt_lmac_header {
199879f0effSWeongyo Jeong 	/* 12 bytes */
200879f0effSWeongyo Jeong 	struct upgt_lmac_h1		header1;
201879f0effSWeongyo Jeong 	struct upgt_lmac_h2		header2;
202879f0effSWeongyo Jeong } __packed;
203879f0effSWeongyo Jeong 
204879f0effSWeongyo Jeong struct upgt_lmac_eeprom {
205879f0effSWeongyo Jeong 	/* 16 bytes */
206879f0effSWeongyo Jeong 	struct upgt_lmac_h1		header1;
207879f0effSWeongyo Jeong 	struct upgt_lmac_h2		header2;
208879f0effSWeongyo Jeong 	uint16_t			offset;
209879f0effSWeongyo Jeong 	uint16_t			len;
210879f0effSWeongyo Jeong 	/* data */
211879f0effSWeongyo Jeong } __packed;
212879f0effSWeongyo Jeong 
213879f0effSWeongyo Jeong #define UPGT_FILTER_TYPE_NONE		0x0000
214879f0effSWeongyo Jeong #define UPGT_FILTER_TYPE_STA		0x0001
215879f0effSWeongyo Jeong #define UPGT_FILTER_TYPE_IBSS		0x0002
216879f0effSWeongyo Jeong #define UPGT_FILTER_TYPE_HOSTAP		0x0004
217879f0effSWeongyo Jeong #define UPGT_FILTER_TYPE_MONITOR	0x0010
218879f0effSWeongyo Jeong #define UPGT_FILTER_TYPE_RESET		0x0020
219879f0effSWeongyo Jeong #define UPGT_FILTER_UNKNOWN1		0x0002
220879f0effSWeongyo Jeong #define UPGT_FILTER_UNKNOWN2		0x0ca8
221879f0effSWeongyo Jeong #define UPGT_FILTER_UNKNOWN3		0xffff
222879f0effSWeongyo Jeong #define UPGT_FILTER_MONITOR_UNKNOWN1	0x0000
223879f0effSWeongyo Jeong #define UPGT_FILTER_MONITOR_UNKNOWN2	0x0000
224879f0effSWeongyo Jeong #define UPGT_FILTER_MONITOR_UNKNOWN3	0x0000
225879f0effSWeongyo Jeong struct upgt_lmac_filter {
226879f0effSWeongyo Jeong 	struct upgt_lmac_h1		header1;
227879f0effSWeongyo Jeong 	struct upgt_lmac_h2		header2;
228879f0effSWeongyo Jeong 	/* 32 bytes */
229879f0effSWeongyo Jeong 	uint16_t			type;
230879f0effSWeongyo Jeong 	uint8_t				dst[IEEE80211_ADDR_LEN];
231879f0effSWeongyo Jeong 	uint8_t				src[IEEE80211_ADDR_LEN];
232879f0effSWeongyo Jeong 	uint16_t			unknown1;
233879f0effSWeongyo Jeong 	uint32_t			rxaddr;
234879f0effSWeongyo Jeong 	uint16_t			unknown2;
235879f0effSWeongyo Jeong 	uint32_t			rxhw;
236879f0effSWeongyo Jeong 	uint16_t			unknown3;
237879f0effSWeongyo Jeong 	uint32_t			unknown4;
238879f0effSWeongyo Jeong } __packed;
239879f0effSWeongyo Jeong 
240879f0effSWeongyo Jeong /* frequence 3 data */
241879f0effSWeongyo Jeong struct upgt_lmac_freq3 {
242879f0effSWeongyo Jeong 	uint16_t			freq;
243879f0effSWeongyo Jeong 	uint8_t				data[6];
244879f0effSWeongyo Jeong } __packed;
245879f0effSWeongyo Jeong 
246879f0effSWeongyo Jeong /* frequence 4 data */
247879f0effSWeongyo Jeong struct upgt_lmac_freq4 {
248879f0effSWeongyo Jeong 	struct upgt_eeprom_freq4_2	cmd;
249879f0effSWeongyo Jeong 	uint8_t				pad;
250879f0effSWeongyo Jeong };
251879f0effSWeongyo Jeong 
252879f0effSWeongyo Jeong /* frequence 6 data */
253879f0effSWeongyo Jeong struct upgt_lmac_freq6 {
254879f0effSWeongyo Jeong 	uint16_t			freq;
255879f0effSWeongyo Jeong 	uint8_t				data[8];
256879f0effSWeongyo Jeong } __packed;
257879f0effSWeongyo Jeong 
258879f0effSWeongyo Jeong #define UPGT_CHANNEL_UNKNOWN1		0x0001
259879f0effSWeongyo Jeong #define UPGT_CHANNEL_UNKNOWN2		0x0000
260879f0effSWeongyo Jeong #define UPGT_CHANNEL_UNKNOWN3		0x48
261879f0effSWeongyo Jeong struct upgt_lmac_channel {
262879f0effSWeongyo Jeong 	struct upgt_lmac_h1		header1;
263879f0effSWeongyo Jeong 	struct upgt_lmac_h2		header2;
264879f0effSWeongyo Jeong 	/* 112 bytes */
265879f0effSWeongyo Jeong 	uint16_t			unknown1;
266879f0effSWeongyo Jeong 	uint16_t			unknown2;
267879f0effSWeongyo Jeong 	uint8_t				pad1[20];
268879f0effSWeongyo Jeong 	struct upgt_lmac_freq6		freq6;
269879f0effSWeongyo Jeong 	uint8_t				settings;
270879f0effSWeongyo Jeong 	uint8_t				unknown3;
271879f0effSWeongyo Jeong 	uint8_t				freq3_1[4];
272879f0effSWeongyo Jeong 	struct upgt_lmac_freq4		freq4[8];
273879f0effSWeongyo Jeong 	uint8_t				freq3_2[4];
274879f0effSWeongyo Jeong 	uint32_t			pad2;
275879f0effSWeongyo Jeong } __packed;
276879f0effSWeongyo Jeong 
277879f0effSWeongyo Jeong #define UPGT_LED_MODE_SET		0x0003
278879f0effSWeongyo Jeong #define UPGT_LED_ACTION_OFF		0x0002
279879f0effSWeongyo Jeong #define UPGT_LED_ACTION_ON		0x0003
280879f0effSWeongyo Jeong #define UPGT_LED_ACTION_TMP_DUR		100	/* ms */
281879f0effSWeongyo Jeong struct upgt_lmac_led {
282879f0effSWeongyo Jeong 	struct upgt_lmac_h1		header1;
283879f0effSWeongyo Jeong 	struct upgt_lmac_h2		header2;
284879f0effSWeongyo Jeong 	uint16_t			mode;
285879f0effSWeongyo Jeong 	uint16_t			action_fix;
286879f0effSWeongyo Jeong 	uint16_t			action_tmp;
287879f0effSWeongyo Jeong 	uint16_t			action_tmp_dur;
288879f0effSWeongyo Jeong } __packed;
289879f0effSWeongyo Jeong 
290879f0effSWeongyo Jeong struct upgt_lmac_stats {
291879f0effSWeongyo Jeong 	struct upgt_lmac_h1		header1;
292879f0effSWeongyo Jeong 	struct upgt_lmac_h2		header2;
293879f0effSWeongyo Jeong 	uint8_t				data[76];
294879f0effSWeongyo Jeong } __packed;
295879f0effSWeongyo Jeong 
296879f0effSWeongyo Jeong struct upgt_lmac_rx_desc {
297879f0effSWeongyo Jeong 	struct upgt_lmac_h1		header1;
298879f0effSWeongyo Jeong 	/* 16 bytes */
299879f0effSWeongyo Jeong 	uint16_t			freq;
300879f0effSWeongyo Jeong 	uint8_t				unknown1;
301879f0effSWeongyo Jeong 	uint8_t				rate;
302879f0effSWeongyo Jeong 	uint8_t				rssi;
303879f0effSWeongyo Jeong 	uint8_t				pad;
304879f0effSWeongyo Jeong 	uint16_t			unknown2;
305879f0effSWeongyo Jeong 	uint32_t			timestamp;
306879f0effSWeongyo Jeong 	uint32_t			unknown3;
307879f0effSWeongyo Jeong 	uint8_t				data[];
308879f0effSWeongyo Jeong } __packed;
309879f0effSWeongyo Jeong 
310879f0effSWeongyo Jeong #define UPGT_TX_DESC_KEY_EXISTS		0x01
311879f0effSWeongyo Jeong struct upgt_lmac_tx_desc_wep {
312879f0effSWeongyo Jeong 	uint8_t				key_exists;
313879f0effSWeongyo Jeong 	uint8_t				key_len;
314879f0effSWeongyo Jeong 	uint8_t				key_val[16];
315879f0effSWeongyo Jeong } __packed;
316879f0effSWeongyo Jeong 
317879f0effSWeongyo Jeong #define UPGT_TX_DESC_TYPE_BEACON	0x00000000
318879f0effSWeongyo Jeong #define UPGT_TX_DESC_TYPE_PROBE		0x00000001
319879f0effSWeongyo Jeong #define UPGT_TX_DESC_TYPE_MGMT		0x00000002
320879f0effSWeongyo Jeong #define UPGT_TX_DESC_TYPE_DATA		0x00000004
321879f0effSWeongyo Jeong #define UPGT_TX_DESC_PAD3_SIZE		2
322879f0effSWeongyo Jeong struct upgt_lmac_tx_desc {
323879f0effSWeongyo Jeong 	struct upgt_lmac_h1		header1;
324879f0effSWeongyo Jeong 	struct upgt_lmac_h2		header2;
325879f0effSWeongyo Jeong 	uint8_t				rates[8];
326879f0effSWeongyo Jeong 	uint16_t			pad1;
327879f0effSWeongyo Jeong 	struct upgt_lmac_tx_desc_wep	wep_key;
328879f0effSWeongyo Jeong 	uint32_t			type;
329879f0effSWeongyo Jeong 	uint32_t			pad2;
330879f0effSWeongyo Jeong 	uint32_t			unknown1;
331879f0effSWeongyo Jeong 	uint32_t			unknown2;
332879f0effSWeongyo Jeong 	uint8_t				pad3[2];
333879f0effSWeongyo Jeong 	/* 802.11 frame data */
334879f0effSWeongyo Jeong } __packed;
335879f0effSWeongyo Jeong 
336879f0effSWeongyo Jeong #define UPGT_TX_DONE_DESC_STATUS_OK	0x0001
337879f0effSWeongyo Jeong struct upgt_lmac_tx_done_desc {
338879f0effSWeongyo Jeong 	struct upgt_lmac_h1		header1;
339879f0effSWeongyo Jeong 	struct upgt_lmac_h2		header2;
340879f0effSWeongyo Jeong 	uint16_t			status;
341879f0effSWeongyo Jeong 	uint16_t			rssi;
342879f0effSWeongyo Jeong 	uint16_t			seq;
343879f0effSWeongyo Jeong 	uint16_t			unknown;
344879f0effSWeongyo Jeong } __packed;
345879f0effSWeongyo Jeong 
346879f0effSWeongyo Jeong /*
347879f0effSWeongyo Jeong  * USB xfers.
348879f0effSWeongyo Jeong  */
349879f0effSWeongyo Jeong struct upgt_data {
350879f0effSWeongyo Jeong 	uint8_t				*buf;
351879f0effSWeongyo Jeong 	uint32_t			 buflen;
352879f0effSWeongyo Jeong 	struct ieee80211_node		*ni;
353879f0effSWeongyo Jeong 	struct mbuf			*m;
354879f0effSWeongyo Jeong 	uint32_t			 addr;
355879f0effSWeongyo Jeong 	STAILQ_ENTRY(upgt_data)		 next;
356879f0effSWeongyo Jeong };
357879f0effSWeongyo Jeong typedef STAILQ_HEAD(, upgt_data) upgt_datahead;
358879f0effSWeongyo Jeong 
359879f0effSWeongyo Jeong /*
360879f0effSWeongyo Jeong  * Prism memory.
361879f0effSWeongyo Jeong  */
362879f0effSWeongyo Jeong struct upgt_memory_page {
363879f0effSWeongyo Jeong 	uint8_t				used;
364879f0effSWeongyo Jeong 	uint32_t			addr;
365879f0effSWeongyo Jeong } __packed;
366879f0effSWeongyo Jeong 
367879f0effSWeongyo Jeong #define UPGT_MEMORY_MAX_PAGES		8
368879f0effSWeongyo Jeong struct upgt_memory {
369879f0effSWeongyo Jeong 	uint8_t				pages;
370879f0effSWeongyo Jeong 	struct upgt_memory_page		page[UPGT_MEMORY_MAX_PAGES];
371879f0effSWeongyo Jeong } __packed;
372879f0effSWeongyo Jeong 
373879f0effSWeongyo Jeong /*
374879f0effSWeongyo Jeong  * BPF
375879f0effSWeongyo Jeong  */
376879f0effSWeongyo Jeong struct upgt_rx_radiotap_header {
377879f0effSWeongyo Jeong 	struct ieee80211_radiotap_header wr_ihdr;
378879f0effSWeongyo Jeong 	uint8_t		wr_flags;
379879f0effSWeongyo Jeong 	uint8_t		wr_rate;
380879f0effSWeongyo Jeong 	uint16_t	wr_chan_freq;
381879f0effSWeongyo Jeong 	uint16_t	wr_chan_flags;
382879f0effSWeongyo Jeong 	int8_t		wr_antsignal;
383e8353a7aSHans Petter Selasky } __packed __aligned(8);
384879f0effSWeongyo Jeong 
385879f0effSWeongyo Jeong #define UPGT_RX_RADIOTAP_PRESENT					\
386879f0effSWeongyo Jeong 	((1 << IEEE80211_RADIOTAP_FLAGS) |				\
387879f0effSWeongyo Jeong 	 (1 << IEEE80211_RADIOTAP_RATE) |				\
388879f0effSWeongyo Jeong 	 (1 << IEEE80211_RADIOTAP_CHANNEL) |				\
389879f0effSWeongyo Jeong 	 (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
390879f0effSWeongyo Jeong 
391879f0effSWeongyo Jeong struct upgt_tx_radiotap_header {
392879f0effSWeongyo Jeong 	struct ieee80211_radiotap_header wt_ihdr;
393879f0effSWeongyo Jeong 	uint8_t		wt_flags;
394879f0effSWeongyo Jeong 	uint8_t		wt_rate;
395879f0effSWeongyo Jeong 	uint16_t	wt_chan_freq;
396879f0effSWeongyo Jeong 	uint16_t	wt_chan_flags;
397*786ac703SAndriy Voskoboinyk } __packed;
398879f0effSWeongyo Jeong 
399879f0effSWeongyo Jeong #define UPGT_TX_RADIOTAP_PRESENT					\
400879f0effSWeongyo Jeong 	((1 << IEEE80211_RADIOTAP_FLAGS) |				\
401879f0effSWeongyo Jeong 	 (1 << IEEE80211_RADIOTAP_RATE) |				\
402879f0effSWeongyo Jeong 	 (1 << IEEE80211_RADIOTAP_CHANNEL))
403879f0effSWeongyo Jeong 
404879f0effSWeongyo Jeong struct upgt_stat {
405879f0effSWeongyo Jeong 	uint32_t		st_tx_active;
406879f0effSWeongyo Jeong 	uint32_t		st_tx_inactive;
407879f0effSWeongyo Jeong 	uint32_t		st_tx_pending;
408879f0effSWeongyo Jeong };
409879f0effSWeongyo Jeong 
410879f0effSWeongyo Jeong #define	UPGT_STAT_INC(sc, var)	(sc)->sc_stat.var++
411879f0effSWeongyo Jeong #define	UPGT_STAT_DEC(sc, var)	(sc)->sc_stat.var--
412879f0effSWeongyo Jeong 
413879f0effSWeongyo Jeong struct upgt_vap {
414879f0effSWeongyo Jeong 	struct ieee80211vap	vap;
415879f0effSWeongyo Jeong 	int			(*newstate)(struct ieee80211vap *,
416879f0effSWeongyo Jeong 				    enum ieee80211_state, int);
417879f0effSWeongyo Jeong };
418879f0effSWeongyo Jeong #define	UPGT_VAP(vap)	((struct upgt_vap *)(vap))
419879f0effSWeongyo Jeong 
420879f0effSWeongyo Jeong struct upgt_softc {
4217a79cebfSGleb Smirnoff 	struct ieee80211com	 sc_ic;
4227a79cebfSGleb Smirnoff 	struct mbufq		 sc_snd;
423879f0effSWeongyo Jeong 	device_t		 sc_dev;
424760bc48eSAndrew Thompson 	struct usb_device	*sc_udev;
425c180b398SHans Petter Selasky 	void			*sc_rx_dma_buf;
426c180b398SHans Petter Selasky 	void			*sc_tx_dma_buf;
427879f0effSWeongyo Jeong 	struct mtx		 sc_mtx;
428879f0effSWeongyo Jeong 	struct upgt_stat	 sc_stat;
429879f0effSWeongyo Jeong 	int			 sc_flags;
430879f0effSWeongyo Jeong #define	UPGT_FLAG_FWLOADED	 (1 << 0)
431879f0effSWeongyo Jeong #define	UPGT_FLAG_INITDONE	 (1 << 1)
432645e4d17SHans Petter Selasky #define	UPGT_FLAG_DETACHED	 (1 << 2)
433879f0effSWeongyo Jeong 	int			 sc_debug;
434879f0effSWeongyo Jeong 
435879f0effSWeongyo Jeong 	enum ieee80211_state	 sc_state;
436879f0effSWeongyo Jeong 	int			 sc_arg;
437879f0effSWeongyo Jeong 	int			 sc_led_blink;
438879f0effSWeongyo Jeong 	struct callout		 sc_led_ch;
439879f0effSWeongyo Jeong 	uint8_t			 sc_cur_rateset[8];
440879f0effSWeongyo Jeong 
441879f0effSWeongyo Jeong 	/* watchdog  */
442879f0effSWeongyo Jeong 	int			 sc_tx_timer;
443879f0effSWeongyo Jeong 	struct callout		 sc_watchdog_ch;
444879f0effSWeongyo Jeong 
445879f0effSWeongyo Jeong 	/* Firmware.  */
446879f0effSWeongyo Jeong 	int			 sc_fw_type;
447879f0effSWeongyo Jeong 	/* memory addresses on device */
448879f0effSWeongyo Jeong 	uint32_t		 sc_memaddr_frame_start;
449879f0effSWeongyo Jeong 	uint32_t		 sc_memaddr_frame_end;
450879f0effSWeongyo Jeong 	uint32_t		 sc_memaddr_rx_start;
451879f0effSWeongyo Jeong 	struct upgt_memory	 sc_memory;
452879f0effSWeongyo Jeong 
453879f0effSWeongyo Jeong 	/* data which we found in the EEPROM */
4541b9c9ab2SHans Petter Selasky 	uint8_t			 sc_eeprom[2 * UPGT_EEPROM_SIZE] __aligned(4);
455879f0effSWeongyo Jeong 	uint16_t		 sc_eeprom_hwrx;
456879f0effSWeongyo Jeong 	struct upgt_lmac_freq3	 sc_eeprom_freq3[IEEE80211_CHAN_MAX];
457879f0effSWeongyo Jeong 	struct upgt_lmac_freq4	 sc_eeprom_freq4[IEEE80211_CHAN_MAX][8];
458879f0effSWeongyo Jeong 	struct upgt_lmac_freq6	 sc_eeprom_freq6[IEEE80211_CHAN_MAX];
459879f0effSWeongyo Jeong 	uint8_t			 sc_eeprom_freq6_settings;
460879f0effSWeongyo Jeong 
461879f0effSWeongyo Jeong 	/* RX/TX  */
462760bc48eSAndrew Thompson 	struct usb_xfer	*sc_xfer[UPGT_N_XFERS];
463879f0effSWeongyo Jeong 	int			 sc_rx_no;
464879f0effSWeongyo Jeong 	int			 sc_tx_no;
465879f0effSWeongyo Jeong 	struct upgt_data	 sc_rx_data[UPGT_RX_MAXCOUNT];
466879f0effSWeongyo Jeong 	upgt_datahead		 sc_rx_active;
467879f0effSWeongyo Jeong 	upgt_datahead		 sc_rx_inactive;
468879f0effSWeongyo Jeong 	struct upgt_data	 sc_tx_data[UPGT_TX_MAXCOUNT];
469879f0effSWeongyo Jeong 	upgt_datahead		 sc_tx_active;
470879f0effSWeongyo Jeong 	upgt_datahead		 sc_tx_inactive;
471879f0effSWeongyo Jeong 	upgt_datahead		 sc_tx_pending;
472879f0effSWeongyo Jeong 
473879f0effSWeongyo Jeong 	/* BPF  */
474879f0effSWeongyo Jeong 	struct upgt_rx_radiotap_header	sc_rxtap;
475879f0effSWeongyo Jeong 	struct upgt_tx_radiotap_header	sc_txtap;
476879f0effSWeongyo Jeong };
477879f0effSWeongyo Jeong 
478879f0effSWeongyo Jeong #define UPGT_LOCK(sc)		mtx_lock(&(sc)->sc_mtx)
479879f0effSWeongyo Jeong #define UPGT_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
480879f0effSWeongyo Jeong #define	UPGT_ASSERT_LOCKED(sc)	mtx_assert(&(sc)->sc_mtx, MA_OWNED)
481