|
@@ -54,11 +54,14 @@ const struct rhashtable_params nfp_bpf_maps_neutral_params = {
|
|
|
static bool nfp_net_ebpf_capable(struct nfp_net *nn)
|
|
|
{
|
|
|
#ifdef __LITTLE_ENDIAN
|
|
|
- if (nn->cap & NFP_NET_CFG_CTRL_BPF &&
|
|
|
- nn_readb(nn, NFP_NET_CFG_BPF_ABI) == NFP_NET_BPF_ABI)
|
|
|
- return true;
|
|
|
-#endif
|
|
|
+ struct nfp_app_bpf *bpf = nn->app->priv;
|
|
|
+
|
|
|
+ return nn->cap & NFP_NET_CFG_CTRL_BPF &&
|
|
|
+ bpf->abi_version &&
|
|
|
+ nn_readb(nn, NFP_NET_CFG_BPF_ABI) == bpf->abi_version;
|
|
|
+#else
|
|
|
return false;
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
static int
|
|
@@ -342,6 +345,26 @@ nfp_bpf_parse_cap_adjust_tail(struct nfp_app_bpf *bpf, void __iomem *value,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int
|
|
|
+nfp_bpf_parse_cap_abi_version(struct nfp_app_bpf *bpf, void __iomem *value,
|
|
|
+ u32 length)
|
|
|
+{
|
|
|
+ if (length < 4) {
|
|
|
+ nfp_err(bpf->app->cpp, "truncated ABI version TLV: %d\n",
|
|
|
+ length);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ bpf->abi_version = readl(value);
|
|
|
+ if (bpf->abi_version != 2) {
|
|
|
+ nfp_warn(bpf->app->cpp, "unsupported BPF ABI version: %d\n",
|
|
|
+ bpf->abi_version);
|
|
|
+ bpf->abi_version = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int nfp_bpf_parse_capabilities(struct nfp_app *app)
|
|
|
{
|
|
|
struct nfp_cpp *cpp = app->pf->cpp;
|
|
@@ -393,6 +416,11 @@ static int nfp_bpf_parse_capabilities(struct nfp_app *app)
|
|
|
length))
|
|
|
goto err_release_free;
|
|
|
break;
|
|
|
+ case NFP_BPF_CAP_TYPE_ABI_VERSION:
|
|
|
+ if (nfp_bpf_parse_cap_abi_version(app->priv, value,
|
|
|
+ length))
|
|
|
+ goto err_release_free;
|
|
|
+ break;
|
|
|
default:
|
|
|
nfp_dbg(cpp, "unknown BPF capability: %d\n", type);
|
|
|
break;
|
|
@@ -414,6 +442,11 @@ err_release_free:
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+static void nfp_bpf_init_capabilities(struct nfp_app_bpf *bpf)
|
|
|
+{
|
|
|
+ bpf->abi_version = 2; /* Original BPF ABI version */
|
|
|
+}
|
|
|
+
|
|
|
static int nfp_bpf_ndo_init(struct nfp_app *app, struct net_device *netdev)
|
|
|
{
|
|
|
struct nfp_app_bpf *bpf = app->priv;
|
|
@@ -447,6 +480,8 @@ static int nfp_bpf_init(struct nfp_app *app)
|
|
|
if (err)
|
|
|
goto err_free_bpf;
|
|
|
|
|
|
+ nfp_bpf_init_capabilities(bpf);
|
|
|
+
|
|
|
err = nfp_bpf_parse_capabilities(app);
|
|
|
if (err)
|
|
|
goto err_free_neutral_maps;
|