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

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

Merge branch 'qed-misc-cleanups-and-fixes'



Yuval Mintz says:

====================
qed: Misc cleanups and fixes

Patches #1 and #2 revolve around register access performed by driver;
The first merely adds some debug, while the second does some fixing
of incorrect PTT usage as well as preventing issues similar to those
fixed by 6f437d43 ("qed: Don't use attention PTT for configuring BW").

Patch #3 better configures HW for architecture where cacheline isn't 64B.

Patches #4-#8 all affect iSCSI related functionaility -
adding statistics information [both to driver & management firmware],
passing information on number of resources to qedi, and simplifying
the Out-of-order implementation in SW.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ec1af27e 1eec2437
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -225,8 +225,9 @@ enum QED_FEATURE {
	QED_PF_L2_QUE,
	QED_VF,
	QED_RDMA_CNQ,
	QED_VF_L2_QUE,
	QED_ISCSI_CQ,
	QED_FCOE_CQ,
	QED_VF_L2_QUE,
	QED_MAX_FEATURES,
};

+4 −4
Original line number Diff line number Diff line
@@ -1438,7 +1438,7 @@ static void qed_cdu_init_pf(struct qed_hwfn *p_hwfn)
	}
}

void qed_qm_init_pf(struct qed_hwfn *p_hwfn)
void qed_qm_init_pf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
{
	struct qed_qm_pf_rt_init_params params;
	struct qed_qm_info *qm_info = &p_hwfn->qm_info;
@@ -1464,7 +1464,7 @@ void qed_qm_init_pf(struct qed_hwfn *p_hwfn)
	params.pq_params = qm_info->qm_pq_params;
	params.vport_params = qm_info->qm_vport_params;

	qed_qm_pf_rt_init(p_hwfn, p_hwfn->p_main_ptt, &params);
	qed_qm_pf_rt_init(p_hwfn, p_ptt, &params);
}

/* CM PF */
@@ -1822,9 +1822,9 @@ void qed_cxt_hw_init_common(struct qed_hwfn *p_hwfn)
	qed_prs_init_common(p_hwfn);
}

void qed_cxt_hw_init_pf(struct qed_hwfn *p_hwfn)
void qed_cxt_hw_init_pf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
{
	qed_qm_init_pf(p_hwfn);
	qed_qm_init_pf(p_hwfn, p_ptt);
	qed_cm_init_pf(p_hwfn);
	qed_dq_init_pf(p_hwfn);
	qed_cdu_init_pf(p_hwfn);
+4 −5
Original line number Diff line number Diff line
@@ -172,19 +172,18 @@ void qed_cxt_hw_init_common(struct qed_hwfn *p_hwfn);
/**
 * @brief qed_cxt_hw_init_pf - Initailze ILT and DQ, PF phase, per path.
 *
 *
 *
 * @param p_hwfn
 * @param p_ptt
 */
void qed_cxt_hw_init_pf(struct qed_hwfn *p_hwfn);
void qed_cxt_hw_init_pf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);

/**
 * @brief qed_qm_init_pf - Initailze the QM PF phase, per path
 *
 * @param p_hwfn
 * @param p_ptt
 */

void qed_qm_init_pf(struct qed_hwfn *p_hwfn);
void qed_qm_init_pf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);

/**
 * @brief Reconfigures QM pf on the fly
+99 −38
Original line number Diff line number Diff line
@@ -75,7 +75,8 @@ enum BAR_ID {
	BAR_ID_1        /* Used for doorbells */
};

static u32 qed_hw_bar_size(struct qed_hwfn *p_hwfn, enum BAR_ID bar_id)
static u32 qed_hw_bar_size(struct qed_hwfn *p_hwfn,
			   struct qed_ptt *p_ptt, enum BAR_ID bar_id)
{
	u32 bar_reg = (bar_id == BAR_ID_0 ?
		       PGLUE_B_REG_PF_BAR0_SIZE : PGLUE_B_REG_PF_BAR1_SIZE);
@@ -84,7 +85,7 @@ static u32 qed_hw_bar_size(struct qed_hwfn *p_hwfn, enum BAR_ID bar_id)
	if (IS_VF(p_hwfn->cdev))
		return 1 << 17;

