Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f38b3766 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'qed-QM-ILT-changes'



Yuval Mintz says:

====================
qed: QM & ILT changes

This series introduces several changes and improvements to existing
queue manager and ILT configurations done during initialization.
Notice some of the patches are actually future fixes, I.e., bugs that
can't be triggered with exisiting driver but are needed for some future
functionality.

Patch #1 refactors the configuration of the hardware's queue manager,
which is quite messy today. This contains most of the bulk [code-wise]
in the series.

Patch #2, #3 fix Timers related ILT configurations that are yet to
affect qed in existing scenarios.

Patch #4 reduces needless ILT lines wasted for RoCE configurations.

Patch #5 allows RoCE partitions to manage with less memory regions
[important, e.g., for Multi-function parititions with RoCE support].
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c8b5d129 f9dc4d1f
Loading
Loading
Loading
Loading
+35 −8
Original line number Diff line number Diff line
@@ -271,9 +271,14 @@ struct qed_hw_info {
				 RESC_NUM(_p_hwfn, resc))
#define FEAT_NUM(_p_hwfn, resc) ((_p_hwfn)->hw_info.feat_num[resc])

	u8				num_tc;
	/* Amount of traffic classes HW supports */
	u8 num_hw_tc;

	/* Amount of TCs which should be active according to DCBx or upper
	 * layer driver configuration.
	 */
	u8 num_active_tc;
	u8				offload_tc;
	u8				non_offload_tc;

	u32				concrete_fid;
	u16				opaque_fid;
