Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
Linus Torvalds [Thu, 18 Mar 2010 23:54:31 +0000 (16:54 -0700)]
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (69 commits)
  [SCSI] scsi_transport_fc: Fix synchronization issue while deleting vport
  [SCSI] bfa: Update the driver version to 2.1.2.1.
  [SCSI] bfa: Remove unused header files and did some cleanup.
  [SCSI] bfa: Handle SCSI IO underrun case.
  [SCSI] bfa: FCS and include file changes.
  [SCSI] bfa: Modified the portstats get/clear logic
  [SCSI] bfa: Replace bfa_get_attr() with specific APIs
  [SCSI] bfa: New portlog entries for events (FIP/FLOGI/FDISC/LOGO).
  [SCSI] bfa: Rename pport to fcport in BFA FCS.
  [SCSI] bfa: IOC fixes, check for IOC down condition.
  [SCSI] bfa: In MSIX mode, ignore spurious RME interrupts when FCoE ports are in FW mismatch state.
  [SCSI] bfa: Fix Command Queue (CPE) full condition check and ack CPE interrupt.
  [SCSI] bfa: IOC recovery fix in fcmode.
  [SCSI] bfa: AEN and byte alignment fixes.
  [SCSI] bfa: Introduce a link notification state machine.
  [SCSI] bfa: Added firmware save clear feature for BFA driver.
  [SCSI] bfa: FCS authentication related changes.
  [SCSI] bfa: PCI VPD, FIP and include file changes.
  [SCSI] bfa: Fix to copy fpma MAC when requested by user space application.
  [SCSI] bfa: RPORT state machine: direct attach mode fix.
  ...

133 files changed:
drivers/infiniband/ulp/iser/iscsi_iser.c
drivers/scsi/Kconfig
drivers/scsi/be2iscsi/be_cmds.c
drivers/scsi/be2iscsi/be_iscsi.c
drivers/scsi/be2iscsi/be_main.c
drivers/scsi/be2iscsi/be_main.h
drivers/scsi/be2iscsi/be_mgmt.c
drivers/scsi/be2iscsi/be_mgmt.h
drivers/scsi/bfa/Makefile
drivers/scsi/bfa/bfa_core.c
drivers/scsi/bfa/bfa_fcport.c
drivers/scsi/bfa/bfa_fcs.c
drivers/scsi/bfa/bfa_fcs_lport.c
drivers/scsi/bfa/bfa_fcs_port.c
drivers/scsi/bfa/bfa_fcs_uf.c
drivers/scsi/bfa/bfa_hw_cb.c
drivers/scsi/bfa/bfa_hw_ct.c
drivers/scsi/bfa/bfa_intr.c
drivers/scsi/bfa/bfa_ioc.c
drivers/scsi/bfa/bfa_ioc.h
drivers/scsi/bfa/bfa_ioc_cb.c [new file with mode: 0644]
drivers/scsi/bfa/bfa_ioc_ct.c [new file with mode: 0644]
drivers/scsi/bfa/bfa_iocfc.c
drivers/scsi/bfa/bfa_iocfc.h
drivers/scsi/bfa/bfa_ioim.c
drivers/scsi/bfa/bfa_itnim.c
drivers/scsi/bfa/bfa_lps.c
drivers/scsi/bfa/bfa_module.c
drivers/scsi/bfa/bfa_modules_priv.h
drivers/scsi/bfa/bfa_port_priv.h
drivers/scsi/bfa/bfa_priv.h
drivers/scsi/bfa/bfa_rport.c
drivers/scsi/bfa/bfa_trcmod_priv.h
drivers/scsi/bfa/bfa_tskim.c
drivers/scsi/bfa/bfad.c
drivers/scsi/bfa/bfad_attr.c
drivers/scsi/bfa/bfad_attr.h
drivers/scsi/bfa/bfad_drv.h
drivers/scsi/bfa/bfad_im.c
drivers/scsi/bfa/bfad_im.h
drivers/scsi/bfa/bfad_intr.c
drivers/scsi/bfa/fabric.c
drivers/scsi/bfa/fcbuild.h
drivers/scsi/bfa/fcpim.c
drivers/scsi/bfa/fcs_fabric.h
drivers/scsi/bfa/fcs_fcpim.h
drivers/scsi/bfa/fcs_lport.h
drivers/scsi/bfa/fcs_port.h
drivers/scsi/bfa/fcs_rport.h
drivers/scsi/bfa/fcs_uf.h
drivers/scsi/bfa/fcs_vport.h
drivers/scsi/bfa/fdmi.c
drivers/scsi/bfa/include/aen/bfa_aen.h
drivers/scsi/bfa/include/bfa.h
drivers/scsi/bfa/include/bfa_svc.h
drivers/scsi/bfa/include/bfa_timer.h
drivers/scsi/bfa/include/bfi/bfi.h
drivers/scsi/bfa/include/bfi/bfi_cbreg.h
drivers/scsi/bfa/include/bfi/bfi_ctreg.h
drivers/scsi/bfa/include/bfi/bfi_ioc.h
drivers/scsi/bfa/include/bfi/bfi_lps.h
drivers/scsi/bfa/include/bfi/bfi_pport.h
drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h
drivers/scsi/bfa/include/cs/bfa_log.h
drivers/scsi/bfa/include/cs/bfa_plog.h
drivers/scsi/bfa/include/cs/bfa_sm.h
drivers/scsi/bfa/include/defs/bfa_defs_aen.h
drivers/scsi/bfa/include/defs/bfa_defs_auth.h
drivers/scsi/bfa/include/defs/bfa_defs_cee.h
drivers/scsi/bfa/include/defs/bfa_defs_driver.h
drivers/scsi/bfa/include/defs/bfa_defs_ethport.h
drivers/scsi/bfa/include/defs/bfa_defs_fcport.h [new file with mode: 0644]
drivers/scsi/bfa/include/defs/bfa_defs_im_common.h [deleted file]
drivers/scsi/bfa/include/defs/bfa_defs_im_team.h [deleted file]
drivers/scsi/bfa/include/defs/bfa_defs_ioc.h
drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h
drivers/scsi/bfa/include/defs/bfa_defs_lport.h
drivers/scsi/bfa/include/defs/bfa_defs_mfg.h
drivers/scsi/bfa/include/defs/bfa_defs_port.h
drivers/scsi/bfa/include/defs/bfa_defs_pport.h
drivers/scsi/bfa/include/defs/bfa_defs_status.h
drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h
drivers/scsi/bfa/include/fcs/bfa_fcs.h
drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h
drivers/scsi/bfa/include/log/bfa_log_hal.h
drivers/scsi/bfa/include/log/bfa_log_linux.h
drivers/scsi/bfa/include/protocol/fc.h
drivers/scsi/bfa/include/protocol/pcifw.h [deleted file]
drivers/scsi/bfa/loop.c
drivers/scsi/bfa/lport_api.c
drivers/scsi/bfa/ms.c
drivers/scsi/bfa/ns.c
drivers/scsi/bfa/rport.c
drivers/scsi/bfa/rport_api.c
drivers/scsi/bfa/rport_ftrs.c
drivers/scsi/bfa/scn.c
drivers/scsi/bfa/vport.c
drivers/scsi/bnx2i/bnx2i_iscsi.c
drivers/scsi/cxgb3i/cxgb3i_iscsi.c
drivers/scsi/device_handler/scsi_dh_emc.c
drivers/scsi/hpsa.c
drivers/scsi/hpsa.h
drivers/scsi/hpsa_cmd.h
drivers/scsi/ibmvscsi/ibmvfc.c
drivers/scsi/ibmvscsi/ibmvscsi.c
drivers/scsi/ibmvscsi/ibmvscsi.h
drivers/scsi/ibmvscsi/iseries_vscsi.c
drivers/scsi/ibmvscsi/rpa_vscsi.c
drivers/scsi/ipr.c
drivers/scsi/ipr.h
drivers/scsi/iscsi_tcp.c
drivers/scsi/libiscsi.c
drivers/scsi/lpfc/lpfc.h
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_bsg.c
drivers/scsi/lpfc/lpfc_bsg.h
drivers/scsi/lpfc/lpfc_crtn.h
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_hbadisc.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_logmsg.h
drivers/scsi/lpfc/lpfc_mbox.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/lpfc/lpfc_sli.h
drivers/scsi/lpfc/lpfc_sli4.h
drivers/scsi/lpfc/lpfc_version.h
drivers/scsi/lpfc/lpfc_vport.c
drivers/scsi/osd/osd_initiator.c
drivers/scsi/raid_class.c
drivers/scsi/scsi_transport_fc.c
drivers/scsi/sd.c
include/scsi/libiscsi.h

index 71237f8..e78af36 100644 (file)
@@ -613,7 +613,7 @@ static struct scsi_host_template iscsi_iser_sht = {
        .cmd_per_lun            = ISER_DEF_CMD_PER_LUN,
        .eh_abort_handler       = iscsi_eh_abort,
        .eh_device_reset_handler= iscsi_eh_device_reset,
-       .eh_target_reset_handler= iscsi_eh_target_reset,
+       .eh_target_reset_handler = iscsi_eh_recover_target,
        .target_alloc           = iscsi_target_alloc,
        .use_clustering         = DISABLE_CLUSTERING,
        .proc_name              = "iscsi_iser",
index 9191d1e..75f2336 100644 (file)
@@ -1,9 +1,15 @@
 menu "SCSI device support"
 
+config SCSI_MOD
+       tristate
+       default y if SCSI=n || SCSI=y
+       default m if SCSI=m
+
 config RAID_ATTRS
        tristate "RAID Transport Class"
        default n
        depends on BLOCK
+       depends on SCSI_MOD
        ---help---
          Provides RAID
 
index 6709857..cda6642 100644 (file)
@@ -32,18 +32,11 @@ void be_mcc_notify(struct beiscsi_hba *phba)
 unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
 {
        unsigned int tag = 0;
-       unsigned int num = 0;
 
-mcc_tag_rdy:
        if (phba->ctrl.mcc_tag_available) {
                tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index];
                phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
                phba->ctrl.mcc_numtag[tag] = 0;
-       } else {
-               udelay(100);
-               num++;
-               if (num < mcc_timeout)
-                       goto mcc_tag_rdy;
        }
        if (tag) {
                phba->ctrl.mcc_tag_available--;
index 29a3aaf..c3928cb 100644 (file)
@@ -482,7 +482,7 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
        tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep);
        if (!tag) {
                SE_DEBUG(DBG_LVL_1,
-                        "mgmt_invalidate_connection Failed for cid=%d \n",
+                        "mgmt_open_connection Failed for cid=%d \n",
                         beiscsi_ep->ep_cid);
        } else {
                wait_event_interruptible(phba->ctrl.mcc_wait[tag],
@@ -701,7 +701,7 @@ void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
        if (!tag) {
                SE_DEBUG(DBG_LVL_1,
                         "mgmt_invalidate_connection Failed for cid=%d \n",
-                        beiscsi_ep->ep_cid);
+                         beiscsi_ep->ep_cid);
        } else {
                wait_event_interruptible(phba->ctrl.mcc_wait[tag],
                                         phba->ctrl.mcc_numtag[tag]);
index 7c22616..fcfb29e 100644 (file)
@@ -58,6 +58,123 @@ static int beiscsi_slave_configure(struct scsi_device *sdev)
        return 0;
 }
 
+static int beiscsi_eh_abort(struct scsi_cmnd *sc)
+{
+       struct iscsi_cls_session *cls_session;
+       struct iscsi_task *aborted_task = (struct iscsi_task *)sc->SCp.ptr;
+       struct beiscsi_io_task *aborted_io_task;
+       struct iscsi_conn *conn;
+       struct beiscsi_conn *beiscsi_conn;
+       struct beiscsi_hba *phba;
+       struct iscsi_session *session;
+       struct invalidate_command_table *inv_tbl;
+       unsigned int cid, tag, num_invalidate;
+
+       cls_session = starget_to_session(scsi_target(sc->device));
+       session = cls_session->dd_data;
+
+       spin_lock_bh(&session->lock);
+       if (!aborted_task || !aborted_task->sc) {
+               /* we raced */
+               spin_unlock_bh(&session->lock);
+               return SUCCESS;
+       }
+
+       aborted_io_task = aborted_task->dd_data;
+       if (!aborted_io_task->scsi_cmnd) {
+               /* raced or invalid command */
+               spin_unlock_bh(&session->lock);
+               return SUCCESS;
+       }
+       spin_unlock_bh(&session->lock);
+       conn = aborted_task->conn;
+       beiscsi_conn = conn->dd_data;
+       phba = beiscsi_conn->phba;
+
+       /* invalidate iocb */
+       cid = beiscsi_conn->beiscsi_conn_cid;
+       inv_tbl = phba->inv_tbl;
+       memset(inv_tbl, 0x0, sizeof(*inv_tbl));
+       inv_tbl->cid = cid;
+       inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index;
+       num_invalidate = 1;
+       tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
+       if (!tag) {
+               shost_printk(KERN_WARNING, phba->shost,
+                            "mgmt_invalidate_icds could not be"
+                            " submitted\n");
+               return FAILED;
+       } else {
+               wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+                                        phba->ctrl.mcc_numtag[tag]);
+               free_mcc_tag(&phba->ctrl, tag);
+       }
+
+       return iscsi_eh_abort(sc);
+}
+
+static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
+{
+       struct iscsi_task *abrt_task;
+       struct beiscsi_io_task *abrt_io_task;
+       struct iscsi_conn *conn;
+       struct beiscsi_conn *beiscsi_conn;
+       struct beiscsi_hba *phba;
+       struct iscsi_session *session;
+       struct iscsi_cls_session *cls_session;
+       struct invalidate_command_table *inv_tbl;
+       unsigned int cid, tag, i, num_invalidate;
+       int rc = FAILED;
+
+       /* invalidate iocbs */
+       cls_session = starget_to_session(scsi_target(sc->device));
+       session = cls_session->dd_data;
+       spin_lock_bh(&session->lock);
+       if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN)
+               goto unlock;
+
+       conn = session->leadconn;
+       beiscsi_conn = conn->dd_data;
+       phba = beiscsi_conn->phba;
+       cid = beiscsi_conn->beiscsi_conn_cid;
+       inv_tbl = phba->inv_tbl;
+       memset(inv_tbl, 0x0, sizeof(*inv_tbl) * BE2_CMDS_PER_CXN);
+       num_invalidate = 0;
+       for (i = 0; i < conn->session->cmds_max; i++) {
+               abrt_task = conn->session->cmds[i];
+               abrt_io_task = abrt_task->dd_data;
+               if (!abrt_task->sc || abrt_task->state == ISCSI_TASK_FREE)
+                       continue;
+
+               if (abrt_task->sc->device->lun != abrt_task->sc->device->lun)
+                       continue;
+
+               inv_tbl->cid = cid;
+               inv_tbl->icd = abrt_io_task->psgl_handle->sgl_index;
+               num_invalidate++;
+               inv_tbl++;
+       }
+       spin_unlock_bh(&session->lock);
+       inv_tbl = phba->inv_tbl;
+
+       tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
+       if (!tag) {
+               shost_printk(KERN_WARNING, phba->shost,
+                            "mgmt_invalidate_icds could not be"
+                            " submitted\n");
+               return FAILED;
+       } else {
+               wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+                                        phba->ctrl.mcc_numtag[tag]);
+               free_mcc_tag(&phba->ctrl, tag);
+       }
+
+       return iscsi_eh_device_reset(sc);
+unlock:
+       spin_unlock_bh(&session->lock);
+       return rc;
+}
+
 /*------------------- PCI Driver operations and data ----------------- */
 static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
        { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
@@ -74,12 +191,12 @@ static struct scsi_host_template beiscsi_sht = {
        .name = "ServerEngines 10Gbe open-iscsi Initiator Driver",
        .proc_name = DRV_NAME,
        .queuecommand = iscsi_queuecommand,
-       .eh_abort_handler = iscsi_eh_abort,
        .change_queue_depth = iscsi_change_queue_depth,
        .slave_configure = beiscsi_slave_configure,
        .target_alloc = iscsi_target_alloc,
-       .eh_device_reset_handler = iscsi_eh_device_reset,
-       .eh_target_reset_handler = iscsi_eh_target_reset,
+       .eh_abort_handler = beiscsi_eh_abort,
+       .eh_device_reset_handler = beiscsi_eh_device_reset,
+       .eh_target_reset_handler = iscsi_eh_session_reset,
        .sg_tablesize = BEISCSI_SGLIST_ELEMENTS,
        .can_queue = BE2_IO_DEPTH,
        .this_id = -1,
@@ -242,7 +359,7 @@ static void beiscsi_get_params(struct beiscsi_hba *phba)
                                    + BE2_TMFS
                                    + BE2_NOPOUT_REQ));
        phba->params.cxns_per_ctrl = phba->fw_config.iscsi_cid_count;
-       phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count;;
+       phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count * 2;
        phba->params.icds_per_ctrl = phba->fw_config.iscsi_icd_count;;
        phba->params.num_sge_per_io = BE2_SGE;
        phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ;
@@ -946,14 +1063,18 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
        case HWH_TYPE_IO:
        case HWH_TYPE_IO_RD:
                if ((task->hdr->opcode & ISCSI_OPCODE_MASK) ==
-                   ISCSI_OP_NOOP_OUT) {
+                    ISCSI_OP_NOOP_OUT)
                        be_complete_nopin_resp(beiscsi_conn, task, psol);
-               } else
+               else
                        be_complete_io(beiscsi_conn, task, psol);
                break;
 
        case HWH_TYPE_LOGOUT:
-               be_complete_logout(beiscsi_conn, task, psol);
+               if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT)
+                       be_complete_logout(beiscsi_conn, task, psol);
+               else
+                       be_complete_tmf(beiscsi_conn, task, psol);
+
                break;
 
        case HWH_TYPE_LOGIN:
@@ -962,10 +1083,6 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
                         "- Solicited path \n");
                break;
 
-       case HWH_TYPE_TMF:
-               be_complete_tmf(beiscsi_conn, task, psol);
-               break;
-
        case HWH_TYPE_NOP:
                be_complete_nopin_resp(beiscsi_conn, task, psol);
                break;
@@ -2052,7 +2169,7 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
        num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) /
                      ((sizeof(struct iscsi_wrb) *
                        phba->params.wrbs_per_cxn));
-       for (index = 0; index < phba->params.cxns_per_ctrl; index += 2) {
+       for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) {
                pwrb_context = &phwi_ctrlr->wrb_context[index];
                if (num_cxn_wrb) {
                        for (j = 0; j < phba->params.wrbs_per_cxn; j++) {
@@ -3073,14 +3190,18 @@ static unsigned char hwi_enable_intr(struct beiscsi_hba *phba)
                reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
                SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr);
                iowrite32(reg, addr);
-               for (i = 0; i <= phba->num_cpus; i++) {
-                       eq = &phwi_context->be_eq[i].q;
+               if (!phba->msix_enabled) {
+                       eq = &phwi_context->be_eq[0].q;
                        SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
                        hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
+               } else {
+                       for (i = 0; i <= phba->num_cpus; i++) {
+                               eq = &phwi_context->be_eq[i].q;
+                               SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
+                               hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
+                       }
                }
-       } else
-               shost_printk(KERN_WARNING, phba->shost,
-                            "In hwi_enable_intr, Not Enabled \n");
+       }
        return true;
 }
 
@@ -3476,19 +3597,13 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg,
 
 static int beiscsi_mtask(struct iscsi_task *task)
 {
-       struct beiscsi_io_task *aborted_io_task, *io_task = task->dd_data;
+       struct beiscsi_io_task *io_task = task->dd_data;
        struct iscsi_conn *conn = task->conn;
        struct beiscsi_conn *beiscsi_conn = conn->dd_data;
        struct beiscsi_hba *phba = beiscsi_conn->phba;
-       struct iscsi_session *session;
        struct iscsi_wrb *pwrb = NULL;
-       struct hwi_controller *phwi_ctrlr;
-       struct hwi_wrb_context *pwrb_context;
-       struct wrb_handle *pwrb_handle;
        unsigned int doorbell = 0;
-       unsigned int i, cid;
-       struct iscsi_task *aborted_task;
-       unsigned int tag;
+       unsigned int cid;
 
        cid = beiscsi_conn->beiscsi_conn_cid;
        pwrb = io_task->pwrb_handle->pwrb;
@@ -3499,6 +3614,7 @@ static int beiscsi_mtask(struct iscsi_task *task)
                      io_task->pwrb_handle->wrb_index);
        AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb,
                      io_task->psgl_handle->sgl_index);
+
        switch (task->hdr->opcode & ISCSI_OPCODE_MASK) {
        case ISCSI_OP_LOGIN:
                AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
@@ -3523,33 +3639,6 @@ static int beiscsi_mtask(struct iscsi_task *task)
                hwi_write_buffer(pwrb, task);
                break;
        case ISCSI_OP_SCSI_TMFUNC:
-               session = conn->session;
-               i = ((struct iscsi_tm *)task->hdr)->rtt;
-               phwi_ctrlr = phba->phwi_ctrlr;
-               pwrb_context = &phwi_ctrlr->wrb_context[cid -
-                                           phba->fw_config.iscsi_cid_start];
-               pwrb_handle = pwrb_context->pwrb_handle_basestd[be32_to_cpu(i)
-                                                               >> 16];
-               aborted_task = pwrb_handle->pio_handle;
-                if (!aborted_task)
-                       return 0;
-
-               aborted_io_task = aborted_task->dd_data;
-               if (!aborted_io_task->scsi_cmnd)
-                       return 0;
-
-               tag = mgmt_invalidate_icds(phba,
-                                    aborted_io_task->psgl_handle->sgl_index,
-                                    cid);
-               if (!tag) {
-                       shost_printk(KERN_WARNING, phba->shost,
-                                    "mgmt_invalidate_icds could not be"
-                                    " submitted\n");
-               } else {
-                       wait_event_interruptible(phba->ctrl.mcc_wait[tag],
-                                                phba->ctrl.mcc_numtag[tag]);
-                       free_mcc_tag(&phba->ctrl, tag);
-               }
                AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
                              INI_TMF_CMD);
                AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
@@ -3558,7 +3647,7 @@ static int beiscsi_mtask(struct iscsi_task *task)
        case ISCSI_OP_LOGOUT:
                AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
                AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
-                               HWH_TYPE_LOGOUT);
+                             HWH_TYPE_LOGOUT);
                hwi_write_buffer(pwrb, task);
                break;
 
@@ -3584,17 +3673,12 @@ static int beiscsi_mtask(struct iscsi_task *task)
 
 static int beiscsi_task_xmit(struct iscsi_task *task)
 {
-       struct iscsi_conn *conn = task->conn;
        struct beiscsi_io_task *io_task = task->dd_data;
        struct scsi_cmnd *sc = task->sc;
-       struct beiscsi_conn *beiscsi_conn = conn->dd_data;
        struct scatterlist *sg;
        int num_sg;
        unsigned int  writedir = 0, xferlen = 0;
 
-       SE_DEBUG(DBG_LVL_4, "\n cid=%d In beiscsi_task_xmit task=%p conn=%p \t"
-                "beiscsi_conn=%p \n", beiscsi_conn->beiscsi_conn_cid,
-                task, conn, beiscsi_conn);
        if (!sc)
                return beiscsi_mtask(task);
 
@@ -3699,7 +3783,6 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
                        " Failed in beiscsi_hba_alloc \n");
                goto disable_pci;
        }
-       SE_DEBUG(DBG_LVL_8, " phba = %p \n", phba);
 
        switch (pcidev->device) {
        case BE_DEVICE_ID1:
index c53a80a..87ec212 100644 (file)
@@ -257,6 +257,11 @@ struct hba_parameters {
        unsigned int num_sge;
 };
 
+struct invalidate_command_table {
+       unsigned short icd;
+       unsigned short cid;
+} __packed;
+
 struct beiscsi_hba {
        struct hba_parameters params;
        struct hwi_controller *phwi_ctrlr;
@@ -329,6 +334,8 @@ struct beiscsi_hba {
        struct work_struct work_cqs;    /* The work being queued */
        struct be_ctrl_info ctrl;
        unsigned int generation;
+       struct invalidate_command_table inv_tbl[128];
+
 };
 
 struct beiscsi_session {
@@ -491,8 +498,6 @@ struct hwi_async_entry {
        struct list_head data_busy_list;
 };
 
-#define BE_MIN_ASYNC_ENTRIES 128
-
 struct hwi_async_pdu_context {
        struct {
                struct be_bus_address pa_base;
@@ -533,7 +538,7 @@ struct hwi_async_pdu_context {
         * This is a varying size list! Do not add anything
         * after this entry!!
         */
-       struct hwi_async_entry async_entry[BE_MIN_ASYNC_ENTRIES];
+       struct hwi_async_entry async_entry[BE2_MAX_SESSIONS * 2];
 };
 
 #define PDUCQE_CODE_MASK       0x0000003F
index 317bcd0..72617b6 100644 (file)
@@ -145,14 +145,15 @@ unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
 }
 
 unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
-                                  unsigned int icd, unsigned int cid)
+                               struct invalidate_command_table *inv_tbl,
+                               unsigned int num_invalidate, unsigned int cid)
 {
        struct be_dma_mem nonemb_cmd;
        struct be_ctrl_info *ctrl = &phba->ctrl;
        struct be_mcc_wrb *wrb;
        struct be_sge *sge;
        struct invalidate_commands_params_in *req;
-       unsigned int tag = 0;
+       unsigned int i, tag = 0;
 
        spin_lock(&ctrl->mbox_lock);
        tag = alloc_mcc_tag(phba);
@@ -183,9 +184,12 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
                        sizeof(*req));
        req->ref_handle = 0;
        req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
-       req->icd_count = 0;
-       req->table[req->icd_count].icd = icd;
-       req->table[req->icd_count].cid = cid;
+       for (i = 0; i < num_invalidate; i++) {
+               req->table[i].icd = inv_tbl->icd;
+               req->table[i].cid = inv_tbl->cid;
+               req->icd_count++;
+               inv_tbl++;
+       }
        sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
        sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
        sge->len = cpu_to_le32(nonemb_cmd.size);
index ecead6a..3d316b8 100644 (file)
@@ -94,7 +94,8 @@ unsigned char mgmt_upload_connection(struct beiscsi_hba *phba,
                                     unsigned short cid,
                                     unsigned int upload_flag);
 unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
-                                  unsigned int icd, unsigned int cid);
+                               struct invalidate_command_table *inv_tbl,
+                               unsigned int num_invalidate, unsigned int cid);
 
 struct iscsi_invalidate_connection_params_in {
        struct be_cmd_req_hdr hdr;
@@ -116,11 +117,6 @@ union iscsi_invalidate_connection_params {
        struct iscsi_invalidate_connection_params_out response;
 } __packed;
 
-struct invalidate_command_table {
-       unsigned short icd;
-       unsigned short cid;
-} __packed;
-
 struct invalidate_commands_params_in {
        struct be_cmd_req_hdr hdr;
        unsigned int ref_handle;
index 1d60094..17e06ca 100644 (file)
@@ -2,14 +2,14 @@ obj-$(CONFIG_SCSI_BFA_FC) := bfa.o
 
 bfa-y := bfad.o bfad_intr.o bfad_os.o bfad_im.o bfad_attr.o bfad_fwimg.o
 
-bfa-y += bfa_core.o bfa_ioc.o bfa_iocfc.o bfa_fcxp.o bfa_lps.o
-bfa-y += bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o 
+bfa-y += bfa_core.o bfa_ioc.o bfa_ioc_ct.o bfa_ioc_cb.o bfa_iocfc.o bfa_fcxp.o
+bfa-y += bfa_lps.o bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o
 bfa-y += bfa_fcport.o bfa_port.o bfa_uf.o bfa_sgpg.o bfa_module.o bfa_ioim.o
 bfa-y += bfa_itnim.o bfa_fcpim.o bfa_tskim.o bfa_log.o bfa_log_module.o
 bfa-y += bfa_csdebug.o bfa_sm.o plog.o
 
-bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o 
+bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o
 bfa-y += bfa_fcs_uf.o bfa_fcs_lport.o fab.o fdmi.o ms.o ns.o scn.o loop.o
 bfa-y += lport_api.o n2n.o rport.o rport_api.o rport_ftrs.o vport.o
 
-ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna
+ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna -DBFA_PERF_BUILD
index 44e2d11..0c08e18 100644 (file)
@@ -385,6 +385,15 @@ bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen)
 }
 
 /**
+ * Clear the saved firmware trace information of an IOC.
+ */
+void
+bfa_debug_fwsave_clear(struct bfa_s *bfa)
+{
+       bfa_ioc_debug_fwsave_clear(&bfa->ioc);
+}
+
+/**
  *             Fetch firmware trace data.
  *
  * @param[in]          bfa                     BFA instance
@@ -399,4 +408,14 @@ bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen)
 {
        return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen);
 }
+
+/**
+ * Reset hw semaphore & usage cnt regs and initialize.
+ */
+void
+bfa_chip_reset(struct bfa_s *bfa)
+{
+       bfa_ioc_ownership_reset(&bfa->ioc);
+       bfa_ioc_pll_init(&bfa->ioc);
+}
 #endif
index aef648b..c589488 100644 (file)
 #include <cs/bfa_plog.h>
 #include <aen/bfa_aen_port.h>
 
-BFA_TRC_FILE(HAL, PPORT);
-BFA_MODULE(pport);
-
-#define bfa_pport_callback(__pport, __event) do {                      \
-       if ((__pport)->bfa->fcs) {      \
-               (__pport)->event_cbfn((__pport)->event_cbarg, (__event));      \
-       } else {                                                        \
-               (__pport)->hcb_event = (__event);      \
-               bfa_cb_queue((__pport)->bfa, &(__pport)->hcb_qe,        \
-               __bfa_cb_port_event, (__pport));      \
-       }                                                               \
-} while (0)
+BFA_TRC_FILE(HAL, FCPORT);
+BFA_MODULE(fcport);
 
 /*
  * The port is considered disabled if corresponding physical port or IOC are
  * disabled explicitly
  */
 #define BFA_PORT_IS_DISABLED(bfa) \
