acxvar.h revision 1.9
1/*	$OpenBSD: acxvar.h,v 1.9 2006/08/06 13:03:03 mglocker Exp $ */
2
3/*
4 * Copyright (c) 2006 Jonathan Gray <jsg@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
19/*
20 * Copyright (c) 2006 The DragonFly Project.  All rights reserved.
21 *
22 * This code is derived from software contributed to The DragonFly Project
23 * by Sepherosa Ziehau <sepherosa@gmail.com>
24 *
25 * Redistribution and use in source and binary forms, with or without
26 * modification, are permitted provided that the following conditions
27 * are met:
28 *
29 * 1. Redistributions of source code must retain the above copyright
30 *    notice, this list of conditions and the following disclaimer.
31 * 2. Redistributions in binary form must reproduce the above copyright
32 *    notice, this list of conditions and the following disclaimer in
33 *    the documentation and/or other materials provided with the
34 *    distribution.
35 * 3. Neither the name of The DragonFly Project nor the names of its
36 *    contributors may be used to endorse or promote products derived
37 *    from this software without specific, prior written permission.
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
40 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
41 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
42 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
43 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
44 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
45 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
47 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
48 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
49 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 */
52
53#ifndef _IF_ACXVAR_H
54#define _IF_ACXVAR_H
55
56#ifdef ACX_DEBUG
57extern int acxdebug;
58#define DPRINTF(x)      do { if (acxdebug) printf x; } while (0)
59#define DPRINTFN(n,x)   do { if (acxdebug >= (n)) printf x; } while (0)
60#else
61#define DPRINTF(x)
62#define DPRINTFN(n,x)
63#endif
64
65#define ACX_FRAME_HDRLEN	sizeof(struct ieee80211_frame)
66#define ACX_MEMBLOCK_SIZE	256
67
68#define ACX_TX_DESC_CNT		16
69#define ACX_RX_DESC_CNT		16
70
71#define ACX_TX_RING_SIZE	\
72	(2 * ACX_TX_DESC_CNT * sizeof(struct acx_host_desc))
73#define ACX_RX_RING_SIZE	\
74	(ACX_RX_DESC_CNT * sizeof(struct acx_host_desc))
75
76#define CSR_READ_1(sc, reg)					\
77	bus_space_read_1((sc)->sc_mem1_bt, (sc)->sc_mem1_bh,	\
78			 (sc)->chip_ioreg[(reg)])
79#define CSR_READ_2(sc, reg)					\
80	bus_space_read_2((sc)->sc_mem1_bt, (sc)->sc_mem1_bh,	\
81			 (sc)->chip_ioreg[(reg)])
82#define CSR_READ_4(sc, reg)					\
83	bus_space_read_4((sc)->sc_mem1_bt, (sc)->sc_mem1_bh,	\
84			 (sc)->chip_ioreg[(reg)])
85
86#define CSR_WRITE_2(sc, reg, val)				\
87	bus_space_write_2((sc)->sc_mem1_bt, (sc)->sc_mem1_bh,	\
88			  (sc)->chip_ioreg[(reg)], val)
89#define CSR_WRITE_4(sc, reg, val)				\
90	bus_space_write_4((sc)->sc_mem1_bt, (sc)->sc_mem1_bh,	\
91			  (sc)->chip_ioreg[(reg)], val)
92
93#define CSR_SETB_2(sc, reg, b)		\
94	CSR_WRITE_2((sc), (reg), CSR_READ_2((sc), (reg)) | (b))
95#define CSR_CLRB_2(sc, reg, b)		\
96	CSR_WRITE_2((sc), (reg), CSR_READ_2((sc), (reg)) & (~(b)))
97
98#define DESC_READ_1(sc, off)		\
99	bus_space_read_1((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, (off))
100#define DESC_READ_4(sc, off)		\
101	bus_space_read_4((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, (off))
102
103#define DESC_WRITE_1(sc, off, val)	\
104	bus_space_write_1((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, (off), (val))
105#define DESC_WRITE_2(sc, off, val)	\
106	bus_space_write_2((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, (off), (val))
107#define DESC_WRITE_4(sc, off, val)	\
108	bus_space_write_4((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, (off), (val))
109#define DESC_WRITE_REGION_1(sc, off, d, dlen)				\
110	bus_space_write_region_1((sc)->sc_mem2_bt, (sc)->sc_mem2_bh,	\
111				 (off),	(const uint8_t *)(d), (dlen))
112
113#define FW_TXDESC_SETFIELD(sc, mb, field, val, sz)	\
114	DESC_WRITE_##sz((sc), (mb)->tb_fwdesc_ofs +	\
115			      offsetof(struct acx_fw_txdesc, field), (val))
116
117#define FW_TXDESC_GETFIELD(sc, mb, field, sz)		\
118	DESC_READ_##sz((sc), (mb)->tb_fwdesc_ofs +	\
119			     offsetof(struct acx_fw_txdesc, field))
120
121#define FW_TXDESC_SETFIELD_1(sc, mb, field, val)	\
122	FW_TXDESC_SETFIELD(sc, mb, field, val, 1)
123#define FW_TXDESC_SETFIELD_2(sc, mb, field, val)	\
124	FW_TXDESC_SETFIELD(sc, mb, field, htole16(val), 2)
125#define FW_TXDESC_SETFIELD_4(sc, mb, field, val)	\
126	FW_TXDESC_SETFIELD(sc, mb, field, htole32(val), 4)
127
128#define FW_TXDESC_GETFIELD_1(sc, mb, field)		\
129	FW_TXDESC_GETFIELD(sc, mb, field, 1)
130#define FW_TXDESC_GETFIELD_4(sc, mb, field)		\
131	letoh32(FW_TXDESC_GETFIELD(sc, mb, field, 4))
132
133/*
134 * Firmware TX descriptor
135 * Fields are little endian
136 */
137struct acx_fw_txdesc {
138	uint32_t	f_tx_next_desc;	/* next acx_fw_txdesc phyaddr */
139	uint32_t	f_tx_host_desc;	/* acx_host_desc phyaddr */
140	uint32_t	f_tx_acx_ptr;
141	uint32_t	f_tx_time;
142	uint16_t	f_tx_len;
143	uint16_t	f_tx_reserved;
144
145	uint32_t	f_tx_dev_spec[4];
146
147	uint8_t		f_tx_ctrl;	/* see DESC_CTRL_ */
148	uint8_t		f_tx_ctrl2;
149	uint8_t		f_tx_error;	/* see DESC_ERR_ */
150	uint8_t		f_tx_ack_fail;
151	uint8_t		f_tx_rts_fail;
152	uint8_t		f_tx_rts_ok;
153
154	/* XXX should be moved to chip specific file */
155	union {
156		struct {
157			uint8_t		rate100;	/* acx100 tx rate */
158			uint8_t		queue_ctrl;
159		} __packed r1;
160		struct {
161			uint16_t	rate111;	/* acx111 tx rate */
162		} __packed r2;
163	} u;
164#define f_tx_rate100	u.r1.rate100
165#define f_tx_queue_ctrl	u.r1.queue_ctrl
166#define f_tx_rate111	u.r2.rate111
167	uint32_t	f_tx_queue_info;
168} __packed;
169
170/*
171 * Firmware RX descriptor
172 * Fields are little endian
173 */
174struct acx_fw_rxdesc {
175	uint32_t	f_rx_next_desc;	/* next acx_fw_rxdesc phyaddr */
176	uint32_t	f_rx_host_desc;	/* acx_host_desc phyaddr */
177	uint32_t	f_rx_acx_ptr;
178	uint32_t	f_rx_time;
179	uint16_t	f_rx_len;
180	uint16_t	f_rx_wep_len;
181	uint32_t	f_rx_wep_ofs;
182
183	uint8_t		f_rx_dev_spec[16];
184
185	uint8_t		f_rx_ctrl;	/* see DESC_CTRL_ */
186	uint8_t		f_rx_rate;
187	uint8_t		f_rx_error;
188	uint8_t		f_rx_snr;	/* signal noise ratio */
189	uint8_t		f_rx_level;
190	uint8_t		f_rx_queue_ctrl;
191	uint16_t	f_rx_unknown0;
192	uint32_t	f_rx_unknown1;
193} __packed;
194
195/*
196 * Host TX/RX descriptor
197 * Fields are little endian
198 */
199struct acx_host_desc {
200	uint32_t	h_data_paddr;	/* data phyaddr */
201	uint16_t	h_data_ofs;
202	uint16_t	h_reserved;
203	uint16_t	h_ctrl;		/* see DESC_CTRL_ */
204	uint16_t	h_data_len;	/* data length */
205	uint32_t	h_next_desc;	/* next acx_host_desc phyaddr */
206	uint32_t	h_pnext;
207	uint32_t	h_status;	/* see DESC_STATUS_ */
208} __packed;
209
210#define DESC_STATUS_FULL		0x80000000
211
212#define DESC_CTRL_SHORT_PREAMBLE	0x01
213#define DESC_CTRL_FIRST_FRAG		0x02
214#define DESC_CTRL_AUTODMA		0x04
215#define DESC_CTRL_RECLAIM		0x08
216#define DESC_CTRL_HOSTDONE		0x20	/* host finished buf proc */
217#define DESC_CTRL_ACXDONE		0x40	/* chip finished buf proc */
218#define DESC_CTRL_HOSTOWN		0x80	/* host controls desc */
219
220#define DESC_ERR_OTHER_FRAG		0x01
221#define DESC_ERR_ABORT			0x02
222#define DESC_ERR_PARAM			0x04
223#define DESC_ERR_NO_WEPKEY		0x08
224#define DESC_ERR_MSDU_TIMEOUT		0x10
225#define DESC_ERR_EXCESSIVE_RETRY	0x20
226#define DESC_ERR_BUF_OVERFLOW		0x40
227#define DESC_ERR_DMA			0x80
228
229/*
230 * Extra header in receiving buffer
231 * Fields are little endian
232 */
233struct acx_rxbuf_hdr {
234	uint16_t	rbh_len;	/* ACX_RXBUG_LEN_MASK part is len */
235	uint8_t		rbh_memblk_cnt;
236	uint8_t		rbh_status;
237	uint8_t		rbh_stat_baseband; /* see ACX_RXBUF_STAT_ */
238	uint8_t		rbh_plcp;
239	uint8_t		rbh_level;	/* signal level */
240	uint8_t		rbh_snr;	/* signal noise ratio */
241	uint32_t	rbh_time;	/* recv timestamp */
242
243	/*
244	 * XXX may have 4~8 byte here which
245	 * depends on firmware version
246	 */
247} __packed;
248
249#define ACX_RXBUF_LEN_MASK	0xfff
250#define ACX_RXBUF_STAT_LNA	0x80	/* low noise amplifier */
251
252struct acx_ring_data {
253	struct acx_host_desc	*rx_ring;
254	bus_dma_segment_t	rx_ring_seg;
255	bus_dmamap_t		rx_ring_dmamap;
256	uint32_t		rx_ring_paddr;
257
258	struct acx_host_desc	*tx_ring;
259	bus_dma_segment_t	tx_ring_seg;
260	bus_dmamap_t		tx_ring_dmamap;
261	uint32_t		tx_ring_paddr;
262};
263
264struct acx_txbuf {
265	struct mbuf		*tb_mbuf;
266	bus_dmamap_t		tb_mbuf_dmamap;
267
268	struct acx_host_desc	*tb_desc1;
269	struct acx_host_desc	*tb_desc2;
270
271	uint32_t		tb_fwdesc_ofs;
272
273	/*
274	 * Used by tx rate updating
275	 */
276	struct acx_node		*tb_node;	/* remote node */
277	int			tb_rate;	/* current tx rate */
278};
279
280struct acx_rxbuf {
281	struct mbuf		*rb_mbuf;
282	bus_dmamap_t		rb_mbuf_dmamap;
283
284	struct acx_host_desc	*rb_desc;
285};
286
287struct acx_buf_data {
288	struct acx_rxbuf	rx_buf[ACX_RX_DESC_CNT];
289	struct acx_txbuf	tx_buf[ACX_TX_DESC_CNT];
290	bus_dmamap_t		mbuf_tmp_dmamap;
291
292	int			rx_scan_start;
293
294	int			tx_free_start;
295	int			tx_used_start;
296	int			tx_used_count;
297};
298
299struct acx_node {
300	struct ieee80211_node nd_node;	/* MUST be first */
301
302	struct ieee80211_rateset nd_rates; /* shared rates */
303	int	nd_txrate;		/* index into nd_rates[] */
304
305	int	nd_txrate_upd_intvl;	/* tx rate upd interval */
306	int	nd_txrate_upd_time;	/* tx rate upd timestamp */
307	int	nd_txrate_sample;	/* num of samples for specific rate */
308};
309
310struct acx_config {
311	uint8_t	antenna;
312	uint8_t	regdom;
313	uint8_t	cca_mode;	/* acx100 */
314	uint8_t	ed_thresh;	/* acx100 */
315};
316
317struct acx_stats {
318	uint64_t	err_oth_frag;	/* XXX error in other frag?? */
319	uint64_t	err_abort;	/* tx abortion */
320	uint64_t	err_param;	/* tx desc contains invalid param */
321	uint64_t	err_no_wepkey;	/* no WEP key exists */
322	uint64_t	err_msdu_timeout; /* MSDU timed out */
323	uint64_t	err_ex_retry;	/* excessive tx retry */
324	uint64_t	err_buf_oflow;	/* buffer overflow */
325	uint64_t	err_dma;	/* DMA error */
326	uint64_t	err_unkn;	/* XXX unknown error */
327};
328
329#define ACX_RX_RADIOTAP_PRESENT						\
330	((1 << IEEE80211_RADIOTAP_FLAGS) |				\
331	 (1 << IEEE80211_RADIOTAP_CHANNEL) |				\
332	 (1 << IEEE80211_RADIOTAP_RSSI))
333
334struct acx_rx_radiotap_hdr {
335	struct ieee80211_radiotap_header	wr_ihdr;
336	uint8_t					wr_flags;
337	uint16_t				wr_chan_freq;
338	uint16_t				wr_chan_flags;
339	uint8_t					wr_rssi;
340	uint8_t					wr_max_rssi;
341} __packed;
342
343#define ACX_TX_RADIOTAP_PRESENT						\
344	((1 << IEEE80211_RADIOTAP_FLAGS) |				\
345	 (1 << IEEE80211_RADIOTAP_RATE) |				\
346	 (1 << IEEE80211_RADIOTAP_CHANNEL))				\
347
348struct acx_tx_radiotap_hdr {
349	struct ieee80211_radiotap_header	wt_ihdr;
350	uint8_t					wt_flags;
351	uint8_t					wt_rate;
352	uint16_t				wt_chan_freq;
353	uint16_t				wt_chan_flags;
354} __packed;
355
356struct acx_softc {
357	/*
358	 * sc_xxx are filled in by common code
359	 * chip_xxx are filled in by chip specific code
360	 */
361	struct device		sc_dev;
362	struct ieee80211com	sc_ic;
363
364	struct timeout		sc_chanscan_timer;
365	uint32_t		sc_flags;	/* see ACX_FLAG_ */
366
367	uint32_t		sc_firmware_ver;
368	uint32_t		sc_hardware_id;
369
370	bus_dma_tag_t		sc_dmat;
371
372	/*
373	 * MMIO 1
374	 */
375	struct resource		*sc_mem1_res;
376	bus_space_tag_t		sc_mem1_bt;
377	bus_space_handle_t	sc_mem1_bh;
378	int			chip_mem1_rid;
379
380	/*
381	 * MMIO 2
382	 */
383	struct resource		*sc_mem2_res;
384	bus_space_tag_t		sc_mem2_bt;
385	bus_space_handle_t	sc_mem2_bh;
386	int			chip_mem2_rid;
387
388	struct resource		*sc_irq_res;
389	void			*sc_irq_handle;
390	int			sc_irq_rid;
391
392	int			(*sc_enable)(struct acx_softc *);
393	void			(*sc_disable)(struct acx_softc *);
394	void			(*sc_power)(struct acx_softc *, int);
395
396	uint32_t		sc_cmd;		/* cmd reg (MMIO 2) */
397	uint32_t		sc_cmd_param;	/* cmd param reg (MMIO 2) */
398	uint32_t		sc_info;	/* unused */
399	uint32_t		sc_info_param;	/* unused */
400
401	const uint16_t		*chip_ioreg;	/* reg map (MMIO 1) */
402
403	/*
404	 * NOTE:
405	 * chip_intr_enable is not necessarily same as
406	 * ~chip_intr_disable
407	 */
408	uint16_t		chip_intr_enable;
409	uint16_t		chip_intr_disable;
410
411	int			chip_hw_crypt;
412	uint16_t		chip_gpio_pled;	/* power led */
413	uint16_t		chip_chan_flags; /* see IEEE80211_CHAN_ */
414	uint16_t		chip_txdesc1_len;
415	int			chip_rxbuf_exhdr; /* based on fw ver */
416	uint32_t		chip_ee_eaddr_ofs;
417	enum ieee80211_phymode	chip_phymode;	/* see IEEE80211_MODE_ */
418	uint8_t			chip_fw_txdesc_ctrl;
419
420	uint8_t			sc_eeprom_ver;	/* unused */
421	uint8_t			sc_form_factor;	/* unused */
422	uint8_t			sc_radio_type;	/* see ACX_RADIO_TYPE_ */
423
424	struct acx_ring_data	sc_ring_data;
425	struct acx_buf_data	sc_buf_data;
426
427	struct acx_stats	sc_stats;	/* statistics */
428
429	/*
430	 * Per interface sysctl variables
431	 */
432	int			sc_txrate_upd_intvl_min;
433	int			sc_txrate_upd_intvl_max;
434	int			sc_txrate_sample_thresh;
435	int			sc_long_retry_limit;
436	int			sc_short_retry_limit;
437	int			sc_msdu_lifetime;
438
439	int			(*sc_newstate)
440				(struct ieee80211com *,
441				 enum ieee80211_state, int);
442
443	int			(*chip_init)		/* non-NULL */
444				(struct acx_softc *);
445
446#if 0
447	int			(*chip_set_wepkey)
448				(struct acx_softc *,
449				 struct ieee80211_key *, int);
450#endif
451
452	int			(*chip_read_config)
453				(struct acx_softc *, struct acx_config *);
454
455	int			(*chip_write_config)
456				(struct acx_softc *, struct acx_config *);
457
458	void			(*chip_set_fw_txdesc_rate) /* non-NULL */
459				(struct acx_softc *, struct acx_txbuf *, int);
460
461	void			(*chip_set_bss_join_param) /* non-NULL */
462				(struct acx_softc *, void *, int);
463
464	void			(*chip_proc_wep_rxbuf)
465				(struct acx_softc *, struct mbuf *, int *);
466
467#if NBPFILTER > 0
468	caddr_t			sc_drvbpf;
469
470	union {
471		struct acx_rx_radiotap_hdr th;
472		uint8_t pad[64];
473	}			sc_rxtapu;
474#define sc_rxtap		sc_rxtapu.th
475	int			sc_rxtap_len;
476
477	union {
478		struct acx_tx_radiotap_hdr th;
479		uint8_t pad[64];
480	}			sc_txtapu;
481#define sc_txtap		sc_txtapu.th
482	int			sc_txtap_len;
483#endif
484};
485
486#define ACX_FLAG_FW_LOADED	0x01
487#define ACX_FLAG_ACX111		0x02
488
489#define ACX_RADIO_TYPE_MAXIM	0x0d
490#define ACX_RADIO_TYPE_RFMD	0x11
491#define ACX_RADIO_TYPE_RALINK	0x15
492#define ACX_RADIO_TYPE_RADIA	0x16
493#define ACX_RADIO_TYPE_UNKN17	0x17
494#define ACX_RADIO_TYPE_UNKN19	0x19
495
496extern const struct ieee80211_rateset	acx_rates_11b;
497extern const struct ieee80211_rateset	acx_rates_11g;
498extern int				acx_beacon_intvl;
499
500void	acx100_set_param(struct acx_softc *);
501void	acx111_set_param(struct acx_softc *);
502
503int	acx_init_tmplt_ordered(struct acx_softc *);
504void	acx_write_phyreg(struct acx_softc *, uint32_t, uint8_t);
505
506int	acx_set_tmplt(struct acx_softc *, uint16_t, void *, uint16_t);
507int	acx_get_conf(struct acx_softc *, uint16_t, void *, uint16_t);
508int	acx_set_conf(struct acx_softc *, uint16_t, void *, uint16_t);
509int	acx_exec_command(struct acx_softc *, uint16_t, void *, uint16_t,
510	    void *, uint16_t);
511int	acx_attach(struct acx_softc *);
512int	acx_detach(void *);
513int	acx_intr(void *);
514
515#endif	/* !_IF_ACXVAR_H */
516