if_bwnvar.h revision 204257
1/*-
2 * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer,
10 *    without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13 *    redistribution must be conditioned upon including a substantially
14 *    similar Disclaimer requirement for further binary redistribution.
15 *
16 * NO WARRANTY
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
28 *
29 * $FreeBSD: head/sys/dev/bwn/if_bwnvar.h 204257 2010-02-23 19:55:54Z weongyo $
30 */
31
32#ifndef _IF_BWNVAR_H
33#define	_IF_BWNVAR_H
34
35struct siba_dev_softc;
36struct bwn_softc;
37struct bwn_mac;
38
39#define	N(a)			(sizeof(a) / sizeof(a[0]))
40#define	BWN_ALIGN			0x1000
41#define	BWN_BUS_SPACE_MAXADDR_30BIT	0x3fffffff
42#define	BWN_RETRY_SHORT			7
43#define	BWN_RETRY_LONG			4
44#define	BWN_STAID_MAX			64
45#define	BWN_TXPWR_IGNORE_TIME		(1 << 0)
46#define	BWN_TXPWR_IGNORE_TSSI		(1 << 1)
47#define	BWN_HAS_TXMAG(phy)						\
48	(((phy)->rev >= 2) && ((phy)->rf_ver == 0x2050) &&		\
49	 ((phy)->rf_rev == 8))
50#define	BWN_HAS_LOOPBACK(phy)						\
51	(((phy)->rev > 1) || ((phy)->gmode))
52#define	BWN_TXERROR_MAX			1000
53#define	BWN_GETTIME(v)	do {						\
54	struct timespec ts;						\
55	nanouptime(&ts);						\
56	(v) = ts.tv_nsec / 1000000 + ts.tv_sec * 1000;			\
57} while (0)
58#define	BWN_ISOLDFMT(mac)		((mac)->mac_fw.rev <= 351)
59#define	BWN_TSSI2DBM(num, den)						\
60	((int32_t)((num < 0) ? num / den : (num + den / 2) / den))
61#define	BWN_HDRSIZE(mac)						\
62	((BWN_ISOLDFMT(mac)) ? (100 + sizeof(struct bwn_plcp6)) :	\
63	    (104 + sizeof(struct bwn_plcp6)))
64#define	BWN_PIO_COOKIE(tq, tp)						\
65	((uint16_t)((((uint16_t)tq->tq_index + 1) << 12) | tp->tp_index))
66#define	BWN_DMA_COOKIE(dr, slot)					\
67	((uint16_t)(((uint16_t)dr->dr_index + 1) << 12) | (uint16_t)slot)
68#define	BWN_READ_2(mac, o)		(siba_read_2(mac->mac_sd, o))
69#define	BWN_READ_4(mac, o)		(siba_read_4(mac->mac_sd, o))
70#define	BWN_WRITE_2(mac, o, v)		(siba_write_2(mac->mac_sd, o, v))
71#define	BWN_WRITE_4(mac, o, v)		(siba_write_4(mac->mac_sd, o, v))
72#define	BWN_PIO_TXQOFFSET(mac)						\
73	((mac->mac_sd->sd_id.sd_rev >= 11) ? 0x18 : 0)
74#define	BWN_PIO_RXQOFFSET(mac)						\
75	((mac->mac_sd->sd_id.sd_rev >= 11) ? 0x38 : 8)
76#define	BWN_SEC_NEWAPI(mac)		(mac->mac_fw.rev >= 351)
77#define	BWN_SEC_KEY2FW(mac, idx)					\
78	(BWN_SEC_NEWAPI(mac) ? idx : ((idx >= 4) ? idx - 4 : idx))
79#define	BWN_RF_READ(mac, r)		(mac->mac_phy.rf_read(mac, r))
80#define	BWN_RF_WRITE(mac, r, v)		(mac->mac_phy.rf_write(mac, r, v))
81#define	BWN_RF_MASK(mac, o, m)						\
82	BWN_RF_WRITE(mac, o, BWN_RF_READ(mac, o) & m)
83#define	BWN_RF_SETMASK(mac, offset, mask, set)				\
84	BWN_RF_WRITE(mac, offset, (BWN_RF_READ(mac, offset) & mask) | set)
85#define	BWN_RF_SET(mac, offset, set)					\
86	BWN_RF_WRITE(mac, offset, BWN_RF_READ(mac, offset) | set)
87#define	BWN_PHY_READ(mac, r)		(mac->mac_phy.phy_read(mac, r))
88#define	BWN_PHY_WRITE(mac, r, v)					\
89	(mac->mac_phy.phy_write(mac, r, v))
90#define	BWN_PHY_SET(mac, offset, set)	do {				\
91	if (mac->mac_phy.phy_maskset != NULL) {				\
92		KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED ||	\
93		    mac->mac_suspended > 0,				\
94		    ("dont access PHY or RF registers after turning on MAC")); \
95		mac->mac_phy.phy_maskset(mac, offset, 0xffff, set);	\
96	} else								\
97		BWN_PHY_WRITE(mac, offset,				\
98		    BWN_PHY_READ(mac, offset) | (set));			\
99} while (0)
100#define	BWN_PHY_SETMASK(mac, offset, mask, set)	do {			\
101	if (mac->mac_phy.phy_maskset != NULL) {				\
102		KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED ||	\
103		    mac->mac_suspended > 0,				\
104		    ("dont access PHY or RF registers after turning on MAC")); \
105		mac->mac_phy.phy_maskset(mac, offset, mask, set);	\
106	} else								\
107		BWN_PHY_WRITE(mac, offset,				\
108		    (BWN_PHY_READ(mac, offset) & (mask)) | (set));	\
109} while (0)
110#define	BWN_PHY_MASK(mac, offset, mask)	do {				\
111	if (mac->mac_phy.phy_maskset != NULL) {				\
112		KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED ||	\
113		    mac->mac_suspended > 0,				\
114		    ("dont access PHY or RF registers after turning on MAC")); \
115		mac->mac_phy.phy_maskset(mac, offset, mask, 0);		\
116	} else								\
117		BWN_PHY_WRITE(mac, offset,				\
118		    BWN_PHY_READ(mac, offset) & mask);			\
119} while (0)
120#define	BWN_PHY_COPY(mac, dst, src)	do {				\
121	KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED ||		\
122	    mac->mac_suspended > 0,					\
123	    ("dont access PHY or RF registers after turning on MAC"));	\
124	BWN_PHY_WRITE(mac, dst, BWN_PHY_READ(mac, src));		\
125} while (0)
126#define BWN_LO_CALIB_EXPIRE		(1000 * (30 - 2))
127#define BWN_LO_PWRVEC_EXPIRE		(1000 * (30 - 2))
128#define BWN_LO_TXCTL_EXPIRE		(1000 * (180 - 4))
129#define	BWN_DMA_BIT_MASK(n)		(((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
130#define BWN_LPD(L, P, D)		(((L) << 2) | ((P) << 1) | ((D) << 0))
131#define BWN_BITREV4(tmp)		(BWN_BITREV8(tmp) >> 4)
132#define	BWN_BITREV8(byte)		(bwn_bitrev_table[byte])
133#define	BWN_BBATTCMP(a, b)		((a)->att == (b)->att)
134#define	BWN_RFATTCMP(a, b)						\
135	(((a)->att == (b)->att) && ((a)->padmix == (b)->padmix))
136#define	BWN_PIO_WRITE_2(mac, tq, offset, value)				\
137	BWN_WRITE_2(mac, (tq)->tq_base + offset, value)
138#define	BWN_PIO_READ_4(mac, tq, offset)					\
139	BWN_READ_4(mac, tq->tq_base + offset)
140#define	BWN_ISCCKRATE(rate)						\
141	(rate == BWN_CCK_RATE_1MB || rate == BWN_CCK_RATE_2MB ||	\
142	 rate == BWN_CCK_RATE_5MB || rate == BWN_CCK_RATE_11MB)
143#define	BWN_ISOFDMRATE(rate)		(!BWN_ISCCKRATE(rate))
144#define	BWN_BARRIER(mac, flags)		siba_barrier(mac->mac_sd, flags)
145#define	BWN_DMA_READ(dr, offset)				\
146	(BWN_READ_4(dr->dr_mac, dr->dr_base + offset))
147#define	BWN_DMA_WRITE(dr, offset, value)			\
148	(BWN_WRITE_4(dr->dr_mac, dr->dr_base + offset, value))
149
150struct bwn_rate {
151	uint16_t			rateid;
152	uint32_t			flags;
153};
154
155#define	BWN_ANT0			0
156#define	BWN_ANT1			1
157#define	BWN_ANTAUTO0			2
158#define	BWN_ANTAUTO1			3
159#define	BWN_ANT2			4
160#define	BWN_ANT3			8
161#define	BWN_ANTAUTO			BWN_ANTAUTO0
162#define	BWN_ANT_DEFAULT			BWN_ANTAUTO
163#define	BWN_TX_SLOTS_PER_FRAME		2
164
165struct bwn_channel {
166	unsigned			freq;
167	unsigned			ieee;
168	unsigned			maxTxPow;
169};
170
171struct bwn_channelinfo {
172	struct bwn_channel		channels[IEEE80211_CHAN_MAX];
173	unsigned			nchannels;
174};
175
176struct bwn_bbatt {
177	uint8_t				att;
178};
179
180struct bwn_bbatt_list {
181	const struct bwn_bbatt		*array;
182	uint8_t				len;
183	uint8_t				min;
184	uint8_t				max;
185};
186
187struct bwn_rfatt {
188	uint8_t				att;
189	int				padmix;
190};
191
192struct bwn_rfatt_list {
193	const struct bwn_rfatt		*array;
194	uint8_t				len;
195	uint8_t				min;
196	uint8_t				max;
197};
198
199#define	BWN_DC_LT_SIZE			32
200
201struct bwn_loctl {
202	int8_t				i;
203	int8_t				q;
204};
205
206struct bwn_lo_calib {
207	struct bwn_bbatt		bbatt;
208	struct bwn_rfatt		rfatt;
209	struct bwn_loctl		ctl;
210	unsigned long			calib_time;
211	TAILQ_ENTRY(bwn_lo_calib)	list;
212};
213
214struct bwn_rxhdr4 {
215	uint16_t			frame_len;
216	uint8_t				pad1[2];
217	uint16_t			phy_status0;
218	union {
219		struct {
220			uint8_t		rssi;
221			uint8_t		sig_qual;
222		} __packed abg;
223		struct {
224			int8_t		power0;
225			int8_t		power1;
226		} __packed n;
227	} __packed phy;
228	uint16_t			phy_status2;
229	uint16_t			phy_status3;
230	uint32_t			mac_status;
231	uint16_t			mac_time;
232	uint16_t			channel;
233} __packed;
234
235struct bwn_txstatus {
236	uint16_t			cookie;
237	uint16_t			seq;
238	uint8_t				phy_stat;
239	uint8_t				framecnt;
240	uint8_t				rtscnt;
241	uint8_t				sreason;
242	uint8_t				pm;
243	uint8_t				im;
244	uint8_t				ampdu;
245	uint8_t				ack;
246};
247
248#define	BWN_TXCTL_PA3DB			0x40
249#define	BWN_TXCTL_PA2DB			0x20
250#define	BWN_TXCTL_TXMIX			0x10
251
252struct bwn_txpwr_loctl {
253	struct bwn_rfatt_list		rfatt;
254	struct bwn_bbatt_list		bbatt;
255	uint16_t			dc_lt[BWN_DC_LT_SIZE];
256	TAILQ_HEAD(, bwn_lo_calib)	calib_list;
257	unsigned long			pwr_vec_read_time;
258	unsigned long			txctl_measured_time;
259	uint8_t				tx_bias;
260	uint8_t				tx_magn;
261	uint64_t			power_vector;
262};
263
264#define	BWN_OFDMTAB_DIR_UNKNOWN		0
265#define	BWN_OFDMTAB_DIR_READ		1
266#define	BWN_OFDMTAB_DIR_WRITE		2
267
268struct bwn_phy_g {
269	unsigned			pg_flags;
270#define	BWN_PHY_G_FLAG_TSSITABLE_ALLOC	(1 << 0)
271#define	BWN_PHY_G_FLAG_RADIOCTX_VALID	(1 << 1)
272	int				pg_aci_enable;
273	int				pg_aci_wlan_automatic;
274	int				pg_aci_hw_rssi;
275	int				pg_rf_on;
276	uint16_t			pg_radioctx_over;
277	uint16_t			pg_radioctx_overval;
278	uint16_t			pg_minlowsig[2];
279	uint16_t			pg_minlowsigpos[2];
280	int8_t				*pg_tssi2dbm;
281	int				pg_idletssi;
282	int				pg_curtssi;
283	uint8_t				pg_avgtssi;
284	struct bwn_bbatt		pg_bbatt;
285	struct bwn_rfatt		pg_rfatt;
286	uint8_t				pg_txctl;
287	int				pg_bbatt_delta;
288	int				pg_rfatt_delta;
289
290	struct bwn_txpwr_loctl		pg_loctl;
291	int16_t				pg_max_lb_gain;
292	int16_t				pg_trsw_rx_gain;
293	int16_t				pg_lna_lod_gain;
294	int16_t				pg_lna_gain;
295	int16_t				pg_pga_gain;
296	int				pg_immode;
297#define	BWN_INTERFSTACK_SIZE	26
298	uint32_t			pg_interfstack[BWN_INTERFSTACK_SIZE];
299
300	int16_t				pg_nrssi[2];
301	int32_t				pg_nrssi_slope;
302	int8_t				pg_nrssi_lt[64];
303
304	uint16_t			pg_lofcal;
305
306	uint16_t			pg_initval;
307	uint16_t			pg_ofdmtab_addr;
308	unsigned			pg_ofdmtab_dir;
309};
310
311#define	BWN_IMMODE_NONE			0
312#define	BWN_IMMODE_NONWLAN		1
313#define	BWN_IMMODE_MANUAL		2
314#define	BWN_IMMODE_AUTO			3
315#define	BWN_TXPWR_RES_NEED_ADJUST	0
316#define	BWN_TXPWR_RES_DONE		1
317
318#define	BWN_PHYLP_TXPCTL_UNKNOWN	0
319#define	BWN_PHYLP_TXPCTL_OFF		1
320#define	BWN_PHYLP_TXPCTL_ON_SW		2
321#define	BWN_PHYLP_TXPCTL_ON_HW		3
322
323struct bwn_phy_lp {
324	uint8_t				plp_chan;
325	uint8_t				plp_chanfullcal;
326	int32_t				plp_antenna;
327	uint8_t				plp_txpctlmode;
328	uint8_t				plp_txisoband_h;
329	uint8_t				plp_txisoband_m;
330	uint8_t				plp_txisoband_l;
331	uint8_t				plp_rxpwroffset;
332	int8_t				plp_txpwridx;
333	uint16_t			plp_tssiidx;
334	uint16_t			plp_tssinpt;
335	uint8_t				plp_rssivf;
336	uint8_t				plp_rssivc;
337	uint8_t				plp_rssigs;
338	uint8_t				plp_rccap;
339	uint8_t				plp_bxarch;
340	uint8_t				plp_crsusr_off;
341	uint8_t				plp_crssys_off;
342	uint32_t			plp_div;
343	int32_t				plp_tonefreq;
344	uint16_t			plp_digfilt[9];
345};
346
347/* for LP */
348struct bwn_txgain {
349	uint16_t			tg_gm;
350	uint16_t			tg_pga;
351	uint16_t			tg_pad;
352	uint16_t			tg_dac;
353};
354
355struct bwn_rxcompco {
356	uint8_t				rc_chan;
357	int8_t				rc_c1;
358	int8_t				rc_c0;
359};
360
361struct bwn_phy_lp_iq_est {
362	uint32_t			ie_iqprod;
363	uint32_t			ie_ipwr;
364	uint32_t			ie_qpwr;
365};
366
367struct bwn_txgain_entry {
368	uint8_t				te_gm;
369	uint8_t				te_pga;
370	uint8_t				te_pad;
371	uint8_t				te_dac;
372	uint8_t				te_bbmult;
373};
374
375/* only for LP PHY */
376struct bwn_stxtable {
377	uint16_t			st_phyoffset;
378	uint16_t			st_physhift;
379	uint16_t			st_rfaddr;
380	uint16_t			st_rfshift;
381	uint16_t			st_mask;
382};
383
384struct bwn_b206x_chan {
385	uint8_t				bc_chan;
386	uint16_t			bc_freq;
387	const uint8_t			*bc_data;
388};
389
390struct bwn_b206x_rfinit_entry {
391	uint16_t			br_offset;
392	uint16_t			br_valuea;
393	uint16_t			br_valueg;
394	uint8_t				br_flags;
395};
396
397struct bwn_phy {
398	uint8_t				type;
399	uint8_t				rev;
400	uint8_t				analog;
401
402	int				supports_2ghz;
403	int				supports_5ghz;
404
405	int				gmode;
406	struct bwn_phy_g		phy_g;
407	struct bwn_phy_lp		phy_lp;
408
409	uint16_t			rf_manuf;
410	uint16_t			rf_ver;
411	uint8_t				rf_rev;
412	int				rf_on;
413
414	int				txpower;
415	int				hwpctl;
416	unsigned long			nexttime;
417	unsigned int			chan;
418	int				txerrors;
419
420	int				(*attach)(struct bwn_mac *);
421	void				(*detach)(struct bwn_mac *);
422	int				(*prepare_hw)(struct bwn_mac *);
423	void				(*init_pre)(struct bwn_mac *);
424	int				(*init)(struct bwn_mac *);
425	void				(*exit)(struct bwn_mac *);
426	uint16_t			(*phy_read)(struct bwn_mac *, uint16_t);
427	void				(*phy_write)(struct bwn_mac *, uint16_t,
428					    uint16_t);
429	void				(*phy_maskset)(struct bwn_mac *,
430					    uint16_t, uint16_t, uint16_t);
431	uint16_t			(*rf_read)(struct bwn_mac *, uint16_t);
432	void				(*rf_write)(struct bwn_mac *, uint16_t,
433					    uint16_t);
434	int				(*use_hwpctl)(struct bwn_mac *);
435	void				(*rf_onoff)(struct bwn_mac *, int);
436	void				(*switch_analog)(struct bwn_mac *, int);
437	int				(*switch_channel)(struct bwn_mac *,
438					    unsigned int);
439	uint32_t			(*get_default_chan)(struct bwn_mac *);
440	void				(*set_antenna)(struct bwn_mac *, int);
441	int				(*set_im)(struct bwn_mac *, int);
442	int				(*recalc_txpwr)(struct bwn_mac *, int);
443	void				(*set_txpwr)(struct bwn_mac *);
444	void				(*task_15s)(struct bwn_mac *);
445	void				(*task_60s)(struct bwn_mac *);
446};
447
448struct bwn_chan_band {
449	uint32_t			flags;
450	uint8_t				nchan;
451#define	BWN_MAX_CHAN_PER_BAND		14
452	uint8_t				chan[BWN_MAX_CHAN_PER_BAND];
453};
454
455#define	BWN_NR_WMEPARAMS		16
456enum {
457	BWN_WMEPARAM_TXOP = 0,
458	BWN_WMEPARAM_CWMIN,
459	BWN_WMEPARAM_CWMAX,
460	BWN_WMEPARAM_CWCUR,
461	BWN_WMEPARAM_AIFS,
462	BWN_WMEPARAM_BSLOTS,
463	BWN_WMEPARAM_REGGAP,
464	BWN_WMEPARAM_STATUS,
465};
466
467#define	BWN_WME_PARAMS(queue)	\
468	(BWN_SHARED_EDCFQ + (BWN_NR_WMEPARAMS * sizeof(uint16_t) * (queue)))
469#define	BWN_WME_BACKGROUND	BWN_WME_PARAMS(0)
470#define	BWN_WME_BESTEFFORT	BWN_WME_PARAMS(1)
471#define	BWN_WME_VIDEO		BWN_WME_PARAMS(2)
472#define	BWN_WME_VOICE		BWN_WME_PARAMS(3)
473
474/*
475 * Radio capture format.
476 */
477#define	BWN_RX_RADIOTAP_PRESENT (		\
478	(1 << IEEE80211_RADIOTAP_TSFT)		| \
479	(1 << IEEE80211_RADIOTAP_FLAGS)		| \
480	(1 << IEEE80211_RADIOTAP_RATE)		| \
481	(1 << IEEE80211_RADIOTAP_CHANNEL)	| \
482	(1 << IEEE80211_RADIOTAP_ANTENNA)	| \
483	(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL)	| \
484	(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)	| \
485	0)
486
487struct bwn_rx_radiotap_header {
488	struct ieee80211_radiotap_header wr_ihdr;
489	uint64_t			wr_tsf;
490	u_int8_t			wr_flags;
491	u_int8_t			wr_rate;
492	u_int16_t			wr_chan_freq;
493	u_int16_t			wr_chan_flags;
494	int8_t				wr_antsignal;
495	int8_t				wr_antnoise;
496	u_int8_t			wr_antenna;
497};
498
499#define	BWN_TX_RADIOTAP_PRESENT (		\
500	(1 << IEEE80211_RADIOTAP_FLAGS)		| \
501	(1 << IEEE80211_RADIOTAP_RATE)		| \
502	(1 << IEEE80211_RADIOTAP_CHANNEL)	| \
503	(1 << IEEE80211_RADIOTAP_DBM_TX_POWER)	| \
504	(1 << IEEE80211_RADIOTAP_ANTENNA)	| \
505	0)
506
507struct bwn_tx_radiotap_header {
508	struct ieee80211_radiotap_header wt_ihdr;
509	u_int8_t			wt_flags;
510	u_int8_t			wt_rate;
511	u_int16_t			wt_chan_freq;
512	u_int16_t			wt_chan_flags;
513	u_int8_t			wt_txpower;
514	u_int8_t			wt_antenna;
515};
516
517struct bwn_stats {
518	int32_t				rtsfail;
519	int32_t				rts;
520	int32_t				link_noise;
521};
522
523/* Noise Calculation (Link Quality) */
524struct bwn_noise {
525	uint8_t				noi_running;
526	uint8_t				noi_nsamples;
527	int8_t				noi_samples[8][4];
528};
529
530#define	BWN_DMA_30BIT			30
531#define	BWN_DMA_32BIT			32
532#define	BWN_DMA_64BIT			64
533
534struct bwn_dmadesc_meta {
535	bus_dmamap_t			mt_dmap;
536	bus_addr_t			mt_paddr;
537	struct mbuf			*mt_m;
538	struct ieee80211_node		*mt_ni;
539	uint8_t				mt_txtype;
540#define	BWN_DMADESC_METATYPE_HEADER	0
541#define	BWN_DMADESC_METATYPE_BODY	1
542	uint8_t				mt_islast;
543};
544
545#define	BWN_DMAINTR_FATALMASK	\
546	((1 << 10) | (1 << 11) | (1 << 12) | (1 << 14) | (1 << 15))
547#define	BWN_DMAINTR_NONFATALMASK	(1 << 13)
548#define	BWN_DMAINTR_RX_DONE		(1 << 16)
549
550#define	BWN_DMA32_DCTL_BYTECNT		0x00001fff
551#define	BWN_DMA32_DCTL_ADDREXT_MASK	0x00030000
552#define	BWN_DMA32_DCTL_ADDREXT_SHIFT	16
553#define	BWN_DMA32_DCTL_DTABLEEND	0x10000000
554#define	BWN_DMA32_DCTL_IRQ		0x20000000
555#define	BWN_DMA32_DCTL_FRAMEEND		0x40000000
556#define	BWN_DMA32_DCTL_FRAMESTART	0x80000000
557struct bwn_dmadesc32 {
558	uint32_t			control;
559	uint32_t			address;
560} __packed;
561
562#define	BWN_DMA64_DCTL0_DTABLEEND	0x10000000
563#define	BWN_DMA64_DCTL0_IRQ		0x20000000
564#define	BWN_DMA64_DCTL0_FRAMEEND	0x40000000
565#define	BWN_DMA64_DCTL0_FRAMESTART	0x80000000
566#define	BWN_DMA64_DCTL1_BYTECNT		0x00001fff
567#define	BWN_DMA64_DCTL1_ADDREXT_MASK	0x00030000
568#define	BWN_DMA64_DCTL1_ADDREXT_SHIFT	16
569struct bwn_dmadesc64 {
570	uint32_t			control0;
571	uint32_t			control1;
572	uint32_t			address_low;
573	uint32_t			address_high;
574} __packed;
575
576struct bwn_dmadesc_generic {
577	union {
578		struct bwn_dmadesc32 dma32;
579		struct bwn_dmadesc64 dma64;
580	} __packed dma;
581} __packed;
582
583struct bwn_dma_ring;
584
585struct bwn_dma_ring {
586	struct bwn_mac			*dr_mac;
587	const struct bwn_dma_ops	*dr_ops;
588	struct bwn_dmadesc_meta		*dr_meta;
589	void				*dr_txhdr_cache;
590	bus_dma_tag_t			dr_ring_dtag;
591	bus_dma_tag_t			dr_txring_dtag;
592	bus_dmamap_t			dr_spare_dmap; /* only for RX */
593	bus_dmamap_t			dr_ring_dmap;
594	bus_addr_t			dr_txring_paddr;
595	void				*dr_ring_descbase;
596	bus_addr_t			dr_ring_dmabase;
597	int				dr_numslots;
598	int				dr_usedslot;
599	int				dr_curslot;
600	uint32_t			dr_frameoffset;
601	uint16_t			dr_rx_bufsize;
602	uint16_t			dr_base;
603	int				dr_index;
604	uint8_t				dr_tx;
605	uint8_t				dr_stop;
606	int				dr_type;
607
608	void				(*getdesc)(struct bwn_dma_ring *,
609					    int, struct bwn_dmadesc_generic **,
610					    struct bwn_dmadesc_meta **);
611	void				(*setdesc)(struct bwn_dma_ring *,
612					    struct bwn_dmadesc_generic *,
613					    bus_addr_t, uint16_t, int, int,
614					    int);
615	void				(*start_transfer)(struct bwn_dma_ring *,
616					    int);
617	void				(*suspend)(struct bwn_dma_ring *);
618	void				(*resume)(struct bwn_dma_ring *);
619	int				(*get_curslot)(struct bwn_dma_ring *);
620	void				(*set_curslot)(struct bwn_dma_ring *,
621					    int);
622};
623
624struct bwn_dma {
625	int				dmatype;
626	bus_dma_tag_t			parent_dtag;
627	bus_dma_tag_t			rxbuf_dtag;
628	bus_dma_tag_t			txbuf_dtag;
629
630	struct bwn_dma_ring		*wme[5];
631	struct bwn_dma_ring		*mcast;
632	struct bwn_dma_ring		*rx;
633	uint64_t			lastseq;	/* XXX FIXME */
634};
635
636struct bwn_pio_rxqueue {
637	struct bwn_mac			*prq_mac;
638	uint16_t			prq_base;
639	uint8_t				prq_rev;
640};
641
642struct bwn_pio_txqueue;
643struct bwn_pio_txpkt {
644	struct bwn_pio_txqueue		*tp_queue;
645	struct ieee80211_node		*tp_ni;
646	struct mbuf			*tp_m;
647	uint8_t				tp_index;
648	TAILQ_ENTRY(bwn_pio_txpkt)	tp_list;
649};
650
651#define	BWN_PIO_MAX_TXPACKETS		32
652struct bwn_pio_txqueue {
653	uint16_t			tq_base;
654	uint16_t			tq_size;
655	uint16_t			tq_used;
656	uint16_t			tq_free;
657	uint8_t				tq_stop;
658	uint8_t				tq_index;
659	struct bwn_pio_txpkt		tq_pkts[BWN_PIO_MAX_TXPACKETS];
660	TAILQ_HEAD(, bwn_pio_txpkt)	tq_pktlist;
661};
662
663struct bwn_pio {
664	struct bwn_pio_txqueue		wme[5];
665	struct bwn_pio_txqueue		mcast;
666	struct bwn_pio_rxqueue		rx;
667};
668
669struct bwn_plcp4 {
670	union {
671		uint32_t		data;
672		uint8_t			raw[4];
673	} __packed o;
674} __packed;
675
676struct bwn_plcp6 {
677	union {
678		uint32_t		data;
679		uint8_t			raw[6];
680	} __packed o;
681} __packed;
682
683struct bwn_txhdr {
684	uint32_t			macctl;
685	uint8_t				macfc[2];
686	uint16_t			tx_festime;
687	uint16_t			phyctl;
688	uint16_t			phyctl_1;
689	uint16_t			phyctl_1fb;
690	uint16_t			phyctl_1rts;
691	uint16_t			phyctl_1rtsfb;
692	uint8_t				phyrate;
693	uint8_t				phyrate_rts;
694	uint8_t				eftypes;	/* extra frame types */
695	uint8_t				chan;
696	uint8_t				iv[16];
697	uint8_t				addr1[IEEE80211_ADDR_LEN];
698	uint16_t			tx_festime_fb;
699	struct bwn_plcp6		rts_plcp_fb;
700	uint16_t			rts_dur_fb;
701	struct bwn_plcp6		plcp_fb;
702	uint16_t			dur_fb;
703	uint16_t			mimo_modelen;
704	uint16_t			mimo_ratelen_fb;
705	uint32_t			timeout;
706
707	union {
708		/* format <= r351 */
709		struct {
710			uint8_t		pad0[2];
711			uint16_t	cookie;
712			uint16_t	tx_status;
713			struct bwn_plcp6	rts_plcp;
714			uint8_t		rts_frame[16];
715			uint8_t		pad1[2];;
716			struct bwn_plcp6	plcp;
717		} __packed old;
718		/* format > r410 */
719		struct {
720			uint16_t	mimo_antenna;
721			uint16_t	preload_size;
722			uint8_t		pad0[2];
723			uint16_t	cookie;
724			uint16_t	tx_status;
725			struct bwn_plcp6	rts_plcp;
726			uint8_t		rts_frame[16];
727			uint8_t		pad1[2];
728			struct bwn_plcp6	plcp;
729		} __packed new;
730	} __packed body;
731} __packed;
732
733#define	BWN_FWTYPE_UCODE		'u'
734#define	BWN_FWTYPE_PCM			'p'
735#define	BWN_FWTYPE_IV			'i'
736struct bwn_fwhdr {
737	uint8_t				type;
738	uint8_t				ver;
739	uint8_t				pad[2];
740	uint32_t			size;
741} __packed;
742
743#define	BWN_FWINITVALS_OFFSET_MASK	0x7fff
744#define	BWN_FWINITVALS_32BIT		0x8000
745struct bwn_fwinitvals {
746	uint16_t			offset_size;
747	union {
748		uint16_t		d16;
749		uint32_t		d32;
750	} __packed data;
751} __packed;
752
753enum bwn_fwtype {
754	BWN_FWTYPE_DEFAULT,
755	BWN_FWTYPE_OPENSOURCE,
756	BWN_NR_FWTYPES,
757};
758
759struct bwn_fwfile {
760	const char			*filename;
761	const struct firmware		*fw;
762	enum bwn_fwtype			type;
763};
764
765struct bwn_key {
766	void				*keyconf;
767	uint8_t				algorithm;
768};
769
770struct bwn_fw {
771	struct bwn_fwfile		ucode;
772	struct bwn_fwfile		pcm;
773	struct bwn_fwfile		initvals;
774	struct bwn_fwfile		initvals_band;
775
776	uint16_t			rev;
777	uint16_t			patch;
778	uint8_t				opensource;
779	uint8_t				no_pcmfile;
780};
781
782struct bwn_lo_g_sm {
783	int				curstate;
784	int				nmeasure;
785	int				multipler;
786	uint16_t			feedth;
787	struct bwn_loctl		loctl;
788};
789
790struct bwn_lo_g_value {
791	uint8_t				old_channel;
792	uint16_t			phy_lomask;
793	uint16_t			phy_extg;
794	uint16_t			phy_dacctl_hwpctl;
795	uint16_t			phy_dacctl;
796	uint16_t			phy_hpwr_tssictl;
797	uint16_t			phy_analogover;
798	uint16_t			phy_analogoverval;
799	uint16_t			phy_rfover;
800	uint16_t			phy_rfoverval;
801	uint16_t			phy_classctl;
802	uint16_t			phy_crs0;
803	uint16_t			phy_pgactl;
804	uint16_t			phy_syncctl;
805	uint16_t			phy_cck0;
806	uint16_t			phy_cck1;
807	uint16_t			phy_cck2;
808	uint16_t			phy_cck3;
809	uint16_t			phy_cck4;
810	uint16_t			reg0;
811	uint16_t			reg1;
812	uint16_t			rf0;
813	uint16_t			rf1;
814	uint16_t			rf2;
815};
816
817#define	BWN_LED_MAX			4
818
819#define	BWN_LED_EVENT_NONE		-1
820#define	BWN_LED_EVENT_POLL		0
821#define	BWN_LED_EVENT_TX		1
822#define	BWN_LED_EVENT_RX		2
823#define	BWN_LED_SLOWDOWN(dur)		(dur) = (((dur) * 3) / 2)
824
825struct bwn_led {
826	uint8_t				led_flags;	/* BWN_LED_F_ */
827	uint8_t				led_act;	/* BWN_LED_ACT_ */
828	uint8_t				led_mask;
829};
830
831#define	BWN_LED_F_ACTLOW		0x1
832#define	BWN_LED_F_BLINK			0x2
833#define	BWN_LED_F_POLLABLE		0x4
834#define	BWN_LED_F_SLOW			0x8
835
836struct bwn_mac {
837	struct bwn_softc		*mac_sc;
838	struct siba_dev_softc		*mac_sd;
839	unsigned			mac_status;
840#define	BWN_MAC_STATUS_UNINIT		0
841#define	BWN_MAC_STATUS_INITED		1
842#define	BWN_MAC_STATUS_STARTED		2
843	unsigned			mac_flags;
844	/* use "Bad Frames Preemption" */
845#define	BWN_MAC_FLAG_BADFRAME_PREEMP	(1 << 0)
846#define	BWN_MAC_FLAG_DFQVALID		(1 << 1)
847#define	BWN_MAC_FLAG_RADIO_ON		(1 << 2)
848#define	BWN_MAC_FLAG_DMA		(1 << 3)
849#define	BWN_MAC_FLAG_WME		(1 << 4)
850#define	BWN_MAC_FLAG_HWCRYPTO		(1 << 5)
851
852	struct resource_spec		*mac_intr_spec;
853#define	BWN_MSI_MESSAGES		1
854	struct resource			*mac_res_irq[BWN_MSI_MESSAGES];
855	void				*mac_intrhand[BWN_MSI_MESSAGES];
856	int				mac_msi;
857
858	struct bwn_noise		mac_noise;
859	struct bwn_phy			mac_phy;
860	struct bwn_stats		mac_stats;
861	uint32_t			mac_reason_intr;
862	uint32_t			mac_reason[6];
863	uint32_t			mac_intr_mask;
864	int				mac_suspended;
865
866	struct bwn_fw			mac_fw;
867
868	union {
869		struct bwn_dma		dma;
870		struct bwn_pio		pio;
871	} mac_method;
872
873	uint16_t			mac_ktp;	/* Key table pointer */
874	uint8_t				mac_max_nr_keys;
875	struct bwn_key			mac_key[58];
876
877	unsigned int			mac_task_state;
878	struct task			mac_intrtask;
879	struct task			mac_hwreset;
880	struct task			mac_txpower;
881
882	TAILQ_ENTRY(bwn_mac)	mac_list;
883};
884
885struct bwn_node {
886	struct ieee80211_node		bn_node;	/* must be the first */
887	struct ieee80211_amrr_node	bn_amn;
888};
889#define	BWN_NODE(ni)			((struct bwn_node *)(ni))
890
891/*
892 * Driver-specific vap state.
893 */
894struct bwn_vap {
895	struct ieee80211vap		bv_vap;	/* base class */
896	struct ieee80211_amrr		bv_amrr;
897	int				(*bv_newstate)(struct ieee80211vap *,
898					    enum ieee80211_state, int);
899};
900#define	BWN_VAP(vap)			((struct bwn_vap *)(vap))
901#define	BWN_VAP_CONST(vap)		((const struct mwl_vap *)(vap))
902
903struct bwn_softc {
904	device_t			sc_dev;
905	struct siba_dev_softc		*sc_sd;
906	struct mtx			sc_mtx;
907	struct ifnet			*sc_ifp;
908	unsigned			sc_flags;
909#define	BWN_FLAG_ATTACHED		(1 << 0)
910#define	BWN_FLAG_INVALID		(1 << 1)
911#define	BWN_FLAG_NEED_BEACON_TP		(1 << 2)
912	unsigned			sc_debug;
913
914	struct bwn_mac		*sc_curmac;
915	TAILQ_HEAD(, bwn_mac)	sc_maclist;
916
917	uint8_t				sc_macaddr[IEEE80211_ADDR_LEN];
918	uint8_t				sc_bssid[IEEE80211_ADDR_LEN];
919	unsigned int			sc_filters;
920	uint8_t				sc_beacons[2];
921	uint8_t				sc_rf_enabled;
922
923	struct wmeParams		sc_wmeParams[4];
924
925	struct callout			sc_rfswitch_ch;	/* for laptop */
926	struct callout			sc_task_ch;
927	struct callout			sc_watchdog_ch;
928	int				sc_watchdog_timer;
929	struct taskqueue		*sc_tq;	/* private task queue */
930	int				(*sc_newstate)(struct ieee80211com *,
931					    enum ieee80211_state, int);
932	void				(*sc_node_cleanup)(
933					    struct ieee80211_node *);
934
935	int				sc_rx_rate;
936	int				sc_tx_rate;
937
938	int				sc_led_blinking;
939	int				sc_led_ticks;
940	struct bwn_led			*sc_blink_led;
941	struct callout			sc_led_blink_ch;
942	int				sc_led_blink_offdur;
943	struct bwn_led			sc_leds[BWN_LED_MAX];
944	int				sc_led_idle;
945	int				sc_led_blink;
946
947	struct bwn_tx_radiotap_header	sc_tx_th;
948	struct bwn_rx_radiotap_header	sc_rx_th;
949};
950
951#define	BWN_LOCK_INIT(sc) \
952	mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->sc_dev), \
953	    MTX_NETWORK_LOCK, MTX_DEF)
954#define	BWN_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->sc_mtx)
955#define	BWN_LOCK(sc)		mtx_lock(&(sc)->sc_mtx)
956#define	BWN_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
957#define	BWN_ASSERT_LOCKED(sc)	mtx_assert(&(sc)->sc_mtx, MA_OWNED)
958
959#endif	/* !_IF_BWNVAR_H */
960