-       ((bfa_pport_is_disabled(bfa) == BFA_TRUE) || \
+       ((bfa_fcport_is_disabled(bfa) == BFA_TRUE) || \
        (bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE))
 
 /*
  * forward declarations
  */
-static bfa_boolean_t bfa_pport_send_enable(struct bfa_pport_s *port);
-static bfa_boolean_t bfa_pport_send_disable(struct bfa_pport_s *port);
-static void     bfa_pport_update_linkinfo(struct bfa_pport_s *pport);
-static void     bfa_pport_reset_linkinfo(struct bfa_pport_s *pport);
-static void     bfa_pport_set_wwns(struct bfa_pport_s *port);
-static void     __bfa_cb_port_event(void *cbarg, bfa_boolean_t complete);
-static void     __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete);
-static void     __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete);
-static void     bfa_port_stats_timeout(void *cbarg);
-static void     bfa_port_stats_clr_timeout(void *cbarg);
+static bfa_boolean_t bfa_fcport_send_enable(struct bfa_fcport_s *fcport);
+static bfa_boolean_t bfa_fcport_send_disable(struct bfa_fcport_s *fcport);
+static void     bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport);
+static void     bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport);
+static void     bfa_fcport_set_wwns(struct bfa_fcport_s *fcport);
+static void     __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete);
+static void     bfa_fcport_callback(struct bfa_fcport_s *fcport,
+                               enum bfa_pport_linkstate event);
+static void     bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln,
+                               enum bfa_pport_linkstate event);
+static void     __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete);
+static void     bfa_fcport_stats_get_timeout(void *cbarg);
+static void     bfa_fcport_stats_clr_timeout(void *cbarg);
 
 /**
  *  bfa_pport_private
@@ -65,111 +58,114 @@ static void     bfa_port_stats_clr_timeout(void *cbarg);
 /**
  * BFA port state machine events
  */
-enum bfa_pport_sm_event {
-       BFA_PPORT_SM_START = 1, /*  start port state machine */
-       BFA_PPORT_SM_STOP = 2,  /*  stop port state machine */
-       BFA_PPORT_SM_ENABLE = 3,        /*  enable port */
-       BFA_PPORT_SM_DISABLE = 4,       /*  disable port state machine */
-       BFA_PPORT_SM_FWRSP = 5, /*  firmware enable/disable rsp */
-       BFA_PPORT_SM_LINKUP = 6,        /*  firmware linkup event */
-       BFA_PPORT_SM_LINKDOWN = 7,      /*  firmware linkup down */
-       BFA_PPORT_SM_QRESUME = 8,       /*  CQ space available */
-       BFA_PPORT_SM_HWFAIL = 9,        /*  IOC h/w failure */
+enum bfa_fcport_sm_event {
+       BFA_FCPORT_SM_START = 1,        /*  start port state machine */
+       BFA_FCPORT_SM_STOP = 2, /*  stop port state machine */
+       BFA_FCPORT_SM_ENABLE = 3,       /*  enable port */
+       BFA_FCPORT_SM_DISABLE = 4,      /*  disable port state machine */
+       BFA_FCPORT_SM_FWRSP = 5,        /*  firmware enable/disable rsp */
+       BFA_FCPORT_SM_LINKUP = 6,       /*  firmware linkup event */
+       BFA_FCPORT_SM_LINKDOWN = 7,     /*  firmware linkup down */
+       BFA_FCPORT_SM_QRESUME = 8,      /*  CQ space available */
+       BFA_FCPORT_SM_HWFAIL = 9,       /*  IOC h/w failure */
 };
 
-static void     bfa_pport_sm_uninit(struct bfa_pport_s *pport,
-                                   enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport,
-                                           enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_enabling(struct bfa_pport_s *pport,
-                                     enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_linkdown(struct bfa_pport_s *pport,
-                                     enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_linkup(struct bfa_pport_s *pport,
-                                   enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_disabling(struct bfa_pport_s *pport,
-                                      enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport,
-                                            enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_disabled(struct bfa_pport_s *pport,
-                                     enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_stopped(struct bfa_pport_s *pport,
-                                    enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_iocdown(struct bfa_pport_s *pport,
-                                    enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_iocfail(struct bfa_pport_s *pport,
-                                    enum bfa_pport_sm_event event);
+/**
+ * BFA port link notification state machine events
+ */
+
+enum bfa_fcport_ln_sm_event {
+       BFA_FCPORT_LN_SM_LINKUP         = 1,    /*  linkup event */
+       BFA_FCPORT_LN_SM_LINKDOWN       = 2,    /*  linkdown event */
+       BFA_FCPORT_LN_SM_NOTIFICATION   = 3     /*  done notification */
+};
+
+static void     bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
+                                       enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
+                                               enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
+                                               enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
+                                               enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
+                                               enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
+                                               enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
+                                               enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
+                                               enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
+                                        enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
+                                        enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
+                                        enum bfa_fcport_sm_event event);
+
+static void     bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
+                                        enum bfa_fcport_ln_sm_event event);
+static void     bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
+                                        enum bfa_fcport_ln_sm_event event);
+static void     bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
+                                        enum bfa_fcport_ln_sm_event event);
+static void     bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
+                                        enum bfa_fcport_ln_sm_event event);
+static void     bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
+                                        enum bfa_fcport_ln_sm_event event);
+static void     bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln,
+                                        enum bfa_fcport_ln_sm_event event);
+static void     bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
+                                        enum bfa_fcport_ln_sm_event event);
 
 static struct bfa_sm_table_s hal_pport_sm_table[] = {
-       {BFA_SM(bfa_pport_sm_uninit), BFA_PPORT_ST_UNINIT},
-       {BFA_SM(bfa_pport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT},
-       {BFA_SM(bfa_pport_sm_enabling), BFA_PPORT_ST_ENABLING},
-       {BFA_SM(bfa_pport_sm_linkdown), BFA_PPORT_ST_LINKDOWN},
-       {BFA_SM(bfa_pport_sm_linkup), BFA_PPORT_ST_LINKUP},
-       {BFA_SM(bfa_pport_sm_disabling_qwait),
-        BFA_PPORT_ST_DISABLING_QWAIT},
-       {BFA_SM(bfa_pport_sm_disabling), BFA_PPORT_ST_DISABLING},
-       {BFA_SM(bfa_pport_sm_disabled), BFA_PPORT_ST_DISABLED},
-       {BFA_SM(bfa_pport_sm_stopped), BFA_PPORT_ST_STOPPED},
-       {BFA_SM(bfa_pport_sm_iocdown), BFA_PPORT_ST_IOCDOWN},
-       {BFA_SM(bfa_pport_sm_iocfail), BFA_PPORT_ST_IOCDOWN},
+       {BFA_SM(bfa_fcport_sm_uninit), BFA_PPORT_ST_UNINIT},
+       {BFA_SM(bfa_fcport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT},
+       {BFA_SM(bfa_fcport_sm_enabling), BFA_PPORT_ST_ENABLING},
+       {BFA_SM(bfa_fcport_sm_linkdown), BFA_PPORT_ST_LINKDOWN},
+       {BFA_SM(bfa_fcport_sm_linkup), BFA_PPORT_ST_LINKUP},
+       {BFA_SM(bfa_fcport_sm_disabling_qwait), BFA_PPORT_ST_DISABLING_QWAIT},
+       {BFA_SM(bfa_fcport_sm_disabling), BFA_PPORT_ST_DISABLING},
+       {BFA_SM(bfa_fcport_sm_disabled), BFA_PPORT_ST_DISABLED},
+       {BFA_SM(bfa_fcport_sm_stopped), BFA_PPORT_ST_STOPPED},
+       {BFA_SM(bfa_fcport_sm_iocdown), BFA_PPORT_ST_IOCDOWN},
+       {BFA_SM(bfa_fcport_sm_iocfail), BFA_PPORT_ST_IOCDOWN},
 };
 
 static void
-bfa_pport_aen_post(struct bfa_pport_s *pport, enum bfa_port_aen_event event)
+bfa_fcport_aen_post(struct bfa_fcport_s *fcport, enum bfa_port_aen_event event)
 {
        union bfa_aen_data_u aen_data;
-       struct bfa_log_mod_s *logmod = pport->bfa->logm;
-       wwn_t           pwwn = pport->pwwn;
+       struct bfa_log_mod_s *logmod = fcport->bfa->logm;
+       wwn_t           pwwn = fcport->pwwn;
        char            pwwn_ptr[BFA_STRING_32];
-       struct bfa_ioc_attr_s ioc_attr;
 
+       memset(&aen_data, 0, sizeof(aen_data));
        wwn2str(pwwn_ptr, pwwn);
-       switch (event) {
-       case BFA_PORT_AEN_ONLINE:
-               bfa_log(logmod, BFA_AEN_PORT_ONLINE, pwwn_ptr);
-               break;
-       case BFA_PORT_AEN_OFFLINE:
-               bfa_log(logmod, BFA_AEN_PORT_OFFLINE, pwwn_ptr);
-               break;
-       case BFA_PORT_AEN_ENABLE:
-               bfa_log(logmod, BFA_AEN_PORT_ENABLE, pwwn_ptr);
-               break;
-       case BFA_PORT_AEN_DISABLE:
-               bfa_log(logmod, BFA_AEN_PORT_DISABLE, pwwn_ptr);
-               break;
-       case BFA_PORT_AEN_DISCONNECT:
-               bfa_log(logmod, BFA_AEN_PORT_DISCONNECT, pwwn_ptr);
-               break;
-       case BFA_PORT_AEN_QOS_NEG:
-               bfa_log(logmod, BFA_AEN_PORT_QOS_NEG, pwwn_ptr);
-               break;
-       default:
-               break;
-       }
+       bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, event), pwwn_ptr);
 
-       bfa_ioc_get_attr(&pport->bfa->ioc, &ioc_attr);
-       aen_data.port.ioc_type = ioc_attr.ioc_type;
+       aen_data.port.ioc_type = bfa_get_type(fcport->bfa);
        aen_data.port.pwwn = pwwn;
 }
 
 static void
-bfa_pport_sm_uninit(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
+                       enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_START:
+       case BFA_FCPORT_SM_START:
                /**
                 * Start event after IOC is configured and BFA is started.
                 */
-               if (bfa_pport_send_enable(pport))
-                       bfa_sm_set_state(pport, bfa_pport_sm_enabling);
+               if (bfa_fcport_send_enable(fcport))
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
                else
-                       bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
                break;
 
-       case BFA_PPORT_SM_ENABLE:
+       case BFA_FCPORT_SM_ENABLE:
                /**
                 * Port is persistently configured to be in enabled state. Do
                 * not change state. Port enabling is done when START event is
@@ -177,389 +173,412 @@ bfa_pport_sm_uninit(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
                 */
                break;
 
-       case BFA_PPORT_SM_DISABLE:
+       case BFA_FCPORT_SM_DISABLE:
                /**
                 * If a port is persistently configured to be disabled, the
                 * first event will a port disable request.
                 */
-               bfa_sm_set_state(pport, bfa_pport_sm_disabled);
+               bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
                break;
 
-       case BFA_PPORT_SM_HWFAIL:
-               bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
+       case BFA_FCPORT_SM_HWFAIL:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
                break;
 
        default:
-               bfa_sm_fault(pport->bfa, event);
+               bfa_sm_fault(fcport->bfa, event);
        }
 }
 
 static void
-bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport,
-                           enum bfa_pport_sm_event event)
+bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
+                           enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_QRESUME:
-               bfa_sm_set_state(pport, bfa_pport_sm_enabling);
-               bfa_pport_send_enable(pport);
+       case BFA_FCPORT_SM_QRESUME:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
+               bfa_fcport_send_enable(fcport);
                break;
 
-       case BFA_PPORT_SM_STOP:
-               bfa_reqq_wcancel(&pport->reqq_wait);
-               bfa_sm_set_state(pport, bfa_pport_sm_stopped);
+       case BFA_FCPORT_SM_STOP:
+               bfa_reqq_wcancel(&fcport->reqq_wait);
+               bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
                break;
 
-       case BFA_PPORT_SM_ENABLE:
+       case BFA_FCPORT_SM_ENABLE:
                /**
                 * Already enable is in progress.
                 */
                break;
 
-       case BFA_PPORT_SM_DISABLE:
+       case BFA_FCPORT_SM_DISABLE:
                /**
                 * Just send disable request to firmware when room becomes
                 * available in request queue.
                 */
-               bfa_sm_set_state(pport, bfa_pport_sm_disabled);
-               bfa_reqq_wcancel(&pport->reqq_wait);
-               bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+               bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
+               bfa_reqq_wcancel(&fcport->reqq_wait);
+               bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                             BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
-               bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
+               bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
                break;
 
-       case BFA_PPORT_SM_LINKUP:
-       case BFA_PPORT_SM_LINKDOWN:
+       case BFA_FCPORT_SM_LINKUP:
+       case BFA_FCPORT_SM_LINKDOWN:
                /**
                 * Possible to get link events when doing back-to-back
                 * enable/disables.
                 */
                break;
 
-       case BFA_PPORT_SM_HWFAIL:
-               bfa_reqq_wcancel(&pport->reqq_wait);
-               bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
+       case BFA_FCPORT_SM_HWFAIL:
+               bfa_reqq_wcancel(&fcport->reqq_wait);
+               bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
                break;
 
        default:
-               bfa_sm_fault(pport->bfa, event);
+               bfa_sm_fault(fcport->bfa, event);
        }
 }
 
 static void
-bfa_pport_sm_enabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
+               enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_FWRSP:
-       case BFA_PPORT_SM_LINKDOWN:
-               bfa_sm_set_state(pport, bfa_pport_sm_linkdown);
+       case BFA_FCPORT_SM_FWRSP:
+       case BFA_FCPORT_SM_LINKDOWN:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown);
                break;
 
-       case BFA_PPORT_SM_LINKUP:
-               bfa_pport_update_linkinfo(pport);
-               bfa_sm_set_state(pport, bfa_pport_sm_linkup);
+       case BFA_FCPORT_SM_LINKUP:
+               bfa_fcport_update_linkinfo(fcport);
+               bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
 
-               bfa_assert(pport->event_cbfn);
-               bfa_pport_callback(pport, BFA_PPORT_LINKUP);
+               bfa_assert(fcport->event_cbfn);
+               bfa_fcport_callback(fcport, BFA_PPORT_LINKUP);
                break;
 
-       case BFA_PPORT_SM_ENABLE:
+       case BFA_FCPORT_SM_ENABLE:
                /**
                 * Already being enabled.
                 */
                break;
 
-       case BFA_PPORT_SM_DISABLE:
-               if (bfa_pport_send_disable(pport))
-                       bfa_sm_set_state(pport, bfa_pport_sm_disabling);
+       case BFA_FCPORT_SM_DISABLE:
+               if (bfa_fcport_send_disable(fcport))
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
                else
-                       bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
 
-               bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+               bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                             BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
-               bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
+               bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
                break;
 
-       case BFA_PPORT_SM_STOP:
-               bfa_sm_set_state(pport, bfa_pport_sm_stopped);
+       case BFA_FCPORT_SM_STOP:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
                break;
 
-       case BFA_PPORT_SM_HWFAIL:
-               bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
+       case BFA_FCPORT_SM_HWFAIL:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
                break;
 
        default:
-               bfa_sm_fault(pport->bfa, event);
+               bfa_sm_fault(fcport->bfa, event);
        }
 }
 
 static void
-bfa_pport_sm_linkdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
+                       enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event;
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_LINKUP:
-               bfa_pport_update_linkinfo(pport);
-               bfa_sm_set_state(pport, bfa_pport_sm_linkup);
-               bfa_assert(pport->event_cbfn);
-               bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+       case BFA_FCPORT_SM_LINKUP:
+               bfa_fcport_update_linkinfo(fcport);
+               bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
+               bfa_assert(fcport->event_cbfn);
+               bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                             BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup");
-               bfa_pport_callback(pport, BFA_PPORT_LINKUP);
-               bfa_pport_aen_post(pport, BFA_PORT_AEN_ONLINE);
+
+               if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
+
+                       bfa_trc(fcport->bfa, pevent->link_state.fcf.fipenabled);
+                       bfa_trc(fcport->bfa, pevent->link_state.fcf.fipfailed);
+
+                       if (pevent->link_state.fcf.fipfailed)
+                               bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
+                                       BFA_PL_EID_FIP_FCF_DISC, 0,
+                                       "FIP FCF Discovery Failed");
+                       else
+                               bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
+                                       BFA_PL_EID_FIP_FCF_DISC, 0,
+                                       "FIP FCF Discovered");
+               }
+
+               bfa_fcport_callback(fcport, BFA_PPORT_LINKUP);
+               bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ONLINE);
                /**
                 * If QoS is enabled and it is not online,
                 * Send a separate event.
                 */
-               if ((pport->cfg.qos_enabled)
-                   && (bfa_os_ntohl(pport->qos_attr.state) != BFA_QOS_ONLINE))
-                       bfa_pport_aen_post(pport, BFA_PORT_AEN_QOS_NEG);
+               if ((fcport->cfg.qos_enabled)
+                   && (bfa_os_ntohl(fcport->qos_attr.state) != BFA_QOS_ONLINE))
+                       bfa_fcport_aen_post(fcport, BFA_PORT_AEN_QOS_NEG);
 
                break;
 
-       case BFA_PPORT_SM_LINKDOWN:
+       case BFA_FCPORT_SM_LINKDOWN:
                /**
                 * Possible to get link down event.
                 */
                break;
 
-       case BFA_PPORT_SM_ENABLE:
+       case BFA_FCPORT_SM_ENABLE:
                /**
                 * Already enabled.
                 */
                break;
 
-       case BFA_PPORT_SM_DISABLE:
-               if (bfa_pport_send_disable(pport))
-                       bfa_sm_set_state(pport, bfa_pport_sm_disabling);
+       case BFA_FCPORT_SM_DISABLE:
+               if (bfa_fcport_send_disable(fcport))
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
                else
-                       bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
 
-               bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+               bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                             BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
-               bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
+               bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
                break;
 
-       case BFA_PPORT_SM_STOP:
-               bfa_sm_set_state(pport, bfa_pport_sm_stopped);
+       case BFA_FCPORT_SM_STOP:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
                break;
 
-       case BFA_PPORT_SM_HWFAIL:
-               bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
+       case BFA_FCPORT_SM_HWFAIL:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
                break;
 
        default:
-               bfa_sm_fault(pport->bfa, event);
+               bfa_sm_fault(fcport->bfa, event);
        }
 }
 
 static void
-bfa_pport_sm_linkup(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
+                       enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_ENABLE:
+       case BFA_FCPORT_SM_ENABLE:
                /**
                 * Already enabled.
                 */
                break;
 
-       case BFA_PPORT_SM_DISABLE:
-               if (bfa_pport_send_disable(pport))
-                       bfa_sm_set_state(pport, bfa_pport_sm_disabling);
+       case BFA_FCPORT_SM_DISABLE:
+               if (bfa_fcport_send_disable(fcport))
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
                else
-                       bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
 
-               bfa_pport_reset_linkinfo(pport);
-               bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
-               bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+               bfa_fcport_reset_linkinfo(fcport);
+               bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
+               bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                             BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
-               bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
-               bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
+               bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
+               bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
                break;
 
-       case BFA_PPORT_SM_LINKDOWN:
-               bfa_sm_set_state(pport, bfa_pport_sm_linkdown);
-               bfa_pport_reset_linkinfo(pport);
-               bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
-               bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+       case BFA_FCPORT_SM_LINKDOWN:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown);
+               bfa_fcport_reset_linkinfo(fcport);
+               bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
+               bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                             BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown");
-               if (BFA_PORT_IS_DISABLED(pport->bfa))
-                       bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
+               if (BFA_PORT_IS_DISABLED(fcport->bfa))
+                       bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
                else
-                       bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
+                       bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
                break;
 
-       case BFA_PPORT_SM_STOP:
-               bfa_sm_set_state(pport, bfa_pport_sm_stopped);
-               bfa_pport_reset_linkinfo(pport);
-               if (BFA_PORT_IS_DISABLED(pport->bfa))
-                       bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
+       case BFA_FCPORT_SM_STOP:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
+               bfa_fcport_reset_linkinfo(fcport);
+               if (BFA_PORT_IS_DISABLED(fcport->bfa))
+                       bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
                else
-                       bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
+                       bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
                break;
 
-       case BFA_PPORT_SM_HWFAIL:
-               bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
-               bfa_pport_reset_linkinfo(pport);
-               bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
-               if (BFA_PORT_IS_DISABLED(pport->bfa))
-                       bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
+       case BFA_FCPORT_SM_HWFAIL:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
+               bfa_fcport_reset_linkinfo(fcport);
+               bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
+               if (BFA_PORT_IS_DISABLED(fcport->bfa))
+                       bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
                else
-                       bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
+                       bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
                break;
 
        default:
-               bfa_sm_fault(pport->bfa, event);
+               bfa_sm_fault(fcport->bfa, event);
        }
 }
 
 static void
-bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport,
-                            enum bfa_pport_sm_event event)
+bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
+                            enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_QRESUME:
-               bfa_sm_set_state(pport, bfa_pport_sm_disabling);
-               bfa_pport_send_disable(pport);
+       case BFA_FCPORT_SM_QRESUME:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
+               bfa_fcport_send_disable(fcport);
                break;
 
-       case BFA_PPORT_SM_STOP:
-               bfa_sm_set_state(pport, bfa_pport_sm_stopped);
-               bfa_reqq_wcancel(&pport->reqq_wait);
+       case BFA_FCPORT_SM_STOP:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
+               bfa_reqq_wcancel(&fcport->reqq_wait);
                break;
 
-       case BFA_PPORT_SM_DISABLE:
+       case BFA_FCPORT_SM_DISABLE:
                /**
                 * Already being disabled.
                 */
                break;
 
-       case BFA_PPORT_SM_LINKUP:
-       case BFA_PPORT_SM_LINKDOWN:
+       case BFA_FCPORT_SM_LINKUP:
+       case BFA_FCPORT_SM_LINKDOWN:
                /**
                 * Possible to get link events when doing back-to-back
                 * enable/disables.
                 */
                break;
 
-       case BFA_PPORT_SM_HWFAIL:
-               bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
-               bfa_reqq_wcancel(&pport->reqq_wait);
+       case BFA_FCPORT_SM_HWFAIL:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
+               bfa_reqq_wcancel(&fcport->reqq_wait);
                break;
 
        default:
-               bfa_sm_fault(pport->bfa, event);
+               bfa_sm_fault(fcport->bfa, event);
        }
 }
 
 static void
-bfa_pport_sm_disabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
+                       enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_FWRSP:
-               bfa_sm_set_state(pport, bfa_pport_sm_disabled);
+       case BFA_FCPORT_SM_FWRSP:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
                break;
 
-       case BFA_PPORT_SM_DISABLE:
+       case BFA_FCPORT_SM_DISABLE:
                /**
                 * Already being disabled.
                 */
                break;
 
-       case BFA_PPORT_SM_ENABLE:
-               if (bfa_pport_send_enable(pport))
-                       bfa_sm_set_state(pport, bfa_pport_sm_enabling);
+       case BFA_FCPORT_SM_ENABLE:
+               if (bfa_fcport_send_enable(fcport))
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
                else
-                       bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
 
-               bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+               bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                             BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
-               bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE);
+               bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
                break;
 
-       case BFA_PPORT_SM_STOP:
-               bfa_sm_set_state(pport, bfa_pport_sm_stopped);
+       case BFA_FCPORT_SM_STOP:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
                break;
 
-       case BFA_PPORT_SM_LINKUP:
-       case BFA_PPORT_SM_LINKDOWN:
+       case BFA_FCPORT_SM_LINKUP:
+       case BFA_FCPORT_SM_LINKDOWN:
                /**
                 * Possible to get link events when doing back-to-back
                 * enable/disables.
                 */
                break;
 
-       case BFA_PPORT_SM_HWFAIL:
-               bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
+       case BFA_FCPORT_SM_HWFAIL:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
                break;
 
        default:
-               bfa_sm_fault(pport->bfa, event);
+               bfa_sm_fault(fcport->bfa, event);
        }
 }
 
 static void
-bfa_pport_sm_disabled(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
+                       enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_START:
+       case BFA_FCPORT_SM_START:
                /**
                 * Ignore start event for a port that is disabled.
                 */
                break;
 
-       case BFA_PPORT_SM_STOP:
-               bfa_sm_set_state(pport, bfa_pport_sm_stopped);
+       case BFA_FCPORT_SM_STOP:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
                break;
 
-       case BFA_PPORT_SM_ENABLE:
-               if (bfa_pport_send_enable(pport))
-                       bfa_sm_set_state(pport, bfa_pport_sm_enabling);
+       case BFA_FCPORT_SM_ENABLE:
+               if (bfa_fcport_send_enable(fcport))
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
                else
-                       bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
 
-               bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+               bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                             BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
-               bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE);
+               bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
                break;
 
-       case BFA_PPORT_SM_DISABLE:
+       case BFA_FCPORT_SM_DISABLE:
                /**
                 * Already disabled.
                 */
                break;
 
-       case BFA_PPORT_SM_HWFAIL:
-               bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
+       case BFA_FCPORT_SM_HWFAIL:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
                break;
 
        default:
-               bfa_sm_fault(pport->bfa, event);
+               bfa_sm_fault(fcport->bfa, event);
        }
 }
 
 static void
-bfa_pport_sm_stopped(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
+                       enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_START:
-               if (bfa_pport_send_enable(pport))
-                       bfa_sm_set_state(pport, bfa_pport_sm_enabling);
+       case BFA_FCPORT_SM_START:
+               if (bfa_fcport_send_enable(fcport))
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
                else
-                       bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
                break;
 
        default:
@@ -574,16 +593,17 @@ bfa_pport_sm_stopped(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
  * Port is enabled. IOC is down/failed.
  */
 static void
-bfa_pport_sm_iocdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
+                       enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_START:
-               if (bfa_pport_send_enable(pport))
-                       bfa_sm_set_state(pport, bfa_pport_sm_enabling);
+       case BFA_FCPORT_SM_START:
+               if (bfa_fcport_send_enable(fcport))
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
                else
-                       bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
                break;
 
        default:
@@ -598,17 +618,18 @@ bfa_pport_sm_iocdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
  * Port is disabled. IOC is down/failed.
  */
 static void
-bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
+                       enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_START:
-               bfa_sm_set_state(pport, bfa_pport_sm_disabled);
+       case BFA_FCPORT_SM_START:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
                break;
 
-       case BFA_PPORT_SM_ENABLE:
-               bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
+       case BFA_FCPORT_SM_ENABLE:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
                break;
 
        default:
@@ -619,41 +640,226 @@ bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
        }
 }
 
+/**
+ * Link state is down
+ */
+static void
+bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
+               enum bfa_fcport_ln_sm_event event)
+{
+       bfa_trc(ln->fcport->bfa, event);
+
+       switch (event) {
+       case BFA_FCPORT_LN_SM_LINKUP:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf);
+               bfa_fcport_queue_cb(ln, BFA_PPORT_LINKUP);
+               break;
+
+       default:
+               bfa_sm_fault(ln->fcport->bfa, event);
+       }
+}
+
+/**
+ * Link state is waiting for down notification
+ */
+static void
+bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
+               enum bfa_fcport_ln_sm_event event)
+{
+       bfa_trc(ln->fcport->bfa, event);
+
+       switch (event) {
+       case BFA_FCPORT_LN_SM_LINKUP:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf);
+               break;
+
+       case BFA_FCPORT_LN_SM_NOTIFICATION:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
+               break;
+
+       default:
+               bfa_sm_fault(ln->fcport->bfa, event);
+       }
+}
+
+/**
+ * Link state is waiting for down notification and there is a pending up
+ */
+static void
+bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
+               enum bfa_fcport_ln_sm_event event)
+{
+       bfa_trc(ln->fcport->bfa, event);
+
+       switch (event) {
+       case BFA_FCPORT_LN_SM_LINKDOWN:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
+               break;
+
+       case BFA_FCPORT_LN_SM_NOTIFICATION:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf);
+               bfa_fcport_queue_cb(ln, BFA_PPORT_LINKUP);
+               break;
+
+       default:
+               bfa_sm_fault(ln->fcport->bfa, event);
+       }
+}
+
+/**
+ * Link state is up
+ */
+static void
+bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
+               enum bfa_fcport_ln_sm_event event)
+{
+       bfa_trc(ln->fcport->bfa, event);
+
+       switch (event) {
+       case BFA_FCPORT_LN_SM_LINKDOWN:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
+               bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
+               break;
 
+       default:
+               bfa_sm_fault(ln->fcport->bfa, event);
+       }
+}
+
+/**
+ * Link state is waiting for up notification
+ */
+static void
+bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
+               enum bfa_fcport_ln_sm_event event)
+{
+       bfa_trc(ln->fcport->bfa, event);
+
+       switch (event) {
+       case BFA_FCPORT_LN_SM_LINKDOWN:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf);
+               break;
+
+       case BFA_FCPORT_LN_SM_NOTIFICATION:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_up);
+               break;
+
+       default:
+               bfa_sm_fault(ln->fcport->bfa, event);
+       }
+}
+
+/**
+ * Link state is waiting for up notification and there is a pending down
+ */
+static void
+bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln,
+               enum bfa_fcport_ln_sm_event event)
+{
+       bfa_trc(ln->fcport->bfa, event);
+
+       switch (event) {
+       case BFA_FCPORT_LN_SM_LINKUP:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_up_nf);
+               break;
+
+       case BFA_FCPORT_LN_SM_NOTIFICATION:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
+               bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
+               break;
+
+       default:
+               bfa_sm_fault(ln->fcport->bfa, event);
+       }
+}
+
+/**
+ * Link state is waiting for up notification and there are pending down and up
+ */
+static void
+bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
+                       enum bfa_fcport_ln_sm_event event)
+{
+       bfa_trc(ln->fcport->bfa, event);
+
+       switch (event) {
+       case BFA_FCPORT_LN_SM_LINKDOWN:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf);
+               break;
+
+       case BFA_FCPORT_LN_SM_NOTIFICATION:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf);
+               bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
+               break;
+
+       default:
+               bfa_sm_fault(ln->fcport->bfa, event);
+       }
+}
 
 /**
  *  bfa_pport_private
  */
 
 static void
