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