diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-01-22 05:23:15 +0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-01-22 05:23:15 +0400 |
commit | 19c22c34dcbecb50c24548aa2ff2b07039c26c14 (patch) | |
tree | 15793721700c05310952fede97a2585ca1959709 /drivers/net/wireless/wl12xx/testmode.c | |
parent | 9e5e3097a3febbf317abc6d1b07bc6c33b20c279 (diff) | |
parent | dcd6c92267155e70a94b3927bce681ce74b80d1f (diff) | |
download | linux-19c22c34dcbecb50c24548aa2ff2b07039c26c14.tar.xz |
Merge tag 'v3.3-rc1' into staging/for_v3.3
* tag 'v3.3-rc1': (8187 commits)
Linux 3.3-rc1
x86, syscall: Need __ARCH_WANT_SYS_IPC for 32 bits
qnx4: don't leak ->BitMap on late failure exits
qnx4: reduce the insane nesting in qnx4_checkroot()
qnx4: di_fname is an array, for crying out loud...
KEYS: Permit key_serial() to be called with a const key pointer
keys: fix user_defined key sparse messages
ima: fix cred sparse warning
uml: fix compile for x86-64
MPILIB: Add a missing ENOMEM check
tpm: fix (ACPI S3) suspend regression
nvme: fix merge error due to change of 'make_request_fn' fn type
xen: using EXPORT_SYMBOL requires including export.h
gpio: tps65910: Use correct offset for gpio initialization
acpi/apei/einj: Add extensions to EINJ from rev 5.0 of acpi spec
intel_idle: Split up and provide per CPU initialization func
ACPI processor: Remove unneeded variable passed by acpi_processor_hotadd_init V2
tg3: Fix single-vector MSI-X code
openvswitch: Fix multipart datapath dumps.
ipv6: fix per device IP snmp counters
...
Diffstat (limited to 'drivers/net/wireless/wl12xx/testmode.c')
-rw-r--r-- | drivers/net/wireless/wl12xx/testmode.c | 77 |
1 files changed, 58 insertions, 19 deletions
diff --git a/drivers/net/wireless/wl12xx/testmode.c b/drivers/net/wireless/wl12xx/testmode.c index 4ae8effaee22..25093c0cb0ed 100644 --- a/drivers/net/wireless/wl12xx/testmode.c +++ b/drivers/net/wireless/wl12xx/testmode.c @@ -26,8 +26,10 @@ #include <net/genetlink.h> #include "wl12xx.h" +#include "debug.h" #include "acx.h" #include "reg.h" +#include "ps.h" #define WL1271_TM_MAX_DATA_LENGTH 1024 @@ -36,6 +38,7 @@ enum wl1271_tm_commands { WL1271_TM_CMD_TEST, WL1271_TM_CMD_INTERROGATE, WL1271_TM_CMD_CONFIGURE, + WL1271_TM_CMD_NVS_PUSH, /* Not in use. Keep to not break ABI */ WL1271_TM_CMD_SET_PLT_MODE, WL1271_TM_CMD_RECOVER, @@ -87,31 +90,47 @@ static int wl1271_tm_cmd_test(struct wl1271 *wl, struct nlattr *tb[]) return -EMSGSIZE; mutex_lock(&wl->mutex); - ret = wl1271_cmd_test(wl, buf, buf_len, answer); - mutex_unlock(&wl->mutex); + if (wl->state == WL1271_STATE_OFF) { + ret = -EINVAL; + goto out; + } + + ret = wl1271_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + ret = wl1271_cmd_test(wl, buf, buf_len, answer); if (ret < 0) { wl1271_warning("testmode cmd test failed: %d", ret); - return ret; + goto out_sleep; } if (answer) { len = nla_total_size(buf_len); skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, len); - if (!skb) - return -ENOMEM; + if (!skb) { + ret = -ENOMEM; + goto out_sleep; + } NLA_PUT(skb, WL1271_TM_ATTR_DATA, buf_len, buf); ret = cfg80211_testmode_reply(skb); if (ret < 0) - return ret; + goto out_sleep; } - return 0; +out_sleep: + wl1271_ps_elp_sleep(wl); +out: + mutex_unlock(&wl->mutex); + + return ret; nla_put_failure: kfree_skb(skb); - return -EMSGSIZE; + ret = -EMSGSIZE; + goto out_sleep; } static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[]) @@ -128,33 +147,53 @@ static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[]) ie_id = nla_get_u8(tb[WL1271_TM_ATTR_IE_ID]); + mutex_lock(&wl->mutex); + + if (wl->state == WL1271_STATE_OFF) { + ret = -EINVAL; + goto out; + } + + ret = wl1271_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) - return -ENOMEM; + if (!cmd) { + ret = -ENOMEM; + goto out_sleep; + } - mutex_lock(&wl->mutex); ret = wl1271_cmd_interrogate(wl, ie_id, cmd, sizeof(*cmd)); - mutex_unlock(&wl->mutex); - if (ret < 0) { wl1271_warning("testmode cmd interrogate failed: %d", ret); - kfree(cmd); - return ret; + goto out_free; } skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, sizeof(*cmd)); if (!skb) { - kfree(cmd); - return -ENOMEM; + ret = -ENOMEM; + goto out_free; } NLA_PUT(skb, WL1271_TM_ATTR_DATA, sizeof(*cmd), cmd); + ret = cfg80211_testmode_reply(skb); + if (ret < 0) + goto out_free; + +out_free: + kfree(cmd); +out_sleep: + wl1271_ps_elp_sleep(wl); +out: + mutex_unlock(&wl->mutex); - return 0; + return ret; nla_put_failure: kfree_skb(skb); - return -EMSGSIZE; + ret = -EMSGSIZE; + goto out_free; } static int wl1271_tm_cmd_configure(struct wl1271 *wl, struct nlattr *tb[]) |