#define NFP_FL_NBI_MTU_SETTING         BIT(1)
 #define NFP_FL_FEATS_GENEVE_OPT                BIT(2)
 #define NFP_FL_FEATS_VLAN_PCP          BIT(3)
+#define NFP_FL_FEATS_VF_RLIM           BIT(4)
 #define NFP_FL_FEATS_FLOW_MOD          BIT(5)
 #define NFP_FL_FEATS_FLOW_MERGE                BIT(30)
 #define NFP_FL_FEATS_LAG               BIT(31)
                                       struct nfp_fl_pre_lag *pre_act);
 int nfp_flower_lag_get_output_id(struct nfp_app *app,
                                 struct net_device *master);
+int nfp_flower_setup_qos_offload(struct nfp_app *app, struct net_device *netdev,
+                                struct tc_cls_matchall_offload *flow);
 int nfp_flower_reg_indir_block_handler(struct nfp_app *app,
                                       struct net_device *netdev,
                                       unsigned long event);
 
        case TC_SETUP_CLSFLOWER:
                return nfp_flower_repr_offload(repr->app, repr->netdev,
                                               type_data);
+       case TC_SETUP_CLSMATCHALL:
+               return nfp_flower_setup_qos_offload(repr->app, repr->netdev,
+                                                   type_data);
        default:
                return -EOPNOTSUPP;
        }
 
--- /dev/null
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/* Copyright (C) 2019 Netronome Systems, Inc. */
+
+#include <net/pkt_cls.h>
+
+#include "cmsg.h"
+#include "main.h"
+
+int nfp_flower_setup_qos_offload(struct nfp_app *app, struct net_device *netdev,
+                                struct tc_cls_matchall_offload *flow)
+{
+       struct netlink_ext_ack *extack = flow->common.extack;
+       struct nfp_flower_priv *fl_priv = app->priv;
+
+       if (!(fl_priv->flower_ext_feats & NFP_FL_FEATS_VF_RLIM)) {
+               NL_SET_ERR_MSG_MOD(extack, "unsupported offload: loaded firmware does not support qos rate limit offload");
+               return -EOPNOTSUPP;
+       }
+
+       return -EOPNOTSUPP;
+}