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

Commit 47abe356 authored by Dhananjay Phadke's avatar Dhananjay Phadke Committed by David S. Miller
Browse files

netxen: add access to on chip memory for tools



Add access to on chip memory, this is used by
debug and diagnostic tools only.

Signed-off-by: default avatarDhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1f5e055d
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -543,13 +543,13 @@ struct netxen_hardware_context {
	void __iomem *pci_base1;
	void __iomem *pci_base2;
	void __iomem *db_base;
	void __iomem *ocm_win_crb;

	unsigned long db_len;
	unsigned long pci_len0;

	int qdr_sn_window;
	int ddr_mn_window;
	u32 mn_win_crb;
	u32 ms_win_crb;
	u32 ocm_win;
	u32 resv1;

	u8 cut_through;
	u8 revision_id;
@@ -1183,8 +1183,7 @@ struct netxen_adapter {
	int (*pci_mem_read)(struct netxen_adapter *, u64, u64 *);
	int (*pci_mem_write)(struct netxen_adapter *, u64, u64);

	unsigned long (*pci_set_window)(struct netxen_adapter *,
			unsigned long long);
	int (*pci_set_window)(struct netxen_adapter *, u64, u32 *);

	u32 (*io_read)(struct netxen_adapter *, void __iomem *);
	void (*io_write)(struct netxen_adapter *, void __iomem *, u32);
+99 −122
Original line number Diff line number Diff line
@@ -1274,72 +1274,6 @@ netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off)
	return data;
}

static int netxen_pci_set_window_warning_count;

static unsigned long
netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
		unsigned long long addr)
{
	void __iomem *offset;
	int window;
	unsigned long long	qdr_max;
	uint8_t func = adapter->ahw.pci_func;

	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
		qdr_max = NETXEN_ADDR_QDR_NET_MAX_P2;
	} else {
		qdr_max = NETXEN_ADDR_QDR_NET_MAX_P3;
	}

	if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
		/* DDR network side */
		addr -= NETXEN_ADDR_DDR_NET;
		window = (addr >> 25) & 0x3ff;
		if (adapter->ahw.ddr_mn_window != window) {
			adapter->ahw.ddr_mn_window = window;
			offset = PCI_OFFSET_SECOND_RANGE(adapter,
				NETXEN_PCIX_PH_REG(PCIE_MN_WINDOW_REG(func)));
			writel(window, offset);
			/* MUST make sure window is set before we forge on... */
			readl(offset);
		}
		addr -= (window * NETXEN_WINDOW_ONE);
		addr += NETXEN_PCI_DDR_NET;
	} else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
		addr -= NETXEN_ADDR_OCM0;
		addr += NETXEN_PCI_OCM0;
	} else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
		addr -= NETXEN_ADDR_OCM1;
		addr += NETXEN_PCI_OCM1;
	} else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_QDR_NET, qdr_max)) {
		/* QDR network side */
		addr -= NETXEN_ADDR_QDR_NET;
		window = (addr >> 22) & 0x3f;
		if (adapter->ahw.qdr_sn_window != window) {
			adapter->ahw.qdr_sn_window = window;
			offset = PCI_OFFSET_SECOND_RANGE(adapter,
				NETXEN_PCIX_PH_REG(PCIE_SN_WINDOW_REG(func)));
			writel((window << 22), offset);
			/* MUST make sure window is set before we forge on... */
			readl(offset);
		}
		addr -= (window * 0x400000);
		addr += NETXEN_PCI_QDR_NET;
	} else {
		/*
		 * peg gdb frequently accesses memory that doesn't exist,
		 * this limits the chit chat so debugging isn't slowed down.
		 */
		if ((netxen_pci_set_window_warning_count++ < 8)
		    || (netxen_pci_set_window_warning_count % 64 == 0))
			printk("%s: Warning:netxen_nic_pci_set_window()"
			       " Unknown address range!\n",
			       netxen_nic_driver_name);
		addr = -1UL;
	}
	return addr;
}

/* window 1 registers only */
static void netxen_nic_io_write_128M(struct netxen_adapter *adapter,
		void __iomem *addr, u32 data)
