1 /*-
2  * Copyright (c) 2020-2023 The FreeBSD Foundation
3  * Copyright (c) 2020-2021 Bjoern A. Zeeb
4  *
5  * This software was developed by Björn Zeeb under sponsorship from
6  * the FreeBSD Foundation.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 /*
31  * Public functions are called linuxkpi_*().
32  * Internal (static) functions are called lkpi_*().
33  *
34  * The internal structures holding metadata over public structures are also
35  * called lkpi_xxx (usually with a member at the end called xxx).
36  * Note: we do not replicate the structure names but the general variable names
37  * for these (e.g., struct hw -> struct lkpi_hw, struct sta -> struct lkpi_sta).
38  * There are macros to access one from the other.
39  * We call the internal versions lxxx (e.g., hw -> lhw, sta -> lsta).
40  */
41 
42 #ifndef _LKPI_SRC_LINUX_80211_H
43 #define _LKPI_SRC_LINUX_80211_H
44 
45 /* #define	LINUXKPI_DEBUG_80211 */
46 
47 #ifndef	D80211_TODO
48 #define	D80211_TODO		0x1
49 #endif
50 #ifndef D80211_IMPROVE
51 #define	D80211_IMPROVE		0x2
52 #endif
53 #define	D80211_IMPROVE_TXQ	0x4
54 #define	D80211_TRACE		0x10
55 #define	D80211_TRACEOK		0x20
56 #define	D80211_TRACE_TX		0x100
57 #define	D80211_TRACE_TX_DUMP	0x200
58 #define	D80211_TRACE_RX		0x1000
59 #define	D80211_TRACE_RX_DUMP	0x2000
60 #define	D80211_TRACE_RX_BEACONS	0x4000
61 #define	D80211_TRACEX		(D80211_TRACE_TX|D80211_TRACE_RX)
62 #define	D80211_TRACEX_DUMP	(D80211_TRACE_TX_DUMP|D80211_TRACE_RX_DUMP)
63 #define	D80211_TRACE_STA	0x10000
64 #define	D80211_TRACE_MO		0x100000
65 
66 #define	IMPROVE_TXQ(...)						\
67     if (linuxkpi_debug_80211 & D80211_IMPROVE_TXQ)			\
68 	printf("%s:%d: XXX LKPI80211 IMPROVE_TXQ\n", __func__, __LINE__)
69 
70 struct lkpi_radiotap_tx_hdr {
71 	struct ieee80211_radiotap_header wt_ihdr;
72 	uint8_t		wt_flags;
73 	uint8_t		wt_rate;
74 	uint16_t	wt_chan_freq;
75 	uint16_t	wt_chan_flags;
76 } __packed;
77 #define	LKPI_RTAP_TX_FLAGS_PRESENT					\
78 	((1 << IEEE80211_RADIOTAP_FLAGS) |				\
79 	 (1 << IEEE80211_RADIOTAP_RATE) |				\
80 	 (1 << IEEE80211_RADIOTAP_CHANNEL))
81 
82 struct lkpi_radiotap_rx_hdr {
83 	struct ieee80211_radiotap_header wr_ihdr;
84 	uint64_t	wr_tsft;
85 	uint8_t		wr_flags;
86 	uint8_t		wr_rate;
87 	uint16_t	wr_chan_freq;
88 	uint16_t	wr_chan_flags;
89 	int8_t		wr_dbm_antsignal;
90 	int8_t		wr_dbm_antnoise;
91 } __packed __aligned(8);
92 #define	LKPI_RTAP_RX_FLAGS_PRESENT					\
93 	((1 << IEEE80211_RADIOTAP_TSFT) |				\
94 	 (1 << IEEE80211_RADIOTAP_FLAGS) |				\
95 	 (1 << IEEE80211_RADIOTAP_RATE) |				\
96 	 (1 << IEEE80211_RADIOTAP_CHANNEL) |				\
97 	 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |			\
98 	 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE))
99 
100 struct lkpi_txq {
101 	TAILQ_ENTRY(lkpi_txq)	txq_entry;
102 
103 	bool			seen_dequeue;
104 	bool			stopped;
105 	uint32_t		txq_generation;
106 	struct sk_buff_head	skbq;
107 
108 	/* Must be last! */
109 	struct ieee80211_txq	txq __aligned(CACHE_LINE_SIZE);
110 };
111 #define	TXQ_TO_LTXQ(_txq)	container_of(_txq, struct lkpi_txq, txq)
112 
113 
114 struct lkpi_sta {
115         TAILQ_ENTRY(lkpi_sta)	lsta_entry;
116 	struct ieee80211_node	*ni;
117 
118 	/* Deferred TX path. */
119 	/* Eventually we might want to migrate this into net80211 entirely. */
120 	/* XXX-BZ can we use sta->txq[] instead directly? */
121 	struct task		txq_task;
122 	struct mbufq		txq;
123 	struct mtx		txq_mtx;
124 
125 	struct ieee80211_key_conf *kc;
126 	enum ieee80211_sta_state state;
127 	bool			added_to_drv;			/* Driver knows; i.e. we called ...(). */
128 	bool			in_mgd;				/* XXX-BZ should this be per-vif? */
129 
130 	/* Must be last! */
131 	struct ieee80211_sta	sta __aligned(CACHE_LINE_SIZE);
132 };
133 #define	STA_TO_LSTA(_sta)	container_of(_sta, struct lkpi_sta, sta)
134 #define	LSTA_TO_STA(_lsta)	(&(_lsta)->sta)
135 
136 struct lkpi_vif {
137         TAILQ_ENTRY(lkpi_vif)	lvif_entry;
138 	struct ieee80211vap	iv_vap;
139 
140 	struct mtx		mtx;
141 	struct wireless_dev	wdev;
142 
143 	/* Other local stuff. */
144 	int			(*iv_newstate)(struct ieee80211vap *,
145 				    enum ieee80211_state, int);
146 	struct ieee80211_node *	(*iv_update_bss)(struct ieee80211vap *,
147 				    struct ieee80211_node *);
148 	TAILQ_HEAD(, lkpi_sta)	lsta_head;
149 	bool			added_to_drv;			/* Driver knows; i.e. we called add_interface(). */
150 
151 	bool			hw_queue_stopped[IEEE80211_NUM_ACS];
152 
153 	/* Must be last! */
154 	struct ieee80211_vif	vif __aligned(CACHE_LINE_SIZE);
155 };
156 #define	VAP_TO_LVIF(_vap)	container_of(_vap, struct lkpi_vif, iv_vap)
157 #define	LVIF_TO_VAP(_lvif)	(&(_lvif)->iv_vap)
158 #define	VIF_TO_LVIF(_vif)	container_of(_vif, struct lkpi_vif, vif)
159 #define	LVIF_TO_VIF(_lvif)	(&(_lvif)->vif)
160 
161 
162 struct lkpi_hw {	/* name it mac80211_sc? */
163 	const struct ieee80211_ops	*ops;
164 	struct ieee80211_scan_request	*hw_req;
165 	struct workqueue_struct		*workq;
166 
167 	/* FreeBSD specific compat. */
168 	/* Linux device is in hw.wiphy->dev after SET_IEEE80211_DEV(). */
169 	struct ieee80211com		*ic;
170 	struct lkpi_radiotap_tx_hdr	rtap_tx;
171 	struct lkpi_radiotap_rx_hdr	rtap_rx;
172 
173 	TAILQ_HEAD(, lkpi_vif)		lvif_head;
174 	struct sx			lvif_sx;
175 
176 	struct sx			sx;
177 
178 	uint32_t			txq_generation[IEEE80211_NUM_ACS];
179 	TAILQ_HEAD(, lkpi_txq)		scheduled_txqs[IEEE80211_NUM_ACS];
180 
181 	/* Scan functions we overload to handle depending on scan mode. */
182 	void                    (*ic_scan_curchan)(struct ieee80211_scan_state *,
183 				    unsigned long);
184 	void                    (*ic_scan_mindwell)(struct ieee80211_scan_state *);
185 
186 	/* Node functions we overload to sync state. */
187 	struct ieee80211_node *	(*ic_node_alloc)(struct ieee80211vap *,
188 				    const uint8_t [IEEE80211_ADDR_LEN]);
189 	int			(*ic_node_init)(struct ieee80211_node *);
190 	void			(*ic_node_cleanup)(struct ieee80211_node *);
191 	void			(*ic_node_free)(struct ieee80211_node *);
192 
193 #define	LKPI_MAC80211_DRV_STARTED	0x00000001
194 	uint32_t			sc_flags;
195 #define	LKPI_LHW_SCAN_RUNNING		0x00000001
196 #define	LKPI_LHW_SCAN_HW		0x00000002
197 	uint32_t			scan_flags;
198 	struct mtx			scan_mtx;
199 
200 	int				supbands;	/* Number of supported bands. */
201 	int				max_rates;	/* Maximum number of bitrates supported in any channel. */
202 	int				scan_ie_len;	/* Length of common per-band scan IEs. */
203 
204 	bool				update_mc;
205 	bool				update_wme;
206 
207 	/* Must be last! */
208 	struct ieee80211_hw		hw __aligned(CACHE_LINE_SIZE);
209 };
210 #define	LHW_TO_HW(_lhw)		(&(_lhw)->hw)
211 #define	HW_TO_LHW(_hw)		container_of(_hw, struct lkpi_hw, hw)
212 
213 struct lkpi_wiphy {
214 	const struct cfg80211_ops	*ops;
215 
216 	/* Must be last! */
217 	struct wiphy			wiphy __aligned(CACHE_LINE_SIZE);
218 };
219 #define	WIPHY_TO_LWIPHY(_wiphy)	container_of(_wiphy, struct lkpi_wiphy, wiphy)
220 #define	LWIPHY_TO_WIPHY(_lwiphy)	(&(_lwiphy)->wiphy)
221 
222 #define	LKPI_80211_LHW_LOCK_INIT(_lhw)			\
223     sx_init_flags(&(_lhw)->sx, "lhw", SX_RECURSE);
224 #define	LKPI_80211_LHW_LOCK_DESTROY(_lhw)		\
225     sx_destroy(&(_lhw)->sx);
226 #define	LKPI_80211_LHW_LOCK(_lhw)			\
227     sx_xlock(&(_lhw)->sx)
228 #define	LKPI_80211_LHW_UNLOCK(_lhw)			\
229     sx_xunlock(&(_lhw)->sx)
230 #define	LKPI_80211_LHW_LOCK_ASSERT(_lhw)		\
231     sx_assert(&(_lhw)->sx, SA_LOCKED)
232 #define	LKPI_80211_LHW_UNLOCK_ASSERT(_lhw)		\
233     sx_assert(&(_lhw)->sx, SA_UNLOCKED)
234 
235 #define	LKPI_80211_LHW_SCAN_LOCK_INIT(_lhw)		\
236     mtx_init(&(_lhw)->scan_mtx, "lhw-scan", NULL, MTX_DEF | MTX_RECURSE);
237 #define	LKPI_80211_LHW_SCAN_LOCK_DESTROY(_lhw)		\
238     mtx_destroy(&(_lhw)->scan_mtx);
239 #define	LKPI_80211_LHW_SCAN_LOCK(_lhw)			\
240     mtx_lock(&(_lhw)->scan_mtx)
241 #define	LKPI_80211_LHW_SCAN_UNLOCK(_lhw)        	\
242     mtx_unlock(&(_lhw)->scan_mtx)
243 #define	LKPI_80211_LHW_SCAN_LOCK_ASSERT(_lhw)		\
244     mtx_assert(&(_lhw)->scan_mtx, MA_OWNED)
245 #define	LKPI_80211_LHW_SCAN_UNLOCK_ASSERT(_lhw)		\
246     mtx_assert(&(_lhw)->scan_mtx, MA_NOTOWNED)
247 
248 #define	LKPI_80211_LHW_LVIF_LOCK(_lhw)	sx_xlock(&(_lhw)->lvif_sx)
249 #define	LKPI_80211_LHW_LVIF_UNLOCK(_lhw) sx_xunlock(&(_lhw)->lvif_sx)
250 
251 #define	LKPI_80211_LVIF_LOCK(_lvif)	mtx_lock(&(_lvif)->mtx)
252 #define	LKPI_80211_LVIF_UNLOCK(_lvif)	mtx_unlock(&(_lvif)->mtx)
253 
254 #define	LKPI_80211_LSTA_LOCK(_lsta)	mtx_lock(&(_lsta)->txq_mtx)
255 #define	LKPI_80211_LSTA_UNLOCK(_lsta)	mtx_unlock(&(_lsta)->txq_mtx)
256 
257 
258 int lkpi_80211_mo_start(struct ieee80211_hw *);
259 void lkpi_80211_mo_stop(struct ieee80211_hw *);
260 int lkpi_80211_mo_get_antenna(struct ieee80211_hw *, u32 *, u32 *);
261 int lkpi_80211_mo_set_frag_threshold(struct ieee80211_hw *, uint32_t);
262 int lkpi_80211_mo_set_rts_threshold(struct ieee80211_hw *, uint32_t);
263 int lkpi_80211_mo_add_interface(struct ieee80211_hw *, struct ieee80211_vif *);
264 void lkpi_80211_mo_remove_interface(struct ieee80211_hw *, struct ieee80211_vif *);
265 int lkpi_80211_mo_hw_scan(struct ieee80211_hw *, struct ieee80211_vif *,
266     struct ieee80211_scan_request *);
267 void lkpi_80211_mo_cancel_hw_scan(struct ieee80211_hw *, struct ieee80211_vif *);
268 void lkpi_80211_mo_sw_scan_complete(struct ieee80211_hw *, struct ieee80211_vif *);
269 void lkpi_80211_mo_sw_scan_start(struct ieee80211_hw *, struct ieee80211_vif *,
270     const u8 *);
271 u64 lkpi_80211_mo_prepare_multicast(struct ieee80211_hw *,
272     struct netdev_hw_addr_list *);
273 void lkpi_80211_mo_configure_filter(struct ieee80211_hw *, unsigned int,
274     unsigned int *, u64);
275 int lkpi_80211_mo_sta_state(struct ieee80211_hw *, struct ieee80211_vif *,
276     struct lkpi_sta *, enum ieee80211_sta_state);
277 int lkpi_80211_mo_config(struct ieee80211_hw *, uint32_t);
278 int lkpi_80211_mo_assign_vif_chanctx(struct ieee80211_hw *, struct ieee80211_vif *,
279     struct ieee80211_chanctx_conf *);
280 void lkpi_80211_mo_unassign_vif_chanctx(struct ieee80211_hw *, struct ieee80211_vif *,
281     struct ieee80211_chanctx_conf **);
282 int lkpi_80211_mo_add_chanctx(struct ieee80211_hw *, struct ieee80211_chanctx_conf *);
283 void lkpi_80211_mo_change_chanctx(struct ieee80211_hw *,
284     struct ieee80211_chanctx_conf *, uint32_t);
285 void lkpi_80211_mo_remove_chanctx(struct ieee80211_hw *,
286     struct ieee80211_chanctx_conf *);
287 void lkpi_80211_mo_bss_info_changed(struct ieee80211_hw *, struct ieee80211_vif *,
288     struct ieee80211_bss_conf *, uint64_t);
289 int lkpi_80211_mo_conf_tx(struct ieee80211_hw *, struct ieee80211_vif *,
290     uint16_t, const struct ieee80211_tx_queue_params *);
291 void lkpi_80211_mo_flush(struct ieee80211_hw *, struct ieee80211_vif *,
292     uint32_t, bool);
293 void lkpi_80211_mo_mgd_prepare_tx(struct ieee80211_hw *, struct ieee80211_vif *,
294     struct ieee80211_prep_tx_info *);
295 void lkpi_80211_mo_mgd_complete_tx(struct ieee80211_hw *, struct ieee80211_vif *,
296     struct ieee80211_prep_tx_info *);
297 void lkpi_80211_mo_tx(struct ieee80211_hw *, struct ieee80211_tx_control *,
298     struct sk_buff *);
299 void lkpi_80211_mo_wake_tx_queue(struct ieee80211_hw *, struct ieee80211_txq *);
300 void lkpi_80211_mo_sync_rx_queues(struct ieee80211_hw *);
301 void lkpi_80211_mo_sta_pre_rcu_remove(struct ieee80211_hw *,
302     struct ieee80211_vif *, struct ieee80211_sta *);
303 int lkpi_80211_mo_set_key(struct ieee80211_hw *, enum set_key_cmd,
304     struct ieee80211_vif *, struct ieee80211_sta *,
305     struct ieee80211_key_conf *);
306 
307 #endif	/* _LKPI_SRC_LINUX_80211_H */
308