// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2018, Intel Corporation. */
#include "ice_sched.h"
/**
* ice_sched_add_root_node - Insert the Tx scheduler root node in SW DB
* @pi: port information structure
* @info: Scheduler element information from firmware
*
* This function inserts the root node of the scheduling tree topology
* to the SW DB.
*/
static enum ice_status
ice_sched_add_root_node(struct ice_port_info *pi,
struct ice_aqc_txsched_elem_data *info)
{
struct ice_sched_node *root;
struct ice_hw *hw;
u16 max_children;
if (!pi)
return ICE_ERR_PARAM;
hw = pi->hw;
root = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*root), GFP_KERNEL);
if (!root)
return ICE_ERR_NO_MEMORY;
max_children = le16_to_cpu(hw->layer_info[0].max_children);
root->children = devm_kcalloc(ice_hw_to_dev(hw), max_children,
sizeof(*root), GFP_KERNEL);
if (!root->children) {
devm_kfree(ice_hw_to_dev(hw), root);
return ICE_ERR_NO_MEMORY;
}
memcpy(&root->info, info, sizeof(*info));
pi->root = root;
return 0;
}
/**
* ice_sched_find_node_by_teid - Find the Tx scheduler node in SW DB
* @start_node: pointer to the starting ice_sched_node struct in a sub-tree
* @teid: node teid to search
*
* This function searches for a node matching the teid in the scheduling tree
* from the SW DB. The search is recursive and is restricted by the number of
* layers it has searched through; stopping at the max supported layer.
*
* This function needs to be called when holding the port_info->sched_lock
*/
struct ice_sched_node *
ice_sched_find_node_by_teid(struct ice_sched_node *start_node, u32 teid)
{
u16 i;
/* The TEID is same as that of the start_node */
if (ICE_TXSCHED_GET_NODE_TEID(start_node) == teid)
return start_node;
/* The node has no children or is at the max layer */
if (!start_node->num_children ||
start_node->tx_
|