Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e491c77e authored by Jing Huang's avatar Jing Huang Committed by David S. Miller
Browse files

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: default avatarJing Huang <huangj@brocade.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 695e0078
Loading
Loading
Loading
Loading
+42 −8
Original line number Original line Diff line number Diff line
@@ -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;

	/* 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);
	}


	if (fwstate == BFI_IOC_UNINIT)
	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.
	 */
	 */