@@ -336,15 +341,19 @@ struct qed_qm_info {
	struct init_qm_port_params	*qm_port_params;
	u16				start_pq;
	u8				start_vport;
	u8				pure_lb_pq;
	u8				offload_pq;
	u8				pure_ack_pq;
	u8 ooo_pq;
	u8				vf_queues_offset;
	u16				 pure_lb_pq;
	u16				offload_pq;
	u16				low_latency_pq;
	u16				pure_ack_pq;
	u16				ooo_pq;
	u16				first_vf_pq;
	u16				first_mcos_pq;
	u16				first_rl_pq;
	u16				num_pqs;
	u16				num_vf_pqs;
	u8				num_vports;
	u8				max_phys_tcs_per_port;
	u8				ooo_tc;
	bool				pf_rl_en;
	bool				pf_wfq_en;
	bool				vport_rl_en;
@@ -729,9 +738,27 @@ void qed_configure_vp_wfq_on_link_change(struct qed_dev *cdev,
					 u32 min_pf_rate);

void qed_clean_wfq_db(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
#define QED_LEADING_HWFN(dev)   (&dev->hwfns[0])
int qed_device_num_engines(struct qed_dev *cdev);

#define QED_LEADING_HWFN(dev)   (&dev->hwfns[0])

/* Flags for indication of required queues */
#define PQ_FLAGS_RLS    (BIT(0))
#define PQ_FLAGS_MCOS   (BIT(1))
#define PQ_FLAGS_LB     (BIT(2))
#define PQ_FLAGS_OOO    (BIT(3))
#define PQ_FLAGS_ACK    (BIT(4))
#define PQ_FLAGS_OFLD   (BIT(5))
#define PQ_FLAGS_VFS    (BIT(6))
#define PQ_FLAGS_LLT    (BIT(7))

/* physical queue index for cm context intialization */
u16 qed_get_cm_pq_idx(struct qed_hwfn *p_hwfn, u32 pq_flags);
u16 qed_get_cm_pq_idx_mcos(struct qed_hwfn *p_hwfn, u8 tc);
u16 qed_get_cm_pq_idx_vf(struct qed_hwfn *p_hwfn, u16 vf);

#define QED_LEADING_HWFN(dev)   (&dev->hwfns[0])

/* Other Linux specific common definitions */
#define DP_NAME(cdev) ((cdev)->name)

+114 −49
Original line number Diff line number Diff line
@@ -241,8 +241,7 @@ struct qed_cxt_mngr {
static bool src_proto(enum protocol_type type)
{
	return type == PROTOCOLID_ISCSI ||
	       type == PROTOCOLID_FCOE ||
	       type == PROTOCOLID_ROCE;
	       type == PROTOCOLID_FCOE;
}

static bool tm_cid_proto(enum protocol_type type)
@@ -303,16 +302,34 @@ struct qed_tm_iids {
	u32 per_vf_tids;
};

static void qed_cxt_tm_iids(struct qed_cxt_mngr *p_mngr,
static void qed_cxt_tm_iids(struct qed_hwfn *p_hwfn,
			    struct qed_cxt_mngr *p_mngr,
			    struct qed_tm_iids *iids)
{
	u32 i, j;

	for (i = 0; i < MAX_CONN_TYPES; i++) {
	bool tm_vf_required = false;
	bool tm_required = false;
	int i, j;

	/* Timers is a special case -> we don't count how many cids require
	 * timers but what's the max cid that will be used by the timer block.
	 * therefore we traverse in reverse order, and once we hit a protocol
	 * that requires the timers memory, we'll sum all the protocols up
	 * to that one.
	 */
	for (i = MAX_CONN_TYPES - 1; i >= 0; i--) {
		struct qed_conn_type_cfg *p_cfg = &p_mngr->conn_cfg[i];

		if (tm_cid_proto(i)) {
		if (tm_cid_proto(i) || tm_required) {
			if (p_cfg->cid_count)
				tm_required = true;

			iids->pf_cids += p_cfg->cid_count;
		}

		if (tm_cid_proto(i) || tm_vf_required) {
			if (p_cfg->cids_per_vf)
				tm_vf_required = true;

			iids->per_vf_cids += p_cfg->cids_per_vf;
		}

@@ -526,7 +543,22 @@ static u32 qed_ilt_get_dynamic_line_cnt(struct qed_hwfn *p_hwfn,
	return lines_to_skip;
}

int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn)
static struct qed_ilt_client_cfg *qed_cxt_set_cli(struct qed_ilt_client_cfg
						  *p_cli)
{
	p_cli->active = false;
	p_cli->first.val = 0;
	p_cli->last.val = 0;
	return p_cli;
}

static struct qed_ilt_cli_blk *qed_cxt_set_blk(struct qed_ilt_cli_blk *p_blk)
{
	p_blk->total_size = 0;
	return p_blk;
}

int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn, u32 *line_count)
{
	struct qed_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
	u32 curr_line, total, i, task_size, line;
@@ -550,7 +582,8 @@ int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn)
		   p_hwfn->my_id, p_hwfn->p_cxt_mngr->pf_start_line);

	/* CDUC */
	p_cli = &p_mngr->clients[ILT_CLI_CDUC];
	p_cli = qed_cxt_set_cli(&p_mngr->clients[ILT_CLI_CDUC]);

	curr_line = p_mngr->pf_start_line;

	/* CDUC PF */
@@ -559,7 +592,7 @@ int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn)
	/* get the counters for the CDUC and QM clients  */
	qed_cxt_cdu_iids(p_mngr, &cdu_iids);

	p_blk = &p_cli->pf_blks[CDUC_BLK];
	p_blk = qed_cxt_set_blk(&p_cli->pf_blks[CDUC_BLK]);

	total = cdu_iids.pf_cids * CONN_CXT_SIZE(p_hwfn);

@@ -573,7 +606,7 @@ int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn)
							       ILT_CLI_CDUC);

	/* CDUC VF */
	p_blk = &p_cli->vf_blks[CDUC_BLK];
	p_blk = qed_cxt_set_blk(&p_cli->vf_blks[CDUC_BLK]);
	total = cdu_iids.per_vf_cids * CONN_CXT_SIZE(p_hwfn);

	qed_ilt_cli_blk_fill(p_cli, p_blk, curr_line,
@@ -587,7 +620,7 @@ int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn)
				     ILT_CLI_CDUC);

	/* CDUT PF */
	p_cli = &p_mngr->clients[ILT_CLI_CDUT];
	p_cli = qed_cxt_set_cli(&p_mngr->clients[ILT_CLI_CDUT]);
	p_cli->first.val = curr_line;

	/* first the 'working' task memory */
@@ -596,7 +629,7 @@ int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn)
		if (!p_seg || p_seg->count == 0)
			continue;

		p_blk = &p_cli->pf_blks[CDUT_SEG_BLK(i)];
		p_blk = qed_cxt_set_blk(&p_cli->pf_blks[CDUT_SEG_BLK(i)]);
		total = p_seg->count * p_mngr->task_type_size[p_seg->type];
		qed_ilt_cli_blk_fill(p_cli, p_blk, curr_line, total,
				     p_mngr->task_type_size[p_seg->type]);
