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