0001
0002
0003
0004
0005
0006
0007 #include "efclib.h"
0008 #include "../libefc_sli/sli4.h"
0009 #include "efc_cmds.h"
0010 #include "efc_sm.h"
0011
0012 static void
0013 efc_nport_free_resources(struct efc_nport *nport, int evt, void *data)
0014 {
0015 struct efc *efc = nport->efc;
0016
0017
0018 nport->attached = false;
0019
0020
0021 if (nport->dma.virt) {
0022 dma_free_coherent(&efc->pci->dev, nport->dma.size,
0023 nport->dma.virt, nport->dma.phys);
0024 memset(&nport->dma, 0, sizeof(struct efc_dma));
0025 }
0026
0027
0028 sli_resource_free(efc->sli, SLI4_RSRC_VPI, nport->indicator);
0029
0030 efc_nport_cb(efc, evt, nport);
0031 }
0032
0033 static int
0034 efc_nport_get_mbox_status(struct efc_nport *nport, u8 *mqe, int status)
0035 {
0036 struct efc *efc = nport->efc;
0037 struct sli4_mbox_command_header *hdr =
0038 (struct sli4_mbox_command_header *)mqe;
0039
0040 if (status || le16_to_cpu(hdr->status)) {
0041 efc_log_debug(efc, "bad status vpi=%#x st=%x hdr=%x\n",
0042 nport->indicator, status, le16_to_cpu(hdr->status));
0043 return -EIO;
0044 }
0045
0046 return 0;
0047 }
0048
0049 static int
0050 efc_nport_free_unreg_vpi_cb(struct efc *efc, int status, u8 *mqe, void *arg)
0051 {
0052 struct efc_nport *nport = arg;
0053 int evt = EFC_EVT_NPORT_FREE_OK;
0054 int rc;
0055
0056 rc = efc_nport_get_mbox_status(nport, mqe, status);
0057 if (rc)
0058 evt = EFC_EVT_NPORT_FREE_FAIL;
0059
0060 efc_nport_free_resources(nport, evt, mqe);
0061 return rc;
0062 }
0063
0064 static void
0065 efc_nport_free_unreg_vpi(struct efc_nport *nport)
0066 {
0067 struct efc *efc = nport->efc;
0068 int rc;
0069 u8 data[SLI4_BMBX_SIZE];
0070
0071 rc = sli_cmd_unreg_vpi(efc->sli, data, nport->indicator,
0072 SLI4_UNREG_TYPE_PORT);
0073 if (rc) {
0074 efc_log_err(efc, "UNREG_VPI format failure\n");
0075 efc_nport_free_resources(nport, EFC_EVT_NPORT_FREE_FAIL, data);
0076 return;
0077 }
0078
0079 rc = efc->tt.issue_mbox_rqst(efc->base, data,
0080 efc_nport_free_unreg_vpi_cb, nport);
0081 if (rc) {
0082 efc_log_err(efc, "UNREG_VPI command failure\n");
0083 efc_nport_free_resources(nport, EFC_EVT_NPORT_FREE_FAIL, data);
0084 }
0085 }
0086
0087 static void
0088 efc_nport_send_evt(struct efc_nport *nport, int evt, void *data)
0089 {
0090 struct efc *efc = nport->efc;
0091
0092
0093 efc_nport_cb(efc, evt, nport);
0094
0095
0096 if (evt == EFC_EVT_NPORT_ATTACH_OK)
0097 nport->attached = true;
0098
0099
0100 if (nport->free_req_pending)
0101 efc_nport_free_unreg_vpi(nport);
0102 }
0103
0104 static int
0105 efc_nport_alloc_init_vpi_cb(struct efc *efc, int status, u8 *mqe, void *arg)
0106 {
0107 struct efc_nport *nport = arg;
0108
0109 if (efc_nport_get_mbox_status(nport, mqe, status)) {
0110 efc_nport_free_resources(nport, EFC_EVT_NPORT_ALLOC_FAIL, mqe);
0111 return -EIO;
0112 }
0113
0114 efc_nport_send_evt(nport, EFC_EVT_NPORT_ALLOC_OK, mqe);
0115 return 0;
0116 }
0117
0118 static void
0119 efc_nport_alloc_init_vpi(struct efc_nport *nport)
0120 {
0121 struct efc *efc = nport->efc;
0122 u8 data[SLI4_BMBX_SIZE];
0123 int rc;
0124
0125
0126 if (nport->free_req_pending) {
0127 efc_nport_free_resources(nport, EFC_EVT_NPORT_FREE_OK, data);
0128 return;
0129 }
0130
0131 rc = sli_cmd_init_vpi(efc->sli, data,
0132 nport->indicator, nport->domain->indicator);
0133 if (rc) {
0134 efc_log_err(efc, "INIT_VPI format failure\n");
0135 efc_nport_free_resources(nport, EFC_EVT_NPORT_ALLOC_FAIL, data);
0136 return;
0137 }
0138
0139 rc = efc->tt.issue_mbox_rqst(efc->base, data,
0140 efc_nport_alloc_init_vpi_cb, nport);
0141 if (rc) {
0142 efc_log_err(efc, "INIT_VPI command failure\n");
0143 efc_nport_free_resources(nport, EFC_EVT_NPORT_ALLOC_FAIL, data);
0144 }
0145 }
0146
0147 static int
0148 efc_nport_alloc_read_sparm64_cb(struct efc *efc, int status, u8 *mqe, void *arg)
0149 {
0150 struct efc_nport *nport = arg;
0151 u8 *payload = NULL;
0152
0153 if (efc_nport_get_mbox_status(nport, mqe, status)) {
0154 efc_nport_free_resources(nport, EFC_EVT_NPORT_ALLOC_FAIL, mqe);
0155 return -EIO;
0156 }
0157
0158 payload = nport->dma.virt;
0159
0160 memcpy(&nport->sli_wwpn, payload + SLI4_READ_SPARM64_WWPN_OFFSET,
0161 sizeof(nport->sli_wwpn));
0162 memcpy(&nport->sli_wwnn, payload + SLI4_READ_SPARM64_WWNN_OFFSET,
0163 sizeof(nport->sli_wwnn));
0164
0165 dma_free_coherent(&efc->pci->dev, nport->dma.size, nport->dma.virt,
0166 nport->dma.phys);
0167 memset(&nport->dma, 0, sizeof(struct efc_dma));
0168 efc_nport_alloc_init_vpi(nport);
0169 return 0;
0170 }
0171
0172 static void
0173 efc_nport_alloc_read_sparm64(struct efc *efc, struct efc_nport *nport)
0174 {
0175 u8 data[SLI4_BMBX_SIZE];
0176 int rc;
0177
0178
0179 nport->dma.size = EFC_SPARAM_DMA_SZ;
0180 nport->dma.virt = dma_alloc_coherent(&efc->pci->dev,
0181 nport->dma.size, &nport->dma.phys,
0182 GFP_KERNEL);
0183 if (!nport->dma.virt) {
0184 efc_log_err(efc, "Failed to allocate DMA memory\n");
0185 efc_nport_free_resources(nport, EFC_EVT_NPORT_ALLOC_FAIL, data);
0186 return;
0187 }
0188
0189 rc = sli_cmd_read_sparm64(efc->sli, data,
0190 &nport->dma, nport->indicator);
0191 if (rc) {
0192 efc_log_err(efc, "READ_SPARM64 format failure\n");
0193 efc_nport_free_resources(nport, EFC_EVT_NPORT_ALLOC_FAIL, data);
0194 return;
0195 }
0196
0197 rc = efc->tt.issue_mbox_rqst(efc->base, data,
0198 efc_nport_alloc_read_sparm64_cb, nport);
0199 if (rc) {
0200 efc_log_err(efc, "READ_SPARM64 command failure\n");
0201 efc_nport_free_resources(nport, EFC_EVT_NPORT_ALLOC_FAIL, data);
0202 }
0203 }
0204
0205 int
0206 efc_cmd_nport_alloc(struct efc *efc, struct efc_nport *nport,
0207 struct efc_domain *domain, u8 *wwpn)
0208 {
0209 u32 index;
0210
0211 nport->indicator = U32_MAX;
0212 nport->free_req_pending = false;
0213
0214 if (wwpn)
0215 memcpy(&nport->sli_wwpn, wwpn, sizeof(nport->sli_wwpn));
0216
0217
0218
0219
0220
0221 if (sli_resource_alloc(efc->sli, SLI4_RSRC_VPI,
0222 &nport->indicator, &index)) {
0223 efc_log_err(efc, "VPI allocation failure\n");
0224 return -EIO;
0225 }
0226
0227 if (domain) {
0228
0229
0230
0231
0232 if (!wwpn)
0233 efc_nport_alloc_read_sparm64(efc, nport);
0234 else
0235 efc_nport_alloc_init_vpi(nport);
0236 } else if (!wwpn) {
0237
0238 efc_log_err(efc, "need WWN for physical port\n");
0239 sli_resource_free(efc->sli, SLI4_RSRC_VPI, nport->indicator);
0240 return -EIO;
0241 }
0242
0243 return 0;
0244 }
0245
0246 static int
0247 efc_nport_attach_reg_vpi_cb(struct efc *efc, int status, u8 *mqe,
0248 void *arg)
0249 {
0250 struct efc_nport *nport = arg;
0251
0252 nport->attaching = false;
0253 if (efc_nport_get_mbox_status(nport, mqe, status)) {
0254 efc_nport_free_resources(nport, EFC_EVT_NPORT_ATTACH_FAIL, mqe);
0255 return -EIO;
0256 }
0257
0258 efc_nport_send_evt(nport, EFC_EVT_NPORT_ATTACH_OK, mqe);
0259 return 0;
0260 }
0261
0262 int
0263 efc_cmd_nport_attach(struct efc *efc, struct efc_nport *nport, u32 fc_id)
0264 {
0265 u8 buf[SLI4_BMBX_SIZE];
0266 int rc = 0;
0267
0268 if (!nport) {
0269 efc_log_err(efc, "bad param(s) nport=%p\n", nport);
0270 return -EIO;
0271 }
0272
0273 nport->fc_id = fc_id;
0274
0275
0276 rc = sli_cmd_reg_vpi(efc->sli, buf, nport->fc_id,
0277 nport->sli_wwpn, nport->indicator,
0278 nport->domain->indicator, false);
0279 if (rc) {
0280 efc_log_err(efc, "REG_VPI format failure\n");
0281 efc_nport_free_resources(nport, EFC_EVT_NPORT_ATTACH_FAIL, buf);
0282 return rc;
0283 }
0284
0285 rc = efc->tt.issue_mbox_rqst(efc->base, buf,
0286 efc_nport_attach_reg_vpi_cb, nport);
0287 if (rc) {
0288 efc_log_err(efc, "REG_VPI command failure\n");
0289 efc_nport_free_resources(nport, EFC_EVT_NPORT_ATTACH_FAIL, buf);
0290 } else {
0291 nport->attaching = true;
0292 }
0293
0294 return rc;
0295 }
0296
0297 int
0298 efc_cmd_nport_free(struct efc *efc, struct efc_nport *nport)
0299 {
0300 if (!nport) {
0301 efc_log_err(efc, "bad parameter(s) nport=%p\n", nport);
0302 return -EIO;
0303 }
0304
0305
0306 if (nport->attached)
0307 efc_nport_free_unreg_vpi(nport);
0308 else if (nport->attaching)
0309 nport->free_req_pending = true;
0310 else
0311 efc_sm_post_event(&nport->sm, EFC_EVT_NPORT_FREE_OK, NULL);
0312
0313 return 0;
0314 }
0315
0316 static int
0317 efc_domain_get_mbox_status(struct efc_domain *domain, u8 *mqe, int status)
0318 {
0319 struct efc *efc = domain->efc;
0320 struct sli4_mbox_command_header *hdr =
0321 (struct sli4_mbox_command_header *)mqe;
0322
0323 if (status || le16_to_cpu(hdr->status)) {
0324 efc_log_debug(efc, "bad status vfi=%#x st=%x hdr=%x\n",
0325 domain->indicator, status,
0326 le16_to_cpu(hdr->status));
0327 return -EIO;
0328 }
0329
0330 return 0;
0331 }
0332
0333 static void
0334 efc_domain_free_resources(struct efc_domain *domain, int evt, void *data)
0335 {
0336 struct efc *efc = domain->efc;
0337
0338
0339 if (domain->dma.virt) {
0340 dma_free_coherent(&efc->pci->dev,
0341 domain->dma.size, domain->dma.virt,
0342 domain->dma.phys);
0343 memset(&domain->dma, 0, sizeof(struct efc_dma));
0344 }
0345
0346
0347 sli_resource_free(efc->sli, SLI4_RSRC_VFI, domain->indicator);
0348
0349 efc_domain_cb(efc, evt, domain);
0350 }
0351
0352 static void
0353 efc_domain_send_nport_evt(struct efc_domain *domain,
0354 int port_evt, int domain_evt, void *data)
0355 {
0356 struct efc *efc = domain->efc;
0357
0358
0359 efc_nport_send_evt(domain->nport, port_evt, NULL);
0360
0361
0362 efc_domain_cb(efc, domain_evt, domain);
0363 }
0364
0365 static int
0366 efc_domain_alloc_read_sparm64_cb(struct efc *efc, int status, u8 *mqe,
0367 void *arg)
0368 {
0369 struct efc_domain *domain = arg;
0370
0371 if (efc_domain_get_mbox_status(domain, mqe, status)) {
0372 efc_domain_free_resources(domain,
0373 EFC_HW_DOMAIN_ALLOC_FAIL, mqe);
0374 return -EIO;
0375 }
0376
0377 efc_domain_send_nport_evt(domain, EFC_EVT_NPORT_ALLOC_OK,
0378 EFC_HW_DOMAIN_ALLOC_OK, mqe);
0379 return 0;
0380 }
0381
0382 static void
0383 efc_domain_alloc_read_sparm64(struct efc_domain *domain)
0384 {
0385 struct efc *efc = domain->efc;
0386 u8 data[SLI4_BMBX_SIZE];
0387 int rc;
0388
0389 rc = sli_cmd_read_sparm64(efc->sli, data, &domain->dma, 0);
0390 if (rc) {
0391 efc_log_err(efc, "READ_SPARM64 format failure\n");
0392 efc_domain_free_resources(domain,
0393 EFC_HW_DOMAIN_ALLOC_FAIL, data);
0394 return;
0395 }
0396
0397 rc = efc->tt.issue_mbox_rqst(efc->base, data,
0398 efc_domain_alloc_read_sparm64_cb, domain);
0399 if (rc) {
0400 efc_log_err(efc, "READ_SPARM64 command failure\n");
0401 efc_domain_free_resources(domain,
0402 EFC_HW_DOMAIN_ALLOC_FAIL, data);
0403 }
0404 }
0405
0406 static int
0407 efc_domain_alloc_init_vfi_cb(struct efc *efc, int status, u8 *mqe,
0408 void *arg)
0409 {
0410 struct efc_domain *domain = arg;
0411
0412 if (efc_domain_get_mbox_status(domain, mqe, status)) {
0413 efc_domain_free_resources(domain,
0414 EFC_HW_DOMAIN_ALLOC_FAIL, mqe);
0415 return -EIO;
0416 }
0417
0418 efc_domain_alloc_read_sparm64(domain);
0419 return 0;
0420 }
0421
0422 static void
0423 efc_domain_alloc_init_vfi(struct efc_domain *domain)
0424 {
0425 struct efc *efc = domain->efc;
0426 struct efc_nport *nport = domain->nport;
0427 u8 data[SLI4_BMBX_SIZE];
0428 int rc;
0429
0430
0431
0432
0433
0434 domain->fcf_indicator = efc->fcfi;
0435 rc = sli_cmd_init_vfi(efc->sli, data, domain->indicator,
0436 domain->fcf_indicator, nport->indicator);
0437 if (rc) {
0438 efc_log_err(efc, "INIT_VFI format failure\n");
0439 efc_domain_free_resources(domain,
0440 EFC_HW_DOMAIN_ALLOC_FAIL, data);
0441 return;
0442 }
0443
0444 efc_log_err(efc, "%s issue mbox\n", __func__);
0445 rc = efc->tt.issue_mbox_rqst(efc->base, data,
0446 efc_domain_alloc_init_vfi_cb, domain);
0447 if (rc) {
0448 efc_log_err(efc, "INIT_VFI command failure\n");
0449 efc_domain_free_resources(domain,
0450 EFC_HW_DOMAIN_ALLOC_FAIL, data);
0451 }
0452 }
0453
0454 int
0455 efc_cmd_domain_alloc(struct efc *efc, struct efc_domain *domain, u32 fcf)
0456 {
0457 u32 index;
0458
0459 if (!domain || !domain->nport) {
0460 efc_log_err(efc, "bad parameter(s) domain=%p nport=%p\n",
0461 domain, domain ? domain->nport : NULL);
0462 return -EIO;
0463 }
0464
0465
0466 domain->dma.size = EFC_SPARAM_DMA_SZ;
0467 domain->dma.virt = dma_alloc_coherent(&efc->pci->dev,
0468 domain->dma.size,
0469 &domain->dma.phys, GFP_KERNEL);
0470 if (!domain->dma.virt) {
0471 efc_log_err(efc, "Failed to allocate DMA memory\n");
0472 return -EIO;
0473 }
0474
0475 domain->fcf = fcf;
0476 domain->fcf_indicator = U32_MAX;
0477 domain->indicator = U32_MAX;
0478
0479 if (sli_resource_alloc(efc->sli, SLI4_RSRC_VFI, &domain->indicator,
0480 &index)) {
0481 efc_log_err(efc, "VFI allocation failure\n");
0482
0483 dma_free_coherent(&efc->pci->dev,
0484 domain->dma.size, domain->dma.virt,
0485 domain->dma.phys);
0486 memset(&domain->dma, 0, sizeof(struct efc_dma));
0487
0488 return -EIO;
0489 }
0490
0491 efc_domain_alloc_init_vfi(domain);
0492 return 0;
0493 }
0494
0495 static int
0496 efc_domain_attach_reg_vfi_cb(struct efc *efc, int status, u8 *mqe,
0497 void *arg)
0498 {
0499 struct efc_domain *domain = arg;
0500
0501 if (efc_domain_get_mbox_status(domain, mqe, status)) {
0502 efc_domain_free_resources(domain,
0503 EFC_HW_DOMAIN_ATTACH_FAIL, mqe);
0504 return -EIO;
0505 }
0506
0507 efc_domain_send_nport_evt(domain, EFC_EVT_NPORT_ATTACH_OK,
0508 EFC_HW_DOMAIN_ATTACH_OK, mqe);
0509 return 0;
0510 }
0511
0512 int
0513 efc_cmd_domain_attach(struct efc *efc, struct efc_domain *domain, u32 fc_id)
0514 {
0515 u8 buf[SLI4_BMBX_SIZE];
0516 int rc = 0;
0517
0518 if (!domain) {
0519 efc_log_err(efc, "bad param(s) domain=%p\n", domain);
0520 return -EIO;
0521 }
0522
0523 domain->nport->fc_id = fc_id;
0524
0525 rc = sli_cmd_reg_vfi(efc->sli, buf, SLI4_BMBX_SIZE, domain->indicator,
0526 domain->fcf_indicator, domain->dma,
0527 domain->nport->indicator, domain->nport->sli_wwpn,
0528 domain->nport->fc_id);
0529 if (rc) {
0530 efc_log_err(efc, "REG_VFI format failure\n");
0531 goto cleanup;
0532 }
0533
0534 rc = efc->tt.issue_mbox_rqst(efc->base, buf,
0535 efc_domain_attach_reg_vfi_cb, domain);
0536 if (rc) {
0537 efc_log_err(efc, "REG_VFI command failure\n");
0538 goto cleanup;
0539 }
0540
0541 return rc;
0542
0543 cleanup:
0544 efc_domain_free_resources(domain, EFC_HW_DOMAIN_ATTACH_FAIL, buf);
0545
0546 return rc;
0547 }
0548
0549 static int
0550 efc_domain_free_unreg_vfi_cb(struct efc *efc, int status, u8 *mqe, void *arg)
0551 {
0552 struct efc_domain *domain = arg;
0553 int evt = EFC_HW_DOMAIN_FREE_OK;
0554 int rc;
0555
0556 rc = efc_domain_get_mbox_status(domain, mqe, status);
0557 if (rc) {
0558 evt = EFC_HW_DOMAIN_FREE_FAIL;
0559 rc = -EIO;
0560 }
0561
0562 efc_domain_free_resources(domain, evt, mqe);
0563 return rc;
0564 }
0565
0566 static void
0567 efc_domain_free_unreg_vfi(struct efc_domain *domain)
0568 {
0569 struct efc *efc = domain->efc;
0570 int rc;
0571 u8 data[SLI4_BMBX_SIZE];
0572
0573 rc = sli_cmd_unreg_vfi(efc->sli, data, domain->indicator,
0574 SLI4_UNREG_TYPE_DOMAIN);
0575 if (rc) {
0576 efc_log_err(efc, "UNREG_VFI format failure\n");
0577 goto cleanup;
0578 }
0579
0580 rc = efc->tt.issue_mbox_rqst(efc->base, data,
0581 efc_domain_free_unreg_vfi_cb, domain);
0582 if (rc) {
0583 efc_log_err(efc, "UNREG_VFI command failure\n");
0584 goto cleanup;
0585 }
0586
0587 return;
0588
0589 cleanup:
0590 efc_domain_free_resources(domain, EFC_HW_DOMAIN_FREE_FAIL, data);
0591 }
0592
0593 int
0594 efc_cmd_domain_free(struct efc *efc, struct efc_domain *domain)
0595 {
0596 if (!domain) {
0597 efc_log_err(efc, "bad parameter(s) domain=%p\n", domain);
0598 return -EIO;
0599 }
0600
0601 efc_domain_free_unreg_vfi(domain);
0602 return 0;
0603 }
0604
0605 int
0606 efc_cmd_node_alloc(struct efc *efc, struct efc_remote_node *rnode, u32 fc_addr,
0607 struct efc_nport *nport)
0608 {
0609
0610 if (rnode->indicator != U32_MAX) {
0611 efc_log_err(efc,
0612 "RPI allocation failure addr=%#x rpi=%#x\n",
0613 fc_addr, rnode->indicator);
0614 return -EIO;
0615 }
0616
0617
0618 rnode->nport = NULL;
0619
0620 if (sli_resource_alloc(efc->sli, SLI4_RSRC_RPI,
0621 &rnode->indicator, &rnode->index)) {
0622 efc_log_err(efc, "RPI allocation failure addr=%#x\n",
0623 fc_addr);
0624 return -EIO;
0625 }
0626
0627 rnode->fc_id = fc_addr;
0628 rnode->nport = nport;
0629
0630 return 0;
0631 }
0632
0633 static int
0634 efc_cmd_node_attach_cb(struct efc *efc, int status, u8 *mqe, void *arg)
0635 {
0636 struct efc_remote_node *rnode = arg;
0637 struct sli4_mbox_command_header *hdr =
0638 (struct sli4_mbox_command_header *)mqe;
0639 int evt = 0;
0640
0641 if (status || le16_to_cpu(hdr->status)) {
0642 efc_log_debug(efc, "bad status cqe=%#x mqe=%#x\n", status,
0643 le16_to_cpu(hdr->status));
0644 rnode->attached = false;
0645 evt = EFC_EVT_NODE_ATTACH_FAIL;
0646 } else {
0647 rnode->attached = true;
0648 evt = EFC_EVT_NODE_ATTACH_OK;
0649 }
0650
0651 efc_remote_node_cb(efc, evt, rnode);
0652
0653 return 0;
0654 }
0655
0656 int
0657 efc_cmd_node_attach(struct efc *efc, struct efc_remote_node *rnode,
0658 struct efc_dma *sparms)
0659 {
0660 int rc = -EIO;
0661 u8 buf[SLI4_BMBX_SIZE];
0662
0663 if (!rnode || !sparms) {
0664 efc_log_err(efc, "bad parameter(s) rnode=%p sparms=%p\n",
0665 rnode, sparms);
0666 return -EIO;
0667 }
0668
0669
0670
0671
0672
0673 if (rnode->index == U32_MAX) {
0674 efc_log_err(efc, "bad parameter rnode->index invalid\n");
0675 return -EIO;
0676 }
0677
0678
0679 if (!sli_cmd_reg_rpi(efc->sli, buf, rnode->indicator,
0680 rnode->nport->indicator, rnode->fc_id, sparms, 0, 0))
0681 rc = efc->tt.issue_mbox_rqst(efc->base, buf,
0682 efc_cmd_node_attach_cb, rnode);
0683
0684 return rc;
0685 }
0686
0687 int
0688 efc_node_free_resources(struct efc *efc, struct efc_remote_node *rnode)
0689 {
0690 int rc = 0;
0691
0692 if (!rnode) {
0693 efc_log_err(efc, "bad parameter rnode=%p\n", rnode);
0694 return -EIO;
0695 }
0696
0697 if (rnode->nport) {
0698 if (rnode->attached) {
0699 efc_log_err(efc, "rnode is still attached\n");
0700 return -EIO;
0701 }
0702 if (rnode->indicator != U32_MAX) {
0703 if (sli_resource_free(efc->sli, SLI4_RSRC_RPI,
0704 rnode->indicator)) {
0705 efc_log_err(efc,
0706 "RPI free fail RPI %d addr=%#x\n",
0707 rnode->indicator, rnode->fc_id);
0708 rc = -EIO;
0709 } else {
0710 rnode->indicator = U32_MAX;
0711 rnode->index = U32_MAX;
0712 }
0713 }
0714 }
0715
0716 return rc;
0717 }
0718
0719 static int
0720 efc_cmd_node_free_cb(struct efc *efc, int status, u8 *mqe, void *arg)
0721 {
0722 struct efc_remote_node *rnode = arg;
0723 struct sli4_mbox_command_header *hdr =
0724 (struct sli4_mbox_command_header *)mqe;
0725 int evt = EFC_EVT_NODE_FREE_FAIL;
0726 int rc = 0;
0727
0728 if (status || le16_to_cpu(hdr->status)) {
0729 efc_log_debug(efc, "bad status cqe=%#x mqe=%#x\n", status,
0730 le16_to_cpu(hdr->status));
0731
0732
0733
0734
0735
0736
0737
0738 if (!rnode->attached ||
0739 (le16_to_cpu(hdr->status) != SLI4_MBX_STATUS_RPI_NOT_REG))
0740 rc = -EIO;
0741 }
0742
0743 if (!rc) {
0744 rnode->attached = false;
0745 evt = EFC_EVT_NODE_FREE_OK;
0746 }
0747
0748 efc_remote_node_cb(efc, evt, rnode);
0749
0750 return rc;
0751 }
0752
0753 int
0754 efc_cmd_node_detach(struct efc *efc, struct efc_remote_node *rnode)
0755 {
0756 u8 buf[SLI4_BMBX_SIZE];
0757 int rc = -EIO;
0758
0759 if (!rnode) {
0760 efc_log_err(efc, "bad parameter rnode=%p\n", rnode);
0761 return -EIO;
0762 }
0763
0764 if (rnode->nport) {
0765 if (!rnode->attached)
0766 return -EIO;
0767
0768 rc = -EIO;
0769
0770 if (!sli_cmd_unreg_rpi(efc->sli, buf, rnode->indicator,
0771 SLI4_RSRC_RPI, U32_MAX))
0772 rc = efc->tt.issue_mbox_rqst(efc->base, buf,
0773 efc_cmd_node_free_cb, rnode);
0774
0775 if (rc != 0) {
0776 efc_log_err(efc, "UNREG_RPI failed\n");
0777 rc = -EIO;
0778 }
0779 }
0780
0781 return rc;
0782 }