@@ -611,7 +644,8 @@ int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn)
		if (!p_seg || p_seg->count == 0)
			continue;

		p_blk = &p_cli->pf_blks[CDUT_FL_SEG_BLK(i, PF)];
		p_blk =
		    qed_cxt_set_blk(&p_cli->pf_blks[CDUT_FL_SEG_BLK(i, PF)]);

		if (!p_seg->has_fl_mem) {
			/* The segment is active (total size pf 'working'
@@ -656,7 +690,7 @@ int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn)
		/* 'working' memory */
		total = p_seg->count * p_mngr->task_type_size[p_seg->type];

		p_blk = &p_cli->vf_blks[CDUT_SEG_BLK(0)];
		p_blk = qed_cxt_set_blk(&p_cli->vf_blks[CDUT_SEG_BLK(0)]);
		qed_ilt_cli_blk_fill(p_cli, p_blk,
				     curr_line, total,
				     p_mngr->task_type_size[p_seg->type]);
@@ -665,7 +699,8 @@ int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn)
				     ILT_CLI_CDUT);

		/* 'init' memory */
		p_blk = &p_cli->vf_blks[CDUT_FL_SEG_BLK(0, VF)];
		p_blk =
		    qed_cxt_set_blk(&p_cli->vf_blks[CDUT_FL_SEG_BLK(0, VF)]);
		if (!p_seg->has_fl_mem) {
			/* see comment above */
			line = p_cli->vf_blks[CDUT_SEG_BLK(0)].start_line;
@@ -693,8 +728,8 @@ int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn)
	}

	/* QM */
	p_cli = &p_mngr->clients[ILT_CLI_QM];
	p_blk = &p_cli->pf_blks[0];
	p_cli = qed_cxt_set_cli(&p_mngr->clients[ILT_CLI_QM]);
	p_blk = qed_cxt_set_blk(&p_cli->pf_blks[0]);

	qed_cxt_qm_iids(p_hwfn, &qm_iids);
	total = qed_qm_pf_mem_size(p_hwfn->rel_pf_id, qm_iids.cids,
@@ -718,7 +753,7 @@ int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn)
	p_cli->pf_total_lines = curr_line - p_blk->start_line;

	/* SRC */
	p_cli = &p_mngr->clients[ILT_CLI_SRC];
	p_cli = qed_cxt_set_cli(&p_mngr->clients[ILT_CLI_SRC]);
	qed_cxt_src_iids(p_mngr, &src_iids);

	/* Both the PF and VFs searcher connections are stored in the per PF
@@ -732,7 +767,7 @@ int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn)

		total = roundup_pow_of_two(local_max);

		p_blk = &p_cli->pf_blks[0];
		p_blk = qed_cxt_set_blk(&p_cli->pf_blks[0]);
		qed_ilt_cli_blk_fill(p_cli, p_blk, curr_line,
				     total * sizeof(struct src_ent),
				     sizeof(struct src_ent));
@@ -743,11 +778,11 @@ int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn)
	}

	/* TM PF */
	p_cli = &p_mngr->clients[ILT_CLI_TM];
	qed_cxt_tm_iids(p_mngr, &tm_iids);
	p_cli = qed_cxt_set_cli(&p_mngr->clients[ILT_CLI_TM]);
	qed_cxt_tm_iids(p_hwfn, p_mngr, &tm_iids);
	total = tm_iids.pf_cids + tm_iids.pf_tids_total;
	if (total) {
		p_blk = &p_cli->pf_blks[0];
		p_blk = qed_cxt_set_blk(&p_cli->pf_blks[0]);
		qed_ilt_cli_blk_fill(p_cli, p_blk, curr_line,
				     total * TM_ELEM_SIZE, TM_ELEM_SIZE);

@@ -759,14 +794,14 @@ int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn)
	/* TM VF */
	total = tm_iids.per_vf_cids + tm_iids.per_vf_tids;
	if (total) {
		p_blk = &p_cli->vf_blks[0];
		p_blk = qed_cxt_set_blk(&p_cli->vf_blks[0]);
		qed_ilt_cli_blk_fill(p_cli, p_blk, curr_line,
				     total * TM_ELEM_SIZE, TM_ELEM_SIZE);

		qed_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
				     ILT_CLI_TM);
		p_cli->pf_total_lines = curr_line - p_blk->start_line;

		p_cli->vf_total_lines = curr_line - p_blk->start_line;
		for (i = 1; i < p_mngr->vf_count; i++)
			qed_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
					     ILT_CLI_TM);
