#define NFP_NUM_BANDS_SYM_NAME "_abi_pci_dscp_num_band_%u"
 #define NFP_ACT_MASK_SYM_NAME  "_abi_nfd_out_q_actions_%u"
 
+#define NFP_RED_SUPPORT_SYM_NAME       "_abi_nfd_out_red_offload_%u"
+
 #define NFP_QLVL_SYM_NAME      "_abi_nfd_out_q_lvls_%u%s"
 #define NFP_QLVL_STRIDE                16
 #define NFP_QLVL_BLOG_BYTES    0
 
        abm->pf_id = nfp_cppcore_pcie_unit(pf->cpp);
 
+       /* Check if Qdisc offloads are supported */
+       res = nfp_pf_rtsym_read_optional(pf, NFP_RED_SUPPORT_SYM_NAME, 1);
+       if (res < 0)
+               return res;
+       abm->red_support = res;
+
        /* Read count of prios and prio bands */
        res = nfp_pf_rtsym_read_optional(pf, NFP_NUM_BANDS_SYM_NAME, 1);
        if (res < 0)
        }
 
        /* Find level and stat symbols */
+       if (!abm->red_support)
+               return 0;
+
        sym = nfp_abm_ctrl_find_q_rtsym(abm, NFP_QLVL_SYM_NAME,
                                        NFP_QLVL_STRIDE);
        if (IS_ERR(sym))
 
        struct nfp_net *nn;
        int err;
 
+       if (!abm->red_support)
+               return -EOPNOTSUPP;
+
        err = nfp_abm_ctrl_qm_enable(abm);
        if (err)
                return err;
        return data;
 }
 
+static int nfp_abm_fw_init_reset(struct nfp_abm *abm)
+{
+       unsigned int i;
+
+       if (!abm->red_support)
+               return 0;
+
+       for (i = 0; i < abm->num_bands * NFP_NET_MAX_RX_RINGS; i++) {
+               __nfp_abm_ctrl_set_q_lvl(abm, i, NFP_ABM_LVL_INFINITY);
+               __nfp_abm_ctrl_set_q_act(abm, i, NFP_ABM_ACT_DROP);
+       }
+
+       return nfp_abm_ctrl_qm_disable(abm);
+}
+
 static int nfp_abm_init(struct nfp_app *app)
 {
        struct nfp_pf *pf = app->pf;
        struct nfp_reprs *reprs;
        struct nfp_abm *abm;
-       unsigned int i;
        int err;
 
        if (!pf->eth_tbl) {
                                   sizeof(*abm->thresholds), GFP_KERNEL);
        if (!abm->thresholds)
                goto err_free_thresh_umap;
-       for (i = 0; i < abm->num_bands * NFP_NET_MAX_RX_RINGS; i++)
-               __nfp_abm_ctrl_set_q_lvl(abm, i, NFP_ABM_LVL_INFINITY);
 
        abm->actions = kvcalloc(abm->num_thresholds, sizeof(*abm->actions),
                                GFP_KERNEL);
        if (!abm->actions)
                goto err_free_thresh;
-       for (i = 0; i < abm->num_bands * NFP_NET_MAX_RX_RINGS; i++)
-               __nfp_abm_ctrl_set_q_act(abm, i, NFP_ABM_ACT_DROP);
 
        /* We start in legacy mode, make sure advanced queuing is disabled */
-       err = nfp_abm_ctrl_qm_disable(abm);
+       err = nfp_abm_fw_init_reset(abm);
        if (err)
                goto err_free_act;
 
 
  * @app:       back pointer to nfp_app
  * @pf_id:     ID of our PF link
  *
+ * @red_support:       is RED offload supported
  * @num_prios: number of supported DSCP priorities
  * @num_bands: number of supported DSCP priority bands
  * @action_mask:       bitmask of supported actions
        struct nfp_app *app;
        unsigned int pf_id;
 
+       unsigned int red_support;
        unsigned int num_prios;
        unsigned int num_bands;
        unsigned int action_mask;