提交 7725ccfd 编写于 作者: J Jing Huang 提交者: James Bottomley

[SCSI] bfa: Brocade BFA FC SCSI driver

Add new driver for Brocade Hardware
Signed-off-by: NJing Huang <huangj@brocade.com>
Signed-off-by: NJames Bottomley <James.Bottomley@suse.de>
上级 5415907a
......@@ -1211,6 +1211,13 @@ L: netdev@vger.kernel.org
S: Supported
F: drivers/net/tg3.*
BROCADE BFA FC SCSI DRIVER
P: Jing Huang
M: huangj@brocade.com
L: linux-scsi@vger.kernel.org
S: Supported
F: drivers/scsi/bfa/
BSG (block layer generic sg v4 driver)
M: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
L: linux-scsi@vger.kernel.org
......
......@@ -1827,6 +1827,16 @@ config SCSI_SRP
To compile this driver as a module, choose M here: the
module will be called libsrp.
config SCSI_BFA_FC
tristate "Brocade BFA Fibre Channel Support"
depends on PCI && SCSI
select SCSI_FC_ATTRS
help
This bfa driver supports all Brocade PCIe FC/FCOE host adapters.
To compile this driver as a module, choose M here. The module will
be called bfa.
endif # SCSI_LOWLEVEL
source "drivers/scsi/pcmcia/Kconfig"
......
......@@ -86,6 +86,7 @@ obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o
obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx/
obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx/
obj-$(CONFIG_SCSI_LPFC) += lpfc/
obj-$(CONFIG_SCSI_BFA_FC) += bfa/
obj-$(CONFIG_SCSI_PAS16) += pas16.o
obj-$(CONFIG_SCSI_T128) += t128.o
obj-$(CONFIG_SCSI_DMX3191D) += dmx3191d.o
......
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_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 += 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
/*
* 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.
*/
#ifndef __BFA_CALLBACK_PRIV_H__
#define __BFA_CALLBACK_PRIV_H__
#include <cs/bfa_q.h>
typedef void (*bfa_cb_cbfn_t) (void *cbarg, bfa_boolean_t complete);
/**
* Generic BFA callback element.
*/
struct bfa_cb_qe_s {
struct list_head qe;
bfa_cb_cbfn_t cbfn;
bfa_boolean_t once;
u32 rsvd;
void *cbarg;
};
#define bfa_cb_queue(__bfa, __hcb_qe, __cbfn, __cbarg) do { \
(__hcb_qe)->cbfn = (__cbfn); \
(__hcb_qe)->cbarg = (__cbarg); \
list_add_tail(&(__hcb_qe)->qe, &(__bfa)->comp_q); \
} while (0)
#define bfa_cb_dequeue(__hcb_qe) list_del(&(__hcb_qe)->qe)
#define bfa_cb_queue_once(__bfa, __hcb_qe, __cbfn, __cbarg) do { \
(__hcb_qe)->cbfn = (__cbfn); \
(__hcb_qe)->cbarg = (__cbarg); \
if (!(__hcb_qe)->once) { \
list_add_tail((__hcb_qe), &(__bfa)->comp_q); \
(__hcb_qe)->once = BFA_TRUE; \
} \
} while (0)
#define bfa_cb_queue_done(__hcb_qe) do { \
(__hcb_qe)->once = BFA_FALSE; \
} while (0)
#endif /* __BFA_CALLBACK_PRIV_H__ */
/*
* 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.
*/
/**
* bfa_cb_ioim_macros.h BFA IOIM driver interface macros.
*/
#ifndef __BFA_HCB_IOIM_MACROS_H__
#define __BFA_HCB_IOIM_MACROS_H__
#include <bfa_os_inc.h>
/*
* #include <linux/dma-mapping.h>
*
* #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> #include
* <scsi/scsi_device.h> #include <scsi/scsi_host.h>
*/
#include "bfad_im_compat.h"
/*
* task attribute values in FCP-2 FCP_CMND IU
*/
#define SIMPLE_Q 0
#define HEAD_OF_Q 1
#define ORDERED_Q 2
#define ACA_Q 4
#define UNTAGGED 5
static inline lun_t
bfad_int_to_lun(u32 luno)
{
union {
u16 scsi_lun[4];
lun_t bfa_lun;
} lun;
lun.bfa_lun = 0;
lun.scsi_lun[0] = bfa_os_htons(luno);
return (lun.bfa_lun);
}
/**
* Get LUN for the I/O request
*/
#define bfa_cb_ioim_get_lun(__dio) \
bfad_int_to_lun(((struct scsi_cmnd *)__dio)->device->lun)
/**
* Get CDB for the I/O request
*/
static inline u8 *
bfa_cb_ioim_get_cdb(struct bfad_ioim_s *dio)
{
struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
return ((u8 *) cmnd->cmnd);
}
/**
* Get I/O direction (read/write) for the I/O request
*/
static inline enum fcp_iodir
bfa_cb_ioim_get_iodir(struct bfad_ioim_s *dio)
{
struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
enum dma_data_direction dmadir;
dmadir = cmnd->sc_data_direction;
if (dmadir == DMA_TO_DEVICE)
return FCP_IODIR_WRITE;
else if (dmadir == DMA_FROM_DEVICE)
return FCP_IODIR_READ;
else
return FCP_IODIR_NONE;
}
/**
* Get IO size in bytes for the I/O request
*/
static inline u32
bfa_cb_ioim_get_size(struct bfad_ioim_s *dio)
{
struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
return (scsi_bufflen(cmnd));
}
/**
* Get timeout for the I/O request
*/
static inline u8
bfa_cb_ioim_get_timeout(struct bfad_ioim_s *dio)
{
struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
/*
* TBD: need a timeout for scsi passthru
*/
if (cmnd->device->host == NULL)
return 4;
return 0;
}
/**
* Get SG element for the I/O request given the SG element index
*/
static inline union bfi_addr_u
bfa_cb_ioim_get_sgaddr(struct bfad_ioim_s *dio, int sgeid)
{
struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
struct scatterlist *sge;
u64 addr;
sge = (struct scatterlist *)scsi_sglist(cmnd) + sgeid;
addr = (u64) sg_dma_address(sge);
return (*(union bfi_addr_u *) &addr);
}
static inline u32
bfa_cb_ioim_get_sglen(struct bfad_ioim_s *dio, int sgeid)
{
struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
struct scatterlist *sge;
u32 len;
sge = (struct scatterlist *)scsi_sglist(cmnd) + sgeid;
len = sg_dma_len(sge);
return len;
}
/**
* Get Command Reference Number for the I/O request. 0 if none.
*/
static inline u8
bfa_cb_ioim_get_crn(struct bfad_ioim_s *dio)
{
return 0;
}
/**
* Get SAM-3 priority for the I/O request. 0 is default.
*/
static inline u8
bfa_cb_ioim_get_priority(struct bfad_ioim_s *dio)
{
return 0;
}
/**
* Get task attributes for the I/O request. Default is FCP_TASK_ATTR_SIMPLE(0).
*/
static inline u8
bfa_cb_ioim_get_taskattr(struct bfad_ioim_s *dio)
{
struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
u8 task_attr = UNTAGGED;
if (cmnd->device->tagged_supported) {
switch (cmnd->tag) {
case HEAD_OF_QUEUE_TAG:
task_attr = HEAD_OF_Q;
break;
case ORDERED_QUEUE_TAG:
task_attr = ORDERED_Q;
break;
default:
task_attr = SIMPLE_Q;
break;
}
}
return task_attr;
}
/**
* Get CDB length in bytes for the I/O request. Default is FCP_CMND_CDB_LEN(16).
*/
static inline u8
bfa_cb_ioim_get_cdblen(struct bfad_ioim_s *dio)
{
struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
return (cmnd->cmd_len);
}
#endif /* __BFA_HCB_IOIM_MACROS_H__ */
/*
* 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 <defs/bfa_defs_cee.h>
#include <cs/bfa_trc.h>
#include <cs/bfa_log.h>
#include <cs/bfa_debug.h>
#include <cee/bfa_cee.h>
#include <bfi/bfi_cee.h>
#include <bfi/bfi.h>
#include <bfa_ioc.h>
#include <cna/bfa_cna_trcmod.h>
BFA_TRC_FILE(CNA, CEE);
#define bfa_ioc_portid(__ioc) ((__ioc)->port_id)
#define bfa_lpuid(__arg) bfa_ioc_portid(&(__arg)->ioc)
static void bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg_s *lldp_cfg);
static void bfa_cee_format_dcbcx_stats(struct bfa_cee_dcbx_stats_s
*dcbcx_stats);
static void bfa_cee_format_lldp_stats(struct bfa_cee_lldp_stats_s
*lldp_stats);
static void bfa_cee_format_cfg_stats(struct bfa_cee_cfg_stats_s *cfg_stats);
static void bfa_cee_format_cee_cfg(void *buffer);
static void bfa_cee_format_cee_stats(void *buffer);
static void
bfa_cee_format_cee_stats(void *buffer)
{
struct bfa_cee_stats_s *cee_stats = buffer;
bfa_cee_format_dcbcx_stats(&cee_stats->dcbx_stats);
bfa_cee_format_lldp_stats(&cee_stats->lldp_stats);
bfa_cee_format_cfg_stats(&cee_stats->cfg_stats);
}
static void
bfa_cee_format_cee_cfg(void *buffer)
{
struct bfa_cee_attr_s *cee_cfg = buffer;
bfa_cee_format_lldp_cfg(&cee_cfg->lldp_remote);
}
static void
bfa_cee_format_dcbcx_stats(struct bfa_cee_dcbx_stats_s *dcbcx_stats)
{
dcbcx_stats->subtlvs_unrecognized =
bfa_os_ntohl(dcbcx_stats->subtlvs_unrecognized);
dcbcx_stats->negotiation_failed =
bfa_os_ntohl(dcbcx_stats->negotiation_failed);
dcbcx_stats->remote_cfg_changed =
bfa_os_ntohl(dcbcx_stats->remote_cfg_changed);
dcbcx_stats->tlvs_received = bfa_os_ntohl(dcbcx_stats->tlvs_received);
dcbcx_stats->tlvs_invalid = bfa_os_ntohl(dcbcx_stats->tlvs_invalid);
dcbcx_stats->seqno = bfa_os_ntohl(dcbcx_stats->seqno);
dcbcx_stats->ackno = bfa_os_ntohl(dcbcx_stats->ackno);
dcbcx_stats->recvd_seqno = bfa_os_ntohl(dcbcx_stats->recvd_seqno);
dcbcx_stats->recvd_ackno = bfa_os_ntohl(dcbcx_stats->recvd_ackno);
}
static void
bfa_cee_format_lldp_stats(struct bfa_cee_lldp_stats_s *lldp_stats)
{
lldp_stats->frames_transmitted =
bfa_os_ntohl(lldp_stats->frames_transmitted);
lldp_stats->frames_aged_out = bfa_os_ntohl(lldp_stats->frames_aged_out);
lldp_stats->frames_discarded =
bfa_os_ntohl(lldp_stats->frames_discarded);
lldp_stats->frames_in_error = bfa_os_ntohl(lldp_stats->frames_in_error);
lldp_stats->frames_rcvd = bfa_os_ntohl(lldp_stats->frames_rcvd);
lldp_stats->tlvs_discarded = bfa_os_ntohl(lldp_stats->tlvs_discarded);
lldp_stats->tlvs_unrecognized =
bfa_os_ntohl(lldp_stats->tlvs_unrecognized);
}
static void
bfa_cee_format_cfg_stats(struct bfa_cee_cfg_stats_s *cfg_stats)
{
cfg_stats->cee_status_down = bfa_os_ntohl(cfg_stats->cee_status_down);
cfg_stats->cee_status_up = bfa_os_ntohl(cfg_stats->cee_status_up);
cfg_stats->cee_hw_cfg_changed =
bfa_os_ntohl(cfg_stats->cee_hw_cfg_changed);
cfg_stats->recvd_invalid_cfg =
bfa_os_ntohl(cfg_stats->recvd_invalid_cfg);
}
static void
bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg_s *lldp_cfg)
{
lldp_cfg->time_to_interval = bfa_os_ntohs(lldp_cfg->time_to_interval);
lldp_cfg->enabled_system_cap =
bfa_os_ntohs(lldp_cfg->enabled_system_cap);
}
/**
* bfa_cee_attr_meminfo()
*
*
* @param[in] void
*
* @return Size of DMA region
*/
static u32
bfa_cee_attr_meminfo(void)
{
return BFA_ROUNDUP(sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ);
}
/**
* bfa_cee_stats_meminfo()
*
*
* @param[in] void
*
* @return Size of DMA region
*/
static u32
bfa_cee_stats_meminfo(void)
{
return BFA_ROUNDUP(sizeof(struct bfa_cee_stats_s), BFA_DMA_ALIGN_SZ);
}
/**
* bfa_cee_get_attr_isr()
*
*
* @param[in] cee - Pointer to the CEE module
* status - Return status from the f/w
*
* @return void
*/
static void
bfa_cee_get_attr_isr(struct bfa_cee_s *cee, bfa_status_t status)
{
cee->get_attr_status = status;
bfa_trc(cee, 0);
if (status == BFA_STATUS_OK) {
bfa_trc(cee, 0);
/*
* The requested data has been copied to the DMA area, *process
* it.
*/
memcpy(cee->attr, cee->attr_dma.kva,
sizeof(struct bfa_cee_attr_s));
bfa_cee_format_cee_cfg(cee->attr);
}
cee->get_attr_pending = BFA_FALSE;
if (cee->cbfn.get_attr_cbfn) {
bfa_trc(cee, 0);
cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, status);
}
bfa_trc(cee, 0);
}
/**
* bfa_cee_get_attr_isr()
*
*
* @param[in] cee - Pointer to the CEE module
* status - Return status from the f/w
*
* @return void
*/
static void
bfa_cee_get_stats_isr(struct bfa_cee_s *cee, bfa_status_t status)
{
cee->get_stats_status = status;
bfa_trc(cee, 0);
if (status == BFA_STATUS_OK) {
bfa_trc(cee, 0);
/*
* The requested data has been copied to the DMA area, process
* it.
*/
memcpy(cee->stats, cee->stats_dma.kva,
sizeof(struct bfa_cee_stats_s));
bfa_cee_format_cee_stats(cee->stats);
}
cee->get_stats_pending = BFA_FALSE;
bfa_trc(cee, 0);
if (cee->cbfn.get_stats_cbfn) {
bfa_trc(cee, 0);
cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, status);
}
bfa_trc(cee, 0);
}
/**
* bfa_cee_get_attr_isr()
*
*
* @param[in] cee - Pointer to the CEE module
* status - Return status from the f/w
*
* @return void
*/
static void
bfa_cee_reset_stats_isr(struct bfa_cee_s *cee, bfa_status_t status)
{
cee->reset_stats_status = status;
cee->reset_stats_pending = BFA_FALSE;
if (cee->cbfn.reset_stats_cbfn)
cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, status);
}
/**
* bfa_cee_meminfo()
*
*
* @param[in] void
*
* @return Size of DMA region
*/
u32
bfa_cee_meminfo(void)
{
return (bfa_cee_attr_meminfo() + bfa_cee_stats_meminfo());
}
/**
* bfa_cee_mem_claim()
*
*
* @param[in] cee CEE module pointer
* dma_kva Kernel Virtual Address of CEE DMA Memory
* dma_pa Physical Address of CEE DMA Memory
*
* @return void
*/
void
bfa_cee_mem_claim(struct bfa_cee_s *cee, u8 *dma_kva, u64 dma_pa)
{
cee->attr_dma.kva = dma_kva;
cee->attr_dma.pa = dma_pa;
cee->stats_dma.kva = dma_kva + bfa_cee_attr_meminfo();
cee->stats_dma.pa = dma_pa + bfa_cee_attr_meminfo();
cee->attr = (struct bfa_cee_attr_s *)dma_kva;
cee->stats =
(struct bfa_cee_stats_s *)(dma_kva + bfa_cee_attr_meminfo());
}
/**
* bfa_cee_get_attr()
*
* Send the request to the f/w to fetch CEE attributes.
*
* @param[in] Pointer to the CEE module data structure.
*
* @return Status
*/
bfa_status_t
bfa_cee_get_attr(struct bfa_cee_s *cee, struct bfa_cee_attr_s *attr,
bfa_cee_get_attr_cbfn_t cbfn, void *cbarg)
{
struct bfi_cee_get_req_s *cmd;
bfa_assert((cee != NULL) && (cee->ioc != NULL));
bfa_trc(cee, 0);
if (!bfa_ioc_is_operational(cee->ioc)) {
bfa_trc(cee, 0);
return BFA_STATUS_IOC_FAILURE;
}
if (cee->get_attr_pending == BFA_TRUE) {
bfa_trc(cee, 0);
return BFA_STATUS_DEVBUSY;
}
cee->get_attr_pending = BFA_TRUE;
cmd = (struct bfi_cee_get_req_s *)cee->get_cfg_mb.msg;
cee->attr = attr;
cee->cbfn.get_attr_cbfn = cbfn;
cee->cbfn.get_attr_cbarg = cbarg;
bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_CFG_REQ,
bfa_ioc_portid(cee->ioc));
bfa_dma_be_addr_set(cmd->dma_addr, cee->attr_dma.pa);
bfa_ioc_mbox_queue(cee->ioc, &cee->get_cfg_mb);
bfa_trc(cee, 0);
return BFA_STATUS_OK;
}
/**
* bfa_cee_get_stats()
*
* Send the request to the f/w to fetch CEE statistics.
*
* @param[in] Pointer to the CEE module data structure.
*
* @return Status
*/
bfa_status_t
bfa_cee_get_stats(struct bfa_cee_s *cee, struct bfa_cee_stats_s *stats,
bfa_cee_get_stats_cbfn_t cbfn, void *cbarg)
{
struct bfi_cee_get_req_s *cmd;
bfa_assert((cee != NULL) && (cee->ioc != NULL));
if (!bfa_ioc_is_operational(cee->ioc)) {
bfa_trc(cee, 0);
return BFA_STATUS_IOC_FAILURE;
}
if (cee->get_stats_pending == BFA_TRUE) {
bfa_trc(cee, 0);
return BFA_STATUS_DEVBUSY;
}
cee->get_stats_pending = BFA_TRUE;
cmd = (struct bfi_cee_get_req_s *)cee->get_stats_mb.msg;
cee->stats = stats;
cee->cbfn.get_stats_cbfn = cbfn;
cee->cbfn.get_stats_cbarg = cbarg;
bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_STATS_REQ,
bfa_ioc_portid(cee->ioc));
bfa_dma_be_addr_set(cmd->dma_addr, cee->stats_dma.pa);
bfa_ioc_mbox_queue(cee->ioc, &cee->get_stats_mb);
bfa_trc(cee, 0);
return BFA_STATUS_OK;
}
/**
* bfa_cee_reset_stats()
*
*
* @param[in] Pointer to the CEE module data structure.
*
* @return Status
*/
bfa_status_t
bfa_cee_reset_stats(struct bfa_cee_s *cee, bfa_cee_reset_stats_cbfn_t cbfn,
void *cbarg)
{
struct bfi_cee_reset_stats_s *cmd;
bfa_assert((cee != NULL) && (cee->ioc != NULL));
if (!bfa_ioc_is_operational(cee->ioc)) {
bfa_trc(cee, 0);
return BFA_STATUS_IOC_FAILURE;
}
if (cee->reset_stats_pending == BFA_TRUE) {
bfa_trc(cee, 0);
return BFA_STATUS_DEVBUSY;
}
cee->reset_stats_pending = BFA_TRUE;
cmd = (struct bfi_cee_reset_stats_s *)cee->reset_stats_mb.msg;
cee->cbfn.reset_stats_cbfn = cbfn;
cee->cbfn.reset_stats_cbarg = cbarg;
bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_RESET_STATS,
bfa_ioc_portid(cee->ioc));
bfa_ioc_mbox_queue(cee->ioc, &cee->reset_stats_mb);
bfa_trc(cee, 0);
return BFA_STATUS_OK;
}
/**
* bfa_cee_isrs()
*
*
* @param[in] Pointer to the CEE module data structure.
*
* @return void
*/
void
bfa_cee_isr(void *cbarg, struct bfi_mbmsg_s *m)
{
union bfi_cee_i2h_msg_u *msg;
struct bfi_cee_get_rsp_s *get_rsp;
struct bfa_cee_s *cee = (struct bfa_cee_s *)cbarg;
msg = (union bfi_cee_i2h_msg_u *)m;
get_rsp = (struct bfi_cee_get_rsp_s *)m;
bfa_trc(cee, msg->mh.msg_id);
switch (msg->mh.msg_id) {
case BFI_CEE_I2H_GET_CFG_RSP:
bfa_trc(cee, get_rsp->cmd_status);
bfa_cee_get_attr_isr(cee, get_rsp->cmd_status);
break;
case BFI_CEE_I2H_GET_STATS_RSP:
bfa_cee_get_stats_isr(cee, get_rsp->cmd_status);
break;
case BFI_CEE_I2H_RESET_STATS_RSP:
bfa_cee_reset_stats_isr(cee, get_rsp->cmd_status);
break;
default:
bfa_assert(0);
}
}
/**
* bfa_cee_hbfail()
*
*
* @param[in] Pointer to the CEE module data structure.
*
* @return void
*/
void
bfa_cee_hbfail(void *arg)
{
struct bfa_cee_s *cee;
cee = (struct bfa_cee_s *)arg;
if (cee->get_attr_pending == BFA_TRUE) {
cee->get_attr_status = BFA_STATUS_FAILED;
cee->get_attr_pending = BFA_FALSE;
if (cee->cbfn.get_attr_cbfn) {
cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg,
BFA_STATUS_FAILED);
}
}
if (cee->get_stats_pending == BFA_TRUE) {
cee->get_stats_status = BFA_STATUS_FAILED;
cee->get_stats_pending = BFA_FALSE;
if (cee->cbfn.get_stats_cbfn) {
cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg,
BFA_STATUS_FAILED);
}
}
if (cee->reset_stats_pending == BFA_TRUE) {
cee->reset_stats_status = BFA_STATUS_FAILED;
cee->reset_stats_pending = BFA_FALSE;
if (cee->cbfn.reset_stats_cbfn) {
cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg,
BFA_STATUS_FAILED);
}
}
}
/**
* bfa_cee_attach()
*
*
* @param[in] cee - Pointer to the CEE module data structure
* ioc - Pointer to the ioc module data structure
* dev - Pointer to the device driver module data structure
* The device driver specific mbox ISR functions have
* this pointer as one of the parameters.
* trcmod -
* logmod -
*
* @return void
*/
void
bfa_cee_attach(struct bfa_cee_s *cee, struct bfa_ioc_s *ioc, void *dev,
struct bfa_trc_mod_s *trcmod, struct bfa_log_mod_s *logmod)
{
bfa_assert(cee != NULL);
cee->dev = dev;
cee->trcmod = trcmod;
cee->logmod = logmod;
cee->ioc = ioc;
bfa_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee);
bfa_ioc_hbfail_init(&cee->hbfail, bfa_cee_hbfail, cee);
bfa_ioc_hbfail_register(cee->ioc, &cee->hbfail);
bfa_trc(cee, 0);
}
/**
* bfa_cee_detach()
*
*
* @param[in] cee - Pointer to the CEE module data structure
*
* @return void
*/
void
bfa_cee_detach(struct bfa_cee_s *cee)
{
/*
* For now, just check if there is some ioctl pending and mark that as
* failed?
*/
/* bfa_cee_hbfail(cee); */
}
/*
* 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 <defs/bfa_defs_pci.h>
#include <cs/bfa_debug.h>
#include <bfa_iocfc.h>
#define DEF_CFG_NUM_FABRICS 1
#define DEF_CFG_NUM_LPORTS 256
#define DEF_CFG_NUM_CQS 4
#define DEF_CFG_NUM_IOIM_REQS (BFA_IOIM_MAX)
#define DEF_CFG_NUM_TSKIM_REQS 128
#define DEF_CFG_NUM_FCXP_REQS 64
#define DEF_CFG_NUM_UF_BUFS 64
#define DEF_CFG_NUM_RPORTS 1024
#define DEF_CFG_NUM_ITNIMS (DEF_CFG_NUM_RPORTS)
#define DEF_CFG_NUM_TINS 256
#define DEF_CFG_NUM_SGPGS 2048
#define DEF_CFG_NUM_REQQ_ELEMS 256
#define DEF_CFG_NUM_RSPQ_ELEMS 64
#define DEF_CFG_NUM_SBOOT_TGTS 16
#define DEF_CFG_NUM_SBOOT_LUNS 16
/**
* Use this function query the memory requirement of the BFA library.
* This function needs to be called before bfa_attach() to get the
* memory required of the BFA layer for a given driver configuration.
*
* This call will fail, if the cap is out of range compared to pre-defined
* values within the BFA library
*
* @param[in] cfg - pointer to bfa_ioc_cfg_t. Driver layer should indicate
* its configuration in this structure.
* The default values for struct bfa_iocfc_cfg_s can be
* fetched using bfa_cfg_get_default() API.
*
* If cap's boundary check fails, the library will use
* the default bfa_cap_t values (and log a warning msg).
*
* @param[out] meminfo - pointer to bfa_meminfo_t. This content
* indicates the memory type (see bfa_mem_type_t) and
* amount of memory required.
*
* Driver should allocate the memory, populate the
* starting address for each block and provide the same
* structure as input parameter to bfa_attach() call.
*
* @return void
*
* Special Considerations: @note
*/
void
bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo)
{
int i;
u32 km_len = 0, dm_len = 0;
bfa_assert((cfg != NULL) && (meminfo != NULL));
bfa_os_memset((void *)meminfo, 0, sizeof(struct bfa_meminfo_s));
meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_type =
BFA_MEM_TYPE_KVA;
meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_type =
BFA_MEM_TYPE_DMA;
bfa_iocfc_meminfo(cfg, &km_len, &dm_len);
for (i = 0; hal_mods[i]; i++)
hal_mods[i]->meminfo(cfg, &km_len, &dm_len);
meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_len = km_len;
meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_len = dm_len;
}
/**
* Use this function to do attach the driver instance with the BFA
* library. This function will not trigger any HW initialization
* process (which will be done in bfa_init() call)
*
* This call will fail, if the cap is out of range compared to
* pre-defined values within the BFA library
*
* @param[out] bfa Pointer to bfa_t.
* @param[in] bfad Opaque handle back to the driver's IOC structure
* @param[in] cfg Pointer to bfa_ioc_cfg_t. Should be same structure
* that was used in bfa_cfg_get_meminfo().
* @param[in] meminfo Pointer to bfa_meminfo_t. The driver should
* use the bfa_cfg_get_meminfo() call to
* find the memory blocks required, allocate the
* required memory and provide the starting addresses.
* @param[in] pcidev pointer to struct bfa_pcidev_s
*
* @return
* void
*
* Special Considerations:
*
* @note
*
*/
void
bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
{
int i;
struct bfa_mem_elem_s *melem;
bfa->fcs = BFA_FALSE;
bfa_assert((cfg != NULL) && (meminfo != NULL));
/**
* initialize all memory pointers for iterative allocation
*/
for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
melem = meminfo->meminfo + i;
melem->kva_curp = melem->kva;
melem->dma_curp = melem->dma;
}
bfa_iocfc_attach(bfa, bfad, cfg, meminfo, pcidev);
for (i = 0; hal_mods[i]; i++)
hal_mods[i]->attach(bfa, bfad, cfg, meminfo, pcidev);
}
/**
* Use this function to delete a BFA IOC. IOC should be stopped (by
* calling bfa_stop()) before this function call.
*
* @param[in] bfa - pointer to bfa_t.
*
* @return
* void
*
* Special Considerations:
*
* @note
*/
void
bfa_detach(struct bfa_s *bfa)
{
int i;
for (i = 0; hal_mods[i]; i++)
hal_mods[i]->detach(bfa);
bfa_iocfc_detach(bfa);
}
void
bfa_init_trc(struct bfa_s *bfa, struct bfa_trc_mod_s *trcmod)
{
bfa->trcmod = trcmod;
}
void
bfa_init_log(struct bfa_s *bfa, struct bfa_log_mod_s *logmod)
{
bfa->logm = logmod;
}
void
bfa_init_aen(struct bfa_s *bfa, struct bfa_aen_s *aen)
{
bfa->aen = aen;
}
void
bfa_init_plog(struct bfa_s *bfa, struct bfa_plog_s *plog)
{
bfa->plog = plog;
}
/**
* Initialize IOC.
*
* This function will return immediately, when the IOC initialization is
* completed, the bfa_cb_init() will be called.
*
* @param[in] bfa instance
*
* @return void
*
* Special Considerations:
*
* @note
* When this function returns, the driver should register the interrupt service
* routine(s) and enable the device interrupts. If this is not done,
* bfa_cb_init() will never get called
*/
void
bfa_init(struct bfa_s *bfa)
{
bfa_iocfc_init(bfa);
}
/**
* Use this function initiate the IOC configuration setup. This function
* will return immediately.
*
* @param[in] bfa instance
*
* @return None
*/
void
bfa_start(struct bfa_s *bfa)
{
bfa_iocfc_start(bfa);
}
/**
* Use this function quiese the IOC. This function will return immediately,
* when the IOC is actually stopped, the bfa_cb_stop() will be called.
*
* @param[in] bfa - pointer to bfa_t.
*
* @return None
*
* Special Considerations:
* bfa_cb_stop() could be called before or after bfa_stop() returns.
*
* @note
* In case of any failure, we could handle it automatically by doing a
* reset and then succeed the bfa_stop() call.
*/
void
bfa_stop(struct bfa_s *bfa)
{
bfa_iocfc_stop(bfa);
}
void
bfa_comp_deq(struct bfa_s *bfa, struct list_head *comp_q)
{
INIT_LIST_HEAD(comp_q);
list_splice_tail_init(&bfa->comp_q, comp_q);
}
void
bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q)
{
struct list_head *qe;
struct list_head *qen;
struct bfa_cb_qe_s *hcb_qe;
list_for_each_safe(qe, qen, comp_q) {
hcb_qe = (struct bfa_cb_qe_s *) qe;
hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE);
}
}
void
bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q)
{
struct list_head *qe;
struct bfa_cb_qe_s *hcb_qe;
while (!list_empty(comp_q)) {
bfa_q_deq(comp_q, &qe);
hcb_qe = (struct bfa_cb_qe_s *) qe;
hcb_qe->cbfn(hcb_qe->cbarg, BFA_FALSE);
}
}
void
bfa_attach_fcs(struct bfa_s *bfa)
{
bfa->fcs = BFA_TRUE;
}
/**
* Periodic timer heart beat from driver
*/
void
bfa_timer_tick(struct bfa_s *bfa)
{
bfa_timer_beat(&bfa->timer_mod);
}
#ifndef BFA_BIOS_BUILD
/**
* Return the list of PCI vendor/device id lists supported by this
* BFA instance.
*/
void
bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids)
{
static struct bfa_pciid_s __pciids[] = {
{BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G2P},
{BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G1P},
{BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT},
};
*npciids = sizeof(__pciids) / sizeof(__pciids[0]);
*pciids = __pciids;
}
/**
* Use this function query the default struct bfa_iocfc_cfg_s value (compiled
* into BFA layer). The OS driver can then turn back and overwrite entries that
* have been configured by the user.
*
* @param[in] cfg - pointer to bfa_ioc_cfg_t
*
* @return
* void
*
* Special Considerations:
* note
*/
void
bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg)
{
cfg->fwcfg.num_fabrics = DEF_CFG_NUM_FABRICS;
cfg->fwcfg.num_lports = DEF_CFG_NUM_LPORTS;
cfg->fwcfg.num_rports = DEF_CFG_NUM_RPORTS;
cfg->fwcfg.num_ioim_reqs = DEF_CFG_NUM_IOIM_REQS;
cfg->fwcfg.num_tskim_reqs = DEF_CFG_NUM_TSKIM_REQS;
cfg->fwcfg.num_fcxp_reqs = DEF_CFG_NUM_FCXP_REQS;
cfg->fwcfg.num_uf_bufs = DEF_CFG_NUM_UF_BUFS;
cfg->fwcfg.num_cqs = DEF_CFG_NUM_CQS;
cfg->drvcfg.num_reqq_elems = DEF_CFG_NUM_REQQ_ELEMS;
cfg->drvcfg.num_rspq_elems = DEF_CFG_NUM_RSPQ_ELEMS;
cfg->drvcfg.num_sgpgs = DEF_CFG_NUM_SGPGS;
cfg->drvcfg.num_sboot_tgts = DEF_CFG_NUM_SBOOT_TGTS;
cfg->drvcfg.num_sboot_luns = DEF_CFG_NUM_SBOOT_LUNS;
cfg->drvcfg.path_tov = BFA_FCPIM_PATHTOV_DEF;
cfg->drvcfg.ioc_recover = BFA_FALSE;
cfg->drvcfg.delay_comp = BFA_FALSE;
}
void
bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg)
{
bfa_cfg_get_default(cfg);
cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MIN;
cfg->fwcfg.num_tskim_reqs = BFA_TSKIM_MIN;
cfg->fwcfg.num_fcxp_reqs = BFA_FCXP_MIN;
cfg->fwcfg.num_uf_bufs = BFA_UF_MIN;
cfg->fwcfg.num_rports = BFA_RPORT_MIN;
cfg->drvcfg.num_sgpgs = BFA_SGPG_MIN;
cfg->drvcfg.num_reqq_elems = BFA_REQQ_NELEMS_MIN;
cfg->drvcfg.num_rspq_elems = BFA_RSPQ_NELEMS_MIN;
cfg->drvcfg.min_cfg = BFA_TRUE;
}
void
bfa_get_attr(struct bfa_s *bfa, struct bfa_ioc_attr_s *ioc_attr)
{
bfa_ioc_get_attr(&bfa->ioc, ioc_attr);
}
/**
* Retrieve firmware trace information on IOC failure.
*/
bfa_status_t
bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen)
{
return bfa_ioc_debug_fwsave(&bfa->ioc, trcdata, trclen);
}
/**
* Fetch firmware trace data.
*
* @param[in] bfa BFA instance
* @param[out] trcdata Firmware trace buffer
* @param[in,out] trclen Firmware trace buffer len
*
* @retval BFA_STATUS_OK Firmware trace is fetched.
* @retval BFA_STATUS_INPROGRESS Firmware trace fetch is in progress.
*/
bfa_status_t
bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen)
{
return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen);
}
#endif
/*
* 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 <cs/bfa_debug.h>
#include <bfa_os_inc.h>
#include <cs/bfa_q.h>
#include <log/bfa_log_hal.h>
/**
* cs_debug_api
*/
void
bfa_panic(int line, char *file, char *panicstr)
{
bfa_log(NULL, BFA_LOG_HAL_ASSERT, file, line, panicstr);
bfa_os_panic();
}
void
bfa_sm_panic(struct bfa_log_mod_s *logm, int line, char *file, int event)
{
bfa_log(logm, BFA_LOG_HAL_SM_ASSERT, file, line, event);
bfa_os_panic();
}
int
bfa_q_is_on_q_func(struct list_head *q, struct list_head *qe)
{
struct list_head *tqe;
tqe = bfa_q_next(q);
while (tqe != q) {
if (tqe == qe)
return (1);
tqe = bfa_q_next(tqe);
if (tqe == NULL)
break;
}
return (0);
}
/*
* 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 <log/bfa_log_hal.h>
BFA_TRC_FILE(HAL, FCPIM);
BFA_MODULE(fcpim);
/**
* hal_fcpim_mod BFA FCP Initiator Mode module
*/
/**
* Compute and return memory needed by FCP(im) module.
*/
static void
bfa_fcpim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
u32 *dm_len)
{
bfa_itnim_meminfo(cfg, km_len, dm_len);
/**
* IO memory
*/
if (cfg->fwcfg.num_ioim_reqs < BFA_IOIM_MIN)
cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MIN;
else if (cfg->fwcfg.num_ioim_reqs > BFA_IOIM_MAX)
cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MAX;
*km_len += cfg->fwcfg.num_ioim_reqs *
(sizeof(struct bfa_ioim_s) + sizeof(struct bfa_ioim_sp_s));
*dm_len += cfg->fwcfg.num_ioim_reqs * BFI_IOIM_SNSLEN;
/**
* task management command memory
*/
if (cfg->fwcfg.num_tskim_reqs < BFA_TSKIM_MIN)
cfg->fwcfg.num_tskim_reqs = BFA_TSKIM_MIN;
*km_len += cfg->fwcfg.num_tskim_reqs * sizeof(struct bfa_tskim_s);
}
static void
bfa_fcpim_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
{
struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
bfa_trc(bfa, cfg->drvcfg.path_tov);
bfa_trc(bfa, cfg->fwcfg.num_rports);
bfa_trc(bfa, cfg->fwcfg.num_ioim_reqs);
bfa_trc(bfa, cfg->fwcfg.num_tskim_reqs);
fcpim->bfa = bfa;
fcpim->num_itnims = cfg->fwcfg.num_rports;
fcpim->num_ioim_reqs = cfg->fwcfg.num_ioim_reqs;
fcpim->num_tskim_reqs = cfg->fwcfg.num_tskim_reqs;
fcpim->path_tov = cfg->drvcfg.path_tov;
fcpim->delay_comp = cfg->drvcfg.delay_comp;
bfa_itnim_attach(fcpim, meminfo);
bfa_tskim_attach(fcpim, meminfo);
bfa_ioim_attach(fcpim, meminfo);
}
static void
bfa_fcpim_initdone(struct bfa_s *bfa)
{
}
static void
bfa_fcpim_detach(struct bfa_s *bfa)
{
struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
bfa_ioim_detach(fcpim);
bfa_tskim_detach(fcpim);
}
static void
bfa_fcpim_start(struct bfa_s *bfa)
{
}
static void
bfa_fcpim_stop(struct bfa_s *bfa)
{
}
static void
bfa_fcpim_iocdisable(struct bfa_s *bfa)
{
struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
struct bfa_itnim_s *itnim;
struct list_head *qe, *qen;
list_for_each_safe(qe, qen, &fcpim->itnim_q) {
itnim = (struct bfa_itnim_s *) qe;
bfa_itnim_iocdisable(itnim);
}
}
void
bfa_fcpim_path_tov_set(struct bfa_s *bfa, u16 path_tov)
{
struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
fcpim->path_tov = path_tov * 1000;
if (fcpim->path_tov > BFA_FCPIM_PATHTOV_MAX)
fcpim->path_tov = BFA_FCPIM_PATHTOV_MAX;
}
u16
bfa_fcpim_path_tov_get(struct bfa_s *bfa)
{
struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
return (fcpim->path_tov / 1000);
}
bfa_status_t
bfa_fcpim_get_modstats(struct bfa_s *bfa, struct bfa_fcpim_stats_s *modstats)
{
struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
*modstats = fcpim->stats;
return BFA_STATUS_OK;
}
bfa_status_t
bfa_fcpim_clr_modstats(struct bfa_s *bfa)
{
struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
memset(&fcpim->stats, 0, sizeof(struct bfa_fcpim_stats_s));
return BFA_STATUS_OK;
}
void
bfa_fcpim_qdepth_set(struct bfa_s *bfa, u16 q_depth)
{
struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
bfa_assert(q_depth <= BFA_IOCFC_QDEPTH_MAX);
fcpim->q_depth = q_depth;
}
u16
bfa_fcpim_qdepth_get(struct bfa_s *bfa)
{
struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
return (fcpim->q_depth);
}
/*
* 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.
*/
#ifndef __BFA_FCPIM_PRIV_H__
#define __BFA_FCPIM_PRIV_H__
#include <bfa_fcpim.h>
#include <defs/bfa_defs_fcpim.h>
#include <cs/bfa_wc.h>
#include "bfa_sgpg_priv.h"
#define BFA_ITNIM_MIN 32
#define BFA_ITNIM_MAX 1024
#define BFA_IOIM_MIN 8
#define BFA_IOIM_MAX 2000
#define BFA_TSKIM_MIN 4
#define BFA_TSKIM_MAX 512
#define BFA_FCPIM_PATHTOV_DEF (30 * 1000) /* in millisecs */
#define BFA_FCPIM_PATHTOV_MAX (90 * 1000) /* in millisecs */
#define bfa_fcpim_stats(__fcpim, __stats) \
(__fcpim)->stats.__stats ++
struct bfa_fcpim_mod_s {
struct bfa_s *bfa;
struct bfa_itnim_s *itnim_arr;
struct bfa_ioim_s *ioim_arr;
struct bfa_ioim_sp_s *ioim_sp_arr;
struct bfa_tskim_s *tskim_arr;
struct bfa_dma_s snsbase;
int num_itnims;
int num_ioim_reqs;
int num_tskim_reqs;
u32 path_tov;
u16 q_depth;
u16 rsvd;
struct list_head itnim_q; /* queue of active itnim */
struct list_head ioim_free_q; /* free IO resources */
struct list_head ioim_resfree_q; /* IOs waiting for f/w */
struct list_head ioim_comp_q; /* IO global comp Q */
struct list_head tskim_free_q;
u32 ios_active; /* current active IOs */
u32 delay_comp;
struct bfa_fcpim_stats_s stats;
};
struct bfa_ioim_s;
struct bfa_tskim_s;
/**
* BFA IO (initiator mode)
*/
struct bfa_ioim_s {
struct list_head qe; /* queue elememt */
bfa_sm_t sm; /* BFA ioim state machine */
struct bfa_s *bfa; /* BFA module */
struct bfa_fcpim_mod_s *fcpim; /* parent fcpim module */
struct bfa_itnim_s *itnim; /* i-t-n nexus for this IO */
struct bfad_ioim_s *dio; /* driver IO handle */
u16 iotag; /* FWI IO tag */
u16 abort_tag; /* unqiue abort request tag */
u16 nsges; /* number of SG elements */
u16 nsgpgs; /* number of SG pages */
struct bfa_sgpg_s *sgpg; /* first SG page */
struct list_head sgpg_q; /* allocated SG pages */
struct bfa_cb_qe_s hcb_qe; /* bfa callback qelem */
bfa_cb_cbfn_t io_cbfn; /* IO completion handler */
struct bfa_ioim_sp_s *iosp; /* slow-path IO handling */
};
struct bfa_ioim_sp_s {
struct bfi_msg_s comp_rspmsg; /* IO comp f/w response */
u8 *snsinfo; /* sense info for this IO */
struct bfa_sgpg_wqe_s sgpg_wqe; /* waitq elem for sgpg */
struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
bfa_boolean_t abort_explicit; /* aborted by OS */
struct bfa_tskim_s *tskim; /* Relevant TM cmd */
};
/**
* BFA Task management command (initiator mode)
*/
struct bfa_tskim_s {
struct list_head qe;
bfa_sm_t sm;
struct bfa_s *bfa; /* BFA module */
struct bfa_fcpim_mod_s *fcpim; /* parent fcpim module */
struct bfa_itnim_s *itnim; /* i-t-n nexus for this IO */
struct bfad_tskim_s *dtsk; /* driver task mgmt cmnd */
bfa_boolean_t notify; /* notify itnim on TM comp */
lun_t lun; /* lun if applicable */
enum fcp_tm_cmnd tm_cmnd; /* task management command */
u16 tsk_tag; /* FWI IO tag */
u8 tsecs; /* timeout in seconds */
struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
struct list_head io_q; /* queue of affected IOs */
struct bfa_wc_s wc; /* waiting counter */
struct bfa_cb_qe_s hcb_qe; /* bfa callback qelem */
enum bfi_tskim_status tsk_status; /* TM status */
};
/**
* BFA i-t-n (initiator mode)
*/
struct bfa_itnim_s {
struct list_head qe; /* queue element */
bfa_sm_t sm; /* i-t-n im BFA state machine */
struct bfa_s *bfa; /* bfa instance */
struct bfa_rport_s *rport; /* bfa rport */
void *ditn; /* driver i-t-n structure */
struct bfi_mhdr_s mhdr; /* pre-built mhdr */
u8 msg_no; /* itnim/rport firmware handle */
u8 reqq; /* CQ for requests */
struct bfa_cb_qe_s hcb_qe; /* bfa callback qelem */
struct list_head pending_q; /* queue of pending IO requests*/
struct list_head io_q; /* queue of active IO requests */
struct list_head io_cleanup_q; /* IO being cleaned up */
struct list_head tsk_q; /* queue of active TM commands */
struct list_head delay_comp_q;/* queue of failed inflight cmds */
bfa_boolean_t seq_rec; /* SQER supported */
bfa_boolean_t is_online; /* itnim is ONLINE for IO */
bfa_boolean_t iotov_active; /* IO TOV timer is active */
struct bfa_wc_s wc; /* waiting counter */
struct bfa_timer_s timer; /* pending IO TOV */
struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
struct bfa_fcpim_mod_s *fcpim; /* fcpim module */
struct bfa_itnim_hal_stats_s stats;
};
#define bfa_itnim_is_online(_itnim) (_itnim)->is_online
#define BFA_FCPIM_MOD(_hal) (&(_hal)->modules.fcpim_mod)
#define BFA_IOIM_FROM_TAG(_fcpim, _iotag) \
(&fcpim->ioim_arr[_iotag])
#define BFA_TSKIM_FROM_TAG(_fcpim, _tmtag) \
(&fcpim->tskim_arr[_tmtag & (fcpim->num_tskim_reqs - 1)])
/*
* function prototypes
*/
void bfa_ioim_attach(struct bfa_fcpim_mod_s *fcpim,
struct bfa_meminfo_s *minfo);
void bfa_ioim_detach(struct bfa_fcpim_mod_s *fcpim);
void bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
void bfa_ioim_good_comp_isr(struct bfa_s *bfa,
struct bfi_msg_s *msg);
void bfa_ioim_cleanup(struct bfa_ioim_s *ioim);
void bfa_ioim_cleanup_tm(struct bfa_ioim_s *ioim,
struct bfa_tskim_s *tskim);
void bfa_ioim_iocdisable(struct bfa_ioim_s *ioim);
void bfa_ioim_tov(struct bfa_ioim_s *ioim);
void bfa_tskim_attach(struct bfa_fcpim_mod_s *fcpim,
struct bfa_meminfo_s *minfo);
void bfa_tskim_detach(struct bfa_fcpim_mod_s *fcpim);
void bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
void bfa_tskim_iodone(struct bfa_tskim_s *tskim);
void bfa_tskim_iocdisable(struct bfa_tskim_s *tskim);
void bfa_tskim_cleanup(struct bfa_tskim_s *tskim);
void bfa_itnim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
u32 *dm_len);
void bfa_itnim_attach(struct bfa_fcpim_mod_s *fcpim,
struct bfa_meminfo_s *minfo);
void bfa_itnim_detach(struct bfa_fcpim_mod_s *fcpim);
void bfa_itnim_iocdisable(struct bfa_itnim_s *itnim);
void bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
void bfa_itnim_iodone(struct bfa_itnim_s *itnim);
void bfa_itnim_tskdone(struct bfa_itnim_s *itnim);
bfa_boolean_t bfa_itnim_hold_io(struct bfa_itnim_s *itnim);
#endif /* __BFA_FCPIM_PRIV_H__ */
此差异已折叠。
/*
* 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.
*/
/**
* bfa_fcs.c BFA FCS main
*/
#include <fcs/bfa_fcs.h>
#include "fcs_port.h"
#include "fcs_uf.h"
#include "fcs_vport.h"
#include "fcs_rport.h"
#include "fcs_fabric.h"
#include "fcs_fcpim.h"
#include "fcs_fcptm.h"
#include "fcbuild.h"
#include "fcs.h"
#include "bfad_drv.h"
#include <fcb/bfa_fcb.h>
/**
* FCS sub-modules
*/
struct bfa_fcs_mod_s {
void (*modinit) (struct bfa_fcs_s *fcs);
void (*modexit) (struct bfa_fcs_s *fcs);
};
#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),
};
/**
* fcs_api BFA FCS API
*/
static void
bfa_fcs_exit_comp(void *fcs_cbarg)
{
struct bfa_fcs_s *fcs = fcs_cbarg;
struct bfad_s *bfad = fcs->bfad;
complete(&bfad->comp);
}
/**
* fcs_api BFA FCS API
*/
/**
* FCS instance initialization.
*
* param[in] fcs FCS instance
* param[in] bfa BFA instance
* param[in] bfad BFA driver instance
*
* return None
*/
void
bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
bfa_boolean_t min_cfg)
{
int i;
struct bfa_fcs_mod_s *mod;
fcs->bfa = bfa;
fcs->bfad = bfad;
fcs->min_cfg = min_cfg;
bfa_attach_fcs(bfa);
fcbuild_init();
for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
mod = &fcs_modules[i];
mod->modinit(fcs);
}
}
/**
* Start FCS operations.
*/
void
bfa_fcs_start(struct bfa_fcs_s *fcs)
{
bfa_fcs_fabric_modstart(fcs);
}
/**
* FCS driver details initialization.
*
* param[in] fcs FCS instance
* param[in] driver_info Driver Details
*
* return None
*/
void
bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
struct bfa_fcs_driver_info_s *driver_info)
{
fcs->driver_info = *driver_info;
bfa_fcs_fabric_psymb_init(&fcs->fabric);
}
/**
* FCS instance cleanup and exit.
*
* param[in] fcs FCS instance
* return None
*/
void
bfa_fcs_exit(struct bfa_fcs_s *fcs)
{
struct bfa_fcs_mod_s *mod;
int nmods, i;
bfa_wc_init(&fcs->wc, bfa_fcs_exit_comp, 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);
}
bfa_wc_wait(&fcs->wc);
}
void
bfa_fcs_trc_init(struct bfa_fcs_s *fcs, struct bfa_trc_mod_s *trcmod)
{
fcs->trcmod = trcmod;
}
void
bfa_fcs_log_init(struct bfa_fcs_s *fcs, struct bfa_log_mod_s *logmod)
{
fcs->logm = logmod;
}
void
bfa_fcs_aen_init(struct bfa_fcs_s *fcs, struct bfa_aen_s *aen)
{
fcs->aen = aen;
}
void
bfa_fcs_modexit_comp(struct bfa_fcs_s *fcs)
{
bfa_wc_down(&fcs->wc);
}
此差异已折叠。
/*
* 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.
*/
/**
* bfa_fcs_pport.c BFA FCS PPORT ( physical port)
*/
#include <fcs/bfa_fcs.h>
#include <bfa_svc.h>
#include <fcs/bfa_fcs_fabric.h>
#include "fcs_trcmod.h"
#include "fcs.h"
#include "fcs_fabric.h"
#include "fcs_port.h"
BFA_TRC_FILE(FCS, PPORT);
static void
bfa_fcs_pport_event_handler(void *cbarg, bfa_pport_event_t event)
{
struct bfa_fcs_s *fcs = cbarg;
bfa_trc(fcs, event);
switch (event) {
case BFA_PPORT_LINKUP:
bfa_fcs_fabric_link_up(&fcs->fabric);
break;
case BFA_PPORT_LINKDOWN:
bfa_fcs_fabric_link_down(&fcs->fabric);
break;
case BFA_PPORT_TRUNK_LINKDOWN:
bfa_assert(0);
break;
default:
bfa_assert(0);
}
}
void
bfa_fcs_pport_modinit(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);
}
/*
* 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.
*/
/**
* bfa_fcs_uf.c BFA FCS UF ( Unsolicited Frames)
*/
#include <fcs/bfa_fcs.h>
#include <bfa_svc.h>
#include <fcs/bfa_fcs_fabric.h>
#include "fcs.h"
#include "fcs_trcmod.h"
#include "fcs_fabric.h"
#include "fcs_uf.h"
BFA_TRC_FILE(FCS, UF);
/**
* BFA callback for unsolicited frame receive handler.
*
* @param[in] cbarg callback arg for receive handler
* @param[in] uf unsolicited frame descriptor
*
* @return None
*/
static void
bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf)
{
struct bfa_fcs_s *fcs = (struct bfa_fcs_s *) cbarg;
struct fchs_s *fchs = bfa_uf_get_frmbuf(uf);
u16 len = bfa_uf_get_frmlen(uf);
struct fc_vft_s *vft;
struct bfa_fcs_fabric_s *fabric;
/**
* check for VFT header
*/
if (fchs->routing == FC_RTG_EXT_HDR &&
fchs->cat_info == FC_CAT_VFT_HDR) {
bfa_stats(fcs, uf.tagged);
vft = bfa_uf_get_frmbuf(uf);
if (fcs->port_vfid == vft->vf_id)
fabric = &fcs->fabric;
else
fabric = bfa_fcs_vf_lookup(fcs, (u16) vft->vf_id);
/**
* drop frame if vfid is unknown
*/
if (!fabric) {
bfa_assert(0);
bfa_stats(fcs, uf.vfid_unknown);
bfa_uf_free(uf);
return;
}
/**
* skip vft header
*/
fchs = (struct fchs_s *) (vft + 1);
len -= sizeof(struct fc_vft_s);
bfa_trc(fcs, vft->vf_id);
} else {
bfa_stats(fcs, uf.untagged);
fabric = &fcs->fabric;
}
bfa_trc(fcs, ((u32 *) fchs)[0]);
bfa_trc(fcs, ((u32 *) fchs)[1]);
bfa_trc(fcs, ((u32 *) fchs)[2]);
bfa_trc(fcs, ((u32 *) fchs)[3]);
bfa_trc(fcs, ((u32 *) fchs)[4]);
bfa_trc(fcs, ((u32 *) fchs)[5]);
bfa_trc(fcs, len);
bfa_fcs_fabric_uf_recv(fabric, fchs, len);
bfa_uf_free(uf);
}
void
bfa_fcs_uf_modinit(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);
}
此差异已折叠。
/*
* 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.
*/
#ifndef __BFA_FCXP_PRIV_H__
#define __BFA_FCXP_PRIV_H__
#include <cs/bfa_sm.h>
#include <protocol/fc.h>
#include <bfa_svc.h>
#include <bfi/bfi_fcxp.h>
#define BFA_FCXP_MIN (1)
#define BFA_FCXP_MAX_IBUF_SZ (2 * 1024 + 256)
#define BFA_FCXP_MAX_LBUF_SZ (4 * 1024 + 256)
struct bfa_fcxp_mod_s {
struct bfa_s *bfa; /* backpointer to BFA */
struct bfa_fcxp_s *fcxp_list; /* array of FCXPs */
u16 num_fcxps; /* max num FCXP requests */
struct list_head fcxp_free_q; /* free FCXPs */
struct list_head fcxp_active_q; /* active FCXPs */
void *req_pld_list_kva; /* list of FCXP req pld */
u64 req_pld_list_pa; /* list of FCXP req pld */
void *rsp_pld_list_kva; /* list of FCXP resp pld */
u64 rsp_pld_list_pa; /* list of FCXP resp pld */
struct list_head wait_q; /* wait queue for free fcxp */
u32 req_pld_sz;
u32 rsp_pld_sz;
};
#define BFA_FCXP_MOD(__bfa) (&(__bfa)->modules.fcxp_mod)
#define BFA_FCXP_FROM_TAG(__mod, __tag) (&(__mod)->fcxp_list[__tag])
typedef void (*fcxp_send_cb_t) (struct bfa_s *ioc, struct bfa_fcxp_s *fcxp,
void *cb_arg, bfa_status_t req_status,
u32 rsp_len, u32 resid_len,
struct fchs_s *rsp_fchs);
/**
* Information needed for a FCXP request
*/
struct bfa_fcxp_req_info_s {
struct bfa_rport_s *bfa_rport; /* Pointer to the bfa rport that was
*returned from bfa_rport_create().
*This could be left NULL for WKA or for
*FCXP interactions before the rport
*nexus is established
*/
struct fchs_s fchs; /* request FC header structure */
u8 cts; /* continous sequence */
u8 class; /* FC class for the request/response */
u16 max_frmsz; /* max send frame size */
u16 vf_id; /* vsan tag if applicable */
u8 lp_tag; /* lport tag */
u32 req_tot_len; /* request payload total length */
};
struct bfa_fcxp_rsp_info_s {
struct fchs_s rsp_fchs; /* Response frame's FC header will
* be *sent back in this field */
u8 rsp_timeout; /* timeout in seconds, 0-no response
*/
u8 rsvd2[3];
u32 rsp_maxlen; /* max response length expected */
};
struct bfa_fcxp_s {
struct list_head qe; /* fcxp queue element */
bfa_sm_t sm; /* state machine */
void *caller; /* driver or fcs */
struct bfa_fcxp_mod_s *fcxp_mod;
/* back pointer to fcxp mod */
u16 fcxp_tag; /* internal tag */
struct bfa_fcxp_req_info_s req_info;
/* request info */
struct bfa_fcxp_rsp_info_s rsp_info;
/* response info */
u8 use_ireqbuf; /* use internal req buf */
u8 use_irspbuf; /* use internal rsp buf */
u32 nreq_sgles; /* num request SGLEs */
u32 nrsp_sgles; /* num response SGLEs */
struct list_head req_sgpg_q; /* SG pages for request buf */
struct list_head req_sgpg_wqe; /* wait queue for req SG page */
struct list_head rsp_sgpg_q; /* SG pages for response buf */
struct list_head rsp_sgpg_wqe; /* wait queue for rsp SG page */
bfa_fcxp_get_sgaddr_t req_sga_cbfn;
/* SG elem addr user function */
bfa_fcxp_get_sglen_t req_sglen_cbfn;
/* SG elem len user function */
bfa_fcxp_get_sgaddr_t rsp_sga_cbfn;
/* SG elem addr user function */
bfa_fcxp_get_sglen_t rsp_sglen_cbfn;
/* SG elem len user function */
bfa_cb_fcxp_send_t send_cbfn; /* send completion callback */
void *send_cbarg; /* callback arg */
struct bfa_sge_s req_sge[BFA_FCXP_MAX_SGES];
/* req SG elems */
struct bfa_sge_s rsp_sge[BFA_FCXP_MAX_SGES];
/* rsp SG elems */
u8 rsp_status; /* comp: rsp status */
u32 rsp_len; /* comp: actual response len */
u32 residue_len; /* comp: residual rsp length */
struct fchs_s rsp_fchs; /* comp: response fchs */
struct bfa_cb_qe_s hcb_qe; /* comp: callback qelem */
struct bfa_reqq_wait_s reqq_wqe;
bfa_boolean_t reqq_waiting;
};
#define BFA_FCXP_REQ_PLD(_fcxp) (bfa_fcxp_get_reqbuf(_fcxp))
#define BFA_FCXP_RSP_FCHS(_fcxp) (&((_fcxp)->rsp_info.fchs))
#define BFA_FCXP_RSP_PLD(_fcxp) (bfa_fcxp_get_rspbuf(_fcxp))
#define BFA_FCXP_REQ_PLD_PA(_fcxp) \
((_fcxp)->fcxp_mod->req_pld_list_pa + \
((_fcxp)->fcxp_mod->req_pld_sz * (_fcxp)->fcxp_tag))
#define BFA_FCXP_RSP_PLD_PA(_fcxp) \
((_fcxp)->fcxp_mod->rsp_pld_list_pa + \
((_fcxp)->fcxp_mod->rsp_pld_sz * (_fcxp)->fcxp_tag))
void bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
#endif /* __BFA_FCXP_PRIV_H__ */
/*
* 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.
*/
#ifndef __BFA_FWIMG_PRIV_H__
#define __BFA_FWIMG_PRIV_H__
#define BFI_FLASH_CHUNK_SZ 256 /* Flash chunk size */
#define BFI_FLASH_CHUNK_SZ_WORDS (BFI_FLASH_CHUNK_SZ/sizeof(u32))
extern u32 *bfi_image_ct_get_chunk(u32 off);
extern u32 bfi_image_ct_size;
extern u32 *bfi_image_cb_get_chunk(u32 off);
extern u32 bfi_image_cb_size;
extern u32 *bfi_image_cb;
extern u32 *bfi_image_ct;
#endif /* __BFA_FWIMG_PRIV_H__ */
/*
* 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_priv.h>
#include <bfi/bfi_cbreg.h>
void
bfa_hwcb_reginit(struct bfa_s *bfa)
{
struct bfa_iocfc_regs_s *bfa_regs = &bfa->iocfc.bfa_regs;
bfa_os_addr_t kva = bfa_ioc_bar0(&bfa->ioc);
int i, q, fn = bfa_ioc_pcifn(&bfa->ioc);
if (fn == 0) {
bfa_regs->intr_status = (kva + HOSTFN0_INT_STATUS);
bfa_regs->intr_mask = (kva + HOSTFN0_INT_MSK);
} else {
bfa_regs->intr_status = (kva + HOSTFN1_INT_STATUS);
bfa_regs->intr_mask = (kva + HOSTFN1_INT_MSK);
}
for (i = 0; i < BFI_IOC_MAX_CQS; i++) {
/*
* CPE registers
*/
q = CPE_Q_NUM(fn, i);
bfa_regs->cpe_q_pi[i] = (kva + CPE_Q_PI(q));
bfa_regs->cpe_q_ci[i] = (kva + CPE_Q_CI(q));
bfa_regs->cpe_q_depth[i] = (kva + CPE_Q_DEPTH(q));
/*
* RME registers
*/
q = CPE_Q_NUM(fn, i);
bfa_regs->rme_q_pi[i] = (kva + RME_Q_PI(q));
bfa_regs->rme_q_ci[i] = (kva + RME_Q_CI(q));
bfa_regs->rme_q_depth[i] = (kva + RME_Q_DEPTH(q));
}
}
void
bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq)
{
}
static void
bfa_hwcb_rspq_ack_msix(struct bfa_s *bfa, int rspq)
{
bfa_reg_write(bfa->iocfc.bfa_regs.intr_status,
__HFN_INT_RME_Q0 << RME_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), rspq));
}
void
bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap,
u32 *num_vecs, u32 *max_vec_bit)
{
#define __HFN_NUMINTS 13
if (bfa_ioc_pcifn(&bfa->ioc) == 0) {
*msix_vecs_bmap = (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 |
__HFN_INT_CPE_Q2 | __HFN_INT_CPE_Q3 |
__HFN_INT_RME_Q0 | __HFN_INT_RME_Q1 |
__HFN_INT_RME_Q2 | __HFN_INT_RME_Q3 |
__HFN_INT_MBOX_LPU0);
*max_vec_bit = __HFN_INT_MBOX_LPU0;
} else {
*msix_vecs_bmap = (__HFN_INT_CPE_Q4 | __HFN_INT_CPE_Q5 |
__HFN_INT_CPE_Q6 | __HFN_INT_CPE_Q7 |
__HFN_INT_RME_Q4 | __HFN_INT_RME_Q5 |
__HFN_INT_RME_Q6 | __HFN_INT_RME_Q7 |
__HFN_INT_MBOX_LPU1);
*max_vec_bit = __HFN_INT_MBOX_LPU1;
}
*msix_vecs_bmap |= (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
__HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS);
*num_vecs = __HFN_NUMINTS;
}
/**
* No special setup required for crossbow -- vector assignments are implicit.
*/
void
bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs)
{
int i;
bfa_assert((nvecs == 1) || (nvecs == __HFN_NUMINTS));
bfa->msix.nvecs = nvecs;
if (nvecs == 1) {
for (i = 0; i < BFA_MSIX_CB_MAX; i++)
bfa->msix.handler[i] = bfa_msix_all;
return;
}
for (i = BFA_MSIX_CPE_Q0; i <= BFA_MSIX_CPE_Q7; i++)
bfa->msix.handler[i] = bfa_msix_reqq;
for (i = BFA_MSIX_RME_Q0; i <= BFA_MSIX_RME_Q7; i++)
bfa->msix.handler[i] = bfa_msix_rspq;
for (; i < BFA_MSIX_CB_MAX; i++)
bfa->msix.handler[i] = bfa_msix_lpu_err;
}
/**
* Crossbow -- dummy, interrupts are masked
*/
void
bfa_hwcb_msix_install(struct bfa_s *bfa)
{
}
void
bfa_hwcb_msix_uninstall(struct bfa_s *bfa)
{
}
/**
* No special enable/disable -- vector assignments are implicit.
*/
void
bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
{
bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix;
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
/*
* 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_intr_priv.h"
BFA_TRC_FILE(HAL, IOCFC_Q);
void
bfa_iocfc_updateq(struct bfa_s *bfa, u32 reqq_ba, u32 rspq_ba,
u32 reqq_sci, u32 rspq_spi, bfa_cb_iocfc_t cbfn,
void *cbarg)
{
struct bfa_iocfc_s *iocfc = &bfa->iocfc;
struct bfi_iocfc_updateq_req_s updateq_req;
iocfc->updateq_cbfn = cbfn;
iocfc->updateq_cbarg = cbarg;
bfi_h2i_set(updateq_req.mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_UPDATEQ_REQ,
bfa_lpuid(bfa));
updateq_req.reqq_ba = bfa_os_htonl(reqq_ba);
updateq_req.rspq_ba = bfa_os_htonl(rspq_ba);
updateq_req.reqq_sci = bfa_os_htonl(reqq_sci);
updateq_req.rspq_spi = bfa_os_htonl(rspq_spi);
bfa_ioc_mbox_send(&bfa->ioc, &updateq_req,
sizeof(struct bfi_iocfc_updateq_req_s));
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
/*
* 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.
*/
#ifndef __BFA_LPS_PRIV_H__
#define __BFA_LPS_PRIV_H__
#include <bfa_svc.h>
struct bfa_lps_mod_s {
struct list_head lps_free_q;
struct list_head lps_active_q;
struct bfa_lps_s *lps_arr;
int num_lps;
};
#define BFA_LPS_MOD(__bfa) (&(__bfa)->modules.lps_mod)
#define BFA_LPS_FROM_TAG(__mod, __tag) (&(__mod)->lps_arr[__tag])
/*
* external functions
*/
void bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
#endif /* __BFA_LPS_PRIV_H__ */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册