Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/ice/ice_sched.c
/* SPDX-License-Identifier: BSD-3-Clause */ | /* SPDX-License-Identifier: BSD-3-Clause */ | ||||
/* Copyright (c) 2020, Intel Corporation | /* Copyright (c) 2021, Intel Corporation | ||||
* All rights reserved. | * All rights reserved. | ||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions are met: | * modification, are permitted provided that the following conditions are met: | ||||
* | * | ||||
* 1. Redistributions of source code must retain the above copyright notice, | * 1. Redistributions of source code must retain the above copyright notice, | ||||
* this list of conditions and the following disclaimer. | * this list of conditions and the following disclaimer. | ||||
* | * | ||||
▲ Show 20 Lines • Show All 739 Lines • ▼ Show 20 Lines | |||||
* ice_sched_clear_rl_prof - clears RL prof entries | * ice_sched_clear_rl_prof - clears RL prof entries | ||||
* @pi: port information structure | * @pi: port information structure | ||||
* | * | ||||
* This function removes all RL profile from HW as well as from SW DB. | * This function removes all RL profile from HW as well as from SW DB. | ||||
*/ | */ | ||||
static void ice_sched_clear_rl_prof(struct ice_port_info *pi) | static void ice_sched_clear_rl_prof(struct ice_port_info *pi) | ||||
{ | { | ||||
u16 ln; | u16 ln; | ||||
struct ice_hw *hw = pi->hw; | |||||
for (ln = 0; ln < pi->hw->num_tx_sched_layers; ln++) { | for (ln = 0; ln < hw->num_tx_sched_layers; ln++) { | ||||
struct ice_aqc_rl_profile_info *rl_prof_elem; | struct ice_aqc_rl_profile_info *rl_prof_elem; | ||||
struct ice_aqc_rl_profile_info *rl_prof_tmp; | struct ice_aqc_rl_profile_info *rl_prof_tmp; | ||||
LIST_FOR_EACH_ENTRY_SAFE(rl_prof_elem, rl_prof_tmp, | LIST_FOR_EACH_ENTRY_SAFE(rl_prof_elem, rl_prof_tmp, | ||||
&pi->rl_prof_list[ln], | &hw->rl_prof_list[ln], | ||||
ice_aqc_rl_profile_info, list_entry) { | ice_aqc_rl_profile_info, list_entry) { | ||||
struct ice_hw *hw = pi->hw; | |||||
enum ice_status status; | enum ice_status status; | ||||
rl_prof_elem->prof_id_ref = 0; | rl_prof_elem->prof_id_ref = 0; | ||||
status = ice_sched_del_rl_profile(hw, rl_prof_elem); | status = ice_sched_del_rl_profile(hw, rl_prof_elem); | ||||
if (status) { | if (status) { | ||||
ice_debug(hw, ICE_DBG_SCHED, "Remove rl profile failed\n"); | ice_debug(hw, ICE_DBG_SCHED, "Remove rl profile failed\n"); | ||||
/* On error, free mem required */ | /* On error, free mem required */ | ||||
LIST_DEL(&rl_prof_elem->list_entry); | LIST_DEL(&rl_prof_elem->list_entry); | ||||
▲ Show 20 Lines • Show All 508 Lines • ▼ Show 20 Lines | enum ice_status ice_sched_init_port(struct ice_port_info *pi) | ||||
/* Remove the default nodes. */ | /* Remove the default nodes. */ | ||||
if (pi->root) | if (pi->root) | ||||
ice_sched_rm_dflt_nodes(pi); | ice_sched_rm_dflt_nodes(pi); | ||||
/* initialize the port for handling the scheduler tree */ | /* initialize the port for handling the scheduler tree */ | ||||
pi->port_state = ICE_SCHED_PORT_STATE_READY; | pi->port_state = ICE_SCHED_PORT_STATE_READY; | ||||
ice_init_lock(&pi->sched_lock); | ice_init_lock(&pi->sched_lock); | ||||
for (i = 0; i < ICE_AQC_TOPO_MAX_LEVEL_NUM; i++) | for (i = 0; i < ICE_AQC_TOPO_MAX_LEVEL_NUM; i++) | ||||
INIT_LIST_HEAD(&pi->rl_prof_list[i]); | INIT_LIST_HEAD(&hw->rl_prof_list[i]); | ||||
err_init_port: | err_init_port: | ||||
if (status && pi->root) { | if (status && pi->root) { | ||||
ice_free_sched_node(pi, pi->root); | ice_free_sched_node(pi, pi->root); | ||||
pi->root = NULL; | pi->root = NULL; | ||||
} | } | ||||
ice_free(hw, buf); | ice_free(hw, buf); | ||||
▲ Show 20 Lines • Show All 972 Lines • ▼ Show 20 Lines | |||||
* @list: pointer to child node teids | * @list: pointer to child node teids | ||||
* | * | ||||
* This function move the child nodes to a given parent. | * This function move the child nodes to a given parent. | ||||
*/ | */ | ||||
static enum ice_status | static enum ice_status | ||||
ice_sched_move_nodes(struct ice_port_info *pi, struct ice_sched_node *parent, | ice_sched_move_nodes(struct ice_port_info *pi, struct ice_sched_node *parent, | ||||
u16 num_items, u32 *list) | u16 num_items, u32 *list) | ||||
{ | { | ||||
enum ice_status status = ICE_SUCCESS; | |||||
struct ice_aqc_move_elem *buf; | struct ice_aqc_move_elem *buf; | ||||
struct ice_sched_node *node; | struct ice_sched_node *node; | ||||
enum ice_status status = ICE_SUCCESS; | |||||
u16 i, grps_movd = 0; | u16 i, grps_movd = 0; | ||||
struct ice_hw *hw; | struct ice_hw *hw; | ||||
u16 buf_len; | u16 buf_len; | ||||
hw = pi->hw; | hw = pi->hw; | ||||
if (!parent || !num_items) | if (!parent || !num_items) | ||||
return ICE_ERR_PARAM; | return ICE_ERR_PARAM; | ||||
▲ Show 20 Lines • Show All 394 Lines • ▼ Show 20 Lines | ice_sched_cfg_agg(struct ice_port_info *pi, u32 agg_id, | ||||
struct ice_hw *hw = pi->hw; | struct ice_hw *hw = pi->hw; | ||||
u8 tc; | u8 tc; | ||||
agg_info = ice_get_agg_info(hw, agg_id); | agg_info = ice_get_agg_info(hw, agg_id); | ||||
if (!agg_info) { | if (!agg_info) { | ||||
/* Create new entry for new aggregator ID */ | /* Create new entry for new aggregator ID */ | ||||
agg_info = (struct ice_sched_agg_info *) | agg_info = (struct ice_sched_agg_info *) | ||||
ice_malloc(hw, sizeof(*agg_info)); | ice_malloc(hw, sizeof(*agg_info)); | ||||
if (!agg_info) { | if (!agg_info) | ||||
status = ICE_ERR_NO_MEMORY; | return ICE_ERR_NO_MEMORY; | ||||
goto exit_reg_agg; | |||||
} | |||||
agg_info->agg_id = agg_id; | agg_info->agg_id = agg_id; | ||||
agg_info->agg_type = agg_type; | agg_info->agg_type = agg_type; | ||||
agg_info->tc_bitmap[0] = 0; | agg_info->tc_bitmap[0] = 0; | ||||
/* Initialize the aggregator VSI list head */ | /* Initialize the aggregator VSI list head */ | ||||
INIT_LIST_HEAD(&agg_info->agg_vsi_list); | INIT_LIST_HEAD(&agg_info->agg_vsi_list); | ||||
/* Add new entry in aggregator list */ | /* Add new entry in aggregator list */ | ||||
Show All 16 Lines | ice_for_each_traffic_class(tc) { | ||||
/* Create new aggregator node for TC */ | /* Create new aggregator node for TC */ | ||||
status = ice_sched_add_agg_cfg(pi, agg_id, tc); | status = ice_sched_add_agg_cfg(pi, agg_id, tc); | ||||
if (status) | if (status) | ||||
break; | break; | ||||
/* Save aggregator node's TC information */ | /* Save aggregator node's TC information */ | ||||
ice_set_bit(tc, agg_info->tc_bitmap); | ice_set_bit(tc, agg_info->tc_bitmap); | ||||
} | } | ||||
exit_reg_agg: | |||||
return status; | return status; | ||||
} | } | ||||
/** | /** | ||||
* ice_cfg_agg - config aggregator node | * ice_cfg_agg - config aggregator node | ||||
* @pi: port information structure | * @pi: port information structure | ||||
* @agg_id: aggregator ID | * @agg_id: aggregator ID | ||||
* @agg_type: aggregator type queue, VSI, or aggregator group | * @agg_type: aggregator type queue, VSI, or aggregator group | ||||
▲ Show 20 Lines • Show All 137 Lines • ▼ Show 20 Lines | ice_for_each_traffic_class(tc) { | ||||
if (!ice_is_tc_ena(*tc_bitmap, tc)) | if (!ice_is_tc_ena(*tc_bitmap, tc)) | ||||
continue; | continue; | ||||
/* Move VSI to new aggregator */ | /* Move VSI to new aggregator */ | ||||
status = ice_sched_move_vsi_to_agg(pi, vsi_handle, agg_id, tc); | status = ice_sched_move_vsi_to_agg(pi, vsi_handle, agg_id, tc); | ||||
if (status) | if (status) | ||||
break; | break; | ||||
if (agg_id != ICE_DFLT_AGG_ID) | |||||
ice_set_bit(tc, agg_vsi_info->tc_bitmap); | ice_set_bit(tc, agg_vsi_info->tc_bitmap); | ||||
else | |||||
ice_clear_bit(tc, agg_vsi_info->tc_bitmap); | |||||
} | } | ||||
/* If VSI moved back to default aggregator, delete agg_vsi_info. */ | |||||
if (!ice_is_any_bit_set(agg_vsi_info->tc_bitmap, | |||||
ICE_MAX_TRAFFIC_CLASS)) { | |||||
LIST_DEL(&agg_vsi_info->list_entry); | |||||
ice_free(hw, agg_vsi_info); | |||||
} | |||||
return status; | return status; | ||||
} | } | ||||
/** | /** | ||||
* ice_sched_rm_unused_rl_prof - remove unused RL profile | * ice_sched_rm_unused_rl_prof - remove unused RL profile | ||||
* @pi: port information structure | * @hw: pointer to the hardware structure | ||||
* | * | ||||
* This function removes unused rate limit profiles from the HW and | * This function removes unused rate limit profiles from the HW and | ||||
* SW DB. The caller needs to hold scheduler lock. | * SW DB. The caller needs to hold scheduler lock. | ||||
*/ | */ | ||||
static void ice_sched_rm_unused_rl_prof(struct ice_port_info *pi) | static void ice_sched_rm_unused_rl_prof(struct ice_hw *hw) | ||||
{ | { | ||||
u16 ln; | u16 ln; | ||||
for (ln = 0; ln < pi->hw->num_tx_sched_layers; ln++) { | for (ln = 0; ln < hw->num_tx_sched_layers; ln++) { | ||||
struct ice_aqc_rl_profile_info *rl_prof_elem; | struct ice_aqc_rl_profile_info *rl_prof_elem; | ||||
struct ice_aqc_rl_profile_info *rl_prof_tmp; | struct ice_aqc_rl_profile_info *rl_prof_tmp; | ||||
LIST_FOR_EACH_ENTRY_SAFE(rl_prof_elem, rl_prof_tmp, | LIST_FOR_EACH_ENTRY_SAFE(rl_prof_elem, rl_prof_tmp, | ||||
&pi->rl_prof_list[ln], | &hw->rl_prof_list[ln], | ||||
ice_aqc_rl_profile_info, list_entry) { | ice_aqc_rl_profile_info, list_entry) { | ||||
if (!ice_sched_del_rl_profile(pi->hw, rl_prof_elem)) | if (!ice_sched_del_rl_profile(hw, rl_prof_elem)) | ||||
ice_debug(pi->hw, ICE_DBG_SCHED, "Removed rl profile\n"); | ice_debug(hw, ICE_DBG_SCHED, "Removed rl profile\n"); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* ice_sched_update_elem - update element | * ice_sched_update_elem - update element | ||||
* @hw: pointer to the HW struct | * @hw: pointer to the HW struct | ||||
* @node: pointer to node | * @node: pointer to node | ||||
▲ Show 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | if (ice_is_any_bit_set(agg_info->tc_bitmap, ICE_MAX_TRAFFIC_CLASS)) { | ||||
goto exit_ice_rm_agg_cfg; | goto exit_ice_rm_agg_cfg; | ||||
} | } | ||||
/* Safe to delete entry now */ | /* Safe to delete entry now */ | ||||
LIST_DEL(&agg_info->list_entry); | LIST_DEL(&agg_info->list_entry); | ||||
ice_free(pi->hw, agg_info); | ice_free(pi->hw, agg_info); | ||||
/* Remove unused RL profile IDs from HW and SW DB */ | /* Remove unused RL profile IDs from HW and SW DB */ | ||||
ice_sched_rm_unused_rl_prof(pi); | ice_sched_rm_unused_rl_prof(pi->hw); | ||||
exit_ice_rm_agg_cfg: | exit_ice_rm_agg_cfg: | ||||
ice_release_lock(&pi->sched_lock); | ice_release_lock(&pi->sched_lock); | ||||
return status; | return status; | ||||
} | } | ||||
/** | /** | ||||
* ice_set_clear_cir_bw_alloc - set or clear CIR BW alloc information | * ice_set_clear_cir_bw_alloc - set or clear CIR BW alloc information | ||||
▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | |||||
* Save or clear EIR bandwidth (BW) in the passed param bw_t_info. | * 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) { | if (bw == ICE_SCHED_DFLT_BW) { | ||||
ice_clear_bit(ICE_BW_TYPE_EIR, bw_t_info->bw_t_bitmap); | ice_clear_bit(ICE_BW_TYPE_EIR, bw_t_info->bw_t_bitmap); | ||||
bw_t_info->eir_bw.bw = 0; | bw_t_info->eir_bw.bw = 0; | ||||
} else { | } else { | ||||
/* EIR BW and Shared BW profiles are mutually exclusive and | |||||
* hence only one of them may be set for any given element. | |||||
* First clear earlier saved shared BW information. | |||||
*/ | |||||
ice_clear_bit(ICE_BW_TYPE_SHARED, bw_t_info->bw_t_bitmap); | |||||
bw_t_info->shared_bw = 0; | |||||
/* save EIR BW information */ | /* save EIR BW information */ | ||||
ice_set_bit(ICE_BW_TYPE_EIR, bw_t_info->bw_t_bitmap); | ice_set_bit(ICE_BW_TYPE_EIR, bw_t_info->bw_t_bitmap); | ||||
bw_t_info->eir_bw.bw = bw; | bw_t_info->eir_bw.bw = bw; | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* ice_set_clear_shared_bw - set or clear shared BW | * ice_set_clear_shared_bw - set or clear shared BW | ||||
* @bw_t_info: bandwidth type information structure | * @bw_t_info: bandwidth type information structure | ||||
* @bw: bandwidth in Kbps - Kilo bits per sec | * @bw: bandwidth in Kbps - Kilo bits per sec | ||||
* | * | ||||
* Save or clear shared bandwidth (BW) in the passed param bw_t_info. | * 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) { | if (bw == ICE_SCHED_DFLT_BW) { | ||||
ice_clear_bit(ICE_BW_TYPE_SHARED, bw_t_info->bw_t_bitmap); | ice_clear_bit(ICE_BW_TYPE_SHARED, bw_t_info->bw_t_bitmap); | ||||
bw_t_info->shared_bw = 0; | bw_t_info->shared_bw = 0; | ||||
} else { | } else { | ||||
/* EIR BW and Shared BW profiles are mutually exclusive and | |||||
* hence only one of them may be set for any given element. | |||||
* First clear earlier saved EIR BW information. | |||||
*/ | |||||
ice_clear_bit(ICE_BW_TYPE_EIR, bw_t_info->bw_t_bitmap); | |||||
bw_t_info->eir_bw.bw = 0; | |||||
/* save shared BW information */ | /* save shared BW information */ | ||||
ice_set_bit(ICE_BW_TYPE_SHARED, bw_t_info->bw_t_bitmap); | ice_set_bit(ICE_BW_TYPE_SHARED, bw_t_info->bw_t_bitmap); | ||||
bw_t_info->shared_bw = bw; | bw_t_info->shared_bw = bw; | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* ice_sched_save_vsi_bw - save VSI node's BW information | * ice_sched_save_vsi_bw - save VSI node's BW information | ||||
▲ Show 20 Lines • Show All 256 Lines • ▼ Show 20 Lines | ice_cfg_agg_bw_dflt_lmt_per_tc(struct ice_port_info *pi, u32 agg_id, u8 tc, | ||||
} | } | ||||
return status; | return status; | ||||
} | } | ||||
/** | /** | ||||
* ice_cfg_vsi_bw_shared_lmt - configure VSI BW shared limit | * ice_cfg_vsi_bw_shared_lmt - configure VSI BW shared limit | ||||
* @pi: port information structure | * @pi: port information structure | ||||
* @vsi_handle: software VSI handle | * @vsi_handle: software VSI handle | ||||
* @bw: bandwidth in Kbps | * @min_bw: minimum bandwidth in Kbps | ||||
* @max_bw: maximum bandwidth in Kbps | |||||
* @shared_bw: shared bandwidth in Kbps | |||||
* | * | ||||
* This function Configures shared rate limiter(SRL) of all VSI type nodes | * Configure shared rate limiter(SRL) of all VSI type nodes across all traffic | ||||
* across all traffic classes for VSI matching handle. | * classes for VSI matching handle. | ||||
*/ | */ | ||||
enum ice_status | enum ice_status | ||||
ice_cfg_vsi_bw_shared_lmt(struct ice_port_info *pi, u16 vsi_handle, u32 bw) | ice_cfg_vsi_bw_shared_lmt(struct ice_port_info *pi, u16 vsi_handle, u32 min_bw, | ||||
u32 max_bw, u32 shared_bw) | |||||
{ | { | ||||
return ice_sched_set_vsi_bw_shared_lmt(pi, vsi_handle, bw); | return ice_sched_set_vsi_bw_shared_lmt(pi, vsi_handle, min_bw, max_bw, | ||||
shared_bw); | |||||
} | } | ||||
/** | /** | ||||
* ice_cfg_vsi_bw_no_shared_lmt - configure VSI BW for no shared limiter | * ice_cfg_vsi_bw_no_shared_lmt - configure VSI BW for no shared limiter | ||||
* @pi: port information structure | * @pi: port information structure | ||||
* @vsi_handle: software VSI handle | * @vsi_handle: software VSI handle | ||||
* | * | ||||
* This function removes the shared rate limiter(SRL) of all VSI type nodes | * This function removes the shared rate limiter(SRL) of all VSI type nodes | ||||
* across all traffic classes for VSI matching handle. | * across all traffic classes for VSI matching handle. | ||||
*/ | */ | ||||
enum ice_status | enum ice_status | ||||
ice_cfg_vsi_bw_no_shared_lmt(struct ice_port_info *pi, u16 vsi_handle) | ice_cfg_vsi_bw_no_shared_lmt(struct ice_port_info *pi, u16 vsi_handle) | ||||
{ | { | ||||
return ice_sched_set_vsi_bw_shared_lmt(pi, vsi_handle, | return ice_sched_set_vsi_bw_shared_lmt(pi, vsi_handle, | ||||
ICE_SCHED_DFLT_BW, | |||||
ICE_SCHED_DFLT_BW, | |||||
ICE_SCHED_DFLT_BW); | ICE_SCHED_DFLT_BW); | ||||
} | } | ||||
/** | /** | ||||
* ice_cfg_agg_bw_shared_lmt - configure aggregator BW shared limit | * ice_cfg_agg_bw_shared_lmt - configure aggregator BW shared limit | ||||
* @pi: port information structure | * @pi: port information structure | ||||
* @agg_id: aggregator ID | * @agg_id: aggregator ID | ||||
* @bw: bandwidth in Kbps | * @min_bw: minimum bandwidth in Kbps | ||||
* @max_bw: maximum bandwidth in Kbps | |||||
* @shared_bw: shared bandwidth in Kbps | |||||
* | * | ||||
* This function configures the shared rate limiter(SRL) of all aggregator type | * This function configures the shared rate limiter(SRL) of all aggregator type | ||||
* nodes across all traffic classes for aggregator matching agg_id. | * nodes across all traffic classes for aggregator matching agg_id. | ||||
*/ | */ | ||||
enum ice_status | enum ice_status | ||||
ice_cfg_agg_bw_shared_lmt(struct ice_port_info *pi, u32 agg_id, u32 bw) | ice_cfg_agg_bw_shared_lmt(struct ice_port_info *pi, u32 agg_id, u32 min_bw, | ||||
u32 max_bw, u32 shared_bw) | |||||
{ | { | ||||
return ice_sched_set_agg_bw_shared_lmt(pi, agg_id, bw); | return ice_sched_set_agg_bw_shared_lmt(pi, agg_id, min_bw, max_bw, | ||||
shared_bw); | |||||
} | } | ||||
/** | /** | ||||
* ice_cfg_agg_bw_no_shared_lmt - configure aggregator BW for no shared limiter | * ice_cfg_agg_bw_no_shared_lmt - configure aggregator BW for no shared limiter | ||||
* @pi: port information structure | * @pi: port information structure | ||||
* @agg_id: aggregator ID | * @agg_id: aggregator ID | ||||
* | * | ||||
* This function removes the shared rate limiter(SRL) of all aggregator type | * This function removes the shared rate limiter(SRL) of all aggregator type | ||||
* nodes across all traffic classes for aggregator matching agg_id. | * nodes across all traffic classes for aggregator matching agg_id. | ||||
*/ | */ | ||||
enum ice_status | enum ice_status | ||||
ice_cfg_agg_bw_no_shared_lmt(struct ice_port_info *pi, u32 agg_id) | ice_cfg_agg_bw_no_shared_lmt(struct ice_port_info *pi, u32 agg_id) | ||||
{ | { | ||||
return ice_sched_set_agg_bw_shared_lmt(pi, agg_id, ICE_SCHED_DFLT_BW); | return ice_sched_set_agg_bw_shared_lmt(pi, agg_id, ICE_SCHED_DFLT_BW, | ||||
ICE_SCHED_DFLT_BW, | |||||
ICE_SCHED_DFLT_BW); | |||||
} | } | ||||
/** | /** | ||||
* ice_cfg_agg_bw_shared_lmt_per_tc - configure aggregator BW shared limit per tc | |||||
* @pi: port information structure | |||||
* @agg_id: aggregator ID | |||||
* @tc: traffic class | |||||
* @min_bw: minimum bandwidth in Kbps | |||||
* @max_bw: maximum bandwidth in Kbps | |||||
* @shared_bw: shared bandwidth in Kbps | |||||
* | |||||
* This function configures the shared rate limiter(SRL) of all aggregator type | |||||
* nodes across all traffic classes for aggregator matching agg_id. | |||||
*/ | |||||
enum ice_status | |||||
ice_cfg_agg_bw_shared_lmt_per_tc(struct ice_port_info *pi, u32 agg_id, u8 tc, | |||||
u32 min_bw, u32 max_bw, u32 shared_bw) | |||||
{ | |||||
return ice_sched_set_agg_bw_shared_lmt_per_tc(pi, agg_id, tc, min_bw, | |||||
max_bw, shared_bw); | |||||
} | |||||
/** | |||||
* ice_cfg_agg_bw_shared_lmt_per_tc - configure aggregator BW shared limit per tc | |||||
* @pi: port information structure | |||||
* @agg_id: aggregator ID | |||||
* @tc: traffic class | |||||
* | |||||
* This function configures the shared rate limiter(SRL) of all aggregator type | |||||
* nodes across all traffic classes for aggregator matching agg_id. | |||||
*/ | |||||
enum ice_status | |||||
ice_cfg_agg_bw_no_shared_lmt_per_tc(struct ice_port_info *pi, u32 agg_id, u8 tc) | |||||
{ | |||||
return ice_sched_set_agg_bw_shared_lmt_per_tc(pi, agg_id, tc, | |||||
ICE_SCHED_DFLT_BW, | |||||
ICE_SCHED_DFLT_BW, | |||||
ICE_SCHED_DFLT_BW); | |||||
} | |||||
/** | |||||
* ice_config_vsi_queue_priority - config VSI queue priority of node | * ice_config_vsi_queue_priority - config VSI queue priority of node | ||||
* @pi: port information structure | * @pi: port information structure | ||||
* @num_qs: number of VSI queues | * @num_qs: number of VSI queues | ||||
* @q_ids: queue IDs array | * @q_ids: queue IDs array | ||||
* @q_prio: queue priority array | * @q_prio: queue priority array | ||||
* | * | ||||
* This function configures the queue node priority (Sibling Priority) of the | * This function configures the queue node priority (Sibling Priority) of the | ||||
* passed in VSI's queue(s) for a given traffic class (TC). | * passed in VSI's queue(s) for a given traffic class (TC). | ||||
▲ Show 20 Lines • Show All 335 Lines • ▼ Show 20 Lines | if (found) { | ||||
status = ICE_ERR_DOES_NOT_EXIST; | status = ICE_ERR_DOES_NOT_EXIST; | ||||
} | } | ||||
return status; | return status; | ||||
} | } | ||||
/** | /** | ||||
* ice_sched_add_rl_profile - add RL profile | * ice_sched_add_rl_profile - add RL profile | ||||
* @pi: port information structure | * @hw: pointer to the hardware structure | ||||
* @rl_type: type of rate limit BW - min, max, or shared | * @rl_type: type of rate limit BW - min, max, or shared | ||||
* @bw: bandwidth in Kbps - Kilo bits per sec | * @bw: bandwidth in Kbps - Kilo bits per sec | ||||
* @layer_num: specifies in which layer to create profile | * @layer_num: specifies in which layer to create profile | ||||
* | * | ||||
* This function first checks the existing list for corresponding BW | * This function first checks the existing list for corresponding BW | ||||
* parameter. If it exists, it returns the associated profile otherwise | * parameter. If it exists, it returns the associated profile otherwise | ||||
* it creates a new rate limit profile for requested BW, and adds it to | * it creates a new rate limit profile for requested BW, and adds it to | ||||
* the HW DB and local list. It returns the new profile or null on error. | * the HW DB and local list. It returns the new profile or null on error. | ||||
* The caller needs to hold the scheduler lock. | * The caller needs to hold the scheduler lock. | ||||
*/ | */ | ||||
static struct ice_aqc_rl_profile_info * | static struct ice_aqc_rl_profile_info * | ||||
ice_sched_add_rl_profile(struct ice_port_info *pi, | ice_sched_add_rl_profile(struct ice_hw *hw, enum ice_rl_type rl_type, | ||||
enum ice_rl_type rl_type, u32 bw, u8 layer_num) | u32 bw, u8 layer_num) | ||||
{ | { | ||||
struct ice_aqc_rl_profile_info *rl_prof_elem; | struct ice_aqc_rl_profile_info *rl_prof_elem; | ||||
u16 profiles_added = 0, num_profiles = 1; | u16 profiles_added = 0, num_profiles = 1; | ||||
struct ice_aqc_rl_profile_elem *buf; | struct ice_aqc_rl_profile_elem *buf; | ||||
enum ice_status status; | enum ice_status status; | ||||
struct ice_hw *hw; | |||||
u8 profile_type; | u8 profile_type; | ||||
if (layer_num >= ICE_AQC_TOPO_MAX_LEVEL_NUM) | if (layer_num >= ICE_AQC_TOPO_MAX_LEVEL_NUM) | ||||
return NULL; | return NULL; | ||||
switch (rl_type) { | switch (rl_type) { | ||||
case ICE_MIN_BW: | case ICE_MIN_BW: | ||||
profile_type = ICE_AQC_RL_PROFILE_TYPE_CIR; | profile_type = ICE_AQC_RL_PROFILE_TYPE_CIR; | ||||
break; | break; | ||||
case ICE_MAX_BW: | case ICE_MAX_BW: | ||||
profile_type = ICE_AQC_RL_PROFILE_TYPE_EIR; | profile_type = ICE_AQC_RL_PROFILE_TYPE_EIR; | ||||
break; | break; | ||||
case ICE_SHARED_BW: | case ICE_SHARED_BW: | ||||
profile_type = ICE_AQC_RL_PROFILE_TYPE_SRL; | profile_type = ICE_AQC_RL_PROFILE_TYPE_SRL; | ||||
break; | break; | ||||
default: | default: | ||||
return NULL; | return NULL; | ||||
} | } | ||||
if (!pi) | if (!hw) | ||||
return NULL; | return NULL; | ||||
hw = pi->hw; | LIST_FOR_EACH_ENTRY(rl_prof_elem, &hw->rl_prof_list[layer_num], | ||||
LIST_FOR_EACH_ENTRY(rl_prof_elem, &pi->rl_prof_list[layer_num], | |||||
ice_aqc_rl_profile_info, list_entry) | ice_aqc_rl_profile_info, list_entry) | ||||
if ((rl_prof_elem->profile.flags & ICE_AQC_RL_PROFILE_TYPE_M) == | if ((rl_prof_elem->profile.flags & ICE_AQC_RL_PROFILE_TYPE_M) == | ||||
profile_type && rl_prof_elem->bw == bw) | profile_type && rl_prof_elem->bw == bw) | ||||
/* Return existing profile ID info */ | /* Return existing profile ID info */ | ||||
return rl_prof_elem; | return rl_prof_elem; | ||||
/* Create new profile ID */ | /* Create new profile ID */ | ||||
rl_prof_elem = (struct ice_aqc_rl_profile_info *) | rl_prof_elem = (struct ice_aqc_rl_profile_info *) | ||||
Show All 16 Lines | ice_sched_add_rl_profile(struct ice_hw *hw, enum ice_rl_type rl_type, | ||||
buf = &rl_prof_elem->profile; | buf = &rl_prof_elem->profile; | ||||
status = ice_aq_add_rl_profile(hw, num_profiles, buf, sizeof(*buf), | status = ice_aq_add_rl_profile(hw, num_profiles, buf, sizeof(*buf), | ||||
&profiles_added, NULL); | &profiles_added, NULL); | ||||
if (status || profiles_added != num_profiles) | if (status || profiles_added != num_profiles) | ||||
goto exit_add_rl_prof; | goto exit_add_rl_prof; | ||||
/* Good entry - add in the list */ | /* Good entry - add in the list */ | ||||
rl_prof_elem->prof_id_ref = 0; | rl_prof_elem->prof_id_ref = 0; | ||||
LIST_ADD(&rl_prof_elem->list_entry, &pi->rl_prof_list[layer_num]); | LIST_ADD(&rl_prof_elem->list_entry, &hw->rl_prof_list[layer_num]); | ||||
return rl_prof_elem; | return rl_prof_elem; | ||||
exit_add_rl_prof: | exit_add_rl_prof: | ||||
ice_free(hw, rl_prof_elem); | ice_free(hw, rl_prof_elem); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
/** | /** | ||||
Show All 15 Lines | ice_sched_cfg_node_bw_lmt(struct ice_hw *hw, struct ice_sched_node *node, | ||||
buf = node->info; | buf = node->info; | ||||
data = &buf.data; | data = &buf.data; | ||||
switch (rl_type) { | switch (rl_type) { | ||||
case ICE_MIN_BW: | case ICE_MIN_BW: | ||||
data->valid_sections |= ICE_AQC_ELEM_VALID_CIR; | data->valid_sections |= ICE_AQC_ELEM_VALID_CIR; | ||||
data->cir_bw.bw_profile_idx = CPU_TO_LE16(rl_prof_id); | data->cir_bw.bw_profile_idx = CPU_TO_LE16(rl_prof_id); | ||||
break; | break; | ||||
case ICE_MAX_BW: | case ICE_MAX_BW: | ||||
/* EIR BW and Shared BW profiles are mutually exclusive and | |||||
* hence only one of them may be set for any given element | |||||
*/ | |||||
if (data->valid_sections & ICE_AQC_ELEM_VALID_SHARED) | |||||
return ICE_ERR_CFG; | |||||
data->valid_sections |= ICE_AQC_ELEM_VALID_EIR; | data->valid_sections |= ICE_AQC_ELEM_VALID_EIR; | ||||
data->eir_bw.bw_profile_idx = CPU_TO_LE16(rl_prof_id); | data->eir_bw.bw_profile_idx = CPU_TO_LE16(rl_prof_id); | ||||
break; | break; | ||||
case ICE_SHARED_BW: | case ICE_SHARED_BW: | ||||
/* Check for removing shared BW */ | |||||
if (rl_prof_id == ICE_SCHED_NO_SHARED_RL_PROF_ID) { | |||||
/* remove shared profile */ | |||||
data->valid_sections &= ~ICE_AQC_ELEM_VALID_SHARED; | |||||
data->srl_id = 0; /* clear SRL field */ | |||||
/* enable back EIR to default profile */ | |||||
data->valid_sections |= ICE_AQC_ELEM_VALID_EIR; | |||||
data->eir_bw.bw_profile_idx = | |||||
CPU_TO_LE16(ICE_SCHED_DFLT_RL_PROF_ID); | |||||
break; | |||||
} | |||||
/* EIR BW and Shared BW profiles are mutually exclusive and | |||||
* hence only one of them may be set for any given element | |||||
*/ | |||||
if ((data->valid_sections & ICE_AQC_ELEM_VALID_EIR) && | |||||
(LE16_TO_CPU(data->eir_bw.bw_profile_idx) != | |||||
ICE_SCHED_DFLT_RL_PROF_ID)) | |||||
return ICE_ERR_CFG; | |||||
/* EIR BW is set to default, disable it */ | |||||
data->valid_sections &= ~ICE_AQC_ELEM_VALID_EIR; | |||||
/* Okay to enable shared BW now */ | |||||
data->valid_sections |= ICE_AQC_ELEM_VALID_SHARED; | data->valid_sections |= ICE_AQC_ELEM_VALID_SHARED; | ||||
data->srl_id = CPU_TO_LE16(rl_prof_id); | data->srl_id = CPU_TO_LE16(rl_prof_id); | ||||
break; | break; | ||||
default: | default: | ||||
/* Unknown rate limit type */ | /* Unknown rate limit type */ | ||||
return ICE_ERR_PARAM; | return ICE_ERR_PARAM; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | else if (srl_layer < node->tx_sched_layer) | ||||
*/ | */ | ||||
return node->parent; | return node->parent; | ||||
else | else | ||||
return node; | return node; | ||||
} | } | ||||
/** | /** | ||||
* ice_sched_rm_rl_profile - remove RL profile ID | * ice_sched_rm_rl_profile - remove RL profile ID | ||||
* @pi: port information structure | * @hw: pointer to the hardware structure | ||||
* @layer_num: layer number where profiles are saved | * @layer_num: layer number where profiles are saved | ||||
* @profile_type: profile type like EIR, CIR, or SRL | * @profile_type: profile type like EIR, CIR, or SRL | ||||
* @profile_id: profile ID to remove | * @profile_id: profile ID to remove | ||||
* | * | ||||
* This function removes rate limit profile from layer 'layer_num' of type | * This function removes rate limit profile from layer 'layer_num' of type | ||||
* 'profile_type' and profile ID as 'profile_id'. The caller needs to hold | * 'profile_type' and profile ID as 'profile_id'. The caller needs to hold | ||||
* scheduler lock. | * scheduler lock. | ||||
*/ | */ | ||||
static enum ice_status | static enum ice_status | ||||
ice_sched_rm_rl_profile(struct ice_port_info *pi, u8 layer_num, u8 profile_type, | ice_sched_rm_rl_profile(struct ice_hw *hw, u8 layer_num, u8 profile_type, | ||||
u16 profile_id) | u16 profile_id) | ||||
{ | { | ||||
struct ice_aqc_rl_profile_info *rl_prof_elem; | struct ice_aqc_rl_profile_info *rl_prof_elem; | ||||
enum ice_status status = ICE_SUCCESS; | enum ice_status status = ICE_SUCCESS; | ||||
if (layer_num >= ICE_AQC_TOPO_MAX_LEVEL_NUM) | if (layer_num >= ICE_AQC_TOPO_MAX_LEVEL_NUM) | ||||
return ICE_ERR_PARAM; | return ICE_ERR_PARAM; | ||||
/* Check the existing list for RL profile */ | /* Check the existing list for RL profile */ | ||||
LIST_FOR_EACH_ENTRY(rl_prof_elem, &pi->rl_prof_list[layer_num], | LIST_FOR_EACH_ENTRY(rl_prof_elem, &hw->rl_prof_list[layer_num], | ||||
ice_aqc_rl_profile_info, list_entry) | ice_aqc_rl_profile_info, list_entry) | ||||
if ((rl_prof_elem->profile.flags & ICE_AQC_RL_PROFILE_TYPE_M) == | if ((rl_prof_elem->profile.flags & ICE_AQC_RL_PROFILE_TYPE_M) == | ||||
profile_type && | profile_type && | ||||
LE16_TO_CPU(rl_prof_elem->profile.profile_id) == | LE16_TO_CPU(rl_prof_elem->profile.profile_id) == | ||||
profile_id) { | profile_id) { | ||||
if (rl_prof_elem->prof_id_ref) | if (rl_prof_elem->prof_id_ref) | ||||
rl_prof_elem->prof_id_ref--; | rl_prof_elem->prof_id_ref--; | ||||
/* Remove old profile ID from database */ | /* Remove old profile ID from database */ | ||||
status = ice_sched_del_rl_profile(pi->hw, rl_prof_elem); | status = ice_sched_del_rl_profile(hw, rl_prof_elem); | ||||
if (status && status != ICE_ERR_IN_USE) | if (status && status != ICE_ERR_IN_USE) | ||||
ice_debug(pi->hw, ICE_DBG_SCHED, "Remove rl profile failed\n"); | ice_debug(hw, ICE_DBG_SCHED, "Remove rl profile failed\n"); | ||||
break; | break; | ||||
} | } | ||||
if (status == ICE_ERR_IN_USE) | if (status == ICE_ERR_IN_USE) | ||||
status = ICE_SUCCESS; | status = ICE_SUCCESS; | ||||
return status; | return status; | ||||
} | } | ||||
/** | /** | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | ice_sched_set_node_bw_dflt(struct ice_port_info *pi, | ||||
if (status) | if (status) | ||||
return status; | return status; | ||||
/* Remove stale RL profile ID */ | /* Remove stale RL profile ID */ | ||||
if (old_id == ICE_SCHED_DFLT_RL_PROF_ID || | if (old_id == ICE_SCHED_DFLT_RL_PROF_ID || | ||||
old_id == ICE_SCHED_INVAL_PROF_ID) | old_id == ICE_SCHED_INVAL_PROF_ID) | ||||
return ICE_SUCCESS; | return ICE_SUCCESS; | ||||
return ice_sched_rm_rl_profile(pi, layer_num, profile_type, old_id); | return ice_sched_rm_rl_profile(hw, layer_num, profile_type, old_id); | ||||
} | } | ||||
/** | /** | ||||
* ice_sched_set_eir_srl_excl - set EIR/SRL exclusiveness | |||||
* @pi: port information structure | |||||
* @node: pointer to node structure | |||||
* @layer_num: layer number where rate limit profiles are saved | |||||
* @rl_type: rate limit type min, max, or shared | |||||
* @bw: bandwidth value | |||||
* | |||||
* This function prepares node element's bandwidth to SRL or EIR exclusively. | |||||
* EIR BW and Shared BW profiles are mutually exclusive and hence only one of | |||||
* them may be set for any given element. This function needs to be called | |||||
* with the scheduler lock held. | |||||
*/ | |||||
static enum ice_status | |||||
ice_sched_set_eir_srl_excl(struct ice_port_info *pi, | |||||
struct ice_sched_node *node, | |||||
u8 layer_num, enum ice_rl_type rl_type, u32 bw) | |||||
{ | |||||
if (rl_type == ICE_SHARED_BW) { | |||||
/* SRL node passed in this case, it may be different node */ | |||||
if (bw == ICE_SCHED_DFLT_BW) | |||||
/* SRL being removed, ice_sched_cfg_node_bw_lmt() | |||||
* enables EIR to default. EIR is not set in this | |||||
* case, so no additional action is required. | |||||
*/ | |||||
return ICE_SUCCESS; | |||||
/* SRL being configured, set EIR to default here. | |||||
* ice_sched_cfg_node_bw_lmt() disables EIR when it | |||||
* configures SRL | |||||
*/ | |||||
return ice_sched_set_node_bw_dflt(pi, node, ICE_MAX_BW, | |||||
layer_num); | |||||
} else if (rl_type == ICE_MAX_BW && | |||||
node->info.data.valid_sections & ICE_AQC_ELEM_VALID_SHARED) { | |||||
/* Remove Shared profile. Set default shared BW call | |||||
* removes shared profile for a node. | |||||
*/ | |||||
return ice_sched_set_node_bw_dflt(pi, node, | |||||
ICE_SHARED_BW, | |||||
layer_num); | |||||
} | |||||
return ICE_SUCCESS; | |||||
} | |||||
/** | |||||
* ice_sched_set_node_bw - set node's bandwidth | * ice_sched_set_node_bw - set node's bandwidth | ||||
* @pi: port information structure | * @pi: port information structure | ||||
* @node: tree node | * @node: tree node | ||||
* @rl_type: rate limit type min, max, or shared | * @rl_type: rate limit type min, max, or shared | ||||
* @bw: bandwidth in Kbps - Kilo bits per sec | * @bw: bandwidth in Kbps - Kilo bits per sec | ||||
* @layer_num: layer number | * @layer_num: layer number | ||||
* | * | ||||
* This function adds new profile corresponding to requested BW, configures | * This function adds new profile corresponding to requested BW, configures | ||||
* node's RL profile ID of type CIR, EIR, or SRL, and removes old profile | * node's RL profile ID of type CIR, EIR, or SRL, and removes old profile | ||||
* ID from local database. The caller needs to hold scheduler lock. | * ID from local database. The caller needs to hold scheduler lock. | ||||
*/ | */ | ||||
static enum ice_status | static enum ice_status | ||||
ice_sched_set_node_bw(struct ice_port_info *pi, struct ice_sched_node *node, | ice_sched_set_node_bw(struct ice_port_info *pi, struct ice_sched_node *node, | ||||
enum ice_rl_type rl_type, u32 bw, u8 layer_num) | enum ice_rl_type rl_type, u32 bw, u8 layer_num) | ||||
{ | { | ||||
struct ice_aqc_rl_profile_info *rl_prof_info; | struct ice_aqc_rl_profile_info *rl_prof_info; | ||||
enum ice_status status = ICE_ERR_PARAM; | enum ice_status status = ICE_ERR_PARAM; | ||||
struct ice_hw *hw = pi->hw; | struct ice_hw *hw = pi->hw; | ||||
u16 old_id, rl_prof_id; | u16 old_id, rl_prof_id; | ||||
rl_prof_info = ice_sched_add_rl_profile(pi, rl_type, bw, layer_num); | rl_prof_info = ice_sched_add_rl_profile(hw, rl_type, bw, layer_num); | ||||
if (!rl_prof_info) | if (!rl_prof_info) | ||||
return status; | return status; | ||||
rl_prof_id = LE16_TO_CPU(rl_prof_info->profile.profile_id); | rl_prof_id = LE16_TO_CPU(rl_prof_info->profile.profile_id); | ||||
/* Save existing RL prof ID for later clean up */ | /* Save existing RL prof ID for later clean up */ | ||||
old_id = ice_sched_get_node_rl_prof_id(node, rl_type); | old_id = ice_sched_get_node_rl_prof_id(node, rl_type); | ||||
/* Configure BW scheduling parameters */ | /* Configure BW scheduling parameters */ | ||||
status = ice_sched_cfg_node_bw_lmt(hw, node, rl_type, rl_prof_id); | status = ice_sched_cfg_node_bw_lmt(hw, node, rl_type, rl_prof_id); | ||||
if (status) | if (status) | ||||
return status; | return status; | ||||
/* New changes has been applied */ | /* New changes has been applied */ | ||||
/* Increment the profile ID reference count */ | /* Increment the profile ID reference count */ | ||||
rl_prof_info->prof_id_ref++; | rl_prof_info->prof_id_ref++; | ||||
/* Check for old ID removal */ | /* Check for old ID removal */ | ||||
if ((old_id == ICE_SCHED_DFLT_RL_PROF_ID && rl_type != ICE_SHARED_BW) || | if ((old_id == ICE_SCHED_DFLT_RL_PROF_ID && rl_type != ICE_SHARED_BW) || | ||||
old_id == ICE_SCHED_INVAL_PROF_ID || old_id == rl_prof_id) | old_id == ICE_SCHED_INVAL_PROF_ID || old_id == rl_prof_id) | ||||
return ICE_SUCCESS; | return ICE_SUCCESS; | ||||
return ice_sched_rm_rl_profile(pi, layer_num, | return ice_sched_rm_rl_profile(hw, layer_num, | ||||
rl_prof_info->profile.flags & | rl_prof_info->profile.flags & | ||||
ICE_AQC_RL_PROFILE_TYPE_M, old_id); | ICE_AQC_RL_PROFILE_TYPE_M, old_id); | ||||
} | } | ||||
/** | /** | ||||
* ice_sched_set_node_bw_lmt - set node's BW limit | * ice_sched_set_node_bw_lmt - set node's BW limit | ||||
* @pi: port information structure | * @pi: port information structure | ||||
* @node: tree node | * @node: tree node | ||||
* @rl_type: rate limit type min, max, or shared | * @rl_type: rate limit type min, max, or shared | ||||
* @bw: bandwidth in Kbps - Kilo bits per sec | * @bw: bandwidth in Kbps - Kilo bits per sec | ||||
* | * | ||||
* It updates node's BW limit parameters like BW RL profile ID of type CIR, | * It updates node's BW limit parameters like BW RL profile ID of type CIR, | ||||
* EIR, or SRL. The caller needs to hold scheduler lock. | * EIR, or SRL. The caller needs to hold scheduler lock. | ||||
* | |||||
* NOTE: Caller provides the correct SRL node in case of shared profile | |||||
* settings. | |||||
*/ | */ | ||||
static enum ice_status | static enum ice_status | ||||
ice_sched_set_node_bw_lmt(struct ice_port_info *pi, struct ice_sched_node *node, | ice_sched_set_node_bw_lmt(struct ice_port_info *pi, struct ice_sched_node *node, | ||||
enum ice_rl_type rl_type, u32 bw) | enum ice_rl_type rl_type, u32 bw) | ||||
{ | { | ||||
struct ice_sched_node *cfg_node = node; | |||||
enum ice_status status; | |||||
struct ice_hw *hw; | struct ice_hw *hw; | ||||
u8 layer_num; | u8 layer_num; | ||||
if (!pi) | if (!pi) | ||||
return ICE_ERR_PARAM; | return ICE_ERR_PARAM; | ||||
hw = pi->hw; | hw = pi->hw; | ||||
/* Remove unused RL profile IDs from HW and SW DB */ | /* Remove unused RL profile IDs from HW and SW DB */ | ||||
ice_sched_rm_unused_rl_prof(pi); | ice_sched_rm_unused_rl_prof(hw); | ||||
layer_num = ice_sched_get_rl_prof_layer(pi, rl_type, | layer_num = ice_sched_get_rl_prof_layer(pi, rl_type, | ||||
node->tx_sched_layer); | node->tx_sched_layer); | ||||
if (layer_num >= hw->num_tx_sched_layers) | if (layer_num >= hw->num_tx_sched_layers) | ||||
return ICE_ERR_PARAM; | return ICE_ERR_PARAM; | ||||
if (rl_type == ICE_SHARED_BW) { | |||||
/* SRL node may be different */ | |||||
cfg_node = ice_sched_get_srl_node(node, layer_num); | |||||
if (!cfg_node) | |||||
return ICE_ERR_CFG; | |||||
} | |||||
/* EIR BW and Shared BW profiles are mutually exclusive and | |||||
* hence only one of them may be set for any given element | |||||
*/ | |||||
status = ice_sched_set_eir_srl_excl(pi, cfg_node, layer_num, rl_type, | |||||
bw); | |||||
if (status) | |||||
return status; | |||||
if (bw == ICE_SCHED_DFLT_BW) | if (bw == ICE_SCHED_DFLT_BW) | ||||
return ice_sched_set_node_bw_dflt(pi, cfg_node, rl_type, | return ice_sched_set_node_bw_dflt(pi, node, rl_type, layer_num); | ||||
layer_num); | return ice_sched_set_node_bw(pi, node, rl_type, bw, layer_num); | ||||
return ice_sched_set_node_bw(pi, cfg_node, rl_type, bw, layer_num); | |||||
} | } | ||||
/** | /** | ||||
* ice_sched_set_node_bw_dflt_lmt - set node's BW limit to default | * ice_sched_set_node_bw_dflt_lmt - set node's BW limit to default | ||||
* @pi: port information structure | * @pi: port information structure | ||||
* @node: pointer to node structure | * @node: pointer to node structure | ||||
* @rl_type: rate limit type min, max, or shared | * @rl_type: rate limit type min, max, or shared | ||||
* | * | ||||
▲ Show 20 Lines • Show All 544 Lines • ▼ Show 20 Lines | ice_for_each_traffic_class(tc) { | ||||
status = ice_sched_validate_srl_node(vsi_node, sel_layer); | status = ice_sched_validate_srl_node(vsi_node, sel_layer); | ||||
if (status) | if (status) | ||||
return status; | return status; | ||||
} | } | ||||
return ICE_SUCCESS; | return ICE_SUCCESS; | ||||
} | } | ||||
/** | /** | ||||
* ice_sched_set_save_vsi_srl_node_bw - set VSI shared limit values | |||||
* @pi: port information structure | |||||
* @vsi_handle: software VSI handle | |||||
* @tc: traffic class | |||||
* @srl_node: sched node to configure | |||||
* @rl_type: rate limit type minimum, maximum, or shared | |||||
* @bw: minimum, maximum, or shared bandwidth in Kbps | |||||
* | |||||
* Configure shared rate limiter(SRL) of VSI type nodes across given traffic | |||||
* class, and saves those value for later use for replaying purposes. The | |||||
* caller holds the scheduler lock. | |||||
*/ | |||||
static enum ice_status | |||||
ice_sched_set_save_vsi_srl_node_bw(struct ice_port_info *pi, u16 vsi_handle, | |||||
u8 tc, struct ice_sched_node *srl_node, | |||||
enum ice_rl_type rl_type, u32 bw) | |||||
{ | |||||
enum ice_status status; | |||||
if (bw == ICE_SCHED_DFLT_BW) { | |||||
status = ice_sched_set_node_bw_dflt_lmt(pi, srl_node, rl_type); | |||||
} else { | |||||
status = ice_sched_set_node_bw_lmt(pi, srl_node, rl_type, bw); | |||||
if (status) | |||||
return status; | |||||
status = ice_sched_save_vsi_bw(pi, vsi_handle, tc, rl_type, bw); | |||||
} | |||||
return status; | |||||
} | |||||
/** | |||||
* ice_sched_set_vsi_node_srl_per_tc - set VSI node BW shared limit for tc | |||||
* @pi: port information structure | |||||
* @vsi_handle: software VSI handle | |||||
* @tc: traffic class | |||||
* @min_bw: minimum bandwidth in Kbps | |||||
* @max_bw: maximum bandwidth in Kbps | |||||
* @shared_bw: shared bandwidth in Kbps | |||||
* | |||||
* Configure shared rate limiter(SRL) of VSI type nodes across requested | |||||
* traffic class for VSI matching handle. When BW value of ICE_SCHED_DFLT_BW | |||||
* is passed, it removes the corresponding bw from the node. The caller | |||||
* holds scheduler lock. | |||||
*/ | |||||
static enum ice_status | |||||
ice_sched_set_vsi_node_srl_per_tc(struct ice_port_info *pi, u16 vsi_handle, | |||||
u8 tc, u32 min_bw, u32 max_bw, u32 shared_bw) | |||||
{ | |||||
struct ice_sched_node *tc_node, *vsi_node, *cfg_node; | |||||
enum ice_status status; | |||||
u8 layer_num; | |||||
tc_node = ice_sched_get_tc_node(pi, tc); | |||||
if (!tc_node) | |||||
return ICE_ERR_CFG; | |||||
vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle); | |||||
if (!vsi_node) | |||||
return ICE_ERR_CFG; | |||||
layer_num = ice_sched_get_rl_prof_layer(pi, ICE_SHARED_BW, | |||||
vsi_node->tx_sched_layer); | |||||
if (layer_num >= pi->hw->num_tx_sched_layers) | |||||
return ICE_ERR_PARAM; | |||||
/* SRL node may be different */ | |||||
cfg_node = ice_sched_get_srl_node(vsi_node, layer_num); | |||||
if (!cfg_node) | |||||
return ICE_ERR_CFG; | |||||
status = ice_sched_set_save_vsi_srl_node_bw(pi, vsi_handle, tc, | |||||
cfg_node, ICE_MIN_BW, | |||||
min_bw); | |||||
if (status) | |||||
return status; | |||||
status = ice_sched_set_save_vsi_srl_node_bw(pi, vsi_handle, tc, | |||||
cfg_node, ICE_MAX_BW, | |||||
max_bw); | |||||
if (status) | |||||
return status; | |||||
return ice_sched_set_save_vsi_srl_node_bw(pi, vsi_handle, tc, cfg_node, | |||||
ICE_SHARED_BW, shared_bw); | |||||
} | |||||
/** | |||||
* ice_sched_set_vsi_bw_shared_lmt - set VSI BW shared limit | * ice_sched_set_vsi_bw_shared_lmt - set VSI BW shared limit | ||||
* @pi: port information structure | * @pi: port information structure | ||||
* @vsi_handle: software VSI handle | * @vsi_handle: software VSI handle | ||||
* @bw: bandwidth in Kbps | * @min_bw: minimum bandwidth in Kbps | ||||
* @max_bw: maximum bandwidth in Kbps | |||||
* @shared_bw: shared bandwidth in Kbps | |||||
* | * | ||||
* This function Configures shared rate limiter(SRL) of all VSI type nodes | * Configure shared rate limiter(SRL) of all VSI type nodes across all traffic | ||||
* across all traffic classes for VSI matching handle. When BW value of | * classes for VSI matching handle. When BW value of ICE_SCHED_DFLT_BW is | ||||
* ICE_SCHED_DFLT_BW is passed, it removes the SRL from the node. | * passed, it removes those value(s) from the node. | ||||
*/ | */ | ||||
enum ice_status | enum ice_status | ||||
ice_sched_set_vsi_bw_shared_lmt(struct ice_port_info *pi, u16 vsi_handle, | ice_sched_set_vsi_bw_shared_lmt(struct ice_port_info *pi, u16 vsi_handle, | ||||
u32 bw) | u32 min_bw, u32 max_bw, u32 shared_bw) | ||||
{ | { | ||||
enum ice_status status = ICE_SUCCESS; | enum ice_status status = ICE_SUCCESS; | ||||
u8 tc; | u8 tc; | ||||
if (!pi) | if (!pi) | ||||
return ICE_ERR_PARAM; | return ICE_ERR_PARAM; | ||||
if (!ice_is_vsi_valid(pi->hw, vsi_handle)) | if (!ice_is_vsi_valid(pi->hw, vsi_handle)) | ||||
return ICE_ERR_PARAM; | return ICE_ERR_PARAM; | ||||
ice_acquire_lock(&pi->sched_lock); | ice_acquire_lock(&pi->sched_lock); | ||||
status = ice_sched_validate_vsi_srl_node(pi, vsi_handle); | status = ice_sched_validate_vsi_srl_node(pi, vsi_handle); | ||||
if (status) | if (status) | ||||
goto exit_set_vsi_bw_shared_lmt; | goto exit_set_vsi_bw_shared_lmt; | ||||
/* Return success if no nodes are present across TC */ | /* Return success if no nodes are present across TC */ | ||||
ice_for_each_traffic_class(tc) { | ice_for_each_traffic_class(tc) { | ||||
struct ice_sched_node *tc_node, *vsi_node; | struct ice_sched_node *tc_node, *vsi_node; | ||||
enum ice_rl_type rl_type = ICE_SHARED_BW; | |||||
tc_node = ice_sched_get_tc_node(pi, tc); | tc_node = ice_sched_get_tc_node(pi, tc); | ||||
if (!tc_node) | if (!tc_node) | ||||
continue; | continue; | ||||
vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle); | vsi_node = ice_sched_get_vsi_node(pi, tc_node, vsi_handle); | ||||
if (!vsi_node) | if (!vsi_node) | ||||
continue; | continue; | ||||
if (bw == ICE_SCHED_DFLT_BW) | status = ice_sched_set_vsi_node_srl_per_tc(pi, vsi_handle, tc, | ||||
/* It removes existing SRL from the node */ | min_bw, max_bw, | ||||
status = ice_sched_set_node_bw_dflt_lmt(pi, vsi_node, | shared_bw); | ||||
rl_type); | |||||
else | |||||
status = ice_sched_set_node_bw_lmt(pi, vsi_node, | |||||
rl_type, bw); | |||||
if (status) | if (status) | ||||
break; | break; | ||||
status = ice_sched_save_vsi_bw(pi, vsi_handle, tc, rl_type, bw); | |||||
if (status) | |||||
break; | |||||
} | } | ||||
exit_set_vsi_bw_shared_lmt: | exit_set_vsi_bw_shared_lmt: | ||||
ice_release_lock(&pi->sched_lock); | ice_release_lock(&pi->sched_lock); | ||||
return status; | return status; | ||||
} | } | ||||
/** | /** | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | ice_for_each_traffic_class(tc) { | ||||
status = ice_sched_validate_srl_node(agg_node, sel_layer); | status = ice_sched_validate_srl_node(agg_node, sel_layer); | ||||
if (status) | if (status) | ||||
break; | break; | ||||
} | } | ||||
return status; | return status; | ||||
} | } | ||||
/** | /** | ||||
* ice_sched_set_agg_bw_shared_lmt - set aggregator BW shared limit | * ice_sched_validate_agg_id - Validate aggregator id | ||||
* @pi: port information structure | * @pi: port information structure | ||||
* @agg_id: aggregator ID | * @agg_id: aggregator ID | ||||
* @bw: bandwidth in Kbps | |||||
* | * | ||||
* This function configures the shared rate limiter(SRL) of all aggregator type | * This function validates aggregator id. Caller holds the scheduler lock. | ||||
* nodes across all traffic classes for aggregator matching agg_id. When | |||||
* BW value of ICE_SCHED_DFLT_BW is passed, it removes SRL from the | |||||
* node(s). | |||||
*/ | */ | ||||
enum ice_status | static enum ice_status | ||||
ice_sched_set_agg_bw_shared_lmt(struct ice_port_info *pi, u32 agg_id, u32 bw) | ice_sched_validate_agg_id(struct ice_port_info *pi, u32 agg_id) | ||||
{ | { | ||||
struct ice_sched_agg_info *agg_info; | struct ice_sched_agg_info *agg_info; | ||||
struct ice_sched_agg_info *tmp; | struct ice_sched_agg_info *tmp; | ||||
bool agg_id_present = false; | bool agg_id_present = false; | ||||
enum ice_status status = ICE_SUCCESS; | enum ice_status status; | ||||
u8 tc; | |||||
if (!pi) | |||||
return ICE_ERR_PARAM; | |||||
ice_acquire_lock(&pi->sched_lock); | |||||
status = ice_sched_validate_agg_srl_node(pi, agg_id); | status = ice_sched_validate_agg_srl_node(pi, agg_id); | ||||
if (status) | if (status) | ||||
goto exit_agg_bw_shared_lmt; | return status; | ||||
LIST_FOR_EACH_ENTRY_SAFE(agg_info, tmp, &pi->hw->agg_list, | LIST_FOR_EACH_ENTRY_SAFE(agg_info, tmp, &pi->hw->agg_list, | ||||
ice_sched_agg_info, list_entry) | ice_sched_agg_info, list_entry) | ||||
if (agg_info->agg_id == agg_id) { | if (agg_info->agg_id == agg_id) { | ||||
agg_id_present = true; | agg_id_present = true; | ||||
break; | break; | ||||
} | } | ||||
if (!agg_id_present) { | if (!agg_id_present) | ||||
status = ICE_ERR_PARAM; | return ICE_ERR_PARAM; | ||||
goto exit_agg_bw_shared_lmt; | |||||
return ICE_SUCCESS; | |||||
} | } | ||||
/** | |||||
* ice_sched_set_save_agg_srl_node_bw - set aggregator shared limit values | |||||
* @pi: port information structure | |||||
* @agg_id: aggregator ID | |||||
* @tc: traffic class | |||||
* @srl_node: sched node to configure | |||||
* @rl_type: rate limit type minimum, maximum, or shared | |||||
* @bw: minimum, maximum, or shared bandwidth in Kbps | |||||
* | |||||
* Configure shared rate limiter(SRL) of aggregator type nodes across | |||||
* requested traffic class, and saves those value for later use for | |||||
* replaying purposes. The caller holds the scheduler lock. | |||||
*/ | |||||
static enum ice_status | |||||
ice_sched_set_save_agg_srl_node_bw(struct ice_port_info *pi, u32 agg_id, u8 tc, | |||||
struct ice_sched_node *srl_node, | |||||
enum ice_rl_type rl_type, u32 bw) | |||||
{ | |||||
enum ice_status status; | |||||
if (bw == ICE_SCHED_DFLT_BW) { | |||||
status = ice_sched_set_node_bw_dflt_lmt(pi, srl_node, rl_type); | |||||
} else { | |||||
status = ice_sched_set_node_bw_lmt(pi, srl_node, rl_type, bw); | |||||
if (status) | |||||
return status; | |||||
status = ice_sched_save_agg_bw(pi, agg_id, tc, rl_type, bw); | |||||
} | |||||
return status; | |||||
} | |||||
/** | |||||
* ice_sched_set_agg_node_srl_per_tc - set aggregator SRL per tc | |||||
* @pi: port information structure | |||||
* @agg_id: aggregator ID | |||||
* @tc: traffic class | |||||
* @min_bw: minimum bandwidth in Kbps | |||||
* @max_bw: maximum bandwidth in Kbps | |||||
* @shared_bw: shared bandwidth in Kbps | |||||
* | |||||
* This function configures the shared rate limiter(SRL) of aggregator type | |||||
* node for a given traffic class for aggregator matching agg_id. When BW | |||||
* value of ICE_SCHED_DFLT_BW is passed, it removes SRL from the node. Caller | |||||
* holds the scheduler lock. | |||||
*/ | |||||
static enum ice_status | |||||
ice_sched_set_agg_node_srl_per_tc(struct ice_port_info *pi, u32 agg_id, | |||||
u8 tc, u32 min_bw, u32 max_bw, u32 shared_bw) | |||||
{ | |||||
struct ice_sched_node *tc_node, *agg_node, *cfg_node; | |||||
enum ice_rl_type rl_type = ICE_SHARED_BW; | |||||
enum ice_status status = ICE_ERR_CFG; | |||||
u8 layer_num; | |||||
tc_node = ice_sched_get_tc_node(pi, tc); | |||||
if (!tc_node) | |||||
return ICE_ERR_CFG; | |||||
agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id); | |||||
if (!agg_node) | |||||
return ICE_ERR_CFG; | |||||
layer_num = ice_sched_get_rl_prof_layer(pi, rl_type, | |||||
agg_node->tx_sched_layer); | |||||
if (layer_num >= pi->hw->num_tx_sched_layers) | |||||
return ICE_ERR_PARAM; | |||||
/* SRL node may be different */ | |||||
cfg_node = ice_sched_get_srl_node(agg_node, layer_num); | |||||
if (!cfg_node) | |||||
return ICE_ERR_CFG; | |||||
status = ice_sched_set_save_agg_srl_node_bw(pi, agg_id, tc, cfg_node, | |||||
ICE_MIN_BW, min_bw); | |||||
if (status) | |||||
return status; | |||||
status = ice_sched_set_save_agg_srl_node_bw(pi, agg_id, tc, cfg_node, | |||||
ICE_MAX_BW, max_bw); | |||||
if (status) | |||||
return status; | |||||
status = ice_sched_set_save_agg_srl_node_bw(pi, agg_id, tc, cfg_node, | |||||
ICE_SHARED_BW, shared_bw); | |||||
return status; | |||||
} | |||||
/** | |||||
* ice_sched_set_agg_bw_shared_lmt - set aggregator BW shared limit | |||||
* @pi: port information structure | |||||
* @agg_id: aggregator ID | |||||
* @min_bw: minimum bandwidth in Kbps | |||||
* @max_bw: maximum bandwidth in Kbps | |||||
* @shared_bw: shared bandwidth in Kbps | |||||
* | |||||
* This function configures the shared rate limiter(SRL) of all aggregator type | |||||
* nodes across all traffic classes for aggregator matching agg_id. When | |||||
* BW value of ICE_SCHED_DFLT_BW is passed, it removes SRL from the | |||||
* node(s). | |||||
*/ | |||||
enum ice_status | |||||
ice_sched_set_agg_bw_shared_lmt(struct ice_port_info *pi, u32 agg_id, | |||||
u32 min_bw, u32 max_bw, u32 shared_bw) | |||||
{ | |||||
enum ice_status status; | |||||
u8 tc; | |||||
if (!pi) | |||||
return ICE_ERR_PARAM; | |||||
ice_acquire_lock(&pi->sched_lock); | |||||
status = ice_sched_validate_agg_id(pi, agg_id); | |||||
if (status) | |||||
goto exit_agg_bw_shared_lmt; | |||||
/* Return success if no nodes are present across TC */ | /* Return success if no nodes are present across TC */ | ||||
ice_for_each_traffic_class(tc) { | ice_for_each_traffic_class(tc) { | ||||
enum ice_rl_type rl_type = ICE_SHARED_BW; | |||||
struct ice_sched_node *tc_node, *agg_node; | struct ice_sched_node *tc_node, *agg_node; | ||||
tc_node = ice_sched_get_tc_node(pi, tc); | tc_node = ice_sched_get_tc_node(pi, tc); | ||||
if (!tc_node) | if (!tc_node) | ||||
continue; | continue; | ||||
agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id); | agg_node = ice_sched_get_agg_node(pi, tc_node, agg_id); | ||||
if (!agg_node) | if (!agg_node) | ||||
continue; | continue; | ||||
if (bw == ICE_SCHED_DFLT_BW) | status = ice_sched_set_agg_node_srl_per_tc(pi, agg_id, tc, | ||||
/* It removes existing SRL from the node */ | min_bw, max_bw, | ||||
status = ice_sched_set_node_bw_dflt_lmt(pi, agg_node, | shared_bw); | ||||
rl_type); | |||||
else | |||||
status = ice_sched_set_node_bw_lmt(pi, agg_node, | |||||
rl_type, bw); | |||||
if (status) | if (status) | ||||
break; | break; | ||||
status = ice_sched_save_agg_bw(pi, agg_id, tc, rl_type, bw); | |||||
if (status) | |||||
break; | |||||
} | } | ||||
exit_agg_bw_shared_lmt: | exit_agg_bw_shared_lmt: | ||||
ice_release_lock(&pi->sched_lock); | |||||
return status; | |||||
} | |||||
/** | |||||
* ice_sched_set_agg_bw_shared_lmt_per_tc - set aggregator BW shared lmt per tc | |||||
* @pi: port information structure | |||||
* @agg_id: aggregator ID | |||||
* @tc: traffic class | |||||
* @min_bw: minimum bandwidth in Kbps | |||||
* @max_bw: maximum bandwidth in Kbps | |||||
* @shared_bw: shared bandwidth in Kbps | |||||
* | |||||
* This function configures the shared rate limiter(SRL) of aggregator type | |||||
* node for a given traffic class for aggregator matching agg_id. When BW | |||||
* value of ICE_SCHED_DFLT_BW is passed, it removes SRL from the node. | |||||
*/ | |||||
enum ice_status | |||||
ice_sched_set_agg_bw_shared_lmt_per_tc(struct ice_port_info *pi, u32 agg_id, | |||||
u8 tc, u32 min_bw, u32 max_bw, | |||||
u32 shared_bw) | |||||
{ | |||||
enum ice_status status; | |||||
if (!pi) | |||||
return ICE_ERR_PARAM; | |||||
ice_acquire_lock(&pi->sched_lock); | |||||
status = ice_sched_validate_agg_id(pi, agg_id); | |||||
if (status) | |||||
goto exit_agg_bw_shared_lmt_per_tc; | |||||
status = ice_sched_set_agg_node_srl_per_tc(pi, agg_id, tc, min_bw, | |||||
max_bw, shared_bw); | |||||
exit_agg_bw_shared_lmt_per_tc: | |||||
ice_release_lock(&pi->sched_lock); | ice_release_lock(&pi->sched_lock); | ||||
return status; | return status; | ||||
} | } | ||||
/** | /** | ||||
* ice_sched_cfg_sibl_node_prio - configure node sibling priority | * ice_sched_cfg_sibl_node_prio - configure node sibling priority | ||||
* @pi: port information structure | * @pi: port information structure | ||||
* @node: sched node to configure | * @node: sched node to configure | ||||
▲ Show 20 Lines • Show All 470 Lines • Show Last 20 Lines |