2 * Copyright (C) 2017 Netronome Systems, Inc.
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
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.
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>
26 #include "netdevsim.h"
28 struct nsim_vf_config
{
36 bool spoofchk_enabled
;
38 bool rss_query_enabled
;
41 static u32 nsim_dev_id
;
43 static struct dentry
*nsim_ddir
;
44 static struct dentry
*nsim_sdev_ddir
;
46 static int nsim_num_vf(struct device
*dev
)
48 struct netdevsim
*ns
= to_nsim(dev
);
53 static struct bus_type nsim_bus
= {
56 .num_vf
= nsim_num_vf
,
59 static int nsim_vfs_enable(struct netdevsim
*ns
, unsigned int num_vfs
)
61 ns
->vfconfigs
= kcalloc(num_vfs
, sizeof(struct nsim_vf_config
),
65 ns
->num_vfs
= num_vfs
;
70 static void nsim_vfs_disable(struct netdevsim
*ns
)
78 nsim_numvfs_store(struct device
*dev
, struct device_attribute
*attr
,
79 const char *buf
, size_t count
)
81 struct netdevsim
*ns
= to_nsim(dev
);
85 ret
= kstrtouint(buf
, 0, &num_vfs
);
90 if (ns
->num_vfs
== num_vfs
)
92 if (ns
->num_vfs
&& num_vfs
) {
98 ret
= nsim_vfs_enable(ns
, num_vfs
);
102 nsim_vfs_disable(ns
);
113 nsim_numvfs_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
115 struct netdevsim
*ns
= to_nsim(dev
);
117 return sprintf(buf
, "%u\n", ns
->num_vfs
);
120 static struct device_attribute nsim_numvfs_attr
=
121 __ATTR(sriov_numvfs
, 0664, nsim_numvfs_show
, nsim_numvfs_store
);
123 static struct attribute
*nsim_dev_attrs
[] = {
124 &nsim_numvfs_attr
.attr
,
128 static const struct attribute_group nsim_dev_attr_group
= {
129 .attrs
= nsim_dev_attrs
,
132 static const struct attribute_group
*nsim_dev_attr_groups
[] = {
133 &nsim_dev_attr_group
,
137 static void nsim_dev_release(struct device
*dev
)
139 struct netdevsim
*ns
= to_nsim(dev
);
141 nsim_vfs_disable(ns
);
142 free_netdev(ns
->netdev
);
145 static struct device_type nsim_dev_type
= {
146 .groups
= nsim_dev_attr_groups
,
147 .release
= nsim_dev_release
,
150 static int nsim_get_port_parent_id(struct net_device
*dev
,
151 struct netdev_phys_item_id
*ppid
)
153 struct netdevsim
*ns
= netdev_priv(dev
);
155 ppid
->id_len
= sizeof(ns
->sdev
->switch_id
);
156 memcpy(&ppid
->id
, &ns
->sdev
->switch_id
, ppid
->id_len
);
160 static int nsim_init(struct net_device
*dev
)
162 char sdev_ddir_name
[10], sdev_link_name
[32];
163 struct netdevsim
*ns
= netdev_priv(dev
);
167 ns
->ddir
= debugfs_create_dir(netdev_name(dev
), nsim_ddir
);
168 if (IS_ERR_OR_NULL(ns
->ddir
))
172 ns
->sdev
= kzalloc(sizeof(*ns
->sdev
), GFP_KERNEL
);
175 goto err_debugfs_destroy
;
177 ns
->sdev
->refcnt
= 1;
178 ns
->sdev
->switch_id
= nsim_dev_id
;
179 sprintf(sdev_ddir_name
, "%u", ns
->sdev
->switch_id
);
180 ns
->sdev
->ddir
= debugfs_create_dir(sdev_ddir_name
,
182 if (IS_ERR_OR_NULL(ns
->sdev
->ddir
)) {
183 err
= PTR_ERR_OR_ZERO(ns
->sdev
->ddir
) ?: -EINVAL
;
187 sprintf(sdev_ddir_name
, "%u", ns
->sdev
->switch_id
);
191 sprintf(sdev_link_name
, "../../" DRV_NAME
"_sdev/%s", sdev_ddir_name
);
192 debugfs_create_symlink("sdev", ns
->ddir
, sdev_link_name
);
194 err
= nsim_bpf_init(ns
);
196 goto err_sdev_destroy
;
198 ns
->dev
.id
= nsim_dev_id
++;
199 ns
->dev
.bus
= &nsim_bus
;
200 ns
->dev
.type
= &nsim_dev_type
;
201 err
= device_register(&ns
->dev
);
205 SET_NETDEV_DEV(dev
, &ns
->dev
);
207 err
= nsim_devlink_setup(ns
);
216 device_unregister(&ns
->dev
);
220 if (!--ns
->sdev
->refcnt
) {
221 debugfs_remove_recursive(ns
->sdev
->ddir
);
226 debugfs_remove_recursive(ns
->ddir
);
230 static void nsim_uninit(struct net_device
*dev
)
232 struct netdevsim
*ns
= netdev_priv(dev
);
234 nsim_ipsec_teardown(ns
);
235 nsim_devlink_teardown(ns
);
236 debugfs_remove_recursive(ns
->ddir
);
238 if (!--ns
->sdev
->refcnt
) {
239 debugfs_remove_recursive(ns
->sdev
->ddir
);
244 static void nsim_free(struct net_device
*dev
)
246 struct netdevsim
*ns
= netdev_priv(dev
);
248 device_unregister(&ns
->dev
);
249 /* netdev and vf state will be freed out of device_release() */
252 static netdev_tx_t
nsim_start_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
254 struct netdevsim
*ns
= netdev_priv(dev
);
256 if (!nsim_ipsec_tx(ns
, skb
))
259 u64_stats_update_begin(&ns
->syncp
);
261 ns
->tx_bytes
+= skb
->len
;
262 u64_stats_update_end(&ns
->syncp
);
270 static void nsim_set_rx_mode(struct net_device
*dev
)
274 static int nsim_change_mtu(struct net_device
*dev
, int new_mtu
)
276 struct netdevsim
*ns
= netdev_priv(dev
);
278 if (ns
->xdp
.prog
&& new_mtu
> NSIM_XDP_MAX_MTU
)
287 nsim_get_stats64(struct net_device
*dev
, struct rtnl_link_stats64
*stats
)
289 struct netdevsim
*ns
= netdev_priv(dev
);
293 start
= u64_stats_fetch_begin(&ns
->syncp
);
294 stats
->tx_bytes
= ns
->tx_bytes
;
295 stats
->tx_packets
= ns
->tx_packets
;
296 } while (u64_stats_fetch_retry(&ns
->syncp
, start
));
300 nsim_setup_tc_block_cb(enum tc_setup_type type
, void *type_data
, void *cb_priv
)
302 return nsim_bpf_setup_tc_block_cb(type
, type_data
, cb_priv
);
306 nsim_setup_tc_block(struct net_device
*dev
, struct tc_block_offload
*f
)
308 struct netdevsim
*ns
= netdev_priv(dev
);
310 if (f
->binder_type
!= TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS
)
313 switch (f
->command
) {
315 return tcf_block_cb_register(f
->block
, nsim_setup_tc_block_cb
,
317 case TC_BLOCK_UNBIND
:
318 tcf_block_cb_unregister(f
->block
, nsim_setup_tc_block_cb
, ns
);
325 static int nsim_set_vf_mac(struct net_device
*dev
, int vf
, u8
*mac
)
327 struct netdevsim
*ns
= netdev_priv(dev
);
329 /* Only refuse multicast addresses, zero address can mean unset/any. */
330 if (vf
>= ns
->num_vfs
|| is_multicast_ether_addr(mac
))
332 memcpy(ns
->vfconfigs
[vf
].vf_mac
, mac
, ETH_ALEN
);
337 static int nsim_set_vf_vlan(struct net_device
*dev
, int vf
,
338 u16 vlan
, u8 qos
, __be16 vlan_proto
)
340 struct netdevsim
*ns
= netdev_priv(dev
);
342 if (vf
>= ns
->num_vfs
|| vlan
> 4095 || qos
> 7)
345 ns
->vfconfigs
[vf
].vlan
= vlan
;
346 ns
->vfconfigs
[vf
].qos
= qos
;
347 ns
->vfconfigs
[vf
].vlan_proto
= vlan_proto
;
352 static int nsim_set_vf_rate(struct net_device
*dev
, int vf
, int min
, int max
)
354 struct netdevsim
*ns
= netdev_priv(dev
);
356 if (vf
>= ns
->num_vfs
)
359 ns
->vfconfigs
[vf
].min_tx_rate
= min
;
360 ns
->vfconfigs
[vf
].max_tx_rate
= max
;
365 static int nsim_set_vf_spoofchk(struct net_device
*dev
, int vf
, bool val
)
367 struct netdevsim
*ns
= netdev_priv(dev
);
369 if (vf
>= ns
->num_vfs
)
371 ns
->vfconfigs
[vf
].spoofchk_enabled
= val
;
376 static int nsim_set_vf_rss_query_en(struct net_device
*dev
, int vf
, bool val
)
378 struct netdevsim
*ns
= netdev_priv(dev
);
380 if (vf
>= ns
->num_vfs
)
382 ns
->vfconfigs
[vf
].rss_query_enabled
= val
;
387 static int nsim_set_vf_trust(struct net_device
*dev
, int vf
, bool val
)
389 struct netdevsim
*ns
= netdev_priv(dev
);
391 if (vf
>= ns
->num_vfs
)
393 ns
->vfconfigs
[vf
].trusted
= val
;
399 nsim_get_vf_config(struct net_device
*dev
, int vf
, struct ifla_vf_info
*ivi
)
401 struct netdevsim
*ns
= netdev_priv(dev
);
403 if (vf
>= ns
->num_vfs
)
407 ivi
->linkstate
= ns
->vfconfigs
[vf
].link_state
;
408 ivi
->min_tx_rate
= ns
->vfconfigs
[vf
].min_tx_rate
;
409 ivi
->max_tx_rate
= ns
->vfconfigs
[vf
].max_tx_rate
;
410 ivi
->vlan
= ns
->vfconfigs
[vf
].vlan
;
411 ivi
->vlan_proto
= ns
->vfconfigs
[vf
].vlan_proto
;
412 ivi
->qos
= ns
->vfconfigs
[vf
].qos
;
413 memcpy(&ivi
->mac
, ns
->vfconfigs
[vf
].vf_mac
, ETH_ALEN
);
414 ivi
->spoofchk
= ns
->vfconfigs
[vf
].spoofchk_enabled
;
415 ivi
->trusted
= ns
->vfconfigs
[vf
].trusted
;
416 ivi
->rss_query_en
= ns
->vfconfigs
[vf
].rss_query_enabled
;
421 static int nsim_set_vf_link_state(struct net_device
*dev
, int vf
, int state
)
423 struct netdevsim
*ns
= netdev_priv(dev
);
425 if (vf
>= ns
->num_vfs
)
429 case IFLA_VF_LINK_STATE_AUTO
:
430 case IFLA_VF_LINK_STATE_ENABLE
:
431 case IFLA_VF_LINK_STATE_DISABLE
:
437 ns
->vfconfigs
[vf
].link_state
= state
;
443 nsim_setup_tc(struct net_device
*dev
, enum tc_setup_type type
, void *type_data
)
447 return nsim_setup_tc_block(dev
, type_data
);
454 nsim_set_features(struct net_device
*dev
, netdev_features_t features
)
456 struct netdevsim
*ns
= netdev_priv(dev
);
458 if ((dev
->features
& NETIF_F_HW_TC
) > (features
& NETIF_F_HW_TC
))
459 return nsim_bpf_disable_tc(ns
);
464 static const struct net_device_ops nsim_netdev_ops
= {
465 .ndo_init
= nsim_init
,
466 .ndo_uninit
= nsim_uninit
,
467 .ndo_start_xmit
= nsim_start_xmit
,
468 .ndo_set_rx_mode
= nsim_set_rx_mode
,
469 .ndo_set_mac_address
= eth_mac_addr
,
470 .ndo_validate_addr
= eth_validate_addr
,
471 .ndo_change_mtu
= nsim_change_mtu
,
472 .ndo_get_stats64
= nsim_get_stats64
,
473 .ndo_set_vf_mac
= nsim_set_vf_mac
,
474 .ndo_set_vf_vlan
= nsim_set_vf_vlan
,
475 .ndo_set_vf_rate
= nsim_set_vf_rate
,
476 .ndo_set_vf_spoofchk
= nsim_set_vf_spoofchk
,
477 .ndo_set_vf_trust
= nsim_set_vf_trust
,
478 .ndo_get_vf_config
= nsim_get_vf_config
,
479 .ndo_set_vf_link_state
= nsim_set_vf_link_state
,
480 .ndo_set_vf_rss_query_en
= nsim_set_vf_rss_query_en
,
481 .ndo_setup_tc
= nsim_setup_tc
,
482 .ndo_set_features
= nsim_set_features
,
484 .ndo_get_port_parent_id
= nsim_get_port_parent_id
,
487 static void nsim_setup(struct net_device
*dev
)
490 eth_hw_addr_random(dev
);
492 dev
->netdev_ops
= &nsim_netdev_ops
;
493 dev
->priv_destructor
= nsim_free
;
495 dev
->tx_queue_len
= 0;
496 dev
->flags
|= IFF_NOARP
;
497 dev
->flags
&= ~IFF_MULTICAST
;
498 dev
->priv_flags
|= IFF_LIVE_ADDR_CHANGE
|
500 dev
->features
|= NETIF_F_HIGHDMA
|
505 dev
->hw_features
|= NETIF_F_HW_TC
;
506 dev
->max_mtu
= ETH_MAX_MTU
;
509 static int nsim_validate(struct nlattr
*tb
[], struct nlattr
*data
[],
510 struct netlink_ext_ack
*extack
)
512 if (tb
[IFLA_ADDRESS
]) {
513 if (nla_len(tb
[IFLA_ADDRESS
]) != ETH_ALEN
)
515 if (!is_valid_ether_addr(nla_data(tb
[IFLA_ADDRESS
])))
516 return -EADDRNOTAVAIL
;
521 static int nsim_newlink(struct net
*src_net
, struct net_device
*dev
,
522 struct nlattr
*tb
[], struct nlattr
*data
[],
523 struct netlink_ext_ack
*extack
)
525 struct netdevsim
*ns
= netdev_priv(dev
);
528 struct net_device
*joindev
;
529 struct netdevsim
*joinns
;
531 joindev
= __dev_get_by_index(src_net
,
532 nla_get_u32(tb
[IFLA_LINK
]));
535 if (joindev
->netdev_ops
!= &nsim_netdev_ops
)
538 joinns
= netdev_priv(joindev
);
539 if (!joinns
->sdev
|| !joinns
->sdev
->refcnt
)
541 ns
->sdev
= joinns
->sdev
;
544 return register_netdevice(dev
);
547 static void nsim_dellink(struct net_device
*dev
, struct list_head
*head
)
549 unregister_netdevice_queue(dev
, head
);
552 static struct rtnl_link_ops nsim_link_ops __read_mostly
= {
554 .priv_size
= sizeof(struct netdevsim
),
556 .validate
= nsim_validate
,
557 .newlink
= nsim_newlink
,
558 .dellink
= nsim_dellink
,
561 static int __init
nsim_module_init(void)
565 nsim_ddir
= debugfs_create_dir(DRV_NAME
, NULL
);
566 if (IS_ERR_OR_NULL(nsim_ddir
))
569 nsim_sdev_ddir
= debugfs_create_dir(DRV_NAME
"_sdev", NULL
);
570 if (IS_ERR_OR_NULL(nsim_sdev_ddir
)) {
572 goto err_debugfs_destroy
;
575 err
= bus_register(&nsim_bus
);
577 goto err_sdir_destroy
;
579 err
= nsim_devlink_init();
583 err
= rtnl_link_register(&nsim_link_ops
);
592 bus_unregister(&nsim_bus
);
594 debugfs_remove_recursive(nsim_sdev_ddir
);
596 debugfs_remove_recursive(nsim_ddir
);
600 static void __exit
nsim_module_exit(void)
602 rtnl_link_unregister(&nsim_link_ops
);
604 bus_unregister(&nsim_bus
);
605 debugfs_remove_recursive(nsim_sdev_ddir
);
606 debugfs_remove_recursive(nsim_ddir
);
609 module_init(nsim_module_init
);
610 module_exit(nsim_module_exit
);
611 MODULE_LICENSE("GPL");
612 MODULE_ALIAS_RTNL_LINK(DRV_NAME
);