@@ -776,8 +811,8 @@ int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn)
	total = qed_cxt_get_srq_count(p_hwfn);

	if (total) {
		p_cli = &p_mngr->clients[ILT_CLI_TSDM];
		p_blk = &p_cli->pf_blks[SRQ_BLK];
		p_cli = qed_cxt_set_cli(&p_mngr->clients[ILT_CLI_TSDM]);
		p_blk = qed_cxt_set_blk(&p_cli->pf_blks[SRQ_BLK]);
		qed_ilt_cli_blk_fill(p_cli, p_blk, curr_line,
				     total * SRQ_CXT_SIZE, SRQ_CXT_SIZE);

@@ -786,13 +821,50 @@ int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn)
		p_cli->pf_total_lines = curr_line - p_blk->start_line;
	}

	*line_count = curr_line - p_hwfn->p_cxt_mngr->pf_start_line;

	if (curr_line - p_hwfn->p_cxt_mngr->pf_start_line >
	    RESC_NUM(p_hwfn, QED_ILT)) {
		DP_ERR(p_hwfn, "too many ilt lines...#lines=%d\n",
		       curr_line - p_hwfn->p_cxt_mngr->pf_start_line);
	    RESC_NUM(p_hwfn, QED_ILT))
		return -EINVAL;

	return 0;
}

u32 qed_cxt_cfg_ilt_compute_excess(struct qed_hwfn *p_hwfn, u32 used_lines)
{
	struct qed_ilt_client_cfg *p_cli;
	u32 excess_lines, available_lines;
	struct qed_cxt_mngr *p_mngr;
	u32 ilt_page_size, elem_size;
	struct qed_tid_seg *p_seg;
	int i;

	available_lines = RESC_NUM(p_hwfn, QED_ILT);
	excess_lines = used_lines - available_lines;

	if (!excess_lines)
		return 0;

	if (p_hwfn->hw_info.personality != QED_PCI_ETH_ROCE)
		return 0;

	p_mngr = p_hwfn->p_cxt_mngr;
	p_cli = &p_mngr->clients[ILT_CLI_CDUT];
	ilt_page_size = ILT_PAGE_IN_BYTES(p_cli->p_size.val);

	for (i = 0; i < NUM_TASK_PF_SEGMENTS; i++) {
		p_seg = qed_cxt_tid_seg_info(p_hwfn, i);
		if (!p_seg || p_seg->count == 0)
			continue;

		elem_size = p_mngr->task_type_size[p_seg->type];
		if (!elem_size)
			continue;

		return (ilt_page_size / elem_size) * excess_lines;
	}

	DP_NOTICE(p_hwfn, "failed computing excess ILT lines\n");
	return 0;
}

@@ -1396,18 +1468,11 @@ void qed_qm_init_pf(struct qed_hwfn *p_hwfn)
}

/* CM PF */
static int qed_cm_init_pf(struct qed_hwfn *p_hwfn)
void qed_cm_init_pf(struct qed_hwfn *p_hwfn)
{
	union qed_qm_pq_params pq_params;
	u16 pq;

	/* XCM pure-LB queue */
	memset(&pq_params, 0, sizeof(pq_params));
	pq_params.core.tc = LB_TC;
	pq = qed_get_qm_pq(p_hwfn, PROTOCOLID_CORE, &pq_params);
	STORE_RT_REG(p_hwfn, XCM_REG_CON_PHY_Q3_RT_OFFSET, pq);

	return 0;
	STORE_RT_REG(p_hwfn, XCM_REG_CON_PHY_Q3_RT_OFFSET,
		     qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_LB));
}

/* DQ PF */
@@ -1639,7 +1704,7 @@ static void qed_tm_init_pf(struct qed_hwfn *p_hwfn)
	u8 i;

	memset(&tm_iids, 0, sizeof(tm_iids));
	qed_cxt_tm_iids(p_mngr, &tm_iids);
	qed_cxt_tm_iids(p_hwfn, p_mngr, &tm_iids);

	/* @@@TBD No pre-scan for now */

@@ -1883,13 +1948,12 @@ int qed_cxt_get_cid_info(struct qed_hwfn *p_hwfn, struct qed_cxt_info *p_info)
}

