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