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, struct ct_arg *arg) 28 { 29 struct qla_hw_data *ha = vha->hw; 30 ms_iocb_entry_t *ms_pkt; 31 32 ms_pkt = (ms_iocb_entry_t *)arg->iocb; 33 memset(ms_pkt, 0, sizeof(ms_iocb_entry_t)); 34 35 ms_pkt->entry_type = MS_IOCB_TYPE; 36 ms_pkt->entry_count = 1; 37 SET_TARGET_ID(ha, ms_pkt->loop_id, SIMPLE_NAME_SERVER); 38 ms_pkt->control_flags = cpu_to_le16(CF_READ | CF_HEAD_TAG); 39 ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); 40 ms_pkt->cmd_dsd_count = cpu_to_le16(1); 41 ms_pkt->total_dsd_count = cpu_to_le16(2); 42 ms_pkt->rsp_bytecount = cpu_to_le32(arg->rsp_size); 43 ms_pkt->req_bytecount = cpu_to_le32(arg->req_size); 44 45 ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(arg->req_dma)); 46 ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(arg->req_dma)); 47 ms_pkt->dseg_req_length = ms_pkt->req_bytecount; 48 49 ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(arg->rsp_dma)); 50 ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(arg->rsp_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, struct ct_arg *arg) 68 { 69 struct qla_hw_data *ha = vha->hw; 70 struct ct_entry_24xx *ct_pkt; 71 72 ct_pkt = (struct ct_entry_24xx *)arg->iocb; 73 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx)); 74 75 ct_pkt->entry_type = CT_IOCB_TYPE; 76 ct_pkt->entry_count = 1; 77 ct_pkt->nport_handle = cpu_to_le16(arg->nport_handle); 78 ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); 79 ct_pkt->cmd_dsd_count = cpu_to_le16(1); 80 ct_pkt->rsp_dsd_count = cpu_to_le16(1); 81 ct_pkt->rsp_byte_count = cpu_to_le32(arg->rsp_size); 82 ct_pkt->cmd_byte_count = cpu_to_le32(arg->req_size); 83 84 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(arg->req_dma)); 85 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(arg->req_dma)); 86 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; 87 88 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(arg->rsp_dma)); 89 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(arg->rsp_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 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 bool lid_is_sns = false; 128 129 rval = QLA_FUNCTION_FAILED; 130 if (ms_pkt->entry_status != 0) { 131 ql_dbg(ql_dbg_disc, vha, 0x2031, 132 "%s failed, error status (%x) on port_id: %02x%02x%02x.\n", 133 routine, ms_pkt->entry_status, vha->d_id.b.domain, 134 vha->d_id.b.area, vha->d_id.b.al_pa); 135 } else { 136 if (IS_FWI2_CAPABLE(ha)) 137 comp_status = le16_to_cpu( 138 ((struct ct_entry_24xx *)ms_pkt)->comp_status); 139 else 140 comp_status = le16_to_cpu(ms_pkt->status); 141 switch (comp_status) { 142 case CS_COMPLETE: 143 case CS_DATA_UNDERRUN: 144 case CS_DATA_OVERRUN: /* Overrun? */ 145 if (ct_rsp->header.response != 146 cpu_to_be16(CT_ACCEPT_RESPONSE)) { 147 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2077, 148 "%s failed rejected request on port_id: %02x%02x%02x Completion status 0x%x, response 0x%x\n", 149 routine, vha->d_id.b.domain, 150 vha->d_id.b.area, vha->d_id.b.al_pa, 151 comp_status, ct_rsp->header.response); 152 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 153 0x2078, (uint8_t *)&ct_rsp->header, 154 sizeof(struct ct_rsp_hdr)); 155 rval = QLA_INVALID_COMMAND; 156 } else 157 rval = QLA_SUCCESS; 158 break; 159 case CS_PORT_LOGGED_OUT: 160 if (IS_FWI2_CAPABLE(ha)) { 161 if (le16_to_cpu(ms_pkt->loop_id.extended) == 162 NPH_SNS) 163 lid_is_sns = true; 164 } else { 165 if (le16_to_cpu(ms_pkt->loop_id.extended) == 166 SIMPLE_NAME_SERVER) 167 lid_is_sns = true; 168 } 169 if (lid_is_sns) { 170 ql_dbg(ql_dbg_async, vha, 0x502b, 171 "%s failed, Name server has logged out", 172 routine); 173 rval = QLA_NOT_LOGGED_IN; 174 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); 175 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); 176 } 177 break; 178 default: 179 ql_dbg(ql_dbg_disc, vha, 0x2033, 180 "%s failed, completion status (%x) on port_id: " 181 "%02x%02x%02x.\n", routine, comp_status, 182 vha->d_id.b.domain, vha->d_id.b.area, 183 vha->d_id.b.al_pa); 184 break; 185 } 186 } 187 return rval; 188 } 189 190 /** 191 * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command. 192 * @ha: HA context 193 * @fcport: fcport entry to updated 194 * 195 * Returns 0 on success. 196 */ 197 int 198 qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport) 199 { 200 int rval; 201 202 ms_iocb_entry_t *ms_pkt; 203 struct ct_sns_req *ct_req; 204 struct ct_sns_rsp *ct_rsp; 205 struct qla_hw_data *ha = vha->hw; 206 struct ct_arg arg; 207 208 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 209 return qla2x00_sns_ga_nxt(vha, fcport); 210 211 arg.iocb = ha->ms_iocb; 212 arg.req_dma = ha->ct_sns_dma; 213 arg.rsp_dma = ha->ct_sns_dma; 214 arg.req_size = GA_NXT_REQ_SIZE; 215 arg.rsp_size = GA_NXT_RSP_SIZE; 216 arg.nport_handle = NPH_SNS; 217 218 /* Issue GA_NXT */ 219 /* Prepare common MS IOCB */ 220 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 221 222 /* Prepare CT request */ 223 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GA_NXT_CMD, 224 GA_NXT_RSP_SIZE); 225 ct_rsp = &ha->ct_sns->p.rsp; 226 227 /* Prepare CT arguments -- port_id */ 228 ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain; 229 ct_req->req.port_id.port_id[1] = fcport->d_id.b.area; 230 ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa; 231 232 /* Execute MS IOCB */ 233 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 234 sizeof(ms_iocb_entry_t)); 235 if (rval != QLA_SUCCESS) { 236 /*EMPTY*/ 237 ql_dbg(ql_dbg_disc, vha, 0x2062, 238 "GA_NXT issue IOCB failed (%d).\n", rval); 239 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GA_NXT") != 240 QLA_SUCCESS) { 241 rval = QLA_FUNCTION_FAILED; 242 } else { 243 /* Populate fc_port_t entry. */ 244 fcport->d_id.b.domain = ct_rsp->rsp.ga_nxt.port_id[0]; 245 fcport->d_id.b.area = ct_rsp->rsp.ga_nxt.port_id[1]; 246 fcport->d_id.b.al_pa = ct_rsp->rsp.ga_nxt.port_id[2]; 247 248 memcpy(fcport->node_name, ct_rsp->rsp.ga_nxt.node_name, 249 WWN_SIZE); 250 memcpy(fcport->port_name, ct_rsp->rsp.ga_nxt.port_name, 251 WWN_SIZE); 252 253 fcport->fc4_type = (ct_rsp->rsp.ga_nxt.fc4_types[2] & BIT_0) ? 254 FC4_TYPE_FCP_SCSI : FC4_TYPE_OTHER; 255 256 if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE && 257 ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE) 258 fcport->d_id.b.domain = 0xf0; 259 260 ql_dbg(ql_dbg_disc, vha, 0x2063, 261 "GA_NXT entry - nn %8phN pn %8phN " 262 "port_id=%02x%02x%02x.\n", 263 fcport->node_name, fcport->port_name, 264 fcport->d_id.b.domain, fcport->d_id.b.area, 265 fcport->d_id.b.al_pa); 266 } 267 268 return (rval); 269 } 270 271 static inline int 272 qla2x00_gid_pt_rsp_size(scsi_qla_host_t *vha) 273 { 274 return vha->hw->max_fibre_devices * 4 + 16; 275 } 276 277 /** 278 * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command. 279 * @ha: HA context 280 * @list: switch info entries to populate 281 * 282 * NOTE: Non-Nx_Ports are not requested. 283 * 284 * Returns 0 on success. 285 */ 286 int 287 qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list) 288 { 289 int rval; 290 uint16_t i; 291 292 ms_iocb_entry_t *ms_pkt; 293 struct ct_sns_req *ct_req; 294 struct ct_sns_rsp *ct_rsp; 295 296 struct ct_sns_gid_pt_data *gid_data; 297 struct qla_hw_data *ha = vha->hw; 298 uint16_t gid_pt_rsp_size; 299 struct ct_arg arg; 300 301 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 302 return qla2x00_sns_gid_pt(vha, list); 303 304 gid_data = NULL; 305 gid_pt_rsp_size = qla2x00_gid_pt_rsp_size(vha); 306 307 arg.iocb = ha->ms_iocb; 308 arg.req_dma = ha->ct_sns_dma; 309 arg.rsp_dma = ha->ct_sns_dma; 310 arg.req_size = GID_PT_REQ_SIZE; 311 arg.rsp_size = gid_pt_rsp_size; 312 arg.nport_handle = NPH_SNS; 313 314 /* Issue GID_PT */ 315 /* Prepare common MS IOCB */ 316 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 317 318 /* Prepare CT request */ 319 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GID_PT_CMD, gid_pt_rsp_size); 320 ct_rsp = &ha->ct_sns->p.rsp; 321 322 /* Prepare CT arguments -- port_type */ 323 ct_req->req.gid_pt.port_type = NS_NX_PORT_TYPE; 324 325 /* Execute MS IOCB */ 326 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 327 sizeof(ms_iocb_entry_t)); 328 if (rval != QLA_SUCCESS) { 329 /*EMPTY*/ 330 ql_dbg(ql_dbg_disc, vha, 0x2055, 331 "GID_PT issue IOCB failed (%d).\n", rval); 332 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GID_PT") != 333 QLA_SUCCESS) { 334 rval = QLA_FUNCTION_FAILED; 335 } else { 336 /* Set port IDs in switch info list. */ 337 for (i = 0; i < ha->max_fibre_devices; i++) { 338 gid_data = &ct_rsp->rsp.gid_pt.entries[i]; 339 list[i].d_id.b.domain = gid_data->port_id[0]; 340 list[i].d_id.b.area = gid_data->port_id[1]; 341 list[i].d_id.b.al_pa = gid_data->port_id[2]; 342 memset(list[i].fabric_port_name, 0, WWN_SIZE); 343 list[i].fp_speed = PORT_SPEED_UNKNOWN; 344 345 /* Last one exit. */ 346 if (gid_data->control_byte & BIT_7) { 347 list[i].d_id.b.rsvd_1 = gid_data->control_byte; 348 break; 349 } 350 } 351 352 /* 353 * If we've used all available slots, then the switch is 354 * reporting back more devices than we can handle with this 355 * single call. Return a failed status, and let GA_NXT handle 356 * the overload. 357 */ 358 if (i == ha->max_fibre_devices) 359 rval = QLA_FUNCTION_FAILED; 360 } 361 362 return (rval); 363 } 364 365 /** 366 * qla2x00_gpn_id() - SNS Get Port Name (GPN_ID) query. 367 * @ha: HA context 368 * @list: switch info entries to populate 369 * 370 * Returns 0 on success. 371 */ 372 int 373 qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list) 374 { 375 int rval = QLA_SUCCESS; 376 uint16_t i; 377 378 ms_iocb_entry_t *ms_pkt; 379 struct ct_sns_req *ct_req; 380 struct ct_sns_rsp *ct_rsp; 381 struct qla_hw_data *ha = vha->hw; 382 struct ct_arg arg; 383 384 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 385 return qla2x00_sns_gpn_id(vha, list); 386 387 arg.iocb = ha->ms_iocb; 388 arg.req_dma = ha->ct_sns_dma; 389 arg.rsp_dma = ha->ct_sns_dma; 390 arg.req_size = GPN_ID_REQ_SIZE; 391 arg.rsp_size = GPN_ID_RSP_SIZE; 392 arg.nport_handle = NPH_SNS; 393 394 for (i = 0; i < ha->max_fibre_devices; i++) { 395 /* Issue GPN_ID */ 396 /* Prepare common MS IOCB */ 397 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 398 399 /* Prepare CT request */ 400 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GPN_ID_CMD, 401 GPN_ID_RSP_SIZE); 402 ct_rsp = &ha->ct_sns->p.rsp; 403 404 /* Prepare CT arguments -- port_id */ 405 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; 406 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; 407 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; 408 409 /* Execute MS IOCB */ 410 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 411 sizeof(ms_iocb_entry_t)); 412 if (rval != QLA_SUCCESS) { 413 /*EMPTY*/ 414 ql_dbg(ql_dbg_disc, vha, 0x2056, 415 "GPN_ID issue IOCB failed (%d).\n", rval); 416 break; 417 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, 418 "GPN_ID") != QLA_SUCCESS) { 419 rval = QLA_FUNCTION_FAILED; 420 break; 421 } else { 422 /* Save portname */ 423 memcpy(list[i].port_name, 424 ct_rsp->rsp.gpn_id.port_name, WWN_SIZE); 425 } 426 427 /* Last device exit. */ 428 if (list[i].d_id.b.rsvd_1 != 0) 429 break; 430 } 431 432 return (rval); 433 } 434 435 /** 436 * qla2x00_gnn_id() - SNS Get Node Name (GNN_ID) query. 437 * @ha: HA context 438 * @list: switch info entries to populate 439 * 440 * Returns 0 on success. 441 */ 442 int 443 qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list) 444 { 445 int rval = QLA_SUCCESS; 446 uint16_t i; 447 struct qla_hw_data *ha = vha->hw; 448 ms_iocb_entry_t *ms_pkt; 449 struct ct_sns_req *ct_req; 450 struct ct_sns_rsp *ct_rsp; 451 struct ct_arg arg; 452 453 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 454 return qla2x00_sns_gnn_id(vha, list); 455 456 arg.iocb = ha->ms_iocb; 457 arg.req_dma = ha->ct_sns_dma; 458 arg.rsp_dma = ha->ct_sns_dma; 459 arg.req_size = GNN_ID_REQ_SIZE; 460 arg.rsp_size = GNN_ID_RSP_SIZE; 461 arg.nport_handle = NPH_SNS; 462 463 for (i = 0; i < ha->max_fibre_devices; i++) { 464 /* Issue GNN_ID */ 465 /* Prepare common MS IOCB */ 466 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 467 468 /* Prepare CT request */ 469 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GNN_ID_CMD, 470 GNN_ID_RSP_SIZE); 471 ct_rsp = &ha->ct_sns->p.rsp; 472 473 /* Prepare CT arguments -- port_id */ 474 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; 475 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; 476 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; 477 478 /* Execute MS IOCB */ 479 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 480 sizeof(ms_iocb_entry_t)); 481 if (rval != QLA_SUCCESS) { 482 /*EMPTY*/ 483 ql_dbg(ql_dbg_disc, vha, 0x2057, 484 "GNN_ID issue IOCB failed (%d).\n", rval); 485 break; 486 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, 487 "GNN_ID") != QLA_SUCCESS) { 488 rval = QLA_FUNCTION_FAILED; 489 break; 490 } else { 491 /* Save nodename */ 492 memcpy(list[i].node_name, 493 ct_rsp->rsp.gnn_id.node_name, WWN_SIZE); 494 495 ql_dbg(ql_dbg_disc, vha, 0x2058, 496 "GID_PT entry - nn %8phN pn %8phN " 497 "portid=%02x%02x%02x.\n", 498 list[i].node_name, list[i].port_name, 499 list[i].d_id.b.domain, list[i].d_id.b.area, 500 list[i].d_id.b.al_pa); 501 } 502 503 /* Last device exit. */ 504 if (list[i].d_id.b.rsvd_1 != 0) 505 break; 506 } 507 508 return (rval); 509 } 510 511 /** 512 * qla2x00_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. 513 * @ha: HA context 514 * 515 * Returns 0 on success. 516 */ 517 int 518 qla2x00_rft_id(scsi_qla_host_t *vha) 519 { 520 int rval; 521 struct qla_hw_data *ha = vha->hw; 522 ms_iocb_entry_t *ms_pkt; 523 struct ct_sns_req *ct_req; 524 struct ct_sns_rsp *ct_rsp; 525 struct ct_arg arg; 526 527 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 528 return qla2x00_sns_rft_id(vha); 529 530 arg.iocb = ha->ms_iocb; 531 arg.req_dma = ha->ct_sns_dma; 532 arg.rsp_dma = ha->ct_sns_dma; 533 arg.req_size = RFT_ID_REQ_SIZE; 534 arg.rsp_size = RFT_ID_RSP_SIZE; 535 arg.nport_handle = NPH_SNS; 536 537 /* Issue RFT_ID */ 538 /* Prepare common MS IOCB */ 539 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 540 541 /* Prepare CT request */ 542 ct_req = qla2x00_prep_ct_req(ha->ct_sns, RFT_ID_CMD, 543 RFT_ID_RSP_SIZE); 544 ct_rsp = &ha->ct_sns->p.rsp; 545 546 /* Prepare CT arguments -- port_id, FC-4 types */ 547 ct_req->req.rft_id.port_id[0] = vha->d_id.b.domain; 548 ct_req->req.rft_id.port_id[1] = vha->d_id.b.area; 549 ct_req->req.rft_id.port_id[2] = vha->d_id.b.al_pa; 550 551 ct_req->req.rft_id.fc4_types[2] = 0x01; /* FCP-3 */ 552 553 if (vha->flags.nvme_enabled) 554 ct_req->req.rft_id.fc4_types[6] = 1; /* NVMe type 28h */ 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, 0x2043, 561 "RFT_ID issue IOCB failed (%d).\n", rval); 562 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RFT_ID") != 563 QLA_SUCCESS) { 564 rval = QLA_FUNCTION_FAILED; 565 } else { 566 ql_dbg(ql_dbg_disc, vha, 0x2044, 567 "RFT_ID exiting normally.\n"); 568 } 569 570 return (rval); 571 } 572 573 /** 574 * qla2x00_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the HBA. 575 * @ha: HA context 576 * 577 * Returns 0 on success. 578 */ 579 int 580 qla2x00_rff_id(scsi_qla_host_t *vha, u8 type) 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 struct ct_arg arg; 588 589 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 590 ql_dbg(ql_dbg_disc, vha, 0x2046, 591 "RFF_ID call not supported on ISP2100/ISP2200.\n"); 592 return (QLA_SUCCESS); 593 } 594 595 arg.iocb = ha->ms_iocb; 596 arg.req_dma = ha->ct_sns_dma; 597 arg.rsp_dma = ha->ct_sns_dma; 598 arg.req_size = RFF_ID_REQ_SIZE; 599 arg.rsp_size = RFF_ID_RSP_SIZE; 600 arg.nport_handle = NPH_SNS; 601 602 /* Issue RFF_ID */ 603 /* Prepare common MS IOCB */ 604 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 605 606 /* Prepare CT request */ 607 ct_req = qla2x00_prep_ct_req(ha->ct_sns, RFF_ID_CMD, 608 RFF_ID_RSP_SIZE); 609 ct_rsp = &ha->ct_sns->p.rsp; 610 611 /* Prepare CT arguments -- port_id, FC-4 feature, FC-4 type */ 612 ct_req->req.rff_id.port_id[0] = vha->d_id.b.domain; 613 ct_req->req.rff_id.port_id[1] = vha->d_id.b.area; 614 ct_req->req.rff_id.port_id[2] = vha->d_id.b.al_pa; 615 616 qlt_rff_id(vha, ct_req); 617 618 ct_req->req.rff_id.fc4_type = type; /* SCSI - FCP */ 619 620 /* Execute MS IOCB */ 621 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 622 sizeof(ms_iocb_entry_t)); 623 if (rval != QLA_SUCCESS) { 624 /*EMPTY*/ 625 ql_dbg(ql_dbg_disc, vha, 0x2047, 626 "RFF_ID issue IOCB failed (%d).\n", rval); 627 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RFF_ID") != 628 QLA_SUCCESS) { 629 rval = QLA_FUNCTION_FAILED; 630 } else { 631 ql_dbg(ql_dbg_disc, vha, 0x2048, 632 "RFF_ID exiting normally.\n"); 633 } 634 635 return (rval); 636 } 637 638 /** 639 * qla2x00_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA. 640 * @ha: HA context 641 * 642 * Returns 0 on success. 643 */ 644 int 645 qla2x00_rnn_id(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 struct ct_arg arg; 653 654 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 655 return qla2x00_sns_rnn_id(vha); 656 657 arg.iocb = ha->ms_iocb; 658 arg.req_dma = ha->ct_sns_dma; 659 arg.rsp_dma = ha->ct_sns_dma; 660 arg.req_size = RNN_ID_REQ_SIZE; 661 arg.rsp_size = RNN_ID_RSP_SIZE; 662 arg.nport_handle = NPH_SNS; 663 664 /* Issue RNN_ID */ 665 /* Prepare common MS IOCB */ 666 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 667 668 /* Prepare CT request */ 669 ct_req = qla2x00_prep_ct_req(ha->ct_sns, RNN_ID_CMD, RNN_ID_RSP_SIZE); 670 ct_rsp = &ha->ct_sns->p.rsp; 671 672 /* Prepare CT arguments -- port_id, node_name */ 673 ct_req->req.rnn_id.port_id[0] = vha->d_id.b.domain; 674 ct_req->req.rnn_id.port_id[1] = vha->d_id.b.area; 675 ct_req->req.rnn_id.port_id[2] = vha->d_id.b.al_pa; 676 677 memcpy(ct_req->req.rnn_id.node_name, vha->node_name, WWN_SIZE); 678 679 /* Execute MS IOCB */ 680 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 681 sizeof(ms_iocb_entry_t)); 682 if (rval != QLA_SUCCESS) { 683 /*EMPTY*/ 684 ql_dbg(ql_dbg_disc, vha, 0x204d, 685 "RNN_ID issue IOCB failed (%d).\n", rval); 686 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RNN_ID") != 687 QLA_SUCCESS) { 688 rval = QLA_FUNCTION_FAILED; 689 } else { 690 ql_dbg(ql_dbg_disc, vha, 0x204e, 691 "RNN_ID exiting normally.\n"); 692 } 693 694 return (rval); 695 } 696 697 void 698 qla2x00_get_sym_node_name(scsi_qla_host_t *vha, uint8_t *snn, size_t size) 699 { 700 struct qla_hw_data *ha = vha->hw; 701 702 if (IS_QLAFX00(ha)) 703 snprintf(snn, size, "%s FW:v%s DVR:v%s", ha->model_number, 704 ha->mr.fw_version, qla2x00_version_str); 705 else 706 snprintf(snn, size, 707 "%s FW:v%d.%02d.%02d DVR:v%s", ha->model_number, 708 ha->fw_major_version, ha->fw_minor_version, 709 ha->fw_subminor_version, qla2x00_version_str); 710 } 711 712 /** 713 * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA. 714 * @ha: HA context 715 * 716 * Returns 0 on success. 717 */ 718 int 719 qla2x00_rsnn_nn(scsi_qla_host_t *vha) 720 { 721 int rval; 722 struct qla_hw_data *ha = vha->hw; 723 ms_iocb_entry_t *ms_pkt; 724 struct ct_sns_req *ct_req; 725 struct ct_sns_rsp *ct_rsp; 726 struct ct_arg arg; 727 728 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 729 ql_dbg(ql_dbg_disc, vha, 0x2050, 730 "RSNN_ID call unsupported on ISP2100/ISP2200.\n"); 731 return (QLA_SUCCESS); 732 } 733 734 arg.iocb = ha->ms_iocb; 735 arg.req_dma = ha->ct_sns_dma; 736 arg.rsp_dma = ha->ct_sns_dma; 737 arg.req_size = 0; 738 arg.rsp_size = RSNN_NN_RSP_SIZE; 739 arg.nport_handle = NPH_SNS; 740 741 /* Issue RSNN_NN */ 742 /* Prepare common MS IOCB */ 743 /* Request size adjusted after CT preparation */ 744 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 745 746 /* Prepare CT request */ 747 ct_req = qla2x00_prep_ct_req(ha->ct_sns, RSNN_NN_CMD, 748 RSNN_NN_RSP_SIZE); 749 ct_rsp = &ha->ct_sns->p.rsp; 750 751 /* Prepare CT arguments -- node_name, symbolic node_name, size */ 752 memcpy(ct_req->req.rsnn_nn.node_name, vha->node_name, WWN_SIZE); 753 754 /* Prepare the Symbolic Node Name */ 755 qla2x00_get_sym_node_name(vha, ct_req->req.rsnn_nn.sym_node_name, 756 sizeof(ct_req->req.rsnn_nn.sym_node_name)); 757 758 /* Calculate SNN length */ 759 ct_req->req.rsnn_nn.name_len = 760 (uint8_t)strlen(ct_req->req.rsnn_nn.sym_node_name); 761 762 /* Update MS IOCB request */ 763 ms_pkt->req_bytecount = 764 cpu_to_le32(24 + 1 + ct_req->req.rsnn_nn.name_len); 765 ms_pkt->dseg_req_length = ms_pkt->req_bytecount; 766 767 /* Execute MS IOCB */ 768 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 769 sizeof(ms_iocb_entry_t)); 770 if (rval != QLA_SUCCESS) { 771 /*EMPTY*/ 772 ql_dbg(ql_dbg_disc, vha, 0x2051, 773 "RSNN_NN issue IOCB failed (%d).\n", rval); 774 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RSNN_NN") != 775 QLA_SUCCESS) { 776 rval = QLA_FUNCTION_FAILED; 777 } else { 778 ql_dbg(ql_dbg_disc, vha, 0x2052, 779 "RSNN_NN exiting normally.\n"); 780 } 781 782 return (rval); 783 } 784 785 /** 786 * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query. 787 * @ha: HA context 788 * @cmd: GS command 789 * @scmd_len: Subcommand length 790 * @data_size: response size in bytes 791 * 792 * Returns a pointer to the @ha's sns_cmd. 793 */ 794 static inline struct sns_cmd_pkt * 795 qla2x00_prep_sns_cmd(scsi_qla_host_t *vha, uint16_t cmd, uint16_t scmd_len, 796 uint16_t data_size) 797 { 798 uint16_t wc; 799 struct sns_cmd_pkt *sns_cmd; 800 struct qla_hw_data *ha = vha->hw; 801 802 sns_cmd = ha->sns_cmd; 803 memset(sns_cmd, 0, sizeof(struct sns_cmd_pkt)); 804 wc = data_size / 2; /* Size in 16bit words. */ 805 sns_cmd->p.cmd.buffer_length = cpu_to_le16(wc); 806 sns_cmd->p.cmd.buffer_address[0] = cpu_to_le32(LSD(ha->sns_cmd_dma)); 807 sns_cmd->p.cmd.buffer_address[1] = cpu_to_le32(MSD(ha->sns_cmd_dma)); 808 sns_cmd->p.cmd.subcommand_length = cpu_to_le16(scmd_len); 809 sns_cmd->p.cmd.subcommand = cpu_to_le16(cmd); 810 wc = (data_size - 16) / 4; /* Size in 32bit words. */ 811 sns_cmd->p.cmd.size = cpu_to_le16(wc); 812 813 vha->qla_stats.control_requests++; 814 815 return (sns_cmd); 816 } 817 818 /** 819 * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command. 820 * @ha: HA context 821 * @fcport: fcport entry to updated 822 * 823 * This command uses the old Exectute SNS Command mailbox routine. 824 * 825 * Returns 0 on success. 826 */ 827 static int 828 qla2x00_sns_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport) 829 { 830 int rval = QLA_SUCCESS; 831 struct qla_hw_data *ha = vha->hw; 832 struct sns_cmd_pkt *sns_cmd; 833 834 /* Issue GA_NXT. */ 835 /* Prepare SNS command request. */ 836 sns_cmd = qla2x00_prep_sns_cmd(vha, GA_NXT_CMD, GA_NXT_SNS_SCMD_LEN, 837 GA_NXT_SNS_DATA_SIZE); 838 839 /* Prepare SNS command arguments -- port_id. */ 840 sns_cmd->p.cmd.param[0] = fcport->d_id.b.al_pa; 841 sns_cmd->p.cmd.param[1] = fcport->d_id.b.area; 842 sns_cmd->p.cmd.param[2] = fcport->d_id.b.domain; 843 844 /* Execute SNS command. */ 845 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GA_NXT_SNS_CMD_SIZE / 2, 846 sizeof(struct sns_cmd_pkt)); 847 if (rval != QLA_SUCCESS) { 848 /*EMPTY*/ 849 ql_dbg(ql_dbg_disc, vha, 0x205f, 850 "GA_NXT Send SNS failed (%d).\n", rval); 851 } else if (sns_cmd->p.gan_data[8] != 0x80 || 852 sns_cmd->p.gan_data[9] != 0x02) { 853 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2084, 854 "GA_NXT failed, rejected request ga_nxt_rsp:\n"); 855 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2074, 856 sns_cmd->p.gan_data, 16); 857 rval = QLA_FUNCTION_FAILED; 858 } else { 859 /* Populate fc_port_t entry. */ 860 fcport->d_id.b.domain = sns_cmd->p.gan_data[17]; 861 fcport->d_id.b.area = sns_cmd->p.gan_data[18]; 862 fcport->d_id.b.al_pa = sns_cmd->p.gan_data[19]; 863 864 memcpy(fcport->node_name, &sns_cmd->p.gan_data[284], WWN_SIZE); 865 memcpy(fcport->port_name, &sns_cmd->p.gan_data[20], WWN_SIZE); 866 867 if (sns_cmd->p.gan_data[16] != NS_N_PORT_TYPE && 868 sns_cmd->p.gan_data[16] != NS_NL_PORT_TYPE) 869 fcport->d_id.b.domain = 0xf0; 870 871 ql_dbg(ql_dbg_disc, vha, 0x2061, 872 "GA_NXT entry - nn %8phN pn %8phN " 873 "port_id=%02x%02x%02x.\n", 874 fcport->node_name, fcport->port_name, 875 fcport->d_id.b.domain, fcport->d_id.b.area, 876 fcport->d_id.b.al_pa); 877 } 878 879 return (rval); 880 } 881 882 /** 883 * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command. 884 * @ha: HA context 885 * @list: switch info entries to populate 886 * 887 * This command uses the old Exectute SNS Command mailbox routine. 888 * 889 * NOTE: Non-Nx_Ports are not requested. 890 * 891 * Returns 0 on success. 892 */ 893 static int 894 qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list) 895 { 896 int rval; 897 struct qla_hw_data *ha = vha->hw; 898 uint16_t i; 899 uint8_t *entry; 900 struct sns_cmd_pkt *sns_cmd; 901 uint16_t gid_pt_sns_data_size; 902 903 gid_pt_sns_data_size = qla2x00_gid_pt_rsp_size(vha); 904 905 /* Issue GID_PT. */ 906 /* Prepare SNS command request. */ 907 sns_cmd = qla2x00_prep_sns_cmd(vha, GID_PT_CMD, GID_PT_SNS_SCMD_LEN, 908 gid_pt_sns_data_size); 909 910 /* Prepare SNS command arguments -- port_type. */ 911 sns_cmd->p.cmd.param[0] = NS_NX_PORT_TYPE; 912 913 /* Execute SNS command. */ 914 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GID_PT_SNS_CMD_SIZE / 2, 915 sizeof(struct sns_cmd_pkt)); 916 if (rval != QLA_SUCCESS) { 917 /*EMPTY*/ 918 ql_dbg(ql_dbg_disc, vha, 0x206d, 919 "GID_PT Send SNS failed (%d).\n", rval); 920 } else if (sns_cmd->p.gid_data[8] != 0x80 || 921 sns_cmd->p.gid_data[9] != 0x02) { 922 ql_dbg(ql_dbg_disc, vha, 0x202f, 923 "GID_PT failed, rejected request, gid_rsp:\n"); 924 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2081, 925 sns_cmd->p.gid_data, 16); 926 rval = QLA_FUNCTION_FAILED; 927 } else { 928 /* Set port IDs in switch info list. */ 929 for (i = 0; i < ha->max_fibre_devices; i++) { 930 entry = &sns_cmd->p.gid_data[(i * 4) + 16]; 931 list[i].d_id.b.domain = entry[1]; 932 list[i].d_id.b.area = entry[2]; 933 list[i].d_id.b.al_pa = entry[3]; 934 935 /* Last one exit. */ 936 if (entry[0] & BIT_7) { 937 list[i].d_id.b.rsvd_1 = entry[0]; 938 break; 939 } 940 } 941 942 /* 943 * If we've used all available slots, then the switch is 944 * reporting back more devices that we can handle with this 945 * single call. Return a failed status, and let GA_NXT handle 946 * the overload. 947 */ 948 if (i == ha->max_fibre_devices) 949 rval = QLA_FUNCTION_FAILED; 950 } 951 952 return (rval); 953 } 954 955 /** 956 * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query. 957 * @ha: HA context 958 * @list: switch info entries to populate 959 * 960 * This command uses the old Exectute SNS Command mailbox routine. 961 * 962 * Returns 0 on success. 963 */ 964 static int 965 qla2x00_sns_gpn_id(scsi_qla_host_t *vha, sw_info_t *list) 966 { 967 int rval = QLA_SUCCESS; 968 struct qla_hw_data *ha = vha->hw; 969 uint16_t i; 970 struct sns_cmd_pkt *sns_cmd; 971 972 for (i = 0; i < ha->max_fibre_devices; i++) { 973 /* Issue GPN_ID */ 974 /* Prepare SNS command request. */ 975 sns_cmd = qla2x00_prep_sns_cmd(vha, GPN_ID_CMD, 976 GPN_ID_SNS_SCMD_LEN, GPN_ID_SNS_DATA_SIZE); 977 978 /* Prepare SNS command arguments -- port_id. */ 979 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa; 980 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area; 981 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain; 982 983 /* Execute SNS command. */ 984 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, 985 GPN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt)); 986 if (rval != QLA_SUCCESS) { 987 /*EMPTY*/ 988 ql_dbg(ql_dbg_disc, vha, 0x2032, 989 "GPN_ID Send SNS failed (%d).\n", rval); 990 } else if (sns_cmd->p.gpn_data[8] != 0x80 || 991 sns_cmd->p.gpn_data[9] != 0x02) { 992 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207e, 993 "GPN_ID failed, rejected request, gpn_rsp:\n"); 994 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207f, 995 sns_cmd->p.gpn_data, 16); 996 rval = QLA_FUNCTION_FAILED; 997 } else { 998 /* Save portname */ 999 memcpy(list[i].port_name, &sns_cmd->p.gpn_data[16], 1000 WWN_SIZE); 1001 } 1002 1003 /* Last device exit. */ 1004 if (list[i].d_id.b.rsvd_1 != 0) 1005 break; 1006 } 1007 1008 return (rval); 1009 } 1010 1011 /** 1012 * qla2x00_sns_gnn_id() - SNS Get Node Name (GNN_ID) query. 1013 * @ha: HA context 1014 * @list: switch info entries to populate 1015 * 1016 * This command uses the old Exectute SNS Command mailbox routine. 1017 * 1018 * Returns 0 on success. 1019 */ 1020 static int 1021 qla2x00_sns_gnn_id(scsi_qla_host_t *vha, sw_info_t *list) 1022 { 1023 int rval = QLA_SUCCESS; 1024 struct qla_hw_data *ha = vha->hw; 1025 uint16_t i; 1026 struct sns_cmd_pkt *sns_cmd; 1027 1028 for (i = 0; i < ha->max_fibre_devices; i++) { 1029 /* Issue GNN_ID */ 1030 /* Prepare SNS command request. */ 1031 sns_cmd = qla2x00_prep_sns_cmd(vha, GNN_ID_CMD, 1032 GNN_ID_SNS_SCMD_LEN, GNN_ID_SNS_DATA_SIZE); 1033 1034 /* Prepare SNS command arguments -- port_id. */ 1035 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa; 1036 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area; 1037 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain; 1038 1039 /* Execute SNS command. */ 1040 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, 1041 GNN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt)); 1042 if (rval != QLA_SUCCESS) { 1043 /*EMPTY*/ 1044 ql_dbg(ql_dbg_disc, vha, 0x203f, 1045 "GNN_ID Send SNS failed (%d).\n", rval); 1046 } else if (sns_cmd->p.gnn_data[8] != 0x80 || 1047 sns_cmd->p.gnn_data[9] != 0x02) { 1048 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2082, 1049 "GNN_ID failed, rejected request, gnn_rsp:\n"); 1050 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207a, 1051 sns_cmd->p.gnn_data, 16); 1052 rval = QLA_FUNCTION_FAILED; 1053 } else { 1054 /* Save nodename */ 1055 memcpy(list[i].node_name, &sns_cmd->p.gnn_data[16], 1056 WWN_SIZE); 1057 1058 ql_dbg(ql_dbg_disc, vha, 0x206e, 1059 "GID_PT entry - nn %8phN pn %8phN " 1060 "port_id=%02x%02x%02x.\n", 1061 list[i].node_name, list[i].port_name, 1062 list[i].d_id.b.domain, list[i].d_id.b.area, 1063 list[i].d_id.b.al_pa); 1064 } 1065 1066 /* Last device exit. */ 1067 if (list[i].d_id.b.rsvd_1 != 0) 1068 break; 1069 } 1070 1071 return (rval); 1072 } 1073 1074 /** 1075 * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. 1076 * @ha: HA context 1077 * 1078 * This command uses the old Exectute SNS Command mailbox routine. 1079 * 1080 * Returns 0 on success. 1081 */ 1082 static int 1083 qla2x00_sns_rft_id(scsi_qla_host_t *vha) 1084 { 1085 int rval; 1086 struct qla_hw_data *ha = vha->hw; 1087 struct sns_cmd_pkt *sns_cmd; 1088 1089 /* Issue RFT_ID. */ 1090 /* Prepare SNS command request. */ 1091 sns_cmd = qla2x00_prep_sns_cmd(vha, RFT_ID_CMD, RFT_ID_SNS_SCMD_LEN, 1092 RFT_ID_SNS_DATA_SIZE); 1093 1094 /* Prepare SNS command arguments -- port_id, FC-4 types */ 1095 sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa; 1096 sns_cmd->p.cmd.param[1] = vha->d_id.b.area; 1097 sns_cmd->p.cmd.param[2] = vha->d_id.b.domain; 1098 1099 sns_cmd->p.cmd.param[5] = 0x01; /* FCP-3 */ 1100 1101 /* Execute SNS command. */ 1102 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RFT_ID_SNS_CMD_SIZE / 2, 1103 sizeof(struct sns_cmd_pkt)); 1104 if (rval != QLA_SUCCESS) { 1105 /*EMPTY*/ 1106 ql_dbg(ql_dbg_disc, vha, 0x2060, 1107 "RFT_ID Send SNS failed (%d).\n", rval); 1108 } else if (sns_cmd->p.rft_data[8] != 0x80 || 1109 sns_cmd->p.rft_data[9] != 0x02) { 1110 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2083, 1111 "RFT_ID failed, rejected request rft_rsp:\n"); 1112 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2080, 1113 sns_cmd->p.rft_data, 16); 1114 rval = QLA_FUNCTION_FAILED; 1115 } else { 1116 ql_dbg(ql_dbg_disc, vha, 0x2073, 1117 "RFT_ID exiting normally.\n"); 1118 } 1119 1120 return (rval); 1121 } 1122 1123 /** 1124 * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA. 1125 * HBA. 1126 * @ha: HA context 1127 * 1128 * This command uses the old Exectute SNS Command mailbox routine. 1129 * 1130 * Returns 0 on success. 1131 */ 1132 static int 1133 qla2x00_sns_rnn_id(scsi_qla_host_t *vha) 1134 { 1135 int rval; 1136 struct qla_hw_data *ha = vha->hw; 1137 struct sns_cmd_pkt *sns_cmd; 1138 1139 /* Issue RNN_ID. */ 1140 /* Prepare SNS command request. */ 1141 sns_cmd = qla2x00_prep_sns_cmd(vha, RNN_ID_CMD, RNN_ID_SNS_SCMD_LEN, 1142 RNN_ID_SNS_DATA_SIZE); 1143 1144 /* Prepare SNS command arguments -- port_id, nodename. */ 1145 sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa; 1146 sns_cmd->p.cmd.param[1] = vha->d_id.b.area; 1147 sns_cmd->p.cmd.param[2] = vha->d_id.b.domain; 1148 1149 sns_cmd->p.cmd.param[4] = vha->node_name[7]; 1150 sns_cmd->p.cmd.param[5] = vha->node_name[6]; 1151 sns_cmd->p.cmd.param[6] = vha->node_name[5]; 1152 sns_cmd->p.cmd.param[7] = vha->node_name[4]; 1153 sns_cmd->p.cmd.param[8] = vha->node_name[3]; 1154 sns_cmd->p.cmd.param[9] = vha->node_name[2]; 1155 sns_cmd->p.cmd.param[10] = vha->node_name[1]; 1156 sns_cmd->p.cmd.param[11] = vha->node_name[0]; 1157 1158 /* Execute SNS command. */ 1159 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RNN_ID_SNS_CMD_SIZE / 2, 1160 sizeof(struct sns_cmd_pkt)); 1161 if (rval != QLA_SUCCESS) { 1162 /*EMPTY*/ 1163 ql_dbg(ql_dbg_disc, vha, 0x204a, 1164 "RNN_ID Send SNS failed (%d).\n", rval); 1165 } else if (sns_cmd->p.rnn_data[8] != 0x80 || 1166 sns_cmd->p.rnn_data[9] != 0x02) { 1167 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207b, 1168 "RNN_ID failed, rejected request, rnn_rsp:\n"); 1169 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207c, 1170 sns_cmd->p.rnn_data, 16); 1171 rval = QLA_FUNCTION_FAILED; 1172 } else { 1173 ql_dbg(ql_dbg_disc, vha, 0x204c, 1174 "RNN_ID exiting normally.\n"); 1175 } 1176 1177 return (rval); 1178 } 1179 1180 /** 1181 * qla2x00_mgmt_svr_login() - Login to fabric Management Service. 1182 * @ha: HA context 1183 * 1184 * Returns 0 on success. 1185 */ 1186 int 1187 qla2x00_mgmt_svr_login(scsi_qla_host_t *vha) 1188 { 1189 int ret, rval; 1190 uint16_t mb[MAILBOX_REGISTER_COUNT]; 1191 struct qla_hw_data *ha = vha->hw; 1192 ret = QLA_SUCCESS; 1193 if (vha->flags.management_server_logged_in) 1194 return ret; 1195 1196 rval = ha->isp_ops->fabric_login(vha, vha->mgmt_svr_loop_id, 0xff, 0xff, 1197 0xfa, mb, BIT_1); 1198 if (rval != QLA_SUCCESS || mb[0] != MBS_COMMAND_COMPLETE) { 1199 if (rval == QLA_MEMORY_ALLOC_FAILED) 1200 ql_dbg(ql_dbg_disc, vha, 0x2085, 1201 "Failed management_server login: loopid=%x " 1202 "rval=%d\n", vha->mgmt_svr_loop_id, rval); 1203 else 1204 ql_dbg(ql_dbg_disc, vha, 0x2024, 1205 "Failed management_server login: loopid=%x " 1206 "mb[0]=%x mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x.\n", 1207 vha->mgmt_svr_loop_id, mb[0], mb[1], mb[2], mb[6], 1208 mb[7]); 1209 ret = QLA_FUNCTION_FAILED; 1210 } else 1211 vha->flags.management_server_logged_in = 1; 1212 1213 return ret; 1214 } 1215 1216 /** 1217 * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query. 1218 * @ha: HA context 1219 * @req_size: request size in bytes 1220 * @rsp_size: response size in bytes 1221 * 1222 * Returns a pointer to the @ha's ms_iocb. 1223 */ 1224 void * 1225 qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size, 1226 uint32_t rsp_size) 1227 { 1228 ms_iocb_entry_t *ms_pkt; 1229 struct qla_hw_data *ha = vha->hw; 1230 ms_pkt = ha->ms_iocb; 1231 memset(ms_pkt, 0, sizeof(ms_iocb_entry_t)); 1232 1233 ms_pkt->entry_type = MS_IOCB_TYPE; 1234 ms_pkt->entry_count = 1; 1235 SET_TARGET_ID(ha, ms_pkt->loop_id, vha->mgmt_svr_loop_id); 1236 ms_pkt->control_flags = cpu_to_le16(CF_READ | CF_HEAD_TAG); 1237 ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); 1238 ms_pkt->cmd_dsd_count = cpu_to_le16(1); 1239 ms_pkt->total_dsd_count = cpu_to_le16(2); 1240 ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size); 1241 ms_pkt->req_bytecount = cpu_to_le32(req_size); 1242 1243 ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 1244 ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 1245 ms_pkt->dseg_req_length = ms_pkt->req_bytecount; 1246 1247 ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 1248 ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 1249 ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount; 1250 1251 return ms_pkt; 1252 } 1253 1254 /** 1255 * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query. 1256 * @ha: HA context 1257 * @req_size: request size in bytes 1258 * @rsp_size: response size in bytes 1259 * 1260 * Returns a pointer to the @ha's ms_iocb. 1261 */ 1262 void * 1263 qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size, 1264 uint32_t rsp_size) 1265 { 1266 struct ct_entry_24xx *ct_pkt; 1267 struct qla_hw_data *ha = vha->hw; 1268 1269 ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; 1270 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx)); 1271 1272 ct_pkt->entry_type = CT_IOCB_TYPE; 1273 ct_pkt->entry_count = 1; 1274 ct_pkt->nport_handle = cpu_to_le16(vha->mgmt_svr_loop_id); 1275 ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); 1276 ct_pkt->cmd_dsd_count = cpu_to_le16(1); 1277 ct_pkt->rsp_dsd_count = cpu_to_le16(1); 1278 ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size); 1279 ct_pkt->cmd_byte_count = cpu_to_le32(req_size); 1280 1281 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 1282 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 1283 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; 1284 1285 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 1286 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 1287 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; 1288 ct_pkt->vp_index = vha->vp_idx; 1289 1290 return ct_pkt; 1291 } 1292 1293 static inline ms_iocb_entry_t * 1294 qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size) 1295 { 1296 struct qla_hw_data *ha = vha->hw; 1297 ms_iocb_entry_t *ms_pkt = ha->ms_iocb; 1298 struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; 1299 1300 if (IS_FWI2_CAPABLE(ha)) { 1301 ct_pkt->cmd_byte_count = cpu_to_le32(req_size); 1302 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; 1303 } else { 1304 ms_pkt->req_bytecount = cpu_to_le32(req_size); 1305 ms_pkt->dseg_req_length = ms_pkt->req_bytecount; 1306 } 1307 1308 return ms_pkt; 1309 } 1310 1311 /** 1312 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query. 1313 * @ct_req: CT request buffer 1314 * @cmd: GS command 1315 * @rsp_size: response size in bytes 1316 * 1317 * Returns a pointer to the intitialized @ct_req. 1318 */ 1319 static inline struct ct_sns_req * 1320 qla2x00_prep_ct_fdmi_req(struct ct_sns_pkt *p, uint16_t cmd, 1321 uint16_t rsp_size) 1322 { 1323 memset(p, 0, sizeof(struct ct_sns_pkt)); 1324 1325 p->p.req.header.revision = 0x01; 1326 p->p.req.header.gs_type = 0xFA; 1327 p->p.req.header.gs_subtype = 0x10; 1328 p->p.req.command = cpu_to_be16(cmd); 1329 p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); 1330 1331 return &p->p.req; 1332 } 1333 1334 /** 1335 * qla2x00_fdmi_rhba() - 1336 * @ha: HA context 1337 * 1338 * Returns 0 on success. 1339 */ 1340 static int 1341 qla2x00_fdmi_rhba(scsi_qla_host_t *vha) 1342 { 1343 int rval, alen; 1344 uint32_t size, sn; 1345 1346 ms_iocb_entry_t *ms_pkt; 1347 struct ct_sns_req *ct_req; 1348 struct ct_sns_rsp *ct_rsp; 1349 void *entries; 1350 struct ct_fdmi_hba_attr *eiter; 1351 struct qla_hw_data *ha = vha->hw; 1352 1353 /* Issue RHBA */ 1354 /* Prepare common MS IOCB */ 1355 /* Request size adjusted after CT preparation */ 1356 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE); 1357 1358 /* Prepare CT request */ 1359 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RHBA_CMD, RHBA_RSP_SIZE); 1360 ct_rsp = &ha->ct_sns->p.rsp; 1361 1362 /* Prepare FDMI command arguments -- attribute block, attributes. */ 1363 memcpy(ct_req->req.rhba.hba_identifier, vha->port_name, WWN_SIZE); 1364 ct_req->req.rhba.entry_count = cpu_to_be32(1); 1365 memcpy(ct_req->req.rhba.port_name, vha->port_name, WWN_SIZE); 1366 size = 2 * WWN_SIZE + 4 + 4; 1367 1368 /* Attributes */ 1369 ct_req->req.rhba.attrs.count = 1370 cpu_to_be32(FDMI_HBA_ATTR_COUNT); 1371 entries = ct_req->req.rhba.hba_identifier; 1372 1373 /* Nodename. */ 1374 eiter = entries + size; 1375 eiter->type = cpu_to_be16(FDMI_HBA_NODE_NAME); 1376 eiter->len = cpu_to_be16(4 + WWN_SIZE); 1377 memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE); 1378 size += 4 + WWN_SIZE; 1379 1380 ql_dbg(ql_dbg_disc, vha, 0x2025, 1381 "NodeName = %8phN.\n", eiter->a.node_name); 1382 1383 /* Manufacturer. */ 1384 eiter = entries + size; 1385 eiter->type = cpu_to_be16(FDMI_HBA_MANUFACTURER); 1386 alen = strlen(QLA2XXX_MANUFACTURER); 1387 snprintf(eiter->a.manufacturer, sizeof(eiter->a.manufacturer), 1388 "%s", "QLogic Corporation"); 1389 alen += 4 - (alen & 3); 1390 eiter->len = cpu_to_be16(4 + alen); 1391 size += 4 + alen; 1392 1393 ql_dbg(ql_dbg_disc, vha, 0x2026, 1394 "Manufacturer = %s.\n", eiter->a.manufacturer); 1395 1396 /* Serial number. */ 1397 eiter = entries + size; 1398 eiter->type = cpu_to_be16(FDMI_HBA_SERIAL_NUMBER); 1399 if (IS_FWI2_CAPABLE(ha)) 1400 qla2xxx_get_vpd_field(vha, "SN", eiter->a.serial_num, 1401 sizeof(eiter->a.serial_num)); 1402 else { 1403 sn = ((ha->serial0 & 0x1f) << 16) | 1404 (ha->serial2 << 8) | ha->serial1; 1405 snprintf(eiter->a.serial_num, sizeof(eiter->a.serial_num), 1406 "%c%05d", 'A' + sn / 100000, sn % 100000); 1407 } 1408 alen = strlen(eiter->a.serial_num); 1409 alen += 4 - (alen & 3); 1410 eiter->len = cpu_to_be16(4 + alen); 1411 size += 4 + alen; 1412 1413 ql_dbg(ql_dbg_disc, vha, 0x2027, 1414 "Serial no. = %s.\n", eiter->a.serial_num); 1415 1416 /* Model name. */ 1417 eiter = entries + size; 1418 eiter->type = cpu_to_be16(FDMI_HBA_MODEL); 1419 snprintf(eiter->a.model, sizeof(eiter->a.model), 1420 "%s", ha->model_number); 1421 alen = strlen(eiter->a.model); 1422 alen += 4 - (alen & 3); 1423 eiter->len = cpu_to_be16(4 + alen); 1424 size += 4 + alen; 1425 1426 ql_dbg(ql_dbg_disc, vha, 0x2028, 1427 "Model Name = %s.\n", eiter->a.model); 1428 1429 /* Model description. */ 1430 eiter = entries + size; 1431 eiter->type = cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION); 1432 snprintf(eiter->a.model_desc, sizeof(eiter->a.model_desc), 1433 "%s", ha->model_desc); 1434 alen = strlen(eiter->a.model_desc); 1435 alen += 4 - (alen & 3); 1436 eiter->len = cpu_to_be16(4 + alen); 1437 size += 4 + alen; 1438 1439 ql_dbg(ql_dbg_disc, vha, 0x2029, 1440 "Model Desc = %s.\n", eiter->a.model_desc); 1441 1442 /* Hardware version. */ 1443 eiter = entries + size; 1444 eiter->type = cpu_to_be16(FDMI_HBA_HARDWARE_VERSION); 1445 if (!IS_FWI2_CAPABLE(ha)) { 1446 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version), 1447 "HW:%s", ha->adapter_id); 1448 } else if (qla2xxx_get_vpd_field(vha, "MN", eiter->a.hw_version, 1449 sizeof(eiter->a.hw_version))) { 1450 ; 1451 } else if (qla2xxx_get_vpd_field(vha, "EC", eiter->a.hw_version, 1452 sizeof(eiter->a.hw_version))) { 1453 ; 1454 } else { 1455 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version), 1456 "HW:%s", ha->adapter_id); 1457 } 1458 alen = strlen(eiter->a.hw_version); 1459 alen += 4 - (alen & 3); 1460 eiter->len = cpu_to_be16(4 + alen); 1461 size += 4 + alen; 1462 1463 ql_dbg(ql_dbg_disc, vha, 0x202a, 1464 "Hardware ver = %s.\n", eiter->a.hw_version); 1465 1466 /* Driver version. */ 1467 eiter = entries + size; 1468 eiter->type = cpu_to_be16(FDMI_HBA_DRIVER_VERSION); 1469 snprintf(eiter->a.driver_version, sizeof(eiter->a.driver_version), 1470 "%s", qla2x00_version_str); 1471 alen = strlen(eiter->a.driver_version); 1472 alen += 4 - (alen & 3); 1473 eiter->len = cpu_to_be16(4 + alen); 1474 size += 4 + alen; 1475 1476 ql_dbg(ql_dbg_disc, vha, 0x202b, 1477 "Driver ver = %s.\n", eiter->a.driver_version); 1478 1479 /* Option ROM version. */ 1480 eiter = entries + size; 1481 eiter->type = cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION); 1482 snprintf(eiter->a.orom_version, sizeof(eiter->a.orom_version), 1483 "%d.%02d", ha->bios_revision[1], ha->bios_revision[0]); 1484 alen = strlen(eiter->a.orom_version); 1485 alen += 4 - (alen & 3); 1486 eiter->len = cpu_to_be16(4 + alen); 1487 size += 4 + alen; 1488 1489 ql_dbg(ql_dbg_disc, vha , 0x202c, 1490 "Optrom vers = %s.\n", eiter->a.orom_version); 1491 1492 /* Firmware version */ 1493 eiter = entries + size; 1494 eiter->type = cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION); 1495 ha->isp_ops->fw_version_str(vha, eiter->a.fw_version, 1496 sizeof(eiter->a.fw_version)); 1497 alen = strlen(eiter->a.fw_version); 1498 alen += 4 - (alen & 3); 1499 eiter->len = cpu_to_be16(4 + alen); 1500 size += 4 + alen; 1501 1502 ql_dbg(ql_dbg_disc, vha, 0x202d, 1503 "Firmware vers = %s.\n", eiter->a.fw_version); 1504 1505 /* Update MS request size. */ 1506 qla2x00_update_ms_fdmi_iocb(vha, size + 16); 1507 1508 ql_dbg(ql_dbg_disc, vha, 0x202e, 1509 "RHBA identifier = %8phN size=%d.\n", 1510 ct_req->req.rhba.hba_identifier, size); 1511 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2076, 1512 entries, size); 1513 1514 /* Execute MS IOCB */ 1515 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 1516 sizeof(ms_iocb_entry_t)); 1517 if (rval != QLA_SUCCESS) { 1518 /*EMPTY*/ 1519 ql_dbg(ql_dbg_disc, vha, 0x2030, 1520 "RHBA issue IOCB failed (%d).\n", rval); 1521 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA") != 1522 QLA_SUCCESS) { 1523 rval = QLA_FUNCTION_FAILED; 1524 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM && 1525 ct_rsp->header.explanation_code == 1526 CT_EXPL_ALREADY_REGISTERED) { 1527 ql_dbg(ql_dbg_disc, vha, 0x2034, 1528 "HBA already registered.\n"); 1529 rval = QLA_ALREADY_REGISTERED; 1530 } else { 1531 ql_dbg(ql_dbg_disc, vha, 0x20ad, 1532 "RHBA FDMI registration failed, CT Reason code: 0x%x, CT Explanation 0x%x\n", 1533 ct_rsp->header.reason_code, 1534 ct_rsp->header.explanation_code); 1535 } 1536 } else { 1537 ql_dbg(ql_dbg_disc, vha, 0x2035, 1538 "RHBA exiting normally.\n"); 1539 } 1540 1541 return rval; 1542 } 1543 1544 /** 1545 * qla2x00_fdmi_rpa() - 1546 * @ha: HA context 1547 * 1548 * Returns 0 on success. 1549 */ 1550 static int 1551 qla2x00_fdmi_rpa(scsi_qla_host_t *vha) 1552 { 1553 int rval, alen; 1554 uint32_t size; 1555 struct qla_hw_data *ha = vha->hw; 1556 ms_iocb_entry_t *ms_pkt; 1557 struct ct_sns_req *ct_req; 1558 struct ct_sns_rsp *ct_rsp; 1559 void *entries; 1560 struct ct_fdmi_port_attr *eiter; 1561 struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb; 1562 struct new_utsname *p_sysid = NULL; 1563 1564 /* Issue RPA */ 1565 /* Prepare common MS IOCB */ 1566 /* Request size adjusted after CT preparation */ 1567 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE); 1568 1569 /* Prepare CT request */ 1570 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPA_CMD, 1571 RPA_RSP_SIZE); 1572 ct_rsp = &ha->ct_sns->p.rsp; 1573 1574 /* Prepare FDMI command arguments -- attribute block, attributes. */ 1575 memcpy(ct_req->req.rpa.port_name, vha->port_name, WWN_SIZE); 1576 size = WWN_SIZE + 4; 1577 1578 /* Attributes */ 1579 ct_req->req.rpa.attrs.count = cpu_to_be32(FDMI_PORT_ATTR_COUNT); 1580 entries = ct_req->req.rpa.port_name; 1581 1582 /* FC4 types. */ 1583 eiter = entries + size; 1584 eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPES); 1585 eiter->len = cpu_to_be16(4 + 32); 1586 eiter->a.fc4_types[2] = 0x01; 1587 size += 4 + 32; 1588 1589 ql_dbg(ql_dbg_disc, vha, 0x2039, 1590 "FC4_TYPES=%02x %02x.\n", 1591 eiter->a.fc4_types[2], 1592 eiter->a.fc4_types[1]); 1593 1594 /* Supported speed. */ 1595 eiter = entries + size; 1596 eiter->type = cpu_to_be16(FDMI_PORT_SUPPORT_SPEED); 1597 eiter->len = cpu_to_be16(4 + 4); 1598 if (IS_CNA_CAPABLE(ha)) 1599 eiter->a.sup_speed = cpu_to_be32( 1600 FDMI_PORT_SPEED_10GB); 1601 else if (IS_QLA27XX(ha)) 1602 eiter->a.sup_speed = cpu_to_be32( 1603 FDMI_PORT_SPEED_32GB| 1604 FDMI_PORT_SPEED_16GB| 1605 FDMI_PORT_SPEED_8GB); 1606 else if (IS_QLA2031(ha)) 1607 eiter->a.sup_speed = cpu_to_be32( 1608 FDMI_PORT_SPEED_16GB| 1609 FDMI_PORT_SPEED_8GB| 1610 FDMI_PORT_SPEED_4GB); 1611 else if (IS_QLA25XX(ha)) 1612 eiter->a.sup_speed = cpu_to_be32( 1613 FDMI_PORT_SPEED_8GB| 1614 FDMI_PORT_SPEED_4GB| 1615 FDMI_PORT_SPEED_2GB| 1616 FDMI_PORT_SPEED_1GB); 1617 else if (IS_QLA24XX_TYPE(ha)) 1618 eiter->a.sup_speed = cpu_to_be32( 1619 FDMI_PORT_SPEED_4GB| 1620 FDMI_PORT_SPEED_2GB| 1621 FDMI_PORT_SPEED_1GB); 1622 else if (IS_QLA23XX(ha)) 1623 eiter->a.sup_speed = cpu_to_be32( 1624 FDMI_PORT_SPEED_2GB| 1625 FDMI_PORT_SPEED_1GB); 1626 else 1627 eiter->a.sup_speed = cpu_to_be32( 1628 FDMI_PORT_SPEED_1GB); 1629 size += 4 + 4; 1630 1631 ql_dbg(ql_dbg_disc, vha, 0x203a, 1632 "Supported_Speed=%x.\n", eiter->a.sup_speed); 1633 1634 /* Current speed. */ 1635 eiter = entries + size; 1636 eiter->type = cpu_to_be16(FDMI_PORT_CURRENT_SPEED); 1637 eiter->len = cpu_to_be16(4 + 4); 1638 switch (ha->link_data_rate) { 1639 case PORT_SPEED_1GB: 1640 eiter->a.cur_speed = 1641 cpu_to_be32(FDMI_PORT_SPEED_1GB); 1642 break; 1643 case PORT_SPEED_2GB: 1644 eiter->a.cur_speed = 1645 cpu_to_be32(FDMI_PORT_SPEED_2GB); 1646 break; 1647 case PORT_SPEED_4GB: 1648 eiter->a.cur_speed = 1649 cpu_to_be32(FDMI_PORT_SPEED_4GB); 1650 break; 1651 case PORT_SPEED_8GB: 1652 eiter->a.cur_speed = 1653 cpu_to_be32(FDMI_PORT_SPEED_8GB); 1654 break; 1655 case PORT_SPEED_10GB: 1656 eiter->a.cur_speed = 1657 cpu_to_be32(FDMI_PORT_SPEED_10GB); 1658 break; 1659 case PORT_SPEED_16GB: 1660 eiter->a.cur_speed = 1661 cpu_to_be32(FDMI_PORT_SPEED_16GB); 1662 break; 1663 case PORT_SPEED_32GB: 1664 eiter->a.cur_speed = 1665 cpu_to_be32(FDMI_PORT_SPEED_32GB); 1666 break; 1667 default: 1668 eiter->a.cur_speed = 1669 cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN); 1670 break; 1671 } 1672 size += 4 + 4; 1673 1674 ql_dbg(ql_dbg_disc, vha, 0x203b, 1675 "Current_Speed=%x.\n", eiter->a.cur_speed); 1676 1677 /* Max frame size. */ 1678 eiter = entries + size; 1679 eiter->type = cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE); 1680 eiter->len = cpu_to_be16(4 + 4); 1681 eiter->a.max_frame_size = IS_FWI2_CAPABLE(ha) ? 1682 le16_to_cpu(icb24->frame_payload_size) : 1683 le16_to_cpu(ha->init_cb->frame_payload_size); 1684 eiter->a.max_frame_size = cpu_to_be32(eiter->a.max_frame_size); 1685 size += 4 + 4; 1686 1687 ql_dbg(ql_dbg_disc, vha, 0x203c, 1688 "Max_Frame_Size=%x.\n", eiter->a.max_frame_size); 1689 1690 /* OS device name. */ 1691 eiter = entries + size; 1692 eiter->type = cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME); 1693 snprintf(eiter->a.os_dev_name, sizeof(eiter->a.os_dev_name), 1694 "%s:host%lu", QLA2XXX_DRIVER_NAME, vha->host_no); 1695 alen = strlen(eiter->a.os_dev_name); 1696 alen += 4 - (alen & 3); 1697 eiter->len = cpu_to_be16(4 + alen); 1698 size += 4 + alen; 1699 1700 ql_dbg(ql_dbg_disc, vha, 0x204b, 1701 "OS_Device_Name=%s.\n", eiter->a.os_dev_name); 1702 1703 /* Hostname. */ 1704 eiter = entries + size; 1705 eiter->type = cpu_to_be16(FDMI_PORT_HOST_NAME); 1706 p_sysid = utsname(); 1707 if (p_sysid) { 1708 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name), 1709 "%s", p_sysid->nodename); 1710 } else { 1711 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name), 1712 "%s", fc_host_system_hostname(vha->host)); 1713 } 1714 alen = strlen(eiter->a.host_name); 1715 alen += 4 - (alen & 3); 1716 eiter->len = cpu_to_be16(4 + alen); 1717 size += 4 + alen; 1718 1719 ql_dbg(ql_dbg_disc, vha, 0x203d, "HostName=%s.\n", eiter->a.host_name); 1720 1721 /* Update MS request size. */ 1722 qla2x00_update_ms_fdmi_iocb(vha, size + 16); 1723 1724 ql_dbg(ql_dbg_disc, vha, 0x203e, 1725 "RPA portname %016llx, size = %d.\n", 1726 wwn_to_u64(ct_req->req.rpa.port_name), size); 1727 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2079, 1728 entries, size); 1729 1730 /* Execute MS IOCB */ 1731 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 1732 sizeof(ms_iocb_entry_t)); 1733 if (rval != QLA_SUCCESS) { 1734 /*EMPTY*/ 1735 ql_dbg(ql_dbg_disc, vha, 0x2040, 1736 "RPA issue IOCB failed (%d).\n", rval); 1737 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA") != 1738 QLA_SUCCESS) { 1739 rval = QLA_FUNCTION_FAILED; 1740 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM && 1741 ct_rsp->header.explanation_code == 1742 CT_EXPL_ALREADY_REGISTERED) { 1743 ql_dbg(ql_dbg_disc, vha, 0x20cd, 1744 "RPA already registered.\n"); 1745 rval = QLA_ALREADY_REGISTERED; 1746 } 1747 1748 } else { 1749 ql_dbg(ql_dbg_disc, vha, 0x2041, 1750 "RPA exiting normally.\n"); 1751 } 1752 1753 return rval; 1754 } 1755 1756 /** 1757 * qla2x00_fdmiv2_rhba() - 1758 * @ha: HA context 1759 * 1760 * Returns 0 on success. 1761 */ 1762 static int 1763 qla2x00_fdmiv2_rhba(scsi_qla_host_t *vha) 1764 { 1765 int rval, alen; 1766 uint32_t size, sn; 1767 ms_iocb_entry_t *ms_pkt; 1768 struct ct_sns_req *ct_req; 1769 struct ct_sns_rsp *ct_rsp; 1770 void *entries; 1771 struct ct_fdmiv2_hba_attr *eiter; 1772 struct qla_hw_data *ha = vha->hw; 1773 struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb; 1774 struct new_utsname *p_sysid = NULL; 1775 1776 /* Issue RHBA */ 1777 /* Prepare common MS IOCB */ 1778 /* Request size adjusted after CT preparation */ 1779 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE); 1780 1781 /* Prepare CT request */ 1782 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RHBA_CMD, 1783 RHBA_RSP_SIZE); 1784 ct_rsp = &ha->ct_sns->p.rsp; 1785 1786 /* Prepare FDMI command arguments -- attribute block, attributes. */ 1787 memcpy(ct_req->req.rhba2.hba_identifier, vha->port_name, WWN_SIZE); 1788 ct_req->req.rhba2.entry_count = cpu_to_be32(1); 1789 memcpy(ct_req->req.rhba2.port_name, vha->port_name, WWN_SIZE); 1790 size = 2 * WWN_SIZE + 4 + 4; 1791 1792 /* Attributes */ 1793 ct_req->req.rhba2.attrs.count = cpu_to_be32(FDMIV2_HBA_ATTR_COUNT); 1794 entries = ct_req->req.rhba2.hba_identifier; 1795 1796 /* Nodename. */ 1797 eiter = entries + size; 1798 eiter->type = cpu_to_be16(FDMI_HBA_NODE_NAME); 1799 eiter->len = cpu_to_be16(4 + WWN_SIZE); 1800 memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE); 1801 size += 4 + WWN_SIZE; 1802 1803 ql_dbg(ql_dbg_disc, vha, 0x207d, 1804 "NodeName = %016llx.\n", wwn_to_u64(eiter->a.node_name)); 1805 1806 /* Manufacturer. */ 1807 eiter = entries + size; 1808 eiter->type = cpu_to_be16(FDMI_HBA_MANUFACTURER); 1809 snprintf(eiter->a.manufacturer, sizeof(eiter->a.manufacturer), 1810 "%s", "QLogic Corporation"); 1811 eiter->a.manufacturer[strlen("QLogic Corporation")] = '\0'; 1812 alen = strlen(eiter->a.manufacturer); 1813 alen += 4 - (alen & 3); 1814 eiter->len = cpu_to_be16(4 + alen); 1815 size += 4 + alen; 1816 1817 ql_dbg(ql_dbg_disc, vha, 0x20a5, 1818 "Manufacturer = %s.\n", eiter->a.manufacturer); 1819 1820 /* Serial number. */ 1821 eiter = entries + size; 1822 eiter->type = cpu_to_be16(FDMI_HBA_SERIAL_NUMBER); 1823 if (IS_FWI2_CAPABLE(ha)) 1824 qla2xxx_get_vpd_field(vha, "SN", eiter->a.serial_num, 1825 sizeof(eiter->a.serial_num)); 1826 else { 1827 sn = ((ha->serial0 & 0x1f) << 16) | 1828 (ha->serial2 << 8) | ha->serial1; 1829 snprintf(eiter->a.serial_num, sizeof(eiter->a.serial_num), 1830 "%c%05d", 'A' + sn / 100000, sn % 100000); 1831 } 1832 alen = strlen(eiter->a.serial_num); 1833 alen += 4 - (alen & 3); 1834 eiter->len = cpu_to_be16(4 + alen); 1835 size += 4 + alen; 1836 1837 ql_dbg(ql_dbg_disc, vha, 0x20a6, 1838 "Serial no. = %s.\n", eiter->a.serial_num); 1839 1840 /* Model name. */ 1841 eiter = entries + size; 1842 eiter->type = cpu_to_be16(FDMI_HBA_MODEL); 1843 snprintf(eiter->a.model, sizeof(eiter->a.model), 1844 "%s", ha->model_number); 1845 alen = strlen(eiter->a.model); 1846 alen += 4 - (alen & 3); 1847 eiter->len = cpu_to_be16(4 + alen); 1848 size += 4 + alen; 1849 1850 ql_dbg(ql_dbg_disc, vha, 0x20a7, 1851 "Model Name = %s.\n", eiter->a.model); 1852 1853 /* Model description. */ 1854 eiter = entries + size; 1855 eiter->type = cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION); 1856 snprintf(eiter->a.model_desc, sizeof(eiter->a.model_desc), 1857 "%s", ha->model_desc); 1858 alen = strlen(eiter->a.model_desc); 1859 alen += 4 - (alen & 3); 1860 eiter->len = cpu_to_be16(4 + alen); 1861 size += 4 + alen; 1862 1863 ql_dbg(ql_dbg_disc, vha, 0x20a8, 1864 "Model Desc = %s.\n", eiter->a.model_desc); 1865 1866 /* Hardware version. */ 1867 eiter = entries + size; 1868 eiter->type = cpu_to_be16(FDMI_HBA_HARDWARE_VERSION); 1869 if (!IS_FWI2_CAPABLE(ha)) { 1870 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version), 1871 "HW:%s", ha->adapter_id); 1872 } else if (qla2xxx_get_vpd_field(vha, "MN", eiter->a.hw_version, 1873 sizeof(eiter->a.hw_version))) { 1874 ; 1875 } else if (qla2xxx_get_vpd_field(vha, "EC", eiter->a.hw_version, 1876 sizeof(eiter->a.hw_version))) { 1877 ; 1878 } else { 1879 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version), 1880 "HW:%s", ha->adapter_id); 1881 } 1882 alen = strlen(eiter->a.hw_version); 1883 alen += 4 - (alen & 3); 1884 eiter->len = cpu_to_be16(4 + alen); 1885 size += 4 + alen; 1886 1887 ql_dbg(ql_dbg_disc, vha, 0x20a9, 1888 "Hardware ver = %s.\n", eiter->a.hw_version); 1889 1890 /* Driver version. */ 1891 eiter = entries + size; 1892 eiter->type = cpu_to_be16(FDMI_HBA_DRIVER_VERSION); 1893 snprintf(eiter->a.driver_version, sizeof(eiter->a.driver_version), 1894 "%s", qla2x00_version_str); 1895 alen = strlen(eiter->a.driver_version); 1896 alen += 4 - (alen & 3); 1897 eiter->len = cpu_to_be16(4 + alen); 1898 size += 4 + alen; 1899 1900 ql_dbg(ql_dbg_disc, vha, 0x20aa, 1901 "Driver ver = %s.\n", eiter->a.driver_version); 1902 1903 /* Option ROM version. */ 1904 eiter = entries + size; 1905 eiter->type = cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION); 1906 snprintf(eiter->a.orom_version, sizeof(eiter->a.orom_version), 1907 "%d.%02d", ha->bios_revision[1], ha->bios_revision[0]); 1908 alen = strlen(eiter->a.orom_version); 1909 alen += 4 - (alen & 3); 1910 eiter->len = cpu_to_be16(4 + alen); 1911 size += 4 + alen; 1912 1913 ql_dbg(ql_dbg_disc, vha , 0x20ab, 1914 "Optrom version = %d.%02d.\n", eiter->a.orom_version[1], 1915 eiter->a.orom_version[0]); 1916 1917 /* Firmware version */ 1918 eiter = entries + size; 1919 eiter->type = cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION); 1920 ha->isp_ops->fw_version_str(vha, eiter->a.fw_version, 1921 sizeof(eiter->a.fw_version)); 1922 alen = strlen(eiter->a.fw_version); 1923 alen += 4 - (alen & 3); 1924 eiter->len = cpu_to_be16(4 + alen); 1925 size += 4 + alen; 1926 1927 ql_dbg(ql_dbg_disc, vha, 0x20ac, 1928 "Firmware vers = %s.\n", eiter->a.fw_version); 1929 1930 /* OS Name and Version */ 1931 eiter = entries + size; 1932 eiter->type = cpu_to_be16(FDMI_HBA_OS_NAME_AND_VERSION); 1933 p_sysid = utsname(); 1934 if (p_sysid) { 1935 snprintf(eiter->a.os_version, sizeof(eiter->a.os_version), 1936 "%s %s %s", 1937 p_sysid->sysname, p_sysid->release, p_sysid->version); 1938 } else { 1939 snprintf(eiter->a.os_version, sizeof(eiter->a.os_version), 1940 "%s %s", "Linux", fc_host_system_hostname(vha->host)); 1941 } 1942 alen = strlen(eiter->a.os_version); 1943 alen += 4 - (alen & 3); 1944 eiter->len = cpu_to_be16(4 + alen); 1945 size += 4 + alen; 1946 1947 ql_dbg(ql_dbg_disc, vha, 0x20ae, 1948 "OS Name and Version = %s.\n", eiter->a.os_version); 1949 1950 /* MAX CT Payload Length */ 1951 eiter = entries + size; 1952 eiter->type = cpu_to_be16(FDMI_HBA_MAXIMUM_CT_PAYLOAD_LENGTH); 1953 eiter->a.max_ct_len = IS_FWI2_CAPABLE(ha) ? 1954 le16_to_cpu(icb24->frame_payload_size) : 1955 le16_to_cpu(ha->init_cb->frame_payload_size); 1956 eiter->a.max_ct_len = cpu_to_be32(eiter->a.max_ct_len); 1957 eiter->len = cpu_to_be16(4 + 4); 1958 size += 4 + 4; 1959 1960 ql_dbg(ql_dbg_disc, vha, 0x20af, 1961 "CT Payload Length = 0x%x.\n", eiter->a.max_ct_len); 1962 1963 /* Node Sybolic Name */ 1964 eiter = entries + size; 1965 eiter->type = cpu_to_be16(FDMI_HBA_NODE_SYMBOLIC_NAME); 1966 qla2x00_get_sym_node_name(vha, eiter->a.sym_name, 1967 sizeof(eiter->a.sym_name)); 1968 alen = strlen(eiter->a.sym_name); 1969 alen += 4 - (alen & 3); 1970 eiter->len = cpu_to_be16(4 + alen); 1971 size += 4 + alen; 1972 1973 ql_dbg(ql_dbg_disc, vha, 0x20b0, 1974 "Symbolic Name = %s.\n", eiter->a.sym_name); 1975 1976 /* Vendor Id */ 1977 eiter = entries + size; 1978 eiter->type = cpu_to_be16(FDMI_HBA_VENDOR_ID); 1979 eiter->a.vendor_id = cpu_to_be32(0x1077); 1980 eiter->len = cpu_to_be16(4 + 4); 1981 size += 4 + 4; 1982 1983 ql_dbg(ql_dbg_disc, vha, 0x20b1, 1984 "Vendor Id = %x.\n", eiter->a.vendor_id); 1985 1986 /* Num Ports */ 1987 eiter = entries + size; 1988 eiter->type = cpu_to_be16(FDMI_HBA_NUM_PORTS); 1989 eiter->a.num_ports = cpu_to_be32(1); 1990 eiter->len = cpu_to_be16(4 + 4); 1991 size += 4 + 4; 1992 1993 ql_dbg(ql_dbg_disc, vha, 0x20b2, 1994 "Port Num = %x.\n", eiter->a.num_ports); 1995 1996 /* Fabric Name */ 1997 eiter = entries + size; 1998 eiter->type = cpu_to_be16(FDMI_HBA_FABRIC_NAME); 1999 memcpy(eiter->a.fabric_name, vha->fabric_node_name, WWN_SIZE); 2000 eiter->len = cpu_to_be16(4 + WWN_SIZE); 2001 size += 4 + WWN_SIZE; 2002 2003 ql_dbg(ql_dbg_disc, vha, 0x20b3, 2004 "Fabric Name = %016llx.\n", wwn_to_u64(eiter->a.fabric_name)); 2005 2006 /* BIOS Version */ 2007 eiter = entries + size; 2008 eiter->type = cpu_to_be16(FDMI_HBA_BOOT_BIOS_NAME); 2009 snprintf(eiter->a.bios_name, sizeof(eiter->a.bios_name), 2010 "BIOS %d.%02d", ha->bios_revision[1], ha->bios_revision[0]); 2011 alen = strlen(eiter->a.bios_name); 2012 alen += 4 - (alen & 3); 2013 eiter->len = cpu_to_be16(4 + alen); 2014 size += 4 + alen; 2015 2016 ql_dbg(ql_dbg_disc, vha, 0x20b4, 2017 "BIOS Name = %s\n", eiter->a.bios_name); 2018 2019 /* Vendor Identifier */ 2020 eiter = entries + size; 2021 eiter->type = cpu_to_be16(FDMI_HBA_TYPE_VENDOR_IDENTIFIER); 2022 snprintf(eiter->a.vendor_identifier, sizeof(eiter->a.vendor_identifier), 2023 "%s", "QLGC"); 2024 alen = strlen(eiter->a.vendor_identifier); 2025 alen += 4 - (alen & 3); 2026 eiter->len = cpu_to_be16(4 + alen); 2027 size += 4 + alen; 2028 2029 ql_dbg(ql_dbg_disc, vha, 0x201b, 2030 "Vendor Identifier = %s.\n", eiter->a.vendor_identifier); 2031 2032 /* Update MS request size. */ 2033 qla2x00_update_ms_fdmi_iocb(vha, size + 16); 2034 2035 ql_dbg(ql_dbg_disc, vha, 0x20b5, 2036 "RHBA identifier = %016llx.\n", 2037 wwn_to_u64(ct_req->req.rhba2.hba_identifier)); 2038 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x20b6, 2039 entries, size); 2040 2041 /* Execute MS IOCB */ 2042 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 2043 sizeof(ms_iocb_entry_t)); 2044 if (rval != QLA_SUCCESS) { 2045 /*EMPTY*/ 2046 ql_dbg(ql_dbg_disc, vha, 0x20b7, 2047 "RHBA issue IOCB failed (%d).\n", rval); 2048 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA") != 2049 QLA_SUCCESS) { 2050 rval = QLA_FUNCTION_FAILED; 2051 2052 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM && 2053 ct_rsp->header.explanation_code == 2054 CT_EXPL_ALREADY_REGISTERED) { 2055 ql_dbg(ql_dbg_disc, vha, 0x20b8, 2056 "HBA already registered.\n"); 2057 rval = QLA_ALREADY_REGISTERED; 2058 } else { 2059 ql_dbg(ql_dbg_disc, vha, 0x2016, 2060 "RHBA FDMI v2 failed, CT Reason code: 0x%x, CT Explanation 0x%x\n", 2061 ct_rsp->header.reason_code, 2062 ct_rsp->header.explanation_code); 2063 } 2064 } else { 2065 ql_dbg(ql_dbg_disc, vha, 0x20b9, 2066 "RHBA FDMI V2 exiting normally.\n"); 2067 } 2068 2069 return rval; 2070 } 2071 2072 /** 2073 * qla2x00_fdmi_dhba() - 2074 * @ha: HA context 2075 * 2076 * Returns 0 on success. 2077 */ 2078 static int 2079 qla2x00_fdmi_dhba(scsi_qla_host_t *vha) 2080 { 2081 int rval; 2082 struct qla_hw_data *ha = vha->hw; 2083 ms_iocb_entry_t *ms_pkt; 2084 struct ct_sns_req *ct_req; 2085 struct ct_sns_rsp *ct_rsp; 2086 2087 /* Issue RPA */ 2088 /* Prepare common MS IOCB */ 2089 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, DHBA_REQ_SIZE, 2090 DHBA_RSP_SIZE); 2091 2092 /* Prepare CT request */ 2093 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, DHBA_CMD, DHBA_RSP_SIZE); 2094 ct_rsp = &ha->ct_sns->p.rsp; 2095 2096 /* Prepare FDMI command arguments -- portname. */ 2097 memcpy(ct_req->req.dhba.port_name, vha->port_name, WWN_SIZE); 2098 2099 ql_dbg(ql_dbg_disc, vha, 0x2036, 2100 "DHBA portname = %8phN.\n", ct_req->req.dhba.port_name); 2101 2102 /* Execute MS IOCB */ 2103 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 2104 sizeof(ms_iocb_entry_t)); 2105 if (rval != QLA_SUCCESS) { 2106 /*EMPTY*/ 2107 ql_dbg(ql_dbg_disc, vha, 0x2037, 2108 "DHBA issue IOCB failed (%d).\n", rval); 2109 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "DHBA") != 2110 QLA_SUCCESS) { 2111 rval = QLA_FUNCTION_FAILED; 2112 } else { 2113 ql_dbg(ql_dbg_disc, vha, 0x2038, 2114 "DHBA exiting normally.\n"); 2115 } 2116 2117 return rval; 2118 } 2119 2120 /** 2121 * qla2x00_fdmiv2_rpa() - 2122 * @ha: HA context 2123 * 2124 * Returns 0 on success. 2125 */ 2126 static int 2127 qla2x00_fdmiv2_rpa(scsi_qla_host_t *vha) 2128 { 2129 int rval, alen; 2130 uint32_t size; 2131 struct qla_hw_data *ha = vha->hw; 2132 ms_iocb_entry_t *ms_pkt; 2133 struct ct_sns_req *ct_req; 2134 struct ct_sns_rsp *ct_rsp; 2135 void *entries; 2136 struct ct_fdmiv2_port_attr *eiter; 2137 struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb; 2138 struct new_utsname *p_sysid = NULL; 2139 2140 /* Issue RPA */ 2141 /* Prepare common MS IOCB */ 2142 /* Request size adjusted after CT preparation */ 2143 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE); 2144 2145 /* Prepare CT request */ 2146 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPA_CMD, RPA_RSP_SIZE); 2147 ct_rsp = &ha->ct_sns->p.rsp; 2148 2149 /* Prepare FDMI command arguments -- attribute block, attributes. */ 2150 memcpy(ct_req->req.rpa2.port_name, vha->port_name, WWN_SIZE); 2151 size = WWN_SIZE + 4; 2152 2153 /* Attributes */ 2154 ct_req->req.rpa2.attrs.count = cpu_to_be32(FDMIV2_PORT_ATTR_COUNT); 2155 entries = ct_req->req.rpa2.port_name; 2156 2157 /* FC4 types. */ 2158 eiter = entries + size; 2159 eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPES); 2160 eiter->len = cpu_to_be16(4 + 32); 2161 eiter->a.fc4_types[2] = 0x01; 2162 size += 4 + 32; 2163 2164 ql_dbg(ql_dbg_disc, vha, 0x20ba, 2165 "FC4_TYPES=%02x %02x.\n", 2166 eiter->a.fc4_types[2], 2167 eiter->a.fc4_types[1]); 2168 2169 if (vha->flags.nvme_enabled) { 2170 eiter->a.fc4_types[6] = 1; /* NVMe type 28h */ 2171 ql_dbg(ql_dbg_disc, vha, 0x211f, 2172 "NVME FC4 Type = %02x 0x0 0x0 0x0 0x0 0x0.\n", 2173 eiter->a.fc4_types[6]); 2174 } 2175 2176 /* Supported speed. */ 2177 eiter = entries + size; 2178 eiter->type = cpu_to_be16(FDMI_PORT_SUPPORT_SPEED); 2179 eiter->len = cpu_to_be16(4 + 4); 2180 if (IS_CNA_CAPABLE(ha)) 2181 eiter->a.sup_speed = cpu_to_be32( 2182 FDMI_PORT_SPEED_10GB); 2183 else if (IS_QLA27XX(ha)) 2184 eiter->a.sup_speed = cpu_to_be32( 2185 FDMI_PORT_SPEED_32GB| 2186 FDMI_PORT_SPEED_16GB| 2187 FDMI_PORT_SPEED_8GB); 2188 else if (IS_QLA2031(ha)) 2189 eiter->a.sup_speed = cpu_to_be32( 2190 FDMI_PORT_SPEED_16GB| 2191 FDMI_PORT_SPEED_8GB| 2192 FDMI_PORT_SPEED_4GB); 2193 else if (IS_QLA25XX(ha)) 2194 eiter->a.sup_speed = cpu_to_be32( 2195 FDMI_PORT_SPEED_8GB| 2196 FDMI_PORT_SPEED_4GB| 2197 FDMI_PORT_SPEED_2GB| 2198 FDMI_PORT_SPEED_1GB); 2199 else if (IS_QLA24XX_TYPE(ha)) 2200 eiter->a.sup_speed = cpu_to_be32( 2201 FDMI_PORT_SPEED_4GB| 2202 FDMI_PORT_SPEED_2GB| 2203 FDMI_PORT_SPEED_1GB); 2204 else if (IS_QLA23XX(ha)) 2205 eiter->a.sup_speed = cpu_to_be32( 2206 FDMI_PORT_SPEED_2GB| 2207 FDMI_PORT_SPEED_1GB); 2208 else 2209 eiter->a.sup_speed = cpu_to_be32( 2210 FDMI_PORT_SPEED_1GB); 2211 size += 4 + 4; 2212 2213 ql_dbg(ql_dbg_disc, vha, 0x20bb, 2214 "Supported Port Speed = %x.\n", eiter->a.sup_speed); 2215 2216 /* Current speed. */ 2217 eiter = entries + size; 2218 eiter->type = cpu_to_be16(FDMI_PORT_CURRENT_SPEED); 2219 eiter->len = cpu_to_be16(4 + 4); 2220 switch (ha->link_data_rate) { 2221 case PORT_SPEED_1GB: 2222 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_1GB); 2223 break; 2224 case PORT_SPEED_2GB: 2225 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_2GB); 2226 break; 2227 case PORT_SPEED_4GB: 2228 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_4GB); 2229 break; 2230 case PORT_SPEED_8GB: 2231 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_8GB); 2232 break; 2233 case PORT_SPEED_10GB: 2234 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_10GB); 2235 break; 2236 case PORT_SPEED_16GB: 2237 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_16GB); 2238 break; 2239 case PORT_SPEED_32GB: 2240 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_32GB); 2241 break; 2242 default: 2243 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN); 2244 break; 2245 } 2246 size += 4 + 4; 2247 2248 ql_dbg(ql_dbg_disc, vha, 0x2017, 2249 "Current_Speed = %x.\n", eiter->a.cur_speed); 2250 2251 /* Max frame size. */ 2252 eiter = entries + size; 2253 eiter->type = cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE); 2254 eiter->len = cpu_to_be16(4 + 4); 2255 eiter->a.max_frame_size = IS_FWI2_CAPABLE(ha) ? 2256 le16_to_cpu(icb24->frame_payload_size): 2257 le16_to_cpu(ha->init_cb->frame_payload_size); 2258 eiter->a.max_frame_size = cpu_to_be32(eiter->a.max_frame_size); 2259 size += 4 + 4; 2260 2261 ql_dbg(ql_dbg_disc, vha, 0x20bc, 2262 "Max_Frame_Size = %x.\n", eiter->a.max_frame_size); 2263 2264 /* OS device name. */ 2265 eiter = entries + size; 2266 eiter->type = cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME); 2267 alen = strlen(QLA2XXX_DRIVER_NAME); 2268 snprintf(eiter->a.os_dev_name, sizeof(eiter->a.os_dev_name), 2269 "%s:host%lu", QLA2XXX_DRIVER_NAME, vha->host_no); 2270 alen += 4 - (alen & 3); 2271 eiter->len = cpu_to_be16(4 + alen); 2272 size += 4 + alen; 2273 2274 ql_dbg(ql_dbg_disc, vha, 0x20be, 2275 "OS_Device_Name = %s.\n", eiter->a.os_dev_name); 2276 2277 /* Hostname. */ 2278 eiter = entries + size; 2279 eiter->type = cpu_to_be16(FDMI_PORT_HOST_NAME); 2280 p_sysid = utsname(); 2281 if (p_sysid) { 2282 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name), 2283 "%s", p_sysid->nodename); 2284 } else { 2285 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name), 2286 "%s", fc_host_system_hostname(vha->host)); 2287 } 2288 alen = strlen(eiter->a.host_name); 2289 alen += 4 - (alen & 3); 2290 eiter->len = cpu_to_be16(4 + alen); 2291 size += 4 + alen; 2292 2293 ql_dbg(ql_dbg_disc, vha, 0x201a, 2294 "HostName=%s.\n", eiter->a.host_name); 2295 2296 /* Node Name */ 2297 eiter = entries + size; 2298 eiter->type = cpu_to_be16(FDMI_PORT_NODE_NAME); 2299 memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE); 2300 eiter->len = cpu_to_be16(4 + WWN_SIZE); 2301 size += 4 + WWN_SIZE; 2302 2303 ql_dbg(ql_dbg_disc, vha, 0x20c0, 2304 "Node Name = %016llx.\n", wwn_to_u64(eiter->a.node_name)); 2305 2306 /* Port Name */ 2307 eiter = entries + size; 2308 eiter->type = cpu_to_be16(FDMI_PORT_NAME); 2309 memcpy(eiter->a.port_name, vha->port_name, WWN_SIZE); 2310 eiter->len = cpu_to_be16(4 + WWN_SIZE); 2311 size += 4 + WWN_SIZE; 2312 2313 ql_dbg(ql_dbg_disc, vha, 0x20c1, 2314 "Port Name = %016llx.\n", wwn_to_u64(eiter->a.port_name)); 2315 2316 /* Port Symbolic Name */ 2317 eiter = entries + size; 2318 eiter->type = cpu_to_be16(FDMI_PORT_SYM_NAME); 2319 qla2x00_get_sym_node_name(vha, eiter->a.port_sym_name, 2320 sizeof(eiter->a.port_sym_name)); 2321 alen = strlen(eiter->a.port_sym_name); 2322 alen += 4 - (alen & 3); 2323 eiter->len = cpu_to_be16(4 + alen); 2324 size += 4 + alen; 2325 2326 ql_dbg(ql_dbg_disc, vha, 0x20c2, 2327 "port symbolic name = %s\n", eiter->a.port_sym_name); 2328 2329 /* Port Type */ 2330 eiter = entries + size; 2331 eiter->type = cpu_to_be16(FDMI_PORT_TYPE); 2332 eiter->a.port_type = cpu_to_be32(NS_NX_PORT_TYPE); 2333 eiter->len = cpu_to_be16(4 + 4); 2334 size += 4 + 4; 2335 2336 ql_dbg(ql_dbg_disc, vha, 0x20c3, 2337 "Port Type = %x.\n", eiter->a.port_type); 2338 2339 /* Class of Service */ 2340 eiter = entries + size; 2341 eiter->type = cpu_to_be16(FDMI_PORT_SUPP_COS); 2342 eiter->a.port_supported_cos = cpu_to_be32(FC_CLASS_3); 2343 eiter->len = cpu_to_be16(4 + 4); 2344 size += 4 + 4; 2345 2346 ql_dbg(ql_dbg_disc, vha, 0x20c4, 2347 "Supported COS = %08x\n", eiter->a.port_supported_cos); 2348 2349 /* Port Fabric Name */ 2350 eiter = entries + size; 2351 eiter->type = cpu_to_be16(FDMI_PORT_FABRIC_NAME); 2352 memcpy(eiter->a.fabric_name, vha->fabric_node_name, WWN_SIZE); 2353 eiter->len = cpu_to_be16(4 + WWN_SIZE); 2354 size += 4 + WWN_SIZE; 2355 2356 ql_dbg(ql_dbg_disc, vha, 0x20c5, 2357 "Fabric Name = %016llx.\n", wwn_to_u64(eiter->a.fabric_name)); 2358 2359 /* FC4_type */ 2360 eiter = entries + size; 2361 eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPE); 2362 eiter->a.port_fc4_type[0] = 0; 2363 eiter->a.port_fc4_type[1] = 0; 2364 eiter->a.port_fc4_type[2] = 1; 2365 eiter->a.port_fc4_type[3] = 0; 2366 eiter->len = cpu_to_be16(4 + 32); 2367 size += 4 + 32; 2368 2369 ql_dbg(ql_dbg_disc, vha, 0x20c6, 2370 "Port Active FC4 Type = %02x %02x.\n", 2371 eiter->a.port_fc4_type[2], eiter->a.port_fc4_type[1]); 2372 2373 if (vha->flags.nvme_enabled) { 2374 eiter->a.port_fc4_type[4] = 0; 2375 eiter->a.port_fc4_type[5] = 0; 2376 eiter->a.port_fc4_type[6] = 1; /* NVMe type 28h */ 2377 ql_dbg(ql_dbg_disc, vha, 0x2120, 2378 "NVME Port Active FC4 Type = %02x 0x0 0x0 0x0 0x0 0x0.\n", 2379 eiter->a.port_fc4_type[6]); 2380 } 2381 2382 /* Port State */ 2383 eiter = entries + size; 2384 eiter->type = cpu_to_be16(FDMI_PORT_STATE); 2385 eiter->a.port_state = cpu_to_be32(1); 2386 eiter->len = cpu_to_be16(4 + 4); 2387 size += 4 + 4; 2388 2389 ql_dbg(ql_dbg_disc, vha, 0x20c7, 2390 "Port State = %x.\n", eiter->a.port_state); 2391 2392 /* Number of Ports */ 2393 eiter = entries + size; 2394 eiter->type = cpu_to_be16(FDMI_PORT_COUNT); 2395 eiter->a.num_ports = cpu_to_be32(1); 2396 eiter->len = cpu_to_be16(4 + 4); 2397 size += 4 + 4; 2398 2399 ql_dbg(ql_dbg_disc, vha, 0x20c8, 2400 "Number of ports = %x.\n", eiter->a.num_ports); 2401 2402 /* Port Id */ 2403 eiter = entries + size; 2404 eiter->type = cpu_to_be16(FDMI_PORT_ID); 2405 eiter->a.port_id = cpu_to_be32(vha->d_id.b24); 2406 eiter->len = cpu_to_be16(4 + 4); 2407 size += 4 + 4; 2408 2409 ql_dbg(ql_dbg_disc, vha, 0x201c, 2410 "Port Id = %x.\n", eiter->a.port_id); 2411 2412 /* Update MS request size. */ 2413 qla2x00_update_ms_fdmi_iocb(vha, size + 16); 2414 2415 ql_dbg(ql_dbg_disc, vha, 0x2018, 2416 "RPA portname= %8phN size=%d.\n", ct_req->req.rpa.port_name, size); 2417 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x20ca, 2418 entries, size); 2419 2420 /* Execute MS IOCB */ 2421 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 2422 sizeof(ms_iocb_entry_t)); 2423 if (rval != QLA_SUCCESS) { 2424 /*EMPTY*/ 2425 ql_dbg(ql_dbg_disc, vha, 0x20cb, 2426 "RPA FDMI v2 issue IOCB failed (%d).\n", rval); 2427 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA") != 2428 QLA_SUCCESS) { 2429 rval = QLA_FUNCTION_FAILED; 2430 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM && 2431 ct_rsp->header.explanation_code == 2432 CT_EXPL_ALREADY_REGISTERED) { 2433 ql_dbg(ql_dbg_disc, vha, 0x20ce, 2434 "RPA FDMI v2 already registered\n"); 2435 rval = QLA_ALREADY_REGISTERED; 2436 } else { 2437 ql_dbg(ql_dbg_disc, vha, 0x2020, 2438 "RPA FDMI v2 failed, CT Reason code: 0x%x, CT Explanation 0x%x\n", 2439 ct_rsp->header.reason_code, 2440 ct_rsp->header.explanation_code); 2441 } 2442 } else { 2443 ql_dbg(ql_dbg_disc, vha, 0x20cc, 2444 "RPA FDMI V2 exiting normally.\n"); 2445 } 2446 2447 return rval; 2448 } 2449 2450 /** 2451 * qla2x00_fdmi_register() - 2452 * @ha: HA context 2453 * 2454 * Returns 0 on success. 2455 */ 2456 int 2457 qla2x00_fdmi_register(scsi_qla_host_t *vha) 2458 { 2459 int rval = QLA_FUNCTION_FAILED; 2460 struct qla_hw_data *ha = vha->hw; 2461 2462 if (IS_QLA2100(ha) || IS_QLA2200(ha) || 2463 IS_QLAFX00(ha)) 2464 return QLA_FUNCTION_FAILED; 2465 2466 rval = qla2x00_mgmt_svr_login(vha); 2467 if (rval) 2468 return rval; 2469 2470 rval = qla2x00_fdmiv2_rhba(vha); 2471 if (rval) { 2472 if (rval != QLA_ALREADY_REGISTERED) 2473 goto try_fdmi; 2474 2475 rval = qla2x00_fdmi_dhba(vha); 2476 if (rval) 2477 goto try_fdmi; 2478 2479 rval = qla2x00_fdmiv2_rhba(vha); 2480 if (rval) 2481 goto try_fdmi; 2482 } 2483 rval = qla2x00_fdmiv2_rpa(vha); 2484 if (rval) 2485 goto try_fdmi; 2486 2487 goto out; 2488 2489 try_fdmi: 2490 rval = qla2x00_fdmi_rhba(vha); 2491 if (rval) { 2492 if (rval != QLA_ALREADY_REGISTERED) 2493 return rval; 2494 2495 rval = qla2x00_fdmi_dhba(vha); 2496 if (rval) 2497 return rval; 2498 2499 rval = qla2x00_fdmi_rhba(vha); 2500 if (rval) 2501 return rval; 2502 } 2503 rval = qla2x00_fdmi_rpa(vha); 2504 out: 2505 return rval; 2506 } 2507 2508 /** 2509 * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query. 2510 * @ha: HA context 2511 * @list: switch info entries to populate 2512 * 2513 * Returns 0 on success. 2514 */ 2515 int 2516 qla2x00_gfpn_id(scsi_qla_host_t *vha, sw_info_t *list) 2517 { 2518 int rval = QLA_SUCCESS; 2519 uint16_t i; 2520 struct qla_hw_data *ha = vha->hw; 2521 ms_iocb_entry_t *ms_pkt; 2522 struct ct_sns_req *ct_req; 2523 struct ct_sns_rsp *ct_rsp; 2524 struct ct_arg arg; 2525 2526 if (!IS_IIDMA_CAPABLE(ha)) 2527 return QLA_FUNCTION_FAILED; 2528 2529 arg.iocb = ha->ms_iocb; 2530 arg.req_dma = ha->ct_sns_dma; 2531 arg.rsp_dma = ha->ct_sns_dma; 2532 arg.req_size = GFPN_ID_REQ_SIZE; 2533 arg.rsp_size = GFPN_ID_RSP_SIZE; 2534 arg.nport_handle = NPH_SNS; 2535 2536 for (i = 0; i < ha->max_fibre_devices; i++) { 2537 /* Issue GFPN_ID */ 2538 /* Prepare common MS IOCB */ 2539 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 2540 2541 /* Prepare CT request */ 2542 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFPN_ID_CMD, 2543 GFPN_ID_RSP_SIZE); 2544 ct_rsp = &ha->ct_sns->p.rsp; 2545 2546 /* Prepare CT arguments -- port_id */ 2547 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; 2548 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; 2549 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; 2550 2551 /* Execute MS IOCB */ 2552 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 2553 sizeof(ms_iocb_entry_t)); 2554 if (rval != QLA_SUCCESS) { 2555 /*EMPTY*/ 2556 ql_dbg(ql_dbg_disc, vha, 0x2023, 2557 "GFPN_ID issue IOCB failed (%d).\n", rval); 2558 break; 2559 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, 2560 "GFPN_ID") != QLA_SUCCESS) { 2561 rval = QLA_FUNCTION_FAILED; 2562 break; 2563 } else { 2564 /* Save fabric portname */ 2565 memcpy(list[i].fabric_port_name, 2566 ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE); 2567 } 2568 2569 /* Last device exit. */ 2570 if (list[i].d_id.b.rsvd_1 != 0) 2571 break; 2572 } 2573 2574 return (rval); 2575 } 2576 2577 2578 static inline struct ct_sns_req * 2579 qla24xx_prep_ct_fm_req(struct ct_sns_pkt *p, uint16_t cmd, 2580 uint16_t rsp_size) 2581 { 2582 memset(p, 0, sizeof(struct ct_sns_pkt)); 2583 2584 p->p.req.header.revision = 0x01; 2585 p->p.req.header.gs_type = 0xFA; 2586 p->p.req.header.gs_subtype = 0x01; 2587 p->p.req.command = cpu_to_be16(cmd); 2588 p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); 2589 2590 return &p->p.req; 2591 } 2592 2593 /** 2594 * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query. 2595 * @ha: HA context 2596 * @list: switch info entries to populate 2597 * 2598 * Returns 0 on success. 2599 */ 2600 int 2601 qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list) 2602 { 2603 int rval; 2604 uint16_t i; 2605 struct qla_hw_data *ha = vha->hw; 2606 ms_iocb_entry_t *ms_pkt; 2607 struct ct_sns_req *ct_req; 2608 struct ct_sns_rsp *ct_rsp; 2609 struct ct_arg arg; 2610 2611 if (!IS_IIDMA_CAPABLE(ha)) 2612 return QLA_FUNCTION_FAILED; 2613 if (!ha->flags.gpsc_supported) 2614 return QLA_FUNCTION_FAILED; 2615 2616 rval = qla2x00_mgmt_svr_login(vha); 2617 if (rval) 2618 return rval; 2619 2620 arg.iocb = ha->ms_iocb; 2621 arg.req_dma = ha->ct_sns_dma; 2622 arg.rsp_dma = ha->ct_sns_dma; 2623 arg.req_size = GPSC_REQ_SIZE; 2624 arg.rsp_size = GPSC_RSP_SIZE; 2625 arg.nport_handle = vha->mgmt_svr_loop_id; 2626 2627 for (i = 0; i < ha->max_fibre_devices; i++) { 2628 /* Issue GFPN_ID */ 2629 /* Prepare common MS IOCB */ 2630 ms_pkt = qla24xx_prep_ms_iocb(vha, &arg); 2631 2632 /* Prepare CT request */ 2633 ct_req = qla24xx_prep_ct_fm_req(ha->ct_sns, GPSC_CMD, 2634 GPSC_RSP_SIZE); 2635 ct_rsp = &ha->ct_sns->p.rsp; 2636 2637 /* Prepare CT arguments -- port_name */ 2638 memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name, 2639 WWN_SIZE); 2640 2641 /* Execute MS IOCB */ 2642 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 2643 sizeof(ms_iocb_entry_t)); 2644 if (rval != QLA_SUCCESS) { 2645 /*EMPTY*/ 2646 ql_dbg(ql_dbg_disc, vha, 0x2059, 2647 "GPSC issue IOCB failed (%d).\n", rval); 2648 } else if ((rval = qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, 2649 "GPSC")) != QLA_SUCCESS) { 2650 /* FM command unsupported? */ 2651 if (rval == QLA_INVALID_COMMAND && 2652 (ct_rsp->header.reason_code == 2653 CT_REASON_INVALID_COMMAND_CODE || 2654 ct_rsp->header.reason_code == 2655 CT_REASON_COMMAND_UNSUPPORTED)) { 2656 ql_dbg(ql_dbg_disc, vha, 0x205a, 2657 "GPSC command unsupported, disabling " 2658 "query.\n"); 2659 ha->flags.gpsc_supported = 0; 2660 rval = QLA_FUNCTION_FAILED; 2661 break; 2662 } 2663 rval = QLA_FUNCTION_FAILED; 2664 } else { 2665 /* Save port-speed */ 2666 switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) { 2667 case BIT_15: 2668 list[i].fp_speed = PORT_SPEED_1GB; 2669 break; 2670 case BIT_14: 2671 list[i].fp_speed = PORT_SPEED_2GB; 2672 break; 2673 case BIT_13: 2674 list[i].fp_speed = PORT_SPEED_4GB; 2675 break; 2676 case BIT_12: 2677 list[i].fp_speed = PORT_SPEED_10GB; 2678 break; 2679 case BIT_11: 2680 list[i].fp_speed = PORT_SPEED_8GB; 2681 break; 2682 case BIT_10: 2683 list[i].fp_speed = PORT_SPEED_16GB; 2684 break; 2685 case BIT_8: 2686 list[i].fp_speed = PORT_SPEED_32GB; 2687 break; 2688 } 2689 2690 ql_dbg(ql_dbg_disc, vha, 0x205b, 2691 "GPSC ext entry - fpn " 2692 "%8phN speeds=%04x speed=%04x.\n", 2693 list[i].fabric_port_name, 2694 be16_to_cpu(ct_rsp->rsp.gpsc.speeds), 2695 be16_to_cpu(ct_rsp->rsp.gpsc.speed)); 2696 } 2697 2698 /* Last device exit. */ 2699 if (list[i].d_id.b.rsvd_1 != 0) 2700 break; 2701 } 2702 2703 return (rval); 2704 } 2705 2706 /** 2707 * qla2x00_gff_id() - SNS Get FC-4 Features (GFF_ID) query. 2708 * 2709 * @ha: HA context 2710 * @list: switch info entries to populate 2711 * 2712 */ 2713 void 2714 qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list) 2715 { 2716 int rval; 2717 uint16_t i; 2718 2719 ms_iocb_entry_t *ms_pkt; 2720 struct ct_sns_req *ct_req; 2721 struct ct_sns_rsp *ct_rsp; 2722 struct qla_hw_data *ha = vha->hw; 2723 uint8_t fcp_scsi_features = 0; 2724 struct ct_arg arg; 2725 2726 for (i = 0; i < ha->max_fibre_devices; i++) { 2727 /* Set default FC4 Type as UNKNOWN so the default is to 2728 * Process this port */ 2729 list[i].fc4_type = FC4_TYPE_UNKNOWN; 2730 2731 /* Do not attempt GFF_ID if we are not FWI_2 capable */ 2732 if (!IS_FWI2_CAPABLE(ha)) 2733 continue; 2734 2735 arg.iocb = ha->ms_iocb; 2736 arg.req_dma = ha->ct_sns_dma; 2737 arg.rsp_dma = ha->ct_sns_dma; 2738 arg.req_size = GFF_ID_REQ_SIZE; 2739 arg.rsp_size = GFF_ID_RSP_SIZE; 2740 arg.nport_handle = NPH_SNS; 2741 2742 /* Prepare common MS IOCB */ 2743 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 2744 2745 /* Prepare CT request */ 2746 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFF_ID_CMD, 2747 GFF_ID_RSP_SIZE); 2748 ct_rsp = &ha->ct_sns->p.rsp; 2749 2750 /* Prepare CT arguments -- port_id */ 2751 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; 2752 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; 2753 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; 2754 2755 /* Execute MS IOCB */ 2756 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 2757 sizeof(ms_iocb_entry_t)); 2758 2759 if (rval != QLA_SUCCESS) { 2760 ql_dbg(ql_dbg_disc, vha, 0x205c, 2761 "GFF_ID issue IOCB failed (%d).\n", rval); 2762 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, 2763 "GFF_ID") != QLA_SUCCESS) { 2764 ql_dbg(ql_dbg_disc, vha, 0x205d, 2765 "GFF_ID IOCB status had a failure status code.\n"); 2766 } else { 2767 fcp_scsi_features = 2768 ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET]; 2769 fcp_scsi_features &= 0x0f; 2770 2771 if (fcp_scsi_features) 2772 list[i].fc4_type = FC4_TYPE_FCP_SCSI; 2773 else 2774 list[i].fc4_type = FC4_TYPE_OTHER; 2775 2776 list[i].fc4f_nvme = 2777 ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET]; 2778 list[i].fc4f_nvme &= 0xf; 2779 } 2780 2781 /* Last device exit. */ 2782 if (list[i].d_id.b.rsvd_1 != 0) 2783 break; 2784 } 2785 } 2786 2787 /* GID_PN completion processing. */ 2788 void qla24xx_handle_gidpn_event(scsi_qla_host_t *vha, struct event_arg *ea) 2789 { 2790 fc_port_t *fcport = ea->fcport; 2791 2792 ql_dbg(ql_dbg_disc, vha, 0x201d, 2793 "%s %8phC login state %d\n", 2794 __func__, fcport->port_name, fcport->fw_login_state); 2795 2796 if (ea->sp->gen2 != fcport->login_gen) { 2797 /* PLOGI/PRLI/LOGO came in while cmd was out.*/ 2798 ql_dbg(ql_dbg_disc, vha, 0x201e, 2799 "%s %8phC generation changed rscn %d|%d login %d|%d \n", 2800 __func__, fcport->port_name, fcport->last_rscn_gen, 2801 fcport->rscn_gen, fcport->last_login_gen, fcport->login_gen); 2802 return; 2803 } 2804 2805 if (!ea->rc) { 2806 if (ea->sp->gen1 == fcport->rscn_gen) { 2807 fcport->scan_state = QLA_FCPORT_FOUND; 2808 fcport->flags |= FCF_FABRIC_DEVICE; 2809 2810 if (fcport->d_id.b24 == ea->id.b24) { 2811 /* cable plugged into the same place */ 2812 switch (vha->host->active_mode) { 2813 case MODE_TARGET: 2814 /* NOOP. let the other guy login to us.*/ 2815 break; 2816 case MODE_INITIATOR: 2817 case MODE_DUAL: 2818 default: 2819 ql_dbg(ql_dbg_disc, vha, 0x201f, 2820 "%s %d %8phC post %s\n", __func__, 2821 __LINE__, fcport->port_name, 2822 (atomic_read(&fcport->state) == 2823 FCS_ONLINE) ? "gpdb" : "gnl"); 2824 2825 if (atomic_read(&fcport->state) == 2826 FCS_ONLINE) 2827 qla24xx_post_gpdb_work(vha, 2828 fcport, PDO_FORCE_ADISC); 2829 else 2830 qla24xx_post_gnl_work(vha, 2831 fcport); 2832 break; 2833 } 2834 } else { /* fcport->d_id.b24 != ea->id.b24 */ 2835 fcport->d_id.b24 = ea->id.b24; 2836 if (fcport->deleted == QLA_SESS_DELETED) { 2837 ql_dbg(ql_dbg_disc, vha, 0x2021, 2838 "%s %d %8phC post del sess\n", 2839 __func__, __LINE__, fcport->port_name); 2840 qlt_schedule_sess_for_deletion_lock(fcport); 2841 } 2842 } 2843 } else { /* ea->sp->gen1 != fcport->rscn_gen */ 2844 ql_dbg(ql_dbg_disc, vha, 0x2022, 2845 "%s %d %8phC post gidpn\n", 2846 __func__, __LINE__, fcport->port_name); 2847 /* rscn came in while cmd was out */ 2848 qla24xx_post_gidpn_work(vha, fcport); 2849 } 2850 } else { /* ea->rc */ 2851 /* cable pulled */ 2852 if (ea->sp->gen1 == fcport->rscn_gen) { 2853 if (ea->sp->gen2 == fcport->login_gen) { 2854 ql_dbg(ql_dbg_disc, vha, 0x2042, 2855 "%s %d %8phC post del sess\n", __func__, 2856 __LINE__, fcport->port_name); 2857 qlt_schedule_sess_for_deletion_lock(fcport); 2858 } else { 2859 ql_dbg(ql_dbg_disc, vha, 0x2045, 2860 "%s %d %8phC login\n", __func__, __LINE__, 2861 fcport->port_name); 2862 qla24xx_fcport_handle_login(vha, fcport); 2863 } 2864 } else { 2865 ql_dbg(ql_dbg_disc, vha, 0x2049, 2866 "%s %d %8phC post gidpn\n", __func__, __LINE__, 2867 fcport->port_name); 2868 qla24xx_post_gidpn_work(vha, fcport); 2869 } 2870 } 2871 } /* gidpn_event */ 2872 2873 static void qla2x00_async_gidpn_sp_done(void *s, int res) 2874 { 2875 struct srb *sp = s; 2876 struct scsi_qla_host *vha = sp->vha; 2877 fc_port_t *fcport = sp->fcport; 2878 u8 *id = fcport->ct_desc.ct_sns->p.rsp.rsp.gid_pn.port_id; 2879 struct event_arg ea; 2880 2881 fcport->flags &= ~FCF_ASYNC_SENT; 2882 2883 memset(&ea, 0, sizeof(ea)); 2884 ea.fcport = fcport; 2885 ea.id.b.domain = id[0]; 2886 ea.id.b.area = id[1]; 2887 ea.id.b.al_pa = id[2]; 2888 ea.sp = sp; 2889 ea.rc = res; 2890 ea.event = FCME_GIDPN_DONE; 2891 2892 ql_dbg(ql_dbg_disc, vha, 0x204f, 2893 "Async done-%s res %x, WWPN %8phC ID %3phC \n", 2894 sp->name, res, fcport->port_name, id); 2895 2896 qla2x00_fcport_event_handler(vha, &ea); 2897 2898 sp->free(sp); 2899 } 2900 2901 int qla24xx_async_gidpn(scsi_qla_host_t *vha, fc_port_t *fcport) 2902 { 2903 int rval = QLA_FUNCTION_FAILED; 2904 struct ct_sns_req *ct_req; 2905 srb_t *sp; 2906 2907 if (!vha->flags.online) 2908 goto done; 2909 2910 fcport->flags |= FCF_ASYNC_SENT; 2911 fcport->disc_state = DSC_GID_PN; 2912 fcport->scan_state = QLA_FCPORT_SCAN; 2913 sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC); 2914 if (!sp) 2915 goto done; 2916 2917 sp->type = SRB_CT_PTHRU_CMD; 2918 sp->name = "gidpn"; 2919 sp->gen1 = fcport->rscn_gen; 2920 sp->gen2 = fcport->login_gen; 2921 2922 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 2923 2924 /* CT_IU preamble */ 2925 ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GID_PN_CMD, 2926 GID_PN_RSP_SIZE); 2927 2928 /* GIDPN req */ 2929 memcpy(ct_req->req.gid_pn.port_name, fcport->port_name, 2930 WWN_SIZE); 2931 2932 /* req & rsp use the same buffer */ 2933 sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns; 2934 sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma; 2935 sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns; 2936 sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma; 2937 sp->u.iocb_cmd.u.ctarg.req_size = GID_PN_REQ_SIZE; 2938 sp->u.iocb_cmd.u.ctarg.rsp_size = GID_PN_RSP_SIZE; 2939 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 2940 2941 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 2942 sp->done = qla2x00_async_gidpn_sp_done; 2943 2944 rval = qla2x00_start_sp(sp); 2945 if (rval != QLA_SUCCESS) 2946 goto done_free_sp; 2947 2948 ql_dbg(ql_dbg_disc, vha, 0x20a4, 2949 "Async-%s - %8phC hdl=%x loopid=%x portid %02x%02x%02x.\n", 2950 sp->name, fcport->port_name, 2951 sp->handle, fcport->loop_id, fcport->d_id.b.domain, 2952 fcport->d_id.b.area, fcport->d_id.b.al_pa); 2953 return rval; 2954 2955 done_free_sp: 2956 sp->free(sp); 2957 done: 2958 fcport->flags &= ~FCF_ASYNC_SENT; 2959 return rval; 2960 } 2961 2962 int qla24xx_post_gidpn_work(struct scsi_qla_host *vha, fc_port_t *fcport) 2963 { 2964 struct qla_work_evt *e; 2965 int ls; 2966 2967 ls = atomic_read(&vha->loop_state); 2968 if (((ls != LOOP_READY) && (ls != LOOP_UP)) || 2969 test_bit(UNLOADING, &vha->dpc_flags)) 2970 return 0; 2971 2972 e = qla2x00_alloc_work(vha, QLA_EVT_GIDPN); 2973 if (!e) 2974 return QLA_FUNCTION_FAILED; 2975 2976 e->u.fcport.fcport = fcport; 2977 return qla2x00_post_work(vha, e); 2978 } 2979 2980 int qla24xx_post_gpsc_work(struct scsi_qla_host *vha, fc_port_t *fcport) 2981 { 2982 struct qla_work_evt *e; 2983 2984 e = qla2x00_alloc_work(vha, QLA_EVT_GPSC); 2985 if (!e) 2986 return QLA_FUNCTION_FAILED; 2987 2988 e->u.fcport.fcport = fcport; 2989 return qla2x00_post_work(vha, e); 2990 } 2991 2992 static void qla24xx_async_gpsc_sp_done(void *s, int res) 2993 { 2994 struct srb *sp = s; 2995 struct scsi_qla_host *vha = sp->vha; 2996 struct qla_hw_data *ha = vha->hw; 2997 fc_port_t *fcport = sp->fcport; 2998 struct ct_sns_rsp *ct_rsp; 2999 struct event_arg ea; 3000 3001 ct_rsp = &fcport->ct_desc.ct_sns->p.rsp; 3002 3003 ql_dbg(ql_dbg_disc, vha, 0x2053, 3004 "Async done-%s res %x, WWPN %8phC \n", 3005 sp->name, res, fcport->port_name); 3006 3007 fcport->flags &= ~FCF_ASYNC_SENT; 3008 3009 if (res == (DID_ERROR << 16)) { 3010 /* entry status error */ 3011 goto done; 3012 } else if (res) { 3013 if ((ct_rsp->header.reason_code == 3014 CT_REASON_INVALID_COMMAND_CODE) || 3015 (ct_rsp->header.reason_code == 3016 CT_REASON_COMMAND_UNSUPPORTED)) { 3017 ql_dbg(ql_dbg_disc, vha, 0x2019, 3018 "GPSC command unsupported, disabling query.\n"); 3019 ha->flags.gpsc_supported = 0; 3020 res = QLA_SUCCESS; 3021 } 3022 } else { 3023 switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) { 3024 case BIT_15: 3025 fcport->fp_speed = PORT_SPEED_1GB; 3026 break; 3027 case BIT_14: 3028 fcport->fp_speed = PORT_SPEED_2GB; 3029 break; 3030 case BIT_13: 3031 fcport->fp_speed = PORT_SPEED_4GB; 3032 break; 3033 case BIT_12: 3034 fcport->fp_speed = PORT_SPEED_10GB; 3035 break; 3036 case BIT_11: 3037 fcport->fp_speed = PORT_SPEED_8GB; 3038 break; 3039 case BIT_10: 3040 fcport->fp_speed = PORT_SPEED_16GB; 3041 break; 3042 case BIT_8: 3043 fcport->fp_speed = PORT_SPEED_32GB; 3044 break; 3045 } 3046 3047 ql_dbg(ql_dbg_disc, vha, 0x2054, 3048 "Async-%s OUT WWPN %8phC speeds=%04x speed=%04x.\n", 3049 sp->name, fcport->fabric_port_name, 3050 be16_to_cpu(ct_rsp->rsp.gpsc.speeds), 3051 be16_to_cpu(ct_rsp->rsp.gpsc.speed)); 3052 } 3053 done: 3054 memset(&ea, 0, sizeof(ea)); 3055 ea.event = FCME_GPSC_DONE; 3056 ea.rc = res; 3057 ea.fcport = fcport; 3058 qla2x00_fcport_event_handler(vha, &ea); 3059 3060 sp->free(sp); 3061 } 3062 3063 int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t *fcport) 3064 { 3065 int rval = QLA_FUNCTION_FAILED; 3066 struct ct_sns_req *ct_req; 3067 srb_t *sp; 3068 3069 if (!vha->flags.online) 3070 goto done; 3071 3072 fcport->flags |= FCF_ASYNC_SENT; 3073 sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); 3074 if (!sp) 3075 goto done; 3076 3077 sp->type = SRB_CT_PTHRU_CMD; 3078 sp->name = "gpsc"; 3079 sp->gen1 = fcport->rscn_gen; 3080 sp->gen2 = fcport->login_gen; 3081 3082 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 3083 3084 /* CT_IU preamble */ 3085 ct_req = qla24xx_prep_ct_fm_req(fcport->ct_desc.ct_sns, GPSC_CMD, 3086 GPSC_RSP_SIZE); 3087 3088 /* GPSC req */ 3089 memcpy(ct_req->req.gpsc.port_name, fcport->fabric_port_name, 3090 WWN_SIZE); 3091 3092 sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns; 3093 sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma; 3094 sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns; 3095 sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma; 3096 sp->u.iocb_cmd.u.ctarg.req_size = GPSC_REQ_SIZE; 3097 sp->u.iocb_cmd.u.ctarg.rsp_size = GPSC_RSP_SIZE; 3098 sp->u.iocb_cmd.u.ctarg.nport_handle = vha->mgmt_svr_loop_id; 3099 3100 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 3101 sp->done = qla24xx_async_gpsc_sp_done; 3102 3103 rval = qla2x00_start_sp(sp); 3104 if (rval != QLA_SUCCESS) 3105 goto done_free_sp; 3106 3107 ql_dbg(ql_dbg_disc, vha, 0x205e, 3108 "Async-%s %8phC hdl=%x loopid=%x portid=%02x%02x%02x.\n", 3109 sp->name, fcport->port_name, sp->handle, 3110 fcport->loop_id, fcport->d_id.b.domain, 3111 fcport->d_id.b.area, fcport->d_id.b.al_pa); 3112 return rval; 3113 3114 done_free_sp: 3115 sp->free(sp); 3116 done: 3117 fcport->flags &= ~FCF_ASYNC_SENT; 3118 return rval; 3119 } 3120 3121 int qla24xx_post_gpnid_work(struct scsi_qla_host *vha, port_id_t *id) 3122 { 3123 struct qla_work_evt *e; 3124 3125 if (test_bit(UNLOADING, &vha->dpc_flags)) 3126 return 0; 3127 3128 e = qla2x00_alloc_work(vha, QLA_EVT_GPNID); 3129 if (!e) 3130 return QLA_FUNCTION_FAILED; 3131 3132 e->u.gpnid.id = *id; 3133 return qla2x00_post_work(vha, e); 3134 } 3135 3136 void qla24xx_async_gpnid_done(scsi_qla_host_t *vha, srb_t *sp) 3137 { 3138 if (sp->u.iocb_cmd.u.ctarg.req) { 3139 dma_free_coherent(&vha->hw->pdev->dev, 3140 sizeof(struct ct_sns_pkt), 3141 sp->u.iocb_cmd.u.ctarg.req, 3142 sp->u.iocb_cmd.u.ctarg.req_dma); 3143 sp->u.iocb_cmd.u.ctarg.req = NULL; 3144 } 3145 if (sp->u.iocb_cmd.u.ctarg.rsp) { 3146 dma_free_coherent(&vha->hw->pdev->dev, 3147 sizeof(struct ct_sns_pkt), 3148 sp->u.iocb_cmd.u.ctarg.rsp, 3149 sp->u.iocb_cmd.u.ctarg.rsp_dma); 3150 sp->u.iocb_cmd.u.ctarg.rsp = NULL; 3151 } 3152 3153 sp->free(sp); 3154 } 3155 3156 void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea) 3157 { 3158 fc_port_t *fcport; 3159 unsigned long flags; 3160 3161 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); 3162 fcport = qla2x00_find_fcport_by_wwpn(vha, ea->port_name, 1); 3163 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); 3164 3165 if (fcport) { 3166 /* cable moved. just plugged in */ 3167 fcport->rscn_gen++; 3168 fcport->d_id = ea->id; 3169 fcport->scan_state = QLA_FCPORT_FOUND; 3170 fcport->flags |= FCF_FABRIC_DEVICE; 3171 3172 switch (fcport->disc_state) { 3173 case DSC_DELETED: 3174 ql_dbg(ql_dbg_disc, vha, 0x210d, 3175 "%s %d %8phC login\n", __func__, __LINE__, 3176 fcport->port_name); 3177 qla24xx_fcport_handle_login(vha, fcport); 3178 break; 3179 case DSC_DELETE_PEND: 3180 break; 3181 default: 3182 ql_dbg(ql_dbg_disc, vha, 0x2064, 3183 "%s %d %8phC post del sess\n", 3184 __func__, __LINE__, fcport->port_name); 3185 qlt_schedule_sess_for_deletion_lock(fcport); 3186 break; 3187 } 3188 } else { 3189 /* create new fcport */ 3190 ql_dbg(ql_dbg_disc, vha, 0x2065, 3191 "%s %d %8phC post new sess\n", 3192 __func__, __LINE__, ea->port_name); 3193 3194 qla24xx_post_newsess_work(vha, &ea->id, ea->port_name, NULL); 3195 } 3196 } 3197 3198 static void qla2x00_async_gpnid_sp_done(void *s, int res) 3199 { 3200 struct srb *sp = s; 3201 struct scsi_qla_host *vha = sp->vha; 3202 struct ct_sns_req *ct_req = 3203 (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req; 3204 struct ct_sns_rsp *ct_rsp = 3205 (struct ct_sns_rsp *)sp->u.iocb_cmd.u.ctarg.rsp; 3206 struct event_arg ea; 3207 struct qla_work_evt *e; 3208 3209 ql_dbg(ql_dbg_disc, vha, 0x2066, 3210 "Async done-%s res %x ID %3phC. %8phC\n", 3211 sp->name, res, ct_req->req.port_id.port_id, 3212 ct_rsp->rsp.gpn_id.port_name); 3213 3214 memset(&ea, 0, sizeof(ea)); 3215 memcpy(ea.port_name, ct_rsp->rsp.gpn_id.port_name, WWN_SIZE); 3216 ea.sp = sp; 3217 ea.id.b.domain = ct_req->req.port_id.port_id[0]; 3218 ea.id.b.area = ct_req->req.port_id.port_id[1]; 3219 ea.id.b.al_pa = ct_req->req.port_id.port_id[2]; 3220 ea.rc = res; 3221 ea.event = FCME_GPNID_DONE; 3222 3223 qla2x00_fcport_event_handler(vha, &ea); 3224 3225 e = qla2x00_alloc_work(vha, QLA_EVT_GPNID_DONE); 3226 if (!e) { 3227 /* please ignore kernel warning. otherwise, we have mem leak. */ 3228 if (sp->u.iocb_cmd.u.ctarg.req) { 3229 dma_free_coherent(&vha->hw->pdev->dev, 3230 sizeof(struct ct_sns_pkt), 3231 sp->u.iocb_cmd.u.ctarg.req, 3232 sp->u.iocb_cmd.u.ctarg.req_dma); 3233 sp->u.iocb_cmd.u.ctarg.req = NULL; 3234 } 3235 if (sp->u.iocb_cmd.u.ctarg.rsp) { 3236 dma_free_coherent(&vha->hw->pdev->dev, 3237 sizeof(struct ct_sns_pkt), 3238 sp->u.iocb_cmd.u.ctarg.rsp, 3239 sp->u.iocb_cmd.u.ctarg.rsp_dma); 3240 sp->u.iocb_cmd.u.ctarg.rsp = NULL; 3241 } 3242 3243 sp->free(sp); 3244 return; 3245 } 3246 3247 e->u.iosb.sp = sp; 3248 qla2x00_post_work(vha, e); 3249 } 3250 3251 /* Get WWPN with Nport ID. */ 3252 int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id) 3253 { 3254 int rval = QLA_FUNCTION_FAILED; 3255 struct ct_sns_req *ct_req; 3256 srb_t *sp; 3257 struct ct_sns_pkt *ct_sns; 3258 3259 if (!vha->flags.online) 3260 goto done; 3261 3262 sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); 3263 if (!sp) 3264 goto done; 3265 3266 sp->type = SRB_CT_PTHRU_CMD; 3267 sp->name = "gpnid"; 3268 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 3269 3270 sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev, 3271 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma, 3272 GFP_KERNEL); 3273 if (!sp->u.iocb_cmd.u.ctarg.req) { 3274 ql_log(ql_log_warn, vha, 0xd041, 3275 "Failed to allocate ct_sns request.\n"); 3276 goto done_free_sp; 3277 } 3278 3279 sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev, 3280 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma, 3281 GFP_KERNEL); 3282 if (!sp->u.iocb_cmd.u.ctarg.rsp) { 3283 ql_log(ql_log_warn, vha, 0xd042, 3284 "Failed to allocate ct_sns request.\n"); 3285 goto done_free_sp; 3286 } 3287 3288 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp; 3289 memset(ct_sns, 0, sizeof(*ct_sns)); 3290 3291 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; 3292 /* CT_IU preamble */ 3293 ct_req = qla2x00_prep_ct_req(ct_sns, GPN_ID_CMD, GPN_ID_RSP_SIZE); 3294 3295 /* GPN_ID req */ 3296 ct_req->req.port_id.port_id[0] = id->b.domain; 3297 ct_req->req.port_id.port_id[1] = id->b.area; 3298 ct_req->req.port_id.port_id[2] = id->b.al_pa; 3299 3300 sp->u.iocb_cmd.u.ctarg.req_size = GPN_ID_REQ_SIZE; 3301 sp->u.iocb_cmd.u.ctarg.rsp_size = GPN_ID_RSP_SIZE; 3302 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 3303 3304 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 3305 sp->done = qla2x00_async_gpnid_sp_done; 3306 3307 rval = qla2x00_start_sp(sp); 3308 if (rval != QLA_SUCCESS) 3309 goto done_free_sp; 3310 3311 ql_dbg(ql_dbg_disc, vha, 0x2067, 3312 "Async-%s hdl=%x ID %3phC.\n", sp->name, 3313 sp->handle, ct_req->req.port_id.port_id); 3314 return rval; 3315 3316 done_free_sp: 3317 if (sp->u.iocb_cmd.u.ctarg.req) { 3318 dma_free_coherent(&vha->hw->pdev->dev, 3319 sizeof(struct ct_sns_pkt), 3320 sp->u.iocb_cmd.u.ctarg.req, 3321 sp->u.iocb_cmd.u.ctarg.req_dma); 3322 sp->u.iocb_cmd.u.ctarg.req = NULL; 3323 } 3324 if (sp->u.iocb_cmd.u.ctarg.rsp) { 3325 dma_free_coherent(&vha->hw->pdev->dev, 3326 sizeof(struct ct_sns_pkt), 3327 sp->u.iocb_cmd.u.ctarg.rsp, 3328 sp->u.iocb_cmd.u.ctarg.rsp_dma); 3329 sp->u.iocb_cmd.u.ctarg.rsp = NULL; 3330 } 3331 3332 sp->free(sp); 3333 done: 3334 return rval; 3335 } 3336 3337 void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea) 3338 { 3339 fc_port_t *fcport = ea->fcport; 3340 3341 qla24xx_post_gnl_work(vha, fcport); 3342 } 3343 3344 void qla24xx_async_gffid_sp_done(void *s, int res) 3345 { 3346 struct srb *sp = s; 3347 struct scsi_qla_host *vha = sp->vha; 3348 fc_port_t *fcport = sp->fcport; 3349 struct ct_sns_rsp *ct_rsp; 3350 struct event_arg ea; 3351 3352 ql_dbg(ql_dbg_disc, vha, 0x2133, 3353 "Async done-%s res %x ID %x. %8phC\n", 3354 sp->name, res, fcport->d_id.b24, fcport->port_name); 3355 3356 fcport->flags &= ~FCF_ASYNC_SENT; 3357 ct_rsp = &fcport->ct_desc.ct_sns->p.rsp; 3358 /* 3359 * FC-GS-7, 5.2.3.12 FC-4 Features - format 3360 * The format of the FC-4 Features object, as defined by the FC-4, 3361 * Shall be an array of 4-bit values, one for each type code value 3362 */ 3363 if (!res) { 3364 if (ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET] & 0xf) { 3365 /* w1 b00:03 */ 3366 fcport->fc4_type = 3367 ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET]; 3368 fcport->fc4_type &= 0xf; 3369 } 3370 3371 if (ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET] & 0xf) { 3372 /* w5 [00:03]/28h */ 3373 fcport->fc4f_nvme = 3374 ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET]; 3375 fcport->fc4f_nvme &= 0xf; 3376 } 3377 } 3378 3379 memset(&ea, 0, sizeof(ea)); 3380 ea.sp = sp; 3381 ea.fcport = sp->fcport; 3382 ea.rc = res; 3383 ea.event = FCME_GFFID_DONE; 3384 3385 qla2x00_fcport_event_handler(vha, &ea); 3386 sp->free(sp); 3387 } 3388 3389 /* Get FC4 Feature with Nport ID. */ 3390 int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport) 3391 { 3392 int rval = QLA_FUNCTION_FAILED; 3393 struct ct_sns_req *ct_req; 3394 srb_t *sp; 3395 3396 if (!vha->flags.online) 3397 return rval; 3398 3399 sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); 3400 if (!sp) 3401 return rval; 3402 3403 fcport->flags |= FCF_ASYNC_SENT; 3404 sp->type = SRB_CT_PTHRU_CMD; 3405 sp->name = "gffid"; 3406 sp->gen1 = fcport->rscn_gen; 3407 sp->gen2 = fcport->login_gen; 3408 3409 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 3410 3411 /* CT_IU preamble */ 3412 ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFF_ID_CMD, 3413 GFF_ID_RSP_SIZE); 3414 3415 ct_req->req.gff_id.port_id[0] = fcport->d_id.b.domain; 3416 ct_req->req.gff_id.port_id[1] = fcport->d_id.b.area; 3417 ct_req->req.gff_id.port_id[2] = fcport->d_id.b.al_pa; 3418 3419 sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns; 3420 sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma; 3421 sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns; 3422 sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma; 3423 sp->u.iocb_cmd.u.ctarg.req_size = GFF_ID_REQ_SIZE; 3424 sp->u.iocb_cmd.u.ctarg.rsp_size = GFF_ID_RSP_SIZE; 3425 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 3426 3427 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 3428 sp->done = qla24xx_async_gffid_sp_done; 3429 3430 rval = qla2x00_start_sp(sp); 3431 if (rval != QLA_SUCCESS) 3432 goto done_free_sp; 3433 3434 ql_dbg(ql_dbg_disc, vha, 0x2132, 3435 "Async-%s hdl=%x %8phC.\n", sp->name, 3436 sp->handle, fcport->port_name); 3437 3438 return rval; 3439 done_free_sp: 3440 sp->free(sp); 3441 fcport->flags &= ~FCF_ASYNC_SENT; 3442 return rval; 3443 } 3444