diff options
-rw-r--r-- | drivers/scsi/bfa/bfa_fcs.c | 10 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_iocfc.c | 11 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_iocfc.h | 3 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad.c | 61 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_attr.c | 43 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_drv.h | 8 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_im.c | 1 | ||||
-rw-r--r-- | drivers/scsi/bfa/fabric.c | 2 | ||||
-rw-r--r-- | drivers/scsi/bfa/fcs_vport.h | 1 | ||||
-rw-r--r-- | drivers/scsi/bfa/include/defs/bfa_defs_port.h | 12 | ||||
-rw-r--r-- | drivers/scsi/bfa/include/defs/bfa_defs_status.h | 5 | ||||
-rw-r--r-- | drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h | 3 | ||||
-rw-r--r-- | drivers/scsi/bfa/include/fcs/bfa_fcs.h | 4 | ||||
-rw-r--r-- | drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h | 4 | ||||
-rw-r--r-- | drivers/scsi/bfa/vport.c | 45 |
15 files changed, 179 insertions, 34 deletions
diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c index 3516172c597..3ec2f49de61 100644 --- a/drivers/scsi/bfa/bfa_fcs.c +++ b/drivers/scsi/bfa/bfa_fcs.c | |||
@@ -99,14 +99,22 @@ bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad, | |||
99 | void | 99 | void |
100 | bfa_fcs_init(struct bfa_fcs_s *fcs) | 100 | bfa_fcs_init(struct bfa_fcs_s *fcs) |
101 | { | 101 | { |
102 | int i; | 102 | int i, npbc_vports; |
103 | struct bfa_fcs_mod_s *mod; | 103 | struct bfa_fcs_mod_s *mod; |
104 | struct bfi_pbc_vport_s pbc_vports[BFI_PBC_MAX_VPORTS]; | ||
104 | 105 | ||
105 | for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) { | 106 | for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) { |
106 | mod = &fcs_modules[i]; | 107 | mod = &fcs_modules[i]; |
107 | if (mod->modinit) | 108 | if (mod->modinit) |
108 | mod->modinit(fcs); | 109 | mod->modinit(fcs); |
109 | } | 110 | } |
111 | /* Initialize pbc vports */ | ||
112 | if (!fcs->min_cfg) { | ||
113 | npbc_vports = | ||
114 | bfa_iocfc_get_pbc_vports(fcs->bfa, pbc_vports); | ||
115 | for (i = 0; i < npbc_vports; i++) | ||
116 | bfa_fcb_pbc_vport_create(fcs->bfa->bfad, pbc_vports[i]); | ||
117 | } | ||
110 | } | 118 | } |
111 | 119 | ||
112 | /** | 120 | /** |
diff --git a/drivers/scsi/bfa/bfa_iocfc.c b/drivers/scsi/bfa/bfa_iocfc.c index afa3da08b78..d3f1052744d 100644 --- a/drivers/scsi/bfa/bfa_iocfc.c +++ b/drivers/scsi/bfa/bfa_iocfc.c | |||
@@ -882,6 +882,17 @@ bfa_iocfc_get_pbc_boot_cfg(struct bfa_s *bfa, struct bfa_boot_pbc_s *pbcfg) | |||
882 | memcpy(pbcfg->pblun, cfgrsp->pbc_cfg.blun, sizeof(pbcfg->pblun)); | 882 | memcpy(pbcfg->pblun, cfgrsp->pbc_cfg.blun, sizeof(pbcfg->pblun)); |
883 | } | 883 | } |
884 | 884 | ||
885 | int | ||
886 | bfa_iocfc_get_pbc_vports(struct bfa_s *bfa, struct bfi_pbc_vport_s *pbc_vport) | ||
887 | { | ||
888 | struct bfa_iocfc_s *iocfc = &bfa->iocfc; | ||
889 | struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp; | ||
890 | |||
891 | memcpy(pbc_vport, cfgrsp->pbc_cfg.vport, sizeof(cfgrsp->pbc_cfg.vport)); | ||
892 | return cfgrsp->pbc_cfg.nvports; | ||
893 | } | ||
894 | |||
895 | |||
885 | #endif | 896 | #endif |
886 | 897 | ||
887 | 898 | ||
diff --git a/drivers/scsi/bfa/bfa_iocfc.h b/drivers/scsi/bfa/bfa_iocfc.h index 3ee9fe7a796..a08309fb981 100644 --- a/drivers/scsi/bfa/bfa_iocfc.h +++ b/drivers/scsi/bfa/bfa_iocfc.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <bfa_ioc.h> | 21 | #include <bfa_ioc.h> |
22 | #include <bfa.h> | 22 | #include <bfa.h> |
23 | #include <bfi/bfi_iocfc.h> | 23 | #include <bfi/bfi_iocfc.h> |
24 | #include <bfi/bfi_pbc.h> | ||
24 | #include <bfa_callback_priv.h> | 25 | #include <bfa_callback_priv.h> |
25 | 26 | ||
26 | #define BFA_REQQ_NELEMS_MIN (4) | 27 | #define BFA_REQQ_NELEMS_MIN (4) |
@@ -169,6 +170,8 @@ void bfa_com_attach(struct bfa_s *bfa, struct bfa_meminfo_s *mi, | |||
169 | void bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t **wwns); | 170 | void bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t **wwns); |
170 | void bfa_iocfc_get_pbc_boot_cfg(struct bfa_s *bfa, | 171 | void bfa_iocfc_get_pbc_boot_cfg(struct bfa_s *bfa, |
171 | struct bfa_boot_pbc_s *pbcfg); | 172 | struct bfa_boot_pbc_s *pbcfg); |
173 | int bfa_iocfc_get_pbc_vports(struct bfa_s *bfa, | ||
174 | struct bfi_pbc_vport_s *pbc_vport); | ||
172 | 175 | ||
173 | #endif /* __BFA_IOCFC_H__ */ | 176 | #endif /* __BFA_IOCFC_H__ */ |
174 | 177 | ||
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index 1b869add20b..37f886d2792 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c | |||
@@ -322,7 +322,31 @@ ext: | |||
322 | return rc; | 322 | return rc; |
323 | } | 323 | } |
324 | 324 | ||
325 | /** | ||
326 | * @brief | ||
327 | * FCS PBC VPORT Create | ||
328 | */ | ||
329 | void | ||
330 | bfa_fcb_pbc_vport_create(struct bfad_s *bfad, struct bfi_pbc_vport_s pbc_vport) | ||
331 | { | ||
332 | |||
333 | struct bfad_pcfg_s *pcfg; | ||
334 | |||
335 | pcfg = kzalloc(sizeof(struct bfad_pcfg_s), GFP_ATOMIC); | ||
336 | if (!pcfg) { | ||
337 | bfa_trc(bfad, 0); | ||
338 | return; | ||
339 | } | ||
325 | 340 | ||
341 | pcfg->port_cfg.roles = BFA_PORT_ROLE_FCP_IM; | ||
342 | pcfg->port_cfg.pwwn = pbc_vport.vp_pwwn; | ||
343 | pcfg->port_cfg.nwwn = pbc_vport.vp_nwwn; | ||
344 | pcfg->port_cfg.preboot_vp = BFA_TRUE; | ||
345 | |||
346 | list_add_tail(&pcfg->list_entry, &bfad->pbc_pcfg_list); | ||
347 | |||
348 | return; | ||
349 | } | ||
326 | 350 | ||
327 | void | 351 | void |
328 | bfad_hal_mem_release(struct bfad_s *bfad) | 352 | bfad_hal_mem_release(struct bfad_s *bfad) |
@@ -481,10 +505,10 @@ ext: | |||
481 | */ | 505 | */ |
482 | bfa_status_t | 506 | bfa_status_t |
483 | bfad_vport_create(struct bfad_s *bfad, u16 vf_id, | 507 | bfad_vport_create(struct bfad_s *bfad, u16 vf_id, |
484 | struct bfa_port_cfg_s *port_cfg, struct device *dev) | 508 | struct bfa_port_cfg_s *port_cfg, struct device *dev) |
485 | { | 509 | { |
486 | struct bfad_vport_s *vport; | 510 | struct bfad_vport_s *vport; |
487 | int rc = BFA_STATUS_OK; | 511 | int rc = BFA_STATUS_OK; |
488 | unsigned long flags; | 512 | unsigned long flags; |
489 | struct completion fcomp; | 513 | struct completion fcomp; |
490 | 514 | ||
@@ -496,8 +520,12 @@ bfad_vport_create(struct bfad_s *bfad, u16 vf_id, | |||
496 | 520 | ||
497 | vport->drv_port.bfad = bfad; | 521 | vport->drv_port.bfad = bfad; |
498 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 522 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
499 | rc = bfa_fcs_vport_create(&vport->fcs_vport, &bfad->bfa_fcs, vf_id, | 523 | if (port_cfg->preboot_vp == BFA_TRUE) |
500 | port_cfg, vport); | 524 | rc = bfa_fcs_pbc_vport_create(&vport->fcs_vport, |
525 | &bfad->bfa_fcs, vf_id, port_cfg, vport); | ||
526 | else | ||
527 | rc = bfa_fcs_vport_create(&vport->fcs_vport, | ||
528 | &bfad->bfa_fcs, vf_id, port_cfg, vport); | ||
501 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 529 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
502 | 530 | ||
503 | if (rc != BFA_STATUS_OK) | 531 | if (rc != BFA_STATUS_OK) |
@@ -884,6 +912,7 @@ bfa_status_t | |||
884 | bfad_start_ops(struct bfad_s *bfad) | 912 | bfad_start_ops(struct bfad_s *bfad) |
885 | { | 913 | { |
886 | int retval; | 914 | int retval; |
915 | struct bfad_pcfg_s *pcfg, *pcfg_new; | ||
887 | 916 | ||
888 | /* PPORT FCS config */ | 917 | /* PPORT FCS config */ |
889 | bfad_fcs_port_cfg(bfad); | 918 | bfad_fcs_port_cfg(bfad); |
@@ -901,6 +930,27 @@ bfad_start_ops(struct bfad_s *bfad) | |||
901 | 930 | ||
902 | bfad_drv_start(bfad); | 931 | bfad_drv_start(bfad); |
903 | 932 | ||
933 | /* pbc vport creation */ | ||
934 | list_for_each_entry_safe(pcfg, pcfg_new, &bfad->pbc_pcfg_list, | ||
935 | list_entry) { | ||
936 | struct fc_vport_identifiers vid; | ||
937 | struct fc_vport *fc_vport; | ||
938 | |||
939 | memset(&vid, 0, sizeof(vid)); | ||
940 | vid.roles = FC_PORT_ROLE_FCP_INITIATOR; | ||
941 | vid.vport_type = FC_PORTTYPE_NPIV; | ||
942 | vid.disable = false; | ||
943 | vid.node_name = wwn_to_u64((u8 *)&pcfg->port_cfg.nwwn); | ||
944 | vid.port_name = wwn_to_u64((u8 *)&pcfg->port_cfg.pwwn); | ||
945 | fc_vport = fc_vport_create(bfad->pport.im_port->shost, 0, &vid); | ||
946 | if (!fc_vport) | ||
947 | printk(KERN_WARNING "bfad%d: failed to create pbc vport" | ||
948 | " %llx\n", bfad->inst_no, vid.port_name); | ||
949 | list_del(&pcfg->list_entry); | ||
950 | kfree(pcfg); | ||
951 | |||
952 | } | ||
953 | |||
904 | /* | 954 | /* |
905 | * If bfa_linkup_delay is set to -1 default; try to retrive the | 955 | * If bfa_linkup_delay is set to -1 default; try to retrive the |
906 | * value using the bfad_os_get_linkup_delay(); else use the | 956 | * value using the bfad_os_get_linkup_delay(); else use the |
@@ -928,7 +978,7 @@ out_cfg_pport_failure: | |||
928 | } | 978 | } |
929 | 979 | ||
930 | int | 980 | int |
931 | bfad_worker (void *ptr) | 981 | bfad_worker(void *ptr) |
932 | { | 982 | { |
933 | struct bfad_s *bfad; | 983 | struct bfad_s *bfad; |
934 | unsigned long flags; | 984 | unsigned long flags; |
@@ -1031,6 +1081,7 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1031 | 1081 | ||
1032 | bfad->ref_count = 0; | 1082 | bfad->ref_count = 0; |
1033 | bfad->pport.bfad = bfad; | 1083 | bfad->pport.bfad = bfad; |
1084 | INIT_LIST_HEAD(&bfad->pbc_pcfg_list); | ||
1034 | 1085 | ||
1035 | bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad, "%s", | 1086 | bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad, "%s", |
1036 | "bfad_worker"); | 1087 | "bfad_worker"); |
diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c index e477bfbfa7d..871a3036356 100644 --- a/drivers/scsi/bfa/bfad_attr.c +++ b/drivers/scsi/bfa/bfad_attr.c | |||
@@ -373,47 +373,53 @@ bfad_im_vport_create(struct fc_vport *fc_vport, bool disable) | |||
373 | (struct bfad_im_port_s *) shost->hostdata[0]; | 373 | (struct bfad_im_port_s *) shost->hostdata[0]; |
374 | struct bfad_s *bfad = im_port->bfad; | 374 | struct bfad_s *bfad = im_port->bfad; |
375 | struct bfa_port_cfg_s port_cfg; | 375 | struct bfa_port_cfg_s port_cfg; |
376 | struct bfad_pcfg_s *pcfg; | ||
376 | int status = 0, rc; | 377 | int status = 0, rc; |
377 | unsigned long flags; | 378 | unsigned long flags; |
378 | 379 | ||
379 | memset(&port_cfg, 0, sizeof(port_cfg)); | 380 | memset(&port_cfg, 0, sizeof(port_cfg)); |
380 | 381 | u64_to_wwn(fc_vport->node_name, (u8 *)&port_cfg.nwwn); | |
381 | port_cfg.pwwn = wwn_to_u64((u8 *) &fc_vport->port_name); | 382 | u64_to_wwn(fc_vport->port_name, (u8 *)&port_cfg.pwwn); |
382 | port_cfg.nwwn = wwn_to_u64((u8 *) &fc_vport->node_name); | ||
383 | |||
384 | if (strlen(vname) > 0) | 383 | if (strlen(vname) > 0) |
385 | strcpy((char *)&port_cfg.sym_name, vname); | 384 | strcpy((char *)&port_cfg.sym_name, vname); |
386 | |||
387 | port_cfg.roles = BFA_PORT_ROLE_FCP_IM; | 385 | port_cfg.roles = BFA_PORT_ROLE_FCP_IM; |
388 | rc = bfad_vport_create(bfad, 0, &port_cfg, &fc_vport->dev); | ||
389 | 386 | ||
387 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
388 | list_for_each_entry(pcfg, &bfad->pbc_pcfg_list, list_entry) { | ||
389 | if (port_cfg.pwwn == pcfg->port_cfg.pwwn) { | ||
390 | port_cfg.preboot_vp = pcfg->port_cfg.preboot_vp; | ||
391 | break; | ||
392 | } | ||
393 | } | ||
394 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
395 | |||
396 | rc = bfad_vport_create(bfad, 0, &port_cfg, &fc_vport->dev); | ||
390 | if (rc == BFA_STATUS_OK) { | 397 | if (rc == BFA_STATUS_OK) { |
391 | struct bfad_vport_s *vport; | 398 | struct bfad_vport_s *vport; |
392 | struct bfa_fcs_vport_s *fcs_vport; | 399 | struct bfa_fcs_vport_s *fcs_vport; |
393 | struct Scsi_Host *vshost; | 400 | struct Scsi_Host *vshost; |
394 | 401 | ||
395 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 402 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
396 | fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, | 403 | fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, |
397 | port_cfg.pwwn); | 404 | port_cfg.pwwn); |
398 | if (fcs_vport == NULL) { | 405 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
399 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 406 | if (fcs_vport == NULL) |
400 | return VPCERR_BAD_WWN; | 407 | return VPCERR_BAD_WWN; |
401 | } | ||
402 | 408 | ||
403 | fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE); | 409 | fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE); |
404 | if (disable) { | 410 | if (disable) { |
411 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
405 | bfa_fcs_vport_stop(fcs_vport); | 412 | bfa_fcs_vport_stop(fcs_vport); |
413 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
406 | fc_vport_set_state(fc_vport, FC_VPORT_DISABLED); | 414 | fc_vport_set_state(fc_vport, FC_VPORT_DISABLED); |
407 | } | 415 | } |
408 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
409 | 416 | ||
410 | vport = fcs_vport->vport_drv; | 417 | vport = fcs_vport->vport_drv; |
411 | vshost = vport->drv_port.im_port->shost; | 418 | vshost = vport->drv_port.im_port->shost; |
412 | fc_host_node_name(vshost) = wwn_to_u64((u8 *) &port_cfg.nwwn); | 419 | fc_host_node_name(vshost) = wwn_to_u64((u8 *)&port_cfg.nwwn); |
413 | fc_host_port_name(vshost) = wwn_to_u64((u8 *) &port_cfg.pwwn); | 420 | fc_host_port_name(vshost) = wwn_to_u64((u8 *)&port_cfg.pwwn); |
414 | fc_vport->dd_data = vport; | 421 | fc_vport->dd_data = vport; |
415 | vport->drv_port.im_port->fc_vport = fc_vport; | 422 | vport->drv_port.im_port->fc_vport = fc_vport; |
416 | |||
417 | } else if (rc == BFA_STATUS_INVALID_WWN) | 423 | } else if (rc == BFA_STATUS_INVALID_WWN) |
418 | return VPCERR_BAD_WWN; | 424 | return VPCERR_BAD_WWN; |
419 | else if (rc == BFA_STATUS_VPORT_EXISTS) | 425 | else if (rc == BFA_STATUS_VPORT_EXISTS) |
@@ -422,7 +428,7 @@ bfad_im_vport_create(struct fc_vport *fc_vport, bool disable) | |||
422 | return VPCERR_NO_FABRIC_SUPP; | 428 | return VPCERR_NO_FABRIC_SUPP; |
423 | else if (rc == BFA_STATUS_VPORT_WWN_BP) | 429 | else if (rc == BFA_STATUS_VPORT_WWN_BP) |
424 | return VPCERR_BAD_WWN; | 430 | return VPCERR_BAD_WWN; |
425 | else | 431 | else |
426 | return FC_VPORT_FAILED; | 432 | return FC_VPORT_FAILED; |
427 | 433 | ||
428 | return status; | 434 | return status; |
@@ -449,7 +455,7 @@ bfad_im_vport_delete(struct fc_vport *fc_vport) | |||
449 | port = im_port->port; | 455 | port = im_port->port; |
450 | 456 | ||
451 | vshost = vport->drv_port.im_port->shost; | 457 | vshost = vport->drv_port.im_port->shost; |
452 | pwwn = wwn_to_u64((u8 *) &fc_host_port_name(vshost)); | 458 | u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn); |
453 | 459 | ||
454 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 460 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
455 | fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn); | 461 | fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn); |
@@ -467,6 +473,9 @@ bfad_im_vport_delete(struct fc_vport *fc_vport) | |||
467 | rc = bfa_fcs_vport_delete(&vport->fcs_vport); | 473 | rc = bfa_fcs_vport_delete(&vport->fcs_vport); |
468 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 474 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
469 | 475 | ||
476 | if (rc == BFA_STATUS_PBC) | ||
477 | return -1; | ||
478 | |||
470 | wait_for_completion(vport->comp_del); | 479 | wait_for_completion(vport->comp_del); |
471 | 480 | ||
472 | free_scsi_host: | 481 | free_scsi_host: |
@@ -490,7 +499,7 @@ bfad_im_vport_disable(struct fc_vport *fc_vport, bool disable) | |||
490 | vport = (struct bfad_vport_s *)fc_vport->dd_data; | 499 | vport = (struct bfad_vport_s *)fc_vport->dd_data; |
491 | bfad = vport->drv_port.bfad; | 500 | bfad = vport->drv_port.bfad; |
492 | vshost = vport->drv_port.im_port->shost; | 501 | vshost = vport->drv_port.im_port->shost; |
493 | pwwn = wwn_to_u64((u8 *) &fc_vport->port_name); | 502 | u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn); |
494 | 503 | ||
495 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 504 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
496 | fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn); | 505 | fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn); |
diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h index 6c920c1b53a..2b58b29fe30 100644 --- a/drivers/scsi/bfa/bfad_drv.h +++ b/drivers/scsi/bfa/bfad_drv.h | |||
@@ -120,6 +120,8 @@ struct bfad_vport_s { | |||
120 | struct bfad_port_s drv_port; | 120 | struct bfad_port_s drv_port; |
121 | struct bfa_fcs_vport_s fcs_vport; | 121 | struct bfa_fcs_vport_s fcs_vport; |
122 | struct completion *comp_del; | 122 | struct completion *comp_del; |
123 | struct list_head list_entry; | ||
124 | struct bfa_port_cfg_s port_cfg; | ||
123 | }; | 125 | }; |
124 | 126 | ||
125 | /* | 127 | /* |
@@ -195,6 +197,12 @@ struct bfad_s { | |||
195 | bfa_boolean_t ipfc_enabled; | 197 | bfa_boolean_t ipfc_enabled; |
196 | union bfad_tmp_buf tmp_buf; | 198 | union bfad_tmp_buf tmp_buf; |
197 | struct fc_host_statistics link_stats; | 199 | struct fc_host_statistics link_stats; |
200 | struct list_head pbc_pcfg_list; | ||
201 | }; | ||
202 | |||
203 | struct bfad_pcfg_s { | ||
204 | struct list_head list_entry; | ||
205 | struct bfa_port_cfg_s port_cfg; | ||
198 | }; | 206 | }; |
199 | 207 | ||
200 | /* | 208 | /* |
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index 5b7cf539e50..0dff0d4b03c 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c | |||
@@ -567,6 +567,7 @@ bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port, | |||
567 | 567 | ||
568 | out_fc_rel: | 568 | out_fc_rel: |
569 | scsi_host_put(im_port->shost); | 569 | scsi_host_put(im_port->shost); |
570 | im_port->shost = NULL; | ||
570 | out_free_idr: | 571 | out_free_idr: |
571 | mutex_lock(&bfad_mutex); | 572 | mutex_lock(&bfad_mutex); |
572 | idr_remove(&bfad_im_port_index, im_port->idr_id); | 573 | idr_remove(&bfad_im_port_index, im_port->idr_id); |
diff --git a/drivers/scsi/bfa/fabric.c b/drivers/scsi/bfa/fabric.c index 8166e9745ec..9315383fff8 100644 --- a/drivers/scsi/bfa/fabric.c +++ b/drivers/scsi/bfa/fabric.c | |||
@@ -789,7 +789,7 @@ bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric) | |||
789 | 789 | ||
790 | list_for_each_safe(qe, qen, &fabric->vport_q) { | 790 | list_for_each_safe(qe, qen, &fabric->vport_q) { |
791 | vport = (struct bfa_fcs_vport_s *)qe; | 791 | vport = (struct bfa_fcs_vport_s *)qe; |
792 | bfa_fcs_vport_delete(vport); | 792 | bfa_fcs_vport_fcs_delete(vport); |
793 | } | 793 | } |
794 | 794 | ||
795 | bfa_fcs_port_delete(&fabric->bport); | 795 | bfa_fcs_port_delete(&fabric->bport); |
diff --git a/drivers/scsi/bfa/fcs_vport.h b/drivers/scsi/bfa/fcs_vport.h index 13c32ebf946..bb647a4a5dd 100644 --- a/drivers/scsi/bfa/fcs_vport.h +++ b/drivers/scsi/bfa/fcs_vport.h | |||
@@ -26,6 +26,7 @@ void bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport); | |||
26 | void bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport); | 26 | void bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport); |
27 | void bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport); | 27 | void bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport); |
28 | void bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport); | 28 | void bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport); |
29 | void bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport); | ||
29 | 30 | ||
30 | #endif /* __FCS_VPORT_H__ */ | 31 | #endif /* __FCS_VPORT_H__ */ |
31 | 32 | ||
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_port.h b/drivers/scsi/bfa/include/defs/bfa_defs_port.h index 501bc9739d9..752a81293d5 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_port.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_port.h | |||
@@ -50,12 +50,12 @@ enum bfa_port_role { | |||
50 | * FCS port configuration. | 50 | * FCS port configuration. |
51 | */ | 51 | */ |
52 | struct bfa_port_cfg_s { | 52 | struct bfa_port_cfg_s { |
53 | wwn_t pwwn; /* port wwn */ | 53 | wwn_t pwwn; /* port wwn */ |
54 | wwn_t nwwn; /* node wwn */ | 54 | wwn_t nwwn; /* node wwn */ |
55 | struct bfa_port_symname_s sym_name; /* vm port symbolic name */ | 55 | struct bfa_port_symname_s sym_name; /* vm port symbolic name */ |
56 | enum bfa_port_role roles; /* FCS port roles */ | 56 | bfa_boolean_t preboot_vp; /* vport created from PBC */ |
57 | u32 rsvd; | 57 | enum bfa_port_role roles; /* FCS port roles */ |
58 | u8 tag[16]; /* opaque tag from application */ | 58 | u8 tag[16]; /* opaque tag from application */ |
59 | }; | 59 | }; |
60 | 60 | ||
61 | /** | 61 | /** |
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_status.h b/drivers/scsi/bfa/include/defs/bfa_defs_status.h index ec78b4cb121..819db5abf46 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_status.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_status.h | |||
@@ -213,7 +213,8 @@ enum bfa_status { | |||
213 | * loaded */ | 213 | * loaded */ |
214 | BFA_STATUS_CARD_TYPE_MISMATCH = 131, /* Card type mismatch */ | 214 | BFA_STATUS_CARD_TYPE_MISMATCH = 131, /* Card type mismatch */ |
215 | BFA_STATUS_BAD_ASICBLK = 132, /* Bad ASIC block */ | 215 | BFA_STATUS_BAD_ASICBLK = 132, /* Bad ASIC block */ |
216 | BFA_STATUS_NO_DRIVER = 133, /* Brocade adapter/driver not installed or loaded */ | 216 | BFA_STATUS_NO_DRIVER = 133, /* Brocade adapter/driver not installed |
217 | * or loaded */ | ||
217 | BFA_STATUS_INVALID_MAC = 134, /* Invalid mac address */ | 218 | BFA_STATUS_INVALID_MAC = 134, /* Invalid mac address */ |
218 | BFA_STATUS_IM_NO_VLAN = 135, /* No VLANs configured on the adapter */ | 219 | BFA_STATUS_IM_NO_VLAN = 135, /* No VLANs configured on the adapter */ |
219 | BFA_STATUS_IM_ETH_LB_FAILED = 136, /* Ethernet loopback test failed */ | 220 | BFA_STATUS_IM_ETH_LB_FAILED = 136, /* Ethernet loopback test failed */ |
@@ -249,6 +250,8 @@ enum bfa_status { | |||
249 | BFA_STATUS_IM_TEAM_CFG_NOT_ALLOWED = 153, /* Given settings are not | 250 | BFA_STATUS_IM_TEAM_CFG_NOT_ALLOWED = 153, /* Given settings are not |
250 | * allowed for the current | 251 | * allowed for the current |
251 | * Teaming mode */ | 252 | * Teaming mode */ |
253 | BFA_STATUS_PBC = 154, /* Operation not allowed for pre-boot | ||
254 | * configuration */ | ||
252 | BFA_STATUS_MAX_VAL /* Unknown error code */ | 255 | BFA_STATUS_MAX_VAL /* Unknown error code */ |
253 | }; | 256 | }; |
254 | #define bfa_status_t enum bfa_status | 257 | #define bfa_status_t enum bfa_status |
diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h index a39f474c2fc..cfd6ba7c47e 100644 --- a/drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h +++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h | |||
@@ -40,7 +40,8 @@ struct bfad_vport_s; | |||
40 | * | 40 | * |
41 | * @return None | 41 | * @return None |
42 | */ | 42 | */ |
43 | void bfa_fcb_vport_delete(struct bfad_vport_s *vport_drv); | 43 | void bfa_fcb_vport_delete(struct bfad_vport_s *vport_drv); |
44 | void bfa_fcb_pbc_vport_create(struct bfad_s *bfad, struct bfi_pbc_vport_s); | ||
44 | 45 | ||
45 | 46 | ||
46 | 47 | ||
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs.h b/drivers/scsi/bfa/include/fcs/bfa_fcs.h index f2fd35fdee2..54e5b81ab2a 100644 --- a/drivers/scsi/bfa/include/fcs/bfa_fcs.h +++ b/drivers/scsi/bfa/include/fcs/bfa_fcs.h | |||
@@ -61,8 +61,8 @@ struct bfa_fcs_s { | |||
61 | /* | 61 | /* |
62 | * bfa fcs API functions | 62 | * bfa fcs API functions |
63 | */ | 63 | */ |
64 | void bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad, | 64 | void bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, |
65 | bfa_boolean_t min_cfg); | 65 | struct bfad_s *bfad, bfa_boolean_t min_cfg); |
66 | void bfa_fcs_init(struct bfa_fcs_s *fcs); | 66 | void bfa_fcs_init(struct bfa_fcs_s *fcs); |
67 | void bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs, | 67 | void bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs, |
68 | struct bfa_fcs_driver_info_s *driver_info); | 68 | struct bfa_fcs_driver_info_s *driver_info); |
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h index cd33f2cd5c3..0af26243086 100644 --- a/drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h +++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h | |||
@@ -49,6 +49,10 @@ bfa_status_t bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, | |||
49 | struct bfa_fcs_s *fcs, u16 vf_id, | 49 | struct bfa_fcs_s *fcs, u16 vf_id, |
50 | struct bfa_port_cfg_s *port_cfg, | 50 | struct bfa_port_cfg_s *port_cfg, |
51 | struct bfad_vport_s *vport_drv); | 51 | struct bfad_vport_s *vport_drv); |
52 | bfa_status_t bfa_fcs_pbc_vport_create(struct bfa_fcs_vport_s *vport, | ||
53 | struct bfa_fcs_s *fcs, uint16_t vf_id, | ||
54 | struct bfa_port_cfg_s *port_cfg, | ||
55 | struct bfad_vport_s *vport_drv); | ||
52 | bfa_status_t bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport); | 56 | bfa_status_t bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport); |
53 | bfa_status_t bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport); | 57 | bfa_status_t bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport); |
54 | bfa_status_t bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport); | 58 | bfa_status_t bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport); |
diff --git a/drivers/scsi/bfa/vport.c b/drivers/scsi/bfa/vport.c index 27cd619a227..f14e9f2d2c3 100644 --- a/drivers/scsi/bfa/vport.c +++ b/drivers/scsi/bfa/vport.c | |||
@@ -594,6 +594,15 @@ bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport) | |||
594 | } | 594 | } |
595 | 595 | ||
596 | /** | 596 | /** |
597 | * delete notification from fabric SM. To be invoked from within FCS. | ||
598 | */ | ||
599 | void | ||
600 | bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport) | ||
601 | { | ||
602 | bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE); | ||
603 | } | ||
604 | |||
605 | /** | ||
597 | * Delete completion callback from associated lport | 606 | * Delete completion callback from associated lport |
598 | */ | 607 | */ |
599 | void | 608 | void |
@@ -646,6 +655,7 @@ bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs, | |||
646 | return BFA_STATUS_VPORT_MAX; | 655 | return BFA_STATUS_VPORT_MAX; |
647 | 656 | ||
648 | vport->vport_drv = vport_drv; | 657 | vport->vport_drv = vport_drv; |
658 | vport_cfg->preboot_vp = BFA_FALSE; | ||
649 | bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); | 659 | bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); |
650 | 660 | ||
651 | bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport); | 661 | bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport); |
@@ -657,6 +667,36 @@ bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs, | |||
657 | } | 667 | } |
658 | 668 | ||
659 | /** | 669 | /** |
670 | * Use this function to instantiate a new FCS PBC vport object. This | ||
671 | * function will not trigger any HW initialization process (which will be | ||
672 | * done in vport_start() call) | ||
673 | * | ||
674 | * param[in] vport - pointer to bfa_fcs_vport_t. This space | ||
675 | * needs to be allocated by the driver. | ||
676 | * param[in] fcs - FCS instance | ||
677 | * param[in] vport_cfg - vport configuration | ||
678 | * param[in] vf_id - VF_ID if vport is created within a VF. | ||
679 | * FC_VF_ID_NULL to specify base fabric. | ||
680 | * param[in] vport_drv - Opaque handle back to the driver's vport | ||
681 | * structure | ||
682 | * | ||
683 | * retval BFA_STATUS_OK - on success. | ||
684 | * retval BFA_STATUS_FAILED - on failure. | ||
685 | */ | ||
686 | bfa_status_t | ||
687 | bfa_fcs_pbc_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs, | ||
688 | uint16_t vf_id, struct bfa_port_cfg_s *vport_cfg, | ||
689 | struct bfad_vport_s *vport_drv) | ||
690 | { | ||
691 | bfa_status_t rc; | ||
692 | |||
693 | rc = bfa_fcs_vport_create(vport, fcs, vf_id, vport_cfg, vport_drv); | ||
694 | vport->lport.port_cfg.preboot_vp = BFA_TRUE; | ||
695 | |||
696 | return rc; | ||
697 | } | ||
698 | |||
699 | /** | ||
660 | * Use this function initialize the vport. | 700 | * Use this function initialize the vport. |
661 | * | 701 | * |
662 | * @param[in] vport - pointer to bfa_fcs_vport_t. | 702 | * @param[in] vport - pointer to bfa_fcs_vport_t. |
@@ -692,6 +732,8 @@ bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport) | |||
692 | * Use this function to delete a vport object. Fabric object should | 732 | * Use this function to delete a vport object. Fabric object should |
693 | * be stopped before this function call. | 733 | * be stopped before this function call. |
694 | * | 734 | * |
735 | * Donot invoke this from within FCS | ||
736 | * | ||
695 | * param[in] vport - pointer to bfa_fcs_vport_t. | 737 | * param[in] vport - pointer to bfa_fcs_vport_t. |
696 | * | 738 | * |
697 | * return None | 739 | * return None |
@@ -699,6 +741,9 @@ bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport) | |||
699 | bfa_status_t | 741 | bfa_status_t |
700 | bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport) | 742 | bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport) |
701 | { | 743 | { |
744 | if (vport->lport.port_cfg.preboot_vp) | ||
745 | return BFA_STATUS_PBC; | ||
746 | |||
702 | bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE); | 747 | bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE); |
703 | 748 | ||
704 | return BFA_STATUS_OK; | 749 | return BFA_STATUS_OK; |