[SCSI] bfa: Added Fabric Assigned Address(FAA) support

- Updated/added data structures and definitions to support FAA protocol.
- Modified the IOC state machine to support FAA.
- Introduced FAA feature configuration - enable/disable/query.

Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index 35c415c..9ec8f04 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -437,6 +437,73 @@
 	return 0;
 }
 
+int
+bfad_iocmd_faa_enable(struct bfad_s *bfad, void *cmd)
+{
+	struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
+	unsigned long   flags;
+	struct bfad_hal_comp    fcomp;
+
+	init_completion(&fcomp.comp);
+	iocmd->status = BFA_STATUS_OK;
+	spin_lock_irqsave(&bfad->bfad_lock, flags);
+	iocmd->status = bfa_faa_enable(&bfad->bfa, bfad_hcb_comp, &fcomp);
+	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+	if (iocmd->status != BFA_STATUS_OK)
+		goto out;
+
+	wait_for_completion(&fcomp.comp);
+	iocmd->status = fcomp.status;
+out:
+	return 0;
+}
+
+int
+bfad_iocmd_faa_disable(struct bfad_s *bfad, void *cmd)
+{
+	struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
+	unsigned long   flags;
+	struct bfad_hal_comp    fcomp;
+
+	init_completion(&fcomp.comp);
+	iocmd->status = BFA_STATUS_OK;
+	spin_lock_irqsave(&bfad->bfad_lock, flags);
+	iocmd->status = bfa_faa_disable(&bfad->bfa, bfad_hcb_comp, &fcomp);
+	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+	if (iocmd->status != BFA_STATUS_OK)
+		goto out;
+
+	wait_for_completion(&fcomp.comp);
+	iocmd->status = fcomp.status;
+out:
+	return 0;
+}
+
+int
+bfad_iocmd_faa_query(struct bfad_s *bfad, void *cmd)
+{
+	struct bfa_bsg_faa_attr_s *iocmd = (struct bfa_bsg_faa_attr_s *)cmd;
+	struct bfad_hal_comp    fcomp;
+	unsigned long   flags;
+
+	init_completion(&fcomp.comp);
+	iocmd->status = BFA_STATUS_OK;
+	spin_lock_irqsave(&bfad->bfad_lock, flags);
+	iocmd->status = bfa_faa_query(&bfad->bfa, &iocmd->faa_attr,
+				bfad_hcb_comp, &fcomp);
+	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+	if (iocmd->status != BFA_STATUS_OK)
+		goto out;
+
+	wait_for_completion(&fcomp.comp);
+	iocmd->status = fcomp.status;
+out:
+	return 0;
+}
+
 static int
 bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
 		unsigned int payload_len)
@@ -487,6 +554,15 @@
 	case IOCMD_FLASH_DISABLE_OPTROM:
 		rc = bfad_iocmd_ablk_optrom(bfad, cmd, iocmd);
 		break;
+	case IOCMD_FAA_ENABLE:
+		rc = bfad_iocmd_faa_enable(bfad, iocmd);
+		break;
+	case IOCMD_FAA_DISABLE:
+		rc = bfad_iocmd_faa_disable(bfad, iocmd);
+		break;
+	case IOCMD_FAA_QUERY:
+		rc = bfad_iocmd_faa_query(bfad, iocmd);
+		break;
 	default:
 		rc = EINVAL;
 		break;