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