aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bfa
diff options
context:
space:
mode:
authorJing Huang <huangj@brocade.com>2010-07-08 22:46:26 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-27 13:04:04 -0400
commitd9883548a0b0afec4786e6c5cd8d03d43a30b779 (patch)
treed7ec50fa682ef49063c80f8d77ca85a4fa38b052 /drivers/scsi/bfa
parented96932470e4ca3aab29518a748dc1162853b456 (diff)
[SCSI] bfa: PBC vport create
This patch enables creating PBC vport. During fcs init, fcs will read PBC vport using bfa iocfc API and invoke fcb callback to add the pbc vport entries into a list. The pbc vport list will be traversed in the subsequent pci probe process and vport will be created using fc transport provided vport create function. Signed-off-by: Jing Huang <huangj@brocade.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/bfa')
-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 3516172c597c..3ec2f49de61d 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 afa3da08b788..d3f1052744d3 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 3ee9fe7a7967..a08309fb981d 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 1b869add20b2..37f886d27922 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 e477bfbfa7d8..871a30363560 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 6c920c1b53a4..2b58b29fe303 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 5b7cf539e50b..0dff0d4b03c9 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 8166e9745ec0..9315383fff8a 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 13c32ebf946c..bb647a4a5dde 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 501bc9739d9d..752a81293d5a 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 ec78b4cb121a..819db5abf461 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 a39f474c2fcf..cfd6ba7c47ec 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 f2fd35fdee28..54e5b81ab2a3 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 cd33f2cd5c34..0af262430860 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 27cd619a227a..f14e9f2d2c30 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;