if_iwnvar.h revision 262422
1139749Simp/*	$FreeBSD: head/sys/dev/iwn/if_iwnvar.h 262422 2014-02-24 02:37:04Z adrian $	*/
2135048Swpaul/*	$OpenBSD: if_iwnvar.h,v 1.18 2010/04/30 16:06:46 damien Exp $	*/
3135048Swpaul
4135048Swpaul/*-
5135048Swpaul * Copyright (c) 2013 Cedric GROSS <cg@cgross.info>
6135048Swpaul * Copyright (c) 2011 Intel Corporation
7135048Swpaul * Copyright (c) 2007, 2008
8135048Swpaul *	Damien Bergamini <damien.bergamini@free.fr>
9135048Swpaul * Copyright (c) 2008 Sam Leffler, Errno Consulting
10135048Swpaul *
11135048Swpaul * Permission to use, copy, modify, and distribute this software for any
12135048Swpaul * purpose with or without fee is hereby granted, provided that the above
13135048Swpaul * copyright notice and this permission notice appear in all copies.
14135048Swpaul *
15135048Swpaul * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
16135048Swpaul * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17135048Swpaul * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
18135048Swpaul * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19135048Swpaul * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20135048Swpaul * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
21135048Swpaul * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22135048Swpaul */
23135048Swpaulenum iwn_rxon_ctx_id {
24135048Swpaul		IWN_RXON_BSS_CTX,
25135048Swpaul		IWN_RXON_PAN_CTX,
26135048Swpaul		IWN_NUM_RXON_CTX
27135048Swpaul};
28135048Swpaul
29135048Swpaulstruct iwn_pan_slot {
30135048Swpaul	uint16_t	time;
31135048Swpaul	uint8_t		type;
32135048Swpaul	uint8_t		reserved;
33135048Swpaul} __packed;
34135048Swpaul
35135048Swpaulstruct iwn_pan_params_cmd {
36135048Swpaul	uint16_t flags;
37135048Swpaul#define	IWN_PAN_PARAMS_FLG_SLOTTED_MODE	(1 << 3)
38135048Swpaul
39135048Swpaul	uint8_t reserved;
40135048Swpaul	uint8_t num_slots;
41135048Swpaul	struct iwn_pan_slot slots[10];
42135048Swpaul} __packed;
43135048Swpaul
44135048Swpaulstruct iwn_led_mode
45135048Swpaul{
46135048Swpaul	uint8_t		led_cur_mode;
47135048Swpaul	uint64_t	led_cur_bt;
48135048Swpaul	uint64_t	led_last_bt;
49135048Swpaul	uint64_t	led_cur_tpt;
50135048Swpaul	uint64_t	led_last_tpt;
51135048Swpaul	uint64_t	led_bt_diff;
52135048Swpaul	int		led_cur_time;
53135048Swpaul	int		led_last_time;
54135048Swpaul};
55135048Swpaul
56135048Swpaulstruct iwn_rx_radiotap_header {
57135048Swpaul	struct ieee80211_radiotap_header wr_ihdr;
58135048Swpaul	uint64_t	wr_tsft;
59135048Swpaul	uint8_t		wr_flags;
60135048Swpaul	uint8_t		wr_rate;
61135048Swpaul	uint16_t	wr_chan_freq;
62135048Swpaul	uint16_t	wr_chan_flags;
63135048Swpaul	int8_t		wr_dbm_antsignal;
64135048Swpaul	int8_t		wr_dbm_antnoise;
65135048Swpaul} __packed;
66135048Swpaul
67135048Swpaul#define IWN_RX_RADIOTAP_PRESENT						\
68135048Swpaul	((1 << IEEE80211_RADIOTAP_TSFT) |				\
69135048Swpaul	 (1 << IEEE80211_RADIOTAP_FLAGS) |				\
70135048Swpaul	 (1 << IEEE80211_RADIOTAP_RATE) |				\
71135048Swpaul	 (1 << IEEE80211_RADIOTAP_CHANNEL) |				\
72135048Swpaul	 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |			\
73135048Swpaul	 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE))
74135048Swpaul
75135048Swpaulstruct iwn_tx_radiotap_header {
76135048Swpaul	struct ieee80211_radiotap_header wt_ihdr;
77135048Swpaul	uint8_t		wt_flags;
78135048Swpaul	uint8_t		wt_rate;
79135048Swpaul	uint16_t	wt_chan_freq;
80135048Swpaul	uint16_t	wt_chan_flags;
81135048Swpaul} __packed;
82135048Swpaul
83150968Sglebius#define IWN_TX_RADIOTAP_PRESENT						\
84150968Sglebius	((1 << IEEE80211_RADIOTAP_FLAGS) |				\
85150968Sglebius	 (1 << IEEE80211_RADIOTAP_RATE) |				\
86150968Sglebius	 (1 << IEEE80211_RADIOTAP_CHANNEL))
87135048Swpaul
88135048Swpaulstruct iwn_dma_info {
89135048Swpaul	bus_dma_tag_t		tag;
90135048Swpaul	bus_dmamap_t		map;
91135048Swpaul	bus_dma_segment_t	seg;
92135048Swpaul	bus_addr_t		paddr;
93135048Swpaul	caddr_t			vaddr;
94135048Swpaul	bus_size_t		size;
95135048Swpaul};
96135048Swpaul
97135048Swpaulstruct iwn_tx_data {
98135048Swpaul	bus_dmamap_t		map;
99135048Swpaul	bus_addr_t		cmd_paddr;
100135048Swpaul	bus_addr_t		scratch_paddr;
101135048Swpaul	struct mbuf		*m;
102147256Sbrooks	struct ieee80211_node	*ni;
103135048Swpaul};
104135048Swpaul
105135048Swpaulstruct iwn_tx_ring {
106135048Swpaul	struct iwn_dma_info	desc_dma;
107135048Swpaul	struct iwn_dma_info	cmd_dma;
108135048Swpaul	struct iwn_tx_desc	*desc;
109135048Swpaul	struct iwn_tx_cmd	*cmd;
110135048Swpaul	struct iwn_tx_data	data[IWN_TX_RING_COUNT];
111135048Swpaul	bus_dma_tag_t		data_dmat;
112135048Swpaul	int			qid;
113135048Swpaul	int			queued;
114135048Swpaul	int			cur;
115135048Swpaul	int			read;
116135048Swpaul};
117135048Swpaul
118135048Swpaulstruct iwn_softc;
119135048Swpaul
120135048Swpaulstruct iwn_rx_data {
121135048Swpaul	struct mbuf	*m;
122151545Simp	bus_dmamap_t	map;
123135048Swpaul};
124135048Swpaul
125135048Swpaulstruct iwn_rx_ring {
126135048Swpaul	struct iwn_dma_info	desc_dma;
127135048Swpaul	struct iwn_dma_info	stat_dma;
128135048Swpaul	uint32_t		*desc;
129135048Swpaul	struct iwn_rx_status	*stat;
130200541Syongari	struct iwn_rx_data	data[IWN_RX_RING_COUNT];
131200541Syongari	bus_dma_tag_t		data_dmat;
132200541Syongari	int			cur;
133200541Syongari};
134135048Swpaul
135135048Swpaulstruct iwn_node {
136135048Swpaul	struct	ieee80211_node		ni;	/* must be the first */
137135048Swpaul	uint16_t			disable_tid;
138135048Swpaul	uint8_t				id;
139135048Swpaul	struct {
140135048Swpaul		uint64_t		bitmap;
141135048Swpaul		int			startidx;
142135048Swpaul		int			nframes;
143200548Syongari	} agg[IEEE80211_TID_SIZE];
144200548Syongari};
145200548Syongari
146200548Syongaristruct iwn_calib_state {
147200548Syongari	uint8_t		state;
148200548Syongari#define IWN_CALIB_STATE_INIT	0
149135048Swpaul#define IWN_CALIB_STATE_ASSOC	1
150200548Syongari#define IWN_CALIB_STATE_RUN	2
151200548Syongari
152200548Syongari	u_int		nbeacons;
153200548Syongari	uint32_t	noise[3];
154200548Syongari	uint32_t	rssi[3];
155200548Syongari	uint32_t	ofdm_x1;
156200548Syongari	uint32_t	ofdm_mrc_x1;
157200548Syongari	uint32_t	ofdm_x4;
158200548Syongari	uint32_t	ofdm_mrc_x4;
159200548Syongari	uint32_t	cck_x4;
160200525Syongari	uint32_t	cck_mrc_x4;
161200548Syongari	uint32_t	bad_plcp_ofdm;
162200548Syongari	uint32_t	fa_ofdm;
163135048Swpaul	uint32_t	bad_plcp_cck;
164200548Syongari	uint32_t	fa_cck;
165200548Syongari	uint32_t	low_fa;
166200548Syongari	uint32_t	bad_plcp_ht;
167200548Syongari	uint8_t		cck_state;
168200548Syongari#define IWN_CCK_STATE_INIT	0
169200548Syongari#define IWN_CCK_STATE_LOFA	1
170200548Syongari#define IWN_CCK_STATE_HIFA	2
171200551Syongari
172200548Syongari	uint8_t		noise_samples[20];
173200548Syongari	u_int		cur_noise_sample;
174200548Syongari	uint8_t		noise_ref;
175200548Syongari	uint32_t	energy_samples[10];
176200548Syongari	u_int		cur_energy_sample;
177200548Syongari	uint32_t	energy_cck;
178200548Syongari};
179200548Syongari
180200548Syongaristruct iwn_calib_info {
181200548Syongari	uint8_t		*buf;
182200548Syongari	u_int		len;
183200548Syongari};
184200548Syongari
185200548Syongaristruct iwn_fw_part {
186200548Syongari	const uint8_t	*text;
187200548Syongari	uint32_t	textsz;
188200548Syongari	const uint8_t	*data;
189135048Swpaul	uint32_t	datasz;
190135048Swpaul};
191135048Swpaul
192135048Swpaulstruct iwn_fw_info {
193135048Swpaul	const uint8_t		*data;
194135048Swpaul	size_t			size;
195135048Swpaul	struct iwn_fw_part	init;
196135048Swpaul	struct iwn_fw_part	main;
197135048Swpaul	struct iwn_fw_part	boot;
198135048Swpaul};
199135048Swpaul
200135048Swpaulstruct iwn_ops {
201135048Swpaul	int		(*load_firmware)(struct iwn_softc *);
202135048Swpaul	void		(*read_eeprom)(struct iwn_softc *);
203135048Swpaul	int		(*post_alive)(struct iwn_softc *);
204135048Swpaul	int		(*nic_config)(struct iwn_softc *);
205135048Swpaul	void		(*update_sched)(struct iwn_softc *, int, int, uint8_t,
206135048Swpaul			    uint16_t);
207135048Swpaul	int		(*get_temperature)(struct iwn_softc *);
208135048Swpaul	int		(*get_rssi)(struct iwn_softc *, struct iwn_rx_stat *);
209135048Swpaul	int		(*set_txpower)(struct iwn_softc *,
210135048Swpaul			    struct ieee80211_channel *, int);
211135048Swpaul	int		(*init_gains)(struct iwn_softc *);
212135048Swpaul	int		(*set_gains)(struct iwn_softc *);
213135048Swpaul	int		(*add_node)(struct iwn_softc *, struct iwn_node_info *,
214135048Swpaul			    int);
215135048Swpaul	void		(*tx_done)(struct iwn_softc *, struct iwn_rx_desc *,
216135048Swpaul			    struct iwn_rx_data *);
217135048Swpaul	void		(*ampdu_tx_start)(struct iwn_softc *,
218135048Swpaul			    struct ieee80211_node *, int, uint8_t, uint16_t);
219135048Swpaul	void		(*ampdu_tx_stop)(struct iwn_softc *, int, uint8_t,
220135048Swpaul			    uint16_t);
221135048Swpaul};
222145520Swpaul
223135048Swpaulstruct iwn_vap {
224135048Swpaul	struct ieee80211vap	iv_vap;
225135048Swpaul	uint8_t			iv_ridx;
226135048Swpaul
227200533Syongari	int			(*iv_newstate)(struct ieee80211vap *,
228135048Swpaul				    enum ieee80211_state, int);
229200536Syongari	int			ctx;
230200536Syongari	int			beacon_int;
231135048Swpaul	uint8_t		macaddr[IEEE80211_ADDR_LEN];
232135048Swpaul
233135048Swpaul};
234135048Swpaul#define	IWN_VAP(_vap)	((struct iwn_vap *)(_vap))
235135048Swpaul
236135048Swpaulstruct iwn_softc {
237135048Swpaul	device_t		sc_dev;
238135048Swpaul
239135048Swpaul	struct ifnet		*sc_ifp;
240135048Swpaul	int			sc_debug;
241135048Swpaul
242135048Swpaul	struct mtx		sc_mtx;
243135048Swpaul
244135048Swpaul	u_int			sc_flags;
245135048Swpaul#define IWN_FLAG_HAS_OTPROM	(1 << 1)
246135048Swpaul#define IWN_FLAG_CALIB_DONE	(1 << 2)
247135048Swpaul#define IWN_FLAG_USE_ICT	(1 << 3)
248135048Swpaul#define IWN_FLAG_INTERNAL_PA	(1 << 4)
249135048Swpaul#define IWN_FLAG_HAS_11N	(1 << 6)
250135048Swpaul#define IWN_FLAG_ENH_SENS	(1 << 7)
251135048Swpaul#define IWN_FLAG_ADV_BTCOEX	(1 << 8)
252135048Swpaul#define IWN_FLAG_PAN_SUPPORT	(1 << 9)
253135048Swpaul#define IWN_FLAG_BTCOEX		(1 << 10)
254135048Swpaul
255135048Swpaul	uint8_t 		hw_type;
256135048Swpaul	/* subdevice_id used to adjust configuration */
257135048Swpaul	uint16_t		subdevice_id;
258135048Swpaul
259135048Swpaul	struct iwn_ops		ops;
260135048Swpaul	const char		*fwname;
261135048Swpaul	const struct iwn_sensitivity_limits
262135048Swpaul				*limits;
263135048Swpaul	int			ntxqs;
264135048Swpaul	int			firstaggqueue;
265135048Swpaul	int			ndmachnls;
266135048Swpaul	uint8_t			broadcast_id;
267145520Swpaul	int			rxonsz;
268135048Swpaul	int			schedsz;
269135048Swpaul	uint32_t		fw_text_maxsz;
270135048Swpaul	uint32_t		fw_data_maxsz;
271135048Swpaul	uint32_t		fwsz;
272135048Swpaul	bus_size_t		sched_txfact_addr;
273200531Syongari	uint32_t		reset_noise_gain;
274135048Swpaul	uint32_t		noise_gain;
275200536Syongari
276145520Swpaul	/* TX scheduler rings. */
277200536Syongari	struct iwn_dma_info	sched_dma;
278135048Swpaul	uint16_t		*sched;
279135048Swpaul	uint32_t		sched_base;
280135048Swpaul
281200533Syongari	/* "Keep Warm" page. */
282135048Swpaul	struct iwn_dma_info	kw_dma;
283135048Swpaul
284135048Swpaul	/* Firmware image. */
285135048Swpaul	const struct firmware	*fw_fp;
286135048Swpaul
287145520Swpaul	/* Firmware DMA transfer. */
288145520Swpaul	struct iwn_dma_info	fw_dma;
289145520Swpaul
290145520Swpaul	/* ICT table. */
291135048Swpaul	struct iwn_dma_info	ict_dma;
292135048Swpaul	uint32_t		*ict;
293135048Swpaul	int			ict_cur;
294200531Syongari
295135048Swpaul	/* TX/RX rings. */
296200536Syongari	struct iwn_tx_ring	txq[IWN5000_NTXQUEUES];
297135048Swpaul	struct iwn_rx_ring	rxq;
298135048Swpaul
299135048Swpaul	struct resource		*mem;
300135048Swpaul	bus_space_tag_t		sc_st;
301135048Swpaul	bus_space_handle_t	sc_sh;
302135048Swpaul	struct resource		*irq;
303135048Swpaul	void 			*sc_ih;
304135048Swpaul	bus_size_t		sc_sz;
305135048Swpaul	int			sc_cap_off;	/* PCIe Capabilities. */
306135048Swpaul
307135048Swpaul	/* Tasks used by the driver */
308135048Swpaul	struct task		sc_reinit_task;
309135048Swpaul	struct task		sc_radioon_task;
310135048Swpaul	struct task		sc_radiooff_task;
311200531Syongari
312135048Swpaul	/* Calibration information */
313200536Syongari	struct callout		calib_to;
314135048Swpaul	int			calib_cnt;
315135048Swpaul	struct iwn_calib_state	calib;
316135048Swpaul	int			last_calib_ticks;
317135048Swpaul	struct callout		watchdog_to;
318135048Swpaul	struct callout		ct_kill_exit_to;
319135048Swpaul	struct iwn_fw_info	fw;
320135048Swpaul	struct iwn_calib_info	calibcmd[IWN5000_PHY_CALIB_MAX_RESULT];
321135048Swpaul	uint32_t		errptr;
322135048Swpaul
323135048Swpaul	struct iwn_rx_stat	last_rx_stat;
324135048Swpaul	int			last_rx_valid;
325135048Swpaul	struct iwn_ucode_info	ucode_info;
326135048Swpaul	struct iwn_rxon		rx_on[IWN_NUM_RXON_CTX];
327135048Swpaul	struct iwn_rxon		*rxon;
328135048Swpaul	int			ctx;
329135048Swpaul	struct ieee80211vap	*ivap[IWN_NUM_RXON_CTX];
330135048Swpaul
331135048Swpaul	/* General statistics */
332135048Swpaul	/*
333135048Swpaul	 * The statistics are reset after each channel
334135048Swpaul	 * change.  So it may be zeroed after things like
335135048Swpaul	 * a background scan.
336135048Swpaul	 *
337135048Swpaul	 * So for now, this is just a cheap hack to
338135048Swpaul	 * expose the last received statistics dump
339135048Swpaul	 * via an ioctl().  Later versions of this
340135048Swpaul	 * could expose the last 'n' messages, or just
341135048Swpaul	 * provide a pipeline for the firmware responses
342135048Swpaul	 * via something like BPF.
343135048Swpaul	 */
344135048Swpaul	struct iwn_stats	last_stat;
345135048Swpaul	int			last_stat_valid;
346135048Swpaul
347135048Swpaul	uint8_t			uc_scan_progress;
348200531Syongari	uint32_t		rawtemp;
349135048Swpaul	int			temp;
350200536Syongari	int			noise;
351200536Syongari	uint32_t		qfullmsk;
352200536Syongari
353135048Swpaul	uint32_t		prom_base;
354135048Swpaul	struct iwn4965_eeprom_band
355135048Swpaul				bands[IWN_NBANDS];
356200540Syongari	struct iwn_eeprom_chan	eeprom_channels[IWN_NBANDS][IWN_MAX_CHAN_PER_BAND];
357200536Syongari	uint16_t		rfcfg;
358135048Swpaul	uint8_t			calib_ver;
359135048Swpaul	char			eeprom_domain[4];
360135048Swpaul	uint32_t		eeprom_crystal;
361135048Swpaul	int16_t			eeprom_temp;
362135048Swpaul	int16_t			eeprom_temp_high;
363135048Swpaul	int16_t			eeprom_voltage;
364135048Swpaul	int8_t			maxpwr2GHz;
365135048Swpaul	int8_t			maxpwr5GHz;
366135048Swpaul	int8_t			maxpwr[IEEE80211_CHAN_MAX];
367135048Swpaul
368135048Swpaul	uint32_t		tlv_feature_flags;
369135048Swpaul
370135048Swpaul	int32_t			temp_off;
371135048Swpaul	uint32_t		int_mask;
372135048Swpaul	uint8_t			ntxchains;
373135048Swpaul	uint8_t			nrxchains;
374135048Swpaul	uint8_t			txchainmask;
375135048Swpaul	uint8_t			rxchainmask;
376135048Swpaul	uint8_t			chainmask;
377135048Swpaul
378135048Swpaul	int			sc_tx_timer;
379135048Swpaul	int			sc_scan_timer;
380135048Swpaul
381135048Swpaul	/* Are we doing a scan? */
382135048Swpaul	int			sc_is_scanning;
383135048Swpaul
384135048Swpaul	struct ieee80211_tx_ampdu *qid2tap[IWN5000_NTXQUEUES];
385200531Syongari
386135048Swpaul	int			(*sc_ampdu_rx_start)(struct ieee80211_node *,
387200536Syongari				    struct ieee80211_rx_ampdu *, int, int, int);
388200536Syongari	void			(*sc_ampdu_rx_stop)(struct ieee80211_node *,
389135048Swpaul				    struct ieee80211_rx_ampdu *);
390135048Swpaul	int			(*sc_addba_request)(struct ieee80211_node *,
391135048Swpaul				    struct ieee80211_tx_ampdu *, int, int, int);
392200540Syongari	int			(*sc_addba_response)(struct ieee80211_node *,
393200536Syongari				    struct ieee80211_tx_ampdu *, int, int, int);
394135048Swpaul	void			(*sc_addba_stop)(struct ieee80211_node *,
395135048Swpaul				    struct ieee80211_tx_ampdu *);
396135048Swpaul
397135048Swpaul	struct	iwn_led_mode sc_led;
398135048Swpaul
399135048Swpaul	struct iwn_rx_radiotap_header sc_rxtap;
400135048Swpaul	struct iwn_tx_radiotap_header sc_txtap;
401135048Swpaul
402135048Swpaul	/* The power save level originally configured by user */
403135048Swpaul	int			desired_pwrsave_level;
404135048Swpaul
405135048Swpaul	/*
406135048Swpaul	 * The current power save level, this may differ from the
407135048Swpaul	 * configured value due to thermal throttling etc.
408135048Swpaul	 */
409135048Swpaul	int			current_pwrsave_level;
410135048Swpaul
411135048Swpaul	/* For specific params */
412135048Swpaul	const struct iwn_base_params *base_params;
413135048Swpaul};
414135048Swpaul
415135048Swpaul#define IWN_LOCK_INIT(_sc) \
416135048Swpaul	mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
417135048Swpaul	    MTX_NETWORK_LOCK, MTX_DEF)
418135048Swpaul#define IWN_LOCK(_sc)			mtx_lock(&(_sc)->sc_mtx)
419135048Swpaul#define IWN_LOCK_ASSERT(_sc)		mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
420135048Swpaul#define IWN_UNLOCK(_sc)			mtx_unlock(&(_sc)->sc_mtx)
421135048Swpaul#define IWN_LOCK_DESTROY(_sc)		mtx_destroy(&(_sc)->sc_mtx)
422135048Swpaul