]> Pileus Git - ~andy/linux/commitdiff
[SCSI] bfa: Added Fabric Assigned Address(FAA) support
authorKrishna Gudipati <kgudipat@brocade.com>
Sat, 25 Jun 2011 03:23:19 +0000 (20:23 -0700)
committerJames Bottomley <JBottomley@Parallels.com>
Wed, 29 Jun 2011 21:59:01 +0000 (16:59 -0500)
- 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>
12 files changed:
drivers/scsi/bfa/bfa.h
drivers/scsi/bfa/bfa_core.c
drivers/scsi/bfa/bfa_defs.h
drivers/scsi/bfa/bfa_defs_svc.h
drivers/scsi/bfa/bfa_ioc.c
drivers/scsi/bfa/bfa_ioc.h
drivers/scsi/bfa/bfa_svc.c
drivers/scsi/bfa/bfa_svc.h
drivers/scsi/bfa/bfad_bsg.c
drivers/scsi/bfa/bfad_bsg.h
drivers/scsi/bfa/bfi.h
drivers/scsi/bfa/bfi_ms.h

index 8c73265f977d073da20c81ab89fae9413e434201..42769bc07ff43b8bf03d30cf23fecfef4a7c1528 100644 (file)
@@ -241,6 +241,31 @@ struct bfa_hwif_s {
 };
 typedef void (*bfa_cb_iocfc_t) (void *cbarg, enum bfa_status status);
 
+struct bfa_faa_cbfn_s {
+       bfa_cb_iocfc_t  faa_cbfn;
+       void            *faa_cbarg;
+};
+
+#define BFA_FAA_ENABLED                1
+#define BFA_FAA_DISABLED       2
+
+/*
+ *     FAA attributes
+ */
+struct bfa_faa_attr_s {
+       wwn_t   faa;
+       u8      faa_state;
+       u8      pwwn_source;
+       u8      rsvd[6];
+};
+
+struct bfa_faa_args_s {
+       struct bfa_faa_attr_s   *faa_attr;
+       struct bfa_faa_cbfn_s   faa_cb;
+       u8                      faa_state;
+       bfa_boolean_t           busy;
+};
+
 struct bfa_iocfc_s {
        struct bfa_s            *bfa;
        struct bfa_iocfc_cfg_s  cfg;
@@ -266,6 +291,7 @@ struct bfa_iocfc_s {
        bfa_cb_iocfc_t          updateq_cbfn; /*  bios callback function */
        void                    *updateq_cbarg; /*  bios callback arg */
        u32     intr_mask;
+       struct bfa_faa_args_s   faa_args;
 };
 
 #define bfa_lpuid(__bfa)                                               \
index 2b497243baf488f208125d137deffb36331e7f12..4befbf9fd88848ab8f92145aa1458574626cd1c1 100644 (file)
@@ -795,6 +795,181 @@ bfa_iocfc_reset_queues(struct bfa_s *bfa)
        }
 }
 
