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