aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSudarsana Reddy Kalluru <sudarsana.kalluru@cavium.com>2018-03-28 08:14:21 -0400
committerDavid S. Miller <davem@davemloft.net>2018-03-29 14:29:55 -0400
commit62e4d4386a954eb071ecd4a72105ea222157f11d (patch)
treef7754fd28e5ed9ad5674f30e4baceeb742185c0a
parentd8bf47af24a28d90bbcd5d58d6dc6c5a40f4f91a (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.h7
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_hsi.h7
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_mcp.c121
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_mcp.h34
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
84enum 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
84struct qed_eth_cb_ops; 91struct qed_eth_cb_ops;
85struct qed_dev_info; 92struct qed_dev_info;
86union qed_mcp_protocol_stats; 93union 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
572int 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
572int qed_mcp_nvm_rd_cmd(struct qed_hwfn *p_hwfn, 597int 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
2289int 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
2304int 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, &param);
2316 cdev->mcp_nvm_resp = resp;
2317 qed_ptt_release(p_hwfn, p_ptt);
2318
2319 return rc;
2320}
2321
2322int 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, &param, 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;
2379out:
2380 qed_ptt_release(p_hwfn, p_ptt);
2381
2382 return rc;
2383}
2384
2264int qed_mcp_bist_register_test(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) 2385int 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 */
444int qed_mcp_nvm_read(struct qed_dev *cdev, u32 addr, u8 *p_buf, u32 len); 444int 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 */
457int 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 */
468int 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 */
478int qed_mcp_nvm_resp(struct qed_dev *cdev, u8 *p_buf);
479
446struct qed_nvm_image_att { 480struct qed_nvm_image_att {
447 u32 start_addr; 481 u32 start_addr;
448 u32 length; 482 u32 length;