Keep track of which Qdisc is currently root. We need to implement TC_SETUP_ROOT_QDISC handling, and for completeness also clear the root Qdisc pointer when it's freed. TC_SETUP_ROOT_QDISC isn't always sent when device is dismantled.
Remembering the root Qdisc will allow us to build the entire hierarchy in following patches. Signed-off-by: Jakub Kicinski <jakub.kicin...@netronome.com> Reviewed-by: John Hurley <john.hur...@netronome.com> --- drivers/net/ethernet/netronome/nfp/abm/main.c | 2 ++ drivers/net/ethernet/netronome/nfp/abm/main.h | 4 ++++ drivers/net/ethernet/netronome/nfp/abm/qdisc.c | 13 +++++++++++++ 3 files changed, 19 insertions(+) diff --git a/drivers/net/ethernet/netronome/nfp/abm/main.c b/drivers/net/ethernet/netronome/nfp/abm/main.c index 35f3a6054569..da5394886a78 100644 --- a/drivers/net/ethernet/netronome/nfp/abm/main.c +++ b/drivers/net/ethernet/netronome/nfp/abm/main.c @@ -37,6 +37,8 @@ nfp_abm_setup_tc(struct nfp_app *app, struct net_device *netdev, return -EOPNOTSUPP; switch (type) { + case TC_SETUP_ROOT_QDISC: + return nfp_abm_setup_root(netdev, repr->app_priv, type_data); case TC_SETUP_QDISC_MQ: return nfp_abm_setup_tc_mq(netdev, repr->app_priv, type_data); case TC_SETUP_QDISC_RED: diff --git a/drivers/net/ethernet/netronome/nfp/abm/main.h b/drivers/net/ethernet/netronome/nfp/abm/main.h index 64cb5ebcf80e..48d519989886 100644 --- a/drivers/net/ethernet/netronome/nfp/abm/main.h +++ b/drivers/net/ethernet/netronome/nfp/abm/main.h @@ -116,6 +116,7 @@ struct nfp_red_qdisc { * @parent: handle of expected parent, i.e. handle of MQ, or TC_H_ROOT * @num_qdiscs: number of currently used qdiscs * @red_qdiscs: array of qdiscs + * @root_qdisc: pointer to the current root of the Qdisc hierarchy * @qdiscs: all qdiscs recorded by major part of the handle */ struct nfp_abm_link { @@ -127,9 +128,12 @@ struct nfp_abm_link { u32 parent; unsigned int num_qdiscs; struct nfp_red_qdisc *red_qdiscs; + struct nfp_qdisc *root_qdisc; struct radix_tree_root qdiscs; }; +int nfp_abm_setup_root(struct net_device *netdev, struct nfp_abm_link *alink, + struct tc_root_qopt_offload *opt); int nfp_abm_setup_tc_red(struct net_device *netdev, struct nfp_abm_link *alink, struct tc_red_qopt_offload *opt); int nfp_abm_setup_tc_mq(struct net_device *netdev, struct nfp_abm_link *alink, diff --git a/drivers/net/ethernet/netronome/nfp/abm/qdisc.c b/drivers/net/ethernet/netronome/nfp/abm/qdisc.c index a6f95924656d..ba6ce2d1eda2 100644 --- a/drivers/net/ethernet/netronome/nfp/abm/qdisc.c +++ b/drivers/net/ethernet/netronome/nfp/abm/qdisc.c @@ -143,6 +143,9 @@ nfp_abm_qdisc_destroy(struct net_device *netdev, struct nfp_abm_link *alink, return; nfp_abm_qdisc_free(netdev, alink, qdisc); + + if (alink->root_qdisc == qdisc) + alink->root_qdisc = NULL; } static void @@ -450,3 +453,13 @@ int nfp_abm_setup_tc_mq(struct net_device *netdev, struct nfp_abm_link *alink, return -EOPNOTSUPP; } } + +int nfp_abm_setup_root(struct net_device *netdev, struct nfp_abm_link *alink, + struct tc_root_qopt_offload *opt) +{ + if (opt->ingress) + return -EOPNOTSUPP; + alink->root_qdisc = nfp_abm_qdisc_find(alink, opt->handle); + + return 0; +} -- 2.17.1