net/ice: support src MAC filter for flow director
[dpdk.git] / drivers / net / ice / base / ice_sched.c
index 0a46dd4..8ee4b70 100644 (file)
@@ -1441,6 +1441,53 @@ ice_sched_find_node_in_subtree(struct ice_hw *hw, struct ice_sched_node *base,
        return false;
 }
 
+/**
+ * ice_sched_get_free_qgrp - Scan all Q group siblings and find a free node
+ * @pi: port information structure
+ * @vsi_node: software VSI handle
+ * @qgrp_node: first Q group node identified for scanning
+ * @owner: LAN or RDMA
+ *
+ * This function retrieves a free LAN or RDMA Q group node by scanning
+ * qgrp_node and its siblings for the Q group with the fewest number
+ * of queues currently assigned.
+ */
+static struct ice_sched_node *
+ice_sched_get_free_qgrp(struct ice_port_info *pi,
+                       struct ice_sched_node *vsi_node,
+                       struct ice_sched_node *qgrp_node, u8 owner)
+{
+       struct ice_sched_node *min_qgrp;
+       u8 min_children;
+
+       if (!qgrp_node)
+               return qgrp_node;
+       min_children = qgrp_node->num_children;
+       if (!min_children)
+               return qgrp_node;
+       min_qgrp = qgrp_node;
+       /* scan all Q groups until find a node which has less than the
+        * minimum number of children. This way all Q group nodes get
+        * equal number of shares and active. The bandwidth will be equally
+        * distributed across all Qs.
+        */
+       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))
+                       if (qgrp_node->num_children < min_children &&
+                           qgrp_node->owner == owner) {
+                               /* replace the new min Q group node */
+                               min_qgrp = qgrp_node;
+                               min_children = min_qgrp->num_children;
+                               /* break if it has no children, */
+                               if (!min_children)
+                                       break;
+                       }
+               qgrp_node = qgrp_node->sibling;
+       }
+       return min_qgrp;
+}
+
 /**
  * ice_sched_get_free_qparent - Get a free LAN or RDMA queue group node
  * @pi: port information structure
@@ -1454,7 +1501,7 @@ struct ice_sched_node *
 ice_sched_get_free_qparent(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
                           u8 owner)
 {
-       struct ice_sched_node *vsi_node, *qgrp_node = NULL;
+       struct ice_sched_node *vsi_node, *qgrp_node;
        struct ice_vsi_ctx *vsi_ctx;
        u16 max_children;
        u8 qgrp_layer;
@@ -1468,7 +1515,7 @@ ice_sched_get_free_qparent(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
        vsi_node = vsi_ctx->sched.vsi_node[tc];
        /* validate invalid VSI ID */
        if (!vsi_node)
-               goto lan_q_exit;
+               return NULL;
 
        /* get the first queue group node from VSI sub-tree */
        qgrp_node = ice_sched_get_first_node(pi, vsi_node, qgrp_layer);
@@ -1481,8 +1528,8 @@ ice_sched_get_free_qparent(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
                qgrp_node = qgrp_node->sibling;
        }
 
-lan_q_exit:
-       return qgrp_node;
+       /* Select the best queue group */
+       return ice_sched_get_free_qgrp(pi, vsi_node, qgrp_node, owner);
 }
 
 /**
@@ -1932,8 +1979,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;
@@ -3079,8 +3125,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);
@@ -3099,8 +3144,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);
@@ -3125,8 +3169,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);
@@ -3188,8 +3231,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)
@@ -3861,8 +3903,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;
 
@@ -4093,7 +4135,8 @@ ice_sched_rm_rl_profile(struct ice_port_info *pi, u8 layer_num, u8 profile_type,
        /* 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)
@@ -4255,8 +4298,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);
 }
 
 /**
@@ -5291,7 +5334,7 @@ void ice_sched_replay_agg(struct ice_hw *hw)
 
        ice_acquire_lock(&pi->sched_lock);
        LIST_FOR_EACH_ENTRY(agg_info, &hw->agg_list, ice_sched_agg_info,
-                           list_entry) {
+                           list_entry)
                /* replay aggregator (re-create aggregator node) */
                if (!ice_cmp_bitmap(agg_info->tc_bitmap,
                                    agg_info->replay_tc_bitmap,
@@ -5320,7 +5363,6 @@ void ice_sched_replay_agg(struct ice_hw *hw)
                                ice_info(hw, "Replay agg bw [id=%d] failed\n",
                                         agg_info->agg_id);
                }
-       }
        ice_release_lock(&pi->sched_lock);
 }
 
@@ -5355,8 +5397,7 @@ void ice_sched_replay_agg_vsi_preinit(struct ice_hw *hw)
  *
  * This function replay TC nodes.
  */
-enum ice_status
-ice_sched_replay_tc_node_bw(struct ice_port_info *pi)
+enum ice_status ice_sched_replay_tc_node_bw(struct ice_port_info *pi)
 {
        enum ice_status status = ICE_SUCCESS;
        u8 tc;
@@ -5479,8 +5520,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;