Linux Audio

Check our new training course

Loading...
v6.8
  1/*
  2 * Copyright (c) 2014 Redpine Signals Inc.
  3 *
  4 * Permission to use, copy, modify, and/or distribute this software for any
  5 * purpose with or without fee is hereby granted, provided that the above
  6 * copyright notice and this permission notice appear in all copies.
  7 *
  8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 15 */
 16
 17#include <linux/etherdevice.h>
 18#include <linux/if.h>
 19#include "rsi_debugfs.h"
 20#include "rsi_mgmt.h"
 21#include "rsi_common.h"
 22#include "rsi_ps.h"
 23
 24char *str_psstate(enum ps_state state)
 25{
 26	switch (state) {
 27	case PS_NONE:
 28		return "PS_NONE";
 29	case PS_DISABLE_REQ_SENT:
 30		return "PS_DISABLE_REQ_SENT";
 31	case PS_ENABLE_REQ_SENT:
 32		return "PS_ENABLE_REQ_SENT";
 33	case PS_ENABLED:
 34		return "PS_ENABLED";
 35	default:
 36		return "INVALID_STATE";
 37	}
 38}
 39
 40static inline void rsi_modify_ps_state(struct rsi_hw *adapter,
 41				       enum ps_state nstate)
 42{
 43	rsi_dbg(INFO_ZONE, "PS state changed %s => %s\n",
 44		str_psstate(adapter->ps_state),
 45		str_psstate(nstate));
 46
 47	adapter->ps_state = nstate;
 48}
 49
 50void rsi_default_ps_params(struct rsi_hw *adapter)
 51{
 52	struct rsi_ps_info *ps_info = &adapter->ps_info;
 53
 54	ps_info->enabled = true;
 55	ps_info->sleep_type = RSI_SLEEP_TYPE_LP;
 56	ps_info->tx_threshold = 0;
 57	ps_info->rx_threshold = 0;
 58	ps_info->tx_hysterisis = 0;
 59	ps_info->rx_hysterisis = 0;
 60	ps_info->monitor_interval = 0;
 61	ps_info->listen_interval = RSI_DEF_LISTEN_INTERVAL;
 62	ps_info->num_bcns_per_lis_int = 0;
 63	ps_info->dtim_interval_duration = 0;
 64	ps_info->num_dtims_per_sleep = 0;
 65	ps_info->deep_sleep_wakeup_period = RSI_DEF_DS_WAKEUP_PERIOD;
 66}
 67
 68void rsi_enable_ps(struct rsi_hw *adapter, struct ieee80211_vif *vif)
 69{
 70	if (adapter->ps_state != PS_NONE) {
 71		rsi_dbg(ERR_ZONE,
 72			"%s: Cannot accept enable PS in %s state\n",
 73			__func__, str_psstate(adapter->ps_state));
 74		return;
 75	}
 76
 77	if (rsi_send_ps_request(adapter, true, vif)) {
 78		rsi_dbg(ERR_ZONE,
 79			"%s: Failed to send PS request to device\n",
 80			__func__);
 81		return;
 82	}
 83
 84	rsi_modify_ps_state(adapter, PS_ENABLE_REQ_SENT);
 85}
 86
 87/* This function is used to disable power save */
 88void rsi_disable_ps(struct rsi_hw *adapter, struct ieee80211_vif *vif)
 89{
 90	if (adapter->ps_state != PS_ENABLED) {
 91		rsi_dbg(ERR_ZONE,
 92			"%s: Cannot accept disable PS in %s state\n",
 93			__func__, str_psstate(adapter->ps_state));
 94		return;
 95	}
 96
 97	if (rsi_send_ps_request(adapter, false, vif)) {
 98		rsi_dbg(ERR_ZONE,
 99			"%s: Failed to send PS request to device\n",
100			__func__);
101		return;
102	}
103
104	rsi_modify_ps_state(adapter, PS_DISABLE_REQ_SENT);
105}
106
107void rsi_conf_uapsd(struct rsi_hw *adapter, struct ieee80211_vif *vif)
108{
109	int ret;
110
111	if (adapter->ps_state != PS_ENABLED)
112		return;
113
114	ret = rsi_send_ps_request(adapter, false, vif);
115	if (!ret)
116		ret = rsi_send_ps_request(adapter, true, vif);
117	if (ret)
118		rsi_dbg(ERR_ZONE,
119			"%s: Failed to send PS request to device\n",
120			__func__);
121}
122
123int rsi_handle_ps_confirm(struct rsi_hw *adapter, u8 *msg)
124{
125	u16 cfm_type = get_unaligned_le16(msg + PS_CONFIRM_INDEX);
126
127	switch (cfm_type) {
128	case RSI_SLEEP_REQUEST:
129		if (adapter->ps_state == PS_ENABLE_REQ_SENT)
130			rsi_modify_ps_state(adapter, PS_ENABLED);
131		break;
132	case RSI_WAKEUP_REQUEST:
133		if (adapter->ps_state == PS_DISABLE_REQ_SENT)
134			rsi_modify_ps_state(adapter, PS_NONE);
135		break;
136	default:
137		rsi_dbg(ERR_ZONE,
138			"Invalid PS confirm type %x in state %s\n",
139			cfm_type, str_psstate(adapter->ps_state));
140		return -1;
141	}
142
143	return 0;
144}
145
v6.9.4
  1/*
  2 * Copyright (c) 2014 Redpine Signals Inc.
  3 *
  4 * Permission to use, copy, modify, and/or distribute this software for any
  5 * purpose with or without fee is hereby granted, provided that the above
  6 * copyright notice and this permission notice appear in all copies.
  7 *
  8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 15 */
 16
 17#include <linux/etherdevice.h>
 18#include <linux/if.h>
 19#include "rsi_debugfs.h"
 20#include "rsi_mgmt.h"
 21#include "rsi_common.h"
 22#include "rsi_ps.h"
 23
 24char *str_psstate(enum ps_state state)
 25{
 26	switch (state) {
 27	case PS_NONE:
 28		return "PS_NONE";
 29	case PS_DISABLE_REQ_SENT:
 30		return "PS_DISABLE_REQ_SENT";
 31	case PS_ENABLE_REQ_SENT:
 32		return "PS_ENABLE_REQ_SENT";
 33	case PS_ENABLED:
 34		return "PS_ENABLED";
 35	default:
 36		return "INVALID_STATE";
 37	}
 38}
 39
 40static inline void rsi_modify_ps_state(struct rsi_hw *adapter,
 41				       enum ps_state nstate)
 42{
 43	rsi_dbg(INFO_ZONE, "PS state changed %s => %s\n",
 44		str_psstate(adapter->ps_state),
 45		str_psstate(nstate));
 46
 47	adapter->ps_state = nstate;
 48}
 49
 50void rsi_default_ps_params(struct rsi_hw *adapter)
 51{
 52	struct rsi_ps_info *ps_info = &adapter->ps_info;
 53
 54	ps_info->enabled = true;
 55	ps_info->sleep_type = RSI_SLEEP_TYPE_LP;
 56	ps_info->tx_threshold = 0;
 57	ps_info->rx_threshold = 0;
 58	ps_info->tx_hysterisis = 0;
 59	ps_info->rx_hysterisis = 0;
 60	ps_info->monitor_interval = 0;
 61	ps_info->listen_interval = RSI_DEF_LISTEN_INTERVAL;
 62	ps_info->num_bcns_per_lis_int = 0;
 63	ps_info->dtim_interval_duration = 0;
 64	ps_info->num_dtims_per_sleep = 0;
 65	ps_info->deep_sleep_wakeup_period = RSI_DEF_DS_WAKEUP_PERIOD;
 66}
 67
 68void rsi_enable_ps(struct rsi_hw *adapter, struct ieee80211_vif *vif)
 69{
 70	if (adapter->ps_state != PS_NONE) {
 71		rsi_dbg(ERR_ZONE,
 72			"%s: Cannot accept enable PS in %s state\n",
 73			__func__, str_psstate(adapter->ps_state));
 74		return;
 75	}
 76
 77	if (rsi_send_ps_request(adapter, true, vif)) {
 78		rsi_dbg(ERR_ZONE,
 79			"%s: Failed to send PS request to device\n",
 80			__func__);
 81		return;
 82	}
 83
 84	rsi_modify_ps_state(adapter, PS_ENABLE_REQ_SENT);
 85}
 86
 87/* This function is used to disable power save */
 88void rsi_disable_ps(struct rsi_hw *adapter, struct ieee80211_vif *vif)
 89{
 90	if (adapter->ps_state != PS_ENABLED) {
 91		rsi_dbg(ERR_ZONE,
 92			"%s: Cannot accept disable PS in %s state\n",
 93			__func__, str_psstate(adapter->ps_state));
 94		return;
 95	}
 96
 97	if (rsi_send_ps_request(adapter, false, vif)) {
 98		rsi_dbg(ERR_ZONE,
 99			"%s: Failed to send PS request to device\n",
100			__func__);
101		return;
102	}
103
104	rsi_modify_ps_state(adapter, PS_DISABLE_REQ_SENT);
105}
106
107void rsi_conf_uapsd(struct rsi_hw *adapter, struct ieee80211_vif *vif)
108{
109	int ret;
110
111	if (adapter->ps_state != PS_ENABLED)
112		return;
113
114	ret = rsi_send_ps_request(adapter, false, vif);
115	if (!ret)
116		ret = rsi_send_ps_request(adapter, true, vif);
117	if (ret)
118		rsi_dbg(ERR_ZONE,
119			"%s: Failed to send PS request to device\n",
120			__func__);
121}
122
123int rsi_handle_ps_confirm(struct rsi_hw *adapter, u8 *msg)
124{
125	u16 cfm_type = get_unaligned_le16(msg + PS_CONFIRM_INDEX);
126
127	switch (cfm_type) {
128	case RSI_SLEEP_REQUEST:
129		if (adapter->ps_state == PS_ENABLE_REQ_SENT)
130			rsi_modify_ps_state(adapter, PS_ENABLED);
131		break;
132	case RSI_WAKEUP_REQUEST:
133		if (adapter->ps_state == PS_DISABLE_REQ_SENT)
134			rsi_modify_ps_state(adapter, PS_NONE);
135		break;
136	default:
137		rsi_dbg(ERR_ZONE,
138			"Invalid PS confirm type %x in state %s\n",
139			cfm_type, str_psstate(adapter->ps_state));
140		return -1;
141	}
142
143	return 0;
144}
145