mirror of
https://github.com/ukui/kernel.git
synced 2026-03-09 10:07:04 -07:00
[SCSI] bfa: Brocade BFA FC SCSI driver
Add new driver for Brocade Hardware Signed-off-by: Jing Huang <huangj@brocade.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
committed by
James Bottomley
parent
5415907af1
commit
7725ccfda5
@@ -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
|
||||
|
||||
15
drivers/scsi/bfa/Makefile
Normal file
15
drivers/scsi/bfa/Makefile
Normal file
@@ -0,0 +1,15 @@
|
||||
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
|
||||
57
drivers/scsi/bfa/bfa_callback_priv.h
Normal file
57
drivers/scsi/bfa/bfa_callback_priv.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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__ */
|
||||
205
drivers/scsi/bfa/bfa_cb_ioim_macros.h
Normal file
205
drivers/scsi/bfa/bfa_cb_ioim_macros.h
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* 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__ */
|
||||
492
drivers/scsi/bfa/bfa_cee.c
Normal file
492
drivers/scsi/bfa/bfa_cee.c
Normal file
@@ -0,0 +1,492 @@
|
||||
/*
|
||||
* 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); */
|
||||
}
|
||||
402
drivers/scsi/bfa/bfa_core.c
Normal file
402
drivers/scsi/bfa/bfa_core.c
Normal file
@@ -0,0 +1,402 @@
|
||||
/*
|
||||
* 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
|
||||
58
drivers/scsi/bfa/bfa_csdebug.c
Normal file
58
drivers/scsi/bfa/bfa_csdebug.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
175
drivers/scsi/bfa/bfa_fcpim.c
Normal file
175
drivers/scsi/bfa/bfa_fcpim.c
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
188
drivers/scsi/bfa/bfa_fcpim_priv.h
Normal file
188
drivers/scsi/bfa/bfa_fcpim_priv.h
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* 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__ */
|
||||
|
||||
1671
drivers/scsi/bfa/bfa_fcport.c
Normal file
1671
drivers/scsi/bfa/bfa_fcport.c
Normal file
File diff suppressed because it is too large
Load Diff
182
drivers/scsi/bfa/bfa_fcs.c
Normal file
182
drivers/scsi/bfa/bfa_fcs.c
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
940
drivers/scsi/bfa/bfa_fcs_lport.c
Normal file
940
drivers/scsi/bfa/bfa_fcs_lport.c
Normal file
File diff suppressed because it is too large
Load Diff
68
drivers/scsi/bfa/bfa_fcs_port.c
Normal file
68
drivers/scsi/bfa/bfa_fcs_port.c
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
105
drivers/scsi/bfa/bfa_fcs_uf.c
Normal file
105
drivers/scsi/bfa/bfa_fcs_uf.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
782
drivers/scsi/bfa/bfa_fcxp.c
Normal file
782
drivers/scsi/bfa/bfa_fcxp.c
Normal file
File diff suppressed because it is too large
Load Diff
138
drivers/scsi/bfa/bfa_fcxp_priv.h
Normal file
138
drivers/scsi/bfa/bfa_fcxp_priv.h
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* 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__ */
|
||||
31
drivers/scsi/bfa/bfa_fwimg_priv.h
Normal file
31
drivers/scsi/bfa/bfa_fwimg_priv.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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__ */
|
||||
142
drivers/scsi/bfa/bfa_hw_cb.c
Normal file
142
drivers/scsi/bfa/bfa_hw_cb.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user