diff options
author | Joe Carnuccio <joe.carnuccio@qlogic.com> | 2014-04-11 16:54:17 -0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2014-05-19 07:31:01 -0400 |
commit | e8887c51f01911f3063e65c229e1f3be102031ba (patch) | |
tree | a7a98f09d4cd2e0319f613616824b5423a1de679 /drivers/scsi | |
parent | 7012532dc8cdbcfb0d13d03ccc2ec18416504f29 (diff) |
qla2xxx: Add ISP8044 serdes bsg interface.
Signed-off-by: Joe Carnuccio <joe.carnuccio@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_bsg.c | 47 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_bsg.h | 7 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 7 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 5 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 72 |
6 files changed, 137 insertions, 3 deletions
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 71ff340f6de4..467c694e6f2e 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c | |||
@@ -2054,9 +2054,49 @@ qla26xx_serdes_op(struct fc_bsg_job *bsg_job) | |||
2054 | bsg_job->reply->reply_payload_rcv_len = sizeof(sr); | 2054 | bsg_job->reply->reply_payload_rcv_len = sizeof(sr); |
2055 | break; | 2055 | break; |
2056 | default: | 2056 | default: |
2057 | ql_log(ql_log_warn, vha, 0x708c, | 2057 | ql_dbg(ql_dbg_user, vha, 0x708c, |
2058 | "Unknown serdes cmd %x.\n", sr.cmd); | 2058 | "Unknown serdes cmd %x.\n", sr.cmd); |
2059 | rval = -EDOM; | 2059 | rval = -EINVAL; |
2060 | break; | ||
2061 | } | ||
2062 | |||
2063 | bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = | ||
2064 | rval ? EXT_STATUS_MAILBOX : 0; | ||
2065 | |||
2066 | bsg_job->reply_len = sizeof(struct fc_bsg_reply); | ||
2067 | bsg_job->reply->result = DID_OK << 16; | ||
2068 | bsg_job->job_done(bsg_job); | ||
2069 | return 0; | ||
2070 | } | ||
2071 | |||
2072 | static int | ||
2073 | qla8044_serdes_op(struct fc_bsg_job *bsg_job) | ||
2074 | { | ||
2075 | struct Scsi_Host *host = bsg_job->shost; | ||
2076 | scsi_qla_host_t *vha = shost_priv(host); | ||
2077 | int rval = 0; | ||
2078 | struct qla_serdes_reg_ex sr; | ||
2079 | |||
2080 | memset(&sr, 0, sizeof(sr)); | ||
2081 | |||
2082 | sg_copy_to_buffer(bsg_job->request_payload.sg_list, | ||
2083 | bsg_job->request_payload.sg_cnt, &sr, sizeof(sr)); | ||
2084 | |||
2085 | switch (sr.cmd) { | ||
2086 | case INT_SC_SERDES_WRITE_REG: | ||
2087 | rval = qla8044_write_serdes_word(vha, sr.addr, sr.val); | ||
2088 | bsg_job->reply->reply_payload_rcv_len = 0; | ||
2089 | break; | ||
2090 | case INT_SC_SERDES_READ_REG: | ||
2091 | rval = qla8044_read_serdes_word(vha, sr.addr, &sr.val); | ||
2092 | sg_copy_from_buffer(bsg_job->reply_payload.sg_list, | ||
2093 | bsg_job->reply_payload.sg_cnt, &sr, sizeof(sr)); | ||
2094 | bsg_job->reply->reply_payload_rcv_len = sizeof(sr); | ||
2095 | break; | ||
2096 | default: | ||
2097 | ql_dbg(ql_dbg_user, vha, 0x70cf, | ||
2098 | "Unknown serdes cmd %x.\n", sr.cmd); | ||
2099 | rval = -EINVAL; | ||
2060 | break; | 2100 | break; |
2061 | } | 2101 | } |
2062 | 2102 | ||
@@ -2121,6 +2161,9 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job) | |||
2121 | case QL_VND_SERDES_OP: | 2161 | case QL_VND_SERDES_OP: |
2122 | return qla26xx_serdes_op(bsg_job); | 2162 | return qla26xx_serdes_op(bsg_job); |
2123 | 2163 | ||
2164 | case QL_VND_SERDES_OP_EX: | ||
2165 | return qla8044_serdes_op(bsg_job); | ||
2166 | |||
2124 | default: | 2167 | default: |
2125 | return -ENOSYS; | 2168 | return -ENOSYS; |
2126 | } | 2169 | } |
diff --git a/drivers/scsi/qla2xxx/qla_bsg.h b/drivers/scsi/qla2xxx/qla_bsg.h index e5c2126221e9..4e49d0a41faa 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.h +++ b/drivers/scsi/qla2xxx/qla_bsg.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #define QL_VND_READ_I2C 0x11 | 24 | #define QL_VND_READ_I2C 0x11 |
25 | #define QL_VND_FX00_MGMT_CMD 0x12 | 25 | #define QL_VND_FX00_MGMT_CMD 0x12 |
26 | #define QL_VND_SERDES_OP 0x13 | 26 | #define QL_VND_SERDES_OP 0x13 |
27 | #define QL_VND_SERDES_OP_EX 0x14 | ||
27 | 28 | ||
28 | /* BSG Vendor specific subcode returns */ | 29 | /* BSG Vendor specific subcode returns */ |
29 | #define EXT_STATUS_OK 0 | 30 | #define EXT_STATUS_OK 0 |
@@ -225,4 +226,10 @@ struct qla_serdes_reg { | |||
225 | uint16_t val; | 226 | uint16_t val; |
226 | } __packed; | 227 | } __packed; |
227 | 228 | ||
229 | struct qla_serdes_reg_ex { | ||
230 | uint16_t cmd; | ||
231 | uint32_t addr; | ||
232 | uint32_t val; | ||
233 | } __packed; | ||
234 | |||
228 | #endif | 235 | #endif |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 7cf1044d017f..ba72e1675599 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -15,7 +15,7 @@ | |||
15 | * | | | 0x0144,0x0146 | | 15 | * | | | 0x0144,0x0146 | |
16 | * | | | 0x015b-0x0160 | | 16 | * | | | 0x015b-0x0160 | |
17 | * | | | 0x016e-0x0170 | | 17 | * | | | 0x016e-0x0170 | |
18 | * | Mailbox commands | 0x1187 | 0x1018-0x1019 | | 18 | * | Mailbox commands | 0x118d | 0x1018-0x1019 | |
19 | * | | | 0x10ca | | 19 | * | | | 0x10ca | |
20 | * | | | 0x1115-0x1116 | | 20 | * | | | 0x1115-0x1116 | |
21 | * | | | 0x111a-0x111b | | 21 | * | | | 0x111a-0x111b | |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index bab1cf12d1e9..23268277f09c 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -965,6 +965,13 @@ struct mbx_cmd_32 { | |||
965 | */ | 965 | */ |
966 | #define MBC_WRITE_MPI_REGISTER 0x01 /* Write MPI Register. */ | 966 | #define MBC_WRITE_MPI_REGISTER 0x01 /* Write MPI Register. */ |
967 | 967 | ||
968 | /* | ||
969 | * ISP8044 mailbox commands | ||
970 | */ | ||
971 | #define MBC_SET_GET_ETH_SERDES_REG 0x150 | ||
972 | #define HCS_WRITE_SERDES 0x3 | ||
973 | #define HCS_READ_SERDES 0x4 | ||
974 | |||
968 | /* Firmware return data sizes */ | 975 | /* Firmware return data sizes */ |
969 | #define FCAL_MAP_SIZE 128 | 976 | #define FCAL_MAP_SIZE 128 |
970 | 977 | ||
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index e665e8109933..b66710ba06ab 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -347,6 +347,11 @@ extern int | |||
347 | qla2x00_read_serdes_word(scsi_qla_host_t *, uint16_t, uint16_t *); | 347 | qla2x00_read_serdes_word(scsi_qla_host_t *, uint16_t, uint16_t *); |
348 | 348 | ||
349 | extern int | 349 | extern int |
350 | qla8044_write_serdes_word(scsi_qla_host_t *, uint32_t, uint32_t); | ||
351 | extern int | ||
352 | qla8044_read_serdes_word(scsi_qla_host_t *, uint32_t, uint32_t *); | ||
353 | |||
354 | extern int | ||
350 | qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); | 355 | qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); |
351 | 356 | ||
352 | extern int | 357 | extern int |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 601562fa11c3..0f7887dd7f3f 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -2879,6 +2879,78 @@ qla2x00_read_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t *data) | |||
2879 | return rval; | 2879 | return rval; |
2880 | } | 2880 | } |
2881 | 2881 | ||
2882 | int | ||
2883 | qla8044_write_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t data) | ||
2884 | { | ||
2885 | int rval; | ||
2886 | mbx_cmd_t mc; | ||
2887 | mbx_cmd_t *mcp = &mc; | ||
2888 | |||
2889 | if (!IS_QLA8044(vha->hw)) | ||
2890 | return QLA_FUNCTION_FAILED; | ||
2891 | |||
2892 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1186, | ||
2893 | "Entered %s.\n", __func__); | ||
2894 | |||
2895 | mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG; | ||
2896 | mcp->mb[1] = HCS_WRITE_SERDES; | ||
2897 | mcp->mb[3] = LSW(addr); | ||
2898 | mcp->mb[4] = MSW(addr); | ||
2899 | mcp->mb[5] = LSW(data); | ||
2900 | mcp->mb[6] = MSW(data); | ||
2901 | mcp->out_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; | ||
2902 | mcp->in_mb = MBX_0; | ||
2903 | mcp->tov = MBX_TOV_SECONDS; | ||
2904 | mcp->flags = 0; | ||
2905 | rval = qla2x00_mailbox_command(vha, mcp); | ||
2906 | |||
2907 | if (rval != QLA_SUCCESS) { | ||
2908 | ql_dbg(ql_dbg_mbx, vha, 0x1187, | ||
2909 | "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); | ||
2910 | } else { | ||
2911 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1188, | ||
2912 | "Done %s.\n", __func__); | ||
2913 | } | ||
2914 | |||
2915 | return rval; | ||
2916 | } | ||
2917 | |||
2918 | int | ||
2919 | qla8044_read_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t *data) | ||
2920 | { | ||
2921 | int rval; | ||
2922 | mbx_cmd_t mc; | ||
2923 | mbx_cmd_t *mcp = &mc; | ||
2924 | |||
2925 | if (!IS_QLA8044(vha->hw)) | ||
2926 | return QLA_FUNCTION_FAILED; | ||
2927 | |||
2928 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1189, | ||
2929 | "Entered %s.\n", __func__); | ||
2930 | |||
2931 | mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG; | ||
2932 | mcp->mb[1] = HCS_READ_SERDES; | ||
2933 | mcp->mb[3] = LSW(addr); | ||
2934 | mcp->mb[4] = MSW(addr); | ||
2935 | mcp->out_mb = MBX_4|MBX_3|MBX_1|MBX_0; | ||
2936 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | ||
2937 | mcp->tov = MBX_TOV_SECONDS; | ||
2938 | mcp->flags = 0; | ||
2939 | rval = qla2x00_mailbox_command(vha, mcp); | ||
2940 | |||
2941 | *data = mcp->mb[2] << 16 | mcp->mb[1]; | ||
2942 | |||
2943 | if (rval != QLA_SUCCESS) { | ||
2944 | ql_dbg(ql_dbg_mbx, vha, 0x118a, | ||
2945 | "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); | ||
2946 | } else { | ||
2947 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118b, | ||
2948 | "Done %s.\n", __func__); | ||
2949 | } | ||
2950 | |||
2951 | return rval; | ||
2952 | } | ||
2953 | |||
2882 | /** | 2954 | /** |
2883 | * qla2x00_set_serdes_params() - | 2955 | * qla2x00_set_serdes_params() - |
2884 | * @ha: HA context | 2956 | * @ha: HA context |