src/dpdk/drivers/net/ice/base/ice_sched.c
enum ice_status ice_sched_init_port(struct ice_port_info *pi)
{
	struct ice_aqc_get_topo_elem *buf;
	enum ice_status status;
	struct ice_hw *hw;
	u8 num_branches;
	u16 num_elems;
	u8 i, j;

	if (!pi)
		return ICE_ERR_PARAM;
	hw = pi->hw;

	/* Query the Default Topology from FW */
	buf = (struct ice_aqc_get_topo_elem *)ice_malloc(hw,
							 ICE_AQ_MAX_BUF_LEN);
	if (!buf)
		return ICE_ERR_NO_MEMORY;

	/* Query default scheduling tree topology */
	status = ice_aq_get_dflt_topo(hw, pi->lport, buf, ICE_AQ_MAX_BUF_LEN,
				      &num_branches, NULL);
	if (status)
		goto err_init_port;

	/* num_branches should be between 1-8 */
	if (num_branches < 1 || num_branches > ICE_TXSCHED_MAX_BRANCHES) {
		ice_debug(hw, ICE_DBG_SCHED, "num_branches unexpected %d\n",
			  num_branches);
		status = ICE_ERR_PARAM;
		goto err_init_port;
	}

	/* get the number of elements on the default/first branch */
	num_elems = LE16_TO_CPU(buf[0].hdr.num_elems);

	/* num_elems should always be between 1-9 */
	if (num_elems < 1 || num_elems > ICE_AQC_TOPO_MAX_LEVEL_NUM) {
		ice_debug(hw, ICE_DBG_SCHED, "num_elems unexpected %d\n",
			  num_elems);
		status = ICE_ERR_PARAM;
		goto err_init_port;
	}

	/* 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 ==
	    ICE_AQC_ELEM_TYPE_LEAF)
		pi->last_node_teid =
			LE32_TO_CPU(buf[0].generic[num_elems - 2].node_teid);
	else
		pi->last_node_teid =
			LE32_TO_CPU(buf[0].generic[num_elems - 1].node_teid);

	/* Insert the Tx Sched root node */
	status = ice_sched_add_root_node(pi, &buf[0].generic[0]);
	if (status)
		goto err_init_port;

	/* Parse the default tree and cache the information */
	for (i = 0; i < num_branches; i++) {
		num_elems = LE16_TO_CPU(buf[i].hdr.num_elems);

		/* Skip root element as already inserted */
		for (j = 1; j < num_elems; j++) {
			/* update the sw entry point */
			if (buf[0].generic[j].data.elem_type ==
			    ICE_AQC_ELEM_TYPE_ENTRY_POINT)
				hw->sw_entry_point_layer = j;

			status = ice_sched_add_node(pi, j, &buf[i].generic[j]);
			if (status)
				goto err_init_port;
		}
	}

	/* Remove the default nodes. */
	if (pi->root)
		ice_sched_rm_dflt_nodes(pi);

	/* initialize the port for handling the scheduler tree */
	pi->port_state = ICE_SCHED_PORT_STATE_READY;
	ice_init_lock(&pi->sched_lock);
	for (i = 0; i < ICE_AQC_TOPO_MAX_LEVEL_NUM; i++)
		INIT_LIST_HEAD(&hw->rl_prof_list[i]);

err_init_port:
	if (status && pi->root) {
		ice_free_sched_node(pi, pi->root);
		pi->root = NULL;
	}

	ice_free(hw, buf);
	return status;
}
/**
 * ice_sched_init_port - Initialize scheduler by querying information from FW
 * @pi: port info structure for the tree to cleanup
 *
 * This function is the initial call to find the total number of Tx scheduler
 * resources, default topology created by firmware and storing the information
 * in SW DB.
 */
Initialize scheduler by querying information from FW
@pi: port info structure for the tree to cleanup

