1dc60165bSWeongyo Jeong /* $OpenBSD: if_uathvar.h,v 1.3 2006/09/20 19:47:17 damien Exp $ */ 2dc60165bSWeongyo Jeong 3dc60165bSWeongyo Jeong /*- 4dc60165bSWeongyo Jeong * Copyright (c) 2006 5dc60165bSWeongyo Jeong * Damien Bergamini <damien.bergamini@free.fr> 6dc60165bSWeongyo Jeong * Copyright (c) 2006 Sam Leffler, Errno Consulting 7dc60165bSWeongyo Jeong * Copyright (c) 2008-2009 Weongyo Jeong <weongyo@freebsd.org> 8dc60165bSWeongyo Jeong * 9dc60165bSWeongyo Jeong * Permission to use, copy, modify, and distribute this software for any 10dc60165bSWeongyo Jeong * purpose with or without fee is hereby granted, provided that the above 11dc60165bSWeongyo Jeong * copyright notice and this permission notice appear in all copies. 12dc60165bSWeongyo Jeong * 13dc60165bSWeongyo Jeong * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14dc60165bSWeongyo Jeong * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15dc60165bSWeongyo Jeong * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16dc60165bSWeongyo Jeong * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17dc60165bSWeongyo Jeong * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18dc60165bSWeongyo Jeong * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19dc60165bSWeongyo Jeong * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20dc60165bSWeongyo Jeong */ 21dc60165bSWeongyo Jeong 22dc60165bSWeongyo Jeong enum { 23dc60165bSWeongyo Jeong UATH_INTR_RX, 24dc60165bSWeongyo Jeong UATH_INTR_TX, 25dc60165bSWeongyo Jeong UATH_BULK_RX, 26dc60165bSWeongyo Jeong UATH_BULK_TX, 27dc60165bSWeongyo Jeong UATH_N_XFERS = 4, 28dc60165bSWeongyo Jeong }; 29dc60165bSWeongyo Jeong 30dc60165bSWeongyo Jeong #define UATH_ID_BSS 2 /* Connection ID */ 31dc60165bSWeongyo Jeong 32dc60165bSWeongyo Jeong #define UATH_RX_DATA_LIST_COUNT 128 33dc60165bSWeongyo Jeong #define UATH_TX_DATA_LIST_COUNT 16 34dc60165bSWeongyo Jeong #define UATH_CMD_LIST_COUNT 60 35dc60165bSWeongyo Jeong 36dc60165bSWeongyo Jeong #define UATH_DATA_TIMEOUT 10000 37dc60165bSWeongyo Jeong #define UATH_CMD_TIMEOUT 1000 38dc60165bSWeongyo Jeong 39dc60165bSWeongyo Jeong /* flags for sending firmware commands */ 40dc60165bSWeongyo Jeong #define UATH_CMD_FLAG_ASYNC (1 << 0) 41dc60165bSWeongyo Jeong #define UATH_CMD_FLAG_READ (1 << 1) 42dc60165bSWeongyo Jeong #define UATH_CMD_FLAG_MAGIC (1 << 2) 43dc60165bSWeongyo Jeong 44dc60165bSWeongyo Jeong struct uath_rx_radiotap_header { 45dc60165bSWeongyo Jeong struct ieee80211_radiotap_header wr_ihdr; 465463c4a4SSam Leffler u_int64_t wr_tsf; 475463c4a4SSam Leffler u_int8_t wr_flags; 485463c4a4SSam Leffler u_int8_t wr_rate; 49dc60165bSWeongyo Jeong uint16_t wr_chan_freq; 50dc60165bSWeongyo Jeong uint16_t wr_chan_flags; 515463c4a4SSam Leffler int8_t wr_antsignal; 525463c4a4SSam Leffler int8_t wr_antnoise; 535463c4a4SSam Leffler u_int8_t wr_antenna; 54e8353a7aSHans Petter Selasky } __packed __aligned(8); 55dc60165bSWeongyo Jeong 565463c4a4SSam Leffler #define UATH_RX_RADIOTAP_PRESENT ( \ 575463c4a4SSam Leffler (1 << IEEE80211_RADIOTAP_TSFT) | \ 585463c4a4SSam Leffler (1 << IEEE80211_RADIOTAP_FLAGS) | \ 595463c4a4SSam Leffler (1 << IEEE80211_RADIOTAP_RATE) | \ 605463c4a4SSam Leffler (1 << IEEE80211_RADIOTAP_ANTENNA) | \ 61dc60165bSWeongyo Jeong (1 << IEEE80211_RADIOTAP_CHANNEL) | \ 625463c4a4SSam Leffler (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ 635463c4a4SSam Leffler (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \ 645463c4a4SSam Leffler 0) 65dc60165bSWeongyo Jeong 66dc60165bSWeongyo Jeong struct uath_tx_radiotap_header { 67dc60165bSWeongyo Jeong struct ieee80211_radiotap_header wt_ihdr; 68dc60165bSWeongyo Jeong uint8_t wt_flags; 69*786ac703SAndriy Voskoboinyk uint8_t wt_pad; 70dc60165bSWeongyo Jeong uint16_t wt_chan_freq; 71dc60165bSWeongyo Jeong uint16_t wt_chan_flags; 72*786ac703SAndriy Voskoboinyk } __packed; 73dc60165bSWeongyo Jeong 74dc60165bSWeongyo Jeong #define UATH_TX_RADIOTAP_PRESENT \ 75dc60165bSWeongyo Jeong ((1 << IEEE80211_RADIOTAP_FLAGS) | \ 76dc60165bSWeongyo Jeong (1 << IEEE80211_RADIOTAP_CHANNEL)) 77dc60165bSWeongyo Jeong 78dc60165bSWeongyo Jeong struct uath_data { 79dc60165bSWeongyo Jeong struct uath_softc *sc; 80dc60165bSWeongyo Jeong uint8_t *buf; 81dc60165bSWeongyo Jeong uint16_t buflen; 82dc60165bSWeongyo Jeong struct mbuf *m; 83dc60165bSWeongyo Jeong struct ieee80211_node *ni; /* NB: tx only */ 84dc60165bSWeongyo Jeong STAILQ_ENTRY(uath_data) next; 85dc60165bSWeongyo Jeong }; 86dc60165bSWeongyo Jeong typedef STAILQ_HEAD(, uath_data) uath_datahead; 87dc60165bSWeongyo Jeong 88dc60165bSWeongyo Jeong struct uath_cmd { 89dc60165bSWeongyo Jeong struct uath_softc *sc; 90dc60165bSWeongyo Jeong uint32_t flags; 91dc60165bSWeongyo Jeong uint32_t msgid; 92dc60165bSWeongyo Jeong uint8_t *buf; 93dc60165bSWeongyo Jeong uint16_t buflen; 94dc60165bSWeongyo Jeong void *odata; /* NB: tx only */ 95dc60165bSWeongyo Jeong int olen; /* space in odata */ 96dc60165bSWeongyo Jeong STAILQ_ENTRY(uath_cmd) next; 97dc60165bSWeongyo Jeong }; 98dc60165bSWeongyo Jeong typedef STAILQ_HEAD(, uath_cmd) uath_cmdhead; 99dc60165bSWeongyo Jeong 100dc60165bSWeongyo Jeong struct uath_wme_settings { 101dc60165bSWeongyo Jeong uint8_t aifsn; 102dc60165bSWeongyo Jeong uint8_t logcwmin; 103dc60165bSWeongyo Jeong uint8_t logcwmax; 104dc60165bSWeongyo Jeong uint16_t txop; 105dc60165bSWeongyo Jeong uint8_t acm; 106dc60165bSWeongyo Jeong }; 107dc60165bSWeongyo Jeong 108dc60165bSWeongyo Jeong struct uath_devcap { 109dc60165bSWeongyo Jeong uint32_t targetVersion; 110dc60165bSWeongyo Jeong uint32_t targetRevision; 111dc60165bSWeongyo Jeong uint32_t macVersion; 112dc60165bSWeongyo Jeong uint32_t macRevision; 113dc60165bSWeongyo Jeong uint32_t phyRevision; 114dc60165bSWeongyo Jeong uint32_t analog5GhzRevision; 115dc60165bSWeongyo Jeong uint32_t analog2GhzRevision; 116dc60165bSWeongyo Jeong uint32_t regDomain; 117dc60165bSWeongyo Jeong uint32_t regCapBits; 118dc60165bSWeongyo Jeong uint32_t countryCode; 119dc60165bSWeongyo Jeong uint32_t keyCacheSize; 120dc60165bSWeongyo Jeong uint32_t numTxQueues; 121dc60165bSWeongyo Jeong uint32_t connectionIdMax; 122dc60165bSWeongyo Jeong uint32_t wirelessModes; 123dc60165bSWeongyo Jeong #define UATH_WIRELESS_MODE_11A 0x01 124dc60165bSWeongyo Jeong #define UATH_WIRELESS_MODE_TURBO 0x02 125dc60165bSWeongyo Jeong #define UATH_WIRELESS_MODE_11B 0x04 126dc60165bSWeongyo Jeong #define UATH_WIRELESS_MODE_11G 0x08 127dc60165bSWeongyo Jeong #define UATH_WIRELESS_MODE_108G 0x10 128dc60165bSWeongyo Jeong uint32_t chanSpreadSupport; 129dc60165bSWeongyo Jeong uint32_t compressSupport; 130dc60165bSWeongyo Jeong uint32_t burstSupport; 131dc60165bSWeongyo Jeong uint32_t fastFramesSupport; 132dc60165bSWeongyo Jeong uint32_t chapTuningSupport; 133dc60165bSWeongyo Jeong uint32_t turboGSupport; 134dc60165bSWeongyo Jeong uint32_t turboPrimeSupport; 135dc60165bSWeongyo Jeong uint32_t deviceType; 136dc60165bSWeongyo Jeong uint32_t wmeSupport; 137dc60165bSWeongyo Jeong uint32_t low2GhzChan; 138dc60165bSWeongyo Jeong uint32_t high2GhzChan; 139dc60165bSWeongyo Jeong uint32_t low5GhzChan; 140dc60165bSWeongyo Jeong uint32_t high5GhzChan; 141dc60165bSWeongyo Jeong uint32_t supportCipherWEP; 142dc60165bSWeongyo Jeong uint32_t supportCipherAES_CCM; 143dc60165bSWeongyo Jeong uint32_t supportCipherTKIP; 144dc60165bSWeongyo Jeong uint32_t supportCipherMicAES_CCM; 145dc60165bSWeongyo Jeong uint32_t supportMicTKIP; 146dc60165bSWeongyo Jeong uint32_t twiceAntennaGain5G; 147dc60165bSWeongyo Jeong uint32_t twiceAntennaGain2G; 148dc60165bSWeongyo Jeong }; 149dc60165bSWeongyo Jeong 150dc60165bSWeongyo Jeong struct uath_stat { 151dc60165bSWeongyo Jeong uint32_t st_badchunkseqnum; 152dc60165bSWeongyo Jeong uint32_t st_invalidlen; 153dc60165bSWeongyo Jeong uint32_t st_multichunk; 154dc60165bSWeongyo Jeong uint32_t st_toobigrxpkt; 155dc60165bSWeongyo Jeong uint32_t st_stopinprogress; 156dc60165bSWeongyo Jeong uint32_t st_crcerr; 157dc60165bSWeongyo Jeong uint32_t st_phyerr; 158dc60165bSWeongyo Jeong uint32_t st_decrypt_crcerr; 159dc60165bSWeongyo Jeong uint32_t st_decrypt_micerr; 160dc60165bSWeongyo Jeong uint32_t st_decomperr; 161dc60165bSWeongyo Jeong uint32_t st_keyerr; 162dc60165bSWeongyo Jeong uint32_t st_err; 163dc60165bSWeongyo Jeong /* CMD/RX/TX queues */ 164dc60165bSWeongyo Jeong uint32_t st_cmd_active; 165dc60165bSWeongyo Jeong uint32_t st_cmd_inactive; 166dc60165bSWeongyo Jeong uint32_t st_cmd_pending; 167dc60165bSWeongyo Jeong uint32_t st_cmd_waiting; 168dc60165bSWeongyo Jeong uint32_t st_rx_active; 169dc60165bSWeongyo Jeong uint32_t st_rx_inactive; 170dc60165bSWeongyo Jeong uint32_t st_tx_active; 171dc60165bSWeongyo Jeong uint32_t st_tx_inactive; 172dc60165bSWeongyo Jeong uint32_t st_tx_pending; 173dc60165bSWeongyo Jeong }; 174dc60165bSWeongyo Jeong #define UATH_STAT_INC(sc, var) (sc)->sc_stat.var++ 175dc60165bSWeongyo Jeong #define UATH_STAT_DEC(sc, var) (sc)->sc_stat.var-- 176dc60165bSWeongyo Jeong 177dc60165bSWeongyo Jeong struct uath_vap { 178dc60165bSWeongyo Jeong struct ieee80211vap vap; 179dc60165bSWeongyo Jeong int (*newstate)(struct ieee80211vap *, 180dc60165bSWeongyo Jeong enum ieee80211_state, int); 181dc60165bSWeongyo Jeong }; 182dc60165bSWeongyo Jeong #define UATH_VAP(vap) ((struct uath_vap *)(vap)) 183dc60165bSWeongyo Jeong 184dc60165bSWeongyo Jeong struct uath_softc { 1857a79cebfSGleb Smirnoff struct ieee80211com sc_ic; 1867a79cebfSGleb Smirnoff struct mbufq sc_snd; 187dc60165bSWeongyo Jeong device_t sc_dev; 188760bc48eSAndrew Thompson struct usb_device *sc_udev; 189c180b398SHans Petter Selasky void *sc_cmd_dma_buf; 190c180b398SHans Petter Selasky void *sc_tx_dma_buf; 191dc60165bSWeongyo Jeong struct mtx sc_mtx; 192dc60165bSWeongyo Jeong uint32_t sc_debug; 193dc60165bSWeongyo Jeong 194dc60165bSWeongyo Jeong struct uath_stat sc_stat; 195dc60165bSWeongyo Jeong int (*sc_newstate)(struct ieee80211com *, 196dc60165bSWeongyo Jeong enum ieee80211_state, int); 197dc60165bSWeongyo Jeong 198760bc48eSAndrew Thompson struct usb_xfer *sc_xfer[UATH_N_XFERS]; 199dc60165bSWeongyo Jeong struct uath_cmd sc_cmd[UATH_CMD_LIST_COUNT]; 200dc60165bSWeongyo Jeong uath_cmdhead sc_cmd_active; 201dc60165bSWeongyo Jeong uath_cmdhead sc_cmd_inactive; 202dc60165bSWeongyo Jeong uath_cmdhead sc_cmd_pending; 203dc60165bSWeongyo Jeong uath_cmdhead sc_cmd_waiting; 204dc60165bSWeongyo Jeong struct uath_data sc_rx[UATH_RX_DATA_LIST_COUNT]; 205dc60165bSWeongyo Jeong uath_datahead sc_rx_active; 206dc60165bSWeongyo Jeong uath_datahead sc_rx_inactive; 207dc60165bSWeongyo Jeong struct uath_data sc_tx[UATH_TX_DATA_LIST_COUNT]; 208dc60165bSWeongyo Jeong uath_datahead sc_tx_active; 209dc60165bSWeongyo Jeong uath_datahead sc_tx_inactive; 210dc60165bSWeongyo Jeong uath_datahead sc_tx_pending; 211dc60165bSWeongyo Jeong 212dc60165bSWeongyo Jeong uint32_t sc_msgid; 213dc60165bSWeongyo Jeong uint32_t sc_seqnum; 214dc60165bSWeongyo Jeong int sc_tx_timer; 215dc60165bSWeongyo Jeong struct callout watchdog_ch; 216dc60165bSWeongyo Jeong struct callout stat_ch; 217dc60165bSWeongyo Jeong /* multi-chunked support */ 218dc60165bSWeongyo Jeong struct mbuf *sc_intrx_head; 219dc60165bSWeongyo Jeong struct mbuf *sc_intrx_tail; 220dc60165bSWeongyo Jeong uint8_t sc_intrx_nextnum; 221dc60165bSWeongyo Jeong uint32_t sc_intrx_len; 222dc60165bSWeongyo Jeong #define UATH_MAX_INTRX_SIZE 3616 223dc60165bSWeongyo Jeong 224dc60165bSWeongyo Jeong struct uath_devcap sc_devcap; 225dc60165bSWeongyo Jeong uint8_t sc_serial[16]; 226dc60165bSWeongyo Jeong 227dc60165bSWeongyo Jeong /* unsorted */ 228dc60165bSWeongyo Jeong uint32_t sc_flags; 229dc60165bSWeongyo Jeong #define UATH_FLAG_INVALID (1 << 1) 230dc60165bSWeongyo Jeong #define UATH_FLAG_INITDONE (1 << 2) 231dc60165bSWeongyo Jeong 232dc60165bSWeongyo Jeong struct uath_rx_radiotap_header sc_rxtap; 233dc60165bSWeongyo Jeong struct uath_tx_radiotap_header sc_txtap; 234dc60165bSWeongyo Jeong }; 235dc60165bSWeongyo Jeong 236dc60165bSWeongyo Jeong #define UATH_LOCK(sc) mtx_lock(&(sc)->sc_mtx) 237dc60165bSWeongyo Jeong #define UATH_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) 238dc60165bSWeongyo Jeong #define UATH_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) 239dc60165bSWeongyo Jeong 240dc60165bSWeongyo Jeong #define UATH_RESET_INTRX(sc) do { \ 241dc60165bSWeongyo Jeong (sc)->sc_intrx_head = NULL; \ 242dc60165bSWeongyo Jeong (sc)->sc_intrx_tail = NULL; \ 243dc60165bSWeongyo Jeong (sc)->sc_intrx_nextnum = 0; \ 244dc60165bSWeongyo Jeong (sc)->sc_intrx_len = 0; \ 245dc60165bSWeongyo Jeong } while (0) 246