Merge remote-tracking branch 'linusw-gpio/for-next' into devm_gpiochip
[linux-2.6-block.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 #include <linux/utsname.h>
10
11 static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *);
12 static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *);
13 static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *);
14 static int qla2x00_sns_gnn_id(scsi_qla_host_t *, sw_info_t *);
15 static int qla2x00_sns_rft_id(scsi_qla_host_t *);
16 static int qla2x00_sns_rnn_id(scsi_qla_host_t *);
17
18 /**
19  * qla2x00_prep_ms_iocb() - Prepare common MS/CT IOCB fields for SNS CT query.
20  * @ha: HA context
21  * @req_size: request size in bytes
22  * @rsp_size: response size in bytes
23  *
24  * Returns a pointer to the @ha's ms_iocb.
25  */
26 void *
27 qla2x00_prep_ms_iocb(scsi_qla_host_t *vha, uint32_t req_size, uint32_t rsp_size)
28 {
29         struct qla_hw_data *ha = vha->hw;
30         ms_iocb_entry_t *ms_pkt;
31
32         ms_pkt = ha->ms_iocb;
33         memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
34
35         ms_pkt->entry_type = MS_IOCB_TYPE;
36         ms_pkt->entry_count = 1;
37         SET_TARGET_ID(ha, ms_pkt->loop_id, SIMPLE_NAME_SERVER);
38         ms_pkt->control_flags = cpu_to_le16(CF_READ | CF_HEAD_TAG);
39         ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
40         ms_pkt->cmd_dsd_count = cpu_to_le16(1);
41         ms_pkt->total_dsd_count = cpu_to_le16(2);
42         ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
43         ms_pkt->req_bytecount = cpu_to_le32(req_size);
44
45         ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
46         ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
47         ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
48
49         ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
50         ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
51         ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount;
52
53         vha->qla_stats.control_requests++;
54
55         return (ms_pkt);
56 }
57
58 /**
59  * qla24xx_prep_ms_iocb() - Prepare common CT IOCB fields for SNS CT query.
60  * @ha: HA context
61  * @req_size: request size in bytes
62  * @rsp_size: response size in bytes
63  *
64  * Returns a pointer to the @ha's ms_iocb.
65  */
66 void *
67 qla24xx_prep_ms_iocb(scsi_qla_host_t *vha, uint32_t req_size, uint32_t rsp_size)
68 {
69         struct qla_hw_data *ha = vha->hw;
70         struct ct_entry_24xx *ct_pkt;
71
72         ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
73         memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
74
75         ct_pkt->entry_type = CT_IOCB_TYPE;
76         ct_pkt->entry_count = 1;
77         ct_pkt->nport_handle = cpu_to_le16(NPH_SNS);
78         ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
79         ct_pkt->cmd_dsd_count = cpu_to_le16(1);
80         ct_pkt->rsp_dsd_count = cpu_to_le16(1);
81         ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
82         ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
83
84         ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
85         ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
86         ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
87
88         ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
89         ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
90         ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
91         ct_pkt->vp_index = vha->vp_idx;
92
93         vha->qla_stats.control_requests++;
94
95         return (ct_pkt);
96 }
97
98 /**
99  * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
100  * @ct_req: CT request buffer
101  * @cmd: GS command
102  * @rsp_size: response size in bytes
103  *
104  * Returns a pointer to the intitialized @ct_req.
105  */
106 static inline struct ct_sns_req *
107 qla2x00_prep_ct_req(struct ct_sns_pkt *p, uint16_t cmd, uint16_t rsp_size)
108 {
109         memset(p, 0, sizeof(struct ct_sns_pkt));
110
111         p->p.req.header.revision = 0x01;
112         p->p.req.header.gs_type = 0xFC;
113         p->p.req.header.gs_subtype = 0x02;
114         p->p.req.command = cpu_to_be16(cmd);
115         p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
116
117         return &p->p.req;
118 }
119
120 static int
121 qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt,
122     struct ct_sns_rsp *ct_rsp, const char *routine)
123 {
124         int rval;
125         uint16_t comp_status;
126         struct qla_hw_data *ha = vha->hw;
127
128         rval = QLA_FUNCTION_FAILED;
129         if (ms_pkt->entry_status != 0) {
130                 ql_dbg(ql_dbg_disc, vha, 0x2031,
131                     "%s failed, error status (%x) on port_id: %02x%02x%02x.\n",
132                     routine, ms_pkt->entry_status, vha->d_id.b.domain,
133                     vha->d_id.b.area, vha->d_id.b.al_pa);
134         } else {
135                 if (IS_FWI2_CAPABLE(ha))
136                         comp_status = le16_to_cpu(
137                             ((struct ct_entry_24xx *)ms_pkt)->comp_status);
138                 else
139                         comp_status = le16_to_cpu(ms_pkt->status);
140                 switch (comp_status) {
141                 case CS_COMPLETE:
142                 case CS_DATA_UNDERRUN:
143                 case CS_DATA_OVERRUN:           /* Overrun? */
144                         if (ct_rsp->header.response !=
145                             cpu_to_be16(CT_ACCEPT_RESPONSE)) {
146                                 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2077,
147                                     "%s failed rejected request on port_id: %02x%02x%02x Compeltion status 0x%x, response 0x%x\n",
148                                     routine, vha->d_id.b.domain,
149                                     vha->d_id.b.area, vha->d_id.b.al_pa,
150                                     comp_status, ct_rsp->header.response);
151                                 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha,
152                                     0x2078, (uint8_t *)&ct_rsp->header,
153                                     sizeof(struct ct_rsp_hdr));
154                                 rval = QLA_INVALID_COMMAND;
155                         } else
156                                 rval = QLA_SUCCESS;
157                         break;
158                 default:
159                         ql_dbg(ql_dbg_disc, vha, 0x2033,
160                             "%s failed, completion status (%x) on port_id: "
161                             "%02x%02x%02x.\n", routine, comp_status,
162                             vha->d_id.b.domain, vha->d_id.b.area,
163                             vha->d_id.b.al_pa);
164                         break;
165                 }
166         }
167         return rval;
168 }
169
170 /**
171  * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
172  * @ha: HA context
173  * @fcport: fcport entry to updated
174  *
175  * Returns 0 on success.
176  */
177 int
178 qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
179 {
180         int             rval;
181
182         ms_iocb_entry_t *ms_pkt;
183         struct ct_sns_req       *ct_req;
184         struct ct_sns_rsp       *ct_rsp;
185         struct qla_hw_data *ha = vha->hw;
186
187         if (IS_QLA2100(ha) || IS_QLA2200(ha))
188                 return qla2x00_sns_ga_nxt(vha, fcport);
189
190         /* Issue GA_NXT */
191         /* Prepare common MS IOCB */
192         ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GA_NXT_REQ_SIZE,
193             GA_NXT_RSP_SIZE);
194
195         /* Prepare CT request */
196         ct_req = qla2x00_prep_ct_req(ha->ct_sns, GA_NXT_CMD,
197             GA_NXT_RSP_SIZE);
198         ct_rsp = &ha->ct_sns->p.rsp;
199
200         /* Prepare CT arguments -- port_id */
201         ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain;
202         ct_req->req.port_id.port_id[1] = fcport->d_id.b.area;
203         ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa;
204
205         /* Execute MS IOCB */
206         rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
207             sizeof(ms_iocb_entry_t));
208         if (rval != QLA_SUCCESS) {
209                 /*EMPTY*/
210                 ql_dbg(ql_dbg_disc, vha, 0x2062,
211                     "GA_NXT issue IOCB failed (%d).\n", rval);
212         } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GA_NXT") !=
213             QLA_SUCCESS) {
214                 rval = QLA_FUNCTION_FAILED;
215         } else {
216                 /* Populate fc_port_t entry. */
217                 fcport->d_id.b.domain = ct_rsp->rsp.ga_nxt.port_id[0];
218                 fcport->d_id.b.area = ct_rsp->rsp.ga_nxt.port_id[1];
219                 fcport->d_id.b.al_pa = ct_rsp->rsp.ga_nxt.port_id[2];
220
221                 memcpy(fcport->node_name, ct_rsp->rsp.ga_nxt.node_name,
222                     WWN_SIZE);
223                 memcpy(fcport->port_name, ct_rsp->rsp.ga_nxt.port_name,
224                     WWN_SIZE);
225
226                 fcport->fc4_type = (ct_rsp->rsp.ga_nxt.fc4_types[2] & BIT_0) ?
227                     FC4_TYPE_FCP_SCSI : FC4_TYPE_OTHER;
228
229                 if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE &&
230                     ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE)
231                         fcport->d_id.b.domain = 0xf0;
232
233                 ql_dbg(ql_dbg_disc, vha, 0x2063,
234                     "GA_NXT entry - nn %8phN pn %8phN "
235                     "port_id=%02x%02x%02x.\n",
236                     fcport->node_name, fcport->port_name,
237                     fcport->d_id.b.domain, fcport->d_id.b.area,
238                     fcport->d_id.b.al_pa);
239         }
240
241         return (rval);
242 }
243
244 static inline int
245 qla2x00_gid_pt_rsp_size(scsi_qla_host_t *vha)
246 {
247         return vha->hw->max_fibre_devices * 4 + 16;
248 }
249
250 /**
251  * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command.
252  * @ha: HA context
253  * @list: switch info entries to populate
254  *
255  * NOTE: Non-Nx_Ports are not requested.
256  *
257  * Returns 0 on success.
258  */
259 int
260 qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
261 {
262         int             rval;
263         uint16_t        i;
264
265         ms_iocb_entry_t *ms_pkt;
266         struct ct_sns_req       *ct_req;
267         struct ct_sns_rsp       *ct_rsp;
268
269         struct ct_sns_gid_pt_data *gid_data;
270         struct qla_hw_data *ha = vha->hw;
271         uint16_t gid_pt_rsp_size;
272
273         if (IS_QLA2100(ha) || IS_QLA2200(ha))
274                 return qla2x00_sns_gid_pt(vha, list);
275
276         gid_data = NULL;
277         gid_pt_rsp_size = qla2x00_gid_pt_rsp_size(vha);
278         /* Issue GID_PT */
279         /* Prepare common MS IOCB */
280         ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GID_PT_REQ_SIZE,
281             gid_pt_rsp_size);
282
283         /* Prepare CT request */
284         ct_req = qla2x00_prep_ct_req(ha->ct_sns, GID_PT_CMD, gid_pt_rsp_size);
285         ct_rsp = &ha->ct_sns->p.rsp;
286
287         /* Prepare CT arguments -- port_type */
288         ct_req->req.gid_pt.port_type = NS_NX_PORT_TYPE;
289
290         /* Execute MS IOCB */
291         rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
292             sizeof(ms_iocb_entry_t));
293         if (rval != QLA_SUCCESS) {
294                 /*EMPTY*/
295                 ql_dbg(ql_dbg_disc, vha, 0x2055,
296                     "GID_PT issue IOCB failed (%d).\n", rval);
297         } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GID_PT") !=
298             QLA_SUCCESS) {
299                 rval = QLA_FUNCTION_FAILED;
300         } else {
301                 /* Set port IDs in switch info list. */
302                 for (i = 0; i < ha->max_fibre_devices; i++) {
303                         gid_data = &ct_rsp->rsp.gid_pt.entries[i];
304                         list[i].d_id.b.domain = gid_data->port_id[0];
305                         list[i].d_id.b.area = gid_data->port_id[1];
306                         list[i].d_id.b.al_pa = gid_data->port_id[2];
307                         memset(list[i].fabric_port_name, 0, WWN_SIZE);
308                         list[i].fp_speed = PORT_SPEED_UNKNOWN;
309
310                         /* Last one exit. */
311                         if (gid_data->control_byte & BIT_7) {
312                                 list[i].d_id.b.rsvd_1 = gid_data->control_byte;
313                                 break;
314                         }
315                 }
316
317                 /*
318                  * If we've used all available slots, then the switch is
319                  * reporting back more devices than we can handle with this
320                  * single call.  Return a failed status, and let GA_NXT handle
321                  * the overload.
322                  */
323                 if (i == ha->max_fibre_devices)
324                         rval = QLA_FUNCTION_FAILED;
325         }
326
327         return (rval);
328 }
329
330 /**
331  * qla2x00_gpn_id() - SNS Get Port Name (GPN_ID) query.
332  * @ha: HA context
333  * @list: switch info entries to populate
334  *
335  * Returns 0 on success.
336  */
337 int
338 qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
339 {
340         int             rval = QLA_SUCCESS;
341         uint16_t        i;
342
343         ms_iocb_entry_t *ms_pkt;
344         struct ct_sns_req       *ct_req;
345         struct ct_sns_rsp       *ct_rsp;
346         struct qla_hw_data *ha = vha->hw;
347
348         if (IS_QLA2100(ha) || IS_QLA2200(ha))
349                 return qla2x00_sns_gpn_id(vha, list);
350
351         for (i = 0; i < ha->max_fibre_devices; i++) {
352                 /* Issue GPN_ID */
353                 /* Prepare common MS IOCB */
354                 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GPN_ID_REQ_SIZE,
355                     GPN_ID_RSP_SIZE);
356
357                 /* Prepare CT request */
358                 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GPN_ID_CMD,
359                     GPN_ID_RSP_SIZE);
360                 ct_rsp = &ha->ct_sns->p.rsp;
361
362                 /* Prepare CT arguments -- port_id */
363                 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
364                 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
365                 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
366
367                 /* Execute MS IOCB */
368                 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
369                     sizeof(ms_iocb_entry_t));
370                 if (rval != QLA_SUCCESS) {
371                         /*EMPTY*/
372                         ql_dbg(ql_dbg_disc, vha, 0x2056,
373                             "GPN_ID issue IOCB failed (%d).\n", rval);
374                         break;
375                 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
376                     "GPN_ID") != QLA_SUCCESS) {
377                         rval = QLA_FUNCTION_FAILED;
378                         break;
379                 } else {
380                         /* Save portname */
381                         memcpy(list[i].port_name,
382                             ct_rsp->rsp.gpn_id.port_name, WWN_SIZE);
383                 }
384
385                 /* Last device exit. */
386                 if (list[i].d_id.b.rsvd_1 != 0)
387                         break;
388         }
389
390         return (rval);
391 }
392
393 /**
394  * qla2x00_gnn_id() - SNS Get Node Name (GNN_ID) query.
395  * @ha: HA context
396  * @list: switch info entries to populate
397  *
398  * Returns 0 on success.
399  */
400 int
401 qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
402 {
403         int             rval = QLA_SUCCESS;
404         uint16_t        i;
405         struct qla_hw_data *ha = vha->hw;
406         ms_iocb_entry_t *ms_pkt;
407         struct ct_sns_req       *ct_req;
408         struct ct_sns_rsp       *ct_rsp;
409
410         if (IS_QLA2100(ha) || IS_QLA2200(ha))
411                 return qla2x00_sns_gnn_id(vha, list);
412
413         for (i = 0; i < ha->max_fibre_devices; i++) {
414                 /* Issue GNN_ID */
415                 /* Prepare common MS IOCB */
416                 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GNN_ID_REQ_SIZE,
417                     GNN_ID_RSP_SIZE);
418
419                 /* Prepare CT request */
420                 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GNN_ID_CMD,
421                     GNN_ID_RSP_SIZE);
422                 ct_rsp = &ha->ct_sns->p.rsp;
423
424                 /* Prepare CT arguments -- port_id */
425                 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
426                 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
427                 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
428
429                 /* Execute MS IOCB */
430                 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
431                     sizeof(ms_iocb_entry_t));
432                 if (rval != QLA_SUCCESS) {
433                         /*EMPTY*/
434                         ql_dbg(ql_dbg_disc, vha, 0x2057,
435                             "GNN_ID issue IOCB failed (%d).\n", rval);
436                         break;
437                 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
438                     "GNN_ID") != QLA_SUCCESS) {
439                         rval = QLA_FUNCTION_FAILED;
440                         break;
441                 } else {
442                         /* Save nodename */
443                         memcpy(list[i].node_name,
444                             ct_rsp->rsp.gnn_id.node_name, WWN_SIZE);
445
446                         ql_dbg(ql_dbg_disc, vha, 0x2058,
447                             "GID_PT entry - nn %8phN pn %8phN "
448                             "portid=%02x%02x%02x.\n",
449                             list[i].node_name, list[i].port_name,
450                             list[i].d_id.b.domain, list[i].d_id.b.area,
451                             list[i].d_id.b.al_pa);
452                 }
453
454                 /* Last device exit. */
455                 if (list[i].d_id.b.rsvd_1 != 0)
456                         break;
457         }
458
459         return (rval);
460 }
461
462 /**
463  * qla2x00_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
464  * @ha: HA context
465  *
466  * Returns 0 on success.
467  */
468 int
469 qla2x00_rft_id(scsi_qla_host_t *vha)
470 {
471         int             rval;
472         struct qla_hw_data *ha = vha->hw;
473         ms_iocb_entry_t *ms_pkt;
474         struct ct_sns_req       *ct_req;
475         struct ct_sns_rsp       *ct_rsp;
476
477         if (IS_QLA2100(ha) || IS_QLA2200(ha))
478                 return qla2x00_sns_rft_id(vha);
479
480         /* Issue RFT_ID */
481         /* Prepare common MS IOCB */
482         ms_pkt = ha->isp_ops->prep_ms_iocb(vha, RFT_ID_REQ_SIZE,
483             RFT_ID_RSP_SIZE);
484
485         /* Prepare CT request */
486         ct_req = qla2x00_prep_ct_req(ha->ct_sns, RFT_ID_CMD,
487             RFT_ID_RSP_SIZE);
488         ct_rsp = &ha->ct_sns->p.rsp;
489
490         /* Prepare CT arguments -- port_id, FC-4 types */
491         ct_req->req.rft_id.port_id[0] = vha->d_id.b.domain;
492         ct_req->req.rft_id.port_id[1] = vha->d_id.b.area;
493         ct_req->req.rft_id.port_id[2] = vha->d_id.b.al_pa;
494
495         ct_req->req.rft_id.fc4_types[2] = 0x01;         /* FCP-3 */
496
497         /* Execute MS IOCB */
498         rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
499             sizeof(ms_iocb_entry_t));
500         if (rval != QLA_SUCCESS) {
501                 /*EMPTY*/
502                 ql_dbg(ql_dbg_disc, vha, 0x2043,
503                     "RFT_ID issue IOCB failed (%d).\n", rval);
504         } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RFT_ID") !=
505             QLA_SUCCESS) {
506                 rval = QLA_FUNCTION_FAILED;
507         } else {
508                 ql_dbg(ql_dbg_disc, vha, 0x2044,
509                     "RFT_ID exiting normally.\n");
510         }
511
512         return (rval);
513 }
514
515 /**
516  * qla2x00_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the HBA.
517  * @ha: HA context
518  *
519  * Returns 0 on success.
520  */
521 int
522 qla2x00_rff_id(scsi_qla_host_t *vha)
523 {
524         int             rval;
525         struct qla_hw_data *ha = vha->hw;
526         ms_iocb_entry_t *ms_pkt;
527         struct ct_sns_req       *ct_req;
528         struct ct_sns_rsp       *ct_rsp;
529
530         if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
531                 ql_dbg(ql_dbg_disc, vha, 0x2046,
532                     "RFF_ID call not supported on ISP2100/ISP2200.\n");
533                 return (QLA_SUCCESS);
534         }
535
536         /* Issue RFF_ID */
537         /* Prepare common MS IOCB */
538         ms_pkt = ha->isp_ops->prep_ms_iocb(vha, RFF_ID_REQ_SIZE,
539             RFF_ID_RSP_SIZE);
540
541         /* Prepare CT request */
542         ct_req = qla2x00_prep_ct_req(ha->ct_sns, RFF_ID_CMD,
543             RFF_ID_RSP_SIZE);
544         ct_rsp = &ha->ct_sns->p.rsp;
545
546         /* Prepare CT arguments -- port_id, FC-4 feature, FC-4 type */
547         ct_req->req.rff_id.port_id[0] = vha->d_id.b.domain;
548         ct_req->req.rff_id.port_id[1] = vha->d_id.b.area;
549         ct_req->req.rff_id.port_id[2] = vha->d_id.b.al_pa;
550
551         qlt_rff_id(vha, ct_req);
552
553         ct_req->req.rff_id.fc4_type = 0x08;             /* SCSI - FCP */
554
555         /* Execute MS IOCB */
556         rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
557             sizeof(ms_iocb_entry_t));
558         if (rval != QLA_SUCCESS) {
559                 /*EMPTY*/
560                 ql_dbg(ql_dbg_disc, vha, 0x2047,
561                     "RFF_ID issue IOCB failed (%d).\n", rval);
562         } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RFF_ID") !=
563             QLA_SUCCESS) {
564                 rval = QLA_FUNCTION_FAILED;
565         } else {
566                 ql_dbg(ql_dbg_disc, vha, 0x2048,
567                     "RFF_ID exiting normally.\n");
568         }
569
570         return (rval);
571 }
572
573 /**
574  * qla2x00_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
575  * @ha: HA context
576  *
577  * Returns 0 on success.
578  */
579 int
580 qla2x00_rnn_id(scsi_qla_host_t *vha)
581 {
582         int             rval;
583         struct qla_hw_data *ha = vha->hw;
584         ms_iocb_entry_t *ms_pkt;
585         struct ct_sns_req       *ct_req;
586         struct ct_sns_rsp       *ct_rsp;
587
588         if (IS_QLA2100(ha) || IS_QLA2200(ha))
589                 return qla2x00_sns_rnn_id(vha);
590
591         /* Issue RNN_ID */
592         /* Prepare common MS IOCB */
593         ms_pkt = ha->isp_ops->prep_ms_iocb(vha, RNN_ID_REQ_SIZE,
594             RNN_ID_RSP_SIZE);
595
596         /* Prepare CT request */
597         ct_req = qla2x00_prep_ct_req(ha->ct_sns, RNN_ID_CMD, RNN_ID_RSP_SIZE);
598         ct_rsp = &ha->ct_sns->p.rsp;
599
600         /* Prepare CT arguments -- port_id, node_name */
601         ct_req->req.rnn_id.port_id[0] = vha->d_id.b.domain;
602         ct_req->req.rnn_id.port_id[1] = vha->d_id.b.area;
603         ct_req->req.rnn_id.port_id[2] = vha->d_id.b.al_pa;
604
605         memcpy(ct_req->req.rnn_id.node_name, vha->node_name, WWN_SIZE);
606
607         /* Execute MS IOCB */
608         rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
609             sizeof(ms_iocb_entry_t));
610         if (rval != QLA_SUCCESS) {
611                 /*EMPTY*/
612                 ql_dbg(ql_dbg_disc, vha, 0x204d,
613                     "RNN_ID issue IOCB failed (%d).\n", rval);
614         } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RNN_ID") !=
615             QLA_SUCCESS) {
616                 rval = QLA_FUNCTION_FAILED;
617         } else {
618                 ql_dbg(ql_dbg_disc, vha, 0x204e,
619                     "RNN_ID exiting normally.\n");
620         }
621
622         return (rval);
623 }
624
625 void
626 qla2x00_get_sym_node_name(scsi_qla_host_t *vha, uint8_t *snn, size_t size)
627 {
628         struct qla_hw_data *ha = vha->hw;
629
630         if (IS_QLAFX00(ha))
631                 snprintf(snn, size, "%s FW:v%s DVR:v%s", ha->model_number,
632                     ha->mr.fw_version, qla2x00_version_str);
633         else
634                 snprintf(snn, size,
635                     "%s FW:v%d.%02d.%02d DVR:v%s", ha->model_number,
636                     ha->fw_major_version, ha->fw_minor_version,
637                     ha->fw_subminor_version, qla2x00_version_str);
638 }
639
640 /**
641  * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA.
642  * @ha: HA context
643  *
644  * Returns 0 on success.
645  */
646 int
647 qla2x00_rsnn_nn(scsi_qla_host_t *vha)
648 {
649         int             rval;
650         struct qla_hw_data *ha = vha->hw;
651         ms_iocb_entry_t *ms_pkt;
652         struct ct_sns_req       *ct_req;
653         struct ct_sns_rsp       *ct_rsp;
654
655         if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
656                 ql_dbg(ql_dbg_disc, vha, 0x2050,
657                     "RSNN_ID call unsupported on ISP2100/ISP2200.\n");
658                 return (QLA_SUCCESS);
659         }
660
661         /* Issue RSNN_NN */
662         /* Prepare common MS IOCB */
663         /*   Request size adjusted after CT preparation */
664         ms_pkt = ha->isp_ops->prep_ms_iocb(vha, 0, RSNN_NN_RSP_SIZE);
665
666         /* Prepare CT request */
667         ct_req = qla2x00_prep_ct_req(ha->ct_sns, RSNN_NN_CMD,
668             RSNN_NN_RSP_SIZE);
669         ct_rsp = &ha->ct_sns->p.rsp;
670
671         /* Prepare CT arguments -- node_name, symbolic node_name, size */
672         memcpy(ct_req->req.rsnn_nn.node_name, vha->node_name, WWN_SIZE);
673
674         /* Prepare the Symbolic Node Name */
675         qla2x00_get_sym_node_name(vha, ct_req->req.rsnn_nn.sym_node_name,
676             sizeof(ct_req->req.rsnn_nn.sym_node_name));
677
678         /* Calculate SNN length */
679         ct_req->req.rsnn_nn.name_len =
680             (uint8_t)strlen(ct_req->req.rsnn_nn.sym_node_name);
681
682         /* Update MS IOCB request */
683         ms_pkt->req_bytecount =
684             cpu_to_le32(24 + 1 + ct_req->req.rsnn_nn.name_len);
685         ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
686
687         /* Execute MS IOCB */
688         rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
689             sizeof(ms_iocb_entry_t));
690         if (rval != QLA_SUCCESS) {
691                 /*EMPTY*/
692                 ql_dbg(ql_dbg_disc, vha, 0x2051,
693                     "RSNN_NN issue IOCB failed (%d).\n", rval);
694         } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RSNN_NN") !=
695             QLA_SUCCESS) {
696                 rval = QLA_FUNCTION_FAILED;
697         } else {
698                 ql_dbg(ql_dbg_disc, vha, 0x2052,
699                     "RSNN_NN exiting normally.\n");
700         }
701
702         return (rval);
703 }
704
705 /**
706  * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query.
707  * @ha: HA context
708  * @cmd: GS command
709  * @scmd_len: Subcommand length
710  * @data_size: response size in bytes
711  *
712  * Returns a pointer to the @ha's sns_cmd.
713  */
714 static inline struct sns_cmd_pkt *
715 qla2x00_prep_sns_cmd(scsi_qla_host_t *vha, uint16_t cmd, uint16_t scmd_len,
716     uint16_t data_size)
717 {
718         uint16_t                wc;
719         struct sns_cmd_pkt      *sns_cmd;
720         struct qla_hw_data *ha = vha->hw;
721
722         sns_cmd = ha->sns_cmd;
723         memset(sns_cmd, 0, sizeof(struct sns_cmd_pkt));
724         wc = data_size / 2;                     /* Size in 16bit words. */
725         sns_cmd->p.cmd.buffer_length = cpu_to_le16(wc);
726         sns_cmd->p.cmd.buffer_address[0] = cpu_to_le32(LSD(ha->sns_cmd_dma));
727         sns_cmd->p.cmd.buffer_address[1] = cpu_to_le32(MSD(ha->sns_cmd_dma));
728         sns_cmd->p.cmd.subcommand_length = cpu_to_le16(scmd_len);
729         sns_cmd->p.cmd.subcommand = cpu_to_le16(cmd);
730         wc = (data_size - 16) / 4;              /* Size in 32bit words. */
731         sns_cmd->p.cmd.size = cpu_to_le16(wc);
732
733         vha->qla_stats.control_requests++;
734
735         return (sns_cmd);
736 }
737
738 /**
739  * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
740  * @ha: HA context
741  * @fcport: fcport entry to updated
742  *
743  * This command uses the old Exectute SNS Command mailbox routine.
744  *
745  * Returns 0 on success.
746  */
747 static int
748 qla2x00_sns_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
749 {
750         int             rval = QLA_SUCCESS;
751         struct qla_hw_data *ha = vha->hw;
752         struct sns_cmd_pkt      *sns_cmd;
753
754         /* Issue GA_NXT. */
755         /* Prepare SNS command request. */
756         sns_cmd = qla2x00_prep_sns_cmd(vha, GA_NXT_CMD, GA_NXT_SNS_SCMD_LEN,
757             GA_NXT_SNS_DATA_SIZE);
758
759         /* Prepare SNS command arguments -- port_id. */
760         sns_cmd->p.cmd.param[0] = fcport->d_id.b.al_pa;
761         sns_cmd->p.cmd.param[1] = fcport->d_id.b.area;
762         sns_cmd->p.cmd.param[2] = fcport->d_id.b.domain;
763
764         /* Execute SNS command. */
765         rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GA_NXT_SNS_CMD_SIZE / 2,
766             sizeof(struct sns_cmd_pkt));
767         if (rval != QLA_SUCCESS) {
768                 /*EMPTY*/
769                 ql_dbg(ql_dbg_disc, vha, 0x205f,
770                     "GA_NXT Send SNS failed (%d).\n", rval);
771         } else if (sns_cmd->p.gan_data[8] != 0x80 ||
772             sns_cmd->p.gan_data[9] != 0x02) {
773                 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2084,
774                     "GA_NXT failed, rejected request ga_nxt_rsp:\n");
775                 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2074,
776                     sns_cmd->p.gan_data, 16);
777                 rval = QLA_FUNCTION_FAILED;
778         } else {
779                 /* Populate fc_port_t entry. */
780                 fcport->d_id.b.domain = sns_cmd->p.gan_data[17];
781                 fcport->d_id.b.area = sns_cmd->p.gan_data[18];
782                 fcport->d_id.b.al_pa = sns_cmd->p.gan_data[19];
783
784                 memcpy(fcport->node_name, &sns_cmd->p.gan_data[284], WWN_SIZE);
785                 memcpy(fcport->port_name, &sns_cmd->p.gan_data[20], WWN_SIZE);
786
787                 if (sns_cmd->p.gan_data[16] != NS_N_PORT_TYPE &&
788                     sns_cmd->p.gan_data[16] != NS_NL_PORT_TYPE)
789                         fcport->d_id.b.domain = 0xf0;
790
791                 ql_dbg(ql_dbg_disc, vha, 0x2061,
792                     "GA_NXT entry - nn %8phN pn %8phN "
793                     "port_id=%02x%02x%02x.\n",
794                     fcport->node_name, fcport->port_name,
795                     fcport->d_id.b.domain, fcport->d_id.b.area,
796                     fcport->d_id.b.al_pa);
797         }
798
799         return (rval);
800 }
801
802 /**
803  * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command.
804  * @ha: HA context
805  * @list: switch info entries to populate
806  *
807  * This command uses the old Exectute SNS Command mailbox routine.
808  *
809  * NOTE: Non-Nx_Ports are not requested.
810  *
811  * Returns 0 on success.
812  */
813 static int
814 qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
815 {
816         int             rval;
817         struct qla_hw_data *ha = vha->hw;
818         uint16_t        i;
819         uint8_t         *entry;
820         struct sns_cmd_pkt      *sns_cmd;
821         uint16_t gid_pt_sns_data_size;
822
823         gid_pt_sns_data_size = qla2x00_gid_pt_rsp_size(vha);
824
825         /* Issue GID_PT. */
826         /* Prepare SNS command request. */
827         sns_cmd = qla2x00_prep_sns_cmd(vha, GID_PT_CMD, GID_PT_SNS_SCMD_LEN,
828             gid_pt_sns_data_size);
829
830         /* Prepare SNS command arguments -- port_type. */
831         sns_cmd->p.cmd.param[0] = NS_NX_PORT_TYPE;
832
833         /* Execute SNS command. */
834         rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GID_PT_SNS_CMD_SIZE / 2,
835             sizeof(struct sns_cmd_pkt));
836         if (rval != QLA_SUCCESS) {
837                 /*EMPTY*/
838                 ql_dbg(ql_dbg_disc, vha, 0x206d,
839                     "GID_PT Send SNS failed (%d).\n", rval);
840         } else if (sns_cmd->p.gid_data[8] != 0x80 ||
841             sns_cmd->p.gid_data[9] != 0x02) {
842                 ql_dbg(ql_dbg_disc, vha, 0x202f,
843                     "GID_PT failed, rejected request, gid_rsp:\n");
844                 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2081,
845                     sns_cmd->p.gid_data, 16);
846                 rval = QLA_FUNCTION_FAILED;
847         } else {
848                 /* Set port IDs in switch info list. */
849                 for (i = 0; i < ha->max_fibre_devices; i++) {
850                         entry = &sns_cmd->p.gid_data[(i * 4) + 16];
851                         list[i].d_id.b.domain = entry[1];
852                         list[i].d_id.b.area = entry[2];
853                         list[i].d_id.b.al_pa = entry[3];
854
855                         /* Last one exit. */
856                         if (entry[0] & BIT_7) {
857                                 list[i].d_id.b.rsvd_1 = entry[0];
858                                 break;
859                         }
860                 }
861
862                 /*
863                  * If we've used all available slots, then the switch is
864                  * reporting back more devices that we can handle with this
865                  * single call.  Return a failed status, and let GA_NXT handle
866                  * the overload.
867                  */
868                 if (i == ha->max_fibre_devices)
869                         rval = QLA_FUNCTION_FAILED;
870         }
871
872         return (rval);
873 }
874
875 /**
876  * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query.
877  * @ha: HA context
878  * @list: switch info entries to populate
879  *
880  * This command uses the old Exectute SNS Command mailbox routine.
881  *
882  * Returns 0 on success.
883  */
884 static int
885 qla2x00_sns_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
886 {
887         int             rval = QLA_SUCCESS;
888         struct qla_hw_data *ha = vha->hw;
889         uint16_t        i;
890         struct sns_cmd_pkt      *sns_cmd;
891
892         for (i = 0; i < ha->max_fibre_devices; i++) {
893                 /* Issue GPN_ID */
894                 /* Prepare SNS command request. */
895                 sns_cmd = qla2x00_prep_sns_cmd(vha, GPN_ID_CMD,
896                     GPN_ID_SNS_SCMD_LEN, GPN_ID_SNS_DATA_SIZE);
897
898                 /* Prepare SNS command arguments -- port_id. */
899                 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa;
900                 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area;
901                 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain;
902
903                 /* Execute SNS command. */
904                 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma,
905                     GPN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt));
906                 if (rval != QLA_SUCCESS) {
907                         /*EMPTY*/
908                         ql_dbg(ql_dbg_disc, vha, 0x2032,
909                             "GPN_ID Send SNS failed (%d).\n", rval);
910                 } else if (sns_cmd->p.gpn_data[8] != 0x80 ||
911                     sns_cmd->p.gpn_data[9] != 0x02) {
912                         ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207e,
913                             "GPN_ID failed, rejected request, gpn_rsp:\n");
914                         ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207f,
915                             sns_cmd->p.gpn_data, 16);
916                         rval = QLA_FUNCTION_FAILED;
917                 } else {
918                         /* Save portname */
919                         memcpy(list[i].port_name, &sns_cmd->p.gpn_data[16],
920                             WWN_SIZE);
921                 }
922
923                 /* Last device exit. */
924                 if (list[i].d_id.b.rsvd_1 != 0)
925                         break;
926         }
927
928         return (rval);
929 }
930
931 /**
932  * qla2x00_sns_gnn_id() - SNS Get Node Name (GNN_ID) query.
933  * @ha: HA context
934  * @list: switch info entries to populate
935  *
936  * This command uses the old Exectute SNS Command mailbox routine.
937  *
938  * Returns 0 on success.
939  */
940 static int
941 qla2x00_sns_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
942 {
943         int             rval = QLA_SUCCESS;
944         struct qla_hw_data *ha = vha->hw;
945         uint16_t        i;
946         struct sns_cmd_pkt      *sns_cmd;
947
948         for (i = 0; i < ha->max_fibre_devices; i++) {
949                 /* Issue GNN_ID */
950                 /* Prepare SNS command request. */
951                 sns_cmd = qla2x00_prep_sns_cmd(vha, GNN_ID_CMD,
952                     GNN_ID_SNS_SCMD_LEN, GNN_ID_SNS_DATA_SIZE);
953
954                 /* Prepare SNS command arguments -- port_id. */
955                 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa;
956                 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area;
957                 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain;
958
959                 /* Execute SNS command. */
960                 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma,
961                     GNN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt));
962                 if (rval != QLA_SUCCESS) {
963                         /*EMPTY*/
964                         ql_dbg(ql_dbg_disc, vha, 0x203f,
965                             "GNN_ID Send SNS failed (%d).\n", rval);
966                 } else if (sns_cmd->p.gnn_data[8] != 0x80 ||
967                     sns_cmd->p.gnn_data[9] != 0x02) {
968                         ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2082,
969                             "GNN_ID failed, rejected request, gnn_rsp:\n");
970                         ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207a,
971                             sns_cmd->p.gnn_data, 16);
972                         rval = QLA_FUNCTION_FAILED;
973                 } else {
974                         /* Save nodename */
975                         memcpy(list[i].node_name, &sns_cmd->p.gnn_data[16],
976                             WWN_SIZE);
977
978                         ql_dbg(ql_dbg_disc, vha, 0x206e,
979                             "GID_PT entry - nn %8phN pn %8phN "
980                             "port_id=%02x%02x%02x.\n",
981                             list[i].node_name, list[i].port_name,
982                             list[i].d_id.b.domain, list[i].d_id.b.area,
983                             list[i].d_id.b.al_pa);
984                 }
985
986                 /* Last device exit. */
987                 if (list[i].d_id.b.rsvd_1 != 0)
988                         break;
989         }
990
991         return (rval);
992 }
993
994 /**
995  * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
996  * @ha: HA context
997  *
998  * This command uses the old Exectute SNS Command mailbox routine.
999  *
1000  * Returns 0 on success.
1001  */
1002 static int
1003 qla2x00_sns_rft_id(scsi_qla_host_t *vha)
1004 {
1005         int             rval;
1006         struct qla_hw_data *ha = vha->hw;
1007         struct sns_cmd_pkt      *sns_cmd;
1008
1009         /* Issue RFT_ID. */
1010         /* Prepare SNS command request. */
1011         sns_cmd = qla2x00_prep_sns_cmd(vha, RFT_ID_CMD, RFT_ID_SNS_SCMD_LEN,
1012             RFT_ID_SNS_DATA_SIZE);
1013
1014         /* Prepare SNS command arguments -- port_id, FC-4 types */
1015         sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa;
1016         sns_cmd->p.cmd.param[1] = vha->d_id.b.area;
1017         sns_cmd->p.cmd.param[2] = vha->d_id.b.domain;
1018
1019         sns_cmd->p.cmd.param[5] = 0x01;                 /* FCP-3 */
1020
1021         /* Execute SNS command. */
1022         rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RFT_ID_SNS_CMD_SIZE / 2,
1023             sizeof(struct sns_cmd_pkt));
1024         if (rval != QLA_SUCCESS) {
1025                 /*EMPTY*/
1026                 ql_dbg(ql_dbg_disc, vha, 0x2060,
1027                     "RFT_ID Send SNS failed (%d).\n", rval);
1028         } else if (sns_cmd->p.rft_data[8] != 0x80 ||
1029             sns_cmd->p.rft_data[9] != 0x02) {
1030                 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2083,
1031                     "RFT_ID failed, rejected request rft_rsp:\n");
1032                 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2080,
1033                     sns_cmd->p.rft_data, 16);
1034                 rval = QLA_FUNCTION_FAILED;
1035         } else {
1036                 ql_dbg(ql_dbg_disc, vha, 0x2073,
1037                     "RFT_ID exiting normally.\n");
1038         }
1039
1040         return (rval);
1041 }
1042
1043 /**
1044  * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
1045  * HBA.
1046  * @ha: HA context
1047  *
1048  * This command uses the old Exectute SNS Command mailbox routine.
1049  *
1050  * Returns 0 on success.
1051  */
1052 static int
1053 qla2x00_sns_rnn_id(scsi_qla_host_t *vha)
1054 {
1055         int             rval;
1056         struct qla_hw_data *ha = vha->hw;
1057         struct sns_cmd_pkt      *sns_cmd;
1058
1059         /* Issue RNN_ID. */
1060         /* Prepare SNS command request. */
1061         sns_cmd = qla2x00_prep_sns_cmd(vha, RNN_ID_CMD, RNN_ID_SNS_SCMD_LEN,
1062             RNN_ID_SNS_DATA_SIZE);
1063
1064         /* Prepare SNS command arguments -- port_id, nodename. */
1065         sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa;
1066         sns_cmd->p.cmd.param[1] = vha->d_id.b.area;
1067         sns_cmd->p.cmd.param[2] = vha->d_id.b.domain;
1068
1069         sns_cmd->p.cmd.param[4] = vha->node_name[7];
1070         sns_cmd->p.cmd.param[5] = vha->node_name[6];
1071         sns_cmd->p.cmd.param[6] = vha->node_name[5];
1072         sns_cmd->p.cmd.param[7] = vha->node_name[4];
1073         sns_cmd->p.cmd.param[8] = vha->node_name[3];
1074         sns_cmd->p.cmd.param[9] = vha->node_name[2];
1075         sns_cmd->p.cmd.param[10] = vha->node_name[1];
1076         sns_cmd->p.cmd.param[11] = vha->node_name[0];
1077
1078         /* Execute SNS command. */
1079         rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RNN_ID_SNS_CMD_SIZE / 2,
1080             sizeof(struct sns_cmd_pkt));
1081         if (rval != QLA_SUCCESS) {
1082                 /*EMPTY*/
1083                 ql_dbg(ql_dbg_disc, vha, 0x204a,
1084                     "RNN_ID Send SNS failed (%d).\n", rval);
1085         } else if (sns_cmd->p.rnn_data[8] != 0x80 ||
1086             sns_cmd->p.rnn_data[9] != 0x02) {
1087                 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207b,
1088                     "RNN_ID failed, rejected request, rnn_rsp:\n");
1089                 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207c,
1090                     sns_cmd->p.rnn_data, 16);
1091                 rval = QLA_FUNCTION_FAILED;
1092         } else {
1093                 ql_dbg(ql_dbg_disc, vha, 0x204c,
1094                     "RNN_ID exiting normally.\n");
1095         }
1096
1097         return (rval);
1098 }
1099
1100 /**
1101  * qla2x00_mgmt_svr_login() - Login to fabric Management Service.
1102  * @ha: HA context
1103  *
1104  * Returns 0 on success.
1105  */
1106 static int
1107 qla2x00_mgmt_svr_login(scsi_qla_host_t *vha)
1108 {
1109         int ret, rval;
1110         uint16_t mb[MAILBOX_REGISTER_COUNT];
1111         struct qla_hw_data *ha = vha->hw;
1112         ret = QLA_SUCCESS;
1113         if (vha->flags.management_server_logged_in)
1114                 return ret;
1115
1116         rval = ha->isp_ops->fabric_login(vha, vha->mgmt_svr_loop_id, 0xff, 0xff,
1117             0xfa, mb, BIT_1);
1118         if (rval != QLA_SUCCESS || mb[0] != MBS_COMMAND_COMPLETE) {
1119                 if (rval == QLA_MEMORY_ALLOC_FAILED)
1120                         ql_dbg(ql_dbg_disc, vha, 0x2085,
1121                             "Failed management_server login: loopid=%x "
1122                             "rval=%d\n", vha->mgmt_svr_loop_id, rval);
1123                 else
1124                         ql_dbg(ql_dbg_disc, vha, 0x2024,
1125                             "Failed management_server login: loopid=%x "
1126                             "mb[0]=%x mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x.\n",
1127                             vha->mgmt_svr_loop_id, mb[0], mb[1], mb[2], mb[6],
1128                             mb[7]);
1129                 ret = QLA_FUNCTION_FAILED;
1130         } else
1131                 vha->flags.management_server_logged_in = 1;
1132
1133         return ret;
1134 }
1135
1136 /**
1137  * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
1138  * @ha: HA context
1139  * @req_size: request size in bytes
1140  * @rsp_size: response size in bytes
1141  *
1142  * Returns a pointer to the @ha's ms_iocb.
1143  */
1144 void *
1145 qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size,
1146     uint32_t rsp_size)
1147 {
1148         ms_iocb_entry_t *ms_pkt;
1149         struct qla_hw_data *ha = vha->hw;
1150         ms_pkt = ha->ms_iocb;
1151         memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
1152
1153         ms_pkt->entry_type = MS_IOCB_TYPE;
1154         ms_pkt->entry_count = 1;
1155         SET_TARGET_ID(ha, ms_pkt->loop_id, vha->mgmt_svr_loop_id);
1156         ms_pkt->control_flags = cpu_to_le16(CF_READ | CF_HEAD_TAG);
1157         ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
1158         ms_pkt->cmd_dsd_count = cpu_to_le16(1);
1159         ms_pkt->total_dsd_count = cpu_to_le16(2);
1160         ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
1161         ms_pkt->req_bytecount = cpu_to_le32(req_size);
1162
1163         ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1164         ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1165         ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
1166
1167         ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1168         ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1169         ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount;
1170
1171         return ms_pkt;
1172 }
1173
1174 /**
1175  * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
1176  * @ha: HA context
1177  * @req_size: request size in bytes
1178  * @rsp_size: response size in bytes
1179  *
1180  * Returns a pointer to the @ha's ms_iocb.
1181  */
1182 void *
1183 qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size,
1184     uint32_t rsp_size)
1185 {
1186         struct ct_entry_24xx *ct_pkt;
1187         struct qla_hw_data *ha = vha->hw;
1188
1189         ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
1190         memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
1191
1192         ct_pkt->entry_type = CT_IOCB_TYPE;
1193         ct_pkt->entry_count = 1;
1194         ct_pkt->nport_handle = cpu_to_le16(vha->mgmt_svr_loop_id);
1195         ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
1196         ct_pkt->cmd_dsd_count = cpu_to_le16(1);
1197         ct_pkt->rsp_dsd_count = cpu_to_le16(1);
1198         ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
1199         ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
1200
1201         ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1202         ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1203         ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
1204
1205         ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1206         ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1207         ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
1208         ct_pkt->vp_index = vha->vp_idx;
1209
1210         return ct_pkt;
1211 }
1212
1213 static inline ms_iocb_entry_t *
1214 qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size)
1215 {
1216         struct qla_hw_data *ha = vha->hw;
1217         ms_iocb_entry_t *ms_pkt = ha->ms_iocb;
1218         struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
1219
1220         if (IS_FWI2_CAPABLE(ha)) {
1221                 ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
1222                 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
1223         } else {
1224                 ms_pkt->req_bytecount = cpu_to_le32(req_size);
1225                 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
1226         }
1227
1228         return ms_pkt;
1229 }
1230
1231 /**
1232  * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
1233  * @ct_req: CT request buffer
1234  * @cmd: GS command
1235  * @rsp_size: response size in bytes
1236  *
1237  * Returns a pointer to the intitialized @ct_req.
1238  */
1239 static inline struct ct_sns_req *
1240 qla2x00_prep_ct_fdmi_req(struct ct_sns_pkt *p, uint16_t cmd,
1241     uint16_t rsp_size)
1242 {
1243         memset(p, 0, sizeof(struct ct_sns_pkt));
1244
1245         p->p.req.header.revision = 0x01;
1246         p->p.req.header.gs_type = 0xFA;
1247         p->p.req.header.gs_subtype = 0x10;
1248         p->p.req.command = cpu_to_be16(cmd);
1249         p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
1250
1251         return &p->p.req;
1252 }
1253
1254 /**
1255  * qla2x00_fdmi_rhba() -
1256  * @ha: HA context
1257  *
1258  * Returns 0 on success.
1259  */
1260 static int
1261 qla2x00_fdmi_rhba(scsi_qla_host_t *vha)
1262 {
1263         int rval, alen;
1264         uint32_t size, sn;
1265
1266         ms_iocb_entry_t *ms_pkt;
1267         struct ct_sns_req *ct_req;
1268         struct ct_sns_rsp *ct_rsp;
1269         void *entries;
1270         struct ct_fdmi_hba_attr *eiter;
1271         struct qla_hw_data *ha = vha->hw;
1272
1273         /* Issue RHBA */
1274         /* Prepare common MS IOCB */
1275         /*   Request size adjusted after CT preparation */
1276         ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE);
1277
1278         /* Prepare CT request */
1279         ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RHBA_CMD, RHBA_RSP_SIZE);
1280         ct_rsp = &ha->ct_sns->p.rsp;
1281
1282         /* Prepare FDMI command arguments -- attribute block, attributes. */
1283         memcpy(ct_req->req.rhba.hba_identifier, vha->port_name, WWN_SIZE);
1284         ct_req->req.rhba.entry_count = cpu_to_be32(1);
1285         memcpy(ct_req->req.rhba.port_name, vha->port_name, WWN_SIZE);
1286         size = 2 * WWN_SIZE + 4 + 4;
1287
1288         /* Attributes */
1289         ct_req->req.rhba.attrs.count =
1290             cpu_to_be32(FDMI_HBA_ATTR_COUNT);
1291         entries = ct_req->req.rhba.hba_identifier;
1292
1293         /* Nodename. */
1294         eiter = entries + size;
1295         eiter->type = cpu_to_be16(FDMI_HBA_NODE_NAME);
1296         eiter->len = cpu_to_be16(4 + WWN_SIZE);
1297         memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE);
1298         size += 4 + WWN_SIZE;
1299
1300         ql_dbg(ql_dbg_disc, vha, 0x2025,
1301             "NodeName = %8phN.\n", eiter->a.node_name);
1302
1303         /* Manufacturer. */
1304         eiter = entries + size;
1305         eiter->type = cpu_to_be16(FDMI_HBA_MANUFACTURER);
1306         alen = strlen(QLA2XXX_MANUFACTURER);
1307         snprintf(eiter->a.manufacturer, sizeof(eiter->a.manufacturer),
1308             "%s", "QLogic Corporation");
1309         alen += 4 - (alen & 3);
1310         eiter->len = cpu_to_be16(4 + alen);
1311         size += 4 + alen;
1312
1313         ql_dbg(ql_dbg_disc, vha, 0x2026,
1314             "Manufacturer = %s.\n", eiter->a.manufacturer);
1315
1316         /* Serial number. */
1317         eiter = entries + size;
1318         eiter->type = cpu_to_be16(FDMI_HBA_SERIAL_NUMBER);
1319         if (IS_FWI2_CAPABLE(ha))
1320                 qla2xxx_get_vpd_field(vha, "SN", eiter->a.serial_num,
1321                     sizeof(eiter->a.serial_num));
1322         else {
1323                 sn = ((ha->serial0 & 0x1f) << 16) |
1324                         (ha->serial2 << 8) | ha->serial1;
1325                 snprintf(eiter->a.serial_num, sizeof(eiter->a.serial_num),
1326                     "%c%05d", 'A' + sn / 100000, sn % 100000);
1327         }
1328         alen = strlen(eiter->a.serial_num);
1329         alen += 4 - (alen & 3);
1330         eiter->len = cpu_to_be16(4 + alen);
1331         size += 4 + alen;
1332
1333         ql_dbg(ql_dbg_disc, vha, 0x2027,
1334             "Serial no. = %s.\n", eiter->a.serial_num);
1335
1336         /* Model name. */
1337         eiter = entries + size;
1338         eiter->type = cpu_to_be16(FDMI_HBA_MODEL);
1339         snprintf(eiter->a.model, sizeof(eiter->a.model),
1340             "%s", ha->model_number);
1341         alen = strlen(eiter->a.model);
1342         alen += 4 - (alen & 3);
1343         eiter->len = cpu_to_be16(4 + alen);
1344         size += 4 + alen;
1345
1346         ql_dbg(ql_dbg_disc, vha, 0x2028,
1347             "Model Name = %s.\n", eiter->a.model);
1348
1349         /* Model description. */
1350         eiter = entries + size;
1351         eiter->type = cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION);
1352         snprintf(eiter->a.model_desc, sizeof(eiter->a.model_desc),
1353             "%s", ha->model_desc);
1354         alen = strlen(eiter->a.model_desc);
1355         alen += 4 - (alen & 3);
1356         eiter->len = cpu_to_be16(4 + alen);
1357         size += 4 + alen;
1358
1359         ql_dbg(ql_dbg_disc, vha, 0x2029,
1360             "Model Desc = %s.\n", eiter->a.model_desc);
1361
1362         /* Hardware version. */
1363         eiter = entries + size;
1364         eiter->type = cpu_to_be16(FDMI_HBA_HARDWARE_VERSION);
1365         if (!IS_FWI2_CAPABLE(ha)) {
1366                 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version),
1367                     "HW:%s", ha->adapter_id);
1368         } else if (qla2xxx_get_vpd_field(vha, "MN", eiter->a.hw_version,
1369                     sizeof(eiter->a.hw_version))) {
1370                 ;
1371         } else if (qla2xxx_get_vpd_field(vha, "EC", eiter->a.hw_version,
1372                     sizeof(eiter->a.hw_version))) {
1373                 ;
1374         } else {
1375                 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version),
1376                     "HW:%s", ha->adapter_id);
1377         }
1378         alen = strlen(eiter->a.hw_version);
1379         alen += 4 - (alen & 3);
1380         eiter->len = cpu_to_be16(4 + alen);
1381         size += 4 + alen;
1382
1383         ql_dbg(ql_dbg_disc, vha, 0x202a,
1384             "Hardware ver = %s.\n", eiter->a.hw_version);
1385
1386         /* Driver version. */
1387         eiter = entries + size;
1388         eiter->type = cpu_to_be16(FDMI_HBA_DRIVER_VERSION);
1389         snprintf(eiter->a.driver_version, sizeof(eiter->a.driver_version),
1390             "%s", qla2x00_version_str);
1391         alen = strlen(eiter->a.driver_version);
1392         alen += 4 - (alen & 3);
1393         eiter->len = cpu_to_be16(4 + alen);
1394         size += 4 + alen;
1395
1396         ql_dbg(ql_dbg_disc, vha, 0x202b,
1397             "Driver ver = %s.\n", eiter->a.driver_version);
1398
1399         /* Option ROM version. */
1400         eiter = entries + size;
1401         eiter->type = cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION);
1402         snprintf(eiter->a.orom_version, sizeof(eiter->a.orom_version),
1403             "%d.%02d", ha->bios_revision[1], ha->bios_revision[0]);
1404         alen = strlen(eiter->a.orom_version);
1405         alen += 4 - (alen & 3);
1406         eiter->len = cpu_to_be16(4 + alen);
1407         size += 4 + alen;
1408
1409         ql_dbg(ql_dbg_disc, vha , 0x202c,
1410             "Optrom vers = %s.\n", eiter->a.orom_version);
1411
1412         /* Firmware version */
1413         eiter = entries + size;
1414         eiter->type = cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION);
1415         ha->isp_ops->fw_version_str(vha, eiter->a.fw_version,
1416             sizeof(eiter->a.fw_version));
1417         alen = strlen(eiter->a.fw_version);
1418         alen += 4 - (alen & 3);
1419         eiter->len = cpu_to_be16(4 + alen);
1420         size += 4 + alen;
1421
1422         ql_dbg(ql_dbg_disc, vha, 0x202d,
1423             "Firmware vers = %s.\n", eiter->a.fw_version);
1424
1425         /* Update MS request size. */
1426         qla2x00_update_ms_fdmi_iocb(vha, size + 16);
1427
1428         ql_dbg(ql_dbg_disc, vha, 0x202e,
1429             "RHBA identifier = %8phN size=%d.\n",
1430             ct_req->req.rhba.hba_identifier, size);
1431         ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2076,
1432             entries, size);
1433
1434         /* Execute MS IOCB */
1435         rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1436             sizeof(ms_iocb_entry_t));
1437         if (rval != QLA_SUCCESS) {
1438                 /*EMPTY*/
1439                 ql_dbg(ql_dbg_disc, vha, 0x2030,
1440                     "RHBA issue IOCB failed (%d).\n", rval);
1441         } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA") !=
1442             QLA_SUCCESS) {
1443                 rval = QLA_FUNCTION_FAILED;
1444                 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
1445                     ct_rsp->header.explanation_code ==
1446                     CT_EXPL_ALREADY_REGISTERED) {
1447                         ql_dbg(ql_dbg_disc, vha, 0x2034,
1448                             "HBA already registered.\n");
1449                         rval = QLA_ALREADY_REGISTERED;
1450                 } else {
1451                         ql_dbg(ql_dbg_disc, vha, 0x20ad,
1452                             "RHBA FDMI registration failed, CT Reason code: 0x%x, CT Explanation 0x%x\n",
1453                             ct_rsp->header.reason_code,
1454                             ct_rsp->header.explanation_code);
1455                 }
1456         } else {
1457                 ql_dbg(ql_dbg_disc, vha, 0x2035,
1458                     "RHBA exiting normally.\n");
1459         }
1460
1461         return rval;
1462 }
1463
1464 /**
1465  * qla2x00_fdmi_rpa() -
1466  * @ha: HA context
1467  *
1468  * Returns 0 on success.
1469  */
1470 static int
1471 qla2x00_fdmi_rpa(scsi_qla_host_t *vha)
1472 {
1473         int rval, alen;
1474         uint32_t size;
1475         struct qla_hw_data *ha = vha->hw;
1476         ms_iocb_entry_t *ms_pkt;
1477         struct ct_sns_req *ct_req;
1478         struct ct_sns_rsp *ct_rsp;
1479         void *entries;
1480         struct ct_fdmi_port_attr *eiter;
1481         struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb;
1482         struct new_utsname *p_sysid = NULL;
1483
1484         /* Issue RPA */
1485         /* Prepare common MS IOCB */
1486         /*   Request size adjusted after CT preparation */
1487         ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE);
1488
1489         /* Prepare CT request */
1490         ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPA_CMD,
1491             RPA_RSP_SIZE);
1492         ct_rsp = &ha->ct_sns->p.rsp;
1493
1494         /* Prepare FDMI command arguments -- attribute block, attributes. */
1495         memcpy(ct_req->req.rpa.port_name, vha->port_name, WWN_SIZE);
1496         size = WWN_SIZE + 4;
1497
1498         /* Attributes */
1499         ct_req->req.rpa.attrs.count = cpu_to_be32(FDMI_PORT_ATTR_COUNT);
1500         entries = ct_req->req.rpa.port_name;
1501
1502         /* FC4 types. */
1503         eiter = entries + size;
1504         eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPES);
1505         eiter->len = cpu_to_be16(4 + 32);
1506         eiter->a.fc4_types[2] = 0x01;
1507         size += 4 + 32;
1508
1509         ql_dbg(ql_dbg_disc, vha, 0x2039,
1510             "FC4_TYPES=%02x %02x.\n",
1511             eiter->a.fc4_types[2],
1512             eiter->a.fc4_types[1]);
1513
1514         /* Supported speed. */
1515         eiter = entries + size;
1516         eiter->type = cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
1517         eiter->len = cpu_to_be16(4 + 4);
1518         if (IS_CNA_CAPABLE(ha))
1519                 eiter->a.sup_speed = cpu_to_be32(
1520                     FDMI_PORT_SPEED_10GB);
1521         else if (IS_QLA27XX(ha))
1522                 eiter->a.sup_speed = cpu_to_be32(
1523                     FDMI_PORT_SPEED_32GB|
1524                     FDMI_PORT_SPEED_16GB|
1525                     FDMI_PORT_SPEED_8GB);
1526         else if (IS_QLA2031(ha))
1527                 eiter->a.sup_speed = cpu_to_be32(
1528                     FDMI_PORT_SPEED_16GB|
1529                     FDMI_PORT_SPEED_8GB|
1530                     FDMI_PORT_SPEED_4GB);
1531         else if (IS_QLA25XX(ha))
1532                 eiter->a.sup_speed = cpu_to_be32(
1533                     FDMI_PORT_SPEED_8GB|
1534                     FDMI_PORT_SPEED_4GB|
1535                     FDMI_PORT_SPEED_2GB|
1536                     FDMI_PORT_SPEED_1GB);
1537         else if (IS_QLA24XX_TYPE(ha))
1538                 eiter->a.sup_speed = cpu_to_be32(
1539                     FDMI_PORT_SPEED_4GB|
1540                     FDMI_PORT_SPEED_2GB|
1541                     FDMI_PORT_SPEED_1GB);
1542         else if (IS_QLA23XX(ha))
1543                 eiter->a.sup_speed = cpu_to_be32(
1544                     FDMI_PORT_SPEED_2GB|
1545                     FDMI_PORT_SPEED_1GB);
1546         else
1547                 eiter->a.sup_speed = cpu_to_be32(
1548                     FDMI_PORT_SPEED_1GB);
1549         size += 4 + 4;
1550
1551         ql_dbg(ql_dbg_disc, vha, 0x203a,
1552             "Supported_Speed=%x.\n", eiter->a.sup_speed);
1553
1554         /* Current speed. */
1555         eiter = entries + size;
1556         eiter->type = cpu_to_be16(FDMI_PORT_CURRENT_SPEED);
1557         eiter->len = cpu_to_be16(4 + 4);
1558         switch (ha->link_data_rate) {
1559         case PORT_SPEED_1GB:
1560                 eiter->a.cur_speed =
1561                     cpu_to_be32(FDMI_PORT_SPEED_1GB);
1562                 break;
1563         case PORT_SPEED_2GB:
1564                 eiter->a.cur_speed =
1565                     cpu_to_be32(FDMI_PORT_SPEED_2GB);
1566                 break;
1567         case PORT_SPEED_4GB:
1568                 eiter->a.cur_speed =
1569                     cpu_to_be32(FDMI_PORT_SPEED_4GB);
1570                 break;
1571         case PORT_SPEED_8GB:
1572                 eiter->a.cur_speed =
1573                     cpu_to_be32(FDMI_PORT_SPEED_8GB);
1574                 break;
1575         case PORT_SPEED_10GB:
1576                 eiter->a.cur_speed =
1577                     cpu_to_be32(FDMI_PORT_SPEED_10GB);
1578                 break;
1579         case PORT_SPEED_16GB:
1580                 eiter->a.cur_speed =
1581                     cpu_to_be32(FDMI_PORT_SPEED_16GB);
1582                 break;
1583         case PORT_SPEED_32GB:
1584                 eiter->a.cur_speed =
1585                     cpu_to_be32(FDMI_PORT_SPEED_32GB);
1586                 break;
1587         default:
1588                 eiter->a.cur_speed =
1589                     cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN);
1590                 break;
1591         }
1592         size += 4 + 4;
1593
1594         ql_dbg(ql_dbg_disc, vha, 0x203b,
1595             "Current_Speed=%x.\n", eiter->a.cur_speed);
1596
1597         /* Max frame size. */
1598         eiter = entries + size;
1599         eiter->type = cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE);
1600         eiter->len = cpu_to_be16(4 + 4);
1601         eiter->a.max_frame_size = IS_FWI2_CAPABLE(ha) ?
1602             le16_to_cpu(icb24->frame_payload_size) :
1603             le16_to_cpu(ha->init_cb->frame_payload_size);
1604         eiter->a.max_frame_size = cpu_to_be32(eiter->a.max_frame_size);
1605         size += 4 + 4;
1606
1607         ql_dbg(ql_dbg_disc, vha, 0x203c,
1608             "Max_Frame_Size=%x.\n", eiter->a.max_frame_size);
1609
1610         /* OS device name. */
1611         eiter = entries + size;
1612         eiter->type = cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME);
1613         snprintf(eiter->a.os_dev_name, sizeof(eiter->a.os_dev_name),
1614             "%s:host%lu", QLA2XXX_DRIVER_NAME, vha->host_no);
1615         alen = strlen(eiter->a.os_dev_name);
1616         alen += 4 - (alen & 3);
1617         eiter->len = cpu_to_be16(4 + alen);
1618         size += 4 + alen;
1619
1620         ql_dbg(ql_dbg_disc, vha, 0x204b,
1621             "OS_Device_Name=%s.\n", eiter->a.os_dev_name);
1622
1623         /* Hostname. */
1624         eiter = entries + size;
1625         eiter->type = cpu_to_be16(FDMI_PORT_HOST_NAME);
1626         p_sysid = utsname();
1627         if (p_sysid) {
1628                 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
1629                     "%s", p_sysid->nodename);
1630         } else {
1631                 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
1632                     "%s", fc_host_system_hostname(vha->host));
1633         }
1634         alen = strlen(eiter->a.host_name);
1635         alen += 4 - (alen & 3);
1636         eiter->len = cpu_to_be16(4 + alen);
1637         size += 4 + alen;
1638
1639         ql_dbg(ql_dbg_disc, vha, 0x203d, "HostName=%s.\n", eiter->a.host_name);
1640
1641         /* Update MS request size. */
1642         qla2x00_update_ms_fdmi_iocb(vha, size + 16);
1643
1644         ql_dbg(ql_dbg_disc, vha, 0x203e,
1645             "RPA portname  %016llx, size = %d.\n",
1646             wwn_to_u64(ct_req->req.rpa.port_name), size);
1647         ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2079,
1648             entries, size);
1649
1650         /* Execute MS IOCB */
1651         rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1652             sizeof(ms_iocb_entry_t));
1653         if (rval != QLA_SUCCESS) {
1654                 /*EMPTY*/
1655                 ql_dbg(ql_dbg_disc, vha, 0x2040,
1656                     "RPA issue IOCB failed (%d).\n", rval);
1657         } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA") !=
1658             QLA_SUCCESS) {
1659                 rval = QLA_FUNCTION_FAILED;
1660                 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
1661                     ct_rsp->header.explanation_code ==
1662                     CT_EXPL_ALREADY_REGISTERED) {
1663                         ql_dbg(ql_dbg_disc, vha, 0x20cd,
1664                             "RPA already registered.\n");
1665                         rval = QLA_ALREADY_REGISTERED;
1666                 }
1667
1668         } else {
1669                 ql_dbg(ql_dbg_disc, vha, 0x2041,
1670                     "RPA exiting normally.\n");
1671         }
1672
1673         return rval;
1674 }
1675
1676 /**
1677  * qla2x00_fdmiv2_rhba() -
1678  * @ha: HA context
1679  *
1680  * Returns 0 on success.
1681  */
1682 static int
1683 qla2x00_fdmiv2_rhba(scsi_qla_host_t *vha)
1684 {
1685         int rval, alen;
1686         uint32_t size, sn;
1687         ms_iocb_entry_t *ms_pkt;
1688         struct ct_sns_req *ct_req;
1689         struct ct_sns_rsp *ct_rsp;
1690         void *entries;
1691         struct ct_fdmiv2_hba_attr *eiter;
1692         struct qla_hw_data *ha = vha->hw;
1693         struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb;
1694         struct new_utsname *p_sysid = NULL;
1695
1696         /* Issue RHBA */
1697         /* Prepare common MS IOCB */
1698         /*   Request size adjusted after CT preparation */
1699         ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE);
1700
1701         /* Prepare CT request */
1702         ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RHBA_CMD,
1703             RHBA_RSP_SIZE);
1704         ct_rsp = &ha->ct_sns->p.rsp;
1705
1706         /* Prepare FDMI command arguments -- attribute block, attributes. */
1707         memcpy(ct_req->req.rhba2.hba_identifier, vha->port_name, WWN_SIZE);
1708         ct_req->req.rhba2.entry_count = cpu_to_be32(1);
1709         memcpy(ct_req->req.rhba2.port_name, vha->port_name, WWN_SIZE);
1710         size = 2 * WWN_SIZE + 4 + 4;
1711
1712         /* Attributes */
1713         ct_req->req.rhba2.attrs.count = cpu_to_be32(FDMIV2_HBA_ATTR_COUNT);
1714         entries = ct_req->req.rhba2.hba_identifier;
1715
1716         /* Nodename. */
1717         eiter = entries + size;
1718         eiter->type = cpu_to_be16(FDMI_HBA_NODE_NAME);
1719         eiter->len = cpu_to_be16(4 + WWN_SIZE);
1720         memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE);
1721         size += 4 + WWN_SIZE;
1722
1723         ql_dbg(ql_dbg_disc, vha, 0x207d,
1724             "NodeName = %016llx.\n", wwn_to_u64(eiter->a.node_name));
1725
1726         /* Manufacturer. */
1727         eiter = entries + size;
1728         eiter->type = cpu_to_be16(FDMI_HBA_MANUFACTURER);
1729         snprintf(eiter->a.manufacturer, sizeof(eiter->a.manufacturer),
1730             "%s", "QLogic Corporation");
1731         eiter->a.manufacturer[strlen("QLogic Corporation")] = '\0';
1732         alen = strlen(eiter->a.manufacturer);
1733         alen += 4 - (alen & 3);
1734         eiter->len = cpu_to_be16(4 + alen);
1735         size += 4 + alen;
1736
1737         ql_dbg(ql_dbg_disc, vha, 0x20a5,
1738             "Manufacturer = %s.\n", eiter->a.manufacturer);
1739
1740         /* Serial number. */
1741         eiter = entries + size;
1742         eiter->type = cpu_to_be16(FDMI_HBA_SERIAL_NUMBER);
1743         if (IS_FWI2_CAPABLE(ha))
1744                 qla2xxx_get_vpd_field(vha, "SN", eiter->a.serial_num,
1745                     sizeof(eiter->a.serial_num));
1746         else {
1747                 sn = ((ha->serial0 & 0x1f) << 16) |
1748                         (ha->serial2 << 8) | ha->serial1;
1749                 snprintf(eiter->a.serial_num, sizeof(eiter->a.serial_num),
1750                     "%c%05d", 'A' + sn / 100000, sn % 100000);
1751         }
1752         alen = strlen(eiter->a.serial_num);
1753         alen += 4 - (alen & 3);
1754         eiter->len = cpu_to_be16(4 + alen);
1755         size += 4 + alen;
1756
1757         ql_dbg(ql_dbg_disc, vha, 0x20a6,
1758             "Serial no. = %s.\n", eiter->a.serial_num);
1759
1760         /* Model name. */
1761         eiter = entries + size;
1762         eiter->type = cpu_to_be16(FDMI_HBA_MODEL);
1763         snprintf(eiter->a.model, sizeof(eiter->a.model),
1764             "%s", ha->model_number);
1765         alen = strlen(eiter->a.model);
1766         alen += 4 - (alen & 3);
1767         eiter->len = cpu_to_be16(4 + alen);
1768         size += 4 + alen;
1769
1770         ql_dbg(ql_dbg_disc, vha, 0x20a7,
1771             "Model Name = %s.\n", eiter->a.model);
1772
1773         /* Model description. */
1774         eiter = entries + size;
1775         eiter->type = cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION);
1776         snprintf(eiter->a.model_desc, sizeof(eiter->a.model_desc),
1777             "%s", ha->model_desc);
1778         alen = strlen(eiter->a.model_desc);
1779         alen += 4 - (alen & 3);
1780         eiter->len = cpu_to_be16(4 + alen);
1781         size += 4 + alen;
1782
1783         ql_dbg(ql_dbg_disc, vha, 0x20a8,
1784             "Model Desc = %s.\n", eiter->a.model_desc);
1785
1786         /* Hardware version. */
1787         eiter = entries + size;
1788         eiter->type = cpu_to_be16(FDMI_HBA_HARDWARE_VERSION);
1789         if (!IS_FWI2_CAPABLE(ha)) {
1790                 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version),
1791                     "HW:%s", ha->adapter_id);
1792         } else if (qla2xxx_get_vpd_field(vha, "MN", eiter->a.hw_version,
1793                     sizeof(eiter->a.hw_version))) {
1794                 ;
1795         } else if (qla2xxx_get_vpd_field(vha, "EC", eiter->a.hw_version,
1796                     sizeof(eiter->a.hw_version))) {
1797                 ;
1798         } else {
1799                 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version),
1800                     "HW:%s", ha->adapter_id);
1801         }
1802         alen = strlen(eiter->a.hw_version);
1803         alen += 4 - (alen & 3);
1804         eiter->len = cpu_to_be16(4 + alen);
1805         size += 4 + alen;
1806
1807         ql_dbg(ql_dbg_disc, vha, 0x20a9,
1808             "Hardware ver = %s.\n", eiter->a.hw_version);
1809
1810         /* Driver version. */
1811         eiter = entries + size;
1812         eiter->type = cpu_to_be16(FDMI_HBA_DRIVER_VERSION);
1813         snprintf(eiter->a.driver_version, sizeof(eiter->a.driver_version),
1814             "%s", qla2x00_version_str);
1815         alen = strlen(eiter->a.driver_version);
1816         alen += 4 - (alen & 3);
1817         eiter->len = cpu_to_be16(4 + alen);
1818         size += 4 + alen;
1819
1820         ql_dbg(ql_dbg_disc, vha, 0x20aa,
1821             "Driver ver = %s.\n", eiter->a.driver_version);
1822
1823         /* Option ROM version. */
1824         eiter = entries + size;
1825         eiter->type = cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION);
1826         snprintf(eiter->a.orom_version, sizeof(eiter->a.orom_version),
1827             "%d.%02d", ha->bios_revision[1], ha->bios_revision[0]);
1828         alen = strlen(eiter->a.orom_version);
1829         alen += 4 - (alen & 3);
1830         eiter->len = cpu_to_be16(4 + alen);
1831         size += 4 + alen;
1832
1833         ql_dbg(ql_dbg_disc, vha , 0x20ab,
1834             "Optrom version = %d.%02d.\n", eiter->a.orom_version[1],
1835             eiter->a.orom_version[0]);
1836
1837         /* Firmware version */
1838         eiter = entries + size;
1839         eiter->type = cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION);
1840         ha->isp_ops->fw_version_str(vha, eiter->a.fw_version,
1841             sizeof(eiter->a.fw_version));
1842         alen = strlen(eiter->a.fw_version);
1843         alen += 4 - (alen & 3);
1844         eiter->len = cpu_to_be16(4 + alen);
1845         size += 4 + alen;
1846
1847         ql_dbg(ql_dbg_disc, vha, 0x20ac,
1848             "Firmware vers = %s.\n", eiter->a.fw_version);
1849
1850         /* OS Name and Version */
1851         eiter = entries + size;
1852         eiter->type = cpu_to_be16(FDMI_HBA_OS_NAME_AND_VERSION);
1853         p_sysid = utsname();
1854         if (p_sysid) {
1855                 snprintf(eiter->a.os_version, sizeof(eiter->a.os_version),
1856                     "%s %s %s",
1857                     p_sysid->sysname, p_sysid->release, p_sysid->version);
1858         } else {
1859                 snprintf(eiter->a.os_version, sizeof(eiter->a.os_version),
1860                     "%s %s", "Linux", fc_host_system_hostname(vha->host));
1861         }
1862         alen = strlen(eiter->a.os_version);
1863         alen += 4 - (alen & 3);
1864         eiter->len = cpu_to_be16(4 + alen);
1865         size += 4 + alen;
1866
1867         ql_dbg(ql_dbg_disc, vha, 0x20ae,
1868             "OS Name and Version = %s.\n", eiter->a.os_version);
1869
1870         /* MAX CT Payload Length */
1871         eiter = entries + size;
1872         eiter->type = cpu_to_be16(FDMI_HBA_MAXIMUM_CT_PAYLOAD_LENGTH);
1873         eiter->a.max_ct_len = IS_FWI2_CAPABLE(ha) ?
1874             le16_to_cpu(icb24->frame_payload_size) :
1875             le16_to_cpu(ha->init_cb->frame_payload_size);
1876         eiter->a.max_ct_len = cpu_to_be32(eiter->a.max_ct_len);
1877         eiter->len = cpu_to_be16(4 + 4);
1878         size += 4 + 4;
1879
1880         ql_dbg(ql_dbg_disc, vha, 0x20af,
1881             "CT Payload Length = 0x%x.\n", eiter->a.max_ct_len);
1882
1883         /* Node Sybolic Name */
1884         eiter = entries + size;
1885         eiter->type = cpu_to_be16(FDMI_HBA_NODE_SYMBOLIC_NAME);
1886         qla2x00_get_sym_node_name(vha, eiter->a.sym_name,
1887             sizeof(eiter->a.sym_name));
1888         alen = strlen(eiter->a.sym_name);
1889         alen += 4 - (alen & 3);
1890         eiter->len = cpu_to_be16(4 + alen);
1891         size += 4 + alen;
1892
1893         ql_dbg(ql_dbg_disc, vha, 0x20b0,
1894             "Symbolic Name = %s.\n", eiter->a.sym_name);
1895
1896         /* Vendor Id */
1897         eiter = entries + size;
1898         eiter->type = cpu_to_be16(FDMI_HBA_VENDOR_ID);
1899         eiter->a.vendor_id = cpu_to_be32(0x1077);
1900         eiter->len = cpu_to_be16(4 + 4);
1901         size += 4 + 4;
1902
1903         ql_dbg(ql_dbg_disc, vha, 0x20b1,
1904             "Vendor Id = %x.\n", eiter->a.vendor_id);
1905
1906         /* Num Ports */
1907         eiter = entries + size;
1908         eiter->type = cpu_to_be16(FDMI_HBA_NUM_PORTS);
1909         eiter->a.num_ports = cpu_to_be32(1);
1910         eiter->len = cpu_to_be16(4 + 4);
1911         size += 4 + 4;
1912
1913         ql_dbg(ql_dbg_disc, vha, 0x20b2,
1914             "Port Num = %x.\n", eiter->a.num_ports);
1915
1916         /* Fabric Name */
1917         eiter = entries + size;
1918         eiter->type = cpu_to_be16(FDMI_HBA_FABRIC_NAME);
1919         memcpy(eiter->a.fabric_name, vha->fabric_node_name, WWN_SIZE);
1920         eiter->len = cpu_to_be16(4 + WWN_SIZE);
1921         size += 4 + WWN_SIZE;
1922
1923         ql_dbg(ql_dbg_disc, vha, 0x20b3,
1924             "Fabric Name = %016llx.\n", wwn_to_u64(eiter->a.fabric_name));
1925
1926         /* BIOS Version */
1927         eiter = entries + size;
1928         eiter->type = cpu_to_be16(FDMI_HBA_BOOT_BIOS_NAME);
1929         snprintf(eiter->a.bios_name, sizeof(eiter->a.bios_name),
1930             "BIOS %d.%02d", ha->bios_revision[1], ha->bios_revision[0]);
1931         alen = strlen(eiter->a.bios_name);
1932         alen += 4 - (alen & 3);
1933         eiter->len = cpu_to_be16(4 + alen);
1934         size += 4 + alen;
1935
1936         ql_dbg(ql_dbg_disc, vha, 0x20b4,
1937             "BIOS Name = %s\n", eiter->a.bios_name);
1938
1939         /* Vendor Identifier */
1940         eiter = entries + size;
1941         eiter->type = cpu_to_be16(FDMI_HBA_TYPE_VENDOR_IDENTIFIER);
1942         snprintf(eiter->a.vendor_indentifer, sizeof(eiter->a.vendor_indentifer),
1943             "%s", "QLGC");
1944         alen = strlen(eiter->a.vendor_indentifer);
1945         alen += 4 - (alen & 3);
1946         eiter->len = cpu_to_be16(4 + alen);
1947         size += 4 + alen;
1948
1949         ql_dbg(ql_dbg_disc, vha, 0x20b1,
1950             "Vendor Identifier = %s.\n", eiter->a.vendor_indentifer);
1951
1952         /* Update MS request size. */
1953         qla2x00_update_ms_fdmi_iocb(vha, size + 16);
1954
1955         ql_dbg(ql_dbg_disc, vha, 0x20b5,
1956             "RHBA identifier = %016llx.\n",
1957             wwn_to_u64(ct_req->req.rhba2.hba_identifier));
1958         ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x20b6,
1959             entries, size);
1960
1961         /* Execute MS IOCB */
1962         rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1963             sizeof(ms_iocb_entry_t));
1964         if (rval != QLA_SUCCESS) {
1965                 /*EMPTY*/
1966                 ql_dbg(ql_dbg_disc, vha, 0x20b7,
1967                     "RHBA issue IOCB failed (%d).\n", rval);
1968         } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA") !=
1969             QLA_SUCCESS) {
1970                 rval = QLA_FUNCTION_FAILED;
1971
1972                 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
1973                     ct_rsp->header.explanation_code ==
1974                     CT_EXPL_ALREADY_REGISTERED) {
1975                         ql_dbg(ql_dbg_disc, vha, 0x20b8,
1976                             "HBA already registered.\n");
1977                         rval = QLA_ALREADY_REGISTERED;
1978                 } else {
1979                         ql_dbg(ql_dbg_disc, vha, 0x2016,
1980                             "RHBA FDMI v2 failed, CT Reason code: 0x%x, CT Explanation 0x%x\n",
1981                             ct_rsp->header.reason_code,
1982                             ct_rsp->header.explanation_code);
1983                 }
1984         } else {
1985                 ql_dbg(ql_dbg_disc, vha, 0x20b9,
1986                     "RHBA FDMI V2 exiting normally.\n");
1987         }
1988
1989         return rval;
1990 }
1991
1992 /**
1993  * qla2x00_fdmi_dhba() -
1994  * @ha: HA context
1995  *
1996  * Returns 0 on success.
1997  */
1998 static int
1999 qla2x00_fdmi_dhba(scsi_qla_host_t *vha)
2000 {
2001         int rval;
2002         struct qla_hw_data *ha = vha->hw;
2003         ms_iocb_entry_t *ms_pkt;
2004         struct ct_sns_req *ct_req;
2005         struct ct_sns_rsp *ct_rsp;
2006
2007         /* Issue RPA */
2008         /* Prepare common MS IOCB */
2009         ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, DHBA_REQ_SIZE,
2010             DHBA_RSP_SIZE);
2011
2012         /* Prepare CT request */
2013         ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, DHBA_CMD, DHBA_RSP_SIZE);
2014         ct_rsp = &ha->ct_sns->p.rsp;
2015
2016         /* Prepare FDMI command arguments -- portname. */
2017         memcpy(ct_req->req.dhba.port_name, vha->port_name, WWN_SIZE);
2018
2019         ql_dbg(ql_dbg_disc, vha, 0x2036,
2020             "DHBA portname = %8phN.\n", ct_req->req.dhba.port_name);
2021
2022         /* Execute MS IOCB */
2023         rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
2024             sizeof(ms_iocb_entry_t));
2025         if (rval != QLA_SUCCESS) {
2026                 /*EMPTY*/
2027                 ql_dbg(ql_dbg_disc, vha, 0x2037,
2028                     "DHBA issue IOCB failed (%d).\n", rval);
2029         } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "DHBA") !=
2030             QLA_SUCCESS) {
2031                 rval = QLA_FUNCTION_FAILED;
2032         } else {
2033                 ql_dbg(ql_dbg_disc, vha, 0x2038,
2034                     "DHBA exiting normally.\n");
2035         }
2036
2037         return rval;
2038 }
2039
2040 /**
2041  * qla2x00_fdmiv2_rpa() -
2042  * @ha: HA context
2043  *
2044  * Returns 0 on success.
2045  */
2046 static int
2047 qla2x00_fdmiv2_rpa(scsi_qla_host_t *vha)
2048 {
2049         int rval, alen;
2050         uint32_t size;
2051         struct qla_hw_data *ha = vha->hw;
2052         ms_iocb_entry_t *ms_pkt;
2053         struct ct_sns_req *ct_req;
2054         struct ct_sns_rsp *ct_rsp;
2055         void *entries;
2056         struct ct_fdmiv2_port_attr *eiter;
2057         struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb;
2058         struct new_utsname *p_sysid = NULL;
2059
2060         /* Issue RPA */
2061         /* Prepare common MS IOCB */
2062         /*   Request size adjusted after CT preparation */
2063         ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE);
2064
2065         /* Prepare CT request */
2066         ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPA_CMD, RPA_RSP_SIZE);
2067         ct_rsp = &ha->ct_sns->p.rsp;
2068
2069         /* Prepare FDMI command arguments -- attribute block, attributes. */
2070         memcpy(ct_req->req.rpa2.port_name, vha->port_name, WWN_SIZE);
2071         size = WWN_SIZE + 4;
2072
2073         /* Attributes */
2074         ct_req->req.rpa2.attrs.count = cpu_to_be32(FDMIV2_PORT_ATTR_COUNT);
2075         entries = ct_req->req.rpa2.port_name;
2076
2077         /* FC4 types. */
2078         eiter = entries + size;
2079         eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPES);
2080         eiter->len = cpu_to_be16(4 + 32);
2081         eiter->a.fc4_types[2] = 0x01;
2082         size += 4 + 32;
2083
2084         ql_dbg(ql_dbg_disc, vha, 0x20ba,
2085             "FC4_TYPES=%02x %02x.\n",
2086             eiter->a.fc4_types[2],
2087             eiter->a.fc4_types[1]);
2088
2089         /* Supported speed. */
2090         eiter = entries + size;
2091         eiter->type = cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
2092         eiter->len = cpu_to_be16(4 + 4);
2093         if (IS_CNA_CAPABLE(ha))
2094                 eiter->a.sup_speed = cpu_to_be32(
2095                     FDMI_PORT_SPEED_10GB);
2096         else if (IS_QLA27XX(ha))
2097                 eiter->a.sup_speed = cpu_to_be32(
2098                     FDMI_PORT_SPEED_32GB|
2099                     FDMI_PORT_SPEED_16GB|
2100                     FDMI_PORT_SPEED_8GB);
2101         else if (IS_QLA2031(ha))
2102                 eiter->a.sup_speed = cpu_to_be32(
2103                     FDMI_PORT_SPEED_16GB|
2104                     FDMI_PORT_SPEED_8GB|
2105                     FDMI_PORT_SPEED_4GB);
2106         else if (IS_QLA25XX(ha))
2107                 eiter->a.sup_speed = cpu_to_be32(
2108                     FDMI_PORT_SPEED_8GB|
2109                     FDMI_PORT_SPEED_4GB|
2110                     FDMI_PORT_SPEED_2GB|
2111                     FDMI_PORT_SPEED_1GB);
2112         else if (IS_QLA24XX_TYPE(ha))
2113                 eiter->a.sup_speed = cpu_to_be32(
2114                     FDMI_PORT_SPEED_4GB|
2115                     FDMI_PORT_SPEED_2GB|
2116                     FDMI_PORT_SPEED_1GB);
2117         else if (IS_QLA23XX(ha))
2118                 eiter->a.sup_speed = cpu_to_be32(
2119                     FDMI_PORT_SPEED_2GB|
2120                     FDMI_PORT_SPEED_1GB);
2121         else
2122                 eiter->a.sup_speed = cpu_to_be32(
2123                     FDMI_PORT_SPEED_1GB);
2124         size += 4 + 4;
2125
2126         ql_dbg(ql_dbg_disc, vha, 0x20bb,
2127             "Supported Port Speed = %x.\n", eiter->a.sup_speed);
2128
2129         /* Current speed. */
2130         eiter = entries + size;
2131         eiter->type = cpu_to_be16(FDMI_PORT_CURRENT_SPEED);
2132         eiter->len = cpu_to_be16(4 + 4);
2133         switch (ha->link_data_rate) {
2134         case PORT_SPEED_1GB:
2135                 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_1GB);
2136                 break;
2137         case PORT_SPEED_2GB:
2138                 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_2GB);
2139                 break;
2140         case PORT_SPEED_4GB:
2141                 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_4GB);
2142                 break;
2143         case PORT_SPEED_8GB:
2144                 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_8GB);
2145                 break;
2146         case PORT_SPEED_10GB:
2147                 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_10GB);
2148                 break;
2149         case PORT_SPEED_16GB:
2150                 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_16GB);
2151                 break;
2152         case PORT_SPEED_32GB:
2153                 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_32GB);
2154                 break;
2155         default:
2156                 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN);
2157                 break;
2158         }
2159         size += 4 + 4;
2160
2161         ql_dbg(ql_dbg_disc, vha, 0x20bc,
2162             "Current_Speed = %x.\n", eiter->a.cur_speed);
2163
2164         /* Max frame size. */
2165         eiter = entries + size;
2166         eiter->type = cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE);
2167         eiter->len = cpu_to_be16(4 + 4);
2168         eiter->a.max_frame_size = IS_FWI2_CAPABLE(ha) ?
2169             le16_to_cpu(icb24->frame_payload_size):
2170             le16_to_cpu(ha->init_cb->frame_payload_size);
2171         eiter->a.max_frame_size = cpu_to_be32(eiter->a.max_frame_size);
2172         size += 4 + 4;
2173
2174         ql_dbg(ql_dbg_disc, vha, 0x20bc,
2175             "Max_Frame_Size = %x.\n", eiter->a.max_frame_size);
2176
2177         /* OS device name. */
2178         eiter = entries + size;
2179         eiter->type = cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME);
2180         alen = strlen(QLA2XXX_DRIVER_NAME);
2181         snprintf(eiter->a.os_dev_name, sizeof(eiter->a.os_dev_name),
2182             "%s:host%lu", QLA2XXX_DRIVER_NAME, vha->host_no);
2183         alen += 4 - (alen & 3);
2184         eiter->len = cpu_to_be16(4 + alen);
2185         size += 4 + alen;
2186
2187         ql_dbg(ql_dbg_disc, vha, 0x20be,
2188             "OS_Device_Name = %s.\n", eiter->a.os_dev_name);
2189
2190         /* Hostname. */
2191         eiter = entries + size;
2192         eiter->type = cpu_to_be16(FDMI_PORT_HOST_NAME);
2193         p_sysid = utsname();
2194         if (p_sysid) {
2195                 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
2196                     "%s", p_sysid->nodename);
2197         } else {
2198                 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
2199                     "%s", fc_host_system_hostname(vha->host));
2200         }
2201         alen = strlen(eiter->a.host_name);
2202         alen += 4 - (alen & 3);
2203         eiter->len = cpu_to_be16(4 + alen);
2204         size += 4 + alen;
2205
2206         ql_dbg(ql_dbg_disc, vha, 0x203d,
2207             "HostName=%s.\n", eiter->a.host_name);
2208
2209         /* Node Name */
2210         eiter = entries + size;
2211         eiter->type = cpu_to_be16(FDMI_PORT_NODE_NAME);
2212         memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE);
2213         eiter->len = cpu_to_be16(4 + WWN_SIZE);
2214         size += 4 + WWN_SIZE;
2215
2216         ql_dbg(ql_dbg_disc, vha, 0x20c0,
2217             "Node Name = %016llx.\n", wwn_to_u64(eiter->a.node_name));
2218
2219         /* Port Name */
2220         eiter = entries + size;
2221         eiter->type = cpu_to_be16(FDMI_PORT_NAME);
2222         memcpy(eiter->a.port_name, vha->port_name, WWN_SIZE);
2223         eiter->len = cpu_to_be16(4 + WWN_SIZE);
2224         size += 4 + WWN_SIZE;
2225
2226         ql_dbg(ql_dbg_disc, vha, 0x20c1,
2227             "Port Name = %016llx.\n", wwn_to_u64(eiter->a.port_name));
2228
2229         /* Port Symbolic Name */
2230         eiter = entries + size;
2231         eiter->type = cpu_to_be16(FDMI_PORT_SYM_NAME);
2232         qla2x00_get_sym_node_name(vha, eiter->a.port_sym_name,
2233             sizeof(eiter->a.port_sym_name));
2234         alen = strlen(eiter->a.port_sym_name);
2235         alen += 4 - (alen & 3);
2236         eiter->len = cpu_to_be16(4 + alen);
2237         size += 4 + alen;
2238
2239         ql_dbg(ql_dbg_disc, vha, 0x20c2,
2240             "port symbolic name = %s\n", eiter->a.port_sym_name);
2241
2242         /* Port Type */
2243         eiter = entries + size;
2244         eiter->type = cpu_to_be16(FDMI_PORT_TYPE);
2245         eiter->a.port_type = cpu_to_be32(NS_NX_PORT_TYPE);
2246         eiter->len = cpu_to_be16(4 + 4);
2247         size += 4 + 4;
2248
2249         ql_dbg(ql_dbg_disc, vha, 0x20c3,
2250             "Port Type = %x.\n", eiter->a.port_type);
2251
2252         /* Class of Service  */
2253         eiter = entries + size;
2254         eiter->type = cpu_to_be16(FDMI_PORT_SUPP_COS);
2255         eiter->a.port_supported_cos = cpu_to_be32(FC_CLASS_3);
2256         eiter->len = cpu_to_be16(4 + 4);
2257         size += 4 + 4;
2258
2259         ql_dbg(ql_dbg_disc, vha, 0x20c4,
2260             "Supported COS = %08x\n", eiter->a.port_supported_cos);
2261
2262         /* Port Fabric Name */
2263         eiter = entries + size;
2264         eiter->type = cpu_to_be16(FDMI_PORT_FABRIC_NAME);
2265         memcpy(eiter->a.fabric_name, vha->fabric_node_name, WWN_SIZE);
2266         eiter->len = cpu_to_be16(4 + WWN_SIZE);
2267         size += 4 + WWN_SIZE;
2268
2269         ql_dbg(ql_dbg_disc, vha, 0x20c5,
2270             "Fabric Name = %016llx.\n", wwn_to_u64(eiter->a.fabric_name));
2271
2272         /* FC4_type */
2273         eiter = entries + size;
2274         eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPE);
2275         eiter->a.port_fc4_type[0] = 0;
2276         eiter->a.port_fc4_type[1] = 0;
2277         eiter->a.port_fc4_type[2] = 1;
2278         eiter->a.port_fc4_type[3] = 0;
2279         eiter->len = cpu_to_be16(4 + 32);
2280         size += 4 + 32;
2281
2282         ql_dbg(ql_dbg_disc, vha, 0x20c6,
2283             "Port Active FC4 Type = %02x %02x.\n",
2284             eiter->a.port_fc4_type[2], eiter->a.port_fc4_type[1]);
2285
2286         /* Port State */
2287         eiter = entries + size;
2288         eiter->type = cpu_to_be16(FDMI_PORT_STATE);
2289         eiter->a.port_state = cpu_to_be32(1);
2290         eiter->len = cpu_to_be16(4 + 4);
2291         size += 4 + 4;
2292
2293         ql_dbg(ql_dbg_disc, vha, 0x20c7,
2294             "Port State = %x.\n", eiter->a.port_state);
2295
2296         /* Number of Ports */
2297         eiter = entries + size;
2298         eiter->type = cpu_to_be16(FDMI_PORT_COUNT);
2299         eiter->a.num_ports = cpu_to_be32(1);
2300         eiter->len = cpu_to_be16(4 + 4);
2301         size += 4 + 4;
2302
2303         ql_dbg(ql_dbg_disc, vha, 0x20c8,
2304             "Number of ports = %x.\n", eiter->a.num_ports);
2305
2306         /* Port Id */
2307         eiter = entries + size;
2308         eiter->type = cpu_to_be16(FDMI_PORT_ID);
2309         eiter->a.port_id = cpu_to_be32(vha->d_id.b24);
2310         eiter->len = cpu_to_be16(4 + 4);
2311         size += 4 + 4;
2312
2313         ql_dbg(ql_dbg_disc, vha, 0x20c8,
2314             "Port Id = %x.\n", eiter->a.port_id);
2315
2316         /* Update MS request size. */
2317         qla2x00_update_ms_fdmi_iocb(vha, size + 16);
2318
2319         ql_dbg(ql_dbg_disc, vha, 0x203e,
2320             "RPA portname= %8phN size=%d.\n", ct_req->req.rpa.port_name, size);
2321         ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x20ca,
2322             entries, size);
2323
2324         /* Execute MS IOCB */
2325         rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
2326             sizeof(ms_iocb_entry_t));
2327         if (rval != QLA_SUCCESS) {
2328                 /*EMPTY*/
2329                 ql_dbg(ql_dbg_disc, vha, 0x20cb,
2330                     "RPA FDMI v2 issue IOCB failed (%d).\n", rval);
2331         } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA") !=
2332             QLA_SUCCESS) {
2333                 rval = QLA_FUNCTION_FAILED;
2334                 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
2335                     ct_rsp->header.explanation_code ==
2336                     CT_EXPL_ALREADY_REGISTERED) {
2337                         ql_dbg(ql_dbg_disc, vha, 0x20ce,
2338                             "RPA FDMI v2 already registered\n");
2339                         rval = QLA_ALREADY_REGISTERED;
2340                 } else {
2341                         ql_dbg(ql_dbg_disc, vha, 0x2020,
2342                             "RPA FDMI v2 failed, CT Reason code: 0x%x, CT Explanation 0x%x\n",
2343                             ct_rsp->header.reason_code,
2344                             ct_rsp->header.explanation_code);
2345                 }
2346         } else {
2347                 ql_dbg(ql_dbg_disc, vha, 0x20cc,
2348                     "RPA FDMI V2 exiting normally.\n");
2349         }
2350
2351         return rval;
2352 }
2353
2354 /**
2355  * qla2x00_fdmi_register() -
2356  * @ha: HA context
2357  *
2358  * Returns 0 on success.
2359  */
2360 int
2361 qla2x00_fdmi_register(scsi_qla_host_t *vha)
2362 {
2363         int rval = QLA_FUNCTION_FAILED;
2364         struct qla_hw_data *ha = vha->hw;
2365
2366         if (IS_QLA2100(ha) || IS_QLA2200(ha) ||
2367             IS_QLAFX00(ha))
2368                 return QLA_FUNCTION_FAILED;
2369
2370         rval = qla2x00_mgmt_svr_login(vha);
2371         if (rval)
2372                 return rval;
2373
2374         rval = qla2x00_fdmiv2_rhba(vha);
2375         if (rval) {
2376                 if (rval != QLA_ALREADY_REGISTERED)
2377                         goto try_fdmi;
2378
2379                 rval = qla2x00_fdmi_dhba(vha);
2380                 if (rval)
2381                         goto try_fdmi;
2382
2383                 rval = qla2x00_fdmiv2_rhba(vha);
2384                 if (rval)
2385                         goto try_fdmi;
2386         }
2387         rval = qla2x00_fdmiv2_rpa(vha);
2388         if (rval)
2389                 goto try_fdmi;
2390
2391         goto out;
2392
2393 try_fdmi:
2394         rval = qla2x00_fdmi_rhba(vha);
2395         if (rval) {
2396                 if (rval != QLA_ALREADY_REGISTERED)
2397                         return rval;
2398
2399                 rval = qla2x00_fdmi_dhba(vha);
2400                 if (rval)
2401                         return rval;
2402
2403                 rval = qla2x00_fdmi_rhba(vha);
2404                 if (rval)
2405                         return rval;
2406         }
2407         rval = qla2x00_fdmi_rpa(vha);
2408 out:
2409         return rval;
2410 }
2411
2412 /**
2413  * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query.
2414  * @ha: HA context
2415  * @list: switch info entries to populate
2416  *
2417  * Returns 0 on success.
2418  */
2419 int
2420 qla2x00_gfpn_id(scsi_qla_host_t *vha, sw_info_t *list)
2421 {
2422         int             rval = QLA_SUCCESS;
2423         uint16_t        i;
2424         struct qla_hw_data *ha = vha->hw;
2425         ms_iocb_entry_t *ms_pkt;
2426         struct ct_sns_req       *ct_req;
2427         struct ct_sns_rsp       *ct_rsp;
2428
2429         if (!IS_IIDMA_CAPABLE(ha))
2430                 return QLA_FUNCTION_FAILED;
2431
2432         for (i = 0; i < ha->max_fibre_devices; i++) {
2433                 /* Issue GFPN_ID */
2434                 /* Prepare common MS IOCB */
2435                 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GFPN_ID_REQ_SIZE,
2436                     GFPN_ID_RSP_SIZE);
2437
2438                 /* Prepare CT request */
2439                 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFPN_ID_CMD,
2440                     GFPN_ID_RSP_SIZE);
2441                 ct_rsp = &ha->ct_sns->p.rsp;
2442
2443                 /* Prepare CT arguments -- port_id */
2444                 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
2445                 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
2446                 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
2447
2448                 /* Execute MS IOCB */
2449                 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
2450                     sizeof(ms_iocb_entry_t));
2451                 if (rval != QLA_SUCCESS) {
2452                         /*EMPTY*/
2453                         ql_dbg(ql_dbg_disc, vha, 0x2023,
2454                             "GFPN_ID issue IOCB failed (%d).\n", rval);
2455                         break;
2456                 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
2457                     "GFPN_ID") != QLA_SUCCESS) {
2458                         rval = QLA_FUNCTION_FAILED;
2459                         break;
2460                 } else {
2461                         /* Save fabric portname */
2462                         memcpy(list[i].fabric_port_name,
2463                             ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE);
2464                 }
2465
2466                 /* Last device exit. */
2467                 if (list[i].d_id.b.rsvd_1 != 0)
2468                         break;
2469         }
2470
2471         return (rval);
2472 }
2473
2474 static inline void *
2475 qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *vha, uint32_t req_size,
2476     uint32_t rsp_size)
2477 {
2478         struct ct_entry_24xx *ct_pkt;
2479         struct qla_hw_data *ha = vha->hw;
2480         ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
2481         memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
2482
2483         ct_pkt->entry_type = CT_IOCB_TYPE;
2484         ct_pkt->entry_count = 1;
2485         ct_pkt->nport_handle = cpu_to_le16(vha->mgmt_svr_loop_id);
2486         ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
2487         ct_pkt->cmd_dsd_count = cpu_to_le16(1);
2488         ct_pkt->rsp_dsd_count = cpu_to_le16(1);
2489         ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
2490         ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
2491
2492         ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
2493         ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
2494         ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
2495
2496         ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
2497         ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
2498         ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
2499         ct_pkt->vp_index = vha->vp_idx;
2500
2501         return ct_pkt;
2502 }
2503
2504
2505 static inline struct ct_sns_req *
2506 qla24xx_prep_ct_fm_req(struct ct_sns_pkt *p, uint16_t cmd,
2507     uint16_t rsp_size)
2508 {
2509         memset(p, 0, sizeof(struct ct_sns_pkt));
2510
2511         p->p.req.header.revision = 0x01;
2512         p->p.req.header.gs_type = 0xFA;
2513         p->p.req.header.gs_subtype = 0x01;
2514         p->p.req.command = cpu_to_be16(cmd);
2515         p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
2516
2517         return &p->p.req;
2518 }
2519
2520 /**
2521  * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query.
2522  * @ha: HA context
2523  * @list: switch info entries to populate
2524  *
2525  * Returns 0 on success.
2526  */
2527 int
2528 qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list)
2529 {
2530         int             rval;
2531         uint16_t        i;
2532         struct qla_hw_data *ha = vha->hw;
2533         ms_iocb_entry_t *ms_pkt;
2534         struct ct_sns_req       *ct_req;
2535         struct ct_sns_rsp       *ct_rsp;
2536
2537         if (!IS_IIDMA_CAPABLE(ha))
2538                 return QLA_FUNCTION_FAILED;
2539         if (!ha->flags.gpsc_supported)
2540                 return QLA_FUNCTION_FAILED;
2541
2542         rval = qla2x00_mgmt_svr_login(vha);
2543         if (rval)
2544                 return rval;
2545
2546         for (i = 0; i < ha->max_fibre_devices; i++) {
2547                 /* Issue GFPN_ID */
2548                 /* Prepare common MS IOCB */
2549                 ms_pkt = qla24xx_prep_ms_fm_iocb(vha, GPSC_REQ_SIZE,
2550                     GPSC_RSP_SIZE);
2551
2552                 /* Prepare CT request */
2553                 ct_req = qla24xx_prep_ct_fm_req(ha->ct_sns, GPSC_CMD,
2554                     GPSC_RSP_SIZE);
2555                 ct_rsp = &ha->ct_sns->p.rsp;
2556
2557                 /* Prepare CT arguments -- port_name */
2558                 memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name,
2559                     WWN_SIZE);
2560
2561                 /* Execute MS IOCB */
2562                 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
2563                     sizeof(ms_iocb_entry_t));
2564                 if (rval != QLA_SUCCESS) {
2565                         /*EMPTY*/
2566                         ql_dbg(ql_dbg_disc, vha, 0x2059,
2567                             "GPSC issue IOCB failed (%d).\n", rval);
2568                 } else if ((rval = qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
2569                     "GPSC")) != QLA_SUCCESS) {
2570                         /* FM command unsupported? */
2571                         if (rval == QLA_INVALID_COMMAND &&
2572                             (ct_rsp->header.reason_code ==
2573                                 CT_REASON_INVALID_COMMAND_CODE ||
2574                              ct_rsp->header.reason_code ==
2575                                 CT_REASON_COMMAND_UNSUPPORTED)) {
2576                                 ql_dbg(ql_dbg_disc, vha, 0x205a,
2577                                     "GPSC command unsupported, disabling "
2578                                     "query.\n");
2579                                 ha->flags.gpsc_supported = 0;
2580                                 rval = QLA_FUNCTION_FAILED;
2581                                 break;
2582                         }
2583                         rval = QLA_FUNCTION_FAILED;
2584                 } else {
2585                         /* Save port-speed */
2586                         switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) {
2587                         case BIT_15:
2588                                 list[i].fp_speed = PORT_SPEED_1GB;
2589                                 break;
2590                         case BIT_14:
2591                                 list[i].fp_speed = PORT_SPEED_2GB;
2592                                 break;
2593                         case BIT_13:
2594                                 list[i].fp_speed = PORT_SPEED_4GB;
2595                                 break;
2596                         case BIT_12:
2597                                 list[i].fp_speed = PORT_SPEED_10GB;
2598                                 break;
2599                         case BIT_11:
2600                                 list[i].fp_speed = PORT_SPEED_8GB;
2601                                 break;
2602                         case BIT_10:
2603                                 list[i].fp_speed = PORT_SPEED_16GB;
2604                                 break;
2605                         case BIT_8:
2606                                 list[i].fp_speed = PORT_SPEED_32GB;
2607                                 break;
2608                         }
2609
2610                         ql_dbg(ql_dbg_disc, vha, 0x205b,
2611                             "GPSC ext entry - fpn "
2612                             "%8phN speeds=%04x speed=%04x.\n",
2613                             list[i].fabric_port_name,
2614                             be16_to_cpu(ct_rsp->rsp.gpsc.speeds),
2615                             be16_to_cpu(ct_rsp->rsp.gpsc.speed));
2616                 }
2617
2618                 /* Last device exit. */
2619                 if (list[i].d_id.b.rsvd_1 != 0)
2620                         break;
2621         }
2622
2623         return (rval);
2624 }
2625
2626 /**
2627  * qla2x00_gff_id() - SNS Get FC-4 Features (GFF_ID) query.
2628  *
2629  * @ha: HA context
2630  * @list: switch info entries to populate
2631  *
2632  */
2633 void
2634 qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list)
2635 {
2636         int             rval;
2637         uint16_t        i;
2638
2639         ms_iocb_entry_t *ms_pkt;
2640         struct ct_sns_req       *ct_req;
2641         struct ct_sns_rsp       *ct_rsp;
2642         struct qla_hw_data *ha = vha->hw;
2643         uint8_t fcp_scsi_features = 0;
2644
2645         for (i = 0; i < ha->max_fibre_devices; i++) {
2646                 /* Set default FC4 Type as UNKNOWN so the default is to
2647                  * Process this port */
2648                 list[i].fc4_type = FC4_TYPE_UNKNOWN;
2649
2650                 /* Do not attempt GFF_ID if we are not FWI_2 capable */
2651                 if (!IS_FWI2_CAPABLE(ha))
2652                         continue;
2653
2654                 /* Prepare common MS IOCB */
2655                 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GFF_ID_REQ_SIZE,
2656                     GFF_ID_RSP_SIZE);
2657
2658                 /* Prepare CT request */
2659                 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFF_ID_CMD,
2660                     GFF_ID_RSP_SIZE);
2661                 ct_rsp = &ha->ct_sns->p.rsp;
2662
2663                 /* Prepare CT arguments -- port_id */
2664                 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
2665                 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
2666                 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
2667
2668                 /* Execute MS IOCB */
2669                 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
2670                    sizeof(ms_iocb_entry_t));
2671
2672                 if (rval != QLA_SUCCESS) {
2673                         ql_dbg(ql_dbg_disc, vha, 0x205c,
2674                             "GFF_ID issue IOCB failed (%d).\n", rval);
2675                 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
2676                                "GFF_ID") != QLA_SUCCESS) {
2677                         ql_dbg(ql_dbg_disc, vha, 0x205d,
2678                             "GFF_ID IOCB status had a failure status code.\n");
2679                 } else {
2680                         fcp_scsi_features =
2681                            ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
2682                         fcp_scsi_features &= 0x0f;
2683
2684                         if (fcp_scsi_features)
2685                                 list[i].fc4_type = FC4_TYPE_FCP_SCSI;
2686                         else
2687                                 list[i].fc4_type = FC4_TYPE_OTHER;
2688                 }
2689
2690                 /* Last device exit. */
2691                 if (list[i].d_id.b.rsvd_1 != 0)
2692                         break;
2693         }
2694 }