This function is the initial call to find the total number of Tx scheduler
resources, default topology created by firmware and storing the information
in SW DB.
Initialize scheduler by querying information from FW @pi : port info structure for the tree to cleanup This function is the initial call to find the total number of Tx scheduler resources default topology created by firmware and storing the information in SW DB .
enum ice_status ice_sched_init_port(struct ice_port_info *pi)
{
	struct ice_aqc_get_topo_elem *buf;
	enum ice_status status;
	struct ice_hw *hw;
	u8 num_branches;
	u16 num_elems;
	u8 i, j;
	if (!pi)
		return ICE_ERR_PARAM;
	hw = pi->hw;
	buf = (struct ice_aqc_get_topo_elem *)ice_malloc(hw,
							 ICE_AQ_MAX_BUF_LEN);
	if (!buf)
		return ICE_ERR_NO_MEMORY;
	status = ice_aq_get_dflt_topo(hw, pi->lport, buf, ICE_AQ_MAX_BUF_LEN,
				      &num_branches, NULL);
	if (status)
		goto err_init_port;
	if (num_branches < 1 || num_branches > ICE_TXSCHED_MAX_BRANCHES) {
		ice_debug(hw, ICE_DBG_SCHED, "num_branches unexpected %d\n",
			  num_branches);
		status = ICE_ERR_PARAM;
		goto err_init_port;
	}
	num_elems = LE16_TO_CPU(buf[0].hdr.num_elems);
	if (num_elems < 1 || num_elems > ICE_AQC_TOPO_MAX_LEVEL_NUM) {
		ice_debug(hw, ICE_DBG_SCHED, "num_elems unexpected %d\n",
			  num_elems);
		status = ICE_ERR_PARAM;
		goto err_init_port;
	}
	if (num_elems > 2 && buf[0].generic[num_elems - 1].data.elem_type ==
	    ICE_AQC_ELEM_TYPE_LEAF)
		pi->last_node_teid =
			LE32_TO_CPU(buf[0].generic[num_elems - 2].node_teid);
	else
		pi->last_node_teid =
			LE32_TO_CPU(buf[0].generic[num_elems - 1].node_teid);
	status = ice_sched_add_root_node(pi, &buf[0].generic[0]);
	if (status)
		goto err_init_port;
	for (i = 0; i < num_branches; i++) {
		num_elems = LE16_TO_CPU(buf[i].hdr.num_elems);
		for (j = 1; j < num_elems; j++) {
			if (buf[0].generic[j].data.elem_type ==
			    ICE_AQC_ELEM_TYPE_ENTRY_POINT)
				hw->sw_entry_point_layer = j;
			status = ice_sched_add_node(pi, j, &buf[i].generic[j]);
			if (status)
				goto err_init_port;
		}
	}
	if (pi->root)
		ice_sched_rm_dflt_nodes(pi);
	pi->port_state = ICE_SCHED_PORT_STATE_READY;
	ice_init_lock(&pi->sched_lock);
	for (i = 0; i < ICE_AQC_TOPO_MAX_LEVEL_NUM; i++)
		INIT_LIST_HEAD(&hw->rl_prof_list[i]);
err_init_port:
	if (status && pi->root) {
		ice_free_sched_node(pi, pi->root);
		pi->root = NULL;
	}
	ice_free(hw, buf);
	return status;
}
enum ice_status ice_sched_init_port ( struct ice_port_info * pi ) { struct ice_aqc_get_topo_elem * buf ; enum ice_status status ; struct ice_hw * hw ; u8 num_branches ; u16 num_elems ; u8 i , j ; if ( ! pi ) return ICE_ERR_PARAM ; hw = pi -> hw ; buf = ( struct ice_aqc_get_topo_elem * ) ice_malloc ( hw , ICE_AQ_MAX_BUF_LEN ) ; if ( ! buf ) return ICE_ERR_NO_MEMORY ; status = ice_aq_get_dflt_topo ( hw , pi -> lport , buf , ICE_AQ_MAX_BUF_LEN , & num_branches , NULL ) ; if ( status ) goto err_init_port ; if ( num_branches < 1 || num_branches > ICE_TXSCHED_MAX_BRANCHES ) { ice_debug ( hw , ICE_DBG_SCHED , " \n " , num_branches ) ; status = ICE_ERR_PARAM ; goto err_init_port ; } num_elems = LE16_TO_CPU ( buf [ 0 ] . hdr . num_elems ) ; if ( num_elems < 1 || num_elems > ICE_AQC_TOPO_MAX_LEVEL_NUM ) { ice_debug ( hw , ICE_DBG_SCHED , " \n " , num_elems ) ; status = ICE_ERR_PARAM ; goto err_init_port ; } if ( num_elems > 2 && buf [ 0 ] . generic [ num_elems - 1 ] . data . elem_type == ICE_AQC_ELEM_TYPE_LEAF ) pi -> last_node_teid = LE32_TO_CPU ( buf [ 0 ] . generic [ num_elems - 2 ] . node_teid ) ; else pi -> last_node_teid = LE32_TO_CPU ( buf [ 0 ] . generic [ num_elems - 1 ] . node_teid ) ; status = ice_sched_add_root_node ( pi , & buf [ 0 ] . generic [ 0 ] ) ; if ( status ) goto err_init_port ; for ( i = 0 ; i < num_branches ; i ++ ) { num_elems = LE16_TO_CPU ( buf [ i ] . hdr . num_elems ) ; for ( j = 1 ; j < num_elems ; j ++ ) { if ( buf [ 0 ] . generic [ j ] . data . elem_type == ICE_AQC_ELEM_TYPE_ENTRY_POINT ) hw -> sw_entry_point_layer = j ; status = ice_sched_add_node ( pi , j , & buf [ i ] . generic [ j ] ) ; if ( status ) goto err_init_port ; } } if ( pi -> root ) ice_sched_rm_dflt_nodes ( pi ) ; pi -> port_state = ICE_SCHED_PORT_STATE_READY ; ice_init_lock ( & pi -> sched_lock ) ; for ( i = 0 ; i < ICE_AQC_TOPO_MAX_LEVEL_NUM ; i ++ ) INIT_LIST_HEAD ( & hw -> rl_prof_list [ i ] ) ; err_init_port : if ( status && pi -> root ) { ice_free_sched_node ( pi , pi -> root ) ; pi -> root = NULL ; } ice_free ( hw , buf ) ; return status ; }
ice_sched_init_port - Initialize scheduler by querying information from FW
 @pi: port info structure for the tree to cleanup
ice_sched_init_port - Initialize scheduler by querying information from FW @pi : port info structure for the tree to cleanup
/* Query the Default Topology from FW */ /* Query default scheduling tree topology */ /* num_branches should be between 1-8 */ /* get the number of elements on the default/first branch */ /* num_elems should always be between 1-9 */ /* If the last node is a leaf node then the index of the queue group
	 * layer is two less than the number of elements.
	 */ /* Insert the Tx Sched root node */ /* Parse the default tree and cache the information */ /* Skip root element as already inserted */ /* update the sw entry point */ /* Remove the default nodes. */ /* initialize the port for handling the scheduler tree */