492 lines
14 KiB
C
492 lines
14 KiB
C
/* $OpenBSD: acxvar.h,v 1.19 2008/07/21 04:12:21 kevlo Exp $ */
|
|
|
|
/*
|
|
* Copyright (c) 2006 Jonathan Gray <jsg@openbsd.org>
|
|
*
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
/*
|
|
* Copyright (c) 2006 The DragonFly Project. All rights reserved.
|
|
*
|
|
* This code is derived from software contributed to The DragonFly Project
|
|
* by Sepherosa Ziehau <sepherosa@gmail.com>
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in
|
|
* the documentation and/or other materials provided with the
|
|
* distribution.
|
|
* 3. Neither the name of The DragonFly Project nor the names of its
|
|
* contributors may be used to endorse or promote products derived
|
|
* from this software without specific, prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*/
|
|
|
|
#ifndef _IF_ACXVAR_H
|
|
#define _IF_ACXVAR_H
|
|
|
|
#ifdef ACX_DEBUG
|
|
extern int acxdebug;
|
|
#define DPRINTF(x) do { if (acxdebug) printf x; } while (0)
|
|
#define DPRINTFN(n,x) do { if (acxdebug >= (n)) printf x; } while (0)
|
|
#else
|
|
#define DPRINTF(x)
|
|
#define DPRINTFN(n,x)
|
|
#endif
|
|
|
|
#define ACX_FRAME_HDRLEN sizeof(struct ieee80211_frame)
|
|
#define ACX_MEMBLOCK_SIZE 256
|
|
|
|
#define ACX_TX_DESC_CNT 16
|
|
#define ACX_RX_DESC_CNT 16
|
|
|
|
#define ACX_TX_RING_SIZE \
|
|
(2 * ACX_TX_DESC_CNT * sizeof(struct acx_host_desc))
|
|
#define ACX_RX_RING_SIZE \
|
|
(ACX_RX_DESC_CNT * sizeof(struct acx_host_desc))
|
|
|
|
#define CSR_READ_1(sc, reg) \
|
|
bus_space_read_1((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, \
|
|
(sc)->chip_ioreg[(reg)])
|
|
#define CSR_READ_2(sc, reg) \
|
|
bus_space_read_2((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, \
|
|
(sc)->chip_ioreg[(reg)])
|
|
#define CSR_READ_4(sc, reg) \
|
|
bus_space_read_4((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, \
|
|
(sc)->chip_ioreg[(reg)])
|
|
|
|
#define CSR_WRITE_2(sc, reg, val) \
|
|
bus_space_write_2((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, \
|
|
(sc)->chip_ioreg[(reg)], val)
|
|
#define CSR_WRITE_4(sc, reg, val) \
|
|
bus_space_write_4((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, \
|
|
(sc)->chip_ioreg[(reg)], val)
|
|
|
|
#define CSR_SETB_2(sc, reg, b) \
|
|
CSR_WRITE_2((sc), (reg), CSR_READ_2((sc), (reg)) | (b))
|
|
#define CSR_CLRB_2(sc, reg, b) \
|
|
CSR_WRITE_2((sc), (reg), CSR_READ_2((sc), (reg)) & (~(b)))
|
|
|
|
#define DESC_WRITE_REGION_1(sc, off, d, dlen) \
|
|
bus_space_write_region_1((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, \
|
|
(off), (const uint8_t *)(d), (dlen))
|
|
|
|
#define FW_TXDESC_SETFIELD_1(sc, mb, field, val) \
|
|
bus_space_write_1((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, \
|
|
(mb)->tb_fwdesc_ofs + offsetof(struct acx_fw_txdesc, field), (val))
|
|
#define FW_TXDESC_SETFIELD_2(sc, mb, field, val) \
|
|
bus_space_write_2((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, \
|
|
(mb)->tb_fwdesc_ofs + offsetof(struct acx_fw_txdesc, field), (val))
|
|
#define FW_TXDESC_SETFIELD_4(sc, mb, field, val) \
|
|
bus_space_write_4((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, \
|
|
(mb)->tb_fwdesc_ofs + offsetof(struct acx_fw_txdesc, field), (val))
|
|
|
|
#define FW_TXDESC_GETFIELD_1(sc, mb, field) \
|
|
bus_space_read_1((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, \
|
|
(mb)->tb_fwdesc_ofs + offsetof(struct acx_fw_txdesc, field))
|
|
|
|
/*
|
|
* Firmware TX descriptor
|
|
* Fields are little endian
|
|
*/
|
|
struct acx_fw_txdesc {
|
|
uint32_t f_tx_next_desc; /* next acx_fw_txdesc phyaddr */
|
|
uint32_t f_tx_host_desc; /* acx_host_desc phyaddr */
|
|
uint32_t f_tx_acx_ptr;
|
|
uint32_t f_tx_time;
|
|
uint16_t f_tx_len;
|
|
uint16_t f_tx_reserved;
|
|
|
|
uint32_t f_tx_dev_spec[4];
|
|
|
|
uint8_t f_tx_ctrl; /* see DESC_CTRL_ */
|
|
uint8_t f_tx_ctrl2;
|
|
uint8_t f_tx_error; /* see DESC_ERR_ */
|
|
uint8_t f_tx_ack_fail;
|
|
uint8_t f_tx_rts_fail;
|
|
uint8_t f_tx_rts_ok;
|
|
|
|
/* XXX should be moved to chip specific file */
|
|
union {
|
|
struct {
|
|
uint8_t rate100; /* acx100 tx rate */
|
|
uint8_t queue_ctrl;
|
|
} __packed r1;
|
|
struct {
|
|
uint16_t rate111; /* acx111 tx rate */
|
|
} __packed r2;
|
|
} u;
|
|
#define f_tx_rate100 u.r1.rate100
|
|
#define f_tx_queue_ctrl u.r1.queue_ctrl
|
|
#define f_tx_rate111 u.r2.rate111
|
|
uint32_t f_tx_queue_info;
|
|
} __packed;
|
|
|
|
/*
|
|
* Firmware RX descriptor
|
|
* Fields are little endian
|
|
*/
|
|
struct acx_fw_rxdesc {
|
|
uint32_t f_rx_next_desc; /* next acx_fw_rxdesc phyaddr */
|
|
uint32_t f_rx_host_desc; /* acx_host_desc phyaddr */
|
|
uint32_t f_rx_acx_ptr;
|
|
uint32_t f_rx_time;
|
|
uint16_t f_rx_len;
|
|
uint16_t f_rx_wep_len;
|
|
uint32_t f_rx_wep_ofs;
|
|
|
|
uint8_t f_rx_dev_spec[16];
|
|
|
|
uint8_t f_rx_ctrl; /* see DESC_CTRL_ */
|
|
uint8_t f_rx_rate;
|
|
uint8_t f_rx_error;
|
|
uint8_t f_rx_snr; /* signal noise ratio */
|
|
uint8_t f_rx_level;
|
|
uint8_t f_rx_queue_ctrl;
|
|
uint16_t f_rx_unknown0;
|
|
uint32_t f_rx_unknown1;
|
|
} __packed;
|
|
|
|
/*
|
|
* Host TX/RX descriptor
|
|
* Fields are little endian
|
|
*/
|
|
struct acx_host_desc {
|
|
uint32_t h_data_paddr; /* data phyaddr */
|
|
uint16_t h_data_ofs;
|
|
uint16_t h_reserved;
|
|
uint16_t h_ctrl; /* see DESC_CTRL_ */
|
|
uint16_t h_data_len; /* data length */
|
|
uint32_t h_next_desc; /* next acx_host_desc phyaddr */
|
|
uint32_t h_pnext;
|
|
uint32_t h_status; /* see DESC_STATUS_ */
|
|
} __packed;
|
|
|
|
#define DESC_STATUS_FULL 0x80000000
|
|
|
|
#define DESC_CTRL_SHORT_PREAMBLE 0x01
|
|
#define DESC_CTRL_FIRST_FRAG 0x02
|
|
#define DESC_CTRL_AUTODMA 0x04
|
|
#define DESC_CTRL_RECLAIM 0x08
|
|
#define DESC_CTRL_HOSTDONE 0x20 /* host finished buf proc */
|
|
#define DESC_CTRL_ACXDONE 0x40 /* chip finished buf proc */
|
|
#define DESC_CTRL_HOSTOWN 0x80 /* host controls desc */
|
|
|
|
#define DESC_ERR_OTHER_FRAG 0x01
|
|
#define DESC_ERR_ABORT 0x02
|
|
#define DESC_ERR_PARAM 0x04
|
|
#define DESC_ERR_NO_WEPKEY 0x08
|
|
#define DESC_ERR_MSDU_TIMEOUT 0x10
|
|
#define DESC_ERR_EXCESSIVE_RETRY 0x20
|
|
#define DESC_ERR_BUF_OVERFLOW 0x40
|
|
#define DESC_ERR_DMA 0x80
|
|
|
|
/*
|
|
* Extra header in receiving buffer
|
|
* Fields are little endian
|
|
*/
|
|
struct acx_rxbuf_hdr {
|
|
uint16_t rbh_len; /* ACX_RXBUG_LEN_MASK part is len */
|
|
uint8_t rbh_memblk_cnt;
|
|
uint8_t rbh_status;
|
|
uint8_t rbh_stat_baseband; /* see ACX_RXBUF_STAT_ */
|
|
uint8_t rbh_plcp;
|
|
uint8_t rbh_level; /* signal level */
|
|
uint8_t rbh_snr; /* signal noise ratio */
|
|
uint32_t rbh_time; /* recv timestamp */
|
|
|
|
/*
|
|
* XXX may have 4~8 byte here which
|
|
* depends on firmware version
|
|
*/
|
|
} __packed;
|
|
|
|
#define ACX_RXBUF_LEN_MASK 0xfff
|
|
#define ACX_RXBUF_STAT_LNA 0x80 /* low noise amplifier */
|
|
|
|
struct acx_ring_data {
|
|
struct acx_host_desc *rx_ring;
|
|
bus_dma_segment_t rx_ring_seg;
|
|
bus_dmamap_t rx_ring_dmamap;
|
|
uint32_t rx_ring_paddr;
|
|
|
|
struct acx_host_desc *tx_ring;
|
|
bus_dma_segment_t tx_ring_seg;
|
|
bus_dmamap_t tx_ring_dmamap;
|
|
uint32_t tx_ring_paddr;
|
|
};
|
|
|
|
struct acx_txbuf {
|
|
struct mbuf *tb_mbuf;
|
|
bus_dmamap_t tb_mbuf_dmamap;
|
|
|
|
struct acx_host_desc *tb_desc1;
|
|
struct acx_host_desc *tb_desc2;
|
|
|
|
uint32_t tb_fwdesc_ofs;
|
|
|
|
/*
|
|
* Used by tx rate updating
|
|
*/
|
|
struct acx_node *tb_node; /* remote node */
|
|
int tb_rate; /* current tx rate */
|
|
};
|
|
|
|
struct acx_rxbuf {
|
|
struct mbuf *rb_mbuf;
|
|
bus_dmamap_t rb_mbuf_dmamap;
|
|
|
|
struct acx_host_desc *rb_desc;
|
|
};
|
|
|
|
struct acx_buf_data {
|
|
struct acx_rxbuf rx_buf[ACX_RX_DESC_CNT];
|
|
struct acx_txbuf tx_buf[ACX_TX_DESC_CNT];
|
|
bus_dmamap_t mbuf_tmp_dmamap;
|
|
|
|
int rx_scan_start;
|
|
|
|
int tx_free_start;
|
|
int tx_used_start;
|
|
int tx_used_count;
|
|
};
|
|
|
|
struct acx_node {
|
|
struct ieee80211_node ni; /* must be first */
|
|
struct ieee80211_amrr_node amn;
|
|
};
|
|
|
|
struct acx_config {
|
|
uint8_t antenna;
|
|
uint8_t regdom;
|
|
uint8_t cca_mode; /* acx100 */
|
|
uint8_t ed_thresh; /* acx100 */
|
|
};
|
|
|
|
struct acx_stats {
|
|
uint64_t err_oth_frag; /* XXX error in other frag?? */
|
|
uint64_t err_abort; /* tx abortion */
|
|
uint64_t err_param; /* tx desc contains invalid param */
|
|
uint64_t err_no_wepkey; /* no WEP key exists */
|
|
uint64_t err_msdu_timeout; /* MSDU timed out */
|
|
uint64_t err_ex_retry; /* excessive tx retry */
|
|
uint64_t err_buf_oflow; /* buffer overflow */
|
|
uint64_t err_dma; /* DMA error */
|
|
uint64_t err_unkn; /* XXX unknown error */
|
|
};
|
|
|
|
#define ACX_RX_RADIOTAP_PRESENT \
|
|
((1 << IEEE80211_RADIOTAP_FLAGS) | \
|
|
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
|
(1 << IEEE80211_RADIOTAP_RSSI))
|
|
|
|
struct acx_rx_radiotap_hdr {
|
|
struct ieee80211_radiotap_header wr_ihdr;
|
|
uint8_t wr_flags;
|
|
uint16_t wr_chan_freq;
|
|
uint16_t wr_chan_flags;
|
|
uint8_t wr_rssi;
|
|
uint8_t wr_max_rssi;
|
|
} __packed;
|
|
|
|
#define ACX_TX_RADIOTAP_PRESENT \
|
|
((1 << IEEE80211_RADIOTAP_FLAGS) | \
|
|
(1 << IEEE80211_RADIOTAP_RATE) | \
|
|
(1 << IEEE80211_RADIOTAP_CHANNEL)) \
|
|
|
|
struct acx_tx_radiotap_hdr {
|
|
struct ieee80211_radiotap_header wt_ihdr;
|
|
uint8_t wt_flags;
|
|
uint8_t wt_rate;
|
|
uint16_t wt_chan_freq;
|
|
uint16_t wt_chan_flags;
|
|
} __packed;
|
|
|
|
struct acx_softc {
|
|
/*
|
|
* sc_xxx are filled in by common code
|
|
* chip_xxx are filled in by chip specific code
|
|
*/
|
|
struct device sc_dev;
|
|
struct ieee80211com sc_ic;
|
|
|
|
struct timeout sc_chanscan_timer;
|
|
uint32_t sc_flags; /* see ACX_FLAG_ */
|
|
|
|
uint32_t sc_firmware_ver;
|
|
uint32_t sc_hardware_id;
|
|
|
|
bus_dma_tag_t sc_dmat;
|
|
|
|
struct ieee80211_amrr amrr;
|
|
struct timeout amrr_ch;
|
|
|
|
/*
|
|
* MMIO 1
|
|
*/
|
|
bus_space_tag_t sc_mem1_bt;
|
|
bus_space_handle_t sc_mem1_bh;
|
|
int chip_mem1_rid;
|
|
|
|
/*
|
|
* MMIO 2
|
|
*/
|
|
bus_space_tag_t sc_mem2_bt;
|
|
bus_space_handle_t sc_mem2_bh;
|
|
int chip_mem2_rid;
|
|
|
|
int (*sc_enable)(struct acx_softc *);
|
|
void (*sc_disable)(struct acx_softc *);
|
|
void (*sc_power)(struct acx_softc *, int);
|
|
|
|
uint32_t sc_cmd; /* cmd reg (MMIO 2) */
|
|
uint32_t sc_cmd_param; /* cmd param reg (MMIO 2) */
|
|
uint32_t sc_info; /* unused */
|
|
uint32_t sc_info_param; /* unused */
|
|
|
|
const uint16_t *chip_ioreg; /* reg map (MMIO 1) */
|
|
|
|
/*
|
|
* NOTE:
|
|
* chip_intr_enable is not necessarily same as
|
|
* ~chip_intr_disable
|
|
*/
|
|
uint16_t chip_intr_enable;
|
|
uint16_t chip_intr_disable;
|
|
|
|
int chip_hw_crypt;
|
|
uint16_t chip_gpio_pled; /* power led */
|
|
uint16_t chip_chan_flags; /* see IEEE80211_CHAN_ */
|
|
uint16_t chip_txdesc1_len;
|
|
int chip_rxbuf_exhdr; /* based on fw ver */
|
|
uint32_t chip_ee_eaddr_ofs;
|
|
enum ieee80211_phymode chip_phymode; /* see IEEE80211_MODE_ */
|
|
uint8_t chip_fw_txdesc_ctrl;
|
|
|
|
uint8_t sc_eeprom_ver; /* unused */
|
|
uint8_t sc_form_factor; /* unused */
|
|
uint8_t sc_radio_type; /* see ACX_RADIO_TYPE_ */
|
|
|
|
struct acx_ring_data sc_ring_data;
|
|
struct acx_buf_data sc_buf_data;
|
|
|
|
struct acx_stats sc_stats; /* statistics */
|
|
|
|
/*
|
|
* Per interface sysctl variables
|
|
*/
|
|
int sc_txtimer;
|
|
int sc_long_retry_limit;
|
|
int sc_short_retry_limit;
|
|
int sc_msdu_lifetime;
|
|
|
|
int (*sc_newstate)
|
|
(struct ieee80211com *,
|
|
enum ieee80211_state, int);
|
|
|
|
int (*chip_init) /* non-NULL */
|
|
(struct acx_softc *);
|
|
|
|
int (*chip_set_wepkey)
|
|
(struct acx_softc *,
|
|
struct ieee80211_key *, int);
|
|
|
|
int (*chip_read_config)
|
|
(struct acx_softc *, struct acx_config *);
|
|
|
|
int (*chip_write_config)
|
|
(struct acx_softc *, struct acx_config *);
|
|
|
|
void (*chip_set_fw_txdesc_rate) /* non-NULL */
|
|
(struct acx_softc *, struct acx_txbuf *, int);
|
|
|
|
void (*chip_set_bss_join_param) /* non-NULL */
|
|
(struct acx_softc *, void *, int);
|
|
|
|
void (*chip_proc_wep_rxbuf)
|
|
(struct acx_softc *, struct mbuf *, int *);
|
|
|
|
#if NBPFILTER > 0
|
|
caddr_t sc_drvbpf;
|
|
|
|
union {
|
|
struct acx_rx_radiotap_hdr th;
|
|
uint8_t pad[64];
|
|
} sc_rxtapu;
|
|
#define sc_rxtap sc_rxtapu.th
|
|
int sc_rxtap_len;
|
|
|
|
union {
|
|
struct acx_tx_radiotap_hdr th;
|
|
uint8_t pad[64];
|
|
} sc_txtapu;
|
|
#define sc_txtap sc_txtapu.th
|
|
int sc_txtap_len;
|
|
#endif
|
|
};
|
|
|
|
#define ACX_FLAG_FW_LOADED 0x01
|
|
#define ACX_FLAG_ACX111 0x02
|
|
|
|
#define ACX_RADIO_TYPE_MAXIM 0x0d
|
|
#define ACX_RADIO_TYPE_RFMD 0x11
|
|
#define ACX_RADIO_TYPE_RALINK 0x15
|
|
#define ACX_RADIO_TYPE_RADIA 0x16
|
|
#define ACX_RADIO_TYPE_UNKN17 0x17
|
|
#define ACX_RADIO_TYPE_UNKN19 0x19
|
|
|
|
#define ACX_RADIO_RSSI_MAXIM 120 /* 100dB */
|
|
#define ACX_RADIO_RSSI_RFMD 215 /* 215dB */
|
|
#define ACX_RADIO_RSSI_RALINK 0 /* XXX unknown yet */
|
|
#define ACX_RADIO_RSSI_RADIA 78 /* 78db */
|
|
#define ACX_RADIO_RSSI_UNKN 0 /* unknown radio */
|
|
|
|
extern const struct ieee80211_rateset acx_rates_11b;
|
|
extern const struct ieee80211_rateset acx_rates_11g;
|
|
extern int acx_beacon_intvl;
|
|
|
|
void acx100_set_param(struct acx_softc *);
|
|
void acx111_set_param(struct acx_softc *);
|
|
|
|
int acx_init_tmplt_ordered(struct acx_softc *);
|
|
void acx_write_phyreg(struct acx_softc *, uint32_t, uint8_t);
|
|
|
|
int acx_set_tmplt(struct acx_softc *, uint16_t, void *, uint16_t);
|
|
int acx_get_conf(struct acx_softc *, uint16_t, void *, uint16_t);
|
|
int acx_set_conf(struct acx_softc *, uint16_t, void *, uint16_t);
|
|
int acx_exec_command(struct acx_softc *, uint16_t, void *, uint16_t,
|
|
void *, uint16_t);
|
|
int acx_attach(struct acx_softc *);
|
|
int acx_detach(void *);
|
|
int acx_intr(void *);
|
|
|
|
#endif /* !_IF_ACXVAR_H */
|