diff options
author | Sudarsana Reddy Kalluru | 2018-03-28 05:14:19 -0700 |
---|---|---|
committer | David S. Miller | 2018-03-29 14:29:55 -0400 |
commit | 43645ce03e0063d7c4a5001215ca815188778881 (patch) | |
tree | 9233850122701dcde1d9a9caa5dfde626e124292 /drivers | |
parent | 50bc60cb155c813157fdca5b3b05194cd325d3e9 (diff) |
qed: Populate nvm image attribute shadow.
This patch adds support for populating the flash image attributes.
Signed-off-by: Sudarsana Reddy Kalluru <Sudarsana.Kalluru@cavium.com>
Signed-off-by: Ariel Elior <ariel.elior@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed.h | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_dev.c | 24 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_mcp.c | 98 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_mcp.h | 22 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_selftest.c | 6 |
5 files changed, 120 insertions, 38 deletions
diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h index 69488554f4b9..b4094992299d 100644 --- a/drivers/net/ethernet/qlogic/qed/qed.h +++ b/drivers/net/ethernet/qlogic/qed/qed.h @@ -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]; diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c index de5527c0c1c7..d2ad5e92c74f 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c @@ -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, diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c index 6f46cb11f349..2519e71a3a2e 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c @@ -2303,9 +2303,9 @@ 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, - struct qed_ptt *p_ptt, - u32 *num_images) +int qed_mcp_bist_nvm_get_num_images(struct qed_hwfn *p_hwfn, + struct qed_ptt *p_ptt, + u32 *num_images) { u32 drv_mb_param = 0, rsp; int rc = 0; @@ -2324,10 +2324,10 @@ 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, - struct qed_ptt *p_ptt, - struct bist_nvm_image_att *p_image_att, - u32 image_index) +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) { u32 buf_size = 0, param, resp = 0, resp_param = 0; int rc; @@ -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; } diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.h b/drivers/net/ethernet/qlogic/qed/qed_mcp.h index c7ec2395d1ce..7d33354b11c6 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.h +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.h @@ -496,9 +496,9 @@ 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, - struct qed_ptt *p_ptt, - u32 *num_images); +int qed_mcp_bist_nvm_get_num_images(struct qed_hwfn *p_hwfn, + struct qed_ptt *p_ptt, + u32 *num_images); /** * @brief Bist nvm test - get image attributes by index @@ -510,10 +510,10 @@ 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, - struct qed_ptt *p_ptt, - struct bist_nvm_image_att *p_image_att, - u32 image_index); +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); /* Using hwfn number (and not pf_num) is required since in CMT mode, * same pf_num may be used by two different hwfn @@ -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 diff --git a/drivers/net/ethernet/qlogic/qed/qed_selftest.c b/drivers/net/ethernet/qlogic/qed/qed_selftest.c index 1bafc05db2b8..b88082f0b41a 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_selftest.c +++ b/drivers/net/ethernet/qlogic/qed/qed_selftest.c @@ -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,8 +136,8 @@ 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, - &image_att, i); + rc = qed_mcp_bist_nvm_get_image_att(p_hwfn, p_ptt, + &image_att, i); if (rc) { DP_ERR(p_hwfn, "Failed getting image index %d attributes\n", |