diff options
Diffstat (limited to 'drivers/net/netdevsim')
| -rw-r--r-- | drivers/net/netdevsim/dev.c | 56 | ||||
| -rw-r--r-- | drivers/net/netdevsim/ipsec.c | 1 | ||||
| -rw-r--r-- | drivers/net/netdevsim/netdev.c | 33 | ||||
| -rw-r--r-- | drivers/net/netdevsim/netdevsim.h | 6 | ||||
| -rw-r--r-- | drivers/net/netdevsim/psp.c | 27 |
5 files changed, 111 insertions, 12 deletions
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c index 95f66c1f59db..2683a989873e 100644 --- a/drivers/net/netdevsim/dev.c +++ b/drivers/net/netdevsim/dev.c @@ -320,6 +320,8 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev) &nsim_dev->max_macs); debugfs_create_bool("test1", 0600, nsim_dev->ddir, &nsim_dev->test1); + debugfs_create_u32("test2", 0600, nsim_dev->ddir, + &nsim_dev->test2); nsim_dev->take_snapshot = debugfs_create_file("take_snapshot", 0200, nsim_dev->ddir, @@ -521,8 +523,53 @@ err_out: enum nsim_devlink_param_id { NSIM_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX, NSIM_DEVLINK_PARAM_ID_TEST1, + NSIM_DEVLINK_PARAM_ID_TEST2, }; +static int +nsim_devlink_param_test2_get(struct devlink *devlink, u32 id, + struct devlink_param_gset_ctx *ctx, + struct netlink_ext_ack *extack) +{ + struct nsim_dev *nsim_dev = devlink_priv(devlink); + + ctx->val.vu32 = nsim_dev->test2; + return 0; +} + +static int +nsim_devlink_param_test2_set(struct devlink *devlink, u32 id, + struct devlink_param_gset_ctx *ctx, + struct netlink_ext_ack *extack) +{ + struct nsim_dev *nsim_dev = devlink_priv(devlink); + + nsim_dev->test2 = ctx->val.vu32; + return 0; +} + +#define NSIM_DEV_TEST2_DEFAULT 1234 + +static int +nsim_devlink_param_test2_get_default(struct devlink *devlink, u32 id, + struct devlink_param_gset_ctx *ctx, + struct netlink_ext_ack *extack) +{ + ctx->val.vu32 = NSIM_DEV_TEST2_DEFAULT; + return 0; +} + +static int +nsim_devlink_param_test2_reset_default(struct devlink *devlink, u32 id, + enum devlink_param_cmode cmode, + struct netlink_ext_ack *extack) +{ + struct nsim_dev *nsim_dev = devlink_priv(devlink); + + nsim_dev->test2 = NSIM_DEV_TEST2_DEFAULT; + return 0; +} + static const struct devlink_param nsim_devlink_params[] = { DEVLINK_PARAM_GENERIC(MAX_MACS, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT), @@ -531,6 +578,14 @@ static const struct devlink_param nsim_devlink_params[] = { "test1", DEVLINK_PARAM_TYPE_BOOL, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT), NULL, NULL, NULL), + DEVLINK_PARAM_DRIVER_WITH_DEFAULTS(NSIM_DEVLINK_PARAM_ID_TEST2, + "test2", DEVLINK_PARAM_TYPE_U32, + BIT(DEVLINK_PARAM_CMODE_RUNTIME), + nsim_devlink_param_test2_get, + nsim_devlink_param_test2_set, + NULL, + nsim_devlink_param_test2_get_default, + nsim_devlink_param_test2_reset_default), }; static void nsim_devlink_set_params_init_values(struct nsim_dev *nsim_dev, @@ -1590,6 +1645,7 @@ int nsim_drv_probe(struct nsim_bus_dev *nsim_bus_dev) nsim_dev->fw_update_flash_chunk_time_ms = NSIM_DEV_FLASH_CHUNK_TIME_MS_DEFAULT; nsim_dev->max_macs = NSIM_DEV_MAX_MACS_DEFAULT; nsim_dev->test1 = NSIM_DEV_TEST1_DEFAULT; + nsim_dev->test2 = NSIM_DEV_TEST2_DEFAULT; spin_lock_init(&nsim_dev->fa_cookie_lock); dev_set_drvdata(&nsim_bus_dev->dev, nsim_dev); diff --git a/drivers/net/netdevsim/ipsec.c b/drivers/net/netdevsim/ipsec.c index 47cdee5577d4..36a1be4923d6 100644 --- a/drivers/net/netdevsim/ipsec.c +++ b/drivers/net/netdevsim/ipsec.c @@ -277,6 +277,7 @@ void nsim_ipsec_init(struct netdevsim *ns) NETIF_F_GSO_ESP) ns->netdev->features |= NSIM_ESP_FEATURES; + ns->netdev->hw_features |= NSIM_ESP_FEATURES; ns->netdev->hw_enc_features |= NSIM_ESP_FEATURES; ns->ipsec.pfile = debugfs_create_file("ipsec", 0400, diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c index ebc3833e95b4..6927c1962277 100644 --- a/drivers/net/netdevsim/netdev.c +++ b/drivers/net/netdevsim/netdev.c @@ -133,15 +133,21 @@ static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev) if (!nsim_ipsec_tx(ns, skb)) goto out_drop_any; - peer_ns = rcu_dereference(ns->peer); - if (!peer_ns) - goto out_drop_any; + /* Check if loopback mode is enabled */ + if (dev->features & NETIF_F_LOOPBACK) { + peer_ns = ns; + peer_dev = dev; + } else { + peer_ns = rcu_dereference(ns->peer); + if (!peer_ns) + goto out_drop_any; + peer_dev = peer_ns->netdev; + } dr = nsim_do_psp(skb, ns, peer_ns, &psp_ext); if (dr) goto out_drop_free; - peer_dev = peer_ns->netdev; rxq = skb_get_queue_mapping(skb); if (rxq >= peer_dev->num_rx_queues) rxq = rxq % peer_dev->num_rx_queues; @@ -433,13 +439,8 @@ static int nsim_rcv(struct nsim_rq *rq, int budget) } /* skb might be discard at netif_receive_skb, save the len */ - skblen = skb->len; - skb_mark_napi_id(skb, &rq->napi); - ret = netif_receive_skb(skb); - if (ret == NET_RX_SUCCESS) - dev_dstats_rx_add(dev, skblen); - else - dev_dstats_rx_dropped(dev); + dev_dstats_rx_add(dev, skb->len); + napi_gro_receive(&rq->napi, skb); } nsim_start_peer_tx_queue(dev, rq); @@ -545,6 +546,7 @@ static void nsim_enable_napi(struct netdevsim *ns) static int nsim_open(struct net_device *dev) { struct netdevsim *ns = netdev_priv(dev); + struct netdevsim *peer; int err; netdev_assert_locked(dev); @@ -555,6 +557,12 @@ static int nsim_open(struct net_device *dev) nsim_enable_napi(ns); + peer = rtnl_dereference(ns->peer); + if (peer && netif_running(peer->netdev)) { + netif_carrier_on(dev); + netif_carrier_on(peer->netdev); + } + return 0; } @@ -974,7 +982,8 @@ static void nsim_setup(struct net_device *dev) NETIF_F_FRAGLIST | NETIF_F_HW_CSUM | NETIF_F_LRO | - NETIF_F_TSO; + NETIF_F_TSO | + NETIF_F_LOOPBACK; dev->pcpu_stat_type = NETDEV_PCPU_STAT_DSTATS; dev->max_mtu = ETH_MAX_MTU; dev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_HW_OFFLOAD; diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h index 02c1c97b7008..d1a941e2b18f 100644 --- a/drivers/net/netdevsim/netdevsim.h +++ b/drivers/net/netdevsim/netdevsim.h @@ -109,6 +109,11 @@ struct netdevsim { int rq_reset_mode; struct { + u64 rx_packets; + u64 rx_bytes; + u64 tx_packets; + u64 tx_bytes; + struct u64_stats_sync syncp; struct psp_dev *dev; u32 spi; u32 assoc_cnt; @@ -326,6 +331,7 @@ struct nsim_dev { u32 fw_update_flash_chunk_time_ms; u32 max_macs; bool test1; + u32 test2; bool dont_allow_reload; bool fail_reload; struct devlink_region *dummy_region; diff --git a/drivers/net/netdevsim/psp.c b/drivers/net/netdevsim/psp.c index 332b5b744f01..727da06101ca 100644 --- a/drivers/net/netdevsim/psp.c +++ b/drivers/net/netdevsim/psp.c @@ -70,6 +70,13 @@ nsim_do_psp(struct sk_buff *skb, struct netdevsim *ns, *psp_ext = skb->extensions; refcount_inc(&(*psp_ext)->refcnt); skb->decrypted = 1; + + u64_stats_update_begin(&ns->psp.syncp); + ns->psp.tx_packets++; + ns->psp.rx_packets++; + ns->psp.tx_bytes += skb->len - skb_inner_transport_offset(skb); + ns->psp.rx_bytes += skb->len - skb_inner_transport_offset(skb); + u64_stats_update_end(&ns->psp.syncp); } else { struct ipv6hdr *ip6h __maybe_unused; struct iphdr *iph; @@ -164,12 +171,32 @@ static void nsim_assoc_del(struct psp_dev *psd, struct psp_assoc *pas) ns->psp.assoc_cnt--; } +static void nsim_get_stats(struct psp_dev *psd, struct psp_dev_stats *stats) +{ + struct netdevsim *ns = psd->drv_priv; + unsigned int start; + + /* WARNING: do *not* blindly zero stats in real drivers! + * All required stats must be reported by the device! + */ + memset(stats, 0, sizeof(struct psp_dev_stats)); + + do { + start = u64_stats_fetch_begin(&ns->psp.syncp); + stats->rx_bytes = ns->psp.rx_bytes; + stats->rx_packets = ns->psp.rx_packets; + stats->tx_bytes = ns->psp.tx_bytes; + stats->tx_packets = ns->psp.tx_packets; + } while (u64_stats_fetch_retry(&ns->psp.syncp, start)); +} + static struct psp_dev_ops nsim_psp_ops = { .set_config = nsim_psp_set_config, .rx_spi_alloc = nsim_rx_spi_alloc, .tx_key_add = nsim_assoc_add, .tx_key_del = nsim_assoc_del, .key_rotate = nsim_key_rotate, + .get_stats = nsim_get_stats, }; static struct psp_dev_caps nsim_psp_caps = { |
