OSDN Git Service

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