	val = qed_rd(p_hwfn, p_hwfn->p_main_ptt, bar_reg);
	val = qed_rd(p_hwfn, p_ptt, bar_reg);
	if (val)
		return 1 << (val + 15);

@@ -780,7 +781,7 @@ int qed_qm_reconf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
	qed_init_clear_rt_data(p_hwfn);

	/* prepare QM portion of runtime array */
	qed_qm_init_pf(p_hwfn);
	qed_qm_init_pf(p_hwfn, p_ptt);

	/* activate init tool on runtime array */
	rc = qed_init_run(p_hwfn, p_ptt, PHASE_QM_PF, p_hwfn->rel_pf_id,
@@ -1191,6 +1192,57 @@ static void qed_init_cau_rt_data(struct qed_dev *cdev)
	}
}

static void qed_init_cache_line_size(struct qed_hwfn *p_hwfn,
				     struct qed_ptt *p_ptt)
{
	u32 val, wr_mbs, cache_line_size;

	val = qed_rd(p_hwfn, p_ptt, PSWRQ2_REG_WR_MBS0);
	switch (val) {
	case 0:
		wr_mbs = 128;
		break;
	case 1:
		wr_mbs = 256;
		break;
	case 2:
		wr_mbs = 512;
		break;
	default:
		DP_INFO(p_hwfn,
			"Unexpected value of PSWRQ2_REG_WR_MBS0 [0x%x]. Avoid configuring PGLUE_B_REG_CACHE_LINE_SIZE.\n",
			val);
		return;
	}

	cache_line_size = min_t(u32, L1_CACHE_BYTES, wr_mbs);
	switch (cache_line_size) {
	case 32:
		val = 0;
		break;
	case 64:
		val = 1;
		break;
	case 128:
		val = 2;
		break;
	case 256:
		val = 3;
		break;
	default:
		DP_INFO(p_hwfn,
			"Unexpected value of cache line size [0x%x]. Avoid configuring PGLUE_B_REG_CACHE_LINE_SIZE.\n",
			cache_line_size);
	}

	if (L1_CACHE_BYTES > wr_mbs)
		DP_INFO(p_hwfn,
			"The cache line size for padding is suboptimal for performance [OS cache line size 0x%x, wr mbs 0x%x]\n",
			L1_CACHE_BYTES, wr_mbs);

	STORE_RT_REG(p_hwfn, PGLUE_REG_B_CACHE_LINE_SIZE_RT_OFFSET, val);
}

