1/*	$OpenBSD: if_upgtvar.h,v 1.14 2008/02/02 13:48:44 mglocker Exp $ */
2
3/*
4 * Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19struct upgt_softc;
20
21/*
22 * General values.
23 */
24enum {
25	UPGT_BULK_RX,
26	UPGT_BULK_TX,
27	UPGT_N_XFERS = 2,
28};
29
30#define UPGT_CONFIG_INDEX		0
31#define UPGT_IFACE_INDEX		0
32#define UPGT_USB_TIMEOUT		1000
33#define UPGT_FIRMWARE_TIMEOUT		10
34
35#define UPGT_MEMADDR_FIRMWARE_START	0x00020000	/* 512 bytes large */
36#define UPGT_MEMSIZE_FRAME_HEAD		0x0070
37#define UPGT_MEMSIZE_RX			0x3500
38
39#define	UPGT_RX_MAXCOUNT		6
40#define	UPGT_TX_MAXCOUNT		128
41#define	UPGT_TX_STAT_INTERVAL		5
42#define	UPGT_RX_MINSZ			(sizeof(struct upgt_lmac_header) + 4)
43
44/* device flags */
45#define UPGT_DEVICE_ATTACHED		(1 << 0)
46
47/* leds */
48#define UPGT_LED_OFF			0
49#define UPGT_LED_ON			1
50#define UPGT_LED_BLINK			2
51
52/*
53 * Firmware.
54 */
55#define UPGT_FW_BLOCK_SIZE		256
56
57#define UPGT_BRA_FWTYPE_SIZE		4
58#define UPGT_BRA_FWTYPE_LM86		"LM86"
59#define UPGT_BRA_FWTYPE_LM87		"LM87"
60enum upgt_fw_type {
61	UPGT_FWTYPE_LM86,
62	UPGT_FWTYPE_LM87
63};
64
65#define UPGT_BRA_TYPE_FW		0x80000001
66#define UPGT_BRA_TYPE_VERSION		0x80000002
67#define UPGT_BRA_TYPE_DEPIF		0x80000003
68#define UPGT_BRA_TYPE_EXPIF		0x80000004
69#define UPGT_BRA_TYPE_DESCR		0x80000101
70#define UPGT_BRA_TYPE_END		0xff0000ff
71struct upgt_fw_bra_option {
72	uint32_t			type;
73	uint32_t			len;
74	uint8_t				data[];
75} __packed;
76
77struct upgt_fw_bra_descr {
78	uint32_t			unknown1;
79	uint32_t			memaddr_space_start;
80	uint32_t			memaddr_space_end;
81	uint32_t			unknown2;
82	uint32_t			unknown3;
83	uint8_t				rates[20];
84} __packed;
85
86#define UPGT_X2_SIGNATURE_SIZE		4
87#define UPGT_X2_SIGNATURE		"x2  "
88struct upgt_fw_x2_header {
89	uint8_t				signature[4];
90	uint32_t			startaddr;
91	uint32_t			len;
92	uint32_t			crc;
93} __packed;
94
95/*
96 * EEPROM.
97 */
98#define UPGT_EEPROM_SIZE		8192
99#define UPGT_EEPROM_BLOCK_SIZE		1020
100
101struct upgt_eeprom_header {
102	/* 14 bytes */
103	uint32_t			magic;
104	uint16_t			pad1;
105	uint16_t			preamble_len;
106	uint32_t			pad2;
107	/* data */
108} __packed;
109
110#define UPGT_EEPROM_TYPE_END		0x0000
111#define UPGT_EEPROM_TYPE_NAME		0x0001
112#define UPGT_EEPROM_TYPE_SERIAL		0x0003
113#define UPGT_EEPROM_TYPE_MAC		0x0101
114#define UPGT_EEPROM_TYPE_HWRX		0x1001
115#define UPGT_EEPROM_TYPE_CHIP		0x1002
116#define UPGT_EEPROM_TYPE_FREQ3		0x1903
117#define UPGT_EEPROM_TYPE_FREQ4		0x1904
118#define UPGT_EEPROM_TYPE_FREQ5		0x1905
119#define UPGT_EEPROM_TYPE_FREQ6		0x1906
120#define UPGT_EEPROM_TYPE_OFF		0xffff
121struct upgt_eeprom_option {
122	uint16_t			len;
123	uint16_t			type;
124	uint8_t				data[];
125	/* data */
126} __packed;
127
128#define UPGT_EEPROM_RX_CONST		0x88
129struct upgt_eeprom_option_hwrx {
130	uint32_t			pad1;
131	uint8_t				rxfilter;
132	uint8_t				pad2[15];
133} __packed;
134
135struct upgt_eeprom_freq3_header {
136	uint8_t				flags;
137	uint8_t				elements;
138} __packed;
139
140struct upgt_eeprom_freq4_header {
141	uint8_t				flags;
142	uint8_t				elements;
143	uint8_t				settings;
144	uint8_t				type;
145} __packed;
146
147struct upgt_eeprom_freq4_1 {
148	uint16_t			freq;
149	uint8_t				data[50];
150} __packed;
151
152struct upgt_eeprom_freq4_2 {
153	uint16_t			head;
154	uint8_t				subtails[4];
155	uint8_t				tail;
156} __packed;
157
158/*
159 * LMAC protocol.
160 */
161struct upgt_lmac_mem {
162	uint32_t			addr;
163	uint32_t			chksum;
164} __packed;
165
166#define UPGT_H1_FLAGS_TX_MGMT		0x00	/* for TX: mgmt frame */
167#define UPGT_H1_FLAGS_TX_NO_CALLBACK	0x01	/* for TX: no USB callback */
168#define UPGT_H1_FLAGS_TX_DATA		0x10	/* for TX: data frame */
169#define UPGT_H1_TYPE_RX_DATA		0x00	/* 802.11 RX data frame */
170#define UPGT_H1_TYPE_RX_DATA_MGMT	0x04	/* 802.11 RX mgmt frame */
171#define UPGT_H1_TYPE_TX_DATA		0x40	/* 802.11 TX data frame */
172#define UPGT_H1_TYPE_CTRL		0x80	/* control frame */
173struct upgt_lmac_h1 {
174	/* 4 bytes */
175	uint8_t				flags;
176	uint8_t				type;
177	uint16_t			len;
178} __packed;
179
180#define UPGT_H2_TYPE_TX_ACK_NO		0x0000
181#define UPGT_H2_TYPE_TX_ACK_YES		0x0001
182#define UPGT_H2_TYPE_MACFILTER		0x0000
183#define UPGT_H2_TYPE_CHANNEL		0x0001
184#define UPGT_H2_TYPE_TX_DONE		0x0008
185#define UPGT_H2_TYPE_STATS		0x000a
186#define UPGT_H2_TYPE_EEPROM		0x000c
187#define UPGT_H2_TYPE_LED		0x000d
188#define UPGT_H2_FLAGS_TX_ACK_NO		0x0101
189#define UPGT_H2_FLAGS_TX_ACK_YES	0x0707
190struct upgt_lmac_h2 {
191	/* 8 bytes */
192	uint32_t			reqid;
193	uint16_t			type;
194	uint16_t			flags;
195} __packed;
196
197struct upgt_lmac_header {
198	/* 12 bytes */
199	struct upgt_lmac_h1		header1;
200	struct upgt_lmac_h2		header2;
201} __packed;
202
203struct upgt_lmac_eeprom {
204	/* 16 bytes */
205	struct upgt_lmac_h1		header1;
206	struct upgt_lmac_h2		header2;
207	uint16_t			offset;
208	uint16_t			len;
209	/* data */
210} __packed;
211
212#define UPGT_FILTER_TYPE_NONE		0x0000
213#define UPGT_FILTER_TYPE_STA		0x0001
214#define UPGT_FILTER_TYPE_IBSS		0x0002
215#define UPGT_FILTER_TYPE_HOSTAP		0x0004
216#define UPGT_FILTER_TYPE_MONITOR	0x0010
217#define UPGT_FILTER_TYPE_RESET		0x0020
218#define UPGT_FILTER_UNKNOWN1		0x0002
219#define UPGT_FILTER_UNKNOWN2		0x0ca8
220#define UPGT_FILTER_UNKNOWN3		0xffff
221#define UPGT_FILTER_MONITOR_UNKNOWN1	0x0000
222#define UPGT_FILTER_MONITOR_UNKNOWN2	0x0000
223#define UPGT_FILTER_MONITOR_UNKNOWN3	0x0000
224struct upgt_lmac_filter {
225	struct upgt_lmac_h1		header1;
226	struct upgt_lmac_h2		header2;
227	/* 32 bytes */
228	uint16_t			type;
229	uint8_t				dst[IEEE80211_ADDR_LEN];
230	uint8_t				src[IEEE80211_ADDR_LEN];
231	uint16_t			unknown1;
232	uint32_t			rxaddr;
233	uint16_t			unknown2;
234	uint32_t			rxhw;
235	uint16_t			unknown3;
236	uint32_t			unknown4;
237} __packed;
238
239/* frequence 3 data */
240struct upgt_lmac_freq3 {
241	uint16_t			freq;
242	uint8_t				data[6];
243} __packed;
244
245/* frequence 4 data */
246struct upgt_lmac_freq4 {
247	struct upgt_eeprom_freq4_2	cmd;
248	uint8_t				pad;
249};
250
251/* frequence 6 data */
252struct upgt_lmac_freq6 {
253	uint16_t			freq;
254	uint8_t				data[8];
255} __packed;
256
257#define UPGT_CHANNEL_UNKNOWN1		0x0001
258#define UPGT_CHANNEL_UNKNOWN2		0x0000
259#define UPGT_CHANNEL_UNKNOWN3		0x48
260struct upgt_lmac_channel {
261	struct upgt_lmac_h1		header1;
262	struct upgt_lmac_h2		header2;
263	/* 112 bytes */
264	uint16_t			unknown1;
265	uint16_t			unknown2;
266	uint8_t				pad1[20];
267	struct upgt_lmac_freq6		freq6;
268	uint8_t				settings;
269	uint8_t				unknown3;
270	uint8_t				freq3_1[4];
271	struct upgt_lmac_freq4		freq4[8];
272	uint8_t				freq3_2[4];
273	uint32_t			pad2;
274} __packed;
275
276#define UPGT_LED_MODE_SET		0x0003
277#define UPGT_LED_ACTION_OFF		0x0002
278#define UPGT_LED_ACTION_ON		0x0003
279#define UPGT_LED_ACTION_TMP_DUR		100	/* ms */
280struct upgt_lmac_led {
281	struct upgt_lmac_h1		header1;
282	struct upgt_lmac_h2		header2;
283	uint16_t			mode;
284	uint16_t			action_fix;
285	uint16_t			action_tmp;
286	uint16_t			action_tmp_dur;
287} __packed;
288
289struct upgt_lmac_stats {
290	struct upgt_lmac_h1		header1;
291	struct upgt_lmac_h2		header2;
292	uint8_t				data[76];
293} __packed;
294
295struct upgt_lmac_rx_desc {
296	struct upgt_lmac_h1		header1;
297	/* 16 bytes */
298	uint16_t			freq;
299	uint8_t				unknown1;
300	uint8_t				rate;
301	uint8_t				rssi;
302	uint8_t				pad;
303	uint16_t			unknown2;
304	uint32_t			timestamp;
305	uint32_t			unknown3;
306	uint8_t				data[];
307} __packed;
308
309#define UPGT_TX_DESC_KEY_EXISTS		0x01
310struct upgt_lmac_tx_desc_wep {
311	uint8_t				key_exists;
312	uint8_t				key_len;
313	uint8_t				key_val[16];
314} __packed;
315
316#define UPGT_TX_DESC_TYPE_BEACON	0x00000000
317#define UPGT_TX_DESC_TYPE_PROBE		0x00000001
318#define UPGT_TX_DESC_TYPE_MGMT		0x00000002
319#define UPGT_TX_DESC_TYPE_DATA		0x00000004
320#define UPGT_TX_DESC_PAD3_SIZE		2
321struct upgt_lmac_tx_desc {
322	struct upgt_lmac_h1		header1;
323	struct upgt_lmac_h2		header2;
324	uint8_t				rates[8];
325	uint16_t			pad1;
326	struct upgt_lmac_tx_desc_wep	wep_key;
327	uint32_t			type;
328	uint32_t			pad2;
329	uint32_t			unknown1;
330	uint32_t			unknown2;
331	uint8_t				pad3[2];
332	/* 802.11 frame data */
333} __packed;
334
335#define UPGT_TX_DONE_DESC_STATUS_OK	0x0001
336struct upgt_lmac_tx_done_desc {
337	struct upgt_lmac_h1		header1;
338	struct upgt_lmac_h2		header2;
339	uint16_t			status;
340	uint16_t			rssi;
341	uint16_t			seq;
342	uint16_t			unknown;
343} __packed;
344
345/*
346 * USB xfers.
347 */
348struct upgt_data {
349	uint8_t				*buf;
350	uint32_t			 buflen;
351	struct ieee80211_node		*ni;
352	struct mbuf			*m;
353	uint32_t			 addr;
354	STAILQ_ENTRY(upgt_data)		 next;
355};
356typedef STAILQ_HEAD(, upgt_data) upgt_datahead;
357
358/*
359 * Prism memory.
360 */
361struct upgt_memory_page {
362	uint8_t				used;
363	uint32_t			addr;
364} __packed;
365
366#define UPGT_MEMORY_MAX_PAGES		8
367struct upgt_memory {
368	uint8_t				pages;
369	struct upgt_memory_page		page[UPGT_MEMORY_MAX_PAGES];
370} __packed;
371
372/*
373 * BPF
374 */
375struct upgt_rx_radiotap_header {
376	struct ieee80211_radiotap_header wr_ihdr;
377	uint8_t		wr_flags;
378	uint8_t		wr_rate;
379	uint16_t	wr_chan_freq;
380	uint16_t	wr_chan_flags;
381	int8_t		wr_antsignal;
382} __packed __aligned(8);
383
384#define UPGT_RX_RADIOTAP_PRESENT					\
385	((1 << IEEE80211_RADIOTAP_FLAGS) |				\
386	 (1 << IEEE80211_RADIOTAP_RATE) |				\
387	 (1 << IEEE80211_RADIOTAP_CHANNEL) |				\
388	 (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
389
390struct upgt_tx_radiotap_header {
391	struct ieee80211_radiotap_header wt_ihdr;
392	uint8_t		wt_flags;
393	uint8_t		wt_rate;
394	uint16_t	wt_chan_freq;
395	uint16_t	wt_chan_flags;
396} __packed;
397
398#define UPGT_TX_RADIOTAP_PRESENT					\
399	((1 << IEEE80211_RADIOTAP_FLAGS) |				\
400	 (1 << IEEE80211_RADIOTAP_RATE) |				\
401	 (1 << IEEE80211_RADIOTAP_CHANNEL))
402
403struct upgt_stat {
404	uint32_t		st_tx_active;
405	uint32_t		st_tx_inactive;
406	uint32_t		st_tx_pending;
407};
408
409#define	UPGT_STAT_INC(sc, var)	(sc)->sc_stat.var++
410#define	UPGT_STAT_DEC(sc, var)	(sc)->sc_stat.var--
411
412struct upgt_vap {
413	struct ieee80211vap	vap;
414	int			(*newstate)(struct ieee80211vap *,
415				    enum ieee80211_state, int);
416};
417#define	UPGT_VAP(vap)	((struct upgt_vap *)(vap))
418
419struct upgt_softc {
420	struct ieee80211com	 sc_ic;
421	struct mbufq		 sc_snd;
422	device_t		 sc_dev;
423	struct usb_device	*sc_udev;
424	void			*sc_rx_dma_buf;
425	void			*sc_tx_dma_buf;
426	struct mtx		 sc_mtx;
427	struct upgt_stat	 sc_stat;
428	int			 sc_flags;
429#define	UPGT_FLAG_FWLOADED	 (1 << 0)
430#define	UPGT_FLAG_INITDONE	 (1 << 1)
431#define	UPGT_FLAG_DETACHED	 (1 << 2)
432	int			 sc_debug;
433
434	enum ieee80211_state	 sc_state;
435	int			 sc_arg;
436	int			 sc_led_blink;
437	struct callout		 sc_led_ch;
438	uint8_t			 sc_cur_rateset[8];
439
440	/* watchdog  */
441	int			 sc_tx_timer;
442	struct callout		 sc_watchdog_ch;
443
444	/* Firmware.  */
445	int			 sc_fw_type;
446	/* memory addresses on device */
447	uint32_t		 sc_memaddr_frame_start;
448	uint32_t		 sc_memaddr_frame_end;
449	uint32_t		 sc_memaddr_rx_start;
450	struct upgt_memory	 sc_memory;
451
452	/* data which we found in the EEPROM */
453	uint8_t			 sc_eeprom[2 * UPGT_EEPROM_SIZE] __aligned(4);
454	uint16_t		 sc_eeprom_hwrx;
455	struct upgt_lmac_freq3	 sc_eeprom_freq3[IEEE80211_CHAN_MAX];
456	struct upgt_lmac_freq4	 sc_eeprom_freq4[IEEE80211_CHAN_MAX][8];
457	struct upgt_lmac_freq6	 sc_eeprom_freq6[IEEE80211_CHAN_MAX];
458	uint8_t			 sc_eeprom_freq6_settings;
459
460	/* RX/TX  */
461	struct usb_xfer	*sc_xfer[UPGT_N_XFERS];
462	int			 sc_rx_no;
463	int			 sc_tx_no;
464	struct upgt_data	 sc_rx_data[UPGT_RX_MAXCOUNT];
465	upgt_datahead		 sc_rx_active;
466	upgt_datahead		 sc_rx_inactive;
467	struct upgt_data	 sc_tx_data[UPGT_TX_MAXCOUNT];
468	upgt_datahead		 sc_tx_active;
469	upgt_datahead		 sc_tx_inactive;
470	upgt_datahead		 sc_tx_pending;
471
472	/* BPF  */
473	struct upgt_rx_radiotap_header	sc_rxtap;
474	struct upgt_tx_radiotap_header	sc_txtap;
475};
476
477#define UPGT_LOCK(sc)		mtx_lock(&(sc)->sc_mtx)
478#define UPGT_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
479#define	UPGT_ASSERT_LOCKED(sc)	mtx_assert(&(sc)->sc_mtx, MA_OWNED)
480