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