static int qed_hw_init_common(struct qed_hwfn *p_hwfn,
			      struct qed_ptt *p_ptt, int hw_mode)
{
@@ -1227,17 +1279,7 @@ static int qed_hw_init_common(struct qed_hwfn *p_hwfn,

	qed_cxt_hw_init_common(p_hwfn);

	/* Close gate from NIG to BRB/Storm; By default they are open, but
	 * we close them to prevent NIG from passing data to reset blocks.
	 * Should have been done in the ENGINE phase, but init-tool lacks
	 * proper port-pretend capabilities.
	 */
	qed_wr(p_hwfn, p_ptt, NIG_REG_RX_BRB_OUT_EN, 0);
	qed_wr(p_hwfn, p_ptt, NIG_REG_STORM_OUT_EN, 0);
	qed_port_pretend(p_hwfn, p_ptt, p_hwfn->port_id ^ 1);
	qed_wr(p_hwfn, p_ptt, NIG_REG_RX_BRB_OUT_EN, 0);
	qed_wr(p_hwfn, p_ptt, NIG_REG_STORM_OUT_EN, 0);
	qed_port_unpretend(p_hwfn, p_ptt);
	qed_init_cache_line_size(p_hwfn, p_ptt);

	rc = qed_init_run(p_hwfn, p_ptt, PHASE_ENGINE, ANY_PHASE_ID, hw_mode);
	if (rc)
@@ -1320,7 +1362,7 @@ qed_hw_init_pf_doorbell_bar(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
	int rc = 0;
	u8 cond;

	db_bar_size = qed_hw_bar_size(p_hwfn, BAR_ID_1);
	db_bar_size = qed_hw_bar_size(p_hwfn, p_ptt, BAR_ID_1);
	if (p_hwfn->cdev->num_hwfns > 1)
		db_bar_size /= 2;

@@ -1431,7 +1473,7 @@ static int qed_hw_init_pf(struct qed_hwfn *p_hwfn,
		p_hwfn->qm_info.pf_rl = 100000;
	}

	qed_cxt_hw_init_pf(p_hwfn);
	qed_cxt_hw_init_pf(p_hwfn, p_ptt);

	qed_int_igu_init_rt(p_hwfn);

@@ -1852,18 +1894,21 @@ int qed_hw_stop(struct qed_dev *cdev)
	return rc2;
}

void qed_hw_stop_fastpath(struct qed_dev *cdev)
int qed_hw_stop_fastpath(struct qed_dev *cdev)
{
	int j;

	for_each_hwfn(cdev, j) {
		struct qed_hwfn *p_hwfn = &cdev->hwfns[j];
		struct qed_ptt *p_ptt = p_hwfn->p_main_ptt;
		struct qed_ptt *p_ptt;

		if (IS_VF(cdev)) {
			qed_vf_pf_int_cleanup(p_hwfn);
			continue;
		}
		p_ptt = qed_ptt_acquire(p_hwfn);
		if (!p_ptt)
			return -EAGAIN;

		DP_VERBOSE(p_hwfn,
			   NETIF_MSG_IFDOWN, "Shutting down the fastpath\n");
@@ -1881,17 +1926,28 @@ void qed_hw_stop_fastpath(struct qed_dev *cdev)

		/* Need to wait 1ms to guarantee SBs are cleared */
		usleep_range(1000, 2000);
		qed_ptt_release(p_hwfn, p_ptt);
	}

	return 0;
}

void qed_hw_start_fastpath(struct qed_hwfn *p_hwfn)
int qed_hw_start_fastpath(struct qed_hwfn *p_hwfn)
{
	struct qed_ptt *p_ptt;

	if (IS_VF(p_hwfn->cdev))
		return;
		return 0;

	p_ptt = qed_ptt_acquire(p_hwfn);
	if (!p_ptt)
		return -EAGAIN;

	/* Re-open incoming traffic */
	qed_wr(p_hwfn, p_hwfn->p_main_ptt,
	       NIG_REG_RX_LLH_BRB_GATE_DNTFWD_PERPF, 0x0);
	qed_wr(p_hwfn, p_ptt, NIG_REG_RX_LLH_BRB_GATE_DNTFWD_PERPF, 0x0);
	qed_ptt_release(p_hwfn, p_ptt);

	return 0;
}

/* Free hwfn memory and resources acquired in hw_hwfn_prepare */
@@ -1989,12 +2045,17 @@ static void qed_hw_set_feat(struct qed_hwfn *p_hwfn)
							 QED_VF_L2_QUE));
	}

	if (p_hwfn->hw_info.personality == QED_PCI_ISCSI)
		feat_num[QED_ISCSI_CQ] = min_t(u32, RESC_NUM(p_hwfn, QED_SB),
					       RESC_NUM(p_hwfn,
							QED_CMDQS_CQS));
	DP_VERBOSE(p_hwfn,
		   NETIF_MSG_PROBE,
		   "#PF_L2_QUEUES=%d VF_L2_QUEUES=%d #ROCE_CNQ=%d #SBS=%d\n",
		   "#PF_L2_QUEUES=%d VF_L2_QUEUES=%d #ROCE_CNQ=%d ISCSI_CQ=%d #SBS=%d\n",
		   (int)FEAT_NUM(p_hwfn, QED_PF_L2_QUE),
		   (int)FEAT_NUM(p_hwfn, QED_VF_L2_QUE),
		   (int)FEAT_NUM(p_hwfn, QED_RDMA_CNQ),
		   (int)FEAT_NUM(p_hwfn, QED_ISCSI_CQ),
		   RESC_NUM(p_hwfn, QED_SB));
}

@@ -2697,9 +2758,9 @@ qed_get_hw_info(struct qed_hwfn *p_hwfn,
	return qed_hw_get_resc(p_hwfn, p_ptt);
}

