提交 961cde93 编写于 作者: L 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.
  ...
......@@ -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",
......
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
......
......@@ -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--;
......
......@@ -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]);
......
......@@ -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:
......
......@@ -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
......
......@@ -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);
......
......@@ -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;
......
......@@ -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
......@@ -384,6 +384,15 @@ bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *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.
*
......@@ -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
此差异已折叠。
......@@ -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);
}
}
......@@ -126,6 +136,23 @@ bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
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.
*
......@@ -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);
......
......@@ -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;
......
......@@ -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);
}
......@@ -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);
}
......@@ -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
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;
}
......
......@@ -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
bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq)
{
......
......@@ -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
......
此差异已折叠。
......@@ -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
......
/*
* 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);
}
此差异已折叠。
此差异已折叠。
......@@ -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);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -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 */
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -19,6 +19,7 @@
#define __BFA_DEFS_ETHPORT_H__
#include <defs/bfa_defs_status.h>
#include <defs/bfa_defs_port.h>
#include <protocol/types.h>
#include <cna/pstats/phyport_defs.h>
#include <cna/pstats/ethport_defs.h>
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册