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