-__bfa_cb_port_event(void *cbarg, bfa_boolean_t complete)
+__bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete)
 {
-       struct bfa_pport_s *pport = cbarg;
+       struct bfa_fcport_ln_s *ln = cbarg;
 
        if (complete)
-               pport->event_cbfn(pport->event_cbarg, pport->hcb_event);
+               ln->fcport->event_cbfn(ln->fcport->event_cbarg, ln->ln_event);
+       else
+               bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION);
 }
 
-#define PPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), \
+static void
+bfa_fcport_callback(struct bfa_fcport_s *fcport, enum bfa_pport_linkstate event)
+{
+       if (fcport->bfa->fcs) {
+               fcport->event_cbfn(fcport->event_cbarg, event);
+               return;
+       }
+
+       switch (event) {
+       case BFA_PPORT_LINKUP:
+               bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKUP);
+               break;
+       case BFA_PPORT_LINKDOWN:
+               bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKDOWN);
+               break;
+       default:
+               bfa_assert(0);
+       }
+}
+
+static void
+bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, enum bfa_pport_linkstate event)
+{
+       ln->ln_event = event;
+       bfa_cb_queue(ln->fcport->bfa, &ln->ln_qe, __bfa_cb_fcport_event, ln);
+}
+
+#define FCPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_fcport_stats_u), \
                                                        BFA_CACHELINE_SZ))
 
 static void
-bfa_pport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
+bfa_fcport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
                  u32 *dm_len)
 {
-       *dm_len += PPORT_STATS_DMA_SZ;
+       *dm_len += FCPORT_STATS_DMA_SZ;
 }
 
 static void
-bfa_pport_qresume(void *cbarg)
+bfa_fcport_qresume(void *cbarg)
 {
-       struct bfa_pport_s *port = cbarg;
+       struct bfa_fcport_s *fcport = cbarg;
 
-       bfa_sm_send_event(port, BFA_PPORT_SM_QRESUME);
+       bfa_sm_send_event(fcport, BFA_FCPORT_SM_QRESUME);
 }
 
 static void
-bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo)
+bfa_fcport_mem_claim(struct bfa_fcport_s *fcport, struct bfa_meminfo_s *meminfo)
 {
        u8        *dm_kva;
        u64        dm_pa;
@@ -661,12 +867,12 @@ bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo)
        dm_kva = bfa_meminfo_dma_virt(meminfo);
        dm_pa = bfa_meminfo_dma_phys(meminfo);
 
-       pport->stats_kva = dm_kva;
-       pport->stats_pa = dm_pa;
-       pport->stats = (union bfa_pport_stats_u *)dm_kva;
+       fcport->stats_kva = dm_kva;
+       fcport->stats_pa = dm_pa;
+       fcport->stats = (union bfa_fcport_stats_u *)dm_kva;
 
-       dm_kva += PPORT_STATS_DMA_SZ;
-       dm_pa += PPORT_STATS_DMA_SZ;
+       dm_kva += FCPORT_STATS_DMA_SZ;
+       dm_pa += FCPORT_STATS_DMA_SZ;
 
        bfa_meminfo_dma_virt(meminfo) = dm_kva;
        bfa_meminfo_dma_phys(meminfo) = dm_pa;
@@ -676,18 +882,21 @@ bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo)
  * Memory initialization.
  */
 static void
-bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
+bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
                 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
-       struct bfa_pport_cfg_s *port_cfg = &pport->cfg;
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+       struct bfa_pport_cfg_s *port_cfg = &fcport->cfg;
+       struct bfa_fcport_ln_s *ln = &fcport->ln;
 
-       bfa_os_memset(pport, 0, sizeof(struct bfa_pport_s));
-       pport->bfa = bfa;
+       bfa_os_memset(fcport, 0, sizeof(struct bfa_fcport_s));
+       fcport->bfa = bfa;
+       ln->fcport = fcport;
 
-       bfa_pport_mem_claim(pport, meminfo);
+       bfa_fcport_mem_claim(fcport, meminfo);
 
-       bfa_sm_set_state(pport, bfa_pport_sm_uninit);
+       bfa_sm_set_state(fcport, bfa_fcport_sm_uninit);
+       bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
 
        /**
         * initialize and set default configuration
@@ -699,30 +908,30 @@ bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
 
        port_cfg->trl_def_speed = BFA_PPORT_SPEED_1GBPS;
 
-       bfa_reqq_winit(&pport->reqq_wait, bfa_pport_qresume, pport);
+       bfa_reqq_winit(&fcport->reqq_wait, bfa_fcport_qresume, fcport);
 }
 
 static void
-bfa_pport_initdone(struct bfa_s *bfa)
+bfa_fcport_initdone(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        /**
         * Initialize port attributes from IOC hardware data.
         */
-       bfa_pport_set_wwns(pport);
-       if (pport->cfg.maxfrsize == 0)
-               pport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
-       pport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
-       pport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
+       bfa_fcport_set_wwns(fcport);
+       if (fcport->cfg.maxfrsize == 0)
+               fcport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
+       fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
+       fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
 
-       bfa_assert(pport->cfg.maxfrsize);
-       bfa_assert(pport->cfg.rx_bbcredit);
-       bfa_assert(pport->speed_sup);
+       bfa_assert(fcport->cfg.maxfrsize);
+       bfa_assert(fcport->cfg.rx_bbcredit);
+       bfa_assert(fcport->speed_sup);
 }
 
 static void
-bfa_pport_detach(struct bfa_s *bfa)
+bfa_fcport_detach(struct bfa_s *bfa)
 {
 }
 
@@ -730,95 +939,97 @@ bfa_pport_detach(struct bfa_s *bfa)
  * Called when IOC is ready.
  */
 static void
-bfa_pport_start(struct bfa_s *bfa)
+bfa_fcport_start(struct bfa_s *bfa)
 {
-       bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_START);
+       bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_START);
 }
 
 /**
  * Called before IOC is stopped.
  */
 static void
-bfa_pport_stop(struct bfa_s *bfa)
+bfa_fcport_stop(struct bfa_s *bfa)
 {
-       bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_STOP);
+       bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_STOP);
 }
 
 /**
  * Called when IOC failure is detected.
  */
 static void
-bfa_pport_iocdisable(struct bfa_s *bfa)
+bfa_fcport_iocdisable(struct bfa_s *bfa)
 {
-       bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_HWFAIL);
+       bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_HWFAIL);
 }
 
 static void
-bfa_pport_update_linkinfo(struct bfa_pport_s *pport)
+bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
 {
-       struct bfi_pport_event_s *pevent = pport->event_arg.i2hmsg.event;
+       struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event;
 
-       pport->speed = pevent->link_state.speed;
-       pport->topology = pevent->link_state.topology;
+       fcport->speed = pevent->link_state.speed;
+       fcport->topology = pevent->link_state.topology;
 
-       if (pport->topology == BFA_PPORT_TOPOLOGY_LOOP)
-               pport->myalpa = pevent->link_state.tl.loop_info.myalpa;
+       if (fcport->topology == BFA_PPORT_TOPOLOGY_LOOP)
+               fcport->myalpa =
+                       pevent->link_state.tl.loop_info.myalpa;
 
        /*
         * QoS Details
         */
-       bfa_os_assign(pport->qos_attr, pevent->link_state.qos_attr);
-       bfa_os_assign(pport->qos_vc_attr, pevent->link_state.qos_vc_attr);
+       bfa_os_assign(fcport->qos_attr, pevent->link_state.qos_attr);
+       bfa_os_assign(fcport->qos_vc_attr, pevent->link_state.qos_vc_attr);
 
-       bfa_trc(pport->bfa, pport->speed);
-       bfa_trc(pport->bfa, pport->topology);
+       bfa_trc(fcport->bfa, fcport->speed);
+       bfa_trc(fcport->bfa, fcport->topology);
 }
 
 static void
-bfa_pport_reset_linkinfo(struct bfa_pport_s *pport)
+bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport)
 {
-       pport->speed = BFA_PPORT_SPEED_UNKNOWN;
-       pport->topology = BFA_PPORT_TOPOLOGY_NONE;
+       fcport->speed = BFA_PPORT_SPEED_UNKNOWN;
+       fcport->topology = BFA_PPORT_TOPOLOGY_NONE;
 }
 
 /**
  * Send port enable message to firmware.
  */
 static          bfa_boolean_t
-bfa_pport_send_enable(struct bfa_pport_s *port)
+bfa_fcport_send_enable(struct bfa_fcport_s *fcport)
 {
-       struct bfi_pport_enable_req_s *m;
+       struct bfi_fcport_enable_req_s *m;
 
        /**
         * Increment message tag before queue check, so that responses to old
         * requests are discarded.
         */
-       port->msgtag++;
+       fcport->msgtag++;
 
        /**
         * check for room in queue to send request now
         */
-       m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
+       m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
        if (!m) {
-               bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait);
+               bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
+                                                       &fcport->reqq_wait);
                return BFA_FALSE;
        }
 
-       bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_ENABLE_REQ,
-                   bfa_lpuid(port->bfa));
-       m->nwwn = port->nwwn;
-       m->pwwn = port->pwwn;
-       m->port_cfg = port->cfg;
-       m->msgtag = port->msgtag;
-       m->port_cfg.maxfrsize = bfa_os_htons(port->cfg.maxfrsize);
-       bfa_dma_be_addr_set(m->stats_dma_addr, port->stats_pa);
-       bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_lo);
-       bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_hi);
+       bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_ENABLE_REQ,
+                               bfa_lpuid(fcport->bfa));
+       m->nwwn = fcport->nwwn;
+       m->pwwn = fcport->pwwn;
+       m->port_cfg = fcport->cfg;
+       m->msgtag = fcport->msgtag;
+       m->port_cfg.maxfrsize = bfa_os_htons(fcport->cfg.maxfrsize);
+       bfa_dma_be_addr_set(m->stats_dma_addr, fcport->stats_pa);
+       bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_lo);
+       bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_hi);
 
        /**
         * queue I/O message to firmware
         */
-       bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
+       bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
        return BFA_TRUE;
 }
 
@@ -826,74 +1037,226 @@ bfa_pport_send_enable(struct bfa_pport_s *port)
  * Send port disable message to firmware.
  */
 static          bfa_boolean_t
-bfa_pport_send_disable(struct bfa_pport_s *port)
+bfa_fcport_send_disable(struct bfa_fcport_s *fcport)
 {
-       bfi_pport_disable_req_t *m;
+       struct bfi_fcport_req_s *m;
 
        /**
         * Increment message tag before queue check, so that responses to old
         * requests are discarded.
         */
-       port->msgtag++;
+       fcport->msgtag++;
 
        /**
         * check for room in queue to send request now
         */
-       m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
+       m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
        if (!m) {
-               bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait);
+               bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
+                                                       &fcport->reqq_wait);
                return BFA_FALSE;
        }
 
-       bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_DISABLE_REQ,
-                   bfa_lpuid(port->bfa));
-       m->msgtag = port->msgtag;
+       bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_DISABLE_REQ,
+                       bfa_lpuid(fcport->bfa));
+       m->msgtag = fcport->msgtag;
 
        /**
         * queue I/O message to firmware
         */
-       bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
+       bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
 
        return BFA_TRUE;
 }
 
 static void
-bfa_pport_set_wwns(struct bfa_pport_s *port)
+bfa_fcport_set_wwns(struct bfa_fcport_s *fcport)
 {
-       port->pwwn = bfa_ioc_get_pwwn(&port->bfa->ioc);
-       port->nwwn = bfa_ioc_get_nwwn(&port->bfa->ioc);
+       fcport->pwwn = bfa_ioc_get_pwwn(&fcport->bfa->ioc);
+       fcport->nwwn = bfa_ioc_get_nwwn(&fcport->bfa->ioc);
 
-       bfa_trc(port->bfa, port->pwwn);
-       bfa_trc(port->bfa, port->nwwn);
+       bfa_trc(fcport->bfa, fcport->pwwn);
+       bfa_trc(fcport->bfa, fcport->nwwn);
 }
 
 static void
-bfa_port_send_txcredit(void *port_cbarg)
+bfa_fcport_send_txcredit(void *port_cbarg)
 {
 
-       struct bfa_pport_s *port = port_cbarg;
-       struct bfi_pport_set_svc_params_req_s *m;
+       struct bfa_fcport_s *fcport = port_cbarg;
+       struct bfi_fcport_set_svc_params_req_s *m;
 
        /**
         * check for room in queue to send request now
         */
-       m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
+       m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
        if (!m) {
-               bfa_trc(port->bfa, port->cfg.tx_bbcredit);
+               bfa_trc(fcport->bfa, fcport->cfg.tx_bbcredit);
                return;
        }
 
-       bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_SET_SVC_PARAMS_REQ,
-                   bfa_lpuid(port->bfa));
-       m->tx_bbcredit = bfa_os_htons((u16) port->cfg.tx_bbcredit);
+       bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ,
+                       bfa_lpuid(fcport->bfa));
+       m->tx_bbcredit = bfa_os_htons((u16) fcport->cfg.tx_bbcredit);
 
        /**
         * queue I/O message to firmware
         */
-       bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
+       bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
 }
 
+static void
+bfa_fcport_qos_stats_swap(struct bfa_qos_stats_s *d,
+       struct bfa_qos_stats_s *s)
+{
+       u32     *dip = (u32 *) d;
+       u32     *sip = (u32 *) s;
+       int             i;
+
+       /* Now swap the 32 bit fields */
+       for (i = 0; i < (sizeof(struct bfa_qos_stats_s)/sizeof(u32)); ++i)
+               dip[i] = bfa_os_ntohl(sip[i]);
+}
 
+static void
+bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d,
+       struct bfa_fcoe_stats_s *s)
+{
+       u32     *dip = (u32 *) d;
+       u32     *sip = (u32 *) s;
+       int             i;
+
+       for (i = 0; i < ((sizeof(struct bfa_fcoe_stats_s))/sizeof(u32));
+               i = i + 2) {
+#ifdef __BIGENDIAN
+               dip[i] = bfa_os_ntohl(sip[i]);
+               dip[i + 1] = bfa_os_ntohl(sip[i + 1]);
+#else
+               dip[i] = bfa_os_ntohl(sip[i + 1]);
+               dip[i + 1] = bfa_os_ntohl(sip[i]);
+#endif
+       }
+}
+
+static void
+__bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete)
+{
+       struct bfa_fcport_s *fcport = cbarg;
+
+       if (complete) {
+               if (fcport->stats_status == BFA_STATUS_OK) {
+
+                       /* Swap FC QoS or FCoE stats */
+                       if (bfa_ioc_get_fcmode(&fcport->bfa->ioc))
+                               bfa_fcport_qos_stats_swap(
+                                       &fcport->stats_ret->fcqos,
+                                       &fcport->stats->fcqos);
+                       else
+                               bfa_fcport_fcoe_stats_swap(
+                                       &fcport->stats_ret->fcoe,
+                                       &fcport->stats->fcoe);
+               }
+               fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
+       } else {
+               fcport->stats_busy = BFA_FALSE;
+               fcport->stats_status = BFA_STATUS_OK;
+       }
+}
+
+static void
+bfa_fcport_stats_get_timeout(void *cbarg)
+{
+       struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
+
+       bfa_trc(fcport->bfa, fcport->stats_qfull);
+
+       if (fcport->stats_qfull) {
+               bfa_reqq_wcancel(&fcport->stats_reqq_wait);
+               fcport->stats_qfull = BFA_FALSE;
+       }
+
+       fcport->stats_status = BFA_STATUS_ETIMER;
+       bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_fcport_stats_get,
+               fcport);
+}
+
+static void
+bfa_fcport_send_stats_get(void *cbarg)
+{
+       struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
+       struct bfi_fcport_req_s *msg;
+
+       msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
+
+       if (!msg) {
+               fcport->stats_qfull = BFA_TRUE;
+               bfa_reqq_winit(&fcport->stats_reqq_wait,
+                               bfa_fcport_send_stats_get, fcport);
+               bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
+                               &fcport->stats_reqq_wait);
+               return;
+       }
+       fcport->stats_qfull = BFA_FALSE;
+
+       bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s));
+       bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_GET_REQ,
+               bfa_lpuid(fcport->bfa));
+       bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
+}
+
+static void
+__bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete)
+{
+       struct bfa_fcport_s *fcport = cbarg;
+
+       if (complete) {
+               fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
+       } else {
+               fcport->stats_busy = BFA_FALSE;
+               fcport->stats_status = BFA_STATUS_OK;
+       }
+}
+
+static void
+bfa_fcport_stats_clr_timeout(void *cbarg)
+{
+       struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
+
+       bfa_trc(fcport->bfa, fcport->stats_qfull);
+
+       if (fcport->stats_qfull) {
+               bfa_reqq_wcancel(&fcport->stats_reqq_wait);
+               fcport->stats_qfull = BFA_FALSE;
+       }
+
+       fcport->stats_status = BFA_STATUS_ETIMER;
+       bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
+                       __bfa_cb_fcport_stats_clr, fcport);
+}
+
+static void
+bfa_fcport_send_stats_clear(void *cbarg)
+{
+       struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
+       struct bfi_fcport_req_s *msg;
+
+       msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
+
+       if (!msg) {
+               fcport->stats_qfull = BFA_TRUE;
+               bfa_reqq_winit(&fcport->stats_reqq_wait,
+                               bfa_fcport_send_stats_clear, fcport);
+               bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
+                               &fcport->stats_reqq_wait);
+               return;
+       }
+       fcport->stats_qfull = BFA_FALSE;
+
+       bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s));
+       bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_CLEAR_REQ,
+                       bfa_lpuid(fcport->bfa));
+       bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
+}
 
 /**
  *  bfa_pport_public
@@ -903,32 +1266,32 @@ bfa_port_send_txcredit(void *port_cbarg)
  * Firmware message handler.
  */
 void
-bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
+bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
-       union bfi_pport_i2h_msg_u i2hmsg;
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+       union bfi_fcport_i2h_msg_u i2hmsg;
 
        i2hmsg.msg = msg;
-       pport->event_arg.i2hmsg = i2hmsg;
+       fcport->event_arg.i2hmsg = i2hmsg;
 
        switch (msg->mhdr.msg_id) {
-       case BFI_PPORT_I2H_ENABLE_RSP:
-               if (pport->msgtag == i2hmsg.enable_rsp->msgtag)
-                       bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP);
+       case BFI_FCPORT_I2H_ENABLE_RSP:
+               if (fcport->msgtag == i2hmsg.penable_rsp->msgtag)
+                       bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
                break;
 
-       case BFI_PPORT_I2H_DISABLE_RSP:
-               if (pport->msgtag == i2hmsg.enable_rsp->msgtag)
-                       bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP);
+       case BFI_FCPORT_I2H_DISABLE_RSP:
+               if (fcport->msgtag == i2hmsg.penable_rsp->msgtag)
+                       bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
                break;
 
-       case BFI_PPORT_I2H_EVENT:
+       case BFI_FCPORT_I2H_EVENT:
                switch (i2hmsg.event->link_state.linkstate) {
                case BFA_PPORT_LINKUP:
-                       bfa_sm_send_event(pport, BFA_PPORT_SM_LINKUP);
+                       bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP);
                        break;
                case BFA_PPORT_LINKDOWN:
-                       bfa_sm_send_event(pport, BFA_PPORT_SM_LINKDOWN);
+                       bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKDOWN);
                        break;
                case BFA_PPORT_TRUNK_LINKDOWN:
                        /** todo: event notification */
@@ -936,42 +1299,40 @@ bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
                }
                break;
 
-       case BFI_PPORT_I2H_GET_STATS_RSP:
-       case BFI_PPORT_I2H_GET_QOS_STATS_RSP:
+       case BFI_FCPORT_I2H_STATS_GET_RSP:
                /*
                 * check for timer pop before processing the rsp
                 */
-               if (pport->stats_busy == BFA_FALSE
-                   || pport->stats_status == BFA_STATUS_ETIMER)
+               if (fcport->stats_busy == BFA_FALSE ||
+                       fcport->stats_status == BFA_STATUS_ETIMER)
                        break;
 
-               bfa_timer_stop(&pport->timer);
-               pport->stats_status = i2hmsg.getstats_rsp->status;
-               bfa_cb_queue(pport->bfa, &pport->hcb_qe, __bfa_cb_port_stats,
-                            pport);
+               bfa_timer_stop(&fcport->timer);
+               fcport->stats_status = i2hmsg.pstatsget_rsp->status;
+               bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
+                               __bfa_cb_fcport_stats_get, fcport);
                break;
-       case BFI_PPORT_I2H_CLEAR_STATS_RSP:
-       case BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP:
+
+       case BFI_FCPORT_I2H_STATS_CLEAR_RSP:
                /*
                 * check for timer pop before processing the rsp
                 */
-               if (pport->stats_busy == BFA_FALSE
-                   || pport->stats_status == BFA_STATUS_ETIMER)
+               if (fcport->stats_busy == BFA_FALSE ||
+                       fcport->stats_status == BFA_STATUS_ETIMER)
                        break;
 
-               bfa_timer_stop(&pport->timer);
-               pport->stats_status = BFA_STATUS_OK;
-               bfa_cb_queue(pport->bfa, &pport->hcb_qe,
-                            __bfa_cb_port_stats_clr, pport);
+               bfa_timer_stop(&fcport->timer);
+               fcport->stats_status = BFA_STATUS_OK;
+               bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
+                               __bfa_cb_fcport_stats_clr, fcport);
                break;
 
        default:
                bfa_assert(0);
+       break;
        }
 }
 
-
-
 /**
  *  bfa_pport_api
  */
@@ -980,35 +1341,35 @@ bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
  * Registered callback for port events.
  */
 void
-bfa_pport_event_register(struct bfa_s *bfa,
+bfa_fcport_event_register(struct bfa_s *bfa,
                         void (*cbfn) (void *cbarg, bfa_pport_event_t event),
                         void *cbarg)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       pport->event_cbfn = cbfn;
-       pport->event_cbarg = cbarg;
+       fcport->event_cbfn = cbfn;
+       fcport->event_cbarg = cbarg;
 }
 
 bfa_status_t
-bfa_pport_enable(struct bfa_s *bfa)
+bfa_fcport_enable(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       if (pport->diag_busy)
+       if (fcport->diag_busy)
                return BFA_STATUS_DIAG_BUSY;
        else if (bfa_sm_cmp_state
-                (BFA_PORT_MOD(bfa), bfa_pport_sm_disabling_qwait))
+                (BFA_FCPORT_MOD(bfa), bfa_fcport_sm_disabling_qwait))
                return BFA_STATUS_DEVBUSY;
 
-       bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_ENABLE);
+       bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_ENABLE);
        return BFA_STATUS_OK;
 }
 
 bfa_status_t
-bfa_pport_disable(struct bfa_s *bfa)
+bfa_fcport_disable(struct bfa_s *bfa)
 {
-       bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_DISABLE);
+       bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DISABLE);
        return BFA_STATUS_OK;
 }
 
@@ -1016,18 +1377,18 @@ bfa_pport_disable(struct bfa_s *bfa)
  * Configure port speed.
  */
 bfa_status_t
-bfa_pport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
+bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        bfa_trc(bfa, speed);
 
-       if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > pport->speed_sup)) {
-               bfa_trc(bfa, pport->speed_sup);
+       if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > fcport->speed_sup)) {
+               bfa_trc(bfa, fcport->speed_sup);
                return BFA_STATUS_UNSUPP_SPEED;
        }
 
-       pport->cfg.speed = speed;
+       fcport->cfg.speed = speed;
 
        return BFA_STATUS_OK;
 }
@@ -1036,23 +1397,23 @@ bfa_pport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
  * Get current speed.
  */
 enum bfa_pport_speed
-bfa_pport_get_speed(struct bfa_s *bfa)
+bfa_fcport_get_speed(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       return port->speed;
+       return fcport->speed;
 }
 
 /**
  * Configure port topology.
  */
 bfa_status_t
-bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
+bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        bfa_trc(bfa, topology);
-       bfa_trc(bfa, pport->cfg.topology);
+       bfa_trc(bfa, fcport->cfg.topology);
 
        switch (topology) {
        case BFA_PPORT_TOPOLOGY_P2P:
@@ -1064,7 +1425,7 @@ bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
                return BFA_STATUS_EINVAL;
        }
 
-       pport->cfg.topology = topology;
+       fcport->cfg.topology = topology;
        return BFA_STATUS_OK;
 }
 
@@ -1072,64 +1433,64 @@ bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
  * Get current topology.
  */
 enum bfa_pport_topology
-bfa_pport_get_topology(struct bfa_s *bfa)
+bfa_fcport_get_topology(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       return port->topology;
+       return fcport->topology;
 }
 
 bfa_status_t
-bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
+bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        bfa_trc(bfa, alpa);
-       bfa_trc(bfa, pport->cfg.cfg_hardalpa);
-       bfa_trc(bfa, pport->cfg.hardalpa);
+       bfa_trc(bfa, fcport->cfg.cfg_hardalpa);
+       bfa_trc(bfa, fcport->cfg.hardalpa);
 
-       pport->cfg.cfg_hardalpa = BFA_TRUE;
-       pport->cfg.hardalpa = alpa;
+       fcport->cfg.cfg_hardalpa = BFA_TRUE;
+       fcport->cfg.hardalpa = alpa;
 
        return BFA_STATUS_OK;
 }
 
 bfa_status_t
-bfa_pport_clr_hardalpa(struct bfa_s *bfa)
+bfa_fcport_clr_hardalpa(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       bfa_trc(bfa, pport->cfg.cfg_hardalpa);
-       bfa_trc(bfa, pport->cfg.hardalpa);
+       bfa_trc(bfa, fcport->cfg.cfg_hardalpa);
+       bfa_trc(bfa, fcport->cfg.hardalpa);
 
-       pport->cfg.cfg_hardalpa = BFA_FALSE;
+       fcport->cfg.cfg_hardalpa = BFA_FALSE;
        return BFA_STATUS_OK;
 }
 
 bfa_boolean_t
-bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa)
+bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       *alpa = port->cfg.hardalpa;
-       return port->cfg.cfg_hardalpa;
+       *alpa = fcport->cfg.hardalpa;
+       return fcport->cfg.cfg_hardalpa;
 }
 
 u8
-bfa_pport_get_myalpa(struct bfa_s *bfa)
+bfa_fcport_get_myalpa(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       return port->myalpa;
+       return fcport->myalpa;
 }
 
 bfa_status_t
-bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
+bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        bfa_trc(bfa, maxfrsize);
-       bfa_trc(bfa, pport->cfg.maxfrsize);
+       bfa_trc(bfa, fcport->cfg.maxfrsize);
 
        /*
         * with in range
@@ -1143,41 +1504,41 @@ bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
        if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1)))
                return BFA_STATUS_INVLD_DFSZ;
 
-       pport->cfg.maxfrsize = maxfrsize;
+       fcport->cfg.maxfrsize = maxfrsize;
        return BFA_STATUS_OK;
 }
 
 u16
-bfa_pport_get_maxfrsize(struct bfa_s *bfa)
+bfa_fcport_get_maxfrsize(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       return port->cfg.maxfrsize;
+       return fcport->cfg.maxfrsize;
 }
 
 u32
-bfa_pport_mypid(struct bfa_s *bfa)
+bfa_fcport_mypid(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       return port->mypid;
+       return fcport->mypid;
 }
 
 u8
-bfa_pport_get_rx_bbcredit(struct bfa_s *bfa)
+bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       return port->cfg.rx_bbcredit;
+       return fcport->cfg.rx_bbcredit;
 }
 
 void
-bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
+bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       port->cfg.tx_bbcredit = (u8) tx_bbcredit;
-       bfa_port_send_txcredit(port);
+       fcport->cfg.tx_bbcredit = (u8) tx_bbcredit;
+       bfa_fcport_send_txcredit(fcport);
 }
 
 /**
@@ -1185,302 +1546,192 @@ bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
  */
 
 wwn_t
-bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node)
+bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
        if (node)
-               return pport->nwwn;
+               return fcport->nwwn;
        else
-               return pport->pwwn;
+               return fcport->pwwn;
 }
 
 void
-bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr)
+bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s));
 
-       attr->nwwn = pport->nwwn;
-       attr->pwwn = pport->pwwn;
+       attr->nwwn = fcport->nwwn;
+       attr->pwwn = fcport->pwwn;
 