+/* Fabric Assigned Address specific functions */
+
+/*
+ *     Check whether IOC is ready before sending command down
+ */
+static bfa_status_t
+bfa_faa_validate_request(struct bfa_s *bfa)
+{
+       enum bfa_ioc_type_e     ioc_type = bfa_get_type(bfa);
+       u32     card_type = bfa->ioc.attr->card_type;
+
+       if (bfa_ioc_is_operational(&bfa->ioc)) {
+               if ((ioc_type != BFA_IOC_TYPE_FC) || bfa_mfg_is_mezz(card_type))
+                       return BFA_STATUS_FEATURE_NOT_SUPPORTED;
+       } else {
+               if (!bfa_ioc_is_acq_addr(&bfa->ioc))
+                       return BFA_STATUS_IOC_NON_OP;
+       }
+
+       return BFA_STATUS_OK;
+}
+
+bfa_status_t
+bfa_faa_enable(struct bfa_s *bfa, bfa_cb_iocfc_t cbfn, void *cbarg)
+{
+       struct bfi_faa_en_dis_s faa_enable_req;
+       struct bfa_iocfc_s      *iocfc = &bfa->iocfc;
+       bfa_status_t            status;
+
+       iocfc->faa_args.faa_cb.faa_cbfn = cbfn;
+       iocfc->faa_args.faa_cb.faa_cbarg = cbarg;
+
+       status = bfa_faa_validate_request(bfa);
+       if (status != BFA_STATUS_OK)
+               return status;
+
+       if (iocfc->faa_args.busy == BFA_TRUE)
+               return BFA_STATUS_DEVBUSY;
+
+       if (iocfc->faa_args.faa_state == BFA_FAA_ENABLED)
+               return BFA_STATUS_FAA_ENABLED;
+
+       if (bfa_fcport_is_trunk_enabled(bfa))
+               return BFA_STATUS_ERROR_TRUNK_ENABLED;
+
+       bfa_fcport_cfg_faa(bfa, BFA_FAA_ENABLED);
+       iocfc->faa_args.busy = BFA_TRUE;
+
+       memset(&faa_enable_req, 0, sizeof(struct bfi_faa_en_dis_s));
+       bfi_h2i_set(faa_enable_req.mh, BFI_MC_IOCFC,
+               BFI_IOCFC_H2I_FAA_ENABLE_REQ, bfa_lpuid(bfa));
+
+       bfa_ioc_mbox_send(&bfa->ioc, &faa_enable_req,
+                       sizeof(struct bfi_faa_en_dis_s));
+
+       return BFA_STATUS_OK;
+}
+
+bfa_status_t
+bfa_faa_disable(struct bfa_s *bfa, bfa_cb_iocfc_t cbfn,
+               void *cbarg)
+{
+       struct bfi_faa_en_dis_s faa_disable_req;
+       struct bfa_iocfc_s      *iocfc = &bfa->iocfc;
+       bfa_status_t            status;
+
+       iocfc->faa_args.faa_cb.faa_cbfn = cbfn;
+       iocfc->faa_args.faa_cb.faa_cbarg = cbarg;
+
+       status = bfa_faa_validate_request(bfa);
+       if (status != BFA_STATUS_OK)
+               return status;
+
+       if (iocfc->faa_args.busy == BFA_TRUE)
+               return BFA_STATUS_DEVBUSY;
+
+       if (iocfc->faa_args.faa_state == BFA_FAA_DISABLED)
+               return BFA_STATUS_FAA_DISABLED;
+
+       bfa_fcport_cfg_faa(bfa, BFA_FAA_DISABLED);
+       iocfc->faa_args.busy = BFA_TRUE;
+
+       memset(&faa_disable_req, 0, sizeof(struct bfi_faa_en_dis_s));
+       bfi_h2i_set(faa_disable_req.mh, BFI_MC_IOCFC,
+               BFI_IOCFC_H2I_FAA_DISABLE_REQ, bfa_lpuid(bfa));
+
+       bfa_ioc_mbox_send(&bfa->ioc, &faa_disable_req,
+               sizeof(struct bfi_faa_en_dis_s));
+
+       return BFA_STATUS_OK;
+}
+
+bfa_status_t
+bfa_faa_query(struct bfa_s *bfa, struct bfa_faa_attr_s *attr,
+               bfa_cb_iocfc_t cbfn, void *cbarg)
+{
+       struct bfi_faa_query_s  faa_attr_req;
+       struct bfa_iocfc_s      *iocfc = &bfa->iocfc;
+       bfa_status_t            status;
+
+       iocfc->faa_args.faa_attr = attr;
+       iocfc->faa_args.faa_cb.faa_cbfn = cbfn;
+       iocfc->faa_args.faa_cb.faa_cbarg = cbarg;
+
+       status = bfa_faa_validate_request(bfa);
+       if (status != BFA_STATUS_OK)
+               return status;
+
+       if (iocfc->faa_args.busy == BFA_TRUE)
+               return BFA_STATUS_DEVBUSY;
+
+       iocfc->faa_args.busy = BFA_TRUE;
+       memset(&faa_attr_req, 0, sizeof(struct bfi_faa_query_s));
+       bfi_h2i_set(faa_attr_req.mh, BFI_MC_IOCFC,
+               BFI_IOCFC_H2I_FAA_QUERY_REQ, bfa_lpuid(bfa));
+
+       bfa_ioc_mbox_send(&bfa->ioc, &faa_attr_req,
+               sizeof(struct bfi_faa_query_s));
+
+       return BFA_STATUS_OK;
+}
+
+/*
+ *     FAA enable response
+ */
+static void
+bfa_faa_enable_reply(struct bfa_iocfc_s *iocfc,
+               struct bfi_faa_en_dis_rsp_s *rsp)
+{
+       void    *cbarg = iocfc->faa_args.faa_cb.faa_cbarg;
+       bfa_status_t    status = rsp->status;
+
+       WARN_ON(!iocfc->faa_args.faa_cb.faa_cbfn);
+
+       iocfc->faa_args.faa_cb.faa_cbfn(cbarg, status);
+       iocfc->faa_args.busy = BFA_FALSE;
+}
+
+/*
+ *     FAA disable response
+ */
+static void
+bfa_faa_disable_reply(struct bfa_iocfc_s *iocfc,
+               struct bfi_faa_en_dis_rsp_s *rsp)
+{
+       void    *cbarg = iocfc->faa_args.faa_cb.faa_cbarg;
+       bfa_status_t    status = rsp->status;
+
+       WARN_ON(!iocfc->faa_args.faa_cb.faa_cbfn);
+
+       iocfc->faa_args.faa_cb.faa_cbfn(cbarg, status);
+       iocfc->faa_args.busy = BFA_FALSE;
+}
+
+/*
+ *     FAA query response
+ */
+static void
+bfa_faa_query_reply(struct bfa_iocfc_s *iocfc,
+               bfi_faa_query_rsp_t *rsp)
+{
+       void    *cbarg = iocfc->faa_args.faa_cb.faa_cbarg;
+
+       if (iocfc->faa_args.faa_attr) {
+               iocfc->faa_args.faa_attr->faa = rsp->faa;
+               iocfc->faa_args.faa_attr->faa_state = rsp->faa_status;
+               iocfc->faa_args.faa_attr->pwwn_source = rsp->addr_source;
+       }
+
+       WARN_ON(!iocfc->faa_args.faa_cb.faa_cbfn);
+
+       iocfc->faa_args.faa_cb.faa_cbfn(cbarg, BFA_STATUS_OK);
+       iocfc->faa_args.busy = BFA_FALSE;
+}
+
 /*
  * IOC enable request is complete
  */