static void qed_rdma_set_pf_params(struct qed_hwfn *p_hwfn,
				   struct qed_rdma_pf_params *p_params)
				   struct qed_rdma_pf_params *p_params,
				   u32 num_tasks)
{
	u32 num_cons, num_tasks, num_qps, num_mrs, num_srqs;
	u32 num_cons, num_qps, num_srqs;
	enum protocol_type proto;

	num_mrs = min_t(u32, RDMA_MAX_TIDS, p_params->num_mrs);
	num_tasks = num_mrs;	/* each mr uses a single task id */
	num_srqs = min_t(u32, 32 * 1024, p_params->num_srqs);

	switch (p_hwfn->hw_info.personality) {
@@ -1918,7 +1982,7 @@ static void qed_rdma_set_pf_params(struct qed_hwfn *p_hwfn,
	}
}

int qed_cxt_set_pf_params(struct qed_hwfn *p_hwfn)
int qed_cxt_set_pf_params(struct qed_hwfn *p_hwfn, u32 rdma_tasks)
{
	/* Set the number of required CORE connections */
	u32 core_cids = 1; /* SPQ */
@@ -1932,7 +1996,8 @@ int qed_cxt_set_pf_params(struct qed_hwfn *p_hwfn)
	{
			qed_rdma_set_pf_params(p_hwfn,
					       &p_hwfn->
				       pf_params.rdma_pf_params);
					       pf_params.rdma_pf_params,
					       rdma_tasks);
		/* no need for break since RoCE coexist with Ethernet */
	}
	case QED_PCI_ETH:
+12 −3
Original line number Diff line number Diff line
@@ -105,19 +105,28 @@ u32 qed_cxt_get_proto_cid_count(struct qed_hwfn *p_hwfn,
 * @brief qed_cxt_set_pf_params - Set the PF params for cxt init
 *
 * @param p_hwfn
 *
 * @param rdma_tasks - requested maximum
 * @return int
 */
int qed_cxt_set_pf_params(struct qed_hwfn *p_hwfn);
int qed_cxt_set_pf_params(struct qed_hwfn *p_hwfn, u32 rdma_tasks);

/**
 * @brief qed_cxt_cfg_ilt_compute - compute ILT init parameters
 *
 * @param p_hwfn
 * @param last_line
 *
 * @return int
 */
int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn);
int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn, u32 *last_line);

/**
 * @brief qed_cxt_cfg_ilt_compute_excess - how many lines can be decreased
 *
 * @param p_hwfn
 * @param used_lines
 */
u32 qed_cxt_cfg_ilt_compute_excess(struct qed_hwfn *p_hwfn, u32 used_lines);

/**
 * @brief qed_cxt_mngr_alloc - Allocate and init the context manager struct
+6 −8
Original line number Diff line number Diff line
@@ -183,7 +183,7 @@ qed_dcbx_dp_protocol(struct qed_hwfn *p_hwfn, struct qed_dcbx_results *p_data)
			   "%s info: update %d, enable %d, prio %d, tc %d, num_tc %d\n",
			   qed_dcbx_app_update[i].name, p_data->arr[id].update,
			   p_data->arr[id].enable, p_data->arr[id].priority,
			   p_data->arr[id].tc, p_hwfn->hw_info.num_tc);
			   p_data->arr[id].tc, p_hwfn->hw_info.num_active_tc);
	}
}

@@ -204,13 +204,9 @@ qed_dcbx_set_params(struct qed_dcbx_results *p_data,
	p_data->arr[type].tc = tc;

	/* QM reconf data */
	if (p_info->personality == personality) {
		if (personality == QED_PCI_ETH)
			p_info->non_offload_tc = tc;
		else
	if (p_info->personality == personality)
		p_info->offload_tc = tc;
}
}

/* Update app protocol data and hw_info fields with the TLV info */
static void
@@ -376,7 +372,9 @@ static int qed_dcbx_process_mib_info(struct qed_hwfn *p_hwfn)
	if (rc)
		return rc;

	p_info->num_tc = QED_MFW_GET_FIELD(p_ets->flags, DCBX_ETS_MAX_TCS);
	p_info->num_active_tc = QED_MFW_GET_FIELD(p_ets->flags,
						  DCBX_ETS_MAX_TCS);
	p_hwfn->qm_info.ooo_tc = QED_MFW_GET_FIELD(p_ets->flags, DCBX_OOO_TC);
	data.pf_id = p_hwfn->rel_pf_id;
	data.dcbx_enabled = !!dcbx_version;

+609 −173

File changed.

Preview size limit exceeded, changes collapsed.

Loading