-       bfa_os_memcpy(&attr->pport_cfg, &pport->cfg,
+       bfa_os_memcpy(&attr->pport_cfg, &fcport->cfg,
                      sizeof(struct bfa_pport_cfg_s));
        /*
         * speed attributes
         */
-       attr->pport_cfg.speed = pport->cfg.speed;
-       attr->speed_supported = pport->speed_sup;
-       attr->speed = pport->speed;
+       attr->pport_cfg.speed = fcport->cfg.speed;
+       attr->speed_supported = fcport->speed_sup;
+       attr->speed = fcport->speed;
        attr->cos_supported = FC_CLASS_3;
 
        /*
         * topology attributes
         */
-       attr->pport_cfg.topology = pport->cfg.topology;
-       attr->topology = pport->topology;
+       attr->pport_cfg.topology = fcport->cfg.topology;
+       attr->topology = fcport->topology;
 
        /*
         * beacon attributes
         */
-       attr->beacon = pport->beacon;
-       attr->link_e2e_beacon = pport->link_e2e_beacon;
-       attr->plog_enabled = bfa_plog_get_setting(pport->bfa->plog);
+       attr->beacon = fcport->beacon;
+       attr->link_e2e_beacon = fcport->link_e2e_beacon;
+       attr->plog_enabled = bfa_plog_get_setting(fcport->bfa->plog);
 
        attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa);
        attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa);
-       attr->port_state = bfa_sm_to_state(hal_pport_sm_table, pport->sm);
-       if (bfa_ioc_is_disabled(&pport->bfa->ioc))
+       attr->port_state = bfa_sm_to_state(hal_pport_sm_table, fcport->sm);
+       if (bfa_ioc_is_disabled(&fcport->bfa->ioc))
                attr->port_state = BFA_PPORT_ST_IOCDIS;
-       else if (bfa_ioc_fw_mismatch(&pport->bfa->ioc))
+       else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc))
                attr->port_state = BFA_PPORT_ST_FWMISMATCH;
 }
 
-static void
-bfa_port_stats_query(void *cbarg)
-{
-       struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
-       bfi_pport_get_stats_req_t *msg;
-
-       msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
-
-       if (!msg) {
-               port->stats_qfull = BFA_TRUE;
-               bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_query,
-                              port);
-               bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
-               return;
-       }
-       port->stats_qfull = BFA_FALSE;
-
-       bfa_os_memset(msg, 0, sizeof(bfi_pport_get_stats_req_t));
-       bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_GET_STATS_REQ,
-                   bfa_lpuid(port->bfa));
-       bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
-
-       return;
-}
-
-static void
-bfa_port_stats_clear(void *cbarg)
-{
-       struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
-       bfi_pport_clear_stats_req_t *msg;
-
-       msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
+#define BFA_FCPORT_STATS_TOV   1000
 
-       if (!msg) {
-               port->stats_qfull = BFA_TRUE;
-               bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_clear,
-                              port);
-               bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
-               return;
-       }
-       port->stats_qfull = BFA_FALSE;
-
-       bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_stats_req_t));
-       bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_STATS_REQ,
-                   bfa_lpuid(port->bfa));
-       bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
-       return;
-}
-
-static void
-bfa_port_qos_stats_clear(void *cbarg)
+/**
+ * Fetch port attributes (FCQoS or FCoE).
+ */
+bfa_status_t
+bfa_fcport_get_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
+                   bfa_cb_pport_t cbfn, void *cbarg)
 {
-       struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
-       bfi_pport_clear_qos_stats_req_t *msg;
-
-       msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       if (!msg) {
-               port->stats_qfull = BFA_TRUE;
-               bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_qos_stats_clear,
-                              port);
-               bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
-               return;
+       if (fcport->stats_busy) {
+               bfa_trc(bfa, fcport->stats_busy);
+               return BFA_STATUS_DEVBUSY;
        }
-       port->stats_qfull = BFA_FALSE;
 
-       bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_qos_stats_req_t));
-       bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ,
-                   bfa_lpuid(port->bfa));
-       bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
-       return;
-}
-
-static void
-bfa_pport_stats_swap(union bfa_pport_stats_u *d, union bfa_pport_stats_u *s)
-{
-       u32       *dip = (u32 *) d;
-       u32       *sip = (u32 *) s;
-       int             i;
+       fcport->stats_busy  = BFA_TRUE;
+       fcport->stats_ret   = stats;
+       fcport->stats_cbfn  = cbfn;
+       fcport->stats_cbarg = cbarg;
 
-       /*
-        * Do 64 bit fields swap first
-        */
-       for (i = 0;
-            i <
-            ((sizeof(union bfa_pport_stats_u) -
-              sizeof(struct bfa_qos_stats_s)) / sizeof(u32)); i = i + 2) {
-#ifdef __BIGENDIAN
-               dip[i] = bfa_os_ntohl(sip[i]);
-               dip[i + 1] = bfa_os_ntohl(sip[i + 1]);
-#else
-               dip[i] = bfa_os_ntohl(sip[i + 1]);
-               dip[i + 1] = bfa_os_ntohl(sip[i]);
-#endif
-       }
+       bfa_fcport_send_stats_get(fcport);
 
-       /*
-        * Now swap the 32 bit fields
-        */
-       for (; i < (sizeof(union bfa_pport_stats_u) / sizeof(u32)); ++i)
-               dip[i] = bfa_os_ntohl(sip[i]);
+       bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_get_timeout,
+               fcport, BFA_FCPORT_STATS_TOV);
+       return BFA_STATUS_OK;
 }
 
-static void
-__bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete)
+/**
+ * Reset port statistics (FCQoS or FCoE).
+ */
+bfa_status_t
+bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
 {
-       struct bfa_pport_s *port = cbarg;
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       if (complete) {
-               port->stats_cbfn(port->stats_cbarg, port->stats_status);
-       } else {
-               port->stats_busy = BFA_FALSE;
-               port->stats_status = BFA_STATUS_OK;
+       if (fcport->stats_busy) {
+               bfa_trc(bfa, fcport->stats_busy);
+               return BFA_STATUS_DEVBUSY;
        }
-}
-
-static void
-bfa_port_stats_clr_timeout(void *cbarg)
-{
-       struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
 
-       bfa_trc(port->bfa, port->stats_qfull);
+       fcport->stats_busy = BFA_TRUE;
+       fcport->stats_cbfn = cbfn;
+       fcport->stats_cbarg = cbarg;
 
-       if (port->stats_qfull) {
-               bfa_reqq_wcancel(&port->stats_reqq_wait);
-               port->stats_qfull = BFA_FALSE;
-       }
+       bfa_fcport_send_stats_clear(fcport);
 
-       port->stats_status = BFA_STATUS_ETIMER;
-       bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats_clr, port);
+       bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_clr_timeout,
+                       fcport, BFA_FCPORT_STATS_TOV);
+       return BFA_STATUS_OK;
 }
 
-static void
-__bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete)
+/**
+ * Fetch FCQoS port statistics
+ */
+bfa_status_t
+bfa_fcport_get_qos_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
+       bfa_cb_pport_t cbfn, void *cbarg)
 {
-       struct bfa_pport_s *port = cbarg;
+       /* Meaningful only for FC mode */
+       bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc));
 
-       if (complete) {
-               if (port->stats_status == BFA_STATUS_OK)
-                       bfa_pport_stats_swap(port->stats_ret, port->stats);
-               port->stats_cbfn(port->stats_cbarg, port->stats_status);
-       } else {
-               port->stats_busy = BFA_FALSE;
-               port->stats_status = BFA_STATUS_OK;
-       }
+       return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
 }
 
-static void
-bfa_port_stats_timeout(void *cbarg)
+/**
+ * Reset FCoE port statistics
+ */
+bfa_status_t
+bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
 {
-       struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
-
-       bfa_trc(port->bfa, port->stats_qfull);
+       /* Meaningful only for FC mode */
+       bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc));
 
-       if (port->stats_qfull) {
-               bfa_reqq_wcancel(&port->stats_reqq_wait);
-               port->stats_qfull = BFA_FALSE;
-       }
-
-       port->stats_status = BFA_STATUS_ETIMER;
-       bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats, port);
+       return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
 }
 
-#define BFA_PORT_STATS_TOV     1000
-
 /**
- * Fetch port attributes.
+ * Fetch FCQoS port statistics
  */
 bfa_status_t
-bfa_pport_get_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats,
-                   bfa_cb_pport_t cbfn, void *cbarg)
+bfa_fcport_get_fcoe_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
+       bfa_cb_pport_t cbfn, void *cbarg)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
-
-       if (port->stats_busy) {
-               bfa_trc(bfa, port->stats_busy);
-               return BFA_STATUS_DEVBUSY;
-       }
-
-       port->stats_busy = BFA_TRUE;
-       port->stats_ret = stats;
-       port->stats_cbfn = cbfn;
-       port->stats_cbarg = cbarg;
-
-       bfa_port_stats_query(port);
+       /* Meaningful only for FCoE mode */
+       bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc));
 
-       bfa_timer_start(bfa, &port->timer, bfa_port_stats_timeout, port,
-                       BFA_PORT_STATS_TOV);
-       return BFA_STATUS_OK;
+       return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
 }
 
+/**
+ * Reset FCoE port statistics
+ */
 bfa_status_t
-bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
+bfa_fcport_clear_fcoe_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
-
-       if (port->stats_busy) {
-               bfa_trc(bfa, port->stats_busy);
-               return BFA_STATUS_DEVBUSY;
-       }
-
-       port->stats_busy = BFA_TRUE;
-       port->stats_cbfn = cbfn;
-       port->stats_cbarg = cbarg;
-
-       bfa_port_stats_clear(port);
+       /* Meaningful only for FCoE mode */
+       bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc));
 
-       bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port,
-                       BFA_PORT_STATS_TOV);
-       return BFA_STATUS_OK;
+       return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
 }
 
 bfa_status_t
-bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap)
+bfa_fcport_trunk_enable(struct bfa_s *bfa, u8 bitmap)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        bfa_trc(bfa, bitmap);
-       bfa_trc(bfa, pport->cfg.trunked);
-       bfa_trc(bfa, pport->cfg.trunk_ports);
+       bfa_trc(bfa, fcport->cfg.trunked);
+       bfa_trc(bfa, fcport->cfg.trunk_ports);
 
        if (!bitmap || (bitmap & (bitmap - 1)))
                return BFA_STATUS_EINVAL;
 
-       pport->cfg.trunked = BFA_TRUE;
-       pport->cfg.trunk_ports = bitmap;
+       fcport->cfg.trunked = BFA_TRUE;
+       fcport->cfg.trunk_ports = bitmap;
 
        return BFA_STATUS_OK;
 }
 
 void
-bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr)
+bfa_fcport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       qos_attr->state = bfa_os_ntohl(pport->qos_attr.state);
-       qos_attr->total_bb_cr = bfa_os_ntohl(pport->qos_attr.total_bb_cr);
+       qos_attr->state = bfa_os_ntohl(fcport->qos_attr.state);
+       qos_attr->total_bb_cr = bfa_os_ntohl(fcport->qos_attr.total_bb_cr);
 }
 
 void
-bfa_pport_qos_get_vc_attr(struct bfa_s *bfa,
+bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa,
                          struct bfa_qos_vc_attr_s *qos_vc_attr)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
-       struct bfa_qos_vc_attr_s *bfa_vc_attr = &pport->qos_vc_attr;
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+       struct bfa_qos_vc_attr_s *bfa_vc_attr = &fcport->qos_vc_attr;
        u32        i = 0;
 
        qos_vc_attr->total_vc_count = bfa_os_ntohs(bfa_vc_attr->total_vc_count);
@@ -1503,119 +1754,89 @@ bfa_pport_qos_get_vc_attr(struct bfa_s *bfa,
 }
 
 /**
- * Fetch QoS Stats.
- */
-bfa_status_t
-bfa_pport_get_qos_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats,
-                       bfa_cb_pport_t cbfn, void *cbarg)
-{
-       /*
-        * QoS stats is embedded in port stats
-        */
-       return bfa_pport_get_stats(bfa, stats, cbfn, cbarg);
-}
-
-bfa_status_t
-bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
-{
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
-
-       if (port->stats_busy) {
-               bfa_trc(bfa, port->stats_busy);
-               return BFA_STATUS_DEVBUSY;
-       }
-
-       port->stats_busy = BFA_TRUE;
-       port->stats_cbfn = cbfn;
-       port->stats_cbarg = cbarg;
-
-       bfa_port_qos_stats_clear(port);
-
-       bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port,
-                       BFA_PORT_STATS_TOV);
-       return BFA_STATUS_OK;
-}
-
-/**
  * Fetch port attributes.
  */
 bfa_status_t
-bfa_pport_trunk_disable(struct bfa_s *bfa)
+bfa_fcport_trunk_disable(struct bfa_s *bfa)
 {
        return BFA_STATUS_OK;
 }
 
 bfa_boolean_t
-bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap)
+bfa_fcport_trunk_query(struct bfa_s *bfa, u32 *bitmap)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       *bitmap = port->cfg.trunk_ports;
-       return port->cfg.trunked;
+       *bitmap = fcport->cfg.trunk_ports;
+       return fcport->cfg.trunked;
 }
 
 bfa_boolean_t
-bfa_pport_is_disabled(struct bfa_s *bfa)
+bfa_fcport_is_disabled(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       return bfa_sm_to_state(hal_pport_sm_table, port->sm) ==
+       return bfa_sm_to_state(hal_pport_sm_table, fcport->sm) ==
                BFA_PPORT_ST_DISABLED;
 
 }
 
 bfa_boolean_t
-bfa_pport_is_ratelim(struct bfa_s *bfa)
+bfa_fcport_is_ratelim(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       return pport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE;
+       return fcport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE;
 
 }
 
 void
-bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off)
+bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+       enum bfa_ioc_type_e ioc_type = bfa_get_type(bfa);
 
        bfa_trc(bfa, on_off);
-       bfa_trc(bfa, pport->cfg.qos_enabled);
+       bfa_trc(bfa, fcport->cfg.qos_enabled);
+
+       bfa_trc(bfa, ioc_type);
 
-       pport->cfg.qos_enabled = on_off;
+       if (ioc_type == BFA_IOC_TYPE_FC)
+               fcport->cfg.qos_enabled = on_off;
 }
 
 void
-bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off)
+bfa_fcport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        bfa_trc(bfa, on_off);
-       bfa_trc(bfa, pport->cfg.ratelimit);
+       bfa_trc(bfa, fcport->cfg.ratelimit);
 
-       pport->cfg.ratelimit = on_off;
-       if (pport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN)
-               pport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS;
+       fcport->cfg.ratelimit = on_off;
+       if (fcport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN)
+               fcport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS;
 }
 
 /**
  * Configure default minimum ratelim speed
  */
 bfa_status_t
-bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
+bfa_fcport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        bfa_trc(bfa, speed);
 
        /*
         * Auto and speeds greater than the supported speed, are invalid
         */
-       if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > pport->speed_sup)) {
-               bfa_trc(bfa, pport->speed_sup);
+       if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > fcport->speed_sup)) {
+               bfa_trc(bfa, fcport->speed_sup);
                return BFA_STATUS_UNSUPP_SPEED;
        }
 
-       pport->cfg.trl_def_speed = speed;
+       fcport->cfg.trl_def_speed = speed;
 
        return BFA_STATUS_OK;
 }
@@ -1624,45 +1845,45 @@ bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
  * Get default minimum ratelim speed
  */
 enum bfa_pport_speed
-bfa_pport_get_ratelim_speed(struct bfa_s *bfa)
+bfa_fcport_get_ratelim_speed(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       bfa_trc(bfa, pport->cfg.trl_def_speed);
-       return pport->cfg.trl_def_speed;
+       bfa_trc(bfa, fcport->cfg.trl_def_speed);
+       return fcport->cfg.trl_def_speed;
 
 }
 
 void
-bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status)
+bfa_fcport_busy(struct bfa_s *bfa, bfa_boolean_t status)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        bfa_trc(bfa, status);
-       bfa_trc(bfa, pport->diag_busy);
+       bfa_trc(bfa, fcport->diag_busy);
 
-       pport->diag_busy = status;
+       fcport->diag_busy = status;
 }
 
 void
-bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
+bfa_fcport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
                 bfa_boolean_t link_e2e_beacon)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        bfa_trc(bfa, beacon);
        bfa_trc(bfa, link_e2e_beacon);
-       bfa_trc(bfa, pport->beacon);
-       bfa_trc(bfa, pport->link_e2e_beacon);
+       bfa_trc(bfa, fcport->beacon);
+       bfa_trc(bfa, fcport->link_e2e_beacon);
 
-       pport->beacon = beacon;
-       pport->link_e2e_beacon = link_e2e_beacon;
+       fcport->beacon = beacon;
+       fcport->link_e2e_beacon = link_e2e_beacon;
 }
 
 bfa_boolean_t
-bfa_pport_is_linkup(struct bfa_s *bfa)
+bfa_fcport_is_linkup(struct bfa_s *bfa)
 {
-       return bfa_sm_cmp_state(BFA_PORT_MOD(bfa), bfa_pport_sm_linkup);
+       return bfa_sm_cmp_state(BFA_FCPORT_MOD(bfa), bfa_fcport_sm_linkup);
 }
 
 
index 7cb39a3..3516172 100644 (file)
@@ -36,6 +36,7 @@
  * FCS sub-modules
  */
 struct bfa_fcs_mod_s {
+       void            (*attach) (struct bfa_fcs_s *fcs);
        void            (*modinit) (struct bfa_fcs_s *fcs);
        void            (*modexit) (struct bfa_fcs_s *fcs);
 };
@@ -43,12 +44,10 @@ struct bfa_fcs_mod_s {
 #define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit }
 
 static struct bfa_fcs_mod_s fcs_modules[] = {
-       BFA_FCS_MODULE(bfa_fcs_pport),
-       BFA_FCS_MODULE(bfa_fcs_uf),
-       BFA_FCS_MODULE(bfa_fcs_fabric),
-       BFA_FCS_MODULE(bfa_fcs_vport),
-       BFA_FCS_MODULE(bfa_fcs_rport),
-       BFA_FCS_MODULE(bfa_fcs_fcpim),
+       { bfa_fcs_pport_attach, NULL, NULL },
+       { bfa_fcs_uf_attach, NULL, NULL },
+       { bfa_fcs_fabric_attach, bfa_fcs_fabric_modinit,
+        bfa_fcs_fabric_modexit },
 };
 
 /**
@@ -71,16 +70,10 @@ bfa_fcs_exit_comp(void *fcs_cbarg)
  */
 
 /**
- *             FCS instance initialization.
- *
- *     param[in]               fcs             FCS instance
- *     param[in]               bfa             BFA instance
- *     param[in]               bfad            BFA driver instance
- *
- *     return None
+ * fcs attach -- called once to initialize data structures at driver attach time
  */
 void
-bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
+bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
                        bfa_boolean_t min_cfg)
 {
        int             i;
@@ -95,7 +88,24 @@ bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
 
        for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
                mod = &fcs_modules[i];
-               mod->modinit(fcs);
+               if (mod->attach)
+                       mod->attach(fcs);
+       }
+}
+
+/**
+ * fcs initialization, called once after bfa initialization is complete
+ */
+void
+bfa_fcs_init(struct bfa_fcs_s *fcs)
+{
+       int             i;
+       struct bfa_fcs_mod_s  *mod;
+
+       for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
+               mod = &fcs_modules[i];
+               if (mod->modinit)
+                       mod->modinit(fcs);
        }
 }
 
@@ -127,6 +137,23 @@ bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
 }
 
 /**
+ *      @brief
+ *              FCS FDMI Driver Parameter Initialization
+ *
+ *      @param[in]              fcs             FCS instance
+ *      @param[in]              fdmi_enable     TRUE/FALSE
+ *
+ *      @return None
+ */
+void
+bfa_fcs_set_fdmi_param(struct bfa_fcs_s *fcs, bfa_boolean_t fdmi_enable)
+{
+
+       fcs->fdmi_enabled = fdmi_enable;
+
+}
+
+/**
  *             FCS instance cleanup and exit.
  *
  *     param[in]               fcs                     FCS instance
@@ -143,10 +170,12 @@ bfa_fcs_exit(struct bfa_fcs_s *fcs)
        nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]);
 
        for (i = 0; i < nmods; i++) {
-               bfa_wc_up(&fcs->wc);
 
                mod = &fcs_modules[i];
-               mod->modexit(fcs);
+               if (mod->modexit) {
+                       bfa_wc_up(&fcs->wc);
+                       mod->modexit(fcs);
+               }
        }
 
        bfa_wc_wait(&fcs->wc);
index c7ab257..7c1251c 100644 (file)
@@ -114,7 +114,7 @@ bfa_fcs_port_sm_uninit(struct bfa_fcs_port_s *port,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
@@ -136,7 +136,7 @@ bfa_fcs_port_sm_init(struct bfa_fcs_port_s *port, enum bfa_fcs_port_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
@@ -176,7 +176,7 @@ bfa_fcs_port_sm_online(struct bfa_fcs_port_s *port,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
@@ -214,7 +214,7 @@ bfa_fcs_port_sm_offline(struct bfa_fcs_port_s *port,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
@@ -234,7 +234,7 @@ bfa_fcs_port_sm_deleting(struct bfa_fcs_port_s *port,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
@@ -263,30 +263,8 @@ bfa_fcs_port_aen_post(struct bfa_fcs_port_s *port,
 
        bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX);
 
-       switch (event) {
-       case BFA_LPORT_AEN_ONLINE:
-               bfa_log(logmod, BFA_AEN_LPORT_ONLINE, lpwwn_ptr,
-                       role_str[role / 2]);
-               break;
-       case BFA_LPORT_AEN_OFFLINE:
-               bfa_log(logmod, BFA_AEN_LPORT_OFFLINE, lpwwn_ptr,
-                       role_str[role / 2]);
-               break;
-       case BFA_LPORT_AEN_NEW:
-               bfa_log(logmod, BFA_AEN_LPORT_NEW, lpwwn_ptr,
-                       role_str[role / 2]);
-               break;
-       case BFA_LPORT_AEN_DELETE:
-               bfa_log(logmod, BFA_AEN_LPORT_DELETE, lpwwn_ptr,
-                       role_str[role / 2]);
-               break;
-       case BFA_LPORT_AEN_DISCONNECT:
-               bfa_log(logmod, BFA_AEN_LPORT_DISCONNECT, lpwwn_ptr,
-                       role_str[role / 2]);
-               break;
-       default:
-               break;
-       }
+       bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, event), lpwwn_ptr,
+               role_str[role/2]);
 
        aen_data.lport.vf_id = port->fabric->vf_id;
        aen_data.lport.roles = role;
@@ -873,36 +851,46 @@ bfa_fcs_port_is_online(struct bfa_fcs_port_s *port)
 }
 
 /**
- * Logical port initialization of base or virtual port.
- * Called by fabric for base port or by vport for virtual ports.
+ * Attach time initialization of logical ports.
  */
 void
-bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
-                  u16 vf_id, struct bfa_port_cfg_s *port_cfg,
-                  struct bfa_fcs_vport_s *vport)
+bfa_fcs_lport_attach(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
+               uint16_t vf_id, struct bfa_fcs_vport_s *vport)
 {
        lport->fcs = fcs;
        lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id);
-       bfa_os_assign(lport->port_cfg, *port_cfg);
        lport->vport = vport;
        lport->lp_tag = (vport) ? bfa_lps_get_tag(vport->lps) :
                         bfa_lps_get_tag(lport->fabric->lps);
 
        INIT_LIST_HEAD(&lport->rport_q);
        lport->num_rports = 0;
+}
+
+/**
+ * Logical port initialization of base or virtual port.
+ * Called by fabric for base port or by vport for virtual ports.
+ */
 
-       lport->bfad_port =
-               bfa_fcb_port_new(fcs->bfad, lport, lport->port_cfg.roles,
+void
+bfa_fcs_lport_init(struct bfa_fcs_port_s *lport,
+               struct bfa_port_cfg_s *port_cfg)
+{
+       struct bfa_fcs_vport_s *vport = lport->vport;
+
+       bfa_os_assign(lport->port_cfg, *port_cfg);
+
+       lport->bfad_port = bfa_fcb_port_new(lport->fcs->bfad, lport,
+                               lport->port_cfg.roles,
                                lport->fabric->vf_drv,
                                vport ? vport->vport_drv : NULL);
+
        bfa_fcs_port_aen_post(lport, BFA_LPORT_AEN_NEW);
 
        bfa_sm_set_state(lport, bfa_fcs_port_sm_uninit);
        bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
 }
 
-
-
 /**
  *  fcs_lport_api
  */
@@ -921,13 +909,20 @@ bfa_fcs_port_get_attr(struct bfa_fcs_port_s *port,
        if (port->fabric) {
                port_attr->port_type = bfa_fcs_fabric_port_type(port->fabric);
                port_attr->loopback = bfa_fcs_fabric_is_loopback(port->fabric);
+               port_attr->authfail =
+                               bfa_fcs_fabric_is_auth_failed(port->fabric);
                port_attr->fabric_name = bfa_fcs_port_get_fabric_name(port);
                memcpy(port_attr->fabric_ip_addr,
                       bfa_fcs_port_get_fabric_ipaddr(port),
                       BFA_FCS_FABRIC_IPADDR_SZ);
 
-               if (port->vport != NULL)
+               if (port->vport != NULL) {
                        port_attr->port_type = BFA_PPORT_TYPE_VPORT;
+                       port_attr->fpma_mac =
+                               bfa_lps_get_lp_mac(port->vport->lps);
+               } else
+                       port_attr->fpma_mac =
+                               bfa_lps_get_lp_mac(port->fabric->lps);
 
        } else {
                port_attr->port_type = BFA_PPORT_TYPE_UNKNOWN;
index 9c4b24e..3c27788 100644 (file)
@@ -55,14 +55,7 @@ bfa_fcs_pport_event_handler(void *cbarg, bfa_pport_event_t event)
 }
 
 void
-bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs)
+bfa_fcs_pport_attach(struct bfa_fcs_s *fcs)
 {
-       bfa_pport_event_register(fcs->bfa, bfa_fcs_pport_event_handler,
-                                    fcs);
-}
-
-void
-bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs)
-{
-       bfa_fcs_modexit_comp(fcs);
+       bfa_fcport_event_register(fcs->bfa, bfa_fcs_pport_event_handler, fcs);
 }
index ad01db6..3d57d48 100644 (file)
@@ -93,13 +93,7 @@ bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf)
 }
 
 void
-bfa_fcs_uf_modinit(struct bfa_fcs_s *fcs)
+bfa_fcs_uf_attach(struct bfa_fcs_s *fcs)
 {
        bfa_uf_recv_register(fcs->bfa, bfa_fcs_uf_recv, fcs);
 }
-
-void
-bfa_fcs_uf_modexit(struct bfa_fcs_s *fcs)
-{
-       bfa_fcs_modexit_comp(fcs);
-}
index ede1438..871a4e2 100644 (file)
@@ -53,6 +53,18 @@ bfa_hwcb_reginit(struct bfa_s *bfa)
 }
 
 void
+bfa_hwcb_reqq_ack(struct bfa_s *bfa, int reqq)
+{
+}
+
+static void
+bfa_hwcb_reqq_ack_msix(struct bfa_s *bfa, int reqq)
+{
+       bfa_reg_write(bfa->iocfc.bfa_regs.intr_status,
+               __HFN_INT_CPE_Q0 << CPE_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), reqq));
+}
+
+void
 bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq)
 {
 }
@@ -136,6 +148,7 @@ bfa_hwcb_msix_uninstall(struct bfa_s *bfa)
 void
 bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
 {
+       bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix;
        bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix;
 }
 
index 51ae574..76ceb9a 100644 (file)
@@ -85,6 +85,15 @@ bfa_hwct_reginit(struct bfa_s *bfa)
 }
 
 void
+bfa_hwct_reqq_ack(struct bfa_s *bfa, int reqq)
+{
+       u32 r32;
+
+       r32 = bfa_reg_read(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq]);
+       bfa_reg_write(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq], r32);
+}
+
+void
 bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq)
 {
        u32     r32;
index b36540e..0eba3f9 100644 (file)
@@ -15,7 +15,7 @@
  * General Public License for more details.
  */
 #include <bfa.h>
-#include <bfi/bfi_cbreg.h>
+#include <bfi/bfi_ctreg.h>
 #include <bfa_port_priv.h>
 #include <bfa_intr_priv.h>
 #include <cs/bfa_debug.h>
@@ -34,6 +34,26 @@ bfa_msix_lpu(struct bfa_s *bfa)
        bfa_ioc_mbox_isr(&bfa->ioc);
 }
 
+static void
+bfa_reqq_resume(struct bfa_s *bfa, int qid)
+{
+       struct list_head *waitq, *qe, *qen;
+       struct bfa_reqq_wait_s *wqe;
+
+       waitq = bfa_reqq(bfa, qid);
+       list_for_each_safe(qe, qen, waitq) {
+               /**
+                * Callback only as long as there is room in request queue
+                */
+               if (bfa_reqq_full(bfa, qid))
+                       break;
+
+               list_del(qe);
+               wqe = (struct bfa_reqq_wait_s *) qe;
+               wqe->qresume(wqe->cbarg);
+       }
+}
+
 void
 bfa_msix_all(struct bfa_s *bfa, int vec)
 {
@@ -96,7 +116,8 @@ bfa_isr_enable(struct bfa_s *bfa)
 
        bfa_msix_install(bfa);
        intr_unmask = (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
-                      __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS);
+                      __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS |
+                      __HFN_INT_LL_HALT);
 
        if (pci_func == 0)
                intr_unmask |= (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 |
@@ -127,23 +148,18 @@ bfa_isr_disable(struct bfa_s *bfa)
 void
 bfa_msix_reqq(struct bfa_s *bfa, int qid)
 {
-       struct list_head                *waitq, *qe, *qen;
-       struct bfa_reqq_wait_s  *wqe;
+       struct list_head *waitq;
 
        qid &= (BFI_IOC_MAX_CQS - 1);
 
-       waitq = bfa_reqq(bfa, qid);
-       list_for_each_safe(qe, qen, waitq) {
-               /**
-                * Callback only as long as there is room in request queue
-                */
-               if (bfa_reqq_full(bfa, qid))
-                       break;
+       bfa->iocfc.hwif.hw_reqq_ack(bfa, qid);
 
-               list_del(qe);
-               wqe = (struct bfa_reqq_wait_s *) qe;
-               wqe->qresume(wqe->cbarg);
-       }
+       /**
+        * Resume any pending requests in the corresponding reqq.
+        */
+       waitq = bfa_reqq(bfa, qid);
+       if (!list_empty(waitq))
+               bfa_reqq_resume(bfa, qid);
 }
 
 void
@@ -157,26 +173,27 @@ bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m)
 }
 
 void
-bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid)
+bfa_msix_rspq(struct bfa_s *bfa, int qid)
 {
-       struct bfi_msg_s      *m;
-       u32        pi, ci;
+       struct bfi_msg_s *m;
+       u32 pi, ci;
+       struct list_head *waitq;
 
-       bfa_trc_fp(bfa, rsp_qid);
+       bfa_trc_fp(bfa, qid);
 
-       rsp_qid &= (BFI_IOC_MAX_CQS - 1);
+       qid &= (BFI_IOC_MAX_CQS - 1);
 
-       bfa->iocfc.hwif.hw_rspq_ack(bfa, rsp_qid);
+       bfa->iocfc.hwif.hw_rspq_ack(bfa, qid);
 
-       ci = bfa_rspq_ci(bfa, rsp_qid);
-       pi = bfa_rspq_pi(bfa, rsp_qid);
+       ci = bfa_rspq_ci(bfa, qid);
+       pi = bfa_rspq_pi(bfa, qid);
 
        bfa_trc_fp(bfa, ci);
        bfa_trc_fp(bfa, pi);
 
        if (bfa->rme_process) {
                while (ci != pi) {
-                       m = bfa_rspq_elem(bfa, rsp_qid, ci);
+                       m = bfa_rspq_elem(bfa, qid, ci);
                        bfa_assert_fp(m->mhdr.msg_class < BFI_MC_MAX);
 
                        bfa_isrs[m->mhdr.msg_class] (bfa, m);
@@ -188,25 +205,59 @@ bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid)
        /**
         * update CI
         */
-       bfa_rspq_ci(bfa, rsp_qid) = pi;
-       bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[rsp_qid], pi);
+       bfa_rspq_ci(bfa, qid) = pi;
+       bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[qid], pi);
        bfa_os_mmiowb();
+
+       /**
+        * Resume any pending requests in the corresponding reqq.
+        */
+       waitq = bfa_reqq(bfa, qid);
+       if (!list_empty(waitq))
+               bfa_reqq_resume(bfa, qid);
 }
 
 void
 bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
 {
-       u32 intr;
+       u32 intr, curr_value;
 
        intr = bfa_reg_read(bfa->iocfc.bfa_regs.intr_status);
 
        if (intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1))
                bfa_msix_lpu(bfa);
 
-       if (intr & (__HFN_INT_ERR_EMC |
-                   __HFN_INT_ERR_LPU0 | __HFN_INT_ERR_LPU1 |
-                   __HFN_INT_ERR_PSS))
+       intr &= (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
+               __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS | __HFN_INT_LL_HALT);
+
+       if (intr) {
+               if (intr & __HFN_INT_LL_HALT) {
+                       /**
+                        * If LL_HALT bit is set then FW Init Halt LL Port
+                        * Register needs to be cleared as well so Interrupt
+                        * Status Register will be cleared.
+                        */
+                       curr_value = bfa_reg_read(bfa->ioc.ioc_regs.ll_halt);
+                       curr_value &= ~__FW_INIT_HALT_P;
+                       bfa_reg_write(bfa->ioc.ioc_regs.ll_halt, curr_value);
+               }
+
+               if (intr & __HFN_INT_ERR_PSS) {
+                       /**
+                        * ERR_PSS bit needs to be cleared as well in case
+                        * interrups are shared so driver's interrupt handler is
+                        * still called eventhough it is already masked out.
+                        */
+                       curr_value = bfa_reg_read(
+                               bfa->ioc.ioc_regs.pss_err_status_reg);
+                       curr_value &= __PSS_ERR_STATUS_SET;
+                       bfa_reg_write(bfa->ioc.ioc_regs.pss_err_status_reg,
+                               curr_value);
+               }
+
+               bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, intr);
                bfa_msix_errint(bfa, intr);
+       }
 }
 
 void
index 397d7e9..e038bc9 100644 (file)
@@ -18,7 +18,7 @@
 #include <bfa.h>
 #include <bfa_ioc.h>
 #include <bfa_fwimg_priv.h>
-#include <bfa_trcmod_priv.h>
+#include <cna/bfa_cna_trcmod.h>
 #include <cs/bfa_debug.h>
 #include <bfi/bfi_ioc.h>
 #include <bfi/bfi_ctreg.h>
 #include <log/bfa_log_hal.h>
 #include <defs/bfa_defs_pci.h>
 
-BFA_TRC_FILE(HAL, IOC);
+BFA_TRC_FILE(CNA, IOC);
 
 /**
  * IOC local definitions
  */
 #define BFA_IOC_TOV            2000    /* msecs */
-#define BFA_IOC_HB_TOV         1000    /* msecs */
-#define BFA_IOC_HB_FAIL_MAX    4
-#define BFA_IOC_HWINIT_MAX     2
+#define BFA_IOC_HWSEM_TOV       500     /* msecs */
+#define BFA_IOC_HB_TOV          500     /* msecs */
+#define BFA_IOC_HWINIT_MAX      2
 #define BFA_IOC_FWIMG_MINSZ     (16 * 1024)
-#define BFA_IOC_TOV_RECOVER    (BFA_IOC_HB_FAIL_MAX * BFA_IOC_HB_TOV \
-                               + BFA_IOC_TOV)
+#define BFA_IOC_TOV_RECOVER      BFA_IOC_HB_TOV
 
 #define bfa_ioc_timer_start(__ioc)                                     \
        bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer,        \
@@ -51,12 +50,25 @@ BFA_TRC_FILE(HAL, IOC);
         (sizeof(struct bfa_trc_mod_s) -                        \
          BFA_TRC_MAX * sizeof(struct bfa_trc_s)))
 #define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn))
-#define bfa_ioc_stats(_ioc, _stats)    ((_ioc)->stats._stats++)
 
-#define BFA_FLASH_CHUNK_NO(off)         (off / BFI_FLASH_CHUNK_SZ_WORDS)
-#define BFA_FLASH_OFFSET_IN_CHUNK(off)  (off % BFI_FLASH_CHUNK_SZ_WORDS)
-#define BFA_FLASH_CHUNK_ADDR(chunkno)   (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)
-bfa_boolean_t   bfa_auto_recover = BFA_FALSE;
+/**
+ * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details.
+ */
+
+#define bfa_ioc_firmware_lock(__ioc)                    \
+                       ((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc))
+#define bfa_ioc_firmware_unlock(__ioc)                  \
+                       ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc))
+#define bfa_ioc_fwimg_get_chunk(__ioc, __off)           \
+                       ((__ioc)->ioc_hwif->ioc_fwimg_get_chunk(__ioc, __off))
+#define bfa_ioc_fwimg_get_size(__ioc)                   \
+                       ((__ioc)->ioc_hwif->ioc_fwimg_get_size(__ioc))
+#define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc))
+#define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc))
+#define bfa_ioc_notify_hbfail(__ioc)                    \
+                       ((__ioc)->ioc_hwif->ioc_notify_hbfail(__ioc))
+
+bfa_boolean_t   bfa_auto_recover = BFA_TRUE;
 
 /*
  * forward declarations
@@ -64,7 +76,6 @@ bfa_boolean_t   bfa_auto_recover = BFA_FALSE;
 static void     bfa_ioc_aen_post(struct bfa_ioc_s *bfa,
                                 enum bfa_ioc_aen_event event);
 static void     bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc);
-static void     bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc);
 static void     bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc);
 static void     bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force);
 static void     bfa_ioc_timeout(void *ioc);
@@ -77,8 +88,6 @@ static void     bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force);
 static void     bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc);
 static void     bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc);
 static void     bfa_ioc_recover(struct bfa_ioc_s *ioc);
-static bfa_boolean_t bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc);
-static void     bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc);
 static void     bfa_ioc_disable_comp(struct bfa_ioc_s *ioc);
 static void     bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc);
 
@@ -508,14 +517,19 @@ bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event)
        bfa_trc(ioc, event);
 
        switch (event) {
-       case IOC_E_HWERROR:
        case IOC_E_FWRSP_DISABLE:
                bfa_ioc_timer_stop(ioc);
+               bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+               break;
+
+       case IOC_E_HWERROR:
+               bfa_ioc_timer_stop(ioc);
                /*
                 * !!! fall through !!!
                 */
 
        case IOC_E_TIMEOUT:
+               bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_FAIL);
                bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
                break;
 
@@ -608,15 +622,12 @@ bfa_ioc_sm_hbfail_entry(struct bfa_ioc_s *ioc)
         * Mark IOC as failed in hardware and stop firmware.
         */
        bfa_ioc_lpu_stop(ioc);
-       bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_HBFAIL);
+       bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_FAIL);
 
-       if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
-               bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P);
-               /*
-                * Wait for halt to take effect
-                */
-               bfa_reg_read(ioc->ioc_regs.ll_halt);
-       }
+       /**
+        * Notify other functions on HB failure.
+        */
+       bfa_ioc_notify_hbfail(ioc);
 
        /**
         * Notify driver and common modules registered for notification.
@@ -672,6 +683,12 @@ bfa_ioc_sm_hbfail(struct bfa_ioc_s *ioc, enum ioc_event event)
                 */
                break;
 
+       case IOC_E_HWERROR:
+               /*
+                * HB failure notification, ignore.
+                */
+               break;
+
        default:
                bfa_sm_fault(ioc, event);
        }
@@ -700,7 +717,7 @@ bfa_ioc_disable_comp(struct bfa_ioc_s *ioc)
        }
 }
 
-static void
+void
 bfa_ioc_sem_timeout(void *ioc_arg)
 {
        struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg;
@@ -708,26 +725,32 @@ bfa_ioc_sem_timeout(void *ioc_arg)
        bfa_ioc_hw_sem_get(ioc);
 }
 
-static void
-bfa_ioc_usage_sem_get(struct bfa_ioc_s *ioc)
+bfa_boolean_t
+bfa_ioc_sem_get(bfa_os_addr_t sem_reg)
 {
-       u32        r32;
-       int             cnt = 0;
-#define BFA_SEM_SPINCNT        1000
+       u32 r32;
+       int cnt = 0;
+#define BFA_SEM_SPINCNT 3000
 
-       do {
-               r32 = bfa_reg_read(ioc->ioc_regs.ioc_usage_sem_reg);
+       r32 = bfa_reg_read(sem_reg);
+
+       while (r32 && (cnt < BFA_SEM_SPINCNT)) {
                cnt++;
-               if (cnt > BFA_SEM_SPINCNT)
-                       break;
-       } while (r32 != 0);
+               bfa_os_udelay(2);
+               r32 = bfa_reg_read(sem_reg);
+       }
+
+       if (r32 == 0)
+               return BFA_TRUE;
+
        bfa_assert(cnt < BFA_SEM_SPINCNT);
+       return BFA_FALSE;
 }
 
-static void
-bfa_ioc_usage_sem_release(struct bfa_ioc_s *ioc)
+void
+bfa_ioc_sem_release(bfa_os_addr_t sem_reg)
 {
-       bfa_reg_write(ioc->ioc_regs.ioc_usage_sem_reg, 1);
+       bfa_reg_write(sem_reg, 1);
 }
 
 static void
@@ -737,7 +760,7 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
 
        /**
         * First read to the semaphore register will return 0, subsequent reads
-        * will return 1. Semaphore is released by writing 0 to the register
+        * will return 1. Semaphore is released by writing 1 to the register
         */
        r32 = bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
        if (r32 == 0) {
@@ -746,10 +769,10 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
        }
 
        bfa_timer_begin(ioc->timer_mod, &ioc->sem_timer, bfa_ioc_sem_timeout,
-                       ioc, BFA_IOC_TOV);
+                       ioc, BFA_IOC_HWSEM_TOV);
 }
 
-static void
+void
 bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc)
 {
        bfa_reg_write(ioc->ioc_regs.ioc_sem_reg, 1);
@@ -828,7 +851,7 @@ bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc)
 /**
  * Get driver and firmware versions.
  */
-static void
+void
 bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
 {
        u32        pgnum, pgoff;
@@ -847,24 +870,10 @@ bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
        }
 }
 
-static u32 *
-bfa_ioc_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
-{
-       if (ioc->ctdev)
-               return bfi_image_ct_get_chunk(off);
-       return bfi_image_cb_get_chunk(off);
-}
-
-static          u32
-bfa_ioc_fwimg_get_size(struct bfa_ioc_s *ioc)
-{
-return (ioc->ctdev) ? bfi_image_ct_size : bfi_image_cb_size;
-}
-
 /**
  * Returns TRUE if same.
  */
-static          bfa_boolean_t
+bfa_boolean_t
 bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
 {
        struct bfi_ioc_image_hdr_s *drv_fwhdr;
@@ -921,95 +930,6 @@ bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc)
 }
 
 /**
- * Return true if firmware of current driver matches the running firmware.
- */
-static          bfa_boolean_t
-bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc)
-{
-       enum bfi_ioc_state ioc_fwstate;
-       u32        usecnt;
-       struct bfi_ioc_image_hdr_s fwhdr;
-
-       /**
-        * Firmware match check is relevant only for CNA.
-        */
-       if (!ioc->cna)
-               return BFA_TRUE;
-
-       /**
-        * If bios boot (flash based) -- do not increment usage count
-        */
-       if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
-               return BFA_TRUE;
-
-       bfa_ioc_usage_sem_get(ioc);
-       usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
-
-       /**
-        * If usage count is 0, always return TRUE.
-        */
-       if (usecnt == 0) {
-               bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1);
-               bfa_ioc_usage_sem_release(ioc);
-               bfa_trc(ioc, usecnt);
-               return BFA_TRUE;
-       }
-
-       ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
-       bfa_trc(ioc, ioc_fwstate);
-
-       /**
-        * Use count cannot be non-zero and chip in uninitialized state.
-        */
-       bfa_assert(ioc_fwstate != BFI_IOC_UNINIT);
-
-       /**
-        * Check if another driver with a different firmware is active
-        */
-       bfa_ioc_fwver_get(ioc, &fwhdr);
-       if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
-               bfa_ioc_usage_sem_release(ioc);
-               bfa_trc(ioc, usecnt);
-               return BFA_FALSE;
-       }
-
-       /**
-        * Same firmware version. Increment the reference count.
-        */
-       usecnt++;
-       bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
-       bfa_ioc_usage_sem_release(ioc);
-       bfa_trc(ioc, usecnt);
-       return BFA_TRUE;
-}
-
-static void
-bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc)
-{
-       u32        usecnt;
-
-       /**
-        * Firmware lock is relevant only for CNA.
-        * If bios boot (flash based) -- do not decrement usage count
-        */
-       if (!ioc->cna || (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ))
-               return;
-
-       /**
-        * decrement usage count
-        */
-       bfa_ioc_usage_sem_get(ioc);
-       usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
-       bfa_assert(usecnt > 0);
-
-       usecnt--;
-       bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
-       bfa_trc(ioc, usecnt);
-
-       bfa_ioc_usage_sem_release(ioc);
-}
-
-/**
  * Conditionally flush any pending message from firmware at start.
  */
 static void
@@ -1152,33 +1072,27 @@ bfa_ioc_send_getattr(struct bfa_ioc_s *ioc)
 static void
 bfa_ioc_hb_check(void *cbarg)
 {
-       struct bfa_ioc_s *ioc = cbarg;
-       u32        hb_count;
+       struct bfa_ioc_s  *ioc = cbarg;
+       u32     hb_count;
 
        hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
        if (ioc->hb_count == hb_count) {
-               ioc->hb_fail++;
-       } else {
-               ioc->hb_count = hb_count;
-               ioc->hb_fail = 0;
-       }
-
-       if (ioc->hb_fail >= BFA_IOC_HB_FAIL_MAX) {
-               bfa_log(ioc->logm, BFA_LOG_HAL_HEARTBEAT_FAILURE, hb_count);
-               ioc->hb_fail = 0;
+               bfa_log(ioc->logm, BFA_LOG_HAL_HEARTBEAT_FAILURE,
+                       hb_count);
                bfa_ioc_recover(ioc);
                return;
+       } else {
+               ioc->hb_count = hb_count;
        }
 
        bfa_ioc_mbox_poll(ioc);
-       bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc,
-                       BFA_IOC_HB_TOV);
+       bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check,
+                       ioc, BFA_IOC_HB_TOV);
 }
 
 static void
 bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc)
 {
-       ioc->hb_fail = 0;
        ioc->hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
        bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc,
                        BFA_IOC_HB_TOV);
@@ -1191,112 +1105,6 @@ bfa_ioc_hb_stop(struct bfa_ioc_s *ioc)
 }
 
 /**
- * Host to LPU mailbox message addresses
- */
-static struct {
-       u32        hfn_mbox, lpu_mbox, hfn_pgn;
-} iocreg_fnreg[] = {
-       {
-       HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0}, {
-       HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1}, {
-       HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2}, {
-       HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3}
-};
-
-/**
- * Host <-> LPU mailbox command/status registers - port 0
- */
-static struct {
-       u32        hfn, lpu;
-} iocreg_mbcmd_p0[] = {
-       {
-       HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT}, {
-       HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT}, {
-       HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT}, {
-       HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT}
-};
-
-/**
- * Host <-> LPU mailbox command/status registers - port 1
- */
-static struct {
-       u32        hfn, lpu;
-} iocreg_mbcmd_p1[] = {
-       {
-       HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT}, {
-       HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT}, {
-       HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT}, {
-       HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT}
-};
-
-/**
- * Shared IRQ handling in INTX mode
- */
-static struct {
-       u32        isr, msk;
-} iocreg_shirq_next[] = {
-       {
-       HOSTFN1_INT_STATUS, HOSTFN1_INT_MSK}, {
-       HOSTFN2_INT_STATUS, HOSTFN2_INT_MSK}, {
-       HOSTFN3_INT_STATUS, HOSTFN3_INT_MSK}, {
-HOSTFN0_INT_STATUS, HOSTFN0_INT_MSK},};
-
-static void
-bfa_ioc_reg_init(struct bfa_ioc_s *ioc)
-{
-       bfa_os_addr_t   rb;
-       int             pcifn = bfa_ioc_pcifn(ioc);
-
-       rb = bfa_ioc_bar0(ioc);
-
-       ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
-       ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
-       ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
-
-       if (ioc->port_id == 0) {
-               ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
-               ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
-               ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
-               ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
-               ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
-       } else {
-               ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
-               ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
-               ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
-               ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
-               ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
-       }
-
-       /**
-        * Shared IRQ handling in INTX mode
-        */
-       ioc->ioc_regs.shirq_isr_next = rb + iocreg_shirq_next[pcifn].isr;
-       ioc->ioc_regs.shirq_msk_next = rb + iocreg_shirq_next[pcifn].msk;
-
-       /*
-        * PSS control registers
-        */
-       ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
-       ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
-       ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
-
-       /*
-        * IOC semaphore registers and serialization
-        */
-       ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
-       ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
-       ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
-
-       /**
-        * sram memory access
-        */
-       ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
-       ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB;
-       if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT)
-               ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
-}
-
-/**
  *      Initiate a full firmware download.
  */
 static void
@@ -1321,9 +1129,6 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
        if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
                boot_type = BFI_BOOT_TYPE_FLASH;
        fwimg = bfa_ioc_fwimg_get_chunk(ioc, chunkno);
-       fwimg[BFI_BOOT_TYPE_OFF / sizeof(u32)] = bfa_os_swap32(boot_type);
-       fwimg[BFI_BOOT_PARAM_OFF / sizeof(u32)] =
-               bfa_os_swap32(boot_param);
 
        pgnum = bfa_ioc_smem_pgnum(ioc, loff);
        pgoff = bfa_ioc_smem_pgoff(ioc, loff);
@@ -1332,17 +1137,17 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
 
        for (i = 0; i < bfa_ioc_fwimg_get_size(ioc); i++) {
 
-               if (BFA_FLASH_CHUNK_NO(i) != chunkno) {
-                       chunkno = BFA_FLASH_CHUNK_NO(i);
+               if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) {
+                       chunkno = BFA_IOC_FLASH_CHUNK_NO(i);
                        fwimg = bfa_ioc_fwimg_get_chunk(ioc,
-                                       BFA_FLASH_CHUNK_ADDR(chunkno));
+                                       BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
                }
 
                /**
                 * write smem
                 */
                bfa_mem_write(ioc->ioc_regs.smem_page_start, loff,
-                             fwimg[BFA_FLASH_OFFSET_IN_CHUNK(i)]);
+                             fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)]);
 
                loff += sizeof(u32);
 
@@ -1358,6 +1163,14 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
 
        bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
                      bfa_ioc_smem_pgnum(ioc, 0));
+
+       /*
+        * Set boot type and boot param at the end.
+        */
+       bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_TYPE_OFF,
+                       bfa_os_swap32(boot_type));
+       bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_PARAM_OFF,
+                       bfa_os_swap32(boot_param));
 }
 
 static void
@@ -1440,168 +1253,10 @@ bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc)
 }
 
 /**
- * Initialize IOC to port mapping.
- */
-
-#define FNC_PERS_FN_SHIFT(__fn)        ((__fn) * 8)
-static void
-bfa_ioc_map_port(struct bfa_ioc_s *ioc)
-{
-       bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
-       u32        r32;
-
-       /**
-        * For crossbow, port id is same as pci function.
-        */
-       if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT) {
-               ioc->port_id = bfa_ioc_pcifn(ioc);
-               return;
-       }
-
-       /**
-        * For catapult, base port id on personality register and IOC type
-        */
-       r32 = bfa_reg_read(rb + FNC_PERS_REG);
-       r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
-       ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
-
-       bfa_trc(ioc, bfa_ioc_pcifn(ioc));
-       bfa_trc(ioc, ioc->port_id);
-}
-
-
-
-/**
  *  bfa_ioc_public
  */
 
 /**
-* Set interrupt mode for a function: INTX or MSIX
- */
-void
-bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
-{
-       bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
-       u32        r32, mode;
-
-       r32 = bfa_reg_read(rb + FNC_PERS_REG);
-       bfa_trc(ioc, r32);
-
-       mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
-               __F0_INTX_STATUS;
-
-       /**
-        * If already in desired mode, do not change anything
-        */
-       if (!msix && mode)
-               return;
-
-       if (msix)
-               mode = __F0_INTX_STATUS_MSIX;
-       else
-               mode = __F0_INTX_STATUS_INTA;
-
-       r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
-       r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
-       bfa_trc(ioc, r32);
-
-       bfa_reg_write(rb + FNC_PERS_REG, r32);
-}
-
-bfa_status_t
-bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
-{
-       bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
-       u32        pll_sclk, pll_fclk, r32;
-
-       if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
-               pll_sclk =
-                       __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
-                       __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(0U) |
-                       __APP_PLL_312_JITLMT0_1(3U) |
-                       __APP_PLL_312_CNTLMT0_1(1U);
-               pll_fclk =
-                       __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
-                       __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(0U) |
-                       __APP_PLL_425_JITLMT0_1(3U) |
-                       __APP_PLL_425_CNTLMT0_1(1U);
-
-               /**
-                *      For catapult, choose operational mode FC/FCoE
-                */
-               if (ioc->fcmode) {
-                       bfa_reg_write((rb + OP_MODE), 0);
-                       bfa_reg_write((rb + ETH_MAC_SER_REG),
-                                     __APP_EMS_CMLCKSEL | __APP_EMS_REFCKBUFEN2
-                                     | __APP_EMS_CHANNEL_SEL);
-               } else {
-                       ioc->pllinit = BFA_TRUE;
-                       bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE);
-                       bfa_reg_write((rb + ETH_MAC_SER_REG),
-                                     __APP_EMS_REFCKBUFEN1);
-               }
-       } else {
-               pll_sclk =
-                       __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
-                       __APP_PLL_312_P0_1(3U) | __APP_PLL_312_JITLMT0_1(3U) |
-                       __APP_PLL_312_CNTLMT0_1(3U);
-               pll_fclk =
-                       __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
-                       __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
-                       __APP_PLL_425_JITLMT0_1(3U) |
-                       __APP_PLL_425_CNTLMT0_1(3U);
-       }
-
-       bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
-       bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
-
-       bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
-
-       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
-                     __APP_PLL_312_LOGIC_SOFT_RESET);
-       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
-                     __APP_PLL_312_BYPASS | __APP_PLL_312_LOGIC_SOFT_RESET);
-       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
-                     __APP_PLL_425_LOGIC_SOFT_RESET);
-       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
-                     __APP_PLL_425_BYPASS | __APP_PLL_425_LOGIC_SOFT_RESET);
-       bfa_os_udelay(2);
-       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
-                     __APP_PLL_312_LOGIC_SOFT_RESET);
-       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
-                     __APP_PLL_425_LOGIC_SOFT_RESET);
-
-       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
-                     pll_sclk | __APP_PLL_312_LOGIC_SOFT_RESET);
-       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
-                     pll_fclk | __APP_PLL_425_LOGIC_SOFT_RESET);
-
-       /**
-        * Wait for PLLs to lock.
-        */
-       bfa_os_udelay(2000);
-       bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
-
-       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk);
-       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk);
-
-       if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
-               bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
-               bfa_os_udelay(1000);
-               r32 = bfa_reg_read((rb + MBIST_STAT_REG));
-               bfa_trc(ioc, r32);
-       }
-
-       return BFA_STATUS_OK;
-}
-
-/**
  * Interface used by diag module to do firmware boot with memory test
  * as the entry vector.
  */
@@ -1642,7 +1297,7 @@ bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param)
 void
 bfa_ioc_auto_recover(bfa_boolean_t auto_recover)
 {
-       bfa_auto_recover = BFA_FALSE;
+       bfa_auto_recover = auto_recover;
 }
 
 
@@ -1764,6 +1419,14 @@ bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
        ioc->ctdev = (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT);
        ioc->cna = ioc->ctdev && !ioc->fcmode;
 
+       /**
+        * Set asic specific interfaces. See bfa_ioc_cb.c and bfa_ioc_ct.c
+        */
+       if (ioc->ctdev)
+               bfa_ioc_set_ct_hwif(ioc);
+       else
+               bfa_ioc_set_cb_hwif(ioc);
+
        bfa_ioc_map_port(ioc);
        bfa_ioc_reg_init(ioc);
 }
@@ -1830,7 +1493,6 @@ return (auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
 void
 bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave)
 {
-       bfa_assert(ioc->auto_recover);
        ioc->dbg_fwsave = dbg_fwsave;
        ioc->dbg_fwsave_len = bfa_ioc_debug_trcsz(ioc->auto_recover);
 }
@@ -1973,7 +1635,7 @@ bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc)
         ((__sm) == BFI_IOC_INITING) ||         \
         ((__sm) == BFI_IOC_HWINIT) ||          \
         ((__sm) == BFI_IOC_DISABLED) ||        \
-        ((__sm) == BFI_IOC_HBFAIL) ||          \
+        ((__sm) == BFI_IOC_FAIL) ||            \
         ((__sm) == BFI_IOC_CFG_DISABLED))
 
 /**
@@ -2017,46 +1679,28 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
                         struct bfa_adapter_attr_s *ad_attr)
 {
        struct bfi_ioc_attr_s *ioc_attr;
-       char            model[BFA_ADAPTER_MODEL_NAME_LEN];
 
        ioc_attr = ioc->attr;
-       bfa_os_memcpy((void *)&ad_attr->serial_num,
-                     (void *)ioc_attr->brcd_serialnum,
-                     BFA_ADAPTER_SERIAL_NUM_LEN);
-
-       bfa_os_memcpy(&ad_attr->fw_ver, ioc_attr->fw_version, BFA_VERSION_LEN);
-       bfa_os_memcpy(&ad_attr->optrom_ver, ioc_attr->optrom_version,
-                     BFA_VERSION_LEN);
-       bfa_os_memcpy(&ad_attr->manufacturer, BFA_MFG_NAME,
-                     BFA_ADAPTER_MFG_NAME_LEN);
+
+       bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num);
+       bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver);
+       bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver);
+       bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer);
        bfa_os_memcpy(&ad_attr->vpd, &ioc_attr->vpd,
                      sizeof(struct bfa_mfg_vpd_s));
 
-       ad_attr->nports = BFI_ADAPTER_GETP(NPORTS, ioc_attr->adapter_prop);
-       ad_attr->max_speed = BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop);
+       ad_attr->nports = bfa_ioc_get_nports(ioc);
+       ad_attr->max_speed = bfa_ioc_speed_sup(ioc);
 
-       /**
-        * model name
-        */
-       if (BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop) == 10) {
-               strcpy(model, "BR-10?0");
-               model[5] = '0' + ad_attr->nports;
-       } else {
-               strcpy(model, "Brocade-??5");
-               model[8] =
-                       '0' + BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop);
-               model[9] = '0' + ad_attr->nports;
-       }
+       bfa_ioc_get_adapter_model(ioc, ad_attr->model);
+       /* For now, model descr uses same model string */
+       bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr);
 
        if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop))
                ad_attr->prototype = 1;
        else
                ad_attr->prototype = 0;
 
-       bfa_os_memcpy(&ad_attr->model, model, BFA_ADAPTER_MODEL_NAME_LEN);
-       bfa_os_memcpy(&ad_attr->model_descr, &ad_attr->model,
-                     BFA_ADAPTER_MODEL_NAME_LEN);
-
        ad_attr->pwwn = bfa_ioc_get_pwwn(ioc);
        ad_attr->mac = bfa_ioc_get_mac(ioc);
 
