diff options
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 4ae8effaee2..25093c0cb0e 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; -	return 0; +out_free: +	kfree(cmd); +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_free;  }  static int wl1271_tm_cmd_configure(struct wl1271 *wl, struct nlattr *tb[])  |