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