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