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