1 /*-
2  * Copyright (c) 2020-2021 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 struct lkpi_radiotap_tx_hdr {
46 	struct ieee80211_radiotap_header wt_ihdr;
47 	uint8_t		wt_flags;
48 	uint8_t		wt_rate;
49 	uint16_t	wt_chan_freq;
50 	uint16_t	wt_chan_flags;
51 } __packed;
52 #define	LKPI_RTAP_TX_FLAGS_PRESENT					\
53 	((1 << IEEE80211_RADIOTAP_FLAGS) |				\
54 	 (1 << IEEE80211_RADIOTAP_RATE) |				\
55 	 (1 << IEEE80211_RADIOTAP_CHANNEL))
56 
57 struct lkpi_radiotap_rx_hdr {
58 	struct ieee80211_radiotap_header wr_ihdr;
59 	uint64_t	wr_tsft;
60 	uint8_t		wr_flags;
61 	uint8_t		wr_rate;
62 	uint16_t	wr_chan_freq;
63 	uint16_t	wr_chan_flags;
64 	int8_t		wr_dbm_antsignal;
65 	int8_t		wr_dbm_antnoise;
66 } __packed __aligned(8);
67 #define	LKPI_RTAP_RX_FLAGS_PRESENT					\
68 	((1 << IEEE80211_RADIOTAP_TSFT) |				\
69 	 (1 << IEEE80211_RADIOTAP_FLAGS) |				\
70 	 (1 << IEEE80211_RADIOTAP_RATE) |				\
71 	 (1 << IEEE80211_RADIOTAP_CHANNEL) |				\
72 	 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |			\
73 	 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE))
74 
75 struct lkpi_txq {
76 	bool			seen_dequeue;
77 	struct sk_buff_head	skbq;
78 
79 	/* Must be last! */
80 	struct ieee80211_txq	txq __aligned(CACHE_LINE_SIZE);
81 };
82 #define	TXQ_TO_LTXQ(_txq)	container_of(_txq, struct lkpi_txq, txq)
83 
84 
85 struct lkpi_sta {
86         TAILQ_ENTRY(lkpi_sta)	lsta_entry;
87 	struct ieee80211_node	*ni;
88 
89 	/* Deferred TX path. */
90 	/* Eventually we might want to migrate this into net80211 entirely. */
91 	/* XXX-BZ can we use sta->txq[] instead directly? */
92 	struct task		txq_task;
93 	struct mbufq		txq;
94 	struct mtx		txq_mtx;
95 
96 	struct ieee80211_key_conf *kc;
97 	enum ieee80211_sta_state state;
98 	bool			added_to_drv;			/* Driver knows; i.e. we called ...(). */
99 	bool			in_mgd;
100 
101 	/* Must be last! */
102 	struct ieee80211_sta	sta __aligned(CACHE_LINE_SIZE);
103 };
104 #define	STA_TO_LSTA(_sta)	container_of(_sta, struct lkpi_sta, sta)
105 #define	LSTA_TO_STA(_lsta)	(&(_lsta)->sta)
106 
107 struct lkpi_vif {
108         TAILQ_ENTRY(lkpi_vif)	lvif_entry;
109 	struct ieee80211vap	iv_vap;
110 
111 	struct mtx		mtx;
112 	struct wireless_dev	wdev;
113 
114 	/* Other local stuff. */
115 	int			(*iv_newstate)(struct ieee80211vap *,
116 				    enum ieee80211_state, int);
117 	TAILQ_HEAD(, lkpi_sta)	lsta_head;
118 	bool			added_to_drv;			/* Driver knows; i.e. we called add_interface(). */
119 
120 	/* Must be last! */
121 	struct ieee80211_vif	vif __aligned(CACHE_LINE_SIZE);
122 };
123 #define	VAP_TO_LVIF(_vap)	container_of(_vap, struct lkpi_vif, iv_vap)
124 #define	LVIF_TO_VAP(_lvif)	(&(_lvif)->iv_vap)
125 #define	VIF_TO_LVIF(_vif)	container_of(_vif, struct lkpi_vif, vif)
126 #define	LVIF_TO_VIF(_lvif)	(&(_lvif)->vif)
127 
128 
129 struct lkpi_hw {	/* name it mac80211_sc? */
130 	const struct ieee80211_ops	*ops;
131 	struct ieee80211_scan_request	*hw_req;
132 	struct workqueue_struct		*workq;
133 
134 	/* FreeBSD specific compat. */
135 	/* Linux device is in hw.wiphy->dev after SET_IEEE80211_DEV(). */
136 	struct ieee80211com		*ic;
137 	struct lkpi_radiotap_tx_hdr	rtap_tx;
138 	struct lkpi_radiotap_rx_hdr	rtap_rx;
139 
140 	TAILQ_HEAD(, lkpi_vif)		lvif_head;
141 
142 	struct mtx			mtx;
143 
144 	/* Node functions we overload to sync state. */
145 	struct ieee80211_node *	(*ic_node_alloc)(struct ieee80211vap *,
146 				    const uint8_t [IEEE80211_ADDR_LEN]);
147 	int			(*ic_node_init)(struct ieee80211_node *);
148 	void			(*ic_node_cleanup)(struct ieee80211_node *);
149 	void			(*ic_node_free)(struct ieee80211_node *);
150 
151 #define	LKPI_MAC80211_DRV_STARTED	0x00000001
152 	uint32_t			sc_flags;
153 #define	LKPI_SCAN_RUNNING		0x00000001
154 	uint32_t			scan_flags;
155 	bool				update_mc;
156 
157 	/* Must be last! */
158 	struct ieee80211_hw		hw __aligned(CACHE_LINE_SIZE);
159 };
160 #define	LHW_TO_HW(_lhw)		(&(_lhw)->hw)
161 #define	HW_TO_LHW(_hw)		container_of(_hw, struct lkpi_hw, hw)
162 
163 struct lkpi_wiphy {
164 	const struct cfg80211_ops	*ops;
165 
166 	/* Must be last! */
167 	struct wiphy			wiphy __aligned(CACHE_LINE_SIZE);
168 };
169 #define	WIPHY_TO_LWIPHY(_wiphy)	container_of(_wiphy, struct lkpi_wiphy, wiphy)
170 #define	LWIPHY_TO_WIPHY(_lwiphy)	(&(_lwiphy)->wiphy)
171 
172 
173 #define	LKPI_80211_LHW_LOCK(_lhw)	mtx_lock(&(_lhw)->mtx)
174 #define	LKPI_80211_LHW_UNLOCK(_lhw)	mtx_unlock(&(_lhw)->mtx)
175 #define	LKPI_80211_LHW_LOCK_ASSERT(_lhw) \
176     mtx_assert(&(_lhw)->mtx, MA_OWNED)
177 #define	LKPI_80211_LHW_UNLOCK_ASSERT(_lhw) \
178     mtx_assert(&(_lhw)->mtx, MA_NOTOWNED)
179 
180 #define	LKPI_80211_LVIF_LOCK(_lvif)	mtx_lock(&(_lvif)->mtx)
181 #define	LKPI_80211_LVIF_UNLOCK(_lvif)	mtx_unlock(&(_lvif)->mtx)
182 
183 #define	LKPI_80211_LSTA_LOCK(_lsta)	mtx_lock(&(_lsta)->txq_mtx)
184 #define	LKPI_80211_LSTA_UNLOCK(_lsta)	mtx_unlock(&(_lsta)->txq_mtx)
185 
186 
187 int lkpi_80211_mo_start(struct ieee80211_hw *);
188 void lkpi_80211_mo_stop(struct ieee80211_hw *);
189 int lkpi_80211_mo_set_frag_threshold(struct ieee80211_hw *, uint32_t);
190 int lkpi_80211_mo_set_rts_threshold(struct ieee80211_hw *, uint32_t);
191 int lkpi_80211_mo_add_interface(struct ieee80211_hw *, struct ieee80211_vif *);
192 void lkpi_80211_mo_remove_interface(struct ieee80211_hw *, struct ieee80211_vif *);
193 int lkpi_80211_mo_hw_scan(struct ieee80211_hw *, struct ieee80211_vif *,
194     struct ieee80211_scan_request *);
195 void lkpi_80211_mo_cancel_hw_scan(struct ieee80211_hw *, struct ieee80211_vif *);
196 void lkpi_80211_mo_sw_scan_complete(struct ieee80211_hw *, struct ieee80211_vif *);
197 void lkpi_80211_mo_sw_scan_start(struct ieee80211_hw *, struct ieee80211_vif *,
198     const u8 *);
199 u64 lkpi_80211_mo_prepare_multicast(struct ieee80211_hw *,
200     struct netdev_hw_addr_list *);
201 void lkpi_80211_mo_configure_filter(struct ieee80211_hw *, unsigned int,
202     unsigned int *, u64);
203 int lkpi_80211_mo_sta_state(struct ieee80211_hw *, struct ieee80211_vif *,
204     struct ieee80211_sta *, enum ieee80211_sta_state);
205 int lkpi_80211_mo_config(struct ieee80211_hw *, uint32_t);
206 int lkpi_80211_mo_assign_vif_chanctx(struct ieee80211_hw *, struct ieee80211_vif *,
207     struct ieee80211_chanctx_conf *);
208 void lkpi_80211_mo_unassign_vif_chanctx(struct ieee80211_hw *, struct ieee80211_vif *,
209     struct ieee80211_chanctx_conf **);
210 int lkpi_80211_mo_add_chanctx(struct ieee80211_hw *, struct ieee80211_chanctx_conf *);
211 void lkpi_80211_mo_change_chanctx(struct ieee80211_hw *,
212     struct ieee80211_chanctx_conf *, uint32_t);
213 void lkpi_80211_mo_remove_chanctx(struct ieee80211_hw *,
214     struct ieee80211_chanctx_conf *);
215 void lkpi_80211_mo_bss_info_changed(struct ieee80211_hw *, struct ieee80211_vif *,
216     struct ieee80211_bss_conf *, uint32_t);
217 int lkpi_80211_mo_conf_tx(struct ieee80211_hw *, struct ieee80211_vif *,
218     uint16_t, const struct ieee80211_tx_queue_params *);
219 void lkpi_80211_mo_flush(struct ieee80211_hw *, struct ieee80211_vif *,
220     uint32_t, bool);
221 void lkpi_80211_mo_mgd_prepare_tx(struct ieee80211_hw *, struct ieee80211_vif *,
222     struct ieee80211_prep_tx_info *);
223 void lkpi_80211_mo_mgd_complete_tx(struct ieee80211_hw *, struct ieee80211_vif *,
224     struct ieee80211_prep_tx_info *);
225 void lkpi_80211_mo_tx(struct ieee80211_hw *, struct ieee80211_tx_control *,
226     struct sk_buff *);
227 void lkpi_80211_mo_wake_tx_queue(struct ieee80211_hw *, struct ieee80211_txq *);
228 void lkpi_80211_mo_sync_rx_queues(struct ieee80211_hw *);
229 void lkpi_80211_mo_sta_pre_rcu_remove(struct ieee80211_hw *,
230     struct ieee80211_vif *, struct ieee80211_sta *);
231 int lkpi_80211_mo_set_key(struct ieee80211_hw *, enum set_key_cmd,
232     struct ieee80211_vif *, struct ieee80211_sta *,
233     struct ieee80211_key_conf *);
234 
235 #endif	/* _LKPI_SRC_LINUX_80211_H */
236