1/*	$OpenBSD: acxvar.h,v 1.20 2024/05/29 01:11:53 jsg 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_WRITE_REGION_1(sc, off, d, dlen)				\
99	bus_space_write_region_1((sc)->sc_mem2_bt, (sc)->sc_mem2_bh,	\
100				 (off),	(const uint8_t *)(d), (dlen))
101
102#define FW_TXDESC_SETFIELD_1(sc, mb, field, val)		\
103	bus_space_write_1((sc)->sc_mem2_bt, (sc)->sc_mem2_bh,	\
104	    (mb)->tb_fwdesc_ofs + offsetof(struct acx_fw_txdesc, field), (val))
105#define FW_TXDESC_SETFIELD_2(sc, mb, field, val)		\
106	bus_space_write_2((sc)->sc_mem2_bt, (sc)->sc_mem2_bh,	\
107	    (mb)->tb_fwdesc_ofs + offsetof(struct acx_fw_txdesc, field), (val))
108#define FW_TXDESC_SETFIELD_4(sc, mb, field, val)	\
109	bus_space_write_4((sc)->sc_mem2_bt, (sc)->sc_mem2_bh,	\
110	    (mb)->tb_fwdesc_ofs + offsetof(struct acx_fw_txdesc, field), (val))
111
112#define FW_TXDESC_GETFIELD_1(sc, mb, field)			\
113	bus_space_read_1((sc)->sc_mem2_bt, (sc)->sc_mem2_bh,	\
114	    (mb)->tb_fwdesc_ofs + offsetof(struct acx_fw_txdesc, field))
115
116/*
117 * Firmware TX descriptor
118 * Fields are little endian
119 */
120struct acx_fw_txdesc {
121	uint32_t	f_tx_next_desc;	/* next acx_fw_txdesc phyaddr */
122	uint32_t	f_tx_host_desc;	/* acx_host_desc phyaddr */
123	uint32_t	f_tx_acx_ptr;
124	uint32_t	f_tx_time;
125	uint16_t	f_tx_len;
126	uint16_t	f_tx_reserved;
127
128	uint32_t	f_tx_dev_spec[4];
129
130	uint8_t		f_tx_ctrl;	/* see DESC_CTRL_ */
131	uint8_t		f_tx_ctrl2;
132	uint8_t		f_tx_error;	/* see DESC_ERR_ */
133	uint8_t		f_tx_ack_fail;
134	uint8_t		f_tx_rts_fail;
135	uint8_t		f_tx_rts_ok;
136
137	/* XXX should be moved to chip specific file */
138	union {
139		struct {
140			uint8_t		rate100;	/* acx100 tx rate */
141			uint8_t		queue_ctrl;
142		} __packed r1;
143		struct {
144			uint16_t	rate111;	/* acx111 tx rate */
145		} __packed r2;
146	} u;
147#define f_tx_rate100	u.r1.rate100
148#define f_tx_queue_ctrl	u.r1.queue_ctrl
149#define f_tx_rate111	u.r2.rate111
150	uint32_t	f_tx_queue_info;
151} __packed;
152
153/*
154 * Firmware RX descriptor
155 * Fields are little endian
156 */
157struct acx_fw_rxdesc {
158	uint32_t	f_rx_next_desc;	/* next acx_fw_rxdesc phyaddr */
159	uint32_t	f_rx_host_desc;	/* acx_host_desc phyaddr */
160	uint32_t	f_rx_acx_ptr;
161	uint32_t	f_rx_time;
162	uint16_t	f_rx_len;
163	uint16_t	f_rx_wep_len;
164	uint32_t	f_rx_wep_ofs;
165
166	uint8_t		f_rx_dev_spec[16];
167
168	uint8_t		f_rx_ctrl;	/* see DESC_CTRL_ */
169	uint8_t		f_rx_rate;
170	uint8_t		f_rx_error;
171	uint8_t		f_rx_snr;	/* signal noise ratio */
172	uint8_t		f_rx_level;
173	uint8_t		f_rx_queue_ctrl;
174	uint16_t	f_rx_unknown0;
175	uint32_t	f_rx_unknown1;
176} __packed;
177
178/*
179 * Host TX/RX descriptor
180 * Fields are little endian
181 */
182struct acx_host_desc {
183	uint32_t	h_data_paddr;	/* data phyaddr */
184	uint16_t	h_data_ofs;
185	uint16_t	h_reserved;
186	uint16_t	h_ctrl;		/* see DESC_CTRL_ */
187	uint16_t	h_data_len;	/* data length */
188	uint32_t	h_next_desc;	/* next acx_host_desc phyaddr */
189	uint32_t	h_pnext;
190	uint32_t	h_status;	/* see DESC_STATUS_ */
191} __packed;
192
193#define DESC_STATUS_FULL		0x80000000
194
195#define DESC_CTRL_SHORT_PREAMBLE	0x01
196#define DESC_CTRL_FIRST_FRAG		0x02
197#define DESC_CTRL_AUTODMA		0x04
198#define DESC_CTRL_RECLAIM		0x08
199#define DESC_CTRL_HOSTDONE		0x20	/* host finished buf proc */
200#define DESC_CTRL_ACXDONE		0x40	/* chip finished buf proc */
201#define DESC_CTRL_HOSTOWN		0x80	/* host controls desc */
202
203#define DESC_ERR_OTHER_FRAG		0x01
204#define DESC_ERR_ABORT			0x02
205#define DESC_ERR_PARAM			0x04
206#define DESC_ERR_NO_WEPKEY		0x08
207#define DESC_ERR_MSDU_TIMEOUT		0x10
208#define DESC_ERR_EXCESSIVE_RETRY	0x20
209#define DESC_ERR_BUF_OVERFLOW		0x40
210#define DESC_ERR_DMA			0x80
211
212/*
213 * Extra header in receiving buffer
214 * Fields are little endian
215 */
216struct acx_rxbuf_hdr {
217	uint16_t	rbh_len;	/* ACX_RXBUG_LEN_MASK part is len */
218	uint8_t		rbh_memblk_cnt;
219	uint8_t		rbh_status;
220	uint8_t		rbh_stat_baseband; /* see ACX_RXBUF_STAT_ */
221	uint8_t		rbh_plcp;
222	uint8_t		rbh_level;	/* signal level */
223	uint8_t		rbh_snr;	/* signal noise ratio */
224	uint32_t	rbh_time;	/* recv timestamp */
225
226	/*
227	 * XXX may have 4~8 byte here which
228	 * depends on firmware version
229	 */
230} __packed;
231
232#define ACX_RXBUF_LEN_MASK	0xfff
233#define ACX_RXBUF_STAT_LNA	0x80	/* low noise amplifier */
234
235struct acx_ring_data {
236	struct acx_host_desc	*rx_ring;
237	bus_dma_segment_t	rx_ring_seg;
238	bus_dmamap_t		rx_ring_dmamap;
239	uint32_t		rx_ring_paddr;
240
241	struct acx_host_desc	*tx_ring;
242	bus_dma_segment_t	tx_ring_seg;
243	bus_dmamap_t		tx_ring_dmamap;
244	uint32_t		tx_ring_paddr;
245};
246
247struct acx_txbuf {
248	struct mbuf		*tb_mbuf;
249	bus_dmamap_t		tb_mbuf_dmamap;
250
251	struct acx_host_desc	*tb_desc1;
252	struct acx_host_desc	*tb_desc2;
253
254	uint32_t		tb_fwdesc_ofs;
255
256	/*
257	 * Used by tx rate updating
258	 */
259	struct acx_node		*tb_node;	/* remote node */
260	int			tb_rate;	/* current tx rate */
261};
262
263struct acx_rxbuf {
264	struct mbuf		*rb_mbuf;
265	bus_dmamap_t		rb_mbuf_dmamap;
266
267	struct acx_host_desc	*rb_desc;
268};
269
270struct acx_buf_data {
271	struct acx_rxbuf	rx_buf[ACX_RX_DESC_CNT];
272	struct acx_txbuf	tx_buf[ACX_TX_DESC_CNT];
273	bus_dmamap_t		mbuf_tmp_dmamap;
274
275	int			rx_scan_start;
276
277	int			tx_free_start;
278	int			tx_used_start;
279	int			tx_used_count;
280};
281
282struct acx_node {
283	struct ieee80211_node		ni;	/* must be first */
284	struct ieee80211_amrr_node	amn;
285};
286
287struct acx_config {
288	uint8_t	antenna;
289	uint8_t	regdom;
290	uint8_t	cca_mode;	/* acx100 */
291	uint8_t	ed_thresh;	/* acx100 */
292};
293
294struct acx_stats {
295	uint64_t	err_oth_frag;	/* XXX error in other frag?? */
296	uint64_t	err_abort;	/* tx abortion */
297	uint64_t	err_param;	/* tx desc contains invalid param */
298	uint64_t	err_no_wepkey;	/* no WEP key exists */
299	uint64_t	err_msdu_timeout; /* MSDU timed out */
300	uint64_t	err_ex_retry;	/* excessive tx retry */
301	uint64_t	err_buf_oflow;	/* buffer overflow */
302	uint64_t	err_dma;	/* DMA error */
303	uint64_t	err_unkn;	/* XXX unknown error */
304};
305
306#define ACX_RX_RADIOTAP_PRESENT						\
307	((1 << IEEE80211_RADIOTAP_FLAGS) |				\
308	 (1 << IEEE80211_RADIOTAP_CHANNEL) |				\
309	 (1 << IEEE80211_RADIOTAP_RSSI))
310
311struct acx_rx_radiotap_hdr {
312	struct ieee80211_radiotap_header	wr_ihdr;
313	uint8_t					wr_flags;
314	uint16_t				wr_chan_freq;
315	uint16_t				wr_chan_flags;
316	uint8_t					wr_rssi;
317	uint8_t					wr_max_rssi;
318} __packed;
319
320#define ACX_TX_RADIOTAP_PRESENT						\
321	((1 << IEEE80211_RADIOTAP_FLAGS) |				\
322	 (1 << IEEE80211_RADIOTAP_RATE) |				\
323	 (1 << IEEE80211_RADIOTAP_CHANNEL))				\
324
325struct acx_tx_radiotap_hdr {
326	struct ieee80211_radiotap_header	wt_ihdr;
327	uint8_t					wt_flags;
328	uint8_t					wt_rate;
329	uint16_t				wt_chan_freq;
330	uint16_t				wt_chan_flags;
331} __packed;
332
333struct acx_softc {
334	/*
335	 * sc_xxx are filled in by common code
336	 * chip_xxx are filled in by chip specific code
337	 */
338	struct device		sc_dev;
339	struct ieee80211com	sc_ic;
340
341	struct timeout		sc_chanscan_timer;
342	uint32_t		sc_flags;	/* see ACX_FLAG_ */
343
344	uint32_t		sc_firmware_ver;
345	uint32_t		sc_hardware_id;
346
347	bus_dma_tag_t		sc_dmat;
348
349	struct ieee80211_amrr	amrr;
350	struct timeout		amrr_ch;
351
352	/*
353	 * MMIO 1
354	 */
355	bus_space_tag_t		sc_mem1_bt;
356	bus_space_handle_t	sc_mem1_bh;
357	int			chip_mem1_rid;
358
359	/*
360	 * MMIO 2
361	 */
362	bus_space_tag_t		sc_mem2_bt;
363	bus_space_handle_t	sc_mem2_bh;
364	int			chip_mem2_rid;
365
366	int			(*sc_enable)(struct acx_softc *);
367	void			(*sc_disable)(struct acx_softc *);
368	void			(*sc_power)(struct acx_softc *, int);
369
370	uint32_t		sc_cmd;		/* cmd reg (MMIO 2) */
371	uint32_t		sc_cmd_param;	/* cmd param reg (MMIO 2) */
372	uint32_t		sc_info;	/* unused */
373	uint32_t		sc_info_param;	/* unused */
374
375	const uint16_t		*chip_ioreg;	/* reg map (MMIO 1) */
376
377	/*
378	 * NOTE:
379	 * chip_intr_enable is not necessarily same as
380	 * ~chip_intr_disable
381	 */
382	uint16_t		chip_intr_enable;
383	uint16_t		chip_intr_disable;
384
385	int			chip_hw_crypt;
386	uint16_t		chip_gpio_pled;	/* power led */
387	uint16_t		chip_chan_flags; /* see IEEE80211_CHAN_ */
388	uint16_t		chip_txdesc1_len;
389	int			chip_rxbuf_exhdr; /* based on fw ver */
390	uint32_t		chip_ee_eaddr_ofs;
391	enum ieee80211_phymode	chip_phymode;	/* see IEEE80211_MODE_ */
392	uint8_t			chip_fw_txdesc_ctrl;
393
394	uint8_t			sc_eeprom_ver;	/* unused */
395	uint8_t			sc_form_factor;	/* unused */
396	uint8_t			sc_radio_type;	/* see ACX_RADIO_TYPE_ */
397
398	struct acx_ring_data	sc_ring_data;
399	struct acx_buf_data	sc_buf_data;
400
401	struct acx_stats	sc_stats;	/* statistics */
402
403	/*
404	 * Per interface sysctl variables
405	 */
406	int			sc_txtimer;
407	int			sc_long_retry_limit;
408	int			sc_short_retry_limit;
409	int			sc_msdu_lifetime;
410
411	int			(*sc_newstate)
412				(struct ieee80211com *,
413				 enum ieee80211_state, int);
414
415	int			(*chip_init)		/* non-NULL */
416				(struct acx_softc *);
417
418	int			(*chip_set_wepkey)
419				(struct acx_softc *,
420				 struct ieee80211_key *, int);
421
422	int			(*chip_read_config)
423				(struct acx_softc *, struct acx_config *);
424
425	int			(*chip_write_config)
426				(struct acx_softc *, struct acx_config *);
427
428	void			(*chip_set_fw_txdesc_rate) /* non-NULL */
429				(struct acx_softc *, struct acx_txbuf *, int);
430
431	void			(*chip_set_bss_join_param) /* non-NULL */
432				(struct acx_softc *, void *, int);
433
434	void			(*chip_proc_wep_rxbuf)
435				(struct acx_softc *, struct mbuf *, int *);
436
437#if NBPFILTER > 0
438	caddr_t			sc_drvbpf;
439
440	union {
441		struct acx_rx_radiotap_hdr th;
442		uint8_t pad[64];
443	}			sc_rxtapu;
444#define sc_rxtap		sc_rxtapu.th
445	int			sc_rxtap_len;
446
447	union {
448		struct acx_tx_radiotap_hdr th;
449		uint8_t pad[64];
450	}			sc_txtapu;
451#define sc_txtap		sc_txtapu.th
452	int			sc_txtap_len;
453#endif
454};
455
456#define ACX_FLAG_FW_LOADED	0x01
457#define ACX_FLAG_ACX111		0x02
458
459#define ACX_RADIO_TYPE_MAXIM	0x0d
460#define ACX_RADIO_TYPE_RFMD	0x11
461#define ACX_RADIO_TYPE_RALINK	0x15
462#define ACX_RADIO_TYPE_RADIA	0x16
463#define ACX_RADIO_TYPE_UNKN17	0x17
464#define ACX_RADIO_TYPE_UNKN19	0x19
465
466#define ACX_RADIO_RSSI_MAXIM	120	/* 100dB */
467#define ACX_RADIO_RSSI_RFMD	215	/* 215dB */
468#define ACX_RADIO_RSSI_RALINK	0	/* XXX unknown yet */
469#define ACX_RADIO_RSSI_RADIA	78	/* 78db */
470#define ACX_RADIO_RSSI_UNKN	0	/* unknown radio */
471
472extern int				acx_beacon_intvl;
473
474void	acx100_set_param(struct acx_softc *);
475void	acx111_set_param(struct acx_softc *);
476
477int	acx_init_tmplt_ordered(struct acx_softc *);
478void	acx_write_phyreg(struct acx_softc *, uint32_t, uint8_t);
479
480int	acx_set_tmplt(struct acx_softc *, uint16_t, void *, uint16_t);
481int	acx_get_conf(struct acx_softc *, uint16_t, void *, uint16_t);
482int	acx_set_conf(struct acx_softc *, uint16_t, void *, uint16_t);
483int	acx_exec_command(struct acx_softc *, uint16_t, void *, uint16_t,
484	    void *, uint16_t);
485int	acx_attach(struct acx_softc *);
486int	acx_detach(void *);
487int	acx_intr(void *);
488
489#endif	/* !_IF_ACXVAR_H */
490