@@ -1389,69 +1323,90 @@ netxen_get_ioaddr(struct netxen_adapter *adapter, u32 offset)
	return (void __iomem *)off;
}

static unsigned long
static int
netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
		u64 addr, u32 *start)
{
	if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
		*start = (addr - NETXEN_ADDR_OCM0  + NETXEN_PCI_OCM0);
		return 0;
	} else if (ADDR_IN_RANGE(addr,
				NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
		*start = (addr - NETXEN_ADDR_OCM1 + NETXEN_PCI_OCM1);
		return 0;
	}

	return -EIO;
}

static int
netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
		unsigned long long addr)
		u64 addr, u32 *start)
{
	int window;
	u32 win_read;
	u32 win_read, window;
	struct pci_dev *pdev = adapter->pdev;

	if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
		/* DDR network side */
		window = MN_WIN(addr);
		adapter->ahw.ddr_mn_window = window;
		NXWR32(adapter, adapter->ahw.mn_win_crb, window);
		win_read = NXRD32(adapter, adapter->ahw.mn_win_crb);
		if ((win_read << 17) != window) {
			printk(KERN_INFO "Written MNwin (0x%x) != "
				"Read MNwin (0x%x)\n", window, win_read);
		}
		addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_DDR_NET;
	} else if (ADDR_IN_RANGE(addr,
				NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
	if ((addr & 0x00ff800) == 0xff800) {
			printk("%s: QM access not handled.\n", __func__);
			addr = -1UL;
		if (printk_ratelimit())
			dev_warn(&pdev->dev, "QM access not handled\n");
		return -EIO;
	}

	window = OCM_WIN(addr);
		adapter->ahw.ddr_mn_window = window;
		NXWR32(adapter, adapter->ahw.mn_win_crb, window);
		win_read = NXRD32(adapter, adapter->ahw.mn_win_crb);
	writel(window, adapter->ahw.ocm_win_crb);
	win_read = readl(adapter->ahw.ocm_win_crb);
	if ((win_read >> 7) != window) {
			printk(KERN_INFO "%s: Written OCMwin (0x%x) != "
					"Read OCMwin (0x%x)\n",
					__func__, window, win_read);
		if (printk_ratelimit())
			dev_warn(&pdev->dev, "failed to set OCM window\n");
		return -EIO;
	}
		addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_OCM0_2M;

	} else if (ADDR_IN_RANGE(addr,
			NETXEN_ADDR_QDR_NET, NETXEN_ADDR_QDR_NET_MAX_P3)) {
		/* QDR network side */
		window = MS_WIN(addr);
		adapter->ahw.qdr_sn_window = window;
		NXWR32(adapter, adapter->ahw.ms_win_crb, window);
		win_read = NXRD32(adapter, adapter->ahw.ms_win_crb);
		if (win_read != window) {
			printk(KERN_INFO "%s: Written MSwin (0x%x) != "
					"Read MSwin (0x%x)\n",
					__func__, window, win_read);
		}
		addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_QDR_NET;

	} else {
		/*
		 * peg gdb frequently accesses memory that doesn't exist,
		 * this limits the chit chat so debugging isn't slowed down.
		 */
		if ((netxen_pci_set_window_warning_count++ < 8)
			|| (netxen_pci_set_window_warning_count%64 == 0)) {
			printk("%s: Warning:%s Unknown address range!\n",
					__func__, netxen_nic_driver_name);
	adapter->ahw.ocm_win = window;
	*start = NETXEN_PCI_OCM0_2M + GET_MEM_OFFS_2M(addr);
	return 0;
}
		addr = -1UL;

static int
netxen_nic_pci_mem_access_direct(struct netxen_adapter *adapter, u64 off,
		u64 *data, int op)
{
	void __iomem *addr, *mem_ptr = NULL;
	resource_size_t mem_base;
	unsigned long flags;
	int ret = -EIO;
	u32 start;

	write_lock_irqsave(&adapter->adapter_lock, flags);

	ret = adapter->pci_set_window(adapter, off, &start);
	if (ret != 0)
		goto unlock;

	addr = pci_base_offset(adapter, start);
	if (addr)
		goto noremap;

	mem_base = pci_resource_start(adapter->pdev, 0) + (start & PAGE_MASK);

	mem_ptr = ioremap(mem_base, PAGE_SIZE);
	if (mem_ptr == NULL) {
		ret = -EIO;
		goto unlock;
	}
	return addr;

	addr = mem_ptr + (start & (PAGE_SIZE - 1));

noremap:
	if (op == 0)	/* read */
		*data = readq(addr);
	else		/* write */
		writeq(*data, addr);

unlock:
	write_unlock_irqrestore(&adapter->adapter_lock, flags);
	if (mem_ptr)
		iounmap(mem_ptr);
	return ret;
}

#define MAX_CTL_CHECK   1000
@@ -1493,6 +1448,14 @@ netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
		goto correct;
	}

	if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX) ||
		ADDR_IN_RANGE(off, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
		if (adapter->ahw.pci_len0 != 0) {
			return netxen_nic_pci_mem_access_direct(adapter,
					off, &data, 1);
		}
	}

	return -EIO;