@@ -803,6 +978,12 @@ bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status)
 {
        struct bfa_s    *bfa = bfa_arg;
 
+       if (status == BFA_STATUS_FAA_ACQ_ADDR) {
+               bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe,
+                               bfa_iocfc_init_cb, bfa);
+               return;
+       }
+
        if (status != BFA_STATUS_OK) {
                bfa_isr_disable(bfa);
                if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT)
@@ -968,6 +1149,17 @@ bfa_iocfc_isr(void *bfaarg, struct bfi_mbmsg_s *m)
        case BFI_IOCFC_I2H_UPDATEQ_RSP:
                iocfc->updateq_cbfn(iocfc->updateq_cbarg, BFA_STATUS_OK);
                break;
+       case BFI_IOCFC_I2H_FAA_ENABLE_RSP:
+               bfa_faa_enable_reply(iocfc,
+                       (struct bfi_faa_en_dis_rsp_s *)msg);
+               break;
+       case BFI_IOCFC_I2H_FAA_DISABLE_RSP:
+               bfa_faa_disable_reply(iocfc,
+                       (struct bfi_faa_en_dis_rsp_s *)msg);
+               break;
+       case BFI_IOCFC_I2H_FAA_QUERY_RSP:
+               bfa_faa_query_reply(iocfc, (bfi_faa_query_rsp_t *)msg);
+               break;
        default:
                WARN_ON(1);
        }
