xref: /netbsd-src/sys/dev/usb/if_otusvar.h (revision c2f76ff004a2cb67efe5b12d97bd3ef7fe89e18d)
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