Commit 775c7742 authored by Krishna Gudipati's avatar Krishna Gudipati Committed by James Bottomley

[SCSI] bfa: IOC and PLL init changes for Brocade-1860 Fabric Adapter.

- Introduced IOC poll mechanism which replaces current interrupt
  based FW READY method.
- The timer based poll routine in IOC will query the ioc_fwstate
  register to see if there is a state change in FW, and sends the READY event.
- Bug fixes in the new asic PLL initialization.
- Added logic to handle CPE/RME queue interrupts before iocfc config done.
  1. Use the queue_process flag to see if iocfc configuration is done
     in INTX mode.
  2. Split the MSIX handler installation in two - one for IOC intr
     handler and the other for cpe/rme queue handler - and delay
     assigning queue handlers until iocfc config is done in MSIX mode.
Signed-off-by: default avatarKrishna Gudipati <kgudipat@brocade.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent dd5aaf45
......@@ -228,7 +228,8 @@ struct bfa_hwif_s {
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);
void (*hw_msix_ctrl_install)(struct bfa_s *bfa);
void (*hw_msix_queue_install)(struct bfa_s *bfa);
void (*hw_msix_uninstall)(struct bfa_s *bfa);
void (*hw_isr_mode_set)(struct bfa_s *bfa, bfa_boolean_t msix);
void (*hw_msix_getvecs)(struct bfa_s *bfa, u32 *vecmap,
......@@ -271,8 +272,10 @@ struct bfa_iocfc_s {
bfa_ioc_portid(&(__bfa)->ioc)
#define bfa_msix_init(__bfa, __nvecs) \
((__bfa)->iocfc.hwif.hw_msix_init(__bfa, __nvecs))
#define bfa_msix_install(__bfa) \
((__bfa)->iocfc.hwif.hw_msix_install(__bfa))
#define bfa_msix_ctrl_install(__bfa) \
((__bfa)->iocfc.hwif.hw_msix_ctrl_install(__bfa))
#define bfa_msix_queue_install(__bfa) \
((__bfa)->iocfc.hwif.hw_msix_queue_install(__bfa))
#define bfa_msix_uninstall(__bfa) \
((__bfa)->iocfc.hwif.hw_msix_uninstall(__bfa))
#define bfa_isr_mode_set(__bfa, __msix) do { \
......@@ -314,7 +317,8 @@ 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);
void bfa_hwcb_msix_ctrl_install(struct bfa_s *bfa);
void bfa_hwcb_msix_queue_install(struct bfa_s *bfa);
void bfa_hwcb_msix_uninstall(struct bfa_s *bfa);
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,
......@@ -326,7 +330,8 @@ void bfa_hwct2_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);
void bfa_hwct_msix_ctrl_install(struct bfa_s *bfa);
void bfa_hwct_msix_queue_install(struct bfa_s *bfa);
void bfa_hwct_msix_uninstall(struct bfa_s *bfa);
void bfa_hwct_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix);
void bfa_hwct_msix_getvecs(struct bfa_s *bfa, u32 *vecmap, u32 *nvecs,
......
......@@ -248,7 +248,7 @@ bfa_intx(struct bfa_s *bfa)
writel(qintr, bfa->iocfc.bfa_regs.intr_status);
for (queue = 0; queue < BFI_IOC_MAX_CQS_ASIC; queue++) {
if (intr & (__HFN_INT_RME_Q0 << queue))
if ((intr & (__HFN_INT_RME_Q0 << queue)) && bfa->queue_process)
bfa_isr_rspq(bfa, queue & (BFI_IOC_MAX_CQS - 1));
}
intr &= ~qintr;
......@@ -262,7 +262,7 @@ bfa_intx(struct bfa_s *bfa)
writel(qintr, bfa->iocfc.bfa_regs.intr_status);
for (queue = 0; queue < BFI_IOC_MAX_CQS_ASIC; queue++) {
if (intr & (__HFN_INT_CPE_Q0 << queue))
if ((intr & (__HFN_INT_CPE_Q0 << queue)) && bfa->queue_process)
bfa_isr_reqq(bfa, queue & (BFI_IOC_MAX_CQS - 1));
}
intr &= ~qintr;
......@@ -282,7 +282,7 @@ bfa_isr_enable(struct bfa_s *bfa)
bfa_trc(bfa, pci_func);
bfa_msix_install(bfa);
bfa_msix_ctrl_install(bfa);
if (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id)) {
umsk = __HFN_INT_ERR_MASK_CT2;
......@@ -326,9 +326,6 @@ bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m)
void
bfa_msix_rspq(struct bfa_s *bfa, int vec)
{
if (!bfa->rme_process)
return;
bfa_isr_rspq(bfa, vec - bfa->iocfc.hwif.rme_vec_q0);
}
......@@ -512,7 +509,8 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
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;
iocfc->hwif.hw_msix_ctrl_install = bfa_hwct_msix_ctrl_install;
iocfc->hwif.hw_msix_queue_install = bfa_hwct_msix_queue_install;
iocfc->hwif.hw_msix_uninstall = bfa_hwct_msix_uninstall;
iocfc->hwif.hw_isr_mode_set = bfa_hwct_isr_mode_set;
iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs;
......@@ -524,7 +522,8 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
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;
iocfc->hwif.hw_msix_ctrl_install = bfa_hwcb_msix_ctrl_install;
iocfc->hwif.hw_msix_queue_install = bfa_hwcb_msix_queue_install;
iocfc->hwif.hw_msix_uninstall = bfa_hwcb_msix_uninstall;
iocfc->hwif.hw_isr_mode_set = bfa_hwcb_isr_mode_set;
iocfc->hwif.hw_msix_getvecs = bfa_hwcb_msix_getvecs;
......@@ -640,7 +639,7 @@ bfa_iocfc_start_submod(struct bfa_s *bfa)
{
int i;
bfa->rme_process = BFA_TRUE;
bfa->queue_process = BFA_TRUE;
for (i = 0; i < BFI_IOC_MAX_CQS; i++)
bfa->iocfc.hwif.hw_rspq_ack(bfa, i);
......@@ -742,6 +741,11 @@ bfa_iocfc_cfgrsp(struct bfa_s *bfa)
*/
bfa_iocfc_qreg(bfa, &cfgrsp->qreg);
/*
* Install MSIX queue handlers
*/
bfa_msix_queue_install(bfa);
/*
* Configuration is complete - initialize/start submodules
*/
......@@ -813,7 +817,7 @@ bfa_iocfc_hbfail_cbfn(void *bfa_arg)
{
struct bfa_s *bfa = bfa_arg;
bfa->rme_process = BFA_FALSE;
bfa->queue_process = BFA_FALSE;
bfa_isr_disable(bfa);
bfa_iocfc_disable_submod(bfa);
......@@ -917,7 +921,7 @@ bfa_iocfc_stop(struct bfa_s *bfa)
{
bfa->iocfc.action = BFA_IOCFC_ACT_STOP;
bfa->rme_process = BFA_FALSE;
bfa->queue_process = BFA_FALSE;
bfa_ioc_disable(&bfa->ioc);
}
......@@ -1017,7 +1021,7 @@ bfa_iocfc_disable(struct bfa_s *bfa)
"IOC Disable");
bfa->iocfc.action = BFA_IOCFC_ACT_DISABLE;
bfa->rme_process = BFA_FALSE;
bfa->queue_process = BFA_FALSE;
bfa_ioc_disable(&bfa->ioc);
}
......
......@@ -85,44 +85,72 @@ bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap,
*num_vecs = __HFN_NUMINTS;
}
/*
* Dummy interrupt handler for handling spurious interrupts.
*/
static void
bfa_hwcb_msix_dummy(struct bfa_s *bfa, int vec)
{
}
/*
* No special setup required for crossbow -- vector assignments are implicit.
*/
void
bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs)
{
int i;
WARN_ON((nvecs != 1) && (nvecs != __HFN_NUMINTS));
bfa->msix.nvecs = nvecs;
if (nvecs == 1) {
for (i = 0; i < BFI_MSIX_CB_MAX; i++)
bfa_hwcb_msix_uninstall(bfa);
}
void
bfa_hwcb_msix_ctrl_install(struct bfa_s *bfa)
{
int i;
if (bfa->msix.nvecs == 0)
return;
if (bfa->msix.nvecs == 1) {
for (i = BFI_MSIX_RME_QMAX_CB+1; i < BFI_MSIX_CB_MAX; i++)
bfa->msix.handler[i] = bfa_msix_all;
return;
}
for (i = BFI_MSIX_CPE_QMIN_CB; i <= BFI_MSIX_CPE_QMAX_CB; i++)
bfa->msix.handler[i] = bfa_msix_reqq;
for (i = BFI_MSIX_RME_QMIN_CB; i <= BFI_MSIX_RME_QMAX_CB; i++)
bfa->msix.handler[i] = bfa_msix_rspq;
for (; i < BFI_MSIX_CB_MAX; i++)
for (i = BFI_MSIX_RME_QMAX_CB+1; i < BFI_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)
bfa_hwcb_msix_queue_install(struct bfa_s *bfa)
{
int i;
if (bfa->msix.nvecs == 0)
return;
if (bfa->msix.nvecs == 1) {
for (i = BFI_MSIX_CPE_QMIN_CB; i <= BFI_MSIX_RME_QMAX_CB; i++)
bfa->msix.handler[i] = bfa_msix_all;
return;
}
for (i = BFI_MSIX_CPE_QMIN_CB; i <= BFI_MSIX_CPE_QMAX_CB; i++)
bfa->msix.handler[i] = bfa_msix_reqq;
for (i = BFI_MSIX_RME_QMIN_CB; i <= BFI_MSIX_RME_QMAX_CB; i++)
bfa->msix.handler[i] = bfa_msix_rspq;
}
void
bfa_hwcb_msix_uninstall(struct bfa_s *bfa)
{
int i;
for (i = 0; i < BFI_MSIX_CB_MAX; i++)
bfa->msix.handler[i] = bfa_hwcb_msix_dummy;
}
/*
......
......@@ -96,7 +96,19 @@ bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs)
}
void
bfa_hwct_msix_install(struct bfa_s *bfa)
bfa_hwct_msix_ctrl_install(struct bfa_s *bfa)
{
if (bfa->msix.nvecs == 0)
return;
if (bfa->msix.nvecs == 1)
bfa->msix.handler[BFI_MSIX_LPU_ERR_CT] = bfa_msix_all;
else
bfa->msix.handler[BFI_MSIX_LPU_ERR_CT] = bfa_msix_lpu_err;
}
void
bfa_hwct_msix_queue_install(struct bfa_s *bfa)
{
int i;
......@@ -104,7 +116,7 @@ bfa_hwct_msix_install(struct bfa_s *bfa)
return;
if (bfa->msix.nvecs == 1) {
for (i = 0; i < BFI_MSIX_CT_MAX; i++)
for (i = BFI_MSIX_CPE_QMIN_CT; i < BFI_MSIX_CT_MAX; i++)
bfa->msix.handler[i] = bfa_msix_all;
return;
}
......@@ -114,8 +126,6 @@ bfa_hwct_msix_install(struct bfa_s *bfa)
for (i = BFI_MSIX_RME_QMIN_CT; i <= BFI_MSIX_RME_QMAX_CT; i++)
bfa->msix.handler[i] = bfa_msix_rspq;
bfa->msix.handler[BFI_MSIX_LPU_ERR_CT] = bfa_msix_lpu_err;
}
void
......
This diff is collapsed.
......@@ -224,8 +224,9 @@ struct bfa_ioc_notify_s {
struct bfa_iocpf_s {
bfa_fsm_t fsm;
struct bfa_ioc_s *ioc;
u32 retry_count;
bfa_boolean_t fw_mismatch_notified;
bfa_boolean_t auto_recover;
u32 poll_time;
};
struct bfa_ioc_s {
......
......@@ -300,8 +300,8 @@ bfa_ioc_ct2_reg_init(struct bfa_ioc_s *ioc)
ioc->ioc_regs.ioc_sem_reg = (rb + CT2_HOST_SEM0_REG);
ioc->ioc_regs.ioc_usage_sem_reg = (rb + CT2_HOST_SEM1_REG);
ioc->ioc_regs.ioc_init_sem_reg = (rb + CT2_HOST_SEM2_REG);
ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
ioc->ioc_regs.ioc_fail_sync = (rb + BFA_IOC_FAIL_SYNC);
ioc->ioc_regs.ioc_usage_reg = (rb + CT2_BFA_FW_USE_COUNT);
ioc->ioc_regs.ioc_fail_sync = (rb + CT2_BFA_IOC_FAIL_SYNC);
/*
* sram memory access
......@@ -636,10 +636,10 @@ bfa_ioc_ct_pll_init(void __iomem *rb, enum bfi_asic_mode mode)
static struct { u32 sclk, speed, half_speed; } ct2_pll[] = {
{0}, /* unused */
{__APP_PLL_SCLK_CLK_DIV2, 0, 0}, /* FC 8G */
{0, __APP_LPU_SPEED, 0}, /* FC 16G */
{0, 0, 0}, /* FC 16G */
{__APP_PLL_SCLK_REFCLK_SEL | __APP_PLL_SCLK_CLK_DIV2, 0, /* ETH */
__APP_LPUCLK_HALFSPEED},
{0, __APP_LPU_SPEED, 0}, /* COMBO */
{0, 0, 0}, /* COMBO */
};
static void
......@@ -664,15 +664,13 @@ bfa_ioc_ct2_sclk_init(void __iomem *rb, enum bfi_asic_mode mode)
writel(r32 | ct2_pll[mode].sclk, (rb + CT2_APP_PLL_SCLK_CTL_REG));
/*
* remove clock gating for ethernet subsystem for ethernet mode
* while doing PLL init dont clock gate ethernet subsystem
*/
if (mode == BFI_ASIC_MODE_ETH) {
r32 = readl((rb + CT2_CHIP_MISC_PRG));
writel(r32 | __ETH_CLK_ENABLE_PORT0, (rb + CT2_CHIP_MISC_PRG));
r32 = readl((rb + CT2_CHIP_MISC_PRG));
writel(r32 | __ETH_CLK_ENABLE_PORT0, (rb + CT2_CHIP_MISC_PRG));
r32 = readl((rb + CT2_PCIE_MISC_REG));
writel(r32 | __ETH_CLK_ENABLE_PORT1, (rb + CT2_PCIE_MISC_REG));
}
r32 = readl((rb + CT2_PCIE_MISC_REG));
writel(r32 | __ETH_CLK_ENABLE_PORT1, (rb + CT2_PCIE_MISC_REG));
/*
* set sclk value
......@@ -693,6 +691,19 @@ bfa_ioc_ct2_sclk_init(void __iomem *rb, enum bfi_asic_mode mode)
r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG));
writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET,
(rb + CT2_APP_PLL_SCLK_CTL_REG));
/*
* clock gating for ethernet subsystem if not in ethernet mode
*/
if (mode != BFI_ASIC_MODE_ETH) {
r32 = readl((rb + CT2_CHIP_MISC_PRG));
writel(r32 & ~__ETH_CLK_ENABLE_PORT0,
(rb + CT2_CHIP_MISC_PRG));
r32 = readl((rb + CT2_PCIE_MISC_REG));
writel(r32 & ~__ETH_CLK_ENABLE_PORT1,
(rb + CT2_PCIE_MISC_REG));
}
}
static void
......@@ -728,7 +739,8 @@ bfa_ioc_ct2_lclk_init(void __iomem *rb, enum bfi_asic_mode mode)
*/
r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG));
r32 &= (__P_LCLK_PLL_LOCK | __APP_LPUCLK_HALFSPEED);
if (mode == BFI_ASIC_MODE_FC || mode == BFI_ASIC_MODE_ETH)
if (mode == BFI_ASIC_MODE_FC || mode == BFI_ASIC_MODE_FC16 ||
mode == BFI_ASIC_MODE_ETH)
r32 |= 0x20c1731b;
else
r32 |= 0x2081731b;
......@@ -755,8 +767,10 @@ bfa_ioc_ct2_mem_init(void __iomem *rb, enum bfi_asic_mode mode)
fcmode = (mode == BFI_ASIC_MODE_FC) || (mode == BFI_ASIC_MODE_FC16);
if (!fcmode) {
writel(__PMM_1T_RESET_P, (rb + CT2_PMM_1T_CONTROL_REG_P0));
writel(__PMM_1T_RESET_P, (rb + CT2_PMM_1T_CONTROL_REG_P1));
writel(__PMM_1T_PNDB_P | __PMM_1T_RESET_P,
(rb + CT2_PMM_1T_CONTROL_REG_P0));
writel(__PMM_1T_PNDB_P | __PMM_1T_RESET_P,
(rb + CT2_PMM_1T_CONTROL_REG_P1));
}
r32 = readl((rb + PSS_CTL_REG));
......@@ -764,6 +778,11 @@ bfa_ioc_ct2_mem_init(void __iomem *rb, enum bfi_asic_mode mode)
writel(r32, (rb + PSS_CTL_REG));
udelay(1000);
if (!fcmode) {
writel(__PMM_1T_PNDB_P, (rb + CT2_PMM_1T_CONTROL_REG_P0));
writel(__PMM_1T_PNDB_P, (rb + CT2_PMM_1T_CONTROL_REG_P1));
}
writel(__EDRAM_BISTR_START, (rb + CT2_MBIST_CTL_REG));
udelay(1000);
writel(0, (rb + CT2_MBIST_CTL_REG));
......@@ -776,6 +795,12 @@ bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode mode)
bfa_ioc_ct2_lclk_init(rb, mode);
bfa_ioc_ct2_mem_init(rb, mode);
/*
* Disable flash presence to NFC by clearing GPIO 0
*/
writel(0, (rb + PSS_GPIO_OUT_REG));
writel(1, (rb + PSS_GPIO_OE_REG));
writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC0_STATE_REG));
writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC1_STATE_REG));
return BFA_STATUS_OK;
......
......@@ -109,7 +109,7 @@ struct bfa_s {
struct bfa_timer_mod_s timer_mod; /* timer module */
struct bfa_modules_s modules; /* BFA modules */
struct list_head comp_q; /* pending completions */
bfa_boolean_t rme_process; /* RME processing enabled */
bfa_boolean_t queue_process; /* queue processing enabled */
struct list_head reqq_waitq[BFI_IOC_MAX_CQS];
bfa_boolean_t fcs; /* FCS is attached to BFA */
struct bfa_msix_s msix;
......
......@@ -221,8 +221,7 @@ enum bfi_ioc_i2h_msgs {
BFI_IOC_I2H_ENABLE_REPLY = BFA_I2HM(1),
BFI_IOC_I2H_DISABLE_REPLY = BFA_I2HM(2),
BFI_IOC_I2H_GETATTR_REPLY = BFA_I2HM(3),
BFI_IOC_I2H_READY_EVENT = BFA_I2HM(4),
BFI_IOC_I2H_HBEAT = BFA_I2HM(5),
BFI_IOC_I2H_HBEAT = BFA_I2HM(4),
};
/*
......@@ -318,15 +317,6 @@ enum bfi_port_mode {
BFI_PORT_MODE_ETH = 2,
};
/*
* BFI_IOC_I2H_READY_EVENT message
*/
struct bfi_ioc_rdy_event_s {
struct bfi_mhdr_s mh; /* common msg header */
u8 init_status; /* init event status */
u8 rsvd[3];
};
struct bfi_ioc_hbeat_s {
struct bfi_mhdr_s mh; /* common msg header */
u32 hb_count; /* current heart beat count */
......@@ -418,7 +408,7 @@ union bfi_ioc_h2i_msg_u {
*/
union bfi_ioc_i2h_msg_u {
struct bfi_mhdr_s mh;
struct bfi_ioc_rdy_event_s rdy_event;
struct bfi_ioc_ctrl_reply_s rdy_event;
u32 mboxmsg[BFI_IOC_MSGSZ];
};
......
......@@ -137,6 +137,10 @@
#define __PSS_LPU0_RESET 0x00000001
#define PSS_ERR_STATUS_REG 0x00018810 /* cb/ct */
#define ERR_SET_REG 0x00018818 /* cb/ct */
#define PSS_GPIO_OUT_REG 0x000188c0 /* cb/ct */
#define __PSS_GPIO_OUT_REG 0x00000fff
#define PSS_GPIO_OE_REG 0x000188c8 /* cb/ct */
#define __PSS_GPIO_OE_REG 0x000000ff
#define HOSTFN0_LPU_MBOX0_0 0x00019200 /* cb/ct */
#define HOSTFN1_LPU_MBOX0_8 0x00019260 /* cb/ct */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment