1
2/*-
3 * Copyright (c) 2006,2007
4 *	Damien Bergamini <damien.bergamini@free.fr>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18struct wpi_rx_radiotap_header {
19	struct ieee80211_radiotap_header wr_ihdr;
20	uint64_t	wr_tsft;
21	uint8_t		wr_flags;
22	uint8_t		wr_rate;
23	uint16_t	wr_chan_freq;
24	uint16_t	wr_chan_flags;
25	int8_t		wr_dbm_antsignal;
26	int8_t		wr_dbm_antnoise;
27	uint8_t		wr_antenna;
28} __packed __aligned(8);
29
30#define WPI_RX_RADIOTAP_PRESENT						\
31	((1 << IEEE80211_RADIOTAP_TSFT) |				\
32	 (1 << IEEE80211_RADIOTAP_FLAGS) |				\
33	 (1 << IEEE80211_RADIOTAP_RATE) |				\
34	 (1 << IEEE80211_RADIOTAP_CHANNEL) |				\
35	 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |			\
36	 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |			\
37	 (1 << IEEE80211_RADIOTAP_ANTENNA))
38
39struct wpi_tx_radiotap_header {
40	struct ieee80211_radiotap_header wt_ihdr;
41	uint8_t		wt_flags;
42	uint8_t		wt_rate;
43	uint16_t	wt_chan_freq;
44	uint16_t	wt_chan_flags;
45} __packed;
46
47#define WPI_TX_RADIOTAP_PRESENT						\
48	((1 << IEEE80211_RADIOTAP_FLAGS) |				\
49	 (1 << IEEE80211_RADIOTAP_RATE) |				\
50	 (1 << IEEE80211_RADIOTAP_CHANNEL))
51
52struct wpi_dma_info {
53	bus_dma_tag_t		tag;
54	bus_dmamap_t		map;
55	bus_addr_t		paddr;
56	caddr_t			vaddr;
57	bus_size_t		size;
58};
59
60struct wpi_tx_data {
61	bus_dmamap_t		map;
62	bus_addr_t		cmd_paddr;
63	struct mbuf		*m;
64	struct ieee80211_node	*ni;
65	int			hdrlen;
66};
67
68struct wpi_tx_ring {
69	struct wpi_dma_info	desc_dma;
70	struct wpi_dma_info	cmd_dma;
71	struct wpi_tx_desc	*desc;
72	struct wpi_tx_cmd	*cmd;
73	struct wpi_tx_data	data[WPI_TX_RING_COUNT];
74	bus_dma_tag_t		data_dmat;
75	uint8_t			qid;
76	uint8_t			cur;
77	uint8_t			pending;
78	int16_t			queued;
79	bool			update:1;
80};
81
82struct wpi_rx_data {
83	struct mbuf	*m;
84	bus_dmamap_t	map;
85};
86
87struct wpi_rx_ring {
88	struct wpi_dma_info	desc_dma;
89	uint32_t		*desc;
90	struct wpi_rx_data	data[WPI_RX_RING_COUNT];
91	bus_dma_tag_t		data_dmat;
92	uint16_t		cur;
93	int			update;
94};
95
96struct wpi_node {
97	struct ieee80211_node	ni;	/* must be the first */
98	uint8_t			id;
99};
100#define WPI_NODE(ni)	((struct wpi_node *)(ni))
101
102struct wpi_power_sample {
103	uint8_t	index;
104	int8_t	power;
105};
106
107struct wpi_power_group {
108#define WPI_SAMPLES_COUNT	5
109	struct wpi_power_sample samples[WPI_SAMPLES_COUNT];
110	uint8_t	chan;
111	int8_t	maxpwr;
112	int16_t	temp;
113};
114
115struct wpi_buf {
116	uint8_t			data[56];  /* sizeof(struct wpi_cmd_beacon) */
117	struct ieee80211_node	*ni;
118	struct mbuf		*m;
119	size_t			size;
120	uint8_t			code;
121	uint16_t		ac;
122};
123
124struct wpi_vap {
125	struct ieee80211vap	wv_vap;
126
127	struct wpi_buf		wv_bcbuf;
128	struct mtx		wv_mtx;
129
130	uint8_t			wv_gtk;
131#define WPI_VAP_KEY(kid)	(1 << kid)
132
133	int			(*wv_newstate)(struct ieee80211vap *,
134				    enum ieee80211_state, int);
135	void			(*wv_recv_mgmt)(struct ieee80211_node *,
136				    struct mbuf *, int,
137				    const struct ieee80211_rx_stats *,
138				    int, int);
139};
140#define	WPI_VAP(vap)	((struct wpi_vap *)(vap))
141
142#define WPI_VAP_LOCK_INIT(_wvp)	\
143	mtx_init(&(_wvp)->wv_mtx, "lock for wv_bcbuf/wv_boff structures", \
144	    NULL, MTX_DEF)
145#define WPI_VAP_LOCK(_wvp)		mtx_lock(&(_wvp)->wv_mtx)
146#define WPI_VAP_UNLOCK(_wvp)		mtx_unlock(&(_wvp)->wv_mtx)
147#define WPI_VAP_LOCK_ASSERT(_wvp)	mtx_assert(&(_wvp)->wv_mtx, MA_OWNED)
148#define WPI_VAP_LOCK_DESTROY(_wvp)	mtx_destroy(&(_wvp)->wv_mtx)
149
150struct wpi_fw_part {
151	const uint8_t	*text;
152	uint32_t	textsz;
153	const uint8_t	*data;
154	uint32_t	datasz;
155};
156
157struct wpi_fw_info {
158	const uint8_t		*data;
159	size_t			size;
160	struct wpi_fw_part	init;
161	struct wpi_fw_part	main;
162	struct wpi_fw_part	boot;
163};
164
165struct wpi_softc {
166	device_t		sc_dev;
167	int			sc_debug;
168
169	int			sc_running;
170
171	struct mtx		sc_mtx;
172	struct ieee80211com	sc_ic;
173	struct ieee80211_ratectl_tx_status sc_txs;
174
175	struct mtx		tx_mtx;
176
177	/* Shared area. */
178	struct wpi_dma_info	shared_dma;
179	struct wpi_shared	*shared;
180
181	struct wpi_tx_ring	txq[WPI_DRV_NTXQUEUES];
182	struct mtx		txq_mtx;
183	struct mtx		txq_state_mtx;
184
185	struct wpi_rx_ring	rxq;
186	uint64_t		rx_tstamp;
187
188	/* TX Thermal Callibration. */
189	struct callout		calib_to;
190
191	struct callout		scan_timeout;
192	struct callout		tx_timeout;
193
194	/* Watch dog timer. */
195	struct callout		watchdog_rfkill;
196
197	/* Firmware image. */
198	struct wpi_fw_info	fw;
199	uint32_t		errptr;
200
201	struct resource		*irq;
202	struct resource		*mem;
203	bus_space_tag_t		sc_st;
204	bus_space_handle_t	sc_sh;
205	void			*sc_ih;
206	bus_size_t		sc_sz;
207	int			sc_cap_off;	/* PCIe Capabilities. */
208
209	struct wpi_rxon		rxon;
210	struct mtx		rxon_mtx;
211
212	int			temp;
213
214	uint32_t		nodesmsk;
215	struct mtx		nt_mtx;
216
217	void			(*sc_node_free)(struct ieee80211_node *);
218	void			(*sc_update_rx_ring)(struct wpi_softc *);
219	void			(*sc_update_tx_ring)(struct wpi_softc *,
220				    struct wpi_tx_ring *);
221
222	struct wpi_rx_radiotap_header	sc_rxtap;
223	struct wpi_tx_radiotap_header	sc_txtap;
224
225	/* Firmware image. */
226	const struct firmware	*fw_fp;
227
228	/* Firmware DMA transfer. */
229	struct wpi_dma_info	fw_dma;
230
231	/* Tasks used by the driver. */
232	struct task		sc_radiooff_task;
233	struct task		sc_radioon_task;
234
235	/* Eeprom info. */
236	uint8_t			cap;
237	uint16_t		rev;
238	uint8_t			type;
239	struct wpi_eeprom_chan
240	    eeprom_channels[WPI_CHAN_BANDS_COUNT][WPI_MAX_CHAN_PER_BAND];
241	struct wpi_power_group	groups[WPI_POWER_GROUPS_COUNT];
242	int8_t			maxpwr[IEEE80211_CHAN_MAX];
243	char			domain[4];	/* Regulatory domain. */
244};
245
246/*
247 * Locking order:
248 * 1. WPI_LOCK;
249 * 2. WPI_RXON_LOCK;
250 * 3. WPI_TX_LOCK;
251 * 4. WPI_NT_LOCK / WPI_VAP_LOCK;
252 * 5. WPI_TXQ_LOCK;
253 * 6. WPI_TXQ_STATE_LOCK;
254 */
255
256#define WPI_LOCK_INIT(_sc) \
257	mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
258	    MTX_NETWORK_LOCK, MTX_DEF)
259#define WPI_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
260#define WPI_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
261#define WPI_LOCK_ASSERT(_sc)	mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
262#define WPI_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->sc_mtx)
263
264#define WPI_RXON_LOCK_INIT(_sc) \
265	mtx_init(&(_sc)->rxon_mtx, "lock for wpi_rxon structure", NULL, MTX_DEF)
266#define WPI_RXON_LOCK(_sc)		mtx_lock(&(_sc)->rxon_mtx)
267#define WPI_RXON_UNLOCK(_sc)		mtx_unlock(&(_sc)->rxon_mtx)
268#define WPI_RXON_LOCK_ASSERT(_sc)	mtx_assert(&(_sc)->rxon_mtx, MA_OWNED)
269#define WPI_RXON_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->rxon_mtx)
270
271#define WPI_TX_LOCK_INIT(_sc) \
272	mtx_init(&(_sc)->tx_mtx, "tx path lock", NULL, MTX_DEF)
273#define WPI_TX_LOCK(_sc)		mtx_lock(&(_sc)->tx_mtx)
274#define WPI_TX_UNLOCK(_sc)		mtx_unlock(&(_sc)->tx_mtx)
275#define WPI_TX_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->tx_mtx)
276
277#define WPI_NT_LOCK_INIT(_sc) \
278	mtx_init(&(_sc)->nt_mtx, "node table lock", NULL, MTX_DEF)
279#define WPI_NT_LOCK(_sc)		mtx_lock(&(_sc)->nt_mtx)
280#define WPI_NT_UNLOCK(_sc)		mtx_unlock(&(_sc)->nt_mtx)
281#define WPI_NT_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->nt_mtx)
282
283#define WPI_TXQ_LOCK_INIT(_sc) \
284	mtx_init(&(_sc)->txq_mtx, "txq/cmdq lock", NULL, MTX_DEF)
285#define WPI_TXQ_LOCK(_sc)		mtx_lock(&(_sc)->txq_mtx)
286#define WPI_TXQ_UNLOCK(_sc)		mtx_unlock(&(_sc)->txq_mtx)
287#define WPI_TXQ_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->txq_mtx)
288
289#define WPI_TXQ_STATE_LOCK_INIT(_sc) \
290	mtx_init(&(_sc)->txq_state_mtx, "txq state lock", NULL, MTX_DEF)
291#define WPI_TXQ_STATE_LOCK(_sc)		mtx_lock(&(_sc)->txq_state_mtx)
292#define WPI_TXQ_STATE_UNLOCK(_sc)	mtx_unlock(&(_sc)->txq_state_mtx)
293#define WPI_TXQ_STATE_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->txq_state_mtx)
294