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