@@ -2064,41 +1708,122 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
        ad_attr->pcie_lanes = ioc_attr->pcie_lanes;
        ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig;
        ad_attr->asic_rev = ioc_attr->asic_rev;
-       ad_attr->hw_ver[0] = 'R';
-       ad_attr->hw_ver[1] = 'e';
-       ad_attr->hw_ver[2] = 'v';
-       ad_attr->hw_ver[3] = '-';
-       ad_attr->hw_ver[4] = ioc_attr->asic_rev;
-       ad_attr->hw_ver[5] = '\0';
+
+       bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver);
 
        ad_attr->cna_capable = ioc->cna;
 }
 
+enum bfa_ioc_type_e
+bfa_ioc_get_type(struct bfa_ioc_s *ioc)
+{
+       if (!ioc->ctdev || ioc->fcmode)
+               return BFA_IOC_TYPE_FC;
+       else if (ioc->ioc_mc == BFI_MC_IOCFC)
+               return BFA_IOC_TYPE_FCoE;
+       else if (ioc->ioc_mc == BFI_MC_LL)
+               return BFA_IOC_TYPE_LL;
+       else {
+               bfa_assert(ioc->ioc_mc == BFI_MC_LL);
+               return BFA_IOC_TYPE_LL;
+       }
+}
+
+void
+bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num)
+{
+       bfa_os_memset((void *)serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN);
+       bfa_os_memcpy((void *)serial_num,
+                       (void *)ioc->attr->brcd_serialnum,
+                       BFA_ADAPTER_SERIAL_NUM_LEN);
+}
+
+void
+bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver)
+{
+       bfa_os_memset((void *)fw_ver, 0, BFA_VERSION_LEN);
+       bfa_os_memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN);
+}
+
+void
+bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev)
+{
+       bfa_assert(chip_rev);
+
+       bfa_os_memset((void *)chip_rev, 0, BFA_IOC_CHIP_REV_LEN);
+
+       chip_rev[0] = 'R';
+       chip_rev[1] = 'e';
+       chip_rev[2] = 'v';
+       chip_rev[3] = '-';
+       chip_rev[4] = ioc->attr->asic_rev;
+       chip_rev[5] = '\0';
+}
+
+void
+bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver)
+{
+       bfa_os_memset((void *)optrom_ver, 0, BFA_VERSION_LEN);
+       bfa_os_memcpy(optrom_ver, ioc->attr->optrom_version,
+               BFA_VERSION_LEN);
+}
+
+void
+bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc, char *manufacturer)
+{
+       bfa_os_memset((void *)manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN);
+       bfa_os_memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN);
+}
+
+void
+bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model)
+{
+       struct bfi_ioc_attr_s   *ioc_attr;
+       u8              nports;
+       u8              max_speed;
+
+       bfa_assert(model);
+       bfa_os_memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN);
+
+       ioc_attr = ioc->attr;
+
+       nports = bfa_ioc_get_nports(ioc);
+       max_speed = bfa_ioc_speed_sup(ioc);
+
+       /**
+        * model name
+        */
+       if (max_speed == 10) {
+               strcpy(model, "BR-10?0");
+               model[5] = '0' + nports;
+       } else {
+               strcpy(model, "Brocade-??5");
+               model[8] = '0' + max_speed;
+               model[9] = '0' + nports;
+       }
+}
+
+enum bfa_ioc_state
+bfa_ioc_get_state(struct bfa_ioc_s *ioc)
+{
+       return bfa_sm_to_state(ioc_sm_table, ioc->fsm);
+}
+
 void
 bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr)
 {
        bfa_os_memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s));
 
-       ioc_attr->state = bfa_sm_to_state(ioc_sm_table, ioc->fsm);
+       ioc_attr->state = bfa_ioc_get_state(ioc);
        ioc_attr->port_id = ioc->port_id;
 
-       if (!ioc->ctdev)
-               ioc_attr->ioc_type = BFA_IOC_TYPE_FC;
-       else if (ioc->ioc_mc == BFI_MC_IOCFC)
-               ioc_attr->ioc_type = BFA_IOC_TYPE_FCoE;
-       else if (ioc->ioc_mc == BFI_MC_LL)
-               ioc_attr->ioc_type = BFA_IOC_TYPE_LL;
+       ioc_attr->ioc_type = bfa_ioc_get_type(ioc);
 
        bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr);
 
        ioc_attr->pci_attr.device_id = ioc->pcidev.device_id;
        ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func;
-       ioc_attr->pci_attr.chip_rev[0] = 'R';
-       ioc_attr->pci_attr.chip_rev[1] = 'e';
-       ioc_attr->pci_attr.chip_rev[2] = 'v';
-       ioc_attr->pci_attr.chip_rev[3] = '-';
-       ioc_attr->pci_attr.chip_rev[4] = ioc_attr->adapter_attr.asic_rev;
-       ioc_attr->pci_attr.chip_rev[5] = '\0';
+       bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev);
 }
 
 /**
@@ -2195,29 +1920,6 @@ bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc)
 }
 
 /**
- * Return true if interrupt should be claimed.
- */
-bfa_boolean_t
-bfa_ioc_intx_claim(struct bfa_ioc_s *ioc)
-{
-       u32        isr, msk;
-
-       /**
-        * Always claim if not catapult.
-        */
-       if (!ioc->ctdev)
-               return BFA_TRUE;
-
-       /**
-        * FALSE if next device is claiming interrupt.
-        * TRUE if next device is not interrupting or not present.
-        */
-       msk = bfa_reg_read(ioc->ioc_regs.shirq_msk_next);
-       isr = bfa_reg_read(ioc->ioc_regs.shirq_isr_next);
-       return !(isr & ~msk);
-}
-
-/**
  * Send AEN notification
  */
 static void
@@ -2226,32 +1928,14 @@ bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
        union bfa_aen_data_u aen_data;
        struct bfa_log_mod_s *logmod = ioc->logm;
        s32         inst_num = 0;
-       struct bfa_ioc_attr_s ioc_attr;
+       enum bfa_ioc_type_e ioc_type;
 
-       switch (event) {
-       case BFA_IOC_AEN_HBGOOD:
-               bfa_log(logmod, BFA_AEN_IOC_HBGOOD, inst_num);
-               break;
-       case BFA_IOC_AEN_HBFAIL:
-               bfa_log(logmod, BFA_AEN_IOC_HBFAIL, inst_num);
-               break;
-       case BFA_IOC_AEN_ENABLE:
-               bfa_log(logmod, BFA_AEN_IOC_ENABLE, inst_num);
-               break;
-       case BFA_IOC_AEN_DISABLE:
-               bfa_log(logmod, BFA_AEN_IOC_DISABLE, inst_num);
-               break;
-       case BFA_IOC_AEN_FWMISMATCH:
-               bfa_log(logmod, BFA_AEN_IOC_FWMISMATCH, inst_num);
-               break;
-       default:
-               break;
-       }
+       bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, event), inst_num);
 
        memset(&aen_data.ioc.pwwn, 0, sizeof(aen_data.ioc.pwwn));
        memset(&aen_data.ioc.mac, 0, sizeof(aen_data.ioc.mac));
-       bfa_ioc_get_attr(ioc, &ioc_attr);
-       switch (ioc_attr.ioc_type) {
+       ioc_type = bfa_ioc_get_type(ioc);
+       switch (ioc_type) {
        case BFA_IOC_TYPE_FC:
                aen_data.ioc.pwwn = bfa_ioc_get_pwwn(ioc);
                break;
@@ -2263,10 +1947,10 @@ bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
                aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
                break;
        default:
-               bfa_assert(ioc_attr.ioc_type == BFA_IOC_TYPE_FC);
+               bfa_assert(ioc_type == BFA_IOC_TYPE_FC);
                break;
        }
-       aen_data.ioc.ioc_type = ioc_attr.ioc_type;
+       aen_data.ioc.ioc_type = ioc_type;
 }
 
 /**
@@ -2290,6 +1974,15 @@ bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
 }
 
 /**
+ * Clear saved firmware trace
+ */
+void
+bfa_ioc_debug_fwsave_clear(struct bfa_ioc_s *ioc)
+{
+       ioc->dbg_fwsave_once = BFA_TRUE;
+}
+
+/**
  * Retrieve saved firmware trace from a prior IOC failure.
  */
 bfa_status_t
@@ -2304,6 +1997,13 @@ bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
 
        pgnum = bfa_ioc_smem_pgnum(ioc, loff);
        loff = bfa_ioc_smem_pgoff(ioc, loff);
+
+       /*
+        *  Hold semaphore to serialize pll init and fwtrc.
+        */
+       if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg))
+               return BFA_STATUS_FAILED;
+
        bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
 
        tlen = *trclen;
@@ -2329,6 +2029,12 @@ bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
        }
        bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
                      bfa_ioc_smem_pgnum(ioc, 0));
+
+       /*
+        *  release semaphore.
+        */
+       bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
+
        bfa_trc(ioc, pgnum);
 
        *trclen = tlen * sizeof(u32);
index 7c30f05..d080440 100644 (file)
@@ -74,15 +74,18 @@ struct bfa_ioc_regs_s {
        bfa_os_addr_t   lpu_mbox_cmd;
        bfa_os_addr_t   lpu_mbox;
        bfa_os_addr_t   pss_ctl_reg;
+       bfa_os_addr_t   pss_err_status_reg;
        bfa_os_addr_t   app_pll_fast_ctl_reg;
        bfa_os_addr_t   app_pll_slow_ctl_reg;
        bfa_os_addr_t   ioc_sem_reg;
        bfa_os_addr_t   ioc_usage_sem_reg;
+       bfa_os_addr_t   ioc_init_sem_reg;
        bfa_os_addr_t   ioc_usage_reg;
        bfa_os_addr_t   host_page_num_fn;
        bfa_os_addr_t   heartbeat;
        bfa_os_addr_t   ioc_fwstate;
        bfa_os_addr_t   ll_halt;
+       bfa_os_addr_t   err_set;
        bfa_os_addr_t   shirq_isr_next;
        bfa_os_addr_t   shirq_msk_next;
        bfa_os_addr_t   smem_page_start;
@@ -154,7 +157,6 @@ struct bfa_ioc_s {
        struct bfa_timer_s      ioc_timer;
        struct bfa_timer_s      sem_timer;
        u32             hb_count;
-       u32             hb_fail;
        u32             retry_count;
        struct list_head                hb_notify_q;
        void                    *dbg_fwsave;
@@ -177,6 +179,22 @@ struct bfa_ioc_s {
        struct bfi_ioc_attr_s   *attr;
        struct bfa_ioc_cbfn_s   *cbfn;
        struct bfa_ioc_mbox_mod_s mbox_mod;
+       struct bfa_ioc_hwif_s   *ioc_hwif;
+};
+
+struct bfa_ioc_hwif_s {
+       bfa_status_t    (*ioc_pll_init) (struct bfa_ioc_s *ioc);
+       bfa_boolean_t   (*ioc_firmware_lock)    (struct bfa_ioc_s *ioc);
+       void            (*ioc_firmware_unlock)  (struct bfa_ioc_s *ioc);
+       u32 *           (*ioc_fwimg_get_chunk)  (struct bfa_ioc_s *ioc,
+                                               u32 off);
+       u32             (*ioc_fwimg_get_size)   (struct bfa_ioc_s *ioc);
+       void            (*ioc_reg_init) (struct bfa_ioc_s *ioc);
+       void            (*ioc_map_port) (struct bfa_ioc_s *ioc);
+       void            (*ioc_isr_mode_set)     (struct bfa_ioc_s *ioc,
+                                               bfa_boolean_t msix);
+       void            (*ioc_notify_hbfail)    (struct bfa_ioc_s *ioc);
+       void            (*ioc_ownership_reset)  (struct bfa_ioc_s *ioc);
 };
 
 #define bfa_ioc_pcifn(__ioc)           ((__ioc)->pcidev.pci_func)
@@ -191,6 +209,15 @@ struct bfa_ioc_s {
 #define bfa_ioc_rx_bbcredit(__ioc)     ((__ioc)->attr->rx_bbcredit)
 #define bfa_ioc_speed_sup(__ioc)       \
        BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop)
+#define bfa_ioc_get_nports(__ioc)       \
+       BFI_ADAPTER_GETP(NPORTS, (__ioc)->attr->adapter_prop)
+
+#define bfa_ioc_stats(_ioc, _stats)     ((_ioc)->stats._stats++)
+#define BFA_IOC_FWIMG_MINSZ     (16 * 1024)
+
+#define BFA_IOC_FLASH_CHUNK_NO(off)             (off / BFI_FLASH_CHUNK_SZ_WORDS)
+#define BFA_IOC_FLASH_OFFSET_IN_CHUNK(off)      (off % BFI_FLASH_CHUNK_SZ_WORDS)
+#define BFA_IOC_FLASH_CHUNK_ADDR(chunkno)  (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)
 
 /**
  * IOC mailbox interface
@@ -207,6 +234,14 @@ void bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc,
 /**
  * IOC interfaces
  */
+#define bfa_ioc_pll_init(__ioc) ((__ioc)->ioc_hwif->ioc_pll_init(__ioc))
+#define bfa_ioc_isr_mode_set(__ioc, __msix)                     \
+                       ((__ioc)->ioc_hwif->ioc_isr_mode_set(__ioc, __msix))
+#define bfa_ioc_ownership_reset(__ioc)                          \
+                       ((__ioc)->ioc_hwif->ioc_ownership_reset(__ioc))
+
+void bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc);
+void bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc);
 void bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa,
                struct bfa_ioc_cbfn_s *cbfn, struct bfa_timer_mod_s *timer_mod,
                struct bfa_trc_mod_s *trcmod,
@@ -223,13 +258,21 @@ bfa_boolean_t bfa_ioc_intx_claim(struct bfa_ioc_s *ioc);
 void bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param);
 void bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *msg);
 void bfa_ioc_error_isr(struct bfa_ioc_s *ioc);
-void bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t intx);
-bfa_status_t bfa_ioc_pll_init(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_is_operational(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_is_disabled(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_cfg_complete(struct bfa_ioc_s *ioc);
+enum bfa_ioc_type_e bfa_ioc_get_type(struct bfa_ioc_s *ioc);
+void bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num);
+void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver);
+void bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver);
+void bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model);
+void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc,
+       char *manufacturer);
+void bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev);
+enum bfa_ioc_state bfa_ioc_get_state(struct bfa_ioc_s *ioc);
+
 void bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr);
 void bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
                struct bfa_adapter_attr_s *ad_attr);
@@ -237,6 +280,7 @@ int bfa_ioc_debug_trcsz(bfa_boolean_t auto_recover);
 void bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave);
 bfa_status_t bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata,
                int *trclen);
+void bfa_ioc_debug_fwsave_clear(struct bfa_ioc_s *ioc);
 bfa_status_t bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata,
                                 int *trclen);
 u32 bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr);
@@ -245,6 +289,13 @@ void bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc);
 void bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc,
        struct bfa_ioc_hbfail_notify_s *notify);
+bfa_boolean_t bfa_ioc_sem_get(bfa_os_addr_t sem_reg);
+void bfa_ioc_sem_release(bfa_os_addr_t sem_reg);
+void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc);
+void bfa_ioc_fwver_get(struct bfa_ioc_s *ioc,
+                       struct bfi_ioc_image_hdr_s *fwhdr);
+bfa_boolean_t bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc,
+                       struct bfi_ioc_image_hdr_s *fwhdr);
 
 /*
  * bfa mfg wwn API functions
diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c
new file mode 100644 (file)
index 0000000..3ce8531
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux driver for Brocade Fibre Channel Host Bus Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <bfa.h>
+#include <bfa_ioc.h>
+#include <bfa_fwimg_priv.h>
+#include <cna/bfa_cna_trcmod.h>
+#include <cs/bfa_debug.h>
+#include <bfi/bfi_ioc.h>
+#include <bfi/bfi_cbreg.h>
+#include <log/bfa_log_hal.h>
+#include <defs/bfa_defs_pci.h>
+
+BFA_TRC_FILE(CNA, IOC_CB);
+
+/*
+ * forward declarations
+ */
+static bfa_status_t bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc);
+static bfa_boolean_t bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc);
+static u32  *bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off);
+static u32 bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
+static void bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc);
+
+struct bfa_ioc_hwif_s hwif_cb = {
+       bfa_ioc_cb_pll_init,
+       bfa_ioc_cb_firmware_lock,
+       bfa_ioc_cb_firmware_unlock,
+       bfa_ioc_cb_fwimg_get_chunk,
+       bfa_ioc_cb_fwimg_get_size,
+       bfa_ioc_cb_reg_init,
+       bfa_ioc_cb_map_port,
+       bfa_ioc_cb_isr_mode_set,
+       bfa_ioc_cb_notify_hbfail,
+       bfa_ioc_cb_ownership_reset,
+};
+
+/**
+ * Called from bfa_ioc_attach() to map asic specific calls.
+ */
+void
+bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc)
+{
+       ioc->ioc_hwif = &hwif_cb;
+}
+
+static u32 *
+bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
+{
+       return bfi_image_cb_get_chunk(off);
+}
+
+static u32
+bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc)
+{
+       return bfi_image_cb_size;
+}
+
+/**
+ * Return true if firmware of current driver matches the running firmware.
+ */
+static bfa_boolean_t
+bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc)
+{
+       return BFA_TRUE;
+}
+
+static void
+bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc)
+{
+}
+
+/**
+ * Notify other functions on HB failure.
+ */
+static void
+bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc)
+{
+       bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET);
+       bfa_reg_read(ioc->ioc_regs.err_set);
+}
+
+/**
+ * Host to LPU mailbox message addresses
+ */
+static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
+       { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
+       { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 }
+};
+
+/**
+ * Host <-> LPU mailbox command/status registers
+ */
+static struct { u32 hfn, lpu; } iocreg_mbcmd[] = {
+       { HOSTFN0_LPU0_CMD_STAT, LPU0_HOSTFN0_CMD_STAT },
+       { HOSTFN1_LPU1_CMD_STAT, LPU1_HOSTFN1_CMD_STAT }
+};
+
+static void
+bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc)
+{
+       bfa_os_addr_t   rb;
+       int             pcifn = bfa_ioc_pcifn(ioc);
+
+       rb = bfa_ioc_bar0(ioc);
+
+       ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
+       ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
+       ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
+
+       if (ioc->port_id == 0) {
+               ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
+               ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
+       } else {
+               ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
+               ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
+       }
+
+       /**
+        * Host <-> LPU mailbox command/status registers
+        */
+       ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd[pcifn].hfn;
+       ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd[pcifn].lpu;
+
+       /*
+        * PSS control registers
+        */
+       ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
+       ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
+       ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_400_CTL_REG);
+       ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_212_CTL_REG);
+
+       /*
+        * IOC semaphore registers and serialization
+        */
+       ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
+       ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
+
+       /**
+        * sram memory access
+        */
+       ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
+       ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB;
+
+       /*
+        * err set reg : for notification of hb failure
+        */
+       ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
+}
+
+/**
+ * Initialize IOC to port mapping.
+ */
+static void
+bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc)
+{
+       /**
+        * For crossbow, port id is same as pci function.
+        */
+       ioc->port_id = bfa_ioc_pcifn(ioc);
+       bfa_trc(ioc, ioc->port_id);
+}
+
+/**
+ * Set interrupt mode for a function: INTX or MSIX
+ */
+static void
+bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
+{
+}
+
+static bfa_status_t
+bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc)
+{
+       bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
+       u32     pll_sclk, pll_fclk;
+
+       /*
+        *  Hold semaphore so that nobody can access the chip during init.
+        */
+       bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
+
+       pll_sclk = __APP_PLL_212_ENABLE | __APP_PLL_212_LRESETN |
+                       __APP_PLL_212_P0_1(3U) |
+                       __APP_PLL_212_JITLMT0_1(3U) |
+                       __APP_PLL_212_CNTLMT0_1(3U);
+       pll_fclk = __APP_PLL_400_ENABLE | __APP_PLL_400_LRESETN |
+                       __APP_PLL_400_RSEL200500 | __APP_PLL_400_P0_1(3U) |
+                       __APP_PLL_400_JITLMT0_1(3U) |
+                       __APP_PLL_400_CNTLMT0_1(3U);
+
+       bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
+       bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
+
+       bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
+
+       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
+                       __APP_PLL_212_LOGIC_SOFT_RESET);
+       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
+                       __APP_PLL_212_BYPASS |
+                       __APP_PLL_212_LOGIC_SOFT_RESET);
+       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
+                       __APP_PLL_400_LOGIC_SOFT_RESET);
+       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
+                       __APP_PLL_400_BYPASS |
+                       __APP_PLL_400_LOGIC_SOFT_RESET);
+       bfa_os_udelay(2);
+       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
+                       __APP_PLL_212_LOGIC_SOFT_RESET);
+       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
+                       __APP_PLL_400_LOGIC_SOFT_RESET);
+
+       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
+                       pll_sclk | __APP_PLL_212_LOGIC_SOFT_RESET);
+       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
+                       pll_fclk | __APP_PLL_400_LOGIC_SOFT_RESET);
+
+       /**
+        * Wait for PLLs to lock.
+        */
+       bfa_os_udelay(2000);
+       bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
+
+       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk);
+       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk);
+
+       /*
+        *  release semaphore.
+        */
+       bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
+
+       return BFA_STATUS_OK;
+}
+
+/**
+ * Cleanup hw semaphore and usecnt registers
+ */
+static void
+bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc)
+{
+
+       /*
+        * Read the hw sem reg to make sure that it is locked
+        * before we clear it. If it is not locked, writing 1
+        * will lock it instead of clearing it.
+        */
+       bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
+       bfa_ioc_hw_sem_release(ioc);
+}
diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c
new file mode 100644 (file)
index 0000000..20b58ad
--- /dev/null
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux driver for Brocade Fibre Channel Host Bus Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <bfa.h>
+#include <bfa_ioc.h>
+#include <bfa_fwimg_priv.h>
+#include <cna/bfa_cna_trcmod.h>
+#include <cs/bfa_debug.h>
+#include <bfi/bfi_ioc.h>
+#include <bfi/bfi_ctreg.h>
+#include <log/bfa_log_hal.h>
+#include <defs/bfa_defs_pci.h>
+
+BFA_TRC_FILE(CNA, IOC_CT);
+
+/*
+ * forward declarations
+ */
+static bfa_status_t bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc);
+static bfa_boolean_t bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc);
+static u32* bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc,
+                                       u32 off);
+static u32 bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
+static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc);
+
+struct bfa_ioc_hwif_s hwif_ct = {
+       bfa_ioc_ct_pll_init,
+       bfa_ioc_ct_firmware_lock,
+       bfa_ioc_ct_firmware_unlock,
+       bfa_ioc_ct_fwimg_get_chunk,
+       bfa_ioc_ct_fwimg_get_size,
+       bfa_ioc_ct_reg_init,
+       bfa_ioc_ct_map_port,
+       bfa_ioc_ct_isr_mode_set,
+       bfa_ioc_ct_notify_hbfail,
+       bfa_ioc_ct_ownership_reset,
+};
+
+/**
+ * Called from bfa_ioc_attach() to map asic specific calls.
+ */
+void
+bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc)
+{
+       ioc->ioc_hwif = &hwif_ct;
+}
+
+static u32*
+bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
+{
+       return bfi_image_ct_get_chunk(off);
+}
+
+static u32
+bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc)
+{
+       return bfi_image_ct_size;
+}
+
+/**
+ * Return true if firmware of current driver matches the running firmware.
+ */
+static bfa_boolean_t
+bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
+{
+       enum bfi_ioc_state ioc_fwstate;
+       u32 usecnt;
+       struct bfi_ioc_image_hdr_s fwhdr;
+
+       /**
+        * Firmware match check is relevant only for CNA.
+        */
+       if (!ioc->cna)
+               return BFA_TRUE;
+
+       /**
+        * If bios boot (flash based) -- do not increment usage count
+        */
+       if (bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
+               return BFA_TRUE;
+
+       bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+       usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
+
+       /**
+        * If usage count is 0, always return TRUE.
+        */
+       if (usecnt == 0) {
+               bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1);
+               bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+               bfa_trc(ioc, usecnt);
+               return BFA_TRUE;
+       }
+
+       ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
+       bfa_trc(ioc, ioc_fwstate);
+
+       /**
+        * Use count cannot be non-zero and chip in uninitialized state.
+        */
+       bfa_assert(ioc_fwstate != BFI_IOC_UNINIT);
+
+       /**
+        * Check if another driver with a different firmware is active
+        */
+       bfa_ioc_fwver_get(ioc, &fwhdr);
+       if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
+               bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+               bfa_trc(ioc, usecnt);
+               return BFA_FALSE;
+       }
+
+       /**
+        * Same firmware version. Increment the reference count.
+        */
+       usecnt++;
+       bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
+       bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+       bfa_trc(ioc, usecnt);
+       return BFA_TRUE;
+}
+
+static void
+bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc)
+{
+       u32 usecnt;
+
+       /**
+        * Firmware lock is relevant only for CNA.
+        * If bios boot (flash based) -- do not decrement usage count
+        */
+       if (!ioc->cna || bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
+               return;
+
+       /**
+        * decrement usage count
+        */
+       bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+       usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
+       bfa_assert(usecnt > 0);
+
+       usecnt--;
+       bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
+       bfa_trc(ioc, usecnt);
+
+       bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+}
+
+/**
+ * Notify other functions on HB failure.
+ */
+static void
+bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc)
+{
+       if (ioc->cna) {
+               bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P);
+               /* Wait for halt to take effect */
+               bfa_reg_read(ioc->ioc_regs.ll_halt);
+       } else {
+               bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET);
+               bfa_reg_read(ioc->ioc_regs.err_set);
+       }
+}
+
+/**
+ * Host to LPU mailbox message addresses
+ */
+static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
+       { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
+       { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 },
+       { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 },
+       { HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 }
+};
+
+/**
+ * Host <-> LPU mailbox command/status registers - port 0
+ */
+static struct { u32 hfn, lpu; } iocreg_mbcmd_p0[] = {
+       { HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT },
+       { HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT },
+       { HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT },
+       { HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT }
+};
+
+/**
+ * Host <-> LPU mailbox command/status registers - port 1
+ */
+static struct { u32 hfn, lpu; } iocreg_mbcmd_p1[] = {
+       { HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT },
+       { HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT },
+       { HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT },
+       { HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT }
+};
+
+static void
+bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc)
+{
+       bfa_os_addr_t   rb;
+       int             pcifn = bfa_ioc_pcifn(ioc);
+
+       rb = bfa_ioc_bar0(ioc);
+
+       ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
+       ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
+       ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
+
+       if (ioc->port_id == 0) {
+               ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
+               ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
+               ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
+               ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
+               ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
+       } else {
+               ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
+               ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
+               ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
+               ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
+               ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
+       }
+
+       /*
+        * PSS control registers
+        */
+       ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
+       ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
+       ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
+       ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
+
+       /*
+        * IOC semaphore registers and serialization
+        */
+       ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
+       ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
+       ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
+       ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
+
+       /**
+        * sram memory access
+        */
+       ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
+       ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
+
+       /*
+        * err set reg : for notification of hb failure in fcmode
+        */
+       ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
+}
+
+/**
+ * Initialize IOC to port mapping.
+ */
+
+#define FNC_PERS_FN_SHIFT(__fn)        ((__fn) * 8)
+static void
+bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc)
+{
+       bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
+       u32     r32;
+
+       /**
+        * For catapult, base port id on personality register and IOC type
+        */
+       r32 = bfa_reg_read(rb + FNC_PERS_REG);
+       r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
+       ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
+
+       bfa_trc(ioc, bfa_ioc_pcifn(ioc));
+       bfa_trc(ioc, ioc->port_id);
+}
+
+/**
+ * Set interrupt mode for a function: INTX or MSIX
+ */
+static void
+bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
+{
+       bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
+       u32     r32, mode;
+
+       r32 = bfa_reg_read(rb + FNC_PERS_REG);
+       bfa_trc(ioc, r32);
+
+       mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
+               __F0_INTX_STATUS;
+
+       /**
+        * If already in desired mode, do not change anything
+        */
+       if (!msix && mode)
+               return;
+
+       if (msix)
+               mode = __F0_INTX_STATUS_MSIX;
+       else
+               mode = __F0_INTX_STATUS_INTA;
+
+       r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
+       r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
+       bfa_trc(ioc, r32);
+
+       bfa_reg_write(rb + FNC_PERS_REG, r32);
+}
+
+static bfa_status_t
+bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc)
+{
+       bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
+       u32     pll_sclk, pll_fclk, r32;
+
+       /*
+        *  Hold semaphore so that nobody can access the chip during init.
+        */
+       bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
+
+       pll_sclk = __APP_PLL_312_LRESETN | __APP_PLL_312_ENARST |
+               __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(3U) |
+               __APP_PLL_312_JITLMT0_1(3U) |
+               __APP_PLL_312_CNTLMT0_1(1U);
+       pll_fclk = __APP_PLL_425_LRESETN | __APP_PLL_425_ENARST |
+               __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
+               __APP_PLL_425_JITLMT0_1(3U) |
+               __APP_PLL_425_CNTLMT0_1(1U);
+
+       /**
+        *      For catapult, choose operational mode FC/FCoE
+        */
+       if (ioc->fcmode) {
+               bfa_reg_write((rb + OP_MODE), 0);
+               bfa_reg_write((rb + ETH_MAC_SER_REG),
+                               __APP_EMS_CMLCKSEL |
+                               __APP_EMS_REFCKBUFEN2 |
+                               __APP_EMS_CHANNEL_SEL);
+       } else {
+               ioc->pllinit = BFA_TRUE;
+               bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE);
+               bfa_reg_write((rb + ETH_MAC_SER_REG),
+                                __APP_EMS_REFCKBUFEN1);
+       }
+
+       bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
+       bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
+
+       bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
+
+       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
+               __APP_PLL_312_LOGIC_SOFT_RESET);
+       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
+               __APP_PLL_425_LOGIC_SOFT_RESET);
+       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
+               __APP_PLL_312_LOGIC_SOFT_RESET | __APP_PLL_312_ENABLE);
+       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
+               __APP_PLL_425_LOGIC_SOFT_RESET | __APP_PLL_425_ENABLE);
+
+       /**
+        * Wait for PLLs to lock.
+        */
+       bfa_reg_read(rb + HOSTFN0_INT_MSK);
+       bfa_os_udelay(2000);
+       bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
+
+       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
+               __APP_PLL_312_ENABLE);
+       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
+               __APP_PLL_425_ENABLE);
+
+       bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
+       bfa_os_udelay(1000);
+       r32 = bfa_reg_read((rb + MBIST_STAT_REG));
+       bfa_trc(ioc, r32);
+       /*
+        *  release semaphore.
+        */
+       bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
+
+       return BFA_STATUS_OK;
+}
+
+/**
+ * Cleanup hw semaphore and usecnt registers
+ */
+static void
+bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc)
+{
+
+       if (ioc->cna) {
+               bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+               bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 0);
+               bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+       }
+
+       /*
+        * Read the hw sem reg to make sure that it is locked
+        * before we clear it. If it is not locked, writing 1
+        * will lock it instead of clearing it.
+        */
+       bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
+       bfa_ioc_hw_sem_release(ioc);
+}
index d7ab792..a76de26 100644 (file)
@@ -172,6 +172,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
         */
        if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) {
                iocfc->hwif.hw_reginit = bfa_hwct_reginit;
+               iocfc->hwif.hw_reqq_ack = bfa_hwct_reqq_ack;
                iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack;
                iocfc->hwif.hw_msix_init = bfa_hwct_msix_init;
                iocfc->hwif.hw_msix_install = bfa_hwct_msix_install;
@@ -180,6 +181,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
                iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs;
        } else {
                iocfc->hwif.hw_reginit = bfa_hwcb_reginit;
+               iocfc->hwif.hw_reqq_ack = bfa_hwcb_reqq_ack;
                iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
                iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init;
                iocfc->hwif.hw_msix_install = bfa_hwcb_msix_install;
@@ -336,8 +338,10 @@ bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete)
                        bfa_cb_init(bfa->bfad, BFA_STATUS_OK);
                else
                        bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED);