index c675e65c77a4b7a3a087b6f1fb1df3e9c48944cf..bb382656c8c9b535411f344014b4198fb8ad7f2c 100644 (file)
@@ -145,6 +145,7 @@ enum bfa_status {
        BFA_STATUS_IOC_FAILURE  = 56,   /* IOC failure - Retry, if persists
                                         * contact support */
        BFA_STATUS_INVALID_WWN  = 57,   /*  Invalid WWN */
+       BFA_STATUS_IOC_NON_OP   = 61,   /* IOC is not operational */
        BFA_STATUS_VERSION_FAIL = 70, /* Application/Driver version mismatch */
        BFA_STATUS_DIAG_BUSY    = 71,   /*  diag busy */
        BFA_STATUS_ENOFSAVE     = 78,   /*  No saved firmware trace */
@@ -157,6 +158,12 @@ enum bfa_status {
        BFA_STATUS_TRUNK_DISABLED  = 165, /* Trunking is disabled on
                                           * the adapter */
        BFA_STATUS_IOPROFILE_OFF = 175, /* IO profile OFF */
+       BFA_STATUS_FEATURE_NOT_SUPPORTED = 192, /* Feature not supported */
+       BFA_STATUS_FAA_ENABLED = 197,   /* FAA is already enabled */
+       BFA_STATUS_FAA_DISABLED = 198,  /* FAA is already disabled */
+       BFA_STATUS_FAA_ACQUIRED = 199,  /* FAA is already acquired */
+       BFA_STATUS_FAA_ACQ_ADDR = 200,  /* Acquiring addr */
+       BFA_STATUS_ERROR_TRUNK_ENABLED = 203,   /* Trunk enabled on adapter */
        BFA_STATUS_MAX_VAL              /* Unknown error code */
 };
 #define bfa_status_t enum bfa_status
@@ -275,6 +282,7 @@ enum bfa_ioc_state {
        BFA_IOC_FWMISMATCH      = 11,   /*  IOC f/w different from drivers */
        BFA_IOC_ENABLING        = 12,   /*  IOC is being enabled */
        BFA_IOC_HWFAIL          = 13,   /*  PCI mapping doesn't exist */
+       BFA_IOC_ACQ_ADDR        = 14,   /*  Acquiring addr from fabric */
 };
 
 /*
@@ -455,10 +463,7 @@ enum bfa_port_speed {
        BFA_PORT_SPEED_8GBPS    = 8,
        BFA_PORT_SPEED_10GBPS   = 10,
        BFA_PORT_SPEED_16GBPS   = 16,
-       BFA_PORT_SPEED_AUTO =
-               (BFA_PORT_SPEED_1GBPS | BFA_PORT_SPEED_2GBPS |
-                BFA_PORT_SPEED_4GBPS | BFA_PORT_SPEED_8GBPS |
-                BFA_PORT_SPEED_16GBPS),
+       BFA_PORT_SPEED_AUTO     = 0xf,
 };
 #define bfa_port_speed_t enum bfa_port_speed
 
index 0ee3f954dc85ceaf3808550c0a7e107fe6bcf3c1..d8861872ac708f253e4ff845ec39bb478fdea4e3 100644 (file)
@@ -635,6 +635,7 @@ enum bfa_port_states {
        BFA_PORT_ST_FWMISMATCH          = 12,
        BFA_PORT_ST_PREBOOT_DISABLED    = 13,
        BFA_PORT_ST_TOGGLING_QWAIT      = 14,
+       BFA_PORT_ST_ACQ_ADDR            = 15,
        BFA_PORT_ST_MAX_STATE,
 };
 
@@ -748,7 +749,8 @@ struct bfa_port_cfg_s {
        u8       ratelimit;     /*  ratelimit enabled or not    */
        u8       trl_def_speed; /*  ratelimit default speed     */
        u8      bb_scn;
-       u8      rsvd[3];
+       u8      faa_state;      /*  FAA enabled/disabled        */
+       u8      rsvd[2];
        u16 path_tov;   /*  device path timeout */
        u16 q_depth;    /*  SCSI Queue depth            */
 };
index 931bf9769ff272ba7864c7090635735d5608ffd1..7b4a567ca22ae5989e82c342f02125db2cf7618e 100644 (file)
@@ -113,6 +113,7 @@ enum ioc_event {
        IOC_E_HWERROR           = 10,   /*  hardware error interrupt    */
        IOC_E_TIMEOUT           = 11,   /*  timeout                     */
        IOC_E_HWFAILED          = 12,   /*  PCI mapping failure notice  */
+       IOC_E_FWRSP_ACQ_ADDR    = 13,   /*  Acquiring address           */
 };
 
 bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc_s, enum ioc_event);
