Commit 5513b920 authored by Anirudh Venkataramanan's avatar Anirudh Venkataramanan Committed by Jeff Kirsher

ice: Update Tx scheduler tree for VSI multi-Tx queue support

This patch adds the ability for a VSI to use multiple Tx queues. More
specifically, the patch
    1) Provides the ability to update the Tx scheduler tree in the
       firmware. The driver can configure the Tx scheduler tree by
       adding/removing multiple Tx queues per TC per VSI.

    2) Allows a VSI to reconfigure its Tx queues during runtime.

    3) Synchronizes the Tx scheduler update operations using locks.
Signed-off-by: default avatarAnirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: default avatarTony Brelinski <tonyx.brelinski@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent fcea6f3d
......@@ -42,6 +42,7 @@ extern const char ice_drv_ver[];
#define ICE_MIN_NUM_DESC 8
#define ICE_MAX_NUM_DESC 8160
#define ICE_REQ_DESC_MULTIPLE 32
#define ICE_DFLT_TRAFFIC_CLASS BIT(0)
#define ICE_INT_NAME_STR_LEN (IFNAMSIZ + 16)
#define ICE_ETHTOOL_FWVER_LEN 32
#define ICE_AQ_LEN 64
......@@ -261,6 +262,12 @@ static inline void ice_irq_dynamic_ena(struct ice_hw *hw, struct ice_vsi *vsi,
wr32(hw, GLINT_DYN_CTL(vector), val);
}
static inline void ice_vsi_set_tc_cfg(struct ice_vsi *vsi)
{
vsi->tc_cfg.ena_tc = ICE_DFLT_TRAFFIC_CLASS;
vsi->tc_cfg.numtc = 1;
}
void ice_set_ethtool_ops(struct net_device *netdev);
int ice_up(struct ice_vsi *vsi);
int ice_down(struct ice_vsi *vsi);
......
......@@ -631,6 +631,25 @@ struct ice_aqc_get_topo {
__le32 addr_low;
};
/* Update TSE (indirect 0x0403)
* Get TSE (indirect 0x0404)
*/
struct ice_aqc_get_cfg_elem {
__le16 num_elem_req; /* Used by commands */
__le16 num_elem_resp; /* Used by responses */
__le32 reserved;
__le32 addr_high;
__le32 addr_low;
};
/* This is the buffer for:
* Suspend Nodes (indirect 0x0409)
* Resume Nodes (indirect 0x040A)
*/
struct ice_aqc_suspend_resume_elem {
__le32 teid[1];
};
/* Add TSE (indirect 0x0401)
* Delete TSE (indirect 0x040F)
* Move TSE (indirect 0x0408)
......@@ -691,6 +710,11 @@ struct ice_aqc_txsched_topo_grp_info_hdr {
__le16 reserved2;
};
struct ice_aqc_add_elem {
struct ice_aqc_txsched_topo_grp_info_hdr hdr;
struct ice_aqc_txsched_elem_data generic[1];
};
struct ice_aqc_get_topo_elem {
struct ice_aqc_txsched_topo_grp_info_hdr hdr;
struct ice_aqc_txsched_elem_data
......@@ -1181,6 +1205,7 @@ struct ice_aq_desc {
struct ice_aqc_get_sw_cfg get_sw_conf;
struct ice_aqc_sw_rules sw_rules;
struct ice_aqc_get_topo get_topo;
struct ice_aqc_get_cfg_elem get_update_elem;
struct ice_aqc_query_txsched_res query_sched_res;
struct ice_aqc_add_move_delete_elem add_move_delete_elem;
struct ice_aqc_nvm nvm;
......@@ -1258,6 +1283,9 @@ enum ice_adminq_opc {
/* transmit scheduler commands */
ice_aqc_opc_get_dflt_topo = 0x0400,
ice_aqc_opc_add_sched_elems = 0x0401,
ice_aqc_opc_suspend_sched_elems = 0x0409,
ice_aqc_opc_resume_sched_elems = 0x040A,
ice_aqc_opc_delete_sched_elems = 0x040F,
ice_aqc_opc_query_sched_res = 0x0412,
......
......@@ -2089,3 +2089,57 @@ ice_dis_vsi_txq(struct ice_port_info *pi, u8 num_queues, u16 *q_ids,
mutex_unlock(&pi->sched_lock);
return status;
}
/**
* ice_cfg_vsi_qs - configure the new/exisiting VSI queues
* @pi: port information structure
* @vsi_id: VSI Id
* @tc_bitmap: TC bitmap
* @maxqs: max queues array per TC
* @owner: lan or rdma
*
* This function adds/updates the VSI queues per TC.
*/
static enum ice_status
ice_cfg_vsi_qs(struct ice_port_info *pi, u16 vsi_id, u8 tc_bitmap,
u16 *maxqs, u8 owner)
{
enum ice_status status = 0;
u8 i;
if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY)
return ICE_ERR_CFG;
mutex_lock(&pi->sched_lock);
for (i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++) {
/* configuration is possible only if TC node is present */
if (!ice_sched_get_tc_node(pi, i))
continue;
status = ice_sched_cfg_vsi(pi, vsi_id, i, maxqs[i], owner,
ice_is_tc_ena(tc_bitmap, i));
if (status)
break;
}
mutex_unlock(&pi->sched_lock);
return status;
}
/**
* ice_cfg_vsi_lan - configure VSI lan queues
* @pi: port information structure
* @vsi_id: VSI Id
* @tc_bitmap: TC bitmap
* @max_lanqs: max lan queues array per TC
*
* This function adds/updates the VSI lan queues per TC.
*/
enum ice_status
ice_cfg_vsi_lan(struct ice_port_info *pi, u16 vsi_id, u8 tc_bitmap,
u16 *max_lanqs)
{
return ice_cfg_vsi_qs(pi, vsi_id, tc_bitmap, max_lanqs,
ICE_SCHED_NODE_OWNER_LAN);
}
......@@ -69,6 +69,9 @@ enum ice_status
ice_dis_vsi_txq(struct ice_port_info *pi, u8 num_queues, u16 *q_ids,
u32 *q_teids, struct ice_sq_cd *cmd_details);
enum ice_status
ice_cfg_vsi_lan(struct ice_port_info *pi, u16 vsi_id, u8 tc_bitmap,
u16 *max_lanqs);
enum ice_status
ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_id, u8 tc, u8 num_qgrps,
struct ice_aqc_add_tx_qgrp *buf, u16 buf_size,
struct ice_sq_cd *cd);
......
......@@ -2085,10 +2085,11 @@ static struct ice_vsi *
ice_vsi_setup(struct ice_pf *pf, enum ice_vsi_type type,
struct ice_port_info *pi)
{
u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };
struct device *dev = &pf->pdev->dev;
struct ice_vsi_ctx ctxt = { 0 };
struct ice_vsi *vsi;
int ret;
int ret, i;
vsi = ice_vsi_alloc(pf, type);
if (!vsi) {
......@@ -2156,6 +2157,20 @@ ice_vsi_setup(struct ice_pf *pf, enum ice_vsi_type type,
*/
goto err_rings;
}
ice_vsi_set_tc_cfg(vsi);
/* configure VSI nodes based on number of queues and TC's */
for (i = 0; i < vsi->tc_cfg.numtc; i++)
max_txqs[i] = vsi->num_txq;
ret = ice_cfg_vsi_lan(vsi->port_info, vsi->vsi_num,
vsi->tc_cfg.ena_tc, max_txqs);
if (ret) {
dev_info(&pf->pdev->dev, "Failed VSI lan queue config\n");
goto err_rings;
}
return vsi;
err_rings:
......@@ -2398,8 +2413,7 @@ static void ice_determine_q_usage(struct ice_pf *pf)
q_left_tx = pf->hw.func_caps.common_cap.num_txq;
q_left_rx = pf->hw.func_caps.common_cap.num_rxq;
/* initial support for only 1 tx queue */
pf->num_lan_tx = 1;
pf->num_lan_tx = min_t(int, q_left_tx, num_online_cpus());
/* only 1 rx queue unless RSS is enabled */
if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags))
......
This diff is collapsed.
......@@ -7,6 +7,7 @@
#include "ice_common.h"
#define ICE_QGRP_LAYER_OFFSET 2
#define ICE_VSI_LAYER_OFFSET 4
struct ice_sched_agg_vsi_info {
struct list_head list_entry;
......@@ -36,4 +37,7 @@ struct ice_sched_node *ice_sched_get_tc_node(struct ice_port_info *pi, u8 tc);
struct ice_sched_node *
ice_sched_get_free_qparent(struct ice_port_info *pi, u16 vsi_id, u8 tc,
u8 owner);
enum ice_status
ice_sched_cfg_vsi(struct ice_port_info *pi, u16 vsi_id, u8 tc, u16 maxqs,
u8 owner, bool enable);
#endif /* _ICE_SCHED_H_ */
......@@ -10,6 +10,11 @@
#include "ice_controlq.h"
#include "ice_lan_tx_rx.h"
static inline bool ice_is_tc_ena(u8 bitmap, u8 tc)
{
return test_bit(tc, (unsigned long *)&bitmap);
}
/* debug masks - set these bits in hw->debug_mask to control output */
#define ICE_DBG_INIT BIT_ULL(1)
#define ICE_DBG_QCTX BIT_ULL(6)
......@@ -194,6 +199,8 @@ enum ice_agg_type {
ICE_AGG_TYPE_QG
};
#define ICE_SCHED_DFLT_RL_PROF_ID 0
/* vsi type list entry to locate corresponding vsi/ag nodes */
struct ice_sched_vsi_info {
struct ice_sched_node *vsi_node[ICE_MAX_TRAFFIC_CLASS];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment