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

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

Merge branch 'qed-Add-Multi-TC-RoCE-support'



Denis Bolotin says:

====================
qed: Add Multi-TC RoCE support

This patch series adds support for multiple concurrent traffic classes for RoCE.
The first three patches enable the required parts of the driver to learn the TC
configuration, and the last one makes use of it to enable the feature.
Please consider applying this to net-next.

V1->V2:
-------
Avoid allocation in qed_dcbx_get_priority_tc().
Move qed_dcbx_get_priority_tc() out of CONFIG_DCB section since it doesn't call
qed_dcbx_query_params() anymore.

v2->V3:
-------
patch 1/3:
qed_dcbx_get_priority_tc() always returns a valid TC by value. In error cases,
it returns QED_DCBX_DEFAULT_TC (currently defined 0).
patch 3/3:
Cosmetic changes in qed_dev.c.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5941923d 61be82b0
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -336,6 +336,10 @@ struct qed_hw_info {
	 */
	u8 num_active_tc;
	u8				offload_tc;
	bool				offload_tc_set;

	bool				multi_tc_roce_en;
#define IS_QED_MULTI_TC_ROCE(p_hwfn) (((p_hwfn)->hw_info.multi_tc_roce_en))

	u32				concrete_fid;
	u16				opaque_fid;
@@ -399,8 +403,8 @@ struct qed_qm_info {
	u16				start_pq;
	u8				start_vport;
	u16				 pure_lb_pq;
	u16				offload_pq;
	u16				low_latency_pq;
	u16				first_ofld_pq;
	u16				first_llt_pq;
	u16				pure_ack_pq;
	u16				ooo_pq;
	u16				first_vf_pq;
@@ -881,11 +885,14 @@ void qed_set_fw_mac_addr(__le16 *fw_msb,
#define PQ_FLAGS_OFLD   (BIT(5))
#define PQ_FLAGS_VFS    (BIT(6))
#define PQ_FLAGS_LLT    (BIT(7))
#define PQ_FLAGS_MTC    (BIT(8))

/* 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);
u16 qed_get_cm_pq_idx_ofld_mtc(struct qed_hwfn *p_hwfn, u8 tc);
u16 qed_get_cm_pq_idx_llt_mtc(struct qed_hwfn *p_hwfn, u8 tc);

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

@@ -921,4 +928,6 @@ int qed_mfw_tlv_req(struct qed_hwfn *hwfn);
int qed_mfw_fill_tlv_data(struct qed_hwfn *hwfn,
			  enum qed_mfw_tlv_type type,
			  union qed_mfw_tlv_data *tlv_data);

void qed_hw_info_set_offload_tc(struct qed_hw_info *p_info, u8 tc);
#endif /* _QED_H */
+19 −1
Original line number Diff line number Diff line
@@ -208,7 +208,7 @@ qed_dcbx_set_params(struct qed_dcbx_results *p_data,

	/* QM reconf data */
	if (p_info->personality == personality)
		p_info->offload_tc = tc;
		qed_hw_info_set_offload_tc(p_info, tc);
}

/* Update app protocol data and hw_info fields with the TLV info */
@@ -989,6 +989,24 @@ void qed_dcbx_set_pf_update_params(struct qed_dcbx_results *p_src,
	qed_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ETH);
}

u8 qed_dcbx_get_priority_tc(struct qed_hwfn *p_hwfn, u8 pri)
{
	struct qed_dcbx_get *dcbx_info = &p_hwfn->p_dcbx_info->get;

	if (pri >= QED_MAX_PFC_PRIORITIES) {
		DP_ERR(p_hwfn, "Invalid priority %d\n", pri);
		return QED_DCBX_DEFAULT_TC;
	}

	if (!dcbx_info->operational.valid) {
		DP_VERBOSE(p_hwfn, QED_MSG_DCB,
			   "Dcbx parameters not available\n");
		return QED_DCBX_DEFAULT_TC;
	}

	return dcbx_info->operational.params.ets_pri_tc_tbl[pri];
}

#ifdef CONFIG_DCB
static int qed_dcbx_query_params(struct qed_hwfn *p_hwfn,
				 struct qed_dcbx_get *p_get,
+3 −0
Original line number Diff line number Diff line
@@ -123,4 +123,7 @@ void qed_dcbx_info_free(struct qed_hwfn *p_hwfn);
void qed_dcbx_set_pf_update_params(struct qed_dcbx_results *p_src,
				   struct pf_update_ramrod_data *p_dest);

#define QED_DCBX_DEFAULT_TC	0

u8 qed_dcbx_get_priority_tc(struct qed_hwfn *p_hwfn, u8 pri);
#endif
+98 −15
Original line number Diff line number Diff line
@@ -215,6 +215,8 @@ static u32 qed_get_pq_flags(struct qed_hwfn *p_hwfn)
		break;
	case QED_PCI_ETH_ROCE:
		flags |= PQ_FLAGS_MCOS | PQ_FLAGS_OFLD | PQ_FLAGS_LLT;
		if (IS_QED_MULTI_TC_ROCE(p_hwfn))
			flags |= PQ_FLAGS_MTC;
		break;
	case QED_PCI_ETH_IWARP:
		flags |= PQ_FLAGS_MCOS | PQ_FLAGS_ACK | PQ_FLAGS_OOO |
@@ -241,6 +243,16 @@ static u16 qed_init_qm_get_num_vfs(struct qed_hwfn *p_hwfn)
	       p_hwfn->cdev->p_iov_info->total_vfs : 0;
}

static u8 qed_init_qm_get_num_mtc_tcs(struct qed_hwfn *p_hwfn)
{
	u32 pq_flags = qed_get_pq_flags(p_hwfn);

	if (!(PQ_FLAGS_MTC & pq_flags))
		return 1;

	return qed_init_qm_get_num_tcs(p_hwfn);
}

#define NUM_DEFAULT_RLS 1

static u16 qed_init_qm_get_num_pf_rls(struct qed_hwfn *p_hwfn)
@@ -282,8 +294,11 @@ static u16 qed_init_qm_get_num_pqs(struct qed_hwfn *p_hwfn)
	       (!!(PQ_FLAGS_MCOS & pq_flags)) *
	       qed_init_qm_get_num_tcs(p_hwfn) +
	       (!!(PQ_FLAGS_LB & pq_flags)) + (!!(PQ_FLAGS_OOO & pq_flags)) +
	       (!!(PQ_FLAGS_ACK & pq_flags)) + (!!(PQ_FLAGS_OFLD & pq_flags)) +
	       (!!(PQ_FLAGS_LLT & pq_flags)) +
	       (!!(PQ_FLAGS_ACK & pq_flags)) +
	       (!!(PQ_FLAGS_OFLD & pq_flags)) *
	       qed_init_qm_get_num_mtc_tcs(p_hwfn) +
	       (!!(PQ_FLAGS_LLT & pq_flags)) *
	       qed_init_qm_get_num_mtc_tcs(p_hwfn) +
	       (!!(PQ_FLAGS_VFS & pq_flags)) * qed_init_qm_get_num_vfs(p_hwfn);
}

@@ -394,7 +409,25 @@ static void qed_init_qm_advance_vport(struct qed_hwfn *p_hwfn)
/* defines for pq init */
#define PQ_INIT_DEFAULT_WRR_GROUP       1
#define PQ_INIT_DEFAULT_TC              0
#define PQ_INIT_OFLD_TC                 (p_hwfn->hw_info.offload_tc)

void qed_hw_info_set_offload_tc(struct qed_hw_info *p_info, u8 tc)
{
	p_info->offload_tc = tc;
	p_info->offload_tc_set = true;
}

static bool qed_is_offload_tc_set(struct qed_hwfn *p_hwfn)
{
	return p_hwfn->hw_info.offload_tc_set;
}

static u32 qed_get_offload_tc(struct qed_hwfn *p_hwfn)
{
	if (qed_is_offload_tc_set(p_hwfn))
		return p_hwfn->hw_info.offload_tc;

	return PQ_INIT_DEFAULT_TC;
}

static void qed_init_qm_pq(struct qed_hwfn *p_hwfn,
			   struct qed_qm_info *qm_info,
@@ -456,9 +489,9 @@ static u16 *qed_init_qm_get_idx_from_flags(struct qed_hwfn *p_hwfn,
	case PQ_FLAGS_ACK:
		return &qm_info->pure_ack_pq;
	case PQ_FLAGS_OFLD:
		return &qm_info->offload_pq;
		return &qm_info->first_ofld_pq;
	case PQ_FLAGS_LLT:
		return &qm_info->low_latency_pq;
		return &qm_info->first_llt_pq;
	case PQ_FLAGS_VFS:
		return &qm_info->first_vf_pq;
	default:
@@ -507,6 +540,28 @@ u16 qed_get_cm_pq_idx_vf(struct qed_hwfn *p_hwfn, u16 vf)
	return qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_VFS) + vf;
}

u16 qed_get_cm_pq_idx_ofld_mtc(struct qed_hwfn *p_hwfn, u8 tc)
{
	u16 first_ofld_pq, pq_offset;

	first_ofld_pq = qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_OFLD);
	pq_offset = (tc < qed_init_qm_get_num_mtc_tcs(p_hwfn)) ?
		    tc : PQ_INIT_DEFAULT_TC;

	return first_ofld_pq + pq_offset;
}

u16 qed_get_cm_pq_idx_llt_mtc(struct qed_hwfn *p_hwfn, u8 tc)
{
	u16 first_llt_pq, pq_offset;

	first_llt_pq = qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_LLT);
	pq_offset = (tc < qed_init_qm_get_num_mtc_tcs(p_hwfn)) ?
		    tc : PQ_INIT_DEFAULT_TC;

	return first_llt_pq + pq_offset;
}

/* Functions for creating specific types of pqs */
static void qed_init_qm_lb_pq(struct qed_hwfn *p_hwfn)
{
@@ -538,7 +593,22 @@ static void qed_init_qm_pure_ack_pq(struct qed_hwfn *p_hwfn)
		return;

	qed_init_qm_set_idx(p_hwfn, PQ_FLAGS_ACK, qm_info->num_pqs);
	qed_init_qm_pq(p_hwfn, qm_info, PQ_INIT_OFLD_TC, PQ_INIT_SHARE_VPORT);
	qed_init_qm_pq(p_hwfn, qm_info, qed_get_offload_tc(p_hwfn),
		       PQ_INIT_SHARE_VPORT);
}

static void qed_init_qm_mtc_pqs(struct qed_hwfn *p_hwfn)
{
	u8 num_tcs = qed_init_qm_get_num_mtc_tcs(p_hwfn);
	struct qed_qm_info *qm_info = &p_hwfn->qm_info;
	u8 tc;

	/* override pq's TC if offload TC is set */
	for (tc = 0; tc < num_tcs; tc++)
		qed_init_qm_pq(p_hwfn, qm_info,
			       qed_is_offload_tc_set(p_hwfn) ?
			       p_hwfn->hw_info.offload_tc : tc,
			       PQ_INIT_SHARE_VPORT);
}

