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

Commit 2c1f73c3 authored by Ron Mercer's avatar Ron Mercer Committed by David S. Miller
Browse files

qlge: Add RAM dump to firmware dump.

parent c89ec8b9
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -2225,6 +2225,9 @@ int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data);
int ql_write_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 data);
int ql_write_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 data);
int ql_unpause_mpi_risc(struct ql_adapter *qdev);
int ql_unpause_mpi_risc(struct ql_adapter *qdev);
int ql_pause_mpi_risc(struct ql_adapter *qdev);
int ql_pause_mpi_risc(struct ql_adapter *qdev);
int ql_hard_reset_mpi_risc(struct ql_adapter *qdev);
int ql_dump_risc_ram_area(struct ql_adapter *qdev, void *buf,
		u32 ram_addr, int word_count);
int ql_core_dump(struct ql_adapter *qdev,
int ql_core_dump(struct ql_adapter *qdev,
		struct ql_mpi_coredump *mpi_coredump);
		struct ql_mpi_coredump *mpi_coredump);
int ql_mb_about_fw(struct ql_adapter *qdev);
int ql_mb_about_fw(struct ql_adapter *qdev);
+35 −0
Original line number Original line Diff line number Diff line
@@ -647,6 +647,41 @@ int ql_core_dump(struct ql_adapter *qdev, struct ql_mpi_coredump *mpi_coredump)
			"Failed RISC unpause. Status = 0x%.08x\n", status);
			"Failed RISC unpause. Status = 0x%.08x\n", status);
		goto err;
		goto err;
	}
	}

	/* Reset the RISC so we can dump RAM */
	status = ql_hard_reset_mpi_risc(qdev);
	if (status) {
		QPRINTK(qdev, DRV, ERR,
			"Failed RISC reset. Status = 0x%.08x\n", status);
		goto err;
	}

	ql_build_coredump_seg_header(&mpi_coredump->code_ram_seg_hdr,
				WCS_RAM_SEG_NUM,
				sizeof(struct mpi_coredump_segment_header)
				+ sizeof(mpi_coredump->code_ram),
				"WCS RAM");
	status = ql_dump_risc_ram_area(qdev, &mpi_coredump->code_ram[0],
					CODE_RAM_ADDR, CODE_RAM_CNT);
	if (status) {
		QPRINTK(qdev, DRV, ERR,
			"Failed Dump of CODE RAM. Status = 0x%.08x\n", status);
		goto err;
	}

	/* Insert the segment header */
	ql_build_coredump_seg_header(&mpi_coredump->memc_ram_seg_hdr,
				MEMC_RAM_SEG_NUM,
				sizeof(struct mpi_coredump_segment_header)
				+ sizeof(mpi_coredump->memc_ram),
				"MEMC RAM");
	status = ql_dump_risc_ram_area(qdev, &mpi_coredump->memc_ram[0],
					MEMC_RAM_ADDR, MEMC_RAM_CNT);
	if (status) {
		QPRINTK(qdev, DRV, ERR,
			"Failed Dump of MEMC RAM. Status = 0x%.08x\n", status);
		goto err;
	}
err:
err:
	ql_sem_unlock(qdev, SEM_PROC_REG_MASK); /* does flush too */
	ql_sem_unlock(qdev, SEM_PROC_REG_MASK); /* does flush too */
	return status;
	return status;
+76 −0
Original line number Original line Diff line number Diff line
@@ -30,6 +30,25 @@ int ql_pause_mpi_risc(struct ql_adapter *qdev)
	return (count == 0) ? -ETIMEDOUT : 0;
	return (count == 0) ? -ETIMEDOUT : 0;
}
}


int ql_hard_reset_mpi_risc(struct ql_adapter *qdev)
{
	u32 tmp;
	int count = UDELAY_COUNT;

	/* Reset the RISC */
	ql_write32(qdev, CSR, CSR_CMD_SET_RST);
	do {
		tmp = ql_read32(qdev, CSR);
		if (tmp & CSR_RR) {
			ql_write32(qdev, CSR, CSR_CMD_CLR_RST);
			break;
		}
		mdelay(UDELAY_DELAY);
		count--;
	} while (count);
	return (count == 0) ? -ETIMEDOUT : 0;
}

int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
{
{
	int status;
	int status;
@@ -728,6 +747,63 @@ int ql_mb_set_port_cfg(struct ql_adapter *qdev)
	return status;
	return status;
}
}


int ql_mb_dump_ram(struct ql_adapter *qdev, u64 req_dma, u32 addr,
	u32 size)
{
	int status = 0;
	struct mbox_params mbc;
	struct mbox_params *mbcp = &mbc;

	memset(mbcp, 0, sizeof(struct mbox_params));

	mbcp->in_count = 9;
	mbcp->out_count = 1;

	mbcp->mbox_in[0] = MB_CMD_DUMP_RISC_RAM;
	mbcp->mbox_in[1] = LSW(addr);
	mbcp->mbox_in[2] = MSW(req_dma);
	mbcp->mbox_in[3] = LSW(req_dma);
	mbcp->mbox_in[4] = MSW(size);
	mbcp->mbox_in[5] = LSW(size);
	mbcp->mbox_in[6] = MSW(MSD(req_dma));
	mbcp->mbox_in[7] = LSW(MSD(req_dma));
	mbcp->mbox_in[8] = MSW(addr);


	status = ql_mailbox_command(qdev, mbcp);
	if (status)
		return status;

	if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
		QPRINTK(qdev, DRV, ERR,
			"Failed to dump risc RAM.\n");
		status = -EIO;
	}
	return status;
}

/* Issue a mailbox command to dump RISC RAM. */
int ql_dump_risc_ram_area(struct ql_adapter *qdev, void *buf,
		u32 ram_addr, int word_count)
{
	int status;
	char *my_buf;
	dma_addr_t buf_dma;

	my_buf = pci_alloc_consistent(qdev->pdev, word_count * sizeof(u32),
					&buf_dma);
	if (!my_buf)
		return -EIO;

	status = ql_mb_dump_ram(qdev, buf_dma, ram_addr, word_count);
	if (!status)
		memcpy(buf, my_buf, word_count * sizeof(u32));

	pci_free_consistent(qdev->pdev, word_count * sizeof(u32), my_buf,
				buf_dma);
	return status;
}

/* Get link settings and maximum frame size settings
/* Get link settings and maximum frame size settings
 * for the current port.
 * for the current port.
 * Most likely will block.
 * Most likely will block.