Merge branch 'master' into for-next

This commit is contained in:
Jiri Kosina
2010-04-23 02:08:44 +02:00
5526 changed files with 96638 additions and 43582 deletions
+4 -4
View File
@@ -2,14 +2,14 @@ obj-$(CONFIG_SCSI_BFA_FC) := bfa.o
bfa-y := bfad.o bfad_intr.o bfad_os.o bfad_im.o bfad_attr.o bfad_fwimg.o
bfa-y += bfa_core.o bfa_ioc.o bfa_iocfc.o bfa_fcxp.o bfa_lps.o
bfa-y += bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o
bfa-y += bfa_core.o bfa_ioc.o bfa_ioc_ct.o bfa_ioc_cb.o bfa_iocfc.o bfa_fcxp.o
bfa-y += bfa_lps.o bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o
bfa-y += bfa_fcport.o bfa_port.o bfa_uf.o bfa_sgpg.o bfa_module.o bfa_ioim.o
bfa-y += bfa_itnim.o bfa_fcpim.o bfa_tskim.o bfa_log.o bfa_log_module.o
bfa-y += bfa_csdebug.o bfa_sm.o plog.o
bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o
bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o
bfa-y += bfa_fcs_uf.o bfa_fcs_lport.o fab.o fdmi.o ms.o ns.o scn.o loop.o
bfa-y += lport_api.o n2n.o rport.o rport_api.o rport_ftrs.o vport.o
ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna
ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna -DBFA_PERF_BUILD
+19
View File
@@ -384,6 +384,15 @@ bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen)
return bfa_ioc_debug_fwsave(&bfa->ioc, trcdata, trclen);
}
/**
* Clear the saved firmware trace information of an IOC.
*/
void
bfa_debug_fwsave_clear(struct bfa_s *bfa)
{
bfa_ioc_debug_fwsave_clear(&bfa->ioc);
}
/**
* Fetch firmware trace data.
*
@@ -399,4 +408,14 @@ bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen)
{
return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen);
}
/**
* Reset hw semaphore & usage cnt regs and initialize.
*/
void
bfa_chip_reset(struct bfa_s *bfa)
{
bfa_ioc_ownership_reset(&bfa->ioc);
bfa_ioc_pll_init(&bfa->ioc);
}
#endif
File diff suppressed because it is too large Load Diff
+46 -17
View File
@@ -36,6 +36,7 @@
* FCS sub-modules
*/
struct bfa_fcs_mod_s {
void (*attach) (struct bfa_fcs_s *fcs);
void (*modinit) (struct bfa_fcs_s *fcs);
void (*modexit) (struct bfa_fcs_s *fcs);
};
@@ -43,12 +44,10 @@ struct bfa_fcs_mod_s {
#define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit }
static struct bfa_fcs_mod_s fcs_modules[] = {
BFA_FCS_MODULE(bfa_fcs_pport),
BFA_FCS_MODULE(bfa_fcs_uf),
BFA_FCS_MODULE(bfa_fcs_fabric),
BFA_FCS_MODULE(bfa_fcs_vport),
BFA_FCS_MODULE(bfa_fcs_rport),
BFA_FCS_MODULE(bfa_fcs_fcpim),
{ bfa_fcs_pport_attach, NULL, NULL },
{ bfa_fcs_uf_attach, NULL, NULL },
{ bfa_fcs_fabric_attach, bfa_fcs_fabric_modinit,
bfa_fcs_fabric_modexit },
};
/**
@@ -71,16 +70,10 @@ bfa_fcs_exit_comp(void *fcs_cbarg)
*/
/**
* FCS instance initialization.
*
* param[in] fcs FCS instance
* param[in] bfa BFA instance
* param[in] bfad BFA driver instance
*
* return None
* fcs attach -- called once to initialize data structures at driver attach time
*/
void
bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
bfa_boolean_t min_cfg)
{
int i;
@@ -95,7 +88,24 @@ bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
mod = &fcs_modules[i];
mod->modinit(fcs);
if (mod->attach)
mod->attach(fcs);
}
}
/**
* fcs initialization, called once after bfa initialization is complete
*/
void
bfa_fcs_init(struct bfa_fcs_s *fcs)
{
int i;
struct bfa_fcs_mod_s *mod;
for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
mod = &fcs_modules[i];
if (mod->modinit)
mod->modinit(fcs);
}
}
@@ -126,6 +136,23 @@ bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
bfa_fcs_fabric_psymb_init(&fcs->fabric);
}
/**
* @brief
* FCS FDMI Driver Parameter Initialization
*
* @param[in] fcs FCS instance
* @param[in] fdmi_enable TRUE/FALSE
*
* @return None
*/
void
bfa_fcs_set_fdmi_param(struct bfa_fcs_s *fcs, bfa_boolean_t fdmi_enable)
{
fcs->fdmi_enabled = fdmi_enable;
}
/**
* FCS instance cleanup and exit.
*
@@ -143,10 +170,12 @@ bfa_fcs_exit(struct bfa_fcs_s *fcs)
nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]);
for (i = 0; i < nmods; i++) {
bfa_wc_up(&fcs->wc);
mod = &fcs_modules[i];
mod->modexit(fcs);
if (mod->modexit) {
bfa_wc_up(&fcs->wc);
mod->modexit(fcs);
}
}
bfa_wc_wait(&fcs->wc);
+35 -40
View File
@@ -114,7 +114,7 @@ bfa_fcs_port_sm_uninit(struct bfa_fcs_port_s *port,
break;
default:
bfa_assert(0);
bfa_sm_fault(port->fcs, event);
}
}
@@ -136,7 +136,7 @@ bfa_fcs_port_sm_init(struct bfa_fcs_port_s *port, enum bfa_fcs_port_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(port->fcs, event);
}
}
@@ -176,7 +176,7 @@ bfa_fcs_port_sm_online(struct bfa_fcs_port_s *port,
break;
default:
bfa_assert(0);
bfa_sm_fault(port->fcs, event);
}
}
@@ -214,7 +214,7 @@ bfa_fcs_port_sm_offline(struct bfa_fcs_port_s *port,
break;
default:
bfa_assert(0);
bfa_sm_fault(port->fcs, event);
}
}
@@ -234,7 +234,7 @@ bfa_fcs_port_sm_deleting(struct bfa_fcs_port_s *port,
break;
default:
bfa_assert(0);
bfa_sm_fault(port->fcs, event);
}
}
@@ -263,30 +263,8 @@ bfa_fcs_port_aen_post(struct bfa_fcs_port_s *port,
bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX);
switch (event) {
case BFA_LPORT_AEN_ONLINE:
bfa_log(logmod, BFA_AEN_LPORT_ONLINE, lpwwn_ptr,
role_str[role / 2]);
break;
case BFA_LPORT_AEN_OFFLINE:
bfa_log(logmod, BFA_AEN_LPORT_OFFLINE, lpwwn_ptr,
role_str[role / 2]);
break;
case BFA_LPORT_AEN_NEW:
bfa_log(logmod, BFA_AEN_LPORT_NEW, lpwwn_ptr,
role_str[role / 2]);
break;
case BFA_LPORT_AEN_DELETE:
bfa_log(logmod, BFA_AEN_LPORT_DELETE, lpwwn_ptr,
role_str[role / 2]);
break;
case BFA_LPORT_AEN_DISCONNECT:
bfa_log(logmod, BFA_AEN_LPORT_DISCONNECT, lpwwn_ptr,
role_str[role / 2]);
break;
default:
break;
}
bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, event), lpwwn_ptr,
role_str[role/2]);
aen_data.lport.vf_id = port->fabric->vf_id;
aen_data.lport.roles = role;
@@ -873,36 +851,46 @@ bfa_fcs_port_is_online(struct bfa_fcs_port_s *port)
}
/**
* Logical port initialization of base or virtual port.
* Called by fabric for base port or by vport for virtual ports.
* Attach time initialization of logical ports.
*/
void
bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
u16 vf_id, struct bfa_port_cfg_s *port_cfg,
struct bfa_fcs_vport_s *vport)
bfa_fcs_lport_attach(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
uint16_t vf_id, struct bfa_fcs_vport_s *vport)
{
lport->fcs = fcs;
lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id);
bfa_os_assign(lport->port_cfg, *port_cfg);
lport->vport = vport;
lport->lp_tag = (vport) ? bfa_lps_get_tag(vport->lps) :
bfa_lps_get_tag(lport->fabric->lps);
INIT_LIST_HEAD(&lport->rport_q);
lport->num_rports = 0;
}
lport->bfad_port =
bfa_fcb_port_new(fcs->bfad, lport, lport->port_cfg.roles,
/**
* Logical port initialization of base or virtual port.
* Called by fabric for base port or by vport for virtual ports.
*/
void
bfa_fcs_lport_init(struct bfa_fcs_port_s *lport,
struct bfa_port_cfg_s *port_cfg)
{
struct bfa_fcs_vport_s *vport = lport->vport;
bfa_os_assign(lport->port_cfg, *port_cfg);
lport->bfad_port = bfa_fcb_port_new(lport->fcs->bfad, lport,
lport->port_cfg.roles,
lport->fabric->vf_drv,
vport ? vport->vport_drv : NULL);
bfa_fcs_port_aen_post(lport, BFA_LPORT_AEN_NEW);
bfa_sm_set_state(lport, bfa_fcs_port_sm_uninit);
bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
}
/**
* fcs_lport_api
*/
@@ -921,13 +909,20 @@ bfa_fcs_port_get_attr(struct bfa_fcs_port_s *port,
if (port->fabric) {
port_attr->port_type = bfa_fcs_fabric_port_type(port->fabric);
port_attr->loopback = bfa_fcs_fabric_is_loopback(port->fabric);
port_attr->authfail =
bfa_fcs_fabric_is_auth_failed(port->fabric);
port_attr->fabric_name = bfa_fcs_port_get_fabric_name(port);
memcpy(port_attr->fabric_ip_addr,
bfa_fcs_port_get_fabric_ipaddr(port),
BFA_FCS_FABRIC_IPADDR_SZ);
if (port->vport != NULL)
if (port->vport != NULL) {
port_attr->port_type = BFA_PPORT_TYPE_VPORT;
port_attr->fpma_mac =
bfa_lps_get_lp_mac(port->vport->lps);
} else
port_attr->fpma_mac =
bfa_lps_get_lp_mac(port->fabric->lps);
} else {
port_attr->port_type = BFA_PPORT_TYPE_UNKNOWN;
+2 -9
View File
@@ -55,14 +55,7 @@ bfa_fcs_pport_event_handler(void *cbarg, bfa_pport_event_t event)
}
void
bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs)
bfa_fcs_pport_attach(struct bfa_fcs_s *fcs)
{
bfa_pport_event_register(fcs->bfa, bfa_fcs_pport_event_handler,
fcs);
}
void
bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs)
{
bfa_fcs_modexit_comp(fcs);
bfa_fcport_event_register(fcs->bfa, bfa_fcs_pport_event_handler, fcs);
}
+1 -7
View File
@@ -93,13 +93,7 @@ bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf)
}
void
bfa_fcs_uf_modinit(struct bfa_fcs_s *fcs)
bfa_fcs_uf_attach(struct bfa_fcs_s *fcs)
{
bfa_uf_recv_register(fcs->bfa, bfa_fcs_uf_recv, fcs);
}
void
bfa_fcs_uf_modexit(struct bfa_fcs_s *fcs)
{
bfa_fcs_modexit_comp(fcs);
}
+13
View File
@@ -52,6 +52,18 @@ bfa_hwcb_reginit(struct bfa_s *bfa)
}
}
void
bfa_hwcb_reqq_ack(struct bfa_s *bfa, int reqq)
{
}
static void
bfa_hwcb_reqq_ack_msix(struct bfa_s *bfa, int reqq)
{
bfa_reg_write(bfa->iocfc.bfa_regs.intr_status,
__HFN_INT_CPE_Q0 << CPE_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), reqq));
}
void
bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq)
{
@@ -136,6 +148,7 @@ bfa_hwcb_msix_uninstall(struct bfa_s *bfa)
void
bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
{
bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix;
bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix;
}
+9
View File
@@ -84,6 +84,15 @@ bfa_hwct_reginit(struct bfa_s *bfa)
}
}
void
bfa_hwct_reqq_ack(struct bfa_s *bfa, int reqq)
{
u32 r32;
r32 = bfa_reg_read(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq]);
bfa_reg_write(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq], r32);
}
void
bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq)
{
+81 -30
View File
@@ -15,7 +15,7 @@
* General Public License for more details.
*/
#include <bfa.h>
#include <bfi/bfi_cbreg.h>
#include <bfi/bfi_ctreg.h>
#include <bfa_port_priv.h>
#include <bfa_intr_priv.h>
#include <cs/bfa_debug.h>
@@ -34,6 +34,26 @@ bfa_msix_lpu(struct bfa_s *bfa)
bfa_ioc_mbox_isr(&bfa->ioc);
}
static void
bfa_reqq_resume(struct bfa_s *bfa, int qid)
{
struct list_head *waitq, *qe, *qen;
struct bfa_reqq_wait_s *wqe;
waitq = bfa_reqq(bfa, qid);
list_for_each_safe(qe, qen, waitq) {
/**
* Callback only as long as there is room in request queue
*/
if (bfa_reqq_full(bfa, qid))
break;
list_del(qe);
wqe = (struct bfa_reqq_wait_s *) qe;
wqe->qresume(wqe->cbarg);
}
}
void
bfa_msix_all(struct bfa_s *bfa, int vec)
{
@@ -96,7 +116,8 @@ bfa_isr_enable(struct bfa_s *bfa)
bfa_msix_install(bfa);
intr_unmask = (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
__HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS);
__HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS |
__HFN_INT_LL_HALT);
if (pci_func == 0)
intr_unmask |= (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 |
@@ -127,23 +148,18 @@ bfa_isr_disable(struct bfa_s *bfa)
void
bfa_msix_reqq(struct bfa_s *bfa, int qid)
{
struct list_head *waitq, *qe, *qen;
struct bfa_reqq_wait_s *wqe;
struct list_head *waitq;
qid &= (BFI_IOC_MAX_CQS - 1);
waitq = bfa_reqq(bfa, qid);
list_for_each_safe(qe, qen, waitq) {
/**
* Callback only as long as there is room in request queue
*/
if (bfa_reqq_full(bfa, qid))
break;
bfa->iocfc.hwif.hw_reqq_ack(bfa, qid);
list_del(qe);
wqe = (struct bfa_reqq_wait_s *) qe;
wqe->qresume(wqe->cbarg);
}
/**
* Resume any pending requests in the corresponding reqq.
*/
waitq = bfa_reqq(bfa, qid);
if (!list_empty(waitq))
bfa_reqq_resume(bfa, qid);
}
void
@@ -157,26 +173,27 @@ bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m)
}
void
bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid)
bfa_msix_rspq(struct bfa_s *bfa, int qid)
{
struct bfi_msg_s *m;
u32 pi, ci;
struct bfi_msg_s *m;
u32 pi, ci;
struct list_head *waitq;
bfa_trc_fp(bfa, rsp_qid);
bfa_trc_fp(bfa, qid);
rsp_qid &= (BFI_IOC_MAX_CQS - 1);
qid &= (BFI_IOC_MAX_CQS - 1);
bfa->iocfc.hwif.hw_rspq_ack(bfa, rsp_qid);
bfa->iocfc.hwif.hw_rspq_ack(bfa, qid);
ci = bfa_rspq_ci(bfa, rsp_qid);
pi = bfa_rspq_pi(bfa, rsp_qid);
ci = bfa_rspq_ci(bfa, qid);
pi = bfa_rspq_pi(bfa, qid);
bfa_trc_fp(bfa, ci);
bfa_trc_fp(bfa, pi);
if (bfa->rme_process) {
while (ci != pi) {
m = bfa_rspq_elem(bfa, rsp_qid, ci);
m = bfa_rspq_elem(bfa, qid, ci);
bfa_assert_fp(m->mhdr.msg_class < BFI_MC_MAX);
bfa_isrs[m->mhdr.msg_class] (bfa, m);
@@ -188,25 +205,59 @@ bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid)
/**
* update CI
*/
bfa_rspq_ci(bfa, rsp_qid) = pi;
bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[rsp_qid], pi);
bfa_rspq_ci(bfa, qid) = pi;
bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[qid], pi);
bfa_os_mmiowb();
/**
* Resume any pending requests in the corresponding reqq.
*/
waitq = bfa_reqq(bfa, qid);
if (!list_empty(waitq))
bfa_reqq_resume(bfa, qid);
}
void
bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
{
u32 intr;
u32 intr, curr_value;
intr = bfa_reg_read(bfa->iocfc.bfa_regs.intr_status);
if (intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1))
bfa_msix_lpu(bfa);
if (intr & (__HFN_INT_ERR_EMC |
__HFN_INT_ERR_LPU0 | __HFN_INT_ERR_LPU1 |
__HFN_INT_ERR_PSS))
intr &= (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
__HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS | __HFN_INT_LL_HALT);
if (intr) {
if (intr & __HFN_INT_LL_HALT) {
/**
* If LL_HALT bit is set then FW Init Halt LL Port
* Register needs to be cleared as well so Interrupt
* Status Register will be cleared.
*/
curr_value = bfa_reg_read(bfa->ioc.ioc_regs.ll_halt);
curr_value &= ~__FW_INIT_HALT_P;
bfa_reg_write(bfa->ioc.ioc_regs.ll_halt, curr_value);
}
if (intr & __HFN_INT_ERR_PSS) {
/**
* ERR_PSS bit needs to be cleared as well in case
* interrups are shared so driver's interrupt handler is
* still called eventhough it is already masked out.
*/
curr_value = bfa_reg_read(
bfa->ioc.ioc_regs.pss_err_status_reg);
curr_value &= __PSS_ERR_STATUS_SET;
bfa_reg_write(bfa->ioc.ioc_regs.pss_err_status_reg,
curr_value);
}
bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, intr);
bfa_msix_errint(bfa, intr);
}
}
void
+233 -527
View File
File diff suppressed because it is too large Load Diff
+54 -3
View File
@@ -74,15 +74,18 @@ struct bfa_ioc_regs_s {
bfa_os_addr_t lpu_mbox_cmd;
bfa_os_addr_t lpu_mbox;
bfa_os_addr_t pss_ctl_reg;
bfa_os_addr_t pss_err_status_reg;
bfa_os_addr_t app_pll_fast_ctl_reg;
bfa_os_addr_t app_pll_slow_ctl_reg;
bfa_os_addr_t ioc_sem_reg;
bfa_os_addr_t ioc_usage_sem_reg;
bfa_os_addr_t ioc_init_sem_reg;
bfa_os_addr_t ioc_usage_reg;
bfa_os_addr_t host_page_num_fn;
bfa_os_addr_t heartbeat;
bfa_os_addr_t ioc_fwstate;
bfa_os_addr_t ll_halt;
bfa_os_addr_t err_set;
bfa_os_addr_t shirq_isr_next;
bfa_os_addr_t shirq_msk_next;
bfa_os_addr_t smem_page_start;
@@ -154,7 +157,6 @@ struct bfa_ioc_s {
struct bfa_timer_s ioc_timer;
struct bfa_timer_s sem_timer;
u32 hb_count;
u32 hb_fail;
u32 retry_count;
struct list_head hb_notify_q;
void *dbg_fwsave;
@@ -177,6 +179,22 @@ struct bfa_ioc_s {
struct bfi_ioc_attr_s *attr;
struct bfa_ioc_cbfn_s *cbfn;
struct bfa_ioc_mbox_mod_s mbox_mod;
struct bfa_ioc_hwif_s *ioc_hwif;
};
struct bfa_ioc_hwif_s {
bfa_status_t (*ioc_pll_init) (struct bfa_ioc_s *ioc);
bfa_boolean_t (*ioc_firmware_lock) (struct bfa_ioc_s *ioc);
void (*ioc_firmware_unlock) (struct bfa_ioc_s *ioc);
u32 * (*ioc_fwimg_get_chunk) (struct bfa_ioc_s *ioc,
u32 off);
u32 (*ioc_fwimg_get_size) (struct bfa_ioc_s *ioc);
void (*ioc_reg_init) (struct bfa_ioc_s *ioc);
void (*ioc_map_port) (struct bfa_ioc_s *ioc);
void (*ioc_isr_mode_set) (struct bfa_ioc_s *ioc,
bfa_boolean_t msix);
void (*ioc_notify_hbfail) (struct bfa_ioc_s *ioc);
void (*ioc_ownership_reset) (struct bfa_ioc_s *ioc);
};
#define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func)
@@ -191,6 +209,15 @@ struct bfa_ioc_s {
#define bfa_ioc_rx_bbcredit(__ioc) ((__ioc)->attr->rx_bbcredit)
#define bfa_ioc_speed_sup(__ioc) \
BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop)
#define bfa_ioc_get_nports(__ioc) \
BFI_ADAPTER_GETP(NPORTS, (__ioc)->attr->adapter_prop)
#define bfa_ioc_stats(_ioc, _stats) ((_ioc)->stats._stats++)
#define BFA_IOC_FWIMG_MINSZ (16 * 1024)
#define BFA_IOC_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS)
#define BFA_IOC_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS)
#define BFA_IOC_FLASH_CHUNK_ADDR(chunkno) (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)
/**
* IOC mailbox interface
@@ -207,6 +234,14 @@ void bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc,
/**
* IOC interfaces
*/
#define bfa_ioc_pll_init(__ioc) ((__ioc)->ioc_hwif->ioc_pll_init(__ioc))
#define bfa_ioc_isr_mode_set(__ioc, __msix) \
((__ioc)->ioc_hwif->ioc_isr_mode_set(__ioc, __msix))
#define bfa_ioc_ownership_reset(__ioc) \
((__ioc)->ioc_hwif->ioc_ownership_reset(__ioc))
void bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc);
void bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc);
void bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa,
struct bfa_ioc_cbfn_s *cbfn, struct bfa_timer_mod_s *timer_mod,
struct bfa_trc_mod_s *trcmod,
@@ -223,13 +258,21 @@ bfa_boolean_t bfa_ioc_intx_claim(struct bfa_ioc_s *ioc);
void bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param);
void bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *msg);
void bfa_ioc_error_isr(struct bfa_ioc_s *ioc);
void bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t intx);
bfa_status_t bfa_ioc_pll_init(struct bfa_ioc_s *ioc);
bfa_boolean_t bfa_ioc_is_operational(struct bfa_ioc_s *ioc);
bfa_boolean_t bfa_ioc_is_disabled(struct bfa_ioc_s *ioc);
bfa_boolean_t bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc);
bfa_boolean_t bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc);
void bfa_ioc_cfg_complete(struct bfa_ioc_s *ioc);
enum bfa_ioc_type_e bfa_ioc_get_type(struct bfa_ioc_s *ioc);
void bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num);
void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver);
void bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver);
void bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model);
void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc,
char *manufacturer);
void bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev);
enum bfa_ioc_state bfa_ioc_get_state(struct bfa_ioc_s *ioc);
void bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr);
void bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
struct bfa_adapter_attr_s *ad_attr);
@@ -237,6 +280,7 @@ int bfa_ioc_debug_trcsz(bfa_boolean_t auto_recover);
void bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave);
bfa_status_t bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata,
int *trclen);
void bfa_ioc_debug_fwsave_clear(struct bfa_ioc_s *ioc);
bfa_status_t bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata,
int *trclen);
u32 bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr);
@@ -245,6 +289,13 @@ void bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc);
bfa_boolean_t bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc);
void bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc,
struct bfa_ioc_hbfail_notify_s *notify);
bfa_boolean_t bfa_ioc_sem_get(bfa_os_addr_t sem_reg);
void bfa_ioc_sem_release(bfa_os_addr_t sem_reg);
void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc);
void bfa_ioc_fwver_get(struct bfa_ioc_s *ioc,
struct bfi_ioc_image_hdr_s *fwhdr);
bfa_boolean_t bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc,
struct bfi_ioc_image_hdr_s *fwhdr);
/*
* bfa mfg wwn API functions
+274
View File
@@ -0,0 +1,274 @@
/*
* Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
* All rights reserved
* www.brocade.com
*
* Linux driver for Brocade Fibre Channel Host Bus Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#include <bfa.h>
#include <bfa_ioc.h>
#include <bfa_fwimg_priv.h>
#include <cna/bfa_cna_trcmod.h>
#include <cs/bfa_debug.h>
#include <bfi/bfi_ioc.h>
#include <bfi/bfi_cbreg.h>
#include <log/bfa_log_hal.h>
#include <defs/bfa_defs_pci.h>
BFA_TRC_FILE(CNA, IOC_CB);
/*
* forward declarations
*/
static bfa_status_t bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc);
static bfa_boolean_t bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc);
static void bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc);
static u32 *bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off);
static u32 bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc);
static void bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc);
static void bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc);
static void bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
static void bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc);
static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc);
struct bfa_ioc_hwif_s hwif_cb = {
bfa_ioc_cb_pll_init,
bfa_ioc_cb_firmware_lock,
bfa_ioc_cb_firmware_unlock,
bfa_ioc_cb_fwimg_get_chunk,
bfa_ioc_cb_fwimg_get_size,
bfa_ioc_cb_reg_init,
bfa_ioc_cb_map_port,
bfa_ioc_cb_isr_mode_set,
bfa_ioc_cb_notify_hbfail,
bfa_ioc_cb_ownership_reset,
};
/**
* Called from bfa_ioc_attach() to map asic specific calls.
*/
void
bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc)
{
ioc->ioc_hwif = &hwif_cb;
}
static u32 *
bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
{
return bfi_image_cb_get_chunk(off);
}
static u32
bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc)
{
return bfi_image_cb_size;
}
/**
* Return true if firmware of current driver matches the running firmware.
*/
static bfa_boolean_t
bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc)
{
return BFA_TRUE;
}
static void
bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc)
{
}
/**
* Notify other functions on HB failure.
*/
static void
bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc)
{
bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET);
bfa_reg_read(ioc->ioc_regs.err_set);
}
/**
* Host to LPU mailbox message addresses
*/
static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
{ HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
{ HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 }
};
/**
* Host <-> LPU mailbox command/status registers
*/
static struct { u32 hfn, lpu; } iocreg_mbcmd[] = {
{ HOSTFN0_LPU0_CMD_STAT, LPU0_HOSTFN0_CMD_STAT },
{ HOSTFN1_LPU1_CMD_STAT, LPU1_HOSTFN1_CMD_STAT }
};
static void
bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc)
{
bfa_os_addr_t rb;
int pcifn = bfa_ioc_pcifn(ioc);
rb = bfa_ioc_bar0(ioc);
ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
if (ioc->port_id == 0) {
ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
} else {
ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
}
/**
* Host <-> LPU mailbox command/status registers
*/
ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd[pcifn].hfn;
ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd[pcifn].lpu;
/*
* PSS control registers
*/
ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_400_CTL_REG);
ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_212_CTL_REG);
/*
* IOC semaphore registers and serialization
*/
ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
/**
* sram memory access
*/
ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB;
/*
* err set reg : for notification of hb failure
*/
ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
}
/**
* Initialize IOC to port mapping.
*/
static void
bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc)
{
/**
* For crossbow, port id is same as pci function.
*/
ioc->port_id = bfa_ioc_pcifn(ioc);
bfa_trc(ioc, ioc->port_id);
}
/**
* Set interrupt mode for a function: INTX or MSIX
*/
static void
bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
{
}
static bfa_status_t
bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc)
{
bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
u32 pll_sclk, pll_fclk;
/*
* Hold semaphore so that nobody can access the chip during init.
*/
bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
pll_sclk = __APP_PLL_212_ENABLE | __APP_PLL_212_LRESETN |
__APP_PLL_212_P0_1(3U) |
__APP_PLL_212_JITLMT0_1(3U) |
__APP_PLL_212_CNTLMT0_1(3U);
pll_fclk = __APP_PLL_400_ENABLE | __APP_PLL_400_LRESETN |
__APP_PLL_400_RSEL200500 | __APP_PLL_400_P0_1(3U) |
__APP_PLL_400_JITLMT0_1(3U) |
__APP_PLL_400_CNTLMT0_1(3U);
bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
__APP_PLL_212_LOGIC_SOFT_RESET);
bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
__APP_PLL_212_BYPASS |
__APP_PLL_212_LOGIC_SOFT_RESET);
bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
__APP_PLL_400_LOGIC_SOFT_RESET);
bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
__APP_PLL_400_BYPASS |
__APP_PLL_400_LOGIC_SOFT_RESET);
bfa_os_udelay(2);
bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
__APP_PLL_212_LOGIC_SOFT_RESET);
bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
__APP_PLL_400_LOGIC_SOFT_RESET);
bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
pll_sclk | __APP_PLL_212_LOGIC_SOFT_RESET);
bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
pll_fclk | __APP_PLL_400_LOGIC_SOFT_RESET);
/**
* Wait for PLLs to lock.
*/
bfa_os_udelay(2000);
bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk);
bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk);
/*
* release semaphore.
*/
bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
return BFA_STATUS_OK;
}
/**
* Cleanup hw semaphore and usecnt registers
*/
static void
bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc)
{
/*
* Read the hw sem reg to make sure that it is locked
* before we clear it. If it is not locked, writing 1
* will lock it instead of clearing it.
*/
bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
bfa_ioc_hw_sem_release(ioc);
}
+423
View File
@@ -0,0 +1,423 @@
/*
* Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
* All rights reserved
* www.brocade.com
*
* Linux driver for Brocade Fibre Channel Host Bus Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#include <bfa.h>
#include <bfa_ioc.h>
#include <bfa_fwimg_priv.h>
#include <cna/bfa_cna_trcmod.h>
#include <cs/bfa_debug.h>
#include <bfi/bfi_ioc.h>
#include <bfi/bfi_ctreg.h>
#include <log/bfa_log_hal.h>
#include <defs/bfa_defs_pci.h>
BFA_TRC_FILE(CNA, IOC_CT);
/*
* forward declarations
*/
static bfa_status_t bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc);
static bfa_boolean_t bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc);
static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc);
static u32* bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc,
u32 off);
static u32 bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc);
static void bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc);
static void bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc);
static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc);
static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc);
struct bfa_ioc_hwif_s hwif_ct = {
bfa_ioc_ct_pll_init,
bfa_ioc_ct_firmware_lock,
bfa_ioc_ct_firmware_unlock,
bfa_ioc_ct_fwimg_get_chunk,
bfa_ioc_ct_fwimg_get_size,
bfa_ioc_ct_reg_init,
bfa_ioc_ct_map_port,
bfa_ioc_ct_isr_mode_set,
bfa_ioc_ct_notify_hbfail,
bfa_ioc_ct_ownership_reset,
};
/**
* Called from bfa_ioc_attach() to map asic specific calls.
*/
void
bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc)
{
ioc->ioc_hwif = &hwif_ct;
}
static u32*
bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
{
return bfi_image_ct_get_chunk(off);
}
static u32
bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc)
{
return bfi_image_ct_size;
}
/**
* Return true if firmware of current driver matches the running firmware.
*/
static bfa_boolean_t
bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
{
enum bfi_ioc_state ioc_fwstate;
u32 usecnt;
struct bfi_ioc_image_hdr_s fwhdr;
/**
* Firmware match check is relevant only for CNA.
*/
if (!ioc->cna)
return BFA_TRUE;
/**
* If bios boot (flash based) -- do not increment usage count
*/
if (bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
return BFA_TRUE;
bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
/**
* If usage count is 0, always return TRUE.
*/
if (usecnt == 0) {
bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1);
bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
bfa_trc(ioc, usecnt);
return BFA_TRUE;
}
ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
bfa_trc(ioc, ioc_fwstate);
/**
* Use count cannot be non-zero and chip in uninitialized state.
*/
bfa_assert(ioc_fwstate != BFI_IOC_UNINIT);
/**
* Check if another driver with a different firmware is active
*/
bfa_ioc_fwver_get(ioc, &fwhdr);
if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
bfa_trc(ioc, usecnt);
return BFA_FALSE;
}
/**
* Same firmware version. Increment the reference count.
*/
usecnt++;
bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
bfa_trc(ioc, usecnt);
return BFA_TRUE;
}
static void
bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc)
{
u32 usecnt;
/**
* Firmware lock is relevant only for CNA.
* If bios boot (flash based) -- do not decrement usage count
*/
if (!ioc->cna || bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
return;
/**
* decrement usage count
*/
bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
bfa_assert(usecnt > 0);
usecnt--;
bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
bfa_trc(ioc, usecnt);
bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
}
/**
* Notify other functions on HB failure.
*/
static void
bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc)
{
if (ioc->cna) {
bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P);
/* Wait for halt to take effect */
bfa_reg_read(ioc->ioc_regs.ll_halt);
} else {
bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET);
bfa_reg_read(ioc->ioc_regs.err_set);
}
}
/**
* Host to LPU mailbox message addresses
*/
static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
{ HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
{ HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 },
{ HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 },
{ HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 }
};
/**
* Host <-> LPU mailbox command/status registers - port 0
*/
static struct { u32 hfn, lpu; } iocreg_mbcmd_p0[] = {
{ HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT },
{ HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT },
{ HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT },
{ HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT }
};
/**
* Host <-> LPU mailbox command/status registers - port 1
*/
static struct { u32 hfn, lpu; } iocreg_mbcmd_p1[] = {
{ HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT },
{ HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT },
{ HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT },
{ HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT }
};
static void
bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc)
{
bfa_os_addr_t rb;
int pcifn = bfa_ioc_pcifn(ioc);
rb = bfa_ioc_bar0(ioc);
ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
if (ioc->port_id == 0) {
ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
} else {
ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
}
/*
* PSS control registers
*/
ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
/*
* IOC semaphore registers and serialization
*/
ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
/**
* sram memory access
*/
ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
/*
* err set reg : for notification of hb failure in fcmode
*/
ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
}
/**
* Initialize IOC to port mapping.
*/
#define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8)
static void
bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc)
{
bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
u32 r32;
/**
* For catapult, base port id on personality register and IOC type
*/
r32 = bfa_reg_read(rb + FNC_PERS_REG);
r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
bfa_trc(ioc, bfa_ioc_pcifn(ioc));
bfa_trc(ioc, ioc->port_id);
}
/**
* Set interrupt mode for a function: INTX or MSIX
*/
static void
bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
{
bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
u32 r32, mode;
r32 = bfa_reg_read(rb + FNC_PERS_REG);
bfa_trc(ioc, r32);
mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
__F0_INTX_STATUS;
/**
* If already in desired mode, do not change anything
*/
if (!msix && mode)
return;
if (msix)
mode = __F0_INTX_STATUS_MSIX;
else
mode = __F0_INTX_STATUS_INTA;
r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
bfa_trc(ioc, r32);
bfa_reg_write(rb + FNC_PERS_REG, r32);
}
static bfa_status_t
bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc)
{
bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
u32 pll_sclk, pll_fclk, r32;
/*
* Hold semaphore so that nobody can access the chip during init.
*/
bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
pll_sclk = __APP_PLL_312_LRESETN | __APP_PLL_312_ENARST |
__APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(3U) |
__APP_PLL_312_JITLMT0_1(3U) |
__APP_PLL_312_CNTLMT0_1(1U);
pll_fclk = __APP_PLL_425_LRESETN | __APP_PLL_425_ENARST |
__APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
__APP_PLL_425_JITLMT0_1(3U) |
__APP_PLL_425_CNTLMT0_1(1U);
/**
* For catapult, choose operational mode FC/FCoE
*/
if (ioc->fcmode) {
bfa_reg_write((rb + OP_MODE), 0);
bfa_reg_write((rb + ETH_MAC_SER_REG),
__APP_EMS_CMLCKSEL |
__APP_EMS_REFCKBUFEN2 |
__APP_EMS_CHANNEL_SEL);
} else {
ioc->pllinit = BFA_TRUE;
bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE);
bfa_reg_write((rb + ETH_MAC_SER_REG),
__APP_EMS_REFCKBUFEN1);
}
bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
__APP_PLL_312_LOGIC_SOFT_RESET);
bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
__APP_PLL_425_LOGIC_SOFT_RESET);
bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
__APP_PLL_312_LOGIC_SOFT_RESET | __APP_PLL_312_ENABLE);
bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
__APP_PLL_425_LOGIC_SOFT_RESET | __APP_PLL_425_ENABLE);
/**
* Wait for PLLs to lock.
*/
bfa_reg_read(rb + HOSTFN0_INT_MSK);
bfa_os_udelay(2000);
bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
__APP_PLL_312_ENABLE);
bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
__APP_PLL_425_ENABLE);
bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
bfa_os_udelay(1000);
r32 = bfa_reg_read((rb + MBIST_STAT_REG));
bfa_trc(ioc, r32);
/*
* release semaphore.
*/
bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
return BFA_STATUS_OK;
}
/**
* Cleanup hw semaphore and usecnt registers
*/
static void
bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc)
{
if (ioc->cna) {
bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 0);
bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
}
/*
* Read the hw sem reg to make sure that it is locked
* before we clear it. If it is not locked, writing 1
* will lock it instead of clearing it.
*/
bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
bfa_ioc_hw_sem_release(ioc);
}
+19 -5
View File
@@ -172,6 +172,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
*/
if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) {
iocfc->hwif.hw_reginit = bfa_hwct_reginit;
iocfc->hwif.hw_reqq_ack = bfa_hwct_reqq_ack;
iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack;
iocfc->hwif.hw_msix_init = bfa_hwct_msix_init;
iocfc->hwif.hw_msix_install = bfa_hwct_msix_install;
@@ -180,6 +181,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs;
} else {
iocfc->hwif.hw_reginit = bfa_hwcb_reginit;
iocfc->hwif.hw_reqq_ack = bfa_hwcb_reqq_ack;
iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init;
iocfc->hwif.hw_msix_install = bfa_hwcb_msix_install;
@@ -336,8 +338,10 @@ bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete)
bfa_cb_init(bfa->bfad, BFA_STATUS_OK);
else
bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED);
} else
bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
} else {
if (bfa->iocfc.cfgdone)
bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
}
}
static void
@@ -619,8 +623,6 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
bfa_ioc_attach(&bfa->ioc, bfa, &bfa_iocfc_cbfn, &bfa->timer_mod,
bfa->trcmod, bfa->aen, bfa->logm);
bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC);
bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs);
/**
* Choose FC (ssid: 0x1C) v/s FCoE (ssid: 0x14) mode.
@@ -628,6 +630,9 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
if (0)
bfa_ioc_set_fcmode(&bfa->ioc);
bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC);
bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs);
bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev);
bfa_iocfc_mem_claim(bfa, cfg, meminfo);
bfa_timer_init(&bfa->timer_mod);
@@ -654,7 +659,6 @@ bfa_iocfc_init(struct bfa_s *bfa)
{
bfa->iocfc.action = BFA_IOCFC_ACT_INIT;
bfa_ioc_enable(&bfa->ioc);
bfa_msix_install(bfa);
}
/**
@@ -797,6 +801,11 @@ bfa_iocfc_get_stats(struct bfa_s *bfa, struct bfa_iocfc_stats_s *stats,
return BFA_STATUS_DEVBUSY;
}
if (!bfa_iocfc_is_operational(bfa)) {
bfa_trc(bfa, 0);
return BFA_STATUS_IOC_NON_OP;
}
iocfc->stats_busy = BFA_TRUE;
iocfc->stats_ret = stats;
iocfc->stats_cbfn = cbfn;
@@ -817,6 +826,11 @@ bfa_iocfc_clear_stats(struct bfa_s *bfa, bfa_cb_ioc_t cbfn, void *cbarg)
return BFA_STATUS_DEVBUSY;
}
if (!bfa_iocfc_is_operational(bfa)) {
bfa_trc(bfa, 0);
return BFA_STATUS_IOC_NON_OP;
}
iocfc->stats_busy = BFA_TRUE;
iocfc->stats_cbfn = cbfn;
iocfc->stats_cbarg = cbarg;
+3
View File
@@ -54,6 +54,7 @@ struct bfa_msix_s {
*/
struct bfa_hwif_s {
void (*hw_reginit)(struct bfa_s *bfa);
void (*hw_reqq_ack)(struct bfa_s *bfa, int reqq);
void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq);
void (*hw_msix_init)(struct bfa_s *bfa, int nvecs);
void (*hw_msix_install)(struct bfa_s *bfa);
@@ -143,6 +144,7 @@ void bfa_msix_rspq(struct bfa_s *bfa, int vec);
void bfa_msix_lpu_err(struct bfa_s *bfa, int vec);
void bfa_hwcb_reginit(struct bfa_s *bfa);
void bfa_hwcb_reqq_ack(struct bfa_s *bfa, int rspq);
void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq);
void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs);
void bfa_hwcb_msix_install(struct bfa_s *bfa);
@@ -151,6 +153,7 @@ void bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix);
void bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *vecmap,
u32 *nvecs, u32 *maxvec);
void bfa_hwct_reginit(struct bfa_s *bfa);
void bfa_hwct_reqq_ack(struct bfa_s *bfa, int rspq);
void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq);
void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs);
void bfa_hwct_msix_install(struct bfa_s *bfa);
+11 -11
View File
@@ -149,7 +149,7 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(ioim->bfa, event);
}
}
@@ -194,7 +194,7 @@ bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(ioim->bfa, event);
}
}
@@ -259,7 +259,7 @@ bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(ioim->bfa, event);
}
}
@@ -317,7 +317,7 @@ bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(ioim->bfa, event);
}
}
@@ -377,7 +377,7 @@ bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(ioim->bfa, event);
}
}
@@ -419,7 +419,7 @@ bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(ioim->bfa, event);
}
}
@@ -467,7 +467,7 @@ bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(ioim->bfa, event);
}
}
@@ -516,7 +516,7 @@ bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(ioim->bfa, event);
}
}
@@ -544,7 +544,7 @@ bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(ioim->bfa, event);
}
}
@@ -577,7 +577,7 @@ bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(ioim->bfa, event);
}
}
@@ -605,7 +605,7 @@ bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(ioim->bfa, event);
}
}
+15 -15
View File
@@ -144,7 +144,7 @@ bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(itnim->bfa, event);
}
}
@@ -175,7 +175,7 @@ bfa_itnim_sm_created(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(itnim->bfa, event);
}
}
@@ -212,7 +212,7 @@ bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(itnim->bfa, event);
}
}
@@ -247,7 +247,7 @@ bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim,
break;
default:
bfa_assert(0);
bfa_sm_fault(itnim->bfa, event);
}
}
@@ -275,7 +275,7 @@ bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
break;
default:
bfa_assert(0);
bfa_sm_fault(itnim->bfa, event);
}
}
@@ -317,7 +317,7 @@ bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(itnim->bfa, event);
}
}
@@ -348,7 +348,7 @@ bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(itnim->bfa, event);
}
}
@@ -385,7 +385,7 @@ bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
break;
default:
bfa_assert(0);
bfa_sm_fault(itnim->bfa, event);
}
}
@@ -413,7 +413,7 @@ bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim,
break;
default:
bfa_assert(0);
bfa_sm_fault(itnim->bfa, event);
}
}
@@ -442,7 +442,7 @@ bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(itnim->bfa, event);
}
}
@@ -470,7 +470,7 @@ bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
break;
default:
bfa_assert(0);
bfa_sm_fault(itnim->bfa, event);
}
}
@@ -502,7 +502,7 @@ bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(itnim->bfa, event);
}
}
@@ -538,7 +538,7 @@ bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
break;
default:
bfa_assert(0);
bfa_sm_fault(itnim->bfa, event);
}
}
@@ -559,7 +559,7 @@ bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(itnim->bfa, event);
}
}
@@ -583,7 +583,7 @@ bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
break;
default:
bfa_assert(0);
bfa_sm_fault(itnim->bfa, event);
}
}
+125 -9
View File
@@ -18,6 +18,7 @@
#include <bfa.h>
#include <bfi/bfi_lps.h>
#include <cs/bfa_debug.h>
#include <defs/bfa_defs_pci.h>
BFA_TRC_FILE(HAL, LPS);
BFA_MODULE(lps);
@@ -25,6 +26,12 @@ BFA_MODULE(lps);
#define BFA_LPS_MIN_LPORTS (1)
#define BFA_LPS_MAX_LPORTS (256)
/*
* Maximum Vports supported per physical port or vf.
*/
#define BFA_LPS_MAX_VPORTS_SUPP_CB 255
#define BFA_LPS_MAX_VPORTS_SUPP_CT 190
/**
* forward declarations
*/
@@ -49,7 +56,7 @@ static void bfa_lps_send_login(struct bfa_lps_s *lps);
static void bfa_lps_send_logout(struct bfa_lps_s *lps);
static void bfa_lps_login_comp(struct bfa_lps_s *lps);
static void bfa_lps_logout_comp(struct bfa_lps_s *lps);
static void bfa_lps_cvl_event(struct bfa_lps_s *lps);
/**
* lps_pvt BFA LPS private functions
@@ -62,6 +69,7 @@ enum bfa_lps_event {
BFA_LPS_SM_RESUME = 4, /* space present in reqq queue */
BFA_LPS_SM_DELETE = 5, /* lps delete from user */
BFA_LPS_SM_OFFLINE = 6, /* Link is offline */
BFA_LPS_SM_RX_CVL = 7, /* Rx clear virtual link */
};
static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event);
@@ -91,6 +99,12 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
bfa_sm_set_state(lps, bfa_lps_sm_login);
bfa_lps_send_login(lps);
}
if (lps->fdisc)
bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
BFA_PL_EID_LOGIN, 0, "FDISC Request");
else
bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
BFA_PL_EID_LOGIN, 0, "FLOGI Request");
break;
case BFA_LPS_SM_LOGOUT:
@@ -101,6 +115,7 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
bfa_lps_free(lps);
break;
case BFA_LPS_SM_RX_CVL:
case BFA_LPS_SM_OFFLINE:
break;
@@ -112,7 +127,7 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(lps->bfa, event);
}
}
@@ -127,10 +142,25 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
switch (event) {
case BFA_LPS_SM_FWRSP:
if (lps->status == BFA_STATUS_OK)
if (lps->status == BFA_STATUS_OK) {
bfa_sm_set_state(lps, bfa_lps_sm_online);
else
if (lps->fdisc)
bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
BFA_PL_EID_LOGIN, 0, "FDISC Accept");
else
bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
BFA_PL_EID_LOGIN, 0, "FLOGI Accept");
} else {
bfa_sm_set_state(lps, bfa_lps_sm_init);
if (lps->fdisc)
bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
BFA_PL_EID_LOGIN, 0,
"FDISC Fail (RJT or timeout)");
else
bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
BFA_PL_EID_LOGIN, 0,
"FLOGI Fail (RJT or timeout)");
}
bfa_lps_login_comp(lps);
break;
@@ -139,7 +169,7 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(lps->bfa, event);
}
}
@@ -162,8 +192,16 @@ bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event)
bfa_reqq_wcancel(&lps->wqe);
break;
case BFA_LPS_SM_RX_CVL:
/*
* Login was not even sent out; so when getting out
* of this state, it will appear like a login retry
* after Clear virtual link
*/
break;
default:
bfa_assert(0);
bfa_sm_fault(lps->bfa, event);
}
}
@@ -185,6 +223,17 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
bfa_sm_set_state(lps, bfa_lps_sm_logout);
bfa_lps_send_logout(lps);
}
bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
BFA_PL_EID_LOGO, 0, "Logout");
break;
case BFA_LPS_SM_RX_CVL:
bfa_sm_set_state(lps, bfa_lps_sm_init);
/* Let the vport module know about this event */
bfa_lps_cvl_event(lps);
bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx");
break;
case BFA_LPS_SM_OFFLINE:
@@ -193,7 +242,7 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(lps->bfa, event);
}
}
@@ -217,7 +266,7 @@ bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(lps->bfa, event);
}
}
@@ -242,7 +291,7 @@ bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event event)
break;
default:
bfa_assert(0);
bfa_sm_fault(lps->bfa, event);
}
}
@@ -395,6 +444,20 @@ bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp)
bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP);
}
/**
* Firmware received a Clear virtual link request (for FCoE)
*/
static void
bfa_lps_rx_cvl_event(struct bfa_s *bfa, struct bfi_lps_cvl_event_s *cvl)
{
struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa);
struct bfa_lps_s *lps;
lps = BFA_LPS_FROM_TAG(mod, cvl->lp_tag);
bfa_sm_send_event(lps, BFA_LPS_SM_RX_CVL);
}
/**
* Space is available in request queue, resume queueing request to firmware.
*/
@@ -531,7 +594,48 @@ bfa_lps_logout_comp(struct bfa_lps_s *lps)
bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg);
}
/**
* Clear virtual link completion handler for non-fcs
*/
static void
bfa_lps_cvl_event_cb(void *arg, bfa_boolean_t complete)
{
struct bfa_lps_s *lps = arg;
if (!complete)
return;
/* Clear virtual link to base port will result in link down */
if (lps->fdisc)
bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg);
}
/**
* Received Clear virtual link event --direct call for fcs,
* queue for others
*/
static void
bfa_lps_cvl_event(struct bfa_lps_s *lps)
{
if (!lps->bfa->fcs) {
bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_cvl_event_cb,
lps);
return;
}
/* Clear virtual link to base port will result in link down */
if (lps->fdisc)
bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg);
}
u32
bfa_lps_get_max_vport(struct bfa_s *bfa)
{
if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT)
return BFA_LPS_MAX_VPORTS_SUPP_CT;
else
return BFA_LPS_MAX_VPORTS_SUPP_CB;
}
/**
* lps_public BFA LPS public functions
@@ -752,6 +856,14 @@ bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps)
return lps->lsrjt_expl;
}
/**
* Return fpma/spma MAC for lport
*/
struct mac_s
bfa_lps_get_lp_mac(struct bfa_lps_s *lps)
{
return lps->lp_mac;
}
/**
* LPS firmware message class handler.
@@ -773,6 +885,10 @@ bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
bfa_lps_logout_rsp(bfa, msg.logout_rsp);
break;
case BFI_LPS_H2I_CVL_EVENT:
bfa_lps_rx_cvl_event(bfa, msg.cvl_event);
break;
default:
bfa_trc(bfa, m->mhdr.msg_id);
bfa_assert(0);
+2 -2
View File
@@ -24,7 +24,7 @@
*/
struct bfa_module_s *hal_mods[] = {
&hal_mod_sgpg,
&hal_mod_pport,
&hal_mod_fcport,
&hal_mod_fcxp,
&hal_mod_lps,
&hal_mod_uf,
@@ -45,7 +45,7 @@ bfa_isr_func_t bfa_isrs[BFI_MC_MAX] = {
bfa_isr_unhandled, /* BFI_MC_DIAG */
bfa_isr_unhandled, /* BFI_MC_FLASH */
bfa_isr_unhandled, /* BFI_MC_CEE */
bfa_pport_isr, /* BFI_MC_PORT */
bfa_fcport_isr, /* BFI_MC_FCPORT */
bfa_isr_unhandled, /* BFI_MC_IOCFC */
bfa_isr_unhandled, /* BFI_MC_LL */
bfa_uf_isr, /* BFI_MC_UF */

Some files were not shown because too many files have changed in this diff Show More