1178676Ssam/*	$FreeBSD: stable/11/sys/dev/iwn/if_iwnvar.h 345636 2019-03-28 09:50:25Z avos $	*/
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;
65345636Savos} __packed __aligned(8);
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
232178676Ssam};
233178676Ssam#define	IWN_VAP(_vap)	((struct iwn_vap *)(_vap))
234178676Ssam
235178676Ssamstruct iwn_softc {
236220726Sbschmidt	device_t		sc_dev;
237178676Ssam	int			sc_debug;
238287312Sadrian	struct cdev		*sc_cdev;
239178676Ssam	struct mtx		sc_mtx;
240287197Sglebius	struct ieee80211com	sc_ic;
241178676Ssam
242198429Srpaulo	u_int			sc_flags;
243198429Srpaulo#define IWN_FLAG_HAS_OTPROM	(1 << 1)
244201209Srpaulo#define IWN_FLAG_CALIB_DONE	(1 << 2)
245201209Srpaulo#define IWN_FLAG_USE_ICT	(1 << 3)
246201209Srpaulo#define IWN_FLAG_INTERNAL_PA	(1 << 4)
247220729Sbschmidt#define IWN_FLAG_HAS_11N	(1 << 6)
248220729Sbschmidt#define IWN_FLAG_ENH_SENS	(1 << 7)
249220891Sbschmidt#define IWN_FLAG_ADV_BTCOEX	(1 << 8)
250254204Sadrian#define IWN_FLAG_PAN_SUPPORT	(1 << 9)
251257134Sadrian#define IWN_FLAG_BTCOEX		(1 << 10)
252287197Sglebius#define	IWN_FLAG_RUNNING	(1 << 11)
253178676Ssam
254198429Srpaulo	uint8_t 		hw_type;
255254204Sadrian	/* subdevice_id used to adjust configuration */
256254204Sadrian	uint16_t		subdevice_id;
257220728Sbschmidt
258220728Sbschmidt	struct iwn_ops		ops;
259198429Srpaulo	const char		*fwname;
260201209Srpaulo	const struct iwn_sensitivity_limits
261201209Srpaulo				*limits;
262220728Sbschmidt	int			ntxqs;
263221651Sbschmidt	int			firstaggqueue;
264220728Sbschmidt	int			ndmachnls;
265220728Sbschmidt	uint8_t			broadcast_id;
266220728Sbschmidt	int			rxonsz;
267220728Sbschmidt	int			schedsz;
268220728Sbschmidt	uint32_t		fw_text_maxsz;
269220728Sbschmidt	uint32_t		fw_data_maxsz;
270220728Sbschmidt	uint32_t		fwsz;
271220728Sbschmidt	bus_size_t		sched_txfact_addr;
272220866Sbschmidt	uint32_t		reset_noise_gain;
273220866Sbschmidt	uint32_t		noise_gain;
274198429Srpaulo
275198429Srpaulo	/* TX scheduler rings. */
276198429Srpaulo	struct iwn_dma_info	sched_dma;
277198429Srpaulo	uint16_t		*sched;
278198429Srpaulo	uint32_t		sched_base;
279198429Srpaulo
280198429Srpaulo	/* "Keep Warm" page. */
281178676Ssam	struct iwn_dma_info	kw_dma;
282178676Ssam
283198429Srpaulo	/* Firmware image. */
284178676Ssam	const struct firmware	*fw_fp;
285178676Ssam
286198429Srpaulo	/* Firmware DMA transfer. */
287178676Ssam	struct iwn_dma_info	fw_dma;
288178676Ssam
289201209Srpaulo	/* ICT table. */
290201209Srpaulo	struct iwn_dma_info	ict_dma;
291201209Srpaulo	uint32_t		*ict;
292201209Srpaulo	int			ict_cur;
293201209Srpaulo
294198429Srpaulo	/* TX/RX rings. */
295198429Srpaulo	struct iwn_tx_ring	txq[IWN5000_NTXQUEUES];
296178676Ssam	struct iwn_rx_ring	rxq;
297178676Ssam
298220726Sbschmidt	struct resource		*mem;
299178676Ssam	bus_space_tag_t		sc_st;
300178676Ssam	bus_space_handle_t	sc_sh;
301220723Sbschmidt	struct resource		*irq;
302178676Ssam	void 			*sc_ih;
303178676Ssam	bus_size_t		sc_sz;
304198429Srpaulo	int			sc_cap_off;	/* PCIe Capabilities. */
305178676Ssam
306178676Ssam	/* Tasks used by the driver */
307191746Sthompsa	struct task		sc_radioon_task;
308191746Sthompsa	struct task		sc_radiooff_task;
309266546Strasz	struct task		sc_panic_task;
310284588Sadrian	struct task		sc_xmit_task;
311201209Srpaulo
312266546Strasz	/* Taskqueue */
313266546Strasz	struct taskqueue	*sc_tq;
314266546Strasz
315259061Sadrian	/* Calibration information */
316220667Sbschmidt	struct callout		calib_to;
317178676Ssam	int			calib_cnt;
318178676Ssam	struct iwn_calib_state	calib;
319259061Sadrian	int			last_calib_ticks;
320300732Savos	struct callout		scan_timeout;
321220667Sbschmidt	struct callout		watchdog_to;
322198429Srpaulo	struct iwn_fw_info	fw;
323258035Sadrian	struct iwn_calib_info	calibcmd[IWN5000_PHY_CALIB_MAX_RESULT];
324198429Srpaulo	uint32_t		errptr;
325198429Srpaulo
326178676Ssam	struct iwn_rx_stat	last_rx_stat;
327178676Ssam	int			last_rx_valid;
328178676Ssam	struct iwn_ucode_info	ucode_info;
329254204Sadrian	struct iwn_rxon		rx_on[IWN_NUM_RXON_CTX];
330254204Sadrian	struct iwn_rxon		*rxon;
331254204Sadrian	int			ctx;
332254204Sadrian	struct ieee80211vap	*ivap[IWN_NUM_RXON_CTX];
333254204Sadrian
334262422Sadrian	/* General statistics */
335262422Sadrian	/*
336262422Sadrian	 * The statistics are reset after each channel
337262422Sadrian	 * change.  So it may be zeroed after things like
338262422Sadrian	 * a background scan.
339262422Sadrian	 *
340262422Sadrian	 * So for now, this is just a cheap hack to
341262422Sadrian	 * expose the last received statistics dump
342262422Sadrian	 * via an ioctl().  Later versions of this
343262422Sadrian	 * could expose the last 'n' messages, or just
344262422Sadrian	 * provide a pipeline for the firmware responses
345262422Sadrian	 * via something like BPF.
346262422Sadrian	 */
347262422Sadrian	struct iwn_stats	last_stat;
348262422Sadrian	int			last_stat_valid;
349262422Sadrian
350254204Sadrian	uint8_t			uc_scan_progress;
351178676Ssam	uint32_t		rawtemp;
352178676Ssam	int			temp;
353178676Ssam	int			noise;
354198429Srpaulo	uint32_t		qfullmsk;
355178676Ssam
356201209Srpaulo	uint32_t		prom_base;
357198429Srpaulo	struct iwn4965_eeprom_band
358198429Srpaulo				bands[IWN_NBANDS];
359201209Srpaulo	struct iwn_eeprom_chan	eeprom_channels[IWN_NBANDS][IWN_MAX_CHAN_PER_BAND];
360198429Srpaulo	uint16_t		rfcfg;
361206444Sbschmidt	uint8_t			calib_ver;
362198429Srpaulo	char			eeprom_domain[4];
363220674Sbschmidt	uint32_t		eeprom_crystal;
364220674Sbschmidt	int16_t			eeprom_temp;
365254204Sadrian	int16_t			eeprom_temp_high;
366178676Ssam	int16_t			eeprom_voltage;
367178676Ssam	int8_t			maxpwr2GHz;
368178676Ssam	int8_t			maxpwr5GHz;
369198429Srpaulo	int8_t			maxpwr[IEEE80211_CHAN_MAX];
370198429Srpaulo
371254204Sadrian	uint32_t		tlv_feature_flags;
372254204Sadrian
373201209Srpaulo	int32_t			temp_off;
374201209Srpaulo	uint32_t		int_mask;
375198429Srpaulo	uint8_t			ntxchains;
376198429Srpaulo	uint8_t			nrxchains;
377201209Srpaulo	uint8_t			txchainmask;
378201209Srpaulo	uint8_t			rxchainmask;
379201209Srpaulo	uint8_t			chainmask;
380198429Srpaulo
381198429Srpaulo	int			sc_tx_timer;
382198429Srpaulo
383258829Sadrian	/* Are we doing a scan? */
384258829Sadrian	int			sc_is_scanning;
385258829Sadrian
386284588Sadrian	/* Are we waiting for a beacon before xmit? */
387284588Sadrian	int			sc_beacon_wait;
388284588Sadrian
389221651Sbschmidt	struct ieee80211_tx_ampdu *qid2tap[IWN5000_NTXQUEUES];
390221651Sbschmidt
391221650Sbschmidt	int			(*sc_ampdu_rx_start)(struct ieee80211_node *,
392221650Sbschmidt				    struct ieee80211_rx_ampdu *, int, int, int);
393221650Sbschmidt	void			(*sc_ampdu_rx_stop)(struct ieee80211_node *,
394221650Sbschmidt				    struct ieee80211_rx_ampdu *);
395221651Sbschmidt	int			(*sc_addba_request)(struct ieee80211_node *,
396221651Sbschmidt				    struct ieee80211_tx_ampdu *, int, int, int);
397221651Sbschmidt	int			(*sc_addba_response)(struct ieee80211_node *,
398221651Sbschmidt				    struct ieee80211_tx_ampdu *, int, int, int);
399221651Sbschmidt	void			(*sc_addba_stop)(struct ieee80211_node *,
400221651Sbschmidt				    struct ieee80211_tx_ampdu *);
401221650Sbschmidt
402254204Sadrian	struct	iwn_led_mode sc_led;
403221651Sbschmidt
404198429Srpaulo	struct iwn_rx_radiotap_header sc_rxtap;
405198429Srpaulo	struct iwn_tx_radiotap_header sc_txtap;
406254204Sadrian
407254204Sadrian	/* The power save level originally configured by user */
408254204Sadrian	int			desired_pwrsave_level;
409254204Sadrian
410254204Sadrian	/*
411254204Sadrian	 * The current power save level, this may differ from the
412254204Sadrian	 * configured value due to thermal throttling etc.
413254204Sadrian	 */
414254204Sadrian	int			current_pwrsave_level;
415254204Sadrian
416258035Sadrian	/* For specific params */
417258035Sadrian	const struct iwn_base_params *base_params;
418270738Sadrian
419270738Sadrian#define	IWN_UCODE_API(ver)	(((ver) & 0x0000FF00) >> 8)
420270738Sadrian	uint32_t		ucode_rev;
421284588Sadrian
422284588Sadrian	/*
423284588Sadrian	 * Global queue for queuing xmit frames
424284588Sadrian	 * when we can't yet transmit (eg raw
425284588Sadrian	 * frames whilst waiting for beacons.)
426284588Sadrian	 */
427284588Sadrian	struct mbufq		sc_xmit_queue;
428178676Ssam};
429178676Ssam
430178676Ssam#define IWN_LOCK_INIT(_sc) \
431178676Ssam	mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
432210108Sbschmidt	    MTX_NETWORK_LOCK, MTX_DEF)
433178676Ssam#define IWN_LOCK(_sc)			mtx_lock(&(_sc)->sc_mtx)
434178676Ssam#define IWN_LOCK_ASSERT(_sc)		mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
435178676Ssam#define IWN_UNLOCK(_sc)			mtx_unlock(&(_sc)->sc_mtx)
436178676Ssam#define IWN_LOCK_DESTROY(_sc)		mtx_destroy(&(_sc)->sc_mtx)
437