#ifndef _DEV_MWL_MVVAR_H
#define _DEV_MWL_MVVAR_H
#include <sys/endian.h>
#include <sys/bus.h>
#include <net80211/ieee80211_radiotap.h>
#include <dev/mwl/mwlhal.h>
#include <dev/mwl/mwlreg.h>
#include <dev/mwl/if_mwlioctl.h>
#ifndef MWL_TXBUF
#define MWL_TXBUF 256
#endif
#ifndef MWL_TXACKBUF
#define MWL_TXACKBUF (MWL_TXBUF/2)
#endif
#ifndef MWL_RXDESC
#define MWL_RXDESC 256
#endif
#ifndef MWL_RXBUF
#define MWL_RXBUF ((5*MWL_RXDESC)/2)
#endif
#ifndef MWL_MAXBA
#define MWL_MAXBA 2
#endif
#ifdef MWL_SGDMA_SUPPORT
#define MWL_TXDESC 6
#else
#define MWL_TXDESC 1
#endif
#ifndef MWL_AGGR_SIZE
#define MWL_AGGR_SIZE 3839
#endif
#define MWL_AGEINTERVAL 1
#define MWL_MAXSTAID 64
struct mwl_txbuf {
STAILQ_ENTRY(mwl_txbuf) bf_list;
void *bf_desc;
bus_addr_t bf_daddr;
bus_dmamap_t bf_dmamap;
int bf_nseg;
bus_dma_segment_t bf_segs[MWL_TXDESC];
struct mbuf *bf_m;
struct ieee80211_node *bf_node;
struct mwl_txq *bf_txq;
};
typedef STAILQ_HEAD(, mwl_txbuf) mwl_txbufhead;
struct mwl_descdma {
const char* dd_name;
void *dd_desc;
bus_addr_t dd_desc_paddr;
bus_size_t dd_desc_len;
bus_dma_segment_t dd_dseg;
int dd_dnseg;
bus_dma_tag_t dd_dmat;
bus_dmamap_t dd_dmamap;
void *dd_bufptr;
};
struct mwl_txq {
struct mwl_descdma dma;
struct mtx lock;
char name[12];
int qnum;
int txpri;
int nfree;
mwl_txbufhead free;
mwl_txbufhead active;
};
#define MWL_TXQ_LOCK_INIT(_sc, _tq) do { \
snprintf((_tq)->name, sizeof((_tq)->name), "%s_txq%u", \
device_get_nameunit((_sc)->sc_dev), (_tq)->qnum); \
mtx_init(&(_tq)->lock, (_tq)->name, NULL, MTX_DEF); \
} while (0)
#define MWL_TXQ_LOCK_DESTROY(_tq) mtx_destroy(&(_tq)->lock)
#define MWL_TXQ_LOCK(_tq) mtx_lock(&(_tq)->lock)
#define MWL_TXQ_UNLOCK(_tq) mtx_unlock(&(_tq)->lock)
#define MWL_TXQ_LOCK_ASSERT(_tq) mtx_assert(&(_tq)->lock, MA_OWNED)
#define MWL_TXDESC_SYNC(txq, ds, how) do { \
bus_dmamap_sync((txq)->dma.dd_dmat, (txq)->dma.dd_dmamap, how); \
} while(0)
struct mwl_jumbo {
SLIST_ENTRY(mwl_jumbo) next;
};
typedef SLIST_HEAD(, mwl_jumbo) mwl_jumbohead;
#define MWL_JUMBO_DATA2BUF(_data) ((struct mwl_jumbo *)(_data))
#define MWL_JUMBO_BUF2DATA(_buf) ((uint8_t *)(_buf))
#define MWL_JUMBO_OFFSET(_sc, _data) \
(((const uint8_t *)(_data)) - (const uint8_t *)((_sc)->sc_rxmem))
#define MWL_JUMBO_DMA_ADDR(_sc, _data) \
((_sc)->sc_rxmem_paddr + MWL_JUMBO_OFFSET(_sc, _data))
struct mwl_rxbuf {
STAILQ_ENTRY(mwl_rxbuf) bf_list;
void *bf_desc;
bus_addr_t bf_daddr;
uint8_t *bf_data;
};
typedef STAILQ_HEAD(, mwl_rxbuf) mwl_rxbufhead;
#define MWL_RXDESC_SYNC(sc, ds, how) do { \
bus_dmamap_sync((sc)->sc_rxdma.dd_dmat, (sc)->sc_rxdma.dd_dmamap, how);\
} while (0)
struct mwl_bastate {
uint16_t qos;
uint8_t txq;
const MWL_HAL_BASTREAM *bastream;
};
static __inline__ void
mwl_bastream_setup(struct mwl_bastate *bas, int tid, int txq)
{
bas->txq = txq;
bas->qos = htole16(tid | IEEE80211_QOS_ACKPOLICY_BA);
}
static __inline__ void
mwl_bastream_free(struct mwl_bastate *bas)
{
bas->qos = 0;
bas->bastream = NULL;
}
static __inline__ int
mwl_bastream_match(const struct mwl_bastate *bas, uint16_t qos)
{
return (qos & htole16(IEEE80211_QOS_TID|IEEE80211_QOS_ACKPOLICY)) ==
bas->qos;
}
struct mwl_node {
struct ieee80211_node mn_node;
struct mwl_ant_info mn_ai;
uint32_t mn_avgrssi;
uint16_t mn_staid;
struct mwl_bastate mn_ba[MWL_MAXBA];
struct mwl_hal_vap *mn_hvap;
};
#define MWL_NODE(ni) ((struct mwl_node *)(ni))
#define MWL_NODE_CONST(ni) ((const struct mwl_node *)(ni))
struct mwl_vap {
struct ieee80211vap mv_vap;
struct mwl_hal_vap *mv_hvap;
struct mwl_hal_vap *mv_ap_hvap;
uint16_t mv_last_ps_sta;
uint16_t mv_eapolformat;
int (*mv_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
int (*mv_set_tim)(struct ieee80211_node *, int);
};
#define MWL_VAP(vap) ((struct mwl_vap *)(vap))
#define MWL_VAP_CONST(vap) ((const struct mwl_vap *)(vap))
struct mwl_softc {
struct ieee80211com sc_ic;
struct mbufq sc_snd;
struct mwl_stats sc_stats;
int sc_debug;
device_t sc_dev;
bus_dma_tag_t sc_dmat;
bus_space_handle_t sc_io0h;
bus_space_tag_t sc_io0t;
bus_space_handle_t sc_io1h;
bus_space_tag_t sc_io1t;
struct mtx sc_mtx;
struct taskqueue *sc_tq;
struct callout sc_watchdog;
int sc_tx_timer;
unsigned int sc_running : 1,
sc_invalid : 1,
sc_recvsetup:1,
sc_csapending:1,
sc_radarena : 1,
sc_rxblocked: 1;
struct mwl_hal *sc_mh;
struct mwl_hal_vap *sc_hvap;
struct mwl_hal_hwspec sc_hwspecs;
uint32_t sc_fwrelease;
struct mwl_hal_txrxdma sc_hwdma;
uint32_t sc_imask;
enum ieee80211_phymode sc_curmode;
u_int16_t sc_curaid;
u_int8_t sc_curbssid[IEEE80211_ADDR_LEN];
MWL_HAL_CHANNEL sc_curchan;
MWL_HAL_TXRATE_HANDLING sc_txratehandling;
u_int16_t sc_rxantenna;
u_int16_t sc_txantenna;
uint8_t sc_napvaps;
uint8_t sc_nwdsvaps;
uint8_t sc_nstavaps;
uint8_t sc_ndwdsvaps;
uint8_t sc_nbssid0;
uint32_t sc_bssidmask;
void (*sc_recv_mgmt)(struct ieee80211com *,
struct mbuf *,
struct ieee80211_node *,
int, int, int, u_int32_t);
int (*sc_newstate)(struct ieee80211com *,
enum ieee80211_state, int);
void (*sc_node_cleanup)(struct ieee80211_node *);
void (*sc_node_drain)(struct ieee80211_node *);
int (*sc_recv_action)(struct ieee80211_node *,
const struct ieee80211_frame *,
const uint8_t *, const uint8_t *);
int (*sc_addba_request)(struct ieee80211_node *,
struct ieee80211_tx_ampdu *,
int dialogtoken, int baparamset,
int batimeout);
int (*sc_addba_response)(struct ieee80211_node *,
struct ieee80211_tx_ampdu *,
int status, int baparamset,
int batimeout);
void (*sc_addba_stop)(struct ieee80211_node *,
struct ieee80211_tx_ampdu *);
struct mwl_descdma sc_rxdma;
mwl_rxbufhead sc_rxbuf;
struct mwl_rxbuf *sc_rxnext;
struct task sc_rxtask;
void *sc_rxmem;
bus_dma_tag_t sc_rxdmat;
bus_size_t sc_rxmemsize;
bus_dmamap_t sc_rxmap;
bus_addr_t sc_rxmem_paddr;
mwl_jumbohead sc_rxfree;
int sc_nrxfree;
struct mtx sc_rxlock;
struct mwl_txq sc_txq[MWL_NUM_TX_QUEUES];
struct mwl_txq *sc_ac2q[5];
struct mbuf *sc_aggrq;
struct task sc_txtask;
struct task sc_bawatchdogtask;
struct task sc_radartask;
struct task sc_chanswitchtask;
uint8_t sc_staid[MWL_MAXSTAID/NBBY];
int sc_ageinterval;
struct callout sc_timer;
struct mwl_tx_radiotap_header sc_tx_th;
struct mwl_rx_radiotap_header sc_rx_th;
#if defined(__HAIKU__)
uint32_t sc_intr_status;
#endif
};
#define MWL_LOCK_INIT(_sc) \
mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
NULL, MTX_DEF | MTX_RECURSE)
#define MWL_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx)
#define MWL_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
#define MWL_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
#define MWL_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
#define MWL_RXFREE_INIT(_sc) \
mtx_init(&(_sc)->sc_rxlock, device_get_nameunit((_sc)->sc_dev), \
NULL, MTX_DEF)
#define MWL_RXFREE_DESTROY(_sc) mtx_destroy(&(_sc)->sc_rxlock)
#define MWL_RXFREE_LOCK(_sc) mtx_lock(&(_sc)->sc_rxlock)
#define MWL_RXFREE_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_rxlock)
#define MWL_RXFREE_ASSERT(_sc) mtx_assert(&(_sc)->sc_rxlock, MA_OWNED)
int mwl_attach(u_int16_t, struct mwl_softc *);
int mwl_detach(struct mwl_softc *);
void mwl_resume(struct mwl_softc *);
void mwl_suspend(struct mwl_softc *);
void mwl_shutdown(void *);
void mwl_intr(void *);
#endif