xref: /openbsd/sys/dev/ic/atwvar.h (revision 891d7ab6)
1 /*	$OpenBSD: atwvar.h,v 1.24 2010/11/20 20:11:19 miod Exp $	*/
2 /*	$NetBSD: atwvar.h,v 1.13 2004/07/23 07:07:55 dyoung Exp $	*/
3 
4 /*
5  * Copyright (c) 2003, 2004 The NetBSD Foundation, Inc.  All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by David Young.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY David Young AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL David Young
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
29  * THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifndef _DEV_IC_ATWVAR_H_
33 #define	_DEV_IC_ATWVAR_H_
34 
35 #include <sys/queue.h>
36 #include <sys/time.h>
37 #include <sys/timeout.h>
38 #include <sys/workq.h>
39 
40 /*
41  * Some misc. statics, useful for debugging.
42  */
43 struct atw_stats {
44 	u_long		ts_tx_tuf;	/* transmit underflow errors */
45 	u_long		ts_tx_tro;	/* transmit jabber timeouts */
46 	u_long		ts_tx_trt;	/* retry count exceeded */
47 	u_long		ts_tx_tlt;	/* lifetime exceeded */
48 	u_long		ts_tx_sofbr;	/* packet size mismatch */
49 };
50 
51 /*
52  * Transmit descriptor list size.  This is arbitrary, but allocate
53  * enough descriptors for 64 pending transmissions and 16 segments
54  * per packet.  Since a descriptor holds 2 buffer addresses, that's
55  * 8 descriptors per packet.  This MUST work out to a power of 2.
56  */
57 #define	ATW_NTXSEGS		16
58 
59 #define	ATW_TXQUEUELEN	64
60 #define	ATW_NTXDESC		(ATW_TXQUEUELEN * ATW_NTXSEGS)
61 #define	ATW_NTXDESC_MASK	(ATW_NTXDESC - 1)
62 #define	ATW_NEXTTX(x)		((x + 1) & ATW_NTXDESC_MASK)
63 
64 /*
65  * Receive descriptor list size.  We have one Rx buffer per incoming
66  * packet, so this logic is a little simpler.
67  */
68 #define	ATW_NRXDESC		64
69 #define	ATW_NRXDESC_MASK	(ATW_NRXDESC - 1)
70 #define	ATW_NEXTRX(x)		((x + 1) & ATW_NRXDESC_MASK)
71 
72 /*
73  * Control structures are DMA'd to the ADM8211 chip.  We allocate them in
74  * a single clump that maps to a single DMA segment to make several things
75  * easier.
76  */
77 struct atw_control_data {
78 	/*
79 	 * The transmit descriptors.
80 	 */
81 	struct atw_txdesc acd_txdescs[ATW_NTXDESC];
82 
83 	/*
84 	 * The receive descriptors.
85 	 */
86 	struct atw_rxdesc acd_rxdescs[ATW_NRXDESC];
87 };
88 
89 #define	ATW_CDOFF(x)		offsetof(struct atw_control_data, x)
90 #define	ATW_CDTXOFF(x)	ATW_CDOFF(acd_txdescs[(x)])
91 #define	ATW_CDRXOFF(x)	ATW_CDOFF(acd_rxdescs[(x)])
92 
93 struct atw_duration {
94 	uint16_t	d_rts_dur;
95 	uint16_t	d_data_dur;
96 	uint16_t	d_plcp_len;
97 	uint8_t		d_residue;	/* unused octets in time slot */
98 };
99 
100 /*
101  * Software state for transmit jobs.
102  */
103 struct atw_txsoft {
104 	struct mbuf *txs_mbuf;		/* head of our mbuf chain */
105 	bus_dmamap_t txs_dmamap;	/* our DMA map */
106 	int txs_firstdesc;		/* first descriptor in packet */
107 	int txs_lastdesc;		/* last descriptor in packet */
108 	int txs_ndescs;			/* number of descriptors */
109 	struct atw_duration txs_d0;
110 	struct atw_duration txs_dn;
111 	SIMPLEQ_ENTRY(atw_txsoft) txs_q;
112 };
113 
114 SIMPLEQ_HEAD(atw_txsq, atw_txsoft);
115 
116 /*
117  * Software state for receive jobs.
118  */
119 struct atw_rxsoft {
120 	struct mbuf *rxs_mbuf;		/* head of our mbuf chain */
121 	bus_dmamap_t rxs_dmamap;	/* our DMA map */
122 };
123 
124 /*
125  * Table which describes the transmit threshold mode.  We generally
126  * start at index 0.  Whenever we get a transmit underrun, we increment
127  * our index, falling back if we encounter the NULL terminator.
128  */
129 struct atw_txthresh_tab {
130 	u_int32_t txth_opmode;		/* OPMODE bits */
131 	const char *txth_name;		/* name of mode */
132 };
133 
134 enum atw_rftype { ATW_RFTYPE_INTERSIL = 0, ATW_RFTYPE_RFMD  = 1,
135        ATW_RFTYPE_MARVEL = 2 };
136 
137 enum atw_bbptype { ATW_BBPTYPE_INTERSIL = 0, ATW_BBPTYPE_RFMD  = 1,
138        ATW_BBPTYPE_MARVEL = 2, ATW_C_BBPTYPE_RFMD  = 5 };
139 
140 /* Radio capture format for ADMtek. */
141 
142 #define ATW_RX_RADIOTAP_PRESENT	\
143 	((1 << IEEE80211_RADIOTAP_FLAGS) | (1 << IEEE80211_RADIOTAP_RATE) | \
144 	 (1 << IEEE80211_RADIOTAP_CHANNEL) | \
145 	 (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
146 
147 struct atw_rx_radiotap_header {
148 	struct ieee80211_radiotap_header	ar_ihdr;
149 	u_int8_t				ar_flags;
150 	u_int8_t				ar_rate;
151 	u_int16_t				ar_chan_freq;
152 	u_int16_t				ar_chan_flags;
153 	u_int8_t				ar_antsignal;
154 } __packed;
155 
156 #define ATW_TX_RADIOTAP_PRESENT	((1 << IEEE80211_RADIOTAP_FLAGS) | \
157 				 (1 << IEEE80211_RADIOTAP_RATE) | \
158 				 (1 << IEEE80211_RADIOTAP_CHANNEL))
159 
160 struct atw_tx_radiotap_header {
161 	struct ieee80211_radiotap_header	at_ihdr;
162 	u_int8_t				at_flags;
163 	u_int8_t				at_rate;
164 	u_int16_t				at_chan_freq;
165 	u_int16_t				at_chan_flags;
166 } __packed;
167 
168 enum atw_revision {
169 	ATW_REVISION_AB = 0x11,	/* ADM8211A */
170 	ATW_REVISION_AF = 0x15,	/* ADM8211A? */
171 	ATW_REVISION_BA = 0x20,	/* ADM8211B */
172 	ATW_REVISION_CA = 0x30	/* ADM8211C/CR */
173 };
174 
175 struct atw_softc {
176 	struct device		sc_dev;
177 	struct ieee80211com	sc_ic;
178 	int			(*sc_enable)(struct atw_softc *);
179 	void			(*sc_disable)(struct atw_softc *);
180 	void			(*sc_power)(struct atw_softc *, int);
181 	int			(*sc_newstate)(struct ieee80211com *,
182 					enum ieee80211_state, int);
183 	void			(*sc_recv_mgmt)(struct ieee80211com *,
184 				    struct mbuf *, struct ieee80211_node *,
185 				    struct ieee80211_rxinfo *, int);
186 	struct ieee80211_node	*(*sc_node_alloc)(struct ieee80211com *);
187 	void			(*sc_node_free)(struct ieee80211com *,
188 					struct ieee80211_node *);
189 
190 	struct atw_stats sc_stats;	/* debugging stats */
191 
192 	int			sc_tx_timer;
193 	int			sc_rescan_timer;
194 
195 	bus_space_tag_t		sc_st;		/* bus space tag */
196 	bus_space_handle_t	sc_sh;		/* bus space handle */
197 	bus_size_t		sc_mapsize;	/* mapping size */
198 	bus_dma_tag_t		sc_dmat;	/* bus dma tag */
199 	u_int32_t		sc_cacheline;	/* cache line size */
200 	u_int32_t		sc_maxburst;	/* maximum burst length */
201 
202 	const struct atw_txthresh_tab	*sc_txth;
203 	int				sc_txthresh; /* current tx threshold */
204 
205 	u_int			sc_cur_chan;	/* current channel */
206 
207 	int			sc_flags;
208 
209 	u_int16_t		*sc_srom;
210 	u_int16_t		sc_sromsz;
211 
212 	caddr_t			sc_radiobpf;
213 
214 	bus_dma_segment_t	sc_cdseg;	/* control data memory */
215 	int			sc_cdnseg;	/* number of segments */
216 	bus_dmamap_t		sc_cddmamap;	/* control data DMA map */
217 #define	sc_cddma	sc_cddmamap->dm_segs[0].ds_addr
218 
219 	/*
220 	 * Software state for transmit and receive descriptors.
221 	 */
222 	struct atw_txsoft sc_txsoft[ATW_TXQUEUELEN];
223 	struct atw_rxsoft sc_rxsoft[ATW_NRXDESC];
224 
225 	/*
226 	 * Control data structures.
227 	 */
228 	struct atw_control_data *sc_control_data;
229 #define	sc_txdescs	sc_control_data->acd_txdescs
230 #define	sc_rxdescs	sc_control_data->acd_rxdescs
231 #define	sc_setup_desc	sc_control_data->acd_setup_desc
232 
233 	int	sc_txfree;		/* number of free Tx descriptors */
234 	int	sc_txnext;		/* next ready Tx descriptor */
235 	int	sc_ntxsegs;		/* number of transmit segs per pkt */
236 
237 	struct atw_txsq sc_txfreeq;	/* free Tx descsofts */
238 	struct atw_txsq sc_txdirtyq;	/* dirty Tx descsofts */
239 
240 	int	sc_rxptr;		/* next ready RX descriptor/descsoft */
241 
242 	u_int32_t	sc_busmode;	/* copy of ATW_PAR */
243 	u_int32_t	sc_opmode;	/* copy of ATW_NAR */
244 	u_int32_t	sc_inten;	/* copy of ATW_IER */
245 	u_int32_t	sc_wepctl;	/* copy of ATW_WEPCTL */
246 
247 	u_int32_t	sc_rxint_mask;	/* mask of Rx interrupts we want */
248 	u_int32_t	sc_txint_mask;	/* mask of Tx interrupts we want */
249 	u_int32_t	sc_linkint_mask;/* link-state interrupts mask */
250 
251 	enum atw_rftype		sc_rftype;
252 	enum atw_bbptype	sc_bbptype;
253 	u_int32_t	sc_synctl_rd;
254 	u_int32_t	sc_synctl_wr;
255 	u_int32_t	sc_bbpctl_rd;
256 	u_int32_t	sc_bbpctl_wr;
257 
258 	void		(*sc_recv_beacon)(struct ieee80211com *, struct mbuf *,
259 			    int, u_int32_t);
260 	void		(*sc_recv_prresp)(struct ieee80211com *, struct mbuf *,
261 			    int, u_int32_t);
262 
263 	/* ADM8211 state variables. */
264 	u_int8_t	sc_sram[ATW_SRAM_MAXSIZE];
265 	u_int		sc_sramlen;
266 	u_int8_t	sc_bssid[IEEE80211_ADDR_LEN];
267 	u_int8_t	sc_rev;
268 	u_int8_t	sc_rf3000_options1;
269 	u_int8_t	sc_rf3000_options2;
270 
271 	struct timeval	sc_last_beacon;
272 	struct timeout	sc_scan_to;
273 	union {
274 		struct atw_rx_radiotap_header	tap;
275 		u_int8_t			pad[64];
276 	} sc_rxtapu;
277 	union {
278 		struct atw_tx_radiotap_header	tap;
279 		u_int8_t			pad[64];
280 	} sc_txtapu;
281 
282 	struct workq_task	sc_resume_wqt;
283 };
284 
285 #define sc_rxtap	sc_rxtapu.tap
286 #define sc_txtap	sc_txtapu.tap
287 
288 #define	sc_if			sc_ic.ic_if
289 
290 /* XXX this is fragile. try not to introduce any u_int32_t's. */
291 struct atw_frame {
292 /*00*/	u_int8_t			atw_dst[IEEE80211_ADDR_LEN];
293 /*06*/	u_int8_t			atw_rate;	/* TX rate in 100Kbps */
294 /*07*/	u_int8_t			atw_service;	/* 0 */
295 /*08*/	u_int16_t			atw_paylen;	/* payload length */
296 /*0a*/	u_int8_t			atw_fc[2];	/* 802.11 Frame
297 							 * Control
298 							 */
299 	/* 802.11 PLCP Length for first & last fragment */
300 /*0c*/	u_int16_t			atw_tail_plcplen;
301 /*0e*/	u_int16_t			atw_head_plcplen;
302 	/* 802.11 Duration for first & last fragment */
303 /*10*/	u_int16_t			atw_tail_dur;
304 /*12*/	u_int16_t			atw_head_dur;
305 /*14*/	u_int8_t			atw_addr4[IEEE80211_ADDR_LEN];
306 	union {
307 		struct {
308 /*1a*/			u_int16_t	hdrctl;	/*transmission control*/
309 /*1c*/			u_int16_t	fragthr;/* fragmentation threshold
310 						 * [0:11], zero [12:15].
311 						 */
312 /*1e*/			u_int8_t	fragnum;/* fragment number [4:7],
313 						 * zero [0:3].
314 						 */
315 /*1f*/			u_int8_t	rtylmt;	/* retry limit */
316 /*20*/			u_int8_t	wepkey0[4];/* ??? */
317 /*24*/			u_int8_t	wepkey1[4];/* ??? */
318 /*28*/			u_int8_t	wepkey2[4];/* ??? */
319 /*2c*/			u_int8_t	wepkey3[4];/* ??? */
320 /*30*/			u_int8_t	keyid;
321 /*31*/			u_int8_t	reserved0[7];
322 		} s1;
323 		struct {
324 			u_int8_t		pad[6];
325 			struct ieee80211_frame	ihdr;
326 		} s2;
327 	} u;
328 } __packed;
329 
330 #define atw_hdrctl	u.s1.hdrctl
331 #define atw_fragthr	u.s1.fragthr
332 #define atw_fragnum	u.s1.fragnum
333 #define atw_rtylmt	u.s1.rtylmt
334 #define atw_keyid	u.s1.keyid
335 #define atw_ihdr	u.s2.ihdr
336 
337 #define ATW_HDRCTL_SHORT_PREAMBLE	(1<<0)	/* use short preamble */
338 #define ATW_HDRCTL_RTSCTS		(1<<4)	/* send RTS */
339 #define ATW_HDRCTL_WEP			(1<<5)
340 #define ATW_HDRCTL_UNKNOWN1		(1<<15) /* MAC adds FCS? */
341 #define ATW_HDRCTL_UNKNOWN2		(1<<8)
342 
343 #define ATW_FRAGTHR_FRAGTHR_MASK	0x0fff
344 #define ATW_FRAGNUM_FRAGNUM_MASK	0x00f0
345 
346 /* Values for sc_flags. */
347 #define	ATWF_MRL		0x00000010	/* memory read line okay */
348 #define	ATWF_MRM		0x00000020	/* memory read multi okay */
349 #define	ATWF_MWI		0x00000040	/* memory write inval okay */
350 #define	ATWF_SHORT_PREAMBLE	0x00000080	/* short preamble enabled */
351 #define	ATWF_RTSCTS		0x00000100	/* RTS/CTS enabled */
352 #define	ATWF_ATTACHED		0x00000800	/* attach has succeeded */
353 #define	ATWF_ENABLED		0x00001000	/* chip is enabled */
354 
355 #define	ATW_IS_ENABLED(sc)	((sc)->sc_flags & ATWF_ENABLED)
356 
357 #define	ATW_CDTXADDR(sc, x)	((sc)->sc_cddma + ATW_CDTXOFF((x)))
358 #define	ATW_CDRXADDR(sc, x)	((sc)->sc_cddma + ATW_CDRXOFF((x)))
359 
360 #define	ATW_CDTXSYNC(sc, x, n, ops)					\
361 do {									\
362 	int __x, __n;							\
363 									\
364 	__x = (x);							\
365 	__n = (n);							\
366 									\
367 	/* If it will wrap around, sync to the end of the ring. */	\
368 	if ((__x + __n) > ATW_NTXDESC) {				\
369 		bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,	\
370 		    ATW_CDTXOFF(__x), sizeof(struct atw_txdesc) *	\
371 		    (ATW_NTXDESC - __x), (ops));			\
372 		__n -= (ATW_NTXDESC - __x);				\
373 		__x = 0;						\
374 	}								\
375 									\
376 	/* Now sync whatever is left. */				\
377 	bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,		\
378 	    ATW_CDTXOFF(__x), sizeof(struct atw_txdesc) * __n, (ops)); \
379 } while (0)
380 
381 #define	ATW_CDRXSYNC(sc, x, ops)					\
382 	bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,		\
383 	    ATW_CDRXOFF((x)), sizeof(struct atw_rxdesc), (ops))
384 
385 /*
386  * Note we rely on MCLBYTES being a power of two.  Because the `length'
387  * field is only 11 bits, we must subtract 1 from the length to avoid
388  * having it truncated to 0!
389  */
390 #define	ATW_INIT_RXDESC(sc, x)						\
391 do {									\
392 	struct atw_rxsoft *__rxs = &sc->sc_rxsoft[(x)];			\
393 	struct atw_rxdesc *__rxd = &sc->sc_rxdescs[(x)];		\
394 	struct mbuf *__m = __rxs->rxs_mbuf;				\
395 									\
396 	__rxd->ar_buf1 =						\
397 	    htole32(__rxs->rxs_dmamap->dm_segs[0].ds_addr);		\
398 	__rxd->ar_buf2 =	/* for descriptor chaining */		\
399 	    htole32(ATW_CDRXADDR((sc), ATW_NEXTRX((x))));		\
400 	__rxd->ar_ctl =							\
401 	    htole32(LSHIFT(((__m->m_ext.ext_size - 1) & ~0x3U),		\
402 	                   ATW_RXCTL_RBS1_MASK) |			\
403 		    0 /* ATW_RXCTL_RCH */ |				\
404 	    ((x) == (ATW_NRXDESC - 1) ? ATW_RXCTL_RER : 0));		\
405 	__rxd->ar_stat = htole32(ATW_RXSTAT_OWN);			\
406 	            							\
407 	ATW_CDRXSYNC((sc), (x),						\
408 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);			\
409 } while (0)
410 
411 /* country codes from ADM8211 SROM */
412 #define	ATW_COUNTRY_FCC 0		/* USA 1-11 */
413 #define	ATW_COUNTRY_IC 1		/* Canada 1-11 */
414 #define	ATW_COUNTRY_ETSI 2		/* European Union (?) 1-13 */
415 #define	ATW_COUNTRY_SPAIN 3		/* 10-11 */
416 #define	ATW_COUNTRY_FRANCE 4		/* 10-13 */
417 #define	ATW_COUNTRY_MKK 5		/* Japan: 14 */
418 #define	ATW_COUNTRY_MKK2 6		/* Japan: 1-14 */
419 
420 /*
421  * register space access macros
422  */
423 #define	ATW_READ(sc, reg)						\
424 	bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))
425 
426 #define	ATW_WRITE(sc, reg, val)					\
427 	bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
428 
429 #define	ATW_SET(sc, reg, mask)					\
430 	ATW_WRITE((sc), (reg), ATW_READ((sc), (reg)) | (mask))
431 
432 #define	ATW_CLR(sc, reg, mask)					\
433 	ATW_WRITE((sc), (reg), ATW_READ((sc), (reg)) & ~(mask))
434 
435 #define	ATW_ISSET(sc, reg, mask)					\
436 	(ATW_READ((sc), (reg)) & (mask))
437 
438 void	atw_attach(struct atw_softc *);
439 int	atw_detach(struct atw_softc *);
440 int	atw_activate(struct device *, int);
441 int	atw_intr(void *arg);
442 int	atw_enable(struct atw_softc *);
443 void	atw_resume(void *, void *);
444 
445 #endif /* _DEV_IC_ATWVAR_H_ */
446