1 /** 2 * Copyright (C) 2005 - 2011 Emulex 3 * All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License version 2 7 * as published by the Free Software Foundation. The full GNU General 8 * Public License is included in this distribution in the file called COPYING. 9 * 10 * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com) 11 * 12 * Contact Information: 13 * linux-drivers@emulex.com 14 * 15 * Emulex 16 * 3333 Susan Street 17 * Costa Mesa, CA 92626 18 */ 19 20 #include <linux/bsg-lib.h> 21 #include <scsi/scsi_transport_iscsi.h> 22 #include <scsi/scsi_bsg_iscsi.h> 23 #include "be_mgmt.h" 24 #include "be_iscsi.h" 25 26 /** 27 * mgmt_reopen_session()- Reopen a session based on reopen_type 28 * @phba: Device priv structure instance 29 * @reopen_type: Type of reopen_session FW should do. 30 * @sess_handle: Session Handle of the session to be re-opened 31 * 32 * return 33 * the TAG used for MBOX Command 34 * 35 **/ 36 unsigned int mgmt_reopen_session(struct beiscsi_hba *phba, 37 unsigned int reopen_type, 38 unsigned int sess_handle) 39 { 40 struct be_ctrl_info *ctrl = &phba->ctrl; 41 struct be_mcc_wrb *wrb; 42 struct be_cmd_reopen_session_req *req; 43 unsigned int tag = 0; 44 45 beiscsi_log(phba, KERN_INFO, 46 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 47 "BG_%d : In bescsi_get_boot_target\n"); 48 49 spin_lock(&ctrl->mbox_lock); 50 tag = alloc_mcc_tag(phba); 51 if (!tag) { 52 spin_unlock(&ctrl->mbox_lock); 53 return tag; 54 } 55 56 wrb = wrb_from_mccq(phba); 57 req = embedded_payload(wrb); 58 wrb->tag0 |= tag; 59 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 60 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, 61 OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS, 62 sizeof(struct be_cmd_reopen_session_resp)); 63 64 /* set the reopen_type,sess_handle */ 65 req->reopen_type = reopen_type; 66 req->session_handle = sess_handle; 67 68 be_mcc_notify(phba); 69 spin_unlock(&ctrl->mbox_lock); 70 return tag; 71 } 72 73 unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba) 74 { 75 struct be_ctrl_info *ctrl = &phba->ctrl; 76 struct be_mcc_wrb *wrb; 77 struct be_cmd_get_boot_target_req *req; 78 unsigned int tag = 0; 79 80 beiscsi_log(phba, KERN_INFO, 81 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 82 "BG_%d : In bescsi_get_boot_target\n"); 83 84 spin_lock(&ctrl->mbox_lock); 85 tag = alloc_mcc_tag(phba); 86 if (!tag) { 87 spin_unlock(&ctrl->mbox_lock); 88 return tag; 89 } 90 91 wrb = wrb_from_mccq(phba); 92 req = embedded_payload(wrb); 93 wrb->tag0 |= tag; 94 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 95 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, 96 OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET, 97 sizeof(struct be_cmd_get_boot_target_resp)); 98 99 be_mcc_notify(phba); 100 spin_unlock(&ctrl->mbox_lock); 101 return tag; 102 } 103 104 unsigned int mgmt_get_session_info(struct beiscsi_hba *phba, 105 u32 boot_session_handle, 106 struct be_dma_mem *nonemb_cmd) 107 { 108 struct be_ctrl_info *ctrl = &phba->ctrl; 109 struct be_mcc_wrb *wrb; 110 unsigned int tag = 0; 111 struct be_cmd_get_session_req *req; 112 struct be_cmd_get_session_resp *resp; 113 struct be_sge *sge; 114 115 beiscsi_log(phba, KERN_INFO, 116 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 117 "BG_%d : In beiscsi_get_session_info\n"); 118 119 spin_lock(&ctrl->mbox_lock); 120 tag = alloc_mcc_tag(phba); 121 if (!tag) { 122 spin_unlock(&ctrl->mbox_lock); 123 return tag; 124 } 125 126 nonemb_cmd->size = sizeof(*resp); 127 req = nonemb_cmd->va; 128 memset(req, 0, sizeof(*req)); 129 wrb = wrb_from_mccq(phba); 130 sge = nonembedded_sgl(wrb); 131 wrb->tag0 |= tag; 132 133 134 wrb->tag0 |= tag; 135 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); 136 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, 137 OPCODE_ISCSI_INI_SESSION_GET_A_SESSION, 138 sizeof(*resp)); 139 req->session_handle = boot_session_handle; 140 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); 141 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); 142 sge->len = cpu_to_le32(nonemb_cmd->size); 143 144 be_mcc_notify(phba); 145 spin_unlock(&ctrl->mbox_lock); 146 return tag; 147 } 148 149 int mgmt_get_fw_config(struct be_ctrl_info *ctrl, 150 struct beiscsi_hba *phba) 151 { 152 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); 153 struct be_fw_cfg *req = embedded_payload(wrb); 154 int status = 0; 155 156 spin_lock(&ctrl->mbox_lock); 157 memset(wrb, 0, sizeof(*wrb)); 158 159 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 160 161 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, 162 OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req)); 163 status = be_mbox_notify(ctrl); 164 if (!status) { 165 struct be_fw_cfg *pfw_cfg; 166 pfw_cfg = req; 167 phba->fw_config.phys_port = pfw_cfg->phys_port; 168 phba->fw_config.iscsi_icd_start = 169 pfw_cfg->ulp[0].icd_base; 170 phba->fw_config.iscsi_icd_count = 171 pfw_cfg->ulp[0].icd_count; 172 phba->fw_config.iscsi_cid_start = 173 pfw_cfg->ulp[0].sq_base; 174 phba->fw_config.iscsi_cid_count = 175 pfw_cfg->ulp[0].sq_count; 176 if (phba->fw_config.iscsi_cid_count > (BE2_MAX_SESSIONS / 2)) { 177 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, 178 "BG_%d : FW reported MAX CXNS as %d\t" 179 "Max Supported = %d.\n", 180 phba->fw_config.iscsi_cid_count, 181 BE2_MAX_SESSIONS); 182 phba->fw_config.iscsi_cid_count = BE2_MAX_SESSIONS / 2; 183 } 184 } else { 185 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT, 186 "BG_%d : Failed in mgmt_get_fw_config\n"); 187 } 188 189 spin_unlock(&ctrl->mbox_lock); 190 return status; 191 } 192 193 int mgmt_check_supported_fw(struct be_ctrl_info *ctrl, 194 struct beiscsi_hba *phba) 195 { 196 struct be_dma_mem nonemb_cmd; 197 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); 198 struct be_mgmt_controller_attributes *req; 199 struct be_sge *sge = nonembedded_sgl(wrb); 200 int status = 0; 201 202 nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev, 203 sizeof(struct be_mgmt_controller_attributes), 204 &nonemb_cmd.dma); 205 if (nonemb_cmd.va == NULL) { 206 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, 207 "BG_%d : Failed to allocate memory for " 208 "mgmt_check_supported_fw\n"); 209 return -ENOMEM; 210 } 211 nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes); 212 req = nonemb_cmd.va; 213 memset(req, 0, sizeof(*req)); 214 spin_lock(&ctrl->mbox_lock); 215 memset(wrb, 0, sizeof(*wrb)); 216 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); 217 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, 218 OPCODE_COMMON_GET_CNTL_ATTRIBUTES, sizeof(*req)); 219 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma)); 220 sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF); 221 sge->len = cpu_to_le32(nonemb_cmd.size); 222 status = be_mbox_notify(ctrl); 223 if (!status) { 224 struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va; 225 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, 226 "BG_%d : Firmware Version of CMD : %s\n" 227 "Firmware Version is : %s\n" 228 "Developer Build, not performing version check...\n", 229 resp->params.hba_attribs 230 .flashrom_version_string, 231 resp->params.hba_attribs. 232 firmware_version_string); 233 234 phba->fw_config.iscsi_features = 235 resp->params.hba_attribs.iscsi_features; 236 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, 237 "BM_%d : phba->fw_config.iscsi_features = %d\n", 238 phba->fw_config.iscsi_features); 239 } else 240 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, 241 "BG_%d : Failed in mgmt_check_supported_fw\n"); 242 spin_unlock(&ctrl->mbox_lock); 243 if (nonemb_cmd.va) 244 pci_free_consistent(ctrl->pdev, nonemb_cmd.size, 245 nonemb_cmd.va, nonemb_cmd.dma); 246 247 return status; 248 } 249 250 unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl, 251 struct beiscsi_hba *phba, 252 struct bsg_job *job, 253 struct be_dma_mem *nonemb_cmd) 254 { 255 struct be_cmd_resp_hdr *resp; 256 struct be_mcc_wrb *wrb = wrb_from_mccq(phba); 257 struct be_sge *mcc_sge = nonembedded_sgl(wrb); 258 unsigned int tag = 0; 259 struct iscsi_bsg_request *bsg_req = job->request; 260 struct be_bsg_vendor_cmd *req = nonemb_cmd->va; 261 unsigned short region, sector_size, sector, offset; 262 263 nonemb_cmd->size = job->request_payload.payload_len; 264 memset(nonemb_cmd->va, 0, nonemb_cmd->size); 265 resp = nonemb_cmd->va; 266 region = bsg_req->rqst_data.h_vendor.vendor_cmd[1]; 267 sector_size = bsg_req->rqst_data.h_vendor.vendor_cmd[2]; 268 sector = bsg_req->rqst_data.h_vendor.vendor_cmd[3]; 269 offset = bsg_req->rqst_data.h_vendor.vendor_cmd[4]; 270 req->region = region; 271 req->sector = sector; 272 req->offset = offset; 273 spin_lock(&ctrl->mbox_lock); 274 memset(wrb, 0, sizeof(*wrb)); 275 276 switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) { 277 case BEISCSI_WRITE_FLASH: 278 offset = sector * sector_size + offset; 279 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, 280 OPCODE_COMMON_WRITE_FLASH, sizeof(*req)); 281 sg_copy_to_buffer(job->request_payload.sg_list, 282 job->request_payload.sg_cnt, 283 nonemb_cmd->va + offset, job->request_len); 284 break; 285 case BEISCSI_READ_FLASH: 286 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, 287 OPCODE_COMMON_READ_FLASH, sizeof(*req)); 288 break; 289 default: 290 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 291 "BG_%d : Unsupported cmd = 0x%x\n\n", 292 bsg_req->rqst_data.h_vendor.vendor_cmd[0]); 293 294 spin_unlock(&ctrl->mbox_lock); 295 return -ENOSYS; 296 } 297 298 tag = alloc_mcc_tag(phba); 299 if (!tag) { 300 spin_unlock(&ctrl->mbox_lock); 301 return tag; 302 } 303 304 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 305 job->request_payload.sg_cnt); 306 mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); 307 mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); 308 mcc_sge->len = cpu_to_le32(nonemb_cmd->size); 309 wrb->tag0 |= tag; 310 311 be_mcc_notify(phba); 312 313 spin_unlock(&ctrl->mbox_lock); 314 return tag; 315 } 316 317 int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute) 318 { 319 struct be_ctrl_info *ctrl = &phba->ctrl; 320 struct be_mcc_wrb *wrb = wrb_from_mccq(phba); 321 struct iscsi_cleanup_req *req = embedded_payload(wrb); 322 int status = 0; 323 324 spin_lock(&ctrl->mbox_lock); 325 memset(wrb, 0, sizeof(*wrb)); 326 327 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 328 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, 329 OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req)); 330 331 req->chute = chute; 332 req->hdr_ring_id = cpu_to_le16(HWI_GET_DEF_HDRQ_ID(phba)); 333 req->data_ring_id = cpu_to_le16(HWI_GET_DEF_BUFQ_ID(phba)); 334 335 status = be_mcc_notify_wait(phba); 336 if (status) 337 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT, 338 "BG_%d : mgmt_epfw_cleanup , FAILED\n"); 339 spin_unlock(&ctrl->mbox_lock); 340 return status; 341 } 342 343 unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba, 344 struct invalidate_command_table *inv_tbl, 345 unsigned int num_invalidate, unsigned int cid, 346 struct be_dma_mem *nonemb_cmd) 347 348 { 349 struct be_ctrl_info *ctrl = &phba->ctrl; 350 struct be_mcc_wrb *wrb; 351 struct be_sge *sge; 352 struct invalidate_commands_params_in *req; 353 unsigned int i, tag = 0; 354 355 spin_lock(&ctrl->mbox_lock); 356 tag = alloc_mcc_tag(phba); 357 if (!tag) { 358 spin_unlock(&ctrl->mbox_lock); 359 return tag; 360 } 361 362 req = nonemb_cmd->va; 363 memset(req, 0, sizeof(*req)); 364 wrb = wrb_from_mccq(phba); 365 sge = nonembedded_sgl(wrb); 366 wrb->tag0 |= tag; 367 368 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); 369 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, 370 OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS, 371 sizeof(*req)); 372 req->ref_handle = 0; 373 req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE; 374 for (i = 0; i < num_invalidate; i++) { 375 req->table[i].icd = inv_tbl->icd; 376 req->table[i].cid = inv_tbl->cid; 377 req->icd_count++; 378 inv_tbl++; 379 } 380 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); 381 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); 382 sge->len = cpu_to_le32(nonemb_cmd->size); 383 384 be_mcc_notify(phba); 385 spin_unlock(&ctrl->mbox_lock); 386 return tag; 387 } 388 389 unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba, 390 struct beiscsi_endpoint *beiscsi_ep, 391 unsigned short cid, 392 unsigned short issue_reset, 393 unsigned short savecfg_flag) 394 { 395 struct be_ctrl_info *ctrl = &phba->ctrl; 396 struct be_mcc_wrb *wrb; 397 struct iscsi_invalidate_connection_params_in *req; 398 unsigned int tag = 0; 399 400 spin_lock(&ctrl->mbox_lock); 401 tag = alloc_mcc_tag(phba); 402 if (!tag) { 403 spin_unlock(&ctrl->mbox_lock); 404 return tag; 405 } 406 wrb = wrb_from_mccq(phba); 407 wrb->tag0 |= tag; 408 req = embedded_payload(wrb); 409 410 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 411 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, 412 OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION, 413 sizeof(*req)); 414 req->session_handle = beiscsi_ep->fw_handle; 415 req->cid = cid; 416 if (issue_reset) 417 req->cleanup_type = CMD_ISCSI_CONNECTION_ISSUE_TCP_RST; 418 else 419 req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE; 420 req->save_cfg = savecfg_flag; 421 be_mcc_notify(phba); 422 spin_unlock(&ctrl->mbox_lock); 423 return tag; 424 } 425 426 unsigned int mgmt_upload_connection(struct beiscsi_hba *phba, 427 unsigned short cid, unsigned int upload_flag) 428 { 429 struct be_ctrl_info *ctrl = &phba->ctrl; 430 struct be_mcc_wrb *wrb; 431 struct tcp_upload_params_in *req; 432 unsigned int tag = 0; 433 434 spin_lock(&ctrl->mbox_lock); 435 tag = alloc_mcc_tag(phba); 436 if (!tag) { 437 spin_unlock(&ctrl->mbox_lock); 438 return tag; 439 } 440 wrb = wrb_from_mccq(phba); 441 req = embedded_payload(wrb); 442 wrb->tag0 |= tag; 443 444 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 445 be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD, 446 OPCODE_COMMON_TCP_UPLOAD, sizeof(*req)); 447 req->id = (unsigned short)cid; 448 req->upload_type = (unsigned char)upload_flag; 449 be_mcc_notify(phba); 450 spin_unlock(&ctrl->mbox_lock); 451 return tag; 452 } 453 454 int mgmt_open_connection(struct beiscsi_hba *phba, 455 struct sockaddr *dst_addr, 456 struct beiscsi_endpoint *beiscsi_ep, 457 struct be_dma_mem *nonemb_cmd) 458 { 459 struct hwi_controller *phwi_ctrlr; 460 struct hwi_context_memory *phwi_context; 461 struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr; 462 struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr; 463 struct be_ctrl_info *ctrl = &phba->ctrl; 464 struct be_mcc_wrb *wrb; 465 struct tcp_connect_and_offload_in *req; 466 unsigned short def_hdr_id; 467 unsigned short def_data_id; 468 struct phys_addr template_address = { 0, 0 }; 469 struct phys_addr *ptemplate_address; 470 unsigned int tag = 0; 471 unsigned int i; 472 unsigned short cid = beiscsi_ep->ep_cid; 473 struct be_sge *sge; 474 475 phwi_ctrlr = phba->phwi_ctrlr; 476 phwi_context = phwi_ctrlr->phwi_ctxt; 477 def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba); 478 def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba); 479 480 ptemplate_address = &template_address; 481 ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address); 482 spin_lock(&ctrl->mbox_lock); 483 tag = alloc_mcc_tag(phba); 484 if (!tag) { 485 spin_unlock(&ctrl->mbox_lock); 486 return tag; 487 } 488 wrb = wrb_from_mccq(phba); 489 memset(wrb, 0, sizeof(*wrb)); 490 sge = nonembedded_sgl(wrb); 491 492 req = nonemb_cmd->va; 493 memset(req, 0, sizeof(*req)); 494 wrb->tag0 |= tag; 495 496 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); 497 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, 498 OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD, 499 sizeof(*req)); 500 if (dst_addr->sa_family == PF_INET) { 501 __be32 s_addr = daddr_in->sin_addr.s_addr; 502 req->ip_address.ip_type = BE2_IPV4; 503 req->ip_address.addr[0] = s_addr & 0x000000ff; 504 req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8; 505 req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16; 506 req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24; 507 req->tcp_port = ntohs(daddr_in->sin_port); 508 beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr; 509 beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port); 510 beiscsi_ep->ip_type = BE2_IPV4; 511 } else if (dst_addr->sa_family == PF_INET6) { 512 req->ip_address.ip_type = BE2_IPV6; 513 memcpy(&req->ip_address.addr, 514 &daddr_in6->sin6_addr.in6_u.u6_addr8, 16); 515 req->tcp_port = ntohs(daddr_in6->sin6_port); 516 beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port); 517 memcpy(&beiscsi_ep->dst6_addr, 518 &daddr_in6->sin6_addr.in6_u.u6_addr8, 16); 519 beiscsi_ep->ip_type = BE2_IPV6; 520 } else{ 521 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 522 "BG_%d : unknown addr family %d\n", 523 dst_addr->sa_family); 524 spin_unlock(&ctrl->mbox_lock); 525 free_mcc_tag(&phba->ctrl, tag); 526 return -EINVAL; 527 528 } 529 req->cid = cid; 530 i = phba->nxt_cqid++; 531 if (phba->nxt_cqid == phba->num_cpus) 532 phba->nxt_cqid = 0; 533 req->cq_id = phwi_context->be_cq[i].id; 534 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 535 "BG_%d : i=%d cq_id=%d\n", i, req->cq_id); 536 req->defq_id = def_hdr_id; 537 req->hdr_ring_id = def_hdr_id; 538 req->data_ring_id = def_data_id; 539 req->do_offload = 1; 540 req->dataout_template_pa.lo = ptemplate_address->lo; 541 req->dataout_template_pa.hi = ptemplate_address->hi; 542 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); 543 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); 544 sge->len = cpu_to_le32(nonemb_cmd->size); 545 be_mcc_notify(phba); 546 spin_unlock(&ctrl->mbox_lock); 547 return tag; 548 } 549 550 unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba) 551 { 552 struct be_ctrl_info *ctrl = &phba->ctrl; 553 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); 554 struct be_cmd_get_all_if_id_req *req = embedded_payload(wrb); 555 struct be_cmd_get_all_if_id_req *pbe_allid = req; 556 int status = 0; 557 558 memset(wrb, 0, sizeof(*wrb)); 559 560 spin_lock(&ctrl->mbox_lock); 561 562 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 563 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, 564 OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID, 565 sizeof(*req)); 566 status = be_mbox_notify(ctrl); 567 if (!status) 568 phba->interface_handle = pbe_allid->if_hndl_list[0]; 569 else { 570 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 571 "BG_%d : Failed in mgmt_get_all_if_id\n"); 572 } 573 spin_unlock(&ctrl->mbox_lock); 574 575 return status; 576 } 577 578 static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba, 579 struct be_dma_mem *nonemb_cmd, void *resp_buf, 580 int resp_buf_len) 581 { 582 struct be_ctrl_info *ctrl = &phba->ctrl; 583 struct be_mcc_wrb *wrb = wrb_from_mccq(phba); 584 unsigned short status, extd_status; 585 struct be_sge *sge; 586 unsigned int tag; 587 int rc = 0; 588 589 spin_lock(&ctrl->mbox_lock); 590 tag = alloc_mcc_tag(phba); 591 if (!tag) { 592 spin_unlock(&ctrl->mbox_lock); 593 rc = -ENOMEM; 594 goto free_cmd; 595 } 596 memset(wrb, 0, sizeof(*wrb)); 597 wrb->tag0 |= tag; 598 sge = nonembedded_sgl(wrb); 599 600 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1); 601 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); 602 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); 603 sge->len = cpu_to_le32(nonemb_cmd->size); 604 605 be_mcc_notify(phba); 606 spin_unlock(&ctrl->mbox_lock); 607 608 wait_event_interruptible(phba->ctrl.mcc_wait[tag], 609 phba->ctrl.mcc_numtag[tag]); 610 611 extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; 612 status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; 613 if (status || extd_status) { 614 beiscsi_log(phba, KERN_ERR, 615 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 616 "BG_%d : mgmt_exec_nonemb_cmd Failed status = %d" 617 "extd_status = %d\n", status, extd_status); 618 rc = -EIO; 619 goto free_tag; 620 } 621 622 if (resp_buf) 623 memcpy(resp_buf, nonemb_cmd->va, resp_buf_len); 624 625 free_tag: 626 free_mcc_tag(&phba->ctrl, tag); 627 free_cmd: 628 pci_free_consistent(ctrl->pdev, nonemb_cmd->size, 629 nonemb_cmd->va, nonemb_cmd->dma); 630 return rc; 631 } 632 633 static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd, 634 int iscsi_cmd, int size) 635 { 636 cmd->va = pci_alloc_consistent(phba->ctrl.pdev, size, &cmd->dma); 637 if (!cmd->va) { 638 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 639 "BG_%d : Failed to allocate memory for if info\n"); 640 return -ENOMEM; 641 } 642 memset(cmd->va, 0, size); 643 cmd->size = size; 644 be_cmd_hdr_prepare(cmd->va, CMD_SUBSYSTEM_ISCSI, iscsi_cmd, size); 645 return 0; 646 } 647 648 static int 649 mgmt_static_ip_modify(struct beiscsi_hba *phba, 650 struct be_cmd_get_if_info_resp *if_info, 651 struct iscsi_iface_param_info *ip_param, 652 struct iscsi_iface_param_info *subnet_param, 653 uint32_t ip_action) 654 { 655 struct be_cmd_set_ip_addr_req *req; 656 struct be_dma_mem nonemb_cmd; 657 uint32_t ip_type; 658 int rc; 659 660 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, 661 OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR, 662 sizeof(*req)); 663 if (rc) 664 return rc; 665 666 ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ? 667 BE2_IPV6 : BE2_IPV4 ; 668 669 req = nonemb_cmd.va; 670 req->ip_params.record_entry_count = 1; 671 req->ip_params.ip_record.action = ip_action; 672 req->ip_params.ip_record.interface_hndl = 673 phba->interface_handle; 674 req->ip_params.ip_record.ip_addr.size_of_structure = 675 sizeof(struct be_ip_addr_subnet_format); 676 req->ip_params.ip_record.ip_addr.ip_type = ip_type; 677 678 if (ip_action == IP_ACTION_ADD) { 679 memcpy(req->ip_params.ip_record.ip_addr.addr, ip_param->value, 680 ip_param->len); 681 682 if (subnet_param) 683 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask, 684 subnet_param->value, subnet_param->len); 685 } else { 686 memcpy(req->ip_params.ip_record.ip_addr.addr, 687 if_info->ip_addr.addr, ip_param->len); 688 689 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask, 690 if_info->ip_addr.subnet_mask, ip_param->len); 691 } 692 693 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0); 694 if (rc < 0) 695 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 696 "BG_%d : Failed to Modify existing IP Address\n"); 697 return rc; 698 } 699 700 static int mgmt_modify_gateway(struct beiscsi_hba *phba, uint8_t *gt_addr, 701 uint32_t gtway_action, uint32_t param_len) 702 { 703 struct be_cmd_set_def_gateway_req *req; 704 struct be_dma_mem nonemb_cmd; 705 int rt_val; 706 707 708 rt_val = mgmt_alloc_cmd_data(phba, &nonemb_cmd, 709 OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY, 710 sizeof(*req)); 711 if (rt_val) 712 return rt_val; 713 714 req = nonemb_cmd.va; 715 req->action = gtway_action; 716 req->ip_addr.ip_type = BE2_IPV4; 717 718 memcpy(req->ip_addr.addr, gt_addr, param_len); 719 720 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0); 721 } 722 723 int mgmt_set_ip(struct beiscsi_hba *phba, 724 struct iscsi_iface_param_info *ip_param, 725 struct iscsi_iface_param_info *subnet_param, 726 uint32_t boot_proto) 727 { 728 struct be_cmd_get_def_gateway_resp gtway_addr_set; 729 struct be_cmd_get_if_info_resp if_info; 730 struct be_cmd_set_dhcp_req *dhcpreq; 731 struct be_cmd_rel_dhcp_req *reldhcp; 732 struct be_dma_mem nonemb_cmd; 733 uint8_t *gtway_addr; 734 uint32_t ip_type; 735 int rc; 736 737 if (mgmt_get_all_if_id(phba)) 738 return -EIO; 739 740 memset(&if_info, 0, sizeof(if_info)); 741 ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ? 742 BE2_IPV6 : BE2_IPV4 ; 743 744 rc = mgmt_get_if_info(phba, ip_type, &if_info); 745 if (rc) 746 return rc; 747 748 if (boot_proto == ISCSI_BOOTPROTO_DHCP) { 749 if (if_info.dhcp_state) { 750 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 751 "BG_%d : DHCP Already Enabled\n"); 752 return 0; 753 } 754 /* The ip_param->len is 1 in DHCP case. Setting 755 proper IP len as this it is used while 756 freeing the Static IP. 757 */ 758 ip_param->len = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ? 759 IP_V6_LEN : IP_V4_LEN; 760 761 } else { 762 if (if_info.dhcp_state) { 763 764 memset(&if_info, 0, sizeof(if_info)); 765 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, 766 OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR, 767 sizeof(*reldhcp)); 768 769 if (rc) 770 return rc; 771 772 reldhcp = nonemb_cmd.va; 773 reldhcp->interface_hndl = phba->interface_handle; 774 reldhcp->ip_type = ip_type; 775 776 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0); 777 if (rc < 0) { 778 beiscsi_log(phba, KERN_WARNING, 779 BEISCSI_LOG_CONFIG, 780 "BG_%d : Failed to Delete existing dhcp\n"); 781 return rc; 782 } 783 } 784 } 785 786 /* Delete the Static IP Set */ 787 if (if_info.ip_addr.addr[0]) { 788 rc = mgmt_static_ip_modify(phba, &if_info, ip_param, NULL, 789 IP_ACTION_DEL); 790 if (rc) 791 return rc; 792 } 793 794 /* Delete the Gateway settings if mode change is to DHCP */ 795 if (boot_proto == ISCSI_BOOTPROTO_DHCP) { 796 memset(>way_addr_set, 0, sizeof(gtway_addr_set)); 797 rc = mgmt_get_gateway(phba, BE2_IPV4, >way_addr_set); 798 if (rc) { 799 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 800 "BG_%d : Failed to Get Gateway Addr\n"); 801 return rc; 802 } 803 804 if (gtway_addr_set.ip_addr.addr[0]) { 805 gtway_addr = (uint8_t *)>way_addr_set.ip_addr.addr; 806 rc = mgmt_modify_gateway(phba, gtway_addr, 807 IP_ACTION_DEL, IP_V4_LEN); 808 809 if (rc) { 810 beiscsi_log(phba, KERN_WARNING, 811 BEISCSI_LOG_CONFIG, 812 "BG_%d : Failed to clear Gateway Addr Set\n"); 813 return rc; 814 } 815 } 816 } 817 818 /* Set Adapter to DHCP/Static Mode */ 819 if (boot_proto == ISCSI_BOOTPROTO_DHCP) { 820 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, 821 OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR, 822 sizeof(*dhcpreq)); 823 if (rc) 824 return rc; 825 826 dhcpreq = nonemb_cmd.va; 827 dhcpreq->flags = BLOCKING; 828 dhcpreq->retry_count = 1; 829 dhcpreq->interface_hndl = phba->interface_handle; 830 dhcpreq->ip_type = BE2_DHCP_V4; 831 832 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0); 833 } else { 834 return mgmt_static_ip_modify(phba, &if_info, ip_param, 835 subnet_param, IP_ACTION_ADD); 836 } 837 838 return rc; 839 } 840 841 int mgmt_set_gateway(struct beiscsi_hba *phba, 842 struct iscsi_iface_param_info *gateway_param) 843 { 844 struct be_cmd_get_def_gateway_resp gtway_addr_set; 845 uint8_t *gtway_addr; 846 int rt_val; 847 848 memset(>way_addr_set, 0, sizeof(gtway_addr_set)); 849 rt_val = mgmt_get_gateway(phba, BE2_IPV4, >way_addr_set); 850 if (rt_val) { 851 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 852 "BG_%d : Failed to Get Gateway Addr\n"); 853 return rt_val; 854 } 855 856 if (gtway_addr_set.ip_addr.addr[0]) { 857 gtway_addr = (uint8_t *)>way_addr_set.ip_addr.addr; 858 rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_DEL, 859 gateway_param->len); 860 if (rt_val) { 861 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 862 "BG_%d : Failed to clear Gateway Addr Set\n"); 863 return rt_val; 864 } 865 } 866 867 gtway_addr = (uint8_t *)&gateway_param->value; 868 rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_ADD, 869 gateway_param->len); 870 871 if (rt_val) 872 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 873 "BG_%d : Failed to Set Gateway Addr\n"); 874 875 return rt_val; 876 } 877 878 int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type, 879 struct be_cmd_get_def_gateway_resp *gateway) 880 { 881 struct be_cmd_get_def_gateway_req *req; 882 struct be_dma_mem nonemb_cmd; 883 int rc; 884 885 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, 886 OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY, 887 sizeof(*gateway)); 888 if (rc) 889 return rc; 890 891 req = nonemb_cmd.va; 892 req->ip_type = ip_type; 893 894 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, gateway, 895 sizeof(*gateway)); 896 } 897 898 int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type, 899 struct be_cmd_get_if_info_resp *if_info) 900 { 901 struct be_cmd_get_if_info_req *req; 902 struct be_dma_mem nonemb_cmd; 903 int rc; 904 905 if (mgmt_get_all_if_id(phba)) 906 return -EIO; 907 908 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, 909 OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO, 910 sizeof(*if_info)); 911 if (rc) 912 return rc; 913 914 req = nonemb_cmd.va; 915 req->interface_hndl = phba->interface_handle; 916 req->ip_type = ip_type; 917 918 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, if_info, 919 sizeof(*if_info)); 920 } 921 922 int mgmt_get_nic_conf(struct beiscsi_hba *phba, 923 struct be_cmd_get_nic_conf_resp *nic) 924 { 925 struct be_dma_mem nonemb_cmd; 926 int rc; 927 928 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, 929 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG, 930 sizeof(*nic)); 931 if (rc) 932 return rc; 933 934 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, nic, sizeof(*nic)); 935 } 936 937 938 939 unsigned int be_cmd_get_initname(struct beiscsi_hba *phba) 940 { 941 unsigned int tag = 0; 942 struct be_mcc_wrb *wrb; 943 struct be_cmd_hba_name *req; 944 struct be_ctrl_info *ctrl = &phba->ctrl; 945 946 spin_lock(&ctrl->mbox_lock); 947 tag = alloc_mcc_tag(phba); 948 if (!tag) { 949 spin_unlock(&ctrl->mbox_lock); 950 return tag; 951 } 952 953 wrb = wrb_from_mccq(phba); 954 req = embedded_payload(wrb); 955 wrb->tag0 |= tag; 956 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 957 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, 958 OPCODE_ISCSI_INI_CFG_GET_HBA_NAME, 959 sizeof(*req)); 960 961 be_mcc_notify(phba); 962 spin_unlock(&ctrl->mbox_lock); 963 return tag; 964 } 965 966 unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba) 967 { 968 unsigned int tag = 0; 969 struct be_mcc_wrb *wrb; 970 struct be_cmd_ntwk_link_status_req *req; 971 struct be_ctrl_info *ctrl = &phba->ctrl; 972 973 spin_lock(&ctrl->mbox_lock); 974 tag = alloc_mcc_tag(phba); 975 if (!tag) { 976 spin_unlock(&ctrl->mbox_lock); 977 return tag; 978 } 979 980 wrb = wrb_from_mccq(phba); 981 req = embedded_payload(wrb); 982 wrb->tag0 |= tag; 983 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 984 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, 985 OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, 986 sizeof(*req)); 987 988 be_mcc_notify(phba); 989 spin_unlock(&ctrl->mbox_lock); 990 return tag; 991 } 992 993 /** 994 * be_mgmt_get_boot_shandle()- Get the session handle 995 * @phba: device priv structure instance 996 * @s_handle: session handle returned for boot session. 997 * 998 * Get the boot target session handle. In case of 999 * crashdump mode driver has to issue and MBX Cmd 1000 * for FW to login to boot target 1001 * 1002 * return 1003 * Success: 0 1004 * Failure: Non-Zero value 1005 * 1006 **/ 1007 int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba, 1008 unsigned int *s_handle) 1009 { 1010 struct be_cmd_get_boot_target_resp *boot_resp; 1011 struct be_mcc_wrb *wrb; 1012 unsigned int tag, wrb_num; 1013 uint8_t boot_retry = 3; 1014 unsigned short status, extd_status; 1015 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; 1016 1017 do { 1018 /* Get the Boot Target Session Handle and Count*/ 1019 tag = mgmt_get_boot_target(phba); 1020 if (!tag) { 1021 beiscsi_log(phba, KERN_ERR, 1022 BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT, 1023 "BG_%d : Getting Boot Target Info Failed\n"); 1024 return -EAGAIN; 1025 } else 1026 wait_event_interruptible(phba->ctrl.mcc_wait[tag], 1027 phba->ctrl.mcc_numtag[tag]); 1028 1029 wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; 1030 extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; 1031 status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; 1032 if (status || extd_status) { 1033 beiscsi_log(phba, KERN_ERR, 1034 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, 1035 "BG_%d : mgmt_get_boot_target Failed" 1036 " status = %d extd_status = %d\n", 1037 status, extd_status); 1038 free_mcc_tag(&phba->ctrl, tag); 1039 return -EBUSY; 1040 } 1041 wrb = queue_get_wrb(mccq, wrb_num); 1042 free_mcc_tag(&phba->ctrl, tag); 1043 boot_resp = embedded_payload(wrb); 1044 1045 /* Check if the there are any Boot targets configured */ 1046 if (!boot_resp->boot_session_count) { 1047 beiscsi_log(phba, KERN_INFO, 1048 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, 1049 "BG_%d ;No boot targets configured\n"); 1050 return -ENXIO; 1051 } 1052 1053 /* FW returns the session handle of the boot session */ 1054 if (boot_resp->boot_session_handle != INVALID_SESS_HANDLE) { 1055 *s_handle = boot_resp->boot_session_handle; 1056 return 0; 1057 } 1058 1059 /* Issue MBX Cmd to FW to login to the boot target */ 1060 tag = mgmt_reopen_session(phba, BE_REOPEN_BOOT_SESSIONS, 1061 INVALID_SESS_HANDLE); 1062 if (!tag) { 1063 beiscsi_log(phba, KERN_ERR, 1064 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, 1065 "BG_%d : mgmt_reopen_session Failed\n"); 1066 return -EAGAIN; 1067 } else 1068 wait_event_interruptible(phba->ctrl.mcc_wait[tag], 1069 phba->ctrl.mcc_numtag[tag]); 1070 1071 wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; 1072 extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; 1073 status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; 1074 if (status || extd_status) { 1075 beiscsi_log(phba, KERN_ERR, 1076 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, 1077 "BG_%d : mgmt_reopen_session Failed" 1078 " status = %d extd_status = %d\n", 1079 status, extd_status); 1080 free_mcc_tag(&phba->ctrl, tag); 1081 return -EBUSY; 1082 } 1083 free_mcc_tag(&phba->ctrl, tag); 1084 1085 } while (--boot_retry); 1086 1087 /* Couldn't log into the boot target */ 1088 beiscsi_log(phba, KERN_ERR, 1089 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, 1090 "BG_%d : Login to Boot Target Failed\n"); 1091 return -ENXIO; 1092 } 1093 1094 /** 1095 * mgmt_set_vlan()- Issue and wait for CMD completion 1096 * @phba: device private structure instance 1097 * @vlan_tag: VLAN tag 1098 * 1099 * Issue the MBX Cmd and wait for the completion of the 1100 * command. 1101 * 1102 * returns 1103 * Success: 0 1104 * Failure: Non-Xero Value 1105 **/ 1106 int mgmt_set_vlan(struct beiscsi_hba *phba, 1107 uint16_t vlan_tag) 1108 { 1109 unsigned int tag, wrb_num; 1110 unsigned short status, extd_status; 1111 1112 tag = be_cmd_set_vlan(phba, vlan_tag); 1113 if (!tag) { 1114 beiscsi_log(phba, KERN_ERR, 1115 (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX), 1116 "BG_%d : VLAN Setting Failed\n"); 1117 return -EBUSY; 1118 } else 1119 wait_event_interruptible(phba->ctrl.mcc_wait[tag], 1120 phba->ctrl.mcc_numtag[tag]); 1121 1122 wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; 1123 extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; 1124 status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; 1125 1126 if (status || extd_status) { 1127 beiscsi_log(phba, KERN_ERR, 1128 (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX), 1129 "BS_%d : status : %d extd_status : %d\n", 1130 status, extd_status); 1131 1132 free_mcc_tag(&phba->ctrl, tag); 1133 return -EAGAIN; 1134 } 1135 1136 free_mcc_tag(&phba->ctrl, tag); 1137 return 0; 1138 } 1139