]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/net/dummy.c
mlx4: use order-0 pages for RX
[karo-tx-linux.git] / drivers / net / dummy.c
1 /* dummy.c: a dummy net driver
2
3         The purpose of this driver is to provide a device to point a
4         route through, but not to actually transmit packets.
5
6         Why?  If you have a machine whose only connection is an occasional
7         PPP/SLIP/PLIP link, you can only connect to your own hostname
8         when the link is up.  Otherwise you have to use localhost.
9         This isn't very consistent.
10
11         One solution is to set up a dummy link using PPP/SLIP/PLIP,
12         but this seems (to me) too much overhead for too little gain.
13         This driver provides a small alternative. Thus you can do
14
15         [when not running slip]
16                 ifconfig dummy slip.addr.ess.here up
17         [to go to slip]
18                 ifconfig dummy down
19                 dip whatever
20
21         This was written by looking at Donald Becker's skeleton driver
22         and the loopback driver.  I then threw away anything that didn't
23         apply!  Thanks to Alan Cox for the key clue on what to do with
24         misguided packets.
25
26                         Nick Holloway, 27th May 1994
27         [I tweaked this explanation a little but that's all]
28                         Alan Cox, 30th May 1994
29 */
30
31 #include <linux/module.h>
32 #include <linux/kernel.h>
33 #include <linux/netdevice.h>
34 #include <linux/etherdevice.h>
35 #include <linux/init.h>
36 #include <linux/moduleparam.h>
37 #include <linux/rtnetlink.h>
38 #include <net/rtnetlink.h>
39 #include <linux/u64_stats_sync.h>
40
41 #define DRV_NAME        "dummy"
42 #define DRV_VERSION     "1.0"
43
44 #undef pr_fmt
45 #define pr_fmt(fmt) DRV_NAME ": " fmt
46
47 static int numdummies = 1;
48 static int num_vfs;
49
50 struct vf_data_storage {
51         u8      vf_mac[ETH_ALEN];
52         u16     pf_vlan; /* When set, guest VLAN config not allowed. */
53         u16     pf_qos;
54         __be16  vlan_proto;
55         u16     min_tx_rate;
56         u16     max_tx_rate;
57         u8      spoofchk_enabled;
58         bool    rss_query_enabled;
59         u8      trusted;
60         int     link_state;
61 };
62
63 struct dummy_priv {
64         struct vf_data_storage  *vfinfo;
65 };
66
67 static int dummy_num_vf(struct device *dev)
68 {
69         return num_vfs;
70 }
71
72 static struct bus_type dummy_bus = {
73         .name   = "dummy",
74         .num_vf = dummy_num_vf,
75 };
76
77 static void release_dummy_parent(struct device *dev)
78 {
79 }
80
81 static struct device dummy_parent = {
82         .init_name      = "dummy",
83         .bus            = &dummy_bus,
84         .release        = release_dummy_parent,
85 };
86
87 /* fake multicast ability */
88 static void set_multicast_list(struct net_device *dev)
89 {
90 }
91
92 struct pcpu_dstats {
93         u64                     tx_packets;
94         u64                     tx_bytes;
95         struct u64_stats_sync   syncp;
96 };
97
98 static void dummy_get_stats64(struct net_device *dev,
99                               struct rtnl_link_stats64 *stats)
100 {
101         int i;
102
103         for_each_possible_cpu(i) {
104                 const struct pcpu_dstats *dstats;
105                 u64 tbytes, tpackets;
106                 unsigned int start;
107
108                 dstats = per_cpu_ptr(dev->dstats, i);
109                 do {
110                         start = u64_stats_fetch_begin_irq(&dstats->syncp);
111                         tbytes = dstats->tx_bytes;
112                         tpackets = dstats->tx_packets;
113                 } while (u64_stats_fetch_retry_irq(&dstats->syncp, start));
114                 stats->tx_bytes += tbytes;
115                 stats->tx_packets += tpackets;
116         }
117 }
118
119 static netdev_tx_t dummy_xmit(struct sk_buff *skb, struct net_device *dev)
120 {
121         struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);
122
123         u64_stats_update_begin(&dstats->syncp);
124         dstats->tx_packets++;
125         dstats->tx_bytes += skb->len;
126         u64_stats_update_end(&dstats->syncp);
127
128         dev_kfree_skb(skb);
129         return NETDEV_TX_OK;
130 }
131
132 static int dummy_dev_init(struct net_device *dev)
133 {
134         struct dummy_priv *priv = netdev_priv(dev);
135
136         dev->dstats = netdev_alloc_pcpu_stats(struct pcpu_dstats);
137         if (!dev->dstats)
138                 return -ENOMEM;
139
140         priv->vfinfo = NULL;
141
142         if (!num_vfs)
143                 return 0;
144
145         dev->dev.parent = &dummy_parent;
146         priv->vfinfo = kcalloc(num_vfs, sizeof(struct vf_data_storage),
147                                GFP_KERNEL);
148         if (!priv->vfinfo) {
149                 free_percpu(dev->dstats);
150                 return -ENOMEM;
151         }
152
153         return 0;
154 }
155
156 static void dummy_dev_uninit(struct net_device *dev)
157 {
158         free_percpu(dev->dstats);
159 }
160
161 static int dummy_change_carrier(struct net_device *dev, bool new_carrier)
162 {
163         if (new_carrier)
164                 netif_carrier_on(dev);
165         else
166                 netif_carrier_off(dev);
167         return 0;
168 }
169
170 static int dummy_set_vf_mac(struct net_device *dev, int vf, u8 *mac)
171 {
172         struct dummy_priv *priv = netdev_priv(dev);
173
174         if (!is_valid_ether_addr(mac) || (vf >= num_vfs))
175                 return -EINVAL;
176
177         memcpy(priv->vfinfo[vf].vf_mac, mac, ETH_ALEN);
178
179         return 0;
180 }
181
182 static int dummy_set_vf_vlan(struct net_device *dev, int vf,
183                              u16 vlan, u8 qos, __be16 vlan_proto)
184 {
185         struct dummy_priv *priv = netdev_priv(dev);
186
187         if ((vf >= num_vfs) || (vlan > 4095) || (qos > 7))
188                 return -EINVAL;
189
190         priv->vfinfo[vf].pf_vlan = vlan;
191         priv->vfinfo[vf].pf_qos = qos;
192         priv->vfinfo[vf].vlan_proto = vlan_proto;
193
194         return 0;
195 }
196
197 static int dummy_set_vf_rate(struct net_device *dev, int vf, int min, int max)
198 {
199         struct dummy_priv *priv = netdev_priv(dev);
200
201         if (vf >= num_vfs)
202                 return -EINVAL;
203
204         priv->vfinfo[vf].min_tx_rate = min;
205         priv->vfinfo[vf].max_tx_rate = max;
206
207         return 0;
208 }
209
210 static int dummy_set_vf_spoofchk(struct net_device *dev, int vf, bool val)
211 {
212         struct dummy_priv *priv = netdev_priv(dev);
213
214         if (vf >= num_vfs)
215                 return -EINVAL;
216
217         priv->vfinfo[vf].spoofchk_enabled = val;
218
219         return 0;
220 }
221
222 static int dummy_set_vf_rss_query_en(struct net_device *dev, int vf, bool val)
223 {
224         struct dummy_priv *priv = netdev_priv(dev);
225
226         if (vf >= num_vfs)
227                 return -EINVAL;
228
229         priv->vfinfo[vf].rss_query_enabled = val;
230
231         return 0;
232 }
233
234 static int dummy_set_vf_trust(struct net_device *dev, int vf, bool val)
235 {
236         struct dummy_priv *priv = netdev_priv(dev);
237
238         if (vf >= num_vfs)
239                 return -EINVAL;
240
241         priv->vfinfo[vf].trusted = val;
242
243         return 0;
244 }
245
246 static int dummy_get_vf_config(struct net_device *dev,
247                                int vf, struct ifla_vf_info *ivi)
248 {
249         struct dummy_priv *priv = netdev_priv(dev);
250
251         if (vf >= num_vfs)
252                 return -EINVAL;
253
254         ivi->vf = vf;
255         memcpy(&ivi->mac, priv->vfinfo[vf].vf_mac, ETH_ALEN);
256         ivi->vlan = priv->vfinfo[vf].pf_vlan;
257         ivi->qos = priv->vfinfo[vf].pf_qos;
258         ivi->spoofchk = priv->vfinfo[vf].spoofchk_enabled;
259         ivi->linkstate = priv->vfinfo[vf].link_state;
260         ivi->min_tx_rate = priv->vfinfo[vf].min_tx_rate;
261         ivi->max_tx_rate = priv->vfinfo[vf].max_tx_rate;
262         ivi->rss_query_en = priv->vfinfo[vf].rss_query_enabled;
263         ivi->trusted = priv->vfinfo[vf].trusted;
264         ivi->vlan_proto = priv->vfinfo[vf].vlan_proto;
265
266         return 0;
267 }
268
269 static int dummy_set_vf_link_state(struct net_device *dev, int vf, int state)
270 {
271         struct dummy_priv *priv = netdev_priv(dev);
272
273         if (vf >= num_vfs)
274                 return -EINVAL;
275
276         priv->vfinfo[vf].link_state = state;
277
278         return 0;
279 }
280
281 static const struct net_device_ops dummy_netdev_ops = {
282         .ndo_init               = dummy_dev_init,
283         .ndo_uninit             = dummy_dev_uninit,
284         .ndo_start_xmit         = dummy_xmit,
285         .ndo_validate_addr      = eth_validate_addr,
286         .ndo_set_rx_mode        = set_multicast_list,
287         .ndo_set_mac_address    = eth_mac_addr,
288         .ndo_get_stats64        = dummy_get_stats64,
289         .ndo_change_carrier     = dummy_change_carrier,
290         .ndo_set_vf_mac         = dummy_set_vf_mac,
291         .ndo_set_vf_vlan        = dummy_set_vf_vlan,
292         .ndo_set_vf_rate        = dummy_set_vf_rate,
293         .ndo_set_vf_spoofchk    = dummy_set_vf_spoofchk,
294         .ndo_set_vf_trust       = dummy_set_vf_trust,
295         .ndo_get_vf_config      = dummy_get_vf_config,
296         .ndo_set_vf_link_state  = dummy_set_vf_link_state,
297         .ndo_set_vf_rss_query_en = dummy_set_vf_rss_query_en,
298 };
299
300 static void dummy_get_drvinfo(struct net_device *dev,
301                               struct ethtool_drvinfo *info)
302 {
303         strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
304         strlcpy(info->version, DRV_VERSION, sizeof(info->version));
305 }
306
307 static const struct ethtool_ops dummy_ethtool_ops = {
308         .get_drvinfo            = dummy_get_drvinfo,
309 };
310
311 static void dummy_free_netdev(struct net_device *dev)
312 {
313         struct dummy_priv *priv = netdev_priv(dev);
314
315         kfree(priv->vfinfo);
316         free_netdev(dev);
317 }
318
319 static void dummy_setup(struct net_device *dev)
320 {
321         ether_setup(dev);
322
323         /* Initialize the device structure. */
324         dev->netdev_ops = &dummy_netdev_ops;
325         dev->ethtool_ops = &dummy_ethtool_ops;
326         dev->destructor = dummy_free_netdev;
327
328         /* Fill in device structure with ethernet-generic values. */
329         dev->flags |= IFF_NOARP;
330         dev->flags &= ~IFF_MULTICAST;
331         dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE;
332         dev->features   |= NETIF_F_SG | NETIF_F_FRAGLIST;
333         dev->features   |= NETIF_F_ALL_TSO | NETIF_F_UFO;
334         dev->features   |= NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX;
335         dev->features   |= NETIF_F_GSO_ENCAP_ALL;
336         dev->hw_features |= dev->features;
337         dev->hw_enc_features |= dev->features;
338         eth_hw_addr_random(dev);
339
340         dev->min_mtu = 0;
341         dev->max_mtu = ETH_MAX_MTU;
342 }
343
344 static int dummy_validate(struct nlattr *tb[], struct nlattr *data[])
345 {
346         if (tb[IFLA_ADDRESS]) {
347                 if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
348                         return -EINVAL;
349                 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
350                         return -EADDRNOTAVAIL;
351         }
352         return 0;
353 }
354
355 static struct rtnl_link_ops dummy_link_ops __read_mostly = {
356         .kind           = DRV_NAME,
357         .priv_size      = sizeof(struct dummy_priv),
358         .setup          = dummy_setup,
359         .validate       = dummy_validate,
360 };
361
362 /* Number of dummy devices to be set up by this module. */
363 module_param(numdummies, int, 0);
364 MODULE_PARM_DESC(numdummies, "Number of dummy pseudo devices");
365
366 module_param(num_vfs, int, 0);
367 MODULE_PARM_DESC(num_vfs, "Number of dummy VFs per dummy device");
368
369 static int __init dummy_init_one(void)
370 {
371         struct net_device *dev_dummy;
372         int err;
373
374         dev_dummy = alloc_netdev(sizeof(struct dummy_priv),
375                                  "dummy%d", NET_NAME_UNKNOWN, dummy_setup);
376         if (!dev_dummy)
377                 return -ENOMEM;
378
379         dev_dummy->rtnl_link_ops = &dummy_link_ops;
380         err = register_netdevice(dev_dummy);
381         if (err < 0)
382                 goto err;
383         return 0;
384
385 err:
386         free_netdev(dev_dummy);
387         return err;
388 }
389
390 static int __init dummy_init_module(void)
391 {
392         int i, err = 0;
393
394         if (num_vfs) {
395                 err = bus_register(&dummy_bus);
396                 if (err < 0) {
397                         pr_err("registering dummy bus failed\n");
398                         return err;
399                 }
400
401                 err = device_register(&dummy_parent);
402                 if (err < 0) {
403                         pr_err("registering dummy parent device failed\n");
404                         bus_unregister(&dummy_bus);
405                         return err;
406                 }
407         }
408
409         rtnl_lock();
410         err = __rtnl_link_register(&dummy_link_ops);
411         if (err < 0)
412                 goto out;
413
414         for (i = 0; i < numdummies && !err; i++) {
415                 err = dummy_init_one();
416                 cond_resched();
417         }
418         if (err < 0)
419                 __rtnl_link_unregister(&dummy_link_ops);
420
421 out:
422         rtnl_unlock();
423
424         if (err && num_vfs) {
425                 device_unregister(&dummy_parent);
426                 bus_unregister(&dummy_bus);
427         }
428
429         return err;
430 }
431
432 static void __exit dummy_cleanup_module(void)
433 {
434         rtnl_link_unregister(&dummy_link_ops);
435
436         if (num_vfs) {
437                 device_unregister(&dummy_parent);
438                 bus_unregister(&dummy_bus);
439         }
440 }
441
442 module_init(dummy_init_module);
443 module_exit(dummy_cleanup_module);
444 MODULE_LICENSE("GPL");
445 MODULE_ALIAS_RTNL_LINK(DRV_NAME);
446 MODULE_VERSION(DRV_VERSION);