diff options
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_sched.c')
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_sched.c | 59 | 
1 files changed, 22 insertions, 37 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_sched.c b/drivers/net/ethernet/intel/ice/ice_sched.c index 2a232504379d..fc624b73d05d 100644 --- a/drivers/net/ethernet/intel/ice/ice_sched.c +++ b/drivers/net/ethernet/intel/ice/ice_sched.c @@ -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];  }  /** @@ -300,7 +284,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) @@ -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)  		devm_kfree(ice_hw_to_dev(hw), node->children); @@ -743,13 +723,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;  	} @@ -1160,7 +1144,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)) @@ -1191,7 +1175,7 @@ ice_sched_get_vsi_node(struct ice_hw *hw, struct ice_sched_node *tc_node,  	u8 vsi_layer;  	vsi_layer = ice_sched_get_vsi_layer(hw); -	node = ice_sched_get_first_node(hw, tc_node, vsi_layer); +	node = ice_sched_get_first_node(hw->port_info, tc_node, vsi_layer);  	/* Check whether it already exists */  	while (node) { @@ -1316,7 +1300,8 @@ 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(hw->port_info, tc_node, +							(u8)i);  			/* scan all the siblings */  			while (node) {  				if (node->num_children < hw->max_children[i])  |