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

Commit c0eab5b3 authored by Raghu Vatsavayi's avatar Raghu Vatsavayi Committed by David S. Miller
Browse files

liquidio: CN23XX firmware download

parent 5b07aee1
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -214,6 +214,37 @@ void cn23xx_dump_pf_initialized_regs(struct octeon_device *oct)
		CVM_CAST64(octeon_read_csr64(oct, CN23XX_SLI_PKT_CNT_INT)));
}

static int cn23xx_pf_soft_reset(struct octeon_device *oct)
{
	octeon_write_csr64(oct, CN23XX_WIN_WR_MASK_REG, 0xFF);

	dev_dbg(&oct->pci_dev->dev, "OCTEON[%d]: BIST enabled for CN23XX soft reset\n",
		oct->octeon_id);

	octeon_write_csr64(oct, CN23XX_SLI_SCRATCH1, 0x1234ULL);

	/* Initiate chip-wide soft reset */
	lio_pci_readq(oct, CN23XX_RST_SOFT_RST);
	lio_pci_writeq(oct, 1, CN23XX_RST_SOFT_RST);

	/* Wait for 100ms as Octeon resets. */
	mdelay(100);

	if (octeon_read_csr64(oct, CN23XX_SLI_SCRATCH1) == 0x1234ULL) {
		dev_err(&oct->pci_dev->dev, "OCTEON[%d]: Soft reset failed\n",
			oct->octeon_id);
		return 1;
	}

	dev_dbg(&oct->pci_dev->dev, "OCTEON[%d]: Reset completed\n",
		oct->octeon_id);

	/* restore the  reset value*/
	octeon_write_csr64(oct, CN23XX_WIN_WR_MASK_REG, 0xFF);

	return 0;
}

static void cn23xx_enable_error_reporting(struct octeon_device *oct)
{
	u32 regval;
@@ -1030,6 +1061,7 @@ int setup_cn23xx_octeon_pf_device(struct octeon_device *oct)
	oct->fn_list.process_interrupt_regs = cn23xx_interrupt_handler;
	oct->fn_list.msix_interrupt_handler = cn23xx_pf_msix_interrupt_handler;

	oct->fn_list.soft_reset = cn23xx_pf_soft_reset;
	oct->fn_list.setup_device_regs = cn23xx_setup_pf_device_regs;

	oct->fn_list.enable_interrupt = cn23xx_enable_pf_interrupt;
@@ -1129,3 +1161,11 @@ void cn23xx_dump_iq_regs(struct octeon_device *oct)
		CVM_CAST64(octeon_read_csr64(
			oct, CN23XX_SLI_S2M_PORTX_CTL(oct->pcie_port))));
}

int cn23xx_fw_loaded(struct octeon_device *oct)
{
	u64 val;

	val = octeon_read_csr64(oct, CN23XX_SLI_SCRATCH1);
	return (val >> 1) & 1ULL;
}
+2 −0
Original line number Diff line number Diff line
@@ -52,4 +52,6 @@ int validate_cn23xx_pf_config_info(struct octeon_device *oct,
				   struct octeon_config *conf23xx);

void cn23xx_dump_pf_initialized_regs(struct octeon_device *oct);

int cn23xx_fw_loaded(struct octeon_device *oct);
#endif
+69 −46
Original line number Diff line number Diff line
@@ -1312,8 +1312,8 @@ static void octeon_destroy_resources(struct octeon_device *oct)

		/* fallthrough */
	case OCT_DEV_PCI_MAP_DONE:

		/* Soft reset the octeon device before exiting */
		if ((!OCTEON_CN23XX_PF(oct)) || !oct->octeon_id)
			oct->fn_list.soft_reset(oct);

		octeon_unmap_pci_barx(oct, 0);
@@ -3823,6 +3823,7 @@ static void nic_starter(struct work_struct *work)
static int octeon_device_init(struct octeon_device *octeon_dev)
{
	int j, ret;
	int fw_loaded = 0;
	char bootcmd[] = "\n";
	struct octeon_device_priv *oct_priv =
		(struct octeon_device_priv *)octeon_dev->priv;
@@ -3844,9 +3845,23 @@ static int octeon_device_init(struct octeon_device *octeon_dev)

	octeon_dev->app_mode = CVM_DRV_INVALID_APP;

	if (OCTEON_CN23XX_PF(octeon_dev)) {
		if (!cn23xx_fw_loaded(octeon_dev)) {
			fw_loaded = 0;
			/* Do a soft reset of the Octeon device. */
			if (octeon_dev->fn_list.soft_reset(octeon_dev))
				return 1;
			/* things might have changed */
			if (!cn23xx_fw_loaded(octeon_dev))
				fw_loaded = 0;
			else
				fw_loaded = 1;
		} else {
			fw_loaded = 1;
		}
	} else if (octeon_dev->fn_list.soft_reset(octeon_dev)) {
		return 1;
	}

	/* Initialize the dispatch mechanism used to push packets arriving on
	 * Octeon Output queues.
@@ -3955,15 +3970,17 @@ static int octeon_device_init(struct octeon_device *octeon_dev)

	atomic_set(&octeon_dev->status, OCT_DEV_IO_QUEUES_DONE);

	if ((!OCTEON_CN23XX_PF(octeon_dev)) || !fw_loaded) {
		dev_dbg(&octeon_dev->pci_dev->dev, "Waiting for DDR initialization...\n");

	if (ddr_timeout == 0)
		dev_info(&octeon_dev->pci_dev->dev, "WAITING. Set ddr_timeout to non-zero value to proceed with initialization.\n");
		if (!ddr_timeout) {
			dev_info(&octeon_dev->pci_dev->dev,
				 "WAITING. Set ddr_timeout to non-zero value to proceed with initialization.\n");
		}

		schedule_timeout_uninterruptible(HZ * LIO_RESET_SECS);

		/* Wait for the octeon to initialize DDR after the soft-reset.*/
	while (ddr_timeout == 0) {
		while (!ddr_timeout) {
			set_current_state(TASK_INTERRUPTIBLE);
			if (schedule_timeout(HZ / 10)) {
				/* user probably pressed Control-C */
@@ -3978,7 +3995,7 @@ static int octeon_device_init(struct octeon_device *octeon_dev)
			return 1;
		}

	if (octeon_wait_for_bootloader(octeon_dev, 1000) != 0) {
		if (octeon_wait_for_bootloader(octeon_dev, 1000)) {
			dev_err(&octeon_dev->pci_dev->dev, "Board not responding\n");
			return 1;
		}
@@ -4006,6 +4023,13 @@ static int octeon_device_init(struct octeon_device *octeon_dev)
			dev_err(&octeon_dev->pci_dev->dev, "Could not load firmware to board\n");
			return 1;
		}
		/* set bit 1 of SLI_SCRATCH_1 to indicate that firmware is
		 * loaded
		 */
		if (OCTEON_CN23XX_PF(octeon_dev))
			octeon_write_csr64(octeon_dev, CN23XX_SLI_SCRATCH1,
					   2ULL);
	}

	handshake[octeon_dev->octeon_id].init_ok = 1;
	complete(&handshake[octeon_dev->octeon_id].init);
@@ -4020,7 +4044,6 @@ static int octeon_device_init(struct octeon_device *octeon_dev)
		       octeon_dev->droq[j]->pkts_credit_reg);

	/* Packets can start arriving on the output queues from this point. */

	return 0;
}