2 * Copyright (c) 2020-2023 The FreeBSD Foundation
3 * Copyright (c) 2020-2021 Bjoern A. Zeeb
5 * This software was developed by Björn Zeeb under sponsorship from
6 * the FreeBSD Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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
31 * Public functions are called linuxkpi_*().
32 * Internal (static) functions are called lkpi_*().
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).
42 #ifndef _LKPI_SRC_LINUX_80211_H
43 #define _LKPI_SRC_LINUX_80211_H
45 /* #define LINUXKPI_DEBUG_80211 */
48 #define D80211_TODO 0x00000001
50 #ifndef D80211_IMPROVE
51 #define D80211_IMPROVE 0x00000002
53 #define D80211_IMPROVE_TXQ 0x00000004
54 #define D80211_TRACE 0x00000010
55 #define D80211_TRACEOK 0x00000020
56 #define D80211_TRACE_TX 0x00000100
57 #define D80211_TRACE_TX_DUMP 0x00000200
58 #define D80211_TRACE_RX 0x00001000
59 #define D80211_TRACE_RX_DUMP 0x00002000
60 #define D80211_TRACE_RX_BEACONS 0x00004000
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 0x00010000
64 #define D80211_TRACE_MO 0x00100000
66 #define IMPROVE_TXQ(...) \
67 if (linuxkpi_debug_80211 & D80211_IMPROVE_TXQ) \
68 printf("%s:%d: XXX LKPI80211 IMPROVE_TXQ\n", __func__, __LINE__)
70 struct lkpi_radiotap_tx_hdr {
71 struct ieee80211_radiotap_header wt_ihdr;
74 uint16_t wt_chan_freq;
75 uint16_t wt_chan_flags;
77 #define LKPI_RTAP_TX_FLAGS_PRESENT \
78 ((1 << IEEE80211_RADIOTAP_FLAGS) | \
79 (1 << IEEE80211_RADIOTAP_RATE) | \
80 (1 << IEEE80211_RADIOTAP_CHANNEL))
82 struct lkpi_radiotap_rx_hdr {
83 struct ieee80211_radiotap_header wr_ihdr;
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))
101 TAILQ_ENTRY(lkpi_txq) txq_entry;
106 uint32_t txq_generation;
107 struct sk_buff_head skbq;
110 struct ieee80211_txq txq __aligned(CACHE_LINE_SIZE);
112 #define TXQ_TO_LTXQ(_txq) container_of(_txq, struct lkpi_txq, txq)
116 TAILQ_ENTRY(lkpi_sta) lsta_entry;
117 struct ieee80211_node *ni;
119 /* Deferred TX path. */
120 /* Eventually we might want to migrate this into net80211 entirely. */
121 /* XXX-BZ can we use sta->txq[] instead directly? */
122 struct task txq_task;
126 struct ieee80211_key_conf *kc;
127 enum ieee80211_sta_state state;
128 bool txq_ready; /* Can we run the taskq? */
129 bool added_to_drv; /* Driver knows; i.e. we called ...(). */
130 bool in_mgd; /* XXX-BZ should this be per-vif? */
133 struct ieee80211_sta sta __aligned(CACHE_LINE_SIZE);
135 #define STA_TO_LSTA(_sta) container_of(_sta, struct lkpi_sta, sta)
136 #define LSTA_TO_STA(_lsta) (&(_lsta)->sta)
139 TAILQ_ENTRY(lkpi_vif) lvif_entry;
140 struct ieee80211vap iv_vap;
143 struct wireless_dev wdev;
145 /* Other local stuff. */
146 int (*iv_newstate)(struct ieee80211vap *,
147 enum ieee80211_state, int);
148 struct ieee80211_node * (*iv_update_bss)(struct ieee80211vap *,
149 struct ieee80211_node *);
150 TAILQ_HEAD(, lkpi_sta) lsta_head;
151 struct lkpi_sta *lvif_bss;
152 bool lvif_bss_synched;
153 bool added_to_drv; /* Driver knows; i.e. we called add_interface(). */
155 bool hw_queue_stopped[IEEE80211_NUM_ACS];
158 struct ieee80211_vif vif __aligned(CACHE_LINE_SIZE);
160 #define VAP_TO_LVIF(_vap) container_of(_vap, struct lkpi_vif, iv_vap)
161 #define LVIF_TO_VAP(_lvif) (&(_lvif)->iv_vap)
162 #define VIF_TO_LVIF(_vif) container_of(_vif, struct lkpi_vif, vif)
163 #define LVIF_TO_VIF(_lvif) (&(_lvif)->vif)
166 struct lkpi_hw { /* name it mac80211_sc? */
167 const struct ieee80211_ops *ops;
168 struct ieee80211_scan_request *hw_req;
169 struct workqueue_struct *workq;
171 /* FreeBSD specific compat. */
172 /* Linux device is in hw.wiphy->dev after SET_IEEE80211_DEV(). */
173 struct ieee80211com *ic;
174 struct lkpi_radiotap_tx_hdr rtap_tx;
175 struct lkpi_radiotap_rx_hdr rtap_rx;
177 TAILQ_HEAD(, lkpi_vif) lvif_head;
183 uint32_t txq_generation[IEEE80211_NUM_ACS];
184 TAILQ_HEAD(, lkpi_txq) scheduled_txqs[IEEE80211_NUM_ACS];
186 /* Scan functions we overload to handle depending on scan mode. */
187 void (*ic_scan_curchan)(struct ieee80211_scan_state *,
189 void (*ic_scan_mindwell)(struct ieee80211_scan_state *);
191 /* Node functions we overload to sync state. */
192 struct ieee80211_node * (*ic_node_alloc)(struct ieee80211vap *,
193 const uint8_t [IEEE80211_ADDR_LEN]);
194 int (*ic_node_init)(struct ieee80211_node *);
195 void (*ic_node_cleanup)(struct ieee80211_node *);
196 void (*ic_node_free)(struct ieee80211_node *);
198 #define LKPI_MAC80211_DRV_STARTED 0x00000001
200 #define LKPI_LHW_SCAN_RUNNING 0x00000001
201 #define LKPI_LHW_SCAN_HW 0x00000002
205 int supbands; /* Number of supported bands. */
206 int max_rates; /* Maximum number of bitrates supported in any channel. */
207 int scan_ie_len; /* Length of common per-band scan IEs. */
213 struct ieee80211_hw hw __aligned(CACHE_LINE_SIZE);
215 #define LHW_TO_HW(_lhw) (&(_lhw)->hw)
216 #define HW_TO_LHW(_hw) container_of(_hw, struct lkpi_hw, hw)
218 struct lkpi_chanctx {
219 bool added_to_drv; /* Managed by MO */
220 struct ieee80211_chanctx_conf conf __aligned(CACHE_LINE_SIZE);
222 #define LCHANCTX_TO_CHANCTX_CONF(_lchanctx) \
224 #define CHANCTX_CONF_TO_LCHANCTX(_conf) \
225 container_of(_conf, struct lkpi_chanctx, conf)
228 const struct cfg80211_ops *ops;
231 struct wiphy wiphy __aligned(CACHE_LINE_SIZE);
233 #define WIPHY_TO_LWIPHY(_wiphy) container_of(_wiphy, struct lkpi_wiphy, wiphy)
234 #define LWIPHY_TO_WIPHY(_lwiphy) (&(_lwiphy)->wiphy)
236 #define LKPI_80211_LHW_LOCK_INIT(_lhw) \
237 sx_init_flags(&(_lhw)->sx, "lhw", SX_RECURSE);
238 #define LKPI_80211_LHW_LOCK_DESTROY(_lhw) \
239 sx_destroy(&(_lhw)->sx);
240 #define LKPI_80211_LHW_LOCK(_lhw) \
241 sx_xlock(&(_lhw)->sx)
242 #define LKPI_80211_LHW_UNLOCK(_lhw) \
243 sx_xunlock(&(_lhw)->sx)
244 #define LKPI_80211_LHW_LOCK_ASSERT(_lhw) \
245 sx_assert(&(_lhw)->sx, SA_LOCKED)
246 #define LKPI_80211_LHW_UNLOCK_ASSERT(_lhw) \
247 sx_assert(&(_lhw)->sx, SA_UNLOCKED)
249 #define LKPI_80211_LHW_SCAN_LOCK_INIT(_lhw) \
250 mtx_init(&(_lhw)->scan_mtx, "lhw-scan", NULL, MTX_DEF | MTX_RECURSE);
251 #define LKPI_80211_LHW_SCAN_LOCK_DESTROY(_lhw) \
252 mtx_destroy(&(_lhw)->scan_mtx);
253 #define LKPI_80211_LHW_SCAN_LOCK(_lhw) \
254 mtx_lock(&(_lhw)->scan_mtx)
255 #define LKPI_80211_LHW_SCAN_UNLOCK(_lhw) \
256 mtx_unlock(&(_lhw)->scan_mtx)
257 #define LKPI_80211_LHW_SCAN_LOCK_ASSERT(_lhw) \
258 mtx_assert(&(_lhw)->scan_mtx, MA_OWNED)
259 #define LKPI_80211_LHW_SCAN_UNLOCK_ASSERT(_lhw) \
260 mtx_assert(&(_lhw)->scan_mtx, MA_NOTOWNED)
262 #define LKPI_80211_LHW_TXQ_LOCK_INIT(_lhw) \
263 mtx_init(&(_lhw)->txq_mtx, "lhw-txq", NULL, MTX_DEF | MTX_RECURSE);
264 #define LKPI_80211_LHW_TXQ_LOCK_DESTROY(_lhw) \
265 mtx_destroy(&(_lhw)->txq_mtx);
266 #define LKPI_80211_LHW_TXQ_LOCK(_lhw) \
267 mtx_lock(&(_lhw)->txq_mtx)
268 #define LKPI_80211_LHW_TXQ_UNLOCK(_lhw) \
269 mtx_unlock(&(_lhw)->txq_mtx)
270 #define LKPI_80211_LHW_TXQ_LOCK_ASSERT(_lhw) \
271 mtx_assert(&(_lhw)->txq_mtx, MA_OWNED)
272 #define LKPI_80211_LHW_TXQ_UNLOCK_ASSERT(_lhw) \
273 mtx_assert(&(_lhw)->txq_mtx, MA_NOTOWNED)
275 #define LKPI_80211_LHW_LVIF_LOCK(_lhw) sx_xlock(&(_lhw)->lvif_sx)
276 #define LKPI_80211_LHW_LVIF_UNLOCK(_lhw) sx_xunlock(&(_lhw)->lvif_sx)
278 #define LKPI_80211_LVIF_LOCK(_lvif) mtx_lock(&(_lvif)->mtx)
279 #define LKPI_80211_LVIF_UNLOCK(_lvif) mtx_unlock(&(_lvif)->mtx)
281 #define LKPI_80211_LSTA_LOCK(_lsta) mtx_lock(&(_lsta)->txq_mtx)
282 #define LKPI_80211_LSTA_UNLOCK(_lsta) mtx_unlock(&(_lsta)->txq_mtx)
284 #define LKPI_80211_LTXQ_LOCK_INIT(_ltxq) \
285 mtx_init(&(_ltxq)->ltxq_mtx, "ltxq", NULL, MTX_DEF);
286 #define LKPI_80211_LTXQ_LOCK_DESTROY(_ltxq) \
287 mtx_destroy(&(_ltxq)->ltxq_mtx);
288 #define LKPI_80211_LTXQ_LOCK(_ltxq) \
289 mtx_lock(&(_ltxq)->ltxq_mtx)
290 #define LKPI_80211_LTXQ_UNLOCK(_ltxq) \
291 mtx_unlock(&(_ltxq)->ltxq_mtx)
292 #define LKPI_80211_LTXQ_LOCK_ASSERT(_ltxq) \
293 mtx_assert(&(_ltxq)->ltxq_mtx, MA_OWNED)
294 #define LKPI_80211_LTXQ_UNLOCK_ASSERT(_ltxq) \
295 mtx_assert(&(_ltxq)->ltxq_mtx, MA_NOTOWNED)
297 int lkpi_80211_mo_start(struct ieee80211_hw *);
298 void lkpi_80211_mo_stop(struct ieee80211_hw *);
299 int lkpi_80211_mo_get_antenna(struct ieee80211_hw *, u32 *, u32 *);
300 int lkpi_80211_mo_set_frag_threshold(struct ieee80211_hw *, uint32_t);
301 int lkpi_80211_mo_set_rts_threshold(struct ieee80211_hw *, uint32_t);
302 int lkpi_80211_mo_add_interface(struct ieee80211_hw *, struct ieee80211_vif *);
303 void lkpi_80211_mo_remove_interface(struct ieee80211_hw *, struct ieee80211_vif *);
304 int lkpi_80211_mo_hw_scan(struct ieee80211_hw *, struct ieee80211_vif *,
305 struct ieee80211_scan_request *);
306 void lkpi_80211_mo_cancel_hw_scan(struct ieee80211_hw *, struct ieee80211_vif *);
307 void lkpi_80211_mo_sw_scan_complete(struct ieee80211_hw *, struct ieee80211_vif *);
308 void lkpi_80211_mo_sw_scan_start(struct ieee80211_hw *, struct ieee80211_vif *,
310 u64 lkpi_80211_mo_prepare_multicast(struct ieee80211_hw *,
311 struct netdev_hw_addr_list *);
312 void lkpi_80211_mo_configure_filter(struct ieee80211_hw *, unsigned int,
313 unsigned int *, u64);
314 int lkpi_80211_mo_sta_state(struct ieee80211_hw *, struct ieee80211_vif *,
315 struct lkpi_sta *, enum ieee80211_sta_state);
316 int lkpi_80211_mo_config(struct ieee80211_hw *, uint32_t);
317 int lkpi_80211_mo_assign_vif_chanctx(struct ieee80211_hw *, struct ieee80211_vif *,
318 struct ieee80211_bss_conf *, struct ieee80211_chanctx_conf *);
319 void lkpi_80211_mo_unassign_vif_chanctx(struct ieee80211_hw *, struct ieee80211_vif *,
320 struct ieee80211_bss_conf *, struct ieee80211_chanctx_conf **);
321 int lkpi_80211_mo_add_chanctx(struct ieee80211_hw *, struct ieee80211_chanctx_conf *);
322 void lkpi_80211_mo_change_chanctx(struct ieee80211_hw *,
323 struct ieee80211_chanctx_conf *, uint32_t);
324 void lkpi_80211_mo_remove_chanctx(struct ieee80211_hw *,
325 struct ieee80211_chanctx_conf *);
326 void lkpi_80211_mo_bss_info_changed(struct ieee80211_hw *, struct ieee80211_vif *,
327 struct ieee80211_bss_conf *, uint64_t);
328 int lkpi_80211_mo_conf_tx(struct ieee80211_hw *, struct ieee80211_vif *,
329 uint32_t, uint16_t, const struct ieee80211_tx_queue_params *);
330 void lkpi_80211_mo_flush(struct ieee80211_hw *, struct ieee80211_vif *,
332 void lkpi_80211_mo_mgd_prepare_tx(struct ieee80211_hw *, struct ieee80211_vif *,
333 struct ieee80211_prep_tx_info *);
334 void lkpi_80211_mo_mgd_complete_tx(struct ieee80211_hw *, struct ieee80211_vif *,
335 struct ieee80211_prep_tx_info *);
336 void lkpi_80211_mo_tx(struct ieee80211_hw *, struct ieee80211_tx_control *,
338 void lkpi_80211_mo_wake_tx_queue(struct ieee80211_hw *, struct ieee80211_txq *);
339 void lkpi_80211_mo_sync_rx_queues(struct ieee80211_hw *);
340 void lkpi_80211_mo_sta_pre_rcu_remove(struct ieee80211_hw *,
341 struct ieee80211_vif *, struct ieee80211_sta *);
342 int lkpi_80211_mo_set_key(struct ieee80211_hw *, enum set_key_cmd,
343 struct ieee80211_vif *, struct ieee80211_sta *,
344 struct ieee80211_key_conf *);
346 #endif /* _LKPI_SRC_LINUX_80211_H */