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

Commit 8662b251 authored by Jussi Kivilinna's avatar Jussi Kivilinna Committed by John W. Linville
Browse files

zd1211rw: move async iowrite16v up to callers



Writing beacon to device happen through multiple write command calls.
zd_usb_iowrite16v uses synchronous urb call and with multiple write
commands in row causes high CPU usage.

Make asynchronous zd_usb_iowrite16v_async available outside zd_usb.c
and use where possible.

This lower CPU usage from ~10% to ~2% on Intel Atom when running
AP-mode with 100 TU beacon interval.

Signed-off-by: default avatarJussi Kivilinna <jussi.kivilinna@mbnet.fi>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent eefdbec1
Loading
Loading
Loading
Loading
+28 −7
Original line number Diff line number Diff line
@@ -142,7 +142,8 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr
	return 0;
}

int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
static int _zd_iowrite32v_async_locked(struct zd_chip *chip,
				       const struct zd_ioreq32 *ioreqs,
				       unsigned int count)
{
	int i, j, r;
@@ -170,7 +171,7 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
		ioreqs16[j+1].addr  = ioreqs[i].addr;
	}

	r = zd_usb_iowrite16v(&chip->usb, ioreqs16, count16);
	r = zd_usb_iowrite16v_async(&chip->usb, ioreqs16, count16);
#ifdef DEBUG
	if (r) {
		dev_dbg_f(zd_chip_dev(chip),
@@ -180,6 +181,20 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
	return r;
}

int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
			  unsigned int count)
{
	int r;

	zd_usb_iowrite16v_async_start(&chip->usb);
	r = _zd_iowrite32v_async_locked(chip, ioreqs, count);
	if (r) {
		zd_usb_iowrite16v_async_end(&chip->usb, 0);
		return r;
	}
	return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */);
}

int zd_iowrite16a_locked(struct zd_chip *chip,
                  const struct zd_ioreq16 *ioreqs, unsigned int count)
{
@@ -187,6 +202,8 @@ int zd_iowrite16a_locked(struct zd_chip *chip,
	unsigned int i, j, t, max;

	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	zd_usb_iowrite16v_async_start(&chip->usb);

	for (i = 0; i < count; i += j + t) {
		t = 0;
		max = count-i;
@@ -199,8 +216,9 @@ int zd_iowrite16a_locked(struct zd_chip *chip,
			}
		}

		r = zd_usb_iowrite16v(&chip->usb, &ioreqs[i], j);
		r = zd_usb_iowrite16v_async(&chip->usb, &ioreqs[i], j);
		if (r) {
			zd_usb_iowrite16v_async_end(&chip->usb, 0);
			dev_dbg_f(zd_chip_dev(chip),
				  "error zd_usb_iowrite16v. Error number %d\n",
				  r);
@@ -208,7 +226,7 @@ int zd_iowrite16a_locked(struct zd_chip *chip,
		}
	}

	return 0;
	return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */);
}

/* Writes a variable number of 32 bit registers. The functions will split
@@ -221,6 +239,8 @@ int zd_iowrite32a_locked(struct zd_chip *chip,
	int r;
	unsigned int i, j, t, max;

	zd_usb_iowrite16v_async_start(&chip->usb);

	for (i = 0; i < count; i += j + t) {
		t = 0;
		max = count-i;
@@ -233,8 +253,9 @@ int zd_iowrite32a_locked(struct zd_chip *chip,
			}
		}

		r = _zd_iowrite32v_locked(chip, &ioreqs[i], j);
		r = _zd_iowrite32v_async_locked(chip, &ioreqs[i], j);
		if (r) {
			zd_usb_iowrite16v_async_end(&chip->usb, 0);
			dev_dbg_f(zd_chip_dev(chip),
				"error _zd_iowrite32v_locked."
				" Error number %d\n", r);
@@ -242,7 +263,7 @@ int zd_iowrite32a_locked(struct zd_chip *chip,
		}
	}

	return 0;
	return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */);
}

int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value)
+5 −6
Original line number Diff line number Diff line
@@ -1674,7 +1674,7 @@ static void iowrite16v_urb_complete(struct urb *urb)

static int zd_submit_waiting_urb(struct zd_usb *usb, bool last)
{
	int r;
	int r = 0;
	struct urb *urb = usb->urb_async_waiting;

	if (!urb)
@@ -1700,7 +1700,7 @@ error:
	return r;
}

static void zd_usb_iowrite16v_async_start(struct zd_usb *usb)
void zd_usb_iowrite16v_async_start(struct zd_usb *usb)
{
	ZD_ASSERT(usb_anchor_empty(&usb->submitted_cmds));
	ZD_ASSERT(usb->urb_async_waiting == NULL);
@@ -1713,7 +1713,7 @@ static void zd_usb_iowrite16v_async_start(struct zd_usb *usb)
	usb->urb_async_waiting = NULL;
}

static int zd_usb_iowrite16v_async_end(struct zd_usb *usb, unsigned int timeout)
int zd_usb_iowrite16v_async_end(struct zd_usb *usb, unsigned int timeout)
{
	int r;

@@ -1749,8 +1749,7 @@ error:
	return r;
}

static int zd_usb_iowrite16v_async(struct zd_usb *usb,
				   const struct zd_ioreq16 *ioreqs,
int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
			    unsigned int count)
{
	int r;
+4 −0
Original line number Diff line number Diff line
@@ -273,6 +273,10 @@ static inline int zd_usb_ioread16(struct zd_usb *usb, u16 *value,
	return zd_usb_ioread16v(usb, value, (const zd_addr_t *)&addr, 1);
}

void zd_usb_iowrite16v_async_start(struct zd_usb *usb);
int zd_usb_iowrite16v_async_end(struct zd_usb *usb, unsigned int timeout);
int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
			    unsigned int count);
int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
	              unsigned int count);