-       } else
-               bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
+       } else {
+               if (bfa->iocfc.cfgdone)
+                       bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
+       }
 }
 
 static void
@@ -619,8 +623,6 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
 
        bfa_ioc_attach(&bfa->ioc, bfa, &bfa_iocfc_cbfn, &bfa->timer_mod,
                bfa->trcmod, bfa->aen, bfa->logm);
-       bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC);
-       bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs);
 
        /**
         * Choose FC (ssid: 0x1C) v/s FCoE (ssid: 0x14) mode.
@@ -628,6 +630,9 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
        if (0)
                bfa_ioc_set_fcmode(&bfa->ioc);
 
+       bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC);
+       bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs);
+
        bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev);
        bfa_iocfc_mem_claim(bfa, cfg, meminfo);
        bfa_timer_init(&bfa->timer_mod);
@@ -654,7 +659,6 @@ bfa_iocfc_init(struct bfa_s *bfa)
 {
        bfa->iocfc.action = BFA_IOCFC_ACT_INIT;
        bfa_ioc_enable(&bfa->ioc);
-       bfa_msix_install(bfa);
 }
 
 /**
@@ -797,6 +801,11 @@ bfa_iocfc_get_stats(struct bfa_s *bfa, struct bfa_iocfc_stats_s *stats,
                return BFA_STATUS_DEVBUSY;
        }
 
+       if (!bfa_iocfc_is_operational(bfa)) {
+               bfa_trc(bfa, 0);
+               return BFA_STATUS_IOC_NON_OP;
+       }
+
        iocfc->stats_busy = BFA_TRUE;
        iocfc->stats_ret = stats;
        iocfc->stats_cbfn = cbfn;
@@ -817,6 +826,11 @@ bfa_iocfc_clear_stats(struct bfa_s *bfa, bfa_cb_ioc_t cbfn, void *cbarg)
                return BFA_STATUS_DEVBUSY;
        }
 
+       if (!bfa_iocfc_is_operational(bfa)) {
+               bfa_trc(bfa, 0);
+               return BFA_STATUS_IOC_NON_OP;
+       }
+
        iocfc->stats_busy = BFA_TRUE;
        iocfc->stats_cbfn = cbfn;
        iocfc->stats_cbarg = cbarg;
index ce9a830..fbb4bdc 100644 (file)
@@ -54,6 +54,7 @@ struct bfa_msix_s {
  */
 struct bfa_hwif_s {
        void (*hw_reginit)(struct bfa_s *bfa);
+       void (*hw_reqq_ack)(struct bfa_s *bfa, int reqq);
        void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq);
        void (*hw_msix_init)(struct bfa_s *bfa, int nvecs);
        void (*hw_msix_install)(struct bfa_s *bfa);
@@ -143,6 +144,7 @@ void bfa_msix_rspq(struct bfa_s *bfa, int vec);
 void bfa_msix_lpu_err(struct bfa_s *bfa, int vec);
 
 void bfa_hwcb_reginit(struct bfa_s *bfa);
+void bfa_hwcb_reqq_ack(struct bfa_s *bfa, int rspq);
 void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq);
 void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs);
 void bfa_hwcb_msix_install(struct bfa_s *bfa);
@@ -151,6 +153,7 @@ void bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix);
 void bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *vecmap,
                        u32 *nvecs, u32 *maxvec);
 void bfa_hwct_reginit(struct bfa_s *bfa);
+void bfa_hwct_reqq_ack(struct bfa_s *bfa, int rspq);
 void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq);
 void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs);
 void bfa_hwct_msix_install(struct bfa_s *bfa);
index f81d359..5b107ab 100644 (file)
@@ -149,7 +149,7 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
@@ -194,7 +194,7 @@ bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
@@ -259,7 +259,7 @@ bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
@@ -317,7 +317,7 @@ bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
@@ -377,7 +377,7 @@ bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
@@ -419,7 +419,7 @@ bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
@@ -467,7 +467,7 @@ bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
@@ -516,7 +516,7 @@ bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
@@ -544,7 +544,7 @@ bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
@@ -577,7 +577,7 @@ bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
@@ -605,7 +605,7 @@ bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
index eabf7d3..a914ff2 100644 (file)
@@ -144,7 +144,7 @@ bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -175,7 +175,7 @@ bfa_itnim_sm_created(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -212,7 +212,7 @@ bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -247,7 +247,7 @@ bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -275,7 +275,7 @@ bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -317,7 +317,7 @@ bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -348,7 +348,7 @@ bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -385,7 +385,7 @@ bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -413,7 +413,7 @@ bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -442,7 +442,7 @@ bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -470,7 +470,7 @@ bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -502,7 +502,7 @@ bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -538,7 +538,7 @@ bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -559,7 +559,7 @@ bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -583,7 +583,7 @@ bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
index 9844b45..ad06f61 100644 (file)
@@ -18,6 +18,7 @@
 #include <bfa.h>
 #include <bfi/bfi_lps.h>
 #include <cs/bfa_debug.h>
+#include <defs/bfa_defs_pci.h>
 
 BFA_TRC_FILE(HAL, LPS);
 BFA_MODULE(lps);
@@ -25,6 +26,12 @@ BFA_MODULE(lps);
 #define BFA_LPS_MIN_LPORTS     (1)
 #define BFA_LPS_MAX_LPORTS     (256)
 
+/*
+ * Maximum Vports supported per physical port or vf.
+ */
+#define BFA_LPS_MAX_VPORTS_SUPP_CB  255
+#define BFA_LPS_MAX_VPORTS_SUPP_CT  190
+
 /**
  * forward declarations
  */
@@ -49,7 +56,7 @@ static void bfa_lps_send_login(struct bfa_lps_s *lps);
 static void bfa_lps_send_logout(struct bfa_lps_s *lps);
 static void bfa_lps_login_comp(struct bfa_lps_s *lps);
 static void bfa_lps_logout_comp(struct bfa_lps_s *lps);
-
+static void bfa_lps_cvl_event(struct bfa_lps_s *lps);
 
 /**
  *  lps_pvt BFA LPS private functions
@@ -62,6 +69,7 @@ enum bfa_lps_event {
        BFA_LPS_SM_RESUME       = 4,    /* space present in reqq queue  */
        BFA_LPS_SM_DELETE       = 5,    /* lps delete from user         */
        BFA_LPS_SM_OFFLINE      = 6,    /* Link is offline              */
+       BFA_LPS_SM_RX_CVL       = 7,    /* Rx clear virtual link        */
 };
 
 static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event);
@@ -91,6 +99,12 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
                        bfa_sm_set_state(lps, bfa_lps_sm_login);
                        bfa_lps_send_login(lps);
                }
+               if (lps->fdisc)
+                       bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+                       BFA_PL_EID_LOGIN, 0, "FDISC Request");
+               else
+                       bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+                       BFA_PL_EID_LOGIN, 0, "FLOGI Request");
                break;
 
        case BFA_LPS_SM_LOGOUT:
@@ -101,6 +115,7 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
                bfa_lps_free(lps);
                break;
 
+       case BFA_LPS_SM_RX_CVL:
        case BFA_LPS_SM_OFFLINE:
                break;
 
@@ -112,7 +127,7 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(lps->bfa, event);
        }
 }
 
@@ -127,10 +142,25 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
 
        switch (event) {
        case BFA_LPS_SM_FWRSP:
-               if (lps->status == BFA_STATUS_OK)
+               if (lps->status == BFA_STATUS_OK) {
                        bfa_sm_set_state(lps, bfa_lps_sm_online);
-               else
+                       if (lps->fdisc)
+                               bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+                               BFA_PL_EID_LOGIN, 0, "FDISC Accept");
+                       else
+                               bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+                               BFA_PL_EID_LOGIN, 0, "FLOGI Accept");
+               } else {
                        bfa_sm_set_state(lps, bfa_lps_sm_init);
+                       if (lps->fdisc)
+                               bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+                               BFA_PL_EID_LOGIN, 0,
+                               "FDISC Fail (RJT or timeout)");
+                       else
+                               bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+                               BFA_PL_EID_LOGIN, 0,
+                               "FLOGI Fail (RJT or timeout)");
+               }
                bfa_lps_login_comp(lps);
                break;
 
@@ -139,7 +169,7 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(lps->bfa, event);
        }
 }
 
@@ -162,8 +192,16 @@ bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event)
                bfa_reqq_wcancel(&lps->wqe);
                break;
 
+       case BFA_LPS_SM_RX_CVL:
+               /*
+                * Login was not even sent out; so when getting out
+                * of this state, it will appear like a login retry
+                * after Clear virtual link
+                */
+               break;
+
        default:
-               bfa_assert(0);
+               bfa_sm_fault(lps->bfa, event);
        }
 }
 
@@ -185,6 +223,17 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
                        bfa_sm_set_state(lps, bfa_lps_sm_logout);
                        bfa_lps_send_logout(lps);
                }
+               bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+                       BFA_PL_EID_LOGO, 0, "Logout");
+               break;
+
+       case BFA_LPS_SM_RX_CVL:
+               bfa_sm_set_state(lps, bfa_lps_sm_init);
+
+               /* Let the vport module know about this event */
+               bfa_lps_cvl_event(lps);
+               bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+                       BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx");
                break;
 
        case BFA_LPS_SM_OFFLINE:
@@ -193,7 +242,7 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(lps->bfa, event);
        }
 }
 
@@ -217,7 +266,7 @@ bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(lps->bfa, event);
        }
 }
 
@@ -242,7 +291,7 @@ bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(lps->bfa, event);
        }
 }
 
@@ -396,6 +445,20 @@ bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp)
 }
 
 /**
+ * Firmware received a Clear virtual link request (for FCoE)
+ */
+static void
+bfa_lps_rx_cvl_event(struct bfa_s *bfa, struct bfi_lps_cvl_event_s *cvl)
+{
+       struct bfa_lps_mod_s    *mod = BFA_LPS_MOD(bfa);
+       struct bfa_lps_s        *lps;
+
+       lps = BFA_LPS_FROM_TAG(mod, cvl->lp_tag);
+
+       bfa_sm_send_event(lps, BFA_LPS_SM_RX_CVL);
+}
+
+/**
  * Space is available in request queue, resume queueing request to firmware.
  */
 static void
@@ -531,7 +594,48 @@ bfa_lps_logout_comp(struct bfa_lps_s *lps)
                bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg);
 }
 
+/**
+ * Clear virtual link completion handler for non-fcs
+ */
+static void
+bfa_lps_cvl_event_cb(void *arg, bfa_boolean_t complete)
+{
+       struct bfa_lps_s *lps   = arg;
+
+       if (!complete)
+               return;
+
+       /* Clear virtual link to base port will result in link down */
+       if (lps->fdisc)
+               bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg);
+}
+
+/**
+ * Received Clear virtual link event --direct call for fcs,
+ * queue for others
+ */
+static void
+bfa_lps_cvl_event(struct bfa_lps_s *lps)
+{
+       if (!lps->bfa->fcs) {
+               bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_cvl_event_cb,
+                               lps);
+               return;
+       }
+
+       /* Clear virtual link to base port will result in link down */
+       if (lps->fdisc)
+               bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg);
+}
 
+u32
+bfa_lps_get_max_vport(struct bfa_s *bfa)
+{
+       if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT)
+               return BFA_LPS_MAX_VPORTS_SUPP_CT;
+       else
+               return BFA_LPS_MAX_VPORTS_SUPP_CB;
+}
 
 /**
  *  lps_public BFA LPS public functions
@@ -752,6 +856,14 @@ bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps)
        return lps->lsrjt_expl;
 }
 
+/**
+ * Return fpma/spma MAC for lport
+ */
+struct mac_s
+bfa_lps_get_lp_mac(struct bfa_lps_s *lps)
+{
+       return lps->lp_mac;
+}
 
 /**
  * LPS firmware message class handler.
@@ -773,6 +885,10 @@ bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
                bfa_lps_logout_rsp(bfa, msg.logout_rsp);
                break;
 
+       case BFI_LPS_H2I_CVL_EVENT:
+               bfa_lps_rx_cvl_event(bfa, msg.cvl_event);
+               break;
+
        default:
                bfa_trc(bfa, m->mhdr.msg_id);
                bfa_assert(0);
index 32eda8e..a7fcc80 100644 (file)
@@ -24,7 +24,7 @@
  */
 struct bfa_module_s *hal_mods[] = {
        &hal_mod_sgpg,
-       &hal_mod_pport,
+       &hal_mod_fcport,
        &hal_mod_fcxp,
        &hal_mod_lps,
        &hal_mod_uf,
@@ -45,7 +45,7 @@ bfa_isr_func_t  bfa_isrs[BFI_MC_MAX] = {
        bfa_isr_unhandled,      /* BFI_MC_DIAG */
        bfa_isr_unhandled,      /* BFI_MC_FLASH */
        bfa_isr_unhandled,      /* BFI_MC_CEE */
-       bfa_pport_isr,          /* BFI_MC_PORT */
+       bfa_fcport_isr,         /* BFI_MC_FCPORT */
        bfa_isr_unhandled,      /* BFI_MC_IOCFC */
        bfa_isr_unhandled,      /* BFI_MC_LL */
        bfa_uf_isr,             /* BFI_MC_UF */
index 96f7053..f554c2f 100644 (file)
@@ -29,7 +29,7 @@
 
 
 struct bfa_modules_s {
-       struct bfa_pport_s      pport;  /*  physical port module        */
+       struct bfa_fcport_s     fcport; /*  fc port module      */
        struct bfa_fcxp_mod_s fcxp_mod; /*  fcxp module         */
        struct bfa_lps_mod_s lps_mod;   /*  fcxp module         */
        struct bfa_uf_mod_s uf_mod;     /*  unsolicited frame module    */
index 51f698a..40e256e 100644 (file)
 #include "bfa_intr_priv.h"
 
 /**
- * BFA physical port data structure
+ * Link notification data structure
  */
-struct bfa_pport_s {
+struct bfa_fcport_ln_s {
+       struct bfa_fcport_s     *fcport;
+       bfa_sm_t                sm;
+       struct bfa_cb_qe_s      ln_qe;  /*  BFA callback queue elem for ln */
+       enum bfa_pport_linkstate ln_event; /*  ln event for callback */
+};
+
+/**
+ * BFA FC port data structure
+ */
+struct bfa_fcport_s {
        struct bfa_s            *bfa;   /*  parent BFA instance */
        bfa_sm_t                sm;     /*  port state machine */
        wwn_t                   nwwn;   /*  node wwn of physical port */
@@ -36,6 +46,8 @@ struct bfa_pport_s {
        enum bfa_pport_topology topology;       /*  current topology */
        u8                      myalpa; /*  my ALPA in LOOP topology */
        u8                      rsvd[3];
+       u32             mypid:24;
+       u32             rsvd_b:8;
        struct bfa_pport_cfg_s  cfg;    /*  current port configuration */
        struct bfa_qos_attr_s  qos_attr;   /* QoS Attributes */
        struct bfa_qos_vc_attr_s qos_vc_attr;  /*  VC info from ELP */
@@ -49,42 +61,31 @@ struct bfa_pport_s {
        void                    (*event_cbfn) (void *cbarg,
                                                bfa_pport_event_t event);
        union {
-               union bfi_pport_i2h_msg_u i2hmsg;
+               union bfi_fcport_i2h_msg_u i2hmsg;
        } event_arg;
        void                    *bfad;  /*  BFA driver handle */
+       struct bfa_fcport_ln_s   ln; /* Link Notification */
        struct bfa_cb_qe_s              hcb_qe; /*  BFA callback queue elem */
-       enum bfa_pport_linkstate        hcb_event;
-                                       /*  link event for callback */
+       struct bfa_timer_s      timer;  /*  timer */
        u32             msgtag; /*  fimrware msg tag for reply */
        u8                      *stats_kva;
        u64             stats_pa;
-       union bfa_pport_stats_u *stats; /*  pport stats */
-       u32             mypid:24;
-       u32             rsvd_b:8;
-       struct bfa_timer_s      timer;  /*  timer */
-       union bfa_pport_stats_u         *stats_ret;
-                                       /*  driver stats location */
-       bfa_status_t            stats_status;
-                                       /*  stats/statsclr status */
-       bfa_boolean_t           stats_busy;
-                                       /*  outstanding stats/statsclr */
-       bfa_boolean_t           stats_qfull;
-       bfa_boolean_t           diag_busy;
-                                       /*  diag busy status */
-       bfa_boolean_t           beacon;
-                                       /*  port beacon status */
-       bfa_boolean_t           link_e2e_beacon;
-                                       /*  link beacon status */
-       bfa_cb_pport_t          stats_cbfn;
-                                       /*  driver callback function */
-       void                    *stats_cbarg;
-                                       /* *!< user callback arg */
+       union bfa_fcport_stats_u *stats;
+       union bfa_fcport_stats_u *stats_ret; /*  driver stats location */
+       bfa_status_t            stats_status; /*  stats/statsclr status */
+       bfa_boolean_t           stats_busy; /*  outstanding stats/statsclr */
+       bfa_boolean_t           stats_qfull;
+       bfa_cb_pport_t          stats_cbfn; /*  driver callback function */
+       void                    *stats_cbarg; /* *!< user callback arg */
+       bfa_boolean_t           diag_busy; /*  diag busy status */
+       bfa_boolean_t           beacon; /*  port beacon status */
+       bfa_boolean_t           link_e2e_beacon; /*  link beacon status */
 };
 
-#define BFA_PORT_MOD(__bfa)    (&(__bfa)->modules.pport)
+#define BFA_FCPORT_MOD(__bfa)  (&(__bfa)->modules.fcport)
 
 /*
  * public functions
  */
-void   bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
+void   bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
 #endif /* __BFA_PORT_PRIV_H__ */
index 0747a6b..be80fc7 100644 (file)
@@ -101,7 +101,7 @@ extern bfa_boolean_t bfa_auto_recover;
 extern struct bfa_module_s hal_mod_flash;
 extern struct bfa_module_s hal_mod_fcdiag;
 extern struct bfa_module_s hal_mod_sgpg;
-extern struct bfa_module_s hal_mod_pport;
+extern struct bfa_module_s hal_mod_fcport;
 extern struct bfa_module_s hal_mod_fcxp;
 extern struct bfa_module_s hal_mod_lps;
 extern struct bfa_module_s hal_mod_uf;
index 3e1990a..7c509fa 100644 (file)
@@ -114,7 +114,7 @@ bfa_rport_sm_uninit(struct bfa_rport_s *rp, enum bfa_rport_event event)
 
        default:
                bfa_stats(rp, sm_un_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -146,7 +146,7 @@ bfa_rport_sm_created(struct bfa_rport_s *rp, enum bfa_rport_event event)
 
        default:
                bfa_stats(rp, sm_cr_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -183,7 +183,7 @@ bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, enum bfa_rport_event event)
 
        default:
                bfa_stats(rp, sm_fwc_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -224,7 +224,7 @@ bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
 
        default:
                bfa_stats(rp, sm_fwc_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -296,7 +296,7 @@ bfa_rport_sm_online(struct bfa_rport_s *rp, enum bfa_rport_event event)
 
        default:
                bfa_stats(rp, sm_on_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -329,7 +329,7 @@ bfa_rport_sm_fwdelete(struct bfa_rport_s *rp, enum bfa_rport_event event)
 
        default:
                bfa_stats(rp, sm_fwd_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -359,7 +359,7 @@ bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
 
        default:
                bfa_stats(rp, sm_fwd_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -394,7 +394,7 @@ bfa_rport_sm_offline(struct bfa_rport_s *rp, enum bfa_rport_event event)
 
        default:
                bfa_stats(rp, sm_off_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -421,7 +421,7 @@ bfa_rport_sm_deleting(struct bfa_rport_s *rp, enum bfa_rport_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -446,7 +446,7 @@ bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -477,7 +477,7 @@ bfa_rport_sm_delete_pending(struct bfa_rport_s *rp,
 
        default:
                bfa_stats(rp, sm_delp_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -512,7 +512,7 @@ bfa_rport_sm_offline_pending(struct bfa_rport_s *rp,
 
        default:
                bfa_stats(rp, sm_offp_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -550,7 +550,7 @@ bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, enum bfa_rport_event event)
 
        default:
                bfa_stats(rp, sm_iocd_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
index b3562dc..a7a8261 100644 (file)
  * !!! needed between trace utility and driver version
  */
 enum {
-       BFA_TRC_HAL_IOC         = 1,
-       BFA_TRC_HAL_INTR        = 2,
-       BFA_TRC_HAL_FCXP        = 3,
-       BFA_TRC_HAL_UF          = 4,
-       BFA_TRC_HAL_DIAG        = 5,
-       BFA_TRC_HAL_RPORT       = 6,
-       BFA_TRC_HAL_FCPIM       = 7,
-       BFA_TRC_HAL_IOIM        = 8,
-       BFA_TRC_HAL_TSKIM       = 9,
-       BFA_TRC_HAL_ITNIM       = 10,
-       BFA_TRC_HAL_PPORT       = 11,
-       BFA_TRC_HAL_SGPG        = 12,
-       BFA_TRC_HAL_FLASH       = 13,
-       BFA_TRC_HAL_DEBUG       = 14,
-       BFA_TRC_HAL_WWN         = 15,
-       BFA_TRC_HAL_FLASH_RAW   = 16,
-       BFA_TRC_HAL_SBOOT       = 17,
-       BFA_TRC_HAL_SBOOT_IO    = 18,
-       BFA_TRC_HAL_SBOOT_INTR  = 19,
-       BFA_TRC_HAL_SBTEST      = 20,
-       BFA_TRC_HAL_IPFC        = 21,
-       BFA_TRC_HAL_IOCFC       = 22,
-       BFA_TRC_HAL_FCPTM       = 23,
-       BFA_TRC_HAL_IOTM        = 24,
-       BFA_TRC_HAL_TSKTM       = 25,
-       BFA_TRC_HAL_TIN         = 26,
-       BFA_TRC_HAL_LPS         = 27,
-       BFA_TRC_HAL_FCDIAG      = 28,
-       BFA_TRC_HAL_PBIND       = 29,
-       BFA_TRC_HAL_IOCFC_CT    = 30,
-       BFA_TRC_HAL_IOCFC_CB    = 31,
-       BFA_TRC_HAL_IOCFC_Q     = 32,
+       BFA_TRC_HAL_INTR        = 1,
+       BFA_TRC_HAL_FCXP        = 2,
+       BFA_TRC_HAL_UF          = 3,
+       BFA_TRC_HAL_RPORT       = 4,
+       BFA_TRC_HAL_FCPIM       = 5,
+       BFA_TRC_HAL_IOIM        = 6,
+       BFA_TRC_HAL_TSKIM       = 7,
+       BFA_TRC_HAL_ITNIM       = 8,
+       BFA_TRC_HAL_FCPORT      = 9,
+       BFA_TRC_HAL_SGPG        = 10,
+       BFA_TRC_HAL_FLASH       = 11,
+       BFA_TRC_HAL_DEBUG       = 12,
+       BFA_TRC_HAL_WWN         = 13,
+       BFA_TRC_HAL_FLASH_RAW   = 14,
+       BFA_TRC_HAL_SBOOT       = 15,
+       BFA_TRC_HAL_SBOOT_IO    = 16,
+       BFA_TRC_HAL_SBOOT_INTR  = 17,
+       BFA_TRC_HAL_SBTEST      = 18,
+       BFA_TRC_HAL_IPFC        = 19,
+       BFA_TRC_HAL_IOCFC       = 20,
+       BFA_TRC_HAL_FCPTM       = 21,
+       BFA_TRC_HAL_IOTM        = 22,
+       BFA_TRC_HAL_TSKTM       = 23,
+       BFA_TRC_HAL_TIN         = 24,
+       BFA_TRC_HAL_LPS         = 25,
+       BFA_TRC_HAL_FCDIAG      = 26,
+       BFA_TRC_HAL_PBIND       = 27,
+       BFA_TRC_HAL_IOCFC_CT    = 28,
+       BFA_TRC_HAL_IOCFC_CB    = 29,
+       BFA_TRC_HAL_IOCFC_Q     = 30,
 };
 
 #endif /* __BFA_TRCMOD_PRIV_H__ */
index ff7a4dc..ad9aaae 100644 (file)
@@ -110,7 +110,7 @@ bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(tskim->bfa, event);
        }
 }
 
@@ -146,7 +146,7 @@ bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(tskim->bfa, event);
        }
 }
 
@@ -178,7 +178,7 @@ bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(tskim->bfa, event);
        }
 }
 
@@ -207,7 +207,7 @@ bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(tskim->bfa, event);
        }
 }
 
@@ -242,7 +242,7 @@ bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(tskim->bfa, event);
        }
 }
 
@@ -277,7 +277,7 @@ bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(tskim->bfa, event);
        }
 }
 
@@ -303,7 +303,7 @@ bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(tskim->bfa, event);
        }
 }
 
index b52b773..6bff08e 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/kthread.h>
 #include "bfad_drv.h"
 #include "bfad_im.h"
 #include "bfad_tm.h"
@@ -53,6 +54,7 @@ static int      log_level = BFA_LOG_WARNING;
 static int      ioc_auto_recover = BFA_TRUE;
 static int      ipfc_enable = BFA_FALSE;
 static int      ipfc_mtu = -1;
+static int     fdmi_enable = BFA_TRUE;
 int            bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH;
 int            bfa_linkup_delay = -1;
 
@@ -74,6 +76,7 @@ module_param(log_level, int, S_IRUGO | S_IWUSR);
 module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR);
 module_param(ipfc_enable, int, S_IRUGO | S_IWUSR);
 module_param(ipfc_mtu, int, S_IRUGO | S_IWUSR);
+module_param(fdmi_enable, int, S_IRUGO | S_IWUSR);
 module_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR);
 
 /*
@@ -95,6 +98,8 @@ bfad_fc4_probe(struct bfad_s *bfad)
 
        if (ipfc_enable)
                bfad_ipfc_probe(bfad);
+
+       bfad->bfad_flags |= BFAD_FC4_PROBE_DONE;
 ext:
        return rc;
 }
@@ -106,6 +111,7 @@ bfad_fc4_probe_undo(struct bfad_s *bfad)
        bfad_tm_probe_undo(bfad);
        if (ipfc_enable)
                bfad_ipfc_probe_undo(bfad);
+       bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE;
 }
 
 static void
@@ -173,9 +179,19 @@ bfa_cb_init(void *drv, bfa_status_t init_status)
 {
        struct bfad_s  *bfad = drv;
 
-       if (init_status == BFA_STATUS_OK)
+       if (init_status == BFA_STATUS_OK) {
                bfad->bfad_flags |= BFAD_HAL_INIT_DONE;
 
+               /* If BFAD_HAL_INIT_FAIL flag is set:
+                * Wake up the kernel thread to start
+                * the bfad operations after HAL init done
+                */
+               if ((bfad->bfad_flags & BFAD_HAL_INIT_FAIL)) {
+                       bfad->bfad_flags &= ~BFAD_HAL_INIT_FAIL;
+                       wake_up_process(bfad->bfad_tsk);
+               }
+       }
+
        complete(&bfad->comp);
 }
 
@@ -648,7 +664,7 @@ bfad_fcs_port_cfg(struct bfad_s *bfad)
 
        sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no);
        memcpy(port_cfg.sym_name.symname, symname, strlen(symname));
-       bfa_pport_get_attr(&bfad->bfa, &attr);
+       bfa_fcport_get_attr(&bfad->bfa, &attr);
        port_cfg.nwwn = attr.nwwn;
        port_cfg.pwwn = attr.pwwn;
 
