net/ice/base: add rate limiter profile bit mask check
[dpdk.git] / drivers / net / ice / base / ice_sched.c
index 0f41531..f48c971 100644 (file)
@@ -1,10 +1,9 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2001-2019
+ * Copyright(c) 2001-2020 Intel Corporation
  */
 
 #include "ice_sched.h"
 
-
 /**
  * ice_sched_add_root_node - Insert the Tx scheduler root node in SW DB
  * @pi: port information structure
@@ -172,7 +171,7 @@ ice_sched_add_node(struct ice_port_info *pi, u8 layer,
                return ICE_ERR_PARAM;
        }
 
-       /* query the current node information from FW  before additing it
+       /* query the current node information from FW before adding it
         * to the SW DB
         */
        status = ice_sched_query_elem(hw, LE32_TO_CPU(info->node_teid), &elem);
@@ -284,7 +283,7 @@ struct ice_sched_node *ice_sched_get_tc_node(struct ice_port_info *pi, u8 tc)
 {
        u8 i;
 
-       if (!pi)
+       if (!pi || !pi->root)
                return NULL;
        for (i = 0; i < pi->root->num_children; i++)
                if (pi->root->children[i]->tc_num == tc)
@@ -600,14 +599,14 @@ ice_alloc_lan_q_ctx(struct ice_hw *hw, u16 vsi_handle, u8 tc, u16 new_numqs)
 /**
  * ice_aq_rl_profile - performs a rate limiting task
  * @hw: pointer to the HW struct
- * @opcode:opcode for add, query, or remove profile(s)
+ * @opcode: opcode for add, query, or remove profile(s)
  * @num_profiles: the number of profiles
  * @buf: pointer to buffer
  * @buf_size: buffer size in bytes
  * @num_processed: number of processed add or remove profile(s) to return
  * @cd: pointer to command details structure
  *
- * Rl profile function to add, query, or remove profile(s)
+ * RL profile function to add, query, or remove profile(s)
  */
 static enum ice_status
 ice_aq_rl_profile(struct ice_hw *hw, enum ice_adminq_opc opcode,
@@ -735,7 +734,7 @@ ice_sched_del_rl_profile(struct ice_hw *hw,
  */
 static void ice_sched_clear_rl_prof(struct ice_port_info *pi)
 {
-       u8 ln;
+       u16 ln;
 
        for (ln = 0; ln < pi->hw->num_tx_sched_layers; ln++) {
                struct ice_aqc_rl_profile_info *rl_prof_elem;
@@ -790,7 +789,7 @@ void ice_sched_clear_agg(struct ice_hw *hw)
 }
 
 /**
- * ice_sched_clear_tx_topo - clears the schduler tree nodes
+ * ice_sched_clear_tx_topo - clears the scheduler tree nodes
  * @pi: port information structure
  *
  * This function removes all the nodes from HW as well as from SW DB.
@@ -841,8 +840,7 @@ void ice_sched_cleanup_all(struct ice_hw *hw)
                hw->layer_info = NULL;
        }
 
-       if (hw->port_info)
-               ice_sched_clear_port(hw->port_info);
+       ice_sched_clear_port(hw->port_info);
 
        hw->num_tx_sched_layers = 0;
        hw->num_tx_sched_phys_layers = 0;
@@ -876,7 +874,6 @@ ice_aq_cfg_l2_node_cgd(struct ice_hw *hw, u16 num_l2_nodes,
        return ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
 }
 
-
 /**
  * ice_sched_add_elems - add nodes to HW and SW DB
  * @pi: port information structure
@@ -902,7 +899,7 @@ ice_sched_add_elems(struct ice_port_info *pi, struct ice_sched_node *tc_node,
        u16 buf_size;
        u32 teid;
 
-       buf_size = sizeof(*buf) + sizeof(*buf->generic) * (num_nodes - 1);
+       buf_size = ice_struct_size(buf, generic, num_nodes - 1);
        buf = (struct ice_aqc_add_elem *)ice_malloc(hw, buf_size);
        if (!buf)
                return ICE_ERR_NO_MEMORY;
@@ -1366,12 +1363,51 @@ enum ice_status ice_sched_query_res_alloc(struct ice_hw *hw)
                goto sched_query_out;
        }
 
-
 sched_query_out:
        ice_free(hw, buf);
        return status;
 }
 
+/**
+ * ice_sched_get_psm_clk_freq - determine the PSM clock frequency
+ * @hw: pointer to the HW struct
+ *
+ * Determine the PSM clock frequency and store in HW struct
+ */
+void ice_sched_get_psm_clk_freq(struct ice_hw *hw)
+{
+       u32 val, clk_src;
+
+       val = rd32(hw, GLGEN_CLKSTAT_SRC);
+       clk_src = (val & GLGEN_CLKSTAT_SRC_PSM_CLK_SRC_M) >>
+               GLGEN_CLKSTAT_SRC_PSM_CLK_SRC_S;
+
+#define PSM_CLK_SRC_367_MHZ 0x0
+#define PSM_CLK_SRC_416_MHZ 0x1
+#define PSM_CLK_SRC_446_MHZ 0x2
+#define PSM_CLK_SRC_390_MHZ 0x3
+
+       switch (clk_src) {
+       case PSM_CLK_SRC_367_MHZ:
+               hw->psm_clk_freq = ICE_PSM_CLK_367MHZ_IN_HZ;
+               break;
+       case PSM_CLK_SRC_416_MHZ:
+               hw->psm_clk_freq = ICE_PSM_CLK_416MHZ_IN_HZ;
+               break;
+       case PSM_CLK_SRC_446_MHZ:
+               hw->psm_clk_freq = ICE_PSM_CLK_446MHZ_IN_HZ;
+               break;
+       case PSM_CLK_SRC_390_MHZ:
+               hw->psm_clk_freq = ICE_PSM_CLK_390MHZ_IN_HZ;
+               break;
+       default:
+               ice_debug(hw, ICE_DBG_SCHED, "PSM clk_src unexpected %u\n",
+                         clk_src);
+               /* fall back to a safe default */
+               hw->psm_clk_freq = ICE_PSM_CLK_446MHZ_IN_HZ;
+       }
+}
+
 /**
  * ice_sched_find_node_in_subtree - Find node in part of base node subtree
  * @hw: pointer to the HW struct
@@ -1480,7 +1516,7 @@ ice_sched_get_vsi_node(struct ice_port_info *pi, struct ice_sched_node *tc_node,
 
 /**
  * ice_sched_get_agg_node - Get an aggregator node based on aggregator ID
- * @hw: pointer to the HW struct
+ * @pi: pointer to the port information structure
  * @tc_node: pointer to the TC node
  * @agg_id: aggregator ID
  *
@@ -1488,14 +1524,17 @@ ice_sched_get_vsi_node(struct ice_port_info *pi, struct ice_sched_node *tc_node,
  * a given TC branch
  */
 static struct ice_sched_node *
-ice_sched_get_agg_node(struct ice_hw *hw, struct ice_sched_node *tc_node,
+ice_sched_get_agg_node(struct ice_port_info *pi, struct ice_sched_node *tc_node,
                       u32 agg_id)
 {
        struct ice_sched_node *node;
+       struct ice_hw *hw = pi->hw;
        u8 agg_layer;
 
+       if (!hw)
+               return NULL;
        agg_layer = ice_sched_get_agg_layer(hw);
-       node = ice_sched_get_first_node(hw->port_info, tc_node, agg_layer);
+       node = ice_sched_get_first_node(pi, tc_node, agg_layer);
 
        /* Check whether it already exists */
        while (node) {
@@ -1893,8 +1932,7 @@ ice_sched_cfg_vsi(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u16 maxqs,
  * This function removes single aggregator VSI info entry from
  * aggregator list.
  */
-static void
-ice_sched_rm_agg_vsi_info(struct ice_port_info *pi, u16 vsi_handle)
+static void ice_sched_rm_agg_vsi_info(struct ice_port_info *pi, u16 vsi_handle)
 {
        struct ice_sched_agg_info *agg_info;
        struct ice_sched_agg_info *atmp;
@@ -2018,7 +2056,6 @@ enum ice_status ice_rm_vsi_lan_cfg(struct ice_port_info *pi, u16 vsi_handle)
        return ice_sched_rm_vsi_cfg(pi, vsi_handle, ICE_SCHED_NODE_OWNER_LAN);
 }
 
-
 /**
  * ice_sched_is_tree_balanced - Check tree nodes are identical or not
  * @hw: pointer to the HW struct
@@ -2076,7 +2113,7 @@ ice_aq_query_node_to_root(struct ice_hw *hw, u32 node_teid,
  * This function validates aggregator ID. The function returns info if
  * aggregator ID is present in list otherwise it returns null.
  */
-static struct ice_sched_agg_info*
+static struct ice_sched_agg_info *
 ice_get_agg_info(struct ice_hw *hw, u32 agg_id)
 {
        struct ice_sched_agg_info *agg_info;
@@ -2178,12 +2215,11 @@ static enum ice_status
 ice_sched_move_nodes(struct ice_port_info *pi, struct ice_sched_node *parent,
                     u16 num_items, u32 *list)
 {
+       enum ice_status status = ICE_SUCCESS;
        struct ice_aqc_move_elem *buf;
        struct ice_sched_node *node;
-       enum ice_status status = ICE_SUCCESS;
+       u16 i, grps_movd = 0;
        struct ice_hw *hw;
-       u16 grps_movd = 0;
-       u8 i;
 
        hw = pi->hw;
 
@@ -2251,7 +2287,7 @@ ice_sched_move_vsi_to_agg(struct ice_port_info *pi, u16 vsi_handle, u32 agg_id,
        if (!tc_node)
                return ICE_ERR_CFG;
 
-       agg_node = ice_sched_get_agg_node(pi->hw, tc_node, agg_id);
+       agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id);
        if (!agg_node)
                return ICE_ERR_DOES_NOT_EXIST;
 
@@ -2388,7 +2424,7 @@ ice_sched_rm_agg_cfg(struct ice_port_info *pi, u32 agg_id, u8 tc)
        if (!tc_node)
                return ICE_ERR_CFG;
 
-       agg_node = ice_sched_get_agg_node(hw, tc_node, agg_id);
+       agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id);
        if (!agg_node)
                return ICE_ERR_DOES_NOT_EXIST;
 
@@ -2497,7 +2533,7 @@ ice_sched_add_agg_cfg(struct ice_port_info *pi, u32 agg_id, u8 tc)
        if (!tc_node)
                return ICE_ERR_CFG;
 
-       agg_node = ice_sched_get_agg_node(hw, tc_node, agg_id);
+       agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id);
        /* Does Agg node already exist ? */
        if (agg_node)
                return status;
@@ -2660,7 +2696,7 @@ ice_cfg_agg(struct ice_port_info *pi, u32 agg_id, enum ice_agg_type agg_type,
  * The function returns aggregator VSI info based on VSI handle. This function
  * needs to be called with scheduler lock held.
  */
-static struct ice_sched_agg_vsi_info*
+static struct ice_sched_agg_vsi_info *
 ice_get_agg_vsi_info(struct ice_sched_agg_info *agg_info, u16 vsi_handle)
 {
        struct ice_sched_agg_vsi_info *agg_vsi_info;
@@ -2682,7 +2718,7 @@ ice_get_agg_vsi_info(struct ice_sched_agg_info *agg_info, u16 vsi_handle)
  * VSI has in this case a different aggregator than the default one. This
  * function needs to be called with scheduler lock held.
  */
-static struct ice_sched_agg_info*
+static struct ice_sched_agg_info *
 ice_get_vsi_agg_info(struct ice_hw *hw, u16 vsi_handle)
 {
        struct ice_sched_agg_info *agg_info;
@@ -2799,7 +2835,7 @@ ice_sched_assoc_vsi_to_agg(struct ice_port_info *pi, u32 agg_id,
  */
 static void ice_sched_rm_unused_rl_prof(struct ice_port_info *pi)
 {
-       u8 ln;
+       u16 ln;
 
        for (ln = 0; ln < pi->hw->num_tx_sched_layers; ln++) {
                struct ice_aqc_rl_profile_info *rl_prof_elem;
@@ -2870,7 +2906,7 @@ ice_sched_update_elem(struct ice_hw *hw, struct ice_sched_node *node,
  */
 static enum ice_status
 ice_sched_cfg_node_bw_alloc(struct ice_hw *hw, struct ice_sched_node *node,
-                           enum ice_rl_type rl_type, u8 bw_alloc)
+                           enum ice_rl_type rl_type, u16 bw_alloc)
 {
        struct ice_aqc_txsched_elem_data buf;
        struct ice_aqc_txsched_elem *data;
@@ -3042,8 +3078,7 @@ ice_sched_save_vsi_bw_alloc(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
  *
  * Save or clear CIR bandwidth (BW) in the passed param bw_t_info.
  */
-static void
-ice_set_clear_cir_bw(struct ice_bw_type_info *bw_t_info, u32 bw)
+static void ice_set_clear_cir_bw(struct ice_bw_type_info *bw_t_info, u32 bw)
 {
        if (bw == ICE_SCHED_DFLT_BW) {
                ice_clear_bit(ICE_BW_TYPE_CIR, bw_t_info->bw_t_bitmap);
@@ -3062,8 +3097,7 @@ ice_set_clear_cir_bw(struct ice_bw_type_info *bw_t_info, u32 bw)
  *
  * Save or clear EIR bandwidth (BW) in the passed param bw_t_info.
  */
-static void
-ice_set_clear_eir_bw(struct ice_bw_type_info *bw_t_info, u32 bw)
+static void ice_set_clear_eir_bw(struct ice_bw_type_info *bw_t_info, u32 bw)
 {
        if (bw == ICE_SCHED_DFLT_BW) {
                ice_clear_bit(ICE_BW_TYPE_EIR, bw_t_info->bw_t_bitmap);
@@ -3088,8 +3122,7 @@ ice_set_clear_eir_bw(struct ice_bw_type_info *bw_t_info, u32 bw)
  *
  * Save or clear shared bandwidth (BW) in the passed param bw_t_info.
  */
-static void
-ice_set_clear_shared_bw(struct ice_bw_type_info *bw_t_info, u32 bw)
+static void ice_set_clear_shared_bw(struct ice_bw_type_info *bw_t_info, u32 bw)
 {
        if (bw == ICE_SCHED_DFLT_BW) {
                ice_clear_bit(ICE_BW_TYPE_SHARED, bw_t_info->bw_t_bitmap);
@@ -3151,8 +3184,7 @@ ice_sched_save_vsi_bw(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
  *
  * Save or clear priority (prio) in the passed param bw_t_info.
  */
-static void
-ice_set_clear_prio(struct ice_bw_type_info *bw_t_info, u8 prio)
+static void ice_set_clear_prio(struct ice_bw_type_info *bw_t_info, u8 prio)
 {
        bw_t_info->generic = prio;
        if (bw_t_info->generic)
@@ -3434,7 +3466,6 @@ ice_cfg_agg_bw_no_shared_lmt(struct ice_port_info *pi, u32 agg_id)
  * @pi: port information structure
  * @num_qs: number of VSI queues
  * @q_ids: queue IDs array
- * @q_ids: queue IDs array
  * @q_prio: queue priority array
  *
  * This function configures the queue node priority (Sibling Priority) of the
@@ -3445,7 +3476,6 @@ ice_cfg_vsi_q_priority(struct ice_port_info *pi, u16 num_qs, u32 *q_ids,
                       u8 *q_prio)
 {
        enum ice_status status = ICE_ERR_PARAM;
-       struct ice_hw *hw = pi->hw;
        u16 i;
 
        ice_acquire_lock(&pi->sched_lock);
@@ -3460,7 +3490,7 @@ ice_cfg_vsi_q_priority(struct ice_port_info *pi, u16 num_qs, u32 *q_ids,
                        break;
                }
                /* Configure Priority */
-               status = ice_sched_cfg_sibl_node_prio(hw, node, q_prio[i]);
+               status = ice_sched_cfg_sibl_node_prio(pi, node, q_prio[i]);
                if (status)
                        break;
        }
@@ -3508,7 +3538,7 @@ ice_cfg_agg_vsi_priority_per_tc(struct ice_port_info *pi, u32 agg_id,
        if (!tc_node)
                goto exit_agg_priority_per_tc;
 
-       agg_node = ice_sched_get_agg_node(hw, tc_node, agg_id);
+       agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id);
        if (!agg_node)
                goto exit_agg_priority_per_tc;
 
@@ -3542,7 +3572,7 @@ ice_cfg_agg_vsi_priority_per_tc(struct ice_port_info *pi, u32 agg_id,
 
                if (ice_sched_find_node_in_subtree(hw, agg_node, vsi_node)) {
                        /* Configure Priority */
-                       status = ice_sched_cfg_sibl_node_prio(hw, vsi_node,
+                       status = ice_sched_cfg_sibl_node_prio(pi, vsi_node,
                                                              node_prio[i]);
                        if (status)
                                break;
@@ -3654,7 +3684,7 @@ ice_cfg_agg_bw_alloc(struct ice_port_info *pi, u32 agg_id, u8 ena_tcmap,
                if (!tc_node)
                        continue;
 
-               agg_node = ice_sched_get_agg_node(hw, tc_node, agg_id);
+               agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id);
                if (!agg_node)
                        continue;
 
@@ -3675,11 +3705,12 @@ exit_cfg_agg_bw_alloc:
 
 /**
  * ice_sched_calc_wakeup - calculate RL profile wakeup parameter
+ * @hw: pointer to the HW struct
  * @bw: bandwidth in Kbps
  *
  * This function calculates the wakeup parameter of RL profile.
  */
-static u16 ice_sched_calc_wakeup(s32 bw)
+static u16 ice_sched_calc_wakeup(struct ice_hw *hw, s32 bw)
 {
        s64 bytes_per_sec, wakeup_int, wakeup_a, wakeup_b, wakeup_f;
        s32 wakeup_f_int;
@@ -3687,7 +3718,7 @@ static u16 ice_sched_calc_wakeup(s32 bw)
 
        /* Get the wakeup integer value */
        bytes_per_sec = DIV_64BIT(((s64)bw * 1000), BITS_PER_BYTE);
-       wakeup_int = DIV_64BIT(ICE_RL_PROF_FREQUENCY, bytes_per_sec);
+       wakeup_int = DIV_64BIT(hw->psm_clk_freq, bytes_per_sec);
        if (wakeup_int > 63) {
                wakeup = (u16)((1 << 15) | wakeup_int);
        } else {
@@ -3696,7 +3727,7 @@ static u16 ice_sched_calc_wakeup(s32 bw)
                 */
                wakeup_b = (s64)ICE_RL_PROF_MULTIPLIER * wakeup_int;
                wakeup_a = DIV_64BIT((s64)ICE_RL_PROF_MULTIPLIER *
-                                    ICE_RL_PROF_FREQUENCY, bytes_per_sec);
+                                    hw->psm_clk_freq, bytes_per_sec);
 
                /* Get Fraction value */
                wakeup_f = wakeup_a - wakeup_b;
@@ -3716,13 +3747,15 @@ static u16 ice_sched_calc_wakeup(s32 bw)
 
 /**
  * ice_sched_bw_to_rl_profile - convert BW to profile parameters
+ * @hw: pointer to the HW struct
  * @bw: bandwidth in Kbps
  * @profile: profile parameters to return
  *
  * This function converts the BW to profile structure format.
  */
 static enum ice_status
-ice_sched_bw_to_rl_profile(u32 bw, struct ice_aqc_rl_profile_elem *profile)
+ice_sched_bw_to_rl_profile(struct ice_hw *hw, u32 bw,
+                          struct ice_aqc_rl_profile_elem *profile)
 {
        enum ice_status status = ICE_ERR_PARAM;
        s64 bytes_per_sec, ts_rate, mv_tmp;
@@ -3742,7 +3775,7 @@ ice_sched_bw_to_rl_profile(u32 bw, struct ice_aqc_rl_profile_elem *profile)
        for (i = 0; i < 64; i++) {
                u64 pow_result = BIT_ULL(i);
 
-               ts_rate = DIV_64BIT((s64)ICE_RL_PROF_FREQUENCY,
+               ts_rate = DIV_64BIT((s64)hw->psm_clk_freq,
                                    pow_result * ICE_RL_PROF_TS_MULTIPLIER);
                if (ts_rate <= 0)
                        continue;
@@ -3766,7 +3799,7 @@ ice_sched_bw_to_rl_profile(u32 bw, struct ice_aqc_rl_profile_elem *profile)
        if (found) {
                u16 wm;
 
-               wm = ice_sched_calc_wakeup(bw);
+               wm = ice_sched_calc_wakeup(hw, bw);
                profile->rl_multiply = CPU_TO_LE16(mv);
                profile->wake_up_calc = CPU_TO_LE16(wm);
                profile->rl_encode = CPU_TO_LE16(encode);
@@ -3798,10 +3831,12 @@ ice_sched_add_rl_profile(struct ice_port_info *pi,
        struct ice_aqc_rl_profile_generic_elem *buf;
        struct ice_aqc_rl_profile_info *rl_prof_elem;
        u16 profiles_added = 0, num_profiles = 1;
-       enum ice_status status = ICE_ERR_PARAM;
+       enum ice_status status;
        struct ice_hw *hw;
        u8 profile_type;
 
+       if (layer_num >= ICE_AQC_TOPO_MAX_LEVEL_NUM)
+               return NULL;
        switch (rl_type) {
        case ICE_MIN_BW:
                profile_type = ICE_AQC_RL_PROFILE_TYPE_CIR;
@@ -3821,8 +3856,8 @@ ice_sched_add_rl_profile(struct ice_port_info *pi,
        hw = pi->hw;
        LIST_FOR_EACH_ENTRY(rl_prof_elem, &pi->rl_prof_list[layer_num],
                            ice_aqc_rl_profile_info, list_entry)
-               if (rl_prof_elem->profile.flags == profile_type &&
-                   rl_prof_elem->bw == bw)
+               if ((rl_prof_elem->profile.flags & ICE_AQC_RL_PROFILE_TYPE_M) ==
+                   profile_type && rl_prof_elem->bw == bw)
                        /* Return existing profile ID info */
                        return rl_prof_elem;
 
@@ -3833,7 +3868,7 @@ ice_sched_add_rl_profile(struct ice_port_info *pi,
        if (!rl_prof_elem)
                return NULL;
 
-       status = ice_sched_bw_to_rl_profile(bw, &rl_prof_elem->profile);
+       status = ice_sched_bw_to_rl_profile(hw, bw, &rl_prof_elem->profile);
        if (status != ICE_SUCCESS)
                goto exit_add_rl_prof;
 
@@ -4048,10 +4083,13 @@ ice_sched_rm_rl_profile(struct ice_port_info *pi, u8 layer_num, u8 profile_type,
        struct ice_aqc_rl_profile_info *rl_prof_elem;
        enum ice_status status = ICE_SUCCESS;
 
+       if (layer_num >= ICE_AQC_TOPO_MAX_LEVEL_NUM)
+               return ICE_ERR_PARAM;
        /* Check the existing list for RL profile */
        LIST_FOR_EACH_ENTRY(rl_prof_elem, &pi->rl_prof_list[layer_num],
                            ice_aqc_rl_profile_info, list_entry)
-               if (rl_prof_elem->profile.flags == profile_type &&
+               if ((rl_prof_elem->profile.flags & ICE_AQC_RL_PROFILE_TYPE_M) ==
+                   profile_type &&
                    LE16_TO_CPU(rl_prof_elem->profile.profile_id) ==
                    profile_id) {
                        if (rl_prof_elem->prof_id_ref)
@@ -4213,8 +4251,8 @@ ice_sched_set_node_bw(struct ice_port_info *pi, struct ice_sched_node *node,
                return ICE_SUCCESS;
 
        return ice_sched_rm_rl_profile(pi, layer_num,
-                                      rl_prof_info->profile.flags,
-                                      old_id);
+                                      rl_prof_info->profile.flags &
+                                      ICE_AQC_RL_PROFILE_TYPE_M, old_id);
 }
 
 /**
@@ -4453,19 +4491,17 @@ static enum ice_status
 ice_sched_save_tc_node_bw(struct ice_port_info *pi, u8 tc,
                          enum ice_rl_type rl_type, u32 bw)
 {
-       struct ice_hw *hw = pi->hw;
-
        if (tc >= ICE_MAX_TRAFFIC_CLASS)
                return ICE_ERR_PARAM;
        switch (rl_type) {
        case ICE_MIN_BW:
-               ice_set_clear_cir_bw(&hw->tc_node_bw_t_info[tc], bw);
+               ice_set_clear_cir_bw(&pi->tc_node_bw_t_info[tc], bw);
                break;
        case ICE_MAX_BW:
-               ice_set_clear_eir_bw(&hw->tc_node_bw_t_info[tc], bw);
+               ice_set_clear_eir_bw(&pi->tc_node_bw_t_info[tc], bw);
                break;
        case ICE_SHARED_BW:
-               ice_set_clear_shared_bw(&hw->tc_node_bw_t_info[tc], bw);
+               ice_set_clear_shared_bw(&pi->tc_node_bw_t_info[tc], bw);
                break;
        default:
                return ICE_ERR_PARAM;
@@ -4552,17 +4588,15 @@ static enum ice_status
 ice_sched_save_tc_node_bw_alloc(struct ice_port_info *pi, u8 tc,
                                enum ice_rl_type rl_type, u16 bw_alloc)
 {
-       struct ice_hw *hw = pi->hw;
-
        if (tc >= ICE_MAX_TRAFFIC_CLASS)
                return ICE_ERR_PARAM;
        switch (rl_type) {
        case ICE_MIN_BW:
-               ice_set_clear_cir_bw_alloc(&hw->tc_node_bw_t_info[tc],
+               ice_set_clear_cir_bw_alloc(&pi->tc_node_bw_t_info[tc],
                                           bw_alloc);
                break;
        case ICE_MAX_BW:
-               ice_set_clear_eir_bw_alloc(&hw->tc_node_bw_t_info[tc],
+               ice_set_clear_eir_bw_alloc(&pi->tc_node_bw_t_info[tc],
                                           bw_alloc);
                break;
        default:
@@ -4710,7 +4744,7 @@ ice_sched_get_node_by_id_type(struct ice_port_info *pi, u32 id,
 
                tc_node = ice_sched_get_tc_node(pi, tc);
                if (tc_node)
-                       node = ice_sched_get_agg_node(pi->hw, tc_node, id);
+                       node = ice_sched_get_agg_node(pi, tc_node, id);
                break;
        }
 
@@ -4921,7 +4955,7 @@ ice_sched_validate_agg_srl_node(struct ice_port_info *pi, u32 agg_id)
                if (!tc_node)
                        continue;
 
-               agg_node = ice_sched_get_agg_node(pi->hw, tc_node, agg_id);
+               agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id);
                if (!agg_node)
                        continue;
                /* SRL bandwidth layer selection */
@@ -4992,7 +5026,7 @@ ice_sched_set_agg_bw_shared_lmt(struct ice_port_info *pi, u32 agg_id, u32 bw)
                if (!tc_node)
                        continue;
 
-               agg_node = ice_sched_get_agg_node(pi->hw, tc_node, agg_id);
+               agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id);
                if (!agg_node)
                        continue;
 
@@ -5017,7 +5051,7 @@ exit_agg_bw_shared_lmt:
 
 /**
  * ice_sched_cfg_sibl_node_prio - configure node sibling priority
- * @hw: pointer to the HW struct
+ * @pi: port information structure
  * @node: sched node to configure
  * @priority: sibling priority
  *
@@ -5025,13 +5059,16 @@ exit_agg_bw_shared_lmt:
  * function needs to be called with scheduler lock held.
  */
 enum ice_status
-ice_sched_cfg_sibl_node_prio(struct ice_hw *hw, struct ice_sched_node *node,
-                            u8 priority)
+ice_sched_cfg_sibl_node_prio(struct ice_port_info *pi,
+                            struct ice_sched_node *node, u8 priority)
 {
        struct ice_aqc_txsched_elem_data buf;
        struct ice_aqc_txsched_elem *data;
+       struct ice_hw *hw = pi->hw;
        enum ice_status status;
 
+       if (!hw)
+               return ICE_ERR_PARAM;
        buf = node->info;
        data = &buf.data;
        data->valid_sections |= ICE_AQC_ELEM_VALID_GENERIC;
@@ -5086,7 +5123,7 @@ enum ice_status ice_cfg_rl_burst_size(struct ice_hw *hw, u32 bytes)
        return ICE_SUCCESS;
 }
 
-/*
+/**
  * ice_sched_replay_node_prio - re-configure node priority
  * @hw: pointer to the HW struct
  * @node: sched node to configure
@@ -5198,7 +5235,7 @@ ice_sched_replay_agg_bw(struct ice_hw *hw, struct ice_sched_agg_info *agg_info)
                        status = ICE_ERR_PARAM;
                        break;
                }
-               agg_node = ice_sched_get_agg_node(hw, tc_node,
+               agg_node = ice_sched_get_agg_node(hw->port_info, tc_node,
                                                  agg_info->agg_id);
                if (!agg_node) {
                        status = ICE_ERR_PARAM;
@@ -5259,8 +5296,7 @@ void ice_sched_replay_agg(struct ice_hw *hw)
                                           ICE_MAX_TRAFFIC_CLASS);
                        enum ice_status status;
 
-                       ice_zero_bitmap(replay_bitmap,
-                                       sizeof(replay_bitmap) * BITS_PER_BYTE);
+                       ice_zero_bitmap(replay_bitmap, ICE_MAX_TRAFFIC_CLASS);
                        ice_sched_get_ena_tc_bitmap(pi,
                                                    agg_info->replay_tc_bitmap,
                                                    replay_bitmap);
@@ -5311,26 +5347,26 @@ void ice_sched_replay_agg_vsi_preinit(struct ice_hw *hw)
 
 /**
  * ice_sched_replay_tc_node_bw - replay TC node(s) BW
- * @hw: pointer to the HW struct
+ * @pi: port information structure
  *
- * This function replay TC nodes. The caller needs to hold the scheduler lock.
+ * This function replay TC nodes.
  */
-enum ice_status
-ice_sched_replay_tc_node_bw(struct ice_hw *hw)
+enum ice_status ice_sched_replay_tc_node_bw(struct ice_port_info *pi)
 {
-       struct ice_port_info *pi = hw->port_info;
        enum ice_status status = ICE_SUCCESS;
        u8 tc;
 
+       if (!pi->hw)
+               return ICE_ERR_PARAM;
        ice_acquire_lock(&pi->sched_lock);
        ice_for_each_traffic_class(tc) {
                struct ice_sched_node *tc_node;
 
-               tc_node = ice_sched_get_tc_node(hw->port_info, tc);
+               tc_node = ice_sched_get_tc_node(pi, tc);
                if (!tc_node)
                        continue; /* TC not present */
-               status = ice_sched_replay_node_bw(hw, tc_node,
-                                                 &hw->tc_node_bw_t_info[tc]);
+               status = ice_sched_replay_node_bw(pi->hw, tc_node,
+                                                 &pi->tc_node_bw_t_info[tc]);
                if (status)
                        break;
        }
@@ -5396,7 +5432,7 @@ ice_sched_replay_vsi_agg(struct ice_hw *hw, u16 vsi_handle)
        struct ice_sched_agg_info *agg_info;
        enum ice_status status;
 
-       ice_zero_bitmap(replay_bitmap, sizeof(replay_bitmap) * BITS_PER_BYTE);
+       ice_zero_bitmap(replay_bitmap, ICE_MAX_TRAFFIC_CLASS);
        if (!ice_is_vsi_valid(hw, vsi_handle))
                return ICE_ERR_PARAM;
        agg_info = ice_get_vsi_agg_info(hw, vsi_handle);
@@ -5438,8 +5474,7 @@ ice_sched_replay_vsi_agg(struct ice_hw *hw, u16 vsi_handle)
  * This function replays association of VSI to aggregator type nodes, and
  * node bandwidth information.
  */
-enum ice_status
-ice_replay_vsi_agg(struct ice_hw *hw, u16 vsi_handle)
+enum ice_status ice_replay_vsi_agg(struct ice_hw *hw, u16 vsi_handle)
 {
        struct ice_port_info *pi = hw->port_info;
        enum ice_status status;