diff options
author | Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | 2011-02-12 13:43:42 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-02-14 15:51:21 -0500 |
commit | 8662b2518ff7995002378058488326ef7cb80de8 (patch) | |
tree | e7b0d1c7fca5820a46ac2411a5b4a8e36f8779c4 /drivers/net | |
parent | eefdbec1ea8b7093d2c09d1825f68438701723cf (diff) |
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: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_chip.c | 35 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_usb.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_usb.h | 4 |
3 files changed, 37 insertions, 13 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index 54f68f134ea7..a73a305d3cba 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c | |||
@@ -142,8 +142,9 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr | |||
142 | return 0; | 142 | return 0; |
143 | } | 143 | } |
144 | 144 | ||
145 | int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, | 145 | static int _zd_iowrite32v_async_locked(struct zd_chip *chip, |
146 | unsigned int count) | 146 | const struct zd_ioreq32 *ioreqs, |
147 | unsigned int count) | ||
147 | { | 148 | { |
148 | int i, j, r; | 149 | int i, j, r; |
149 | struct zd_ioreq16 ioreqs16[USB_MAX_IOWRITE32_COUNT * 2]; | 150 | 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 | ioreqs16[j+1].addr = ioreqs[i].addr; | 171 | ioreqs16[j+1].addr = ioreqs[i].addr; |
171 | } | 172 | } |
172 | 173 | ||
173 | r = zd_usb_iowrite16v(&chip->usb, ioreqs16, count16); | 174 | r = zd_usb_iowrite16v_async(&chip->usb, ioreqs16, count16); |
174 | #ifdef DEBUG | 175 | #ifdef DEBUG |
175 | if (r) { | 176 | if (r) { |
176 | dev_dbg_f(zd_chip_dev(chip), | 177 | 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 | return r; | 181 | return r; |
181 | } | 182 | } |
182 | 183 | ||
184 | int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, | ||
185 | unsigned int count) | ||
186 | { | ||
187 | int r; | ||
188 | |||
189 | zd_usb_iowrite16v_async_start(&chip->usb); | ||
190 | r = _zd_iowrite32v_async_locked(chip, ioreqs, count); | ||
191 | if (r) { | ||
192 | zd_usb_iowrite16v_async_end(&chip->usb, 0); | ||
193 | return r; | ||
194 | } | ||
195 | return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */); | ||
196 | } | ||
197 | |||
183 | int zd_iowrite16a_locked(struct zd_chip *chip, | 198 | int zd_iowrite16a_locked(struct zd_chip *chip, |
184 | const struct zd_ioreq16 *ioreqs, unsigned int count) | 199 | const struct zd_ioreq16 *ioreqs, unsigned int count) |
185 | { | 200 | { |
@@ -187,6 +202,8 @@ int zd_iowrite16a_locked(struct zd_chip *chip, | |||
187 | unsigned int i, j, t, max; | 202 | unsigned int i, j, t, max; |
188 | 203 | ||
189 | ZD_ASSERT(mutex_is_locked(&chip->mutex)); | 204 | ZD_ASSERT(mutex_is_locked(&chip->mutex)); |
205 | zd_usb_iowrite16v_async_start(&chip->usb); | ||
206 | |||
190 | for (i = 0; i < count; i += j + t) { | 207 | for (i = 0; i < count; i += j + t) { |
191 | t = 0; | 208 | t = 0; |
192 | max = count-i; | 209 | max = count-i; |
@@ -199,8 +216,9 @@ int zd_iowrite16a_locked(struct zd_chip *chip, | |||
199 | } | 216 | } |
200 | } | 217 | } |
201 | 218 | ||
202 | r = zd_usb_iowrite16v(&chip->usb, &ioreqs[i], j); | 219 | r = zd_usb_iowrite16v_async(&chip->usb, &ioreqs[i], j); |
203 | if (r) { | 220 | if (r) { |
221 | zd_usb_iowrite16v_async_end(&chip->usb, 0); | ||
204 | dev_dbg_f(zd_chip_dev(chip), | 222 | dev_dbg_f(zd_chip_dev(chip), |
205 | "error zd_usb_iowrite16v. Error number %d\n", | 223 | "error zd_usb_iowrite16v. Error number %d\n", |
206 | r); | 224 | r); |
@@ -208,7 +226,7 @@ int zd_iowrite16a_locked(struct zd_chip *chip, | |||
208 | } | 226 | } |
209 | } | 227 | } |
210 | 228 | ||
211 | return 0; | 229 | return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */); |
212 | } | 230 | } |
213 | 231 | ||
214 | /* Writes a variable number of 32 bit registers. The functions will split | 232 | /* 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 | int r; | 239 | int r; |
222 | unsigned int i, j, t, max; | 240 | unsigned int i, j, t, max; |
223 | 241 | ||
242 | zd_usb_iowrite16v_async_start(&chip->usb); | ||
243 | |||
224 | for (i = 0; i < count; i += j + t) { | 244 | for (i = 0; i < count; i += j + t) { |
225 | t = 0; | 245 | t = 0; |
226 | max = count-i; | 246 | max = count-i; |
@@ -233,8 +253,9 @@ int zd_iowrite32a_locked(struct zd_chip *chip, | |||
233 | } | 253 | } |
234 | } | 254 | } |
235 | 255 | ||
236 | r = _zd_iowrite32v_locked(chip, &ioreqs[i], j); | 256 | r = _zd_iowrite32v_async_locked(chip, &ioreqs[i], j); |
237 | if (r) { | 257 | if (r) { |
258 | zd_usb_iowrite16v_async_end(&chip->usb, 0); | ||
238 | dev_dbg_f(zd_chip_dev(chip), | 259 | dev_dbg_f(zd_chip_dev(chip), |
239 | "error _zd_iowrite32v_locked." | 260 | "error _zd_iowrite32v_locked." |
240 | " Error number %d\n", r); | 261 | " Error number %d\n", r); |
@@ -242,7 +263,7 @@ int zd_iowrite32a_locked(struct zd_chip *chip, | |||
242 | } | 263 | } |
243 | } | 264 | } |
244 | 265 | ||
245 | return 0; | 266 | return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */); |
246 | } | 267 | } |
247 | 268 | ||
248 | int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value) | 269 | int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value) |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index c98f6e7eed3d..81e80489a052 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -1674,7 +1674,7 @@ static void iowrite16v_urb_complete(struct urb *urb) | |||
1674 | 1674 | ||
1675 | static int zd_submit_waiting_urb(struct zd_usb *usb, bool last) | 1675 | static int zd_submit_waiting_urb(struct zd_usb *usb, bool last) |
1676 | { | 1676 | { |
1677 | int r; | 1677 | int r = 0; |
1678 | struct urb *urb = usb->urb_async_waiting; | 1678 | struct urb *urb = usb->urb_async_waiting; |
1679 | 1679 | ||
1680 | if (!urb) | 1680 | if (!urb) |
@@ -1700,7 +1700,7 @@ error: | |||
1700 | return r; | 1700 | return r; |
1701 | } | 1701 | } |
1702 | 1702 | ||
1703 | static void zd_usb_iowrite16v_async_start(struct zd_usb *usb) | 1703 | void zd_usb_iowrite16v_async_start(struct zd_usb *usb) |
1704 | { | 1704 | { |
1705 | ZD_ASSERT(usb_anchor_empty(&usb->submitted_cmds)); | 1705 | ZD_ASSERT(usb_anchor_empty(&usb->submitted_cmds)); |
1706 | ZD_ASSERT(usb->urb_async_waiting == NULL); | 1706 | ZD_ASSERT(usb->urb_async_waiting == NULL); |
@@ -1713,7 +1713,7 @@ static void zd_usb_iowrite16v_async_start(struct zd_usb *usb) | |||
1713 | usb->urb_async_waiting = NULL; | 1713 | usb->urb_async_waiting = NULL; |
1714 | } | 1714 | } |
1715 | 1715 | ||
1716 | static int zd_usb_iowrite16v_async_end(struct zd_usb *usb, unsigned int timeout) | 1716 | int zd_usb_iowrite16v_async_end(struct zd_usb *usb, unsigned int timeout) |
1717 | { | 1717 | { |
1718 | int r; | 1718 | int r; |
1719 | 1719 | ||
@@ -1749,9 +1749,8 @@ error: | |||
1749 | return r; | 1749 | return r; |
1750 | } | 1750 | } |
1751 | 1751 | ||
1752 | static int zd_usb_iowrite16v_async(struct zd_usb *usb, | 1752 | int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, |
1753 | const struct zd_ioreq16 *ioreqs, | 1753 | unsigned int count) |
1754 | unsigned int count) | ||
1755 | { | 1754 | { |
1756 | int r; | 1755 | int r; |
1757 | struct usb_device *udev; | 1756 | struct usb_device *udev; |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index 929142692063..b3df2c8116cc 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h | |||
@@ -273,6 +273,10 @@ static inline int zd_usb_ioread16(struct zd_usb *usb, u16 *value, | |||
273 | return zd_usb_ioread16v(usb, value, (const zd_addr_t *)&addr, 1); | 273 | return zd_usb_ioread16v(usb, value, (const zd_addr_t *)&addr, 1); |
274 | } | 274 | } |
275 | 275 | ||
276 | void zd_usb_iowrite16v_async_start(struct zd_usb *usb); | ||
277 | int zd_usb_iowrite16v_async_end(struct zd_usb *usb, unsigned int timeout); | ||
278 | int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, | ||
279 | unsigned int count); | ||
276 | int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, | 280 | int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, |
277 | unsigned int count); | 281 | unsigned int count); |
278 | 282 | ||