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

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
...@@ -142,8 +142,9 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr ...@@ -142,8 +142,9 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr
return 0; 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,
unsigned int count) const struct zd_ioreq32 *ioreqs,
unsigned int count)
{ {
int i, j, r; int i, j, r;
struct zd_ioreq16 ioreqs16[USB_MAX_IOWRITE32_COUNT * 2]; struct zd_ioreq16 ioreqs16[USB_MAX_IOWRITE32_COUNT * 2];
...@@ -170,7 +171,7 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, ...@@ -170,7 +171,7 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
ioreqs16[j+1].addr = ioreqs[i].addr; 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 #ifdef DEBUG
if (r) { if (r) {
dev_dbg_f(zd_chip_dev(chip), dev_dbg_f(zd_chip_dev(chip),
...@@ -180,6 +181,20 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, ...@@ -180,6 +181,20 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
return r; 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, int zd_iowrite16a_locked(struct zd_chip *chip,
const struct zd_ioreq16 *ioreqs, unsigned int count) const struct zd_ioreq16 *ioreqs, unsigned int count)
{ {
...@@ -187,6 +202,8 @@ int zd_iowrite16a_locked(struct zd_chip *chip, ...@@ -187,6 +202,8 @@ int zd_iowrite16a_locked(struct zd_chip *chip,
unsigned int i, j, t, max; unsigned int i, j, t, max;
ZD_ASSERT(mutex_is_locked(&chip->mutex)); ZD_ASSERT(mutex_is_locked(&chip->mutex));
zd_usb_iowrite16v_async_start(&chip->usb);
for (i = 0; i < count; i += j + t) { for (i = 0; i < count; i += j + t) {
t = 0; t = 0;
max = count-i; max = count-i;
...@@ -199,8 +216,9 @@ int zd_iowrite16a_locked(struct zd_chip *chip, ...@@ -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) { if (r) {
zd_usb_iowrite16v_async_end(&chip->usb, 0);
dev_dbg_f(zd_chip_dev(chip), dev_dbg_f(zd_chip_dev(chip),
"error zd_usb_iowrite16v. Error number %d\n", "error zd_usb_iowrite16v. Error number %d\n",
r); r);
...@@ -208,7 +226,7 @@ int zd_iowrite16a_locked(struct zd_chip *chip, ...@@ -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 /* Writes a variable number of 32 bit registers. The functions will split
...@@ -221,6 +239,8 @@ int zd_iowrite32a_locked(struct zd_chip *chip, ...@@ -221,6 +239,8 @@ int zd_iowrite32a_locked(struct zd_chip *chip,
int r; int r;
unsigned int i, j, t, max; unsigned int i, j, t, max;
zd_usb_iowrite16v_async_start(&chip->usb);
for (i = 0; i < count; i += j + t) { for (i = 0; i < count; i += j + t) {
t = 0; t = 0;
max = count-i; max = count-i;
...@@ -233,8 +253,9 @@ int zd_iowrite32a_locked(struct zd_chip *chip, ...@@ -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) { if (r) {
zd_usb_iowrite16v_async_end(&chip->usb, 0);
dev_dbg_f(zd_chip_dev(chip), dev_dbg_f(zd_chip_dev(chip),
"error _zd_iowrite32v_locked." "error _zd_iowrite32v_locked."
" Error number %d\n", r); " Error number %d\n", r);
...@@ -242,7 +263,7 @@ int zd_iowrite32a_locked(struct zd_chip *chip, ...@@ -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) int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value)
......
...@@ -1674,7 +1674,7 @@ static void iowrite16v_urb_complete(struct urb *urb) ...@@ -1674,7 +1674,7 @@ static void iowrite16v_urb_complete(struct urb *urb)
static int zd_submit_waiting_urb(struct zd_usb *usb, bool last) static int zd_submit_waiting_urb(struct zd_usb *usb, bool last)
{ {
int r; int r = 0;
struct urb *urb = usb->urb_async_waiting; struct urb *urb = usb->urb_async_waiting;
if (!urb) if (!urb)
...@@ -1700,7 +1700,7 @@ static int zd_submit_waiting_urb(struct zd_usb *usb, bool last) ...@@ -1700,7 +1700,7 @@ static int zd_submit_waiting_urb(struct zd_usb *usb, bool last)
return r; 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_anchor_empty(&usb->submitted_cmds));
ZD_ASSERT(usb->urb_async_waiting == NULL); ZD_ASSERT(usb->urb_async_waiting == NULL);
...@@ -1713,7 +1713,7 @@ static void zd_usb_iowrite16v_async_start(struct zd_usb *usb) ...@@ -1713,7 +1713,7 @@ static void zd_usb_iowrite16v_async_start(struct zd_usb *usb)
usb->urb_async_waiting = NULL; 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; int r;
...@@ -1749,9 +1749,8 @@ static int zd_usb_iowrite16v_async_end(struct zd_usb *usb, unsigned int timeout) ...@@ -1749,9 +1749,8 @@ static int zd_usb_iowrite16v_async_end(struct zd_usb *usb, unsigned int timeout)
return r; return r;
} }
static int zd_usb_iowrite16v_async(struct zd_usb *usb, int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
const struct zd_ioreq16 *ioreqs, unsigned int count)
unsigned int count)
{ {
int r; int r;
struct usb_device *udev; struct usb_device *udev;
......
...@@ -273,6 +273,10 @@ static inline int zd_usb_ioread16(struct zd_usb *usb, u16 *value, ...@@ -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); 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, int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
unsigned int count); unsigned int count);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment