Commit 961cde93 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6

* 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.
  ...
parents f82c37e7 0d9dc7c8
...@@ -613,7 +613,7 @@ static struct scsi_host_template iscsi_iser_sht = { ...@@ -613,7 +613,7 @@ static struct scsi_host_template iscsi_iser_sht = {
.cmd_per_lun = ISER_DEF_CMD_PER_LUN, .cmd_per_lun = ISER_DEF_CMD_PER_LUN,
.eh_abort_handler = iscsi_eh_abort, .eh_abort_handler = iscsi_eh_abort,
.eh_device_reset_handler= iscsi_eh_device_reset, .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, .target_alloc = iscsi_target_alloc,
.use_clustering = DISABLE_CLUSTERING, .use_clustering = DISABLE_CLUSTERING,
.proc_name = "iscsi_iser", .proc_name = "iscsi_iser",
......
menu "SCSI device support" menu "SCSI device support"
config SCSI_MOD
tristate
default y if SCSI=n || SCSI=y
default m if SCSI=m
config RAID_ATTRS config RAID_ATTRS
tristate "RAID Transport Class" tristate "RAID Transport Class"
default n default n
depends on BLOCK depends on BLOCK
depends on SCSI_MOD
---help--- ---help---
Provides RAID Provides RAID
......
...@@ -32,18 +32,11 @@ void be_mcc_notify(struct beiscsi_hba *phba) ...@@ -32,18 +32,11 @@ void be_mcc_notify(struct beiscsi_hba *phba)
unsigned int alloc_mcc_tag(struct beiscsi_hba *phba) unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
{ {
unsigned int tag = 0; unsigned int tag = 0;
unsigned int num = 0;
mcc_tag_rdy:
if (phba->ctrl.mcc_tag_available) { if (phba->ctrl.mcc_tag_available) {
tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index]; tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index];
phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0; phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
phba->ctrl.mcc_numtag[tag] = 0; phba->ctrl.mcc_numtag[tag] = 0;
} else {
udelay(100);
num++;
if (num < mcc_timeout)
goto mcc_tag_rdy;
} }
if (tag) { if (tag) {
phba->ctrl.mcc_tag_available--; phba->ctrl.mcc_tag_available--;
......
...@@ -482,7 +482,7 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, ...@@ -482,7 +482,7 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep); tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep);
if (!tag) { if (!tag) {
SE_DEBUG(DBG_LVL_1, 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); beiscsi_ep->ep_cid);
} else { } else {
wait_event_interruptible(phba->ctrl.mcc_wait[tag], wait_event_interruptible(phba->ctrl.mcc_wait[tag],
......
...@@ -58,6 +58,123 @@ static int beiscsi_slave_configure(struct scsi_device *sdev) ...@@ -58,6 +58,123 @@ static int beiscsi_slave_configure(struct scsi_device *sdev)
return 0; 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 ----------------- */ /*------------------- PCI Driver operations and data ----------------- */
static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = { static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
...@@ -74,12 +191,12 @@ static struct scsi_host_template beiscsi_sht = { ...@@ -74,12 +191,12 @@ static struct scsi_host_template beiscsi_sht = {
.name = "ServerEngines 10Gbe open-iscsi Initiator Driver", .name = "ServerEngines 10Gbe open-iscsi Initiator Driver",
.proc_name = DRV_NAME, .proc_name = DRV_NAME,
.queuecommand = iscsi_queuecommand, .queuecommand = iscsi_queuecommand,
.eh_abort_handler = iscsi_eh_abort,
.change_queue_depth = iscsi_change_queue_depth, .change_queue_depth = iscsi_change_queue_depth,
.slave_configure = beiscsi_slave_configure, .slave_configure = beiscsi_slave_configure,
.target_alloc = iscsi_target_alloc, .target_alloc = iscsi_target_alloc,
.eh_device_reset_handler = iscsi_eh_device_reset, .eh_abort_handler = beiscsi_eh_abort,
.eh_target_reset_handler = iscsi_eh_target_reset, .eh_device_reset_handler = beiscsi_eh_device_reset,
.eh_target_reset_handler = iscsi_eh_session_reset,
.sg_tablesize = BEISCSI_SGLIST_ELEMENTS, .sg_tablesize = BEISCSI_SGLIST_ELEMENTS,
.can_queue = BE2_IO_DEPTH, .can_queue = BE2_IO_DEPTH,
.this_id = -1, .this_id = -1,
...@@ -242,7 +359,7 @@ static void beiscsi_get_params(struct beiscsi_hba *phba) ...@@ -242,7 +359,7 @@ static void beiscsi_get_params(struct beiscsi_hba *phba)
+ BE2_TMFS + BE2_TMFS
+ BE2_NOPOUT_REQ)); + BE2_NOPOUT_REQ));
phba->params.cxns_per_ctrl = phba->fw_config.iscsi_cid_count; 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.icds_per_ctrl = phba->fw_config.iscsi_icd_count;;
phba->params.num_sge_per_io = BE2_SGE; phba->params.num_sge_per_io = BE2_SGE;
phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ; phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ;
...@@ -946,14 +1063,18 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn, ...@@ -946,14 +1063,18 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
case HWH_TYPE_IO: case HWH_TYPE_IO:
case HWH_TYPE_IO_RD: case HWH_TYPE_IO_RD:
if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == if ((task->hdr->opcode & ISCSI_OPCODE_MASK) ==
ISCSI_OP_NOOP_OUT) { ISCSI_OP_NOOP_OUT)
be_complete_nopin_resp(beiscsi_conn, task, psol); be_complete_nopin_resp(beiscsi_conn, task, psol);
} else else
be_complete_io(beiscsi_conn, task, psol); be_complete_io(beiscsi_conn, task, psol);
break; break;
case HWH_TYPE_LOGOUT: case HWH_TYPE_LOGOUT:
if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT)
be_complete_logout(beiscsi_conn, task, psol); be_complete_logout(beiscsi_conn, task, psol);
else
be_complete_tmf(beiscsi_conn, task, psol);
break; break;
case HWH_TYPE_LOGIN: case HWH_TYPE_LOGIN:
...@@ -962,10 +1083,6 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn, ...@@ -962,10 +1083,6 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
"- Solicited path \n"); "- Solicited path \n");
break; break;
case HWH_TYPE_TMF:
be_complete_tmf(beiscsi_conn, task, psol);
break;
case HWH_TYPE_NOP: case HWH_TYPE_NOP:
be_complete_nopin_resp(beiscsi_conn, task, psol); be_complete_nopin_resp(beiscsi_conn, task, psol);
break; break;
...@@ -2052,7 +2169,7 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba) ...@@ -2052,7 +2169,7 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) / num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) /
((sizeof(struct iscsi_wrb) * ((sizeof(struct iscsi_wrb) *
phba->params.wrbs_per_cxn)); 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]; pwrb_context = &phwi_ctrlr->wrb_context[index];
if (num_cxn_wrb) { if (num_cxn_wrb) {
for (j = 0; j < phba->params.wrbs_per_cxn; j++) { for (j = 0; j < phba->params.wrbs_per_cxn; j++) {
...@@ -3073,14 +3190,18 @@ static unsigned char hwi_enable_intr(struct beiscsi_hba *phba) ...@@ -3073,14 +3190,18 @@ static unsigned char hwi_enable_intr(struct beiscsi_hba *phba)
reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK; reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr); SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr);
iowrite32(reg, addr); iowrite32(reg, addr);
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++) { for (i = 0; i <= phba->num_cpus; i++) {
eq = &phwi_context->be_eq[i].q; eq = &phwi_context->be_eq[i].q;
SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id); SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1); 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; return true;
} }
...@@ -3476,19 +3597,13 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg, ...@@ -3476,19 +3597,13 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg,
static int beiscsi_mtask(struct iscsi_task *task) 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 iscsi_conn *conn = task->conn;
struct beiscsi_conn *beiscsi_conn = conn->dd_data; struct beiscsi_conn *beiscsi_conn = conn->dd_data;
struct beiscsi_hba *phba = beiscsi_conn->phba; struct beiscsi_hba *phba = beiscsi_conn->phba;
struct iscsi_session *session;
struct iscsi_wrb *pwrb = NULL; 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 doorbell = 0;
unsigned int i, cid; unsigned int cid;
struct iscsi_task *aborted_task;
unsigned int tag;
cid = beiscsi_conn->beiscsi_conn_cid; cid = beiscsi_conn->beiscsi_conn_cid;
pwrb = io_task->pwrb_handle->pwrb; pwrb = io_task->pwrb_handle->pwrb;
...@@ -3499,6 +3614,7 @@ static int beiscsi_mtask(struct iscsi_task *task) ...@@ -3499,6 +3614,7 @@ static int beiscsi_mtask(struct iscsi_task *task)
io_task->pwrb_handle->wrb_index); io_task->pwrb_handle->wrb_index);
AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb, AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb,
io_task->psgl_handle->sgl_index); io_task->psgl_handle->sgl_index);
switch (task->hdr->opcode & ISCSI_OPCODE_MASK) { switch (task->hdr->opcode & ISCSI_OPCODE_MASK) {
case ISCSI_OP_LOGIN: case ISCSI_OP_LOGIN:
AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
...@@ -3523,33 +3639,6 @@ static int beiscsi_mtask(struct iscsi_task *task) ...@@ -3523,33 +3639,6 @@ static int beiscsi_mtask(struct iscsi_task *task)
hwi_write_buffer(pwrb, task); hwi_write_buffer(pwrb, task);
break; break;
case ISCSI_OP_SCSI_TMFUNC: 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, AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
INI_TMF_CMD); INI_TMF_CMD);
AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
...@@ -3584,17 +3673,12 @@ static int beiscsi_mtask(struct iscsi_task *task) ...@@ -3584,17 +3673,12 @@ static int beiscsi_mtask(struct iscsi_task *task)
static int beiscsi_task_xmit(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 beiscsi_io_task *io_task = task->dd_data;
struct scsi_cmnd *sc = task->sc; struct scsi_cmnd *sc = task->sc;
struct beiscsi_conn *beiscsi_conn = conn->dd_data;
struct scatterlist *sg; struct scatterlist *sg;
int num_sg; int num_sg;
unsigned int writedir = 0, xferlen = 0; 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) if (!sc)
return beiscsi_mtask(task); return beiscsi_mtask(task);
...@@ -3699,7 +3783,6 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, ...@@ -3699,7 +3783,6 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
" Failed in beiscsi_hba_alloc \n"); " Failed in beiscsi_hba_alloc \n");
goto disable_pci; goto disable_pci;
} }
SE_DEBUG(DBG_LVL_8, " phba = %p \n", phba);
switch (pcidev->device) { switch (pcidev->device) {
case BE_DEVICE_ID1: case BE_DEVICE_ID1:
......
...@@ -257,6 +257,11 @@ struct hba_parameters { ...@@ -257,6 +257,11 @@ struct hba_parameters {
unsigned int num_sge; unsigned int num_sge;
}; };
struct invalidate_command_table {
unsigned short icd;
unsigned short cid;
} __packed;
struct beiscsi_hba { struct beiscsi_hba {
struct hba_parameters params; struct hba_parameters params;
struct hwi_controller *phwi_ctrlr; struct hwi_controller *phwi_ctrlr;
...@@ -329,6 +334,8 @@ struct beiscsi_hba { ...@@ -329,6 +334,8 @@ struct beiscsi_hba {
struct work_struct work_cqs; /* The work being queued */ struct work_struct work_cqs; /* The work being queued */
struct be_ctrl_info ctrl; struct be_ctrl_info ctrl;
unsigned int generation; unsigned int generation;
struct invalidate_command_table inv_tbl[128];
}; };
struct beiscsi_session { struct beiscsi_session {
...@@ -491,8 +498,6 @@ struct hwi_async_entry { ...@@ -491,8 +498,6 @@ struct hwi_async_entry {
struct list_head data_busy_list; struct list_head data_busy_list;
}; };
#define BE_MIN_ASYNC_ENTRIES 128
struct hwi_async_pdu_context { struct hwi_async_pdu_context {
struct { struct {
struct be_bus_address pa_base; struct be_bus_address pa_base;
...@@ -533,7 +538,7 @@ struct hwi_async_pdu_context { ...@@ -533,7 +538,7 @@ struct hwi_async_pdu_context {
* This is a varying size list! Do not add anything * This is a varying size list! Do not add anything
* after this entry!! * 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 #define PDUCQE_CODE_MASK 0x0000003F
......
...@@ -145,14 +145,15 @@ unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute) ...@@ -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 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_dma_mem nonemb_cmd;
struct be_ctrl_info *ctrl = &phba->ctrl; struct be_ctrl_info *ctrl = &phba->ctrl;
struct be_mcc_wrb *wrb; struct be_mcc_wrb *wrb;
struct be_sge *sge; struct be_sge *sge;
struct invalidate_commands_params_in *req; struct invalidate_commands_params_in *req;
unsigned int tag = 0; unsigned int i, tag = 0;
spin_lock(&ctrl->mbox_lock); spin_lock(&ctrl->mbox_lock);
tag = alloc_mcc_tag(phba); tag = alloc_mcc_tag(phba);
...@@ -183,9 +184,12 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, ...@@ -183,9 +184,12 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
sizeof(*req)); sizeof(*req));
req->ref_handle = 0; req->ref_handle = 0;
req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE; req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
req->icd_count = 0; for (i = 0; i < num_invalidate; i++) {
req->table[req->icd_count].icd = icd; req->table[i].icd = inv_tbl->icd;
req->table[req->icd_count].cid = cid; 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_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF); sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
sge->len = cpu_to_le32(nonemb_cmd.size); sge->len = cpu_to_le32(nonemb_cmd.size);
......
...@@ -94,7 +94,8 @@ unsigned char mgmt_upload_connection(struct beiscsi_hba *phba, ...@@ -94,7 +94,8 @@ unsigned char mgmt_upload_connection(struct beiscsi_hba *phba,
unsigned short cid, unsigned short cid,
unsigned int upload_flag); unsigned int upload_flag);
unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, 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 iscsi_invalidate_connection_params_in {
struct be_cmd_req_hdr hdr; struct be_cmd_req_hdr hdr;
...@@ -116,11 +117,6 @@ union iscsi_invalidate_connection_params { ...@@ -116,11 +117,6 @@ union iscsi_invalidate_connection_params {
struct iscsi_invalidate_connection_params_out response; struct iscsi_invalidate_connection_params_out response;
} __packed; } __packed;
struct invalidate_command_table {
unsigned short icd;
unsigned short cid;
} __packed;
struct invalidate_commands_params_in { struct invalidate_commands_params_in {
struct be_cmd_req_hdr hdr; struct be_cmd_req_hdr hdr;
unsigned int ref_handle; unsigned int ref_handle;
......
...@@ -2,8 +2,8 @@ obj-$(CONFIG_SCSI_BFA_FC) := bfa.o ...@@ -2,8 +2,8 @@ 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 := 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_core.o bfa_ioc.o bfa_ioc_ct.o bfa_ioc_cb.o bfa_iocfc.o bfa_fcxp.o
bfa-y += bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.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_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_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 += bfa_csdebug.o bfa_sm.o plog.o
...@@ -12,4 +12,4 @@ bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o ...@@ -12,4 +12,4 @@ 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 += 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 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
...@@ -384,6 +384,15 @@ bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen) ...@@ -384,6 +384,15 @@ bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen)
return bfa_ioc_debug_fwsave(&bfa->ioc, trcdata, trclen); return bfa_ioc_debug_fwsave(&bfa->ioc, trcdata, 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. * Fetch firmware trace data.
* *
...@@ -399,4 +408,14 @@ bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen) ...@@ -399,4 +408,14 @@ bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen)
{ {
return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, 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 #endif
This diff is collapsed.
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
* FCS sub-modules * FCS sub-modules
*/ */
struct bfa_fcs_mod_s { struct bfa_fcs_mod_s {
void (*attach) (struct bfa_fcs_s *fcs);
void (*modinit) (struct bfa_fcs_s *fcs); void (*modinit) (struct bfa_fcs_s *fcs);
void (*modexit) (struct bfa_fcs_s *fcs); void (*modexit) (struct bfa_fcs_s *fcs);
}; };
...@@ -43,12 +44,10 @@ struct bfa_fcs_mod_s { ...@@ -43,12 +44,10 @@ struct bfa_fcs_mod_s {
#define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit } #define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit }
static struct bfa_fcs_mod_s fcs_modules[] = { static struct bfa_fcs_mod_s fcs_modules[] = {
BFA_FCS_MODULE(bfa_fcs_pport), { bfa_fcs_pport_attach, NULL, NULL },
BFA_FCS_MODULE(bfa_fcs_uf), { bfa_fcs_uf_attach, NULL, NULL },
BFA_FCS_MODULE(bfa_fcs_fabric), { bfa_fcs_fabric_attach, bfa_fcs_fabric_modinit,
BFA_FCS_MODULE(bfa_fcs_vport), bfa_fcs_fabric_modexit },
BFA_FCS_MODULE(bfa_fcs_rport),
BFA_FCS_MODULE(bfa_fcs_fcpim),
}; };
/** /**
...@@ -71,16 +70,10 @@ bfa_fcs_exit_comp(void *fcs_cbarg) ...@@ -71,16 +70,10 @@ bfa_fcs_exit_comp(void *fcs_cbarg)
*/ */
/** /**
* FCS instance initialization. * fcs attach -- called once to initialize data structures at driver attach time
*
* param[in] fcs FCS instance
* param[in] bfa BFA instance
* param[in] bfad BFA driver instance
*
* return None
*/ */
void 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) bfa_boolean_t min_cfg)
{ {
int i; int i;
...@@ -95,6 +88,23 @@ bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad, ...@@ -95,6 +88,23 @@ 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++) { for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
mod = &fcs_modules[i]; mod = &fcs_modules[i];
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); mod->modinit(fcs);
} }
} }
...@@ -126,6 +136,23 @@ bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs, ...@@ -126,6 +136,23 @@ bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
bfa_fcs_fabric_psymb_init(&fcs->fabric); bfa_fcs_fabric_psymb_init(&fcs->fabric);
} }
/**
* @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. * FCS instance cleanup and exit.
* *
...@@ -143,11 +170,13 @@ bfa_fcs_exit(struct bfa_fcs_s *fcs) ...@@ -143,11 +170,13 @@ bfa_fcs_exit(struct bfa_fcs_s *fcs)
nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]); nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]);
for (i = 0; i < nmods; i++) { for (i = 0; i < nmods; i++) {
bfa_wc_up(&fcs->wc);
mod = &fcs_modules[i]; mod = &fcs_modules[i];
if (mod->modexit) {
bfa_wc_up(&fcs->wc);
mod->modexit(fcs); mod->modexit(fcs);
} }
}
bfa_wc_wait(&fcs->wc); bfa_wc_wait(&fcs->wc);
} }
......
...@@ -114,7 +114,7 @@ bfa_fcs_port_sm_uninit(struct bfa_fcs_port_s *port, ...@@ -114,7 +114,7 @@ bfa_fcs_port_sm_uninit(struct bfa_fcs_port_s *port,
break; break;
default: 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) ...@@ -136,7 +136,7 @@ bfa_fcs_port_sm_init(struct bfa_fcs_port_s *port, enum bfa_fcs_port_event event)
break; break;
default: 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, ...@@ -176,7 +176,7 @@ bfa_fcs_port_sm_online(struct bfa_fcs_port_s *port,
break; break;
default: 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, ...@@ -214,7 +214,7 @@ bfa_fcs_port_sm_offline(struct bfa_fcs_port_s *port,
break; break;
default: 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, ...@@ -234,7 +234,7 @@ bfa_fcs_port_sm_deleting(struct bfa_fcs_port_s *port,
break; break;
default: 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, ...@@ -263,30 +263,8 @@ bfa_fcs_port_aen_post(struct bfa_fcs_port_s *port,
bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX); bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX);
switch (event) { bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, event), lpwwn_ptr,
case BFA_LPORT_AEN_ONLINE: role_str[role/2]);
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;
}
aen_data.lport.vf_id = port->fabric->vf_id; aen_data.lport.vf_id = port->fabric->vf_id;
aen_data.lport.roles = role; aen_data.lport.roles = role;
...@@ -873,36 +851,46 @@ bfa_fcs_port_is_online(struct bfa_fcs_port_s *port) ...@@ -873,36 +851,46 @@ bfa_fcs_port_is_online(struct bfa_fcs_port_s *port)
} }
/** /**
* Logical port initialization of base or virtual port. * Attach time initialization of logical ports.
* Called by fabric for base port or by vport for virtual ports.
*/ */
void void
bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs, bfa_fcs_lport_attach(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
u16 vf_id, struct bfa_port_cfg_s *port_cfg, uint16_t vf_id, struct bfa_fcs_vport_s *vport)
struct bfa_fcs_vport_s *vport)
{ {
lport->fcs = fcs; lport->fcs = fcs;
lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id); lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id);
bfa_os_assign(lport->port_cfg, *port_cfg);
lport->vport = vport; lport->vport = vport;
lport->lp_tag = (vport) ? bfa_lps_get_tag(vport->lps) : lport->lp_tag = (vport) ? bfa_lps_get_tag(vport->lps) :
bfa_lps_get_tag(lport->fabric->lps); bfa_lps_get_tag(lport->fabric->lps);
INIT_LIST_HEAD(&lport->rport_q); INIT_LIST_HEAD(&lport->rport_q);
lport->num_rports = 0; 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 = void
bfa_fcb_port_new(fcs->bfad, lport, lport->port_cfg.roles, 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, lport->fabric->vf_drv,
vport ? vport->vport_drv : NULL); vport ? vport->vport_drv : NULL);
bfa_fcs_port_aen_post(lport, BFA_LPORT_AEN_NEW); bfa_fcs_port_aen_post(lport, BFA_LPORT_AEN_NEW);
bfa_sm_set_state(lport, bfa_fcs_port_sm_uninit); bfa_sm_set_state(lport, bfa_fcs_port_sm_uninit);
bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE); bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
} }
/** /**
* fcs_lport_api * fcs_lport_api
*/ */
...@@ -921,13 +909,20 @@ bfa_fcs_port_get_attr(struct bfa_fcs_port_s *port, ...@@ -921,13 +909,20 @@ bfa_fcs_port_get_attr(struct bfa_fcs_port_s *port,
if (port->fabric) { if (port->fabric) {
port_attr->port_type = bfa_fcs_fabric_port_type(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->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); port_attr->fabric_name = bfa_fcs_port_get_fabric_name(port);
memcpy(port_attr->fabric_ip_addr, memcpy(port_attr->fabric_ip_addr,
bfa_fcs_port_get_fabric_ipaddr(port), bfa_fcs_port_get_fabric_ipaddr(port),
BFA_FCS_FABRIC_IPADDR_SZ); BFA_FCS_FABRIC_IPADDR_SZ);
if (port->vport != NULL) if (port->vport != NULL) {
port_attr->port_type = BFA_PPORT_TYPE_VPORT; 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 { } else {
port_attr->port_type = BFA_PPORT_TYPE_UNKNOWN; port_attr->port_type = BFA_PPORT_TYPE_UNKNOWN;
......
...@@ -55,14 +55,7 @@ bfa_fcs_pport_event_handler(void *cbarg, bfa_pport_event_t event) ...@@ -55,14 +55,7 @@ bfa_fcs_pport_event_handler(void *cbarg, bfa_pport_event_t event)
} }
void 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, bfa_fcport_event_register(fcs->bfa, bfa_fcs_pport_event_handler, fcs);
fcs);
}
void
bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs)
{
bfa_fcs_modexit_comp(fcs);
} }
...@@ -93,13 +93,7 @@ bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf) ...@@ -93,13 +93,7 @@ bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf)
} }
void 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); 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);
}
...@@ -52,6 +52,18 @@ bfa_hwcb_reginit(struct bfa_s *bfa) ...@@ -52,6 +52,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 void
bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq) bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq)
{ {
...@@ -136,6 +148,7 @@ bfa_hwcb_msix_uninstall(struct bfa_s *bfa) ...@@ -136,6 +148,7 @@ bfa_hwcb_msix_uninstall(struct bfa_s *bfa)
void void
bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix) 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; bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix;
} }
......
...@@ -84,6 +84,15 @@ bfa_hwct_reginit(struct bfa_s *bfa) ...@@ -84,6 +84,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 void
bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq) bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq)
{ {
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* General Public License for more details. * General Public License for more details.
*/ */
#include <bfa.h> #include <bfa.h>
#include <bfi/bfi_cbreg.h> #include <bfi/bfi_ctreg.h>
#include <bfa_port_priv.h> #include <bfa_port_priv.h>
#include <bfa_intr_priv.h> #include <bfa_intr_priv.h>
#include <cs/bfa_debug.h> #include <cs/bfa_debug.h>
...@@ -34,6 +34,26 @@ bfa_msix_lpu(struct bfa_s *bfa) ...@@ -34,6 +34,26 @@ bfa_msix_lpu(struct bfa_s *bfa)
bfa_ioc_mbox_isr(&bfa->ioc); 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 void
bfa_msix_all(struct bfa_s *bfa, int vec) bfa_msix_all(struct bfa_s *bfa, int vec)
{ {
...@@ -96,7 +116,8 @@ bfa_isr_enable(struct bfa_s *bfa) ...@@ -96,7 +116,8 @@ bfa_isr_enable(struct bfa_s *bfa)
bfa_msix_install(bfa); bfa_msix_install(bfa);
intr_unmask = (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 | 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) if (pci_func == 0)
intr_unmask |= (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 | intr_unmask |= (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 |
...@@ -127,23 +148,18 @@ bfa_isr_disable(struct bfa_s *bfa) ...@@ -127,23 +148,18 @@ bfa_isr_disable(struct bfa_s *bfa)
void void
bfa_msix_reqq(struct bfa_s *bfa, int qid) bfa_msix_reqq(struct bfa_s *bfa, int qid)
{ {
struct list_head *waitq, *qe, *qen; struct list_head *waitq;
struct bfa_reqq_wait_s *wqe;
qid &= (BFI_IOC_MAX_CQS - 1); qid &= (BFI_IOC_MAX_CQS - 1);
waitq = bfa_reqq(bfa, qid); bfa->iocfc.hwif.hw_reqq_ack(bfa, qid);
list_for_each_safe(qe, qen, waitq) {
/** /**
* Callback only as long as there is room in request queue * Resume any pending requests in the corresponding reqq.
*/ */
if (bfa_reqq_full(bfa, qid)) waitq = bfa_reqq(bfa, qid);
break; if (!list_empty(waitq))
bfa_reqq_resume(bfa, qid);
list_del(qe);
wqe = (struct bfa_reqq_wait_s *) qe;
wqe->qresume(wqe->cbarg);
}
} }
void void
...@@ -157,26 +173,27 @@ bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m) ...@@ -157,26 +173,27 @@ bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m)
} }
void 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; struct bfi_msg_s *m;
u32 pi, ci; 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); ci = bfa_rspq_ci(bfa, qid);
pi = bfa_rspq_pi(bfa, rsp_qid); pi = bfa_rspq_pi(bfa, qid);
bfa_trc_fp(bfa, ci); bfa_trc_fp(bfa, ci);
bfa_trc_fp(bfa, pi); bfa_trc_fp(bfa, pi);
if (bfa->rme_process) { if (bfa->rme_process) {
while (ci != pi) { 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_assert_fp(m->mhdr.msg_class < BFI_MC_MAX);
bfa_isrs[m->mhdr.msg_class] (bfa, m); bfa_isrs[m->mhdr.msg_class] (bfa, m);
...@@ -188,25 +205,59 @@ bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid) ...@@ -188,25 +205,59 @@ bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid)
/** /**
* update CI * update CI
*/ */
bfa_rspq_ci(bfa, rsp_qid) = pi; bfa_rspq_ci(bfa, qid) = pi;
bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[rsp_qid], pi); bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[qid], pi);
bfa_os_mmiowb(); 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 void
bfa_msix_lpu_err(struct bfa_s *bfa, int vec) 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); intr = bfa_reg_read(bfa->iocfc.bfa_regs.intr_status);
if (intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1)) if (intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1))
bfa_msix_lpu(bfa); bfa_msix_lpu(bfa);
if (intr & (__HFN_INT_ERR_EMC | intr &= (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
__HFN_INT_ERR_LPU0 | __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS | __HFN_INT_LL_HALT);
__HFN_INT_ERR_PSS))
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); bfa_msix_errint(bfa, intr);
}
} }
void void
......
This diff is collapsed.
...@@ -74,15 +74,18 @@ struct bfa_ioc_regs_s { ...@@ -74,15 +74,18 @@ struct bfa_ioc_regs_s {
bfa_os_addr_t lpu_mbox_cmd; bfa_os_addr_t lpu_mbox_cmd;
bfa_os_addr_t lpu_mbox; bfa_os_addr_t lpu_mbox;
bfa_os_addr_t pss_ctl_reg; 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_fast_ctl_reg;
bfa_os_addr_t app_pll_slow_ctl_reg; bfa_os_addr_t app_pll_slow_ctl_reg;
bfa_os_addr_t ioc_sem_reg; bfa_os_addr_t ioc_sem_reg;
bfa_os_addr_t ioc_usage_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 ioc_usage_reg;
bfa_os_addr_t host_page_num_fn; bfa_os_addr_t host_page_num_fn;
bfa_os_addr_t heartbeat; bfa_os_addr_t heartbeat;
bfa_os_addr_t ioc_fwstate; bfa_os_addr_t ioc_fwstate;
bfa_os_addr_t ll_halt; bfa_os_addr_t ll_halt;
bfa_os_addr_t err_set;
bfa_os_addr_t shirq_isr_next; bfa_os_addr_t shirq_isr_next;
bfa_os_addr_t shirq_msk_next; bfa_os_addr_t shirq_msk_next;
bfa_os_addr_t smem_page_start; bfa_os_addr_t smem_page_start;
...@@ -154,7 +157,6 @@ struct bfa_ioc_s { ...@@ -154,7 +157,6 @@ struct bfa_ioc_s {
struct bfa_timer_s ioc_timer; struct bfa_timer_s ioc_timer;
struct bfa_timer_s sem_timer; struct bfa_timer_s sem_timer;
u32 hb_count; u32 hb_count;
u32 hb_fail;
u32 retry_count; u32 retry_count;
struct list_head hb_notify_q; struct list_head hb_notify_q;
void *dbg_fwsave; void *dbg_fwsave;
...@@ -177,6 +179,22 @@ struct bfa_ioc_s { ...@@ -177,6 +179,22 @@ struct bfa_ioc_s {
struct bfi_ioc_attr_s *attr; struct bfi_ioc_attr_s *attr;
struct bfa_ioc_cbfn_s *cbfn; struct bfa_ioc_cbfn_s *cbfn;
struct bfa_ioc_mbox_mod_s mbox_mod; 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) #define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func)
...@@ -191,6 +209,15 @@ struct bfa_ioc_s { ...@@ -191,6 +209,15 @@ struct bfa_ioc_s {
#define bfa_ioc_rx_bbcredit(__ioc) ((__ioc)->attr->rx_bbcredit) #define bfa_ioc_rx_bbcredit(__ioc) ((__ioc)->attr->rx_bbcredit)
#define bfa_ioc_speed_sup(__ioc) \ #define bfa_ioc_speed_sup(__ioc) \
BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop) 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 * IOC mailbox interface
...@@ -207,6 +234,14 @@ void bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc, ...@@ -207,6 +234,14 @@ void bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc,
/** /**
* IOC interfaces * 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, 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_ioc_cbfn_s *cbfn, struct bfa_timer_mod_s *timer_mod,
struct bfa_trc_mod_s *trcmod, struct bfa_trc_mod_s *trcmod,
...@@ -223,13 +258,21 @@ bfa_boolean_t bfa_ioc_intx_claim(struct bfa_ioc_s *ioc); ...@@ -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_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_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *msg);
void bfa_ioc_error_isr(struct bfa_ioc_s *ioc); 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_operational(struct bfa_ioc_s *ioc);
bfa_boolean_t bfa_ioc_is_disabled(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_fw_mismatch(struct bfa_ioc_s *ioc);
bfa_boolean_t bfa_ioc_adapter_is_disabled(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); 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_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr);
void bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, void bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
struct bfa_adapter_attr_s *ad_attr); struct bfa_adapter_attr_s *ad_attr);
...@@ -237,6 +280,7 @@ int bfa_ioc_debug_trcsz(bfa_boolean_t auto_recover); ...@@ -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); 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, bfa_status_t bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata,
int *trclen); 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, bfa_status_t bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata,
int *trclen); int *trclen);
u32 bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr); 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); ...@@ -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); bfa_boolean_t bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc);
void bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc, void bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc,
struct bfa_ioc_hbfail_notify_s *notify); 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 * bfa mfg wwn API functions
......
/*
* 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);
}
This diff is collapsed.
...@@ -172,6 +172,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, ...@@ -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) { if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) {
iocfc->hwif.hw_reginit = bfa_hwct_reginit; 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_rspq_ack = bfa_hwct_rspq_ack;
iocfc->hwif.hw_msix_init = bfa_hwct_msix_init; iocfc->hwif.hw_msix_init = bfa_hwct_msix_init;
iocfc->hwif.hw_msix_install = bfa_hwct_msix_install; 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, ...@@ -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; iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs;
} else { } else {
iocfc->hwif.hw_reginit = bfa_hwcb_reginit; 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_rspq_ack = bfa_hwcb_rspq_ack;
iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init; iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init;
iocfc->hwif.hw_msix_install = bfa_hwcb_msix_install; iocfc->hwif.hw_msix_install = bfa_hwcb_msix_install;
...@@ -336,8 +338,10 @@ bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete) ...@@ -336,8 +338,10 @@ bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete)
bfa_cb_init(bfa->bfad, BFA_STATUS_OK); bfa_cb_init(bfa->bfad, BFA_STATUS_OK);
else else
bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED); bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED);
} else } else {
if (bfa->iocfc.cfgdone)
bfa->iocfc.action = BFA_IOCFC_ACT_NONE; bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
}
} }
static void static void
...@@ -619,8 +623,6 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, ...@@ -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_ioc_attach(&bfa->ioc, bfa, &bfa_iocfc_cbfn, &bfa->timer_mod,
bfa->trcmod, bfa->aen, bfa->logm); 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. * 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, ...@@ -628,6 +630,9 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
if (0) if (0)
bfa_ioc_set_fcmode(&bfa->ioc); 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_init_mem(bfa, bfad, cfg, pcidev);
bfa_iocfc_mem_claim(bfa, cfg, meminfo); bfa_iocfc_mem_claim(bfa, cfg, meminfo);
bfa_timer_init(&bfa->timer_mod); bfa_timer_init(&bfa->timer_mod);
...@@ -654,7 +659,6 @@ bfa_iocfc_init(struct bfa_s *bfa) ...@@ -654,7 +659,6 @@ bfa_iocfc_init(struct bfa_s *bfa)
{ {
bfa->iocfc.action = BFA_IOCFC_ACT_INIT; bfa->iocfc.action = BFA_IOCFC_ACT_INIT;
bfa_ioc_enable(&bfa->ioc); 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, ...@@ -797,6 +801,11 @@ bfa_iocfc_get_stats(struct bfa_s *bfa, struct bfa_iocfc_stats_s *stats,
return BFA_STATUS_DEVBUSY; 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_busy = BFA_TRUE;
iocfc->stats_ret = stats; iocfc->stats_ret = stats;
iocfc->stats_cbfn = cbfn; iocfc->stats_cbfn = cbfn;
...@@ -817,6 +826,11 @@ bfa_iocfc_clear_stats(struct bfa_s *bfa, bfa_cb_ioc_t cbfn, void *cbarg) ...@@ -817,6 +826,11 @@ bfa_iocfc_clear_stats(struct bfa_s *bfa, bfa_cb_ioc_t cbfn, void *cbarg)
return BFA_STATUS_DEVBUSY; 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_busy = BFA_TRUE;
iocfc->stats_cbfn = cbfn; iocfc->stats_cbfn = cbfn;
iocfc->stats_cbarg = cbarg; iocfc->stats_cbarg = cbarg;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment