Ejemplo n.º 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;
}
Ejemplo n.º 2
0
static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil,
			    const char *name, struct vring *vring,
			    char _s, char _h)
{
	void __iomem *x = wmi_addr(wil, vring->hwtail);

	seq_printf(s, "VRING %s = {\n", name);
	seq_printf(s, "  pa     = %pad\n", &vring->pa);
	seq_printf(s, "  va     = 0x%p\n", vring->va);
	seq_printf(s, "  size   = %d\n", vring->size);
	seq_printf(s, "  swtail = %d\n", vring->swtail);
	seq_printf(s, "  swhead = %d\n", vring->swhead);
	seq_printf(s, "  hwtail = [0x%08x] -> ", vring->hwtail);
	if (x)
		seq_printf(s, "0x%08x\n", ioread32(x));
	else
		seq_puts(s, "???\n");

	if (vring->va && (vring->size < 1025)) {
		uint i;

		for (i = 0; i < vring->size; i++) {
			volatile struct vring_tx_desc *d = &vring->va[i].tx;

			if ((i % 64) == 0 && (i != 0))
				seq_puts(s, "\n");
			seq_printf(s, "%c", (d->dma.status & BIT(0)) ?
					_s : (vring->ctx[i].skb ? _h : 'h'));
		}
		seq_puts(s, "\n");
	}
	seq_puts(s, "}\n");
}
Ejemplo n.º 3
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);
}
Ejemplo n.º 4
0
Archivo: wmi.c Proyecto: 03199618/linux
	} __packed cmd = {
		.hdr = {
			.type = WIL_MBOX_HDR_TYPE_WMI,
			.flags = 0,
			.len = cpu_to_le16(sizeof(cmd.wmi) + len),
		},
		.wmi = {
			.mid = 0,
			.id = cpu_to_le16(cmdid),
		},
	};
	struct wil6210_mbox_ring *r = &wil->mbox_ctl.tx;
	struct wil6210_mbox_ring_desc d_head;
	u32 next_head;
	void __iomem *dst;
	void __iomem *head = wmi_addr(wil, r->head);
	uint retry;

	if (sizeof(cmd) + len > r->entry_size) {
		wil_err(wil, "WMI size too large: %d bytes, max is %d\n",
			(int)(sizeof(cmd) + len), r->entry_size);
		return -ERANGE;
	}

	might_sleep();

	if (!test_bit(wil_status_fwready, &wil->status)) {
		wil_err(wil, "FW not ready\n");
		return -EAGAIN;
	}