@@ -125,6 +126,7 @@ bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc_s, enum ioc_event);
 bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event);
 bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event);
 bfa_fsm_state_decl(bfa_ioc, hwfail, struct bfa_ioc_s, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, acq_addr, struct bfa_ioc_s, enum ioc_event);
 
 static struct bfa_sm_table_s ioc_sm_table[] = {
        {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT},
@@ -137,6 +139,7 @@ static struct bfa_sm_table_s ioc_sm_table[] = {
        {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
        {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
        {BFA_SM(bfa_ioc_sm_hwfail), BFA_IOC_HWFAIL},
+       {BFA_SM(bfa_ioc_sm_acq_addr), BFA_IOC_ACQ_ADDR},
 };
 
 /*
@@ -368,10 +371,16 @@ bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event)
        case IOC_E_FWRSP_GETATTR:
                bfa_ioc_timer_stop(ioc);
                bfa_ioc_check_attr_wwns(ioc);
+               bfa_ioc_hb_monitor(ioc);
                bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
                break;
 
+       case IOC_E_FWRSP_ACQ_ADDR:
+               bfa_ioc_timer_stop(ioc);
+               bfa_ioc_hb_monitor(ioc);
+               bfa_fsm_set_state(ioc, bfa_ioc_sm_acq_addr);
                break;
+
        case IOC_E_PFFAILED:
        case IOC_E_HWERROR:
                bfa_ioc_timer_stop(ioc);
@@ -396,6 +405,50 @@ bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event)
        }
 }
 
+/*
+ * Acquiring address from fabric (entry function)
+ */
+static void
+bfa_ioc_sm_acq_addr_entry(struct bfa_ioc_s *ioc)
+{
+}
+
+/*
+ *     Acquiring address from the fabric
+ */
+static void
+bfa_ioc_sm_acq_addr(struct bfa_ioc_s *ioc, enum ioc_event event)
+{
+       bfa_trc(ioc, event);
+
+       switch (event) {
+       case IOC_E_FWRSP_GETATTR:
+               bfa_ioc_check_attr_wwns(ioc);
+               bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
+               break;
+
+       case IOC_E_PFFAILED:
+       case IOC_E_HWERROR:
+               bfa_hb_timer_stop(ioc);
+       case IOC_E_HBFAIL:
+               ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+               bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
+               if (event != IOC_E_PFFAILED)
+                       bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL);
+               break;
+
+       case IOC_E_DISABLE:
+               bfa_hb_timer_stop(ioc);
+               bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
+               break;
+
+       case IOC_E_ENABLE:
+               break;
+
+       default:
+               bfa_sm_fault(ioc, event);
+       }
+}
 
 static void
 bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc)
@@ -404,7 +457,6 @@ bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc)
 
        ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
        bfa_ioc_event_notify(ioc, BFA_IOC_E_ENABLED);
-       bfa_ioc_hb_monitor(ioc);
        BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC enabled\n");
 }
 
@@ -2065,6 +2117,10 @@ bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *m)
                bfa_ioc_getattr_reply(ioc);
                break;
 
+       case BFI_IOC_I2H_ACQ_ADDR_REPLY:
+               bfa_fsm_send_event(ioc, IOC_E_FWRSP_ACQ_ADDR);
+               break;
+
        default:
                bfa_trc(ioc, msg->mh.msg_id);
                WARN_ON(1);
@@ -2359,6 +2415,15 @@ bfa_ioc_is_disabled(struct bfa_ioc_s *ioc)
                bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled);
 }
 
+/*
+ * Return TRUE if IOC is in acquiring address state
+ */
+bfa_boolean_t
+bfa_ioc_is_acq_addr(struct bfa_ioc_s *ioc)
+{
+       return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_acq_addr);
+}
+
 /*
  * return true if IOC firmware is different.
  */
