aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJoe Carnuccio <joe.carnuccio@qlogic.com>2014-04-11 16:54:17 -0400
committerChristoph Hellwig <hch@lst.de>2014-05-19 07:31:01 -0400
commite8887c51f01911f3063e65c229e1f3be102031ba (patch)
treea7a98f09d4cd2e0319f613616824b5423a1de679 /drivers/scsi
parent7012532dc8cdbcfb0d13d03ccc2ec18416504f29 (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.c47
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.h7
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h7
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h5
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c72
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
2072static int
2073qla8044_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
229struct 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
347qla2x00_read_serdes_word(scsi_qla_host_t *, uint16_t, uint16_t *); 347qla2x00_read_serdes_word(scsi_qla_host_t *, uint16_t, uint16_t *);
348 348
349extern int 349extern int
350qla8044_write_serdes_word(scsi_qla_host_t *, uint32_t, uint32_t);
351extern int
352qla8044_read_serdes_word(scsi_qla_host_t *, uint32_t, uint32_t *);
353
354extern int
350qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); 355qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
351 356
352extern int 357extern 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
2882int
2883qla8044_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
2918int
2919qla8044_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