diff options
author | Sudarsana Reddy Kalluru <sudarsana.kalluru@cavium.com> | 2018-03-28 08:14:19 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-29 14:29:55 -0400 |
commit | 43645ce03e0063d7c4a5001215ca815188778881 (patch) | |
tree | 9233850122701dcde1d9a9caa5dfde626e124292 | |
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>
-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 { | |||
437 | BAR_ID_1 /* Used for doorbells */ | 437 | BAR_ID_1 /* Used for doorbells */ |
438 | }; | 438 | }; |
439 | 439 | ||
440 | struct 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 | ||
2935 | static 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 | |||
2935 | static int qed_hw_prepare_single(struct qed_hwfn *p_hwfn, | 2941 | static 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; |
3020 | err3: | ||
3021 | if (IS_LEAD_HWFN(p_hwfn)) | ||
3022 | qed_nvm_info_free(p_hwfn); | ||
3004 | err2: | 3023 | err2: |
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 | ||
3093 | static void qed_chain_free_next_ptr(struct qed_dev *cdev, | 3115 | 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) | |||
2303 | return rc; | 2303 | return rc; |
2304 | } | 2304 | } |
2305 | 2305 | ||
2306 | int qed_mcp_bist_nvm_test_get_num_images(struct qed_hwfn *p_hwfn, | 2306 | int 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 | ||
2327 | int qed_mcp_bist_nvm_test_get_image_att(struct qed_hwfn *p_hwfn, | 2327 | int 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 | ||
2354 | int 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 | } | ||
2400 | out: | ||
2401 | qed_ptt_release(p_hwfn, p_ptt); | ||
2402 | return 0; | ||
2403 | |||
2404 | err1: | ||
2405 | kfree(nvm_info->image_att); | ||
2406 | err0: | ||
2407 | qed_ptt_release(p_hwfn, p_ptt); | ||
2408 | return rc; | ||
2409 | } | ||
2410 | |||
2354 | static int | 2411 | static int |
2355 | qed_mcp_get_nvm_image_att(struct qed_hwfn *p_hwfn, | 2412 | qed_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 | */ |
499 | int qed_mcp_bist_nvm_test_get_num_images(struct qed_hwfn *p_hwfn, | 499 | int 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 | */ |
513 | int qed_mcp_bist_nvm_test_get_image_att(struct qed_hwfn *p_hwfn, | 513 | int 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 | */ |
959 | int qed_mcp_set_capabilities(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt); | 959 | int 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 | */ | ||
966 | int 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", |