1 /* $NetBSD: if_otusvar.h,v 1.1 2010/11/03 20:03:02 christos Exp $ */ 2 /* $OpenBSD: if_otusreg.h,v 1.6 2009/04/06 18:17:01 damien Exp $ */ 3 4 /*- 5 * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr> 6 * Copyright (c) 2007-2008 Atheros Communications, Inc. 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose with or without fee is hereby granted, provided that the above 10 * copyright notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 #ifndef HAVE_EDCA 22 /************************************************************ 23 * XXX: This block belongs in sys/net80211/ieee80211_var.h. 24 */ 25 /* 26 * EDCA AC parameters. 27 */ 28 struct ieee80211_edca_ac_params { 29 u_int8_t ac_ecwmin; /* CWmin = 2^ECWmin - 1 */ 30 u_int8_t ac_ecwmax; /* CWmax = 2^ECWmax - 1 */ 31 u_int8_t ac_aifsn; 32 u_int16_t ac_txoplimit; /* 32TU */ 33 u_int8_t ac_acm; 34 }; 35 /************************************************************/ 36 #endif /* ! HAVE_EDCA */ 37 38 #ifndef HAVE_EDCA 39 /************************************************************ 40 * XXX: This block belongs in sys/net80211/ieee80211.h. 41 */ 42 43 /* 44 * EDCA Access Categories. 45 */ 46 enum ieee80211_edca_ac { 47 EDCA_AC_BK = 1, /* Background */ 48 EDCA_AC_BE = 0, /* Best Effort */ 49 EDCA_AC_VI = 2, /* Video */ 50 EDCA_AC_VO = 3 /* Voice */ 51 }; 52 #define EDCA_NUM_AC 4 53 54 /* XXX: OpenBSD has more of these defined with the standard referenced */ 55 #define IEEE80211_QOS_ACK_POLICY_NOACK 0x0020 56 #define IEEE80211_QOS_ACK_POLICY_MASK 0x0060 57 58 static __inline int 59 ieee80211_has_addr4(const struct ieee80211_frame *wh) 60 { 61 return (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == 62 IEEE80211_FC1_DIR_DSTODS; 63 } 64 65 static __inline int 66 ieee80211_has_qos(const struct ieee80211_frame *wh) 67 { 68 return (wh->i_fc[0] & 69 (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) == 70 (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS); 71 } 72 73 static __inline u_int16_t 74 ieee80211_get_qos(const struct ieee80211_frame *wh) 75 { 76 const u_int8_t *frm; 77 78 if (ieee80211_has_addr4(wh)) 79 frm = ((const struct ieee80211_qosframe_addr4 *)wh)->i_qos; 80 else 81 frm = ((const struct ieee80211_qosframe *)wh)->i_qos; 82 83 return le16toh(*(const u_int16_t *)frm); 84 } 85 /************************************************************/ 86 #endif /* ! HAVE_EDCA */ 87 88 /* Default EDCA parameters for when QoS is disabled. */ 89 static const struct ieee80211_edca_ac_params otus_edca_def[] = { 90 { 4, 10, 3, 0, 0 }, 91 { 4, 10, 7, 0, 0 }, 92 { 3, 4, 2, 94, 0 }, 93 { 2, 3, 2, 47, 0 } 94 }; 95 96 #define OTUS_TX_DATA_LIST_COUNT 8 97 #define OTUS_RX_DATA_LIST_COUNT 1 98 99 #define OTUS_CMD_TIMEOUT 1000 100 #define OTUS_TX_TIMEOUT 1000 101 102 #define OTUS_UID(aid) (IEEE80211_AID(aid) + 4) 103 104 #define OTUS_MAX_TXCMDSZ 64 105 #define OTUS_RXBUFSZ (8 * 1024) 106 #define OTUS_TXBUFSZ (4 * 1024) 107 108 #define OTUS_RIDX_CCK1 0 109 #define OTUS_RIDX_OFDM6 4 110 #define OTUS_RIDX_OFDM24 8 111 #define OTUS_RIDX_MAX 11 112 static const struct otus_rate { 113 uint8_t rate; 114 uint8_t mcs; 115 } otus_rates[] = { 116 { 2, 0x0 }, 117 { 4, 0x1 }, 118 { 11, 0x2 }, 119 { 22, 0x3 }, 120 { 12, 0xb }, 121 { 18, 0xf }, 122 { 24, 0xa }, 123 { 36, 0xe }, 124 { 48, 0x9 }, 125 { 72, 0xd }, 126 { 96, 0x8 }, 127 { 108, 0xc } 128 }; 129 130 struct otus_rx_radiotap_header { 131 struct ieee80211_radiotap_header wr_ihdr; 132 uint8_t wr_flags; 133 uint8_t wr_rate; 134 uint16_t wr_chan_freq; 135 uint16_t wr_chan_flags; 136 uint8_t wr_antsignal; 137 } __packed; 138 139 #define OTUS_RX_RADIOTAP_PRESENT \ 140 (1 << IEEE80211_RADIOTAP_FLAGS | \ 141 1 << IEEE80211_RADIOTAP_RATE | \ 142 1 << IEEE80211_RADIOTAP_CHANNEL | \ 143 1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) 144 145 struct otus_tx_radiotap_header { 146 struct ieee80211_radiotap_header wt_ihdr; 147 uint8_t wt_flags; 148 uint8_t wt_rate; 149 uint16_t wt_chan_freq; 150 uint16_t wt_chan_flags; 151 } __packed; 152 153 #define OTUS_TX_RADIOTAP_PRESENT \ 154 (1 << IEEE80211_RADIOTAP_FLAGS | \ 155 1 << IEEE80211_RADIOTAP_RATE | \ 156 1 << IEEE80211_RADIOTAP_CHANNEL) 157 158 159 struct otus_softc; 160 161 struct otus_tx_cmd { 162 usbd_xfer_handle xfer; 163 uint8_t *buf; 164 void *odata; 165 uint16_t token; 166 uint8_t done; 167 }; 168 169 struct otus_rx_data { 170 struct otus_softc *sc; 171 usbd_xfer_handle xfer; 172 uint8_t *buf; 173 }; 174 175 struct otus_tx_data { 176 struct otus_softc *sc; 177 usbd_xfer_handle xfer; 178 uint8_t *buf; 179 }; 180 181 struct otus_host_cmd { 182 void (*cb)(struct otus_softc *, void *); 183 uint8_t data[256]; 184 }; 185 186 #define OTUS_HOST_CMD_RING_COUNT 32 187 struct otus_host_cmd_ring { 188 struct otus_host_cmd cmd[OTUS_HOST_CMD_RING_COUNT]; 189 int cur; 190 int next; 191 int queued; 192 }; 193 194 struct otus_node { 195 struct ieee80211_node ni; /* must be first */ 196 struct ieee80211_amrr_node amn; 197 uint8_t ridx[IEEE80211_RATE_MAXSIZE]; 198 }; 199 200 struct otus_cmd_newstate { 201 enum ieee80211_state state; 202 int arg; 203 }; 204 205 struct otus_cmd_key { 206 struct ieee80211_key key; 207 uint16_t associd; 208 }; 209 210 struct otus_softc { 211 device_t sc_dev; 212 struct ieee80211com sc_ic; 213 struct ethercom sc_ec; 214 #define sc_if sc_ec.ec_if 215 int (*sc_newstate)(struct ieee80211com *, 216 enum ieee80211_state, int); 217 void (*sc_led_newstate)(struct otus_softc *); 218 219 usbd_device_handle sc_udev; 220 usbd_interface_handle sc_iface; 221 222 struct ar5416eeprom sc_eeprom; 223 uint8_t sc_capflags; 224 uint8_t sc_rxmask; 225 uint8_t sc_txmask; 226 227 usbd_pipe_handle sc_data_tx_pipe; 228 usbd_pipe_handle sc_data_rx_pipe; 229 usbd_pipe_handle sc_cmd_tx_pipe; 230 usbd_pipe_handle sc_cmd_rx_pipe; 231 uint8_t *sc_ibuf; 232 233 int sc_if_flags; 234 int sc_tx_timer; 235 int sc_fixed_ridx; 236 int sc_bb_reset; 237 238 struct ieee80211_channel *sc_curchan; 239 240 struct usb_task sc_task; 241 callout_t sc_scan_to; 242 callout_t sc_calib_to; 243 struct ieee80211_amrr sc_amrr; 244 245 unsigned int sc_write_idx; 246 int sc_tx_cur; 247 int sc_tx_queued; 248 uint32_t sc_led_state; 249 250 kmutex_t sc_cmd_mtx; 251 kmutex_t sc_task_mtx; 252 kmutex_t sc_write_mtx; 253 254 const uint32_t *sc_phy_vals; 255 256 struct { 257 uint32_t reg; 258 uint32_t val; 259 } __packed sc_write_buf[AR_FW_MAX_WRITES]; 260 261 struct otus_host_cmd_ring sc_cmdq; 262 struct otus_tx_cmd sc_tx_cmd; 263 struct otus_tx_data sc_tx_data[OTUS_TX_DATA_LIST_COUNT]; 264 struct otus_rx_data sc_rx_data[OTUS_RX_DATA_LIST_COUNT]; 265 266 struct bpf_if * sc_drvbpf; 267 union { 268 struct otus_rx_radiotap_header th; 269 uint8_t pad[64]; 270 } sc_rxtapu; 271 #define sc_rxtap sc_rxtapu.th 272 int sc_rxtap_len; 273 union { 274 struct otus_tx_radiotap_header th; 275 uint8_t pad[64]; 276 } sc_txtapu; 277 #define sc_txtap sc_txtapu.th 278 int sc_txtap_len; 279 }; 280