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 fcport->flags &= ~FCF_ASYNC_ACTIVE; 3183 return rval; 3184 } 3185 3186 int qla24xx_post_gidpn_work(struct scsi_qla_host *vha, fc_port_t *fcport) 3187 { 3188 struct qla_work_evt *e; 3189 int ls; 3190 3191 ls = atomic_read(&vha->loop_state); 3192 if (((ls != LOOP_READY) && (ls != LOOP_UP)) || 3193 test_bit(UNLOADING, &vha->dpc_flags)) 3194 return 0; 3195 3196 e = qla2x00_alloc_work(vha, QLA_EVT_GIDPN); 3197 if (!e) 3198 return QLA_FUNCTION_FAILED; 3199 3200 e->u.fcport.fcport = fcport; 3201 fcport->flags |= FCF_ASYNC_ACTIVE; 3202 return qla2x00_post_work(vha, e); 3203 } 3204 3205 int qla24xx_post_gpsc_work(struct scsi_qla_host *vha, fc_port_t *fcport) 3206 { 3207 struct qla_work_evt *e; 3208 3209 e = qla2x00_alloc_work(vha, QLA_EVT_GPSC); 3210 if (!e) 3211 return QLA_FUNCTION_FAILED; 3212 3213 e->u.fcport.fcport = fcport; 3214 fcport->flags |= FCF_ASYNC_ACTIVE; 3215 return qla2x00_post_work(vha, e); 3216 } 3217 3218 void qla24xx_handle_gpsc_event(scsi_qla_host_t *vha, struct event_arg *ea) 3219 { 3220 struct fc_port *fcport = ea->fcport; 3221 3222 ql_dbg(ql_dbg_disc, vha, 0x20d8, 3223 "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d lid %d\n", 3224 __func__, fcport->port_name, fcport->disc_state, 3225 fcport->fw_login_state, ea->rc, ea->sp->gen2, fcport->login_gen, 3226 ea->sp->gen2, fcport->rscn_gen|ea->sp->gen1, fcport->loop_id); 3227 3228 if (fcport->disc_state == DSC_DELETE_PEND) 3229 return; 3230 3231 if (ea->sp->gen2 != fcport->login_gen) { 3232 /* target side must have changed it. */ 3233 ql_dbg(ql_dbg_disc, vha, 0x20d3, 3234 "%s %8phC generation changed\n", 3235 __func__, fcport->port_name); 3236 return; 3237 } else if (ea->sp->gen1 != fcport->rscn_gen) { 3238 ql_dbg(ql_dbg_disc, vha, 0x20d4, "%s %d %8phC post gidpn\n", 3239 __func__, __LINE__, fcport->port_name); 3240 qla24xx_post_gidpn_work(vha, fcport); 3241 return; 3242 } 3243 3244 qla24xx_post_upd_fcport_work(vha, ea->fcport); 3245 } 3246 3247 static void qla24xx_async_gpsc_sp_done(void *s, int res) 3248 { 3249 struct srb *sp = s; 3250 struct scsi_qla_host *vha = sp->vha; 3251 struct qla_hw_data *ha = vha->hw; 3252 fc_port_t *fcport = sp->fcport; 3253 struct ct_sns_rsp *ct_rsp; 3254 struct event_arg ea; 3255 3256 ct_rsp = &fcport->ct_desc.ct_sns->p.rsp; 3257 3258 ql_dbg(ql_dbg_disc, vha, 0x2053, 3259 "Async done-%s res %x, WWPN %8phC \n", 3260 sp->name, res, fcport->port_name); 3261 3262 fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); 3263 3264 if (res == (DID_ERROR << 16)) { 3265 /* entry status error */ 3266 goto done; 3267 } else if (res) { 3268 if ((ct_rsp->header.reason_code == 3269 CT_REASON_INVALID_COMMAND_CODE) || 3270 (ct_rsp->header.reason_code == 3271 CT_REASON_COMMAND_UNSUPPORTED)) { 3272 ql_dbg(ql_dbg_disc, vha, 0x2019, 3273 "GPSC command unsupported, disabling query.\n"); 3274 ha->flags.gpsc_supported = 0; 3275 res = QLA_SUCCESS; 3276 } 3277 } else { 3278 switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) { 3279 case BIT_15: 3280 fcport->fp_speed = PORT_SPEED_1GB; 3281 break; 3282 case BIT_14: 3283 fcport->fp_speed = PORT_SPEED_2GB; 3284 break; 3285 case BIT_13: 3286 fcport->fp_speed = PORT_SPEED_4GB; 3287 break; 3288 case BIT_12: 3289 fcport->fp_speed = PORT_SPEED_10GB; 3290 break; 3291 case BIT_11: 3292 fcport->fp_speed = PORT_SPEED_8GB; 3293 break; 3294 case BIT_10: 3295 fcport->fp_speed = PORT_SPEED_16GB; 3296 break; 3297 case BIT_8: 3298 fcport->fp_speed = PORT_SPEED_32GB; 3299 break; 3300 } 3301 3302 ql_dbg(ql_dbg_disc, vha, 0x2054, 3303 "Async-%s OUT WWPN %8phC speeds=%04x speed=%04x.\n", 3304 sp->name, fcport->fabric_port_name, 3305 be16_to_cpu(ct_rsp->rsp.gpsc.speeds), 3306 be16_to_cpu(ct_rsp->rsp.gpsc.speed)); 3307 } 3308 done: 3309 memset(&ea, 0, sizeof(ea)); 3310 ea.event = FCME_GPSC_DONE; 3311 ea.rc = res; 3312 ea.fcport = fcport; 3313 ea.sp = sp; 3314 qla2x00_fcport_event_handler(vha, &ea); 3315 3316 sp->free(sp); 3317 } 3318 3319 int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t *fcport) 3320 { 3321 int rval = QLA_FUNCTION_FAILED; 3322 struct ct_sns_req *ct_req; 3323 srb_t *sp; 3324 3325 if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) 3326 return rval; 3327 3328 sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); 3329 if (!sp) 3330 goto done; 3331 3332 fcport->flags |= FCF_ASYNC_SENT; 3333 sp->type = SRB_CT_PTHRU_CMD; 3334 sp->name = "gpsc"; 3335 sp->gen1 = fcport->rscn_gen; 3336 sp->gen2 = fcport->login_gen; 3337 3338 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 3339 3340 /* CT_IU preamble */ 3341 ct_req = qla24xx_prep_ct_fm_req(fcport->ct_desc.ct_sns, GPSC_CMD, 3342 GPSC_RSP_SIZE); 3343 3344 /* GPSC req */ 3345 memcpy(ct_req->req.gpsc.port_name, fcport->fabric_port_name, 3346 WWN_SIZE); 3347 3348 sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns; 3349 sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma; 3350 sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns; 3351 sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma; 3352 sp->u.iocb_cmd.u.ctarg.req_size = GPSC_REQ_SIZE; 3353 sp->u.iocb_cmd.u.ctarg.rsp_size = GPSC_RSP_SIZE; 3354 sp->u.iocb_cmd.u.ctarg.nport_handle = vha->mgmt_svr_loop_id; 3355 3356 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 3357 sp->done = qla24xx_async_gpsc_sp_done; 3358 3359 rval = qla2x00_start_sp(sp); 3360 if (rval != QLA_SUCCESS) 3361 goto done_free_sp; 3362 3363 ql_dbg(ql_dbg_disc, vha, 0x205e, 3364 "Async-%s %8phC hdl=%x loopid=%x portid=%02x%02x%02x.\n", 3365 sp->name, fcport->port_name, sp->handle, 3366 fcport->loop_id, fcport->d_id.b.domain, 3367 fcport->d_id.b.area, fcport->d_id.b.al_pa); 3368 return rval; 3369 3370 done_free_sp: 3371 sp->free(sp); 3372 fcport->flags &= ~FCF_ASYNC_SENT; 3373 done: 3374 fcport->flags &= ~FCF_ASYNC_ACTIVE; 3375 return rval; 3376 } 3377 3378 int qla24xx_post_gpnid_work(struct scsi_qla_host *vha, port_id_t *id) 3379 { 3380 struct qla_work_evt *e; 3381 3382 if (test_bit(UNLOADING, &vha->dpc_flags)) 3383 return 0; 3384 3385 e = qla2x00_alloc_work(vha, QLA_EVT_GPNID); 3386 if (!e) 3387 return QLA_FUNCTION_FAILED; 3388 3389 e->u.gpnid.id = *id; 3390 return qla2x00_post_work(vha, e); 3391 } 3392 3393 void qla24xx_sp_unmap(scsi_qla_host_t *vha, srb_t *sp) 3394 { 3395 if (sp->u.iocb_cmd.u.ctarg.req) { 3396 dma_free_coherent(&vha->hw->pdev->dev, 3397 sizeof(struct ct_sns_pkt), 3398 sp->u.iocb_cmd.u.ctarg.req, 3399 sp->u.iocb_cmd.u.ctarg.req_dma); 3400 sp->u.iocb_cmd.u.ctarg.req = NULL; 3401 } 3402 if (sp->u.iocb_cmd.u.ctarg.rsp) { 3403 dma_free_coherent(&vha->hw->pdev->dev, 3404 sizeof(struct ct_sns_pkt), 3405 sp->u.iocb_cmd.u.ctarg.rsp, 3406 sp->u.iocb_cmd.u.ctarg.rsp_dma); 3407 sp->u.iocb_cmd.u.ctarg.rsp = NULL; 3408 } 3409 3410 sp->free(sp); 3411 } 3412 3413 void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea) 3414 { 3415 fc_port_t *fcport, *conflict, *t; 3416 u16 data[2]; 3417 3418 ql_dbg(ql_dbg_disc, vha, 0xffff, 3419 "%s %d port_id: %06x\n", 3420 __func__, __LINE__, ea->id.b24); 3421 3422 if (ea->rc) { 3423 /* cable is disconnected */ 3424 list_for_each_entry_safe(fcport, t, &vha->vp_fcports, list) { 3425 if (fcport->d_id.b24 == ea->id.b24) { 3426 ql_dbg(ql_dbg_disc, vha, 0xffff, 3427 "%s %d %8phC DS %d\n", 3428 __func__, __LINE__, 3429 fcport->port_name, 3430 fcport->disc_state); 3431 fcport->scan_state = QLA_FCPORT_SCAN; 3432 switch (fcport->disc_state) { 3433 case DSC_DELETED: 3434 case DSC_DELETE_PEND: 3435 break; 3436 default: 3437 ql_dbg(ql_dbg_disc, vha, 0xffff, 3438 "%s %d %8phC post del sess\n", 3439 __func__, __LINE__, 3440 fcport->port_name); 3441 qlt_schedule_sess_for_deletion(fcport); 3442 break; 3443 } 3444 } 3445 } 3446 } else { 3447 /* cable is connected */ 3448 fcport = qla2x00_find_fcport_by_wwpn(vha, ea->port_name, 1); 3449 if (fcport) { 3450 list_for_each_entry_safe(conflict, t, &vha->vp_fcports, 3451 list) { 3452 if ((conflict->d_id.b24 == ea->id.b24) && 3453 (fcport != conflict)) { 3454 /* 2 fcports with conflict Nport ID or 3455 * an existing fcport is having nport ID 3456 * conflict with new fcport. 3457 */ 3458 3459 ql_dbg(ql_dbg_disc, vha, 0xffff, 3460 "%s %d %8phC DS %d\n", 3461 __func__, __LINE__, 3462 conflict->port_name, 3463 conflict->disc_state); 3464 conflict->scan_state = QLA_FCPORT_SCAN; 3465 switch (conflict->disc_state) { 3466 case DSC_DELETED: 3467 case DSC_DELETE_PEND: 3468 break; 3469 default: 3470 ql_dbg(ql_dbg_disc, vha, 0xffff, 3471 "%s %d %8phC post del sess\n", 3472 __func__, __LINE__, 3473 conflict->port_name); 3474 qlt_schedule_sess_for_deletion 3475 (conflict); 3476 break; 3477 } 3478 } 3479 } 3480 3481 fcport->rscn_gen++; 3482 fcport->scan_state = QLA_FCPORT_FOUND; 3483 fcport->flags |= FCF_FABRIC_DEVICE; 3484 switch (fcport->disc_state) { 3485 case DSC_LOGIN_COMPLETE: 3486 /* recheck session is still intact. */ 3487 ql_dbg(ql_dbg_disc, vha, 0x210d, 3488 "%s %d %8phC revalidate session with ADISC\n", 3489 __func__, __LINE__, fcport->port_name); 3490 data[0] = data[1] = 0; 3491 qla2x00_post_async_adisc_work(vha, fcport, 3492 data); 3493 break; 3494 case DSC_DELETED: 3495 ql_dbg(ql_dbg_disc, vha, 0x210d, 3496 "%s %d %8phC login\n", __func__, __LINE__, 3497 fcport->port_name); 3498 fcport->d_id = ea->id; 3499 qla24xx_fcport_handle_login(vha, fcport); 3500 break; 3501 case DSC_DELETE_PEND: 3502 fcport->d_id = ea->id; 3503 break; 3504 default: 3505 fcport->d_id = ea->id; 3506 break; 3507 } 3508 } else { 3509 list_for_each_entry_safe(conflict, t, &vha->vp_fcports, 3510 list) { 3511 if (conflict->d_id.b24 == ea->id.b24) { 3512 /* 2 fcports with conflict Nport ID or 3513 * an existing fcport is having nport ID 3514 * conflict with new fcport. 3515 */ 3516 ql_dbg(ql_dbg_disc, vha, 0xffff, 3517 "%s %d %8phC DS %d\n", 3518 __func__, __LINE__, 3519 conflict->port_name, 3520 conflict->disc_state); 3521 3522 conflict->scan_state = QLA_FCPORT_SCAN; 3523 switch (conflict->disc_state) { 3524 case DSC_DELETED: 3525 case DSC_DELETE_PEND: 3526 break; 3527 default: 3528 ql_dbg(ql_dbg_disc, vha, 0xffff, 3529 "%s %d %8phC post del sess\n", 3530 __func__, __LINE__, 3531 conflict->port_name); 3532 qlt_schedule_sess_for_deletion 3533 (conflict); 3534 break; 3535 } 3536 } 3537 } 3538 3539 /* create new fcport */ 3540 ql_dbg(ql_dbg_disc, vha, 0x2065, 3541 "%s %d %8phC post new sess\n", 3542 __func__, __LINE__, ea->port_name); 3543 qla24xx_post_newsess_work(vha, &ea->id, 3544 ea->port_name, NULL, NULL, FC4_TYPE_UNKNOWN); 3545 } 3546 } 3547 } 3548 3549 static void qla2x00_async_gpnid_sp_done(void *s, int res) 3550 { 3551 struct srb *sp = s; 3552 struct scsi_qla_host *vha = sp->vha; 3553 struct ct_sns_req *ct_req = 3554 (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req; 3555 struct ct_sns_rsp *ct_rsp = 3556 (struct ct_sns_rsp *)sp->u.iocb_cmd.u.ctarg.rsp; 3557 struct event_arg ea; 3558 struct qla_work_evt *e; 3559 unsigned long flags; 3560 3561 if (res) 3562 ql_dbg(ql_dbg_disc, vha, 0x2066, 3563 "Async done-%s fail res %x rscn gen %d ID %3phC. %8phC\n", 3564 sp->name, res, sp->gen1, ct_req->req.port_id.port_id, 3565 ct_rsp->rsp.gpn_id.port_name); 3566 else 3567 ql_dbg(ql_dbg_disc, vha, 0x2066, 3568 "Async done-%s good rscn gen %d ID %3phC. %8phC\n", 3569 sp->name, sp->gen1, ct_req->req.port_id.port_id, 3570 ct_rsp->rsp.gpn_id.port_name); 3571 3572 memset(&ea, 0, sizeof(ea)); 3573 memcpy(ea.port_name, ct_rsp->rsp.gpn_id.port_name, WWN_SIZE); 3574 ea.sp = sp; 3575 ea.id.b.domain = ct_req->req.port_id.port_id[0]; 3576 ea.id.b.area = ct_req->req.port_id.port_id[1]; 3577 ea.id.b.al_pa = ct_req->req.port_id.port_id[2]; 3578 ea.rc = res; 3579 ea.event = FCME_GPNID_DONE; 3580 3581 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); 3582 list_del(&sp->elem); 3583 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); 3584 3585 if (res) { 3586 if (res == QLA_FUNCTION_TIMEOUT) { 3587 qla24xx_post_gpnid_work(sp->vha, &ea.id); 3588 sp->free(sp); 3589 return; 3590 } 3591 } else if (sp->gen1) { 3592 /* There was another RSCN for this Nport ID */ 3593 qla24xx_post_gpnid_work(sp->vha, &ea.id); 3594 sp->free(sp); 3595 return; 3596 } 3597 3598 qla2x00_fcport_event_handler(vha, &ea); 3599 3600 e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP); 3601 if (!e) { 3602 /* please ignore kernel warning. otherwise, we have mem leak. */ 3603 if (sp->u.iocb_cmd.u.ctarg.req) { 3604 dma_free_coherent(&vha->hw->pdev->dev, 3605 sizeof(struct ct_sns_pkt), 3606 sp->u.iocb_cmd.u.ctarg.req, 3607 sp->u.iocb_cmd.u.ctarg.req_dma); 3608 sp->u.iocb_cmd.u.ctarg.req = NULL; 3609 } 3610 if (sp->u.iocb_cmd.u.ctarg.rsp) { 3611 dma_free_coherent(&vha->hw->pdev->dev, 3612 sizeof(struct ct_sns_pkt), 3613 sp->u.iocb_cmd.u.ctarg.rsp, 3614 sp->u.iocb_cmd.u.ctarg.rsp_dma); 3615 sp->u.iocb_cmd.u.ctarg.rsp = NULL; 3616 } 3617 3618 sp->free(sp); 3619 return; 3620 } 3621 3622 e->u.iosb.sp = sp; 3623 qla2x00_post_work(vha, e); 3624 } 3625 3626 /* Get WWPN with Nport ID. */ 3627 int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id) 3628 { 3629 int rval = QLA_FUNCTION_FAILED; 3630 struct ct_sns_req *ct_req; 3631 srb_t *sp, *tsp; 3632 struct ct_sns_pkt *ct_sns; 3633 unsigned long flags; 3634 3635 if (!vha->flags.online) 3636 goto done; 3637 3638 sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); 3639 if (!sp) 3640 goto done; 3641 3642 sp->type = SRB_CT_PTHRU_CMD; 3643 sp->name = "gpnid"; 3644 sp->u.iocb_cmd.u.ctarg.id = *id; 3645 sp->gen1 = 0; 3646 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 3647 3648 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); 3649 list_for_each_entry(tsp, &vha->gpnid_list, elem) { 3650 if (tsp->u.iocb_cmd.u.ctarg.id.b24 == id->b24) { 3651 tsp->gen1++; 3652 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); 3653 sp->free(sp); 3654 goto done; 3655 } 3656 } 3657 list_add_tail(&sp->elem, &vha->gpnid_list); 3658 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); 3659 3660 sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev, 3661 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma, 3662 GFP_KERNEL); 3663 if (!sp->u.iocb_cmd.u.ctarg.req) { 3664 ql_log(ql_log_warn, vha, 0xd041, 3665 "Failed to allocate ct_sns request.\n"); 3666 goto done_free_sp; 3667 } 3668 3669 sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev, 3670 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma, 3671 GFP_KERNEL); 3672 if (!sp->u.iocb_cmd.u.ctarg.rsp) { 3673 ql_log(ql_log_warn, vha, 0xd042, 3674 "Failed to allocate ct_sns request.\n"); 3675 goto done_free_sp; 3676 } 3677 3678 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp; 3679 memset(ct_sns, 0, sizeof(*ct_sns)); 3680 3681 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; 3682 /* CT_IU preamble */ 3683 ct_req = qla2x00_prep_ct_req(ct_sns, GPN_ID_CMD, GPN_ID_RSP_SIZE); 3684 3685 /* GPN_ID req */ 3686 ct_req->req.port_id.port_id[0] = id->b.domain; 3687 ct_req->req.port_id.port_id[1] = id->b.area; 3688 ct_req->req.port_id.port_id[2] = id->b.al_pa; 3689 3690 sp->u.iocb_cmd.u.ctarg.req_size = GPN_ID_REQ_SIZE; 3691 sp->u.iocb_cmd.u.ctarg.rsp_size = GPN_ID_RSP_SIZE; 3692 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 3693 3694 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 3695 sp->done = qla2x00_async_gpnid_sp_done; 3696 3697 rval = qla2x00_start_sp(sp); 3698 if (rval != QLA_SUCCESS) 3699 goto done_free_sp; 3700 3701 ql_dbg(ql_dbg_disc, vha, 0x2067, 3702 "Async-%s hdl=%x ID %3phC.\n", sp->name, 3703 sp->handle, ct_req->req.port_id.port_id); 3704 return rval; 3705 3706 done_free_sp: 3707 if (sp->u.iocb_cmd.u.ctarg.req) { 3708 dma_free_coherent(&vha->hw->pdev->dev, 3709 sizeof(struct ct_sns_pkt), 3710 sp->u.iocb_cmd.u.ctarg.req, 3711 sp->u.iocb_cmd.u.ctarg.req_dma); 3712 sp->u.iocb_cmd.u.ctarg.req = NULL; 3713 } 3714 if (sp->u.iocb_cmd.u.ctarg.rsp) { 3715 dma_free_coherent(&vha->hw->pdev->dev, 3716 sizeof(struct ct_sns_pkt), 3717 sp->u.iocb_cmd.u.ctarg.rsp, 3718 sp->u.iocb_cmd.u.ctarg.rsp_dma); 3719 sp->u.iocb_cmd.u.ctarg.rsp = NULL; 3720 } 3721 3722 sp->free(sp); 3723 done: 3724 return rval; 3725 } 3726 3727 void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea) 3728 { 3729 fc_port_t *fcport = ea->fcport; 3730 3731 qla24xx_post_gnl_work(vha, fcport); 3732 } 3733 3734 void qla24xx_async_gffid_sp_done(void *s, int res) 3735 { 3736 struct srb *sp = s; 3737 struct scsi_qla_host *vha = sp->vha; 3738 fc_port_t *fcport = sp->fcport; 3739 struct ct_sns_rsp *ct_rsp; 3740 struct event_arg ea; 3741 3742 ql_dbg(ql_dbg_disc, vha, 0x2133, 3743 "Async done-%s res %x ID %x. %8phC\n", 3744 sp->name, res, fcport->d_id.b24, fcport->port_name); 3745 3746 fcport->flags &= ~FCF_ASYNC_SENT; 3747 ct_rsp = &fcport->ct_desc.ct_sns->p.rsp; 3748 /* 3749 * FC-GS-7, 5.2.3.12 FC-4 Features - format 3750 * The format of the FC-4 Features object, as defined by the FC-4, 3751 * Shall be an array of 4-bit values, one for each type code value 3752 */ 3753 if (!res) { 3754 if (ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET] & 0xf) { 3755 /* w1 b00:03 */ 3756 fcport->fc4_type = 3757 ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET]; 3758 fcport->fc4_type &= 0xf; 3759 } 3760 3761 if (ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET] & 0xf) { 3762 /* w5 [00:03]/28h */ 3763 fcport->fc4f_nvme = 3764 ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET]; 3765 fcport->fc4f_nvme &= 0xf; 3766 } 3767 } 3768 3769 memset(&ea, 0, sizeof(ea)); 3770 ea.sp = sp; 3771 ea.fcport = sp->fcport; 3772 ea.rc = res; 3773 ea.event = FCME_GFFID_DONE; 3774 3775 qla2x00_fcport_event_handler(vha, &ea); 3776 sp->free(sp); 3777 } 3778 3779 /* Get FC4 Feature with Nport ID. */ 3780 int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport) 3781 { 3782 int rval = QLA_FUNCTION_FAILED; 3783 struct ct_sns_req *ct_req; 3784 srb_t *sp; 3785 3786 if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) 3787 return rval; 3788 3789 sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); 3790 if (!sp) 3791 return rval; 3792 3793 fcport->flags |= FCF_ASYNC_SENT; 3794 sp->type = SRB_CT_PTHRU_CMD; 3795 sp->name = "gffid"; 3796 sp->gen1 = fcport->rscn_gen; 3797 sp->gen2 = fcport->login_gen; 3798 3799 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 3800 3801 /* CT_IU preamble */ 3802 ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFF_ID_CMD, 3803 GFF_ID_RSP_SIZE); 3804 3805 ct_req->req.gff_id.port_id[0] = fcport->d_id.b.domain; 3806 ct_req->req.gff_id.port_id[1] = fcport->d_id.b.area; 3807 ct_req->req.gff_id.port_id[2] = fcport->d_id.b.al_pa; 3808 3809 sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns; 3810 sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma; 3811 sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns; 3812 sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma; 3813 sp->u.iocb_cmd.u.ctarg.req_size = GFF_ID_REQ_SIZE; 3814 sp->u.iocb_cmd.u.ctarg.rsp_size = GFF_ID_RSP_SIZE; 3815 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 3816 3817 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 3818 sp->done = qla24xx_async_gffid_sp_done; 3819 3820 rval = qla2x00_start_sp(sp); 3821 if (rval != QLA_SUCCESS) 3822 goto done_free_sp; 3823 3824 ql_dbg(ql_dbg_disc, vha, 0x2132, 3825 "Async-%s hdl=%x %8phC.\n", sp->name, 3826 sp->handle, fcport->port_name); 3827 3828 return rval; 3829 done_free_sp: 3830 sp->free(sp); 3831 fcport->flags &= ~FCF_ASYNC_SENT; 3832 return rval; 3833 } 3834 3835 /* GPN_FT + GNN_FT*/ 3836 static int qla2x00_is_a_vp(scsi_qla_host_t *vha, u64 wwn) 3837 { 3838 struct qla_hw_data *ha = vha->hw; 3839 scsi_qla_host_t *vp; 3840 unsigned long flags; 3841 u64 twwn; 3842 int rc = 0; 3843 3844 if (!ha->num_vhosts) 3845 return 0; 3846 3847 spin_lock_irqsave(&ha->vport_slock, flags); 3848 list_for_each_entry(vp, &ha->vp_list, list) { 3849 twwn = wwn_to_u64(vp->port_name); 3850 if (wwn == twwn) { 3851 rc = 1; 3852 break; 3853 } 3854 } 3855 spin_unlock_irqrestore(&ha->vport_slock, flags); 3856 3857 return rc; 3858 } 3859 3860 void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) 3861 { 3862 fc_port_t *fcport; 3863 u32 i, rc; 3864 bool found; 3865 u8 fc4type = sp->gen2; 3866 struct fab_scan_rp *rp; 3867 unsigned long flags; 3868 3869 ql_dbg(ql_dbg_disc, vha, 0xffff, 3870 "%s enter\n", __func__); 3871 3872 if (sp->gen1 != vha->hw->base_qpair->chip_reset) { 3873 ql_dbg(ql_dbg_disc, vha, 0xffff, 3874 "%s scan stop due to chip reset %x/%x\n", 3875 sp->name, sp->gen1, vha->hw->base_qpair->chip_reset); 3876 goto out; 3877 } 3878 3879 rc = sp->rc; 3880 if (rc) { 3881 vha->scan.scan_retry++; 3882 if (vha->scan.scan_retry < MAX_SCAN_RETRIES) { 3883 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); 3884 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); 3885 } else { 3886 ql_dbg(ql_dbg_disc, vha, 0xffff, 3887 "Fabric scan failed on all retries.\n"); 3888 } 3889 goto out; 3890 } 3891 vha->scan.scan_retry = 0; 3892 3893 list_for_each_entry(fcport, &vha->vp_fcports, list) 3894 fcport->scan_state = QLA_FCPORT_SCAN; 3895 3896 for (i = 0; i < vha->hw->max_fibre_devices; i++) { 3897 u64 wwn; 3898 3899 rp = &vha->scan.l[i]; 3900 found = false; 3901 3902 wwn = wwn_to_u64(rp->port_name); 3903 if (wwn == 0) 3904 continue; 3905 3906 if (!memcmp(rp->port_name, vha->port_name, WWN_SIZE)) 3907 continue; 3908 3909 /* Bypass reserved domain fields. */ 3910 if ((rp->id.b.domain & 0xf0) == 0xf0) 3911 continue; 3912 3913 /* Bypass virtual ports of the same host. */ 3914 if (qla2x00_is_a_vp(vha, wwn)) 3915 continue; 3916 3917 list_for_each_entry(fcport, &vha->vp_fcports, list) { 3918 if (memcmp(rp->port_name, fcport->port_name, WWN_SIZE)) 3919 continue; 3920 fcport->scan_state = QLA_FCPORT_FOUND; 3921 fcport->d_id.b24 = rp->id.b24; 3922 found = true; 3923 /* 3924 * If device was not a fabric device before. 3925 */ 3926 if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) { 3927 qla2x00_clear_loop_id(fcport); 3928 fcport->flags |= FCF_FABRIC_DEVICE; 3929 } 3930 break; 3931 } 3932 3933 if (!found) { 3934 ql_dbg(ql_dbg_disc, vha, 0xffff, 3935 "%s %d %8phC post new sess\n", 3936 __func__, __LINE__, rp->port_name); 3937 qla24xx_post_newsess_work(vha, &rp->id, rp->port_name, 3938 rp->node_name, NULL, fc4type); 3939 } 3940 } 3941 3942 /* 3943 * Logout all previous fabric dev marked lost, except FCP2 devices. 3944 */ 3945 list_for_each_entry(fcport, &vha->vp_fcports, list) { 3946 if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) 3947 continue; 3948 3949 if (fcport->scan_state != QLA_FCPORT_FOUND) { 3950 if ((qla_dual_mode_enabled(vha) || 3951 qla_ini_mode_enabled(vha)) && 3952 atomic_read(&fcport->state) == FCS_ONLINE) { 3953 qla2x00_mark_device_lost(vha, fcport, 3954 ql2xplogiabsentdevice, 0); 3955 3956 if (fcport->loop_id != FC_NO_LOOP_ID && 3957 (fcport->flags & FCF_FCP2_DEVICE) == 0) { 3958 ql_dbg(ql_dbg_disc, vha, 0x20f0, 3959 "%s %d %8phC post del sess\n", 3960 __func__, __LINE__, 3961 fcport->port_name); 3962 3963 qlt_schedule_sess_for_deletion(fcport); 3964 continue; 3965 } 3966 } 3967 } else 3968 qla24xx_fcport_handle_login(vha, fcport); 3969 } 3970 3971 out: 3972 qla24xx_sp_unmap(vha, sp); 3973 spin_lock_irqsave(&vha->work_lock, flags); 3974 vha->scan.scan_flags &= ~SF_SCANNING; 3975 spin_unlock_irqrestore(&vha->work_lock, flags); 3976 3977 if ((fc4type == FC4_TYPE_FCP_SCSI) && vha->flags.nvme_enabled) 3978 qla24xx_async_gpnft(vha, FC4_TYPE_NVME); 3979 } 3980 3981 static void qla2x00_async_gpnft_gnnft_sp_done(void *s, int res) 3982 { 3983 struct srb *sp = s; 3984 struct scsi_qla_host *vha = sp->vha; 3985 struct qla_work_evt *e; 3986 struct ct_sns_req *ct_req = 3987 (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req; 3988 struct ct_sns_gpnft_rsp *ct_rsp = 3989 (struct ct_sns_gpnft_rsp *)sp->u.iocb_cmd.u.ctarg.rsp; 3990 struct ct_sns_gpn_ft_data *d; 3991 struct fab_scan_rp *rp; 3992 int i, j, k; 3993 u16 cmd = be16_to_cpu(ct_req->command); 3994 3995 /* gen2 field is holding the fc4type */ 3996 ql_dbg(ql_dbg_disc, vha, 0xffff, 3997 "Async done-%s res %x FC4Type %x\n", 3998 sp->name, res, sp->gen2); 3999 4000 if (res) { 4001 unsigned long flags; 4002 4003 sp->free(sp); 4004 spin_lock_irqsave(&vha->work_lock, flags); 4005 vha->scan.scan_flags &= ~SF_SCANNING; 4006 vha->scan.scan_retry++; 4007 spin_unlock_irqrestore(&vha->work_lock, flags); 4008 4009 if (vha->scan.scan_retry < MAX_SCAN_RETRIES) { 4010 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); 4011 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); 4012 qla2xxx_wake_dpc(vha); 4013 } else { 4014 ql_dbg(ql_dbg_disc, sp->vha, 0xffff, 4015 "Async done-%s rescan failed on all retries\n", 4016 sp->name); 4017 } 4018 return; 4019 } 4020 4021 if (!res) { 4022 port_id_t id; 4023 u64 wwn; 4024 4025 j = 0; 4026 for (i = 0; i < vha->hw->max_fibre_devices; i++) { 4027 d = &ct_rsp->entries[i]; 4028 4029 id.b.rsvd_1 = 0; 4030 id.b.domain = d->port_id[0]; 4031 id.b.area = d->port_id[1]; 4032 id.b.al_pa = d->port_id[2]; 4033 wwn = wwn_to_u64(d->port_name); 4034 4035 if (id.b24 == 0 || wwn == 0) 4036 continue; 4037 4038 if (cmd == GPN_FT_CMD) { 4039 rp = &vha->scan.l[j]; 4040 rp->id = id; 4041 memcpy(rp->port_name, d->port_name, 8); 4042 j++; 4043 } else {/* GNN_FT_CMD */ 4044 for (k = 0; k < vha->hw->max_fibre_devices; 4045 k++) { 4046 rp = &vha->scan.l[k]; 4047 if (id.b24 == rp->id.b24) { 4048 memcpy(rp->node_name, 4049 d->port_name, 8); 4050 break; 4051 } 4052 } 4053 } 4054 } 4055 } 4056 4057 if (cmd == GPN_FT_CMD) 4058 e = qla2x00_alloc_work(vha, QLA_EVT_GPNFT_DONE); 4059 else 4060 e = qla2x00_alloc_work(vha, QLA_EVT_GNNFT_DONE); 4061 if (!e) { 4062 /* please ignore kernel warning. Otherwise, we have mem leak. */ 4063 if (sp->u.iocb_cmd.u.ctarg.req) { 4064 dma_free_coherent(&vha->hw->pdev->dev, 4065 sizeof(struct ct_sns_pkt), 4066 sp->u.iocb_cmd.u.ctarg.req, 4067 sp->u.iocb_cmd.u.ctarg.req_dma); 4068 sp->u.iocb_cmd.u.ctarg.req = NULL; 4069 } 4070 if (sp->u.iocb_cmd.u.ctarg.rsp) { 4071 dma_free_coherent(&vha->hw->pdev->dev, 4072 sizeof(struct ct_sns_pkt), 4073 sp->u.iocb_cmd.u.ctarg.rsp, 4074 sp->u.iocb_cmd.u.ctarg.rsp_dma); 4075 sp->u.iocb_cmd.u.ctarg.rsp = NULL; 4076 } 4077 4078 ql_dbg(ql_dbg_disc, vha, 0xffff, 4079 "Async done-%s unable to alloc work element\n", 4080 sp->name); 4081 sp->free(sp); 4082 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); 4083 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); 4084 return; 4085 } 4086 4087 sp->rc = res; 4088 e->u.iosb.sp = sp; 4089 4090 qla2x00_post_work(vha, e); 4091 } 4092 4093 /* 4094 * Get WWNN list for fc4_type 4095 * 4096 * It is assumed the same SRB is re-used from GPNFT to avoid 4097 * mem free & re-alloc 4098 */ 4099 static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp, 4100 u8 fc4_type) 4101 { 4102 int rval = QLA_FUNCTION_FAILED; 4103 struct ct_sns_req *ct_req; 4104 struct ct_sns_pkt *ct_sns; 4105 4106 if (!vha->flags.online) { 4107 vha->scan.scan_flags &= ~SF_SCANNING; 4108 goto done_free_sp; 4109 } 4110 4111 if (!sp->u.iocb_cmd.u.ctarg.req || !sp->u.iocb_cmd.u.ctarg.rsp) { 4112 ql_log(ql_log_warn, vha, 0xffff, 4113 "%s: req %p rsp %p are not setup\n", 4114 __func__, sp->u.iocb_cmd.u.ctarg.req, 4115 sp->u.iocb_cmd.u.ctarg.rsp); 4116 vha->scan.scan_flags &= ~SF_SCANNING; 4117 WARN_ON(1); 4118 goto done_free_sp; 4119 } 4120 sp->type = SRB_CT_PTHRU_CMD; 4121 sp->name = "gnnft"; 4122 sp->gen1 = vha->hw->base_qpair->chip_reset; 4123 sp->gen2 = fc4_type; 4124 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 4125 4126 memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size); 4127 memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size); 4128 4129 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; 4130 /* CT_IU preamble */ 4131 ct_req = qla2x00_prep_ct_req(ct_sns, GNN_FT_CMD, 4132 sp->u.iocb_cmd.u.ctarg.rsp_size); 4133 4134 /* GPN_FT req */ 4135 ct_req->req.gpn_ft.port_type = fc4_type; 4136 4137 sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE; 4138 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 4139 4140 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 4141 sp->done = qla2x00_async_gpnft_gnnft_sp_done; 4142 4143 rval = qla2x00_start_sp(sp); 4144 if (rval != QLA_SUCCESS) 4145 goto done_free_sp; 4146 4147 ql_dbg(ql_dbg_disc, vha, 0xffff, 4148 "Async-%s hdl=%x FC4Type %x.\n", sp->name, 4149 sp->handle, ct_req->req.gpn_ft.port_type); 4150 return rval; 4151 4152 done_free_sp: 4153 if (sp->u.iocb_cmd.u.ctarg.req) { 4154 dma_free_coherent(&vha->hw->pdev->dev, 4155 sizeof(struct ct_sns_pkt), 4156 sp->u.iocb_cmd.u.ctarg.req, 4157 sp->u.iocb_cmd.u.ctarg.req_dma); 4158 sp->u.iocb_cmd.u.ctarg.req = NULL; 4159 } 4160 if (sp->u.iocb_cmd.u.ctarg.rsp) { 4161 dma_free_coherent(&vha->hw->pdev->dev, 4162 sizeof(struct ct_sns_pkt), 4163 sp->u.iocb_cmd.u.ctarg.rsp, 4164 sp->u.iocb_cmd.u.ctarg.rsp_dma); 4165 sp->u.iocb_cmd.u.ctarg.rsp = NULL; 4166 } 4167 4168 sp->free(sp); 4169 4170 return rval; 4171 } /* GNNFT */ 4172 4173 void qla24xx_async_gpnft_done(scsi_qla_host_t *vha, srb_t *sp) 4174 { 4175 ql_dbg(ql_dbg_disc, vha, 0xffff, 4176 "%s enter\n", __func__); 4177 del_timer(&sp->u.iocb_cmd.timer); 4178 qla24xx_async_gnnft(vha, sp, sp->gen2); 4179 } 4180 4181 /* Get WWPN list for certain fc4_type */ 4182 int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type) 4183 { 4184 int rval = QLA_FUNCTION_FAILED; 4185 struct ct_sns_req *ct_req; 4186 srb_t *sp; 4187 struct ct_sns_pkt *ct_sns; 4188 u32 rspsz; 4189 unsigned long flags; 4190 4191 if (!vha->flags.online) 4192 return rval; 4193 4194 spin_lock_irqsave(&vha->work_lock, flags); 4195 if (vha->scan.scan_flags & SF_SCANNING) { 4196 spin_unlock_irqrestore(&vha->work_lock, flags); 4197 ql_dbg(ql_dbg_disc, vha, 0xffff, "scan active\n"); 4198 return rval; 4199 } 4200 vha->scan.scan_flags |= SF_SCANNING; 4201 spin_unlock_irqrestore(&vha->work_lock, flags); 4202 4203 sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); 4204 if (!sp) { 4205 vha->scan.scan_flags &= ~SF_SCANNING; 4206 return rval; 4207 } 4208 4209 sp->type = SRB_CT_PTHRU_CMD; 4210 sp->name = "gpnft"; 4211 sp->gen1 = vha->hw->base_qpair->chip_reset; 4212 sp->gen2 = fc4_type; 4213 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 4214 4215 sp->u.iocb_cmd.u.ctarg.req = dma_zalloc_coherent(&vha->hw->pdev->dev, 4216 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma, 4217 GFP_KERNEL); 4218 if (!sp->u.iocb_cmd.u.ctarg.req) { 4219 ql_log(ql_log_warn, vha, 0xffff, 4220 "Failed to allocate ct_sns request.\n"); 4221 vha->scan.scan_flags &= ~SF_SCANNING; 4222 goto done_free_sp; 4223 } 4224 4225 rspsz = sizeof(struct ct_sns_gpnft_rsp) + 4226 ((vha->hw->max_fibre_devices - 1) * 4227 sizeof(struct ct_sns_gpn_ft_data)); 4228 4229 sp->u.iocb_cmd.u.ctarg.rsp = dma_zalloc_coherent(&vha->hw->pdev->dev, 4230 rspsz, &sp->u.iocb_cmd.u.ctarg.rsp_dma, GFP_KERNEL); 4231 if (!sp->u.iocb_cmd.u.ctarg.rsp) { 4232 ql_log(ql_log_warn, vha, 0xffff, 4233 "Failed to allocate ct_sns request.\n"); 4234 vha->scan.scan_flags &= ~SF_SCANNING; 4235 goto done_free_sp; 4236 } 4237 4238 memset(vha->scan.l, 0, vha->scan.size); 4239 4240 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; 4241 /* CT_IU preamble */ 4242 ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz); 4243 4244 /* GPN_FT req */ 4245 ct_req->req.gpn_ft.port_type = fc4_type; 4246 4247 sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE; 4248 sp->u.iocb_cmd.u.ctarg.rsp_size = rspsz; 4249 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 4250 4251 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 4252 sp->done = qla2x00_async_gpnft_gnnft_sp_done; 4253 4254 rval = qla2x00_start_sp(sp); 4255 if (rval != QLA_SUCCESS) { 4256 vha->scan.scan_flags &= ~SF_SCANNING; 4257 goto done_free_sp; 4258 } 4259 4260 ql_dbg(ql_dbg_disc, vha, 0xffff, 4261 "Async-%s hdl=%x FC4Type %x.\n", sp->name, 4262 sp->handle, ct_req->req.gpn_ft.port_type); 4263 return rval; 4264 4265 done_free_sp: 4266 if (sp->u.iocb_cmd.u.ctarg.req) { 4267 dma_free_coherent(&vha->hw->pdev->dev, 4268 sizeof(struct ct_sns_pkt), 4269 sp->u.iocb_cmd.u.ctarg.req, 4270 sp->u.iocb_cmd.u.ctarg.req_dma); 4271 sp->u.iocb_cmd.u.ctarg.req = NULL; 4272 } 4273 if (sp->u.iocb_cmd.u.ctarg.rsp) { 4274 dma_free_coherent(&vha->hw->pdev->dev, 4275 sizeof(struct ct_sns_pkt), 4276 sp->u.iocb_cmd.u.ctarg.rsp, 4277 sp->u.iocb_cmd.u.ctarg.rsp_dma); 4278 sp->u.iocb_cmd.u.ctarg.rsp = NULL; 4279 } 4280 4281 sp->free(sp); 4282 4283 return rval; 4284 } 4285 4286 void qla_scan_work_fn(struct work_struct *work) 4287 { 4288 struct fab_scan *s = container_of(to_delayed_work(work), 4289 struct fab_scan, scan_work); 4290 struct scsi_qla_host *vha = container_of(s, struct scsi_qla_host, 4291 scan); 4292 unsigned long flags; 4293 4294 ql_dbg(ql_dbg_disc, vha, 0xffff, 4295 "%s: schedule loop resync\n", __func__); 4296 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); 4297 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); 4298 qla2xxx_wake_dpc(vha); 4299 spin_lock_irqsave(&vha->work_lock, flags); 4300 vha->scan.scan_flags &= ~SF_QUEUED; 4301 spin_unlock_irqrestore(&vha->work_lock, flags); 4302 } 4303 4304 /* GNN_ID */ 4305 void qla24xx_handle_gnnid_event(scsi_qla_host_t *vha, struct event_arg *ea) 4306 { 4307 qla24xx_post_gnl_work(vha, ea->fcport); 4308 } 4309 4310 static void qla2x00_async_gnnid_sp_done(void *s, int res) 4311 { 4312 struct srb *sp = s; 4313 struct scsi_qla_host *vha = sp->vha; 4314 fc_port_t *fcport = sp->fcport; 4315 u8 *node_name = fcport->ct_desc.ct_sns->p.rsp.rsp.gnn_id.node_name; 4316 struct event_arg ea; 4317 u64 wwnn; 4318 4319 fcport->flags &= ~FCF_ASYNC_SENT; 4320 wwnn = wwn_to_u64(node_name); 4321 if (wwnn) 4322 memcpy(fcport->node_name, node_name, WWN_SIZE); 4323 4324 memset(&ea, 0, sizeof(ea)); 4325 ea.fcport = fcport; 4326 ea.sp = sp; 4327 ea.rc = res; 4328 ea.event = FCME_GNNID_DONE; 4329 4330 ql_dbg(ql_dbg_disc, vha, 0x204f, 4331 "Async done-%s res %x, WWPN %8phC %8phC\n", 4332 sp->name, res, fcport->port_name, fcport->node_name); 4333 4334 qla2x00_fcport_event_handler(vha, &ea); 4335 4336 sp->free(sp); 4337 } 4338 4339 int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport) 4340 { 4341 int rval = QLA_FUNCTION_FAILED; 4342 struct ct_sns_req *ct_req; 4343 srb_t *sp; 4344 4345 if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) 4346 return rval; 4347 4348 fcport->disc_state = DSC_GNN_ID; 4349 sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC); 4350 if (!sp) 4351 goto done; 4352 4353 fcport->flags |= FCF_ASYNC_SENT; 4354 sp->type = SRB_CT_PTHRU_CMD; 4355 sp->name = "gnnid"; 4356 sp->gen1 = fcport->rscn_gen; 4357 sp->gen2 = fcport->login_gen; 4358 4359 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 4360 4361 /* CT_IU preamble */ 4362 ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GNN_ID_CMD, 4363 GNN_ID_RSP_SIZE); 4364 4365 /* GNN_ID req */ 4366 ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain; 4367 ct_req->req.port_id.port_id[1] = fcport->d_id.b.area; 4368 ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa; 4369 4370 4371 /* req & rsp use the same buffer */ 4372 sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns; 4373 sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma; 4374 sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns; 4375 sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma; 4376 sp->u.iocb_cmd.u.ctarg.req_size = GNN_ID_REQ_SIZE; 4377 sp->u.iocb_cmd.u.ctarg.rsp_size = GNN_ID_RSP_SIZE; 4378 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 4379 4380 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 4381 sp->done = qla2x00_async_gnnid_sp_done; 4382 4383 rval = qla2x00_start_sp(sp); 4384 if (rval != QLA_SUCCESS) 4385 goto done_free_sp; 4386 ql_dbg(ql_dbg_disc, vha, 0xffff, 4387 "Async-%s - %8phC hdl=%x loopid=%x portid %06x.\n", 4388 sp->name, fcport->port_name, 4389 sp->handle, fcport->loop_id, fcport->d_id.b24); 4390 return rval; 4391 4392 done_free_sp: 4393 sp->free(sp); 4394 fcport->flags &= ~FCF_ASYNC_SENT; 4395 done: 4396 return rval; 4397 } 4398 4399 int qla24xx_post_gnnid_work(struct scsi_qla_host *vha, fc_port_t *fcport) 4400 { 4401 struct qla_work_evt *e; 4402 int ls; 4403 4404 ls = atomic_read(&vha->loop_state); 4405 if (((ls != LOOP_READY) && (ls != LOOP_UP)) || 4406 test_bit(UNLOADING, &vha->dpc_flags)) 4407 return 0; 4408 4409 e = qla2x00_alloc_work(vha, QLA_EVT_GNNID); 4410 if (!e) 4411 return QLA_FUNCTION_FAILED; 4412 4413 e->u.fcport.fcport = fcport; 4414 return qla2x00_post_work(vha, e); 4415 } 4416 4417 /* GPFN_ID */ 4418 void qla24xx_handle_gfpnid_event(scsi_qla_host_t *vha, struct event_arg *ea) 4419 { 4420 fc_port_t *fcport = ea->fcport; 4421 4422 ql_dbg(ql_dbg_disc, vha, 0xffff, 4423 "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d fcpcnt %d\n", 4424 __func__, fcport->port_name, fcport->disc_state, 4425 fcport->fw_login_state, ea->rc, fcport->login_gen, ea->sp->gen2, 4426 fcport->rscn_gen, ea->sp->gen1, vha->fcport_count); 4427 4428 if (fcport->disc_state == DSC_DELETE_PEND) 4429 return; 4430 4431 if (ea->sp->gen2 != fcport->login_gen) { 4432 /* target side must have changed it. */ 4433 ql_dbg(ql_dbg_disc, vha, 0x20d3, 4434 "%s %8phC generation changed\n", 4435 __func__, fcport->port_name); 4436 return; 4437 } else if (ea->sp->gen1 != fcport->rscn_gen) { 4438 ql_dbg(ql_dbg_disc, vha, 0x20d4, "%s %d %8phC post gidpn\n", 4439 __func__, __LINE__, fcport->port_name); 4440 qla24xx_post_gidpn_work(vha, fcport); 4441 return; 4442 } 4443 4444 qla24xx_post_gpsc_work(vha, fcport); 4445 } 4446 4447 static void qla2x00_async_gfpnid_sp_done(void *s, int res) 4448 { 4449 struct srb *sp = s; 4450 struct scsi_qla_host *vha = sp->vha; 4451 fc_port_t *fcport = sp->fcport; 4452 u8 *fpn = fcport->ct_desc.ct_sns->p.rsp.rsp.gfpn_id.port_name; 4453 struct event_arg ea; 4454 u64 wwn; 4455 4456 fcport->flags &= ~FCF_ASYNC_SENT; 4457 wwn = wwn_to_u64(fpn); 4458 if (wwn) 4459 memcpy(fcport->fabric_port_name, fpn, WWN_SIZE); 4460 4461 memset(&ea, 0, sizeof(ea)); 4462 ea.fcport = fcport; 4463 ea.sp = sp; 4464 ea.rc = res; 4465 ea.event = FCME_GFPNID_DONE; 4466 4467 ql_dbg(ql_dbg_disc, vha, 0x204f, 4468 "Async done-%s res %x, WWPN %8phC %8phC\n", 4469 sp->name, res, fcport->port_name, fcport->fabric_port_name); 4470 4471 qla2x00_fcport_event_handler(vha, &ea); 4472 4473 sp->free(sp); 4474 } 4475 4476 int qla24xx_async_gfpnid(scsi_qla_host_t *vha, fc_port_t *fcport) 4477 { 4478 int rval = QLA_FUNCTION_FAILED; 4479 struct ct_sns_req *ct_req; 4480 srb_t *sp; 4481 4482 if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) 4483 return rval; 4484 4485 fcport->disc_state = DSC_GFPN_ID; 4486 sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC); 4487 if (!sp) 4488 goto done; 4489 4490 fcport->flags |= FCF_ASYNC_SENT; 4491 sp->type = SRB_CT_PTHRU_CMD; 4492 sp->name = "gfpnid"; 4493 sp->gen1 = fcport->rscn_gen; 4494 sp->gen2 = fcport->login_gen; 4495 4496 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 4497 4498 /* CT_IU preamble */ 4499 ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFPN_ID_CMD, 4500 GFPN_ID_RSP_SIZE); 4501 4502 /* GFPN_ID req */ 4503 ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain; 4504 ct_req->req.port_id.port_id[1] = fcport->d_id.b.area; 4505 ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa; 4506 4507 4508 /* req & rsp use the same buffer */ 4509 sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns; 4510 sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma; 4511 sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns; 4512 sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma; 4513 sp->u.iocb_cmd.u.ctarg.req_size = GFPN_ID_REQ_SIZE; 4514 sp->u.iocb_cmd.u.ctarg.rsp_size = GFPN_ID_RSP_SIZE; 4515 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 4516 4517 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 4518 sp->done = qla2x00_async_gfpnid_sp_done; 4519 4520 rval = qla2x00_start_sp(sp); 4521 if (rval != QLA_SUCCESS) 4522 goto done_free_sp; 4523 4524 ql_dbg(ql_dbg_disc, vha, 0xffff, 4525 "Async-%s - %8phC hdl=%x loopid=%x portid %06x.\n", 4526 sp->name, fcport->port_name, 4527 sp->handle, fcport->loop_id, fcport->d_id.b24); 4528 return rval; 4529 4530 done_free_sp: 4531 sp->free(sp); 4532 fcport->flags &= ~FCF_ASYNC_SENT; 4533 done: 4534 return rval; 4535 } 4536 4537 int qla24xx_post_gfpnid_work(struct scsi_qla_host *vha, fc_port_t *fcport) 4538 { 4539 struct qla_work_evt *e; 4540 int ls; 4541 4542 ls = atomic_read(&vha->loop_state); 4543 if (((ls != LOOP_READY) && (ls != LOOP_UP)) || 4544 test_bit(UNLOADING, &vha->dpc_flags)) 4545 return 0; 4546 4547 e = qla2x00_alloc_work(vha, QLA_EVT_GFPNID); 4548 if (!e) 4549 return QLA_FUNCTION_FAILED; 4550 4551 e->u.fcport.fcport = fcport; 4552 return qla2x00_post_work(vha, e); 4553 } 4554