if_otusvar.h revision 1.1.2.2 1 /* $NetBSD: if_otusvar.h,v 1.1.2.2 2010/11/06 08:08:35 uebayasi 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
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