if_iwnvar.h revision 284588
1178676Ssam/*	$FreeBSD: head/sys/dev/iwn/if_iwnvar.h 284588 2015-06-19 01:44:17Z adrian $	*/
2210111Sbschmidt/*	$OpenBSD: if_iwnvar.h,v 1.18 2010/04/30 16:06:46 damien Exp $	*/
3198429Srpaulo
4178676Ssam/*-
5254204Sadrian * Copyright (c) 2013 Cedric GROSS <cg@cgross.info>
6254204Sadrian * Copyright (c) 2011 Intel Corporation
7198429Srpaulo * Copyright (c) 2007, 2008
8178676Ssam *	Damien Bergamini <damien.bergamini@free.fr>
9178676Ssam * Copyright (c) 2008 Sam Leffler, Errno Consulting
10178676Ssam *
11178676Ssam * Permission to use, copy, modify, and distribute this software for any
12178676Ssam * purpose with or without fee is hereby granted, provided that the above
13178676Ssam * copyright notice and this permission notice appear in all copies.
14178676Ssam *
15178676Ssam * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
16178676Ssam * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17178676Ssam * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
18178676Ssam * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19178676Ssam * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20178676Ssam * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
21178676Ssam * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22178676Ssam */
23254204Sadrianenum iwn_rxon_ctx_id {
24254204Sadrian		IWN_RXON_BSS_CTX,
25254204Sadrian		IWN_RXON_PAN_CTX,
26254204Sadrian		IWN_NUM_RXON_CTX
27254204Sadrian};
28178676Ssam
29254204Sadrianstruct iwn_pan_slot {
30254204Sadrian	uint16_t	time;
31254204Sadrian	uint8_t		type;
32254204Sadrian	uint8_t		reserved;
33254204Sadrian} __packed;
34254204Sadrian
35254204Sadrianstruct iwn_pan_params_cmd {
36254204Sadrian	uint16_t flags;
37254204Sadrian#define	IWN_PAN_PARAMS_FLG_SLOTTED_MODE	(1 << 3)
38254204Sadrian
39254204Sadrian	uint8_t reserved;
40254204Sadrian	uint8_t num_slots;
41254204Sadrian	struct iwn_pan_slot slots[10];
42254204Sadrian} __packed;
43254204Sadrian
44254204Sadrianstruct iwn_led_mode
45254204Sadrian{
46254204Sadrian	uint8_t		led_cur_mode;
47254204Sadrian	uint64_t	led_cur_bt;
48254204Sadrian	uint64_t	led_last_bt;
49254204Sadrian	uint64_t	led_cur_tpt;
50254204Sadrian	uint64_t	led_last_tpt;
51254204Sadrian	uint64_t	led_bt_diff;
52254204Sadrian	int		led_cur_time;
53254204Sadrian	int		led_last_time;
54254204Sadrian};
55254204Sadrian
56178676Ssamstruct iwn_rx_radiotap_header {
57178676Ssam	struct ieee80211_radiotap_header wr_ihdr;
58178676Ssam	uint64_t	wr_tsft;
59178676Ssam	uint8_t		wr_flags;
60178676Ssam	uint8_t		wr_rate;
61178676Ssam	uint16_t	wr_chan_freq;
62178676Ssam	uint16_t	wr_chan_flags;
63178676Ssam	int8_t		wr_dbm_antsignal;
64178676Ssam	int8_t		wr_dbm_antnoise;
65178676Ssam} __packed;
66178676Ssam
67178676Ssam#define IWN_RX_RADIOTAP_PRESENT						\
68178676Ssam	((1 << IEEE80211_RADIOTAP_TSFT) |				\
69178676Ssam	 (1 << IEEE80211_RADIOTAP_FLAGS) |				\
70178676Ssam	 (1 << IEEE80211_RADIOTAP_RATE) |				\
71178676Ssam	 (1 << IEEE80211_RADIOTAP_CHANNEL) |				\
72178676Ssam	 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |			\
73178676Ssam	 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE))
74178676Ssam
75178676Ssamstruct iwn_tx_radiotap_header {
76178676Ssam	struct ieee80211_radiotap_header wt_ihdr;
77178676Ssam	uint8_t		wt_flags;
78178676Ssam	uint8_t		wt_rate;
79178676Ssam	uint16_t	wt_chan_freq;
80178676Ssam	uint16_t	wt_chan_flags;
81178676Ssam} __packed;
82178676Ssam
83178676Ssam#define IWN_TX_RADIOTAP_PRESENT						\
84178676Ssam	((1 << IEEE80211_RADIOTAP_FLAGS) |				\
85178676Ssam	 (1 << IEEE80211_RADIOTAP_RATE) |				\
86178676Ssam	 (1 << IEEE80211_RADIOTAP_CHANNEL))
87178676Ssam
88178676Ssamstruct iwn_dma_info {
89178676Ssam	bus_dma_tag_t		tag;
90178676Ssam	bus_dmamap_t		map;
91178676Ssam	bus_dma_segment_t	seg;
92178676Ssam	bus_addr_t		paddr;
93178676Ssam	caddr_t			vaddr;
94178676Ssam	bus_size_t		size;
95178676Ssam};
96178676Ssam
97178676Ssamstruct iwn_tx_data {
98178676Ssam	bus_dmamap_t		map;
99198429Srpaulo	bus_addr_t		cmd_paddr;
100198429Srpaulo	bus_addr_t		scratch_paddr;
101178676Ssam	struct mbuf		*m;
102178676Ssam	struct ieee80211_node	*ni;
103178676Ssam};
104178676Ssam
105178676Ssamstruct iwn_tx_ring {
106178676Ssam	struct iwn_dma_info	desc_dma;
107178676Ssam	struct iwn_dma_info	cmd_dma;
108178676Ssam	struct iwn_tx_desc	*desc;
109178676Ssam	struct iwn_tx_cmd	*cmd;
110178676Ssam	struct iwn_tx_data	data[IWN_TX_RING_COUNT];
111201209Srpaulo	bus_dma_tag_t		data_dmat;
112178676Ssam	int			qid;
113178676Ssam	int			queued;
114178676Ssam	int			cur;
115221651Sbschmidt	int			read;
116178676Ssam};
117178676Ssam
118198429Srpaulostruct iwn_softc;
119198429Srpaulo
120178676Ssamstruct iwn_rx_data {
121198429Srpaulo	struct mbuf	*m;
122198429Srpaulo	bus_dmamap_t	map;
123178676Ssam};
124178676Ssam
125178676Ssamstruct iwn_rx_ring {
126178676Ssam	struct iwn_dma_info	desc_dma;
127198429Srpaulo	struct iwn_dma_info	stat_dma;
128178676Ssam	uint32_t		*desc;
129198429Srpaulo	struct iwn_rx_status	*stat;
130178676Ssam	struct iwn_rx_data	data[IWN_RX_RING_COUNT];
131201209Srpaulo	bus_dma_tag_t		data_dmat;
132178676Ssam	int			cur;
133178676Ssam};
134178676Ssam
135178676Ssamstruct iwn_node {
136178676Ssam	struct	ieee80211_node		ni;	/* must be the first */
137198429Srpaulo	uint16_t			disable_tid;
138198429Srpaulo	uint8_t				id;
139221651Sbschmidt	struct {
140221651Sbschmidt		uint64_t		bitmap;
141221651Sbschmidt		int			startidx;
142221651Sbschmidt		int			nframes;
143221651Sbschmidt	} agg[IEEE80211_TID_SIZE];
144178676Ssam};
145178676Ssam
146178676Ssamstruct iwn_calib_state {
147178676Ssam	uint8_t		state;
148178676Ssam#define IWN_CALIB_STATE_INIT	0
149178676Ssam#define IWN_CALIB_STATE_ASSOC	1
150178676Ssam#define IWN_CALIB_STATE_RUN	2
151198429Srpaulo
152178676Ssam	u_int		nbeacons;
153178676Ssam	uint32_t	noise[3];
154178676Ssam	uint32_t	rssi[3];
155198429Srpaulo	uint32_t	ofdm_x1;
156198429Srpaulo	uint32_t	ofdm_mrc_x1;
157198429Srpaulo	uint32_t	ofdm_x4;
158198429Srpaulo	uint32_t	ofdm_mrc_x4;
159198429Srpaulo	uint32_t	cck_x4;
160198429Srpaulo	uint32_t	cck_mrc_x4;
161178676Ssam	uint32_t	bad_plcp_ofdm;
162178676Ssam	uint32_t	fa_ofdm;
163178676Ssam	uint32_t	bad_plcp_cck;
164178676Ssam	uint32_t	fa_cck;
165178676Ssam	uint32_t	low_fa;
166259061Sadrian	uint32_t	bad_plcp_ht;
167178676Ssam	uint8_t		cck_state;
168178676Ssam#define IWN_CCK_STATE_INIT	0
169178676Ssam#define IWN_CCK_STATE_LOFA	1
170178676Ssam#define IWN_CCK_STATE_HIFA	2
171198429Srpaulo
172178676Ssam	uint8_t		noise_samples[20];
173178676Ssam	u_int		cur_noise_sample;
174178676Ssam	uint8_t		noise_ref;
175178676Ssam	uint32_t	energy_samples[10];
176178676Ssam	u_int		cur_energy_sample;
177178676Ssam	uint32_t	energy_cck;
178178676Ssam};
179178676Ssam
180198429Srpaulostruct iwn_calib_info {
181198429Srpaulo	uint8_t		*buf;
182198429Srpaulo	u_int		len;
183198429Srpaulo};
184198429Srpaulo
185198429Srpaulostruct iwn_fw_part {
186198429Srpaulo	const uint8_t	*text;
187198429Srpaulo	uint32_t	textsz;
188198429Srpaulo	const uint8_t	*data;
189198429Srpaulo	uint32_t	datasz;
190198429Srpaulo};
191198429Srpaulo
192198429Srpaulostruct iwn_fw_info {
193210111Sbschmidt	const uint8_t		*data;
194210111Sbschmidt	size_t			size;
195198429Srpaulo	struct iwn_fw_part	init;
196198429Srpaulo	struct iwn_fw_part	main;
197198429Srpaulo	struct iwn_fw_part	boot;
198198429Srpaulo};
199198429Srpaulo
200220728Sbschmidtstruct iwn_ops {
201198429Srpaulo	int		(*load_firmware)(struct iwn_softc *);
202198429Srpaulo	void		(*read_eeprom)(struct iwn_softc *);
203198429Srpaulo	int		(*post_alive)(struct iwn_softc *);
204198429Srpaulo	int		(*nic_config)(struct iwn_softc *);
205198429Srpaulo	void		(*update_sched)(struct iwn_softc *, int, int, uint8_t,
206198429Srpaulo			    uint16_t);
207198429Srpaulo	int		(*get_temperature)(struct iwn_softc *);
208198429Srpaulo	int		(*get_rssi)(struct iwn_softc *, struct iwn_rx_stat *);
209201882Skeramida	int		(*set_txpower)(struct iwn_softc *,
210201882Skeramida			    struct ieee80211_channel *, int);
211198429Srpaulo	int		(*init_gains)(struct iwn_softc *);
212198429Srpaulo	int		(*set_gains)(struct iwn_softc *);
213198429Srpaulo	int		(*add_node)(struct iwn_softc *, struct iwn_node_info *,
214198429Srpaulo			    int);
215198429Srpaulo	void		(*tx_done)(struct iwn_softc *, struct iwn_rx_desc *,
216198429Srpaulo			    struct iwn_rx_data *);
217201209Srpaulo	void		(*ampdu_tx_start)(struct iwn_softc *,
218221651Sbschmidt			    struct ieee80211_node *, int, uint8_t, uint16_t);
219221651Sbschmidt	void		(*ampdu_tx_stop)(struct iwn_softc *, int, uint8_t,
220201209Srpaulo			    uint16_t);
221198429Srpaulo};
222198429Srpaulo
223178676Ssamstruct iwn_vap {
224178676Ssam	struct ieee80211vap	iv_vap;
225198429Srpaulo	uint8_t			iv_ridx;
226178676Ssam
227178676Ssam	int			(*iv_newstate)(struct ieee80211vap *,
228178676Ssam				    enum ieee80211_state, int);
229254204Sadrian	int			ctx;
230254204Sadrian	int			beacon_int;
231254204Sadrian	uint8_t		macaddr[IEEE80211_ADDR_LEN];
232254204Sadrian
233178676Ssam};
234178676Ssam#define	IWN_VAP(_vap)	((struct iwn_vap *)(_vap))
235178676Ssam
236178676Ssamstruct iwn_softc {
237220726Sbschmidt	device_t		sc_dev;
238220723Sbschmidt
239178676Ssam	struct ifnet		*sc_ifp;
240178676Ssam	int			sc_debug;
241178676Ssam
242178676Ssam	struct mtx		sc_mtx;
243178676Ssam
244198429Srpaulo	u_int			sc_flags;
245198429Srpaulo#define IWN_FLAG_HAS_OTPROM	(1 << 1)
246201209Srpaulo#define IWN_FLAG_CALIB_DONE	(1 << 2)
247201209Srpaulo#define IWN_FLAG_USE_ICT	(1 << 3)
248201209Srpaulo#define IWN_FLAG_INTERNAL_PA	(1 << 4)
249220729Sbschmidt#define IWN_FLAG_HAS_11N	(1 << 6)
250220729Sbschmidt#define IWN_FLAG_ENH_SENS	(1 << 7)
251220891Sbschmidt#define IWN_FLAG_ADV_BTCOEX	(1 << 8)
252254204Sadrian#define IWN_FLAG_PAN_SUPPORT	(1 << 9)
253257134Sadrian#define IWN_FLAG_BTCOEX		(1 << 10)
254178676Ssam
255198429Srpaulo	uint8_t 		hw_type;
256254204Sadrian	/* subdevice_id used to adjust configuration */
257254204Sadrian	uint16_t		subdevice_id;
258220728Sbschmidt
259220728Sbschmidt	struct iwn_ops		ops;
260198429Srpaulo	const char		*fwname;
261201209Srpaulo	const struct iwn_sensitivity_limits
262201209Srpaulo				*limits;
263220728Sbschmidt	int			ntxqs;
264221651Sbschmidt	int			firstaggqueue;
265220728Sbschmidt	int			ndmachnls;
266220728Sbschmidt	uint8_t			broadcast_id;
267220728Sbschmidt	int			rxonsz;
268220728Sbschmidt	int			schedsz;
269220728Sbschmidt	uint32_t		fw_text_maxsz;
270220728Sbschmidt	uint32_t		fw_data_maxsz;
271220728Sbschmidt	uint32_t		fwsz;
272220728Sbschmidt	bus_size_t		sched_txfact_addr;
273220866Sbschmidt	uint32_t		reset_noise_gain;
274220866Sbschmidt	uint32_t		noise_gain;
275198429Srpaulo
276198429Srpaulo	/* TX scheduler rings. */
277198429Srpaulo	struct iwn_dma_info	sched_dma;
278198429Srpaulo	uint16_t		*sched;
279198429Srpaulo	uint32_t		sched_base;
280198429Srpaulo
281198429Srpaulo	/* "Keep Warm" page. */
282178676Ssam	struct iwn_dma_info	kw_dma;
283178676Ssam
284198429Srpaulo	/* Firmware image. */
285178676Ssam	const struct firmware	*fw_fp;
286178676Ssam
287198429Srpaulo	/* Firmware DMA transfer. */
288178676Ssam	struct iwn_dma_info	fw_dma;
289178676Ssam
290201209Srpaulo	/* ICT table. */
291201209Srpaulo	struct iwn_dma_info	ict_dma;
292201209Srpaulo	uint32_t		*ict;
293201209Srpaulo	int			ict_cur;
294201209Srpaulo
295198429Srpaulo	/* TX/RX rings. */
296198429Srpaulo	struct iwn_tx_ring	txq[IWN5000_NTXQUEUES];
297178676Ssam	struct iwn_rx_ring	rxq;
298178676Ssam
299220726Sbschmidt	struct resource		*mem;
300178676Ssam	bus_space_tag_t		sc_st;
301178676Ssam	bus_space_handle_t	sc_sh;
302220723Sbschmidt	struct resource		*irq;
303178676Ssam	void 			*sc_ih;
304178676Ssam	bus_size_t		sc_sz;
305198429Srpaulo	int			sc_cap_off;	/* PCIe Capabilities. */
306178676Ssam
307178676Ssam	/* Tasks used by the driver */
308220726Sbschmidt	struct task		sc_reinit_task;
309191746Sthompsa	struct task		sc_radioon_task;
310191746Sthompsa	struct task		sc_radiooff_task;
311266546Strasz	struct task		sc_panic_task;
312284588Sadrian	struct task		sc_xmit_task;
313201209Srpaulo
314266546Strasz	/* Taskqueue */
315266546Strasz	struct taskqueue	*sc_tq;
316266546Strasz
317259061Sadrian	/* Calibration information */
318220667Sbschmidt	struct callout		calib_to;
319178676Ssam	int			calib_cnt;
320178676Ssam	struct iwn_calib_state	calib;
321259061Sadrian	int			last_calib_ticks;
322220667Sbschmidt	struct callout		watchdog_to;
323254204Sadrian	struct callout		ct_kill_exit_to;
324198429Srpaulo	struct iwn_fw_info	fw;
325258035Sadrian	struct iwn_calib_info	calibcmd[IWN5000_PHY_CALIB_MAX_RESULT];
326198429Srpaulo	uint32_t		errptr;
327198429Srpaulo
328178676Ssam	struct iwn_rx_stat	last_rx_stat;
329178676Ssam	int			last_rx_valid;
330178676Ssam	struct iwn_ucode_info	ucode_info;
331254204Sadrian	struct iwn_rxon		rx_on[IWN_NUM_RXON_CTX];
332254204Sadrian	struct iwn_rxon		*rxon;
333254204Sadrian	int			ctx;
334254204Sadrian	struct ieee80211vap	*ivap[IWN_NUM_RXON_CTX];
335254204Sadrian
336262422Sadrian	/* General statistics */
337262422Sadrian	/*
338262422Sadrian	 * The statistics are reset after each channel
339262422Sadrian	 * change.  So it may be zeroed after things like
340262422Sadrian	 * a background scan.
341262422Sadrian	 *
342262422Sadrian	 * So for now, this is just a cheap hack to
343262422Sadrian	 * expose the last received statistics dump
344262422Sadrian	 * via an ioctl().  Later versions of this
345262422Sadrian	 * could expose the last 'n' messages, or just
346262422Sadrian	 * provide a pipeline for the firmware responses
347262422Sadrian	 * via something like BPF.
348262422Sadrian	 */
349262422Sadrian	struct iwn_stats	last_stat;
350262422Sadrian	int			last_stat_valid;
351262422Sadrian
352254204Sadrian	uint8_t			uc_scan_progress;
353178676Ssam	uint32_t		rawtemp;
354178676Ssam	int			temp;
355178676Ssam	int			noise;
356198429Srpaulo	uint32_t		qfullmsk;
357178676Ssam
358201209Srpaulo	uint32_t		prom_base;
359198429Srpaulo	struct iwn4965_eeprom_band
360198429Srpaulo				bands[IWN_NBANDS];
361201209Srpaulo	struct iwn_eeprom_chan	eeprom_channels[IWN_NBANDS][IWN_MAX_CHAN_PER_BAND];
362198429Srpaulo	uint16_t		rfcfg;
363206444Sbschmidt	uint8_t			calib_ver;
364198429Srpaulo	char			eeprom_domain[4];
365220674Sbschmidt	uint32_t		eeprom_crystal;
366220674Sbschmidt	int16_t			eeprom_temp;
367254204Sadrian	int16_t			eeprom_temp_high;
368178676Ssam	int16_t			eeprom_voltage;
369178676Ssam	int8_t			maxpwr2GHz;
370178676Ssam	int8_t			maxpwr5GHz;
371198429Srpaulo	int8_t			maxpwr[IEEE80211_CHAN_MAX];
372198429Srpaulo
373254204Sadrian	uint32_t		tlv_feature_flags;
374254204Sadrian
375201209Srpaulo	int32_t			temp_off;
376201209Srpaulo	uint32_t		int_mask;
377198429Srpaulo	uint8_t			ntxchains;
378198429Srpaulo	uint8_t			nrxchains;
379201209Srpaulo	uint8_t			txchainmask;
380201209Srpaulo	uint8_t			rxchainmask;
381201209Srpaulo	uint8_t			chainmask;
382198429Srpaulo
383198429Srpaulo	int			sc_tx_timer;
384254204Sadrian	int			sc_scan_timer;
385198429Srpaulo
386258829Sadrian	/* Are we doing a scan? */
387258829Sadrian	int			sc_is_scanning;
388258829Sadrian
389284588Sadrian	/* Are we waiting for a beacon before xmit? */
390284588Sadrian	int			sc_beacon_wait;
391284588Sadrian
392221651Sbschmidt	struct ieee80211_tx_ampdu *qid2tap[IWN5000_NTXQUEUES];
393221651Sbschmidt
394221650Sbschmidt	int			(*sc_ampdu_rx_start)(struct ieee80211_node *,
395221650Sbschmidt				    struct ieee80211_rx_ampdu *, int, int, int);
396221650Sbschmidt	void			(*sc_ampdu_rx_stop)(struct ieee80211_node *,
397221650Sbschmidt				    struct ieee80211_rx_ampdu *);
398221651Sbschmidt	int			(*sc_addba_request)(struct ieee80211_node *,
399221651Sbschmidt				    struct ieee80211_tx_ampdu *, int, int, int);
400221651Sbschmidt	int			(*sc_addba_response)(struct ieee80211_node *,
401221651Sbschmidt				    struct ieee80211_tx_ampdu *, int, int, int);
402221651Sbschmidt	void			(*sc_addba_stop)(struct ieee80211_node *,
403221651Sbschmidt				    struct ieee80211_tx_ampdu *);
404221650Sbschmidt
405254204Sadrian	struct	iwn_led_mode sc_led;
406221651Sbschmidt
407198429Srpaulo	struct iwn_rx_radiotap_header sc_rxtap;
408198429Srpaulo	struct iwn_tx_radiotap_header sc_txtap;
409254204Sadrian
410254204Sadrian	/* The power save level originally configured by user */
411254204Sadrian	int			desired_pwrsave_level;
412254204Sadrian
413254204Sadrian	/*
414254204Sadrian	 * The current power save level, this may differ from the
415254204Sadrian	 * configured value due to thermal throttling etc.
416254204Sadrian	 */
417254204Sadrian	int			current_pwrsave_level;
418254204Sadrian
419258035Sadrian	/* For specific params */
420258035Sadrian	const struct iwn_base_params *base_params;
421270738Sadrian
422270738Sadrian#define	IWN_UCODE_API(ver)	(((ver) & 0x0000FF00) >> 8)
423270738Sadrian	uint32_t		ucode_rev;
424284588Sadrian
425284588Sadrian	/*
426284588Sadrian	 * Global queue for queuing xmit frames
427284588Sadrian	 * when we can't yet transmit (eg raw
428284588Sadrian	 * frames whilst waiting for beacons.)
429284588Sadrian	 */
430284588Sadrian	struct mbufq		sc_xmit_queue;
431178676Ssam};
432178676Ssam
433178676Ssam#define IWN_LOCK_INIT(_sc) \
434178676Ssam	mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
435210108Sbschmidt	    MTX_NETWORK_LOCK, MTX_DEF)
436178676Ssam#define IWN_LOCK(_sc)			mtx_lock(&(_sc)->sc_mtx)
437178676Ssam#define IWN_LOCK_ASSERT(_sc)		mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
438178676Ssam#define IWN_UNLOCK(_sc)			mtx_unlock(&(_sc)->sc_mtx)
439178676Ssam#define IWN_LOCK_DESTROY(_sc)		mtx_destroy(&(_sc)->sc_mtx)
440