index 337d0366845f7592db13a33acfd6b842c1b9e8d3..78e9606217eae665ab1d51d9740b8ffa5995f8d9 100644 (file)
@@ -390,6 +390,7 @@ void bfa_ioc_error_isr(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_is_operational(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_is_initialized(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_is_disabled(struct bfa_ioc_s *ioc);
+bfa_boolean_t bfa_ioc_is_acq_addr(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc);
 void bfa_ioc_reset_fwstate(struct bfa_ioc_s *ioc);
index 5373e5ddd4adf28c4cf31759eaba3c5276b165a5..fe99ce20ec28c9fc4aa685e517ba993694f693b6 100644 (file)
@@ -3502,6 +3502,28 @@ bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_port_speed speed)
                return BFA_STATUS_UNSUPP_SPEED;
        }
 
+       /* For Mezz card, port speed entered needs to be checked */
+       if (bfa_mfg_is_mezz(fcport->bfa->ioc.attr->card_type)) {
+               if (bfa_ioc_get_type(&fcport->bfa->ioc) == BFA_IOC_TYPE_FC) {
+                       /* For CT2, 1G is not supported */
+                       if ((speed == BFA_PORT_SPEED_1GBPS) &&
+                           (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id)))
+                               return BFA_STATUS_UNSUPP_SPEED;
+
+                       /* Already checked for Auto Speed and Max Speed supp */
+                       if (!(speed == BFA_PORT_SPEED_1GBPS ||
+                             speed == BFA_PORT_SPEED_2GBPS ||
+                             speed == BFA_PORT_SPEED_4GBPS ||
+                             speed == BFA_PORT_SPEED_8GBPS ||
+                             speed == BFA_PORT_SPEED_16GBPS ||
+                             speed == BFA_PORT_SPEED_AUTO))
+                               return BFA_STATUS_UNSUPP_SPEED;
+               } else {
+                       if (speed != BFA_PORT_SPEED_10GBPS)
+                               return BFA_STATUS_UNSUPP_SPEED;
+               }
+       }
+
        fcport->cfg.speed = speed;
 
        return BFA_STATUS_OK;
@@ -3705,6 +3727,8 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr)
                        attr->port_state = BFA_PORT_ST_IOCDIS;
                else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc))
                        attr->port_state = BFA_PORT_ST_FWMISMATCH;
+               else if (bfa_ioc_is_acq_addr(&fcport->bfa->ioc))
+                       attr->port_state = BFA_PORT_ST_ACQ_ADDR;
        }
 
        /* FCoE vlan */
@@ -3786,6 +3810,18 @@ bfa_fcport_is_ratelim(struct bfa_s *bfa)
 
 }
 
+/*
+ *     Enable/Disable FAA feature in port config
+ */
+void
+bfa_fcport_cfg_faa(struct bfa_s *bfa, u8 state)
+{
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+
+       bfa_trc(bfa, state);
+       fcport->cfg.faa_state = state;
+}
+
 /*
  * Get default minimum ratelim speed
  */
index c81cf5cb856f024a3d4620729382217ee661a62b..acb30efc953d2266314e92e71f02cb3b22de69d7 100644 (file)
@@ -529,6 +529,7 @@ bfa_status_t bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_port_t cbfn,
 bfa_boolean_t bfa_fcport_is_qos_enabled(struct bfa_s *bfa);
 bfa_boolean_t bfa_fcport_is_trunk_enabled(struct bfa_s *bfa);
 bfa_status_t bfa_fcport_is_pbcdisabled(struct bfa_s *bfa);
+void bfa_fcport_cfg_faa(struct bfa_s *bfa, u8 state);
 
 /*
  * bfa rport API functions
@@ -623,4 +624,12 @@ void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status);
 void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg);
 void bfa_cb_lps_cvl_event(void *bfad, void *uarg);
 
+/* FAA specific APIs */
+bfa_status_t bfa_faa_enable(struct bfa_s *bfa,
+                       bfa_cb_iocfc_t cbfn, void *cbarg);
+bfa_status_t bfa_faa_disable(struct bfa_s *bfa,
+                       bfa_cb_iocfc_t cbfn, void *cbarg);
+bfa_status_t bfa_faa_query(struct bfa_s *bfa, struct bfa_faa_attr_s *attr,
+                       bfa_cb_iocfc_t cbfn, void *cbarg);
+
 #endif /* __BFA_SVC_H__ */
index 35c415c81dad5b82b8bc9ae10865144d4a042b9c..9ec8f04b16c08306955cea1df5d790f1375a720d 100644 (file)
@@ -437,6 +437,73 @@ out:
        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 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
        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;
