Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ce86893f authored by Karun Eagalapati's avatar Karun Eagalapati Committed by Kalle Valo
Browse files

rsi: add support for legacy power save



This patch adds support for legacy power save. Necessary
configuration frames are downloaded to firmware when power save
is enabled/disabled

Signed-off-by: default avatarKarun Eagalapati <karun256@gmail.com>
Signed-off-by: default avatarAmitkumar Karwar <amit.karwar@redpinesignals.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 588349a1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@ rsi_91x-y += rsi_91x_core.o
rsi_91x-y			+= rsi_91x_mac80211.o
rsi_91x-y			+= rsi_91x_mgmt.o
rsi_91x-y			+= rsi_91x_hal.o
rsi_91x-y			+= rsi_91x_ps.o
rsi_91x-$(CONFIG_RSI_DEBUGFS)	+= rsi_91x_debugfs.o

rsi_usb-y			+= rsi_91x_usb.o rsi_91x_usb_ops.o
+7 −0
Original line number Diff line number Diff line
@@ -111,6 +111,8 @@ static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
/* This function prepares descriptor for given data packet */
static int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
{
	struct rsi_hw *adapter = common->priv;
	struct ieee80211_vif *vif;
	struct ieee80211_hdr *wh = NULL;
	struct ieee80211_tx_info *info;
	struct skb_info *tx_params;
@@ -148,6 +150,7 @@ static int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
	xtend_desc = (struct xtended_desc *)&skb->data[FRAME_DESC_SZ];
	wh = (struct ieee80211_hdr *)&skb->data[header_size];
	seq_num = (le16_to_cpu(wh->seq_ctrl) >> 4);
	vif = adapter->vifs[0];

	data_desc->xtend_desc_size = header_size - FRAME_DESC_SZ;

@@ -156,6 +159,10 @@ static int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
		data_desc->mac_flags |= cpu_to_le16(RSI_QOS_ENABLE);
	}

	if ((vif->type == NL80211_IFTYPE_STATION) &&
	    (adapter->ps_state == PS_ENABLED))
		wh->frame_control |= cpu_to_le16(RSI_SET_PS_ENABLE);

	if ((!(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) &&
	    (common->secinfo.security_enable)) {
		if (rsi_is_cipher_wep(common))
+22 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include "rsi_debugfs.h"
#include "rsi_mgmt.h"
#include "rsi_common.h"
#include "rsi_ps.h"

static const struct ieee80211_channel rsi_2ghz_channels[] = {
	{ .band = NL80211_BAND_2GHZ, .center_freq = 2412,
@@ -467,6 +468,8 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw,
{
	struct rsi_hw *adapter = hw->priv;
	struct rsi_common *common = adapter->priv;
	struct ieee80211_vif *vif = adapter->vifs[0];
	struct ieee80211_conf *conf = &hw->conf;
	int status = -EOPNOTSUPP;

	mutex_lock(&common->mutex);
@@ -480,6 +483,19 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw,
		status = rsi_config_power(hw);
	}

	/* Power save parameters */
	if ((changed & IEEE80211_CONF_CHANGE_PS) &&
	    (vif->type == NL80211_IFTYPE_STATION)) {
		unsigned long flags;

		spin_lock_irqsave(&adapter->ps_lock, flags);
		if (conf->flags & IEEE80211_CONF_PS)
			rsi_enable_ps(adapter);
		else
			rsi_disable_ps(adapter);
		spin_unlock_irqrestore(&adapter->ps_lock, flags);
	}

	mutex_unlock(&common->mutex);

	return status;
@@ -522,6 +538,8 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
{
	struct rsi_hw *adapter = hw->priv;
	struct rsi_common *common = adapter->priv;
	struct ieee80211_bss_conf *bss = &vif->bss_conf;
	struct ieee80211_conf *conf = &hw->conf;
	u16 rx_filter_word = 0;

	mutex_lock(&common->mutex);
@@ -540,6 +558,8 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
				      bss_conf->bssid,
				      bss_conf->qos,
				      bss_conf->aid);
		adapter->ps_info.dtim_interval_duration = bss->dtim_period;
		adapter->ps_info.listen_interval = conf->listen_interval;
	}

	if (changed & BSS_CHANGED_CQM) {
@@ -1283,6 +1303,8 @@ int rsi_mac80211_attach(struct rsi_common *common)
	ieee80211_hw_set(hw, SIGNAL_DBM);
	ieee80211_hw_set(hw, HAS_RATE_CONTROL);
	ieee80211_hw_set(hw, AMPDU_AGGREGATION);
	ieee80211_hw_set(hw, SUPPORTS_PS);
	ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);

	hw->queues = MAX_HW_QUEUES;
	hw->extra_tx_headroom = RSI_NEEDED_HEADROOM;
+2 −0
Original line number Diff line number Diff line
@@ -231,6 +231,8 @@ struct rsi_hw *rsi_91x_init(void)
		goto err;
	}

	rsi_default_ps_params(adapter);
	spin_lock_init(&adapter->ps_lock);
	common->init_done = true;
	return adapter;

+56 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/etherdevice.h>
#include "rsi_mgmt.h"
#include "rsi_common.h"
#include "rsi_ps.h"

static struct bootup_params boot_params_20 = {
	.magic_number = cpu_to_le16(0x5aa5),
@@ -1396,6 +1397,58 @@ int rsi_send_rx_filter_frame(struct rsi_common *common, u16 rx_filter_word)
	return rsi_send_internal_mgmt_frame(common, skb);
}

int rsi_send_ps_request(struct rsi_hw *adapter, bool enable)
{
	struct rsi_common *common = adapter->priv;
	struct ieee80211_bss_conf *bss = &adapter->vifs[0]->bss_conf;
	struct rsi_request_ps *ps;
	struct rsi_ps_info *ps_info;
	struct sk_buff *skb;
	int frame_len = sizeof(*ps);

	skb = dev_alloc_skb(frame_len);
	if (!skb)
		return -ENOMEM;
	memset(skb->data, 0, frame_len);

	ps = (struct rsi_request_ps *)skb->data;
	ps_info = &adapter->ps_info;

	rsi_set_len_qno(&ps->desc.desc_dword0.len_qno,
			(frame_len - FRAME_DESC_SZ), RSI_WIFI_MGMT_Q);
	ps->desc.desc_dword0.frame_type = WAKEUP_SLEEP_REQUEST;
	if (enable) {
		ps->ps_sleep.enable = RSI_PS_ENABLE;
		ps->desc.desc_dword3.token = cpu_to_le16(RSI_SLEEP_REQUEST);
	} else {
		ps->ps_sleep.enable = RSI_PS_DISABLE;
		ps->desc.desc_dword0.len_qno |= cpu_to_le16(RSI_PS_DISABLE_IND);
		ps->desc.desc_dword3.token = cpu_to_le16(RSI_WAKEUP_REQUEST);
	}
	ps->ps_sleep.sleep_type = ps_info->sleep_type;
	ps->ps_sleep.num_bcns_per_lis_int =
		cpu_to_le16(ps_info->num_bcns_per_lis_int);
	ps->ps_sleep.sleep_duration =
		cpu_to_le32(ps_info->deep_sleep_wakeup_period);

	if (bss->assoc)
		ps->ps_sleep.connected_sleep = RSI_CONNECTED_SLEEP;
	else
		ps->ps_sleep.connected_sleep = RSI_DEEP_SLEEP;

	ps->ps_listen_interval = cpu_to_le32(ps_info->listen_interval);
	ps->ps_dtim_interval_duration =
		cpu_to_le32(ps_info->dtim_interval_duration);

	if (ps_info->listen_interval > ps_info->dtim_interval_duration)
		ps->ps_listen_interval = cpu_to_le32(RSI_PS_DISABLE);

	ps->ps_num_dtim_intervals = cpu_to_le16(ps_info->num_dtims_per_sleep);
	skb_put(skb, frame_len);

	return rsi_send_internal_mgmt_frame(common, skb);
}

/**
 * rsi_set_antenna() - This fuction send antenna configuration request
 *		       to device
@@ -1569,7 +1622,9 @@ static int rsi_handle_ta_confirm_type(struct rsi_common *common,
			return 0;
		}
		break;

	case WAKEUP_SLEEP_REQUEST:
		rsi_dbg(INFO_ZONE, "Wakeup/Sleep confirmation.\n");
		return rsi_handle_ps_confirm(adapter, msg);
	default:
		rsi_dbg(INFO_ZONE, "%s: Invalid TA confirm pkt received\n",
			__func__);
Loading