mirror of
https://github.com/torvalds/linux.git
synced 2024-11-15 16:41:58 +00:00
bna: Serialize smem access during adapter initialization
Use init semaphore to serialize execution of the "unlock IOC semaphore" code. Added bfa_ioc_fwver_clear() function to clear the firmware header if last firmwar boot is not from driver. Signed-off-by: Jing Huang <huangj@brocade.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
695e00789a
commit
e491c77ed3
@ -1207,27 +1207,62 @@ bfa_nw_ioc_sem_release(void __iomem *sem_reg)
|
|||||||
writel(1, sem_reg);
|
writel(1, sem_reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear fwver hdr */
|
||||||
|
static void
|
||||||
|
bfa_ioc_fwver_clear(struct bfa_ioc *ioc)
|
||||||
|
{
|
||||||
|
u32 pgnum, pgoff, loff = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
|
||||||
|
pgoff = PSS_SMEM_PGOFF(loff);
|
||||||
|
writel(pgnum, ioc->ioc_regs.host_page_num_fn);
|
||||||
|
|
||||||
|
for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr) / sizeof(u32)); i++) {
|
||||||
|
writel(0, ioc->ioc_regs.smem_page_start + loff);
|
||||||
|
loff += sizeof(u32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bfa_ioc_hw_sem_init(struct bfa_ioc *ioc)
|
bfa_ioc_hw_sem_init(struct bfa_ioc *ioc)
|
||||||
{
|
{
|
||||||
struct bfi_ioc_image_hdr fwhdr;
|
struct bfi_ioc_image_hdr fwhdr;
|
||||||
u32 fwstate = readl(ioc->ioc_regs.ioc_fwstate);
|
u32 fwstate, r32;
|
||||||
|
|
||||||
if (fwstate == BFI_IOC_UNINIT)
|
/* Spin on init semaphore to serialize. */
|
||||||
|
r32 = readl(ioc->ioc_regs.ioc_init_sem_reg);
|
||||||
|
while (r32 & 0x1) {
|
||||||
|
udelay(20);
|
||||||
|
r32 = readl(ioc->ioc_regs.ioc_init_sem_reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
fwstate = readl(ioc->ioc_regs.ioc_fwstate);
|
||||||
|
if (fwstate == BFI_IOC_UNINIT) {
|
||||||
|
writel(1, ioc->ioc_regs.ioc_init_sem_reg);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bfa_nw_ioc_fwver_get(ioc, &fwhdr);
|
bfa_nw_ioc_fwver_get(ioc, &fwhdr);
|
||||||
|
|
||||||
if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL)
|
if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL) {
|
||||||
|
writel(1, ioc->ioc_regs.ioc_init_sem_reg);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bfa_ioc_fwver_clear(ioc);
|
||||||
writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
|
writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
|
||||||
|
writel(BFI_IOC_UNINIT, ioc->ioc_regs.alt_ioc_fwstate);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to lock and then unlock the semaphore.
|
* Try to lock and then unlock the semaphore.
|
||||||
*/
|
*/
|
||||||
readl(ioc->ioc_regs.ioc_sem_reg);
|
readl(ioc->ioc_regs.ioc_sem_reg);
|
||||||
writel(1, ioc->ioc_regs.ioc_sem_reg);
|
writel(1, ioc->ioc_regs.ioc_sem_reg);
|
||||||
|
|
||||||
|
/* Unlock init semaphore */
|
||||||
|
writel(1, ioc->ioc_regs.ioc_init_sem_reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1585,11 +1620,6 @@ bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type,
|
|||||||
u32 i;
|
u32 i;
|
||||||
u32 asicmode;
|
u32 asicmode;
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize LMEM first before code download
|
|
||||||
*/
|
|
||||||
bfa_ioc_lmem_init(ioc);
|
|
||||||
|
|
||||||
fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), chunkno);
|
fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), chunkno);
|
||||||
|
|
||||||
pgnum = bfa_ioc_smem_pgnum(ioc, loff);
|
pgnum = bfa_ioc_smem_pgnum(ioc, loff);
|
||||||
@ -1914,6 +1944,10 @@ bfa_ioc_pll_init(struct bfa_ioc *ioc)
|
|||||||
bfa_ioc_pll_init_asic(ioc);
|
bfa_ioc_pll_init_asic(ioc);
|
||||||
|
|
||||||
ioc->pllinit = true;
|
ioc->pllinit = true;
|
||||||
|
|
||||||
|
/* Initialize LMEM */
|
||||||
|
bfa_ioc_lmem_init(ioc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* release semaphore.
|
* release semaphore.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user