static int qed_get_dev_info(struct qed_dev *cdev)
static int qed_get_dev_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
{
	struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
	struct qed_dev *cdev = p_hwfn->cdev;
	u16 device_id_mask;
	u32 tmp;

@@ -2721,15 +2782,13 @@ static int qed_get_dev_info(struct qed_dev *cdev)
		return -EBUSY;
	}

	cdev->chip_num = (u16)qed_rd(p_hwfn, p_hwfn->p_main_ptt,
				     MISCS_REG_CHIP_NUM);
	cdev->chip_rev = (u16)qed_rd(p_hwfn, p_hwfn->p_main_ptt,
				     MISCS_REG_CHIP_REV);
	cdev->chip_num = (u16)qed_rd(p_hwfn, p_ptt, MISCS_REG_CHIP_NUM);
	cdev->chip_rev = (u16)qed_rd(p_hwfn, p_ptt, MISCS_REG_CHIP_REV);

	MASK_FIELD(CHIP_REV, cdev->chip_rev);

	/* Learn number of HW-functions */
	tmp = qed_rd(p_hwfn, p_hwfn->p_main_ptt,
		     MISCS_REG_CMT_ENABLED_FOR_PAIR);
	tmp = qed_rd(p_hwfn, p_ptt, MISCS_REG_CMT_ENABLED_FOR_PAIR);

	if (tmp & (1 << p_hwfn->rel_pf_id)) {
		DP_NOTICE(cdev->hwfns, "device in CMT mode\n");
@@ -2738,11 +2797,10 @@ static int qed_get_dev_info(struct qed_dev *cdev)
		cdev->num_hwfns = 1;
	}

	cdev->chip_bond_id = qed_rd(p_hwfn, p_hwfn->p_main_ptt,
	cdev->chip_bond_id = qed_rd(p_hwfn, p_ptt,
				    MISCS_REG_CHIP_TEST_REG) >> 4;
	MASK_FIELD(CHIP_BOND_ID, cdev->chip_bond_id);
	cdev->chip_metal = (u16)qed_rd(p_hwfn, p_hwfn->p_main_ptt,
				       MISCS_REG_CHIP_METAL);
	cdev->chip_metal = (u16)qed_rd(p_hwfn, p_ptt, MISCS_REG_CHIP_METAL);
	MASK_FIELD(CHIP_METAL, cdev->chip_metal);

	DP_INFO(cdev->hwfns,
@@ -2795,7 +2853,7 @@ static int qed_hw_prepare_single(struct qed_hwfn *p_hwfn,

	/* First hwfn learns basic information, e.g., number of hwfns */
	if (!p_hwfn->my_id) {
		rc = qed_get_dev_info(p_hwfn->cdev);
		rc = qed_get_dev_info(p_hwfn, p_hwfn->p_main_ptt);
		if (rc)
			goto err1;
	}
@@ -2866,11 +2924,14 @@ int qed_hw_prepare(struct qed_dev *cdev,
		u8 __iomem *addr;

		/* adjust bar offset for second engine */
		addr = cdev->regview + qed_hw_bar_size(p_hwfn, BAR_ID_0) / 2;
		addr = cdev->regview +
		       qed_hw_bar_size(p_hwfn, p_hwfn->p_main_ptt,
				       BAR_ID_0) / 2;
		p_regview = addr;

		/* adjust doorbell bar offset for second engine */
		addr = cdev->doorbells + qed_hw_bar_size(p_hwfn, BAR_ID_1) / 2;
		addr = cdev->doorbells +
		       qed_hw_bar_size(p_hwfn, p_hwfn->p_main_ptt,
				       BAR_ID_1) / 2;
		p_doorbell = addr;

		/* prepare second hw function */
+5 −3
Original line number Diff line number Diff line
@@ -165,17 +165,19 @@ int qed_hw_stop(struct qed_dev *cdev);
 *
 * @param cdev
 *
 * @return int
 */
void qed_hw_stop_fastpath(struct qed_dev *cdev);
int qed_hw_stop_fastpath(struct qed_dev *cdev);

/**
 * @brief qed_hw_start_fastpath -restart fastpath traffic,
 *		only if hw_stop_fastpath was called
 *
 * @param cdev
 * @param p_hwfn
 *
 * @return int
 */
void qed_hw_start_fastpath(struct qed_hwfn *p_hwfn);
int qed_hw_start_fastpath(struct qed_hwfn *p_hwfn);


/**
Loading