xref: /openbsd/sys/dev/ic/acxvar.h (revision f88d426d)
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
57 extern 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  */
120 struct 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  */
157 struct 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  */
182 struct 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  */
216 struct 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 
235 struct 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 
247 struct 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 
263 struct acx_rxbuf {
264 	struct mbuf		*rb_mbuf;
265 	bus_dmamap_t		rb_mbuf_dmamap;
266 
267 	struct acx_host_desc	*rb_desc;
268 };
269 
270 struct 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 
282 struct acx_node {
283 	struct ieee80211_node		ni;	/* must be first */
284 	struct ieee80211_amrr_node	amn;
285 };
286 
287 struct acx_config {
288 	uint8_t	antenna;
289 	uint8_t	regdom;
290 	uint8_t	cca_mode;	/* acx100 */
291 	uint8_t	ed_thresh;	/* acx100 */
292 };
293 
294 struct 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 
311 struct 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 
325 struct 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 
333 struct 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 
472 extern int				acx_beacon_intvl;
473 
474 void	acx100_set_param(struct acx_softc *);
475 void	acx111_set_param(struct acx_softc *);
476 
477 int	acx_init_tmplt_ordered(struct acx_softc *);
478 void	acx_write_phyreg(struct acx_softc *, uint32_t, uint8_t);
479 
480 int	acx_set_tmplt(struct acx_softc *, uint16_t, void *, uint16_t);
481 int	acx_get_conf(struct acx_softc *, uint16_t, void *, uint16_t);
482 int	acx_set_conf(struct acx_softc *, uint16_t, void *, uint16_t);
483 int	acx_exec_command(struct acx_softc *, uint16_t, void *, uint16_t,
484 	    void *, uint16_t);
485 int	acx_attach(struct acx_softc *);
486 int	acx_detach(void *);
487 int	acx_intr(void *);
488 
489 #endif	/* !_IF_ACXVAR_H */
490