Example #1
0
static void __iomem *wil_ioc_addr(struct wil6210_priv *wil, uint32_t addr,
				  uint32_t size, enum wil_memio_op op)
{
	void __iomem *a;
	u32 off;

	switch (op & wil_mmio_addr_mask) {
	case wil_mmio_addr_linker:
		a = wmi_buffer(wil, cpu_to_le32(addr));
		break;
	case wil_mmio_addr_ahb:
		a = wmi_addr(wil, addr);
		break;
	case wil_mmio_addr_bar:
		a = wmi_addr(wil, addr + WIL6210_FW_HOST_OFF);
		break;
	default:
		wil_err(wil, "Unsupported address mode, op = 0x%08x\n", op);
		return NULL;
	}

	off = a - wil->csr;
	if (size >= WIL6210_MEM_SIZE - off) {
		wil_err(wil, "Requested block does not fit into memory: "
			"off = 0x%08x size = 0x%08x\n", off, size);
		return NULL;
	}

	return a;
}
Example #2
0
File: wmi.c Project: 03199618/linux
int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr,
		 struct wil6210_mbox_hdr *hdr)
{
	void __iomem *src = wmi_buffer(wil, ptr);
	if (!src)
		return -EINVAL;

	wil_memcpy_fromio_32(hdr, src, sizeof(*hdr));

	return 0;
}
Example #3
0
static int wil_memread_debugfs_show(struct seq_file *s, void *data)
{
	struct wil6210_priv *wil = s->private;
	void __iomem *a = wmi_buffer(wil, cpu_to_le32(mem_addr));

	if (a)
		seq_printf(s, "[0x%08x] = 0x%08x\n", mem_addr, readl(a));
	else
		seq_printf(s, "[0x%08x] = INVALID\n", mem_addr);

	return 0;
}
Example #4
0
/* memory rw */
static ssize_t wil_read_file_mem(struct file *file, char __user *user_buf,
				 size_t count, loff_t *ppos)
{
	char kbuf[30];
	struct wil6210_priv *wil = file->private_data;
	void __iomem *a = wmi_buffer(wil, cpu_to_le32(mem_addr));

	if (a)
		snprintf(kbuf, sizeof(kbuf), "[0x%08x] = 0x%08x\n",
			 mem_addr, ioread32(a));
	else
		snprintf(kbuf, sizeof(kbuf), "[0x%08x] = INVALID\n",
			 mem_addr);

	return simple_read_from_buffer(user_buf, count, ppos, kbuf, sizeof(kbuf));
}
Example #5
0
static ssize_t wil_write_file_mem(struct file *file, const char __user *buf,
				  size_t count, loff_t *ppos)
{
	ssize_t rc;
	int n;
	char *kbuf;
	ulong val;
	struct wil6210_priv *wil = file->private_data;
	void __iomem *a = wmi_buffer(wil, cpu_to_le32(mem_addr));
	if (!a)
		return -EINVAL;

	if (*ppos != 0)
		return -EINVAL;

	kbuf = kmalloc(count + 1, GFP_KERNEL);
	if (!kbuf)
		return -ENOMEM;

	rc = simple_write_to_buffer(kbuf, count, ppos, buf, count);
	if (rc < 0) {
		kfree(kbuf);
		return rc;
	}

	kbuf[count] = '\0';
	n = sscanf(kbuf, "%li", &val);
	kfree(kbuf);

	if (n != 1)
		return -EINVAL;

	iowrite32(val, a);
	wmb(); /* make sure write propagated to HW */

	return rc;
}
Example #6
0
static void wil_print_ring(struct seq_file *s, const char *prefix,
			   void __iomem *off)
{
	struct wil6210_priv *wil = s->private;
	struct wil6210_mbox_ring r;
	int rsize;
	uint i;

	wil_halp_vote(wil);

	wil_memcpy_fromio_32(&r, off, sizeof(r));
	wil_mbox_ring_le2cpus(&r);
	/*
	 * we just read memory block from NIC. This memory may be
	 * garbage. Check validity before using it.
	 */
	rsize = r.size / sizeof(struct wil6210_mbox_ring_desc);

	seq_printf(s, "ring %s = {\n", prefix);
	seq_printf(s, "  base = 0x%08x\n", r.base);
	seq_printf(s, "  size = 0x%04x bytes -> %d entries\n", r.size, rsize);
	seq_printf(s, "  tail = 0x%08x\n", r.tail);
	seq_printf(s, "  head = 0x%08x\n", r.head);
	seq_printf(s, "  entry size = %d\n", r.entry_size);

	if (r.size % sizeof(struct wil6210_mbox_ring_desc)) {
		seq_printf(s, "  ??? size is not multiple of %zd, garbage?\n",
			   sizeof(struct wil6210_mbox_ring_desc));
		goto out;
	}

	if (!wmi_addr(wil, r.base) ||
	    !wmi_addr(wil, r.tail) ||
	    !wmi_addr(wil, r.head)) {
		seq_puts(s, "  ??? pointers are garbage?\n");
		goto out;
	}

	for (i = 0; i < rsize; i++) {
		struct wil6210_mbox_ring_desc d;
		struct wil6210_mbox_hdr hdr;
		size_t delta = i * sizeof(d);
		void __iomem *x = wil->csr + HOSTADDR(r.base) + delta;

		wil_memcpy_fromio_32(&d, x, sizeof(d));

		seq_printf(s, "  [%2x] %s %s%s 0x%08x", i,
			   d.sync ? "F" : "E",
			   (r.tail - r.base == delta) ? "t" : " ",
			   (r.head - r.base == delta) ? "h" : " ",
			   le32_to_cpu(d.addr));
		if (0 == wmi_read_hdr(wil, d.addr, &hdr)) {
			u16 len = le16_to_cpu(hdr.len);

			seq_printf(s, " -> %04x %04x %04x %02x\n",
				   le16_to_cpu(hdr.seq), len,
				   le16_to_cpu(hdr.type), hdr.flags);
			if (len <= MAX_MBOXITEM_SIZE) {
				unsigned char databuf[MAX_MBOXITEM_SIZE];
				void __iomem *src = wmi_buffer(wil, d.addr) +
					sizeof(struct wil6210_mbox_hdr);
				/*
				 * No need to check @src for validity -
				 * we already validated @d.addr while
				 * reading header
				 */
				wil_memcpy_fromio_32(databuf, src, len);
				wil_seq_hexdump(s, databuf, len, "      : ");
			}
		} else {
			seq_puts(s, "\n");
		}
	}
 out:
	seq_puts(s, "}\n");
	wil_halp_unvote(wil);
}