blob: a0df3b1b3823cdddb8ad0ef6a3e326f0f7977479 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Andrew Vasquezfa90c542005-10-27 11:10:08 -07002 * QLogic Fibre Channel HBA Driver
Armen Baloyanbd21eaf2014-04-11 16:54:24 -04003 * Copyright (c) 2003-2014 QLogic Corporation
Linus Torvalds1da177e2005-04-16 15:20:36 -07004 *
Andrew Vasquezfa90c542005-10-27 11:10:08 -07005 * See LICENSE.qla2xxx for copyright and licensing details.
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 */
7#include "qla_def.h"
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04008#include "qla_target.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -07009
Linus Torvalds1da177e2005-04-16 15:20:36 -070010static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *);
11static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *);
12static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *);
13static int qla2x00_sns_gnn_id(scsi_qla_host_t *, sw_info_t *);
14static int qla2x00_sns_rft_id(scsi_qla_host_t *);
15static int qla2x00_sns_rnn_id(scsi_qla_host_t *);
16
17/**
Andrew Vasquez8c958a92005-07-06 10:30:47 -070018 * qla2x00_prep_ms_iocb() - Prepare common MS/CT IOCB fields for SNS CT query.
Linus Torvalds1da177e2005-04-16 15:20:36 -070019 * @ha: HA context
20 * @req_size: request size in bytes
21 * @rsp_size: response size in bytes
22 *
23 * Returns a pointer to the @ha's ms_iocb.
24 */
Andrew Vasquez8c958a92005-07-06 10:30:47 -070025void *
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080026qla2x00_prep_ms_iocb(scsi_qla_host_t *vha, uint32_t req_size, uint32_t rsp_size)
Linus Torvalds1da177e2005-04-16 15:20:36 -070027{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080028 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -070029 ms_iocb_entry_t *ms_pkt;
30
31 ms_pkt = ha->ms_iocb;
32 memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
33
34 ms_pkt->entry_type = MS_IOCB_TYPE;
35 ms_pkt->entry_count = 1;
36 SET_TARGET_ID(ha, ms_pkt->loop_id, SIMPLE_NAME_SERVER);
37 ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG);
Andrew Vasquez00a537b2008-02-28 14:06:11 -080038 ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -070039 ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
40 ms_pkt->total_dsd_count = __constant_cpu_to_le16(2);
41 ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
42 ms_pkt->req_bytecount = cpu_to_le32(req_size);
43
44 ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
45 ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
46 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
47
48 ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
49 ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
50 ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount;
51
Joe Carnucciofabbb8d2013-08-27 01:37:40 -040052 vha->qla_stats.control_requests++;
53
Linus Torvalds1da177e2005-04-16 15:20:36 -070054 return (ms_pkt);
55}
56
57/**
Andrew Vasquez8c958a92005-07-06 10:30:47 -070058 * qla24xx_prep_ms_iocb() - Prepare common CT IOCB fields for SNS CT query.
59 * @ha: HA context
60 * @req_size: request size in bytes
61 * @rsp_size: response size in bytes
62 *
63 * Returns a pointer to the @ha's ms_iocb.
64 */
65void *
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080066qla24xx_prep_ms_iocb(scsi_qla_host_t *vha, uint32_t req_size, uint32_t rsp_size)
Andrew Vasquez8c958a92005-07-06 10:30:47 -070067{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080068 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez8c958a92005-07-06 10:30:47 -070069 struct ct_entry_24xx *ct_pkt;
70
71 ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
72 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
73
74 ct_pkt->entry_type = CT_IOCB_TYPE;
75 ct_pkt->entry_count = 1;
76 ct_pkt->nport_handle = __constant_cpu_to_le16(NPH_SNS);
Andrew Vasquez00a537b2008-02-28 14:06:11 -080077 ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Andrew Vasquez8c958a92005-07-06 10:30:47 -070078 ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
79 ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
80 ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
81 ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
82
83 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
84 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
85 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
86
87 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
88 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
89 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080090 ct_pkt->vp_index = vha->vp_idx;
Andrew Vasquez8c958a92005-07-06 10:30:47 -070091
Joe Carnucciofabbb8d2013-08-27 01:37:40 -040092 vha->qla_stats.control_requests++;
93
Andrew Vasquez8c958a92005-07-06 10:30:47 -070094 return (ct_pkt);
95}
96
97/**
Linus Torvalds1da177e2005-04-16 15:20:36 -070098 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
99 * @ct_req: CT request buffer
100 * @cmd: GS command
101 * @rsp_size: response size in bytes
102 *
103 * Returns a pointer to the intitialized @ct_req.
104 */
105static inline struct ct_sns_req *
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400106qla2x00_prep_ct_req(struct ct_sns_pkt *p, uint16_t cmd, uint16_t rsp_size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107{
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400108 memset(p, 0, sizeof(struct ct_sns_pkt));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400110 p->p.req.header.revision = 0x01;
111 p->p.req.header.gs_type = 0xFC;
112 p->p.req.header.gs_subtype = 0x02;
113 p->p.req.command = cpu_to_be16(cmd);
114 p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400116 return &p->p.req;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117}
118
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700119static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800120qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt,
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700121 struct ct_sns_rsp *ct_rsp, const char *routine)
122{
123 int rval;
124 uint16_t comp_status;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800125 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700126
127 rval = QLA_FUNCTION_FAILED;
128 if (ms_pkt->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700129 ql_dbg(ql_dbg_disc, vha, 0x2031,
130 "%s failed, error status (%x) on port_id: %02x%02x%02x.\n",
131 routine, ms_pkt->entry_status, vha->d_id.b.domain,
132 vha->d_id.b.area, vha->d_id.b.al_pa);
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700133 } else {
Andrew Vasqueze4289242007-07-19 15:05:56 -0700134 if (IS_FWI2_CAPABLE(ha))
Andrew Vasquezcdfc82a2006-12-13 19:20:26 -0800135 comp_status = le16_to_cpu(
136 ((struct ct_entry_24xx *)ms_pkt)->comp_status);
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700137 else
138 comp_status = le16_to_cpu(ms_pkt->status);
139 switch (comp_status) {
140 case CS_COMPLETE:
141 case CS_DATA_UNDERRUN:
142 case CS_DATA_OVERRUN: /* Overrun? */
143 if (ct_rsp->header.response !=
144 __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700145 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2077,
146 "%s failed rejected request on port_id: "
147 "%02x%02x%02x.\n", routine,
Giridhar Malavalicf2d7712011-02-23 15:27:09 -0800148 vha->d_id.b.domain, vha->d_id.b.area,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700149 vha->d_id.b.al_pa);
150 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha,
151 0x2078, (uint8_t *)&ct_rsp->header,
152 sizeof(struct ct_rsp_hdr));
Andrew Vasquez4346b142006-12-13 19:20:28 -0800153 rval = QLA_INVALID_COMMAND;
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700154 } else
155 rval = QLA_SUCCESS;
156 break;
157 default:
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700158 ql_dbg(ql_dbg_disc, vha, 0x2033,
159 "%s failed, completion status (%x) on port_id: "
160 "%02x%02x%02x.\n", routine, comp_status,
Giridhar Malavalicf2d7712011-02-23 15:27:09 -0800161 vha->d_id.b.domain, vha->d_id.b.area,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700162 vha->d_id.b.al_pa);
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700163 break;
164 }
165 }
166 return rval;
167}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168
169/**
170 * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
171 * @ha: HA context
172 * @fcport: fcport entry to updated
173 *
174 * Returns 0 on success.
175 */
176int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800177qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178{
179 int rval;
180
181 ms_iocb_entry_t *ms_pkt;
182 struct ct_sns_req *ct_req;
183 struct ct_sns_rsp *ct_rsp;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800184 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800186 if (IS_QLA2100(ha) || IS_QLA2200(ha))
187 return qla2x00_sns_ga_nxt(vha, fcport);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188
189 /* Issue GA_NXT */
190 /* Prepare common MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800191 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GA_NXT_REQ_SIZE,
Andrew Vasquezfd34f552007-07-19 15:06:00 -0700192 GA_NXT_RSP_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193
194 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400195 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GA_NXT_CMD,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196 GA_NXT_RSP_SIZE);
197 ct_rsp = &ha->ct_sns->p.rsp;
198
199 /* Prepare CT arguments -- port_id */
200 ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain;
201 ct_req->req.port_id.port_id[1] = fcport->d_id.b.area;
202 ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa;
203
204 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800205 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206 sizeof(ms_iocb_entry_t));
207 if (rval != QLA_SUCCESS) {
208 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700209 ql_dbg(ql_dbg_disc, vha, 0x2062,
210 "GA_NXT issue IOCB failed (%d).\n", rval);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800211 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GA_NXT") !=
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700212 QLA_SUCCESS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213 rval = QLA_FUNCTION_FAILED;
214 } else {
215 /* Populate fc_port_t entry. */
216 fcport->d_id.b.domain = ct_rsp->rsp.ga_nxt.port_id[0];
217 fcport->d_id.b.area = ct_rsp->rsp.ga_nxt.port_id[1];
218 fcport->d_id.b.al_pa = ct_rsp->rsp.ga_nxt.port_id[2];
219
220 memcpy(fcport->node_name, ct_rsp->rsp.ga_nxt.node_name,
221 WWN_SIZE);
222 memcpy(fcport->port_name, ct_rsp->rsp.ga_nxt.port_name,
223 WWN_SIZE);
224
Armen Baloyana72b9902012-11-21 02:40:30 -0500225 fcport->fc4_type = (ct_rsp->rsp.ga_nxt.fc4_types[2] & BIT_0) ?
226 FC4_TYPE_FCP_SCSI : FC4_TYPE_OTHER;
227
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228 if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE &&
229 ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE)
230 fcport->d_id.b.domain = 0xf0;
231
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700232 ql_dbg(ql_dbg_disc, vha, 0x2063,
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -0400233 "GA_NXT entry - nn %8phN pn %8phN "
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700234 "port_id=%02x%02x%02x.\n",
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -0400235 fcport->node_name, fcport->port_name,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236 fcport->d_id.b.domain, fcport->d_id.b.area,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700237 fcport->d_id.b.al_pa);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238 }
239
240 return (rval);
241}
242
Chad Dupuis642ef982012-02-09 11:15:57 -0800243static inline int
244qla2x00_gid_pt_rsp_size(scsi_qla_host_t *vha)
245{
246 return vha->hw->max_fibre_devices * 4 + 16;
247}
248
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249/**
250 * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command.
251 * @ha: HA context
252 * @list: switch info entries to populate
253 *
254 * NOTE: Non-Nx_Ports are not requested.
255 *
256 * Returns 0 on success.
257 */
258int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800259qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260{
261 int rval;
262 uint16_t i;
263
264 ms_iocb_entry_t *ms_pkt;
265 struct ct_sns_req *ct_req;
266 struct ct_sns_rsp *ct_rsp;
267
268 struct ct_sns_gid_pt_data *gid_data;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800269 struct qla_hw_data *ha = vha->hw;
Chad Dupuis642ef982012-02-09 11:15:57 -0800270 uint16_t gid_pt_rsp_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800272 if (IS_QLA2100(ha) || IS_QLA2200(ha))
273 return qla2x00_sns_gid_pt(vha, list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274
275 gid_data = NULL;
Chad Dupuis642ef982012-02-09 11:15:57 -0800276 gid_pt_rsp_size = qla2x00_gid_pt_rsp_size(vha);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277 /* Issue GID_PT */
278 /* Prepare common MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800279 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GID_PT_REQ_SIZE,
Chad Dupuis642ef982012-02-09 11:15:57 -0800280 gid_pt_rsp_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281
282 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400283 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GID_PT_CMD, gid_pt_rsp_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284 ct_rsp = &ha->ct_sns->p.rsp;
285
286 /* Prepare CT arguments -- port_type */
287 ct_req->req.gid_pt.port_type = NS_NX_PORT_TYPE;
288
289 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800290 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 sizeof(ms_iocb_entry_t));
292 if (rval != QLA_SUCCESS) {
293 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700294 ql_dbg(ql_dbg_disc, vha, 0x2055,
295 "GID_PT issue IOCB failed (%d).\n", rval);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800296 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GID_PT") !=
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700297 QLA_SUCCESS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298 rval = QLA_FUNCTION_FAILED;
299 } else {
300 /* Set port IDs in switch info list. */
Chad Dupuis642ef982012-02-09 11:15:57 -0800301 for (i = 0; i < ha->max_fibre_devices; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302 gid_data = &ct_rsp->rsp.gid_pt.entries[i];
303 list[i].d_id.b.domain = gid_data->port_id[0];
304 list[i].d_id.b.area = gid_data->port_id[1];
305 list[i].d_id.b.al_pa = gid_data->port_id[2];
Andrew Vasqueza3cbdfa2007-08-13 10:13:18 -0700306 memset(list[i].fabric_port_name, 0, WWN_SIZE);
307 list[i].fp_speed = PORT_SPEED_UNKNOWN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308
309 /* Last one exit. */
310 if (gid_data->control_byte & BIT_7) {
311 list[i].d_id.b.rsvd_1 = gid_data->control_byte;
312 break;
313 }
314 }
315
316 /*
317 * If we've used all available slots, then the switch is
318 * reporting back more devices than we can handle with this
319 * single call. Return a failed status, and let GA_NXT handle
320 * the overload.
321 */
Chad Dupuis642ef982012-02-09 11:15:57 -0800322 if (i == ha->max_fibre_devices)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 rval = QLA_FUNCTION_FAILED;
324 }
325
326 return (rval);
327}
328
329/**
330 * qla2x00_gpn_id() - SNS Get Port Name (GPN_ID) query.
331 * @ha: HA context
332 * @list: switch info entries to populate
333 *
334 * Returns 0 on success.
335 */
336int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800337qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338{
Chad Dupuis642ef982012-02-09 11:15:57 -0800339 int rval = QLA_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340 uint16_t i;
341
342 ms_iocb_entry_t *ms_pkt;
343 struct ct_sns_req *ct_req;
344 struct ct_sns_rsp *ct_rsp;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800345 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800347 if (IS_QLA2100(ha) || IS_QLA2200(ha))
348 return qla2x00_sns_gpn_id(vha, list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349
Chad Dupuis642ef982012-02-09 11:15:57 -0800350 for (i = 0; i < ha->max_fibre_devices; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 /* Issue GPN_ID */
352 /* Prepare common MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800353 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GPN_ID_REQ_SIZE,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354 GPN_ID_RSP_SIZE);
355
356 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400357 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GPN_ID_CMD,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358 GPN_ID_RSP_SIZE);
359 ct_rsp = &ha->ct_sns->p.rsp;
360
361 /* Prepare CT arguments -- port_id */
362 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
363 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
364 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
365
366 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800367 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 sizeof(ms_iocb_entry_t));
369 if (rval != QLA_SUCCESS) {
370 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700371 ql_dbg(ql_dbg_disc, vha, 0x2056,
372 "GPN_ID issue IOCB failed (%d).\n", rval);
Arun Easidafdf892012-02-09 11:16:00 -0800373 break;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800374 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700375 "GPN_ID") != QLA_SUCCESS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376 rval = QLA_FUNCTION_FAILED;
Arun Easidafdf892012-02-09 11:16:00 -0800377 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 } else {
379 /* Save portname */
380 memcpy(list[i].port_name,
381 ct_rsp->rsp.gpn_id.port_name, WWN_SIZE);
382 }
383
384 /* Last device exit. */
385 if (list[i].d_id.b.rsvd_1 != 0)
386 break;
387 }
388
389 return (rval);
390}
391
392/**
393 * qla2x00_gnn_id() - SNS Get Node Name (GNN_ID) query.
394 * @ha: HA context
395 * @list: switch info entries to populate
396 *
397 * Returns 0 on success.
398 */
399int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800400qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401{
Chad Dupuis642ef982012-02-09 11:15:57 -0800402 int rval = QLA_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403 uint16_t i;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800404 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405 ms_iocb_entry_t *ms_pkt;
406 struct ct_sns_req *ct_req;
407 struct ct_sns_rsp *ct_rsp;
408
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800409 if (IS_QLA2100(ha) || IS_QLA2200(ha))
410 return qla2x00_sns_gnn_id(vha, list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
Chad Dupuis642ef982012-02-09 11:15:57 -0800412 for (i = 0; i < ha->max_fibre_devices; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 /* Issue GNN_ID */
414 /* Prepare common MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800415 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GNN_ID_REQ_SIZE,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416 GNN_ID_RSP_SIZE);
417
418 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400419 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GNN_ID_CMD,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 GNN_ID_RSP_SIZE);
421 ct_rsp = &ha->ct_sns->p.rsp;
422
423 /* Prepare CT arguments -- port_id */
424 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
425 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
426 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
427
428 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800429 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430 sizeof(ms_iocb_entry_t));
431 if (rval != QLA_SUCCESS) {
432 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700433 ql_dbg(ql_dbg_disc, vha, 0x2057,
434 "GNN_ID issue IOCB failed (%d).\n", rval);
Arun Easidafdf892012-02-09 11:16:00 -0800435 break;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800436 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700437 "GNN_ID") != QLA_SUCCESS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 rval = QLA_FUNCTION_FAILED;
Arun Easidafdf892012-02-09 11:16:00 -0800439 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440 } else {
441 /* Save nodename */
442 memcpy(list[i].node_name,
443 ct_rsp->rsp.gnn_id.node_name, WWN_SIZE);
444
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700445 ql_dbg(ql_dbg_disc, vha, 0x2058,
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -0400446 "GID_PT entry - nn %8phN pn %8phN "
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447 "portid=%02x%02x%02x.\n",
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -0400448 list[i].node_name, list[i].port_name,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 list[i].d_id.b.domain, list[i].d_id.b.area,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700450 list[i].d_id.b.al_pa);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 }
452
453 /* Last device exit. */
454 if (list[i].d_id.b.rsvd_1 != 0)
455 break;
456 }
457
458 return (rval);
459}
460
461/**
462 * qla2x00_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
463 * @ha: HA context
464 *
465 * Returns 0 on success.
466 */
467int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800468qla2x00_rft_id(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469{
470 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800471 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 ms_iocb_entry_t *ms_pkt;
473 struct ct_sns_req *ct_req;
474 struct ct_sns_rsp *ct_rsp;
475
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800476 if (IS_QLA2100(ha) || IS_QLA2200(ha))
477 return qla2x00_sns_rft_id(vha);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478
479 /* Issue RFT_ID */
480 /* Prepare common MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800481 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, RFT_ID_REQ_SIZE,
Andrew Vasquezfd34f552007-07-19 15:06:00 -0700482 RFT_ID_RSP_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483
484 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400485 ct_req = qla2x00_prep_ct_req(ha->ct_sns, RFT_ID_CMD,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486 RFT_ID_RSP_SIZE);
487 ct_rsp = &ha->ct_sns->p.rsp;
488
489 /* Prepare CT arguments -- port_id, FC-4 types */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800490 ct_req->req.rft_id.port_id[0] = vha->d_id.b.domain;
491 ct_req->req.rft_id.port_id[1] = vha->d_id.b.area;
492 ct_req->req.rft_id.port_id[2] = vha->d_id.b.al_pa;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493
494 ct_req->req.rft_id.fc4_types[2] = 0x01; /* FCP-3 */
495
496 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800497 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498 sizeof(ms_iocb_entry_t));
499 if (rval != QLA_SUCCESS) {
500 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700501 ql_dbg(ql_dbg_disc, vha, 0x2043,
502 "RFT_ID issue IOCB failed (%d).\n", rval);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800503 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RFT_ID") !=
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700504 QLA_SUCCESS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 rval = QLA_FUNCTION_FAILED;
506 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700507 ql_dbg(ql_dbg_disc, vha, 0x2044,
508 "RFT_ID exiting normally.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 }
510
511 return (rval);
512}
513
514/**
515 * qla2x00_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the HBA.
516 * @ha: HA context
517 *
518 * Returns 0 on success.
519 */
520int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800521qla2x00_rff_id(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522{
523 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800524 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 ms_iocb_entry_t *ms_pkt;
526 struct ct_sns_req *ct_req;
527 struct ct_sns_rsp *ct_rsp;
528
529 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700530 ql_dbg(ql_dbg_disc, vha, 0x2046,
531 "RFF_ID call not supported on ISP2100/ISP2200.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532 return (QLA_SUCCESS);
533 }
534
535 /* Issue RFF_ID */
536 /* Prepare common MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800537 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, RFF_ID_REQ_SIZE,
Andrew Vasquezfd34f552007-07-19 15:06:00 -0700538 RFF_ID_RSP_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539
540 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400541 ct_req = qla2x00_prep_ct_req(ha->ct_sns, RFF_ID_CMD,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 RFF_ID_RSP_SIZE);
543 ct_rsp = &ha->ct_sns->p.rsp;
544
545 /* Prepare CT arguments -- port_id, FC-4 feature, FC-4 type */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800546 ct_req->req.rff_id.port_id[0] = vha->d_id.b.domain;
547 ct_req->req.rff_id.port_id[1] = vha->d_id.b.area;
548 ct_req->req.rff_id.port_id[2] = vha->d_id.b.al_pa;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549
Nicholas Bellinger2d70c102012-05-15 14:34:28 -0400550 qlt_rff_id(vha, ct_req);
551
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552 ct_req->req.rff_id.fc4_type = 0x08; /* SCSI - FCP */
553
554 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800555 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 sizeof(ms_iocb_entry_t));
557 if (rval != QLA_SUCCESS) {
558 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700559 ql_dbg(ql_dbg_disc, vha, 0x2047,
560 "RFF_ID issue IOCB failed (%d).\n", rval);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800561 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RFF_ID") !=
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700562 QLA_SUCCESS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 rval = QLA_FUNCTION_FAILED;
564 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700565 ql_dbg(ql_dbg_disc, vha, 0x2048,
566 "RFF_ID exiting normally.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 }
568
569 return (rval);
570}
571
572/**
573 * qla2x00_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
574 * @ha: HA context
575 *
576 * Returns 0 on success.
577 */
578int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800579qla2x00_rnn_id(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580{
581 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800582 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583 ms_iocb_entry_t *ms_pkt;
584 struct ct_sns_req *ct_req;
585 struct ct_sns_rsp *ct_rsp;
586
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800587 if (IS_QLA2100(ha) || IS_QLA2200(ha))
588 return qla2x00_sns_rnn_id(vha);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589
590 /* Issue RNN_ID */
591 /* Prepare common MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800592 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, RNN_ID_REQ_SIZE,
Andrew Vasquezfd34f552007-07-19 15:06:00 -0700593 RNN_ID_RSP_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594
595 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400596 ct_req = qla2x00_prep_ct_req(ha->ct_sns, RNN_ID_CMD, RNN_ID_RSP_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 ct_rsp = &ha->ct_sns->p.rsp;
598
599 /* Prepare CT arguments -- port_id, node_name */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800600 ct_req->req.rnn_id.port_id[0] = vha->d_id.b.domain;
601 ct_req->req.rnn_id.port_id[1] = vha->d_id.b.area;
602 ct_req->req.rnn_id.port_id[2] = vha->d_id.b.al_pa;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800604 memcpy(ct_req->req.rnn_id.node_name, vha->node_name, WWN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605
606 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800607 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 sizeof(ms_iocb_entry_t));
609 if (rval != QLA_SUCCESS) {
610 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700611 ql_dbg(ql_dbg_disc, vha, 0x204d,
612 "RNN_ID issue IOCB failed (%d).\n", rval);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800613 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RNN_ID") !=
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700614 QLA_SUCCESS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615 rval = QLA_FUNCTION_FAILED;
616 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700617 ql_dbg(ql_dbg_disc, vha, 0x204e,
618 "RNN_ID exiting normally.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619 }
620
621 return (rval);
622}
623
Andrew Vasquez1620f7c2006-10-02 12:00:44 -0700624void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800625qla2x00_get_sym_node_name(scsi_qla_host_t *vha, uint8_t *snn)
Andrew Vasquez1620f7c2006-10-02 12:00:44 -0700626{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800627 struct qla_hw_data *ha = vha->hw;
Giridhar Malavali8ae6d9c2013-03-28 08:21:23 -0400628
629 if (IS_QLAFX00(ha))
630 sprintf(snn, "%s FW:v%s DVR:v%s", ha->model_number,
631 ha->mr.fw_version, qla2x00_version_str);
632 else
633 sprintf(snn, "%s FW:v%d.%02d.%02d DVR:v%s", ha->model_number,
634 ha->fw_major_version, ha->fw_minor_version,
635 ha->fw_subminor_version, qla2x00_version_str);
Andrew Vasquez1620f7c2006-10-02 12:00:44 -0700636}
637
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638/**
639 * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA.
640 * @ha: HA context
641 *
642 * Returns 0 on success.
643 */
644int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800645qla2x00_rsnn_nn(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646{
647 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800648 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649 ms_iocb_entry_t *ms_pkt;
650 struct ct_sns_req *ct_req;
651 struct ct_sns_rsp *ct_rsp;
652
653 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700654 ql_dbg(ql_dbg_disc, vha, 0x2050,
655 "RSNN_ID call unsupported on ISP2100/ISP2200.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656 return (QLA_SUCCESS);
657 }
658
659 /* Issue RSNN_NN */
660 /* Prepare common MS IOCB */
661 /* Request size adjusted after CT preparation */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800662 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, 0, RSNN_NN_RSP_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700663
664 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400665 ct_req = qla2x00_prep_ct_req(ha->ct_sns, RSNN_NN_CMD,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666 RSNN_NN_RSP_SIZE);
667 ct_rsp = &ha->ct_sns->p.rsp;
668
669 /* Prepare CT arguments -- node_name, symbolic node_name, size */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800670 memcpy(ct_req->req.rsnn_nn.node_name, vha->node_name, WWN_SIZE);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700671
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672 /* Prepare the Symbolic Node Name */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800673 qla2x00_get_sym_node_name(vha, ct_req->req.rsnn_nn.sym_node_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674
675 /* Calculate SNN length */
Andrew Vasquez1620f7c2006-10-02 12:00:44 -0700676 ct_req->req.rsnn_nn.name_len =
677 (uint8_t)strlen(ct_req->req.rsnn_nn.sym_node_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678
679 /* Update MS IOCB request */
680 ms_pkt->req_bytecount =
681 cpu_to_le32(24 + 1 + ct_req->req.rsnn_nn.name_len);
682 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
683
684 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800685 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 sizeof(ms_iocb_entry_t));
687 if (rval != QLA_SUCCESS) {
688 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700689 ql_dbg(ql_dbg_disc, vha, 0x2051,
690 "RSNN_NN issue IOCB failed (%d).\n", rval);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800691 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RSNN_NN") !=
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700692 QLA_SUCCESS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693 rval = QLA_FUNCTION_FAILED;
694 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700695 ql_dbg(ql_dbg_disc, vha, 0x2052,
696 "RSNN_NN exiting normally.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697 }
698
699 return (rval);
700}
701
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702/**
703 * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query.
704 * @ha: HA context
705 * @cmd: GS command
706 * @scmd_len: Subcommand length
707 * @data_size: response size in bytes
708 *
709 * Returns a pointer to the @ha's sns_cmd.
710 */
711static inline struct sns_cmd_pkt *
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800712qla2x00_prep_sns_cmd(scsi_qla_host_t *vha, uint16_t cmd, uint16_t scmd_len,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713 uint16_t data_size)
714{
715 uint16_t wc;
716 struct sns_cmd_pkt *sns_cmd;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800717 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718
719 sns_cmd = ha->sns_cmd;
720 memset(sns_cmd, 0, sizeof(struct sns_cmd_pkt));
721 wc = data_size / 2; /* Size in 16bit words. */
722 sns_cmd->p.cmd.buffer_length = cpu_to_le16(wc);
723 sns_cmd->p.cmd.buffer_address[0] = cpu_to_le32(LSD(ha->sns_cmd_dma));
724 sns_cmd->p.cmd.buffer_address[1] = cpu_to_le32(MSD(ha->sns_cmd_dma));
725 sns_cmd->p.cmd.subcommand_length = cpu_to_le16(scmd_len);
726 sns_cmd->p.cmd.subcommand = cpu_to_le16(cmd);
727 wc = (data_size - 16) / 4; /* Size in 32bit words. */
728 sns_cmd->p.cmd.size = cpu_to_le16(wc);
729
Joe Carnucciofabbb8d2013-08-27 01:37:40 -0400730 vha->qla_stats.control_requests++;
731
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732 return (sns_cmd);
733}
734
735/**
736 * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
737 * @ha: HA context
738 * @fcport: fcport entry to updated
739 *
740 * This command uses the old Exectute SNS Command mailbox routine.
741 *
742 * Returns 0 on success.
743 */
744static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800745qla2x00_sns_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746{
Chad Dupuis642ef982012-02-09 11:15:57 -0800747 int rval = QLA_SUCCESS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800748 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749 struct sns_cmd_pkt *sns_cmd;
750
751 /* Issue GA_NXT. */
752 /* Prepare SNS command request. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800753 sns_cmd = qla2x00_prep_sns_cmd(vha, GA_NXT_CMD, GA_NXT_SNS_SCMD_LEN,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754 GA_NXT_SNS_DATA_SIZE);
755
756 /* Prepare SNS command arguments -- port_id. */
757 sns_cmd->p.cmd.param[0] = fcport->d_id.b.al_pa;
758 sns_cmd->p.cmd.param[1] = fcport->d_id.b.area;
759 sns_cmd->p.cmd.param[2] = fcport->d_id.b.domain;
760
761 /* Execute SNS command. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800762 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GA_NXT_SNS_CMD_SIZE / 2,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 sizeof(struct sns_cmd_pkt));
764 if (rval != QLA_SUCCESS) {
765 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700766 ql_dbg(ql_dbg_disc, vha, 0x205f,
767 "GA_NXT Send SNS failed (%d).\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 } else if (sns_cmd->p.gan_data[8] != 0x80 ||
769 sns_cmd->p.gan_data[9] != 0x02) {
Chad Dupuiscfb09192011-11-18 09:03:07 -0800770 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2084,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700771 "GA_NXT failed, rejected request ga_nxt_rsp:\n");
772 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2074,
773 sns_cmd->p.gan_data, 16);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774 rval = QLA_FUNCTION_FAILED;
775 } else {
776 /* Populate fc_port_t entry. */
777 fcport->d_id.b.domain = sns_cmd->p.gan_data[17];
778 fcport->d_id.b.area = sns_cmd->p.gan_data[18];
779 fcport->d_id.b.al_pa = sns_cmd->p.gan_data[19];
780
781 memcpy(fcport->node_name, &sns_cmd->p.gan_data[284], WWN_SIZE);
782 memcpy(fcport->port_name, &sns_cmd->p.gan_data[20], WWN_SIZE);
783
784 if (sns_cmd->p.gan_data[16] != NS_N_PORT_TYPE &&
785 sns_cmd->p.gan_data[16] != NS_NL_PORT_TYPE)
786 fcport->d_id.b.domain = 0xf0;
787
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700788 ql_dbg(ql_dbg_disc, vha, 0x2061,
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -0400789 "GA_NXT entry - nn %8phN pn %8phN "
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700790 "port_id=%02x%02x%02x.\n",
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -0400791 fcport->node_name, fcport->port_name,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792 fcport->d_id.b.domain, fcport->d_id.b.area,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700793 fcport->d_id.b.al_pa);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794 }
795
796 return (rval);
797}
798
799/**
800 * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command.
801 * @ha: HA context
802 * @list: switch info entries to populate
803 *
804 * This command uses the old Exectute SNS Command mailbox routine.
805 *
806 * NOTE: Non-Nx_Ports are not requested.
807 *
808 * Returns 0 on success.
809 */
810static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800811qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812{
813 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800814 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815 uint16_t i;
816 uint8_t *entry;
817 struct sns_cmd_pkt *sns_cmd;
Chad Dupuis642ef982012-02-09 11:15:57 -0800818 uint16_t gid_pt_sns_data_size;
819
820 gid_pt_sns_data_size = qla2x00_gid_pt_rsp_size(vha);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821
822 /* Issue GID_PT. */
823 /* Prepare SNS command request. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800824 sns_cmd = qla2x00_prep_sns_cmd(vha, GID_PT_CMD, GID_PT_SNS_SCMD_LEN,
Chad Dupuis642ef982012-02-09 11:15:57 -0800825 gid_pt_sns_data_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826
827 /* Prepare SNS command arguments -- port_type. */
828 sns_cmd->p.cmd.param[0] = NS_NX_PORT_TYPE;
829
830 /* Execute SNS command. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800831 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GID_PT_SNS_CMD_SIZE / 2,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832 sizeof(struct sns_cmd_pkt));
833 if (rval != QLA_SUCCESS) {
834 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700835 ql_dbg(ql_dbg_disc, vha, 0x206d,
836 "GID_PT Send SNS failed (%d).\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837 } else if (sns_cmd->p.gid_data[8] != 0x80 ||
838 sns_cmd->p.gid_data[9] != 0x02) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700839 ql_dbg(ql_dbg_disc, vha, 0x202f,
840 "GID_PT failed, rejected request, gid_rsp:\n");
841 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2081,
842 sns_cmd->p.gid_data, 16);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843 rval = QLA_FUNCTION_FAILED;
844 } else {
845 /* Set port IDs in switch info list. */
Chad Dupuis642ef982012-02-09 11:15:57 -0800846 for (i = 0; i < ha->max_fibre_devices; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847 entry = &sns_cmd->p.gid_data[(i * 4) + 16];
848 list[i].d_id.b.domain = entry[1];
849 list[i].d_id.b.area = entry[2];
850 list[i].d_id.b.al_pa = entry[3];
851
852 /* Last one exit. */
853 if (entry[0] & BIT_7) {
854 list[i].d_id.b.rsvd_1 = entry[0];
855 break;
856 }
857 }
858
859 /*
860 * If we've used all available slots, then the switch is
861 * reporting back more devices that we can handle with this
862 * single call. Return a failed status, and let GA_NXT handle
863 * the overload.
864 */
Chad Dupuis642ef982012-02-09 11:15:57 -0800865 if (i == ha->max_fibre_devices)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866 rval = QLA_FUNCTION_FAILED;
867 }
868
869 return (rval);
870}
871
872/**
873 * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query.
874 * @ha: HA context
875 * @list: switch info entries to populate
876 *
877 * This command uses the old Exectute SNS Command mailbox routine.
878 *
879 * Returns 0 on success.
880 */
881static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800882qla2x00_sns_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883{
Chad Dupuis642ef982012-02-09 11:15:57 -0800884 int rval = QLA_SUCCESS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800885 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886 uint16_t i;
887 struct sns_cmd_pkt *sns_cmd;
888
Chad Dupuis642ef982012-02-09 11:15:57 -0800889 for (i = 0; i < ha->max_fibre_devices; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890 /* Issue GPN_ID */
891 /* Prepare SNS command request. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800892 sns_cmd = qla2x00_prep_sns_cmd(vha, GPN_ID_CMD,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 GPN_ID_SNS_SCMD_LEN, GPN_ID_SNS_DATA_SIZE);
894
895 /* Prepare SNS command arguments -- port_id. */
896 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa;
897 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area;
898 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain;
899
900 /* Execute SNS command. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800901 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902 GPN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt));
903 if (rval != QLA_SUCCESS) {
904 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700905 ql_dbg(ql_dbg_disc, vha, 0x2032,
906 "GPN_ID Send SNS failed (%d).\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907 } else if (sns_cmd->p.gpn_data[8] != 0x80 ||
908 sns_cmd->p.gpn_data[9] != 0x02) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700909 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207e,
910 "GPN_ID failed, rejected request, gpn_rsp:\n");
Giridhar Malavali8ae6d9c2013-03-28 08:21:23 -0400911 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207f,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700912 sns_cmd->p.gpn_data, 16);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913 rval = QLA_FUNCTION_FAILED;
914 } else {
915 /* Save portname */
916 memcpy(list[i].port_name, &sns_cmd->p.gpn_data[16],
917 WWN_SIZE);
918 }
919
920 /* Last device exit. */
921 if (list[i].d_id.b.rsvd_1 != 0)
922 break;
923 }
924
925 return (rval);
926}
927
928/**
929 * qla2x00_sns_gnn_id() - SNS Get Node Name (GNN_ID) query.
930 * @ha: HA context
931 * @list: switch info entries to populate
932 *
933 * This command uses the old Exectute SNS Command mailbox routine.
934 *
935 * Returns 0 on success.
936 */
937static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800938qla2x00_sns_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939{
Chad Dupuis642ef982012-02-09 11:15:57 -0800940 int rval = QLA_SUCCESS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800941 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942 uint16_t i;
943 struct sns_cmd_pkt *sns_cmd;
944
Chad Dupuis642ef982012-02-09 11:15:57 -0800945 for (i = 0; i < ha->max_fibre_devices; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946 /* Issue GNN_ID */
947 /* Prepare SNS command request. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800948 sns_cmd = qla2x00_prep_sns_cmd(vha, GNN_ID_CMD,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 GNN_ID_SNS_SCMD_LEN, GNN_ID_SNS_DATA_SIZE);
950
951 /* Prepare SNS command arguments -- port_id. */
952 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa;
953 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area;
954 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain;
955
956 /* Execute SNS command. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800957 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958 GNN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt));
959 if (rval != QLA_SUCCESS) {
960 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700961 ql_dbg(ql_dbg_disc, vha, 0x203f,
962 "GNN_ID Send SNS failed (%d).\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963 } else if (sns_cmd->p.gnn_data[8] != 0x80 ||
964 sns_cmd->p.gnn_data[9] != 0x02) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700965 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2082,
966 "GNN_ID failed, rejected request, gnn_rsp:\n");
967 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207a,
968 sns_cmd->p.gnn_data, 16);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969 rval = QLA_FUNCTION_FAILED;
970 } else {
971 /* Save nodename */
972 memcpy(list[i].node_name, &sns_cmd->p.gnn_data[16],
973 WWN_SIZE);
974
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700975 ql_dbg(ql_dbg_disc, vha, 0x206e,
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -0400976 "GID_PT entry - nn %8phN pn %8phN "
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700977 "port_id=%02x%02x%02x.\n",
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -0400978 list[i].node_name, list[i].port_name,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700979 list[i].d_id.b.domain, list[i].d_id.b.area,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700980 list[i].d_id.b.al_pa);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981 }
982
983 /* Last device exit. */
984 if (list[i].d_id.b.rsvd_1 != 0)
985 break;
986 }
987
988 return (rval);
989}
990
991/**
992 * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
993 * @ha: HA context
994 *
995 * This command uses the old Exectute SNS Command mailbox routine.
996 *
997 * Returns 0 on success.
998 */
999static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001000qla2x00_sns_rft_id(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001{
1002 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001003 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004 struct sns_cmd_pkt *sns_cmd;
1005
1006 /* Issue RFT_ID. */
1007 /* Prepare SNS command request. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001008 sns_cmd = qla2x00_prep_sns_cmd(vha, RFT_ID_CMD, RFT_ID_SNS_SCMD_LEN,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009 RFT_ID_SNS_DATA_SIZE);
1010
1011 /* Prepare SNS command arguments -- port_id, FC-4 types */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001012 sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa;
1013 sns_cmd->p.cmd.param[1] = vha->d_id.b.area;
1014 sns_cmd->p.cmd.param[2] = vha->d_id.b.domain;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015
1016 sns_cmd->p.cmd.param[5] = 0x01; /* FCP-3 */
1017
1018 /* Execute SNS command. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001019 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RFT_ID_SNS_CMD_SIZE / 2,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020 sizeof(struct sns_cmd_pkt));
1021 if (rval != QLA_SUCCESS) {
1022 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001023 ql_dbg(ql_dbg_disc, vha, 0x2060,
1024 "RFT_ID Send SNS failed (%d).\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 } else if (sns_cmd->p.rft_data[8] != 0x80 ||
1026 sns_cmd->p.rft_data[9] != 0x02) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001027 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2083,
1028 "RFT_ID failed, rejected request rft_rsp:\n");
1029 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2080,
1030 sns_cmd->p.rft_data, 16);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031 rval = QLA_FUNCTION_FAILED;
1032 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001033 ql_dbg(ql_dbg_disc, vha, 0x2073,
1034 "RFT_ID exiting normally.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035 }
1036
1037 return (rval);
1038}
1039
1040/**
1041 * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
1042 * HBA.
1043 * @ha: HA context
1044 *
1045 * This command uses the old Exectute SNS Command mailbox routine.
1046 *
1047 * Returns 0 on success.
1048 */
1049static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001050qla2x00_sns_rnn_id(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051{
1052 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001053 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054 struct sns_cmd_pkt *sns_cmd;
1055
1056 /* Issue RNN_ID. */
1057 /* Prepare SNS command request. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001058 sns_cmd = qla2x00_prep_sns_cmd(vha, RNN_ID_CMD, RNN_ID_SNS_SCMD_LEN,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059 RNN_ID_SNS_DATA_SIZE);
1060
1061 /* Prepare SNS command arguments -- port_id, nodename. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001062 sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa;
1063 sns_cmd->p.cmd.param[1] = vha->d_id.b.area;
1064 sns_cmd->p.cmd.param[2] = vha->d_id.b.domain;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001066 sns_cmd->p.cmd.param[4] = vha->node_name[7];
1067 sns_cmd->p.cmd.param[5] = vha->node_name[6];
1068 sns_cmd->p.cmd.param[6] = vha->node_name[5];
1069 sns_cmd->p.cmd.param[7] = vha->node_name[4];
1070 sns_cmd->p.cmd.param[8] = vha->node_name[3];
1071 sns_cmd->p.cmd.param[9] = vha->node_name[2];
1072 sns_cmd->p.cmd.param[10] = vha->node_name[1];
1073 sns_cmd->p.cmd.param[11] = vha->node_name[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074
1075 /* Execute SNS command. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001076 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RNN_ID_SNS_CMD_SIZE / 2,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 sizeof(struct sns_cmd_pkt));
1078 if (rval != QLA_SUCCESS) {
1079 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001080 ql_dbg(ql_dbg_disc, vha, 0x204a,
1081 "RNN_ID Send SNS failed (%d).\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082 } else if (sns_cmd->p.rnn_data[8] != 0x80 ||
1083 sns_cmd->p.rnn_data[9] != 0x02) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001084 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207b,
1085 "RNN_ID failed, rejected request, rnn_rsp:\n");
1086 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207c,
1087 sns_cmd->p.rnn_data, 16);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088 rval = QLA_FUNCTION_FAILED;
1089 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001090 ql_dbg(ql_dbg_disc, vha, 0x204c,
1091 "RNN_ID exiting normally.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092 }
1093
1094 return (rval);
1095}
Andrew Vasquezcca53352005-08-26 19:08:30 -07001096
1097/**
Joe Perchesb1c11812008-02-03 17:28:22 +02001098 * qla2x00_mgmt_svr_login() - Login to fabric Management Service.
Andrew Vasquezcca53352005-08-26 19:08:30 -07001099 * @ha: HA context
1100 *
1101 * Returns 0 on success.
1102 */
1103static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001104qla2x00_mgmt_svr_login(scsi_qla_host_t *vha)
Andrew Vasquezcca53352005-08-26 19:08:30 -07001105{
Chad Dupuis0b91d112012-02-09 11:15:42 -08001106 int ret, rval;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001107 uint16_t mb[MAILBOX_REGISTER_COUNT];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001108 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001109 ret = QLA_SUCCESS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001110 if (vha->flags.management_server_logged_in)
Andrew Vasquezcca53352005-08-26 19:08:30 -07001111 return ret;
1112
Chad Dupuis0b91d112012-02-09 11:15:42 -08001113 rval = ha->isp_ops->fabric_login(vha, vha->mgmt_svr_loop_id, 0xff, 0xff,
Andrew Vasquez58570ac2012-08-22 14:21:18 -04001114 0xfa, mb, BIT_1);
Chad Dupuis0b91d112012-02-09 11:15:42 -08001115 if (rval != QLA_SUCCESS || mb[0] != MBS_COMMAND_COMPLETE) {
1116 if (rval == QLA_MEMORY_ALLOC_FAILED)
1117 ql_dbg(ql_dbg_disc, vha, 0x2085,
1118 "Failed management_server login: loopid=%x "
1119 "rval=%d\n", vha->mgmt_svr_loop_id, rval);
1120 else
1121 ql_dbg(ql_dbg_disc, vha, 0x2024,
1122 "Failed management_server login: loopid=%x "
1123 "mb[0]=%x mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x.\n",
1124 vha->mgmt_svr_loop_id, mb[0], mb[1], mb[2], mb[6],
1125 mb[7]);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001126 ret = QLA_FUNCTION_FAILED;
1127 } else
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001128 vha->flags.management_server_logged_in = 1;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001129
1130 return ret;
1131}
1132
1133/**
1134 * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
1135 * @ha: HA context
1136 * @req_size: request size in bytes
1137 * @rsp_size: response size in bytes
1138 *
1139 * Returns a pointer to the @ha's ms_iocb.
1140 */
1141void *
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001142qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size,
Andrew Vasquezcca53352005-08-26 19:08:30 -07001143 uint32_t rsp_size)
1144{
1145 ms_iocb_entry_t *ms_pkt;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001146 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001147 ms_pkt = ha->ms_iocb;
1148 memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
1149
1150 ms_pkt->entry_type = MS_IOCB_TYPE;
1151 ms_pkt->entry_count = 1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001152 SET_TARGET_ID(ha, ms_pkt->loop_id, vha->mgmt_svr_loop_id);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001153 ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08001154 ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001155 ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
1156 ms_pkt->total_dsd_count = __constant_cpu_to_le16(2);
1157 ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
1158 ms_pkt->req_bytecount = cpu_to_le32(req_size);
1159
1160 ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1161 ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1162 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
1163
1164 ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1165 ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1166 ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount;
1167
1168 return ms_pkt;
1169}
1170
1171/**
1172 * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
1173 * @ha: HA context
1174 * @req_size: request size in bytes
1175 * @rsp_size: response size in bytes
1176 *
1177 * Returns a pointer to the @ha's ms_iocb.
1178 */
1179void *
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001180qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size,
Andrew Vasquezcca53352005-08-26 19:08:30 -07001181 uint32_t rsp_size)
1182{
1183 struct ct_entry_24xx *ct_pkt;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001184 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001185
1186 ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
1187 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
1188
1189 ct_pkt->entry_type = CT_IOCB_TYPE;
1190 ct_pkt->entry_count = 1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001191 ct_pkt->nport_handle = cpu_to_le16(vha->mgmt_svr_loop_id);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08001192 ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001193 ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
1194 ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
1195 ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
1196 ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
1197
1198 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1199 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1200 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
1201
1202 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1203 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1204 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001205 ct_pkt->vp_index = vha->vp_idx;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001206
1207 return ct_pkt;
1208}
1209
1210static inline ms_iocb_entry_t *
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001211qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size)
Andrew Vasquezcca53352005-08-26 19:08:30 -07001212{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001213 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001214 ms_iocb_entry_t *ms_pkt = ha->ms_iocb;
1215 struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
1216
Andrew Vasqueze4289242007-07-19 15:05:56 -07001217 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquezcca53352005-08-26 19:08:30 -07001218 ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
1219 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
1220 } else {
1221 ms_pkt->req_bytecount = cpu_to_le32(req_size);
1222 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
1223 }
1224
1225 return ms_pkt;
1226}
1227
1228/**
1229 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
1230 * @ct_req: CT request buffer
1231 * @cmd: GS command
1232 * @rsp_size: response size in bytes
1233 *
1234 * Returns a pointer to the intitialized @ct_req.
1235 */
1236static inline struct ct_sns_req *
Bart Van Assche6ec6f902013-06-25 11:27:28 -04001237qla2x00_prep_ct_fdmi_req(struct ct_sns_pkt *p, uint16_t cmd,
Andrew Vasquezcca53352005-08-26 19:08:30 -07001238 uint16_t rsp_size)
1239{
Bart Van Assche6ec6f902013-06-25 11:27:28 -04001240 memset(p, 0, sizeof(struct ct_sns_pkt));
Andrew Vasquezcca53352005-08-26 19:08:30 -07001241
Bart Van Assche6ec6f902013-06-25 11:27:28 -04001242 p->p.req.header.revision = 0x01;
1243 p->p.req.header.gs_type = 0xFA;
1244 p->p.req.header.gs_subtype = 0x10;
1245 p->p.req.command = cpu_to_be16(cmd);
1246 p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001247
Bart Van Assche6ec6f902013-06-25 11:27:28 -04001248 return &p->p.req;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001249}
1250
1251/**
1252 * qla2x00_fdmi_rhba() -
1253 * @ha: HA context
1254 *
1255 * Returns 0 on success.
1256 */
1257static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001258qla2x00_fdmi_rhba(scsi_qla_host_t *vha)
Andrew Vasquezcca53352005-08-26 19:08:30 -07001259{
1260 int rval, alen;
1261 uint32_t size, sn;
1262
1263 ms_iocb_entry_t *ms_pkt;
1264 struct ct_sns_req *ct_req;
1265 struct ct_sns_rsp *ct_rsp;
1266 uint8_t *entries;
1267 struct ct_fdmi_hba_attr *eiter;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001268 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001269
1270 /* Issue RHBA */
1271 /* Prepare common MS IOCB */
1272 /* Request size adjusted after CT preparation */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001273 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001274
1275 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -04001276 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RHBA_CMD, RHBA_RSP_SIZE);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001277 ct_rsp = &ha->ct_sns->p.rsp;
1278
1279 /* Prepare FDMI command arguments -- attribute block, attributes. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001280 memcpy(ct_req->req.rhba.hba_identifier, vha->port_name, WWN_SIZE);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001281 ct_req->req.rhba.entry_count = __constant_cpu_to_be32(1);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001282 memcpy(ct_req->req.rhba.port_name, vha->port_name, WWN_SIZE);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001283 size = 2 * WWN_SIZE + 4 + 4;
1284
1285 /* Attributes */
1286 ct_req->req.rhba.attrs.count =
1287 __constant_cpu_to_be32(FDMI_HBA_ATTR_COUNT);
1288 entries = ct_req->req.rhba.hba_identifier;
1289
1290 /* Nodename. */
1291 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1292 eiter->type = __constant_cpu_to_be16(FDMI_HBA_NODE_NAME);
1293 eiter->len = __constant_cpu_to_be16(4 + WWN_SIZE);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001294 memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001295 size += 4 + WWN_SIZE;
1296
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001297 ql_dbg(ql_dbg_disc, vha, 0x2025,
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -04001298 "NodeName = %8phN.\n", eiter->a.node_name);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001299
1300 /* Manufacturer. */
1301 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1302 eiter->type = __constant_cpu_to_be16(FDMI_HBA_MANUFACTURER);
Paul Bollef24b6972013-02-08 01:57:55 -05001303 alen = strlen(QLA2XXX_MANUFACTURER);
1304 strncpy(eiter->a.manufacturer, QLA2XXX_MANUFACTURER, alen + 1);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001305 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1306 eiter->len = cpu_to_be16(4 + alen);
1307 size += 4 + alen;
1308
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001309 ql_dbg(ql_dbg_disc, vha, 0x2026,
1310 "Manufacturer = %s.\n", eiter->a.manufacturer);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001311
1312 /* Serial number. */
1313 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1314 eiter->type = __constant_cpu_to_be16(FDMI_HBA_SERIAL_NUMBER);
1315 sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1;
1316 sprintf(eiter->a.serial_num, "%c%05d", 'A' + sn / 100000, sn % 100000);
1317 alen = strlen(eiter->a.serial_num);
1318 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1319 eiter->len = cpu_to_be16(4 + alen);
1320 size += 4 + alen;
1321
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001322 ql_dbg(ql_dbg_disc, vha, 0x2027,
1323 "Serial no. = %s.\n", eiter->a.serial_num);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001324
1325 /* Model name. */
1326 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1327 eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL);
1328 strcpy(eiter->a.model, ha->model_number);
1329 alen = strlen(eiter->a.model);
1330 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1331 eiter->len = cpu_to_be16(4 + alen);
1332 size += 4 + alen;
1333
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001334 ql_dbg(ql_dbg_disc, vha, 0x2028,
1335 "Model Name = %s.\n", eiter->a.model);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001336
1337 /* Model description. */
1338 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1339 eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION);
Bart Van Asschec5dcfaa2013-06-25 11:27:25 -04001340 strncpy(eiter->a.model_desc, ha->model_desc, 80);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001341 alen = strlen(eiter->a.model_desc);
1342 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1343 eiter->len = cpu_to_be16(4 + alen);
1344 size += 4 + alen;
1345
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001346 ql_dbg(ql_dbg_disc, vha, 0x2029,
1347 "Model Desc = %s.\n", eiter->a.model_desc);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001348
1349 /* Hardware version. */
1350 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1351 eiter->type = __constant_cpu_to_be16(FDMI_HBA_HARDWARE_VERSION);
1352 strcpy(eiter->a.hw_version, ha->adapter_id);
1353 alen = strlen(eiter->a.hw_version);
1354 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1355 eiter->len = cpu_to_be16(4 + alen);
1356 size += 4 + alen;
1357
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001358 ql_dbg(ql_dbg_disc, vha, 0x202a,
1359 "Hardware ver = %s.\n", eiter->a.hw_version);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001360
1361 /* Driver version. */
1362 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1363 eiter->type = __constant_cpu_to_be16(FDMI_HBA_DRIVER_VERSION);
1364 strcpy(eiter->a.driver_version, qla2x00_version_str);
1365 alen = strlen(eiter->a.driver_version);
1366 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1367 eiter->len = cpu_to_be16(4 + alen);
1368 size += 4 + alen;
1369
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001370 ql_dbg(ql_dbg_disc, vha, 0x202b,
1371 "Driver ver = %s.\n", eiter->a.driver_version);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001372
1373 /* Option ROM version. */
1374 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1375 eiter->type = __constant_cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION);
1376 strcpy(eiter->a.orom_version, "0.00");
1377 alen = strlen(eiter->a.orom_version);
1378 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1379 eiter->len = cpu_to_be16(4 + alen);
1380 size += 4 + alen;
1381
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001382 ql_dbg(ql_dbg_disc, vha , 0x202c,
1383 "Optrom vers = %s.\n", eiter->a.orom_version);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001384
1385 /* Firmware version */
1386 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1387 eiter->type = __constant_cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001388 ha->isp_ops->fw_version_str(vha, eiter->a.fw_version);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001389 alen = strlen(eiter->a.fw_version);
1390 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1391 eiter->len = cpu_to_be16(4 + alen);
1392 size += 4 + alen;
1393
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001394 ql_dbg(ql_dbg_disc, vha, 0x202d,
1395 "Firmware vers = %s.\n", eiter->a.fw_version);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001396
1397 /* Update MS request size. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001398 qla2x00_update_ms_fdmi_iocb(vha, size + 16);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001399
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001400 ql_dbg(ql_dbg_disc, vha, 0x202e,
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -04001401 "RHBA identifier = %8phN size=%d.\n",
1402 ct_req->req.rhba.hba_identifier, size);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001403 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2076,
1404 entries, size);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001405
1406 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001407 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Andrew Vasquezcca53352005-08-26 19:08:30 -07001408 sizeof(ms_iocb_entry_t));
1409 if (rval != QLA_SUCCESS) {
1410 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001411 ql_dbg(ql_dbg_disc, vha, 0x2030,
1412 "RHBA issue IOCB failed (%d).\n", rval);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001413 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA") !=
Andrew Vasquezcca53352005-08-26 19:08:30 -07001414 QLA_SUCCESS) {
1415 rval = QLA_FUNCTION_FAILED;
1416 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
1417 ct_rsp->header.explanation_code ==
1418 CT_EXPL_ALREADY_REGISTERED) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001419 ql_dbg(ql_dbg_disc, vha, 0x2034,
1420 "HBA already registered.\n");
Andrew Vasquezcca53352005-08-26 19:08:30 -07001421 rval = QLA_ALREADY_REGISTERED;
1422 }
1423 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001424 ql_dbg(ql_dbg_disc, vha, 0x2035,
1425 "RHBA exiting normally.\n");
Andrew Vasquezcca53352005-08-26 19:08:30 -07001426 }
1427
1428 return rval;
1429}
1430
1431/**
1432 * qla2x00_fdmi_dhba() -
1433 * @ha: HA context
1434 *
1435 * Returns 0 on success.
1436 */
1437static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001438qla2x00_fdmi_dhba(scsi_qla_host_t *vha)
Andrew Vasquezcca53352005-08-26 19:08:30 -07001439{
1440 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001441 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001442 ms_iocb_entry_t *ms_pkt;
1443 struct ct_sns_req *ct_req;
1444 struct ct_sns_rsp *ct_rsp;
1445
1446 /* Issue RPA */
1447 /* Prepare common MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001448 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, DHBA_REQ_SIZE,
Andrew Vasquezcca53352005-08-26 19:08:30 -07001449 DHBA_RSP_SIZE);
1450
1451 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -04001452 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, DHBA_CMD, DHBA_RSP_SIZE);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001453 ct_rsp = &ha->ct_sns->p.rsp;
1454
1455 /* Prepare FDMI command arguments -- portname. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001456 memcpy(ct_req->req.dhba.port_name, vha->port_name, WWN_SIZE);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001457
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001458 ql_dbg(ql_dbg_disc, vha, 0x2036,
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -04001459 "DHBA portname = %8phN.\n", ct_req->req.dhba.port_name);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001460
1461 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001462 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Andrew Vasquezcca53352005-08-26 19:08:30 -07001463 sizeof(ms_iocb_entry_t));
1464 if (rval != QLA_SUCCESS) {
1465 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001466 ql_dbg(ql_dbg_disc, vha, 0x2037,
1467 "DHBA issue IOCB failed (%d).\n", rval);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001468 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "DHBA") !=
Andrew Vasquezcca53352005-08-26 19:08:30 -07001469 QLA_SUCCESS) {
1470 rval = QLA_FUNCTION_FAILED;
1471 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001472 ql_dbg(ql_dbg_disc, vha, 0x2038,
1473 "DHBA exiting normally.\n");
Andrew Vasquezcca53352005-08-26 19:08:30 -07001474 }
1475
1476 return rval;
1477}
1478
1479/**
1480 * qla2x00_fdmi_rpa() -
1481 * @ha: HA context
1482 *
1483 * Returns 0 on success.
1484 */
1485static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001486qla2x00_fdmi_rpa(scsi_qla_host_t *vha)
Andrew Vasquezcca53352005-08-26 19:08:30 -07001487{
1488 int rval, alen;
1489 uint32_t size, max_frame_size;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001490 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001491 ms_iocb_entry_t *ms_pkt;
1492 struct ct_sns_req *ct_req;
1493 struct ct_sns_rsp *ct_rsp;
1494 uint8_t *entries;
1495 struct ct_fdmi_port_attr *eiter;
1496 struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb;
1497
1498 /* Issue RPA */
1499 /* Prepare common MS IOCB */
1500 /* Request size adjusted after CT preparation */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001501 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001502
1503 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -04001504 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPA_CMD, RPA_RSP_SIZE);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001505 ct_rsp = &ha->ct_sns->p.rsp;
1506
1507 /* Prepare FDMI command arguments -- attribute block, attributes. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001508 memcpy(ct_req->req.rpa.port_name, vha->port_name, WWN_SIZE);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001509 size = WWN_SIZE + 4;
1510
1511 /* Attributes */
1512 ct_req->req.rpa.attrs.count =
Andrew Vasquez8a85e1712007-09-20 14:07:41 -07001513 __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT - 1);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001514 entries = ct_req->req.rpa.port_name;
1515
1516 /* FC4 types. */
1517 eiter = (struct ct_fdmi_port_attr *) (entries + size);
1518 eiter->type = __constant_cpu_to_be16(FDMI_PORT_FC4_TYPES);
1519 eiter->len = __constant_cpu_to_be16(4 + 32);
1520 eiter->a.fc4_types[2] = 0x01;
1521 size += 4 + 32;
1522
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001523 ql_dbg(ql_dbg_disc, vha, 0x2039,
1524 "FC4_TYPES=%02x %02x.\n",
1525 eiter->a.fc4_types[2],
1526 eiter->a.fc4_types[1]);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001527
1528 /* Supported speed. */
1529 eiter = (struct ct_fdmi_port_attr *) (entries + size);
1530 eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
1531 eiter->len = __constant_cpu_to_be16(4 + 4);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001532 if (IS_CNA_CAPABLE(ha))
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001533 eiter->a.sup_speed = __constant_cpu_to_be32(
1534 FDMI_PORT_SPEED_10GB);
Chad Dupuisf73cb692014-02-26 04:15:06 -05001535 else if (IS_QLA27XX(ha))
1536 eiter->a.sup_speed = __constant_cpu_to_be32(
1537 FDMI_PORT_SPEED_32GB|FDMI_PORT_SPEED_16GB|
1538 FDMI_PORT_SPEED_8GB);
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001539 else if (IS_QLA25XX(ha))
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001540 eiter->a.sup_speed = __constant_cpu_to_be32(
1541 FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB|
1542 FDMI_PORT_SPEED_4GB|FDMI_PORT_SPEED_8GB);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001543 else if (IS_QLA24XX_TYPE(ha))
Andrew Vasquez58815692007-07-19 15:05:58 -07001544 eiter->a.sup_speed = __constant_cpu_to_be32(
1545 FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB|
1546 FDMI_PORT_SPEED_4GB);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001547 else if (IS_QLA23XX(ha))
Andrew Vasquez58815692007-07-19 15:05:58 -07001548 eiter->a.sup_speed =__constant_cpu_to_be32(
1549 FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001550 else
Andrew Vasquez58815692007-07-19 15:05:58 -07001551 eiter->a.sup_speed = __constant_cpu_to_be32(
1552 FDMI_PORT_SPEED_1GB);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001553 size += 4 + 4;
1554
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001555 ql_dbg(ql_dbg_disc, vha, 0x203a,
1556 "Supported_Speed=%x.\n", eiter->a.sup_speed);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001557
1558 /* Current speed. */
1559 eiter = (struct ct_fdmi_port_attr *) (entries + size);
1560 eiter->type = __constant_cpu_to_be16(FDMI_PORT_CURRENT_SPEED);
1561 eiter->len = __constant_cpu_to_be16(4 + 4);
1562 switch (ha->link_data_rate) {
Andrew Vasquez58815692007-07-19 15:05:58 -07001563 case PORT_SPEED_1GB:
1564 eiter->a.cur_speed =
1565 __constant_cpu_to_be32(FDMI_PORT_SPEED_1GB);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001566 break;
Andrew Vasquez58815692007-07-19 15:05:58 -07001567 case PORT_SPEED_2GB:
1568 eiter->a.cur_speed =
1569 __constant_cpu_to_be32(FDMI_PORT_SPEED_2GB);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001570 break;
Andrew Vasquez58815692007-07-19 15:05:58 -07001571 case PORT_SPEED_4GB:
1572 eiter->a.cur_speed =
1573 __constant_cpu_to_be32(FDMI_PORT_SPEED_4GB);
1574 break;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001575 case PORT_SPEED_8GB:
1576 eiter->a.cur_speed =
1577 __constant_cpu_to_be32(FDMI_PORT_SPEED_8GB);
1578 break;
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001579 case PORT_SPEED_10GB:
1580 eiter->a.cur_speed =
1581 __constant_cpu_to_be32(FDMI_PORT_SPEED_10GB);
1582 break;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001583 case PORT_SPEED_16GB:
1584 eiter->a.cur_speed =
1585 __constant_cpu_to_be32(FDMI_PORT_SPEED_16GB);
1586 break;
Chad Dupuisf73cb692014-02-26 04:15:06 -05001587 case PORT_SPEED_32GB:
1588 eiter->a.cur_speed =
1589 __constant_cpu_to_be32(FDMI_PORT_SPEED_32GB);
1590 break;
Andrew Vasquez58815692007-07-19 15:05:58 -07001591 default:
1592 eiter->a.cur_speed =
1593 __constant_cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001594 break;
1595 }
1596 size += 4 + 4;
1597
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001598 ql_dbg(ql_dbg_disc, vha, 0x203b,
1599 "Current_Speed=%x.\n", eiter->a.cur_speed);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001600
1601 /* Max frame size. */
1602 eiter = (struct ct_fdmi_port_attr *) (entries + size);
1603 eiter->type = __constant_cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE);
1604 eiter->len = __constant_cpu_to_be16(4 + 4);
Andrew Vasqueze4289242007-07-19 15:05:56 -07001605 max_frame_size = IS_FWI2_CAPABLE(ha) ?
Seokmann Juc6852c42008-04-24 15:21:29 -07001606 le16_to_cpu(icb24->frame_payload_size):
1607 le16_to_cpu(ha->init_cb->frame_payload_size);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001608 eiter->a.max_frame_size = cpu_to_be32(max_frame_size);
1609 size += 4 + 4;
1610
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001611 ql_dbg(ql_dbg_disc, vha, 0x203c,
1612 "Max_Frame_Size=%x.\n", eiter->a.max_frame_size);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001613
1614 /* OS device name. */
1615 eiter = (struct ct_fdmi_port_attr *) (entries + size);
1616 eiter->type = __constant_cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME);
Paul Bollef24b6972013-02-08 01:57:55 -05001617 alen = strlen(QLA2XXX_DRIVER_NAME);
1618 strncpy(eiter->a.os_dev_name, QLA2XXX_DRIVER_NAME, alen + 1);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001619 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1620 eiter->len = cpu_to_be16(4 + alen);
1621 size += 4 + alen;
1622
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001623 ql_dbg(ql_dbg_disc, vha, 0x204b,
1624 "OS_Device_Name=%s.\n", eiter->a.os_dev_name);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001625
Andrew Vasqueza740a3f2006-10-02 12:00:45 -07001626 /* Hostname. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001627 if (strlen(fc_host_system_hostname(vha->host))) {
Andrew Vasquez8a85e1712007-09-20 14:07:41 -07001628 ct_req->req.rpa.attrs.count =
1629 __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT);
Andrew Vasqueza740a3f2006-10-02 12:00:45 -07001630 eiter = (struct ct_fdmi_port_attr *) (entries + size);
1631 eiter->type = __constant_cpu_to_be16(FDMI_PORT_HOST_NAME);
1632 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001633 "%s", fc_host_system_hostname(vha->host));
Andrew Vasqueza740a3f2006-10-02 12:00:45 -07001634 alen = strlen(eiter->a.host_name);
1635 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1636 eiter->len = cpu_to_be16(4 + alen);
1637 size += 4 + alen;
1638
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001639 ql_dbg(ql_dbg_disc, vha, 0x203d,
1640 "HostName=%s.\n", eiter->a.host_name);
Andrew Vasqueza740a3f2006-10-02 12:00:45 -07001641 }
1642
Andrew Vasquezcca53352005-08-26 19:08:30 -07001643 /* Update MS request size. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001644 qla2x00_update_ms_fdmi_iocb(vha, size + 16);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001645
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001646 ql_dbg(ql_dbg_disc, vha, 0x203e,
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -04001647 "RPA portname= %8phN size=%d.\n", ct_req->req.rpa.port_name, size);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001648 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2079,
1649 entries, size);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001650
1651 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001652 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Andrew Vasquezcca53352005-08-26 19:08:30 -07001653 sizeof(ms_iocb_entry_t));
1654 if (rval != QLA_SUCCESS) {
1655 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001656 ql_dbg(ql_dbg_disc, vha, 0x2040,
1657 "RPA issue IOCB failed (%d).\n", rval);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001658 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA") !=
Andrew Vasquezcca53352005-08-26 19:08:30 -07001659 QLA_SUCCESS) {
1660 rval = QLA_FUNCTION_FAILED;
1661 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001662 ql_dbg(ql_dbg_disc, vha, 0x2041,
1663 "RPA exiting nornally.\n");
Andrew Vasquezcca53352005-08-26 19:08:30 -07001664 }
1665
1666 return rval;
1667}
1668
1669/**
1670 * qla2x00_fdmi_register() -
1671 * @ha: HA context
1672 *
1673 * Returns 0 on success.
1674 */
1675int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001676qla2x00_fdmi_register(scsi_qla_host_t *vha)
Andrew Vasquezcca53352005-08-26 19:08:30 -07001677{
1678 int rval;
Andrew Vasquez80de7ef2009-07-31 15:09:33 -07001679 struct qla_hw_data *ha = vha->hw;
1680
Giridhar Malavali8ae6d9c2013-03-28 08:21:23 -04001681 if (IS_QLA2100(ha) || IS_QLA2200(ha) ||
1682 IS_QLAFX00(ha))
Andrew Vasquez80de7ef2009-07-31 15:09:33 -07001683 return QLA_FUNCTION_FAILED;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001684
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001685 rval = qla2x00_mgmt_svr_login(vha);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001686 if (rval)
1687 return rval;
1688
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001689 rval = qla2x00_fdmi_rhba(vha);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001690 if (rval) {
1691 if (rval != QLA_ALREADY_REGISTERED)
1692 return rval;
1693
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001694 rval = qla2x00_fdmi_dhba(vha);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001695 if (rval)
1696 return rval;
1697
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001698 rval = qla2x00_fdmi_rhba(vha);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001699 if (rval)
1700 return rval;
1701 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001702 rval = qla2x00_fdmi_rpa(vha);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001703
1704 return rval;
1705}
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001706
1707/**
1708 * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query.
1709 * @ha: HA context
1710 * @list: switch info entries to populate
1711 *
1712 * Returns 0 on success.
1713 */
1714int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001715qla2x00_gfpn_id(scsi_qla_host_t *vha, sw_info_t *list)
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001716{
Chad Dupuis642ef982012-02-09 11:15:57 -08001717 int rval = QLA_SUCCESS;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001718 uint16_t i;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001719 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001720 ms_iocb_entry_t *ms_pkt;
1721 struct ct_sns_req *ct_req;
1722 struct ct_sns_rsp *ct_rsp;
1723
Andrew Vasquezc76f2c02007-07-19 15:05:57 -07001724 if (!IS_IIDMA_CAPABLE(ha))
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001725 return QLA_FUNCTION_FAILED;
1726
Chad Dupuis642ef982012-02-09 11:15:57 -08001727 for (i = 0; i < ha->max_fibre_devices; i++) {
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001728 /* Issue GFPN_ID */
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001729 /* Prepare common MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001730 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GFPN_ID_REQ_SIZE,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001731 GFPN_ID_RSP_SIZE);
1732
1733 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -04001734 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFPN_ID_CMD,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001735 GFPN_ID_RSP_SIZE);
1736 ct_rsp = &ha->ct_sns->p.rsp;
1737
1738 /* Prepare CT arguments -- port_id */
1739 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
1740 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
1741 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
1742
1743 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001744 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001745 sizeof(ms_iocb_entry_t));
1746 if (rval != QLA_SUCCESS) {
1747 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001748 ql_dbg(ql_dbg_disc, vha, 0x2023,
1749 "GFPN_ID issue IOCB failed (%d).\n", rval);
Arun Easidafdf892012-02-09 11:16:00 -08001750 break;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001751 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001752 "GFPN_ID") != QLA_SUCCESS) {
1753 rval = QLA_FUNCTION_FAILED;
Arun Easidafdf892012-02-09 11:16:00 -08001754 break;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001755 } else {
1756 /* Save fabric portname */
1757 memcpy(list[i].fabric_port_name,
1758 ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE);
1759 }
1760
1761 /* Last device exit. */
1762 if (list[i].d_id.b.rsvd_1 != 0)
1763 break;
1764 }
1765
1766 return (rval);
1767}
1768
1769static inline void *
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001770qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *vha, uint32_t req_size,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001771 uint32_t rsp_size)
1772{
1773 struct ct_entry_24xx *ct_pkt;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001774 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001775 ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
1776 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
1777
1778 ct_pkt->entry_type = CT_IOCB_TYPE;
1779 ct_pkt->entry_count = 1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001780 ct_pkt->nport_handle = cpu_to_le16(vha->mgmt_svr_loop_id);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08001781 ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001782 ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
1783 ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
1784 ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
1785 ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
1786
1787 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1788 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1789 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
1790
1791 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1792 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1793 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001794 ct_pkt->vp_index = vha->vp_idx;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001795
1796 return ct_pkt;
1797}
1798
1799
1800static inline struct ct_sns_req *
Bart Van Assche6ec6f902013-06-25 11:27:28 -04001801qla24xx_prep_ct_fm_req(struct ct_sns_pkt *p, uint16_t cmd,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001802 uint16_t rsp_size)
1803{
Bart Van Assche6ec6f902013-06-25 11:27:28 -04001804 memset(p, 0, sizeof(struct ct_sns_pkt));
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001805
Bart Van Assche6ec6f902013-06-25 11:27:28 -04001806 p->p.req.header.revision = 0x01;
1807 p->p.req.header.gs_type = 0xFA;
1808 p->p.req.header.gs_subtype = 0x01;
1809 p->p.req.command = cpu_to_be16(cmd);
1810 p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001811
Bart Van Assche6ec6f902013-06-25 11:27:28 -04001812 return &p->p.req;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001813}
1814
1815/**
1816 * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query.
1817 * @ha: HA context
1818 * @list: switch info entries to populate
1819 *
1820 * Returns 0 on success.
1821 */
1822int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001823qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list)
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001824{
1825 int rval;
1826 uint16_t i;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001827 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001828 ms_iocb_entry_t *ms_pkt;
1829 struct ct_sns_req *ct_req;
1830 struct ct_sns_rsp *ct_rsp;
1831
Andrew Vasquezc76f2c02007-07-19 15:05:57 -07001832 if (!IS_IIDMA_CAPABLE(ha))
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001833 return QLA_FUNCTION_FAILED;
Andrew Vasquez4346b142006-12-13 19:20:28 -08001834 if (!ha->flags.gpsc_supported)
1835 return QLA_FUNCTION_FAILED;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001836
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001837 rval = qla2x00_mgmt_svr_login(vha);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001838 if (rval)
1839 return rval;
1840
Chad Dupuis642ef982012-02-09 11:15:57 -08001841 for (i = 0; i < ha->max_fibre_devices; i++) {
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001842 /* Issue GFPN_ID */
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001843 /* Prepare common MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001844 ms_pkt = qla24xx_prep_ms_fm_iocb(vha, GPSC_REQ_SIZE,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001845 GPSC_RSP_SIZE);
1846
1847 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -04001848 ct_req = qla24xx_prep_ct_fm_req(ha->ct_sns, GPSC_CMD,
1849 GPSC_RSP_SIZE);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001850 ct_rsp = &ha->ct_sns->p.rsp;
1851
1852 /* Prepare CT arguments -- port_name */
1853 memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name,
1854 WWN_SIZE);
1855
1856 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001857 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001858 sizeof(ms_iocb_entry_t));
1859 if (rval != QLA_SUCCESS) {
1860 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001861 ql_dbg(ql_dbg_disc, vha, 0x2059,
1862 "GPSC issue IOCB failed (%d).\n", rval);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001863 } else if ((rval = qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
Andrew Vasquez4346b142006-12-13 19:20:28 -08001864 "GPSC")) != QLA_SUCCESS) {
1865 /* FM command unsupported? */
1866 if (rval == QLA_INVALID_COMMAND &&
Andrew Vasquez3fe7cfb2008-04-03 13:13:23 -07001867 (ct_rsp->header.reason_code ==
1868 CT_REASON_INVALID_COMMAND_CODE ||
1869 ct_rsp->header.reason_code ==
1870 CT_REASON_COMMAND_UNSUPPORTED)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001871 ql_dbg(ql_dbg_disc, vha, 0x205a,
1872 "GPSC command unsupported, disabling "
1873 "query.\n");
Andrew Vasquez4346b142006-12-13 19:20:28 -08001874 ha->flags.gpsc_supported = 0;
1875 rval = QLA_FUNCTION_FAILED;
1876 break;
1877 }
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001878 rval = QLA_FUNCTION_FAILED;
1879 } else {
Andrew Vasqueza3cbdfa2007-08-13 10:13:18 -07001880 /* Save port-speed */
1881 switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) {
1882 case BIT_15:
1883 list[i].fp_speed = PORT_SPEED_1GB;
1884 break;
1885 case BIT_14:
1886 list[i].fp_speed = PORT_SPEED_2GB;
1887 break;
1888 case BIT_13:
1889 list[i].fp_speed = PORT_SPEED_4GB;
1890 break;
Andrew Vasquez9f8fdde2009-06-03 09:55:22 -07001891 case BIT_12:
1892 list[i].fp_speed = PORT_SPEED_10GB;
1893 break;
Andrew Vasqueza3cbdfa2007-08-13 10:13:18 -07001894 case BIT_11:
1895 list[i].fp_speed = PORT_SPEED_8GB;
1896 break;
Joe Carnuccioc53dfac2012-11-21 02:40:39 -05001897 case BIT_10:
1898 list[i].fp_speed = PORT_SPEED_16GB;
1899 break;
Chad Dupuisf73cb692014-02-26 04:15:06 -05001900 case BIT_8:
1901 list[i].fp_speed = PORT_SPEED_32GB;
1902 break;
Andrew Vasqueza3cbdfa2007-08-13 10:13:18 -07001903 }
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001904
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001905 ql_dbg(ql_dbg_disc, vha, 0x205b,
1906 "GPSC ext entry - fpn "
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -04001907 "%8phN speeds=%04x speed=%04x.\n",
1908 list[i].fabric_port_name,
Andrew Vasqueza3cbdfa2007-08-13 10:13:18 -07001909 be16_to_cpu(ct_rsp->rsp.gpsc.speeds),
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001910 be16_to_cpu(ct_rsp->rsp.gpsc.speed));
Andrew Vasquezd8b45212006-10-02 12:00:43 -07001911 }
1912
1913 /* Last device exit. */
1914 if (list[i].d_id.b.rsvd_1 != 0)
1915 break;
1916 }
1917
1918 return (rval);
1919}
Chad Dupuise8c72ba2010-07-23 15:28:25 +05001920
1921/**
1922 * qla2x00_gff_id() - SNS Get FC-4 Features (GFF_ID) query.
1923 *
1924 * @ha: HA context
1925 * @list: switch info entries to populate
1926 *
1927 */
1928void
1929qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list)
1930{
1931 int rval;
1932 uint16_t i;
1933
1934 ms_iocb_entry_t *ms_pkt;
1935 struct ct_sns_req *ct_req;
1936 struct ct_sns_rsp *ct_rsp;
1937 struct qla_hw_data *ha = vha->hw;
1938 uint8_t fcp_scsi_features = 0;
1939
Chad Dupuis642ef982012-02-09 11:15:57 -08001940 for (i = 0; i < ha->max_fibre_devices; i++) {
Chad Dupuise8c72ba2010-07-23 15:28:25 +05001941 /* Set default FC4 Type as UNKNOWN so the default is to
1942 * Process this port */
1943 list[i].fc4_type = FC4_TYPE_UNKNOWN;
1944
1945 /* Do not attempt GFF_ID if we are not FWI_2 capable */
1946 if (!IS_FWI2_CAPABLE(ha))
1947 continue;
1948
1949 /* Prepare common MS IOCB */
1950 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GFF_ID_REQ_SIZE,
1951 GFF_ID_RSP_SIZE);
1952
1953 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -04001954 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFF_ID_CMD,
Chad Dupuise8c72ba2010-07-23 15:28:25 +05001955 GFF_ID_RSP_SIZE);
1956 ct_rsp = &ha->ct_sns->p.rsp;
1957
1958 /* Prepare CT arguments -- port_id */
1959 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
1960 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
1961 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
1962
1963 /* Execute MS IOCB */
1964 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1965 sizeof(ms_iocb_entry_t));
1966
1967 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001968 ql_dbg(ql_dbg_disc, vha, 0x205c,
1969 "GFF_ID issue IOCB failed (%d).\n", rval);
Chad Dupuise8c72ba2010-07-23 15:28:25 +05001970 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
Andrew Vasquez7a78ced2011-02-23 15:27:12 -08001971 "GFF_ID") != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001972 ql_dbg(ql_dbg_disc, vha, 0x205d,
1973 "GFF_ID IOCB status had a failure status code.\n");
Chad Dupuise8c72ba2010-07-23 15:28:25 +05001974 } else {
1975 fcp_scsi_features =
1976 ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
1977 fcp_scsi_features &= 0x0f;
1978
1979 if (fcp_scsi_features)
1980 list[i].fc4_type = FC4_TYPE_FCP_SCSI;
1981 else
1982 list[i].fc4_type = FC4_TYPE_OTHER;
1983 }
1984
1985 /* Last device exit. */
1986 if (list[i].d_id.b.rsvd_1 != 0)
1987 break;
1988 }
1989}