static void qed_init_qm_offload_pq(struct qed_hwfn *p_hwfn)
@@ -549,7 +619,7 @@ static void qed_init_qm_offload_pq(struct qed_hwfn *p_hwfn)
		return;

	qed_init_qm_set_idx(p_hwfn, PQ_FLAGS_OFLD, qm_info->num_pqs);
	qed_init_qm_pq(p_hwfn, qm_info, PQ_INIT_OFLD_TC, PQ_INIT_SHARE_VPORT);
	qed_init_qm_mtc_pqs(p_hwfn);
}

static void qed_init_qm_low_latency_pq(struct qed_hwfn *p_hwfn)
@@ -560,7 +630,7 @@ static void qed_init_qm_low_latency_pq(struct qed_hwfn *p_hwfn)
		return;

	qed_init_qm_set_idx(p_hwfn, PQ_FLAGS_LLT, qm_info->num_pqs);
	qed_init_qm_pq(p_hwfn, qm_info, PQ_INIT_OFLD_TC, PQ_INIT_SHARE_VPORT);
	qed_init_qm_mtc_pqs(p_hwfn);
}

static void qed_init_qm_mcos_pqs(struct qed_hwfn *p_hwfn)
@@ -601,7 +671,8 @@ static void qed_init_qm_rl_pqs(struct qed_hwfn *p_hwfn)

	qed_init_qm_set_idx(p_hwfn, PQ_FLAGS_RLS, qm_info->num_pqs);
	for (pf_rls_idx = 0; pf_rls_idx < num_pf_rls; pf_rls_idx++)
		qed_init_qm_pq(p_hwfn, qm_info, PQ_INIT_OFLD_TC, PQ_INIT_PF_RL);
		qed_init_qm_pq(p_hwfn, qm_info, qed_get_offload_tc(p_hwfn),
			       PQ_INIT_PF_RL);
}

