Commit 43645ce0 authored by Sudarsana Reddy Kalluru's avatar Sudarsana Reddy Kalluru Committed by David S. Miller
Browse files

qed: Populate nvm image attribute shadow.



This patch adds support for populating the flash image attributes.

Signed-off-by: default avatarSudarsana Reddy Kalluru <Sudarsana.Kalluru@cavium.com>
Signed-off-by: default avatarAriel Elior <ariel.elior@cavium.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 50bc60cb
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -437,6 +437,11 @@ enum BAR_ID {
	BAR_ID_1		/* Used for doorbells */
};

struct qed_nvm_image_info {
	u32 num_images;
	struct bist_nvm_image_att *image_att;
};

#define DRV_MODULE_VERSION		      \
	__stringify(QED_MAJOR_VERSION) "."    \
	__stringify(QED_MINOR_VERSION) "."    \
@@ -561,6 +566,9 @@ struct qed_hwfn {
	/* L2-related */
	struct qed_l2_info *p_l2_info;

	/* Nvm images number and attributes */
	struct qed_nvm_image_info nvm_info;

	struct qed_ptt *p_arfs_ptt;

	struct qed_simd_fp_handler	simd_proto_handler[64];
+23 −1
Original line number Diff line number Diff line
@@ -2932,6 +2932,12 @@ static int qed_get_dev_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
	return 0;
}

static void qed_nvm_info_free(struct qed_hwfn *p_hwfn)
{
	kfree(p_hwfn->nvm_info.image_att);
	p_hwfn->nvm_info.image_att = NULL;
}

