diff options
author | Sudarsana Reddy Kalluru <sudarsana.kalluru@cavium.com> | 2018-07-18 09:27:22 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-07-20 02:35:37 -0400 |
commit | b51dab46c6adfbb7e80cd0f59ae17b8a30d94b1a (patch) | |
tree | 021ba3aaa7dac05ada2c0a2539b3142a936faff0 | |
parent | 57dc2bfc334aef84364d4939205fb86c6473b13a (diff) |
qed: Add qed APIs for PHY module query.
This patch adds qed APIs for reading the PHY module.
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_hsi.h | 16 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_main.c | 23 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_mcp.c | 49 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_mcp.h | 16 | ||||
-rw-r--r-- | include/linux/qed/qed_if.h | 15 |
5 files changed, 119 insertions, 0 deletions
diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h b/drivers/net/ethernet/qlogic/qed/qed_hsi.h index bee10c1781fb..8faceb691657 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h +++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h | |||
@@ -12444,6 +12444,8 @@ struct public_drv_mb { | |||
12444 | #define DRV_MSG_CODE_STATS_TYPE_ISCSI 3 | 12444 | #define DRV_MSG_CODE_STATS_TYPE_ISCSI 3 |
12445 | #define DRV_MSG_CODE_STATS_TYPE_RDMA 4 | 12445 | #define DRV_MSG_CODE_STATS_TYPE_RDMA 4 |
12446 | 12446 | ||
12447 | #define DRV_MSG_CODE_TRANSCEIVER_READ 0x00160000 | ||
12448 | |||
12447 | #define DRV_MSG_CODE_MASK_PARITIES 0x001a0000 | 12449 | #define DRV_MSG_CODE_MASK_PARITIES 0x001a0000 |
12448 | 12450 | ||
12449 | #define DRV_MSG_CODE_BIST_TEST 0x001e0000 | 12451 | #define DRV_MSG_CODE_BIST_TEST 0x001e0000 |
@@ -12543,6 +12545,15 @@ struct public_drv_mb { | |||
12543 | #define DRV_MB_PARAM_SET_LED_MODE_ON 0x1 | 12545 | #define DRV_MB_PARAM_SET_LED_MODE_ON 0x1 |
12544 | #define DRV_MB_PARAM_SET_LED_MODE_OFF 0x2 | 12546 | #define DRV_MB_PARAM_SET_LED_MODE_OFF 0x2 |
12545 | 12547 | ||
12548 | #define DRV_MB_PARAM_TRANSCEIVER_PORT_OFFSET 0 | ||
12549 | #define DRV_MB_PARAM_TRANSCEIVER_PORT_MASK 0x00000003 | ||
12550 | #define DRV_MB_PARAM_TRANSCEIVER_SIZE_OFFSET 2 | ||
12551 | #define DRV_MB_PARAM_TRANSCEIVER_SIZE_MASK 0x000000FC | ||
12552 | #define DRV_MB_PARAM_TRANSCEIVER_I2C_ADDRESS_OFFSET 8 | ||
12553 | #define DRV_MB_PARAM_TRANSCEIVER_I2C_ADDRESS_MASK 0x0000FF00 | ||
12554 | #define DRV_MB_PARAM_TRANSCEIVER_OFFSET_OFFSET 16 | ||
12555 | #define DRV_MB_PARAM_TRANSCEIVER_OFFSET_MASK 0xFFFF0000 | ||
12556 | |||
12546 | /* Resource Allocation params - Driver version support */ | 12557 | /* Resource Allocation params - Driver version support */ |
12547 | #define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_MASK 0xFFFF0000 | 12558 | #define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_MASK 0xFFFF0000 |
12548 | #define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_SHIFT 16 | 12559 | #define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_SHIFT 16 |
@@ -12596,6 +12607,9 @@ struct public_drv_mb { | |||
12596 | #define FW_MSG_CODE_PHY_OK 0x00110000 | 12607 | #define FW_MSG_CODE_PHY_OK 0x00110000 |
12597 | #define FW_MSG_CODE_OK 0x00160000 | 12608 | #define FW_MSG_CODE_OK 0x00160000 |
12598 | #define FW_MSG_CODE_ERROR 0x00170000 | 12609 | #define FW_MSG_CODE_ERROR 0x00170000 |
12610 | #define FW_MSG_CODE_TRANSCEIVER_DIAG_OK 0x00160000 | ||
12611 | #define FW_MSG_CODE_TRANSCEIVER_DIAG_ERROR 0x00170000 | ||
12612 | #define FW_MSG_CODE_TRANSCEIVER_NOT_PRESENT 0x00020000 | ||
12599 | 12613 | ||
12600 | #define FW_MSG_CODE_OS_WOL_SUPPORTED 0x00800000 | 12614 | #define FW_MSG_CODE_OS_WOL_SUPPORTED 0x00800000 |
12601 | #define FW_MSG_CODE_OS_WOL_NOT_SUPPORTED 0x00810000 | 12615 | #define FW_MSG_CODE_OS_WOL_NOT_SUPPORTED 0x00810000 |
@@ -12687,6 +12701,8 @@ struct mcp_public_data { | |||
12687 | struct public_func func[MCP_GLOB_FUNC_MAX]; | 12701 | struct public_func func[MCP_GLOB_FUNC_MAX]; |
12688 | }; | 12702 | }; |
12689 | 12703 | ||
12704 | #define MAX_I2C_TRANSACTION_SIZE 16 | ||
12705 | |||
12690 | /* OCBB definitions */ | 12706 | /* OCBB definitions */ |
12691 | enum tlvs { | 12707 | enum tlvs { |
12692 | /* Category 1: Device Properties */ | 12708 | /* Category 1: Device Properties */ |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c index 0cbc74d6ca8b..158944aa6097 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_main.c +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c | |||
@@ -2102,6 +2102,28 @@ out: | |||
2102 | return status; | 2102 | return status; |
2103 | } | 2103 | } |
2104 | 2104 | ||
2105 | static int qed_read_module_eeprom(struct qed_dev *cdev, char *buf, | ||
2106 | u8 dev_addr, u32 offset, u32 len) | ||
2107 | { | ||
2108 | struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); | ||
2109 | struct qed_ptt *ptt; | ||
2110 | int rc = 0; | ||
2111 | |||
2112 | if (IS_VF(cdev)) | ||
2113 | return 0; | ||
2114 | |||
2115 | ptt = qed_ptt_acquire(hwfn); | ||
2116 | if (!ptt) | ||
2117 | return -EAGAIN; | ||
2118 | |||
2119 | rc = qed_mcp_phy_sfp_read(hwfn, ptt, MFW_PORT(hwfn), dev_addr, | ||
2120 | offset, len, buf); | ||
2121 | |||
2122 | qed_ptt_release(hwfn, ptt); | ||
2123 | |||
2124 | return rc; | ||
2125 | } | ||
2126 | |||
2105 | static struct qed_selftest_ops qed_selftest_ops_pass = { | 2127 | static struct qed_selftest_ops qed_selftest_ops_pass = { |
2106 | .selftest_memory = &qed_selftest_memory, | 2128 | .selftest_memory = &qed_selftest_memory, |
2107 | .selftest_interrupt = &qed_selftest_interrupt, | 2129 | .selftest_interrupt = &qed_selftest_interrupt, |
@@ -2144,6 +2166,7 @@ const struct qed_common_ops qed_common_ops_pass = { | |||
2144 | .update_mac = &qed_update_mac, | 2166 | .update_mac = &qed_update_mac, |
2145 | .update_mtu = &qed_update_mtu, | 2167 | .update_mtu = &qed_update_mtu, |
2146 | .update_wol = &qed_update_wol, | 2168 | .update_wol = &qed_update_wol, |
2169 | .read_module_eeprom = &qed_read_module_eeprom, | ||
2147 | }; | 2170 | }; |
2148 | 2171 | ||
2149 | void qed_get_protocol_stats(struct qed_dev *cdev, | 2172 | void qed_get_protocol_stats(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 4e0b443c9519..62a220fce6e1 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c | |||
@@ -2463,6 +2463,55 @@ out: | |||
2463 | return rc; | 2463 | return rc; |
2464 | } | 2464 | } |
2465 | 2465 | ||
2466 | int qed_mcp_phy_sfp_read(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, | ||
2467 | u32 port, u32 addr, u32 offset, u32 len, u8 *p_buf) | ||
2468 | { | ||
2469 | u32 bytes_left, bytes_to_copy, buf_size, nvm_offset = 0; | ||
2470 | u32 resp, param; | ||
2471 | int rc; | ||
2472 | |||
2473 | nvm_offset |= (port << DRV_MB_PARAM_TRANSCEIVER_PORT_OFFSET) & | ||
2474 | DRV_MB_PARAM_TRANSCEIVER_PORT_MASK; | ||
2475 | nvm_offset |= (addr << DRV_MB_PARAM_TRANSCEIVER_I2C_ADDRESS_OFFSET) & | ||
2476 | DRV_MB_PARAM_TRANSCEIVER_I2C_ADDRESS_MASK; | ||
2477 | |||
2478 | addr = offset; | ||
2479 | offset = 0; | ||
2480 | bytes_left = len; | ||
2481 | while (bytes_left > 0) { | ||
2482 | bytes_to_copy = min_t(u32, bytes_left, | ||
2483 | MAX_I2C_TRANSACTION_SIZE); | ||
2484 | nvm_offset &= (DRV_MB_PARAM_TRANSCEIVER_I2C_ADDRESS_MASK | | ||
2485 | DRV_MB_PARAM_TRANSCEIVER_PORT_MASK); | ||
2486 | nvm_offset |= ((addr + offset) << | ||
2487 | DRV_MB_PARAM_TRANSCEIVER_OFFSET_OFFSET) & | ||
2488 | DRV_MB_PARAM_TRANSCEIVER_OFFSET_MASK; | ||
2489 | nvm_offset |= (bytes_to_copy << | ||
2490 | DRV_MB_PARAM_TRANSCEIVER_SIZE_OFFSET) & | ||
2491 | DRV_MB_PARAM_TRANSCEIVER_SIZE_MASK; | ||
2492 | rc = qed_mcp_nvm_rd_cmd(p_hwfn, p_ptt, | ||
2493 | DRV_MSG_CODE_TRANSCEIVER_READ, | ||
2494 | nvm_offset, &resp, ¶m, &buf_size, | ||
2495 | (u32 *)(p_buf + offset)); | ||
2496 | if (rc) { | ||
2497 | DP_NOTICE(p_hwfn, | ||
2498 | "Failed to send a transceiver read command to the MFW. rc = %d.\n", | ||
2499 | rc); | ||
2500 | return rc; | ||
2501 | } | ||
2502 | |||
2503 | if (resp == FW_MSG_CODE_TRANSCEIVER_NOT_PRESENT) | ||
2504 | return -ENODEV; | ||
2505 | else if (resp != FW_MSG_CODE_TRANSCEIVER_DIAG_OK) | ||
2506 | return -EINVAL; | ||
2507 | |||
2508 | offset += buf_size; | ||
2509 | bytes_left -= buf_size; | ||
2510 | } | ||
2511 | |||
2512 | return 0; | ||
2513 | } | ||
2514 | |||
2466 | int qed_mcp_bist_register_test(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) | 2515 | int qed_mcp_bist_register_test(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) |
2467 | { | 2516 | { |
2468 | u32 drv_mb_param = 0, rsp, param; | 2517 | 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 632a838f1fe3..047976d5c6e9 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.h +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.h | |||
@@ -840,6 +840,22 @@ int qed_mcp_nvm_rd_cmd(struct qed_hwfn *p_hwfn, | |||
840 | u32 *o_mcp_param, u32 *o_txn_size, u32 *o_buf); | 840 | u32 *o_mcp_param, u32 *o_txn_size, u32 *o_buf); |
841 | 841 | ||
842 | /** | 842 | /** |
843 | * @brief Read from sfp | ||
844 | * | ||
845 | * @param p_hwfn - hw function | ||
846 | * @param p_ptt - PTT required for register access | ||
847 | * @param port - transceiver port | ||
848 | * @param addr - I2C address | ||
849 | * @param offset - offset in sfp | ||
850 | * @param len - buffer length | ||
851 | * @param p_buf - buffer to read into | ||
852 | * | ||
853 | * @return int - 0 - operation was successful. | ||
854 | */ | ||
855 | int qed_mcp_phy_sfp_read(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, | ||
856 | u32 port, u32 addr, u32 offset, u32 len, u8 *p_buf); | ||
857 | |||
858 | /** | ||
843 | * @brief indicates whether the MFW objects [under mcp_info] are accessible | 859 | * @brief indicates whether the MFW objects [under mcp_info] are accessible |
844 | * | 860 | * |
845 | * @param p_hwfn | 861 | * @param p_hwfn |
diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h index b4040023cbfb..8cd34645e892 100644 --- a/include/linux/qed/qed_if.h +++ b/include/linux/qed/qed_if.h | |||
@@ -759,6 +759,9 @@ struct qed_generic_tlvs { | |||
759 | u8 mac[QED_TLV_MAC_COUNT][ETH_ALEN]; | 759 | u8 mac[QED_TLV_MAC_COUNT][ETH_ALEN]; |
760 | }; | 760 | }; |
761 | 761 | ||
762 | #define QED_I2C_DEV_ADDR_A0 0xA0 | ||
763 | #define QED_I2C_DEV_ADDR_A2 0xA2 | ||
764 | |||
762 | #define QED_NVM_SIGNATURE 0x12435687 | 765 | #define QED_NVM_SIGNATURE 0x12435687 |
763 | 766 | ||
764 | enum qed_nvm_flash_cmd { | 767 | enum qed_nvm_flash_cmd { |
@@ -1026,6 +1029,18 @@ struct qed_common_ops { | |||
1026 | * @param enabled - true iff WoL should be enabled. | 1029 | * @param enabled - true iff WoL should be enabled. |
1027 | */ | 1030 | */ |
1028 | int (*update_wol) (struct qed_dev *cdev, bool enabled); | 1031 | int (*update_wol) (struct qed_dev *cdev, bool enabled); |
1032 | |||
1033 | /** | ||
1034 | * @brief read_module_eeprom | ||
1035 | * | ||
1036 | * @param cdev | ||
1037 | * @param buf - buffer | ||
1038 | * @param dev_addr - PHY device memory region | ||
1039 | * @param offset - offset into eeprom contents to be read | ||
1040 | * @param len - buffer length, i.e., max bytes to be read | ||
1041 | */ | ||
1042 | int (*read_module_eeprom)(struct qed_dev *cdev, | ||
1043 | char *buf, u8 dev_addr, u32 offset, u32 len); | ||
1029 | }; | 1044 | }; |
1030 | 1045 | ||
1031 | #define MASK_FIELD(_name, _value) \ | 1046 | #define MASK_FIELD(_name, _value) \ |