1178676Ssam/*	$FreeBSD$	*/
2210111Sbschmidt/*	$OpenBSD: if_iwnvar.h,v 1.18 2010/04/30 16:06:46 damien Exp $	*/
3198429Srpaulo
4178676Ssam/*-
5198429Srpaulo * Copyright (c) 2007, 2008
6178676Ssam *	Damien Bergamini <damien.bergamini@free.fr>
7178676Ssam * Copyright (c) 2008 Sam Leffler, Errno Consulting
8178676Ssam *
9178676Ssam * Permission to use, copy, modify, and distribute this software for any
10178676Ssam * purpose with or without fee is hereby granted, provided that the above
11178676Ssam * copyright notice and this permission notice appear in all copies.
12178676Ssam *
13178676Ssam * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14178676Ssam * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15178676Ssam * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16178676Ssam * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17178676Ssam * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18178676Ssam * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19178676Ssam * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20178676Ssam */
21178676Ssam
22178676Ssamstruct iwn_rx_radiotap_header {
23178676Ssam	struct ieee80211_radiotap_header wr_ihdr;
24178676Ssam	uint64_t	wr_tsft;
25178676Ssam	uint8_t		wr_flags;
26178676Ssam	uint8_t		wr_rate;
27178676Ssam	uint16_t	wr_chan_freq;
28178676Ssam	uint16_t	wr_chan_flags;
29178676Ssam	int8_t		wr_dbm_antsignal;
30178676Ssam	int8_t		wr_dbm_antnoise;
31178676Ssam} __packed;
32178676Ssam
33178676Ssam#define IWN_RX_RADIOTAP_PRESENT						\
34178676Ssam	((1 << IEEE80211_RADIOTAP_TSFT) |				\
35178676Ssam	 (1 << IEEE80211_RADIOTAP_FLAGS) |				\
36178676Ssam	 (1 << IEEE80211_RADIOTAP_RATE) |				\
37178676Ssam	 (1 << IEEE80211_RADIOTAP_CHANNEL) |				\
38178676Ssam	 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |			\
39178676Ssam	 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE))
40178676Ssam
41178676Ssamstruct iwn_tx_radiotap_header {
42178676Ssam	struct ieee80211_radiotap_header wt_ihdr;
43178676Ssam	uint8_t		wt_flags;
44178676Ssam	uint8_t		wt_rate;
45178676Ssam	uint16_t	wt_chan_freq;
46178676Ssam	uint16_t	wt_chan_flags;
47178676Ssam} __packed;
48178676Ssam
49178676Ssam#define IWN_TX_RADIOTAP_PRESENT						\
50178676Ssam	((1 << IEEE80211_RADIOTAP_FLAGS) |				\
51178676Ssam	 (1 << IEEE80211_RADIOTAP_RATE) |				\
52178676Ssam	 (1 << IEEE80211_RADIOTAP_CHANNEL))
53178676Ssam
54178676Ssamstruct iwn_dma_info {
55178676Ssam	bus_dma_tag_t		tag;
56178676Ssam	bus_dmamap_t		map;
57178676Ssam	bus_dma_segment_t	seg;
58178676Ssam	bus_addr_t		paddr;
59178676Ssam	caddr_t			vaddr;
60178676Ssam	bus_size_t		size;
61178676Ssam};
62178676Ssam
63178676Ssamstruct iwn_tx_data {
64178676Ssam	bus_dmamap_t		map;
65198429Srpaulo	bus_addr_t		cmd_paddr;
66198429Srpaulo	bus_addr_t		scratch_paddr;
67178676Ssam	struct mbuf		*m;
68178676Ssam	struct ieee80211_node	*ni;
69178676Ssam};
70178676Ssam
71178676Ssamstruct iwn_tx_ring {
72178676Ssam	struct iwn_dma_info	desc_dma;
73178676Ssam	struct iwn_dma_info	cmd_dma;
74178676Ssam	struct iwn_tx_desc	*desc;
75178676Ssam	struct iwn_tx_cmd	*cmd;
76178676Ssam	struct iwn_tx_data	data[IWN_TX_RING_COUNT];
77201209Srpaulo	bus_dma_tag_t		data_dmat;
78178676Ssam	int			qid;
79178676Ssam	int			queued;
80178676Ssam	int			cur;
81221651Sbschmidt	int			read;
82178676Ssam};
83178676Ssam
84198429Srpaulostruct iwn_softc;
85198429Srpaulo
86178676Ssamstruct iwn_rx_data {
87198429Srpaulo	struct mbuf	*m;
88198429Srpaulo	bus_dmamap_t	map;
89178676Ssam};
90178676Ssam
91178676Ssamstruct iwn_rx_ring {
92178676Ssam	struct iwn_dma_info	desc_dma;
93198429Srpaulo	struct iwn_dma_info	stat_dma;
94178676Ssam	uint32_t		*desc;
95198429Srpaulo	struct iwn_rx_status	*stat;
96178676Ssam	struct iwn_rx_data	data[IWN_RX_RING_COUNT];
97201209Srpaulo	bus_dma_tag_t		data_dmat;
98178676Ssam	int			cur;
99178676Ssam};
100178676Ssam
101178676Ssamstruct iwn_node {
102178676Ssam	struct	ieee80211_node		ni;	/* must be the first */
103198429Srpaulo	uint16_t			disable_tid;
104198429Srpaulo	uint8_t				id;
105221648Sbschmidt	uint32_t			ridx[256];
106221651Sbschmidt	struct {
107221651Sbschmidt		uint64_t		bitmap;
108221651Sbschmidt		int			startidx;
109221651Sbschmidt		int			nframes;
110221651Sbschmidt	} agg[IEEE80211_TID_SIZE];
111178676Ssam};
112178676Ssam
113178676Ssamstruct iwn_calib_state {
114178676Ssam	uint8_t		state;
115178676Ssam#define IWN_CALIB_STATE_INIT	0
116178676Ssam#define IWN_CALIB_STATE_ASSOC	1
117178676Ssam#define IWN_CALIB_STATE_RUN	2
118198429Srpaulo
119178676Ssam	u_int		nbeacons;
120178676Ssam	uint32_t	noise[3];
121178676Ssam	uint32_t	rssi[3];
122198429Srpaulo	uint32_t	ofdm_x1;
123198429Srpaulo	uint32_t	ofdm_mrc_x1;
124198429Srpaulo	uint32_t	ofdm_x4;
125198429Srpaulo	uint32_t	ofdm_mrc_x4;
126198429Srpaulo	uint32_t	cck_x4;
127198429Srpaulo	uint32_t	cck_mrc_x4;
128178676Ssam	uint32_t	bad_plcp_ofdm;
129178676Ssam	uint32_t	fa_ofdm;
130178676Ssam	uint32_t	bad_plcp_cck;
131178676Ssam	uint32_t	fa_cck;
132178676Ssam	uint32_t	low_fa;
133178676Ssam	uint8_t		cck_state;
134178676Ssam#define IWN_CCK_STATE_INIT	0
135178676Ssam#define IWN_CCK_STATE_LOFA	1
136178676Ssam#define IWN_CCK_STATE_HIFA	2
137198429Srpaulo
138178676Ssam	uint8_t		noise_samples[20];
139178676Ssam	u_int		cur_noise_sample;
140178676Ssam	uint8_t		noise_ref;
141178676Ssam	uint32_t	energy_samples[10];
142178676Ssam	u_int		cur_energy_sample;
143178676Ssam	uint32_t	energy_cck;
144178676Ssam};
145178676Ssam
146198429Srpaulostruct iwn_calib_info {
147198429Srpaulo	uint8_t		*buf;
148198429Srpaulo	u_int		len;
149198429Srpaulo};
150198429Srpaulo
151198429Srpaulostruct iwn_fw_part {
152198429Srpaulo	const uint8_t	*text;
153198429Srpaulo	uint32_t	textsz;
154198429Srpaulo	const uint8_t	*data;
155198429Srpaulo	uint32_t	datasz;
156198429Srpaulo};
157198429Srpaulo
158198429Srpaulostruct iwn_fw_info {
159210111Sbschmidt	const uint8_t		*data;
160210111Sbschmidt	size_t			size;
161198429Srpaulo	struct iwn_fw_part	init;
162198429Srpaulo	struct iwn_fw_part	main;
163198429Srpaulo	struct iwn_fw_part	boot;
164198429Srpaulo};
165198429Srpaulo
166220728Sbschmidtstruct iwn_ops {
167198429Srpaulo	int		(*load_firmware)(struct iwn_softc *);
168198429Srpaulo	void		(*read_eeprom)(struct iwn_softc *);
169198429Srpaulo	int		(*post_alive)(struct iwn_softc *);
170198429Srpaulo	int		(*nic_config)(struct iwn_softc *);
171198429Srpaulo	void		(*update_sched)(struct iwn_softc *, int, int, uint8_t,
172198429Srpaulo			    uint16_t);
173198429Srpaulo	int		(*get_temperature)(struct iwn_softc *);
174198429Srpaulo	int		(*get_rssi)(struct iwn_softc *, struct iwn_rx_stat *);
175201882Skeramida	int		(*set_txpower)(struct iwn_softc *,
176201882Skeramida			    struct ieee80211_channel *, int);
177198429Srpaulo	int		(*init_gains)(struct iwn_softc *);
178198429Srpaulo	int		(*set_gains)(struct iwn_softc *);
179198429Srpaulo	int		(*add_node)(struct iwn_softc *, struct iwn_node_info *,
180198429Srpaulo			    int);
181198429Srpaulo	void		(*tx_done)(struct iwn_softc *, struct iwn_rx_desc *,
182198429Srpaulo			    struct iwn_rx_data *);
183201209Srpaulo	void		(*ampdu_tx_start)(struct iwn_softc *,
184221651Sbschmidt			    struct ieee80211_node *, int, uint8_t, uint16_t);
185221651Sbschmidt	void		(*ampdu_tx_stop)(struct iwn_softc *, int, uint8_t,
186201209Srpaulo			    uint16_t);
187198429Srpaulo};
188198429Srpaulo
189178676Ssamstruct iwn_vap {
190178676Ssam	struct ieee80211vap	iv_vap;
191198429Srpaulo	uint8_t			iv_ridx;
192178676Ssam
193178676Ssam	int			(*iv_newstate)(struct ieee80211vap *,
194178676Ssam				    enum ieee80211_state, int);
195178676Ssam};
196178676Ssam#define	IWN_VAP(_vap)	((struct iwn_vap *)(_vap))
197178676Ssam
198178676Ssamstruct iwn_softc {
199220726Sbschmidt	device_t		sc_dev;
200220723Sbschmidt
201178676Ssam	struct ifnet		*sc_ifp;
202178676Ssam	int			sc_debug;
203178676Ssam
204178676Ssam	struct mtx		sc_mtx;
205178676Ssam
206198429Srpaulo	u_int			sc_flags;
207198429Srpaulo#define IWN_FLAG_HAS_OTPROM	(1 << 1)
208201209Srpaulo#define IWN_FLAG_CALIB_DONE	(1 << 2)
209201209Srpaulo#define IWN_FLAG_USE_ICT	(1 << 3)
210201209Srpaulo#define IWN_FLAG_INTERNAL_PA	(1 << 4)
211220729Sbschmidt#define IWN_FLAG_HAS_11N	(1 << 6)
212220729Sbschmidt#define IWN_FLAG_ENH_SENS	(1 << 7)
213220891Sbschmidt#define IWN_FLAG_ADV_BTCOEX	(1 << 8)
214178676Ssam
215198429Srpaulo	uint8_t 		hw_type;
216220728Sbschmidt
217220728Sbschmidt	struct iwn_ops		ops;
218198429Srpaulo	const char		*fwname;
219201209Srpaulo	const struct iwn_sensitivity_limits
220201209Srpaulo				*limits;
221220728Sbschmidt	int			ntxqs;
222221651Sbschmidt	int			firstaggqueue;
223220728Sbschmidt	int			ndmachnls;
224220728Sbschmidt	uint8_t			broadcast_id;
225220728Sbschmidt	int			rxonsz;
226220728Sbschmidt	int			schedsz;
227220728Sbschmidt	uint32_t		fw_text_maxsz;
228220728Sbschmidt	uint32_t		fw_data_maxsz;
229220728Sbschmidt	uint32_t		fwsz;
230220728Sbschmidt	bus_size_t		sched_txfact_addr;
231220866Sbschmidt	uint32_t		reset_noise_gain;
232220866Sbschmidt	uint32_t		noise_gain;
233198429Srpaulo
234198429Srpaulo	/* TX scheduler rings. */
235198429Srpaulo	struct iwn_dma_info	sched_dma;
236198429Srpaulo	uint16_t		*sched;
237198429Srpaulo	uint32_t		sched_base;
238198429Srpaulo
239198429Srpaulo	/* "Keep Warm" page. */
240178676Ssam	struct iwn_dma_info	kw_dma;
241178676Ssam
242198429Srpaulo	/* Firmware image. */
243178676Ssam	const struct firmware	*fw_fp;
244178676Ssam
245198429Srpaulo	/* Firmware DMA transfer. */
246178676Ssam	struct iwn_dma_info	fw_dma;
247178676Ssam
248201209Srpaulo	/* ICT table. */
249201209Srpaulo	struct iwn_dma_info	ict_dma;
250201209Srpaulo	uint32_t		*ict;
251201209Srpaulo	int			ict_cur;
252201209Srpaulo
253198429Srpaulo	/* TX/RX rings. */
254198429Srpaulo	struct iwn_tx_ring	txq[IWN5000_NTXQUEUES];
255178676Ssam	struct iwn_rx_ring	rxq;
256178676Ssam
257220726Sbschmidt	struct resource		*mem;
258178676Ssam	bus_space_tag_t		sc_st;
259178676Ssam	bus_space_handle_t	sc_sh;
260220723Sbschmidt	struct resource		*irq;
261178676Ssam	void 			*sc_ih;
262178676Ssam	bus_size_t		sc_sz;
263198429Srpaulo	int			sc_cap_off;	/* PCIe Capabilities. */
264178676Ssam
265178676Ssam	/* Tasks used by the driver */
266220726Sbschmidt	struct task		sc_reinit_task;
267191746Sthompsa	struct task		sc_radioon_task;
268191746Sthompsa	struct task		sc_radiooff_task;
269201209Srpaulo
270220667Sbschmidt	struct callout		calib_to;
271178676Ssam	int			calib_cnt;
272178676Ssam	struct iwn_calib_state	calib;
273220667Sbschmidt	struct callout		watchdog_to;
274178676Ssam
275198429Srpaulo	struct iwn_fw_info	fw;
276220674Sbschmidt	struct iwn_calib_info	calibcmd[5];
277198429Srpaulo	uint32_t		errptr;
278198429Srpaulo
279178676Ssam	struct iwn_rx_stat	last_rx_stat;
280178676Ssam	int			last_rx_valid;
281178676Ssam	struct iwn_ucode_info	ucode_info;
282198429Srpaulo	struct iwn_rxon		rxon;
283178676Ssam	uint32_t		rawtemp;
284178676Ssam	int			temp;
285178676Ssam	int			noise;
286198429Srpaulo	uint32_t		qfullmsk;
287178676Ssam
288201209Srpaulo	uint32_t		prom_base;
289198429Srpaulo	struct iwn4965_eeprom_band
290198429Srpaulo				bands[IWN_NBANDS];
291201209Srpaulo	struct iwn_eeprom_chan	eeprom_channels[IWN_NBANDS][IWN_MAX_CHAN_PER_BAND];
292198429Srpaulo	uint16_t		rfcfg;
293206444Sbschmidt	uint8_t			calib_ver;
294198429Srpaulo	char			eeprom_domain[4];
295220674Sbschmidt	uint32_t		eeprom_crystal;
296220674Sbschmidt	int16_t			eeprom_temp;
297178676Ssam	int16_t			eeprom_voltage;
298178676Ssam	int8_t			maxpwr2GHz;
299178676Ssam	int8_t			maxpwr5GHz;
300198429Srpaulo	int8_t			maxpwr[IEEE80211_CHAN_MAX];
301198429Srpaulo
302201209Srpaulo	int32_t			temp_off;
303201209Srpaulo	uint32_t		int_mask;
304198429Srpaulo	uint8_t			ntxchains;
305198429Srpaulo	uint8_t			nrxchains;
306201209Srpaulo	uint8_t			txchainmask;
307201209Srpaulo	uint8_t			rxchainmask;
308201209Srpaulo	uint8_t			chainmask;
309198429Srpaulo
310198429Srpaulo	int			sc_tx_timer;
311198429Srpaulo
312221651Sbschmidt	struct ieee80211_tx_ampdu *qid2tap[IWN5000_NTXQUEUES];
313221651Sbschmidt
314221650Sbschmidt	int			(*sc_ampdu_rx_start)(struct ieee80211_node *,
315221650Sbschmidt				    struct ieee80211_rx_ampdu *, int, int, int);
316221650Sbschmidt	void			(*sc_ampdu_rx_stop)(struct ieee80211_node *,
317221650Sbschmidt				    struct ieee80211_rx_ampdu *);
318221651Sbschmidt	int			(*sc_addba_request)(struct ieee80211_node *,
319221651Sbschmidt				    struct ieee80211_tx_ampdu *, int, int, int);
320221651Sbschmidt	int			(*sc_addba_response)(struct ieee80211_node *,
321221651Sbschmidt				    struct ieee80211_tx_ampdu *, int, int, int);
322221651Sbschmidt	void			(*sc_addba_stop)(struct ieee80211_node *,
323221651Sbschmidt				    struct ieee80211_tx_ampdu *);
324221650Sbschmidt
325221651Sbschmidt
326198429Srpaulo	struct iwn_rx_radiotap_header sc_rxtap;
327198429Srpaulo	struct iwn_tx_radiotap_header sc_txtap;
328178676Ssam};
329178676Ssam
330178676Ssam#define IWN_LOCK_INIT(_sc) \
331178676Ssam	mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
332210108Sbschmidt	    MTX_NETWORK_LOCK, MTX_DEF)
333178676Ssam#define IWN_LOCK(_sc)			mtx_lock(&(_sc)->sc_mtx)
334178676Ssam#define IWN_LOCK_ASSERT(_sc)		mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
335178676Ssam#define IWN_UNLOCK(_sc)			mtx_unlock(&(_sc)->sc_mtx)
336178676Ssam#define IWN_LOCK_DESTROY(_sc)		mtx_destroy(&(_sc)->sc_mtx)
337