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 static int qla_async_rftid(scsi_qla_host_t *, port_id_t *); 18 static int qla_async_rffid(scsi_qla_host_t *, port_id_t *, u8, u8); 19 static int qla_async_rnnid(scsi_qla_host_t *, port_id_t *, u8*); 20 static int qla_async_rsnn_nn(scsi_qla_host_t *); 21 22 /** 23 * qla2x00_prep_ms_iocb() - Prepare common MS/CT IOCB fields for SNS CT query. 24 * @ha: HA context 25 * @req_size: request size in bytes 26 * @rsp_size: response size in bytes 27 * 28 * Returns a pointer to the @ha's ms_iocb. 29 */ 30 void * 31 qla2x00_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg) 32 { 33 struct qla_hw_data *ha = vha->hw; 34 ms_iocb_entry_t *ms_pkt; 35 36 ms_pkt = (ms_iocb_entry_t *)arg->iocb; 37 memset(ms_pkt, 0, sizeof(ms_iocb_entry_t)); 38 39 ms_pkt->entry_type = MS_IOCB_TYPE; 40 ms_pkt->entry_count = 1; 41 SET_TARGET_ID(ha, ms_pkt->loop_id, SIMPLE_NAME_SERVER); 42 ms_pkt->control_flags = cpu_to_le16(CF_READ | CF_HEAD_TAG); 43 ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); 44 ms_pkt->cmd_dsd_count = cpu_to_le16(1); 45 ms_pkt->total_dsd_count = cpu_to_le16(2); 46 ms_pkt->rsp_bytecount = cpu_to_le32(arg->rsp_size); 47 ms_pkt->req_bytecount = cpu_to_le32(arg->req_size); 48 49 ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(arg->req_dma)); 50 ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(arg->req_dma)); 51 ms_pkt->dseg_req_length = ms_pkt->req_bytecount; 52 53 ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(arg->rsp_dma)); 54 ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(arg->rsp_dma)); 55 ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount; 56 57 vha->qla_stats.control_requests++; 58 59 return (ms_pkt); 60 } 61 62 /** 63 * qla24xx_prep_ms_iocb() - Prepare common CT IOCB fields for SNS CT query. 64 * @ha: HA context 65 * @req_size: request size in bytes 66 * @rsp_size: response size in bytes 67 * 68 * Returns a pointer to the @ha's ms_iocb. 69 */ 70 void * 71 qla24xx_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg) 72 { 73 struct qla_hw_data *ha = vha->hw; 74 struct ct_entry_24xx *ct_pkt; 75 76 ct_pkt = (struct ct_entry_24xx *)arg->iocb; 77 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx)); 78 79 ct_pkt->entry_type = CT_IOCB_TYPE; 80 ct_pkt->entry_count = 1; 81 ct_pkt->nport_handle = cpu_to_le16(arg->nport_handle); 82 ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); 83 ct_pkt->cmd_dsd_count = cpu_to_le16(1); 84 ct_pkt->rsp_dsd_count = cpu_to_le16(1); 85 ct_pkt->rsp_byte_count = cpu_to_le32(arg->rsp_size); 86 ct_pkt->cmd_byte_count = cpu_to_le32(arg->req_size); 87 88 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(arg->req_dma)); 89 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(arg->req_dma)); 90 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; 91 92 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(arg->rsp_dma)); 93 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(arg->rsp_dma)); 94 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; 95 ct_pkt->vp_index = vha->vp_idx; 96 97 vha->qla_stats.control_requests++; 98 99 return (ct_pkt); 100 } 101 102 /** 103 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query. 104 * @ct_req: CT request buffer 105 * @cmd: GS command 106 * @rsp_size: response size in bytes 107 * 108 * Returns a pointer to the intitialized @ct_req. 109 */ 110 static inline struct ct_sns_req * 111 qla2x00_prep_ct_req(struct ct_sns_pkt *p, uint16_t cmd, uint16_t rsp_size) 112 { 113 memset(p, 0, sizeof(struct ct_sns_pkt)); 114 115 p->p.req.header.revision = 0x01; 116 p->p.req.header.gs_type = 0xFC; 117 p->p.req.header.gs_subtype = 0x02; 118 p->p.req.command = cpu_to_be16(cmd); 119 p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); 120 121 return &p->p.req; 122 } 123 124 int 125 qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt, 126 struct ct_sns_rsp *ct_rsp, const char *routine) 127 { 128 int rval; 129 uint16_t comp_status; 130 struct qla_hw_data *ha = vha->hw; 131 bool lid_is_sns = false; 132 133 rval = QLA_FUNCTION_FAILED; 134 if (ms_pkt->entry_status != 0) { 135 ql_dbg(ql_dbg_disc, vha, 0x2031, 136 "%s failed, error status (%x) on port_id: %02x%02x%02x.\n", 137 routine, ms_pkt->entry_status, vha->d_id.b.domain, 138 vha->d_id.b.area, vha->d_id.b.al_pa); 139 } else { 140 if (IS_FWI2_CAPABLE(ha)) 141 comp_status = le16_to_cpu( 142 ((struct ct_entry_24xx *)ms_pkt)->comp_status); 143 else 144 comp_status = le16_to_cpu(ms_pkt->status); 145 switch (comp_status) { 146 case CS_COMPLETE: 147 case CS_DATA_UNDERRUN: 148 case CS_DATA_OVERRUN: /* Overrun? */ 149 if (ct_rsp->header.response != 150 cpu_to_be16(CT_ACCEPT_RESPONSE)) { 151 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2077, 152 "%s failed rejected request on port_id: %02x%02x%02x Completion status 0x%x, response 0x%x\n", 153 routine, vha->d_id.b.domain, 154 vha->d_id.b.area, vha->d_id.b.al_pa, 155 comp_status, ct_rsp->header.response); 156 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 157 0x2078, (uint8_t *)&ct_rsp->header, 158 sizeof(struct ct_rsp_hdr)); 159 rval = QLA_INVALID_COMMAND; 160 } else 161 rval = QLA_SUCCESS; 162 break; 163 case CS_PORT_LOGGED_OUT: 164 if (IS_FWI2_CAPABLE(ha)) { 165 if (le16_to_cpu(ms_pkt->loop_id.extended) == 166 NPH_SNS) 167 lid_is_sns = true; 168 } else { 169 if (le16_to_cpu(ms_pkt->loop_id.extended) == 170 SIMPLE_NAME_SERVER) 171 lid_is_sns = true; 172 } 173 if (lid_is_sns) { 174 ql_dbg(ql_dbg_async, vha, 0x502b, 175 "%s failed, Name server has logged out", 176 routine); 177 rval = QLA_NOT_LOGGED_IN; 178 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); 179 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); 180 } 181 break; 182 case CS_TIMEOUT: 183 rval = QLA_FUNCTION_TIMEOUT; 184 /* fall through */ 185 default: 186 ql_dbg(ql_dbg_disc, vha, 0x2033, 187 "%s failed, completion status (%x) on port_id: " 188 "%02x%02x%02x.\n", routine, comp_status, 189 vha->d_id.b.domain, vha->d_id.b.area, 190 vha->d_id.b.al_pa); 191 break; 192 } 193 } 194 return rval; 195 } 196 197 /** 198 * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command. 199 * @ha: HA context 200 * @fcport: fcport entry to updated 201 * 202 * Returns 0 on success. 203 */ 204 int 205 qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport) 206 { 207 int rval; 208 209 ms_iocb_entry_t *ms_pkt; 210 struct ct_sns_req *ct_req; 211 struct ct_sns_rsp *ct_rsp; 212 struct qla_hw_data *ha = vha->hw; 213 struct ct_arg arg; 214 215 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 216 return qla2x00_sns_ga_nxt(vha, fcport); 217 218 arg.iocb = ha->ms_iocb; 219 arg.req_dma = ha->ct_sns_dma; 220 arg.rsp_dma = ha->ct_sns_dma; 221 arg.req_size = GA_NXT_REQ_SIZE; 222 arg.rsp_size = GA_NXT_RSP_SIZE; 223 arg.nport_handle = NPH_SNS; 224 225 /* Issue GA_NXT */ 226 /* Prepare common MS IOCB */ 227 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 228 229 /* Prepare CT request */ 230 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GA_NXT_CMD, 231 GA_NXT_RSP_SIZE); 232 ct_rsp = &ha->ct_sns->p.rsp; 233 234 /* Prepare CT arguments -- port_id */ 235 ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain; 236 ct_req->req.port_id.port_id[1] = fcport->d_id.b.area; 237 ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa; 238 239 /* Execute MS IOCB */ 240 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 241 sizeof(ms_iocb_entry_t)); 242 if (rval != QLA_SUCCESS) { 243 /*EMPTY*/ 244 ql_dbg(ql_dbg_disc, vha, 0x2062, 245 "GA_NXT issue IOCB failed (%d).\n", rval); 246 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GA_NXT") != 247 QLA_SUCCESS) { 248 rval = QLA_FUNCTION_FAILED; 249 } else { 250 /* Populate fc_port_t entry. */ 251 fcport->d_id.b.domain = ct_rsp->rsp.ga_nxt.port_id[0]; 252 fcport->d_id.b.area = ct_rsp->rsp.ga_nxt.port_id[1]; 253 fcport->d_id.b.al_pa = ct_rsp->rsp.ga_nxt.port_id[2]; 254 255 memcpy(fcport->node_name, ct_rsp->rsp.ga_nxt.node_name, 256 WWN_SIZE); 257 memcpy(fcport->port_name, ct_rsp->rsp.ga_nxt.port_name, 258 WWN_SIZE); 259 260 fcport->fc4_type = (ct_rsp->rsp.ga_nxt.fc4_types[2] & BIT_0) ? 261 FC4_TYPE_FCP_SCSI : FC4_TYPE_OTHER; 262 263 if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE && 264 ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE) 265 fcport->d_id.b.domain = 0xf0; 266 267 ql_dbg(ql_dbg_disc, vha, 0x2063, 268 "GA_NXT entry - nn %8phN pn %8phN " 269 "port_id=%02x%02x%02x.\n", 270 fcport->node_name, fcport->port_name, 271 fcport->d_id.b.domain, fcport->d_id.b.area, 272 fcport->d_id.b.al_pa); 273 } 274 275 return (rval); 276 } 277 278 static inline int 279 qla2x00_gid_pt_rsp_size(scsi_qla_host_t *vha) 280 { 281 return vha->hw->max_fibre_devices * 4 + 16; 282 } 283 284 /** 285 * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command. 286 * @ha: HA context 287 * @list: switch info entries to populate 288 * 289 * NOTE: Non-Nx_Ports are not requested. 290 * 291 * Returns 0 on success. 292 */ 293 int 294 qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list) 295 { 296 int rval; 297 uint16_t i; 298 299 ms_iocb_entry_t *ms_pkt; 300 struct ct_sns_req *ct_req; 301 struct ct_sns_rsp *ct_rsp; 302 303 struct ct_sns_gid_pt_data *gid_data; 304 struct qla_hw_data *ha = vha->hw; 305 uint16_t gid_pt_rsp_size; 306 struct ct_arg arg; 307 308 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 309 return qla2x00_sns_gid_pt(vha, list); 310 311 gid_data = NULL; 312 gid_pt_rsp_size = qla2x00_gid_pt_rsp_size(vha); 313 314 arg.iocb = ha->ms_iocb; 315 arg.req_dma = ha->ct_sns_dma; 316 arg.rsp_dma = ha->ct_sns_dma; 317 arg.req_size = GID_PT_REQ_SIZE; 318 arg.rsp_size = gid_pt_rsp_size; 319 arg.nport_handle = NPH_SNS; 320 321 /* Issue GID_PT */ 322 /* Prepare common MS IOCB */ 323 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 324 325 /* Prepare CT request */ 326 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GID_PT_CMD, gid_pt_rsp_size); 327 ct_rsp = &ha->ct_sns->p.rsp; 328 329 /* Prepare CT arguments -- port_type */ 330 ct_req->req.gid_pt.port_type = NS_NX_PORT_TYPE; 331 332 /* Execute MS IOCB */ 333 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 334 sizeof(ms_iocb_entry_t)); 335 if (rval != QLA_SUCCESS) { 336 /*EMPTY*/ 337 ql_dbg(ql_dbg_disc, vha, 0x2055, 338 "GID_PT issue IOCB failed (%d).\n", rval); 339 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GID_PT") != 340 QLA_SUCCESS) { 341 rval = QLA_FUNCTION_FAILED; 342 } else { 343 /* Set port IDs in switch info list. */ 344 for (i = 0; i < ha->max_fibre_devices; i++) { 345 gid_data = &ct_rsp->rsp.gid_pt.entries[i]; 346 list[i].d_id.b.domain = gid_data->port_id[0]; 347 list[i].d_id.b.area = gid_data->port_id[1]; 348 list[i].d_id.b.al_pa = gid_data->port_id[2]; 349 memset(list[i].fabric_port_name, 0, WWN_SIZE); 350 list[i].fp_speed = PORT_SPEED_UNKNOWN; 351 352 /* Last one exit. */ 353 if (gid_data->control_byte & BIT_7) { 354 list[i].d_id.b.rsvd_1 = gid_data->control_byte; 355 break; 356 } 357 } 358 359 /* 360 * If we've used all available slots, then the switch is 361 * reporting back more devices than we can handle with this 362 * single call. Return a failed status, and let GA_NXT handle 363 * the overload. 364 */ 365 if (i == ha->max_fibre_devices) 366 rval = QLA_FUNCTION_FAILED; 367 } 368 369 return (rval); 370 } 371 372 /** 373 * qla2x00_gpn_id() - SNS Get Port Name (GPN_ID) query. 374 * @ha: HA context 375 * @list: switch info entries to populate 376 * 377 * Returns 0 on success. 378 */ 379 int 380 qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list) 381 { 382 int rval = QLA_SUCCESS; 383 uint16_t i; 384 385 ms_iocb_entry_t *ms_pkt; 386 struct ct_sns_req *ct_req; 387 struct ct_sns_rsp *ct_rsp; 388 struct qla_hw_data *ha = vha->hw; 389 struct ct_arg arg; 390 391 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 392 return qla2x00_sns_gpn_id(vha, list); 393 394 arg.iocb = ha->ms_iocb; 395 arg.req_dma = ha->ct_sns_dma; 396 arg.rsp_dma = ha->ct_sns_dma; 397 arg.req_size = GPN_ID_REQ_SIZE; 398 arg.rsp_size = GPN_ID_RSP_SIZE; 399 arg.nport_handle = NPH_SNS; 400 401 for (i = 0; i < ha->max_fibre_devices; i++) { 402 /* Issue GPN_ID */ 403 /* Prepare common MS IOCB */ 404 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 405 406 /* Prepare CT request */ 407 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GPN_ID_CMD, 408 GPN_ID_RSP_SIZE); 409 ct_rsp = &ha->ct_sns->p.rsp; 410 411 /* Prepare CT arguments -- port_id */ 412 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; 413 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; 414 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; 415 416 /* Execute MS IOCB */ 417 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 418 sizeof(ms_iocb_entry_t)); 419 if (rval != QLA_SUCCESS) { 420 /*EMPTY*/ 421 ql_dbg(ql_dbg_disc, vha, 0x2056, 422 "GPN_ID issue IOCB failed (%d).\n", rval); 423 break; 424 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, 425 "GPN_ID") != QLA_SUCCESS) { 426 rval = QLA_FUNCTION_FAILED; 427 break; 428 } else { 429 /* Save portname */ 430 memcpy(list[i].port_name, 431 ct_rsp->rsp.gpn_id.port_name, WWN_SIZE); 432 } 433 434 /* Last device exit. */ 435 if (list[i].d_id.b.rsvd_1 != 0) 436 break; 437 } 438 439 return (rval); 440 } 441 442 /** 443 * qla2x00_gnn_id() - SNS Get Node Name (GNN_ID) query. 444 * @ha: HA context 445 * @list: switch info entries to populate 446 * 447 * Returns 0 on success. 448 */ 449 int 450 qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list) 451 { 452 int rval = QLA_SUCCESS; 453 uint16_t i; 454 struct qla_hw_data *ha = vha->hw; 455 ms_iocb_entry_t *ms_pkt; 456 struct ct_sns_req *ct_req; 457 struct ct_sns_rsp *ct_rsp; 458 struct ct_arg arg; 459 460 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 461 return qla2x00_sns_gnn_id(vha, list); 462 463 arg.iocb = ha->ms_iocb; 464 arg.req_dma = ha->ct_sns_dma; 465 arg.rsp_dma = ha->ct_sns_dma; 466 arg.req_size = GNN_ID_REQ_SIZE; 467 arg.rsp_size = GNN_ID_RSP_SIZE; 468 arg.nport_handle = NPH_SNS; 469 470 for (i = 0; i < ha->max_fibre_devices; i++) { 471 /* Issue GNN_ID */ 472 /* Prepare common MS IOCB */ 473 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 474 475 /* Prepare CT request */ 476 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GNN_ID_CMD, 477 GNN_ID_RSP_SIZE); 478 ct_rsp = &ha->ct_sns->p.rsp; 479 480 /* Prepare CT arguments -- port_id */ 481 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; 482 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; 483 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; 484 485 /* Execute MS IOCB */ 486 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 487 sizeof(ms_iocb_entry_t)); 488 if (rval != QLA_SUCCESS) { 489 /*EMPTY*/ 490 ql_dbg(ql_dbg_disc, vha, 0x2057, 491 "GNN_ID issue IOCB failed (%d).\n", rval); 492 break; 493 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, 494 "GNN_ID") != QLA_SUCCESS) { 495 rval = QLA_FUNCTION_FAILED; 496 break; 497 } else { 498 /* Save nodename */ 499 memcpy(list[i].node_name, 500 ct_rsp->rsp.gnn_id.node_name, WWN_SIZE); 501 502 ql_dbg(ql_dbg_disc, vha, 0x2058, 503 "GID_PT entry - nn %8phN pn %8phN " 504 "portid=%02x%02x%02x.\n", 505 list[i].node_name, list[i].port_name, 506 list[i].d_id.b.domain, list[i].d_id.b.area, 507 list[i].d_id.b.al_pa); 508 } 509 510 /* Last device exit. */ 511 if (list[i].d_id.b.rsvd_1 != 0) 512 break; 513 } 514 515 return (rval); 516 } 517 518 static void qla2x00_async_sns_sp_done(void *s, int rc) 519 { 520 struct srb *sp = s; 521 struct scsi_qla_host *vha = sp->vha; 522 struct ct_sns_pkt *ct_sns; 523 struct qla_work_evt *e; 524 525 sp->rc = rc; 526 if (rc == QLA_SUCCESS) { 527 ql_dbg(ql_dbg_disc, vha, 0x204f, 528 "Async done-%s exiting normally.\n", 529 sp->name); 530 } else if (rc == QLA_FUNCTION_TIMEOUT) { 531 ql_dbg(ql_dbg_disc, vha, 0x204f, 532 "Async done-%s timeout\n", sp->name); 533 } else { 534 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp; 535 memset(ct_sns, 0, sizeof(*ct_sns)); 536 sp->retry_count++; 537 if (sp->retry_count > 3) 538 goto err; 539 540 ql_dbg(ql_dbg_disc, vha, 0x204f, 541 "Async done-%s fail rc %x. Retry count %d\n", 542 sp->name, rc, sp->retry_count); 543 544 e = qla2x00_alloc_work(vha, QLA_EVT_SP_RETRY); 545 if (!e) 546 goto err2; 547 548 del_timer(&sp->u.iocb_cmd.timer); 549 e->u.iosb.sp = sp; 550 qla2x00_post_work(vha, e); 551 return; 552 } 553 554 err: 555 e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP); 556 err2: 557 if (!e) { 558 /* please ignore kernel warning. otherwise, we have mem leak. */ 559 if (sp->u.iocb_cmd.u.ctarg.req) { 560 dma_free_coherent(&vha->hw->pdev->dev, 561 sizeof(struct ct_sns_pkt), 562 sp->u.iocb_cmd.u.ctarg.req, 563 sp->u.iocb_cmd.u.ctarg.req_dma); 564 sp->u.iocb_cmd.u.ctarg.req = NULL; 565 } 566 567 if (sp->u.iocb_cmd.u.ctarg.rsp) { 568 dma_free_coherent(&vha->hw->pdev->dev, 569 sizeof(struct ct_sns_pkt), 570 sp->u.iocb_cmd.u.ctarg.rsp, 571 sp->u.iocb_cmd.u.ctarg.rsp_dma); 572 sp->u.iocb_cmd.u.ctarg.rsp = NULL; 573 } 574 575 sp->free(sp); 576 577 return; 578 } 579 580 e->u.iosb.sp = sp; 581 qla2x00_post_work(vha, e); 582 } 583 584 /** 585 * qla2x00_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. 586 * @ha: HA context 587 * 588 * Returns 0 on success. 589 */ 590 int 591 qla2x00_rft_id(scsi_qla_host_t *vha) 592 { 593 struct qla_hw_data *ha = vha->hw; 594 595 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 596 return qla2x00_sns_rft_id(vha); 597 598 return qla_async_rftid(vha, &vha->d_id); 599 } 600 601 static int qla_async_rftid(scsi_qla_host_t *vha, port_id_t *d_id) 602 { 603 int rval = QLA_MEMORY_ALLOC_FAILED; 604 struct ct_sns_req *ct_req; 605 srb_t *sp; 606 struct ct_sns_pkt *ct_sns; 607 608 if (!vha->flags.online) 609 goto done; 610 611 sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); 612 if (!sp) 613 goto done; 614 615 sp->type = SRB_CT_PTHRU_CMD; 616 sp->name = "rft_id"; 617 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 618 619 sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev, 620 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma, 621 GFP_KERNEL); 622 if (!sp->u.iocb_cmd.u.ctarg.req) { 623 ql_log(ql_log_warn, vha, 0xd041, 624 "%s: Failed to allocate ct_sns request.\n", 625 __func__); 626 goto done_free_sp; 627 } 628 629 sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev, 630 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma, 631 GFP_KERNEL); 632 if (!sp->u.iocb_cmd.u.ctarg.rsp) { 633 ql_log(ql_log_warn, vha, 0xd042, 634 "%s: Failed to allocate ct_sns request.\n", 635 __func__); 636 goto done_free_sp; 637 } 638 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp; 639 memset(ct_sns, 0, sizeof(*ct_sns)); 640 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; 641 642 /* Prepare CT request */ 643 ct_req = qla2x00_prep_ct_req(ct_sns, RFT_ID_CMD, RFT_ID_RSP_SIZE); 644 645 /* Prepare CT arguments -- port_id, FC-4 types */ 646 ct_req->req.rft_id.port_id[0] = vha->d_id.b.domain; 647 ct_req->req.rft_id.port_id[1] = vha->d_id.b.area; 648 ct_req->req.rft_id.port_id[2] = vha->d_id.b.al_pa; 649 ct_req->req.rft_id.fc4_types[2] = 0x01; /* FCP-3 */ 650 651 if (vha->flags.nvme_enabled) 652 ct_req->req.rft_id.fc4_types[6] = 1; /* NVMe type 28h */ 653 654 sp->u.iocb_cmd.u.ctarg.req_size = RFT_ID_REQ_SIZE; 655 sp->u.iocb_cmd.u.ctarg.rsp_size = RFT_ID_RSP_SIZE; 656 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 657 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 658 sp->done = qla2x00_async_sns_sp_done; 659 660 rval = qla2x00_start_sp(sp); 661 if (rval != QLA_SUCCESS) { 662 ql_dbg(ql_dbg_disc, vha, 0x2043, 663 "RFT_ID issue IOCB failed (%d).\n", rval); 664 goto done_free_sp; 665 } 666 ql_dbg(ql_dbg_disc, vha, 0xffff, 667 "Async-%s - hdl=%x portid %06x.\n", 668 sp->name, sp->handle, d_id->b24); 669 return rval; 670 done_free_sp: 671 sp->free(sp); 672 done: 673 return rval; 674 } 675 676 /** 677 * qla2x00_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the HBA. 678 * @ha: HA context 679 * 680 * Returns 0 on success. 681 */ 682 int 683 qla2x00_rff_id(scsi_qla_host_t *vha, u8 type) 684 { 685 struct qla_hw_data *ha = vha->hw; 686 687 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 688 ql_dbg(ql_dbg_disc, vha, 0x2046, 689 "RFF_ID call not supported on ISP2100/ISP2200.\n"); 690 return (QLA_SUCCESS); 691 } 692 693 return qla_async_rffid(vha, &vha->d_id, qlt_rff_id(vha), 694 FC4_TYPE_FCP_SCSI); 695 } 696 697 static int qla_async_rffid(scsi_qla_host_t *vha, port_id_t *d_id, 698 u8 fc4feature, u8 fc4type) 699 { 700 int rval = QLA_MEMORY_ALLOC_FAILED; 701 struct ct_sns_req *ct_req; 702 srb_t *sp; 703 struct ct_sns_pkt *ct_sns; 704 705 sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); 706 if (!sp) 707 goto done; 708 709 sp->type = SRB_CT_PTHRU_CMD; 710 sp->name = "rff_id"; 711 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 712 713 sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev, 714 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma, 715 GFP_KERNEL); 716 if (!sp->u.iocb_cmd.u.ctarg.req) { 717 ql_log(ql_log_warn, vha, 0xd041, 718 "%s: Failed to allocate ct_sns request.\n", 719 __func__); 720 goto done_free_sp; 721 } 722 723 sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev, 724 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma, 725 GFP_KERNEL); 726 if (!sp->u.iocb_cmd.u.ctarg.rsp) { 727 ql_log(ql_log_warn, vha, 0xd042, 728 "%s: Failed to allocate ct_sns request.\n", 729 __func__); 730 goto done_free_sp; 731 } 732 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp; 733 memset(ct_sns, 0, sizeof(*ct_sns)); 734 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; 735 736 /* Prepare CT request */ 737 ct_req = qla2x00_prep_ct_req(ct_sns, RFF_ID_CMD, RFF_ID_RSP_SIZE); 738 739 /* Prepare CT arguments -- port_id, FC-4 feature, FC-4 type */ 740 ct_req->req.rff_id.port_id[0] = d_id->b.domain; 741 ct_req->req.rff_id.port_id[1] = d_id->b.area; 742 ct_req->req.rff_id.port_id[2] = d_id->b.al_pa; 743 ct_req->req.rff_id.fc4_feature = fc4feature; 744 ct_req->req.rff_id.fc4_type = fc4type; /* SCSI - FCP */ 745 746 sp->u.iocb_cmd.u.ctarg.req_size = RFF_ID_REQ_SIZE; 747 sp->u.iocb_cmd.u.ctarg.rsp_size = RFF_ID_RSP_SIZE; 748 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 749 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 750 sp->done = qla2x00_async_sns_sp_done; 751 752 rval = qla2x00_start_sp(sp); 753 if (rval != QLA_SUCCESS) { 754 ql_dbg(ql_dbg_disc, vha, 0x2047, 755 "RFF_ID issue IOCB failed (%d).\n", rval); 756 goto done_free_sp; 757 } 758 759 ql_dbg(ql_dbg_disc, vha, 0xffff, 760 "Async-%s - hdl=%x portid %06x feature %x type %x.\n", 761 sp->name, sp->handle, d_id->b24, fc4feature, fc4type); 762 return rval; 763 764 done_free_sp: 765 sp->free(sp); 766 done: 767 return rval; 768 } 769 770 /** 771 * qla2x00_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA. 772 * @ha: HA context 773 * 774 * Returns 0 on success. 775 */ 776 int 777 qla2x00_rnn_id(scsi_qla_host_t *vha) 778 { 779 struct qla_hw_data *ha = vha->hw; 780 781 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 782 return qla2x00_sns_rnn_id(vha); 783 784 return qla_async_rnnid(vha, &vha->d_id, vha->node_name); 785 } 786 787 static int qla_async_rnnid(scsi_qla_host_t *vha, port_id_t *d_id, 788 u8 *node_name) 789 { 790 int rval = QLA_MEMORY_ALLOC_FAILED; 791 struct ct_sns_req *ct_req; 792 srb_t *sp; 793 struct ct_sns_pkt *ct_sns; 794 795 sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); 796 if (!sp) 797 goto done; 798 799 sp->type = SRB_CT_PTHRU_CMD; 800 sp->name = "rnid"; 801 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 802 803 sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev, 804 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma, 805 GFP_KERNEL); 806 if (!sp->u.iocb_cmd.u.ctarg.req) { 807 ql_log(ql_log_warn, vha, 0xd041, 808 "%s: Failed to allocate ct_sns request.\n", 809 __func__); 810 goto done_free_sp; 811 } 812 813 sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev, 814 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma, 815 GFP_KERNEL); 816 if (!sp->u.iocb_cmd.u.ctarg.rsp) { 817 ql_log(ql_log_warn, vha, 0xd042, 818 "%s: Failed to allocate ct_sns request.\n", 819 __func__); 820 goto done_free_sp; 821 } 822 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp; 823 memset(ct_sns, 0, sizeof(*ct_sns)); 824 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; 825 826 /* Prepare CT request */ 827 ct_req = qla2x00_prep_ct_req(ct_sns, RNN_ID_CMD, RNN_ID_RSP_SIZE); 828 829 /* Prepare CT arguments -- port_id, node_name */ 830 ct_req->req.rnn_id.port_id[0] = vha->d_id.b.domain; 831 ct_req->req.rnn_id.port_id[1] = vha->d_id.b.area; 832 ct_req->req.rnn_id.port_id[2] = vha->d_id.b.al_pa; 833 memcpy(ct_req->req.rnn_id.node_name, vha->node_name, WWN_SIZE); 834 835 sp->u.iocb_cmd.u.ctarg.req_size = RNN_ID_REQ_SIZE; 836 sp->u.iocb_cmd.u.ctarg.rsp_size = RNN_ID_RSP_SIZE; 837 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 838 839 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 840 sp->done = qla2x00_async_sns_sp_done; 841 842 rval = qla2x00_start_sp(sp); 843 if (rval != QLA_SUCCESS) { 844 ql_dbg(ql_dbg_disc, vha, 0x204d, 845 "RNN_ID issue IOCB failed (%d).\n", rval); 846 goto done_free_sp; 847 } 848 ql_dbg(ql_dbg_disc, vha, 0xffff, 849 "Async-%s - hdl=%x portid %06x\n", 850 sp->name, sp->handle, d_id->b24); 851 852 return rval; 853 854 done_free_sp: 855 sp->free(sp); 856 done: 857 return rval; 858 } 859 860 void 861 qla2x00_get_sym_node_name(scsi_qla_host_t *vha, uint8_t *snn, size_t size) 862 { 863 struct qla_hw_data *ha = vha->hw; 864 865 if (IS_QLAFX00(ha)) 866 snprintf(snn, size, "%s FW:v%s DVR:v%s", ha->model_number, 867 ha->mr.fw_version, qla2x00_version_str); 868 else 869 snprintf(snn, size, 870 "%s FW:v%d.%02d.%02d DVR:v%s", ha->model_number, 871 ha->fw_major_version, ha->fw_minor_version, 872 ha->fw_subminor_version, qla2x00_version_str); 873 } 874 875 /** 876 * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA. 877 * @ha: HA context 878 * 879 * Returns 0 on success. 880 */ 881 int 882 qla2x00_rsnn_nn(scsi_qla_host_t *vha) 883 { 884 struct qla_hw_data *ha = vha->hw; 885 886 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 887 ql_dbg(ql_dbg_disc, vha, 0x2050, 888 "RSNN_ID call unsupported on ISP2100/ISP2200.\n"); 889 return (QLA_SUCCESS); 890 } 891 892 return qla_async_rsnn_nn(vha); 893 } 894 895 static int qla_async_rsnn_nn(scsi_qla_host_t *vha) 896 { 897 int rval = QLA_MEMORY_ALLOC_FAILED; 898 struct ct_sns_req *ct_req; 899 srb_t *sp; 900 struct ct_sns_pkt *ct_sns; 901 902 sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); 903 if (!sp) 904 goto done; 905 906 sp->type = SRB_CT_PTHRU_CMD; 907 sp->name = "rsnn_nn"; 908 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 909 910 sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev, 911 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma, 912 GFP_KERNEL); 913 if (!sp->u.iocb_cmd.u.ctarg.req) { 914 ql_log(ql_log_warn, vha, 0xd041, 915 "%s: Failed to allocate ct_sns request.\n", 916 __func__); 917 goto done_free_sp; 918 } 919 920 sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev, 921 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma, 922 GFP_KERNEL); 923 if (!sp->u.iocb_cmd.u.ctarg.rsp) { 924 ql_log(ql_log_warn, vha, 0xd042, 925 "%s: Failed to allocate ct_sns request.\n", 926 __func__); 927 goto done_free_sp; 928 } 929 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp; 930 memset(ct_sns, 0, sizeof(*ct_sns)); 931 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; 932 933 /* Prepare CT request */ 934 ct_req = qla2x00_prep_ct_req(ct_sns, RSNN_NN_CMD, RSNN_NN_RSP_SIZE); 935 936 /* Prepare CT arguments -- node_name, symbolic node_name, size */ 937 memcpy(ct_req->req.rsnn_nn.node_name, vha->node_name, WWN_SIZE); 938 939 /* Prepare the Symbolic Node Name */ 940 qla2x00_get_sym_node_name(vha, ct_req->req.rsnn_nn.sym_node_name, 941 sizeof(ct_req->req.rsnn_nn.sym_node_name)); 942 ct_req->req.rsnn_nn.name_len = 943 (uint8_t)strlen(ct_req->req.rsnn_nn.sym_node_name); 944 945 946 sp->u.iocb_cmd.u.ctarg.req_size = 24 + 1 + ct_req->req.rsnn_nn.name_len; 947 sp->u.iocb_cmd.u.ctarg.rsp_size = RSNN_NN_RSP_SIZE; 948 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 949 950 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 951 sp->done = qla2x00_async_sns_sp_done; 952 953 rval = qla2x00_start_sp(sp); 954 if (rval != QLA_SUCCESS) { 955 ql_dbg(ql_dbg_disc, vha, 0x2043, 956 "RFT_ID issue IOCB failed (%d).\n", rval); 957 goto done_free_sp; 958 } 959 ql_dbg(ql_dbg_disc, vha, 0xffff, 960 "Async-%s - hdl=%x.\n", 961 sp->name, sp->handle); 962 963 return rval; 964 965 done_free_sp: 966 sp->free(sp); 967 done: 968 return rval; 969 } 970 971 /** 972 * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query. 973 * @ha: HA context 974 * @cmd: GS command 975 * @scmd_len: Subcommand length 976 * @data_size: response size in bytes 977 * 978 * Returns a pointer to the @ha's sns_cmd. 979 */ 980 static inline struct sns_cmd_pkt * 981 qla2x00_prep_sns_cmd(scsi_qla_host_t *vha, uint16_t cmd, uint16_t scmd_len, 982 uint16_t data_size) 983 { 984 uint16_t wc; 985 struct sns_cmd_pkt *sns_cmd; 986 struct qla_hw_data *ha = vha->hw; 987 988 sns_cmd = ha->sns_cmd; 989 memset(sns_cmd, 0, sizeof(struct sns_cmd_pkt)); 990 wc = data_size / 2; /* Size in 16bit words. */ 991 sns_cmd->p.cmd.buffer_length = cpu_to_le16(wc); 992 sns_cmd->p.cmd.buffer_address[0] = cpu_to_le32(LSD(ha->sns_cmd_dma)); 993 sns_cmd->p.cmd.buffer_address[1] = cpu_to_le32(MSD(ha->sns_cmd_dma)); 994 sns_cmd->p.cmd.subcommand_length = cpu_to_le16(scmd_len); 995 sns_cmd->p.cmd.subcommand = cpu_to_le16(cmd); 996 wc = (data_size - 16) / 4; /* Size in 32bit words. */ 997 sns_cmd->p.cmd.size = cpu_to_le16(wc); 998 999 vha->qla_stats.control_requests++; 1000 1001 return (sns_cmd); 1002 } 1003 1004 /** 1005 * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command. 1006 * @ha: HA context 1007 * @fcport: fcport entry to updated 1008 * 1009 * This command uses the old Exectute SNS Command mailbox routine. 1010 * 1011 * Returns 0 on success. 1012 */ 1013 static int 1014 qla2x00_sns_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport) 1015 { 1016 int rval = QLA_SUCCESS; 1017 struct qla_hw_data *ha = vha->hw; 1018 struct sns_cmd_pkt *sns_cmd; 1019 1020 /* Issue GA_NXT. */ 1021 /* Prepare SNS command request. */ 1022 sns_cmd = qla2x00_prep_sns_cmd(vha, GA_NXT_CMD, GA_NXT_SNS_SCMD_LEN, 1023 GA_NXT_SNS_DATA_SIZE); 1024 1025 /* Prepare SNS command arguments -- port_id. */ 1026 sns_cmd->p.cmd.param[0] = fcport->d_id.b.al_pa; 1027 sns_cmd->p.cmd.param[1] = fcport->d_id.b.area; 1028 sns_cmd->p.cmd.param[2] = fcport->d_id.b.domain; 1029 1030 /* Execute SNS command. */ 1031 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GA_NXT_SNS_CMD_SIZE / 2, 1032 sizeof(struct sns_cmd_pkt)); 1033 if (rval != QLA_SUCCESS) { 1034 /*EMPTY*/ 1035 ql_dbg(ql_dbg_disc, vha, 0x205f, 1036 "GA_NXT Send SNS failed (%d).\n", rval); 1037 } else if (sns_cmd->p.gan_data[8] != 0x80 || 1038 sns_cmd->p.gan_data[9] != 0x02) { 1039 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2084, 1040 "GA_NXT failed, rejected request ga_nxt_rsp:\n"); 1041 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2074, 1042 sns_cmd->p.gan_data, 16); 1043 rval = QLA_FUNCTION_FAILED; 1044 } else { 1045 /* Populate fc_port_t entry. */ 1046 fcport->d_id.b.domain = sns_cmd->p.gan_data[17]; 1047 fcport->d_id.b.area = sns_cmd->p.gan_data[18]; 1048 fcport->d_id.b.al_pa = sns_cmd->p.gan_data[19]; 1049 1050 memcpy(fcport->node_name, &sns_cmd->p.gan_data[284], WWN_SIZE); 1051 memcpy(fcport->port_name, &sns_cmd->p.gan_data[20], WWN_SIZE); 1052 1053 if (sns_cmd->p.gan_data[16] != NS_N_PORT_TYPE && 1054 sns_cmd->p.gan_data[16] != NS_NL_PORT_TYPE) 1055 fcport->d_id.b.domain = 0xf0; 1056 1057 ql_dbg(ql_dbg_disc, vha, 0x2061, 1058 "GA_NXT entry - nn %8phN pn %8phN " 1059 "port_id=%02x%02x%02x.\n", 1060 fcport->node_name, fcport->port_name, 1061 fcport->d_id.b.domain, fcport->d_id.b.area, 1062 fcport->d_id.b.al_pa); 1063 } 1064 1065 return (rval); 1066 } 1067 1068 /** 1069 * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command. 1070 * @ha: HA context 1071 * @list: switch info entries to populate 1072 * 1073 * This command uses the old Exectute SNS Command mailbox routine. 1074 * 1075 * NOTE: Non-Nx_Ports are not requested. 1076 * 1077 * Returns 0 on success. 1078 */ 1079 static int 1080 qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list) 1081 { 1082 int rval; 1083 struct qla_hw_data *ha = vha->hw; 1084 uint16_t i; 1085 uint8_t *entry; 1086 struct sns_cmd_pkt *sns_cmd; 1087 uint16_t gid_pt_sns_data_size; 1088 1089 gid_pt_sns_data_size = qla2x00_gid_pt_rsp_size(vha); 1090 1091 /* Issue GID_PT. */ 1092 /* Prepare SNS command request. */ 1093 sns_cmd = qla2x00_prep_sns_cmd(vha, GID_PT_CMD, GID_PT_SNS_SCMD_LEN, 1094 gid_pt_sns_data_size); 1095 1096 /* Prepare SNS command arguments -- port_type. */ 1097 sns_cmd->p.cmd.param[0] = NS_NX_PORT_TYPE; 1098 1099 /* Execute SNS command. */ 1100 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GID_PT_SNS_CMD_SIZE / 2, 1101 sizeof(struct sns_cmd_pkt)); 1102 if (rval != QLA_SUCCESS) { 1103 /*EMPTY*/ 1104 ql_dbg(ql_dbg_disc, vha, 0x206d, 1105 "GID_PT Send SNS failed (%d).\n", rval); 1106 } else if (sns_cmd->p.gid_data[8] != 0x80 || 1107 sns_cmd->p.gid_data[9] != 0x02) { 1108 ql_dbg(ql_dbg_disc, vha, 0x202f, 1109 "GID_PT failed, rejected request, gid_rsp:\n"); 1110 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2081, 1111 sns_cmd->p.gid_data, 16); 1112 rval = QLA_FUNCTION_FAILED; 1113 } else { 1114 /* Set port IDs in switch info list. */ 1115 for (i = 0; i < ha->max_fibre_devices; i++) { 1116 entry = &sns_cmd->p.gid_data[(i * 4) + 16]; 1117 list[i].d_id.b.domain = entry[1]; 1118 list[i].d_id.b.area = entry[2]; 1119 list[i].d_id.b.al_pa = entry[3]; 1120 1121 /* Last one exit. */ 1122 if (entry[0] & BIT_7) { 1123 list[i].d_id.b.rsvd_1 = entry[0]; 1124 break; 1125 } 1126 } 1127 1128 /* 1129 * If we've used all available slots, then the switch is 1130 * reporting back more devices that we can handle with this 1131 * single call. Return a failed status, and let GA_NXT handle 1132 * the overload. 1133 */ 1134 if (i == ha->max_fibre_devices) 1135 rval = QLA_FUNCTION_FAILED; 1136 } 1137 1138 return (rval); 1139 } 1140 1141 /** 1142 * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query. 1143 * @ha: HA context 1144 * @list: switch info entries to populate 1145 * 1146 * This command uses the old Exectute SNS Command mailbox routine. 1147 * 1148 * Returns 0 on success. 1149 */ 1150 static int 1151 qla2x00_sns_gpn_id(scsi_qla_host_t *vha, sw_info_t *list) 1152 { 1153 int rval = QLA_SUCCESS; 1154 struct qla_hw_data *ha = vha->hw; 1155 uint16_t i; 1156 struct sns_cmd_pkt *sns_cmd; 1157 1158 for (i = 0; i < ha->max_fibre_devices; i++) { 1159 /* Issue GPN_ID */ 1160 /* Prepare SNS command request. */ 1161 sns_cmd = qla2x00_prep_sns_cmd(vha, GPN_ID_CMD, 1162 GPN_ID_SNS_SCMD_LEN, GPN_ID_SNS_DATA_SIZE); 1163 1164 /* Prepare SNS command arguments -- port_id. */ 1165 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa; 1166 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area; 1167 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain; 1168 1169 /* Execute SNS command. */ 1170 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, 1171 GPN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt)); 1172 if (rval != QLA_SUCCESS) { 1173 /*EMPTY*/ 1174 ql_dbg(ql_dbg_disc, vha, 0x2032, 1175 "GPN_ID Send SNS failed (%d).\n", rval); 1176 } else if (sns_cmd->p.gpn_data[8] != 0x80 || 1177 sns_cmd->p.gpn_data[9] != 0x02) { 1178 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207e, 1179 "GPN_ID failed, rejected request, gpn_rsp:\n"); 1180 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207f, 1181 sns_cmd->p.gpn_data, 16); 1182 rval = QLA_FUNCTION_FAILED; 1183 } else { 1184 /* Save portname */ 1185 memcpy(list[i].port_name, &sns_cmd->p.gpn_data[16], 1186 WWN_SIZE); 1187 } 1188 1189 /* Last device exit. */ 1190 if (list[i].d_id.b.rsvd_1 != 0) 1191 break; 1192 } 1193 1194 return (rval); 1195 } 1196 1197 /** 1198 * qla2x00_sns_gnn_id() - SNS Get Node Name (GNN_ID) query. 1199 * @ha: HA context 1200 * @list: switch info entries to populate 1201 * 1202 * This command uses the old Exectute SNS Command mailbox routine. 1203 * 1204 * Returns 0 on success. 1205 */ 1206 static int 1207 qla2x00_sns_gnn_id(scsi_qla_host_t *vha, sw_info_t *list) 1208 { 1209 int rval = QLA_SUCCESS; 1210 struct qla_hw_data *ha = vha->hw; 1211 uint16_t i; 1212 struct sns_cmd_pkt *sns_cmd; 1213 1214 for (i = 0; i < ha->max_fibre_devices; i++) { 1215 /* Issue GNN_ID */ 1216 /* Prepare SNS command request. */ 1217 sns_cmd = qla2x00_prep_sns_cmd(vha, GNN_ID_CMD, 1218 GNN_ID_SNS_SCMD_LEN, GNN_ID_SNS_DATA_SIZE); 1219 1220 /* Prepare SNS command arguments -- port_id. */ 1221 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa; 1222 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area; 1223 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain; 1224 1225 /* Execute SNS command. */ 1226 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, 1227 GNN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt)); 1228 if (rval != QLA_SUCCESS) { 1229 /*EMPTY*/ 1230 ql_dbg(ql_dbg_disc, vha, 0x203f, 1231 "GNN_ID Send SNS failed (%d).\n", rval); 1232 } else if (sns_cmd->p.gnn_data[8] != 0x80 || 1233 sns_cmd->p.gnn_data[9] != 0x02) { 1234 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2082, 1235 "GNN_ID failed, rejected request, gnn_rsp:\n"); 1236 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207a, 1237 sns_cmd->p.gnn_data, 16); 1238 rval = QLA_FUNCTION_FAILED; 1239 } else { 1240 /* Save nodename */ 1241 memcpy(list[i].node_name, &sns_cmd->p.gnn_data[16], 1242 WWN_SIZE); 1243 1244 ql_dbg(ql_dbg_disc, vha, 0x206e, 1245 "GID_PT entry - nn %8phN pn %8phN " 1246 "port_id=%02x%02x%02x.\n", 1247 list[i].node_name, list[i].port_name, 1248 list[i].d_id.b.domain, list[i].d_id.b.area, 1249 list[i].d_id.b.al_pa); 1250 } 1251 1252 /* Last device exit. */ 1253 if (list[i].d_id.b.rsvd_1 != 0) 1254 break; 1255 } 1256 1257 return (rval); 1258 } 1259 1260 /** 1261 * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. 1262 * @ha: HA context 1263 * 1264 * This command uses the old Exectute SNS Command mailbox routine. 1265 * 1266 * Returns 0 on success. 1267 */ 1268 static int 1269 qla2x00_sns_rft_id(scsi_qla_host_t *vha) 1270 { 1271 int rval; 1272 struct qla_hw_data *ha = vha->hw; 1273 struct sns_cmd_pkt *sns_cmd; 1274 1275 /* Issue RFT_ID. */ 1276 /* Prepare SNS command request. */ 1277 sns_cmd = qla2x00_prep_sns_cmd(vha, RFT_ID_CMD, RFT_ID_SNS_SCMD_LEN, 1278 RFT_ID_SNS_DATA_SIZE); 1279 1280 /* Prepare SNS command arguments -- port_id, FC-4 types */ 1281 sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa; 1282 sns_cmd->p.cmd.param[1] = vha->d_id.b.area; 1283 sns_cmd->p.cmd.param[2] = vha->d_id.b.domain; 1284 1285 sns_cmd->p.cmd.param[5] = 0x01; /* FCP-3 */ 1286 1287 /* Execute SNS command. */ 1288 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RFT_ID_SNS_CMD_SIZE / 2, 1289 sizeof(struct sns_cmd_pkt)); 1290 if (rval != QLA_SUCCESS) { 1291 /*EMPTY*/ 1292 ql_dbg(ql_dbg_disc, vha, 0x2060, 1293 "RFT_ID Send SNS failed (%d).\n", rval); 1294 } else if (sns_cmd->p.rft_data[8] != 0x80 || 1295 sns_cmd->p.rft_data[9] != 0x02) { 1296 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2083, 1297 "RFT_ID failed, rejected request rft_rsp:\n"); 1298 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2080, 1299 sns_cmd->p.rft_data, 16); 1300 rval = QLA_FUNCTION_FAILED; 1301 } else { 1302 ql_dbg(ql_dbg_disc, vha, 0x2073, 1303 "RFT_ID exiting normally.\n"); 1304 } 1305 1306 return (rval); 1307 } 1308 1309 /** 1310 * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA. 1311 * HBA. 1312 * @ha: HA context 1313 * 1314 * This command uses the old Exectute SNS Command mailbox routine. 1315 * 1316 * Returns 0 on success. 1317 */ 1318 static int 1319 qla2x00_sns_rnn_id(scsi_qla_host_t *vha) 1320 { 1321 int rval; 1322 struct qla_hw_data *ha = vha->hw; 1323 struct sns_cmd_pkt *sns_cmd; 1324 1325 /* Issue RNN_ID. */ 1326 /* Prepare SNS command request. */ 1327 sns_cmd = qla2x00_prep_sns_cmd(vha, RNN_ID_CMD, RNN_ID_SNS_SCMD_LEN, 1328 RNN_ID_SNS_DATA_SIZE); 1329 1330 /* Prepare SNS command arguments -- port_id, nodename. */ 1331 sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa; 1332 sns_cmd->p.cmd.param[1] = vha->d_id.b.area; 1333 sns_cmd->p.cmd.param[2] = vha->d_id.b.domain; 1334 1335 sns_cmd->p.cmd.param[4] = vha->node_name[7]; 1336 sns_cmd->p.cmd.param[5] = vha->node_name[6]; 1337 sns_cmd->p.cmd.param[6] = vha->node_name[5]; 1338 sns_cmd->p.cmd.param[7] = vha->node_name[4]; 1339 sns_cmd->p.cmd.param[8] = vha->node_name[3]; 1340 sns_cmd->p.cmd.param[9] = vha->node_name[2]; 1341 sns_cmd->p.cmd.param[10] = vha->node_name[1]; 1342 sns_cmd->p.cmd.param[11] = vha->node_name[0]; 1343 1344 /* Execute SNS command. */ 1345 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RNN_ID_SNS_CMD_SIZE / 2, 1346 sizeof(struct sns_cmd_pkt)); 1347 if (rval != QLA_SUCCESS) { 1348 /*EMPTY*/ 1349 ql_dbg(ql_dbg_disc, vha, 0x204a, 1350 "RNN_ID Send SNS failed (%d).\n", rval); 1351 } else if (sns_cmd->p.rnn_data[8] != 0x80 || 1352 sns_cmd->p.rnn_data[9] != 0x02) { 1353 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207b, 1354 "RNN_ID failed, rejected request, rnn_rsp:\n"); 1355 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207c, 1356 sns_cmd->p.rnn_data, 16); 1357 rval = QLA_FUNCTION_FAILED; 1358 } else { 1359 ql_dbg(ql_dbg_disc, vha, 0x204c, 1360 "RNN_ID exiting normally.\n"); 1361 } 1362 1363 return (rval); 1364 } 1365 1366 /** 1367 * qla2x00_mgmt_svr_login() - Login to fabric Management Service. 1368 * @ha: HA context 1369 * 1370 * Returns 0 on success. 1371 */ 1372 int 1373 qla2x00_mgmt_svr_login(scsi_qla_host_t *vha) 1374 { 1375 int ret, rval; 1376 uint16_t mb[MAILBOX_REGISTER_COUNT]; 1377 struct qla_hw_data *ha = vha->hw; 1378 ret = QLA_SUCCESS; 1379 if (vha->flags.management_server_logged_in) 1380 return ret; 1381 1382 rval = ha->isp_ops->fabric_login(vha, vha->mgmt_svr_loop_id, 0xff, 0xff, 1383 0xfa, mb, BIT_1); 1384 if (rval != QLA_SUCCESS || mb[0] != MBS_COMMAND_COMPLETE) { 1385 if (rval == QLA_MEMORY_ALLOC_FAILED) 1386 ql_dbg(ql_dbg_disc, vha, 0x2085, 1387 "Failed management_server login: loopid=%x " 1388 "rval=%d\n", vha->mgmt_svr_loop_id, rval); 1389 else 1390 ql_dbg(ql_dbg_disc, vha, 0x2024, 1391 "Failed management_server login: loopid=%x " 1392 "mb[0]=%x mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x.\n", 1393 vha->mgmt_svr_loop_id, mb[0], mb[1], mb[2], mb[6], 1394 mb[7]); 1395 ret = QLA_FUNCTION_FAILED; 1396 } else 1397 vha->flags.management_server_logged_in = 1; 1398 1399 return ret; 1400 } 1401 1402 /** 1403 * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query. 1404 * @ha: HA context 1405 * @req_size: request size in bytes 1406 * @rsp_size: response size in bytes 1407 * 1408 * Returns a pointer to the @ha's ms_iocb. 1409 */ 1410 void * 1411 qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size, 1412 uint32_t rsp_size) 1413 { 1414 ms_iocb_entry_t *ms_pkt; 1415 struct qla_hw_data *ha = vha->hw; 1416 ms_pkt = ha->ms_iocb; 1417 memset(ms_pkt, 0, sizeof(ms_iocb_entry_t)); 1418 1419 ms_pkt->entry_type = MS_IOCB_TYPE; 1420 ms_pkt->entry_count = 1; 1421 SET_TARGET_ID(ha, ms_pkt->loop_id, vha->mgmt_svr_loop_id); 1422 ms_pkt->control_flags = cpu_to_le16(CF_READ | CF_HEAD_TAG); 1423 ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); 1424 ms_pkt->cmd_dsd_count = cpu_to_le16(1); 1425 ms_pkt->total_dsd_count = cpu_to_le16(2); 1426 ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size); 1427 ms_pkt->req_bytecount = cpu_to_le32(req_size); 1428 1429 ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 1430 ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 1431 ms_pkt->dseg_req_length = ms_pkt->req_bytecount; 1432 1433 ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 1434 ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 1435 ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount; 1436 1437 return ms_pkt; 1438 } 1439 1440 /** 1441 * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query. 1442 * @ha: HA context 1443 * @req_size: request size in bytes 1444 * @rsp_size: response size in bytes 1445 * 1446 * Returns a pointer to the @ha's ms_iocb. 1447 */ 1448 void * 1449 qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size, 1450 uint32_t rsp_size) 1451 { 1452 struct ct_entry_24xx *ct_pkt; 1453 struct qla_hw_data *ha = vha->hw; 1454 1455 ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; 1456 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx)); 1457 1458 ct_pkt->entry_type = CT_IOCB_TYPE; 1459 ct_pkt->entry_count = 1; 1460 ct_pkt->nport_handle = cpu_to_le16(vha->mgmt_svr_loop_id); 1461 ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); 1462 ct_pkt->cmd_dsd_count = cpu_to_le16(1); 1463 ct_pkt->rsp_dsd_count = cpu_to_le16(1); 1464 ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size); 1465 ct_pkt->cmd_byte_count = cpu_to_le32(req_size); 1466 1467 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 1468 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 1469 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; 1470 1471 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 1472 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 1473 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; 1474 ct_pkt->vp_index = vha->vp_idx; 1475 1476 return ct_pkt; 1477 } 1478 1479 static inline ms_iocb_entry_t * 1480 qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size) 1481 { 1482 struct qla_hw_data *ha = vha->hw; 1483 ms_iocb_entry_t *ms_pkt = ha->ms_iocb; 1484 struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; 1485 1486 if (IS_FWI2_CAPABLE(ha)) { 1487 ct_pkt->cmd_byte_count = cpu_to_le32(req_size); 1488 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; 1489 } else { 1490 ms_pkt->req_bytecount = cpu_to_le32(req_size); 1491 ms_pkt->dseg_req_length = ms_pkt->req_bytecount; 1492 } 1493 1494 return ms_pkt; 1495 } 1496 1497 /** 1498 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query. 1499 * @ct_req: CT request buffer 1500 * @cmd: GS command 1501 * @rsp_size: response size in bytes 1502 * 1503 * Returns a pointer to the intitialized @ct_req. 1504 */ 1505 static inline struct ct_sns_req * 1506 qla2x00_prep_ct_fdmi_req(struct ct_sns_pkt *p, uint16_t cmd, 1507 uint16_t rsp_size) 1508 { 1509 memset(p, 0, sizeof(struct ct_sns_pkt)); 1510 1511 p->p.req.header.revision = 0x01; 1512 p->p.req.header.gs_type = 0xFA; 1513 p->p.req.header.gs_subtype = 0x10; 1514 p->p.req.command = cpu_to_be16(cmd); 1515 p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); 1516 1517 return &p->p.req; 1518 } 1519 1520 /** 1521 * qla2x00_fdmi_rhba() - 1522 * @ha: HA context 1523 * 1524 * Returns 0 on success. 1525 */ 1526 static int 1527 qla2x00_fdmi_rhba(scsi_qla_host_t *vha) 1528 { 1529 int rval, alen; 1530 uint32_t size, sn; 1531 1532 ms_iocb_entry_t *ms_pkt; 1533 struct ct_sns_req *ct_req; 1534 struct ct_sns_rsp *ct_rsp; 1535 void *entries; 1536 struct ct_fdmi_hba_attr *eiter; 1537 struct qla_hw_data *ha = vha->hw; 1538 1539 /* Issue RHBA */ 1540 /* Prepare common MS IOCB */ 1541 /* Request size adjusted after CT preparation */ 1542 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE); 1543 1544 /* Prepare CT request */ 1545 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RHBA_CMD, RHBA_RSP_SIZE); 1546 ct_rsp = &ha->ct_sns->p.rsp; 1547 1548 /* Prepare FDMI command arguments -- attribute block, attributes. */ 1549 memcpy(ct_req->req.rhba.hba_identifier, vha->port_name, WWN_SIZE); 1550 ct_req->req.rhba.entry_count = cpu_to_be32(1); 1551 memcpy(ct_req->req.rhba.port_name, vha->port_name, WWN_SIZE); 1552 size = 2 * WWN_SIZE + 4 + 4; 1553 1554 /* Attributes */ 1555 ct_req->req.rhba.attrs.count = 1556 cpu_to_be32(FDMI_HBA_ATTR_COUNT); 1557 entries = ct_req->req.rhba.hba_identifier; 1558 1559 /* Nodename. */ 1560 eiter = entries + size; 1561 eiter->type = cpu_to_be16(FDMI_HBA_NODE_NAME); 1562 eiter->len = cpu_to_be16(4 + WWN_SIZE); 1563 memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE); 1564 size += 4 + WWN_SIZE; 1565 1566 ql_dbg(ql_dbg_disc, vha, 0x2025, 1567 "NodeName = %8phN.\n", eiter->a.node_name); 1568 1569 /* Manufacturer. */ 1570 eiter = entries + size; 1571 eiter->type = cpu_to_be16(FDMI_HBA_MANUFACTURER); 1572 alen = strlen(QLA2XXX_MANUFACTURER); 1573 snprintf(eiter->a.manufacturer, sizeof(eiter->a.manufacturer), 1574 "%s", "QLogic Corporation"); 1575 alen += 4 - (alen & 3); 1576 eiter->len = cpu_to_be16(4 + alen); 1577 size += 4 + alen; 1578 1579 ql_dbg(ql_dbg_disc, vha, 0x2026, 1580 "Manufacturer = %s.\n", eiter->a.manufacturer); 1581 1582 /* Serial number. */ 1583 eiter = entries + size; 1584 eiter->type = cpu_to_be16(FDMI_HBA_SERIAL_NUMBER); 1585 if (IS_FWI2_CAPABLE(ha)) 1586 qla2xxx_get_vpd_field(vha, "SN", eiter->a.serial_num, 1587 sizeof(eiter->a.serial_num)); 1588 else { 1589 sn = ((ha->serial0 & 0x1f) << 16) | 1590 (ha->serial2 << 8) | ha->serial1; 1591 snprintf(eiter->a.serial_num, sizeof(eiter->a.serial_num), 1592 "%c%05d", 'A' + sn / 100000, sn % 100000); 1593 } 1594 alen = strlen(eiter->a.serial_num); 1595 alen += 4 - (alen & 3); 1596 eiter->len = cpu_to_be16(4 + alen); 1597 size += 4 + alen; 1598 1599 ql_dbg(ql_dbg_disc, vha, 0x2027, 1600 "Serial no. = %s.\n", eiter->a.serial_num); 1601 1602 /* Model name. */ 1603 eiter = entries + size; 1604 eiter->type = cpu_to_be16(FDMI_HBA_MODEL); 1605 snprintf(eiter->a.model, sizeof(eiter->a.model), 1606 "%s", ha->model_number); 1607 alen = strlen(eiter->a.model); 1608 alen += 4 - (alen & 3); 1609 eiter->len = cpu_to_be16(4 + alen); 1610 size += 4 + alen; 1611 1612 ql_dbg(ql_dbg_disc, vha, 0x2028, 1613 "Model Name = %s.\n", eiter->a.model); 1614 1615 /* Model description. */ 1616 eiter = entries + size; 1617 eiter->type = cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION); 1618 snprintf(eiter->a.model_desc, sizeof(eiter->a.model_desc), 1619 "%s", ha->model_desc); 1620 alen = strlen(eiter->a.model_desc); 1621 alen += 4 - (alen & 3); 1622 eiter->len = cpu_to_be16(4 + alen); 1623 size += 4 + alen; 1624 1625 ql_dbg(ql_dbg_disc, vha, 0x2029, 1626 "Model Desc = %s.\n", eiter->a.model_desc); 1627 1628 /* Hardware version. */ 1629 eiter = entries + size; 1630 eiter->type = cpu_to_be16(FDMI_HBA_HARDWARE_VERSION); 1631 if (!IS_FWI2_CAPABLE(ha)) { 1632 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version), 1633 "HW:%s", ha->adapter_id); 1634 } else if (qla2xxx_get_vpd_field(vha, "MN", eiter->a.hw_version, 1635 sizeof(eiter->a.hw_version))) { 1636 ; 1637 } else if (qla2xxx_get_vpd_field(vha, "EC", eiter->a.hw_version, 1638 sizeof(eiter->a.hw_version))) { 1639 ; 1640 } else { 1641 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version), 1642 "HW:%s", ha->adapter_id); 1643 } 1644 alen = strlen(eiter->a.hw_version); 1645 alen += 4 - (alen & 3); 1646 eiter->len = cpu_to_be16(4 + alen); 1647 size += 4 + alen; 1648 1649 ql_dbg(ql_dbg_disc, vha, 0x202a, 1650 "Hardware ver = %s.\n", eiter->a.hw_version); 1651 1652 /* Driver version. */ 1653 eiter = entries + size; 1654 eiter->type = cpu_to_be16(FDMI_HBA_DRIVER_VERSION); 1655 snprintf(eiter->a.driver_version, sizeof(eiter->a.driver_version), 1656 "%s", qla2x00_version_str); 1657 alen = strlen(eiter->a.driver_version); 1658 alen += 4 - (alen & 3); 1659 eiter->len = cpu_to_be16(4 + alen); 1660 size += 4 + alen; 1661 1662 ql_dbg(ql_dbg_disc, vha, 0x202b, 1663 "Driver ver = %s.\n", eiter->a.driver_version); 1664 1665 /* Option ROM version. */ 1666 eiter = entries + size; 1667 eiter->type = cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION); 1668 snprintf(eiter->a.orom_version, sizeof(eiter->a.orom_version), 1669 "%d.%02d", ha->bios_revision[1], ha->bios_revision[0]); 1670 alen = strlen(eiter->a.orom_version); 1671 alen += 4 - (alen & 3); 1672 eiter->len = cpu_to_be16(4 + alen); 1673 size += 4 + alen; 1674 1675 ql_dbg(ql_dbg_disc, vha , 0x202c, 1676 "Optrom vers = %s.\n", eiter->a.orom_version); 1677 1678 /* Firmware version */ 1679 eiter = entries + size; 1680 eiter->type = cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION); 1681 ha->isp_ops->fw_version_str(vha, eiter->a.fw_version, 1682 sizeof(eiter->a.fw_version)); 1683 alen = strlen(eiter->a.fw_version); 1684 alen += 4 - (alen & 3); 1685 eiter->len = cpu_to_be16(4 + alen); 1686 size += 4 + alen; 1687 1688 ql_dbg(ql_dbg_disc, vha, 0x202d, 1689 "Firmware vers = %s.\n", eiter->a.fw_version); 1690 1691 /* Update MS request size. */ 1692 qla2x00_update_ms_fdmi_iocb(vha, size + 16); 1693 1694 ql_dbg(ql_dbg_disc, vha, 0x202e, 1695 "RHBA identifier = %8phN size=%d.\n", 1696 ct_req->req.rhba.hba_identifier, size); 1697 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2076, 1698 entries, size); 1699 1700 /* Execute MS IOCB */ 1701 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 1702 sizeof(ms_iocb_entry_t)); 1703 if (rval != QLA_SUCCESS) { 1704 /*EMPTY*/ 1705 ql_dbg(ql_dbg_disc, vha, 0x2030, 1706 "RHBA issue IOCB failed (%d).\n", rval); 1707 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA") != 1708 QLA_SUCCESS) { 1709 rval = QLA_FUNCTION_FAILED; 1710 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM && 1711 ct_rsp->header.explanation_code == 1712 CT_EXPL_ALREADY_REGISTERED) { 1713 ql_dbg(ql_dbg_disc, vha, 0x2034, 1714 "HBA already registered.\n"); 1715 rval = QLA_ALREADY_REGISTERED; 1716 } else { 1717 ql_dbg(ql_dbg_disc, vha, 0x20ad, 1718 "RHBA FDMI registration failed, CT Reason code: 0x%x, CT Explanation 0x%x\n", 1719 ct_rsp->header.reason_code, 1720 ct_rsp->header.explanation_code); 1721 } 1722 } else { 1723 ql_dbg(ql_dbg_disc, vha, 0x2035, 1724 "RHBA exiting normally.\n"); 1725 } 1726 1727 return rval; 1728 } 1729 1730 /** 1731 * qla2x00_fdmi_rpa() - 1732 * @ha: HA context 1733 * 1734 * Returns 0 on success. 1735 */ 1736 static int 1737 qla2x00_fdmi_rpa(scsi_qla_host_t *vha) 1738 { 1739 int rval, alen; 1740 uint32_t size; 1741 struct qla_hw_data *ha = vha->hw; 1742 ms_iocb_entry_t *ms_pkt; 1743 struct ct_sns_req *ct_req; 1744 struct ct_sns_rsp *ct_rsp; 1745 void *entries; 1746 struct ct_fdmi_port_attr *eiter; 1747 struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb; 1748 struct new_utsname *p_sysid = NULL; 1749 1750 /* Issue RPA */ 1751 /* Prepare common MS IOCB */ 1752 /* Request size adjusted after CT preparation */ 1753 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE); 1754 1755 /* Prepare CT request */ 1756 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPA_CMD, 1757 RPA_RSP_SIZE); 1758 ct_rsp = &ha->ct_sns->p.rsp; 1759 1760 /* Prepare FDMI command arguments -- attribute block, attributes. */ 1761 memcpy(ct_req->req.rpa.port_name, vha->port_name, WWN_SIZE); 1762 size = WWN_SIZE + 4; 1763 1764 /* Attributes */ 1765 ct_req->req.rpa.attrs.count = cpu_to_be32(FDMI_PORT_ATTR_COUNT); 1766 entries = ct_req->req.rpa.port_name; 1767 1768 /* FC4 types. */ 1769 eiter = entries + size; 1770 eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPES); 1771 eiter->len = cpu_to_be16(4 + 32); 1772 eiter->a.fc4_types[2] = 0x01; 1773 size += 4 + 32; 1774 1775 ql_dbg(ql_dbg_disc, vha, 0x2039, 1776 "FC4_TYPES=%02x %02x.\n", 1777 eiter->a.fc4_types[2], 1778 eiter->a.fc4_types[1]); 1779 1780 /* Supported speed. */ 1781 eiter = entries + size; 1782 eiter->type = cpu_to_be16(FDMI_PORT_SUPPORT_SPEED); 1783 eiter->len = cpu_to_be16(4 + 4); 1784 if (IS_CNA_CAPABLE(ha)) 1785 eiter->a.sup_speed = cpu_to_be32( 1786 FDMI_PORT_SPEED_10GB); 1787 else if (IS_QLA27XX(ha)) 1788 eiter->a.sup_speed = cpu_to_be32( 1789 FDMI_PORT_SPEED_32GB| 1790 FDMI_PORT_SPEED_16GB| 1791 FDMI_PORT_SPEED_8GB); 1792 else if (IS_QLA2031(ha)) 1793 eiter->a.sup_speed = cpu_to_be32( 1794 FDMI_PORT_SPEED_16GB| 1795 FDMI_PORT_SPEED_8GB| 1796 FDMI_PORT_SPEED_4GB); 1797 else if (IS_QLA25XX(ha)) 1798 eiter->a.sup_speed = cpu_to_be32( 1799 FDMI_PORT_SPEED_8GB| 1800 FDMI_PORT_SPEED_4GB| 1801 FDMI_PORT_SPEED_2GB| 1802 FDMI_PORT_SPEED_1GB); 1803 else if (IS_QLA24XX_TYPE(ha)) 1804 eiter->a.sup_speed = cpu_to_be32( 1805 FDMI_PORT_SPEED_4GB| 1806 FDMI_PORT_SPEED_2GB| 1807 FDMI_PORT_SPEED_1GB); 1808 else if (IS_QLA23XX(ha)) 1809 eiter->a.sup_speed = cpu_to_be32( 1810 FDMI_PORT_SPEED_2GB| 1811 FDMI_PORT_SPEED_1GB); 1812 else 1813 eiter->a.sup_speed = cpu_to_be32( 1814 FDMI_PORT_SPEED_1GB); 1815 size += 4 + 4; 1816 1817 ql_dbg(ql_dbg_disc, vha, 0x203a, 1818 "Supported_Speed=%x.\n", eiter->a.sup_speed); 1819 1820 /* Current speed. */ 1821 eiter = entries + size; 1822 eiter->type = cpu_to_be16(FDMI_PORT_CURRENT_SPEED); 1823 eiter->len = cpu_to_be16(4 + 4); 1824 switch (ha->link_data_rate) { 1825 case PORT_SPEED_1GB: 1826 eiter->a.cur_speed = 1827 cpu_to_be32(FDMI_PORT_SPEED_1GB); 1828 break; 1829 case PORT_SPEED_2GB: 1830 eiter->a.cur_speed = 1831 cpu_to_be32(FDMI_PORT_SPEED_2GB); 1832 break; 1833 case PORT_SPEED_4GB: 1834 eiter->a.cur_speed = 1835 cpu_to_be32(FDMI_PORT_SPEED_4GB); 1836 break; 1837 case PORT_SPEED_8GB: 1838 eiter->a.cur_speed = 1839 cpu_to_be32(FDMI_PORT_SPEED_8GB); 1840 break; 1841 case PORT_SPEED_10GB: 1842 eiter->a.cur_speed = 1843 cpu_to_be32(FDMI_PORT_SPEED_10GB); 1844 break; 1845 case PORT_SPEED_16GB: 1846 eiter->a.cur_speed = 1847 cpu_to_be32(FDMI_PORT_SPEED_16GB); 1848 break; 1849 case PORT_SPEED_32GB: 1850 eiter->a.cur_speed = 1851 cpu_to_be32(FDMI_PORT_SPEED_32GB); 1852 break; 1853 default: 1854 eiter->a.cur_speed = 1855 cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN); 1856 break; 1857 } 1858 size += 4 + 4; 1859 1860 ql_dbg(ql_dbg_disc, vha, 0x203b, 1861 "Current_Speed=%x.\n", eiter->a.cur_speed); 1862 1863 /* Max frame size. */ 1864 eiter = entries + size; 1865 eiter->type = cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE); 1866 eiter->len = cpu_to_be16(4 + 4); 1867 eiter->a.max_frame_size = IS_FWI2_CAPABLE(ha) ? 1868 le16_to_cpu(icb24->frame_payload_size) : 1869 le16_to_cpu(ha->init_cb->frame_payload_size); 1870 eiter->a.max_frame_size = cpu_to_be32(eiter->a.max_frame_size); 1871 size += 4 + 4; 1872 1873 ql_dbg(ql_dbg_disc, vha, 0x203c, 1874 "Max_Frame_Size=%x.\n", eiter->a.max_frame_size); 1875 1876 /* OS device name. */ 1877 eiter = entries + size; 1878 eiter->type = cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME); 1879 snprintf(eiter->a.os_dev_name, sizeof(eiter->a.os_dev_name), 1880 "%s:host%lu", QLA2XXX_DRIVER_NAME, vha->host_no); 1881 alen = strlen(eiter->a.os_dev_name); 1882 alen += 4 - (alen & 3); 1883 eiter->len = cpu_to_be16(4 + alen); 1884 size += 4 + alen; 1885 1886 ql_dbg(ql_dbg_disc, vha, 0x204b, 1887 "OS_Device_Name=%s.\n", eiter->a.os_dev_name); 1888 1889 /* Hostname. */ 1890 eiter = entries + size; 1891 eiter->type = cpu_to_be16(FDMI_PORT_HOST_NAME); 1892 p_sysid = utsname(); 1893 if (p_sysid) { 1894 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name), 1895 "%s", p_sysid->nodename); 1896 } else { 1897 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name), 1898 "%s", fc_host_system_hostname(vha->host)); 1899 } 1900 alen = strlen(eiter->a.host_name); 1901 alen += 4 - (alen & 3); 1902 eiter->len = cpu_to_be16(4 + alen); 1903 size += 4 + alen; 1904 1905 ql_dbg(ql_dbg_disc, vha, 0x203d, "HostName=%s.\n", eiter->a.host_name); 1906 1907 /* Update MS request size. */ 1908 qla2x00_update_ms_fdmi_iocb(vha, size + 16); 1909 1910 ql_dbg(ql_dbg_disc, vha, 0x203e, 1911 "RPA portname %016llx, size = %d.\n", 1912 wwn_to_u64(ct_req->req.rpa.port_name), size); 1913 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2079, 1914 entries, size); 1915 1916 /* Execute MS IOCB */ 1917 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 1918 sizeof(ms_iocb_entry_t)); 1919 if (rval != QLA_SUCCESS) { 1920 /*EMPTY*/ 1921 ql_dbg(ql_dbg_disc, vha, 0x2040, 1922 "RPA issue IOCB failed (%d).\n", rval); 1923 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA") != 1924 QLA_SUCCESS) { 1925 rval = QLA_FUNCTION_FAILED; 1926 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM && 1927 ct_rsp->header.explanation_code == 1928 CT_EXPL_ALREADY_REGISTERED) { 1929 ql_dbg(ql_dbg_disc, vha, 0x20cd, 1930 "RPA already registered.\n"); 1931 rval = QLA_ALREADY_REGISTERED; 1932 } 1933 1934 } else { 1935 ql_dbg(ql_dbg_disc, vha, 0x2041, 1936 "RPA exiting normally.\n"); 1937 } 1938 1939 return rval; 1940 } 1941 1942 /** 1943 * qla2x00_fdmiv2_rhba() - 1944 * @ha: HA context 1945 * 1946 * Returns 0 on success. 1947 */ 1948 static int 1949 qla2x00_fdmiv2_rhba(scsi_qla_host_t *vha) 1950 { 1951 int rval, alen; 1952 uint32_t size, sn; 1953 ms_iocb_entry_t *ms_pkt; 1954 struct ct_sns_req *ct_req; 1955 struct ct_sns_rsp *ct_rsp; 1956 void *entries; 1957 struct ct_fdmiv2_hba_attr *eiter; 1958 struct qla_hw_data *ha = vha->hw; 1959 struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb; 1960 struct new_utsname *p_sysid = NULL; 1961 1962 /* Issue RHBA */ 1963 /* Prepare common MS IOCB */ 1964 /* Request size adjusted after CT preparation */ 1965 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE); 1966 1967 /* Prepare CT request */ 1968 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RHBA_CMD, 1969 RHBA_RSP_SIZE); 1970 ct_rsp = &ha->ct_sns->p.rsp; 1971 1972 /* Prepare FDMI command arguments -- attribute block, attributes. */ 1973 memcpy(ct_req->req.rhba2.hba_identifier, vha->port_name, WWN_SIZE); 1974 ct_req->req.rhba2.entry_count = cpu_to_be32(1); 1975 memcpy(ct_req->req.rhba2.port_name, vha->port_name, WWN_SIZE); 1976 size = 2 * WWN_SIZE + 4 + 4; 1977 1978 /* Attributes */ 1979 ct_req->req.rhba2.attrs.count = cpu_to_be32(FDMIV2_HBA_ATTR_COUNT); 1980 entries = ct_req->req.rhba2.hba_identifier; 1981 1982 /* Nodename. */ 1983 eiter = entries + size; 1984 eiter->type = cpu_to_be16(FDMI_HBA_NODE_NAME); 1985 eiter->len = cpu_to_be16(4 + WWN_SIZE); 1986 memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE); 1987 size += 4 + WWN_SIZE; 1988 1989 ql_dbg(ql_dbg_disc, vha, 0x207d, 1990 "NodeName = %016llx.\n", wwn_to_u64(eiter->a.node_name)); 1991 1992 /* Manufacturer. */ 1993 eiter = entries + size; 1994 eiter->type = cpu_to_be16(FDMI_HBA_MANUFACTURER); 1995 snprintf(eiter->a.manufacturer, sizeof(eiter->a.manufacturer), 1996 "%s", "QLogic Corporation"); 1997 eiter->a.manufacturer[strlen("QLogic Corporation")] = '\0'; 1998 alen = strlen(eiter->a.manufacturer); 1999 alen += 4 - (alen & 3); 2000 eiter->len = cpu_to_be16(4 + alen); 2001 size += 4 + alen; 2002 2003 ql_dbg(ql_dbg_disc, vha, 0x20a5, 2004 "Manufacturer = %s.\n", eiter->a.manufacturer); 2005 2006 /* Serial number. */ 2007 eiter = entries + size; 2008 eiter->type = cpu_to_be16(FDMI_HBA_SERIAL_NUMBER); 2009 if (IS_FWI2_CAPABLE(ha)) 2010 qla2xxx_get_vpd_field(vha, "SN", eiter->a.serial_num, 2011 sizeof(eiter->a.serial_num)); 2012 else { 2013 sn = ((ha->serial0 & 0x1f) << 16) | 2014 (ha->serial2 << 8) | ha->serial1; 2015 snprintf(eiter->a.serial_num, sizeof(eiter->a.serial_num), 2016 "%c%05d", 'A' + sn / 100000, sn % 100000); 2017 } 2018 alen = strlen(eiter->a.serial_num); 2019 alen += 4 - (alen & 3); 2020 eiter->len = cpu_to_be16(4 + alen); 2021 size += 4 + alen; 2022 2023 ql_dbg(ql_dbg_disc, vha, 0x20a6, 2024 "Serial no. = %s.\n", eiter->a.serial_num); 2025 2026 /* Model name. */ 2027 eiter = entries + size; 2028 eiter->type = cpu_to_be16(FDMI_HBA_MODEL); 2029 snprintf(eiter->a.model, sizeof(eiter->a.model), 2030 "%s", ha->model_number); 2031 alen = strlen(eiter->a.model); 2032 alen += 4 - (alen & 3); 2033 eiter->len = cpu_to_be16(4 + alen); 2034 size += 4 + alen; 2035 2036 ql_dbg(ql_dbg_disc, vha, 0x20a7, 2037 "Model Name = %s.\n", eiter->a.model); 2038 2039 /* Model description. */ 2040 eiter = entries + size; 2041 eiter->type = cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION); 2042 snprintf(eiter->a.model_desc, sizeof(eiter->a.model_desc), 2043 "%s", ha->model_desc); 2044 alen = strlen(eiter->a.model_desc); 2045 alen += 4 - (alen & 3); 2046 eiter->len = cpu_to_be16(4 + alen); 2047 size += 4 + alen; 2048 2049 ql_dbg(ql_dbg_disc, vha, 0x20a8, 2050 "Model Desc = %s.\n", eiter->a.model_desc); 2051 2052 /* Hardware version. */ 2053 eiter = entries + size; 2054 eiter->type = cpu_to_be16(FDMI_HBA_HARDWARE_VERSION); 2055 if (!IS_FWI2_CAPABLE(ha)) { 2056 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version), 2057 "HW:%s", ha->adapter_id); 2058 } else if (qla2xxx_get_vpd_field(vha, "MN", eiter->a.hw_version, 2059 sizeof(eiter->a.hw_version))) { 2060 ; 2061 } else if (qla2xxx_get_vpd_field(vha, "EC", eiter->a.hw_version, 2062 sizeof(eiter->a.hw_version))) { 2063 ; 2064 } else { 2065 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version), 2066 "HW:%s", ha->adapter_id); 2067 } 2068 alen = strlen(eiter->a.hw_version); 2069 alen += 4 - (alen & 3); 2070 eiter->len = cpu_to_be16(4 + alen); 2071 size += 4 + alen; 2072 2073 ql_dbg(ql_dbg_disc, vha, 0x20a9, 2074 "Hardware ver = %s.\n", eiter->a.hw_version); 2075 2076 /* Driver version. */ 2077 eiter = entries + size; 2078 eiter->type = cpu_to_be16(FDMI_HBA_DRIVER_VERSION); 2079 snprintf(eiter->a.driver_version, sizeof(eiter->a.driver_version), 2080 "%s", qla2x00_version_str); 2081 alen = strlen(eiter->a.driver_version); 2082 alen += 4 - (alen & 3); 2083 eiter->len = cpu_to_be16(4 + alen); 2084 size += 4 + alen; 2085 2086 ql_dbg(ql_dbg_disc, vha, 0x20aa, 2087 "Driver ver = %s.\n", eiter->a.driver_version); 2088 2089 /* Option ROM version. */ 2090 eiter = entries + size; 2091 eiter->type = cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION); 2092 snprintf(eiter->a.orom_version, sizeof(eiter->a.orom_version), 2093 "%d.%02d", ha->bios_revision[1], ha->bios_revision[0]); 2094 alen = strlen(eiter->a.orom_version); 2095 alen += 4 - (alen & 3); 2096 eiter->len = cpu_to_be16(4 + alen); 2097 size += 4 + alen; 2098 2099 ql_dbg(ql_dbg_disc, vha , 0x20ab, 2100 "Optrom version = %d.%02d.\n", eiter->a.orom_version[1], 2101 eiter->a.orom_version[0]); 2102 2103 /* Firmware version */ 2104 eiter = entries + size; 2105 eiter->type = cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION); 2106 ha->isp_ops->fw_version_str(vha, eiter->a.fw_version, 2107 sizeof(eiter->a.fw_version)); 2108 alen = strlen(eiter->a.fw_version); 2109 alen += 4 - (alen & 3); 2110 eiter->len = cpu_to_be16(4 + alen); 2111 size += 4 + alen; 2112 2113 ql_dbg(ql_dbg_disc, vha, 0x20ac, 2114 "Firmware vers = %s.\n", eiter->a.fw_version); 2115 2116 /* OS Name and Version */ 2117 eiter = entries + size; 2118 eiter->type = cpu_to_be16(FDMI_HBA_OS_NAME_AND_VERSION); 2119 p_sysid = utsname(); 2120 if (p_sysid) { 2121 snprintf(eiter->a.os_version, sizeof(eiter->a.os_version), 2122 "%s %s %s", 2123 p_sysid->sysname, p_sysid->release, p_sysid->version); 2124 } else { 2125 snprintf(eiter->a.os_version, sizeof(eiter->a.os_version), 2126 "%s %s", "Linux", fc_host_system_hostname(vha->host)); 2127 } 2128 alen = strlen(eiter->a.os_version); 2129 alen += 4 - (alen & 3); 2130 eiter->len = cpu_to_be16(4 + alen); 2131 size += 4 + alen; 2132 2133 ql_dbg(ql_dbg_disc, vha, 0x20ae, 2134 "OS Name and Version = %s.\n", eiter->a.os_version); 2135 2136 /* MAX CT Payload Length */ 2137 eiter = entries + size; 2138 eiter->type = cpu_to_be16(FDMI_HBA_MAXIMUM_CT_PAYLOAD_LENGTH); 2139 eiter->a.max_ct_len = IS_FWI2_CAPABLE(ha) ? 2140 le16_to_cpu(icb24->frame_payload_size) : 2141 le16_to_cpu(ha->init_cb->frame_payload_size); 2142 eiter->a.max_ct_len = cpu_to_be32(eiter->a.max_ct_len); 2143 eiter->len = cpu_to_be16(4 + 4); 2144 size += 4 + 4; 2145 2146 ql_dbg(ql_dbg_disc, vha, 0x20af, 2147 "CT Payload Length = 0x%x.\n", eiter->a.max_ct_len); 2148 2149 /* Node Sybolic Name */ 2150 eiter = entries + size; 2151 eiter->type = cpu_to_be16(FDMI_HBA_NODE_SYMBOLIC_NAME); 2152 qla2x00_get_sym_node_name(vha, eiter->a.sym_name, 2153 sizeof(eiter->a.sym_name)); 2154 alen = strlen(eiter->a.sym_name); 2155 alen += 4 - (alen & 3); 2156 eiter->len = cpu_to_be16(4 + alen); 2157 size += 4 + alen; 2158 2159 ql_dbg(ql_dbg_disc, vha, 0x20b0, 2160 "Symbolic Name = %s.\n", eiter->a.sym_name); 2161 2162 /* Vendor Id */ 2163 eiter = entries + size; 2164 eiter->type = cpu_to_be16(FDMI_HBA_VENDOR_ID); 2165 eiter->a.vendor_id = cpu_to_be32(0x1077); 2166 eiter->len = cpu_to_be16(4 + 4); 2167 size += 4 + 4; 2168 2169 ql_dbg(ql_dbg_disc, vha, 0x20b1, 2170 "Vendor Id = %x.\n", eiter->a.vendor_id); 2171 2172 /* Num Ports */ 2173 eiter = entries + size; 2174 eiter->type = cpu_to_be16(FDMI_HBA_NUM_PORTS); 2175 eiter->a.num_ports = cpu_to_be32(1); 2176 eiter->len = cpu_to_be16(4 + 4); 2177 size += 4 + 4; 2178 2179 ql_dbg(ql_dbg_disc, vha, 0x20b2, 2180 "Port Num = %x.\n", eiter->a.num_ports); 2181 2182 /* Fabric Name */ 2183 eiter = entries + size; 2184 eiter->type = cpu_to_be16(FDMI_HBA_FABRIC_NAME); 2185 memcpy(eiter->a.fabric_name, vha->fabric_node_name, WWN_SIZE); 2186 eiter->len = cpu_to_be16(4 + WWN_SIZE); 2187 size += 4 + WWN_SIZE; 2188 2189 ql_dbg(ql_dbg_disc, vha, 0x20b3, 2190 "Fabric Name = %016llx.\n", wwn_to_u64(eiter->a.fabric_name)); 2191 2192 /* BIOS Version */ 2193 eiter = entries + size; 2194 eiter->type = cpu_to_be16(FDMI_HBA_BOOT_BIOS_NAME); 2195 snprintf(eiter->a.bios_name, sizeof(eiter->a.bios_name), 2196 "BIOS %d.%02d", ha->bios_revision[1], ha->bios_revision[0]); 2197 alen = strlen(eiter->a.bios_name); 2198 alen += 4 - (alen & 3); 2199 eiter->len = cpu_to_be16(4 + alen); 2200 size += 4 + alen; 2201 2202 ql_dbg(ql_dbg_disc, vha, 0x20b4, 2203 "BIOS Name = %s\n", eiter->a.bios_name); 2204 2205 /* Vendor Identifier */ 2206 eiter = entries + size; 2207 eiter->type = cpu_to_be16(FDMI_HBA_TYPE_VENDOR_IDENTIFIER); 2208 snprintf(eiter->a.vendor_identifier, sizeof(eiter->a.vendor_identifier), 2209 "%s", "QLGC"); 2210 alen = strlen(eiter->a.vendor_identifier); 2211 alen += 4 - (alen & 3); 2212 eiter->len = cpu_to_be16(4 + alen); 2213 size += 4 + alen; 2214 2215 ql_dbg(ql_dbg_disc, vha, 0x201b, 2216 "Vendor Identifier = %s.\n", eiter->a.vendor_identifier); 2217 2218 /* Update MS request size. */ 2219 qla2x00_update_ms_fdmi_iocb(vha, size + 16); 2220 2221 ql_dbg(ql_dbg_disc, vha, 0x20b5, 2222 "RHBA identifier = %016llx.\n", 2223 wwn_to_u64(ct_req->req.rhba2.hba_identifier)); 2224 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x20b6, 2225 entries, size); 2226 2227 /* Execute MS IOCB */ 2228 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 2229 sizeof(ms_iocb_entry_t)); 2230 if (rval != QLA_SUCCESS) { 2231 /*EMPTY*/ 2232 ql_dbg(ql_dbg_disc, vha, 0x20b7, 2233 "RHBA issue IOCB failed (%d).\n", rval); 2234 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA") != 2235 QLA_SUCCESS) { 2236 rval = QLA_FUNCTION_FAILED; 2237 2238 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM && 2239 ct_rsp->header.explanation_code == 2240 CT_EXPL_ALREADY_REGISTERED) { 2241 ql_dbg(ql_dbg_disc, vha, 0x20b8, 2242 "HBA already registered.\n"); 2243 rval = QLA_ALREADY_REGISTERED; 2244 } else { 2245 ql_dbg(ql_dbg_disc, vha, 0x2016, 2246 "RHBA FDMI v2 failed, CT Reason code: 0x%x, CT Explanation 0x%x\n", 2247 ct_rsp->header.reason_code, 2248 ct_rsp->header.explanation_code); 2249 } 2250 } else { 2251 ql_dbg(ql_dbg_disc, vha, 0x20b9, 2252 "RHBA FDMI V2 exiting normally.\n"); 2253 } 2254 2255 return rval; 2256 } 2257 2258 /** 2259 * qla2x00_fdmi_dhba() - 2260 * @ha: HA context 2261 * 2262 * Returns 0 on success. 2263 */ 2264 static int 2265 qla2x00_fdmi_dhba(scsi_qla_host_t *vha) 2266 { 2267 int rval; 2268 struct qla_hw_data *ha = vha->hw; 2269 ms_iocb_entry_t *ms_pkt; 2270 struct ct_sns_req *ct_req; 2271 struct ct_sns_rsp *ct_rsp; 2272 2273 /* Issue RPA */ 2274 /* Prepare common MS IOCB */ 2275 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, DHBA_REQ_SIZE, 2276 DHBA_RSP_SIZE); 2277 2278 /* Prepare CT request */ 2279 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, DHBA_CMD, DHBA_RSP_SIZE); 2280 ct_rsp = &ha->ct_sns->p.rsp; 2281 2282 /* Prepare FDMI command arguments -- portname. */ 2283 memcpy(ct_req->req.dhba.port_name, vha->port_name, WWN_SIZE); 2284 2285 ql_dbg(ql_dbg_disc, vha, 0x2036, 2286 "DHBA portname = %8phN.\n", ct_req->req.dhba.port_name); 2287 2288 /* Execute MS IOCB */ 2289 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 2290 sizeof(ms_iocb_entry_t)); 2291 if (rval != QLA_SUCCESS) { 2292 /*EMPTY*/ 2293 ql_dbg(ql_dbg_disc, vha, 0x2037, 2294 "DHBA issue IOCB failed (%d).\n", rval); 2295 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "DHBA") != 2296 QLA_SUCCESS) { 2297 rval = QLA_FUNCTION_FAILED; 2298 } else { 2299 ql_dbg(ql_dbg_disc, vha, 0x2038, 2300 "DHBA exiting normally.\n"); 2301 } 2302 2303 return rval; 2304 } 2305 2306 /** 2307 * qla2x00_fdmiv2_rpa() - 2308 * @ha: HA context 2309 * 2310 * Returns 0 on success. 2311 */ 2312 static int 2313 qla2x00_fdmiv2_rpa(scsi_qla_host_t *vha) 2314 { 2315 int rval, alen; 2316 uint32_t size; 2317 struct qla_hw_data *ha = vha->hw; 2318 ms_iocb_entry_t *ms_pkt; 2319 struct ct_sns_req *ct_req; 2320 struct ct_sns_rsp *ct_rsp; 2321 void *entries; 2322 struct ct_fdmiv2_port_attr *eiter; 2323 struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb; 2324 struct new_utsname *p_sysid = NULL; 2325 2326 /* Issue RPA */ 2327 /* Prepare common MS IOCB */ 2328 /* Request size adjusted after CT preparation */ 2329 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE); 2330 2331 /* Prepare CT request */ 2332 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPA_CMD, RPA_RSP_SIZE); 2333 ct_rsp = &ha->ct_sns->p.rsp; 2334 2335 /* Prepare FDMI command arguments -- attribute block, attributes. */ 2336 memcpy(ct_req->req.rpa2.port_name, vha->port_name, WWN_SIZE); 2337 size = WWN_SIZE + 4; 2338 2339 /* Attributes */ 2340 ct_req->req.rpa2.attrs.count = cpu_to_be32(FDMIV2_PORT_ATTR_COUNT); 2341 entries = ct_req->req.rpa2.port_name; 2342 2343 /* FC4 types. */ 2344 eiter = entries + size; 2345 eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPES); 2346 eiter->len = cpu_to_be16(4 + 32); 2347 eiter->a.fc4_types[2] = 0x01; 2348 size += 4 + 32; 2349 2350 ql_dbg(ql_dbg_disc, vha, 0x20ba, 2351 "FC4_TYPES=%02x %02x.\n", 2352 eiter->a.fc4_types[2], 2353 eiter->a.fc4_types[1]); 2354 2355 if (vha->flags.nvme_enabled) { 2356 eiter->a.fc4_types[6] = 1; /* NVMe type 28h */ 2357 ql_dbg(ql_dbg_disc, vha, 0x211f, 2358 "NVME FC4 Type = %02x 0x0 0x0 0x0 0x0 0x0.\n", 2359 eiter->a.fc4_types[6]); 2360 } 2361 2362 /* Supported speed. */ 2363 eiter = entries + size; 2364 eiter->type = cpu_to_be16(FDMI_PORT_SUPPORT_SPEED); 2365 eiter->len = cpu_to_be16(4 + 4); 2366 if (IS_CNA_CAPABLE(ha)) 2367 eiter->a.sup_speed = cpu_to_be32( 2368 FDMI_PORT_SPEED_10GB); 2369 else if (IS_QLA27XX(ha)) 2370 eiter->a.sup_speed = cpu_to_be32( 2371 FDMI_PORT_SPEED_32GB| 2372 FDMI_PORT_SPEED_16GB| 2373 FDMI_PORT_SPEED_8GB); 2374 else if (IS_QLA2031(ha)) 2375 eiter->a.sup_speed = cpu_to_be32( 2376 FDMI_PORT_SPEED_16GB| 2377 FDMI_PORT_SPEED_8GB| 2378 FDMI_PORT_SPEED_4GB); 2379 else if (IS_QLA25XX(ha)) 2380 eiter->a.sup_speed = cpu_to_be32( 2381 FDMI_PORT_SPEED_8GB| 2382 FDMI_PORT_SPEED_4GB| 2383 FDMI_PORT_SPEED_2GB| 2384 FDMI_PORT_SPEED_1GB); 2385 else if (IS_QLA24XX_TYPE(ha)) 2386 eiter->a.sup_speed = cpu_to_be32( 2387 FDMI_PORT_SPEED_4GB| 2388 FDMI_PORT_SPEED_2GB| 2389 FDMI_PORT_SPEED_1GB); 2390 else if (IS_QLA23XX(ha)) 2391 eiter->a.sup_speed = cpu_to_be32( 2392 FDMI_PORT_SPEED_2GB| 2393 FDMI_PORT_SPEED_1GB); 2394 else 2395 eiter->a.sup_speed = cpu_to_be32( 2396 FDMI_PORT_SPEED_1GB); 2397 size += 4 + 4; 2398 2399 ql_dbg(ql_dbg_disc, vha, 0x20bb, 2400 "Supported Port Speed = %x.\n", eiter->a.sup_speed); 2401 2402 /* Current speed. */ 2403 eiter = entries + size; 2404 eiter->type = cpu_to_be16(FDMI_PORT_CURRENT_SPEED); 2405 eiter->len = cpu_to_be16(4 + 4); 2406 switch (ha->link_data_rate) { 2407 case PORT_SPEED_1GB: 2408 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_1GB); 2409 break; 2410 case PORT_SPEED_2GB: 2411 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_2GB); 2412 break; 2413 case PORT_SPEED_4GB: 2414 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_4GB); 2415 break; 2416 case PORT_SPEED_8GB: 2417 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_8GB); 2418 break; 2419 case PORT_SPEED_10GB: 2420 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_10GB); 2421 break; 2422 case PORT_SPEED_16GB: 2423 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_16GB); 2424 break; 2425 case PORT_SPEED_32GB: 2426 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_32GB); 2427 break; 2428 default: 2429 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN); 2430 break; 2431 } 2432 size += 4 + 4; 2433 2434 ql_dbg(ql_dbg_disc, vha, 0x2017, 2435 "Current_Speed = %x.\n", eiter->a.cur_speed); 2436 2437 /* Max frame size. */ 2438 eiter = entries + size; 2439 eiter->type = cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE); 2440 eiter->len = cpu_to_be16(4 + 4); 2441 eiter->a.max_frame_size = IS_FWI2_CAPABLE(ha) ? 2442 le16_to_cpu(icb24->frame_payload_size): 2443 le16_to_cpu(ha->init_cb->frame_payload_size); 2444 eiter->a.max_frame_size = cpu_to_be32(eiter->a.max_frame_size); 2445 size += 4 + 4; 2446 2447 ql_dbg(ql_dbg_disc, vha, 0x20bc, 2448 "Max_Frame_Size = %x.\n", eiter->a.max_frame_size); 2449 2450 /* OS device name. */ 2451 eiter = entries + size; 2452 eiter->type = cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME); 2453 alen = strlen(QLA2XXX_DRIVER_NAME); 2454 snprintf(eiter->a.os_dev_name, sizeof(eiter->a.os_dev_name), 2455 "%s:host%lu", QLA2XXX_DRIVER_NAME, vha->host_no); 2456 alen += 4 - (alen & 3); 2457 eiter->len = cpu_to_be16(4 + alen); 2458 size += 4 + alen; 2459 2460 ql_dbg(ql_dbg_disc, vha, 0x20be, 2461 "OS_Device_Name = %s.\n", eiter->a.os_dev_name); 2462 2463 /* Hostname. */ 2464 eiter = entries + size; 2465 eiter->type = cpu_to_be16(FDMI_PORT_HOST_NAME); 2466 p_sysid = utsname(); 2467 if (p_sysid) { 2468 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name), 2469 "%s", p_sysid->nodename); 2470 } else { 2471 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name), 2472 "%s", fc_host_system_hostname(vha->host)); 2473 } 2474 alen = strlen(eiter->a.host_name); 2475 alen += 4 - (alen & 3); 2476 eiter->len = cpu_to_be16(4 + alen); 2477 size += 4 + alen; 2478 2479 ql_dbg(ql_dbg_disc, vha, 0x201a, 2480 "HostName=%s.\n", eiter->a.host_name); 2481 2482 /* Node Name */ 2483 eiter = entries + size; 2484 eiter->type = cpu_to_be16(FDMI_PORT_NODE_NAME); 2485 memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE); 2486 eiter->len = cpu_to_be16(4 + WWN_SIZE); 2487 size += 4 + WWN_SIZE; 2488 2489 ql_dbg(ql_dbg_disc, vha, 0x20c0, 2490 "Node Name = %016llx.\n", wwn_to_u64(eiter->a.node_name)); 2491 2492 /* Port Name */ 2493 eiter = entries + size; 2494 eiter->type = cpu_to_be16(FDMI_PORT_NAME); 2495 memcpy(eiter->a.port_name, vha->port_name, WWN_SIZE); 2496 eiter->len = cpu_to_be16(4 + WWN_SIZE); 2497 size += 4 + WWN_SIZE; 2498 2499 ql_dbg(ql_dbg_disc, vha, 0x20c1, 2500 "Port Name = %016llx.\n", wwn_to_u64(eiter->a.port_name)); 2501 2502 /* Port Symbolic Name */ 2503 eiter = entries + size; 2504 eiter->type = cpu_to_be16(FDMI_PORT_SYM_NAME); 2505 qla2x00_get_sym_node_name(vha, eiter->a.port_sym_name, 2506 sizeof(eiter->a.port_sym_name)); 2507 alen = strlen(eiter->a.port_sym_name); 2508 alen += 4 - (alen & 3); 2509 eiter->len = cpu_to_be16(4 + alen); 2510 size += 4 + alen; 2511 2512 ql_dbg(ql_dbg_disc, vha, 0x20c2, 2513 "port symbolic name = %s\n", eiter->a.port_sym_name); 2514 2515 /* Port Type */ 2516 eiter = entries + size; 2517 eiter->type = cpu_to_be16(FDMI_PORT_TYPE); 2518 eiter->a.port_type = cpu_to_be32(NS_NX_PORT_TYPE); 2519 eiter->len = cpu_to_be16(4 + 4); 2520 size += 4 + 4; 2521 2522 ql_dbg(ql_dbg_disc, vha, 0x20c3, 2523 "Port Type = %x.\n", eiter->a.port_type); 2524 2525 /* Class of Service */ 2526 eiter = entries + size; 2527 eiter->type = cpu_to_be16(FDMI_PORT_SUPP_COS); 2528 eiter->a.port_supported_cos = cpu_to_be32(FC_CLASS_3); 2529 eiter->len = cpu_to_be16(4 + 4); 2530 size += 4 + 4; 2531 2532 ql_dbg(ql_dbg_disc, vha, 0x20c4, 2533 "Supported COS = %08x\n", eiter->a.port_supported_cos); 2534 2535 /* Port Fabric Name */ 2536 eiter = entries + size; 2537 eiter->type = cpu_to_be16(FDMI_PORT_FABRIC_NAME); 2538 memcpy(eiter->a.fabric_name, vha->fabric_node_name, WWN_SIZE); 2539 eiter->len = cpu_to_be16(4 + WWN_SIZE); 2540 size += 4 + WWN_SIZE; 2541 2542 ql_dbg(ql_dbg_disc, vha, 0x20c5, 2543 "Fabric Name = %016llx.\n", wwn_to_u64(eiter->a.fabric_name)); 2544 2545 /* FC4_type */ 2546 eiter = entries + size; 2547 eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPE); 2548 eiter->a.port_fc4_type[0] = 0; 2549 eiter->a.port_fc4_type[1] = 0; 2550 eiter->a.port_fc4_type[2] = 1; 2551 eiter->a.port_fc4_type[3] = 0; 2552 eiter->len = cpu_to_be16(4 + 32); 2553 size += 4 + 32; 2554 2555 ql_dbg(ql_dbg_disc, vha, 0x20c6, 2556 "Port Active FC4 Type = %02x %02x.\n", 2557 eiter->a.port_fc4_type[2], eiter->a.port_fc4_type[1]); 2558 2559 if (vha->flags.nvme_enabled) { 2560 eiter->a.port_fc4_type[4] = 0; 2561 eiter->a.port_fc4_type[5] = 0; 2562 eiter->a.port_fc4_type[6] = 1; /* NVMe type 28h */ 2563 ql_dbg(ql_dbg_disc, vha, 0x2120, 2564 "NVME Port Active FC4 Type = %02x 0x0 0x0 0x0 0x0 0x0.\n", 2565 eiter->a.port_fc4_type[6]); 2566 } 2567 2568 /* Port State */ 2569 eiter = entries + size; 2570 eiter->type = cpu_to_be16(FDMI_PORT_STATE); 2571 eiter->a.port_state = cpu_to_be32(1); 2572 eiter->len = cpu_to_be16(4 + 4); 2573 size += 4 + 4; 2574 2575 ql_dbg(ql_dbg_disc, vha, 0x20c7, 2576 "Port State = %x.\n", eiter->a.port_state); 2577 2578 /* Number of Ports */ 2579 eiter = entries + size; 2580 eiter->type = cpu_to_be16(FDMI_PORT_COUNT); 2581 eiter->a.num_ports = cpu_to_be32(1); 2582 eiter->len = cpu_to_be16(4 + 4); 2583 size += 4 + 4; 2584 2585 ql_dbg(ql_dbg_disc, vha, 0x20c8, 2586 "Number of ports = %x.\n", eiter->a.num_ports); 2587 2588 /* Port Id */ 2589 eiter = entries + size; 2590 eiter->type = cpu_to_be16(FDMI_PORT_ID); 2591 eiter->a.port_id = cpu_to_be32(vha->d_id.b24); 2592 eiter->len = cpu_to_be16(4 + 4); 2593 size += 4 + 4; 2594 2595 ql_dbg(ql_dbg_disc, vha, 0x201c, 2596 "Port Id = %x.\n", eiter->a.port_id); 2597 2598 /* Update MS request size. */ 2599 qla2x00_update_ms_fdmi_iocb(vha, size + 16); 2600 2601 ql_dbg(ql_dbg_disc, vha, 0x2018, 2602 "RPA portname= %8phN size=%d.\n", ct_req->req.rpa.port_name, size); 2603 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x20ca, 2604 entries, size); 2605 2606 /* Execute MS IOCB */ 2607 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 2608 sizeof(ms_iocb_entry_t)); 2609 if (rval != QLA_SUCCESS) { 2610 /*EMPTY*/ 2611 ql_dbg(ql_dbg_disc, vha, 0x20cb, 2612 "RPA FDMI v2 issue IOCB failed (%d).\n", rval); 2613 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA") != 2614 QLA_SUCCESS) { 2615 rval = QLA_FUNCTION_FAILED; 2616 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM && 2617 ct_rsp->header.explanation_code == 2618 CT_EXPL_ALREADY_REGISTERED) { 2619 ql_dbg(ql_dbg_disc, vha, 0x20ce, 2620 "RPA FDMI v2 already registered\n"); 2621 rval = QLA_ALREADY_REGISTERED; 2622 } else { 2623 ql_dbg(ql_dbg_disc, vha, 0x2020, 2624 "RPA FDMI v2 failed, CT Reason code: 0x%x, CT Explanation 0x%x\n", 2625 ct_rsp->header.reason_code, 2626 ct_rsp->header.explanation_code); 2627 } 2628 } else { 2629 ql_dbg(ql_dbg_disc, vha, 0x20cc, 2630 "RPA FDMI V2 exiting normally.\n"); 2631 } 2632 2633 return rval; 2634 } 2635 2636 /** 2637 * qla2x00_fdmi_register() - 2638 * @ha: HA context 2639 * 2640 * Returns 0 on success. 2641 */ 2642 int 2643 qla2x00_fdmi_register(scsi_qla_host_t *vha) 2644 { 2645 int rval = QLA_FUNCTION_FAILED; 2646 struct qla_hw_data *ha = vha->hw; 2647 2648 if (IS_QLA2100(ha) || IS_QLA2200(ha) || 2649 IS_QLAFX00(ha)) 2650 return QLA_FUNCTION_FAILED; 2651 2652 rval = qla2x00_mgmt_svr_login(vha); 2653 if (rval) 2654 return rval; 2655 2656 rval = qla2x00_fdmiv2_rhba(vha); 2657 if (rval) { 2658 if (rval != QLA_ALREADY_REGISTERED) 2659 goto try_fdmi; 2660 2661 rval = qla2x00_fdmi_dhba(vha); 2662 if (rval) 2663 goto try_fdmi; 2664 2665 rval = qla2x00_fdmiv2_rhba(vha); 2666 if (rval) 2667 goto try_fdmi; 2668 } 2669 rval = qla2x00_fdmiv2_rpa(vha); 2670 if (rval) 2671 goto try_fdmi; 2672 2673 goto out; 2674 2675 try_fdmi: 2676 rval = qla2x00_fdmi_rhba(vha); 2677 if (rval) { 2678 if (rval != QLA_ALREADY_REGISTERED) 2679 return rval; 2680 2681 rval = qla2x00_fdmi_dhba(vha); 2682 if (rval) 2683 return rval; 2684 2685 rval = qla2x00_fdmi_rhba(vha); 2686 if (rval) 2687 return rval; 2688 } 2689 rval = qla2x00_fdmi_rpa(vha); 2690 out: 2691 return rval; 2692 } 2693 2694 /** 2695 * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query. 2696 * @ha: HA context 2697 * @list: switch info entries to populate 2698 * 2699 * Returns 0 on success. 2700 */ 2701 int 2702 qla2x00_gfpn_id(scsi_qla_host_t *vha, sw_info_t *list) 2703 { 2704 int rval = QLA_SUCCESS; 2705 uint16_t i; 2706 struct qla_hw_data *ha = vha->hw; 2707 ms_iocb_entry_t *ms_pkt; 2708 struct ct_sns_req *ct_req; 2709 struct ct_sns_rsp *ct_rsp; 2710 struct ct_arg arg; 2711 2712 if (!IS_IIDMA_CAPABLE(ha)) 2713 return QLA_FUNCTION_FAILED; 2714 2715 arg.iocb = ha->ms_iocb; 2716 arg.req_dma = ha->ct_sns_dma; 2717 arg.rsp_dma = ha->ct_sns_dma; 2718 arg.req_size = GFPN_ID_REQ_SIZE; 2719 arg.rsp_size = GFPN_ID_RSP_SIZE; 2720 arg.nport_handle = NPH_SNS; 2721 2722 for (i = 0; i < ha->max_fibre_devices; i++) { 2723 /* Issue GFPN_ID */ 2724 /* Prepare common MS IOCB */ 2725 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 2726 2727 /* Prepare CT request */ 2728 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFPN_ID_CMD, 2729 GFPN_ID_RSP_SIZE); 2730 ct_rsp = &ha->ct_sns->p.rsp; 2731 2732 /* Prepare CT arguments -- port_id */ 2733 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; 2734 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; 2735 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; 2736 2737 /* Execute MS IOCB */ 2738 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 2739 sizeof(ms_iocb_entry_t)); 2740 if (rval != QLA_SUCCESS) { 2741 /*EMPTY*/ 2742 ql_dbg(ql_dbg_disc, vha, 0x2023, 2743 "GFPN_ID issue IOCB failed (%d).\n", rval); 2744 break; 2745 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, 2746 "GFPN_ID") != QLA_SUCCESS) { 2747 rval = QLA_FUNCTION_FAILED; 2748 break; 2749 } else { 2750 /* Save fabric portname */ 2751 memcpy(list[i].fabric_port_name, 2752 ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE); 2753 } 2754 2755 /* Last device exit. */ 2756 if (list[i].d_id.b.rsvd_1 != 0) 2757 break; 2758 } 2759 2760 return (rval); 2761 } 2762 2763 2764 static inline struct ct_sns_req * 2765 qla24xx_prep_ct_fm_req(struct ct_sns_pkt *p, uint16_t cmd, 2766 uint16_t rsp_size) 2767 { 2768 memset(p, 0, sizeof(struct ct_sns_pkt)); 2769 2770 p->p.req.header.revision = 0x01; 2771 p->p.req.header.gs_type = 0xFA; 2772 p->p.req.header.gs_subtype = 0x01; 2773 p->p.req.command = cpu_to_be16(cmd); 2774 p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); 2775 2776 return &p->p.req; 2777 } 2778 2779 /** 2780 * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query. 2781 * @ha: HA context 2782 * @list: switch info entries to populate 2783 * 2784 * Returns 0 on success. 2785 */ 2786 int 2787 qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list) 2788 { 2789 int rval; 2790 uint16_t i; 2791 struct qla_hw_data *ha = vha->hw; 2792 ms_iocb_entry_t *ms_pkt; 2793 struct ct_sns_req *ct_req; 2794 struct ct_sns_rsp *ct_rsp; 2795 struct ct_arg arg; 2796 2797 if (!IS_IIDMA_CAPABLE(ha)) 2798 return QLA_FUNCTION_FAILED; 2799 if (!ha->flags.gpsc_supported) 2800 return QLA_FUNCTION_FAILED; 2801 2802 rval = qla2x00_mgmt_svr_login(vha); 2803 if (rval) 2804 return rval; 2805 2806 arg.iocb = ha->ms_iocb; 2807 arg.req_dma = ha->ct_sns_dma; 2808 arg.rsp_dma = ha->ct_sns_dma; 2809 arg.req_size = GPSC_REQ_SIZE; 2810 arg.rsp_size = GPSC_RSP_SIZE; 2811 arg.nport_handle = vha->mgmt_svr_loop_id; 2812 2813 for (i = 0; i < ha->max_fibre_devices; i++) { 2814 /* Issue GFPN_ID */ 2815 /* Prepare common MS IOCB */ 2816 ms_pkt = qla24xx_prep_ms_iocb(vha, &arg); 2817 2818 /* Prepare CT request */ 2819 ct_req = qla24xx_prep_ct_fm_req(ha->ct_sns, GPSC_CMD, 2820 GPSC_RSP_SIZE); 2821 ct_rsp = &ha->ct_sns->p.rsp; 2822 2823 /* Prepare CT arguments -- port_name */ 2824 memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name, 2825 WWN_SIZE); 2826 2827 /* Execute MS IOCB */ 2828 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 2829 sizeof(ms_iocb_entry_t)); 2830 if (rval != QLA_SUCCESS) { 2831 /*EMPTY*/ 2832 ql_dbg(ql_dbg_disc, vha, 0x2059, 2833 "GPSC issue IOCB failed (%d).\n", rval); 2834 } else if ((rval = qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, 2835 "GPSC")) != QLA_SUCCESS) { 2836 /* FM command unsupported? */ 2837 if (rval == QLA_INVALID_COMMAND && 2838 (ct_rsp->header.reason_code == 2839 CT_REASON_INVALID_COMMAND_CODE || 2840 ct_rsp->header.reason_code == 2841 CT_REASON_COMMAND_UNSUPPORTED)) { 2842 ql_dbg(ql_dbg_disc, vha, 0x205a, 2843 "GPSC command unsupported, disabling " 2844 "query.\n"); 2845 ha->flags.gpsc_supported = 0; 2846 rval = QLA_FUNCTION_FAILED; 2847 break; 2848 } 2849 rval = QLA_FUNCTION_FAILED; 2850 } else { 2851 /* Save port-speed */ 2852 switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) { 2853 case BIT_15: 2854 list[i].fp_speed = PORT_SPEED_1GB; 2855 break; 2856 case BIT_14: 2857 list[i].fp_speed = PORT_SPEED_2GB; 2858 break; 2859 case BIT_13: 2860 list[i].fp_speed = PORT_SPEED_4GB; 2861 break; 2862 case BIT_12: 2863 list[i].fp_speed = PORT_SPEED_10GB; 2864 break; 2865 case BIT_11: 2866 list[i].fp_speed = PORT_SPEED_8GB; 2867 break; 2868 case BIT_10: 2869 list[i].fp_speed = PORT_SPEED_16GB; 2870 break; 2871 case BIT_8: 2872 list[i].fp_speed = PORT_SPEED_32GB; 2873 break; 2874 } 2875 2876 ql_dbg(ql_dbg_disc, vha, 0x205b, 2877 "GPSC ext entry - fpn " 2878 "%8phN speeds=%04x speed=%04x.\n", 2879 list[i].fabric_port_name, 2880 be16_to_cpu(ct_rsp->rsp.gpsc.speeds), 2881 be16_to_cpu(ct_rsp->rsp.gpsc.speed)); 2882 } 2883 2884 /* Last device exit. */ 2885 if (list[i].d_id.b.rsvd_1 != 0) 2886 break; 2887 } 2888 2889 return (rval); 2890 } 2891 2892 /** 2893 * qla2x00_gff_id() - SNS Get FC-4 Features (GFF_ID) query. 2894 * 2895 * @ha: HA context 2896 * @list: switch info entries to populate 2897 * 2898 */ 2899 void 2900 qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list) 2901 { 2902 int rval; 2903 uint16_t i; 2904 2905 ms_iocb_entry_t *ms_pkt; 2906 struct ct_sns_req *ct_req; 2907 struct ct_sns_rsp *ct_rsp; 2908 struct qla_hw_data *ha = vha->hw; 2909 uint8_t fcp_scsi_features = 0; 2910 struct ct_arg arg; 2911 2912 for (i = 0; i < ha->max_fibre_devices; i++) { 2913 /* Set default FC4 Type as UNKNOWN so the default is to 2914 * Process this port */ 2915 list[i].fc4_type = FC4_TYPE_UNKNOWN; 2916 2917 /* Do not attempt GFF_ID if we are not FWI_2 capable */ 2918 if (!IS_FWI2_CAPABLE(ha)) 2919 continue; 2920 2921 arg.iocb = ha->ms_iocb; 2922 arg.req_dma = ha->ct_sns_dma; 2923 arg.rsp_dma = ha->ct_sns_dma; 2924 arg.req_size = GFF_ID_REQ_SIZE; 2925 arg.rsp_size = GFF_ID_RSP_SIZE; 2926 arg.nport_handle = NPH_SNS; 2927 2928 /* Prepare common MS IOCB */ 2929 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 2930 2931 /* Prepare CT request */ 2932 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFF_ID_CMD, 2933 GFF_ID_RSP_SIZE); 2934 ct_rsp = &ha->ct_sns->p.rsp; 2935 2936 /* Prepare CT arguments -- port_id */ 2937 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; 2938 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; 2939 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; 2940 2941 /* Execute MS IOCB */ 2942 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 2943 sizeof(ms_iocb_entry_t)); 2944 2945 if (rval != QLA_SUCCESS) { 2946 ql_dbg(ql_dbg_disc, vha, 0x205c, 2947 "GFF_ID issue IOCB failed (%d).\n", rval); 2948 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, 2949 "GFF_ID") != QLA_SUCCESS) { 2950 ql_dbg(ql_dbg_disc, vha, 0x205d, 2951 "GFF_ID IOCB status had a failure status code.\n"); 2952 } else { 2953 fcp_scsi_features = 2954 ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET]; 2955 fcp_scsi_features &= 0x0f; 2956 2957 if (fcp_scsi_features) 2958 list[i].fc4_type = FC4_TYPE_FCP_SCSI; 2959 else 2960 list[i].fc4_type = FC4_TYPE_OTHER; 2961 2962 list[i].fc4f_nvme = 2963 ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET]; 2964 list[i].fc4f_nvme &= 0xf; 2965 } 2966 2967 /* Last device exit. */ 2968 if (list[i].d_id.b.rsvd_1 != 0) 2969 break; 2970 } 2971 } 2972 2973 /* GID_PN completion processing. */ 2974 void qla24xx_handle_gidpn_event(scsi_qla_host_t *vha, struct event_arg *ea) 2975 { 2976 fc_port_t *fcport = ea->fcport; 2977 2978 ql_dbg(ql_dbg_disc, vha, 0x201d, 2979 "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d lid %d\n", 2980 __func__, fcport->port_name, fcport->disc_state, 2981 fcport->fw_login_state, ea->rc, fcport->login_gen, ea->sp->gen2, 2982 fcport->rscn_gen, ea->sp->gen1, fcport->loop_id); 2983 2984 if (fcport->disc_state == DSC_DELETE_PEND) 2985 return; 2986 2987 if (ea->sp->gen2 != fcport->login_gen) { 2988 /* PLOGI/PRLI/LOGO came in while cmd was out.*/ 2989 ql_dbg(ql_dbg_disc, vha, 0x201e, 2990 "%s %8phC generation changed rscn %d|%d n", 2991 __func__, fcport->port_name, fcport->last_rscn_gen, 2992 fcport->rscn_gen); 2993 return; 2994 } 2995 2996 if (!ea->rc) { 2997 if (ea->sp->gen1 == fcport->rscn_gen) { 2998 fcport->scan_state = QLA_FCPORT_FOUND; 2999 fcport->flags |= FCF_FABRIC_DEVICE; 3000 3001 if (fcport->d_id.b24 == ea->id.b24) { 3002 /* cable plugged into the same place */ 3003 switch (vha->host->active_mode) { 3004 case MODE_TARGET: 3005 if (fcport->fw_login_state == 3006 DSC_LS_PRLI_COMP) { 3007 u16 data[2]; 3008 /* 3009 * Late RSCN was delivered. 3010 * Remote port already login'ed. 3011 */ 3012 ql_dbg(ql_dbg_disc, vha, 0x201f, 3013 "%s %d %8phC post adisc\n", 3014 __func__, __LINE__, 3015 fcport->port_name); 3016 data[0] = data[1] = 0; 3017 qla2x00_post_async_adisc_work( 3018 vha, fcport, data); 3019 } 3020 break; 3021 case MODE_INITIATOR: 3022 case MODE_DUAL: 3023 default: 3024 ql_dbg(ql_dbg_disc, vha, 0x201f, 3025 "%s %d %8phC post %s\n", __func__, 3026 __LINE__, fcport->port_name, 3027 (atomic_read(&fcport->state) == 3028 FCS_ONLINE) ? "adisc" : "gnl"); 3029 3030 if (atomic_read(&fcport->state) == 3031 FCS_ONLINE) { 3032 u16 data[2]; 3033 3034 data[0] = data[1] = 0; 3035 qla2x00_post_async_adisc_work( 3036 vha, fcport, data); 3037 } else { 3038 qla24xx_post_gnl_work(vha, 3039 fcport); 3040 } 3041 break; 3042 } 3043 } else { /* fcport->d_id.b24 != ea->id.b24 */ 3044 fcport->d_id.b24 = ea->id.b24; 3045 fcport->id_changed = 1; 3046 if (fcport->deleted != QLA_SESS_DELETED) { 3047 ql_dbg(ql_dbg_disc, vha, 0x2021, 3048 "%s %d %8phC post del sess\n", 3049 __func__, __LINE__, fcport->port_name); 3050 qlt_schedule_sess_for_deletion(fcport); 3051 } 3052 } 3053 } else { /* ea->sp->gen1 != fcport->rscn_gen */ 3054 ql_dbg(ql_dbg_disc, vha, 0x2022, 3055 "%s %d %8phC post gidpn\n", 3056 __func__, __LINE__, fcport->port_name); 3057 /* rscn came in while cmd was out */ 3058 qla24xx_post_gidpn_work(vha, fcport); 3059 } 3060 } else { /* ea->rc */ 3061 /* cable pulled */ 3062 if (ea->sp->gen1 == fcport->rscn_gen) { 3063 if (ea->sp->gen2 == fcport->login_gen) { 3064 ql_dbg(ql_dbg_disc, vha, 0x2042, 3065 "%s %d %8phC post del sess\n", __func__, 3066 __LINE__, fcport->port_name); 3067 qlt_schedule_sess_for_deletion(fcport); 3068 } else { 3069 ql_dbg(ql_dbg_disc, vha, 0x2045, 3070 "%s %d %8phC login\n", __func__, __LINE__, 3071 fcport->port_name); 3072 qla24xx_fcport_handle_login(vha, fcport); 3073 } 3074 } else { 3075 ql_dbg(ql_dbg_disc, vha, 0x2049, 3076 "%s %d %8phC post gidpn\n", __func__, __LINE__, 3077 fcport->port_name); 3078 qla24xx_post_gidpn_work(vha, fcport); 3079 } 3080 } 3081 } /* gidpn_event */ 3082 3083 static void qla2x00_async_gidpn_sp_done(void *s, int res) 3084 { 3085 struct srb *sp = s; 3086 struct scsi_qla_host *vha = sp->vha; 3087 fc_port_t *fcport = sp->fcport; 3088 u8 *id = fcport->ct_desc.ct_sns->p.rsp.rsp.gid_pn.port_id; 3089 struct event_arg ea; 3090 3091 fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); 3092 3093 memset(&ea, 0, sizeof(ea)); 3094 ea.fcport = fcport; 3095 ea.id.b.domain = id[0]; 3096 ea.id.b.area = id[1]; 3097 ea.id.b.al_pa = id[2]; 3098 ea.sp = sp; 3099 ea.rc = res; 3100 ea.event = FCME_GIDPN_DONE; 3101 3102 if (res == QLA_FUNCTION_TIMEOUT) { 3103 ql_dbg(ql_dbg_disc, sp->vha, 0xffff, 3104 "Async done-%s WWPN %8phC timed out.\n", 3105 sp->name, fcport->port_name); 3106 qla24xx_post_gidpn_work(sp->vha, fcport); 3107 sp->free(sp); 3108 return; 3109 } else if (res) { 3110 ql_dbg(ql_dbg_disc, sp->vha, 0xffff, 3111 "Async done-%s fail res %x, WWPN %8phC\n", 3112 sp->name, res, fcport->port_name); 3113 } else { 3114 ql_dbg(ql_dbg_disc, vha, 0x204f, 3115 "Async done-%s good WWPN %8phC ID %3phC\n", 3116 sp->name, fcport->port_name, id); 3117 } 3118 3119 qla2x00_fcport_event_handler(vha, &ea); 3120 3121 sp->free(sp); 3122 } 3123 3124 int qla24xx_async_gidpn(scsi_qla_host_t *vha, fc_port_t *fcport) 3125 { 3126 int rval = QLA_FUNCTION_FAILED; 3127 struct ct_sns_req *ct_req; 3128 srb_t *sp; 3129 3130 if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) 3131 return rval; 3132 3133 fcport->disc_state = DSC_GID_PN; 3134 fcport->scan_state = QLA_FCPORT_SCAN; 3135 sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC); 3136 if (!sp) 3137 goto done; 3138 3139 fcport->flags |= FCF_ASYNC_SENT; 3140 sp->type = SRB_CT_PTHRU_CMD; 3141 sp->name = "gidpn"; 3142 sp->gen1 = fcport->rscn_gen; 3143 sp->gen2 = fcport->login_gen; 3144 3145 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 3146 3147 /* CT_IU preamble */ 3148 ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GID_PN_CMD, 3149 GID_PN_RSP_SIZE); 3150 3151 /* GIDPN req */ 3152 memcpy(ct_req->req.gid_pn.port_name, fcport->port_name, 3153 WWN_SIZE); 3154 3155 /* req & rsp use the same buffer */ 3156 sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns; 3157 sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma; 3158 sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns; 3159 sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma; 3160 sp->u.iocb_cmd.u.ctarg.req_size = GID_PN_REQ_SIZE; 3161 sp->u.iocb_cmd.u.ctarg.rsp_size = GID_PN_RSP_SIZE; 3162 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 3163 3164 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 3165 sp->done = qla2x00_async_gidpn_sp_done; 3166 3167 rval = qla2x00_start_sp(sp); 3168 if (rval != QLA_SUCCESS) 3169 goto done_free_sp; 3170 3171 ql_dbg(ql_dbg_disc, vha, 0x20a4, 3172 "Async-%s - %8phC hdl=%x loopid=%x portid %02x%02x%02x.\n", 3173 sp->name, fcport->port_name, 3174 sp->handle, fcport->loop_id, fcport->d_id.b.domain, 3175 fcport->d_id.b.area, fcport->d_id.b.al_pa); 3176 return rval; 3177 3178 done_free_sp: 3179 sp->free(sp); 3180 fcport->flags &= ~FCF_ASYNC_SENT; 3181 done: 3182 return rval; 3183 } 3184 3185 int qla24xx_post_gidpn_work(struct scsi_qla_host *vha, fc_port_t *fcport) 3186 { 3187 struct qla_work_evt *e; 3188 int ls; 3189 3190 ls = atomic_read(&vha->loop_state); 3191 if (((ls != LOOP_READY) && (ls != LOOP_UP)) || 3192 test_bit(UNLOADING, &vha->dpc_flags)) 3193 return 0; 3194 3195 e = qla2x00_alloc_work(vha, QLA_EVT_GIDPN); 3196 if (!e) 3197 return QLA_FUNCTION_FAILED; 3198 3199 e->u.fcport.fcport = fcport; 3200 fcport->flags |= FCF_ASYNC_ACTIVE; 3201 return qla2x00_post_work(vha, e); 3202 } 3203 3204 int qla24xx_post_gpsc_work(struct scsi_qla_host *vha, fc_port_t *fcport) 3205 { 3206 struct qla_work_evt *e; 3207 3208 e = qla2x00_alloc_work(vha, QLA_EVT_GPSC); 3209 if (!e) 3210 return QLA_FUNCTION_FAILED; 3211 3212 e->u.fcport.fcport = fcport; 3213 fcport->flags |= FCF_ASYNC_ACTIVE; 3214 return qla2x00_post_work(vha, e); 3215 } 3216 3217 void qla24xx_handle_gpsc_event(scsi_qla_host_t *vha, struct event_arg *ea) 3218 { 3219 struct fc_port *fcport = ea->fcport; 3220 3221 ql_dbg(ql_dbg_disc, vha, 0x20d8, 3222 "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d lid %d\n", 3223 __func__, fcport->port_name, fcport->disc_state, 3224 fcport->fw_login_state, ea->rc, ea->sp->gen2, fcport->login_gen, 3225 ea->sp->gen2, fcport->rscn_gen|ea->sp->gen1, fcport->loop_id); 3226 3227 if (fcport->disc_state == DSC_DELETE_PEND) 3228 return; 3229 3230 if (ea->sp->gen2 != fcport->login_gen) { 3231 /* target side must have changed it. */ 3232 ql_dbg(ql_dbg_disc, vha, 0x20d3, 3233 "%s %8phC generation changed\n", 3234 __func__, fcport->port_name); 3235 return; 3236 } else if (ea->sp->gen1 != fcport->rscn_gen) { 3237 ql_dbg(ql_dbg_disc, vha, 0x20d4, "%s %d %8phC post gidpn\n", 3238 __func__, __LINE__, fcport->port_name); 3239 qla24xx_post_gidpn_work(vha, fcport); 3240 return; 3241 } 3242 3243 qla24xx_post_upd_fcport_work(vha, ea->fcport); 3244 } 3245 3246 static void qla24xx_async_gpsc_sp_done(void *s, int res) 3247 { 3248 struct srb *sp = s; 3249 struct scsi_qla_host *vha = sp->vha; 3250 struct qla_hw_data *ha = vha->hw; 3251 fc_port_t *fcport = sp->fcport; 3252 struct ct_sns_rsp *ct_rsp; 3253 struct event_arg ea; 3254 3255 ct_rsp = &fcport->ct_desc.ct_sns->p.rsp; 3256 3257 ql_dbg(ql_dbg_disc, vha, 0x2053, 3258 "Async done-%s res %x, WWPN %8phC \n", 3259 sp->name, res, fcport->port_name); 3260 3261 fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); 3262 3263 if (res == (DID_ERROR << 16)) { 3264 /* entry status error */ 3265 goto done; 3266 } else if (res) { 3267 if ((ct_rsp->header.reason_code == 3268 CT_REASON_INVALID_COMMAND_CODE) || 3269 (ct_rsp->header.reason_code == 3270 CT_REASON_COMMAND_UNSUPPORTED)) { 3271 ql_dbg(ql_dbg_disc, vha, 0x2019, 3272 "GPSC command unsupported, disabling query.\n"); 3273 ha->flags.gpsc_supported = 0; 3274 res = QLA_SUCCESS; 3275 } 3276 } else { 3277 switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) { 3278 case BIT_15: 3279 fcport->fp_speed = PORT_SPEED_1GB; 3280 break; 3281 case BIT_14: 3282 fcport->fp_speed = PORT_SPEED_2GB; 3283 break; 3284 case BIT_13: 3285 fcport->fp_speed = PORT_SPEED_4GB; 3286 break; 3287 case BIT_12: 3288 fcport->fp_speed = PORT_SPEED_10GB; 3289 break; 3290 case BIT_11: 3291 fcport->fp_speed = PORT_SPEED_8GB; 3292 break; 3293 case BIT_10: 3294 fcport->fp_speed = PORT_SPEED_16GB; 3295 break; 3296 case BIT_8: 3297 fcport->fp_speed = PORT_SPEED_32GB; 3298 break; 3299 } 3300 3301 ql_dbg(ql_dbg_disc, vha, 0x2054, 3302 "Async-%s OUT WWPN %8phC speeds=%04x speed=%04x.\n", 3303 sp->name, fcport->fabric_port_name, 3304 be16_to_cpu(ct_rsp->rsp.gpsc.speeds), 3305 be16_to_cpu(ct_rsp->rsp.gpsc.speed)); 3306 } 3307 done: 3308 memset(&ea, 0, sizeof(ea)); 3309 ea.event = FCME_GPSC_DONE; 3310 ea.rc = res; 3311 ea.fcport = fcport; 3312 ea.sp = sp; 3313 qla2x00_fcport_event_handler(vha, &ea); 3314 3315 sp->free(sp); 3316 } 3317 3318 int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t *fcport) 3319 { 3320 int rval = QLA_FUNCTION_FAILED; 3321 struct ct_sns_req *ct_req; 3322 srb_t *sp; 3323 3324 if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) 3325 return rval; 3326 3327 sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); 3328 if (!sp) 3329 goto done; 3330 3331 fcport->flags |= FCF_ASYNC_SENT; 3332 sp->type = SRB_CT_PTHRU_CMD; 3333 sp->name = "gpsc"; 3334 sp->gen1 = fcport->rscn_gen; 3335 sp->gen2 = fcport->login_gen; 3336 3337 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 3338 3339 /* CT_IU preamble */ 3340 ct_req = qla24xx_prep_ct_fm_req(fcport->ct_desc.ct_sns, GPSC_CMD, 3341 GPSC_RSP_SIZE); 3342 3343 /* GPSC req */ 3344 memcpy(ct_req->req.gpsc.port_name, fcport->fabric_port_name, 3345 WWN_SIZE); 3346 3347 sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns; 3348 sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma; 3349 sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns; 3350 sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma; 3351 sp->u.iocb_cmd.u.ctarg.req_size = GPSC_REQ_SIZE; 3352 sp->u.iocb_cmd.u.ctarg.rsp_size = GPSC_RSP_SIZE; 3353 sp->u.iocb_cmd.u.ctarg.nport_handle = vha->mgmt_svr_loop_id; 3354 3355 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 3356 sp->done = qla24xx_async_gpsc_sp_done; 3357 3358 rval = qla2x00_start_sp(sp); 3359 if (rval != QLA_SUCCESS) 3360 goto done_free_sp; 3361 3362 ql_dbg(ql_dbg_disc, vha, 0x205e, 3363 "Async-%s %8phC hdl=%x loopid=%x portid=%02x%02x%02x.\n", 3364 sp->name, fcport->port_name, sp->handle, 3365 fcport->loop_id, fcport->d_id.b.domain, 3366 fcport->d_id.b.area, fcport->d_id.b.al_pa); 3367 return rval; 3368 3369 done_free_sp: 3370 sp->free(sp); 3371 fcport->flags &= ~FCF_ASYNC_SENT; 3372 done: 3373 return rval; 3374 } 3375 3376 int qla24xx_post_gpnid_work(struct scsi_qla_host *vha, port_id_t *id) 3377 { 3378 struct qla_work_evt *e; 3379 3380 if (test_bit(UNLOADING, &vha->dpc_flags)) 3381 return 0; 3382 3383 e = qla2x00_alloc_work(vha, QLA_EVT_GPNID); 3384 if (!e) 3385 return QLA_FUNCTION_FAILED; 3386 3387 e->u.gpnid.id = *id; 3388 return qla2x00_post_work(vha, e); 3389 } 3390 3391 void qla24xx_sp_unmap(scsi_qla_host_t *vha, srb_t *sp) 3392 { 3393 if (sp->u.iocb_cmd.u.ctarg.req) { 3394 dma_free_coherent(&vha->hw->pdev->dev, 3395 sizeof(struct ct_sns_pkt), 3396 sp->u.iocb_cmd.u.ctarg.req, 3397 sp->u.iocb_cmd.u.ctarg.req_dma); 3398 sp->u.iocb_cmd.u.ctarg.req = NULL; 3399 } 3400 if (sp->u.iocb_cmd.u.ctarg.rsp) { 3401 dma_free_coherent(&vha->hw->pdev->dev, 3402 sizeof(struct ct_sns_pkt), 3403 sp->u.iocb_cmd.u.ctarg.rsp, 3404 sp->u.iocb_cmd.u.ctarg.rsp_dma); 3405 sp->u.iocb_cmd.u.ctarg.rsp = NULL; 3406 } 3407 3408 sp->free(sp); 3409 } 3410 3411 void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea) 3412 { 3413 fc_port_t *fcport, *conflict, *t; 3414 u16 data[2]; 3415 3416 ql_dbg(ql_dbg_disc, vha, 0xffff, 3417 "%s %d port_id: %06x\n", 3418 __func__, __LINE__, ea->id.b24); 3419 3420 if (ea->rc) { 3421 /* cable is disconnected */ 3422 list_for_each_entry_safe(fcport, t, &vha->vp_fcports, list) { 3423 if (fcport->d_id.b24 == ea->id.b24) { 3424 ql_dbg(ql_dbg_disc, vha, 0xffff, 3425 "%s %d %8phC DS %d\n", 3426 __func__, __LINE__, 3427 fcport->port_name, 3428 fcport->disc_state); 3429 fcport->scan_state = QLA_FCPORT_SCAN; 3430 switch (fcport->disc_state) { 3431 case DSC_DELETED: 3432 case DSC_DELETE_PEND: 3433 break; 3434 default: 3435 ql_dbg(ql_dbg_disc, vha, 0xffff, 3436 "%s %d %8phC post del sess\n", 3437 __func__, __LINE__, 3438 fcport->port_name); 3439 qlt_schedule_sess_for_deletion(fcport); 3440 break; 3441 } 3442 } 3443 } 3444 } else { 3445 /* cable is connected */ 3446 fcport = qla2x00_find_fcport_by_wwpn(vha, ea->port_name, 1); 3447 if (fcport) { 3448 list_for_each_entry_safe(conflict, t, &vha->vp_fcports, 3449 list) { 3450 if ((conflict->d_id.b24 == ea->id.b24) && 3451 (fcport != conflict)) { 3452 /* 2 fcports with conflict Nport ID or 3453 * an existing fcport is having nport ID 3454 * conflict with new fcport. 3455 */ 3456 3457 ql_dbg(ql_dbg_disc, vha, 0xffff, 3458 "%s %d %8phC DS %d\n", 3459 __func__, __LINE__, 3460 conflict->port_name, 3461 conflict->disc_state); 3462 conflict->scan_state = QLA_FCPORT_SCAN; 3463 switch (conflict->disc_state) { 3464 case DSC_DELETED: 3465 case DSC_DELETE_PEND: 3466 break; 3467 default: 3468 ql_dbg(ql_dbg_disc, vha, 0xffff, 3469 "%s %d %8phC post del sess\n", 3470 __func__, __LINE__, 3471 conflict->port_name); 3472 qlt_schedule_sess_for_deletion 3473 (conflict); 3474 break; 3475 } 3476 } 3477 } 3478 3479 fcport->rscn_gen++; 3480 fcport->scan_state = QLA_FCPORT_FOUND; 3481 fcport->flags |= FCF_FABRIC_DEVICE; 3482 switch (fcport->disc_state) { 3483 case DSC_LOGIN_COMPLETE: 3484 /* recheck session is still intact. */ 3485 ql_dbg(ql_dbg_disc, vha, 0x210d, 3486 "%s %d %8phC revalidate session with ADISC\n", 3487 __func__, __LINE__, fcport->port_name); 3488 data[0] = data[1] = 0; 3489 qla2x00_post_async_adisc_work(vha, fcport, 3490 data); 3491 break; 3492 case DSC_DELETED: 3493 ql_dbg(ql_dbg_disc, vha, 0x210d, 3494 "%s %d %8phC login\n", __func__, __LINE__, 3495 fcport->port_name); 3496 fcport->d_id = ea->id; 3497 qla24xx_fcport_handle_login(vha, fcport); 3498 break; 3499 case DSC_DELETE_PEND: 3500 fcport->d_id = ea->id; 3501 break; 3502 default: 3503 fcport->d_id = ea->id; 3504 break; 3505 } 3506 } else { 3507 list_for_each_entry_safe(conflict, t, &vha->vp_fcports, 3508 list) { 3509 if (conflict->d_id.b24 == ea->id.b24) { 3510 /* 2 fcports with conflict Nport ID or 3511 * an existing fcport is having nport ID 3512 * conflict with new fcport. 3513 */ 3514 ql_dbg(ql_dbg_disc, vha, 0xffff, 3515 "%s %d %8phC DS %d\n", 3516 __func__, __LINE__, 3517 conflict->port_name, 3518 conflict->disc_state); 3519 3520 conflict->scan_state = QLA_FCPORT_SCAN; 3521 switch (conflict->disc_state) { 3522 case DSC_DELETED: 3523 case DSC_DELETE_PEND: 3524 break; 3525 default: 3526 ql_dbg(ql_dbg_disc, vha, 0xffff, 3527 "%s %d %8phC post del sess\n", 3528 __func__, __LINE__, 3529 conflict->port_name); 3530 qlt_schedule_sess_for_deletion 3531 (conflict); 3532 break; 3533 } 3534 } 3535 } 3536 3537 /* create new fcport */ 3538 ql_dbg(ql_dbg_disc, vha, 0x2065, 3539 "%s %d %8phC post new sess\n", 3540 __func__, __LINE__, ea->port_name); 3541 qla24xx_post_newsess_work(vha, &ea->id, 3542 ea->port_name, NULL, NULL, FC4_TYPE_UNKNOWN); 3543 } 3544 } 3545 } 3546 3547 static void qla2x00_async_gpnid_sp_done(void *s, int res) 3548 { 3549 struct srb *sp = s; 3550 struct scsi_qla_host *vha = sp->vha; 3551 struct ct_sns_req *ct_req = 3552 (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req; 3553 struct ct_sns_rsp *ct_rsp = 3554 (struct ct_sns_rsp *)sp->u.iocb_cmd.u.ctarg.rsp; 3555 struct event_arg ea; 3556 struct qla_work_evt *e; 3557 unsigned long flags; 3558 3559 if (res) 3560 ql_dbg(ql_dbg_disc, vha, 0x2066, 3561 "Async done-%s fail res %x rscn gen %d ID %3phC. %8phC\n", 3562 sp->name, res, sp->gen1, ct_req->req.port_id.port_id, 3563 ct_rsp->rsp.gpn_id.port_name); 3564 else 3565 ql_dbg(ql_dbg_disc, vha, 0x2066, 3566 "Async done-%s good rscn gen %d ID %3phC. %8phC\n", 3567 sp->name, sp->gen1, ct_req->req.port_id.port_id, 3568 ct_rsp->rsp.gpn_id.port_name); 3569 3570 memset(&ea, 0, sizeof(ea)); 3571 memcpy(ea.port_name, ct_rsp->rsp.gpn_id.port_name, WWN_SIZE); 3572 ea.sp = sp; 3573 ea.id.b.domain = ct_req->req.port_id.port_id[0]; 3574 ea.id.b.area = ct_req->req.port_id.port_id[1]; 3575 ea.id.b.al_pa = ct_req->req.port_id.port_id[2]; 3576 ea.rc = res; 3577 ea.event = FCME_GPNID_DONE; 3578 3579 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); 3580 list_del(&sp->elem); 3581 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); 3582 3583 if (res) { 3584 if (res == QLA_FUNCTION_TIMEOUT) { 3585 qla24xx_post_gpnid_work(sp->vha, &ea.id); 3586 sp->free(sp); 3587 return; 3588 } 3589 } else if (sp->gen1) { 3590 /* There was another RSCN for this Nport ID */ 3591 qla24xx_post_gpnid_work(sp->vha, &ea.id); 3592 sp->free(sp); 3593 return; 3594 } 3595 3596 qla2x00_fcport_event_handler(vha, &ea); 3597 3598 e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP); 3599 if (!e) { 3600 /* please ignore kernel warning. otherwise, we have mem leak. */ 3601 if (sp->u.iocb_cmd.u.ctarg.req) { 3602 dma_free_coherent(&vha->hw->pdev->dev, 3603 sizeof(struct ct_sns_pkt), 3604 sp->u.iocb_cmd.u.ctarg.req, 3605 sp->u.iocb_cmd.u.ctarg.req_dma); 3606 sp->u.iocb_cmd.u.ctarg.req = NULL; 3607 } 3608 if (sp->u.iocb_cmd.u.ctarg.rsp) { 3609 dma_free_coherent(&vha->hw->pdev->dev, 3610 sizeof(struct ct_sns_pkt), 3611 sp->u.iocb_cmd.u.ctarg.rsp, 3612 sp->u.iocb_cmd.u.ctarg.rsp_dma); 3613 sp->u.iocb_cmd.u.ctarg.rsp = NULL; 3614 } 3615 3616 sp->free(sp); 3617 return; 3618 } 3619 3620 e->u.iosb.sp = sp; 3621 qla2x00_post_work(vha, e); 3622 } 3623 3624 /* Get WWPN with Nport ID. */ 3625 int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id) 3626 { 3627 int rval = QLA_FUNCTION_FAILED; 3628 struct ct_sns_req *ct_req; 3629 srb_t *sp, *tsp; 3630 struct ct_sns_pkt *ct_sns; 3631 unsigned long flags; 3632 3633 if (!vha->flags.online) 3634 goto done; 3635 3636 sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); 3637 if (!sp) 3638 goto done; 3639 3640 sp->type = SRB_CT_PTHRU_CMD; 3641 sp->name = "gpnid"; 3642 sp->u.iocb_cmd.u.ctarg.id = *id; 3643 sp->gen1 = 0; 3644 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 3645 3646 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); 3647 list_for_each_entry(tsp, &vha->gpnid_list, elem) { 3648 if (tsp->u.iocb_cmd.u.ctarg.id.b24 == id->b24) { 3649 tsp->gen1++; 3650 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); 3651 sp->free(sp); 3652 goto done; 3653 } 3654 } 3655 list_add_tail(&sp->elem, &vha->gpnid_list); 3656 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); 3657 3658 sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev, 3659 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma, 3660 GFP_KERNEL); 3661 if (!sp->u.iocb_cmd.u.ctarg.req) { 3662 ql_log(ql_log_warn, vha, 0xd041, 3663 "Failed to allocate ct_sns request.\n"); 3664 goto done_free_sp; 3665 } 3666 3667 sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev, 3668 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma, 3669 GFP_KERNEL); 3670 if (!sp->u.iocb_cmd.u.ctarg.rsp) { 3671 ql_log(ql_log_warn, vha, 0xd042, 3672 "Failed to allocate ct_sns request.\n"); 3673 goto done_free_sp; 3674 } 3675 3676 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp; 3677 memset(ct_sns, 0, sizeof(*ct_sns)); 3678 3679 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; 3680 /* CT_IU preamble */ 3681 ct_req = qla2x00_prep_ct_req(ct_sns, GPN_ID_CMD, GPN_ID_RSP_SIZE); 3682 3683 /* GPN_ID req */ 3684 ct_req->req.port_id.port_id[0] = id->b.domain; 3685 ct_req->req.port_id.port_id[1] = id->b.area; 3686 ct_req->req.port_id.port_id[2] = id->b.al_pa; 3687 3688 sp->u.iocb_cmd.u.ctarg.req_size = GPN_ID_REQ_SIZE; 3689 sp->u.iocb_cmd.u.ctarg.rsp_size = GPN_ID_RSP_SIZE; 3690 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 3691 3692 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 3693 sp->done = qla2x00_async_gpnid_sp_done; 3694 3695 rval = qla2x00_start_sp(sp); 3696 if (rval != QLA_SUCCESS) 3697 goto done_free_sp; 3698 3699 ql_dbg(ql_dbg_disc, vha, 0x2067, 3700 "Async-%s hdl=%x ID %3phC.\n", sp->name, 3701 sp->handle, ct_req->req.port_id.port_id); 3702 return rval; 3703 3704 done_free_sp: 3705 if (sp->u.iocb_cmd.u.ctarg.req) { 3706 dma_free_coherent(&vha->hw->pdev->dev, 3707 sizeof(struct ct_sns_pkt), 3708 sp->u.iocb_cmd.u.ctarg.req, 3709 sp->u.iocb_cmd.u.ctarg.req_dma); 3710 sp->u.iocb_cmd.u.ctarg.req = NULL; 3711 } 3712 if (sp->u.iocb_cmd.u.ctarg.rsp) { 3713 dma_free_coherent(&vha->hw->pdev->dev, 3714 sizeof(struct ct_sns_pkt), 3715 sp->u.iocb_cmd.u.ctarg.rsp, 3716 sp->u.iocb_cmd.u.ctarg.rsp_dma); 3717 sp->u.iocb_cmd.u.ctarg.rsp = NULL; 3718 } 3719 3720 sp->free(sp); 3721 done: 3722 return rval; 3723 } 3724 3725 void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea) 3726 { 3727 fc_port_t *fcport = ea->fcport; 3728 3729 qla24xx_post_gnl_work(vha, fcport); 3730 } 3731 3732 void qla24xx_async_gffid_sp_done(void *s, int res) 3733 { 3734 struct srb *sp = s; 3735 struct scsi_qla_host *vha = sp->vha; 3736 fc_port_t *fcport = sp->fcport; 3737 struct ct_sns_rsp *ct_rsp; 3738 struct event_arg ea; 3739 3740 ql_dbg(ql_dbg_disc, vha, 0x2133, 3741 "Async done-%s res %x ID %x. %8phC\n", 3742 sp->name, res, fcport->d_id.b24, fcport->port_name); 3743 3744 fcport->flags &= ~FCF_ASYNC_SENT; 3745 ct_rsp = &fcport->ct_desc.ct_sns->p.rsp; 3746 /* 3747 * FC-GS-7, 5.2.3.12 FC-4 Features - format 3748 * The format of the FC-4 Features object, as defined by the FC-4, 3749 * Shall be an array of 4-bit values, one for each type code value 3750 */ 3751 if (!res) { 3752 if (ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET] & 0xf) { 3753 /* w1 b00:03 */ 3754 fcport->fc4_type = 3755 ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET]; 3756 fcport->fc4_type &= 0xf; 3757 } 3758 3759 if (ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET] & 0xf) { 3760 /* w5 [00:03]/28h */ 3761 fcport->fc4f_nvme = 3762 ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET]; 3763 fcport->fc4f_nvme &= 0xf; 3764 } 3765 } 3766 3767 memset(&ea, 0, sizeof(ea)); 3768 ea.sp = sp; 3769 ea.fcport = sp->fcport; 3770 ea.rc = res; 3771 ea.event = FCME_GFFID_DONE; 3772 3773 qla2x00_fcport_event_handler(vha, &ea); 3774 sp->free(sp); 3775 } 3776 3777 /* Get FC4 Feature with Nport ID. */ 3778 int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport) 3779 { 3780 int rval = QLA_FUNCTION_FAILED; 3781 struct ct_sns_req *ct_req; 3782 srb_t *sp; 3783 3784 if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) 3785 return rval; 3786 3787 sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); 3788 if (!sp) 3789 return rval; 3790 3791 fcport->flags |= FCF_ASYNC_SENT; 3792 sp->type = SRB_CT_PTHRU_CMD; 3793 sp->name = "gffid"; 3794 sp->gen1 = fcport->rscn_gen; 3795 sp->gen2 = fcport->login_gen; 3796 3797 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 3798 3799 /* CT_IU preamble */ 3800 ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFF_ID_CMD, 3801 GFF_ID_RSP_SIZE); 3802 3803 ct_req->req.gff_id.port_id[0] = fcport->d_id.b.domain; 3804 ct_req->req.gff_id.port_id[1] = fcport->d_id.b.area; 3805 ct_req->req.gff_id.port_id[2] = fcport->d_id.b.al_pa; 3806 3807 sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns; 3808 sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma; 3809 sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns; 3810 sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma; 3811 sp->u.iocb_cmd.u.ctarg.req_size = GFF_ID_REQ_SIZE; 3812 sp->u.iocb_cmd.u.ctarg.rsp_size = GFF_ID_RSP_SIZE; 3813 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 3814 3815 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 3816 sp->done = qla24xx_async_gffid_sp_done; 3817 3818 rval = qla2x00_start_sp(sp); 3819 if (rval != QLA_SUCCESS) 3820 goto done_free_sp; 3821 3822 ql_dbg(ql_dbg_disc, vha, 0x2132, 3823 "Async-%s hdl=%x %8phC.\n", sp->name, 3824 sp->handle, fcport->port_name); 3825 3826 return rval; 3827 done_free_sp: 3828 sp->free(sp); 3829 fcport->flags &= ~FCF_ASYNC_SENT; 3830 return rval; 3831 } 3832 3833 /* GPN_FT + GNN_FT*/ 3834 static int qla2x00_is_a_vp(scsi_qla_host_t *vha, u64 wwn) 3835 { 3836 struct qla_hw_data *ha = vha->hw; 3837 scsi_qla_host_t *vp; 3838 unsigned long flags; 3839 u64 twwn; 3840 int rc = 0; 3841 3842 if (!ha->num_vhosts) 3843 return 0; 3844 3845 spin_lock_irqsave(&ha->vport_slock, flags); 3846 list_for_each_entry(vp, &ha->vp_list, list) { 3847 twwn = wwn_to_u64(vp->port_name); 3848 if (wwn == twwn) { 3849 rc = 1; 3850 break; 3851 } 3852 } 3853 spin_unlock_irqrestore(&ha->vport_slock, flags); 3854 3855 return rc; 3856 } 3857 3858 void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) 3859 { 3860 fc_port_t *fcport; 3861 u32 i, rc; 3862 bool found; 3863 u8 fc4type = sp->gen2; 3864 struct fab_scan_rp *rp; 3865 unsigned long flags; 3866 3867 ql_dbg(ql_dbg_disc, vha, 0xffff, 3868 "%s enter\n", __func__); 3869 3870 if (sp->gen1 != vha->hw->base_qpair->chip_reset) { 3871 ql_dbg(ql_dbg_disc, vha, 0xffff, 3872 "%s scan stop due to chip reset %x/%x\n", 3873 sp->name, sp->gen1, vha->hw->base_qpair->chip_reset); 3874 goto out; 3875 } 3876 3877 rc = sp->rc; 3878 if (rc) { 3879 vha->scan.scan_retry++; 3880 if (vha->scan.scan_retry < MAX_SCAN_RETRIES) { 3881 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); 3882 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); 3883 } else { 3884 ql_dbg(ql_dbg_disc, vha, 0xffff, 3885 "Fabric scan failed on all retries.\n"); 3886 } 3887 goto out; 3888 } 3889 vha->scan.scan_retry = 0; 3890 3891 list_for_each_entry(fcport, &vha->vp_fcports, list) 3892 fcport->scan_state = QLA_FCPORT_SCAN; 3893 3894 for (i = 0; i < vha->hw->max_fibre_devices; i++) { 3895 u64 wwn; 3896 3897 rp = &vha->scan.l[i]; 3898 found = false; 3899 3900 wwn = wwn_to_u64(rp->port_name); 3901 if (wwn == 0) 3902 continue; 3903 3904 if (!memcmp(rp->port_name, vha->port_name, WWN_SIZE)) 3905 continue; 3906 3907 /* Bypass reserved domain fields. */ 3908 if ((rp->id.b.domain & 0xf0) == 0xf0) 3909 continue; 3910 3911 /* Bypass virtual ports of the same host. */ 3912 if (qla2x00_is_a_vp(vha, wwn)) 3913 continue; 3914 3915 list_for_each_entry(fcport, &vha->vp_fcports, list) { 3916 if (memcmp(rp->port_name, fcport->port_name, WWN_SIZE)) 3917 continue; 3918 fcport->scan_state = QLA_FCPORT_FOUND; 3919 fcport->d_id.b24 = rp->id.b24; 3920 found = true; 3921 /* 3922 * If device was not a fabric device before. 3923 */ 3924 if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) { 3925 qla2x00_clear_loop_id(fcport); 3926 fcport->flags |= FCF_FABRIC_DEVICE; 3927 } 3928 break; 3929 } 3930 3931 if (!found) { 3932 ql_dbg(ql_dbg_disc, vha, 0xffff, 3933 "%s %d %8phC post new sess\n", 3934 __func__, __LINE__, rp->port_name); 3935 qla24xx_post_newsess_work(vha, &rp->id, rp->port_name, 3936 rp->node_name, NULL, fc4type); 3937 } 3938 } 3939 3940 /* 3941 * Logout all previous fabric dev marked lost, except FCP2 devices. 3942 */ 3943 list_for_each_entry(fcport, &vha->vp_fcports, list) { 3944 if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) 3945 continue; 3946 3947 if (fcport->scan_state != QLA_FCPORT_FOUND) { 3948 if ((qla_dual_mode_enabled(vha) || 3949 qla_ini_mode_enabled(vha)) && 3950 atomic_read(&fcport->state) == FCS_ONLINE) { 3951 qla2x00_mark_device_lost(vha, fcport, 3952 ql2xplogiabsentdevice, 0); 3953 3954 if (fcport->loop_id != FC_NO_LOOP_ID && 3955 (fcport->flags & FCF_FCP2_DEVICE) == 0) { 3956 ql_dbg(ql_dbg_disc, vha, 0x20f0, 3957 "%s %d %8phC post del sess\n", 3958 __func__, __LINE__, 3959 fcport->port_name); 3960 3961 qlt_schedule_sess_for_deletion(fcport); 3962 continue; 3963 } 3964 } 3965 } else 3966 qla24xx_fcport_handle_login(vha, fcport); 3967 } 3968 3969 out: 3970 qla24xx_sp_unmap(vha, sp); 3971 spin_lock_irqsave(&vha->work_lock, flags); 3972 vha->scan.scan_flags &= ~SF_SCANNING; 3973 spin_unlock_irqrestore(&vha->work_lock, flags); 3974 } 3975 3976 static void qla2x00_async_gpnft_gnnft_sp_done(void *s, int res) 3977 { 3978 struct srb *sp = s; 3979 struct scsi_qla_host *vha = sp->vha; 3980 struct qla_work_evt *e; 3981 struct ct_sns_req *ct_req = 3982 (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req; 3983 struct ct_sns_gpnft_rsp *ct_rsp = 3984 (struct ct_sns_gpnft_rsp *)sp->u.iocb_cmd.u.ctarg.rsp; 3985 struct ct_sns_gpn_ft_data *d; 3986 struct fab_scan_rp *rp; 3987 int i, j, k; 3988 u16 cmd = be16_to_cpu(ct_req->command); 3989 3990 /* gen2 field is holding the fc4type */ 3991 ql_dbg(ql_dbg_disc, vha, 0xffff, 3992 "Async done-%s res %x FC4Type %x\n", 3993 sp->name, res, sp->gen2); 3994 3995 if (res) { 3996 unsigned long flags; 3997 3998 sp->free(sp); 3999 spin_lock_irqsave(&vha->work_lock, flags); 4000 vha->scan.scan_flags &= ~SF_SCANNING; 4001 vha->scan.scan_retry++; 4002 spin_unlock_irqrestore(&vha->work_lock, flags); 4003 4004 if (vha->scan.scan_retry < MAX_SCAN_RETRIES) { 4005 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); 4006 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); 4007 qla2xxx_wake_dpc(vha); 4008 } else { 4009 ql_dbg(ql_dbg_disc, sp->vha, 0xffff, 4010 "Async done-%s rescan failed on all retries\n", 4011 sp->name); 4012 } 4013 return; 4014 } 4015 4016 if (!res) { 4017 port_id_t id; 4018 u64 wwn; 4019 4020 j = 0; 4021 for (i = 0; i < vha->hw->max_fibre_devices; i++) { 4022 d = &ct_rsp->entries[i]; 4023 4024 id.b.rsvd_1 = 0; 4025 id.b.domain = d->port_id[0]; 4026 id.b.area = d->port_id[1]; 4027 id.b.al_pa = d->port_id[2]; 4028 wwn = wwn_to_u64(d->port_name); 4029 4030 if (id.b24 == 0 || wwn == 0) 4031 continue; 4032 4033 if (cmd == GPN_FT_CMD) { 4034 rp = &vha->scan.l[j]; 4035 rp->id = id; 4036 memcpy(rp->port_name, d->port_name, 8); 4037 j++; 4038 } else {/* GNN_FT_CMD */ 4039 for (k = 0; k < vha->hw->max_fibre_devices; 4040 k++) { 4041 rp = &vha->scan.l[k]; 4042 if (id.b24 == rp->id.b24) { 4043 memcpy(rp->node_name, 4044 d->port_name, 8); 4045 break; 4046 } 4047 } 4048 } 4049 } 4050 } 4051 4052 if (cmd == GPN_FT_CMD) 4053 e = qla2x00_alloc_work(vha, QLA_EVT_GPNFT_DONE); 4054 else 4055 e = qla2x00_alloc_work(vha, QLA_EVT_GNNFT_DONE); 4056 if (!e) { 4057 /* please ignore kernel warning. Otherwise, we have mem leak. */ 4058 if (sp->u.iocb_cmd.u.ctarg.req) { 4059 dma_free_coherent(&vha->hw->pdev->dev, 4060 sizeof(struct ct_sns_pkt), 4061 sp->u.iocb_cmd.u.ctarg.req, 4062 sp->u.iocb_cmd.u.ctarg.req_dma); 4063 sp->u.iocb_cmd.u.ctarg.req = NULL; 4064 } 4065 if (sp->u.iocb_cmd.u.ctarg.rsp) { 4066 dma_free_coherent(&vha->hw->pdev->dev, 4067 sizeof(struct ct_sns_pkt), 4068 sp->u.iocb_cmd.u.ctarg.rsp, 4069 sp->u.iocb_cmd.u.ctarg.rsp_dma); 4070 sp->u.iocb_cmd.u.ctarg.rsp = NULL; 4071 } 4072 4073 ql_dbg(ql_dbg_disc, vha, 0xffff, 4074 "Async done-%s unable to alloc work element\n", 4075 sp->name); 4076 sp->free(sp); 4077 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); 4078 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); 4079 return; 4080 } 4081 4082 sp->rc = res; 4083 e->u.iosb.sp = sp; 4084 4085 qla2x00_post_work(vha, e); 4086 } 4087 4088 /* 4089 * Get WWNN list for fc4_type 4090 * 4091 * It is assumed the same SRB is re-used from GPNFT to avoid 4092 * mem free & re-alloc 4093 */ 4094 static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp, 4095 u8 fc4_type) 4096 { 4097 int rval = QLA_FUNCTION_FAILED; 4098 struct ct_sns_req *ct_req; 4099 struct ct_sns_pkt *ct_sns; 4100 4101 if (!vha->flags.online) { 4102 vha->scan.scan_flags &= ~SF_SCANNING; 4103 goto done_free_sp; 4104 } 4105 4106 if (!sp->u.iocb_cmd.u.ctarg.req || !sp->u.iocb_cmd.u.ctarg.rsp) { 4107 ql_log(ql_log_warn, vha, 0xffff, 4108 "%s: req %p rsp %p are not setup\n", 4109 __func__, sp->u.iocb_cmd.u.ctarg.req, 4110 sp->u.iocb_cmd.u.ctarg.rsp); 4111 vha->scan.scan_flags &= ~SF_SCANNING; 4112 WARN_ON(1); 4113 goto done_free_sp; 4114 } 4115 sp->type = SRB_CT_PTHRU_CMD; 4116 sp->name = "gnnft"; 4117 sp->gen1 = vha->hw->base_qpair->chip_reset; 4118 sp->gen2 = fc4_type; 4119 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 4120 4121 memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size); 4122 memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size); 4123 4124 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; 4125 /* CT_IU preamble */ 4126 ct_req = qla2x00_prep_ct_req(ct_sns, GNN_FT_CMD, 4127 sp->u.iocb_cmd.u.ctarg.rsp_size); 4128 4129 /* GPN_FT req */ 4130 ct_req->req.gpn_ft.port_type = fc4_type; 4131 4132 sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE; 4133 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 4134 4135 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 4136 sp->done = qla2x00_async_gpnft_gnnft_sp_done; 4137 4138 rval = qla2x00_start_sp(sp); 4139 if (rval != QLA_SUCCESS) 4140 goto done_free_sp; 4141 4142 ql_dbg(ql_dbg_disc, vha, 0xffff, 4143 "Async-%s hdl=%x FC4Type %x.\n", sp->name, 4144 sp->handle, ct_req->req.gpn_ft.port_type); 4145 return rval; 4146 4147 done_free_sp: 4148 if (sp->u.iocb_cmd.u.ctarg.req) { 4149 dma_free_coherent(&vha->hw->pdev->dev, 4150 sizeof(struct ct_sns_pkt), 4151 sp->u.iocb_cmd.u.ctarg.req, 4152 sp->u.iocb_cmd.u.ctarg.req_dma); 4153 sp->u.iocb_cmd.u.ctarg.req = NULL; 4154 } 4155 if (sp->u.iocb_cmd.u.ctarg.rsp) { 4156 dma_free_coherent(&vha->hw->pdev->dev, 4157 sizeof(struct ct_sns_pkt), 4158 sp->u.iocb_cmd.u.ctarg.rsp, 4159 sp->u.iocb_cmd.u.ctarg.rsp_dma); 4160 sp->u.iocb_cmd.u.ctarg.rsp = NULL; 4161 } 4162 4163 sp->free(sp); 4164 4165 return rval; 4166 } /* GNNFT */ 4167 4168 void qla24xx_async_gpnft_done(scsi_qla_host_t *vha, srb_t *sp) 4169 { 4170 ql_dbg(ql_dbg_disc, vha, 0xffff, 4171 "%s enter\n", __func__); 4172 del_timer(&sp->u.iocb_cmd.timer); 4173 qla24xx_async_gnnft(vha, sp, sp->gen2); 4174 } 4175 4176 /* Get WWPN list for certain fc4_type */ 4177 int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type) 4178 { 4179 int rval = QLA_FUNCTION_FAILED; 4180 struct ct_sns_req *ct_req; 4181 srb_t *sp; 4182 struct ct_sns_pkt *ct_sns; 4183 u32 rspsz; 4184 unsigned long flags; 4185 4186 if (!vha->flags.online) 4187 return rval; 4188 4189 spin_lock_irqsave(&vha->work_lock, flags); 4190 if (vha->scan.scan_flags & SF_SCANNING) { 4191 spin_unlock_irqrestore(&vha->work_lock, flags); 4192 ql_dbg(ql_dbg_disc, vha, 0xffff, "scan active\n"); 4193 return rval; 4194 } 4195 vha->scan.scan_flags |= SF_SCANNING; 4196 spin_unlock_irqrestore(&vha->work_lock, flags); 4197 4198 sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); 4199 if (!sp) { 4200 vha->scan.scan_flags &= ~SF_SCANNING; 4201 return rval; 4202 } 4203 4204 sp->type = SRB_CT_PTHRU_CMD; 4205 sp->name = "gpnft"; 4206 sp->gen1 = vha->hw->base_qpair->chip_reset; 4207 sp->gen2 = fc4_type; 4208 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 4209 4210 sp->u.iocb_cmd.u.ctarg.req = dma_zalloc_coherent(&vha->hw->pdev->dev, 4211 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma, 4212 GFP_KERNEL); 4213 if (!sp->u.iocb_cmd.u.ctarg.req) { 4214 ql_log(ql_log_warn, vha, 0xffff, 4215 "Failed to allocate ct_sns request.\n"); 4216 vha->scan.scan_flags &= ~SF_SCANNING; 4217 goto done_free_sp; 4218 } 4219 4220 rspsz = sizeof(struct ct_sns_gpnft_rsp) + 4221 ((vha->hw->max_fibre_devices - 1) * 4222 sizeof(struct ct_sns_gpn_ft_data)); 4223 4224 sp->u.iocb_cmd.u.ctarg.rsp = dma_zalloc_coherent(&vha->hw->pdev->dev, 4225 rspsz, &sp->u.iocb_cmd.u.ctarg.rsp_dma, GFP_KERNEL); 4226 if (!sp->u.iocb_cmd.u.ctarg.rsp) { 4227 ql_log(ql_log_warn, vha, 0xffff, 4228 "Failed to allocate ct_sns request.\n"); 4229 vha->scan.scan_flags &= ~SF_SCANNING; 4230 goto done_free_sp; 4231 } 4232 4233 memset(vha->scan.l, 0, vha->scan.size); 4234 4235 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; 4236 /* CT_IU preamble */ 4237 ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz); 4238 4239 /* GPN_FT req */ 4240 ct_req->req.gpn_ft.port_type = fc4_type; 4241 4242 sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE; 4243 sp->u.iocb_cmd.u.ctarg.rsp_size = rspsz; 4244 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 4245 4246 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 4247 sp->done = qla2x00_async_gpnft_gnnft_sp_done; 4248 4249 rval = qla2x00_start_sp(sp); 4250 if (rval != QLA_SUCCESS) { 4251 vha->scan.scan_flags &= ~SF_SCANNING; 4252 goto done_free_sp; 4253 } 4254 4255 ql_dbg(ql_dbg_disc, vha, 0xffff, 4256 "Async-%s hdl=%x FC4Type %x.\n", sp->name, 4257 sp->handle, ct_req->req.gpn_ft.port_type); 4258 return rval; 4259 4260 done_free_sp: 4261 if (sp->u.iocb_cmd.u.ctarg.req) { 4262 dma_free_coherent(&vha->hw->pdev->dev, 4263 sizeof(struct ct_sns_pkt), 4264 sp->u.iocb_cmd.u.ctarg.req, 4265 sp->u.iocb_cmd.u.ctarg.req_dma); 4266 sp->u.iocb_cmd.u.ctarg.req = NULL; 4267 } 4268 if (sp->u.iocb_cmd.u.ctarg.rsp) { 4269 dma_free_coherent(&vha->hw->pdev->dev, 4270 sizeof(struct ct_sns_pkt), 4271 sp->u.iocb_cmd.u.ctarg.rsp, 4272 sp->u.iocb_cmd.u.ctarg.rsp_dma); 4273 sp->u.iocb_cmd.u.ctarg.rsp = NULL; 4274 } 4275 4276 sp->free(sp); 4277 4278 return rval; 4279 } 4280 4281 void qla_scan_work_fn(struct work_struct *work) 4282 { 4283 struct fab_scan *s = container_of(to_delayed_work(work), 4284 struct fab_scan, scan_work); 4285 struct scsi_qla_host *vha = container_of(s, struct scsi_qla_host, 4286 scan); 4287 unsigned long flags; 4288 4289 ql_dbg(ql_dbg_disc, vha, 0xffff, 4290 "%s: schedule loop resync\n", __func__); 4291 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); 4292 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); 4293 qla2xxx_wake_dpc(vha); 4294 spin_lock_irqsave(&vha->work_lock, flags); 4295 vha->scan.scan_flags &= ~SF_QUEUED; 4296 spin_unlock_irqrestore(&vha->work_lock, flags); 4297 } 4298 4299 /* GNN_ID */ 4300 void qla24xx_handle_gnnid_event(scsi_qla_host_t *vha, struct event_arg *ea) 4301 { 4302 qla24xx_post_gnl_work(vha, ea->fcport); 4303 } 4304 4305 static void qla2x00_async_gnnid_sp_done(void *s, int res) 4306 { 4307 struct srb *sp = s; 4308 struct scsi_qla_host *vha = sp->vha; 4309 fc_port_t *fcport = sp->fcport; 4310 u8 *node_name = fcport->ct_desc.ct_sns->p.rsp.rsp.gnn_id.node_name; 4311 struct event_arg ea; 4312 u64 wwnn; 4313 4314 fcport->flags &= ~FCF_ASYNC_SENT; 4315 wwnn = wwn_to_u64(node_name); 4316 if (wwnn) 4317 memcpy(fcport->node_name, node_name, WWN_SIZE); 4318 4319 memset(&ea, 0, sizeof(ea)); 4320 ea.fcport = fcport; 4321 ea.sp = sp; 4322 ea.rc = res; 4323 ea.event = FCME_GNNID_DONE; 4324 4325 ql_dbg(ql_dbg_disc, vha, 0x204f, 4326 "Async done-%s res %x, WWPN %8phC %8phC\n", 4327 sp->name, res, fcport->port_name, fcport->node_name); 4328 4329 qla2x00_fcport_event_handler(vha, &ea); 4330 4331 sp->free(sp); 4332 } 4333 4334 int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport) 4335 { 4336 int rval = QLA_FUNCTION_FAILED; 4337 struct ct_sns_req *ct_req; 4338 srb_t *sp; 4339 4340 if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) 4341 return rval; 4342 4343 fcport->disc_state = DSC_GNN_ID; 4344 sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC); 4345 if (!sp) 4346 goto done; 4347 4348 fcport->flags |= FCF_ASYNC_SENT; 4349 sp->type = SRB_CT_PTHRU_CMD; 4350 sp->name = "gnnid"; 4351 sp->gen1 = fcport->rscn_gen; 4352 sp->gen2 = fcport->login_gen; 4353 4354 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 4355 4356 /* CT_IU preamble */ 4357 ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GNN_ID_CMD, 4358 GNN_ID_RSP_SIZE); 4359 4360 /* GNN_ID req */ 4361 ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain; 4362 ct_req->req.port_id.port_id[1] = fcport->d_id.b.area; 4363 ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa; 4364 4365 4366 /* req & rsp use the same buffer */ 4367 sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns; 4368 sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma; 4369 sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns; 4370 sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma; 4371 sp->u.iocb_cmd.u.ctarg.req_size = GNN_ID_REQ_SIZE; 4372 sp->u.iocb_cmd.u.ctarg.rsp_size = GNN_ID_RSP_SIZE; 4373 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 4374 4375 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 4376 sp->done = qla2x00_async_gnnid_sp_done; 4377 4378 rval = qla2x00_start_sp(sp); 4379 if (rval != QLA_SUCCESS) 4380 goto done_free_sp; 4381 ql_dbg(ql_dbg_disc, vha, 0xffff, 4382 "Async-%s - %8phC hdl=%x loopid=%x portid %06x.\n", 4383 sp->name, fcport->port_name, 4384 sp->handle, fcport->loop_id, fcport->d_id.b24); 4385 return rval; 4386 4387 done_free_sp: 4388 sp->free(sp); 4389 fcport->flags &= ~FCF_ASYNC_SENT; 4390 done: 4391 return rval; 4392 } 4393 4394 int qla24xx_post_gnnid_work(struct scsi_qla_host *vha, fc_port_t *fcport) 4395 { 4396 struct qla_work_evt *e; 4397 int ls; 4398 4399 ls = atomic_read(&vha->loop_state); 4400 if (((ls != LOOP_READY) && (ls != LOOP_UP)) || 4401 test_bit(UNLOADING, &vha->dpc_flags)) 4402 return 0; 4403 4404 e = qla2x00_alloc_work(vha, QLA_EVT_GNNID); 4405 if (!e) 4406 return QLA_FUNCTION_FAILED; 4407 4408 e->u.fcport.fcport = fcport; 4409 return qla2x00_post_work(vha, e); 4410 } 4411 4412 /* GPFN_ID */ 4413 void qla24xx_handle_gfpnid_event(scsi_qla_host_t *vha, struct event_arg *ea) 4414 { 4415 fc_port_t *fcport = ea->fcport; 4416 4417 ql_dbg(ql_dbg_disc, vha, 0xffff, 4418 "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d fcpcnt %d\n", 4419 __func__, fcport->port_name, fcport->disc_state, 4420 fcport->fw_login_state, ea->rc, fcport->login_gen, ea->sp->gen2, 4421 fcport->rscn_gen, ea->sp->gen1, vha->fcport_count); 4422 4423 if (fcport->disc_state == DSC_DELETE_PEND) 4424 return; 4425 4426 if (ea->sp->gen2 != fcport->login_gen) { 4427 /* target side must have changed it. */ 4428 ql_dbg(ql_dbg_disc, vha, 0x20d3, 4429 "%s %8phC generation changed\n", 4430 __func__, fcport->port_name); 4431 return; 4432 } else if (ea->sp->gen1 != fcport->rscn_gen) { 4433 ql_dbg(ql_dbg_disc, vha, 0x20d4, "%s %d %8phC post gidpn\n", 4434 __func__, __LINE__, fcport->port_name); 4435 qla24xx_post_gidpn_work(vha, fcport); 4436 return; 4437 } 4438 4439 qla24xx_post_gpsc_work(vha, fcport); 4440 } 4441 4442 static void qla2x00_async_gfpnid_sp_done(void *s, int res) 4443 { 4444 struct srb *sp = s; 4445 struct scsi_qla_host *vha = sp->vha; 4446 fc_port_t *fcport = sp->fcport; 4447 u8 *fpn = fcport->ct_desc.ct_sns->p.rsp.rsp.gfpn_id.port_name; 4448 struct event_arg ea; 4449 u64 wwn; 4450 4451 fcport->flags &= ~FCF_ASYNC_SENT; 4452 wwn = wwn_to_u64(fpn); 4453 if (wwn) 4454 memcpy(fcport->fabric_port_name, fpn, WWN_SIZE); 4455 4456 memset(&ea, 0, sizeof(ea)); 4457 ea.fcport = fcport; 4458 ea.sp = sp; 4459 ea.rc = res; 4460 ea.event = FCME_GFPNID_DONE; 4461 4462 ql_dbg(ql_dbg_disc, vha, 0x204f, 4463 "Async done-%s res %x, WWPN %8phC %8phC\n", 4464 sp->name, res, fcport->port_name, fcport->fabric_port_name); 4465 4466 qla2x00_fcport_event_handler(vha, &ea); 4467 4468 sp->free(sp); 4469 } 4470 4471 int qla24xx_async_gfpnid(scsi_qla_host_t *vha, fc_port_t *fcport) 4472 { 4473 int rval = QLA_FUNCTION_FAILED; 4474 struct ct_sns_req *ct_req; 4475 srb_t *sp; 4476 4477 if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) 4478 return rval; 4479 4480 fcport->disc_state = DSC_GFPN_ID; 4481 sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC); 4482 if (!sp) 4483 goto done; 4484 4485 fcport->flags |= FCF_ASYNC_SENT; 4486 sp->type = SRB_CT_PTHRU_CMD; 4487 sp->name = "gfpnid"; 4488 sp->gen1 = fcport->rscn_gen; 4489 sp->gen2 = fcport->login_gen; 4490 4491 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 4492 4493 /* CT_IU preamble */ 4494 ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFPN_ID_CMD, 4495 GFPN_ID_RSP_SIZE); 4496 4497 /* GFPN_ID req */ 4498 ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain; 4499 ct_req->req.port_id.port_id[1] = fcport->d_id.b.area; 4500 ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa; 4501 4502 4503 /* req & rsp use the same buffer */ 4504 sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns; 4505 sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma; 4506 sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns; 4507 sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma; 4508 sp->u.iocb_cmd.u.ctarg.req_size = GFPN_ID_REQ_SIZE; 4509 sp->u.iocb_cmd.u.ctarg.rsp_size = GFPN_ID_RSP_SIZE; 4510 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 4511 4512 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 4513 sp->done = qla2x00_async_gfpnid_sp_done; 4514 4515 rval = qla2x00_start_sp(sp); 4516 if (rval != QLA_SUCCESS) 4517 goto done_free_sp; 4518 4519 ql_dbg(ql_dbg_disc, vha, 0xffff, 4520 "Async-%s - %8phC hdl=%x loopid=%x portid %06x.\n", 4521 sp->name, fcport->port_name, 4522 sp->handle, fcport->loop_id, fcport->d_id.b24); 4523 return rval; 4524 4525 done_free_sp: 4526 sp->free(sp); 4527 fcport->flags &= ~FCF_ASYNC_SENT; 4528 done: 4529 return rval; 4530 } 4531 4532 int qla24xx_post_gfpnid_work(struct scsi_qla_host *vha, fc_port_t *fcport) 4533 { 4534 struct qla_work_evt *e; 4535 int ls; 4536 4537 ls = atomic_read(&vha->loop_state); 4538 if (((ls != LOOP_READY) && (ls != LOOP_UP)) || 4539 test_bit(UNLOADING, &vha->dpc_flags)) 4540 return 0; 4541 4542 e = qla2x00_alloc_work(vha, QLA_EVT_GFPNID); 4543 if (!e) 4544 return QLA_FUNCTION_FAILED; 4545 4546 e->u.fcport.fcport = fcport; 4547 return qla2x00_post_work(vha, e); 4548 } 4549