aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSudarsana Reddy Kalluru <sudarsana.kalluru@cavium.com>2018-03-28 08:14:19 -0400
committerDavid S. Miller <davem@davemloft.net>2018-03-29 14:29:55 -0400
commit43645ce03e0063d7c4a5001215ca815188778881 (patch)
tree9233850122701dcde1d9a9caa5dfde626e124292
parent50bc60cb155c813157fdca5b3b05194cd325d3e9 (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>
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed.h8
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_dev.c24
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_mcp.c98
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_mcp.h22
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_selftest.c6
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 {
437 BAR_ID_1 /* Used for doorbells */ 437 BAR_ID_1 /* Used for doorbells */
438}; 438};
439 439
440struct qed_nvm_image_info {
441 u32 num_images;
442 struct bist_nvm_image_att *image_att;
443};
444
440#define DRV_MODULE_VERSION \ 445#define DRV_MODULE_VERSION \
441 __stringify(QED_MAJOR_VERSION) "." \ 446 __stringify(QED_MAJOR_VERSION) "." \
442 __stringify(QED_MINOR_VERSION) "." \ 447 __stringify(QED_MINOR_VERSION) "." \
@@ -561,6 +566,9 @@ struct qed_hwfn {
561 /* L2-related */ 566 /* L2-related */
562 struct qed_l2_info *p_l2_info; 567 struct qed_l2_info *p_l2_info;
563 568
569 /* Nvm images number and attributes */
570 struct qed_nvm_image_info nvm_info;
571
564 struct qed_ptt *p_arfs_ptt; 572 struct qed_ptt *p_arfs_ptt;
565 573
566 struct qed_simd_fp_handler simd_proto_handler[64]; 574 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)
2932 return 0; 2932 return 0;
2933} 2933}
2934 2934
2935static void qed_nvm_info_free(struct qed_hwfn *p_hwfn)
2936{
2937 kfree(p_hwfn->nvm_info.image_att);
2938 p_hwfn->nvm_info.image_att = NULL;
2939}
2940
2935static int qed_hw_prepare_single(struct qed_hwfn *p_hwfn, 2941static int qed_hw_prepare_single(struct qed_hwfn *p_hwfn,
2936 void __iomem *p_regview, 2942 void __iomem *p_regview,
2937 void __iomem *p_doorbells, 2943 void __iomem *p_doorbells,
@@ -2995,12 +3001,25 @@ static int qed_hw_prepare_single(struct qed_hwfn *p_hwfn,
2995 DP_NOTICE(p_hwfn, "Failed to initiate PF FLR\n"); 3001 DP_NOTICE(p_hwfn, "Failed to initiate PF FLR\n");
2996 } 3002 }
2997 3003
3004 /* NVRAM info initialization and population */
3005 if (IS_LEAD_HWFN(p_hwfn)) {
3006 rc = qed_mcp_nvm_info_populate(p_hwfn);
3007 if (rc) {
3008 DP_NOTICE(p_hwfn,
3009 "Failed to populate nvm info shadow\n");
3010 goto err2;
3011 }
3012 }
3013
2998 /* Allocate the init RT array and initialize the init-ops engine */ 3014 /* Allocate the init RT array and initialize the init-ops engine */
2999 rc = qed_init_alloc(p_hwfn); 3015 rc = qed_init_alloc(p_hwfn);
3000 if (rc) 3016 if (rc)
3001 goto err2; 3017 goto err3;
3002 3018
3003 return rc; 3019 return rc;
3020err3:
3021 if (IS_LEAD_HWFN(p_hwfn))
3022 qed_nvm_info_free(p_hwfn);
3004err2: 3023err2:
3005 if (IS_LEAD_HWFN(p_hwfn)) 3024 if (IS_LEAD_HWFN(p_hwfn))
3006 qed_iov_free_hw_info(p_hwfn->cdev); 3025 qed_iov_free_hw_info(p_hwfn->cdev);
@@ -3056,6 +3075,7 @@ int qed_hw_prepare(struct qed_dev *cdev,
3056 if (rc) { 3075 if (rc) {
3057 if (IS_PF(cdev)) { 3076 if (IS_PF(cdev)) {
3058 qed_init_free(p_hwfn); 3077 qed_init_free(p_hwfn);
3078 qed_nvm_info_free(p_hwfn);
3059 qed_mcp_free(p_hwfn); 3079 qed_mcp_free(p_hwfn);
3060 qed_hw_hwfn_free(p_hwfn); 3080 qed_hw_hwfn_free(p_hwfn);
3061 } 3081 }
@@ -3088,6 +3108,8 @@ void qed_hw_remove(struct qed_dev *cdev)
3088 } 3108 }
3089 3109
3090 qed_iov_free_hw_info(cdev); 3110 qed_iov_free_hw_info(cdev);
3111
3112 qed_nvm_info_free(p_hwfn);
3091} 3113}
3092 3114
3093static void qed_chain_free_next_ptr(struct qed_dev *cdev, 3115static 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)
2303 return rc; 2303 return rc;
2304} 2304}
2305 2305
2306int qed_mcp_bist_nvm_test_get_num_images(struct qed_hwfn *p_hwfn, 2306int qed_mcp_bist_nvm_get_num_images(struct qed_hwfn *p_hwfn,
2307 struct qed_ptt *p_ptt, 2307 struct qed_ptt *p_ptt,
2308 u32 *num_images) 2308 u32 *num_images)
2309{ 2309{
2310 u32 drv_mb_param = 0, rsp; 2310 u32 drv_mb_param = 0, rsp;
2311 int rc = 0; 2311 int rc = 0;
@@ -2324,10 +2324,10 @@ int qed_mcp_bist_nvm_test_get_num_images(struct qed_hwfn *p_hwfn,
2324 return rc; 2324 return rc;
2325} 2325}
2326 2326
2327int qed_mcp_bist_nvm_test_get_image_att(struct qed_hwfn *p_hwfn, 2327int qed_mcp_bist_nvm_get_image_att(struct qed_hwfn *p_hwfn,
2328 struct qed_ptt *p_ptt, 2328 struct qed_ptt *p_ptt,
2329 struct bist_nvm_image_att *p_image_att, 2329 struct bist_nvm_image_att *p_image_att,
2330 u32 image_index) 2330 u32 image_index)
2331{ 2331{
2332 u32 buf_size = 0, param, resp = 0, resp_param = 0; 2332 u32 buf_size = 0, param, resp = 0, resp_param = 0;
2333 int rc; 2333 int rc;
@@ -2351,16 +2351,71 @@ int qed_mcp_bist_nvm_test_get_image_att(struct qed_hwfn *p_hwfn,
2351 return rc; 2351 return rc;
2352} 2352}
2353 2353
2354int qed_mcp_nvm_info_populate(struct qed_hwfn *p_hwfn)
2355{
2356 struct qed_nvm_image_info *nvm_info = &p_hwfn->nvm_info;
2357 struct qed_ptt *p_ptt;
2358 int rc;
2359 u32 i;
2360
2361 p_ptt = qed_ptt_acquire(p_hwfn);
2362 if (!p_ptt) {
2363 DP_ERR(p_hwfn, "failed to acquire ptt\n");
2364 return -EBUSY;
2365 }
2366
2367 /* Acquire from MFW the amount of available images */
2368 nvm_info->num_images = 0;
2369 rc = qed_mcp_bist_nvm_get_num_images(p_hwfn,
2370 p_ptt, &nvm_info->num_images);
2371 if (rc == -EOPNOTSUPP) {
2372 DP_INFO(p_hwfn, "DRV_MSG_CODE_BIST_TEST is not supported\n");
2373 goto out;
2374 } else if (rc || !nvm_info->num_images) {
2375 DP_ERR(p_hwfn, "Failed getting number of images\n");
2376 goto err0;
2377 }
2378
2379 nvm_info->image_att = kmalloc(nvm_info->num_images *
2380 sizeof(struct bist_nvm_image_att),
2381 GFP_KERNEL);
2382 if (!nvm_info->image_att) {
2383 rc = -ENOMEM;
2384 goto err0;
2385 }
2386
2387 /* Iterate over images and get their attributes */
2388 for (i = 0; i < nvm_info->num_images; i++) {
2389 rc = qed_mcp_bist_nvm_get_image_att(p_hwfn, p_ptt,
2390 &nvm_info->image_att[i], i);
2391 if (rc) {
2392 DP_ERR(p_hwfn,
2393 "Failed getting image index %d attributes\n", i);
2394 goto err1;
2395 }
2396
2397 DP_VERBOSE(p_hwfn, QED_MSG_SP, "image index %d, size %x\n", i,
2398 nvm_info->image_att[i].len);
2399 }
2400out:
2401 qed_ptt_release(p_hwfn, p_ptt);
2402 return 0;
2403
2404err1:
2405 kfree(nvm_info->image_att);
2406err0:
2407 qed_ptt_release(p_hwfn, p_ptt);
2408 return rc;
2409}
2410
2354static int 2411static int
2355qed_mcp_get_nvm_image_att(struct qed_hwfn *p_hwfn, 2412qed_mcp_get_nvm_image_att(struct qed_hwfn *p_hwfn,
2356 struct qed_ptt *p_ptt, 2413 struct qed_ptt *p_ptt,
2357 enum qed_nvm_images image_id, 2414 enum qed_nvm_images image_id,
2358 struct qed_nvm_image_att *p_image_att) 2415 struct qed_nvm_image_att *p_image_att)
2359{ 2416{
2360 struct bist_nvm_image_att mfw_image_att;
2361 enum nvm_image_type type; 2417 enum nvm_image_type type;
2362 u32 num_images, i; 2418 u32 i;
2363 int rc;
2364 2419
2365 /* Translate image_id into MFW definitions */ 2420 /* Translate image_id into MFW definitions */
2366 switch (image_id) { 2421 switch (image_id) {
@@ -2376,29 +2431,18 @@ qed_mcp_get_nvm_image_att(struct qed_hwfn *p_hwfn,
2376 return -EINVAL; 2431 return -EINVAL;
2377 } 2432 }
2378 2433
2379 /* Learn number of images, then traverse and see if one fits */ 2434 for (i = 0; i < p_hwfn->nvm_info.num_images; i++)
2380 rc = qed_mcp_bist_nvm_test_get_num_images(p_hwfn, p_ptt, &num_images); 2435 if (type == p_hwfn->nvm_info.image_att[i].image_type)
2381 if (rc || !num_images)
2382 return -EINVAL;
2383
2384 for (i = 0; i < num_images; i++) {
2385 rc = qed_mcp_bist_nvm_test_get_image_att(p_hwfn, p_ptt,
2386 &mfw_image_att, i);
2387 if (rc)
2388 return rc;
2389
2390 if (type == mfw_image_att.image_type)
2391 break; 2436 break;
2392 } 2437 if (i == p_hwfn->nvm_info.num_images) {
2393 if (i == num_images) {
2394 DP_VERBOSE(p_hwfn, QED_MSG_STORAGE, 2438 DP_VERBOSE(p_hwfn, QED_MSG_STORAGE,
2395 "Failed to find nvram image of type %08x\n", 2439 "Failed to find nvram image of type %08x\n",
2396 image_id); 2440 image_id);
2397 return -EINVAL; 2441 return -ENOENT;
2398 } 2442 }
2399 2443
2400 p_image_att->start_addr = mfw_image_att.nvm_start_addr; 2444 p_image_att->start_addr = p_hwfn->nvm_info.image_att[i].nvm_start_addr;
2401 p_image_att->length = mfw_image_att.len; 2445 p_image_att->length = p_hwfn->nvm_info.image_att[i].len;
2402 2446
2403 return 0; 2447 return 0;
2404} 2448}
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,
496 * 496 *
497 * @return int - 0 - operation was successful. 497 * @return int - 0 - operation was successful.
498 */ 498 */
499int qed_mcp_bist_nvm_test_get_num_images(struct qed_hwfn *p_hwfn, 499int qed_mcp_bist_nvm_get_num_images(struct qed_hwfn *p_hwfn,
500 struct qed_ptt *p_ptt, 500 struct qed_ptt *p_ptt,
501 u32 *num_images); 501 u32 *num_images);
502 502
503/** 503/**
504 * @brief Bist nvm test - get image attributes by index 504 * @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,
510 * 510 *
511 * @return int - 0 - operation was successful. 511 * @return int - 0 - operation was successful.
512 */ 512 */
513int qed_mcp_bist_nvm_test_get_image_att(struct qed_hwfn *p_hwfn, 513int qed_mcp_bist_nvm_get_image_att(struct qed_hwfn *p_hwfn,
514 struct qed_ptt *p_ptt, 514 struct qed_ptt *p_ptt,
515 struct bist_nvm_image_att *p_image_att, 515 struct bist_nvm_image_att *p_image_att,
516 u32 image_index); 516 u32 image_index);
517 517
518/* Using hwfn number (and not pf_num) is required since in CMT mode, 518/* Using hwfn number (and not pf_num) is required since in CMT mode,
519 * same pf_num may be used by two different hwfn 519 * 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);
957 * @param p_ptt 957 * @param p_ptt
958 */ 958 */
959int qed_mcp_set_capabilities(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt); 959int qed_mcp_set_capabilities(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
960
961/**
962 * @brief Populate the nvm info shadow in the given hardware function
963 *
964 * @param p_hwfn
965 */
966int qed_mcp_nvm_info_populate(struct qed_hwfn *p_hwfn);
967
960#endif 968#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)
125 } 125 }
126 126
127 /* Acquire from MFW the amount of available images */ 127 /* Acquire from MFW the amount of available images */
128 rc = qed_mcp_bist_nvm_test_get_num_images(p_hwfn, p_ptt, &num_images); 128 rc = qed_mcp_bist_nvm_get_num_images(p_hwfn, p_ptt, &num_images);
129 if (rc || !num_images) { 129 if (rc || !num_images) {
130 DP_ERR(p_hwfn, "Failed getting number of images\n"); 130 DP_ERR(p_hwfn, "Failed getting number of images\n");
131 return -EINVAL; 131 return -EINVAL;
@@ -136,8 +136,8 @@ int qed_selftest_nvram(struct qed_dev *cdev)
136 /* This mailbox returns information about the image required for 136 /* This mailbox returns information about the image required for
137 * reading it. 137 * reading it.
138 */ 138 */
139 rc = qed_mcp_bist_nvm_test_get_image_att(p_hwfn, p_ptt, 139 rc = qed_mcp_bist_nvm_get_image_att(p_hwfn, p_ptt,
140 &image_att, i); 140 &image_att, i);
141 if (rc) { 141 if (rc) {
142 DP_ERR(p_hwfn, 142 DP_ERR(p_hwfn,
143 "Failed getting image index %d attributes\n", 143 "Failed getting image index %d attributes\n",