correct:
@@ -1564,6 +1527,14 @@ netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
		goto correct;
	}

	if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX) ||
		ADDR_IN_RANGE(off, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
		if (adapter->ahw.pci_len0 != 0) {
			return netxen_nic_pci_mem_access_direct(adapter,
					off, data, 0);
		}
	}

	return -EIO;

correct:
@@ -1628,6 +1599,9 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
		goto correct;
	}

	if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX))
		return netxen_nic_pci_mem_access_direct(adapter, off, &data, 1);

	return -EIO;

correct:
@@ -1690,6 +1664,9 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
		goto correct;
	}

	if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX))
		return netxen_nic_pci_mem_access_direct(adapter, off, data, 0);

	return -EIO;

correct:
+8 −16
Original line number Diff line number Diff line
@@ -607,13 +607,11 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
	 * accessed it should set the window to 0 and then reset it to 1.
	 */
	adapter->curr_window = 255;
	adapter->ahw.qdr_sn_window = -1;
	adapter->ahw.ddr_mn_window = -1;
	adapter->ahw.ocm_win = -1;

	/* remap phys address */
	mem_base = pci_resource_start(pdev, 0);	/* 0 is for BAR 0 */
	mem_len = pci_resource_len(pdev, 0);
	pci_len0 = 0;

	/* 128 Meg of memory */
	if (mem_len == NETXEN_PCI_128MB_SIZE) {
@@ -622,6 +620,7 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
				SECOND_PAGE_GROUP_SIZE);
		mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START,
				THIRD_PAGE_GROUP_SIZE);
		pci_len0 = FIRST_PAGE_GROUP_SIZE;
	} else if (mem_len == NETXEN_PCI_32MB_SIZE) {
		mem_ptr1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE);
		mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START -
@@ -634,19 +633,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
			return -EIO;
		}
		pci_len0 = mem_len;

		adapter->ahw.ddr_mn_window = 0;
		adapter->ahw.qdr_sn_window = 0;

		adapter->ahw.mn_win_crb = NETXEN_PCI_CRBSPACE +
			0x100000 + PCIX_MN_WINDOW + (pci_func * 0x20);
		adapter->ahw.ms_win_crb = NETXEN_PCI_CRBSPACE +
			0x100000 + PCIX_SN_WINDOW;
		if (pci_func < 4)
			adapter->ahw.ms_win_crb += (pci_func * 0x20);
		else
			adapter->ahw.ms_win_crb +=
					0xA0 + ((pci_func - 4) * 0x10);
	} else {
		return -EIO;
	}
@@ -660,6 +646,11 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
	adapter->ahw.pci_base1 = mem_ptr1;
	adapter->ahw.pci_base2 = mem_ptr2;

	if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
		adapter->ahw.ocm_win_crb = netxen_get_ioaddr(adapter,
			NETXEN_PCIX_PS_REG(PCIE_MN_WINDOW_REG(pci_func)));
	}

	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
		goto skip_doorbell;

@@ -1447,6 +1438,7 @@ netxen_nic_resume(struct pci_dev *pdev)
		return err;

	adapter->curr_window = 255;
	adapter->ahw.ocm_win = -1;

	err = netxen_start_firmware(adapter);
	if (err) {