net/ice: fix RSS for GTPU
[dpdk.git] / drivers / net / ice / base / ice_sched.c
index 01c8def..af42fad 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
@@ -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
@@ -2021,7 +2057,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
@@ -2872,7 +2907,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;
@@ -3676,11 +3711,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;
@@ -3688,7 +3724,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 {
@@ -3697,7 +3733,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;
@@ -3717,13 +3753,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;
@@ -3743,7 +3781,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;
@@ -3767,7 +3805,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);
@@ -3799,10 +3837,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;
@@ -3834,7 +3874,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;
 
@@ -4049,6 +4089,8 @@ 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)