src/dpdk/drivers/net/ice/base/ice_sched.c
void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node)
{
	struct ice_sched_node *parent;
	struct ice_hw *hw = pi->hw;
	u8 i, j;

	/* Free the children before freeing up the parent node
	 * The parent array is updated below and that shifts the nodes
	 * in the array. So always pick the first child if num children > 0
	 */
	while (node->num_children)
		ice_free_sched_node(pi, node->children[0]);

	/* Leaf, TC and root nodes can't be deleted by SW */
	if (node->tx_sched_layer >= hw->sw_entry_point_layer &&
	    node->info.data.elem_type != ICE_AQC_ELEM_TYPE_TC &&
	    node->info.data.elem_type != ICE_AQC_ELEM_TYPE_ROOT_PORT &&
	    node->info.data.elem_type != ICE_AQC_ELEM_TYPE_LEAF) {
		u32 teid = LE32_TO_CPU(node->info.node_teid);

		ice_sched_remove_elems(hw, node->parent, 1, &teid);
	}
	parent = node->parent;
	/* root has no parent */
	if (parent) {
		struct ice_sched_node *p;

		/* update the parent */
		for (i = 0; i < parent->num_children; i++)
			if (parent->children[i] == node) {
				for (j = i + 1; j < parent->num_children; j++)
					parent->children[j - 1] =
						parent->children[j];
				parent->num_children--;
				break;
			}

		p = ice_sched_get_first_node(pi, node, node->tx_sched_layer);
		while (p) {
			if (p->sibling == node) {
				p->sibling = node->sibling;
				break;
			}
			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;
	}

	/* leaf nodes have no children */
	if (node->children)
		ice_free(hw, node->children);
	ice_free(hw, node);
}
/**
 * ice_free_sched_node - Free a Tx scheduler node from SW DB
 * @pi: port information structure
 * @node: pointer to the ice_sched_node struct
 *
 * This function frees up a node from SW DB as well as from HW
 *
 * This function needs to be called with the port_info->sched_lock held
 */
Free a Tx scheduler node from SW DB
@pi: port information structure
@node: pointer to the ice_sched_node struct

This function frees up a node from SW DB as well as from HW

This function needs to be called with the port_info->sched_lock held
Free a Tx scheduler node from SW DB @pi : port information structure @node : pointer to the ice_sched_node struct This function frees up a node from SW DB as well as from HW This function needs to be called with the port_info - > sched_lock held
void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node)
{
	struct ice_sched_node *parent;
	struct ice_hw *hw = pi->hw;
	u8 i, j;
	while (node->num_children)
		ice_free_sched_node(pi, node->children[0]);
	if (node->tx_sched_layer >= hw->sw_entry_point_layer &&
	    node->info.data.elem_type != ICE_AQC_ELEM_TYPE_TC &&
	    node->info.data.elem_type != ICE_AQC_ELEM_TYPE_ROOT_PORT &&
	    node->info.data.elem_type != ICE_AQC_ELEM_TYPE_LEAF) {
		u32 teid = LE32_TO_CPU(node->info.node_teid);
		ice_sched_remove_elems(hw, node->parent, 1, &teid);
	}
	parent = node->parent;
	if (parent) {
		struct ice_sched_node *p;
		for (i = 0; i < parent->num_children; i++)
			if (parent->children[i] == node) {
				for (j = i + 1; j < parent->num_children; j++)
					parent->children[j - 1] =
						parent->children[j];
				parent->num_children--;
				break;
			}
		p = ice_sched_get_first_node(pi, node, node->tx_sched_layer);
		while (p) {
			if (p->sibling == node) {
				p->sibling = node->sibling;
				break;
			}
			p = p->sibling;
		}
		if (pi->sib_head[node->tc_num][node->tx_sched_layer] == node)
			pi->sib_head[node->tc_num][node->tx_sched_layer] =
				node->sibling;
	}
	if (node->children)
		ice_free(hw, node->children);
	ice_free(hw, node);
}
void ice_free_sched_node ( struct ice_port_info * pi , struct ice_sched_node * node ) { struct ice_sched_node * parent ; struct ice_hw * hw = pi -> hw ; u8 i , j ; while ( node -> num_children ) ice_free_sched_node ( pi , node -> children [ 0 ] ) ; if ( node -> tx_sched_layer >= hw -> sw_entry_point_layer && node -> info . data . elem_type != ICE_AQC_ELEM_TYPE_TC && node -> info . data . elem_type != ICE_AQC_ELEM_TYPE_ROOT_PORT && node -> info . data . elem_type != ICE_AQC_ELEM_TYPE_LEAF ) { u32 teid = LE32_TO_CPU ( node -> info . node_teid ) ; ice_sched_remove_elems ( hw , node -> parent , 1 , & teid ) ; } parent = node -> parent ; if ( parent ) { struct ice_sched_node * p ; for ( i = 0 ; i < parent -> num_children ; i ++ ) if ( parent -> children [ i ] == node ) { for ( j = i + 1 ; j < parent -> num_children ; j ++ ) parent -> children [ j - 1 ] = parent -> children [ j ] ; parent -> num_children -- ; break ; } p = ice_sched_get_first_node ( pi , node , node -> tx_sched_layer ) ; while ( p ) { if ( p -> sibling == node ) { p -> sibling = node -> sibling ; break ; } p = p -> sibling ; } if ( pi -> sib_head [ node -> tc_num ] [ node -> tx_sched_layer ] == node ) pi -> sib_head [ node -> tc_num ] [ node -> tx_sched_layer ] = node -> sibling ; } if ( node -> children ) ice_free ( hw , node -> children ) ; ice_free ( hw , node ) ; }
ice_free_sched_node - Free a Tx scheduler node from SW DB
 @pi: port information structure
 @node: pointer to the ice_sched_node struct
ice_free_sched_node - Free a Tx scheduler node from SW DB @pi : port information structure @node : pointer to the ice_sched_node struct
/* Free the children before freeing up the parent node
	 * The parent array is updated below and that shifts the nodes
	 * in the array. So always pick the first child if num children > 0
	 */ /* Leaf, TC and root nodes can't be deleted by SW */ /* root has no parent */ /* update the parent */ /* update the sibling head if head is getting removed */ /* leaf nodes have no children */