static int qed_hw_prepare_single(struct qed_hwfn *p_hwfn,
				 void __iomem *p_regview,
				 void __iomem *p_doorbells,
@@ -2995,12 +3001,25 @@ static int qed_hw_prepare_single(struct qed_hwfn *p_hwfn,
			DP_NOTICE(p_hwfn, "Failed to initiate PF FLR\n");
	}

	/* NVRAM info initialization and population */
	if (IS_LEAD_HWFN(p_hwfn)) {
		rc = qed_mcp_nvm_info_populate(p_hwfn);
		if (rc) {
			DP_NOTICE(p_hwfn,
				  "Failed to populate nvm info shadow\n");
			goto err2;
		}
	}

	/* Allocate the init RT array and initialize the init-ops engine */
	rc = qed_init_alloc(p_hwfn);
	if (rc)
		goto err2;
		goto err3;

	return rc;
err3:
	if (IS_LEAD_HWFN(p_hwfn))
		qed_nvm_info_free(p_hwfn);
err2:
	if (IS_LEAD_HWFN(p_hwfn))
		qed_iov_free_hw_info(p_hwfn->cdev);
@@ -3056,6 +3075,7 @@ int qed_hw_prepare(struct qed_dev *cdev,
		if (rc) {
			if (IS_PF(cdev)) {
				qed_init_free(p_hwfn);
				qed_nvm_info_free(p_hwfn);
				qed_mcp_free(p_hwfn);
				qed_hw_hwfn_free(p_hwfn);
			}
@@ -3088,6 +3108,8 @@ void qed_hw_remove(struct qed_dev *cdev)
	}

	qed_iov_free_hw_info(cdev);

	qed_nvm_info_free(p_hwfn);
}

static void qed_chain_free_next_ptr(struct qed_dev *cdev,
+71 −27
Original line number Diff line number Diff line
@@ -2303,7 +2303,7 @@ int qed_mcp_bist_clock_test(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
	return rc;
}

int qed_mcp_bist_nvm_test_get_num_images(struct qed_hwfn *p_hwfn,
int qed_mcp_bist_nvm_get_num_images(struct qed_hwfn *p_hwfn,
				    struct qed_ptt *p_ptt,
				    u32 *num_images)
{
@@ -2324,7 +2324,7 @@ int qed_mcp_bist_nvm_test_get_num_images(struct qed_hwfn *p_hwfn,
	return rc;
}

int qed_mcp_bist_nvm_test_get_image_att(struct qed_hwfn *p_hwfn,
int qed_mcp_bist_nvm_get_image_att(struct qed_hwfn *p_hwfn,
				   struct qed_ptt *p_ptt,
				   struct bist_nvm_image_att *p_image_att,
				   u32 image_index)
@@ -2351,16 +2351,71 @@ int qed_mcp_bist_nvm_test_get_image_att(struct qed_hwfn *p_hwfn,
	return rc;
}

int qed_mcp_nvm_info_populate(struct qed_hwfn *p_hwfn)
{
	struct qed_nvm_image_info *nvm_info = &p_hwfn->nvm_info;
	struct qed_ptt *p_ptt;
	int rc;
	u32 i;

	p_ptt = qed_ptt_acquire(p_hwfn);
	if (!p_ptt) {
		DP_ERR(p_hwfn, "failed to acquire ptt\n");
		return -EBUSY;
	}

	/* Acquire from MFW the amount of available images */
	nvm_info->num_images = 0;
	rc = qed_mcp_bist_nvm_get_num_images(p_hwfn,
					     p_ptt, &nvm_info->num_images);
	if (rc == -EOPNOTSUPP) {
		DP_INFO(p_hwfn, "DRV_MSG_CODE_BIST_TEST is not supported\n");
		goto out;
	} else if (rc || !nvm_info->num_images) {
		DP_ERR(p_hwfn, "Failed getting number of images\n");
		goto err0;
	}

	nvm_info->image_att = kmalloc(nvm_info->num_images *
				      sizeof(struct bist_nvm_image_att),
				      GFP_KERNEL);
	if (!nvm_info->image_att) {
		rc = -ENOMEM;
		goto err0;
	}

	/* Iterate over images and get their attributes */
	for (i = 0; i < nvm_info->num_images; i++) {
		rc = qed_mcp_bist_nvm_get_image_att(p_hwfn, p_ptt,
						    &nvm_info->image_att[i], i);
		if (rc) {
			DP_ERR(p_hwfn,
			       "Failed getting image index %d attributes\n", i);
			goto err1;
		}

		DP_VERBOSE(p_hwfn, QED_MSG_SP, "image index %d, size %x\n", i,
			   nvm_info->image_att[i].len);
	}
out:
	qed_ptt_release(p_hwfn, p_ptt);
	return 0;

err1:
	kfree(nvm_info->image_att);
err0:
	qed_ptt_release(p_hwfn, p_ptt);
	return rc;
}

static int
qed_mcp_get_nvm_image_att(struct qed_hwfn *p_hwfn,
			  struct qed_ptt *p_ptt,
			  enum qed_nvm_images image_id,
			  struct qed_nvm_image_att *p_image_att)
{
	struct bist_nvm_image_att mfw_image_att;
	enum nvm_image_type type;
	u32 num_images, i;
	int rc;
	u32 i;

	/* Translate image_id into MFW definitions */
	switch (image_id) {
@@ -2376,29 +2431,18 @@ qed_mcp_get_nvm_image_att(struct qed_hwfn *p_hwfn,
		return -EINVAL;
	}

	/* Learn number of images, then traverse and see if one fits */
	rc = qed_mcp_bist_nvm_test_get_num_images(p_hwfn, p_ptt, &num_images);
	if (rc || !num_images)
		return -EINVAL;

	for (i = 0; i < num_images; i++) {
		rc = qed_mcp_bist_nvm_test_get_image_att(p_hwfn, p_ptt,
							 &mfw_image_att, i);
		if (rc)
			return rc;

		if (type == mfw_image_att.image_type)
	for (i = 0; i < p_hwfn->nvm_info.num_images; i++)
		if (type == p_hwfn->nvm_info.image_att[i].image_type)
			break;
	}
	if (i == num_images) {
	if (i == p_hwfn->nvm_info.num_images) {
		DP_VERBOSE(p_hwfn, QED_MSG_STORAGE,
			   "Failed to find nvram image of type %08x\n",
			   image_id);
		return -EINVAL;
		return -ENOENT;
	}

	p_image_att->start_addr = mfw_image_att.nvm_start_addr;
	p_image_att->length = mfw_image_att.len;
	p_image_att->start_addr = p_hwfn->nvm_info.image_att[i].nvm_start_addr;
	p_image_att->length = p_hwfn->nvm_info.image_att[i].len;

	return 0;
}
+15 −7
Original line number Diff line number Diff line
@@ -496,7 +496,7 @@ int qed_mcp_bist_clock_test(struct qed_hwfn *p_hwfn,
 *
 * @return int - 0 - operation was successful.
 */
int qed_mcp_bist_nvm_test_get_num_images(struct qed_hwfn *p_hwfn,
int qed_mcp_bist_nvm_get_num_images(struct qed_hwfn *p_hwfn,
				    struct qed_ptt *p_ptt,
				    u32 *num_images);

@@ -510,7 +510,7 @@ int qed_mcp_bist_nvm_test_get_num_images(struct qed_hwfn *p_hwfn,
 *
 * @return int - 0 - operation was successful.
 */
int qed_mcp_bist_nvm_test_get_image_att(struct qed_hwfn *p_hwfn,
int qed_mcp_bist_nvm_get_image_att(struct qed_hwfn *p_hwfn,
				   struct qed_ptt *p_ptt,
				   struct bist_nvm_image_att *p_image_att,
				   u32 image_index);
@@ -957,4 +957,12 @@ int qed_mcp_get_capabilities(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
 * @param p_ptt
 */
int qed_mcp_set_capabilities(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);

/**
 * @brief Populate the nvm info shadow in the given hardware function
 *
 * @param p_hwfn
 */
int qed_mcp_nvm_info_populate(struct qed_hwfn *p_hwfn);

#endif
+3 −3
Original line number Diff line number Diff line
@@ -125,7 +125,7 @@ int qed_selftest_nvram(struct qed_dev *cdev)
	}

	/* Acquire from MFW the amount of available images */
	rc = qed_mcp_bist_nvm_test_get_num_images(p_hwfn, p_ptt, &num_images);
	rc = qed_mcp_bist_nvm_get_num_images(p_hwfn, p_ptt, &num_images);
	if (rc || !num_images) {
		DP_ERR(p_hwfn, "Failed getting number of images\n");
		return -EINVAL;
@@ -136,7 +136,7 @@ int qed_selftest_nvram(struct qed_dev *cdev)
		/* This mailbox returns information about the image required for
		 * reading it.
		 */
		rc = qed_mcp_bist_nvm_test_get_image_att(p_hwfn, p_ptt,
		rc = qed_mcp_bist_nvm_get_image_att(p_hwfn, p_ptt,
						    &image_att, i);
		if (rc) {
			DP_ERR(p_hwfn,