1 /* $OpenBSD: acxvar.h,v 1.18 2007/07/18 18:10:31 damien 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 struct resource *sc_mem1_res;
356 bus_space_tag_t sc_mem1_bt;
357 bus_space_handle_t sc_mem1_bh;
358 int chip_mem1_rid;
359
360 /*
361 * MMIO 2
362 */
363 struct resource *sc_mem2_res;
364 bus_space_tag_t sc_mem2_bt;
365 bus_space_handle_t sc_mem2_bh;
366 int chip_mem2_rid;
367
368 struct resource *sc_irq_res;
369 void *sc_irq_handle;
370 int sc_irq_rid;
371
372 int (*sc_enable)(struct acx_softc *);
373 void (*sc_disable)(struct acx_softc *);
374 void (*sc_power)(struct acx_softc *, int);
375
376 uint32_t sc_cmd; /* cmd reg (MMIO 2) */
377 uint32_t sc_cmd_param; /* cmd param reg (MMIO 2) */
378 uint32_t sc_info; /* unused */
379 uint32_t sc_info_param; /* unused */
380
381 const uint16_t *chip_ioreg; /* reg map (MMIO 1) */
382
383 /*
384 * NOTE:
385 * chip_intr_enable is not necessarily same as
386 * ~chip_intr_disable
387 */
388 uint16_t chip_intr_enable;
389 uint16_t chip_intr_disable;
390
391 int chip_hw_crypt;
392 uint16_t chip_gpio_pled; /* power led */
393 uint16_t chip_chan_flags; /* see IEEE80211_CHAN_ */
394 uint16_t chip_txdesc1_len;
395 int chip_rxbuf_exhdr; /* based on fw ver */
396 uint32_t chip_ee_eaddr_ofs;
397 enum ieee80211_phymode chip_phymode; /* see IEEE80211_MODE_ */
398 uint8_t chip_fw_txdesc_ctrl;
399
400 uint8_t sc_eeprom_ver; /* unused */
401 uint8_t sc_form_factor; /* unused */
402 uint8_t sc_radio_type; /* see ACX_RADIO_TYPE_ */
403
404 struct acx_ring_data sc_ring_data;
405 struct acx_buf_data sc_buf_data;
406
407 struct acx_stats sc_stats; /* statistics */
408
409 /*
410 * Per interface sysctl variables
411 */
412 int sc_txtimer;
413 int sc_long_retry_limit;
414 int sc_short_retry_limit;
415 int sc_msdu_lifetime;
416
417 int (*sc_newstate)
418 (struct ieee80211com *,
419 enum ieee80211_state, int);
420
421 int (*chip_init) /* non-NULL */
422 (struct acx_softc *);
423
424 int (*chip_set_wepkey)
425 (struct acx_softc *,
426 struct ieee80211_key *, int);
427
428 int (*chip_read_config)
429 (struct acx_softc *, struct acx_config *);
430
431 int (*chip_write_config)
432 (struct acx_softc *, struct acx_config *);
433
434 void (*chip_set_fw_txdesc_rate) /* non-NULL */
435 (struct acx_softc *, struct acx_txbuf *, int);
436
437 void (*chip_set_bss_join_param) /* non-NULL */
438 (struct acx_softc *, void *, int);
439
440 void (*chip_proc_wep_rxbuf)
441 (struct acx_softc *, struct mbuf *, int *);
442
443 #if NBPFILTER > 0
444 caddr_t sc_drvbpf;
445
446 union {
447 struct acx_rx_radiotap_hdr th;
448 uint8_t pad[64];
449 } sc_rxtapu;
450 #define sc_rxtap sc_rxtapu.th
451 int sc_rxtap_len;
452
453 union {
454 struct acx_tx_radiotap_hdr th;
455 uint8_t pad[64];
456 } sc_txtapu;
457 #define sc_txtap sc_txtapu.th
458 int sc_txtap_len;
459 #endif
460 };
461
462 #define ACX_FLAG_FW_LOADED 0x01
463 #define ACX_FLAG_ACX111 0x02
464
465 #define ACX_RADIO_TYPE_MAXIM 0x0d
466 #define ACX_RADIO_TYPE_RFMD 0x11
467 #define ACX_RADIO_TYPE_RALINK 0x15
468 #define ACX_RADIO_TYPE_RADIA 0x16
469 #define ACX_RADIO_TYPE_UNKN17 0x17
470 #define ACX_RADIO_TYPE_UNKN19 0x19
471
472 #define ACX_RADIO_RSSI_MAXIM 120 /* 100dB */
473 #define ACX_RADIO_RSSI_RFMD 215 /* 215dB */
474 #define ACX_RADIO_RSSI_RALINK 0 /* XXX unknown yet */
475 #define ACX_RADIO_RSSI_RADIA 78 /* 78db */
476 #define ACX_RADIO_RSSI_UNKN 0 /* unknown radio */
477
478 extern const struct ieee80211_rateset acx_rates_11b;
479 extern const struct ieee80211_rateset acx_rates_11g;
480 extern int acx_beacon_intvl;
481
482 void acx100_set_param(struct acx_softc *);
483 void acx111_set_param(struct acx_softc *);
484
485 int acx_init_tmplt_ordered(struct acx_softc *);
486 void acx_write_phyreg(struct acx_softc *, uint32_t, uint8_t);
487
488 int acx_set_tmplt(struct acx_softc *, uint16_t, void *, uint16_t);
489 int acx_get_conf(struct acx_softc *, uint16_t, void *, uint16_t);
490 int acx_set_conf(struct acx_softc *, uint16_t, void *, uint16_t);
491 int acx_exec_command(struct acx_softc *, uint16_t, void *, uint16_t,
492 void *, uint16_t);
493 int acx_attach(struct acx_softc *);
494 int acx_detach(void *);
495 int acx_intr(void *);
496
497 #endif /* !_IF_ACXVAR_H */