index a4dcb39883e7622bcdf5f063b7eb99b187c95f25..49f558fc2375a8d63969c5eaefe7ee8d1a3633bf 100644 (file)
@@ -39,6 +39,9 @@ enum {
        IOCMD_PORT_CFG_MODE,
        IOCMD_FLASH_ENABLE_OPTROM,
        IOCMD_FLASH_DISABLE_OPTROM,
+       IOCMD_FAA_ENABLE,
+       IOCMD_FAA_DISABLE,
+       IOCMD_FAA_QUERY,
 };
 
 struct bfa_bsg_gen_s {
@@ -156,6 +159,13 @@ struct bfa_bsg_port_cfg_mode_s {
        struct bfa_port_cfg_mode_s cfg;
 };
 
+struct bfa_bsg_faa_attr_s {
+       bfa_status_t            status;
+       u16                     bfad_num;
+       u16                     rsvd;
+       struct bfa_faa_attr_s   faa_attr;
+};
+
 struct bfa_bsg_fcpt_s {
        bfa_status_t    status;
        u16             vf_id;
index 02e445612546c4ba693ce5703de14ec581c43bc4..d8f1a7105139cff1b4a080ef89af733b8d623863 100644 (file)
@@ -222,6 +222,7 @@ enum bfi_ioc_i2h_msgs {
        BFI_IOC_I2H_DISABLE_REPLY       = BFA_I2HM(2),
        BFI_IOC_I2H_GETATTR_REPLY       = BFA_I2HM(3),
        BFI_IOC_I2H_HBEAT               = BFA_I2HM(4),
+       BFI_IOC_I2H_ACQ_ADDR_REPLY      = BFA_I2HM(5),
 };
 
 /*
index 263631dcfa7cce2309e9e06f8224e8390c5acba9..c665a800c41d46b628628bad2c4da2aa86c1b5f7 100644 (file)
@@ -28,11 +28,17 @@ enum bfi_iocfc_h2i_msgs {
        BFI_IOCFC_H2I_CFG_REQ           = 1,
        BFI_IOCFC_H2I_SET_INTR_REQ      = 2,
        BFI_IOCFC_H2I_UPDATEQ_REQ       = 3,
+       BFI_IOCFC_H2I_FAA_ENABLE_REQ    = 4,
+       BFI_IOCFC_H2I_FAA_DISABLE_REQ   = 5,
+       BFI_IOCFC_H2I_FAA_QUERY_REQ     = 6,
 };
 
 enum bfi_iocfc_i2h_msgs {
        BFI_IOCFC_I2H_CFG_REPLY         = BFA_I2HM(1),
        BFI_IOCFC_I2H_UPDATEQ_RSP       = BFA_I2HM(3),
+       BFI_IOCFC_I2H_FAA_ENABLE_RSP    = BFA_I2HM(4),
+       BFI_IOCFC_I2H_FAA_DISABLE_RSP   = BFA_I2HM(5),
+       BFI_IOCFC_I2H_FAA_QUERY_RSP     = BFA_I2HM(6),
 };
 
 struct bfi_iocfc_cfg_s {
@@ -166,6 +172,37 @@ union bfi_iocfc_i2h_msg_u {
        u32 mboxmsg[BFI_IOC_MSGSZ];
 };
 
+/*
+ * BFI_IOCFC_H2I_FAA_ENABLE_REQ BFI_IOCFC_H2I_FAA_DISABLE_REQ message
+ */
+struct bfi_faa_en_dis_s {
+       struct bfi_mhdr_s mh;   /* common msg header    */
+};
+
+/*
+ * BFI_IOCFC_H2I_FAA_QUERY_REQ message
+ */
+struct bfi_faa_query_s {
+       struct bfi_mhdr_s mh;   /* common msg header    */
+       u8      faa_status;     /* FAA status           */
+       u8      addr_source;    /* PWWN source          */
+       u8      rsvd[2];
+       wwn_t   faa;            /* Fabric acquired PWWN */
+};
+
+/*
+ * BFI_IOCFC_I2H_FAA_ENABLE_RSP, BFI_IOCFC_I2H_FAA_DISABLE_RSP message
+ */
+struct bfi_faa_en_dis_rsp_s {
+       struct bfi_mhdr_s mh;   /* common msg header    */
+       u8      status;         /* updateq  status      */
+       u8      rsvd[3];
+};
+
+/*
+ * BFI_IOCFC_I2H_FAA_QUERY_RSP message
+ */
+#define bfi_faa_query_rsp_t struct bfi_faa_query_s
 
 enum bfi_fcport_h2i {
        BFI_FCPORT_H2I_ENABLE_REQ               = (1),