summaryrefslogtreecommitdiff
path: root/drivers/net/netdevsim
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/netdevsim')
-rw-r--r--drivers/net/netdevsim/bpf.c11
-rw-r--r--drivers/net/netdevsim/bus.c7
-rw-r--r--drivers/net/netdevsim/ethtool.c53
-rw-r--r--drivers/net/netdevsim/ipsec.c10
-rw-r--r--drivers/net/netdevsim/netdev.c10
-rw-r--r--drivers/net/netdevsim/netdevsim.h8
-rw-r--r--drivers/net/netdevsim/psp.c33
7 files changed, 87 insertions, 45 deletions
diff --git a/drivers/net/netdevsim/bpf.c b/drivers/net/netdevsim/bpf.c
index 16aa88278398..f45c1c8f0584 100644
--- a/drivers/net/netdevsim/bpf.c
+++ b/drivers/net/netdevsim/bpf.c
@@ -144,6 +144,17 @@ int nsim_bpf_setup_tc_block_cb(enum tc_setup_type type,
return -EOPNOTSUPP;
}
+ /* A dev-bound program can be replayed here when a netdev joins
+ * a shared block, after the core attach-time check has run;
+ * enforce the device match as nfp does.
+ */
+ if (prog && bpf_prog_is_dev_bound(prog->aux) &&
+ !bpf_offload_dev_match(prog, ns->netdev)) {
+ NSIM_EA(cls_bpf->common.extack,
+ "program bound to a different device");
+ return -EINVAL;
+ }
+
if (cls_bpf->command != TC_CLSBPF_OFFLOAD)
return -EOPNOTSUPP;
diff --git a/drivers/net/netdevsim/bus.c b/drivers/net/netdevsim/bus.c
index 5c55c308487b..b792ee10b1c1 100644
--- a/drivers/net/netdevsim/bus.c
+++ b/drivers/net/netdevsim/bus.c
@@ -194,7 +194,6 @@ new_device_store(const struct bus_type *bus, const char *buf, size_t count)
goto err;
}
- refcount_inc(&nsim_bus_devs);
/* Allow using nsim_bus_dev */
smp_store_release(&nsim_bus_dev->init, true);
@@ -465,6 +464,7 @@ nsim_bus_dev_new(unsigned int id, unsigned int port_count, unsigned int num_queu
/* Disallow using nsim_bus_dev */
smp_store_release(&nsim_bus_dev->init, false);
+ refcount_inc(&nsim_bus_devs);
err = device_register(&nsim_bus_dev->dev);
if (err)
goto err_nsim_bus_dev_id_free;
@@ -520,8 +520,6 @@ void nsim_bus_exit(void)
/* Disallow using resources */
smp_store_release(&nsim_bus_enable, false);
- if (refcount_dec_and_test(&nsim_bus_devs))
- complete(&nsim_bus_devs_released);
mutex_lock(&nsim_bus_dev_list_lock);
list_for_each_entry_safe(nsim_bus_dev, tmp, &nsim_bus_dev_list, list) {
@@ -530,6 +528,9 @@ void nsim_bus_exit(void)
}
mutex_unlock(&nsim_bus_dev_list_lock);
+ if (refcount_dec_and_test(&nsim_bus_devs))
+ complete(&nsim_bus_devs_released);
+
wait_for_completion(&nsim_bus_devs_released);
driver_unregister(&nsim_driver);
diff --git a/drivers/net/netdevsim/ethtool.c b/drivers/net/netdevsim/ethtool.c
index 025ea79879f3..c3d2bc783d55 100644
--- a/drivers/net/netdevsim/ethtool.c
+++ b/drivers/net/netdevsim/ethtool.c
@@ -205,7 +205,59 @@ static int nsim_get_ts_info(struct net_device *dev,
return 0;
}
+static u32 nsim_get_rxfh_key_size(struct net_device *dev)
+{
+ return NETDEV_RSS_KEY_LEN;
+}
+
+static u32 nsim_get_rxfh_indir_size(struct net_device *dev)
+{
+ return NSIM_RSS_INDIR_SIZE;
+}
+
+static int nsim_get_rxfh(struct net_device *dev,
+ struct ethtool_rxfh_param *rxfh)
+{
+ struct netdevsim *ns = netdev_priv(dev);
+ u32 i;
+
+ rxfh->hfunc = ETH_RSS_HASH_TOP;
+ if (rxfh->indir) {
+ for (i = 0; i < NSIM_RSS_INDIR_SIZE; i++)
+ rxfh->indir[i] = ethtool_rxfh_indir_default(i, ns->ethtool.channels);
+ }
+ if (rxfh->key)
+ memcpy(rxfh->key, ns->ethtool.rss_key,
+ sizeof(ns->ethtool.rss_key));
+
+ return 0;
+}
+
+static int nsim_get_rxfh_fields(struct net_device *dev,
+ struct ethtool_rxfh_fields *info)
+{
+ switch (info->flow_type) {
+ case TCP_V4_FLOW:
+ case UDP_V4_FLOW:
+ case TCP_V6_FLOW:
+ case UDP_V6_FLOW:
+ info->data = RXH_IP_SRC | RXH_IP_DST |
+ RXH_L4_B_0_1 | RXH_L4_B_2_3;
+ return 0;
+ case IPV4_FLOW:
+ case IPV6_FLOW:
+ info->data = RXH_IP_SRC | RXH_IP_DST;
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
static const struct ethtool_ops nsim_ethtool_ops = {
+ .get_rxfh_key_size = nsim_get_rxfh_key_size,
+ .get_rxfh_indir_size = nsim_get_rxfh_indir_size,
+ .get_rxfh = nsim_get_rxfh,
+ .get_rxfh_fields = nsim_get_rxfh_fields,
.supported_coalesce_params = ETHTOOL_COALESCE_ALL_PARAMS,
.supported_ring_params = ETHTOOL_RING_USE_TCP_DATA_SPLIT |
ETHTOOL_RING_USE_HDS_THRS,
@@ -250,6 +302,7 @@ void nsim_ethtool_init(struct netdevsim *ns)
ns->ethtool.fec.active_fec = ETHTOOL_FEC_NONE;
ns->ethtool.channels = ns->nsim_bus_dev->num_queues;
+ netdev_rss_key_fill(ns->ethtool.rss_key, sizeof(ns->ethtool.rss_key));
ethtool = debugfs_create_dir("ethtool", ns->nsim_dev_port->ddir);
ns->ethtool_ddir = ethtool;
diff --git a/drivers/net/netdevsim/ipsec.c b/drivers/net/netdevsim/ipsec.c
index 36a1be4923d6..5722837bcda3 100644
--- a/drivers/net/netdevsim/ipsec.c
+++ b/drivers/net/netdevsim/ipsec.c
@@ -50,11 +50,11 @@ static ssize_t nsim_dbg_netdev_ops_read(struct file *filp,
p += scnprintf(p, bufsize - (p - buf),
"sa[%i] spi=0x%08x proto=0x%x salt=0x%08x crypt=%d\n",
i, be32_to_cpu(sap->xs->id.spi),
- sap->xs->id.proto, sap->salt, sap->crypt);
+ sap->xs->id.proto, be32_to_cpu(sap->salt), sap->crypt);
p += scnprintf(p, bufsize - (p - buf),
"sa[%i] key=0x%08x %08x %08x %08x\n",
- i, sap->key[0], sap->key[1],
- sap->key[2], sap->key[3]);
+ i, be32_to_cpu(sap->key[0]), be32_to_cpu(sap->key[1]),
+ be32_to_cpu(sap->key[2]), be32_to_cpu(sap->key[3]));
}
len = simple_read_from_buffer(buffer, count, ppos, buf, p - buf);
@@ -87,7 +87,7 @@ static int nsim_ipsec_find_empty_idx(struct nsim_ipsec *ipsec)
static int nsim_ipsec_parse_proto_keys(struct net_device *dev,
struct xfrm_state *xs,
- u32 *mykey, u32 *mysalt)
+ __be32 *mykey, __be32 *mysalt)
{
const char aes_gcm_name[] = "rfc4106(gcm(aes))";
unsigned char *key_data;
@@ -117,7 +117,7 @@ static int nsim_ipsec_parse_proto_keys(struct net_device *dev,
/* 160 accounts for 16 byte key and 4 byte salt */
if (key_len > NSIM_IPSEC_AUTH_BITS) {
- *mysalt = ((u32 *)key_data)[4];
+ *mysalt = ((__be32 *)key_data)[4];
} else if (key_len == NSIM_IPSEC_AUTH_BITS) {
*mysalt = 0;
} else {
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index b4a99f3ceac6..eebc02ccc4a9 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -185,6 +185,14 @@ out_drop_cnt:
return NETDEV_TX_OK;
}
+static netdev_tx_t nsim_start_xmit_vf(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ dev_dstats_tx_dropped(dev);
+ kfree_skb(skb);
+ return NETDEV_TX_OK;
+}
+
static int nsim_set_rx_mode(struct net_device *dev,
struct netdev_hw_addr_list *uc,
struct netdev_hw_addr_list *mc)
@@ -651,7 +659,7 @@ static const struct net_device_ops nsim_netdev_ops = {
};
static const struct net_device_ops nsim_vf_netdev_ops = {
- .ndo_start_xmit = nsim_start_xmit,
+ .ndo_start_xmit = nsim_start_xmit_vf,
.ndo_set_rx_mode_async = nsim_set_rx_mode,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index 55aec41237b9..fd5599cd3bb9 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -42,8 +42,8 @@
struct nsim_sa {
struct xfrm_state *xs;
__be32 ipaddr[4];
- u32 key[4];
- u32 salt;
+ __be32 key[4];
+ __be32 salt;
bool used;
bool crypt;
bool rx;
@@ -87,10 +87,13 @@ struct nsim_ethtool_pauseparam {
bool report_stats_tx;
};
+#define NSIM_RSS_INDIR_SIZE 128
+
struct nsim_ethtool {
u32 get_err;
u32 set_err;
u32 channels;
+ u8 rss_key[NETDEV_RSS_KEY_LEN];
struct nsim_ethtool_pauseparam pauseparam;
struct ethtool_coalesce coalesce;
struct ethtool_ringparam ring;
@@ -122,7 +125,6 @@ struct netdevsim {
struct dentry *rereg;
struct mutex rereg_lock;
u32 spi;
- u32 assoc_cnt;
} psp;
struct nsim_bus_dev *nsim_bus_dev;
diff --git a/drivers/net/netdevsim/psp.c b/drivers/net/netdevsim/psp.c
index 6b3532b5e360..b7452c49b581 100644
--- a/drivers/net/netdevsim/psp.c
+++ b/drivers/net/netdevsim/psp.c
@@ -23,7 +23,6 @@ nsim_do_psp(struct sk_buff *skb, struct netdevsim *ns,
struct psp_assoc *pas;
struct net *net;
int psp_len;
- void **ptr;
rcu_read_lock();
pas = psp_skb_get_assoc_rcu(skb);
@@ -37,12 +36,6 @@ nsim_do_psp(struct sk_buff *skb, struct netdevsim *ns,
goto out_unlock;
}
- ptr = psp_assoc_drv_data(pas);
- if (*ptr != ns) {
- rc = SKB_DROP_REASON_PSP_OUTPUT;
- goto out_unlock;
- }
-
net = sock_net(skb->sk);
if (!psp_dev_encapsulate(net, skb, pas->tx.spi, pas->version, 0)) {
rc = SKB_DROP_REASON_PSP_OUTPUT;
@@ -149,19 +142,6 @@ nsim_rx_spi_alloc(struct psp_dev *psd, u32 version,
return 0;
}
-static int nsim_assoc_add(struct psp_dev *psd, struct psp_assoc *pas,
- struct netlink_ext_ack *extack)
-{
- struct netdevsim *ns = psd->drv_priv;
- void **ptr = psp_assoc_drv_data(pas);
-
- /* Copy drv_priv from psd to assoc */
- *ptr = psd->drv_priv;
- ns->psp.assoc_cnt++;
-
- return 0;
-}
-
static int nsim_key_rotate(struct psp_dev *psd, struct netlink_ext_ack *extack)
{
struct netdevsim *ns = psd->drv_priv;
@@ -177,15 +157,6 @@ static int nsim_key_rotate(struct psp_dev *psd, struct netlink_ext_ack *extack)
return 0;
}
-static void nsim_assoc_del(struct psp_dev *psd, struct psp_assoc *pas)
-{
- struct netdevsim *ns = psd->drv_priv;
- void **ptr = psp_assoc_drv_data(pas);
-
- *ptr = NULL;
- ns->psp.assoc_cnt--;
-}
-
static void nsim_get_stats(struct psp_dev *psd, struct psp_dev_stats *stats)
{
struct netdevsim *ns = psd->drv_priv;
@@ -204,8 +175,6 @@ static void nsim_get_stats(struct psp_dev *psd, struct psp_dev_stats *stats)
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,
};
@@ -215,7 +184,6 @@ static struct psp_dev_caps nsim_psp_caps = {
1 << PSP_VERSION_HDR0_AES_GMAC_128 |
1 << PSP_VERSION_HDR0_AES_GCM_256 |
1 << PSP_VERSION_HDR0_AES_GMAC_256,
- .assoc_drv_spc = sizeof(void *),
};
static void __nsim_psp_uninit(struct netdevsim *ns, bool teardown)
@@ -230,7 +198,6 @@ static void __nsim_psp_uninit(struct netdevsim *ns, bool teardown)
synchronize_rcu();
psp_dev_unregister(psd);
}
- WARN_ON(ns->psp.assoc_cnt);
}
void nsim_psp_uninit(struct netdevsim *ns)