diff options
author | Sudarsana Reddy Kalluru <sudarsana.kalluru@cavium.com> | 2018-03-28 08:14:21 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-29 14:29:55 -0400 |
commit | 62e4d4386a954eb071ecd4a72105ea222157f11d (patch) | |
tree | f7754fd28e5ed9ad5674f30e4baceeb742185c0a | |
parent | d8bf47af24a28d90bbcd5d58d6dc6c5a40f4f91a (diff) |
qed: Add APIs for flash access.
This patch adds APIs for flash access.
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 | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_hsi.h | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_mcp.c | 121 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_mcp.h | 34 |
4 files changed, 168 insertions, 1 deletions
diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h index b4094992299d..e07460a68d30 100644 --- a/drivers/net/ethernet/qlogic/qed/qed.h +++ b/drivers/net/ethernet/qlogic/qed/qed.h | |||
@@ -81,6 +81,13 @@ enum qed_coalescing_mode { | |||
81 | QED_COAL_MODE_ENABLE | 81 | QED_COAL_MODE_ENABLE |
82 | }; | 82 | }; |
83 | 83 | ||
84 | enum qed_nvm_cmd { | ||
85 | QED_PUT_FILE_BEGIN = DRV_MSG_CODE_NVM_PUT_FILE_BEGIN, | ||
86 | QED_PUT_FILE_DATA = DRV_MSG_CODE_NVM_PUT_FILE_DATA, | ||
87 | QED_NVM_WRITE_NVRAM = DRV_MSG_CODE_NVM_WRITE_NVRAM, | ||
88 | QED_GET_MCP_NVM_RESP = 0xFFFFFF00 | ||
89 | }; | ||
90 | |||
84 | struct qed_eth_cb_ops; | 91 | struct qed_eth_cb_ops; |
85 | struct qed_dev_info; | 92 | struct qed_dev_info; |
86 | union qed_mcp_protocol_stats; | 93 | union qed_mcp_protocol_stats; |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h b/drivers/net/ethernet/qlogic/qed/qed_hsi.h index 2c6a679166e1..7f5ec42dde48 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h +++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h | |||
@@ -12268,8 +12268,11 @@ struct public_drv_mb { | |||
12268 | #define DRV_MSG_CODE_VF_DISABLED_DONE 0xc0000000 | 12268 | #define DRV_MSG_CODE_VF_DISABLED_DONE 0xc0000000 |
12269 | #define DRV_MSG_CODE_CFG_VF_MSIX 0xc0010000 | 12269 | #define DRV_MSG_CODE_CFG_VF_MSIX 0xc0010000 |
12270 | #define DRV_MSG_CODE_CFG_PF_VFS_MSIX 0xc0020000 | 12270 | #define DRV_MSG_CODE_CFG_PF_VFS_MSIX 0xc0020000 |
12271 | #define DRV_MSG_CODE_NVM_PUT_FILE_BEGIN 0x00010000 | ||
12272 | #define DRV_MSG_CODE_NVM_PUT_FILE_DATA 0x00020000 | ||
12271 | #define DRV_MSG_CODE_NVM_GET_FILE_ATT 0x00030000 | 12273 | #define DRV_MSG_CODE_NVM_GET_FILE_ATT 0x00030000 |
12272 | #define DRV_MSG_CODE_NVM_READ_NVRAM 0x00050000 | 12274 | #define DRV_MSG_CODE_NVM_READ_NVRAM 0x00050000 |
12275 | #define DRV_MSG_CODE_NVM_WRITE_NVRAM 0x00060000 | ||
12273 | #define DRV_MSG_CODE_MCP_RESET 0x00090000 | 12276 | #define DRV_MSG_CODE_MCP_RESET 0x00090000 |
12274 | #define DRV_MSG_CODE_SET_VERSION 0x000f0000 | 12277 | #define DRV_MSG_CODE_SET_VERSION 0x000f0000 |
12275 | #define DRV_MSG_CODE_MCP_HALT 0x00100000 | 12278 | #define DRV_MSG_CODE_MCP_HALT 0x00100000 |
@@ -12323,7 +12326,6 @@ struct public_drv_mb { | |||
12323 | 12326 | ||
12324 | #define DRV_MSG_CODE_FEATURE_SUPPORT 0x00300000 | 12327 | #define DRV_MSG_CODE_FEATURE_SUPPORT 0x00300000 |
12325 | #define DRV_MSG_CODE_GET_MFW_FEATURE_SUPPORT 0x00310000 | 12328 | #define DRV_MSG_CODE_GET_MFW_FEATURE_SUPPORT 0x00310000 |
12326 | |||
12327 | #define DRV_MSG_SEQ_NUMBER_MASK 0x0000ffff | 12329 | #define DRV_MSG_SEQ_NUMBER_MASK 0x0000ffff |
12328 | 12330 | ||
12329 | u32 drv_mb_param; | 12331 | u32 drv_mb_param; |
@@ -12435,7 +12437,10 @@ struct public_drv_mb { | |||
12435 | #define FW_MSG_CODE_DRV_CFG_VF_MSIX_DONE 0xb0010000 | 12437 | #define FW_MSG_CODE_DRV_CFG_VF_MSIX_DONE 0xb0010000 |
12436 | 12438 | ||
12437 | #define FW_MSG_CODE_NVM_OK 0x00010000 | 12439 | #define FW_MSG_CODE_NVM_OK 0x00010000 |
12440 | #define FW_MSG_CODE_NVM_PUT_FILE_FINISH_OK 0x00400000 | ||
12441 | #define FW_MSG_CODE_PHY_OK 0x00110000 | ||
12438 | #define FW_MSG_CODE_OK 0x00160000 | 12442 | #define FW_MSG_CODE_OK 0x00160000 |
12443 | #define FW_MSG_CODE_ERROR 0x00170000 | ||
12439 | 12444 | ||
12440 | #define FW_MSG_CODE_OS_WOL_SUPPORTED 0x00800000 | 12445 | #define FW_MSG_CODE_OS_WOL_SUPPORTED 0x00800000 |
12441 | #define FW_MSG_CODE_OS_WOL_NOT_SUPPORTED 0x00810000 | 12446 | #define FW_MSG_CODE_OS_WOL_NOT_SUPPORTED 0x00810000 |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c index 2519e71a3a2e..ec0d425766a7 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c | |||
@@ -569,6 +569,31 @@ int qed_mcp_cmd(struct qed_hwfn *p_hwfn, | |||
569 | return 0; | 569 | return 0; |
570 | } | 570 | } |
571 | 571 | ||
572 | int qed_mcp_nvm_wr_cmd(struct qed_hwfn *p_hwfn, | ||
573 | struct qed_ptt *p_ptt, | ||
574 | u32 cmd, | ||
575 | u32 param, | ||
576 | u32 *o_mcp_resp, | ||
577 | u32 *o_mcp_param, u32 i_txn_size, u32 *i_buf) | ||
578 | { | ||
579 | struct qed_mcp_mb_params mb_params; | ||
580 | int rc; | ||
581 | |||
582 | memset(&mb_params, 0, sizeof(mb_params)); | ||
583 | mb_params.cmd = cmd; | ||
584 | mb_params.param = param; | ||
585 | mb_params.p_data_src = i_buf; | ||
586 | mb_params.data_src_size = (u8)i_txn_size; | ||
587 | rc = qed_mcp_cmd_and_union(p_hwfn, p_ptt, &mb_params); | ||
588 | if (rc) | ||
589 | return rc; | ||
590 | |||
591 | *o_mcp_resp = mb_params.mcp_resp; | ||
592 | *o_mcp_param = mb_params.mcp_param; | ||
593 | |||
594 | return 0; | ||
595 | } | ||
596 | |||
572 | int qed_mcp_nvm_rd_cmd(struct qed_hwfn *p_hwfn, | 597 | int qed_mcp_nvm_rd_cmd(struct qed_hwfn *p_hwfn, |
573 | struct qed_ptt *p_ptt, | 598 | struct qed_ptt *p_ptt, |
574 | u32 cmd, | 599 | u32 cmd, |
@@ -2261,6 +2286,102 @@ int qed_mcp_nvm_read(struct qed_dev *cdev, u32 addr, u8 *p_buf, u32 len) | |||
2261 | return rc; | 2286 | return rc; |
2262 | } | 2287 | } |
2263 | 2288 | ||
2289 | int qed_mcp_nvm_resp(struct qed_dev *cdev, u8 *p_buf) | ||
2290 | { | ||
2291 | struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev); | ||
2292 | struct qed_ptt *p_ptt; | ||
2293 | |||
2294 | p_ptt = qed_ptt_acquire(p_hwfn); | ||
2295 | if (!p_ptt) | ||
2296 | return -EBUSY; | ||
2297 | |||
2298 | memcpy(p_buf, &cdev->mcp_nvm_resp, sizeof(cdev->mcp_nvm_resp)); | ||
2299 | qed_ptt_release(p_hwfn, p_ptt); | ||
2300 | |||
2301 | return 0; | ||
2302 | } | ||
2303 | |||
2304 | int qed_mcp_nvm_put_file_begin(struct qed_dev *cdev, u32 addr) | ||
2305 | { | ||
2306 | struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev); | ||
2307 | struct qed_ptt *p_ptt; | ||
2308 | u32 resp, param; | ||
2309 | int rc; | ||
2310 | |||
2311 | p_ptt = qed_ptt_acquire(p_hwfn); | ||
2312 | if (!p_ptt) | ||
2313 | return -EBUSY; | ||
2314 | rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_NVM_PUT_FILE_BEGIN, addr, | ||
2315 | &resp, ¶m); | ||
2316 | cdev->mcp_nvm_resp = resp; | ||
2317 | qed_ptt_release(p_hwfn, p_ptt); | ||
2318 | |||
2319 | return rc; | ||
2320 | } | ||
2321 | |||
2322 | int qed_mcp_nvm_write(struct qed_dev *cdev, | ||
2323 | u32 cmd, u32 addr, u8 *p_buf, u32 len) | ||
2324 | { | ||
2325 | u32 buf_idx = 0, buf_size, nvm_cmd, nvm_offset, resp = 0, param; | ||
2326 | struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev); | ||
2327 | struct qed_ptt *p_ptt; | ||
2328 | int rc = -EINVAL; | ||
2329 | |||
2330 | p_ptt = qed_ptt_acquire(p_hwfn); | ||
2331 | if (!p_ptt) | ||
2332 | return -EBUSY; | ||
2333 | |||
2334 | switch (cmd) { | ||
2335 | case QED_PUT_FILE_DATA: | ||
2336 | nvm_cmd = DRV_MSG_CODE_NVM_PUT_FILE_DATA; | ||
2337 | break; | ||
2338 | case QED_NVM_WRITE_NVRAM: | ||
2339 | nvm_cmd = DRV_MSG_CODE_NVM_WRITE_NVRAM; | ||
2340 | break; | ||
2341 | default: | ||
2342 | DP_NOTICE(p_hwfn, "Invalid nvm write command 0x%x\n", cmd); | ||
2343 | rc = -EINVAL; | ||
2344 | goto out; | ||
2345 | } | ||
2346 | |||
2347 | while (buf_idx < len) { | ||
2348 | buf_size = min_t(u32, (len - buf_idx), MCP_DRV_NVM_BUF_LEN); | ||
2349 | nvm_offset = ((buf_size << DRV_MB_PARAM_NVM_LEN_OFFSET) | | ||
2350 | addr) + buf_idx; | ||
2351 | rc = qed_mcp_nvm_wr_cmd(p_hwfn, p_ptt, nvm_cmd, nvm_offset, | ||
2352 | &resp, ¶m, buf_size, | ||
2353 | (u32 *)&p_buf[buf_idx]); | ||
2354 | if (rc) { | ||
2355 | DP_NOTICE(cdev, "nvm write failed, rc = %d\n", rc); | ||
2356 | resp = FW_MSG_CODE_ERROR; | ||
2357 | break; | ||
2358 | } | ||
2359 | |||
2360 | if (resp != FW_MSG_CODE_OK && | ||
2361 | resp != FW_MSG_CODE_NVM_OK && | ||
2362 | resp != FW_MSG_CODE_NVM_PUT_FILE_FINISH_OK) { | ||
2363 | DP_NOTICE(cdev, | ||
2364 | "nvm write failed, resp = 0x%08x\n", resp); | ||
2365 | rc = -EINVAL; | ||
2366 | break; | ||
2367 | } | ||
2368 | |||
2369 | /* This can be a lengthy process, and it's possible scheduler | ||
2370 | * isn't pre-emptable. Sleep a bit to prevent CPU hogging. | ||
2371 | */ | ||
2372 | if (buf_idx % 0x1000 > (buf_idx + buf_size) % 0x1000) | ||
2373 | usleep_range(1000, 2000); | ||
2374 | |||
2375 | buf_idx += buf_size; | ||
2376 | } | ||
2377 | |||
2378 | cdev->mcp_nvm_resp = resp; | ||
2379 | out: | ||
2380 | qed_ptt_release(p_hwfn, p_ptt); | ||
2381 | |||
2382 | return rc; | ||
2383 | } | ||
2384 | |||
2264 | int qed_mcp_bist_register_test(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) | 2385 | int qed_mcp_bist_register_test(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) |
2265 | { | 2386 | { |
2266 | u32 drv_mb_param = 0, rsp, param; | 2387 | u32 drv_mb_param = 0, rsp, param; |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.h b/drivers/net/ethernet/qlogic/qed/qed_mcp.h index 7d33354b11c6..8a5c988d0c3c 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.h +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.h | |||
@@ -443,6 +443,40 @@ int qed_mcp_set_led(struct qed_hwfn *p_hwfn, | |||
443 | */ | 443 | */ |
444 | int qed_mcp_nvm_read(struct qed_dev *cdev, u32 addr, u8 *p_buf, u32 len); | 444 | int qed_mcp_nvm_read(struct qed_dev *cdev, u32 addr, u8 *p_buf, u32 len); |
445 | 445 | ||
446 | /** | ||
447 | * @brief Write to nvm | ||
448 | * | ||
449 | * @param cdev | ||
450 | * @param addr - nvm offset | ||
451 | * @param cmd - nvm command | ||
452 | * @param p_buf - nvm write buffer | ||
453 | * @param len - buffer len | ||
454 | * | ||
455 | * @return int - 0 - operation was successful. | ||
456 | */ | ||
457 | int qed_mcp_nvm_write(struct qed_dev *cdev, | ||
458 | u32 cmd, u32 addr, u8 *p_buf, u32 len); | ||
459 | |||
460 | /** | ||
461 | * @brief Put file begin | ||
462 | * | ||
463 | * @param cdev | ||
464 | * @param addr - nvm offset | ||
465 | * | ||
466 | * @return int - 0 - operation was successful. | ||
467 | */ | ||
468 | int qed_mcp_nvm_put_file_begin(struct qed_dev *cdev, u32 addr); | ||
469 | |||
470 | /** | ||
471 | * @brief Check latest response | ||
472 | * | ||
473 | * @param cdev | ||
474 | * @param p_buf - nvm write buffer | ||
475 | * | ||
476 | * @return int - 0 - operation was successful. | ||
477 | */ | ||
478 | int qed_mcp_nvm_resp(struct qed_dev *cdev, u8 *p_buf); | ||
479 | |||
446 | struct qed_nvm_image_att { | 480 | struct qed_nvm_image_att { |
447 | u32 start_addr; | 481 | u32 start_addr; |
448 | u32 length; | 482 | u32 length; |