Merge branch 'exynos-drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git...
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / scsi / qla2xxx / qla_gs.c
1 /*
2  * QLogic Fibre Channel HBA Driver
3  * Copyright (c)  2003-2012 QLogic Corporation
4  *
5  * See LICENSE.qla2xxx for copyright and licensing details.
6  */
7 #include "qla_def.h"
8 #include "qla_target.h"
9
10 static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *);
11 static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *);
12 static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *);
13 static int qla2x00_sns_gnn_id(scsi_qla_host_t *, sw_info_t *);
14 static int qla2x00_sns_rft_id(scsi_qla_host_t *);
15 static int qla2x00_sns_rnn_id(scsi_qla_host_t *);
16
17 /**
18  * qla2x00_prep_ms_iocb() - Prepare common MS/CT IOCB fields for SNS CT query.
19  * @ha: HA context
20  * @req_size: request size in bytes
21  * @rsp_size: response size in bytes
22  *
23  * Returns a pointer to the @ha's ms_iocb.
24  */
25 void *
26 qla2x00_prep_ms_iocb(scsi_qla_host_t *vha, uint32_t req_size, uint32_t rsp_size)
27 {
28         struct qla_hw_data *ha = vha->hw;
29         ms_iocb_entry_t *ms_pkt;
30
31         ms_pkt = ha->ms_iocb;
32         memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
33
34         ms_pkt->entry_type = MS_IOCB_TYPE;
35         ms_pkt->entry_count = 1;
36         SET_TARGET_ID(ha, ms_pkt->loop_id, SIMPLE_NAME_SERVER);
37         ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG);
38         ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
39         ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
40         ms_pkt->total_dsd_count = __constant_cpu_to_le16(2);
41         ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
42         ms_pkt->req_bytecount = cpu_to_le32(req_size);
43
44         ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
45         ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
46         ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
47
48         ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
49         ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
50         ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount;
51
52         return (ms_pkt);
53 }
54
55 /**
56  * qla24xx_prep_ms_iocb() - Prepare common CT IOCB fields for SNS CT query.
57  * @ha: HA context
58  * @req_size: request size in bytes
59  * @rsp_size: response size in bytes
60  *
61  * Returns a pointer to the @ha's ms_iocb.
62  */
63 void *
64 qla24xx_prep_ms_iocb(scsi_qla_host_t *vha, uint32_t req_size, uint32_t rsp_size)
65 {
66         struct qla_hw_data *ha = vha->hw;
67         struct ct_entry_24xx *ct_pkt;
68
69         ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
70         memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
71
72         ct_pkt->entry_type = CT_IOCB_TYPE;
73         ct_pkt->entry_count = 1;
74         ct_pkt->nport_handle = __constant_cpu_to_le16(NPH_SNS);
75         ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
76         ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
77         ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
78         ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
79         ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
80
81         ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
82         ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
83         ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
84
85         ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
86         ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
87         ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
88         ct_pkt->vp_index = vha->vp_idx;
89
90         return (ct_pkt);
91 }
92
93 /**
94  * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
95  * @ct_req: CT request buffer
96  * @cmd: GS command
97  * @rsp_size: response size in bytes
98  *
99  * Returns a pointer to the intitialized @ct_req.
100  */
101 static inline struct ct_sns_req *
102 qla2x00_prep_ct_req(struct ct_sns_req *ct_req, uint16_t cmd, uint16_t rsp_size)
103 {
104         memset(ct_req, 0, sizeof(struct ct_sns_pkt));
105
106         ct_req->header.revision = 0x01;
107         ct_req->header.gs_type = 0xFC;
108         ct_req->header.gs_subtype = 0x02;
109         ct_req->command = cpu_to_be16(cmd);
110         ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
111
112         return (ct_req);
113 }
114
115 static int
116 qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt,
117     struct ct_sns_rsp *ct_rsp, const char *routine)
118 {
119         int rval;
120         uint16_t comp_status;
121         struct qla_hw_data *ha = vha->hw;
122
123         rval = QLA_FUNCTION_FAILED;
124         if (ms_pkt->entry_status != 0) {
125                 ql_dbg(ql_dbg_disc, vha, 0x2031,
126                     "%s failed, error status (%x) on port_id: %02x%02x%02x.\n",
127                     routine, ms_pkt->entry_status, vha->d_id.b.domain,
128                     vha->d_id.b.area, vha->d_id.b.al_pa);
129         } else {
130                 if (IS_FWI2_CAPABLE(ha))
131                         comp_status = le16_to_cpu(
132                             ((struct ct_entry_24xx *)ms_pkt)->comp_status);
133                 else
134                         comp_status = le16_to_cpu(ms_pkt->status);
135                 switch (comp_status) {
136                 case CS_COMPLETE:
137                 case CS_DATA_UNDERRUN:
138                 case CS_DATA_OVERRUN:           /* Overrun? */
139                         if (ct_rsp->header.response !=
140                             __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) {
141                                 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2077,
142                                     "%s failed rejected request on port_id: "
143                                     "%02x%02x%02x.\n", routine,
144                                     vha->d_id.b.domain, vha->d_id.b.area,
145                                     vha->d_id.b.al_pa);
146                                 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha,
147                                     0x2078, (uint8_t *)&ct_rsp->header,
148                                     sizeof(struct ct_rsp_hdr));
149                                 rval = QLA_INVALID_COMMAND;
150                         } else
151                                 rval = QLA_SUCCESS;
152                         break;
153                 default:
154                         ql_dbg(ql_dbg_disc, vha, 0x2033,
155                             "%s failed, completion status (%x) on port_id: "
156                             "%02x%02x%02x.\n", routine, comp_status,
157                             vha->d_id.b.domain, vha->d_id.b.area,
158                             vha->d_id.b.al_pa);
159                         break;
160                 }
161         }
162         return rval;
163 }
164
165 /**
166  * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
167  * @ha: HA context
168  * @fcport: fcport entry to updated
169  *
170  * Returns 0 on success.
171  */
172 int
173 qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
174 {
175         int             rval;
176
177         ms_iocb_entry_t *ms_pkt;
178         struct ct_sns_req       *ct_req;
179         struct ct_sns_rsp       *ct_rsp;
180         struct qla_hw_data *ha = vha->hw;
181
182         if (IS_QLA2100(ha) || IS_QLA2200(ha))
183                 return qla2x00_sns_ga_nxt(vha, fcport);
184
185         /* Issue GA_NXT */
186         /* Prepare common MS IOCB */
187         ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GA_NXT_REQ_SIZE,
188             GA_NXT_RSP_SIZE);
189
190         /* Prepare CT request */
191         ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GA_NXT_CMD,
192             GA_NXT_RSP_SIZE);
193         ct_rsp = &ha->ct_sns->p.rsp;
194
195         /* Prepare CT arguments -- port_id */
196         ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain;
197         ct_req->req.port_id.port_id[1] = fcport->d_id.b.area;
198         ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa;
199
200         /* Execute MS IOCB */
201         rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
202             sizeof(ms_iocb_entry_t));
203         if (rval != QLA_SUCCESS) {
204                 /*EMPTY*/
205                 ql_dbg(ql_dbg_disc, vha, 0x2062,
206                     "GA_NXT issue IOCB failed (%d).\n", rval);
207         } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GA_NXT") !=
208             QLA_SUCCESS) {
209                 rval = QLA_FUNCTION_FAILED;
210         } else {
211                 /* Populate fc_port_t entry. */
212                 fcport->d_id.b.domain = ct_rsp->rsp.ga_nxt.port_id[0];
213                 fcport->d_id.b.area = ct_rsp->rsp.ga_nxt.port_id[1];
214                 fcport->d_id.b.al_pa = ct_rsp->rsp.ga_nxt.port_id[2];
215
216                 memcpy(fcport->node_name, ct_rsp->rsp.ga_nxt.node_name,
217                     WWN_SIZE);
218                 memcpy(fcport->port_name, ct_rsp->rsp.ga_nxt.port_name,
219                     WWN_SIZE);
220
221                 fcport->fc4_type = (ct_rsp->rsp.ga_nxt.fc4_types[2] & BIT_0) ?
222                     FC4_TYPE_FCP_SCSI : FC4_TYPE_OTHER;
223
224                 if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE &&
225                     ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE)
226                         fcport->d_id.b.domain = 0xf0;
227
228                 ql_dbg(ql_dbg_disc, vha, 0x2063,
229                     "GA_NXT entry - nn %02x%02x%02x%02x%02x%02x%02x%02x "
230                     "pn %02x%02x%02x%02x%02x%02x%02x%02x "
231                     "port_id=%02x%02x%02x.\n",
232                     fcport->node_name[0], fcport->node_name[1],
233                     fcport->node_name[2], fcport->node_name[3],
234                     fcport->node_name[4], fcport->node_name[5],
235                     fcport->node_name[6], fcport->node_name[7],
236                     fcport->port_name[0], fcport->port_name[1],
237                     fcport->port_name[2], fcport->port_name[3],
238                     fcport->port_name[4], fcport->port_name[5],
239                     fcport->port_name[6], fcport->port_name[7],
240                     fcport->d_id.b.domain, fcport->d_id.b.area,
241                     fcport->d_id.b.al_pa);
242         }
243
244         return (rval);
245 }
246
247 static inline int
248 qla2x00_gid_pt_rsp_size(scsi_qla_host_t *vha)
249 {
250         return vha->hw->max_fibre_devices * 4 + 16;
251 }
252
253 /**
254  * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command.
255  * @ha: HA context
256  * @list: switch info entries to populate
257  *
258  * NOTE: Non-Nx_Ports are not requested.
259  *
260  * Returns 0 on success.
261  */
262 int
263 qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
264 {
265         int             rval;
266         uint16_t        i;
267
268         ms_iocb_entry_t *ms_pkt;
269         struct ct_sns_req       *ct_req;
270         struct ct_sns_rsp       *ct_rsp;
271
272         struct ct_sns_gid_pt_data *gid_data;
273         struct qla_hw_data *ha = vha->hw;
274         uint16_t gid_pt_rsp_size;
275
276         if (IS_QLA2100(ha) || IS_QLA2200(ha))
277                 return qla2x00_sns_gid_pt(vha, list);
278
279         gid_data = NULL;
280         gid_pt_rsp_size = qla2x00_gid_pt_rsp_size(vha);
281         /* Issue GID_PT */
282         /* Prepare common MS IOCB */
283         ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GID_PT_REQ_SIZE,
284             gid_pt_rsp_size);
285
286         /* Prepare CT request */
287         ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GID_PT_CMD,
288             gid_pt_rsp_size);
289         ct_rsp = &ha->ct_sns->p.rsp;
290
291         /* Prepare CT arguments -- port_type */
292         ct_req->req.gid_pt.port_type = NS_NX_PORT_TYPE;
293
294         /* Execute MS IOCB */
295         rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
296             sizeof(ms_iocb_entry_t));
297         if (rval != QLA_SUCCESS) {
298                 /*EMPTY*/
299                 ql_dbg(ql_dbg_disc, vha, 0x2055,
300                     "GID_PT issue IOCB failed (%d).\n", rval);
301         } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GID_PT") !=
302             QLA_SUCCESS) {
303                 rval = QLA_FUNCTION_FAILED;
304         } else {
305                 /* Set port IDs in switch info list. */
306                 for (i = 0; i < ha->max_fibre_devices; i++) {
307                         gid_data = &ct_rsp->rsp.gid_pt.entries[i];
308                         list[i].d_id.b.domain = gid_data->port_id[0];
309                         list[i].d_id.b.area = gid_data->port_id[1];
310                         list[i].d_id.b.al_pa = gid_data->port_id[2];
311                         memset(list[i].fabric_port_name, 0, WWN_SIZE);
312                         list[i].fp_speed = PORT_SPEED_UNKNOWN;
313
314                         /* Last one exit. */
315                         if (gid_data->control_byte & BIT_7) {
316                                 list[i].d_id.b.rsvd_1 = gid_data->control_byte;
317                                 break;
318                         }
319                 }
320
321                 /*
322                  * If we've used all available slots, then the switch is
323                  * reporting back more devices than we can handle with this
324                  * single call.  Return a failed status, and let GA_NXT handle
325                  * the overload.
326                  */
327                 if (i == ha->max_fibre_devices)
328                         rval = QLA_FUNCTION_FAILED;
329         }
330
331         return (rval);
332 }
333
334 /**
335  * qla2x00_gpn_id() - SNS Get Port Name (GPN_ID) query.
336  * @ha: HA context
337  * @list: switch info entries to populate
338  *
339  * Returns 0 on success.
340  */
341 int
342 qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
343 {
344         int             rval = QLA_SUCCESS;
345         uint16_t        i;
346
347         ms_iocb_entry_t *ms_pkt;
348         struct ct_sns_req       *ct_req;
349         struct ct_sns_rsp       *ct_rsp;
350         struct qla_hw_data *ha = vha->hw;
351
352         if (IS_QLA2100(ha) || IS_QLA2200(ha))
353                 return qla2x00_sns_gpn_id(vha, list);
354
355         for (i = 0; i < ha->max_fibre_devices; i++) {
356                 /* Issue GPN_ID */
357                 /* Prepare common MS IOCB */
358                 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GPN_ID_REQ_SIZE,
359                     GPN_ID_RSP_SIZE);
360
361                 /* Prepare CT request */
362                 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GPN_ID_CMD,
363                     GPN_ID_RSP_SIZE);
364                 ct_rsp = &ha->ct_sns->p.rsp;
365
366                 /* Prepare CT arguments -- port_id */
367                 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
368                 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
369                 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
370
371                 /* Execute MS IOCB */
372                 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
373                     sizeof(ms_iocb_entry_t));
374                 if (rval != QLA_SUCCESS) {
375                         /*EMPTY*/
376                         ql_dbg(ql_dbg_disc, vha, 0x2056,
377                             "GPN_ID issue IOCB failed (%d).\n", rval);
378                         break;
379                 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
380                     "GPN_ID") != QLA_SUCCESS) {
381                         rval = QLA_FUNCTION_FAILED;
382                         break;
383                 } else {
384                         /* Save portname */
385                         memcpy(list[i].port_name,
386                             ct_rsp->rsp.gpn_id.port_name, WWN_SIZE);
387                 }
388
389                 /* Last device exit. */
390                 if (list[i].d_id.b.rsvd_1 != 0)
391                         break;
392         }
393
394         return (rval);
395 }
396
397 /**
398  * qla2x00_gnn_id() - SNS Get Node Name (GNN_ID) query.
399  * @ha: HA context
400  * @list: switch info entries to populate
401  *
402  * Returns 0 on success.
403  */
404 int
405 qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
406 {
407         int             rval = QLA_SUCCESS;
408         uint16_t        i;
409         struct qla_hw_data *ha = vha->hw;
410         ms_iocb_entry_t *ms_pkt;
411         struct ct_sns_req       *ct_req;
412         struct ct_sns_rsp       *ct_rsp;
413
414         if (IS_QLA2100(ha) || IS_QLA2200(ha))
415                 return qla2x00_sns_gnn_id(vha, list);
416
417         for (i = 0; i < ha->max_fibre_devices; i++) {
418                 /* Issue GNN_ID */
419                 /* Prepare common MS IOCB */
420                 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GNN_ID_REQ_SIZE,
421                     GNN_ID_RSP_SIZE);
422
423                 /* Prepare CT request */
424                 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GNN_ID_CMD,
425                     GNN_ID_RSP_SIZE);
426                 ct_rsp = &ha->ct_sns->p.rsp;
427
428                 /* Prepare CT arguments -- port_id */
429                 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
430                 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
431                 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
432
433                 /* Execute MS IOCB */
434                 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
435                     sizeof(ms_iocb_entry_t));
436                 if (rval != QLA_SUCCESS) {
437                         /*EMPTY*/
438                         ql_dbg(ql_dbg_disc, vha, 0x2057,
439                             "GNN_ID issue IOCB failed (%d).\n", rval);
440                         break;
441                 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
442                     "GNN_ID") != QLA_SUCCESS) {
443                         rval = QLA_FUNCTION_FAILED;
444                         break;
445                 } else {
446                         /* Save nodename */
447                         memcpy(list[i].node_name,
448                             ct_rsp->rsp.gnn_id.node_name, WWN_SIZE);
449
450                         ql_dbg(ql_dbg_disc, vha, 0x2058,
451                             "GID_PT entry - nn %02x%02x%02x%02x%02x%02x%02X%02x "
452                             "pn %02x%02x%02x%02x%02x%02x%02X%02x "
453                             "portid=%02x%02x%02x.\n",
454                             list[i].node_name[0], list[i].node_name[1],
455                             list[i].node_name[2], list[i].node_name[3],
456                             list[i].node_name[4], list[i].node_name[5],
457                             list[i].node_name[6], list[i].node_name[7],
458                             list[i].port_name[0], list[i].port_name[1],
459                             list[i].port_name[2], list[i].port_name[3],
460                             list[i].port_name[4], list[i].port_name[5],
461                             list[i].port_name[6], list[i].port_name[7],
462                             list[i].d_id.b.domain, list[i].d_id.b.area,
463                             list[i].d_id.b.al_pa);
464                 }
465
466                 /* Last device exit. */
467                 if (list[i].d_id.b.rsvd_1 != 0)
468                         break;
469         }
470
471         return (rval);
472 }
473
474 /**
475  * qla2x00_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
476  * @ha: HA context
477  *
478  * Returns 0 on success.
479  */
480 int
481 qla2x00_rft_id(scsi_qla_host_t *vha)
482 {
483         int             rval;
484         struct qla_hw_data *ha = vha->hw;
485         ms_iocb_entry_t *ms_pkt;
486         struct ct_sns_req       *ct_req;
487         struct ct_sns_rsp       *ct_rsp;
488
489         if (IS_QLA2100(ha) || IS_QLA2200(ha))
490                 return qla2x00_sns_rft_id(vha);
491
492         /* Issue RFT_ID */
493         /* Prepare common MS IOCB */
494         ms_pkt = ha->isp_ops->prep_ms_iocb(vha, RFT_ID_REQ_SIZE,
495             RFT_ID_RSP_SIZE);
496
497         /* Prepare CT request */
498         ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFT_ID_CMD,
499             RFT_ID_RSP_SIZE);
500         ct_rsp = &ha->ct_sns->p.rsp;
501
502         /* Prepare CT arguments -- port_id, FC-4 types */
503         ct_req->req.rft_id.port_id[0] = vha->d_id.b.domain;
504         ct_req->req.rft_id.port_id[1] = vha->d_id.b.area;
505         ct_req->req.rft_id.port_id[2] = vha->d_id.b.al_pa;
506
507         ct_req->req.rft_id.fc4_types[2] = 0x01;         /* FCP-3 */
508
509         /* Execute MS IOCB */
510         rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
511             sizeof(ms_iocb_entry_t));
512         if (rval != QLA_SUCCESS) {
513                 /*EMPTY*/
514                 ql_dbg(ql_dbg_disc, vha, 0x2043,
515                     "RFT_ID issue IOCB failed (%d).\n", rval);
516         } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RFT_ID") !=
517             QLA_SUCCESS) {
518                 rval = QLA_FUNCTION_FAILED;
519         } else {
520                 ql_dbg(ql_dbg_disc, vha, 0x2044,
521                     "RFT_ID exiting normally.\n");
522         }
523
524         return (rval);
525 }
526
527 /**
528  * qla2x00_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the HBA.
529  * @ha: HA context
530  *
531  * Returns 0 on success.
532  */
533 int
534 qla2x00_rff_id(scsi_qla_host_t *vha)
535 {
536         int             rval;
537         struct qla_hw_data *ha = vha->hw;
538         ms_iocb_entry_t *ms_pkt;
539         struct ct_sns_req       *ct_req;
540         struct ct_sns_rsp       *ct_rsp;
541
542         if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
543                 ql_dbg(ql_dbg_disc, vha, 0x2046,
544                     "RFF_ID call not supported on ISP2100/ISP2200.\n");
545                 return (QLA_SUCCESS);
546         }
547
548         /* Issue RFF_ID */
549         /* Prepare common MS IOCB */
550         ms_pkt = ha->isp_ops->prep_ms_iocb(vha, RFF_ID_REQ_SIZE,
551             RFF_ID_RSP_SIZE);
552
553         /* Prepare CT request */
554         ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFF_ID_CMD,
555             RFF_ID_RSP_SIZE);
556         ct_rsp = &ha->ct_sns->p.rsp;
557
558         /* Prepare CT arguments -- port_id, FC-4 feature, FC-4 type */
559         ct_req->req.rff_id.port_id[0] = vha->d_id.b.domain;
560         ct_req->req.rff_id.port_id[1] = vha->d_id.b.area;
561         ct_req->req.rff_id.port_id[2] = vha->d_id.b.al_pa;
562
563         qlt_rff_id(vha, ct_req);
564
565         ct_req->req.rff_id.fc4_type = 0x08;             /* SCSI - FCP */
566
567         /* Execute MS IOCB */
568         rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
569             sizeof(ms_iocb_entry_t));
570         if (rval != QLA_SUCCESS) {
571                 /*EMPTY*/
572                 ql_dbg(ql_dbg_disc, vha, 0x2047,
573                     "RFF_ID issue IOCB failed (%d).\n", rval);
574         } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RFF_ID") !=
575             QLA_SUCCESS) {
576                 rval = QLA_FUNCTION_FAILED;
577         } else {
578                 ql_dbg(ql_dbg_disc, vha, 0x2048,
579                     "RFF_ID exiting normally.\n");
580         }
581
582         return (rval);
583 }
584
585 /**
586  * qla2x00_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
587  * @ha: HA context
588  *
589  * Returns 0 on success.
590  */
591 int
592 qla2x00_rnn_id(scsi_qla_host_t *vha)
593 {
594         int             rval;
595         struct qla_hw_data *ha = vha->hw;
596         ms_iocb_entry_t *ms_pkt;
597         struct ct_sns_req       *ct_req;
598         struct ct_sns_rsp       *ct_rsp;
599
600         if (IS_QLA2100(ha) || IS_QLA2200(ha))
601                 return qla2x00_sns_rnn_id(vha);
602
603         /* Issue RNN_ID */
604         /* Prepare common MS IOCB */
605         ms_pkt = ha->isp_ops->prep_ms_iocb(vha, RNN_ID_REQ_SIZE,
606             RNN_ID_RSP_SIZE);
607
608         /* Prepare CT request */
609         ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RNN_ID_CMD,
610             RNN_ID_RSP_SIZE);
611         ct_rsp = &ha->ct_sns->p.rsp;
612
613         /* Prepare CT arguments -- port_id, node_name */
614         ct_req->req.rnn_id.port_id[0] = vha->d_id.b.domain;
615         ct_req->req.rnn_id.port_id[1] = vha->d_id.b.area;
616         ct_req->req.rnn_id.port_id[2] = vha->d_id.b.al_pa;
617
618         memcpy(ct_req->req.rnn_id.node_name, vha->node_name, WWN_SIZE);
619
620         /* Execute MS IOCB */
621         rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
622             sizeof(ms_iocb_entry_t));
623         if (rval != QLA_SUCCESS) {
624                 /*EMPTY*/
625                 ql_dbg(ql_dbg_disc, vha, 0x204d,
626                     "RNN_ID issue IOCB failed (%d).\n", rval);
627         } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RNN_ID") !=
628             QLA_SUCCESS) {
629                 rval = QLA_FUNCTION_FAILED;
630         } else {
631                 ql_dbg(ql_dbg_disc, vha, 0x204e,
632                     "RNN_ID exiting normally.\n");
633         }
634
635         return (rval);
636 }
637
638 void
639 qla2x00_get_sym_node_name(scsi_qla_host_t *vha, uint8_t *snn)
640 {
641         struct qla_hw_data *ha = vha->hw;
642         sprintf(snn, "%s FW:v%d.%02d.%02d DVR:v%s",ha->model_number,
643             ha->fw_major_version, ha->fw_minor_version,
644             ha->fw_subminor_version, qla2x00_version_str);
645 }
646
647 /**
648  * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA.
649  * @ha: HA context
650  *
651  * Returns 0 on success.
652  */
653 int
654 qla2x00_rsnn_nn(scsi_qla_host_t *vha)
655 {
656         int             rval;
657         struct qla_hw_data *ha = vha->hw;
658         ms_iocb_entry_t *ms_pkt;
659         struct ct_sns_req       *ct_req;
660         struct ct_sns_rsp       *ct_rsp;
661
662         if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
663                 ql_dbg(ql_dbg_disc, vha, 0x2050,
664                     "RSNN_ID call unsupported on ISP2100/ISP2200.\n");
665                 return (QLA_SUCCESS);
666         }
667
668         /* Issue RSNN_NN */
669         /* Prepare common MS IOCB */
670         /*   Request size adjusted after CT preparation */
671         ms_pkt = ha->isp_ops->prep_ms_iocb(vha, 0, RSNN_NN_RSP_SIZE);
672
673         /* Prepare CT request */
674         ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RSNN_NN_CMD,
675             RSNN_NN_RSP_SIZE);
676         ct_rsp = &ha->ct_sns->p.rsp;
677
678         /* Prepare CT arguments -- node_name, symbolic node_name, size */
679         memcpy(ct_req->req.rsnn_nn.node_name, vha->node_name, WWN_SIZE);
680
681         /* Prepare the Symbolic Node Name */
682         qla2x00_get_sym_node_name(vha, ct_req->req.rsnn_nn.sym_node_name);
683
684         /* Calculate SNN length */
685         ct_req->req.rsnn_nn.name_len =
686             (uint8_t)strlen(ct_req->req.rsnn_nn.sym_node_name);
687
688         /* Update MS IOCB request */
689         ms_pkt->req_bytecount =
690             cpu_to_le32(24 + 1 + ct_req->req.rsnn_nn.name_len);
691         ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
692
693         /* Execute MS IOCB */
694         rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
695             sizeof(ms_iocb_entry_t));
696         if (rval != QLA_SUCCESS) {
697                 /*EMPTY*/
698                 ql_dbg(ql_dbg_disc, vha, 0x2051,
699                     "RSNN_NN issue IOCB failed (%d).\n", rval);
700         } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RSNN_NN") !=
701             QLA_SUCCESS) {
702                 rval = QLA_FUNCTION_FAILED;
703         } else {
704                 ql_dbg(ql_dbg_disc, vha, 0x2052,
705                     "RSNN_NN exiting normally.\n");
706         }
707
708         return (rval);
709 }
710
711 /**
712  * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query.
713  * @ha: HA context
714  * @cmd: GS command
715  * @scmd_len: Subcommand length
716  * @data_size: response size in bytes
717  *
718  * Returns a pointer to the @ha's sns_cmd.
719  */
720 static inline struct sns_cmd_pkt *
721 qla2x00_prep_sns_cmd(scsi_qla_host_t *vha, uint16_t cmd, uint16_t scmd_len,
722     uint16_t data_size)
723 {
724         uint16_t                wc;
725         struct sns_cmd_pkt      *sns_cmd;
726         struct qla_hw_data *ha = vha->hw;
727
728         sns_cmd = ha->sns_cmd;
729         memset(sns_cmd, 0, sizeof(struct sns_cmd_pkt));
730         wc = data_size / 2;                     /* Size in 16bit words. */
731         sns_cmd->p.cmd.buffer_length = cpu_to_le16(wc);
732         sns_cmd->p.cmd.buffer_address[0] = cpu_to_le32(LSD(ha->sns_cmd_dma));
733         sns_cmd->p.cmd.buffer_address[1] = cpu_to_le32(MSD(ha->sns_cmd_dma));
734         sns_cmd->p.cmd.subcommand_length = cpu_to_le16(scmd_len);
735         sns_cmd->p.cmd.subcommand = cpu_to_le16(cmd);
736         wc = (data_size - 16) / 4;              /* Size in 32bit words. */
737         sns_cmd->p.cmd.size = cpu_to_le16(wc);
738
739         return (sns_cmd);
740 }
741
742 /**
743  * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
744  * @ha: HA context
745  * @fcport: fcport entry to updated
746  *
747  * This command uses the old Exectute SNS Command mailbox routine.
748  *
749  * Returns 0 on success.
750  */
751 static int
752 qla2x00_sns_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
753 {
754         int             rval = QLA_SUCCESS;
755         struct qla_hw_data *ha = vha->hw;
756         struct sns_cmd_pkt      *sns_cmd;
757
758         /* Issue GA_NXT. */
759         /* Prepare SNS command request. */
760         sns_cmd = qla2x00_prep_sns_cmd(vha, GA_NXT_CMD, GA_NXT_SNS_SCMD_LEN,
761             GA_NXT_SNS_DATA_SIZE);
762
763         /* Prepare SNS command arguments -- port_id. */
764         sns_cmd->p.cmd.param[0] = fcport->d_id.b.al_pa;
765         sns_cmd->p.cmd.param[1] = fcport->d_id.b.area;
766         sns_cmd->p.cmd.param[2] = fcport->d_id.b.domain;
767
768         /* Execute SNS command. */
769         rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GA_NXT_SNS_CMD_SIZE / 2,
770             sizeof(struct sns_cmd_pkt));
771         if (rval != QLA_SUCCESS) {
772                 /*EMPTY*/
773                 ql_dbg(ql_dbg_disc, vha, 0x205f,
774                     "GA_NXT Send SNS failed (%d).\n", rval);
775         } else if (sns_cmd->p.gan_data[8] != 0x80 ||
776             sns_cmd->p.gan_data[9] != 0x02) {
777                 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2084,
778                     "GA_NXT failed, rejected request ga_nxt_rsp:\n");
779                 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2074,
780                     sns_cmd->p.gan_data, 16);
781                 rval = QLA_FUNCTION_FAILED;
782         } else {
783                 /* Populate fc_port_t entry. */
784                 fcport->d_id.b.domain = sns_cmd->p.gan_data[17];
785                 fcport->d_id.b.area = sns_cmd->p.gan_data[18];
786                 fcport->d_id.b.al_pa = sns_cmd->p.gan_data[19];
787
788                 memcpy(fcport->node_name, &sns_cmd->p.gan_data[284], WWN_SIZE);
789                 memcpy(fcport->port_name, &sns_cmd->p.gan_data[20], WWN_SIZE);
790
791                 if (sns_cmd->p.gan_data[16] != NS_N_PORT_TYPE &&
792                     sns_cmd->p.gan_data[16] != NS_NL_PORT_TYPE)
793                         fcport->d_id.b.domain = 0xf0;
794
795                 ql_dbg(ql_dbg_disc, vha, 0x2061,
796                     "GA_NXT entry - nn %02x%02x%02x%02x%02x%02x%02x%02x "
797                     "pn %02x%02x%02x%02x%02x%02x%02x%02x "
798                     "port_id=%02x%02x%02x.\n",
799                     fcport->node_name[0], fcport->node_name[1],
800                     fcport->node_name[2], fcport->node_name[3],
801                     fcport->node_name[4], fcport->node_name[5],
802                     fcport->node_name[6], fcport->node_name[7],
803                     fcport->port_name[0], fcport->port_name[1],
804                     fcport->port_name[2], fcport->port_name[3],
805                     fcport->port_name[4], fcport->port_name[5],
806                     fcport->port_name[6], fcport->port_name[7],
807                     fcport->d_id.b.domain, fcport->d_id.b.area,
808                     fcport->d_id.b.al_pa);
809         }
810
811         return (rval);
812 }
813
814 /**
815  * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command.
816  * @ha: HA context
817  * @list: switch info entries to populate
818  *
819  * This command uses the old Exectute SNS Command mailbox routine.
820  *
821  * NOTE: Non-Nx_Ports are not requested.
822  *
823  * Returns 0 on success.
824  */
825 static int
826 qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
827 {
828         int             rval;
829         struct qla_hw_data *ha = vha->hw;
830         uint16_t        i;
831         uint8_t         *entry;
832         struct sns_cmd_pkt      *sns_cmd;
833         uint16_t gid_pt_sns_data_size;
834
835         gid_pt_sns_data_size = qla2x00_gid_pt_rsp_size(vha);
836
837         /* Issue GID_PT. */
838         /* Prepare SNS command request. */
839         sns_cmd = qla2x00_prep_sns_cmd(vha, GID_PT_CMD, GID_PT_SNS_SCMD_LEN,
840             gid_pt_sns_data_size);
841
842         /* Prepare SNS command arguments -- port_type. */
843         sns_cmd->p.cmd.param[0] = NS_NX_PORT_TYPE;
844
845         /* Execute SNS command. */
846         rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GID_PT_SNS_CMD_SIZE / 2,
847             sizeof(struct sns_cmd_pkt));
848         if (rval != QLA_SUCCESS) {
849                 /*EMPTY*/
850                 ql_dbg(ql_dbg_disc, vha, 0x206d,
851                     "GID_PT Send SNS failed (%d).\n", rval);
852         } else if (sns_cmd->p.gid_data[8] != 0x80 ||
853             sns_cmd->p.gid_data[9] != 0x02) {
854                 ql_dbg(ql_dbg_disc, vha, 0x202f,
855                     "GID_PT failed, rejected request, gid_rsp:\n");
856                 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2081,
857                     sns_cmd->p.gid_data, 16);
858                 rval = QLA_FUNCTION_FAILED;
859         } else {
860                 /* Set port IDs in switch info list. */
861                 for (i = 0; i < ha->max_fibre_devices; i++) {
862                         entry = &sns_cmd->p.gid_data[(i * 4) + 16];
863                         list[i].d_id.b.domain = entry[1];
864                         list[i].d_id.b.area = entry[2];
865                         list[i].d_id.b.al_pa = entry[3];
866
867                         /* Last one exit. */
868                         if (entry[0] & BIT_7) {
869                                 list[i].d_id.b.rsvd_1 = entry[0];
870                                 break;
871                         }
872                 }
873
874                 /*
875                  * If we've used all available slots, then the switch is
876                  * reporting back more devices that we can handle with this
877                  * single call.  Return a failed status, and let GA_NXT handle
878                  * the overload.
879                  */
880                 if (i == ha->max_fibre_devices)
881                         rval = QLA_FUNCTION_FAILED;
882         }
883
884         return (rval);
885 }
886
887 /**
888  * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query.
889  * @ha: HA context
890  * @list: switch info entries to populate
891  *
892  * This command uses the old Exectute SNS Command mailbox routine.
893  *
894  * Returns 0 on success.
895  */
896 static int
897 qla2x00_sns_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
898 {
899         int             rval = QLA_SUCCESS;
900         struct qla_hw_data *ha = vha->hw;
901         uint16_t        i;
902         struct sns_cmd_pkt      *sns_cmd;
903
904         for (i = 0; i < ha->max_fibre_devices; i++) {
905                 /* Issue GPN_ID */
906                 /* Prepare SNS command request. */
907                 sns_cmd = qla2x00_prep_sns_cmd(vha, GPN_ID_CMD,
908                     GPN_ID_SNS_SCMD_LEN, GPN_ID_SNS_DATA_SIZE);
909
910                 /* Prepare SNS command arguments -- port_id. */
911                 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa;
912                 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area;
913                 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain;
914
915                 /* Execute SNS command. */
916                 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma,
917                     GPN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt));
918                 if (rval != QLA_SUCCESS) {
919                         /*EMPTY*/
920                         ql_dbg(ql_dbg_disc, vha, 0x2032,
921                             "GPN_ID Send SNS failed (%d).\n", rval);
922                 } else if (sns_cmd->p.gpn_data[8] != 0x80 ||
923                     sns_cmd->p.gpn_data[9] != 0x02) {
924                         ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207e,
925                             "GPN_ID failed, rejected request, gpn_rsp:\n");
926                         ql_dump_buffer(ql_dbg_disc, vha, 0x207f,
927                             sns_cmd->p.gpn_data, 16);
928                         rval = QLA_FUNCTION_FAILED;
929                 } else {
930                         /* Save portname */
931                         memcpy(list[i].port_name, &sns_cmd->p.gpn_data[16],
932                             WWN_SIZE);
933                 }
934
935                 /* Last device exit. */
936                 if (list[i].d_id.b.rsvd_1 != 0)
937                         break;
938         }
939
940         return (rval);
941 }
942
943 /**
944  * qla2x00_sns_gnn_id() - SNS Get Node Name (GNN_ID) query.
945  * @ha: HA context
946  * @list: switch info entries to populate
947  *
948  * This command uses the old Exectute SNS Command mailbox routine.
949  *
950  * Returns 0 on success.
951  */
952 static int
953 qla2x00_sns_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
954 {
955         int             rval = QLA_SUCCESS;
956         struct qla_hw_data *ha = vha->hw;
957         uint16_t        i;
958         struct sns_cmd_pkt      *sns_cmd;
959
960         for (i = 0; i < ha->max_fibre_devices; i++) {
961                 /* Issue GNN_ID */
962                 /* Prepare SNS command request. */
963                 sns_cmd = qla2x00_prep_sns_cmd(vha, GNN_ID_CMD,
964                     GNN_ID_SNS_SCMD_LEN, GNN_ID_SNS_DATA_SIZE);
965
966                 /* Prepare SNS command arguments -- port_id. */
967                 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa;
968                 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area;
969                 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain;
970
971                 /* Execute SNS command. */
972                 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma,
973                     GNN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt));
974                 if (rval != QLA_SUCCESS) {
975                         /*EMPTY*/
976                         ql_dbg(ql_dbg_disc, vha, 0x203f,
977                             "GNN_ID Send SNS failed (%d).\n", rval);
978                 } else if (sns_cmd->p.gnn_data[8] != 0x80 ||
979                     sns_cmd->p.gnn_data[9] != 0x02) {
980                         ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2082,
981                             "GNN_ID failed, rejected request, gnn_rsp:\n");
982                         ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207a,
983                             sns_cmd->p.gnn_data, 16);
984                         rval = QLA_FUNCTION_FAILED;
985                 } else {
986                         /* Save nodename */
987                         memcpy(list[i].node_name, &sns_cmd->p.gnn_data[16],
988                             WWN_SIZE);
989
990                         ql_dbg(ql_dbg_disc, vha, 0x206e,
991                             "GID_PT entry - nn %02x%02x%02x%02x%02x%02x%02x%02x "
992                             "pn %02x%02x%02x%02x%02x%02x%02x%02x "
993                             "port_id=%02x%02x%02x.\n",
994                             list[i].node_name[0], list[i].node_name[1],
995                             list[i].node_name[2], list[i].node_name[3],
996                             list[i].node_name[4], list[i].node_name[5],
997                             list[i].node_name[6], list[i].node_name[7],
998                             list[i].port_name[0], list[i].port_name[1],
999                             list[i].port_name[2], list[i].port_name[3],
1000                             list[i].port_name[4], list[i].port_name[5],
1001                             list[i].port_name[6], list[i].port_name[7],
1002                             list[i].d_id.b.domain, list[i].d_id.b.area,
1003                             list[i].d_id.b.al_pa);
1004                 }
1005
1006                 /* Last device exit. */
1007                 if (list[i].d_id.b.rsvd_1 != 0)
1008                         break;
1009         }
1010
1011         return (rval);
1012 }
1013
1014 /**
1015  * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
1016  * @ha: HA context
1017  *
1018  * This command uses the old Exectute SNS Command mailbox routine.
1019  *
1020  * Returns 0 on success.
1021  */
1022 static int
1023 qla2x00_sns_rft_id(scsi_qla_host_t *vha)
1024 {
1025         int             rval;
1026         struct qla_hw_data *ha = vha->hw;
1027         struct sns_cmd_pkt      *sns_cmd;
1028
1029         /* Issue RFT_ID. */
1030         /* Prepare SNS command request. */
1031         sns_cmd = qla2x00_prep_sns_cmd(vha, RFT_ID_CMD, RFT_ID_SNS_SCMD_LEN,
1032             RFT_ID_SNS_DATA_SIZE);
1033
1034         /* Prepare SNS command arguments -- port_id, FC-4 types */
1035         sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa;
1036         sns_cmd->p.cmd.param[1] = vha->d_id.b.area;
1037         sns_cmd->p.cmd.param[2] = vha->d_id.b.domain;
1038
1039         sns_cmd->p.cmd.param[5] = 0x01;                 /* FCP-3 */
1040
1041         /* Execute SNS command. */
1042         rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RFT_ID_SNS_CMD_SIZE / 2,
1043             sizeof(struct sns_cmd_pkt));
1044         if (rval != QLA_SUCCESS) {
1045                 /*EMPTY*/
1046                 ql_dbg(ql_dbg_disc, vha, 0x2060,
1047                     "RFT_ID Send SNS failed (%d).\n", rval);
1048         } else if (sns_cmd->p.rft_data[8] != 0x80 ||
1049             sns_cmd->p.rft_data[9] != 0x02) {
1050                 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2083,
1051                     "RFT_ID failed, rejected request rft_rsp:\n");
1052                 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2080,
1053                     sns_cmd->p.rft_data, 16);
1054                 rval = QLA_FUNCTION_FAILED;
1055         } else {
1056                 ql_dbg(ql_dbg_disc, vha, 0x2073,
1057                     "RFT_ID exiting normally.\n");
1058         }
1059
1060         return (rval);
1061 }
1062
1063 /**
1064  * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
1065  * HBA.
1066  * @ha: HA context
1067  *
1068  * This command uses the old Exectute SNS Command mailbox routine.
1069  *
1070  * Returns 0 on success.
1071  */
1072 static int
1073 qla2x00_sns_rnn_id(scsi_qla_host_t *vha)
1074 {
1075         int             rval;
1076         struct qla_hw_data *ha = vha->hw;
1077         struct sns_cmd_pkt      *sns_cmd;
1078
1079         /* Issue RNN_ID. */
1080         /* Prepare SNS command request. */
1081         sns_cmd = qla2x00_prep_sns_cmd(vha, RNN_ID_CMD, RNN_ID_SNS_SCMD_LEN,
1082             RNN_ID_SNS_DATA_SIZE);
1083
1084         /* Prepare SNS command arguments -- port_id, nodename. */
1085         sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa;
1086         sns_cmd->p.cmd.param[1] = vha->d_id.b.area;
1087         sns_cmd->p.cmd.param[2] = vha->d_id.b.domain;
1088
1089         sns_cmd->p.cmd.param[4] = vha->node_name[7];
1090         sns_cmd->p.cmd.param[5] = vha->node_name[6];
1091         sns_cmd->p.cmd.param[6] = vha->node_name[5];
1092         sns_cmd->p.cmd.param[7] = vha->node_name[4];
1093         sns_cmd->p.cmd.param[8] = vha->node_name[3];
1094         sns_cmd->p.cmd.param[9] = vha->node_name[2];
1095         sns_cmd->p.cmd.param[10] = vha->node_name[1];
1096         sns_cmd->p.cmd.param[11] = vha->node_name[0];
1097
1098         /* Execute SNS command. */
1099         rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RNN_ID_SNS_CMD_SIZE / 2,
1100             sizeof(struct sns_cmd_pkt));
1101         if (rval != QLA_SUCCESS) {
1102                 /*EMPTY*/
1103                 ql_dbg(ql_dbg_disc, vha, 0x204a,
1104                     "RNN_ID Send SNS failed (%d).\n", rval);
1105         } else if (sns_cmd->p.rnn_data[8] != 0x80 ||
1106             sns_cmd->p.rnn_data[9] != 0x02) {
1107                 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207b,
1108                     "RNN_ID failed, rejected request, rnn_rsp:\n");
1109                 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207c,
1110                     sns_cmd->p.rnn_data, 16);
1111                 rval = QLA_FUNCTION_FAILED;
1112         } else {
1113                 ql_dbg(ql_dbg_disc, vha, 0x204c,
1114                     "RNN_ID exiting normally.\n");
1115         }
1116
1117         return (rval);
1118 }
1119
1120 /**
1121  * qla2x00_mgmt_svr_login() - Login to fabric Management Service.
1122  * @ha: HA context
1123  *
1124  * Returns 0 on success.
1125  */
1126 static int
1127 qla2x00_mgmt_svr_login(scsi_qla_host_t *vha)
1128 {
1129         int ret, rval;
1130         uint16_t mb[MAILBOX_REGISTER_COUNT];
1131         struct qla_hw_data *ha = vha->hw;
1132         ret = QLA_SUCCESS;
1133         if (vha->flags.management_server_logged_in)
1134                 return ret;
1135
1136         rval = ha->isp_ops->fabric_login(vha, vha->mgmt_svr_loop_id, 0xff, 0xff,
1137             0xfa, mb, BIT_1);
1138         if (rval != QLA_SUCCESS || mb[0] != MBS_COMMAND_COMPLETE) {
1139                 if (rval == QLA_MEMORY_ALLOC_FAILED)
1140                         ql_dbg(ql_dbg_disc, vha, 0x2085,
1141                             "Failed management_server login: loopid=%x "
1142                             "rval=%d\n", vha->mgmt_svr_loop_id, rval);
1143                 else
1144                         ql_dbg(ql_dbg_disc, vha, 0x2024,
1145                             "Failed management_server login: loopid=%x "
1146                             "mb[0]=%x mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x.\n",
1147                             vha->mgmt_svr_loop_id, mb[0], mb[1], mb[2], mb[6],
1148                             mb[7]);
1149                 ret = QLA_FUNCTION_FAILED;
1150         } else
1151                 vha->flags.management_server_logged_in = 1;
1152
1153         return ret;
1154 }
1155
1156 /**
1157  * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
1158  * @ha: HA context
1159  * @req_size: request size in bytes
1160  * @rsp_size: response size in bytes
1161  *
1162  * Returns a pointer to the @ha's ms_iocb.
1163  */
1164 void *
1165 qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size,
1166     uint32_t rsp_size)
1167 {
1168         ms_iocb_entry_t *ms_pkt;
1169         struct qla_hw_data *ha = vha->hw;
1170         ms_pkt = ha->ms_iocb;
1171         memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
1172
1173         ms_pkt->entry_type = MS_IOCB_TYPE;
1174         ms_pkt->entry_count = 1;
1175         SET_TARGET_ID(ha, ms_pkt->loop_id, vha->mgmt_svr_loop_id);
1176         ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG);
1177         ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
1178         ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
1179         ms_pkt->total_dsd_count = __constant_cpu_to_le16(2);
1180         ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
1181         ms_pkt->req_bytecount = cpu_to_le32(req_size);
1182
1183         ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1184         ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1185         ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
1186
1187         ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1188         ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1189         ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount;
1190
1191         return ms_pkt;
1192 }
1193
1194 /**
1195  * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
1196  * @ha: HA context
1197  * @req_size: request size in bytes
1198  * @rsp_size: response size in bytes
1199  *
1200  * Returns a pointer to the @ha's ms_iocb.
1201  */
1202 void *
1203 qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size,
1204     uint32_t rsp_size)
1205 {
1206         struct ct_entry_24xx *ct_pkt;
1207         struct qla_hw_data *ha = vha->hw;
1208
1209         ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
1210         memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
1211
1212         ct_pkt->entry_type = CT_IOCB_TYPE;
1213         ct_pkt->entry_count = 1;
1214         ct_pkt->nport_handle = cpu_to_le16(vha->mgmt_svr_loop_id);
1215         ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
1216         ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
1217         ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
1218         ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
1219         ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
1220
1221         ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1222         ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1223         ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
1224
1225         ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1226         ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1227         ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
1228         ct_pkt->vp_index = vha->vp_idx;
1229
1230         return ct_pkt;
1231 }
1232
1233 static inline ms_iocb_entry_t *
1234 qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size)
1235 {
1236         struct qla_hw_data *ha = vha->hw;
1237         ms_iocb_entry_t *ms_pkt = ha->ms_iocb;
1238         struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
1239
1240         if (IS_FWI2_CAPABLE(ha)) {
1241                 ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
1242                 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
1243         } else {
1244                 ms_pkt->req_bytecount = cpu_to_le32(req_size);
1245                 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
1246         }
1247
1248         return ms_pkt;
1249 }
1250
1251 /**
1252  * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
1253  * @ct_req: CT request buffer
1254  * @cmd: GS command
1255  * @rsp_size: response size in bytes
1256  *
1257  * Returns a pointer to the intitialized @ct_req.
1258  */
1259 static inline struct ct_sns_req *
1260 qla2x00_prep_ct_fdmi_req(struct ct_sns_req *ct_req, uint16_t cmd,
1261     uint16_t rsp_size)
1262 {
1263         memset(ct_req, 0, sizeof(struct ct_sns_pkt));
1264
1265         ct_req->header.revision = 0x01;
1266         ct_req->header.gs_type = 0xFA;
1267         ct_req->header.gs_subtype = 0x10;
1268         ct_req->command = cpu_to_be16(cmd);
1269         ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
1270
1271         return ct_req;
1272 }
1273
1274 /**
1275  * qla2x00_fdmi_rhba() -
1276  * @ha: HA context
1277  *
1278  * Returns 0 on success.
1279  */
1280 static int
1281 qla2x00_fdmi_rhba(scsi_qla_host_t *vha)
1282 {
1283         int rval, alen;
1284         uint32_t size, sn;
1285
1286         ms_iocb_entry_t *ms_pkt;
1287         struct ct_sns_req *ct_req;
1288         struct ct_sns_rsp *ct_rsp;
1289         uint8_t *entries;
1290         struct ct_fdmi_hba_attr *eiter;
1291         struct qla_hw_data *ha = vha->hw;
1292
1293         /* Issue RHBA */
1294         /* Prepare common MS IOCB */
1295         /*   Request size adjusted after CT preparation */
1296         ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE);
1297
1298         /* Prepare CT request */
1299         ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RHBA_CMD,
1300             RHBA_RSP_SIZE);
1301         ct_rsp = &ha->ct_sns->p.rsp;
1302
1303         /* Prepare FDMI command arguments -- attribute block, attributes. */
1304         memcpy(ct_req->req.rhba.hba_identifier, vha->port_name, WWN_SIZE);
1305         ct_req->req.rhba.entry_count = __constant_cpu_to_be32(1);
1306         memcpy(ct_req->req.rhba.port_name, vha->port_name, WWN_SIZE);
1307         size = 2 * WWN_SIZE + 4 + 4;
1308
1309         /* Attributes */
1310         ct_req->req.rhba.attrs.count =
1311             __constant_cpu_to_be32(FDMI_HBA_ATTR_COUNT);
1312         entries = ct_req->req.rhba.hba_identifier;
1313
1314         /* Nodename. */
1315         eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1316         eiter->type = __constant_cpu_to_be16(FDMI_HBA_NODE_NAME);
1317         eiter->len = __constant_cpu_to_be16(4 + WWN_SIZE);
1318         memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE);
1319         size += 4 + WWN_SIZE;
1320
1321         ql_dbg(ql_dbg_disc, vha, 0x2025,
1322             "NodeName = %02x%02x%02x%02x%02x%02x%02x%02x.\n",
1323             eiter->a.node_name[0], eiter->a.node_name[1],
1324             eiter->a.node_name[2], eiter->a.node_name[3],
1325             eiter->a.node_name[4], eiter->a.node_name[5],
1326             eiter->a.node_name[6], eiter->a.node_name[7]);
1327
1328         /* Manufacturer. */
1329         eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1330         eiter->type = __constant_cpu_to_be16(FDMI_HBA_MANUFACTURER);
1331         strcpy(eiter->a.manufacturer, "QLogic Corporation");
1332         alen = strlen(eiter->a.manufacturer);
1333         alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1334         eiter->len = cpu_to_be16(4 + alen);
1335         size += 4 + alen;
1336
1337         ql_dbg(ql_dbg_disc, vha, 0x2026,
1338             "Manufacturer = %s.\n", eiter->a.manufacturer);
1339
1340         /* Serial number. */
1341         eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1342         eiter->type = __constant_cpu_to_be16(FDMI_HBA_SERIAL_NUMBER);
1343         sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1;
1344         sprintf(eiter->a.serial_num, "%c%05d", 'A' + sn / 100000, sn % 100000);
1345         alen = strlen(eiter->a.serial_num);
1346         alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1347         eiter->len = cpu_to_be16(4 + alen);
1348         size += 4 + alen;
1349
1350         ql_dbg(ql_dbg_disc, vha, 0x2027,
1351             "Serial no. = %s.\n", eiter->a.serial_num);
1352
1353         /* Model name. */
1354         eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1355         eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL);
1356         strcpy(eiter->a.model, ha->model_number);
1357         alen = strlen(eiter->a.model);
1358         alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1359         eiter->len = cpu_to_be16(4 + alen);
1360         size += 4 + alen;
1361
1362         ql_dbg(ql_dbg_disc, vha, 0x2028,
1363             "Model Name = %s.\n", eiter->a.model);
1364
1365         /* Model description. */
1366         eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1367         eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION);
1368         if (ha->model_desc)
1369                 strncpy(eiter->a.model_desc, ha->model_desc, 80);
1370         alen = strlen(eiter->a.model_desc);
1371         alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1372         eiter->len = cpu_to_be16(4 + alen);
1373         size += 4 + alen;
1374
1375         ql_dbg(ql_dbg_disc, vha, 0x2029,
1376             "Model Desc = %s.\n", eiter->a.model_desc);
1377
1378         /* Hardware version. */
1379         eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1380         eiter->type = __constant_cpu_to_be16(FDMI_HBA_HARDWARE_VERSION);
1381         strcpy(eiter->a.hw_version, ha->adapter_id);
1382         alen = strlen(eiter->a.hw_version);
1383         alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1384         eiter->len = cpu_to_be16(4 + alen);
1385         size += 4 + alen;
1386
1387         ql_dbg(ql_dbg_disc, vha, 0x202a,
1388             "Hardware ver = %s.\n", eiter->a.hw_version);
1389
1390         /* Driver version. */
1391         eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1392         eiter->type = __constant_cpu_to_be16(FDMI_HBA_DRIVER_VERSION);
1393         strcpy(eiter->a.driver_version, qla2x00_version_str);
1394         alen = strlen(eiter->a.driver_version);
1395         alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1396         eiter->len = cpu_to_be16(4 + alen);
1397         size += 4 + alen;
1398
1399         ql_dbg(ql_dbg_disc, vha, 0x202b,
1400             "Driver ver = %s.\n", eiter->a.driver_version);
1401
1402         /* Option ROM version. */
1403         eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1404         eiter->type = __constant_cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION);
1405         strcpy(eiter->a.orom_version, "0.00");
1406         alen = strlen(eiter->a.orom_version);
1407         alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1408         eiter->len = cpu_to_be16(4 + alen);
1409         size += 4 + alen;
1410
1411         ql_dbg(ql_dbg_disc, vha , 0x202c,
1412             "Optrom vers = %s.\n", eiter->a.orom_version);
1413
1414         /* Firmware version */
1415         eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1416         eiter->type = __constant_cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION);
1417         ha->isp_ops->fw_version_str(vha, eiter->a.fw_version);
1418         alen = strlen(eiter->a.fw_version);
1419         alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1420         eiter->len = cpu_to_be16(4 + alen);
1421         size += 4 + alen;
1422
1423         ql_dbg(ql_dbg_disc, vha, 0x202d,
1424             "Firmware vers = %s.\n", eiter->a.fw_version);
1425
1426         /* Update MS request size. */
1427         qla2x00_update_ms_fdmi_iocb(vha, size + 16);
1428
1429         ql_dbg(ql_dbg_disc, vha, 0x202e,
1430             "RHBA identifier = "
1431             "%02x%02x%02x%02x%02x%02x%02x%02x size=%d.\n",
1432             ct_req->req.rhba.hba_identifier[0],
1433             ct_req->req.rhba.hba_identifier[1],
1434             ct_req->req.rhba.hba_identifier[2],
1435             ct_req->req.rhba.hba_identifier[3],
1436             ct_req->req.rhba.hba_identifier[4],
1437             ct_req->req.rhba.hba_identifier[5],
1438             ct_req->req.rhba.hba_identifier[6],
1439             ct_req->req.rhba.hba_identifier[7], size);
1440         ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2076,
1441             entries, size);
1442
1443         /* Execute MS IOCB */
1444         rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1445             sizeof(ms_iocb_entry_t));
1446         if (rval != QLA_SUCCESS) {
1447                 /*EMPTY*/
1448                 ql_dbg(ql_dbg_disc, vha, 0x2030,
1449                     "RHBA issue IOCB failed (%d).\n", rval);
1450         } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA") !=
1451             QLA_SUCCESS) {
1452                 rval = QLA_FUNCTION_FAILED;
1453                 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
1454                     ct_rsp->header.explanation_code ==
1455                     CT_EXPL_ALREADY_REGISTERED) {
1456                         ql_dbg(ql_dbg_disc, vha, 0x2034,
1457                             "HBA already registered.\n");
1458                         rval = QLA_ALREADY_REGISTERED;
1459                 }
1460         } else {
1461                 ql_dbg(ql_dbg_disc, vha, 0x2035,
1462                     "RHBA exiting normally.\n");
1463         }
1464
1465         return rval;
1466 }
1467
1468 /**
1469  * qla2x00_fdmi_dhba() -
1470  * @ha: HA context
1471  *
1472  * Returns 0 on success.
1473  */
1474 static int
1475 qla2x00_fdmi_dhba(scsi_qla_host_t *vha)
1476 {
1477         int rval;
1478         struct qla_hw_data *ha = vha->hw;
1479         ms_iocb_entry_t *ms_pkt;
1480         struct ct_sns_req *ct_req;
1481         struct ct_sns_rsp *ct_rsp;
1482
1483         /* Issue RPA */
1484         /* Prepare common MS IOCB */
1485         ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, DHBA_REQ_SIZE,
1486             DHBA_RSP_SIZE);
1487
1488         /* Prepare CT request */
1489         ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, DHBA_CMD,
1490             DHBA_RSP_SIZE);
1491         ct_rsp = &ha->ct_sns->p.rsp;
1492
1493         /* Prepare FDMI command arguments -- portname. */
1494         memcpy(ct_req->req.dhba.port_name, vha->port_name, WWN_SIZE);
1495
1496         ql_dbg(ql_dbg_disc, vha, 0x2036,
1497             "DHBA portname = %02x%02x%02x%02x%02x%02x%02x%02x.\n",
1498             ct_req->req.dhba.port_name[0], ct_req->req.dhba.port_name[1],
1499             ct_req->req.dhba.port_name[2], ct_req->req.dhba.port_name[3],
1500             ct_req->req.dhba.port_name[4], ct_req->req.dhba.port_name[5],
1501             ct_req->req.dhba.port_name[6], ct_req->req.dhba.port_name[7]);
1502
1503         /* Execute MS IOCB */
1504         rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1505             sizeof(ms_iocb_entry_t));
1506         if (rval != QLA_SUCCESS) {
1507                 /*EMPTY*/
1508                 ql_dbg(ql_dbg_disc, vha, 0x2037,
1509                     "DHBA issue IOCB failed (%d).\n", rval);
1510         } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "DHBA") !=
1511             QLA_SUCCESS) {
1512                 rval = QLA_FUNCTION_FAILED;
1513         } else {
1514                 ql_dbg(ql_dbg_disc, vha, 0x2038,
1515                     "DHBA exiting normally.\n");
1516         }
1517
1518         return rval;
1519 }
1520
1521 /**
1522  * qla2x00_fdmi_rpa() -
1523  * @ha: HA context
1524  *
1525  * Returns 0 on success.
1526  */
1527 static int
1528 qla2x00_fdmi_rpa(scsi_qla_host_t *vha)
1529 {
1530         int rval, alen;
1531         uint32_t size, max_frame_size;
1532         struct qla_hw_data *ha = vha->hw;
1533         ms_iocb_entry_t *ms_pkt;
1534         struct ct_sns_req *ct_req;
1535         struct ct_sns_rsp *ct_rsp;
1536         uint8_t *entries;
1537         struct ct_fdmi_port_attr *eiter;
1538         struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb;
1539
1540         /* Issue RPA */
1541         /* Prepare common MS IOCB */
1542         /*   Request size adjusted after CT preparation */
1543         ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE);
1544
1545         /* Prepare CT request */
1546         ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RPA_CMD,
1547             RPA_RSP_SIZE);
1548         ct_rsp = &ha->ct_sns->p.rsp;
1549
1550         /* Prepare FDMI command arguments -- attribute block, attributes. */
1551         memcpy(ct_req->req.rpa.port_name, vha->port_name, WWN_SIZE);
1552         size = WWN_SIZE + 4;
1553
1554         /* Attributes */
1555         ct_req->req.rpa.attrs.count =
1556             __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT - 1);
1557         entries = ct_req->req.rpa.port_name;
1558
1559         /* FC4 types. */
1560         eiter = (struct ct_fdmi_port_attr *) (entries + size);
1561         eiter->type = __constant_cpu_to_be16(FDMI_PORT_FC4_TYPES);
1562         eiter->len = __constant_cpu_to_be16(4 + 32);
1563         eiter->a.fc4_types[2] = 0x01;
1564         size += 4 + 32;
1565
1566         ql_dbg(ql_dbg_disc, vha, 0x2039,
1567             "FC4_TYPES=%02x %02x.\n",
1568             eiter->a.fc4_types[2],
1569             eiter->a.fc4_types[1]);
1570
1571         /* Supported speed. */
1572         eiter = (struct ct_fdmi_port_attr *) (entries + size);
1573         eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
1574         eiter->len = __constant_cpu_to_be16(4 + 4);
1575         if (IS_CNA_CAPABLE(ha))
1576                 eiter->a.sup_speed = __constant_cpu_to_be32(
1577                     FDMI_PORT_SPEED_10GB);
1578         else if (IS_QLA25XX(ha))
1579                 eiter->a.sup_speed = __constant_cpu_to_be32(
1580                     FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB|
1581                     FDMI_PORT_SPEED_4GB|FDMI_PORT_SPEED_8GB);
1582         else if (IS_QLA24XX_TYPE(ha))
1583                 eiter->a.sup_speed = __constant_cpu_to_be32(
1584                     FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB|
1585                     FDMI_PORT_SPEED_4GB);
1586         else if (IS_QLA23XX(ha))
1587                 eiter->a.sup_speed =__constant_cpu_to_be32(
1588                     FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB);
1589         else
1590                 eiter->a.sup_speed = __constant_cpu_to_be32(
1591                     FDMI_PORT_SPEED_1GB);
1592         size += 4 + 4;
1593
1594         ql_dbg(ql_dbg_disc, vha, 0x203a,
1595             "Supported_Speed=%x.\n", eiter->a.sup_speed);
1596
1597         /* Current speed. */
1598         eiter = (struct ct_fdmi_port_attr *) (entries + size);
1599         eiter->type = __constant_cpu_to_be16(FDMI_PORT_CURRENT_SPEED);
1600         eiter->len = __constant_cpu_to_be16(4 + 4);
1601         switch (ha->link_data_rate) {
1602         case PORT_SPEED_1GB:
1603                 eiter->a.cur_speed =
1604                     __constant_cpu_to_be32(FDMI_PORT_SPEED_1GB);
1605                 break;
1606         case PORT_SPEED_2GB:
1607                 eiter->a.cur_speed =
1608                     __constant_cpu_to_be32(FDMI_PORT_SPEED_2GB);
1609                 break;
1610         case PORT_SPEED_4GB:
1611                 eiter->a.cur_speed =
1612                     __constant_cpu_to_be32(FDMI_PORT_SPEED_4GB);
1613                 break;
1614         case PORT_SPEED_8GB:
1615                 eiter->a.cur_speed =
1616                     __constant_cpu_to_be32(FDMI_PORT_SPEED_8GB);
1617                 break;
1618         case PORT_SPEED_10GB:
1619                 eiter->a.cur_speed =
1620                     __constant_cpu_to_be32(FDMI_PORT_SPEED_10GB);
1621                 break;
1622         case PORT_SPEED_16GB:
1623                 eiter->a.cur_speed =
1624                     __constant_cpu_to_be32(FDMI_PORT_SPEED_16GB);
1625                 break;
1626         default:
1627                 eiter->a.cur_speed =
1628                     __constant_cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN);
1629                 break;
1630         }
1631         size += 4 + 4;
1632
1633         ql_dbg(ql_dbg_disc, vha, 0x203b,
1634             "Current_Speed=%x.\n", eiter->a.cur_speed);
1635
1636         /* Max frame size. */
1637         eiter = (struct ct_fdmi_port_attr *) (entries + size);
1638         eiter->type = __constant_cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE);
1639         eiter->len = __constant_cpu_to_be16(4 + 4);
1640         max_frame_size = IS_FWI2_CAPABLE(ha) ?
1641             le16_to_cpu(icb24->frame_payload_size):
1642             le16_to_cpu(ha->init_cb->frame_payload_size);
1643         eiter->a.max_frame_size = cpu_to_be32(max_frame_size);
1644         size += 4 + 4;
1645
1646         ql_dbg(ql_dbg_disc, vha, 0x203c,
1647             "Max_Frame_Size=%x.\n", eiter->a.max_frame_size);
1648
1649         /* OS device name. */
1650         eiter = (struct ct_fdmi_port_attr *) (entries + size);
1651         eiter->type = __constant_cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME);
1652         strcpy(eiter->a.os_dev_name, QLA2XXX_DRIVER_NAME);
1653         alen = strlen(eiter->a.os_dev_name);
1654         alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1655         eiter->len = cpu_to_be16(4 + alen);
1656         size += 4 + alen;
1657
1658         ql_dbg(ql_dbg_disc, vha, 0x204b,
1659             "OS_Device_Name=%s.\n", eiter->a.os_dev_name);
1660
1661         /* Hostname. */
1662         if (strlen(fc_host_system_hostname(vha->host))) {
1663                 ct_req->req.rpa.attrs.count =
1664                     __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT);
1665                 eiter = (struct ct_fdmi_port_attr *) (entries + size);
1666                 eiter->type = __constant_cpu_to_be16(FDMI_PORT_HOST_NAME);
1667                 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
1668                     "%s", fc_host_system_hostname(vha->host));
1669                 alen = strlen(eiter->a.host_name);
1670                 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1671                 eiter->len = cpu_to_be16(4 + alen);
1672                 size += 4 + alen;
1673
1674                 ql_dbg(ql_dbg_disc, vha, 0x203d,
1675                     "HostName=%s.\n", eiter->a.host_name);
1676         }
1677
1678         /* Update MS request size. */
1679         qla2x00_update_ms_fdmi_iocb(vha, size + 16);
1680
1681         ql_dbg(ql_dbg_disc, vha, 0x203e,
1682             "RPA portname= %02x%02x%02x%02x%02X%02x%02x%02x size=%d.\n",
1683             ct_req->req.rpa.port_name[0], ct_req->req.rpa.port_name[1],
1684             ct_req->req.rpa.port_name[2], ct_req->req.rpa.port_name[3],
1685             ct_req->req.rpa.port_name[4], ct_req->req.rpa.port_name[5],
1686             ct_req->req.rpa.port_name[6], ct_req->req.rpa.port_name[7],
1687             size);
1688         ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2079,
1689             entries, size);
1690
1691         /* Execute MS IOCB */
1692         rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1693             sizeof(ms_iocb_entry_t));
1694         if (rval != QLA_SUCCESS) {
1695                 /*EMPTY*/
1696                 ql_dbg(ql_dbg_disc, vha, 0x2040,
1697                     "RPA issue IOCB failed (%d).\n", rval);
1698         } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA") !=
1699             QLA_SUCCESS) {
1700                 rval = QLA_FUNCTION_FAILED;
1701         } else {
1702                 ql_dbg(ql_dbg_disc, vha, 0x2041,
1703                     "RPA exiting nornally.\n");
1704         }
1705
1706         return rval;
1707 }
1708
1709 /**
1710  * qla2x00_fdmi_register() -
1711  * @ha: HA context
1712  *
1713  * Returns 0 on success.
1714  */
1715 int
1716 qla2x00_fdmi_register(scsi_qla_host_t *vha)
1717 {
1718         int rval;
1719        struct qla_hw_data *ha = vha->hw;
1720
1721         if (IS_QLA2100(ha) || IS_QLA2200(ha))
1722                 return QLA_FUNCTION_FAILED;
1723
1724         rval = qla2x00_mgmt_svr_login(vha);
1725         if (rval)
1726                 return rval;
1727
1728         rval = qla2x00_fdmi_rhba(vha);
1729         if (rval) {
1730                 if (rval != QLA_ALREADY_REGISTERED)
1731                         return rval;
1732
1733                 rval = qla2x00_fdmi_dhba(vha);
1734                 if (rval)
1735                         return rval;
1736
1737                 rval = qla2x00_fdmi_rhba(vha);
1738                 if (rval)
1739                         return rval;
1740         }
1741         rval = qla2x00_fdmi_rpa(vha);
1742
1743         return rval;
1744 }
1745
1746 /**
1747  * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query.
1748  * @ha: HA context
1749  * @list: switch info entries to populate
1750  *
1751  * Returns 0 on success.
1752  */
1753 int
1754 qla2x00_gfpn_id(scsi_qla_host_t *vha, sw_info_t *list)
1755 {
1756         int             rval = QLA_SUCCESS;
1757         uint16_t        i;
1758         struct qla_hw_data *ha = vha->hw;
1759         ms_iocb_entry_t *ms_pkt;
1760         struct ct_sns_req       *ct_req;
1761         struct ct_sns_rsp       *ct_rsp;
1762
1763         if (!IS_IIDMA_CAPABLE(ha))
1764                 return QLA_FUNCTION_FAILED;
1765
1766         for (i = 0; i < ha->max_fibre_devices; i++) {
1767                 /* Issue GFPN_ID */
1768                 /* Prepare common MS IOCB */
1769                 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GFPN_ID_REQ_SIZE,
1770                     GFPN_ID_RSP_SIZE);
1771
1772                 /* Prepare CT request */
1773                 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFPN_ID_CMD,
1774                     GFPN_ID_RSP_SIZE);
1775                 ct_rsp = &ha->ct_sns->p.rsp;
1776
1777                 /* Prepare CT arguments -- port_id */
1778                 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
1779                 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
1780                 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
1781
1782                 /* Execute MS IOCB */
1783                 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1784                     sizeof(ms_iocb_entry_t));
1785                 if (rval != QLA_SUCCESS) {
1786                         /*EMPTY*/
1787                         ql_dbg(ql_dbg_disc, vha, 0x2023,
1788                             "GFPN_ID issue IOCB failed (%d).\n", rval);
1789                         break;
1790                 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
1791                     "GFPN_ID") != QLA_SUCCESS) {
1792                         rval = QLA_FUNCTION_FAILED;
1793                         break;
1794                 } else {
1795                         /* Save fabric portname */
1796                         memcpy(list[i].fabric_port_name,
1797                             ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE);
1798                 }
1799
1800                 /* Last device exit. */
1801                 if (list[i].d_id.b.rsvd_1 != 0)
1802                         break;
1803         }
1804
1805         return (rval);
1806 }
1807
1808 static inline void *
1809 qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *vha, uint32_t req_size,
1810     uint32_t rsp_size)
1811 {
1812         struct ct_entry_24xx *ct_pkt;
1813         struct qla_hw_data *ha = vha->hw;
1814         ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
1815         memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
1816
1817         ct_pkt->entry_type = CT_IOCB_TYPE;
1818         ct_pkt->entry_count = 1;
1819         ct_pkt->nport_handle = cpu_to_le16(vha->mgmt_svr_loop_id);
1820         ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
1821         ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
1822         ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
1823         ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
1824         ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
1825
1826         ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1827         ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1828         ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
1829
1830         ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1831         ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1832         ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
1833         ct_pkt->vp_index = vha->vp_idx;
1834
1835         return ct_pkt;
1836 }
1837
1838
1839 static inline struct ct_sns_req *
1840 qla24xx_prep_ct_fm_req(struct ct_sns_req *ct_req, uint16_t cmd,
1841     uint16_t rsp_size)
1842 {
1843         memset(ct_req, 0, sizeof(struct ct_sns_pkt));
1844
1845         ct_req->header.revision = 0x01;
1846         ct_req->header.gs_type = 0xFA;
1847         ct_req->header.gs_subtype = 0x01;
1848         ct_req->command = cpu_to_be16(cmd);
1849         ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
1850
1851         return ct_req;
1852 }
1853
1854 /**
1855  * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query.
1856  * @ha: HA context
1857  * @list: switch info entries to populate
1858  *
1859  * Returns 0 on success.
1860  */
1861 int
1862 qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list)
1863 {
1864         int             rval;
1865         uint16_t        i;
1866         struct qla_hw_data *ha = vha->hw;
1867         ms_iocb_entry_t *ms_pkt;
1868         struct ct_sns_req       *ct_req;
1869         struct ct_sns_rsp       *ct_rsp;
1870
1871         if (!IS_IIDMA_CAPABLE(ha))
1872                 return QLA_FUNCTION_FAILED;
1873         if (!ha->flags.gpsc_supported)
1874                 return QLA_FUNCTION_FAILED;
1875
1876         rval = qla2x00_mgmt_svr_login(vha);
1877         if (rval)
1878                 return rval;
1879
1880         for (i = 0; i < ha->max_fibre_devices; i++) {
1881                 /* Issue GFPN_ID */
1882                 /* Prepare common MS IOCB */
1883                 ms_pkt = qla24xx_prep_ms_fm_iocb(vha, GPSC_REQ_SIZE,
1884                     GPSC_RSP_SIZE);
1885
1886                 /* Prepare CT request */
1887                 ct_req = qla24xx_prep_ct_fm_req(&ha->ct_sns->p.req,
1888                     GPSC_CMD, GPSC_RSP_SIZE);
1889                 ct_rsp = &ha->ct_sns->p.rsp;
1890
1891                 /* Prepare CT arguments -- port_name */
1892                 memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name,
1893                     WWN_SIZE);
1894
1895                 /* Execute MS IOCB */
1896                 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1897                     sizeof(ms_iocb_entry_t));
1898                 if (rval != QLA_SUCCESS) {
1899                         /*EMPTY*/
1900                         ql_dbg(ql_dbg_disc, vha, 0x2059,
1901                             "GPSC issue IOCB failed (%d).\n", rval);
1902                 } else if ((rval = qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
1903                     "GPSC")) != QLA_SUCCESS) {
1904                         /* FM command unsupported? */
1905                         if (rval == QLA_INVALID_COMMAND &&
1906                             (ct_rsp->header.reason_code ==
1907                                 CT_REASON_INVALID_COMMAND_CODE ||
1908                              ct_rsp->header.reason_code ==
1909                                 CT_REASON_COMMAND_UNSUPPORTED)) {
1910                                 ql_dbg(ql_dbg_disc, vha, 0x205a,
1911                                     "GPSC command unsupported, disabling "
1912                                     "query.\n");
1913                                 ha->flags.gpsc_supported = 0;
1914                                 rval = QLA_FUNCTION_FAILED;
1915                                 break;
1916                         }
1917                         rval = QLA_FUNCTION_FAILED;
1918                 } else {
1919                         /* Save port-speed */
1920                         switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) {
1921                         case BIT_15:
1922                                 list[i].fp_speed = PORT_SPEED_1GB;
1923                                 break;
1924                         case BIT_14:
1925                                 list[i].fp_speed = PORT_SPEED_2GB;
1926                                 break;
1927                         case BIT_13:
1928                                 list[i].fp_speed = PORT_SPEED_4GB;
1929                                 break;
1930                         case BIT_12:
1931                                 list[i].fp_speed = PORT_SPEED_10GB;
1932                                 break;
1933                         case BIT_11:
1934                                 list[i].fp_speed = PORT_SPEED_8GB;
1935                                 break;
1936                         case BIT_10:
1937                                 list[i].fp_speed = PORT_SPEED_16GB;
1938                                 break;
1939                         }
1940
1941                         ql_dbg(ql_dbg_disc, vha, 0x205b,
1942                             "GPSC ext entry - fpn "
1943                             "%02x%02x%02x%02x%02x%02x%02x%02x speeds=%04x "
1944                             "speed=%04x.\n",
1945                             list[i].fabric_port_name[0],
1946                             list[i].fabric_port_name[1],
1947                             list[i].fabric_port_name[2],
1948                             list[i].fabric_port_name[3],
1949                             list[i].fabric_port_name[4],
1950                             list[i].fabric_port_name[5],
1951                             list[i].fabric_port_name[6],
1952                             list[i].fabric_port_name[7],
1953                             be16_to_cpu(ct_rsp->rsp.gpsc.speeds),
1954                             be16_to_cpu(ct_rsp->rsp.gpsc.speed));
1955                 }
1956
1957                 /* Last device exit. */
1958                 if (list[i].d_id.b.rsvd_1 != 0)
1959                         break;
1960         }
1961
1962         return (rval);
1963 }
1964
1965 /**
1966  * qla2x00_gff_id() - SNS Get FC-4 Features (GFF_ID) query.
1967  *
1968  * @ha: HA context
1969  * @list: switch info entries to populate
1970  *
1971  */
1972 void
1973 qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list)
1974 {
1975         int             rval;
1976         uint16_t        i;
1977
1978         ms_iocb_entry_t *ms_pkt;
1979         struct ct_sns_req       *ct_req;
1980         struct ct_sns_rsp       *ct_rsp;
1981         struct qla_hw_data *ha = vha->hw;
1982         uint8_t fcp_scsi_features = 0;
1983
1984         for (i = 0; i < ha->max_fibre_devices; i++) {
1985                 /* Set default FC4 Type as UNKNOWN so the default is to
1986                  * Process this port */
1987                 list[i].fc4_type = FC4_TYPE_UNKNOWN;
1988
1989                 /* Do not attempt GFF_ID if we are not FWI_2 capable */
1990                 if (!IS_FWI2_CAPABLE(ha))
1991                         continue;
1992
1993                 /* Prepare common MS IOCB */
1994                 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GFF_ID_REQ_SIZE,
1995                     GFF_ID_RSP_SIZE);
1996
1997                 /* Prepare CT request */
1998                 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFF_ID_CMD,
1999                     GFF_ID_RSP_SIZE);
2000                 ct_rsp = &ha->ct_sns->p.rsp;
2001
2002                 /* Prepare CT arguments -- port_id */
2003                 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
2004                 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
2005                 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
2006
2007                 /* Execute MS IOCB */
2008                 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
2009                    sizeof(ms_iocb_entry_t));
2010
2011                 if (rval != QLA_SUCCESS) {
2012                         ql_dbg(ql_dbg_disc, vha, 0x205c,
2013                             "GFF_ID issue IOCB failed (%d).\n", rval);
2014                 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
2015                                "GFF_ID") != QLA_SUCCESS) {
2016                         ql_dbg(ql_dbg_disc, vha, 0x205d,
2017                             "GFF_ID IOCB status had a failure status code.\n");
2018                 } else {
2019                         fcp_scsi_features =
2020                            ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
2021                         fcp_scsi_features &= 0x0f;
2022
2023                         if (fcp_scsi_features)
2024                                 list[i].fc4_type = FC4_TYPE_FCP_SCSI;
2025                         else
2026                                 list[i].fc4_type = FC4_TYPE_OTHER;
2027                 }
2028
2029                 /* Last device exit. */
2030                 if (list[i].d_id.b.rsvd_1 != 0)
2031                         break;
2032         }
2033 }