net/ice/base: refactor VSI node scheduler
[dpdk.git] / drivers / net / ice / base / ice_sched.c
index 855e384..0f41531 100644 (file)
@@ -260,33 +260,17 @@ ice_sched_remove_elems(struct ice_hw *hw, struct ice_sched_node *parent,
 
 /**
  * ice_sched_get_first_node - get the first node of the given layer
- * @hw: pointer to the HW struct
+ * @pi: port information structure
  * @parent: pointer the base node of the subtree
  * @layer: layer number
  *
  * This function retrieves the first node of the given layer from the subtree
  */
 static struct ice_sched_node *
-ice_sched_get_first_node(struct ice_hw *hw, struct ice_sched_node *parent,
-                        u8 layer)
+ice_sched_get_first_node(struct ice_port_info *pi,
+                        struct ice_sched_node *parent, u8 layer)
 {
-       u8 i;
-
-       if (layer < hw->sw_entry_point_layer)
-               return NULL;
-       for (i = 0; i < parent->num_children; i++) {
-               struct ice_sched_node *node = parent->children[i];
-
-               if (node) {
-                       if (node->tx_sched_layer == layer)
-                               return node;
-                       /* this recursion is intentional, and wouldn't
-                        * go more than 9 calls
-                        */
-                       return ice_sched_get_first_node(hw, node, layer);
-               }
-       }
-       return NULL;
+       return pi->sib_head[parent->tc_num][layer];
 }
 
 /**
@@ -342,7 +326,7 @@ void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node)
        parent = node->parent;
        /* root has no parent */
        if (parent) {
-               struct ice_sched_node *p, *tc_node;
+               struct ice_sched_node *p;
 
                /* update the parent */
                for (i = 0; i < parent->num_children; i++)
@@ -354,16 +338,7 @@ void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node)
                                break;
                        }
 
-               /* search for previous sibling that points to this node and
-                * remove the reference
-                */
-               tc_node = ice_sched_get_tc_node(pi, node->tc_num);
-               if (!tc_node) {
-                       ice_debug(hw, ICE_DBG_SCHED,
-                                 "Invalid TC number %d\n", node->tc_num);
-                       goto err_exit;
-               }
-               p = ice_sched_get_first_node(hw, tc_node, node->tx_sched_layer);
+               p = ice_sched_get_first_node(pi, node, node->tx_sched_layer);
                while (p) {
                        if (p->sibling == node) {
                                p->sibling = node->sibling;
@@ -371,8 +346,13 @@ void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node)
                        }
                        p = p->sibling;
                }
+
+               /* update the sibling head if head is getting removed */
+               if (pi->sib_head[node->tc_num][node->tx_sched_layer] == node)
+                       pi->sib_head[node->tc_num][node->tx_sched_layer] =
+                               node->sibling;
        }
-err_exit:
+
        /* leaf nodes have no children */
        if (node->children)
                ice_free(hw, node->children);
@@ -979,13 +959,17 @@ ice_sched_add_elems(struct ice_port_info *pi, struct ice_sched_node *tc_node,
 
                /* add it to previous node sibling pointer */
                /* Note: siblings are not linked across branches */
-               prev = ice_sched_get_first_node(hw, tc_node, layer);
+               prev = ice_sched_get_first_node(pi, tc_node, layer);
                if (prev && prev != new_node) {
                        while (prev->sibling)
                                prev = prev->sibling;
                        prev->sibling = new_node;
                }
 
+               /* initialize the sibling head */
+               if (!pi->sib_head[tc_node->tc_num][layer])
+                       pi->sib_head[tc_node->tc_num][layer] = new_node;
+
                if (i == 0)
                        *first_node_teid = teid;
        }
@@ -1249,7 +1233,7 @@ enum ice_status ice_sched_init_port(struct ice_port_info *pi)
                goto err_init_port;
        }
 
