]> Git Repo - linux.git/blob - drivers/net/netdevsim/netdev.c
Merge tag 'devicetree-for-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / drivers / net / netdevsim / netdev.c
1 /*
2  * Copyright (C) 2017 Netronome Systems, Inc.
3  *
4  * This software is licensed under the GNU General License Version 2,
5  * June 1991 as shown in the file COPYING in the top-level directory of this
6  * source tree.
7  *
8  * THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS"
9  * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
10  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
11  * FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
12  * OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
13  * THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
14  */
15
16 #include <linux/debugfs.h>
17 #include <linux/etherdevice.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/netdevice.h>
21 #include <linux/slab.h>
22 #include <net/netlink.h>
23 #include <net/pkt_cls.h>
24 #include <net/rtnetlink.h>
25
26 #include "netdevsim.h"
27
28 struct nsim_vf_config {
29         int link_state;
30         u16 min_tx_rate;
31         u16 max_tx_rate;
32         u16 vlan;
33         __be16 vlan_proto;
34         u16 qos;
35         u8 vf_mac[ETH_ALEN];
36         bool spoofchk_enabled;
37         bool trusted;
38         bool rss_query_enabled;
39 };
40
41 static u32 nsim_dev_id;
42
43 static int nsim_num_vf(struct device *dev)
44 {
45         struct netdevsim *ns = to_nsim(dev);
46
47         return ns->num_vfs;
48 }
49
50 static struct bus_type nsim_bus = {
51         .name           = DRV_NAME,
52         .dev_name       = DRV_NAME,
53         .num_vf         = nsim_num_vf,
54 };
55
56 static int nsim_vfs_enable(struct netdevsim *ns, unsigned int num_vfs)
57 {
58         ns->vfconfigs = kcalloc(num_vfs, sizeof(struct nsim_vf_config),
59                                 GFP_KERNEL);
60         if (!ns->vfconfigs)
61                 return -ENOMEM;
62         ns->num_vfs = num_vfs;
63
64         return 0;
65 }
66
67 static void nsim_vfs_disable(struct netdevsim *ns)
68 {
69         kfree(ns->vfconfigs);
70         ns->vfconfigs = NULL;
71         ns->num_vfs = 0;
72 }
73
74 static ssize_t
75 nsim_numvfs_store(struct device *dev, struct device_attribute *attr,
76                   const char *buf, size_t count)
77 {
78         struct netdevsim *ns = to_nsim(dev);
79         unsigned int num_vfs;
80         int ret;
81
82         ret = kstrtouint(buf, 0, &num_vfs);
83         if (ret)
84                 return ret;
85
86         rtnl_lock();
87         if (ns->num_vfs == num_vfs)
88                 goto exit_good;
89         if (ns->num_vfs && num_vfs) {
90                 ret = -EBUSY;
91                 goto exit_unlock;
92         }
93
94         if (num_vfs) {
95                 ret = nsim_vfs_enable(ns, num_vfs);
96                 if (ret)
97                         goto exit_unlock;
98         } else {
99                 nsim_vfs_disable(ns);
100         }
101 exit_good:
102         ret = count;
103 exit_unlock:
104         rtnl_unlock();
105
106         return ret;
107 }
108
109 static ssize_t
110 nsim_numvfs_show(struct device *dev, struct device_attribute *attr, char *buf)
111 {
112         struct netdevsim *ns = to_nsim(dev);
113
114         return sprintf(buf, "%u\n", ns->num_vfs);
115 }
116
117 static struct device_attribute nsim_numvfs_attr =
118         __ATTR(sriov_numvfs, 0664, nsim_numvfs_show, nsim_numvfs_store);
119
120 static struct attribute *nsim_dev_attrs[] = {
121         &nsim_numvfs_attr.attr,
122         NULL,
123 };
124
125 static const struct attribute_group nsim_dev_attr_group = {
126         .attrs = nsim_dev_attrs,
127 };
128
129 static const struct attribute_group *nsim_dev_attr_groups[] = {
130         &nsim_dev_attr_group,
131         NULL,
132 };
133
134 static void nsim_dev_release(struct device *dev)
135 {
136         struct netdevsim *ns = to_nsim(dev);
137
138         nsim_vfs_disable(ns);
139         free_netdev(ns->netdev);
140 }
141
142 static struct device_type nsim_dev_type = {
143         .groups = nsim_dev_attr_groups,
144         .release = nsim_dev_release,
145 };
146
147 static int nsim_init(struct net_device *dev)
148 {
149         struct netdevsim *ns = netdev_priv(dev);
150         int err;
151
152         ns->netdev = dev;
153         ns->ddir = debugfs_create_dir(netdev_name(dev), nsim_ddir);
154         if (IS_ERR_OR_NULL(ns->ddir))
155                 return -ENOMEM;
156
157         err = nsim_bpf_init(ns);
158         if (err)
159                 goto err_debugfs_destroy;
160
161         ns->dev.id = nsim_dev_id++;
162         ns->dev.bus = &nsim_bus;
163         ns->dev.type = &nsim_dev_type;
164         err = device_register(&ns->dev);
165         if (err)
166                 goto err_bpf_uninit;
167
168         SET_NETDEV_DEV(dev, &ns->dev);
169
170         err = nsim_devlink_setup(ns);
171         if (err)
172                 goto err_unreg_dev;
173
174         return 0;
175
176 err_unreg_dev:
177         device_unregister(&ns->dev);
178 err_bpf_uninit:
179         nsim_bpf_uninit(ns);
180 err_debugfs_destroy:
181         debugfs_remove_recursive(ns->ddir);
182         return err;
183 }
184
185 static void nsim_uninit(struct net_device *dev)
186 {
187         struct netdevsim *ns = netdev_priv(dev);
188
189         nsim_devlink_teardown(ns);
190         debugfs_remove_recursive(ns->ddir);
191         nsim_bpf_uninit(ns);
192 }
193
194 static void nsim_free(struct net_device *dev)
195 {
196         struct netdevsim *ns = netdev_priv(dev);
197
198         device_unregister(&ns->dev);
199         /* netdev and vf state will be freed out of device_release() */
200 }
201
202 static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)
203 {
204         struct netdevsim *ns = netdev_priv(dev);
205
206         u64_stats_update_begin(&ns->syncp);
207         ns->tx_packets++;
208         ns->tx_bytes += skb->len;
209         u64_stats_update_end(&ns->syncp);
210
211         dev_kfree_skb(skb);
212
213         return NETDEV_TX_OK;
214 }
215
216 static void nsim_set_rx_mode(struct net_device *dev)
217 {
218 }
219
220 static int nsim_change_mtu(struct net_device *dev, int new_mtu)
221 {
222         struct netdevsim *ns = netdev_priv(dev);
223
224         if (ns->xdp_prog_mode == XDP_ATTACHED_DRV &&
225             new_mtu > NSIM_XDP_MAX_MTU)
226                 return -EBUSY;
227
228         dev->mtu = new_mtu;
229
230         return 0;
231 }
232
233 static void
234 nsim_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
235 {
236         struct netdevsim *ns = netdev_priv(dev);
237         unsigned int start;
238
239         do {
240                 start = u64_stats_fetch_begin(&ns->syncp);
241                 stats->tx_bytes = ns->tx_bytes;
242                 stats->tx_packets = ns->tx_packets;
243         } while (u64_stats_fetch_retry(&ns->syncp, start));
244 }
245
246 static int
247 nsim_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv)
248 {
249         return nsim_bpf_setup_tc_block_cb(type, type_data, cb_priv);
250 }
251
252 static int
253 nsim_setup_tc_block(struct net_device *dev, struct tc_block_offload *f)
254 {
255         struct netdevsim *ns = netdev_priv(dev);
256
257         if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
258                 return -EOPNOTSUPP;
259
260         switch (f->command) {
261         case TC_BLOCK_BIND:
262                 return tcf_block_cb_register(f->block, nsim_setup_tc_block_cb,
263                                              ns, ns);
264         case TC_BLOCK_UNBIND:
265                 tcf_block_cb_unregister(f->block, nsim_setup_tc_block_cb, ns);
266                 return 0;
267         default:
268                 return -EOPNOTSUPP;
269         }
270 }
271
272 static int nsim_set_vf_mac(struct net_device *dev, int vf, u8 *mac)
273 {
274         struct netdevsim *ns = netdev_priv(dev);
275
276         /* Only refuse multicast addresses, zero address can mean unset/any. */
277         if (vf >= ns->num_vfs || is_multicast_ether_addr(mac))
278                 return -EINVAL;
279         memcpy(ns->vfconfigs[vf].vf_mac, mac, ETH_ALEN);
280
281         return 0;
282 }
283
284 static int nsim_set_vf_vlan(struct net_device *dev, int vf,
285                             u16 vlan, u8 qos, __be16 vlan_proto)
286 {
287         struct netdevsim *ns = netdev_priv(dev);
288
289         if (vf >= ns->num_vfs || vlan > 4095 || qos > 7)
290                 return -EINVAL;
291
292         ns->vfconfigs[vf].vlan = vlan;
293         ns->vfconfigs[vf].qos = qos;
294         ns->vfconfigs[vf].vlan_proto = vlan_proto;
295
296         return 0;
297 }
298
299 static int nsim_set_vf_rate(struct net_device *dev, int vf, int min, int max)
300 {
301         struct netdevsim *ns = netdev_priv(dev);
302
303         if (vf >= ns->num_vfs)
304                 return -EINVAL;
305
306         ns->vfconfigs[vf].min_tx_rate = min;
307         ns->vfconfigs[vf].max_tx_rate = max;
308
309         return 0;
310 }
311
312 static int nsim_set_vf_spoofchk(struct net_device *dev, int vf, bool val)
313 {
314         struct netdevsim *ns = netdev_priv(dev);
315
316         if (vf >= ns->num_vfs)
317                 return -EINVAL;
318         ns->vfconfigs[vf].spoofchk_enabled = val;
319
320         return 0;
321 }
322
323 static int nsim_set_vf_rss_query_en(struct net_device *dev, int vf, bool val)
324 {
325         struct netdevsim *ns = netdev_priv(dev);
326
327         if (vf >= ns->num_vfs)
328                 return -EINVAL;
329         ns->vfconfigs[vf].rss_query_enabled = val;
330
331         return 0;
332 }
333
334 static int nsim_set_vf_trust(struct net_device *dev, int vf, bool val)
335 {
336         struct netdevsim *ns = netdev_priv(dev);
337
338         if (vf >= ns->num_vfs)
339                 return -EINVAL;
340         ns->vfconfigs[vf].trusted = val;
341
342         return 0;
343 }
344
345 static int
346 nsim_get_vf_config(struct net_device *dev, int vf, struct ifla_vf_info *ivi)
347 {
348         struct netdevsim *ns = netdev_priv(dev);
349
350         if (vf >= ns->num_vfs)
351                 return -EINVAL;
352
353         ivi->vf = vf;
354         ivi->linkstate = ns->vfconfigs[vf].link_state;
355         ivi->min_tx_rate = ns->vfconfigs[vf].min_tx_rate;
356         ivi->max_tx_rate = ns->vfconfigs[vf].max_tx_rate;
357         ivi->vlan = ns->vfconfigs[vf].vlan;
358         ivi->vlan_proto = ns->vfconfigs[vf].vlan_proto;
359         ivi->qos = ns->vfconfigs[vf].qos;
360         memcpy(&ivi->mac, ns->vfconfigs[vf].vf_mac, ETH_ALEN);
361         ivi->spoofchk = ns->vfconfigs[vf].spoofchk_enabled;
362         ivi->trusted = ns->vfconfigs[vf].trusted;
363         ivi->rss_query_en = ns->vfconfigs[vf].rss_query_enabled;
364
365         return 0;
366 }
367
368 static int nsim_set_vf_link_state(struct net_device *dev, int vf, int state)
369 {
370         struct netdevsim *ns = netdev_priv(dev);
371
372         if (vf >= ns->num_vfs)
373                 return -EINVAL;
374
375         switch (state) {
376         case IFLA_VF_LINK_STATE_AUTO:
377         case IFLA_VF_LINK_STATE_ENABLE:
378         case IFLA_VF_LINK_STATE_DISABLE:
379                 break;
380         default:
381                 return -EINVAL;
382         }
383
384         ns->vfconfigs[vf].link_state = state;
385
386         return 0;
387 }
388
389 static int
390 nsim_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data)
391 {
392         switch (type) {
393         case TC_SETUP_BLOCK:
394                 return nsim_setup_tc_block(dev, type_data);
395         default:
396                 return -EOPNOTSUPP;
397         }
398 }
399
400 static int
401 nsim_set_features(struct net_device *dev, netdev_features_t features)
402 {
403         struct netdevsim *ns = netdev_priv(dev);
404
405         if ((dev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC))
406                 return nsim_bpf_disable_tc(ns);
407
408         return 0;
409 }
410
411 static const struct net_device_ops nsim_netdev_ops = {
412         .ndo_init               = nsim_init,
413         .ndo_uninit             = nsim_uninit,
414         .ndo_start_xmit         = nsim_start_xmit,
415         .ndo_set_rx_mode        = nsim_set_rx_mode,
416         .ndo_set_mac_address    = eth_mac_addr,
417         .ndo_validate_addr      = eth_validate_addr,
418         .ndo_change_mtu         = nsim_change_mtu,
419         .ndo_get_stats64        = nsim_get_stats64,
420         .ndo_set_vf_mac         = nsim_set_vf_mac,
421         .ndo_set_vf_vlan        = nsim_set_vf_vlan,
422         .ndo_set_vf_rate        = nsim_set_vf_rate,
423         .ndo_set_vf_spoofchk    = nsim_set_vf_spoofchk,
424         .ndo_set_vf_trust       = nsim_set_vf_trust,
425         .ndo_get_vf_config      = nsim_get_vf_config,
426         .ndo_set_vf_link_state  = nsim_set_vf_link_state,
427         .ndo_set_vf_rss_query_en = nsim_set_vf_rss_query_en,
428         .ndo_setup_tc           = nsim_setup_tc,
429         .ndo_set_features       = nsim_set_features,
430         .ndo_bpf                = nsim_bpf,
431 };
432
433 static void nsim_setup(struct net_device *dev)
434 {
435         ether_setup(dev);
436         eth_hw_addr_random(dev);
437
438         dev->netdev_ops = &nsim_netdev_ops;
439         dev->priv_destructor = nsim_free;
440
441         dev->tx_queue_len = 0;
442         dev->flags |= IFF_NOARP;
443         dev->flags &= ~IFF_MULTICAST;
444         dev->priv_flags |= IFF_LIVE_ADDR_CHANGE |
445                            IFF_NO_QUEUE;
446         dev->features |= NETIF_F_HIGHDMA |
447                          NETIF_F_SG |
448                          NETIF_F_FRAGLIST |
449                          NETIF_F_HW_CSUM |
450                          NETIF_F_TSO;
451         dev->hw_features |= NETIF_F_HW_TC;
452         dev->max_mtu = ETH_MAX_MTU;
453 }
454
455 static int nsim_validate(struct nlattr *tb[], struct nlattr *data[],
456                          struct netlink_ext_ack *extack)
457 {
458         if (tb[IFLA_ADDRESS]) {
459                 if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
460                         return -EINVAL;
461                 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
462                         return -EADDRNOTAVAIL;
463         }
464         return 0;
465 }
466
467 static struct rtnl_link_ops nsim_link_ops __read_mostly = {
468         .kind           = DRV_NAME,
469         .priv_size      = sizeof(struct netdevsim),
470         .setup          = nsim_setup,
471         .validate       = nsim_validate,
472 };
473
474 struct dentry *nsim_ddir;
475
476 static int __init nsim_module_init(void)
477 {
478         int err;
479
480         nsim_ddir = debugfs_create_dir(DRV_NAME, NULL);
481         if (IS_ERR_OR_NULL(nsim_ddir))
482                 return -ENOMEM;
483
484         err = bus_register(&nsim_bus);
485         if (err)
486                 goto err_debugfs_destroy;
487
488         err = nsim_devlink_init();
489         if (err)
490                 goto err_unreg_bus;
491
492         err = rtnl_link_register(&nsim_link_ops);
493         if (err)
494                 goto err_dl_fini;
495
496         return 0;
497
498 err_dl_fini:
499         nsim_devlink_exit();
500 err_unreg_bus:
501         bus_unregister(&nsim_bus);
502 err_debugfs_destroy:
503         debugfs_remove_recursive(nsim_ddir);
504         return err;
505 }
506
507 static void __exit nsim_module_exit(void)
508 {
509         rtnl_link_unregister(&nsim_link_ops);
510         nsim_devlink_exit();
511         bus_unregister(&nsim_bus);
512         debugfs_remove_recursive(nsim_ddir);
513 }
514
515 module_init(nsim_module_init);
516 module_exit(nsim_module_exit);
517 MODULE_LICENSE("GPL");
518 MODULE_ALIAS_RTNL_LINK(DRV_NAME);
This page took 0.061643 seconds and 4 git commands to generate.