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