-       /* If the last node is a leaf node then the index of the Q group
+       /* If the last node is a leaf node then the index of the queue group
         * layer is two less than the number of elements.
         */
        if (num_elems > 2 && buf[0].generic[num_elems - 1].data.elem_type ==
@@ -1451,7 +1435,7 @@ ice_sched_get_free_qparent(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
                goto lan_q_exit;
 
        /* get the first queue group node from VSI sub-tree */
-       qgrp_node = ice_sched_get_first_node(pi->hw, vsi_node, qgrp_layer);
+       qgrp_node = ice_sched_get_first_node(pi, vsi_node, qgrp_layer);
        while (qgrp_node) {
                /* make sure the qgroup node is part of the VSI subtree */
                if (ice_sched_find_node_in_subtree(pi->hw, vsi_node, qgrp_node))
@@ -1467,7 +1451,7 @@ lan_q_exit:
 
 /**
  * ice_sched_get_vsi_node - Get a VSI node based on VSI ID
- * @hw: pointer to the HW struct
+ * @pi: pointer to the port information structure
  * @tc_node: pointer to the TC node
  * @vsi_handle: software VSI handle
  *
@@ -1475,14 +1459,14 @@ lan_q_exit:
  * TC branch
  */
 struct ice_sched_node *
-ice_sched_get_vsi_node(struct ice_hw *hw, struct ice_sched_node *tc_node,
+ice_sched_get_vsi_node(struct ice_port_info *pi, struct ice_sched_node *tc_node,
                       u16 vsi_handle)
 {
        struct ice_sched_node *node;
        u8 vsi_layer;
 
-       vsi_layer = ice_sched_get_vsi_layer(hw);
-       node = ice_sched_get_first_node(hw, tc_node, vsi_layer);
+       vsi_layer = ice_sched_get_vsi_layer(pi->hw);
+       node = ice_sched_get_first_node(pi, tc_node, vsi_layer);
 
        /* Check whether it already exists */
        while (node) {
@@ -1511,7 +1495,7 @@ ice_sched_get_agg_node(struct ice_hw *hw, struct ice_sched_node *tc_node,
        u8 agg_layer;
 
        agg_layer = ice_sched_get_agg_layer(hw);
-       node = ice_sched_get_first_node(hw, tc_node, agg_layer);
+       node = ice_sched_get_first_node(hw->port_info, tc_node, agg_layer);
 
        /* Check whether it already exists */
        while (node) {
@@ -1603,7 +1587,7 @@ ice_sched_add_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_handle,
 
        qgl = ice_sched_get_qgrp_layer(hw);
        vsil = ice_sched_get_vsi_layer(hw);
-       parent = ice_sched_get_vsi_node(hw, tc_node, vsi_handle);
+       parent = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
        for (i = vsil + 1; i <= qgl; i++) {
                if (!parent)
                        return ICE_ERR_CFG;
@@ -1636,7 +1620,7 @@ ice_sched_add_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_handle,
 
 /**
  * ice_sched_calc_vsi_support_nodes - calculate number of VSI support nodes
- * @hw: pointer to the HW struct
+ * @pi: pointer to the port info structure
  * @tc_node: pointer to TC node
  * @num_nodes: pointer to num nodes array
  *
@@ -1645,15 +1629,15 @@ ice_sched_add_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_handle,
  * layers
  */
 static void
-ice_sched_calc_vsi_support_nodes(struct ice_hw *hw,
+ice_sched_calc_vsi_support_nodes(struct ice_port_info *pi,
                                 struct ice_sched_node *tc_node, u16 *num_nodes)
 {
        struct ice_sched_node *node;
        u8 vsil;
        int i;
 
-       vsil = ice_sched_get_vsi_layer(hw);
-       for (i = vsil; i >= hw->sw_entry_point_layer; i--)
+       vsil = ice_sched_get_vsi_layer(pi->hw);
+       for (i = vsil; i >= pi->hw->sw_entry_point_layer; i--)
                /* Add intermediate nodes if TC has no children and
                 * need at least one node for VSI
                 */
@@ -1663,10 +1647,11 @@ ice_sched_calc_vsi_support_nodes(struct ice_hw *hw,
                        /* If intermediate nodes are reached max children
                         * then add a new one.
                         */
-                       node = ice_sched_get_first_node(hw, tc_node, (u8)i);
+                       node = ice_sched_get_first_node(pi, tc_node, (u8)i);
                        /* scan all the siblings */
                        while (node) {
-                               if (node->num_children < hw->max_children[i])
+                               if (node->num_children <
+                                   pi->hw->max_children[i])
                                        break;
                                node = node->sibling;
                        }
@@ -1746,14 +1731,13 @@ ice_sched_add_vsi_to_topo(struct ice_port_info *pi, u16 vsi_handle, u8 tc)
 {
        u16 num_nodes[ICE_AQC_TOPO_MAX_LEVEL_NUM] = { 0 };
        struct ice_sched_node *tc_node;
-       struct ice_hw *hw = pi->hw;
 
        tc_node = ice_sched_get_tc_node(pi, tc);
        if (!tc_node)
                return ICE_ERR_PARAM;
 
        /* calculate number of supported nodes needed for this VSI */
-       ice_sched_calc_vsi_support_nodes(hw, tc_node, num_nodes);
+       ice_sched_calc_vsi_support_nodes(pi, tc_node, num_nodes);
 
        /* add VSI supported nodes to TC subtree */
        return ice_sched_add_vsi_support_nodes(pi, vsi_handle, tc_node,
@@ -1786,7 +1770,7 @@ ice_sched_update_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_handle,
        if (!tc_node)
                return ICE_ERR_CFG;
 
-       vsi_node = ice_sched_get_vsi_node(hw, tc_node, vsi_handle);
+       vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
        if (!vsi_node)
                return ICE_ERR_CFG;
 
@@ -1849,7 +1833,7 @@ ice_sched_cfg_vsi(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u16 maxqs,
        vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
        if (!vsi_ctx)
                return ICE_ERR_PARAM;
-       vsi_node = ice_sched_get_vsi_node(hw, tc_node, vsi_handle);
+       vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
 
        /* suspend the VSI if TC is not enabled */
        if (!enable) {
@@ -1870,7 +1854,7 @@ ice_sched_cfg_vsi(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u16 maxqs,
                if (status)
                        return status;
 
-               vsi_node = ice_sched_get_vsi_node(hw, tc_node, vsi_handle);
+               vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
                if (!vsi_node)
                        return ICE_ERR_CFG;
 
@@ -1981,7 +1965,7 @@ ice_sched_rm_vsi_cfg(struct ice_port_info *pi, u16 vsi_handle, u8 owner)
                if (!tc_node)
                        continue;
 
-               vsi_node = ice_sched_get_vsi_node(pi->hw, tc_node, vsi_handle);
+               vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
                if (!vsi_node)
                        continue;
 
@@ -2271,7 +2255,7 @@ ice_sched_move_vsi_to_agg(struct ice_port_info *pi, u16 vsi_handle, u32 agg_id,
        if (!agg_node)
                return ICE_ERR_DOES_NOT_EXIST;
 
-       vsi_node = ice_sched_get_vsi_node(pi->hw, tc_node, vsi_handle);
+       vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
        if (!vsi_node)
                return ICE_ERR_DOES_NOT_EXIST;
 
@@ -2528,7 +2512,7 @@ ice_sched_add_agg_cfg(struct ice_port_info *pi, u32 agg_id, u8 tc)
         * intermediate node on those layers
         */
        for (i = hw->sw_entry_point_layer; i < aggl; i++) {
-               parent = ice_sched_get_first_node(hw, tc_node, i);
+               parent = ice_sched_get_first_node(pi, tc_node, i);
 
                /* scan all the siblings */
                while (parent) {
@@ -3544,13 +3528,15 @@ ice_cfg_agg_vsi_priority_per_tc(struct ice_port_info *pi, u32 agg_id,
                LIST_FOR_EACH_ENTRY(agg_vsi_info, &agg_info->agg_vsi_list,
                                    ice_sched_agg_vsi_info, list_entry)
                        if (agg_vsi_info->vsi_handle == vsi_handle) {
+                               /* cppcheck-suppress unreadVariable */
                                vsi_handle_valid = true;
                                break;
                        }
+
                if (!vsi_handle_valid)
                        goto exit_agg_priority_per_tc;
 
-               vsi_node = ice_sched_get_vsi_node(hw, tc_node, vsi_handle);
+               vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
                if (!vsi_node)
                        goto exit_agg_priority_per_tc;
 
@@ -3606,7 +3592,7 @@ ice_cfg_vsi_bw_alloc(struct ice_port_info *pi, u16 vsi_handle, u8 ena_tcmap,
                if (!tc_node)
                        continue;
 
-               vsi_node = ice_sched_get_vsi_node(pi->hw, tc_node, vsi_handle);
+               vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
                if (!vsi_node)
                        continue;
 
@@ -4818,7 +4804,7 @@ ice_sched_validate_vsi_srl_node(struct ice_port_info *pi, u16 vsi_handle)
                if (!tc_node)
                        continue;
 
-               vsi_node = ice_sched_get_vsi_node(pi->hw, tc_node, vsi_handle);
+               vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
                if (!vsi_node)
                        continue;
 
@@ -4877,7 +4863,7 @@ ice_sched_set_vsi_bw_shared_lmt(struct ice_port_info *pi, u16 vsi_handle,
                if (!tc_node)
                        continue;
 
-               vsi_node = ice_sched_get_vsi_node(pi->hw, tc_node, vsi_handle);
+               vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
                if (!vsi_node)
                        continue;
 
@@ -5075,16 +5061,15 @@ enum ice_status ice_cfg_rl_burst_size(struct ice_hw *hw, u32 bytes)
        if (bytes < ICE_MIN_BURST_SIZE_ALLOWED ||
            bytes > ICE_MAX_BURST_SIZE_ALLOWED)
                return ICE_ERR_PARAM;
-       if (bytes <= ICE_MAX_BURST_SIZE_BYTE_GRANULARITY) {
-               /* byte granularity case */
+       if (ice_round_to_num(bytes, 64) <=
+           ICE_MAX_BURST_SIZE_64_BYTE_GRANULARITY) {
+               /* 64 byte granularity case */
                /* Disable MSB granularity bit */
-               burst_size_to_prog = ICE_BYTE_GRANULARITY;
-               /* round number to nearest 256 granularity */
-               bytes = ice_round_to_num(bytes, 256);
-               /* check rounding doesn't go beyond allowed */
-               if (bytes > ICE_MAX_BURST_SIZE_BYTE_GRANULARITY)
-                       bytes = ICE_MAX_BURST_SIZE_BYTE_GRANULARITY;
-               burst_size_to_prog |= (u16)bytes;
+               burst_size_to_prog = ICE_64_BYTE_GRANULARITY;
+               /* round number to nearest 64 byte granularity */
+               bytes = ice_round_to_num(bytes, 64);
+               /* The value is in 64 byte chunks */
+               burst_size_to_prog |= (u16)(bytes / 64);
        } else {
                /* k bytes granularity case */
                /* Enable MSB granularity bit */
@@ -5382,7 +5367,7 @@ ice_sched_replay_vsi_bw(struct ice_hw *hw, u16 vsi_handle,
                tc_node = ice_sched_get_tc_node(pi, tc);
                if (!tc_node)
                        continue;
-               vsi_node = ice_sched_get_vsi_node(hw, tc_node, vsi_handle);
+               vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle);
                if (!vsi_node)
                        continue;
                bw_t_info = &vsi_ctx->sched.bw_t_info[tc];