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-2021 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 *
netdev_notifier_info_to_dev(struct netdev_notifier_info * ni)165 netdev_notifier_info_to_dev(struct netdev_notifier_info *ni)
166 {
167 return (ni->dev);
168 }
169
170 static inline struct ifnet *
netdev_notifier_info_to_ifp(struct netdev_notifier_info * ni)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 struct napi_struct {
186 TAILQ_ENTRY(napi_struct) entry;
187
188 struct list_head rx_list;
189 struct net_device *dev;
190 int (*poll)(struct napi_struct *, int);
191 int budget;
192 int rx_count;
193
194 /*
195 * These flags mostly need to be checked/changed atomically
196 * (multiple together in some cases).
197 */
198 volatile unsigned long _flags;
199
200 /* FreeBSD internal. */
201 /* Use task for now, so we can easily switch between direct and task. */
202 struct task napi_task;
203 };
204
205 void linuxkpi_init_dummy_netdev(struct net_device *);
206 void linuxkpi_netif_napi_add(struct net_device *, struct napi_struct *,
207 int(*napi_poll)(struct napi_struct *, int), int);
208 void linuxkpi_netif_napi_del(struct napi_struct *);
209 bool linuxkpi_napi_schedule_prep(struct napi_struct *);
210 void linuxkpi___napi_schedule(struct napi_struct *);
211 void linuxkpi_napi_schedule(struct napi_struct *);
212 void linuxkpi_napi_reschedule(struct napi_struct *);
213 bool linuxkpi_napi_complete_done(struct napi_struct *, int);
214 bool linuxkpi_napi_complete(struct napi_struct *);
215 void linuxkpi_napi_disable(struct napi_struct *);
216 void linuxkpi_napi_enable(struct napi_struct *);
217 void linuxkpi_napi_synchronize(struct napi_struct *);
218
219 #define init_dummy_netdev(_n) \
220 linuxkpi_init_dummy_netdev(_n)
221 #define netif_napi_add(_nd, _ns, _p, _b) \
222 linuxkpi_netif_napi_add(_nd, _ns, _p, _b)
223 #define netif_napi_del(_n) \
224 linuxkpi_netif_napi_del(_n)
225 #define napi_schedule_prep(_n) \
226 linuxkpi_napi_schedule_prep(_n)
227 #define __napi_schedule(_n) \
228 linuxkpi___napi_schedule(_n)
229 #define napi_schedule(_n) \
230 linuxkpi_napi_schedule(_n)
231 #define napi_reschedule(_n) \
232 linuxkpi_napi_reschedule(_n)
233 #define napi_complete_done(_n, _r) \
234 linuxkpi_napi_complete_done(_n, _r)
235 #define napi_complete(_n) \
236 linuxkpi_napi_complete(_n)
237 #define napi_disable(_n) \
238 linuxkpi_napi_disable(_n)
239 #define napi_enable(_n) \
240 linuxkpi_napi_enable(_n)
241 #define napi_synchronize(_n) \
242 linuxkpi_napi_synchronize(_n)
243
244 /* -------------------------------------------------------------------------- */
245
246 static inline void
netdev_rss_key_fill(uint32_t * buf,size_t len)247 netdev_rss_key_fill(uint32_t *buf, size_t len)
248 {
249
250 /*
251 * Remembering from a previous life there was discussions on what is
252 * a good RSS hash key. See end of rss_init() in net/rss_config.c.
253 * iwlwifi is looking for a 10byte "secret" so stay with random for now.
254 */
255 get_random_bytes(buf, len);
256 }
257
258 static inline int
netdev_hw_addr_list_count(struct netdev_hw_addr_list * list)259 netdev_hw_addr_list_count(struct netdev_hw_addr_list *list)
260 {
261
262 return (list->count);
263 }
264
265 static inline int
netdev_mc_count(struct net_device * ndev)266 netdev_mc_count(struct net_device *ndev)
267 {
268
269 return (netdev_hw_addr_list_count(&ndev->mc));
270 }
271
272 #define netdev_hw_addr_list_for_each(_addr, _list) \
273 list_for_each_entry((_addr), &(_list)->addr_list, addr_list)
274
275 #define netdev_for_each_mc_addr(na, ndev) \
276 netdev_hw_addr_list_for_each(na, &(ndev)->mc)
277
278 static __inline void
synchronize_net(void)279 synchronize_net(void)
280 {
281
282 /* We probably cannot do that unconditionally at some point anymore. */
283 synchronize_rcu();
284 }
285
286 /* -------------------------------------------------------------------------- */
287
288 struct net_device *linuxkpi_alloc_netdev(size_t, const char *, uint32_t,
289 void(*)(struct net_device *));
290 void linuxkpi_free_netdev(struct net_device *);
291
292 #define alloc_netdev(_l, _n, _f, _func) \
293 linuxkpi_alloc_netdev(_l, _n, _f, _func)
294 #define free_netdev(_n) \
295 linuxkpi_free_netdev(_n)
296
297 static inline void *
netdev_priv(const struct net_device * ndev)298 netdev_priv(const struct net_device *ndev)
299 {
300
301 return (__DECONST(void *, ndev->drv_priv));
302 }
303
304 /* -------------------------------------------------------------------------- */
305 /* This is really rtnetlink and probably belongs elsewhere. */
306
307 #define rtnl_lock() do { } while(0)
308 #define rtnl_unlock() do { } while(0)
309
310 #endif /* _LINUXKPI_LINUX_NETDEVICE_H */
311