static void qed_init_qm_pq_params(struct qed_hwfn *p_hwfn)
@@ -642,14 +713,21 @@ static int qed_init_qm_sanity(struct qed_hwfn *p_hwfn)
		return -EINVAL;
	}

	if (qed_init_qm_get_num_pqs(p_hwfn) > RESC_NUM(p_hwfn, QED_PQ)) {
		DP_ERR(p_hwfn, "requested amount of pqs exceeds resource\n");
		return -EINVAL;
	}
	if (qed_init_qm_get_num_pqs(p_hwfn) <= RESC_NUM(p_hwfn, QED_PQ))
		return 0;

	if (QED_IS_ROCE_PERSONALITY(p_hwfn)) {
		p_hwfn->hw_info.multi_tc_roce_en = 0;
		DP_NOTICE(p_hwfn,
			  "multi-tc roce was disabled to reduce requested amount of pqs\n");
		if (qed_init_qm_get_num_pqs(p_hwfn) <= RESC_NUM(p_hwfn, QED_PQ))
			return 0;
	}

	DP_ERR(p_hwfn, "requested amount of pqs exceeds resource\n");
	return -EINVAL;
}

static void qed_dp_init_qm_params(struct qed_hwfn *p_hwfn)
{
	struct qed_qm_info *qm_info = &p_hwfn->qm_info;
@@ -661,11 +739,13 @@ static void qed_dp_init_qm_params(struct qed_hwfn *p_hwfn)
	/* top level params */
	DP_VERBOSE(p_hwfn,
		   NETIF_MSG_HW,
		   "qm init top level params: start_pq %d, start_vport %d, pure_lb_pq %d, offload_pq %d, pure_ack_pq %d\n",
		   "qm init top level params: start_pq %d, start_vport %d, pure_lb_pq %d, offload_pq %d, llt_pq %d, pure_ack_pq %d\n",
		   qm_info->start_pq,
		   qm_info->start_vport,
		   qm_info->pure_lb_pq,
		   qm_info->offload_pq, qm_info->pure_ack_pq);
		   qm_info->first_ofld_pq,
		   qm_info->first_llt_pq,
		   qm_info->pure_ack_pq);
	DP_VERBOSE(p_hwfn,
		   NETIF_MSG_HW,
		   "ooo_pq %d, first_vf_pq %d, num_pqs %d, num_vf_pqs %d, num_vports %d, max_phys_tcs_per_port %d\n",
@@ -2898,6 +2978,9 @@ qed_get_hw_info(struct qed_hwfn *p_hwfn,
		p_hwfn->hw_info.personality = protocol;
	}

	if (QED_IS_ROCE_PERSONALITY(p_hwfn))
		p_hwfn->hw_info.multi_tc_roce_en = 1;

	p_hwfn->hw_info.num_hw_tc = NUM_PHYS_TCS_4PORT_K2;
	p_hwfn->hw_info.num_active_tc = 1;

+2 −1
Original line number Diff line number Diff line
@@ -1552,7 +1552,8 @@ qed_mcp_handle_ufp_event(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)

	if (p_hwfn->ufp_info.mode == QED_UFP_MODE_VNIC_BW) {
		p_hwfn->qm_info.ooo_tc = p_hwfn->ufp_info.tc;
		p_hwfn->hw_info.offload_tc = p_hwfn->ufp_info.tc;
		qed_hw_info_set_offload_tc(&p_hwfn->hw_info,
					   p_hwfn->ufp_info.tc);

		qed_qm_reconf(p_hwfn, p_ptt);
	} else if (p_hwfn->ufp_info.mode == QED_UFP_MODE_ETS) {
Loading