blob: 94e8a8592f6904be9b4bbe408f705b0e28a342f8 [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"
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04009#include <linux/utsname.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070010
Linus Torvalds1da177e2005-04-16 15:20:36 -070011static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *);
12static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *);
13static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *);
14static int qla2x00_sns_gnn_id(scsi_qla_host_t *, sw_info_t *);
15static int qla2x00_sns_rft_id(scsi_qla_host_t *);
16static int qla2x00_sns_rnn_id(scsi_qla_host_t *);
17
18/**
Andrew Vasquez8c958a92005-07-06 10:30:47 -070019 * qla2x00_prep_ms_iocb() - Prepare common MS/CT IOCB fields for SNS CT query.
Linus Torvalds1da177e2005-04-16 15:20:36 -070020 * @ha: HA context
21 * @req_size: request size in bytes
22 * @rsp_size: response size in bytes
23 *
24 * Returns a pointer to the @ha's ms_iocb.
25 */
Andrew Vasquez8c958a92005-07-06 10:30:47 -070026void *
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080027qla2x00_prep_ms_iocb(scsi_qla_host_t *vha, uint32_t req_size, uint32_t rsp_size)
Linus Torvalds1da177e2005-04-16 15:20:36 -070028{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080029 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -070030 ms_iocb_entry_t *ms_pkt;
31
32 ms_pkt = ha->ms_iocb;
33 memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
34
35 ms_pkt->entry_type = MS_IOCB_TYPE;
36 ms_pkt->entry_count = 1;
37 SET_TARGET_ID(ha, ms_pkt->loop_id, SIMPLE_NAME_SERVER);
Bart Van Asschead950362015-07-09 07:24:08 -070038 ms_pkt->control_flags = cpu_to_le16(CF_READ | CF_HEAD_TAG);
Andrew Vasquez00a537b2008-02-28 14:06:11 -080039 ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Bart Van Asschead950362015-07-09 07:24:08 -070040 ms_pkt->cmd_dsd_count = cpu_to_le16(1);
41 ms_pkt->total_dsd_count = cpu_to_le16(2);
Linus Torvalds1da177e2005-04-16 15:20:36 -070042 ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
43 ms_pkt->req_bytecount = cpu_to_le32(req_size);
44
45 ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
46 ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
47 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
48
49 ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
50 ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
51 ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount;
52
Joe Carnucciofabbb8d2013-08-27 01:37:40 -040053 vha->qla_stats.control_requests++;
54
Linus Torvalds1da177e2005-04-16 15:20:36 -070055 return (ms_pkt);
56}
57
58/**
Andrew Vasquez8c958a92005-07-06 10:30:47 -070059 * qla24xx_prep_ms_iocb() - Prepare common CT IOCB fields for SNS CT query.
60 * @ha: HA context
61 * @req_size: request size in bytes
62 * @rsp_size: response size in bytes
63 *
64 * Returns a pointer to the @ha's ms_iocb.
65 */
66void *
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080067qla24xx_prep_ms_iocb(scsi_qla_host_t *vha, uint32_t req_size, uint32_t rsp_size)
Andrew Vasquez8c958a92005-07-06 10:30:47 -070068{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080069 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez8c958a92005-07-06 10:30:47 -070070 struct ct_entry_24xx *ct_pkt;
71
72 ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
73 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
74
75 ct_pkt->entry_type = CT_IOCB_TYPE;
76 ct_pkt->entry_count = 1;
Bart Van Asschead950362015-07-09 07:24:08 -070077 ct_pkt->nport_handle = cpu_to_le16(NPH_SNS);
Andrew Vasquez00a537b2008-02-28 14:06:11 -080078 ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Bart Van Asschead950362015-07-09 07:24:08 -070079 ct_pkt->cmd_dsd_count = cpu_to_le16(1);
80 ct_pkt->rsp_dsd_count = cpu_to_le16(1);
Andrew Vasquez8c958a92005-07-06 10:30:47 -070081 ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
82 ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
83
84 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
85 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
86 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
87
88 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
89 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
90 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080091 ct_pkt->vp_index = vha->vp_idx;
Andrew Vasquez8c958a92005-07-06 10:30:47 -070092
Joe Carnucciofabbb8d2013-08-27 01:37:40 -040093 vha->qla_stats.control_requests++;
94
Andrew Vasquez8c958a92005-07-06 10:30:47 -070095 return (ct_pkt);
96}
97
98/**
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
100 * @ct_req: CT request buffer
101 * @cmd: GS command
102 * @rsp_size: response size in bytes
103 *
104 * Returns a pointer to the intitialized @ct_req.
105 */
106static inline struct ct_sns_req *
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400107qla2x00_prep_ct_req(struct ct_sns_pkt *p, uint16_t cmd, uint16_t rsp_size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108{
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400109 memset(p, 0, sizeof(struct ct_sns_pkt));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400111 p->p.req.header.revision = 0x01;
112 p->p.req.header.gs_type = 0xFC;
113 p->p.req.header.gs_subtype = 0x02;
114 p->p.req.command = cpu_to_be16(cmd);
115 p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400117 return &p->p.req;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118}
119
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700120static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800121qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt,
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700122 struct ct_sns_rsp *ct_rsp, const char *routine)
123{
124 int rval;
125 uint16_t comp_status;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800126 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700127
128 rval = QLA_FUNCTION_FAILED;
129 if (ms_pkt->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700130 ql_dbg(ql_dbg_disc, vha, 0x2031,
131 "%s failed, error status (%x) on port_id: %02x%02x%02x.\n",
132 routine, ms_pkt->entry_status, vha->d_id.b.domain,
133 vha->d_id.b.area, vha->d_id.b.al_pa);
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700134 } else {
Andrew Vasqueze4289242007-07-19 15:05:56 -0700135 if (IS_FWI2_CAPABLE(ha))
Andrew Vasquezcdfc82a2006-12-13 19:20:26 -0800136 comp_status = le16_to_cpu(
137 ((struct ct_entry_24xx *)ms_pkt)->comp_status);
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700138 else
139 comp_status = le16_to_cpu(ms_pkt->status);
140 switch (comp_status) {
141 case CS_COMPLETE:
142 case CS_DATA_UNDERRUN:
143 case CS_DATA_OVERRUN: /* Overrun? */
144 if (ct_rsp->header.response !=
Bart Van Asschead950362015-07-09 07:24:08 -0700145 cpu_to_be16(CT_ACCEPT_RESPONSE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700146 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2077,
Himanshu Madhanidf57cab2014-09-25 05:16:46 -0400147 "%s failed rejected request on port_id: %02x%02x%02x Compeltion status 0x%x, response 0x%x\n",
148 routine, vha->d_id.b.domain,
149 vha->d_id.b.area, vha->d_id.b.al_pa,
150 comp_status, ct_rsp->header.response);
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700151 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha,
152 0x2078, (uint8_t *)&ct_rsp->header,
153 sizeof(struct ct_rsp_hdr));
Andrew Vasquez4346b142006-12-13 19:20:28 -0800154 rval = QLA_INVALID_COMMAND;
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700155 } else
156 rval = QLA_SUCCESS;
157 break;
158 default:
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700159 ql_dbg(ql_dbg_disc, vha, 0x2033,
160 "%s failed, completion status (%x) on port_id: "
161 "%02x%02x%02x.\n", routine, comp_status,
Giridhar Malavalicf2d7712011-02-23 15:27:09 -0800162 vha->d_id.b.domain, vha->d_id.b.area,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700163 vha->d_id.b.al_pa);
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700164 break;
165 }
166 }
167 return rval;
168}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169
170/**
171 * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
172 * @ha: HA context
173 * @fcport: fcport entry to updated
174 *
175 * Returns 0 on success.
176 */
177int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800178qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179{
180 int rval;
181
182 ms_iocb_entry_t *ms_pkt;
183 struct ct_sns_req *ct_req;
184 struct ct_sns_rsp *ct_rsp;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800185 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800187 if (IS_QLA2100(ha) || IS_QLA2200(ha))
188 return qla2x00_sns_ga_nxt(vha, fcport);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189
190 /* Issue GA_NXT */
191 /* Prepare common MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800192 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GA_NXT_REQ_SIZE,
Andrew Vasquezfd34f552007-07-19 15:06:00 -0700193 GA_NXT_RSP_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194
195 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400196 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GA_NXT_CMD,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197 GA_NXT_RSP_SIZE);
198 ct_rsp = &ha->ct_sns->p.rsp;
199
200 /* Prepare CT arguments -- port_id */
201 ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain;
202 ct_req->req.port_id.port_id[1] = fcport->d_id.b.area;
203 ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa;
204
205 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800206 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207 sizeof(ms_iocb_entry_t));
208 if (rval != QLA_SUCCESS) {
209 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700210 ql_dbg(ql_dbg_disc, vha, 0x2062,
211 "GA_NXT issue IOCB failed (%d).\n", rval);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800212 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GA_NXT") !=
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700213 QLA_SUCCESS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214 rval = QLA_FUNCTION_FAILED;
215 } else {
216 /* Populate fc_port_t entry. */
217 fcport->d_id.b.domain = ct_rsp->rsp.ga_nxt.port_id[0];
218 fcport->d_id.b.area = ct_rsp->rsp.ga_nxt.port_id[1];
219 fcport->d_id.b.al_pa = ct_rsp->rsp.ga_nxt.port_id[2];
220
221 memcpy(fcport->node_name, ct_rsp->rsp.ga_nxt.node_name,
222 WWN_SIZE);
223 memcpy(fcport->port_name, ct_rsp->rsp.ga_nxt.port_name,
224 WWN_SIZE);
225
Armen Baloyana72b9902012-11-21 02:40:30 -0500226 fcport->fc4_type = (ct_rsp->rsp.ga_nxt.fc4_types[2] & BIT_0) ?
227 FC4_TYPE_FCP_SCSI : FC4_TYPE_OTHER;
228
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229 if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE &&
230 ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE)
231 fcport->d_id.b.domain = 0xf0;
232
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700233 ql_dbg(ql_dbg_disc, vha, 0x2063,
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -0400234 "GA_NXT entry - nn %8phN pn %8phN "
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700235 "port_id=%02x%02x%02x.\n",
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -0400236 fcport->node_name, fcport->port_name,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 fcport->d_id.b.domain, fcport->d_id.b.area,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700238 fcport->d_id.b.al_pa);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239 }
240
241 return (rval);
242}
243
Chad Dupuis642ef982012-02-09 11:15:57 -0800244static inline int
245qla2x00_gid_pt_rsp_size(scsi_qla_host_t *vha)
246{
247 return vha->hw->max_fibre_devices * 4 + 16;
248}
249
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250/**
251 * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command.
252 * @ha: HA context
253 * @list: switch info entries to populate
254 *
255 * NOTE: Non-Nx_Ports are not requested.
256 *
257 * Returns 0 on success.
258 */
259int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800260qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261{
262 int rval;
263 uint16_t i;
264
265 ms_iocb_entry_t *ms_pkt;
266 struct ct_sns_req *ct_req;
267 struct ct_sns_rsp *ct_rsp;
268
269 struct ct_sns_gid_pt_data *gid_data;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800270 struct qla_hw_data *ha = vha->hw;
Chad Dupuis642ef982012-02-09 11:15:57 -0800271 uint16_t gid_pt_rsp_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800273 if (IS_QLA2100(ha) || IS_QLA2200(ha))
274 return qla2x00_sns_gid_pt(vha, list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275
276 gid_data = NULL;
Chad Dupuis642ef982012-02-09 11:15:57 -0800277 gid_pt_rsp_size = qla2x00_gid_pt_rsp_size(vha);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278 /* Issue GID_PT */
279 /* Prepare common MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800280 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GID_PT_REQ_SIZE,
Chad Dupuis642ef982012-02-09 11:15:57 -0800281 gid_pt_rsp_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282
283 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400284 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GID_PT_CMD, gid_pt_rsp_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285 ct_rsp = &ha->ct_sns->p.rsp;
286
287 /* Prepare CT arguments -- port_type */
288 ct_req->req.gid_pt.port_type = NS_NX_PORT_TYPE;
289
290 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800291 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292 sizeof(ms_iocb_entry_t));
293 if (rval != QLA_SUCCESS) {
294 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700295 ql_dbg(ql_dbg_disc, vha, 0x2055,
296 "GID_PT issue IOCB failed (%d).\n", rval);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800297 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GID_PT") !=
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700298 QLA_SUCCESS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299 rval = QLA_FUNCTION_FAILED;
300 } else {
301 /* Set port IDs in switch info list. */
Chad Dupuis642ef982012-02-09 11:15:57 -0800302 for (i = 0; i < ha->max_fibre_devices; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303 gid_data = &ct_rsp->rsp.gid_pt.entries[i];
304 list[i].d_id.b.domain = gid_data->port_id[0];
305 list[i].d_id.b.area = gid_data->port_id[1];
306 list[i].d_id.b.al_pa = gid_data->port_id[2];
Andrew Vasqueza3cbdfa2007-08-13 10:13:18 -0700307 memset(list[i].fabric_port_name, 0, WWN_SIZE);
308 list[i].fp_speed = PORT_SPEED_UNKNOWN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309
310 /* Last one exit. */
311 if (gid_data->control_byte & BIT_7) {
312 list[i].d_id.b.rsvd_1 = gid_data->control_byte;
313 break;
314 }
315 }
316
317 /*
318 * If we've used all available slots, then the switch is
319 * reporting back more devices than we can handle with this
320 * single call. Return a failed status, and let GA_NXT handle
321 * the overload.
322 */
Chad Dupuis642ef982012-02-09 11:15:57 -0800323 if (i == ha->max_fibre_devices)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324 rval = QLA_FUNCTION_FAILED;
325 }
326
327 return (rval);
328}
329
330/**
331 * qla2x00_gpn_id() - SNS Get Port Name (GPN_ID) query.
332 * @ha: HA context
333 * @list: switch info entries to populate
334 *
335 * Returns 0 on success.
336 */
337int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800338qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700339{
Chad Dupuis642ef982012-02-09 11:15:57 -0800340 int rval = QLA_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 uint16_t i;
342
343 ms_iocb_entry_t *ms_pkt;
344 struct ct_sns_req *ct_req;
345 struct ct_sns_rsp *ct_rsp;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800346 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800348 if (IS_QLA2100(ha) || IS_QLA2200(ha))
349 return qla2x00_sns_gpn_id(vha, list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350
Chad Dupuis642ef982012-02-09 11:15:57 -0800351 for (i = 0; i < ha->max_fibre_devices; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352 /* Issue GPN_ID */
353 /* Prepare common MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800354 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GPN_ID_REQ_SIZE,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355 GPN_ID_RSP_SIZE);
356
357 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400358 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GPN_ID_CMD,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359 GPN_ID_RSP_SIZE);
360 ct_rsp = &ha->ct_sns->p.rsp;
361
362 /* Prepare CT arguments -- port_id */
363 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
364 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
365 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
366
367 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800368 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 sizeof(ms_iocb_entry_t));
370 if (rval != QLA_SUCCESS) {
371 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700372 ql_dbg(ql_dbg_disc, vha, 0x2056,
373 "GPN_ID issue IOCB failed (%d).\n", rval);
Arun Easidafdf892012-02-09 11:16:00 -0800374 break;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800375 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700376 "GPN_ID") != QLA_SUCCESS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 rval = QLA_FUNCTION_FAILED;
Arun Easidafdf892012-02-09 11:16:00 -0800378 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 } else {
380 /* Save portname */
381 memcpy(list[i].port_name,
382 ct_rsp->rsp.gpn_id.port_name, WWN_SIZE);
383 }
384
385 /* Last device exit. */
386 if (list[i].d_id.b.rsvd_1 != 0)
387 break;
388 }
389
390 return (rval);
391}
392
393/**
394 * qla2x00_gnn_id() - SNS Get Node Name (GNN_ID) query.
395 * @ha: HA context
396 * @list: switch info entries to populate
397 *
398 * Returns 0 on success.
399 */
400int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800401qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402{
Chad Dupuis642ef982012-02-09 11:15:57 -0800403 int rval = QLA_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404 uint16_t i;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800405 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406 ms_iocb_entry_t *ms_pkt;
407 struct ct_sns_req *ct_req;
408 struct ct_sns_rsp *ct_rsp;
409
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800410 if (IS_QLA2100(ha) || IS_QLA2200(ha))
411 return qla2x00_sns_gnn_id(vha, list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412
Chad Dupuis642ef982012-02-09 11:15:57 -0800413 for (i = 0; i < ha->max_fibre_devices; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414 /* Issue GNN_ID */
415 /* Prepare common MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800416 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GNN_ID_REQ_SIZE,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417 GNN_ID_RSP_SIZE);
418
419 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400420 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GNN_ID_CMD,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 GNN_ID_RSP_SIZE);
422 ct_rsp = &ha->ct_sns->p.rsp;
423
424 /* Prepare CT arguments -- port_id */
425 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
426 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
427 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
428
429 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800430 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431 sizeof(ms_iocb_entry_t));
432 if (rval != QLA_SUCCESS) {
433 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700434 ql_dbg(ql_dbg_disc, vha, 0x2057,
435 "GNN_ID issue IOCB failed (%d).\n", rval);
Arun Easidafdf892012-02-09 11:16:00 -0800436 break;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800437 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700438 "GNN_ID") != QLA_SUCCESS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439 rval = QLA_FUNCTION_FAILED;
Arun Easidafdf892012-02-09 11:16:00 -0800440 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441 } else {
442 /* Save nodename */
443 memcpy(list[i].node_name,
444 ct_rsp->rsp.gnn_id.node_name, WWN_SIZE);
445
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700446 ql_dbg(ql_dbg_disc, vha, 0x2058,
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -0400447 "GID_PT entry - nn %8phN pn %8phN "
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448 "portid=%02x%02x%02x.\n",
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -0400449 list[i].node_name, list[i].port_name,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450 list[i].d_id.b.domain, list[i].d_id.b.area,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700451 list[i].d_id.b.al_pa);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 }
453
454 /* Last device exit. */
455 if (list[i].d_id.b.rsvd_1 != 0)
456 break;
457 }
458
459 return (rval);
460}
461
462/**
463 * qla2x00_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
464 * @ha: HA context
465 *
466 * Returns 0 on success.
467 */
468int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800469qla2x00_rft_id(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470{
471 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800472 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 ms_iocb_entry_t *ms_pkt;
474 struct ct_sns_req *ct_req;
475 struct ct_sns_rsp *ct_rsp;
476
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800477 if (IS_QLA2100(ha) || IS_QLA2200(ha))
478 return qla2x00_sns_rft_id(vha);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479
480 /* Issue RFT_ID */
481 /* Prepare common MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800482 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, RFT_ID_REQ_SIZE,
Andrew Vasquezfd34f552007-07-19 15:06:00 -0700483 RFT_ID_RSP_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484
485 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400486 ct_req = qla2x00_prep_ct_req(ha->ct_sns, RFT_ID_CMD,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487 RFT_ID_RSP_SIZE);
488 ct_rsp = &ha->ct_sns->p.rsp;
489
490 /* Prepare CT arguments -- port_id, FC-4 types */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800491 ct_req->req.rft_id.port_id[0] = vha->d_id.b.domain;
492 ct_req->req.rft_id.port_id[1] = vha->d_id.b.area;
493 ct_req->req.rft_id.port_id[2] = vha->d_id.b.al_pa;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494
495 ct_req->req.rft_id.fc4_types[2] = 0x01; /* FCP-3 */
496
497 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800498 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499 sizeof(ms_iocb_entry_t));
500 if (rval != QLA_SUCCESS) {
501 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700502 ql_dbg(ql_dbg_disc, vha, 0x2043,
503 "RFT_ID issue IOCB failed (%d).\n", rval);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800504 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RFT_ID") !=
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700505 QLA_SUCCESS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506 rval = QLA_FUNCTION_FAILED;
507 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700508 ql_dbg(ql_dbg_disc, vha, 0x2044,
509 "RFT_ID exiting normally.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510 }
511
512 return (rval);
513}
514
515/**
516 * qla2x00_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the HBA.
517 * @ha: HA context
518 *
519 * Returns 0 on success.
520 */
521int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800522qla2x00_rff_id(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523{
524 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800525 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526 ms_iocb_entry_t *ms_pkt;
527 struct ct_sns_req *ct_req;
528 struct ct_sns_rsp *ct_rsp;
529
530 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700531 ql_dbg(ql_dbg_disc, vha, 0x2046,
532 "RFF_ID call not supported on ISP2100/ISP2200.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533 return (QLA_SUCCESS);
534 }
535
536 /* Issue RFF_ID */
537 /* Prepare common MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800538 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, RFF_ID_REQ_SIZE,
Andrew Vasquezfd34f552007-07-19 15:06:00 -0700539 RFF_ID_RSP_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540
541 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400542 ct_req = qla2x00_prep_ct_req(ha->ct_sns, RFF_ID_CMD,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 RFF_ID_RSP_SIZE);
544 ct_rsp = &ha->ct_sns->p.rsp;
545
546 /* Prepare CT arguments -- port_id, FC-4 feature, FC-4 type */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800547 ct_req->req.rff_id.port_id[0] = vha->d_id.b.domain;
548 ct_req->req.rff_id.port_id[1] = vha->d_id.b.area;
549 ct_req->req.rff_id.port_id[2] = vha->d_id.b.al_pa;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550
Nicholas Bellinger2d70c102012-05-15 14:34:28 -0400551 qlt_rff_id(vha, ct_req);
552
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553 ct_req->req.rff_id.fc4_type = 0x08; /* SCSI - FCP */
554
555 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800556 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 sizeof(ms_iocb_entry_t));
558 if (rval != QLA_SUCCESS) {
559 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700560 ql_dbg(ql_dbg_disc, vha, 0x2047,
561 "RFF_ID issue IOCB failed (%d).\n", rval);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800562 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RFF_ID") !=
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700563 QLA_SUCCESS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564 rval = QLA_FUNCTION_FAILED;
565 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700566 ql_dbg(ql_dbg_disc, vha, 0x2048,
567 "RFF_ID exiting normally.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 }
569
570 return (rval);
571}
572
573/**
574 * qla2x00_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
575 * @ha: HA context
576 *
577 * Returns 0 on success.
578 */
579int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800580qla2x00_rnn_id(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581{
582 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800583 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 ms_iocb_entry_t *ms_pkt;
585 struct ct_sns_req *ct_req;
586 struct ct_sns_rsp *ct_rsp;
587
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800588 if (IS_QLA2100(ha) || IS_QLA2200(ha))
589 return qla2x00_sns_rnn_id(vha);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590
591 /* Issue RNN_ID */
592 /* Prepare common MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800593 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, RNN_ID_REQ_SIZE,
Andrew Vasquezfd34f552007-07-19 15:06:00 -0700594 RNN_ID_RSP_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595
596 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400597 ct_req = qla2x00_prep_ct_req(ha->ct_sns, RNN_ID_CMD, RNN_ID_RSP_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 ct_rsp = &ha->ct_sns->p.rsp;
599
600 /* Prepare CT arguments -- port_id, node_name */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800601 ct_req->req.rnn_id.port_id[0] = vha->d_id.b.domain;
602 ct_req->req.rnn_id.port_id[1] = vha->d_id.b.area;
603 ct_req->req.rnn_id.port_id[2] = vha->d_id.b.al_pa;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800605 memcpy(ct_req->req.rnn_id.node_name, vha->node_name, WWN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606
607 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800608 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609 sizeof(ms_iocb_entry_t));
610 if (rval != QLA_SUCCESS) {
611 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700612 ql_dbg(ql_dbg_disc, vha, 0x204d,
613 "RNN_ID issue IOCB failed (%d).\n", rval);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800614 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RNN_ID") !=
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700615 QLA_SUCCESS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616 rval = QLA_FUNCTION_FAILED;
617 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700618 ql_dbg(ql_dbg_disc, vha, 0x204e,
619 "RNN_ID exiting normally.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620 }
621
622 return (rval);
623}
624
Andrew Vasquez1620f7c2006-10-02 12:00:44 -0700625void
Himanshu Madhanidf57cab2014-09-25 05:16:46 -0400626qla2x00_get_sym_node_name(scsi_qla_host_t *vha, uint8_t *snn, size_t size)
Andrew Vasquez1620f7c2006-10-02 12:00:44 -0700627{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800628 struct qla_hw_data *ha = vha->hw;
Giridhar Malavali8ae6d9c2013-03-28 08:21:23 -0400629
630 if (IS_QLAFX00(ha))
Himanshu Madhanidf57cab2014-09-25 05:16:46 -0400631 snprintf(snn, size, "%s FW:v%s DVR:v%s", ha->model_number,
Giridhar Malavali8ae6d9c2013-03-28 08:21:23 -0400632 ha->mr.fw_version, qla2x00_version_str);
633 else
Himanshu Madhanidf57cab2014-09-25 05:16:46 -0400634 snprintf(snn, size,
635 "%s FW:v%d.%02d.%02d DVR:v%s", ha->model_number,
Giridhar Malavali8ae6d9c2013-03-28 08:21:23 -0400636 ha->fw_major_version, ha->fw_minor_version,
637 ha->fw_subminor_version, qla2x00_version_str);
Andrew Vasquez1620f7c2006-10-02 12:00:44 -0700638}
639
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640/**
641 * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA.
642 * @ha: HA context
643 *
644 * Returns 0 on success.
645 */
646int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800647qla2x00_rsnn_nn(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648{
649 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800650 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651 ms_iocb_entry_t *ms_pkt;
652 struct ct_sns_req *ct_req;
653 struct ct_sns_rsp *ct_rsp;
654
655 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700656 ql_dbg(ql_dbg_disc, vha, 0x2050,
657 "RSNN_ID call unsupported on ISP2100/ISP2200.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658 return (QLA_SUCCESS);
659 }
660
661 /* Issue RSNN_NN */
662 /* Prepare common MS IOCB */
663 /* Request size adjusted after CT preparation */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800664 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, 0, RSNN_NN_RSP_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665
666 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -0400667 ct_req = qla2x00_prep_ct_req(ha->ct_sns, RSNN_NN_CMD,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668 RSNN_NN_RSP_SIZE);
669 ct_rsp = &ha->ct_sns->p.rsp;
670
671 /* Prepare CT arguments -- node_name, symbolic node_name, size */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800672 memcpy(ct_req->req.rsnn_nn.node_name, vha->node_name, WWN_SIZE);
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700673
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674 /* Prepare the Symbolic Node Name */
Himanshu Madhanidf57cab2014-09-25 05:16:46 -0400675 qla2x00_get_sym_node_name(vha, ct_req->req.rsnn_nn.sym_node_name,
676 sizeof(ct_req->req.rsnn_nn.sym_node_name));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677
678 /* Calculate SNN length */
Andrew Vasquez1620f7c2006-10-02 12:00:44 -0700679 ct_req->req.rsnn_nn.name_len =
680 (uint8_t)strlen(ct_req->req.rsnn_nn.sym_node_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681
682 /* Update MS IOCB request */
683 ms_pkt->req_bytecount =
684 cpu_to_le32(24 + 1 + ct_req->req.rsnn_nn.name_len);
685 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
686
687 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800688 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689 sizeof(ms_iocb_entry_t));
690 if (rval != QLA_SUCCESS) {
691 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700692 ql_dbg(ql_dbg_disc, vha, 0x2051,
693 "RSNN_NN issue IOCB failed (%d).\n", rval);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800694 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RSNN_NN") !=
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700695 QLA_SUCCESS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 rval = QLA_FUNCTION_FAILED;
697 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700698 ql_dbg(ql_dbg_disc, vha, 0x2052,
699 "RSNN_NN exiting normally.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 }
701
702 return (rval);
703}
704
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705/**
706 * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query.
707 * @ha: HA context
708 * @cmd: GS command
709 * @scmd_len: Subcommand length
710 * @data_size: response size in bytes
711 *
712 * Returns a pointer to the @ha's sns_cmd.
713 */
714static inline struct sns_cmd_pkt *
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800715qla2x00_prep_sns_cmd(scsi_qla_host_t *vha, uint16_t cmd, uint16_t scmd_len,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716 uint16_t data_size)
717{
718 uint16_t wc;
719 struct sns_cmd_pkt *sns_cmd;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800720 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721
722 sns_cmd = ha->sns_cmd;
723 memset(sns_cmd, 0, sizeof(struct sns_cmd_pkt));
724 wc = data_size / 2; /* Size in 16bit words. */
725 sns_cmd->p.cmd.buffer_length = cpu_to_le16(wc);
726 sns_cmd->p.cmd.buffer_address[0] = cpu_to_le32(LSD(ha->sns_cmd_dma));
727 sns_cmd->p.cmd.buffer_address[1] = cpu_to_le32(MSD(ha->sns_cmd_dma));
728 sns_cmd->p.cmd.subcommand_length = cpu_to_le16(scmd_len);
729 sns_cmd->p.cmd.subcommand = cpu_to_le16(cmd);
730 wc = (data_size - 16) / 4; /* Size in 32bit words. */
731 sns_cmd->p.cmd.size = cpu_to_le16(wc);
732
Joe Carnucciofabbb8d2013-08-27 01:37:40 -0400733 vha->qla_stats.control_requests++;
734
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 return (sns_cmd);
736}
737
738/**
739 * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
740 * @ha: HA context
741 * @fcport: fcport entry to updated
742 *
743 * This command uses the old Exectute SNS Command mailbox routine.
744 *
745 * Returns 0 on success.
746 */
747static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800748qla2x00_sns_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749{
Chad Dupuis642ef982012-02-09 11:15:57 -0800750 int rval = QLA_SUCCESS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800751 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752 struct sns_cmd_pkt *sns_cmd;
753
754 /* Issue GA_NXT. */
755 /* Prepare SNS command request. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800756 sns_cmd = qla2x00_prep_sns_cmd(vha, GA_NXT_CMD, GA_NXT_SNS_SCMD_LEN,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757 GA_NXT_SNS_DATA_SIZE);
758
759 /* Prepare SNS command arguments -- port_id. */
760 sns_cmd->p.cmd.param[0] = fcport->d_id.b.al_pa;
761 sns_cmd->p.cmd.param[1] = fcport->d_id.b.area;
762 sns_cmd->p.cmd.param[2] = fcport->d_id.b.domain;
763
764 /* Execute SNS command. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800765 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GA_NXT_SNS_CMD_SIZE / 2,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 sizeof(struct sns_cmd_pkt));
767 if (rval != QLA_SUCCESS) {
768 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700769 ql_dbg(ql_dbg_disc, vha, 0x205f,
770 "GA_NXT Send SNS failed (%d).\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 } else if (sns_cmd->p.gan_data[8] != 0x80 ||
772 sns_cmd->p.gan_data[9] != 0x02) {
Chad Dupuiscfb09192011-11-18 09:03:07 -0800773 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2084,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700774 "GA_NXT failed, rejected request ga_nxt_rsp:\n");
775 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2074,
776 sns_cmd->p.gan_data, 16);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777 rval = QLA_FUNCTION_FAILED;
778 } else {
779 /* Populate fc_port_t entry. */
780 fcport->d_id.b.domain = sns_cmd->p.gan_data[17];
781 fcport->d_id.b.area = sns_cmd->p.gan_data[18];
782 fcport->d_id.b.al_pa = sns_cmd->p.gan_data[19];
783
784 memcpy(fcport->node_name, &sns_cmd->p.gan_data[284], WWN_SIZE);
785 memcpy(fcport->port_name, &sns_cmd->p.gan_data[20], WWN_SIZE);
786
787 if (sns_cmd->p.gan_data[16] != NS_N_PORT_TYPE &&
788 sns_cmd->p.gan_data[16] != NS_NL_PORT_TYPE)
789 fcport->d_id.b.domain = 0xf0;
790
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700791 ql_dbg(ql_dbg_disc, vha, 0x2061,
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -0400792 "GA_NXT entry - nn %8phN pn %8phN "
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700793 "port_id=%02x%02x%02x.\n",
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -0400794 fcport->node_name, fcport->port_name,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795 fcport->d_id.b.domain, fcport->d_id.b.area,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700796 fcport->d_id.b.al_pa);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797 }
798
799 return (rval);
800}
801
802/**
803 * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command.
804 * @ha: HA context
805 * @list: switch info entries to populate
806 *
807 * This command uses the old Exectute SNS Command mailbox routine.
808 *
809 * NOTE: Non-Nx_Ports are not requested.
810 *
811 * Returns 0 on success.
812 */
813static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800814qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815{
816 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800817 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818 uint16_t i;
819 uint8_t *entry;
820 struct sns_cmd_pkt *sns_cmd;
Chad Dupuis642ef982012-02-09 11:15:57 -0800821 uint16_t gid_pt_sns_data_size;
822
823 gid_pt_sns_data_size = qla2x00_gid_pt_rsp_size(vha);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824
825 /* Issue GID_PT. */
826 /* Prepare SNS command request. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800827 sns_cmd = qla2x00_prep_sns_cmd(vha, GID_PT_CMD, GID_PT_SNS_SCMD_LEN,
Chad Dupuis642ef982012-02-09 11:15:57 -0800828 gid_pt_sns_data_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829
830 /* Prepare SNS command arguments -- port_type. */
831 sns_cmd->p.cmd.param[0] = NS_NX_PORT_TYPE;
832
833 /* Execute SNS command. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800834 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GID_PT_SNS_CMD_SIZE / 2,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835 sizeof(struct sns_cmd_pkt));
836 if (rval != QLA_SUCCESS) {
837 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700838 ql_dbg(ql_dbg_disc, vha, 0x206d,
839 "GID_PT Send SNS failed (%d).\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840 } else if (sns_cmd->p.gid_data[8] != 0x80 ||
841 sns_cmd->p.gid_data[9] != 0x02) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700842 ql_dbg(ql_dbg_disc, vha, 0x202f,
843 "GID_PT failed, rejected request, gid_rsp:\n");
844 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2081,
845 sns_cmd->p.gid_data, 16);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846 rval = QLA_FUNCTION_FAILED;
847 } else {
848 /* Set port IDs in switch info list. */
Chad Dupuis642ef982012-02-09 11:15:57 -0800849 for (i = 0; i < ha->max_fibre_devices; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850 entry = &sns_cmd->p.gid_data[(i * 4) + 16];
851 list[i].d_id.b.domain = entry[1];
852 list[i].d_id.b.area = entry[2];
853 list[i].d_id.b.al_pa = entry[3];
854
855 /* Last one exit. */
856 if (entry[0] & BIT_7) {
857 list[i].d_id.b.rsvd_1 = entry[0];
858 break;
859 }
860 }
861
862 /*
863 * If we've used all available slots, then the switch is
864 * reporting back more devices that we can handle with this
865 * single call. Return a failed status, and let GA_NXT handle
866 * the overload.
867 */
Chad Dupuis642ef982012-02-09 11:15:57 -0800868 if (i == ha->max_fibre_devices)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869 rval = QLA_FUNCTION_FAILED;
870 }
871
872 return (rval);
873}
874
875/**
876 * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query.
877 * @ha: HA context
878 * @list: switch info entries to populate
879 *
880 * This command uses the old Exectute SNS Command mailbox routine.
881 *
882 * Returns 0 on success.
883 */
884static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800885qla2x00_sns_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886{
Chad Dupuis642ef982012-02-09 11:15:57 -0800887 int rval = QLA_SUCCESS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800888 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889 uint16_t i;
890 struct sns_cmd_pkt *sns_cmd;
891
Chad Dupuis642ef982012-02-09 11:15:57 -0800892 for (i = 0; i < ha->max_fibre_devices; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 /* Issue GPN_ID */
894 /* Prepare SNS command request. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800895 sns_cmd = qla2x00_prep_sns_cmd(vha, GPN_ID_CMD,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896 GPN_ID_SNS_SCMD_LEN, GPN_ID_SNS_DATA_SIZE);
897
898 /* Prepare SNS command arguments -- port_id. */
899 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa;
900 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area;
901 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain;
902
903 /* Execute SNS command. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800904 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 GPN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt));
906 if (rval != QLA_SUCCESS) {
907 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700908 ql_dbg(ql_dbg_disc, vha, 0x2032,
909 "GPN_ID Send SNS failed (%d).\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910 } else if (sns_cmd->p.gpn_data[8] != 0x80 ||
911 sns_cmd->p.gpn_data[9] != 0x02) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700912 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207e,
913 "GPN_ID failed, rejected request, gpn_rsp:\n");
Giridhar Malavali8ae6d9c2013-03-28 08:21:23 -0400914 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207f,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700915 sns_cmd->p.gpn_data, 16);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916 rval = QLA_FUNCTION_FAILED;
917 } else {
918 /* Save portname */
919 memcpy(list[i].port_name, &sns_cmd->p.gpn_data[16],
920 WWN_SIZE);
921 }
922
923 /* Last device exit. */
924 if (list[i].d_id.b.rsvd_1 != 0)
925 break;
926 }
927
928 return (rval);
929}
930
931/**
932 * qla2x00_sns_gnn_id() - SNS Get Node Name (GNN_ID) query.
933 * @ha: HA context
934 * @list: switch info entries to populate
935 *
936 * This command uses the old Exectute SNS Command mailbox routine.
937 *
938 * Returns 0 on success.
939 */
940static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800941qla2x00_sns_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942{
Chad Dupuis642ef982012-02-09 11:15:57 -0800943 int rval = QLA_SUCCESS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800944 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945 uint16_t i;
946 struct sns_cmd_pkt *sns_cmd;
947
Chad Dupuis642ef982012-02-09 11:15:57 -0800948 for (i = 0; i < ha->max_fibre_devices; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 /* Issue GNN_ID */
950 /* Prepare SNS command request. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800951 sns_cmd = qla2x00_prep_sns_cmd(vha, GNN_ID_CMD,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952 GNN_ID_SNS_SCMD_LEN, GNN_ID_SNS_DATA_SIZE);
953
954 /* Prepare SNS command arguments -- port_id. */
955 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa;
956 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area;
957 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain;
958
959 /* Execute SNS command. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800960 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961 GNN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt));
962 if (rval != QLA_SUCCESS) {
963 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700964 ql_dbg(ql_dbg_disc, vha, 0x203f,
965 "GNN_ID Send SNS failed (%d).\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966 } else if (sns_cmd->p.gnn_data[8] != 0x80 ||
967 sns_cmd->p.gnn_data[9] != 0x02) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700968 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2082,
969 "GNN_ID failed, rejected request, gnn_rsp:\n");
970 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207a,
971 sns_cmd->p.gnn_data, 16);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972 rval = QLA_FUNCTION_FAILED;
973 } else {
974 /* Save nodename */
975 memcpy(list[i].node_name, &sns_cmd->p.gnn_data[16],
976 WWN_SIZE);
977
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700978 ql_dbg(ql_dbg_disc, vha, 0x206e,
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -0400979 "GID_PT entry - nn %8phN pn %8phN "
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700980 "port_id=%02x%02x%02x.\n",
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -0400981 list[i].node_name, list[i].port_name,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982 list[i].d_id.b.domain, list[i].d_id.b.area,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700983 list[i].d_id.b.al_pa);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984 }
985
986 /* Last device exit. */
987 if (list[i].d_id.b.rsvd_1 != 0)
988 break;
989 }
990
991 return (rval);
992}
993
994/**
995 * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
996 * @ha: HA context
997 *
998 * This command uses the old Exectute SNS Command mailbox routine.
999 *
1000 * Returns 0 on success.
1001 */
1002static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001003qla2x00_sns_rft_id(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004{
1005 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001006 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007 struct sns_cmd_pkt *sns_cmd;
1008
1009 /* Issue RFT_ID. */
1010 /* Prepare SNS command request. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001011 sns_cmd = qla2x00_prep_sns_cmd(vha, RFT_ID_CMD, RFT_ID_SNS_SCMD_LEN,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012 RFT_ID_SNS_DATA_SIZE);
1013
1014 /* Prepare SNS command arguments -- port_id, FC-4 types */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001015 sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa;
1016 sns_cmd->p.cmd.param[1] = vha->d_id.b.area;
1017 sns_cmd->p.cmd.param[2] = vha->d_id.b.domain;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018
1019 sns_cmd->p.cmd.param[5] = 0x01; /* FCP-3 */
1020
1021 /* Execute SNS command. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001022 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RFT_ID_SNS_CMD_SIZE / 2,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023 sizeof(struct sns_cmd_pkt));
1024 if (rval != QLA_SUCCESS) {
1025 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001026 ql_dbg(ql_dbg_disc, vha, 0x2060,
1027 "RFT_ID Send SNS failed (%d).\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 } else if (sns_cmd->p.rft_data[8] != 0x80 ||
1029 sns_cmd->p.rft_data[9] != 0x02) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001030 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2083,
1031 "RFT_ID failed, rejected request rft_rsp:\n");
1032 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2080,
1033 sns_cmd->p.rft_data, 16);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034 rval = QLA_FUNCTION_FAILED;
1035 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001036 ql_dbg(ql_dbg_disc, vha, 0x2073,
1037 "RFT_ID exiting normally.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038 }
1039
1040 return (rval);
1041}
1042
1043/**
1044 * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
1045 * HBA.
1046 * @ha: HA context
1047 *
1048 * This command uses the old Exectute SNS Command mailbox routine.
1049 *
1050 * Returns 0 on success.
1051 */
1052static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001053qla2x00_sns_rnn_id(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054{
1055 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001056 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057 struct sns_cmd_pkt *sns_cmd;
1058
1059 /* Issue RNN_ID. */
1060 /* Prepare SNS command request. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001061 sns_cmd = qla2x00_prep_sns_cmd(vha, RNN_ID_CMD, RNN_ID_SNS_SCMD_LEN,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062 RNN_ID_SNS_DATA_SIZE);
1063
1064 /* Prepare SNS command arguments -- port_id, nodename. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001065 sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa;
1066 sns_cmd->p.cmd.param[1] = vha->d_id.b.area;
1067 sns_cmd->p.cmd.param[2] = vha->d_id.b.domain;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001069 sns_cmd->p.cmd.param[4] = vha->node_name[7];
1070 sns_cmd->p.cmd.param[5] = vha->node_name[6];
1071 sns_cmd->p.cmd.param[6] = vha->node_name[5];
1072 sns_cmd->p.cmd.param[7] = vha->node_name[4];
1073 sns_cmd->p.cmd.param[8] = vha->node_name[3];
1074 sns_cmd->p.cmd.param[9] = vha->node_name[2];
1075 sns_cmd->p.cmd.param[10] = vha->node_name[1];
1076 sns_cmd->p.cmd.param[11] = vha->node_name[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077
1078 /* Execute SNS command. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001079 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RNN_ID_SNS_CMD_SIZE / 2,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080 sizeof(struct sns_cmd_pkt));
1081 if (rval != QLA_SUCCESS) {
1082 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001083 ql_dbg(ql_dbg_disc, vha, 0x204a,
1084 "RNN_ID Send SNS failed (%d).\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 } else if (sns_cmd->p.rnn_data[8] != 0x80 ||
1086 sns_cmd->p.rnn_data[9] != 0x02) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001087 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207b,
1088 "RNN_ID failed, rejected request, rnn_rsp:\n");
1089 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207c,
1090 sns_cmd->p.rnn_data, 16);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091 rval = QLA_FUNCTION_FAILED;
1092 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001093 ql_dbg(ql_dbg_disc, vha, 0x204c,
1094 "RNN_ID exiting normally.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095 }
1096
1097 return (rval);
1098}
Andrew Vasquezcca53352005-08-26 19:08:30 -07001099
1100/**
Joe Perchesb1c11812008-02-03 17:28:22 +02001101 * qla2x00_mgmt_svr_login() - Login to fabric Management Service.
Andrew Vasquezcca53352005-08-26 19:08:30 -07001102 * @ha: HA context
1103 *
1104 * Returns 0 on success.
1105 */
1106static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001107qla2x00_mgmt_svr_login(scsi_qla_host_t *vha)
Andrew Vasquezcca53352005-08-26 19:08:30 -07001108{
Chad Dupuis0b91d112012-02-09 11:15:42 -08001109 int ret, rval;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001110 uint16_t mb[MAILBOX_REGISTER_COUNT];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001111 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001112 ret = QLA_SUCCESS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001113 if (vha->flags.management_server_logged_in)
Andrew Vasquezcca53352005-08-26 19:08:30 -07001114 return ret;
1115
Chad Dupuis0b91d112012-02-09 11:15:42 -08001116 rval = ha->isp_ops->fabric_login(vha, vha->mgmt_svr_loop_id, 0xff, 0xff,
Andrew Vasquez58570ac2012-08-22 14:21:18 -04001117 0xfa, mb, BIT_1);
Chad Dupuis0b91d112012-02-09 11:15:42 -08001118 if (rval != QLA_SUCCESS || mb[0] != MBS_COMMAND_COMPLETE) {
1119 if (rval == QLA_MEMORY_ALLOC_FAILED)
1120 ql_dbg(ql_dbg_disc, vha, 0x2085,
1121 "Failed management_server login: loopid=%x "
1122 "rval=%d\n", vha->mgmt_svr_loop_id, rval);
1123 else
1124 ql_dbg(ql_dbg_disc, vha, 0x2024,
1125 "Failed management_server login: loopid=%x "
1126 "mb[0]=%x mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x.\n",
1127 vha->mgmt_svr_loop_id, mb[0], mb[1], mb[2], mb[6],
1128 mb[7]);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001129 ret = QLA_FUNCTION_FAILED;
1130 } else
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001131 vha->flags.management_server_logged_in = 1;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001132
1133 return ret;
1134}
1135
1136/**
1137 * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
1138 * @ha: HA context
1139 * @req_size: request size in bytes
1140 * @rsp_size: response size in bytes
1141 *
1142 * Returns a pointer to the @ha's ms_iocb.
1143 */
1144void *
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001145qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size,
Andrew Vasquezcca53352005-08-26 19:08:30 -07001146 uint32_t rsp_size)
1147{
1148 ms_iocb_entry_t *ms_pkt;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001149 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001150 ms_pkt = ha->ms_iocb;
1151 memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
1152
1153 ms_pkt->entry_type = MS_IOCB_TYPE;
1154 ms_pkt->entry_count = 1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001155 SET_TARGET_ID(ha, ms_pkt->loop_id, vha->mgmt_svr_loop_id);
Bart Van Asschead950362015-07-09 07:24:08 -07001156 ms_pkt->control_flags = cpu_to_le16(CF_READ | CF_HEAD_TAG);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08001157 ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Bart Van Asschead950362015-07-09 07:24:08 -07001158 ms_pkt->cmd_dsd_count = cpu_to_le16(1);
1159 ms_pkt->total_dsd_count = cpu_to_le16(2);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001160 ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
1161 ms_pkt->req_bytecount = cpu_to_le32(req_size);
1162
1163 ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1164 ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1165 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
1166
1167 ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1168 ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1169 ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount;
1170
1171 return ms_pkt;
1172}
1173
1174/**
1175 * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
1176 * @ha: HA context
1177 * @req_size: request size in bytes
1178 * @rsp_size: response size in bytes
1179 *
1180 * Returns a pointer to the @ha's ms_iocb.
1181 */
1182void *
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001183qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size,
Andrew Vasquezcca53352005-08-26 19:08:30 -07001184 uint32_t rsp_size)
1185{
1186 struct ct_entry_24xx *ct_pkt;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001187 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001188
1189 ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
1190 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
1191
1192 ct_pkt->entry_type = CT_IOCB_TYPE;
1193 ct_pkt->entry_count = 1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001194 ct_pkt->nport_handle = cpu_to_le16(vha->mgmt_svr_loop_id);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08001195 ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Bart Van Asschead950362015-07-09 07:24:08 -07001196 ct_pkt->cmd_dsd_count = cpu_to_le16(1);
1197 ct_pkt->rsp_dsd_count = cpu_to_le16(1);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001198 ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
1199 ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
1200
1201 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1202 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1203 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
1204
1205 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1206 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1207 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001208 ct_pkt->vp_index = vha->vp_idx;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001209
1210 return ct_pkt;
1211}
1212
1213static inline ms_iocb_entry_t *
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001214qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size)
Andrew Vasquezcca53352005-08-26 19:08:30 -07001215{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001216 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001217 ms_iocb_entry_t *ms_pkt = ha->ms_iocb;
1218 struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
1219
Andrew Vasqueze4289242007-07-19 15:05:56 -07001220 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquezcca53352005-08-26 19:08:30 -07001221 ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
1222 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
1223 } else {
1224 ms_pkt->req_bytecount = cpu_to_le32(req_size);
1225 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
1226 }
1227
1228 return ms_pkt;
1229}
1230
1231/**
1232 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
1233 * @ct_req: CT request buffer
1234 * @cmd: GS command
1235 * @rsp_size: response size in bytes
1236 *
1237 * Returns a pointer to the intitialized @ct_req.
1238 */
1239static inline struct ct_sns_req *
Bart Van Assche6ec6f902013-06-25 11:27:28 -04001240qla2x00_prep_ct_fdmi_req(struct ct_sns_pkt *p, uint16_t cmd,
Andrew Vasquezcca53352005-08-26 19:08:30 -07001241 uint16_t rsp_size)
1242{
Bart Van Assche6ec6f902013-06-25 11:27:28 -04001243 memset(p, 0, sizeof(struct ct_sns_pkt));
Andrew Vasquezcca53352005-08-26 19:08:30 -07001244
Bart Van Assche6ec6f902013-06-25 11:27:28 -04001245 p->p.req.header.revision = 0x01;
1246 p->p.req.header.gs_type = 0xFA;
1247 p->p.req.header.gs_subtype = 0x10;
1248 p->p.req.command = cpu_to_be16(cmd);
1249 p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001250
Bart Van Assche6ec6f902013-06-25 11:27:28 -04001251 return &p->p.req;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001252}
1253
1254/**
1255 * qla2x00_fdmi_rhba() -
1256 * @ha: HA context
1257 *
1258 * Returns 0 on success.
1259 */
1260static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001261qla2x00_fdmi_rhba(scsi_qla_host_t *vha)
Andrew Vasquezcca53352005-08-26 19:08:30 -07001262{
1263 int rval, alen;
1264 uint32_t size, sn;
1265
1266 ms_iocb_entry_t *ms_pkt;
1267 struct ct_sns_req *ct_req;
1268 struct ct_sns_rsp *ct_rsp;
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001269 void *entries;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001270 struct ct_fdmi_hba_attr *eiter;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001271 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezcca53352005-08-26 19:08:30 -07001272
1273 /* Issue RHBA */
1274 /* Prepare common MS IOCB */
1275 /* Request size adjusted after CT preparation */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001276 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001277
1278 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -04001279 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RHBA_CMD, RHBA_RSP_SIZE);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001280 ct_rsp = &ha->ct_sns->p.rsp;
1281
1282 /* Prepare FDMI command arguments -- attribute block, attributes. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001283 memcpy(ct_req->req.rhba.hba_identifier, vha->port_name, WWN_SIZE);
Bart Van Asschead950362015-07-09 07:24:08 -07001284 ct_req->req.rhba.entry_count = cpu_to_be32(1);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001285 memcpy(ct_req->req.rhba.port_name, vha->port_name, WWN_SIZE);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001286 size = 2 * WWN_SIZE + 4 + 4;
1287
1288 /* Attributes */
1289 ct_req->req.rhba.attrs.count =
Bart Van Asschead950362015-07-09 07:24:08 -07001290 cpu_to_be32(FDMI_HBA_ATTR_COUNT);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001291 entries = ct_req->req.rhba.hba_identifier;
1292
1293 /* Nodename. */
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001294 eiter = entries + size;
Bart Van Asschead950362015-07-09 07:24:08 -07001295 eiter->type = cpu_to_be16(FDMI_HBA_NODE_NAME);
1296 eiter->len = cpu_to_be16(4 + WWN_SIZE);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001297 memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001298 size += 4 + WWN_SIZE;
1299
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001300 ql_dbg(ql_dbg_disc, vha, 0x2025,
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -04001301 "NodeName = %8phN.\n", eiter->a.node_name);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001302
1303 /* Manufacturer. */
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001304 eiter = entries + size;
Bart Van Asschead950362015-07-09 07:24:08 -07001305 eiter->type = cpu_to_be16(FDMI_HBA_MANUFACTURER);
Paul Bollef24b6972013-02-08 01:57:55 -05001306 alen = strlen(QLA2XXX_MANUFACTURER);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001307 snprintf(eiter->a.manufacturer, sizeof(eiter->a.manufacturer),
1308 "%s", "QLogic Corporation");
1309 alen += 4 - (alen & 3);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001310 eiter->len = cpu_to_be16(4 + alen);
1311 size += 4 + alen;
1312
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001313 ql_dbg(ql_dbg_disc, vha, 0x2026,
1314 "Manufacturer = %s.\n", eiter->a.manufacturer);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001315
1316 /* Serial number. */
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001317 eiter = entries + size;
Bart Van Asschead950362015-07-09 07:24:08 -07001318 eiter->type = cpu_to_be16(FDMI_HBA_SERIAL_NUMBER);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001319 if (IS_FWI2_CAPABLE(ha))
1320 qla2xxx_get_vpd_field(vha, "SN", eiter->a.serial_num,
1321 sizeof(eiter->a.serial_num));
1322 else {
1323 sn = ((ha->serial0 & 0x1f) << 16) |
1324 (ha->serial2 << 8) | ha->serial1;
1325 snprintf(eiter->a.serial_num, sizeof(eiter->a.serial_num),
1326 "%c%05d", 'A' + sn / 100000, sn % 100000);
1327 }
Andrew Vasquezcca53352005-08-26 19:08:30 -07001328 alen = strlen(eiter->a.serial_num);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001329 alen += 4 - (alen & 3);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001330 eiter->len = cpu_to_be16(4 + alen);
1331 size += 4 + alen;
1332
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001333 ql_dbg(ql_dbg_disc, vha, 0x2027,
1334 "Serial no. = %s.\n", eiter->a.serial_num);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001335
1336 /* Model name. */
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001337 eiter = entries + size;
Bart Van Asschead950362015-07-09 07:24:08 -07001338 eiter->type = cpu_to_be16(FDMI_HBA_MODEL);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001339 snprintf(eiter->a.model, sizeof(eiter->a.model),
1340 "%s", ha->model_number);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001341 alen = strlen(eiter->a.model);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001342 alen += 4 - (alen & 3);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001343 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, 0x2028,
1347 "Model Name = %s.\n", eiter->a.model);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001348
1349 /* Model description. */
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001350 eiter = entries + size;
Bart Van Asschead950362015-07-09 07:24:08 -07001351 eiter->type = cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001352 snprintf(eiter->a.model_desc, sizeof(eiter->a.model_desc),
1353 "%s", ha->model_desc);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001354 alen = strlen(eiter->a.model_desc);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001355 alen += 4 - (alen & 3);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001356 eiter->len = cpu_to_be16(4 + alen);
1357 size += 4 + alen;
1358
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001359 ql_dbg(ql_dbg_disc, vha, 0x2029,
1360 "Model Desc = %s.\n", eiter->a.model_desc);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001361
1362 /* Hardware version. */
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001363 eiter = entries + size;
Bart Van Asschead950362015-07-09 07:24:08 -07001364 eiter->type = cpu_to_be16(FDMI_HBA_HARDWARE_VERSION);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001365 if (!IS_FWI2_CAPABLE(ha)) {
1366 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version),
1367 "HW:%s", ha->adapter_id);
1368 } else if (qla2xxx_get_vpd_field(vha, "MN", eiter->a.hw_version,
1369 sizeof(eiter->a.hw_version))) {
1370 ;
1371 } else if (qla2xxx_get_vpd_field(vha, "EC", eiter->a.hw_version,
1372 sizeof(eiter->a.hw_version))) {
1373 ;
1374 } else {
1375 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version),
1376 "HW:%s", ha->adapter_id);
1377 }
Andrew Vasquezcca53352005-08-26 19:08:30 -07001378 alen = strlen(eiter->a.hw_version);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001379 alen += 4 - (alen & 3);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001380 eiter->len = cpu_to_be16(4 + alen);
1381 size += 4 + alen;
1382
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001383 ql_dbg(ql_dbg_disc, vha, 0x202a,
1384 "Hardware ver = %s.\n", eiter->a.hw_version);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001385
1386 /* Driver version. */
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001387 eiter = entries + size;
Bart Van Asschead950362015-07-09 07:24:08 -07001388 eiter->type = cpu_to_be16(FDMI_HBA_DRIVER_VERSION);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001389 snprintf(eiter->a.driver_version, sizeof(eiter->a.driver_version),
1390 "%s", qla2x00_version_str);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001391 alen = strlen(eiter->a.driver_version);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001392 alen += 4 - (alen & 3);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001393 eiter->len = cpu_to_be16(4 + alen);
1394 size += 4 + alen;
1395
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001396 ql_dbg(ql_dbg_disc, vha, 0x202b,
1397 "Driver ver = %s.\n", eiter->a.driver_version);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001398
1399 /* Option ROM version. */
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001400 eiter = entries + size;
Bart Van Asschead950362015-07-09 07:24:08 -07001401 eiter->type = cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001402 snprintf(eiter->a.orom_version, sizeof(eiter->a.orom_version),
1403 "%d.%02d", ha->bios_revision[1], ha->bios_revision[0]);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001404 alen = strlen(eiter->a.orom_version);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001405 alen += 4 - (alen & 3);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001406 eiter->len = cpu_to_be16(4 + alen);
1407 size += 4 + alen;
1408
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001409 ql_dbg(ql_dbg_disc, vha , 0x202c,
1410 "Optrom vers = %s.\n", eiter->a.orom_version);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001411
1412 /* Firmware version */
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001413 eiter = entries + size;
Bart Van Asschead950362015-07-09 07:24:08 -07001414 eiter->type = cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001415 ha->isp_ops->fw_version_str(vha, eiter->a.fw_version,
1416 sizeof(eiter->a.fw_version));
Andrew Vasquezcca53352005-08-26 19:08:30 -07001417 alen = strlen(eiter->a.fw_version);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001418 alen += 4 - (alen & 3);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001419 eiter->len = cpu_to_be16(4 + alen);
1420 size += 4 + alen;
1421
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001422 ql_dbg(ql_dbg_disc, vha, 0x202d,
1423 "Firmware vers = %s.\n", eiter->a.fw_version);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001424
1425 /* Update MS request size. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001426 qla2x00_update_ms_fdmi_iocb(vha, size + 16);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001427
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001428 ql_dbg(ql_dbg_disc, vha, 0x202e,
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -04001429 "RHBA identifier = %8phN size=%d.\n",
1430 ct_req->req.rhba.hba_identifier, size);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001431 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2076,
1432 entries, size);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001433
1434 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001435 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Andrew Vasquezcca53352005-08-26 19:08:30 -07001436 sizeof(ms_iocb_entry_t));
1437 if (rval != QLA_SUCCESS) {
1438 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001439 ql_dbg(ql_dbg_disc, vha, 0x2030,
1440 "RHBA issue IOCB failed (%d).\n", rval);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001441 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA") !=
Andrew Vasquezcca53352005-08-26 19:08:30 -07001442 QLA_SUCCESS) {
1443 rval = QLA_FUNCTION_FAILED;
1444 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
1445 ct_rsp->header.explanation_code ==
1446 CT_EXPL_ALREADY_REGISTERED) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001447 ql_dbg(ql_dbg_disc, vha, 0x2034,
1448 "HBA already registered.\n");
Andrew Vasquezcca53352005-08-26 19:08:30 -07001449 rval = QLA_ALREADY_REGISTERED;
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001450 } else {
1451 ql_dbg(ql_dbg_disc, vha, 0x20ad,
1452 "RHBA FDMI registration failed, CT Reason code: 0x%x, CT Explanation 0x%x\n",
1453 ct_rsp->header.reason_code,
1454 ct_rsp->header.explanation_code);
Andrew Vasquezcca53352005-08-26 19:08:30 -07001455 }
1456 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001457 ql_dbg(ql_dbg_disc, vha, 0x2035,
1458 "RHBA exiting normally.\n");
Andrew Vasquezcca53352005-08-26 19:08:30 -07001459 }
1460
1461 return rval;
1462}
1463
1464/**
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04001465 * qla2x00_fdmi_rpa() -
1466 * @ha: HA context
1467 *
1468 * Returns 0 on success.
1469 */
1470static int
1471qla2x00_fdmi_rpa(scsi_qla_host_t *vha)
1472{
1473 int rval, alen;
1474 uint32_t size;
1475 struct qla_hw_data *ha = vha->hw;
1476 ms_iocb_entry_t *ms_pkt;
1477 struct ct_sns_req *ct_req;
1478 struct ct_sns_rsp *ct_rsp;
1479 void *entries;
1480 struct ct_fdmi_port_attr *eiter;
1481 struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb;
1482 struct new_utsname *p_sysid = NULL;
1483
1484 /* Issue RPA */
1485 /* Prepare common MS IOCB */
1486 /* Request size adjusted after CT preparation */
1487 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE);
1488
1489 /* Prepare CT request */
1490 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPA_CMD,
1491 RPA_RSP_SIZE);
1492 ct_rsp = &ha->ct_sns->p.rsp;
1493
1494 /* Prepare FDMI command arguments -- attribute block, attributes. */
1495 memcpy(ct_req->req.rpa.port_name, vha->port_name, WWN_SIZE);
1496 size = WWN_SIZE + 4;
1497
1498 /* Attributes */
1499 ct_req->req.rpa.attrs.count = cpu_to_be32(FDMI_PORT_ATTR_COUNT);
1500 entries = ct_req->req.rpa.port_name;
1501
1502 /* FC4 types. */
1503 eiter = entries + size;
1504 eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPES);
1505 eiter->len = cpu_to_be16(4 + 32);
1506 eiter->a.fc4_types[2] = 0x01;
1507 size += 4 + 32;
1508
1509 ql_dbg(ql_dbg_disc, vha, 0x2039,
1510 "FC4_TYPES=%02x %02x.\n",
1511 eiter->a.fc4_types[2],
1512 eiter->a.fc4_types[1]);
1513
1514 /* Supported speed. */
1515 eiter = entries + size;
1516 eiter->type = cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
1517 eiter->len = cpu_to_be16(4 + 4);
1518 if (IS_CNA_CAPABLE(ha))
1519 eiter->a.sup_speed = cpu_to_be32(
1520 FDMI_PORT_SPEED_10GB);
1521 else if (IS_QLA27XX(ha))
1522 eiter->a.sup_speed = cpu_to_be32(
1523 FDMI_PORT_SPEED_32GB|
1524 FDMI_PORT_SPEED_16GB|
1525 FDMI_PORT_SPEED_8GB);
1526 else if (IS_QLA2031(ha))
1527 eiter->a.sup_speed = cpu_to_be32(
1528 FDMI_PORT_SPEED_16GB|
1529 FDMI_PORT_SPEED_8GB|
1530 FDMI_PORT_SPEED_4GB);
1531 else if (IS_QLA25XX(ha))
1532 eiter->a.sup_speed = cpu_to_be32(
1533 FDMI_PORT_SPEED_8GB|
1534 FDMI_PORT_SPEED_4GB|
1535 FDMI_PORT_SPEED_2GB|
1536 FDMI_PORT_SPEED_1GB);
1537 else if (IS_QLA24XX_TYPE(ha))
1538 eiter->a.sup_speed = cpu_to_be32(
1539 FDMI_PORT_SPEED_4GB|
1540 FDMI_PORT_SPEED_2GB|
1541 FDMI_PORT_SPEED_1GB);
1542 else if (IS_QLA23XX(ha))
1543 eiter->a.sup_speed = cpu_to_be32(
1544 FDMI_PORT_SPEED_2GB|
1545 FDMI_PORT_SPEED_1GB);
1546 else
1547 eiter->a.sup_speed = cpu_to_be32(
1548 FDMI_PORT_SPEED_1GB);
1549 size += 4 + 4;
1550
1551 ql_dbg(ql_dbg_disc, vha, 0x203a,
1552 "Supported_Speed=%x.\n", eiter->a.sup_speed);
1553
1554 /* Current speed. */
1555 eiter = entries + size;
1556 eiter->type = cpu_to_be16(FDMI_PORT_CURRENT_SPEED);
1557 eiter->len = cpu_to_be16(4 + 4);
1558 switch (ha->link_data_rate) {
1559 case PORT_SPEED_1GB:
1560 eiter->a.cur_speed =
1561 cpu_to_be32(FDMI_PORT_SPEED_1GB);
1562 break;
1563 case PORT_SPEED_2GB:
1564 eiter->a.cur_speed =
1565 cpu_to_be32(FDMI_PORT_SPEED_2GB);
1566 break;
1567 case PORT_SPEED_4GB:
1568 eiter->a.cur_speed =
1569 cpu_to_be32(FDMI_PORT_SPEED_4GB);
1570 break;
1571 case PORT_SPEED_8GB:
1572 eiter->a.cur_speed =
1573 cpu_to_be32(FDMI_PORT_SPEED_8GB);
1574 break;
1575 case PORT_SPEED_10GB:
1576 eiter->a.cur_speed =
1577 cpu_to_be32(FDMI_PORT_SPEED_10GB);
1578 break;
1579 case PORT_SPEED_16GB:
1580 eiter->a.cur_speed =
1581 cpu_to_be32(FDMI_PORT_SPEED_16GB);
1582 break;
1583 case PORT_SPEED_32GB:
1584 eiter->a.cur_speed =
1585 cpu_to_be32(FDMI_PORT_SPEED_32GB);
1586 break;
1587 default:
1588 eiter->a.cur_speed =
1589 cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN);
1590 break;
1591 }
1592 size += 4 + 4;
1593
1594 ql_dbg(ql_dbg_disc, vha, 0x203b,
1595 "Current_Speed=%x.\n", eiter->a.cur_speed);
1596
1597 /* Max frame size. */
1598 eiter = entries + size;
1599 eiter->type = cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE);
1600 eiter->len = cpu_to_be16(4 + 4);
1601 eiter->a.max_frame_size = IS_FWI2_CAPABLE(ha) ?
1602 le16_to_cpu(icb24->frame_payload_size) :
1603 le16_to_cpu(ha->init_cb->frame_payload_size);
1604 eiter->a.max_frame_size = cpu_to_be32(eiter->a.max_frame_size);
1605 size += 4 + 4;
1606
1607 ql_dbg(ql_dbg_disc, vha, 0x203c,
1608 "Max_Frame_Size=%x.\n", eiter->a.max_frame_size);
1609
1610 /* OS device name. */
1611 eiter = entries + size;
1612 eiter->type = cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME);
1613 snprintf(eiter->a.os_dev_name, sizeof(eiter->a.os_dev_name),
1614 "%s:host%lu", QLA2XXX_DRIVER_NAME, vha->host_no);
1615 alen = strlen(eiter->a.os_dev_name);
1616 alen += 4 - (alen & 3);
1617 eiter->len = cpu_to_be16(4 + alen);
1618 size += 4 + alen;
1619
1620 ql_dbg(ql_dbg_disc, vha, 0x204b,
1621 "OS_Device_Name=%s.\n", eiter->a.os_dev_name);
1622
1623 /* Hostname. */
1624 eiter = entries + size;
1625 eiter->type = cpu_to_be16(FDMI_PORT_HOST_NAME);
1626 p_sysid = utsname();
1627 if (p_sysid) {
1628 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
1629 "%s", p_sysid->nodename);
1630 } else {
1631 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
1632 "%s", fc_host_system_hostname(vha->host));
1633 }
1634 alen = strlen(eiter->a.host_name);
1635 alen += 4 - (alen & 3);
1636 eiter->len = cpu_to_be16(4 + alen);
1637 size += 4 + alen;
1638
1639 ql_dbg(ql_dbg_disc, vha, 0x203d, "HostName=%s.\n", eiter->a.host_name);
1640
1641 /* Update MS request size. */
1642 qla2x00_update_ms_fdmi_iocb(vha, size + 16);
1643
1644 ql_dbg(ql_dbg_disc, vha, 0x203e,
1645 "RPA portname %016llx, size = %d.\n",
1646 wwn_to_u64(ct_req->req.rpa.port_name), size);
1647 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2079,
1648 entries, size);
1649
1650 /* Execute MS IOCB */
1651 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1652 sizeof(ms_iocb_entry_t));
1653 if (rval != QLA_SUCCESS) {
1654 /*EMPTY*/
1655 ql_dbg(ql_dbg_disc, vha, 0x2040,
1656 "RPA issue IOCB failed (%d).\n", rval);
1657 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA") !=
1658 QLA_SUCCESS) {
1659 rval = QLA_FUNCTION_FAILED;
1660 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
1661 ct_rsp->header.explanation_code ==
1662 CT_EXPL_ALREADY_REGISTERED) {
1663 ql_dbg(ql_dbg_disc, vha, 0x20cd,
1664 "RPA already registered.\n");
1665 rval = QLA_ALREADY_REGISTERED;
1666 }
1667
1668 } else {
1669 ql_dbg(ql_dbg_disc, vha, 0x2041,
1670 "RPA exiting normally.\n");
1671 }
1672
1673 return rval;
1674}
1675
1676/**
1677 * qla2x00_fdmiv2_rhba() -
1678 * @ha: HA context
1679 *
1680 * Returns 0 on success.
1681 */
1682static int
1683qla2x00_fdmiv2_rhba(scsi_qla_host_t *vha)
1684{
1685 int rval, alen;
1686 uint32_t size, sn;
1687 ms_iocb_entry_t *ms_pkt;
1688 struct ct_sns_req *ct_req;
1689 struct ct_sns_rsp *ct_rsp;
1690 void *entries;
1691 struct ct_fdmiv2_hba_attr *eiter;
1692 struct qla_hw_data *ha = vha->hw;
1693 struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb;
1694 struct new_utsname *p_sysid = NULL;
1695
1696 /* Issue RHBA */
1697 /* Prepare common MS IOCB */
1698 /* Request size adjusted after CT preparation */
1699 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE);
1700
1701 /* Prepare CT request */
1702 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RHBA_CMD,
1703 RHBA_RSP_SIZE);
1704 ct_rsp = &ha->ct_sns->p.rsp;
1705
1706 /* Prepare FDMI command arguments -- attribute block, attributes. */
1707 memcpy(ct_req->req.rhba2.hba_identifier, vha->port_name, WWN_SIZE);
1708 ct_req->req.rhba2.entry_count = cpu_to_be32(1);
1709 memcpy(ct_req->req.rhba2.port_name, vha->port_name, WWN_SIZE);
1710 size = 2 * WWN_SIZE + 4 + 4;
1711
1712 /* Attributes */
1713 ct_req->req.rhba2.attrs.count = cpu_to_be32(FDMIV2_HBA_ATTR_COUNT);
1714 entries = ct_req->req.rhba2.hba_identifier;
1715
1716 /* Nodename. */
1717 eiter = entries + size;
1718 eiter->type = cpu_to_be16(FDMI_HBA_NODE_NAME);
1719 eiter->len = cpu_to_be16(4 + WWN_SIZE);
1720 memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE);
1721 size += 4 + WWN_SIZE;
1722
1723 ql_dbg(ql_dbg_disc, vha, 0x207d,
1724 "NodeName = %016llx.\n", wwn_to_u64(eiter->a.node_name));
1725
1726 /* Manufacturer. */
1727 eiter = entries + size;
1728 eiter->type = cpu_to_be16(FDMI_HBA_MANUFACTURER);
1729 snprintf(eiter->a.manufacturer, sizeof(eiter->a.manufacturer),
1730 "%s", "QLogic Corporation");
1731 eiter->a.manufacturer[strlen("QLogic Corporation")] = '\0';
1732 alen = strlen(eiter->a.manufacturer);
1733 alen += 4 - (alen & 3);
1734 eiter->len = cpu_to_be16(4 + alen);
1735 size += 4 + alen;
1736
1737 ql_dbg(ql_dbg_disc, vha, 0x20a5,
1738 "Manufacturer = %s.\n", eiter->a.manufacturer);
1739
1740 /* Serial number. */
1741 eiter = entries + size;
1742 eiter->type = cpu_to_be16(FDMI_HBA_SERIAL_NUMBER);
1743 if (IS_FWI2_CAPABLE(ha))
1744 qla2xxx_get_vpd_field(vha, "SN", eiter->a.serial_num,
1745 sizeof(eiter->a.serial_num));
1746 else {
1747 sn = ((ha->serial0 & 0x1f) << 16) |
1748 (ha->serial2 << 8) | ha->serial1;
1749 snprintf(eiter->a.serial_num, sizeof(eiter->a.serial_num),
1750 "%c%05d", 'A' + sn / 100000, sn % 100000);
1751 }
1752 alen = strlen(eiter->a.serial_num);
1753 alen += 4 - (alen & 3);
1754 eiter->len = cpu_to_be16(4 + alen);
1755 size += 4 + alen;
1756
1757 ql_dbg(ql_dbg_disc, vha, 0x20a6,
1758 "Serial no. = %s.\n", eiter->a.serial_num);
1759
1760 /* Model name. */
1761 eiter = entries + size;
1762 eiter->type = cpu_to_be16(FDMI_HBA_MODEL);
1763 snprintf(eiter->a.model, sizeof(eiter->a.model),
1764 "%s", ha->model_number);
1765 alen = strlen(eiter->a.model);
1766 alen += 4 - (alen & 3);
1767 eiter->len = cpu_to_be16(4 + alen);
1768 size += 4 + alen;
1769
1770 ql_dbg(ql_dbg_disc, vha, 0x20a7,
1771 "Model Name = %s.\n", eiter->a.model);
1772
1773 /* Model description. */
1774 eiter = entries + size;
1775 eiter->type = cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION);
1776 snprintf(eiter->a.model_desc, sizeof(eiter->a.model_desc),
1777 "%s", ha->model_desc);
1778 alen = strlen(eiter->a.model_desc);
1779 alen += 4 - (alen & 3);
1780 eiter->len = cpu_to_be16(4 + alen);
1781 size += 4 + alen;
1782
1783 ql_dbg(ql_dbg_disc, vha, 0x20a8,
1784 "Model Desc = %s.\n", eiter->a.model_desc);
1785
1786 /* Hardware version. */
1787 eiter = entries + size;
1788 eiter->type = cpu_to_be16(FDMI_HBA_HARDWARE_VERSION);
1789 if (!IS_FWI2_CAPABLE(ha)) {
1790 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version),
1791 "HW:%s", ha->adapter_id);
1792 } else if (qla2xxx_get_vpd_field(vha, "MN", eiter->a.hw_version,
1793 sizeof(eiter->a.hw_version))) {
1794 ;
1795 } else if (qla2xxx_get_vpd_field(vha, "EC", eiter->a.hw_version,
1796 sizeof(eiter->a.hw_version))) {
1797 ;
1798 } else {
1799 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version),
1800 "HW:%s", ha->adapter_id);
1801 }
1802 alen = strlen(eiter->a.hw_version);
1803 alen += 4 - (alen & 3);
1804 eiter->len = cpu_to_be16(4 + alen);
1805 size += 4 + alen;
1806
1807 ql_dbg(ql_dbg_disc, vha, 0x20a9,
1808 "Hardware ver = %s.\n", eiter->a.hw_version);
1809
1810 /* Driver version. */
1811 eiter = entries + size;
1812 eiter->type = cpu_to_be16(FDMI_HBA_DRIVER_VERSION);
1813 snprintf(eiter->a.driver_version, sizeof(eiter->a.driver_version),
1814 "%s", qla2x00_version_str);
1815 alen = strlen(eiter->a.driver_version);
1816 alen += 4 - (alen & 3);
1817 eiter->len = cpu_to_be16(4 + alen);
1818 size += 4 + alen;
1819
1820 ql_dbg(ql_dbg_disc, vha, 0x20aa,
1821 "Driver ver = %s.\n", eiter->a.driver_version);
1822
1823 /* Option ROM version. */
1824 eiter = entries + size;
1825 eiter->type = cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION);
1826 snprintf(eiter->a.orom_version, sizeof(eiter->a.orom_version),
1827 "%d.%02d", ha->bios_revision[1], ha->bios_revision[0]);
1828 alen = strlen(eiter->a.orom_version);
1829 alen += 4 - (alen & 3);
1830 eiter->len = cpu_to_be16(4 + alen);
1831 size += 4 + alen;
1832
1833 ql_dbg(ql_dbg_disc, vha , 0x20ab,
1834 "Optrom version = %d.%02d.\n", eiter->a.orom_version[1],
1835 eiter->a.orom_version[0]);
1836
1837 /* Firmware version */
1838 eiter = entries + size;
1839 eiter->type = cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION);
1840 ha->isp_ops->fw_version_str(vha, eiter->a.fw_version,
1841 sizeof(eiter->a.fw_version));
1842 alen = strlen(eiter->a.fw_version);
1843 alen += 4 - (alen & 3);
1844 eiter->len = cpu_to_be16(4 + alen);
1845 size += 4 + alen;
1846
1847 ql_dbg(ql_dbg_disc, vha, 0x20ac,
1848 "Firmware vers = %s.\n", eiter->a.fw_version);
1849
1850 /* OS Name and Version */
1851 eiter = entries + size;
1852 eiter->type = cpu_to_be16(FDMI_HBA_OS_NAME_AND_VERSION);
1853 p_sysid = utsname();
1854 if (p_sysid) {
1855 snprintf(eiter->a.os_version, sizeof(eiter->a.os_version),
1856 "%s %s %s",
1857 p_sysid->sysname, p_sysid->release, p_sysid->version);
1858 } else {
1859 snprintf(eiter->a.os_version, sizeof(eiter->a.os_version),
1860 "%s %s", "Linux", fc_host_system_hostname(vha->host));
1861 }
1862 alen = strlen(eiter->a.os_version);
1863 alen += 4 - (alen & 3);
1864 eiter->len = cpu_to_be16(4 + alen);
1865 size += 4 + alen;
1866
1867 ql_dbg(ql_dbg_disc, vha, 0x20ae,
1868 "OS Name and Version = %s.\n", eiter->a.os_version);
1869
1870 /* MAX CT Payload Length */
1871 eiter = entries + size;
1872 eiter->type = cpu_to_be16(FDMI_HBA_MAXIMUM_CT_PAYLOAD_LENGTH);
1873 eiter->a.max_ct_len = IS_FWI2_CAPABLE(ha) ?
1874 le16_to_cpu(icb24->frame_payload_size) :
1875 le16_to_cpu(ha->init_cb->frame_payload_size);
1876 eiter->a.max_ct_len = cpu_to_be32(eiter->a.max_ct_len);
1877 eiter->len = cpu_to_be16(4 + 4);
1878 size += 4 + 4;
1879
1880 ql_dbg(ql_dbg_disc, vha, 0x20af,
1881 "CT Payload Length = 0x%x.\n", eiter->a.max_ct_len);
1882
1883 /* Node Sybolic Name */
1884 eiter = entries + size;
1885 eiter->type = cpu_to_be16(FDMI_HBA_NODE_SYMBOLIC_NAME);
1886 qla2x00_get_sym_node_name(vha, eiter->a.sym_name,
1887 sizeof(eiter->a.sym_name));
1888 alen = strlen(eiter->a.sym_name);
1889 alen += 4 - (alen & 3);
1890 eiter->len = cpu_to_be16(4 + alen);
1891 size += 4 + alen;
1892
1893 ql_dbg(ql_dbg_disc, vha, 0x20b0,
1894 "Symbolic Name = %s.\n", eiter->a.sym_name);
1895
1896 /* Vendor Id */
1897 eiter = entries + size;
1898 eiter->type = cpu_to_be16(FDMI_HBA_VENDOR_ID);
1899 eiter->a.vendor_id = cpu_to_be32(0x1077);
1900 eiter->len = cpu_to_be16(4 + 4);
1901 size += 4 + 4;
1902
1903 ql_dbg(ql_dbg_disc, vha, 0x20b1,
1904 "Vendor Id = %x.\n", eiter->a.vendor_id);
1905
1906 /* Num Ports */
1907 eiter = entries + size;
1908 eiter->type = cpu_to_be16(FDMI_HBA_NUM_PORTS);
1909 eiter->a.num_ports = cpu_to_be32(1);
1910 eiter->len = cpu_to_be16(4 + 4);
1911 size += 4 + 4;
1912
1913 ql_dbg(ql_dbg_disc, vha, 0x20b2,
1914 "Port Num = %x.\n", eiter->a.num_ports);
1915
1916 /* Fabric Name */
1917 eiter = entries + size;
1918 eiter->type = cpu_to_be16(FDMI_HBA_FABRIC_NAME);
1919 memcpy(eiter->a.fabric_name, vha->fabric_node_name, WWN_SIZE);
1920 eiter->len = cpu_to_be16(4 + WWN_SIZE);
1921 size += 4 + WWN_SIZE;
1922
1923 ql_dbg(ql_dbg_disc, vha, 0x20b3,
1924 "Fabric Name = %016llx.\n", wwn_to_u64(eiter->a.fabric_name));
1925
1926 /* BIOS Version */
1927 eiter = entries + size;
1928 eiter->type = cpu_to_be16(FDMI_HBA_BOOT_BIOS_NAME);
1929 snprintf(eiter->a.bios_name, sizeof(eiter->a.bios_name),
1930 "BIOS %d.%02d", ha->bios_revision[1], ha->bios_revision[0]);
1931 alen = strlen(eiter->a.bios_name);
1932 alen += 4 - (alen & 3);
1933 eiter->len = cpu_to_be16(4 + alen);
1934 size += 4 + alen;
1935
1936 ql_dbg(ql_dbg_disc, vha, 0x20b4,
1937 "BIOS Name = %s\n", eiter->a.bios_name);
1938
1939 /* Vendor Identifier */
1940 eiter = entries + size;
1941 eiter->type = cpu_to_be16(FDMI_HBA_TYPE_VENDOR_IDENTIFIER);
1942 snprintf(eiter->a.vendor_indentifer, sizeof(eiter->a.vendor_indentifer),
1943 "%s", "QLGC");
1944 alen = strlen(eiter->a.vendor_indentifer);
1945 alen += 4 - (alen & 3);
1946 eiter->len = cpu_to_be16(4 + alen);
1947 size += 4 + alen;
1948
1949 ql_dbg(ql_dbg_disc, vha, 0x20b1,
1950 "Vendor Identifier = %s.\n", eiter->a.vendor_indentifer);
1951
1952 /* Update MS request size. */
1953 qla2x00_update_ms_fdmi_iocb(vha, size + 16);
1954
1955 ql_dbg(ql_dbg_disc, vha, 0x20b5,
1956 "RHBA identifier = %016llx.\n",
1957 wwn_to_u64(ct_req->req.rhba2.hba_identifier));
1958 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x20b6,
1959 entries, size);
1960
1961 /* Execute MS IOCB */
1962 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1963 sizeof(ms_iocb_entry_t));
1964 if (rval != QLA_SUCCESS) {
1965 /*EMPTY*/
1966 ql_dbg(ql_dbg_disc, vha, 0x20b7,
1967 "RHBA issue IOCB failed (%d).\n", rval);
1968 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA") !=
1969 QLA_SUCCESS) {
1970 rval = QLA_FUNCTION_FAILED;
1971
1972 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
1973 ct_rsp->header.explanation_code ==
1974 CT_EXPL_ALREADY_REGISTERED) {
1975 ql_dbg(ql_dbg_disc, vha, 0x20b8,
1976 "HBA already registered.\n");
1977 rval = QLA_ALREADY_REGISTERED;
1978 } else {
1979 ql_dbg(ql_dbg_disc, vha, 0x2016,
1980 "RHBA FDMI v2 failed, CT Reason code: 0x%x, CT Explanation 0x%x\n",
1981 ct_rsp->header.reason_code,
1982 ct_rsp->header.explanation_code);
1983 }
1984 } else {
1985 ql_dbg(ql_dbg_disc, vha, 0x20b9,
1986 "RHBA FDMI V2 exiting normally.\n");
1987 }
1988
1989 return rval;
1990}
1991
1992/**
Andrew Vasquezcca53352005-08-26 19:08:30 -07001993 * qla2x00_fdmi_dhba() -
1994 * @ha: HA context
1995 *
1996 * Returns 0 on success.
1997 */
1998static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001999qla2x00_fdmi_dhba(scsi_qla_host_t *vha)
Andrew Vasquezcca53352005-08-26 19:08:30 -07002000{
2001 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002002 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezcca53352005-08-26 19:08:30 -07002003 ms_iocb_entry_t *ms_pkt;
2004 struct ct_sns_req *ct_req;
2005 struct ct_sns_rsp *ct_rsp;
2006
2007 /* Issue RPA */
2008 /* Prepare common MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002009 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, DHBA_REQ_SIZE,
Andrew Vasquezcca53352005-08-26 19:08:30 -07002010 DHBA_RSP_SIZE);
2011
2012 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -04002013 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, DHBA_CMD, DHBA_RSP_SIZE);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002014 ct_rsp = &ha->ct_sns->p.rsp;
2015
2016 /* Prepare FDMI command arguments -- portname. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002017 memcpy(ct_req->req.dhba.port_name, vha->port_name, WWN_SIZE);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002018
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002019 ql_dbg(ql_dbg_disc, vha, 0x2036,
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -04002020 "DHBA portname = %8phN.\n", ct_req->req.dhba.port_name);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002021
2022 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002023 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Andrew Vasquezcca53352005-08-26 19:08:30 -07002024 sizeof(ms_iocb_entry_t));
2025 if (rval != QLA_SUCCESS) {
2026 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002027 ql_dbg(ql_dbg_disc, vha, 0x2037,
2028 "DHBA issue IOCB failed (%d).\n", rval);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002029 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "DHBA") !=
Andrew Vasquezcca53352005-08-26 19:08:30 -07002030 QLA_SUCCESS) {
2031 rval = QLA_FUNCTION_FAILED;
2032 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002033 ql_dbg(ql_dbg_disc, vha, 0x2038,
2034 "DHBA exiting normally.\n");
Andrew Vasquezcca53352005-08-26 19:08:30 -07002035 }
2036
2037 return rval;
2038}
2039
2040/**
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002041 * qla2x00_fdmiv2_rpa() -
Andrew Vasquezcca53352005-08-26 19:08:30 -07002042 * @ha: HA context
2043 *
2044 * Returns 0 on success.
2045 */
2046static int
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002047qla2x00_fdmiv2_rpa(scsi_qla_host_t *vha)
Andrew Vasquezcca53352005-08-26 19:08:30 -07002048{
2049 int rval, alen;
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002050 uint32_t size;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002051 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezcca53352005-08-26 19:08:30 -07002052 ms_iocb_entry_t *ms_pkt;
2053 struct ct_sns_req *ct_req;
2054 struct ct_sns_rsp *ct_rsp;
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002055 void *entries;
2056 struct ct_fdmiv2_port_attr *eiter;
Andrew Vasquezcca53352005-08-26 19:08:30 -07002057 struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb;
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002058 struct new_utsname *p_sysid = NULL;
Andrew Vasquezcca53352005-08-26 19:08:30 -07002059
2060 /* Issue RPA */
2061 /* Prepare common MS IOCB */
2062 /* Request size adjusted after CT preparation */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002063 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002064
2065 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -04002066 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPA_CMD, RPA_RSP_SIZE);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002067 ct_rsp = &ha->ct_sns->p.rsp;
2068
2069 /* Prepare FDMI command arguments -- attribute block, attributes. */
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002070 memcpy(ct_req->req.rpa2.port_name, vha->port_name, WWN_SIZE);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002071 size = WWN_SIZE + 4;
2072
2073 /* Attributes */
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002074 ct_req->req.rpa2.attrs.count = cpu_to_be32(FDMIV2_PORT_ATTR_COUNT);
2075 entries = ct_req->req.rpa2.port_name;
Andrew Vasquezcca53352005-08-26 19:08:30 -07002076
2077 /* FC4 types. */
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002078 eiter = entries + size;
2079 eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPES);
2080 eiter->len = cpu_to_be16(4 + 32);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002081 eiter->a.fc4_types[2] = 0x01;
2082 size += 4 + 32;
2083
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002084 ql_dbg(ql_dbg_disc, vha, 0x20ba,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002085 "FC4_TYPES=%02x %02x.\n",
2086 eiter->a.fc4_types[2],
2087 eiter->a.fc4_types[1]);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002088
2089 /* Supported speed. */
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002090 eiter = entries + size;
2091 eiter->type = cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
2092 eiter->len = cpu_to_be16(4 + 4);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002093 if (IS_CNA_CAPABLE(ha))
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002094 eiter->a.sup_speed = cpu_to_be32(
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08002095 FDMI_PORT_SPEED_10GB);
Chad Dupuisf73cb692014-02-26 04:15:06 -05002096 else if (IS_QLA27XX(ha))
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002097 eiter->a.sup_speed = cpu_to_be32(
2098 FDMI_PORT_SPEED_32GB|
2099 FDMI_PORT_SPEED_16GB|
Chad Dupuisf73cb692014-02-26 04:15:06 -05002100 FDMI_PORT_SPEED_8GB);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002101 else if (IS_QLA2031(ha))
2102 eiter->a.sup_speed = cpu_to_be32(
2103 FDMI_PORT_SPEED_16GB|
2104 FDMI_PORT_SPEED_8GB|
Andrew Vasquez58815692007-07-19 15:05:58 -07002105 FDMI_PORT_SPEED_4GB);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002106 else if (IS_QLA25XX(ha))
2107 eiter->a.sup_speed = cpu_to_be32(
2108 FDMI_PORT_SPEED_8GB|
2109 FDMI_PORT_SPEED_4GB|
2110 FDMI_PORT_SPEED_2GB|
2111 FDMI_PORT_SPEED_1GB);
2112 else if (IS_QLA24XX_TYPE(ha))
2113 eiter->a.sup_speed = cpu_to_be32(
2114 FDMI_PORT_SPEED_4GB|
2115 FDMI_PORT_SPEED_2GB|
2116 FDMI_PORT_SPEED_1GB);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002117 else if (IS_QLA23XX(ha))
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002118 eiter->a.sup_speed = cpu_to_be32(
2119 FDMI_PORT_SPEED_2GB|
2120 FDMI_PORT_SPEED_1GB);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002121 else
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002122 eiter->a.sup_speed = cpu_to_be32(
Andrew Vasquez58815692007-07-19 15:05:58 -07002123 FDMI_PORT_SPEED_1GB);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002124 size += 4 + 4;
2125
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002126 ql_dbg(ql_dbg_disc, vha, 0x20bb,
2127 "Supported Port Speed = %x.\n", eiter->a.sup_speed);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002128
2129 /* Current speed. */
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002130 eiter = entries + size;
2131 eiter->type = cpu_to_be16(FDMI_PORT_CURRENT_SPEED);
2132 eiter->len = cpu_to_be16(4 + 4);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002133 switch (ha->link_data_rate) {
Andrew Vasquez58815692007-07-19 15:05:58 -07002134 case PORT_SPEED_1GB:
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002135 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_1GB);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002136 break;
Andrew Vasquez58815692007-07-19 15:05:58 -07002137 case PORT_SPEED_2GB:
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002138 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_2GB);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002139 break;
Andrew Vasquez58815692007-07-19 15:05:58 -07002140 case PORT_SPEED_4GB:
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002141 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_4GB);
Andrew Vasquez58815692007-07-19 15:05:58 -07002142 break;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07002143 case PORT_SPEED_8GB:
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002144 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_8GB);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07002145 break;
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08002146 case PORT_SPEED_10GB:
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002147 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_10GB);
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08002148 break;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002149 case PORT_SPEED_16GB:
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002150 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_16GB);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002151 break;
Chad Dupuisf73cb692014-02-26 04:15:06 -05002152 case PORT_SPEED_32GB:
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002153 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_32GB);
Chad Dupuisf73cb692014-02-26 04:15:06 -05002154 break;
Andrew Vasquez58815692007-07-19 15:05:58 -07002155 default:
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002156 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002157 break;
2158 }
2159 size += 4 + 4;
2160
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002161 ql_dbg(ql_dbg_disc, vha, 0x20bc,
2162 "Current_Speed = %x.\n", eiter->a.cur_speed);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002163
2164 /* Max frame size. */
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002165 eiter = entries + size;
2166 eiter->type = cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE);
2167 eiter->len = cpu_to_be16(4 + 4);
2168 eiter->a.max_frame_size = IS_FWI2_CAPABLE(ha) ?
Seokmann Juc6852c42008-04-24 15:21:29 -07002169 le16_to_cpu(icb24->frame_payload_size):
2170 le16_to_cpu(ha->init_cb->frame_payload_size);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002171 eiter->a.max_frame_size = cpu_to_be32(eiter->a.max_frame_size);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002172 size += 4 + 4;
2173
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002174 ql_dbg(ql_dbg_disc, vha, 0x20bc,
2175 "Max_Frame_Size = %x.\n", eiter->a.max_frame_size);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002176
2177 /* OS device name. */
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002178 eiter = entries + size;
2179 eiter->type = cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME);
Paul Bollef24b6972013-02-08 01:57:55 -05002180 alen = strlen(QLA2XXX_DRIVER_NAME);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002181 snprintf(eiter->a.os_dev_name, sizeof(eiter->a.os_dev_name),
2182 "%s:host%lu", QLA2XXX_DRIVER_NAME, vha->host_no);
2183 alen += 4 - (alen & 3);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002184 eiter->len = cpu_to_be16(4 + alen);
2185 size += 4 + alen;
2186
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002187 ql_dbg(ql_dbg_disc, vha, 0x20be,
2188 "OS_Device_Name = %s.\n", eiter->a.os_dev_name);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002189
Andrew Vasqueza740a3f2006-10-02 12:00:45 -07002190 /* Hostname. */
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002191 eiter = entries + size;
2192 eiter->type = cpu_to_be16(FDMI_PORT_HOST_NAME);
2193 p_sysid = utsname();
2194 if (p_sysid) {
2195 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
2196 "%s", p_sysid->nodename);
2197 } else {
Andrew Vasqueza740a3f2006-10-02 12:00:45 -07002198 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002199 "%s", fc_host_system_hostname(vha->host));
Andrew Vasqueza740a3f2006-10-02 12:00:45 -07002200 }
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002201 alen = strlen(eiter->a.host_name);
2202 alen += 4 - (alen & 3);
2203 eiter->len = cpu_to_be16(4 + alen);
2204 size += 4 + alen;
2205
2206 ql_dbg(ql_dbg_disc, vha, 0x203d,
2207 "HostName=%s.\n", eiter->a.host_name);
2208
2209 /* Node Name */
2210 eiter = entries + size;
2211 eiter->type = cpu_to_be16(FDMI_PORT_NODE_NAME);
2212 memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE);
2213 eiter->len = cpu_to_be16(4 + WWN_SIZE);
2214 size += 4 + WWN_SIZE;
2215
2216 ql_dbg(ql_dbg_disc, vha, 0x20c0,
2217 "Node Name = %016llx.\n", wwn_to_u64(eiter->a.node_name));
2218
2219 /* Port Name */
2220 eiter = entries + size;
2221 eiter->type = cpu_to_be16(FDMI_PORT_NAME);
2222 memcpy(eiter->a.port_name, vha->port_name, WWN_SIZE);
2223 eiter->len = cpu_to_be16(4 + WWN_SIZE);
2224 size += 4 + WWN_SIZE;
2225
2226 ql_dbg(ql_dbg_disc, vha, 0x20c1,
2227 "Port Name = %016llx.\n", wwn_to_u64(eiter->a.port_name));
2228
2229 /* Port Symbolic Name */
2230 eiter = entries + size;
2231 eiter->type = cpu_to_be16(FDMI_PORT_SYM_NAME);
2232 qla2x00_get_sym_node_name(vha, eiter->a.port_sym_name,
2233 sizeof(eiter->a.port_sym_name));
2234 alen = strlen(eiter->a.port_sym_name);
2235 alen += 4 - (alen & 3);
2236 eiter->len = cpu_to_be16(4 + alen);
2237 size += 4 + alen;
2238
2239 ql_dbg(ql_dbg_disc, vha, 0x20c2,
2240 "port symbolic name = %s\n", eiter->a.port_sym_name);
2241
2242 /* Port Type */
2243 eiter = entries + size;
2244 eiter->type = cpu_to_be16(FDMI_PORT_TYPE);
2245 eiter->a.port_type = cpu_to_be32(NS_NX_PORT_TYPE);
2246 eiter->len = cpu_to_be16(4 + 4);
2247 size += 4 + 4;
2248
2249 ql_dbg(ql_dbg_disc, vha, 0x20c3,
2250 "Port Type = %x.\n", eiter->a.port_type);
2251
2252 /* Class of Service */
2253 eiter = entries + size;
2254 eiter->type = cpu_to_be16(FDMI_PORT_SUPP_COS);
2255 eiter->a.port_supported_cos = cpu_to_be32(FC_CLASS_3);
2256 eiter->len = cpu_to_be16(4 + 4);
2257 size += 4 + 4;
2258
2259 ql_dbg(ql_dbg_disc, vha, 0x20c4,
2260 "Supported COS = %08x\n", eiter->a.port_supported_cos);
2261
2262 /* Port Fabric Name */
2263 eiter = entries + size;
2264 eiter->type = cpu_to_be16(FDMI_PORT_FABRIC_NAME);
2265 memcpy(eiter->a.fabric_name, vha->fabric_node_name, WWN_SIZE);
2266 eiter->len = cpu_to_be16(4 + WWN_SIZE);
2267 size += 4 + WWN_SIZE;
2268
2269 ql_dbg(ql_dbg_disc, vha, 0x20c5,
2270 "Fabric Name = %016llx.\n", wwn_to_u64(eiter->a.fabric_name));
2271
2272 /* FC4_type */
2273 eiter = entries + size;
2274 eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPE);
2275 eiter->a.port_fc4_type[0] = 0;
2276 eiter->a.port_fc4_type[1] = 0;
2277 eiter->a.port_fc4_type[2] = 1;
2278 eiter->a.port_fc4_type[3] = 0;
2279 eiter->len = cpu_to_be16(4 + 32);
2280 size += 4 + 32;
2281
2282 ql_dbg(ql_dbg_disc, vha, 0x20c6,
2283 "Port Active FC4 Type = %02x %02x.\n",
2284 eiter->a.port_fc4_type[2], eiter->a.port_fc4_type[1]);
2285
2286 /* Port State */
2287 eiter = entries + size;
2288 eiter->type = cpu_to_be16(FDMI_PORT_STATE);
2289 eiter->a.port_state = cpu_to_be32(1);
2290 eiter->len = cpu_to_be16(4 + 4);
2291 size += 4 + 4;
2292
2293 ql_dbg(ql_dbg_disc, vha, 0x20c7,
2294 "Port State = %x.\n", eiter->a.port_state);
2295
2296 /* Number of Ports */
2297 eiter = entries + size;
2298 eiter->type = cpu_to_be16(FDMI_PORT_COUNT);
2299 eiter->a.num_ports = cpu_to_be32(1);
2300 eiter->len = cpu_to_be16(4 + 4);
2301 size += 4 + 4;
2302
2303 ql_dbg(ql_dbg_disc, vha, 0x20c8,
2304 "Number of ports = %x.\n", eiter->a.num_ports);
2305
2306 /* Port Id */
2307 eiter = entries + size;
2308 eiter->type = cpu_to_be16(FDMI_PORT_ID);
2309 eiter->a.port_id = cpu_to_be32(vha->d_id.b24);
2310 eiter->len = cpu_to_be16(4 + 4);
2311 size += 4 + 4;
2312
2313 ql_dbg(ql_dbg_disc, vha, 0x20c8,
2314 "Port Id = %x.\n", eiter->a.port_id);
Andrew Vasqueza740a3f2006-10-02 12:00:45 -07002315
Andrew Vasquezcca53352005-08-26 19:08:30 -07002316 /* Update MS request size. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002317 qla2x00_update_ms_fdmi_iocb(vha, size + 16);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002318
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002319 ql_dbg(ql_dbg_disc, vha, 0x203e,
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -04002320 "RPA portname= %8phN size=%d.\n", ct_req->req.rpa.port_name, size);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002321 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x20ca,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002322 entries, size);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002323
2324 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002325 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Andrew Vasquezcca53352005-08-26 19:08:30 -07002326 sizeof(ms_iocb_entry_t));
2327 if (rval != QLA_SUCCESS) {
2328 /*EMPTY*/
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002329 ql_dbg(ql_dbg_disc, vha, 0x20cb,
2330 "RPA FDMI v2 issue IOCB failed (%d).\n", rval);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002331 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA") !=
Andrew Vasquezcca53352005-08-26 19:08:30 -07002332 QLA_SUCCESS) {
2333 rval = QLA_FUNCTION_FAILED;
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002334 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
2335 ct_rsp->header.explanation_code ==
2336 CT_EXPL_ALREADY_REGISTERED) {
2337 ql_dbg(ql_dbg_disc, vha, 0x20ce,
2338 "RPA FDMI v2 already registered\n");
2339 rval = QLA_ALREADY_REGISTERED;
2340 } else {
2341 ql_dbg(ql_dbg_disc, vha, 0x2020,
2342 "RPA FDMI v2 failed, CT Reason code: 0x%x, CT Explanation 0x%x\n",
2343 ct_rsp->header.reason_code,
2344 ct_rsp->header.explanation_code);
2345 }
Andrew Vasquezcca53352005-08-26 19:08:30 -07002346 } else {
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002347 ql_dbg(ql_dbg_disc, vha, 0x20cc,
2348 "RPA FDMI V2 exiting normally.\n");
Andrew Vasquezcca53352005-08-26 19:08:30 -07002349 }
2350
2351 return rval;
2352}
2353
2354/**
2355 * qla2x00_fdmi_register() -
2356 * @ha: HA context
2357 *
2358 * Returns 0 on success.
2359 */
2360int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002361qla2x00_fdmi_register(scsi_qla_host_t *vha)
Andrew Vasquezcca53352005-08-26 19:08:30 -07002362{
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002363 int rval = QLA_FUNCTION_FAILED;
2364 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez80de7ef2009-07-31 15:09:33 -07002365
Giridhar Malavali8ae6d9c2013-03-28 08:21:23 -04002366 if (IS_QLA2100(ha) || IS_QLA2200(ha) ||
2367 IS_QLAFX00(ha))
Andrew Vasquez80de7ef2009-07-31 15:09:33 -07002368 return QLA_FUNCTION_FAILED;
Andrew Vasquezcca53352005-08-26 19:08:30 -07002369
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002370 rval = qla2x00_mgmt_svr_login(vha);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002371 if (rval)
2372 return rval;
2373
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002374 rval = qla2x00_fdmiv2_rhba(vha);
2375 if (rval) {
2376 if (rval != QLA_ALREADY_REGISTERED)
2377 goto try_fdmi;
2378
2379 rval = qla2x00_fdmi_dhba(vha);
2380 if (rval)
2381 goto try_fdmi;
2382
2383 rval = qla2x00_fdmiv2_rhba(vha);
2384 if (rval)
2385 goto try_fdmi;
2386 }
2387 rval = qla2x00_fdmiv2_rpa(vha);
2388 if (rval)
2389 goto try_fdmi;
2390
2391 goto out;
2392
2393try_fdmi:
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002394 rval = qla2x00_fdmi_rhba(vha);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002395 if (rval) {
2396 if (rval != QLA_ALREADY_REGISTERED)
2397 return rval;
2398
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002399 rval = qla2x00_fdmi_dhba(vha);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002400 if (rval)
2401 return rval;
2402
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002403 rval = qla2x00_fdmi_rhba(vha);
Andrew Vasquezcca53352005-08-26 19:08:30 -07002404 if (rval)
2405 return rval;
2406 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002407 rval = qla2x00_fdmi_rpa(vha);
Himanshu Madhanidf57cab2014-09-25 05:16:46 -04002408out:
Andrew Vasquezcca53352005-08-26 19:08:30 -07002409 return rval;
2410}
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002411
2412/**
2413 * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query.
2414 * @ha: HA context
2415 * @list: switch info entries to populate
2416 *
2417 * Returns 0 on success.
2418 */
2419int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002420qla2x00_gfpn_id(scsi_qla_host_t *vha, sw_info_t *list)
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002421{
Chad Dupuis642ef982012-02-09 11:15:57 -08002422 int rval = QLA_SUCCESS;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002423 uint16_t i;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002424 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002425 ms_iocb_entry_t *ms_pkt;
2426 struct ct_sns_req *ct_req;
2427 struct ct_sns_rsp *ct_rsp;
2428
Andrew Vasquezc76f2c02007-07-19 15:05:57 -07002429 if (!IS_IIDMA_CAPABLE(ha))
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002430 return QLA_FUNCTION_FAILED;
2431
Chad Dupuis642ef982012-02-09 11:15:57 -08002432 for (i = 0; i < ha->max_fibre_devices; i++) {
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002433 /* Issue GFPN_ID */
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002434 /* Prepare common MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002435 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GFPN_ID_REQ_SIZE,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002436 GFPN_ID_RSP_SIZE);
2437
2438 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -04002439 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFPN_ID_CMD,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002440 GFPN_ID_RSP_SIZE);
2441 ct_rsp = &ha->ct_sns->p.rsp;
2442
2443 /* Prepare CT arguments -- port_id */
2444 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
2445 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
2446 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
2447
2448 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002449 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002450 sizeof(ms_iocb_entry_t));
2451 if (rval != QLA_SUCCESS) {
2452 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002453 ql_dbg(ql_dbg_disc, vha, 0x2023,
2454 "GFPN_ID issue IOCB failed (%d).\n", rval);
Arun Easidafdf892012-02-09 11:16:00 -08002455 break;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002456 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002457 "GFPN_ID") != QLA_SUCCESS) {
2458 rval = QLA_FUNCTION_FAILED;
Arun Easidafdf892012-02-09 11:16:00 -08002459 break;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002460 } else {
2461 /* Save fabric portname */
2462 memcpy(list[i].fabric_port_name,
2463 ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE);
2464 }
2465
2466 /* Last device exit. */
2467 if (list[i].d_id.b.rsvd_1 != 0)
2468 break;
2469 }
2470
2471 return (rval);
2472}
2473
2474static inline void *
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002475qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *vha, uint32_t req_size,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002476 uint32_t rsp_size)
2477{
2478 struct ct_entry_24xx *ct_pkt;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002479 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002480 ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
2481 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
2482
2483 ct_pkt->entry_type = CT_IOCB_TYPE;
2484 ct_pkt->entry_count = 1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002485 ct_pkt->nport_handle = cpu_to_le16(vha->mgmt_svr_loop_id);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08002486 ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Bart Van Asschead950362015-07-09 07:24:08 -07002487 ct_pkt->cmd_dsd_count = cpu_to_le16(1);
2488 ct_pkt->rsp_dsd_count = cpu_to_le16(1);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002489 ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
2490 ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
2491
2492 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
2493 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
2494 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
2495
2496 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
2497 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
2498 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002499 ct_pkt->vp_index = vha->vp_idx;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002500
2501 return ct_pkt;
2502}
2503
2504
2505static inline struct ct_sns_req *
Bart Van Assche6ec6f902013-06-25 11:27:28 -04002506qla24xx_prep_ct_fm_req(struct ct_sns_pkt *p, uint16_t cmd,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002507 uint16_t rsp_size)
2508{
Bart Van Assche6ec6f902013-06-25 11:27:28 -04002509 memset(p, 0, sizeof(struct ct_sns_pkt));
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002510
Bart Van Assche6ec6f902013-06-25 11:27:28 -04002511 p->p.req.header.revision = 0x01;
2512 p->p.req.header.gs_type = 0xFA;
2513 p->p.req.header.gs_subtype = 0x01;
2514 p->p.req.command = cpu_to_be16(cmd);
2515 p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002516
Bart Van Assche6ec6f902013-06-25 11:27:28 -04002517 return &p->p.req;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002518}
2519
2520/**
2521 * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query.
2522 * @ha: HA context
2523 * @list: switch info entries to populate
2524 *
2525 * Returns 0 on success.
2526 */
2527int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002528qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list)
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002529{
2530 int rval;
2531 uint16_t i;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002532 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002533 ms_iocb_entry_t *ms_pkt;
2534 struct ct_sns_req *ct_req;
2535 struct ct_sns_rsp *ct_rsp;
2536
Andrew Vasquezc76f2c02007-07-19 15:05:57 -07002537 if (!IS_IIDMA_CAPABLE(ha))
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002538 return QLA_FUNCTION_FAILED;
Andrew Vasquez4346b142006-12-13 19:20:28 -08002539 if (!ha->flags.gpsc_supported)
2540 return QLA_FUNCTION_FAILED;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002541
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002542 rval = qla2x00_mgmt_svr_login(vha);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002543 if (rval)
2544 return rval;
2545
Chad Dupuis642ef982012-02-09 11:15:57 -08002546 for (i = 0; i < ha->max_fibre_devices; i++) {
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002547 /* Issue GFPN_ID */
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002548 /* Prepare common MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002549 ms_pkt = qla24xx_prep_ms_fm_iocb(vha, GPSC_REQ_SIZE,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002550 GPSC_RSP_SIZE);
2551
2552 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -04002553 ct_req = qla24xx_prep_ct_fm_req(ha->ct_sns, GPSC_CMD,
2554 GPSC_RSP_SIZE);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002555 ct_rsp = &ha->ct_sns->p.rsp;
2556
2557 /* Prepare CT arguments -- port_name */
2558 memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name,
2559 WWN_SIZE);
2560
2561 /* Execute MS IOCB */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002562 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002563 sizeof(ms_iocb_entry_t));
2564 if (rval != QLA_SUCCESS) {
2565 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002566 ql_dbg(ql_dbg_disc, vha, 0x2059,
2567 "GPSC issue IOCB failed (%d).\n", rval);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002568 } else if ((rval = qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
Andrew Vasquez4346b142006-12-13 19:20:28 -08002569 "GPSC")) != QLA_SUCCESS) {
2570 /* FM command unsupported? */
2571 if (rval == QLA_INVALID_COMMAND &&
Andrew Vasquez3fe7cfb2008-04-03 13:13:23 -07002572 (ct_rsp->header.reason_code ==
2573 CT_REASON_INVALID_COMMAND_CODE ||
2574 ct_rsp->header.reason_code ==
2575 CT_REASON_COMMAND_UNSUPPORTED)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002576 ql_dbg(ql_dbg_disc, vha, 0x205a,
2577 "GPSC command unsupported, disabling "
2578 "query.\n");
Andrew Vasquez4346b142006-12-13 19:20:28 -08002579 ha->flags.gpsc_supported = 0;
2580 rval = QLA_FUNCTION_FAILED;
2581 break;
2582 }
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002583 rval = QLA_FUNCTION_FAILED;
2584 } else {
Andrew Vasqueza3cbdfa2007-08-13 10:13:18 -07002585 /* Save port-speed */
2586 switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) {
2587 case BIT_15:
2588 list[i].fp_speed = PORT_SPEED_1GB;
2589 break;
2590 case BIT_14:
2591 list[i].fp_speed = PORT_SPEED_2GB;
2592 break;
2593 case BIT_13:
2594 list[i].fp_speed = PORT_SPEED_4GB;
2595 break;
Andrew Vasquez9f8fdde2009-06-03 09:55:22 -07002596 case BIT_12:
2597 list[i].fp_speed = PORT_SPEED_10GB;
2598 break;
Andrew Vasqueza3cbdfa2007-08-13 10:13:18 -07002599 case BIT_11:
2600 list[i].fp_speed = PORT_SPEED_8GB;
2601 break;
Joe Carnuccioc53dfac2012-11-21 02:40:39 -05002602 case BIT_10:
2603 list[i].fp_speed = PORT_SPEED_16GB;
2604 break;
Chad Dupuisf73cb692014-02-26 04:15:06 -05002605 case BIT_8:
2606 list[i].fp_speed = PORT_SPEED_32GB;
2607 break;
Andrew Vasqueza3cbdfa2007-08-13 10:13:18 -07002608 }
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002609
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002610 ql_dbg(ql_dbg_disc, vha, 0x205b,
2611 "GPSC ext entry - fpn "
Oleksandr Khoshaba7b833552013-08-27 01:37:27 -04002612 "%8phN speeds=%04x speed=%04x.\n",
2613 list[i].fabric_port_name,
Andrew Vasqueza3cbdfa2007-08-13 10:13:18 -07002614 be16_to_cpu(ct_rsp->rsp.gpsc.speeds),
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002615 be16_to_cpu(ct_rsp->rsp.gpsc.speed));
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002616 }
2617
2618 /* Last device exit. */
2619 if (list[i].d_id.b.rsvd_1 != 0)
2620 break;
2621 }
2622
2623 return (rval);
2624}
Chad Dupuise8c72ba2010-07-23 15:28:25 +05002625
2626/**
2627 * qla2x00_gff_id() - SNS Get FC-4 Features (GFF_ID) query.
2628 *
2629 * @ha: HA context
2630 * @list: switch info entries to populate
2631 *
2632 */
2633void
2634qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list)
2635{
2636 int rval;
2637 uint16_t i;
2638
2639 ms_iocb_entry_t *ms_pkt;
2640 struct ct_sns_req *ct_req;
2641 struct ct_sns_rsp *ct_rsp;
2642 struct qla_hw_data *ha = vha->hw;
2643 uint8_t fcp_scsi_features = 0;
2644
Chad Dupuis642ef982012-02-09 11:15:57 -08002645 for (i = 0; i < ha->max_fibre_devices; i++) {
Chad Dupuise8c72ba2010-07-23 15:28:25 +05002646 /* Set default FC4 Type as UNKNOWN so the default is to
2647 * Process this port */
2648 list[i].fc4_type = FC4_TYPE_UNKNOWN;
2649
2650 /* Do not attempt GFF_ID if we are not FWI_2 capable */
2651 if (!IS_FWI2_CAPABLE(ha))
2652 continue;
2653
2654 /* Prepare common MS IOCB */
2655 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GFF_ID_REQ_SIZE,
2656 GFF_ID_RSP_SIZE);
2657
2658 /* Prepare CT request */
Bart Van Assche6ec6f902013-06-25 11:27:28 -04002659 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFF_ID_CMD,
Chad Dupuise8c72ba2010-07-23 15:28:25 +05002660 GFF_ID_RSP_SIZE);
2661 ct_rsp = &ha->ct_sns->p.rsp;
2662
2663 /* Prepare CT arguments -- port_id */
2664 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
2665 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
2666 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
2667
2668 /* Execute MS IOCB */
2669 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
2670 sizeof(ms_iocb_entry_t));
2671
2672 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002673 ql_dbg(ql_dbg_disc, vha, 0x205c,
2674 "GFF_ID issue IOCB failed (%d).\n", rval);
Chad Dupuise8c72ba2010-07-23 15:28:25 +05002675 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
Andrew Vasquez7a78ced2011-02-23 15:27:12 -08002676 "GFF_ID") != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002677 ql_dbg(ql_dbg_disc, vha, 0x205d,
2678 "GFF_ID IOCB status had a failure status code.\n");
Chad Dupuise8c72ba2010-07-23 15:28:25 +05002679 } else {
2680 fcp_scsi_features =
2681 ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
2682 fcp_scsi_features &= 0x0f;
2683
2684 if (fcp_scsi_features)
2685 list[i].fc4_type = FC4_TYPE_FCP_SCSI;
2686 else
2687 list[i].fc4_type = FC4_TYPE_OTHER;
2688 }
2689
2690 /* Last device exit. */
2691 if (list[i].d_id.b.rsvd_1 != 0)
2692 break;
2693 }
2694}