/**
  * ice_request_fw - Device initialization routine
  * @pf: pointer to the PF instance
+ * @firmware: double pointer to firmware struct
+ *
+ * Return: zero when successful, negative values otherwise.
  */
-static void ice_request_fw(struct ice_pf *pf)
+static int ice_request_fw(struct ice_pf *pf, const struct firmware **firmware)
 {
        char *opt_fw_filename = ice_get_opt_fw_name(pf);
-       const struct firmware *firmware = NULL;
        struct device *dev = ice_pf_to_dev(pf);
        int err = 0;
 
         * and warning messages for other errors.
         */
        if (opt_fw_filename) {
-               err = firmware_request_nowarn(&firmware, opt_fw_filename, dev);
-               if (err) {
-                       kfree(opt_fw_filename);
-                       goto dflt_pkg_load;
-               }
-
-               /* request for firmware was successful. Download to device */
-               ice_load_pkg(firmware, pf);
+               err = firmware_request_nowarn(firmware, opt_fw_filename, dev);
                kfree(opt_fw_filename);
-               release_firmware(firmware);
-               return;
+               if (!err)
+                       return err;
        }
+       err = request_firmware(firmware, ICE_DDP_PKG_FILE, dev);
+       if (err)
+               dev_err(dev, "The DDP package file was not found or could not be read. Entering Safe Mode\n");
+
+       return err;
+}
+
+/**
+ * ice_init_tx_topology - performs Tx topology initialization
+ * @hw: pointer to the hardware structure
+ * @firmware: pointer to firmware structure
+ *
+ * Return: zero when init was successful, negative values otherwise.
+ */
+static int
+ice_init_tx_topology(struct ice_hw *hw, const struct firmware *firmware)
+{
+       u8 num_tx_sched_layers = hw->num_tx_sched_layers;
+       struct ice_pf *pf = hw->back;
+       struct device *dev;
+       u8 *buf_copy;
+       int err;
+
+       dev = ice_pf_to_dev(pf);
+       /* ice_cfg_tx_topo buf argument is not a constant,
+        * so we have to make a copy
+        */
+       buf_copy = kmemdup(firmware->data, firmware->size, GFP_KERNEL);
+
+       err = ice_cfg_tx_topo(hw, buf_copy, firmware->size);
+       if (!err) {
+               if (hw->num_tx_sched_layers > num_tx_sched_layers)
+                       dev_info(dev, "Tx scheduling layers switching feature disabled\n");
+               else
+                       dev_info(dev, "Tx scheduling layers switching feature enabled\n");
+               /* if there was a change in topology ice_cfg_tx_topo triggered
+                * a CORER and we need to re-init hw
+                */
+               ice_deinit_hw(hw);
+               err = ice_init_hw(hw);
 
-dflt_pkg_load:
-       err = request_firmware(&firmware, ICE_DDP_PKG_FILE, dev);
+               return err;
+       } else if (err == -EIO) {
+               dev_info(dev, "DDP package does not support Tx scheduling layers switching feature - please update to the latest DDP package and try again\n");
+       }
+
+       return 0;
+}
+
+/**
+ * ice_init_ddp_config - DDP related configuration
+ * @hw: pointer to the hardware structure
+ * @pf: pointer to pf structure
+ *
+ * This function loads DDP file from the disk, then initializes Tx
+ * topology. At the end DDP package is loaded on the card.
+ *
+ * Return: zero when init was successful, negative values otherwise.
+ */
+static int ice_init_ddp_config(struct ice_hw *hw, struct ice_pf *pf)
+{
+       struct device *dev = ice_pf_to_dev(pf);
+       const struct firmware *firmware = NULL;
+       int err;
+
+       err = ice_request_fw(pf, &firmware);
        if (err) {
-               dev_err(dev, "The DDP package file was not found or could not be read. Entering Safe Mode\n");
-               return;
+               dev_err(dev, "Fail during requesting FW: %d\n", err);
+               return err;
+       }
+
+       err = ice_init_tx_topology(hw, firmware);
+       if (err) {
+               dev_err(dev, "Fail during initialization of Tx topology: %d\n",
+                       err);
+               release_firmware(firmware);
+               return err;
        }
 
-       /* request for firmware was successful. Download to device */
+       /* Download firmware to device */
        ice_load_pkg(firmware, pf);
        release_firmware(firmware);
+
+       return 0;
 }
 
 /**
 
        ice_init_feature_support(pf);
 
-       ice_request_fw(pf);
+       err = ice_init_ddp_config(hw, pf);
+       if (err)
+               return err;
 
-       /* if ice_request_fw fails, ICE_FLAG_ADV_FEATURES bit won't be
+       /* if ice_init_ddp_config fails, ICE_FLAG_ADV_FEATURES bit won't be
         * set in pf->state, which will cause ice_is_safe_mode to return
         * true
         */