1 /*-
2  * Copyright (c) 2010 Isilon Systems, Inc.
3  * Copyright (c) 2010 iX Systems, Inc.
4  * Copyright (c) 2010 Panasas, Inc.
5  * Copyright (c) 2013-2019 Mellanox Technologies, Ltd.
6  * All rights reserved.
7  * Copyright (c) 2020-2021 The FreeBSD Foundation
8  * Copyright (c) 2020-2022 Bjoern A. Zeeb
9  *
10  * Portions of this software were developed by Björn Zeeb
11  * under sponsorship from the FreeBSD Foundation.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice unmodified, this list of conditions, and the following
18  *    disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  * $FreeBSD$
35  */
36 #ifndef	_LINUXKPI_LINUX_NETDEVICE_H
37 #define	_LINUXKPI_LINUX_NETDEVICE_H
38 
39 #include <linux/types.h>
40 #include <linux/netdev_features.h>
41 
42 #include <sys/param.h>
43 #include <sys/kernel.h>
44 #include <sys/lock.h>
45 #include <sys/mutex.h>
46 #include <sys/malloc.h>
47 #include <sys/queue.h>
48 #include <sys/socket.h>
49 #include <sys/taskqueue.h>
50 
51 #include <net/if_types.h>
52 #include <net/if.h>
53 #include <net/if_var.h>
54 #include <net/if_dl.h>
55 
56 #include <linux/bitops.h>
57 #include <linux/list.h>
58 #include <linux/device.h>
59 #include <linux/net.h>
60 #include <linux/if_ether.h>
61 #include <linux/notifier.h>
62 #include <linux/random.h>
63 #include <linux/rcupdate.h>
64 
65 #ifdef VIMAGE
66 #define	init_net *vnet0
67 #else
68 #define	init_net *((struct vnet *)0)
69 #endif
70 
71 struct sk_buff;
72 struct net_device;
73 struct wireless_dev;		/* net/cfg80211.h */
74 
75 #define	MAX_ADDR_LEN		20
76 
77 #define	NET_NAME_UNKNOWN	0
78 
79 enum netdev_tx {
80 	NETDEV_TX_OK		= 0,
81 };
82 typedef	enum netdev_tx		netdev_tx_t;
83 
84 struct netdev_hw_addr {
85 	struct list_head	addr_list;
86 	uint8_t			addr[MAX_ADDR_LEN];
87 };
88 
89 struct netdev_hw_addr_list {
90 	struct list_head	addr_list;
91 	int			count;
92 };
93 
94 enum net_device_reg_state {
95 	NETREG_DUMMY		= 1,
96 	NETREG_REGISTERED,
97 };
98 
99 struct net_device_ops {
100 	int (*ndo_open)(struct net_device *);
101 	int (*ndo_stop)(struct net_device *);
102 	int (*ndo_set_mac_address)(struct net_device *,  void *);
103 	netdev_tx_t (*ndo_start_xmit)(struct sk_buff *, struct net_device *);
104 	void (*ndo_set_rx_mode)(struct net_device *);
105 };
106 
107 struct net_device {
108 	/* BSD specific for compat. */
109 	struct ifnet			bsdifp;
110 
111 	/* net_device fields seen publicly. */
112 	/* XXX can we later make some aliases to ifnet? */
113 	char				name[IFNAMSIZ];
114 	struct wireless_dev		*ieee80211_ptr;
115 	uint8_t				dev_addr[ETH_ALEN];
116 	struct netdev_hw_addr_list	mc;
117 	netdev_features_t		features;
118 	struct {
119 		unsigned long		multicast;
120 
121 		unsigned long		rx_bytes;
122 		unsigned long		rx_errors;
123 		unsigned long		rx_packets;
124 		unsigned long		tx_bytes;
125 		unsigned long		tx_dropped;
126 		unsigned long		tx_errors;
127 		unsigned long		tx_packets;
128 	} stats;
129 	enum net_device_reg_state	reg_state;
130 	const struct ethtool_ops	*ethtool_ops;
131 	const struct net_device_ops	*netdev_ops;
132 
133 	bool				needs_free_netdev;
134 	/* Not properly typed as-of now. */
135 	int	flags, type;
136 	int	name_assign_type, needed_headroom;
137 
138 	void (*priv_destructor)(struct net_device *);
139 
140 	/* net_device internal. */
141 	struct device			dev;
142 
143 	/*
144 	 * In case we delete the net_device we need to be able to clear all
145 	 * NAPI consumers.
146 	 */
147 	struct mtx			napi_mtx;
148 	TAILQ_HEAD(, napi_struct)	napi_head;
149 	struct taskqueue		*napi_tq;
150 
151 	/* Must stay last. */
152 	uint8_t				drv_priv[0] __aligned(CACHE_LINE_SIZE);
153 };
154 
155 #define	SET_NETDEV_DEV(_ndev, _dev)	(_ndev)->dev.parent = _dev;
156 
157 /* -------------------------------------------------------------------------- */
158 /* According to linux::ipoib_main.c. */
159 struct netdev_notifier_info {
160 	struct net_device	*dev;
161 	struct ifnet		*ifp;
162 };
163 
164 static inline struct net_device *
165 netdev_notifier_info_to_dev(struct netdev_notifier_info *ni)
166 {
167 	return (ni->dev);
168 }
169 
170 static inline struct ifnet *
171 netdev_notifier_info_to_ifp(struct netdev_notifier_info *ni)
172 {
173 	return (ni->ifp);
174 }
175 
176 int	register_netdevice_notifier(struct notifier_block *);
177 int	register_inetaddr_notifier(struct notifier_block *);
178 int	unregister_netdevice_notifier(struct notifier_block *);
179 int	unregister_inetaddr_notifier(struct notifier_block *);
180 
181 /* -------------------------------------------------------------------------- */
182 
183 #define	NAPI_POLL_WEIGHT			64	/* budget */
184 
185 /*
186  * There are drivers directly testing napi state bits, so we need to publicly
187  * expose them.  If you ask me, those accesses should be hid behind an
188  * inline function and the bit flags not be directly exposed.
189  */
190 enum napi_state_bits {
191 	/*
192 	 * Official Linux flags encountered.
193 	 */
194 	NAPI_STATE_SCHED = 1,
195 
196 	/*
197 	 * Our internal versions (for now).
198 	 */
199 	/* Do not schedule new things while we are waiting to clear things. */
200 	LKPI_NAPI_FLAG_DISABLE_PENDING = 0,
201 	/* To synchronise that only one poll is ever running. */
202 	LKPI_NAPI_FLAG_IS_SCHEDULED = 1,
203 	/* If trying to schedule while poll is running. Need to re-schedule. */
204 	LKPI_NAPI_FLAG_LOST_RACE_TRY_AGAIN = 2,
205 	/* When shutting down forcefully prevent anything from running task/poll. */
206 	LKPI_NAPI_FLAG_SHUTDOWN = 3,
207 };
208 
209 struct napi_struct {
210 	TAILQ_ENTRY(napi_struct)	entry;
211 
212 	struct list_head	rx_list;
213 	struct net_device	*dev;
214 	int			(*poll)(struct napi_struct *, int);
215 	int			budget;
216 	int			rx_count;
217 
218 
219 	/*
220 	 * These flags mostly need to be checked/changed atomically
221 	 * (multiple together in some cases).
222 	 */
223 	volatile unsigned long	state;
224 
225 	/* FreeBSD internal. */
226 	/* Use task for now, so we can easily switch between direct and task. */
227 	struct task		napi_task;
228 };
229 
230 void linuxkpi_init_dummy_netdev(struct net_device *);
231 void linuxkpi_netif_napi_add(struct net_device *, struct napi_struct *,
232     int(*napi_poll)(struct napi_struct *, int), int);
233 void linuxkpi_netif_napi_del(struct napi_struct *);
234 bool linuxkpi_napi_schedule_prep(struct napi_struct *);
235 void linuxkpi___napi_schedule(struct napi_struct *);
236 void linuxkpi_napi_schedule(struct napi_struct *);
237 void linuxkpi_napi_reschedule(struct napi_struct *);
238 bool linuxkpi_napi_complete_done(struct napi_struct *, int);
239 bool linuxkpi_napi_complete(struct napi_struct *);
240 void linuxkpi_napi_disable(struct napi_struct *);
241 void linuxkpi_napi_enable(struct napi_struct *);
242 void linuxkpi_napi_synchronize(struct napi_struct *);
243 
244 #define	init_dummy_netdev(_n)						\
245 	linuxkpi_init_dummy_netdev(_n)
246 #define	netif_napi_add(_nd, _ns, _p, _b)				\
247 	linuxkpi_netif_napi_add(_nd, _ns, _p, _b)
248 #define	netif_napi_del(_n)						\
249 	linuxkpi_netif_napi_del(_n)
250 #define	napi_schedule_prep(_n)						\
251 	linuxkpi_napi_schedule_prep(_n)
252 #define	__napi_schedule(_n)						\
253 	linuxkpi___napi_schedule(_n)
254 #define	napi_schedule(_n)						\
255 	linuxkpi_napi_schedule(_n)
256 #define	napi_reschedule(_n)						\
257 	linuxkpi_napi_reschedule(_n)
258 #define	napi_complete_done(_n, _r)					\
259 	linuxkpi_napi_complete_done(_n, _r)
260 #define	napi_complete(_n)						\
261 	linuxkpi_napi_complete(_n)
262 #define	napi_disable(_n)						\
263 	linuxkpi_napi_disable(_n)
264 #define	napi_enable(_n)							\
265 	linuxkpi_napi_enable(_n)
266 #define	napi_synchronize(_n)						\
267 	linuxkpi_napi_synchronize(_n)
268 
269 /* -------------------------------------------------------------------------- */
270 
271 static inline void
272 netdev_rss_key_fill(uint32_t *buf, size_t len)
273 {
274 
275 	/*
276 	 * Remembering from a previous life there was discussions on what is
277 	 * a good RSS hash key.  See end of rss_init() in net/rss_config.c.
278 	 * iwlwifi is looking for a 10byte "secret" so stay with random for now.
279 	 */
280 	get_random_bytes(buf, len);
281 }
282 
283 static inline int
284 netdev_hw_addr_list_count(struct netdev_hw_addr_list *list)
285 {
286 
287 	return (list->count);
288 }
289 
290 static inline int
291 netdev_mc_count(struct net_device *ndev)
292 {
293 
294 	return (netdev_hw_addr_list_count(&ndev->mc));
295 }
296 
297 #define	netdev_hw_addr_list_for_each(_addr, _list)			\
298 	list_for_each_entry((_addr), &(_list)->addr_list, addr_list)
299 
300 #define	netdev_for_each_mc_addr(na, ndev)				\
301 	netdev_hw_addr_list_for_each(na, &(ndev)->mc)
302 
303 static __inline void
304 synchronize_net(void)
305 {
306 
307 	/* We probably cannot do that unconditionally at some point anymore. */
308 	synchronize_rcu();
309 }
310 
311 /* -------------------------------------------------------------------------- */
312 
313 struct net_device *linuxkpi_alloc_netdev(size_t, const char *, uint32_t,
314     void(*)(struct net_device *));
315 void linuxkpi_free_netdev(struct net_device *);
316 
317 #define	alloc_netdev(_l, _n, _f, _func)						\
318 	linuxkpi_alloc_netdev(_l, _n, _f, _func)
319 #define	free_netdev(_n)								\
320 	linuxkpi_free_netdev(_n)
321 
322 static inline void *
323 netdev_priv(const struct net_device *ndev)
324 {
325 
326 	return (__DECONST(void *, ndev->drv_priv));
327 }
328 
329 /* -------------------------------------------------------------------------- */
330 /* This is really rtnetlink and probably belongs elsewhere. */
331 
332 #define	rtnl_lock()		do { } while(0)
333 #define	rtnl_unlock()		do { } while(0)
334 
335 #endif	/* _LINUXKPI_LINUX_NETDEVICE_H */
336