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