@@ -661,7 +677,6 @@ bfad_drv_init(struct bfad_s *bfad)
        bfa_status_t    rc;
        unsigned long   flags;
        struct bfa_fcs_driver_info_s driver_info;
-       int             i;
 
        bfad->cfg_data.rport_del_timeout = rport_del_timeout;
        bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth;
@@ -681,12 +696,7 @@ bfad_drv_init(struct bfad_s *bfad)
        bfa_init_log(&bfad->bfa, bfad->logmod);
        bfa_init_trc(&bfad->bfa, bfad->trcmod);
        bfa_init_aen(&bfad->bfa, bfad->aen);
-       INIT_LIST_HEAD(&bfad->file_q);
-       INIT_LIST_HEAD(&bfad->file_free_q);
-       for (i = 0; i < BFAD_AEN_MAX_APPS; i++) {
-               bfa_q_qe_init(&bfad->file_buf[i].qe);
-               list_add_tail(&bfad->file_buf[i].qe, &bfad->file_free_q);
-       }
+       memset(bfad->file_map, 0, sizeof(bfad->file_map));
        bfa_init_plog(&bfad->bfa, &bfad->plog_buf);
        bfa_plog_init(&bfad->plog_buf);
        bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START,
@@ -746,8 +756,16 @@ bfad_drv_init(struct bfad_s *bfad)
        bfa_fcs_log_init(&bfad->bfa_fcs, bfad->logmod);
        bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod);
        bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen);
-       bfa_fcs_init(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
+       bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
+
+       /* Do FCS init only when HAL init is done */
+       if ((bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
+               bfa_fcs_init(&bfad->bfa_fcs);
+               bfad->bfad_flags |= BFAD_FCS_INIT_DONE;
+       }
+
        bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info);
+       bfa_fcs_set_fdmi_param(&bfad->bfa_fcs, fdmi_enable);
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 
        bfad->bfad_flags |= BFAD_DRV_INIT_DONE;
@@ -763,12 +781,21 @@ out_hal_mem_alloc_failure:
 void
 bfad_drv_uninit(struct bfad_s *bfad)
 {
+       unsigned long   flags;
+
+       spin_lock_irqsave(&bfad->bfad_lock, flags);
+       init_completion(&bfad->comp);
+       bfa_stop(&bfad->bfa);
+       spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+       wait_for_completion(&bfad->comp);
+
        del_timer_sync(&bfad->hal_tmo);
        bfa_isr_disable(&bfad->bfa);
        bfa_detach(&bfad->bfa);
        bfad_remove_intr(bfad);
-       bfa_assert(list_empty(&bfad->file_q));
        bfad_hal_mem_release(bfad);
+
+       bfad->bfad_flags &= ~BFAD_DRV_INIT_DONE;
 }
 
 void
@@ -859,6 +886,86 @@ bfad_drv_log_level_set(struct bfad_s *bfad)
                bfa_log_set_level_all(&bfad->log_data, log_level);
 }
 
+bfa_status_t
+bfad_start_ops(struct bfad_s *bfad)
+{
+       int retval;
+
+       /* PPORT FCS config */
+       bfad_fcs_port_cfg(bfad);
+
+       retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM);
+       if (retval != BFA_STATUS_OK)
+               goto out_cfg_pport_failure;
+
+       /* BFAD level FC4 (IM/TM/IPFC) specific resource allocation */
+       retval = bfad_fc4_probe(bfad);
+       if (retval != BFA_STATUS_OK) {
+               printk(KERN_WARNING "bfad_fc4_probe failed\n");
+               goto out_fc4_probe_failure;
+       }
+
+       bfad_drv_start(bfad);
+
+       /*
+        * If bfa_linkup_delay is set to -1 default; try to retrive the
+        * value using the bfad_os_get_linkup_delay(); else use the
+        * passed in module param value as the bfa_linkup_delay.
+        */
+       if (bfa_linkup_delay < 0) {
+
+               bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
+               bfad_os_rport_online_wait(bfad);
+               bfa_linkup_delay = -1;
+
+       } else {
+               bfad_os_rport_online_wait(bfad);
+       }
+
+       bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name);
+
+       return BFA_STATUS_OK;
+
+out_fc4_probe_failure:
+       bfad_fc4_probe_undo(bfad);
+       bfad_uncfg_pport(bfad);
+out_cfg_pport_failure:
+       return BFA_STATUS_FAILED;
+}
+
+int
+bfad_worker (void *ptr)
+{
+       struct bfad_s *bfad;
+       unsigned long   flags;
+
+       bfad = (struct bfad_s *)ptr;
+
+       while (!kthread_should_stop()) {
+
+               /* Check if the FCS init is done from bfad_drv_init;
+                * if not done do FCS init and set the flag.
+                */
+               if (!(bfad->bfad_flags & BFAD_FCS_INIT_DONE)) {
+                       spin_lock_irqsave(&bfad->bfad_lock, flags);
+                       bfa_fcs_init(&bfad->bfa_fcs);
+                       bfad->bfad_flags |= BFAD_FCS_INIT_DONE;
+                       spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+               }
+
+               /* Start the bfad operations after HAL init done */
+               bfad_start_ops(bfad);
+
+               spin_lock_irqsave(&bfad->bfad_lock, flags);
+               bfad->bfad_tsk = NULL;
+               spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+               break;
+       }
+
+       return 0;
+}
+
  /*
   *  PCI_entry PCI driver entries * {
   */
@@ -871,7 +978,6 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
 {
        struct bfad_s  *bfad;
        int             error = -ENODEV, retval;
-       char            buf[16];
 
        /*
         * For single port cards - only claim function 0
@@ -902,8 +1008,7 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
        bfa_trc(bfad, bfad_inst);
 
        bfad->logmod = &bfad->log_data;
-       sprintf(buf, "%d", bfad_inst);
-       bfa_log_init(bfad->logmod, buf, bfa_os_printf);
+       bfa_log_init(bfad->logmod, (char *)pci_name(pdev), bfa_os_printf);
 
        bfad_drv_log_level_set(bfad);
 
@@ -933,57 +1038,39 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
        bfad->ref_count = 0;
        bfad->pport.bfad = bfad;
 
+       bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad, "%s",
+                                       "bfad_worker");
+       if (IS_ERR(bfad->bfad_tsk)) {
+               printk(KERN_INFO "bfad[%d]: Kernel thread"
+                       " creation failed!\n",
+                       bfad->inst_no);
+               goto out_kthread_create_failure;
+       }
+
        retval = bfad_drv_init(bfad);
        if (retval != BFA_STATUS_OK)
                goto out_drv_init_failure;
        if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
+               bfad->bfad_flags |= BFAD_HAL_INIT_FAIL;
                printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no);
                goto ok;
        }
 
-       /*
-        * PPORT FCS config
-        */
-       bfad_fcs_port_cfg(bfad);
-
-       retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM);
+       retval = bfad_start_ops(bfad);
        if (retval != BFA_STATUS_OK)
-               goto out_cfg_pport_failure;
-
-       /*
-        * BFAD level FC4 (IM/TM/IPFC) specific resource allocation
-        */
-       retval = bfad_fc4_probe(bfad);
-       if (retval != BFA_STATUS_OK) {
-               printk(KERN_WARNING "bfad_fc4_probe failed\n");
-               goto out_fc4_probe_failure;
-       }
+               goto out_start_ops_failure;
 
-       bfad_drv_start(bfad);
-
-       /*
-        * If bfa_linkup_delay is set to -1 default; try to retrive the
-        * value using the bfad_os_get_linkup_delay(); else use the
-        * passed in module param value as the bfa_linkup_delay.
-        */
-       if (bfa_linkup_delay < 0) {
-               bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
-               bfad_os_rport_online_wait(bfad);
-               bfa_linkup_delay = -1;
-       } else {
-               bfad_os_rport_online_wait(bfad);
-       }
+       kthread_stop(bfad->bfad_tsk);
+       bfad->bfad_tsk = NULL;
 
-       bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name);
 ok:
        return 0;
 
-out_fc4_probe_failure:
-       bfad_fc4_probe_undo(bfad);
-       bfad_uncfg_pport(bfad);
-out_cfg_pport_failure:
+out_start_ops_failure:
        bfad_drv_uninit(bfad);
 out_drv_init_failure:
+       kthread_stop(bfad->bfad_tsk);
+out_kthread_create_failure:
        mutex_lock(&bfad_mutex);
        bfad_inst--;
        list_del(&bfad->list_entry);
@@ -1008,6 +1095,11 @@ bfad_pci_remove(struct pci_dev *pdev)
 
        bfa_trc(bfad, bfad->inst_no);
 
+       spin_lock_irqsave(&bfad->bfad_lock, flags);
+       if (bfad->bfad_tsk != NULL)
+               kthread_stop(bfad->bfad_tsk);
+       spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
        if ((bfad->bfad_flags & BFAD_DRV_INIT_DONE)
            && !(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
 
@@ -1024,13 +1116,25 @@ bfad_pci_remove(struct pci_dev *pdev)
                goto remove_sysfs;
        }
 
-       if (bfad->bfad_flags & BFAD_HAL_START_DONE)
+       if (bfad->bfad_flags & BFAD_HAL_START_DONE) {
                bfad_drv_stop(bfad);
+       } else if (bfad->bfad_flags & BFAD_DRV_INIT_DONE) {
+               /* Invoking bfa_stop() before bfa_detach
+                * when HAL and DRV init are success
+                * but HAL start did not occur.
+                */
+               spin_lock_irqsave(&bfad->bfad_lock, flags);
+               init_completion(&bfad->comp);
+               bfa_stop(&bfad->bfa);
+               spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+               wait_for_completion(&bfad->comp);
+       }
 
        bfad_remove_intr(bfad);
-
        del_timer_sync(&bfad->hal_tmo);
-       bfad_fc4_probe_undo(bfad);
+
+       if (bfad->bfad_flags & BFAD_FC4_PROBE_DONE)
+               bfad_fc4_probe_undo(bfad);
 
        if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE)
                bfad_uncfg_pport(bfad);
index 9129ae3..d97f691 100644 (file)
@@ -141,7 +141,7 @@ bfad_im_get_host_port_type(struct Scsi_Host *shost)
        struct bfad_s         *bfad = im_port->bfad;
        struct bfa_pport_attr_s attr;
 
-       bfa_pport_get_attr(&bfad->bfa, &attr);
+       bfa_fcport_get_attr(&bfad->bfa, &attr);
 
        switch (attr.port_type) {
        case BFA_PPORT_TYPE_NPORT:
@@ -173,7 +173,7 @@ bfad_im_get_host_port_state(struct Scsi_Host *shost)
        struct bfad_s         *bfad = im_port->bfad;
        struct bfa_pport_attr_s attr;
 
-       bfa_pport_get_attr(&bfad->bfa, &attr);
+       bfa_fcport_get_attr(&bfad->bfa, &attr);
 
        switch (attr.port_state) {
        case BFA_PPORT_ST_LINKDOWN:
@@ -229,8 +229,10 @@ bfad_im_get_host_speed(struct Scsi_Host *shost)
                        (struct bfad_im_port_s *) shost->hostdata[0];
        struct bfad_s         *bfad = im_port->bfad;
        struct bfa_pport_attr_s attr;
+       unsigned long   flags;
 
-       bfa_pport_get_attr(&bfad->bfa, &attr);
+       spin_lock_irqsave(shost->host_lock, flags);
+       bfa_fcport_get_attr(&bfad->bfa, &attr);
        switch (attr.speed) {
        case BFA_PPORT_SPEED_8GBPS:
                fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
@@ -248,6 +250,7 @@ bfad_im_get_host_speed(struct Scsi_Host *shost)
                fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
                break;
        }
+       spin_unlock_irqrestore(shost->host_lock, flags);
 }
 
 /**
@@ -285,7 +288,7 @@ bfad_im_get_stats(struct Scsi_Host *shost)
        init_completion(&fcomp.comp);
        spin_lock_irqsave(&bfad->bfad_lock, flags);
        memset(hstats, 0, sizeof(struct fc_host_statistics));
-       rc = bfa_pport_get_stats(&bfad->bfa,
+       rc =  bfa_port_get_stats(BFA_FCPORT(&bfad->bfa),
                                     (union bfa_pport_stats_u *) hstats,
                                     bfad_hcb_comp, &fcomp);
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -312,7 +315,8 @@ bfad_im_reset_stats(struct Scsi_Host *shost)
 
        init_completion(&fcomp.comp);
        spin_lock_irqsave(&bfad->bfad_lock, flags);
-       rc = bfa_pport_clear_stats(&bfad->bfa, bfad_hcb_comp, &fcomp);
+       rc = bfa_port_clear_stats(BFA_FCPORT(&bfad->bfa), bfad_hcb_comp,
+               &fcomp);
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 
        if (rc != BFA_STATUS_OK)
@@ -421,12 +425,10 @@ bfad_im_serial_num_show(struct device *dev, struct device_attribute *attr,
        struct bfad_im_port_s *im_port =
                        (struct bfad_im_port_s *) shost->hostdata[0];
        struct bfad_s         *bfad = im_port->bfad;
-       struct bfa_ioc_attr_s  ioc_attr;
+       char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
 
-       memset(&ioc_attr, 0, sizeof(ioc_attr));
-       bfa_get_attr(&bfad->bfa, &ioc_attr);
-       return snprintf(buf, PAGE_SIZE, "%s\n",
-                       ioc_attr.adapter_attr.serial_num);
+       bfa_get_adapter_serial_num(&bfad->bfa, serial_num);
+       return snprintf(buf, PAGE_SIZE, "%s\n", serial_num);
 }
 
 static ssize_t
@@ -437,11 +439,10 @@ bfad_im_model_show(struct device *dev, struct device_attribute *attr,
        struct bfad_im_port_s *im_port =
                        (struct bfad_im_port_s *) shost->hostdata[0];
        struct bfad_s         *bfad = im_port->bfad;
-       struct bfa_ioc_attr_s  ioc_attr;
+       char model[BFA_ADAPTER_MODEL_NAME_LEN];
 
-       memset(&ioc_attr, 0, sizeof(ioc_attr));
-       bfa_get_attr(&bfad->bfa, &ioc_attr);
-       return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.model);
+       bfa_get_adapter_model(&bfad->bfa, model);
+       return snprintf(buf, PAGE_SIZE, "%s\n", model);
 }
 
 static ssize_t
@@ -452,12 +453,10 @@ bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr,
        struct bfad_im_port_s *im_port =
                        (struct bfad_im_port_s *) shost->hostdata[0];
        struct bfad_s         *bfad = im_port->bfad;
-       struct bfa_ioc_attr_s  ioc_attr;
+       char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN];
 
-       memset(&ioc_attr, 0, sizeof(ioc_attr));
-       bfa_get_attr(&bfad->bfa, &ioc_attr);
-       return snprintf(buf, PAGE_SIZE, "%s\n",
-                       ioc_attr.adapter_attr.model_descr);
+       bfa_get_adapter_model(&bfad->bfa, model_descr);
+       return snprintf(buf, PAGE_SIZE, "%s\n", model_descr);
 }
 
 static ssize_t
@@ -482,14 +481,13 @@ bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr,
        struct bfad_im_port_s *im_port =
                        (struct bfad_im_port_s *) shost->hostdata[0];
        struct bfad_s         *bfad = im_port->bfad;
-       struct bfa_ioc_attr_s  ioc_attr;
-
-       memset(&ioc_attr, 0, sizeof(ioc_attr));
-       bfa_get_attr(&bfad->bfa, &ioc_attr);
+       char model[BFA_ADAPTER_MODEL_NAME_LEN];
+       char fw_ver[BFA_VERSION_LEN];
 
+       bfa_get_adapter_model(&bfad->bfa, model);
+       bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
        return snprintf(buf, PAGE_SIZE, "Brocade %s FV%s DV%s\n",
-                       ioc_attr.adapter_attr.model,
-                       ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION);
+               model, fw_ver, BFAD_DRIVER_VERSION);
 }
 
 static ssize_t
@@ -500,11 +498,10 @@ bfad_im_hw_version_show(struct device *dev, struct device_attribute *attr,
        struct bfad_im_port_s *im_port =
                        (struct bfad_im_port_s *) shost->hostdata[0];
        struct bfad_s         *bfad = im_port->bfad;
-       struct bfa_ioc_attr_s  ioc_attr;
+       char hw_ver[BFA_VERSION_LEN];
 
-       memset(&ioc_attr, 0, sizeof(ioc_attr));
-       bfa_get_attr(&bfad->bfa, &ioc_attr);
-       return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.hw_ver);
+       bfa_get_pci_chip_rev(&bfad->bfa, hw_ver);
+       return snprintf(buf, PAGE_SIZE, "%s\n", hw_ver);
 }
 
 static ssize_t
@@ -522,12 +519,10 @@ bfad_im_optionrom_version_show(struct device *dev,
        struct bfad_im_port_s *im_port =
                        (struct bfad_im_port_s *) shost->hostdata[0];
        struct bfad_s         *bfad = im_port->bfad;
-       struct bfa_ioc_attr_s  ioc_attr;
+       char optrom_ver[BFA_VERSION_LEN];
 
-       memset(&ioc_attr, 0, sizeof(ioc_attr));
-       bfa_get_attr(&bfad->bfa, &ioc_attr);
-       return snprintf(buf, PAGE_SIZE, "%s\n",
-                       ioc_attr.adapter_attr.optrom_ver);
+       bfa_get_adapter_optrom_ver(&bfad->bfa, optrom_ver);
+       return snprintf(buf, PAGE_SIZE, "%s\n", optrom_ver);
 }
 
 static ssize_t
@@ -538,11 +533,10 @@ bfad_im_fw_version_show(struct device *dev, struct device_attribute *attr,
        struct bfad_im_port_s *im_port =
                        (struct bfad_im_port_s *) shost->hostdata[0];
        struct bfad_s         *bfad = im_port->bfad;
-       struct bfa_ioc_attr_s  ioc_attr;
+       char fw_ver[BFA_VERSION_LEN];
 
-       memset(&ioc_attr, 0, sizeof(ioc_attr));
-       bfa_get_attr(&bfad->bfa, &ioc_attr);
-       return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.fw_ver);
+       bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
+       return snprintf(buf, PAGE_SIZE, "%s\n", fw_ver);
 }
 
 static ssize_t
@@ -553,11 +547,9 @@ bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr,
        struct bfad_im_port_s *im_port =
                        (struct bfad_im_port_s *) shost->hostdata[0];
        struct bfad_s         *bfad = im_port->bfad;
-       struct bfa_ioc_attr_s  ioc_attr;
 
-       memset(&ioc_attr, 0, sizeof(ioc_attr));
-       bfa_get_attr(&bfad->bfa, &ioc_attr);
-       return snprintf(buf, PAGE_SIZE, "%d\n", ioc_attr.adapter_attr.nports);
+       return snprintf(buf, PAGE_SIZE, "%d\n",
+               bfa_get_nports(&bfad->bfa));
 }
 
 static ssize_t
index 4d3312d..bf01020 100644 (file)
@@ -17,9 +17,6 @@
 
 #ifndef __BFAD_ATTR_H__
 #define __BFAD_ATTR_H__
-/**
- *  bfad_attr.h VMware driver configuration interface module.
- */
 
 /**
  *  FC_transport_template FC transport template
@@ -52,12 +49,6 @@ bfad_im_get_starget_port_name(struct scsi_target *starget);
 void
 bfad_im_get_host_port_id(struct Scsi_Host *shost);
 
-/**
- * FC transport template entry, issue a LIP.
- */
-int
-bfad_im_issue_fc_host_lip(struct Scsi_Host *shost);
-
 struct Scsi_Host*
 bfad_os_starget_to_shost(struct scsi_target *starget);
 
index 172c81e..107848c 100644 (file)
@@ -46,7 +46,7 @@
 #ifdef BFA_DRIVER_VERSION
 #define BFAD_DRIVER_VERSION    BFA_DRIVER_VERSION
 #else
-#define BFAD_DRIVER_VERSION    "2.0.0.0"
+#define BFAD_DRIVER_VERSION    "2.1.2.1"
 #endif
 
 
@@ -62,7 +62,9 @@
 #define BFAD_HAL_START_DONE                    0x00000010
 #define BFAD_PORT_ONLINE                       0x00000020
 #define BFAD_RPORT_ONLINE                      0x00000040
-
+#define BFAD_FCS_INIT_DONE                      0x00000080
+#define BFAD_HAL_INIT_FAIL                      0x00000100
+#define BFAD_FC4_PROBE_DONE                     0x00000200
 #define BFAD_PORT_DELETE                       0x00000001
 
 /*
@@ -137,12 +139,16 @@ struct bfad_cfg_param_s {
        u32        binding_method;
 };
 
-#define BFAD_AEN_MAX_APPS 8
-struct bfad_aen_file_s {
-       struct list_head  qe;
-       struct bfad_s *bfad;
-       s32 ri;
-       s32 app_id;
+union bfad_tmp_buf {
+       /* From struct bfa_adapter_attr_s */
+       char            manufacturer[BFA_ADAPTER_MFG_NAME_LEN];
+       char            serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
+       char            model[BFA_ADAPTER_MODEL_NAME_LEN];
+       char            fw_ver[BFA_VERSION_LEN];
+       char            optrom_ver[BFA_VERSION_LEN];
+
+       /* From struct bfa_ioc_pci_attr_s */
+       u8         chip_rev[BFA_IOC_CHIP_REV_LEN];  /*  chip revision */
 };
 
 /*
@@ -168,6 +174,7 @@ struct bfad_s {
        u32        inst_no;     /* BFAD instance number */
        u32        bfad_flags;
        spinlock_t      bfad_lock;
+       struct task_struct *bfad_tsk;
        struct bfad_cfg_param_s cfg_data;
        struct bfad_msix_s msix_tab[MAX_MSIX_ENTRY];
        int             nvec;
@@ -183,18 +190,12 @@ struct bfad_s {
        struct bfa_log_mod_s  *logmod;
        struct bfa_aen_s      *aen;
        struct bfa_aen_s       aen_buf;
-       struct bfad_aen_file_s file_buf[BFAD_AEN_MAX_APPS];
-       struct list_head         file_q;
-       struct list_head         file_free_q;
+       void            *file_map[BFA_AEN_MAX_APP];
        struct bfa_plog_s      plog_buf;
        int             ref_count;
        bfa_boolean_t   ipfc_enabled;
+       union bfad_tmp_buf tmp_buf;
        struct fc_host_statistics link_stats;
-
-       struct kobject *bfa_kobj;
-       struct kobject *ioc_kobj;
-       struct kobject *pport_kobj;
-       struct kobject *lport_kobj;
 };
 
 /*
@@ -258,6 +259,7 @@ bfa_status_t    bfad_vf_create(struct bfad_s *bfad, u16 vf_id,
                               struct bfa_port_cfg_s *port_cfg);
 bfa_status_t    bfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role);
 bfa_status_t    bfad_drv_init(struct bfad_s *bfad);
+bfa_status_t   bfad_start_ops(struct bfad_s *bfad);
 void            bfad_drv_start(struct bfad_s *bfad);
 void            bfad_uncfg_pport(struct bfad_s *bfad);
 void            bfad_drv_stop(struct bfad_s *bfad);
@@ -279,6 +281,7 @@ void                bfad_drv_uninit(struct bfad_s *bfad);
 void           bfad_drv_log_level_set(struct bfad_s *bfad);
 bfa_status_t   bfad_fc4_module_init(void);
 void           bfad_fc4_module_exit(void);
+int            bfad_worker (void *ptr);
 
 void bfad_pci_remove(struct pci_dev *pdev);
 int bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid);
index f788c2a..f9fc67a 100644 (file)
@@ -43,11 +43,11 @@ bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio,
        struct bfad_s         *bfad = drv;
        struct bfad_itnim_data_s *itnim_data;
        struct bfad_itnim_s *itnim;
+       u8         host_status = DID_OK;
 
        switch (io_status) {
        case BFI_IOIM_STS_OK:
                bfa_trc(bfad, scsi_status);
-               cmnd->result = ScsiResult(DID_OK, scsi_status);
                scsi_set_resid(cmnd, 0);
 
                if (sns_len > 0) {
@@ -56,8 +56,18 @@ bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio,
                                sns_len = SCSI_SENSE_BUFFERSIZE;
                        memcpy(cmnd->sense_buffer, sns_info, sns_len);
                }
-               if (residue > 0)
+               if (residue > 0) {
+                       bfa_trc(bfad, residue);
                        scsi_set_resid(cmnd, residue);
+                       if (!sns_len && (scsi_status == SAM_STAT_GOOD) &&
+                               (scsi_bufflen(cmnd) - residue) <
+                                       cmnd->underflow) {
+                               bfa_trc(bfad, 0);
+                               host_status = DID_ERROR;
+                       }
+               }
+               cmnd->result = ScsiResult(host_status, scsi_status);
+
                break;
 
        case BFI_IOIM_STS_ABORTED:
@@ -167,17 +177,15 @@ bfad_im_info(struct Scsi_Host *shost)
        static char     bfa_buf[256];
        struct bfad_im_port_s *im_port =
                        (struct bfad_im_port_s *) shost->hostdata[0];
-       struct bfa_ioc_attr_s  ioc_attr;
        struct bfad_s         *bfad = im_port->bfad;
+       char model[BFA_ADAPTER_MODEL_NAME_LEN];
 
-       memset(&ioc_attr, 0, sizeof(ioc_attr));
-       bfa_get_attr(&bfad->bfa, &ioc_attr);
+       bfa_get_adapter_model(&bfad->bfa, model);
 
        memset(bfa_buf, 0, sizeof(bfa_buf));
        snprintf(bfa_buf, sizeof(bfa_buf),
-                "Brocade FC/FCOE Adapter, " "model: %s hwpath: %s driver: %s",
-                ioc_attr.adapter_attr.model, bfad->pci_name,
-                BFAD_DRIVER_VERSION);
+               "Brocade FC/FCOE Adapter, " "model: %s hwpath: %s driver: %s",
+               model, bfad->pci_name, BFAD_DRIVER_VERSION);
        return bfa_buf;
 }
 
@@ -501,16 +509,6 @@ void bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim)
 }
 
 /**
- * Path TOV processing begin notification -- dummy for linux
- */
-void
-bfa_fcb_itnim_tov_begin(struct bfad_itnim_s *itnim)
-{
-}
-
-
-
-/**
  * Allocate a Scsi_Host for a port.
  */
 int
@@ -931,10 +929,9 @@ bfad_os_fc_host_init(struct bfad_im_port_s *im_port)
        struct Scsi_Host *host = im_port->shost;
        struct bfad_s         *bfad = im_port->bfad;
        struct bfad_port_s    *port = im_port->port;
-       union attr {
-               struct bfa_pport_attr_s pattr;
-               struct bfa_ioc_attr_s  ioc_attr;
-       } attr;
+       struct bfa_pport_attr_s pattr;
+       char model[BFA_ADAPTER_MODEL_NAME_LEN];
+       char fw_ver[BFA_VERSION_LEN];
 
        fc_host_node_name(host) =
                bfa_os_htonll((bfa_fcs_port_get_nwwn(port->fcs_port)));
@@ -954,20 +951,18 @@ bfad_os_fc_host_init(struct bfad_im_port_s *im_port)
        /* For fibre channel services type 0x20 */
        fc_host_supported_fc4s(host)[7] = 1;
 
-       memset(&attr.ioc_attr, 0, sizeof(attr.ioc_attr));
-       bfa_get_attr(&bfad->bfa, &attr.ioc_attr);
+       bfa_get_adapter_model(&bfad->bfa, model);
+       bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
        sprintf(fc_host_symbolic_name(host), "Brocade %s FV%s DV%s",
-               attr.ioc_attr.adapter_attr.model,
-               attr.ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION);
+               model, fw_ver, BFAD_DRIVER_VERSION);
 
        fc_host_supported_speeds(host) = 0;
        fc_host_supported_speeds(host) |=
                FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT |
                FC_PORTSPEED_1GBIT;
 
-       memset(&attr.pattr, 0, sizeof(attr.pattr));
-       bfa_pport_get_attr(&bfad->bfa, &attr.pattr);
-       fc_host_maxframe_size(host) = attr.pattr.pport_cfg.maxfrsize;
+       bfa_fcport_get_attr(&bfad->bfa, &pattr);
+       fc_host_maxframe_size(host) = pattr.pport_cfg.maxfrsize;
 }
 
 static void
index 189a5b2..85ab2da 100644 (file)
@@ -23,7 +23,6 @@
 
 #define FCPI_NAME " fcpim"
 
-void bfad_flags_set(struct bfad_s *bfad, u32 flags);
 bfa_status_t bfad_im_module_init(void);
 void bfad_im_module_exit(void);
 bfa_status_t bfad_im_probe(struct bfad_s *bfad);
@@ -126,7 +125,6 @@ bfa_status_t bfad_os_thread_workq(struct bfad_s *bfad);
 void bfad_os_destroy_workq(struct bfad_im_s *im);
 void bfad_os_itnim_process(struct bfad_itnim_s *itnim_drv);
 void bfad_os_fc_host_init(struct bfad_im_port_s *im_port);
-void bfad_os_init_work(struct bfad_im_port_s *im_port);
 void bfad_os_scsi_host_free(struct bfad_s *bfad,
                                 struct bfad_im_port_s *im_port);
 void bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim,
@@ -136,9 +134,6 @@ struct bfad_itnim_s *bfad_os_get_itnim(struct bfad_im_port_s *im_port, int id);
 int bfad_os_scsi_add_host(struct Scsi_Host *shost,
                struct bfad_im_port_s *im_port, struct bfad_s *bfad);
 
-/*
- * scsi_host_template entries
- */
 void bfad_im_itnim_unmap(struct bfad_im_port_s  *im_port,
                         struct bfad_itn