aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/bfa/bfa_fcs.c10
-rw-r--r--drivers/scsi/bfa/bfa_iocfc.c11
-rw-r--r--drivers/scsi/bfa/bfa_iocfc.h3
-rw-r--r--drivers/scsi/bfa/bfad.c61
-rw-r--r--drivers/scsi/bfa/bfad_attr.c43
-rw-r--r--drivers/scsi/bfa/bfad_drv.h8
-rw-r--r--drivers/scsi/bfa/bfad_im.c1
-rw-r--r--drivers/scsi/bfa/fabric.c2
-rw-r--r--drivers/scsi/bfa/fcs_vport.h1
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_port.h12
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_status.h5
-rw-r--r--drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h3
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs.h4
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h4
-rw-r--r--drivers/scsi/bfa/vport.c45
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,
99void 99void
100bfa_fcs_init(struct bfa_fcs_s *fcs) 100bfa_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
885int
886bfa_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,
169void bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t **wwns); 170void bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t **wwns);
170void bfa_iocfc_get_pbc_boot_cfg(struct bfa_s *bfa, 171void bfa_iocfc_get_pbc_boot_cfg(struct bfa_s *bfa,
171 struct bfa_boot_pbc_s *pbcfg); 172 struct bfa_boot_pbc_s *pbcfg);
173int 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 */
329void
330bfa_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
327void 351void
328bfad_hal_mem_release(struct bfad_s *bfad) 352bfad_hal_mem_release(struct bfad_s *bfad)
@@ -481,10 +505,10 @@ ext:
481 */ 505 */
482bfa_status_t 506bfa_status_t
483bfad_vport_create(struct bfad_s *bfad, u16 vf_id, 507bfad_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
884bfad_start_ops(struct bfad_s *bfad) 912bfad_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
930int 980int
931bfad_worker (void *ptr) 981bfad_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
472free_scsi_host: 481free_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
203struct 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
568out_fc_rel: 568out_fc_rel:
569 scsi_host_put(im_port->shost); 569 scsi_host_put(im_port->shost);
570 im_port->shost = NULL;
570out_free_idr: 571out_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);
26void bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport); 26void bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport);
27void bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport); 27void bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport);
28void bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport); 28void bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport);
29void 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 */
52struct bfa_port_cfg_s { 52struct 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 */
43void bfa_fcb_vport_delete(struct bfad_vport_s *vport_drv); 43void bfa_fcb_vport_delete(struct bfad_vport_s *vport_drv);
44void 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 */
64void bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad, 64void 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);
66void bfa_fcs_init(struct bfa_fcs_s *fcs); 66void bfa_fcs_init(struct bfa_fcs_s *fcs);
67void bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs, 67void 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);
52bfa_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);
52bfa_status_t bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport); 56bfa_status_t bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport);
53bfa_status_t bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport); 57bfa_status_t bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport);
54bfa_status_t bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport); 58bfa_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 */
599void
600bfa_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 */
599void 608void
@@ -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 */
686bfa_status_t
687bfa_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)
699bfa_status_t 741bfa_status_t
700bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport) 742bfa_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;