summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/carl9170
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/carl9170')
-rw-r--r--drivers/net/wireless/ath/carl9170/cmd.h51
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/usb.c25
3 files changed, 48 insertions, 30 deletions
diff --git a/drivers/net/wireless/ath/carl9170/cmd.h b/drivers/net/wireless/ath/carl9170/cmd.h
index f78728c3829..568174c71b9 100644
--- a/drivers/net/wireless/ath/carl9170/cmd.h
+++ b/drivers/net/wireless/ath/carl9170/cmd.h
@@ -116,8 +116,9 @@ __regwrite_out : \
} while (0);
-#define carl9170_async_get_buf() \
+#define carl9170_async_regwrite_get_buf() \
do { \
+ __nreg = 0; \
__cmd = carl9170_cmd_buf(__carl, CARL9170_CMD_WREG_ASYNC, \
CARL9170_MAX_CMD_PAYLOAD_LEN); \
if (__cmd == NULL) { \
@@ -128,38 +129,42 @@ do { \
#define carl9170_async_regwrite_begin(carl) \
do { \
- int __nreg = 0, __err = 0; \
struct ar9170 *__carl = carl; \
struct carl9170_cmd *__cmd; \
- carl9170_async_get_buf(); \
+ unsigned int __nreg; \
+ int __err = 0; \
+ carl9170_async_regwrite_get_buf(); \
+
+#define carl9170_async_regwrite_flush() \
+do { \
+ if (__cmd == NULL || __nreg == 0) \
+ break; \
+ \
+ if (IS_ACCEPTING_CMD(__carl) && __nreg) { \
+ __cmd->hdr.len = 8 * __nreg; \
+ __err = __carl9170_exec_cmd(__carl, __cmd, true); \
+ __cmd = NULL; \
+ break; \
+ } \
+ goto __async_regwrite_out; \
+} while (0)
#define carl9170_async_regwrite(r, v) do { \
+ if (__cmd == NULL) \
+ carl9170_async_regwrite_get_buf(); \
__cmd->wreg.regs[__nreg].addr = cpu_to_le32(r); \
__cmd->wreg.regs[__nreg].val = cpu_to_le32(v); \
__nreg++; \
- if ((__nreg >= PAYLOAD_MAX/2)) { \
- if (IS_ACCEPTING_CMD(__carl)) { \
- __cmd->hdr.len = 8 * __nreg; \
- __err = __carl9170_exec_cmd(__carl, __cmd, true);\
- __cmd = NULL; \
- carl9170_async_get_buf(); \
- } else { \
- goto __async_regwrite_out; \
- } \
- __nreg = 0; \
- if (__err) \
- goto __async_regwrite_out; \
- } \
+ if ((__nreg >= PAYLOAD_MAX / 2)) \
+ carl9170_async_regwrite_flush(); \
} while (0)
-#define carl9170_async_regwrite_finish() \
+#define carl9170_async_regwrite_finish() do { \
__async_regwrite_out : \
- if (__err == 0 && __nreg) { \
- __cmd->hdr.len = 8 * __nreg; \
- if (IS_ACCEPTING_CMD(__carl)) \
- __err = __carl9170_exec_cmd(__carl, __cmd, true);\
- __nreg = 0; \
- }
+ if (__cmd != NULL && __err == 0) \
+ carl9170_async_regwrite_flush(); \
+ kfree(__cmd); \
+} while (0) \
#define carl9170_async_regwrite_result() \
__err; \
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index 3cc99f3f7ab..980ae70ea42 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -639,8 +639,8 @@ init:
if (err)
goto unlock;
} else {
- err = carl9170_mod_virtual_mac(ar, vif_id, vif->addr);
rcu_read_unlock();
+ err = carl9170_mod_virtual_mac(ar, vif_id, vif->addr);
if (err)
goto unlock;
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c
index c7f6193934e..d8607f4c144 100644
--- a/drivers/net/wireless/ath/carl9170/usb.c
+++ b/drivers/net/wireless/ath/carl9170/usb.c
@@ -591,16 +591,23 @@ int __carl9170_exec_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd,
const bool free_buf)
{
struct urb *urb;
+ int err = 0;
- if (!IS_INITIALIZED(ar))
- return -EPERM;
+ if (!IS_INITIALIZED(ar)) {
+ err = -EPERM;
+ goto err_free;
+ }
- if (WARN_ON(cmd->hdr.len > CARL9170_MAX_CMD_LEN - 4))
- return -EINVAL;
+ if (WARN_ON(cmd->hdr.len > CARL9170_MAX_CMD_LEN - 4)) {
+ err = -EINVAL;
+ goto err_free;
+ }
urb = usb_alloc_urb(0, GFP_ATOMIC);
- if (!urb)
- return -ENOMEM;
+ if (!urb) {
+ err = -ENOMEM;
+ goto err_free;
+ }
usb_fill_int_urb(urb, ar->udev, usb_sndintpipe(ar->udev,
AR9170_USB_EP_CMD), cmd, cmd->hdr.len + 4,
@@ -613,6 +620,12 @@ int __carl9170_exec_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd,
usb_free_urb(urb);
return carl9170_usb_submit_cmd_urb(ar);
+
+err_free:
+ if (free_buf)
+ kfree(cmd);
+
+ return err;
}
int carl9170_exec_cmd(struct ar9170 *ar, const enum carl9170_cmd_oids cmd,