Verified Commit 21036910 authored by Angus Ainslie's avatar Angus Ainslie Committed by Sebastian Krzyszkowiak

wireless: redpine: Import Redpine's 2.0.0.0024 driver

Import the updated driver from here

https://github.com/SiliconLabs/RS911X-nLink-OSDSigned-off-by: default avatarAngus Ainslie <angus@akkea.ca>
parent 6f3052d5
config WLAN_VENDOR_REDPINE
bool "Redpine Signals Inc devices - PROPRIETARY DRIVER"
default y
help
If you have a wireless card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
kernel: saying N will just cause the configurator to skip all
the questions about cards. If you say Y, you will be asked for
your specific card in the following questions.
if WLAN_VENDOR_REDPINE
config REDPINE_91X
tristate "Redpine Signals Inc 91x WLAN driver support"
depends on MAC80211
help
This option enabes support for REDPINE 1x1 devices.
Select M (recommended), if you have a REDPINE 1x1 wireless module.
config REDPINE_DEBUGFS
bool "Redpine Signals Inc debug support"
depends on REDPINE_91X
default y
help
Say Y, if you would like to enable debug support. This option
creates debugfs entries.
config REDPINE_SDIO
tristate "Redpine Signals SDIO bus support"
depends on MMC && REDPINE_91X
default m
help
This option enables the SDIO bus support in rsi drivers.
Select M (recommended), if you have a REDPINE 1x1 wireless module.
config REDPINE_USB
tristate "Redpine Signals USB bus support"
depends on USB && REDPINE_91X
default m
help
This option enables the USB bus support in rsi drivers.
Select M (recommended), if you have a REDPINE 1x1 wireless module.
config REDPINE_BT_ALONE
bool "Redpine Signals BT alone (classic/LE) mode support"
depends on REDPINE_91X
default n
help
This option enables the BT classic alone upport in rsi drivers.
Say Y, if you want to use this feature.
config REDPINE_COEX_MODE
bool "Redpine Signals Wi-Fi BT Coex support"
depends on REDPINE_91X
default n
help
This option enables the Wi-Fi BT coex support in rsi drivers.
Select Y, if you have to use this feature.
config REDPINE_WOW
bool "Redpine Signals WoWLAN support"
depends on REDPINE_91X
default n
help
This option enables the WoWLAN support.
Say Y if you want to use this feature.
config REDPINE_P2P
bool "Redpine Signals Wi-Fi Direct support"
depends on REDPINE_91X
default n
help
This option enables the Wi-Fi Direct support in rsi drivers.
Select Y, if you have to use this feature.
config HW_SCAN_OFFLOAD
bool "Redpine Signals Hardware scan offload feature"
depends on REDPINE_91X
default n
help
This option enables the hardware scan offload option in rsi drivers.
Select Y, if you have to use this feature.
config CARACALLA_BOARD
bool "Redpine device support on Caracalla board"
depends on REDPINE_91X
default n
help
This option is used to support Caracalla board with REDPINE driver.
Select Y, if you have to use this support.
config REDPINE_ZIGB
bool "Redpine device support on Zigbee"
depends on REDPINE_91X && REDPINE_COEX_MODE
default n
help
This option is used to support Zigbee with REDPINE driver.
Select Y, if you have to use this support.
config RS9116_FLASH_MODE
bool "Redpine Signals RS9116 chip Flash mode FW load support"
depends on REDPINE_91X && REDPINE_COEX_MODE
default n
help
This option enables Flash mode FW load support for RS9116.
Say Y if you want to use this feature.
config RS9116_PURISM
bool "Redpine Signals PURISM FW support"
depends on REDPINE_91X && REDPINE_COEX_MODE
default n
help
This option enables the PURISM FW support.
Say Y if you want to use this feature.
endif # WLAN_VENDOR_REDPINE
#/*
# Copyright (c) 2017 Redpine Signals Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION). HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#*/
redpine_91x-y += rsi_91x_main.o
redpine_91x-y += rsi_91x_core.o
redpine_91x-y += rsi_91x_mac80211.o
redpine_91x-y += rsi_91x_mgmt.o
redpine_91x-y += rsi_91x_hal.o
redpine_91x-y += rsi_91x_ps.o
redpine_91x-$(CONFIG_REDPINE_DEBUGFS) += rsi_91x_debugfs.o
redpine_91x-$(CONFIG_REDPINE_BT_ALONE) += rsi_91x_hci.o
redpine_91x-$(CONFIG_RSI_BT_ANDROID) += rsi_91x_bluedroid.o
redpine_91x-$(CONFIG_REDPINE_COEX_MODE) += rsi_91x_coex.o
redpine_91x-$(CONFIG_REDPINE_COEX_MODE) += rsi_91x_hci.o
redpine_91x-$(CONFIG_REDPINE_ZIGB) += rsi_91x_zigb.o
redpine_91x-$(CONFIG_REDPINE_11K) += rsi_91x_rrm.o
redpine_usb-$(CONFIG_REDPINE_USB) += rsi_91x_usb.o rsi_91x_usb_ops.o
redpine_sdio-$(CONFIG_REDPINE_SDIO) += rsi_91x_sdio.o rsi_91x_sdio_ops.o
obj-$(CONFIG_REDPINE_91X) += redpine_91x.o
obj-$(CONFIG_REDPINE_SDIO) += redpine_sdio.o
obj-$(CONFIG_REDPINE_USB) += redpine_usb.o
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (c) 2017 Redpine Signals Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION). HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "rsi_main.h"
#include "rsi_coex.h"
#include "rsi_hal.h"
#include "rsi_mgmt.h"
static u8 rsi_coex_determine_coex_q(struct rsi_coex_ctrl_block *coex_cb)
{
u8 q_num = INVALID_QUEUE;
if (skb_queue_len(&coex_cb->coex_tx_qs[VIP_Q]) > 0)
q_num = VIP_Q;
if (skb_queue_len(&coex_cb->coex_tx_qs[COEX_Q]) > 0)
q_num = COEX_Q;
if (skb_queue_len(&coex_cb->coex_tx_qs[BT_Q]) > 0)
q_num = BT_Q;
if (skb_queue_len(&coex_cb->coex_tx_qs[ZIGB_Q]) > 0)
q_num = ZIGB_Q;
if (skb_queue_len(&coex_cb->coex_tx_qs[WLAN_Q]) > 0)
q_num = WLAN_Q;
return q_num;
}
static void rsi_coex_sched_tx_pkts(struct rsi_coex_ctrl_block *coex_cb)
{
u8 coex_q;
struct sk_buff *skb;
#ifdef CONFIG_REDPINE_ZIGB
struct rsi_common *common = coex_cb->priv;
#endif
while (1) {
coex_q = rsi_coex_determine_coex_q(coex_cb);
redpine_dbg(INFO_ZONE, "queue = %d\n", coex_q);
if (coex_q == INVALID_QUEUE) {
redpine_dbg(DATA_TX_ZONE, "No more pkt\n");
break;
}
if ((coex_q == BT_Q) || (coex_q == ZIGB_Q)) {
skb = skb_dequeue(&coex_cb->coex_tx_qs[BT_Q]);
#ifdef CONFIG_REDPINE_ZIGB
if (common->zb_fsm_state == ZB_DEVICE_READY) {
redpine_dbg(DATA_TX_ZONE, "Sending zigbee pkt\n");
rsi_send_zb_pkt(coex_cb->priv, skb);
} else {
#endif
redpine_dbg(DATA_TX_ZONE, "Sending BT pkt\n");
rsi_send_bt_pkt(coex_cb->priv, skb);
#ifdef CONFIG_REDPINE_ZIGB
}
#endif
}
}
}
/**
* rsi_coex_scheduler_thread() - This function is a kernel thread to schedule
* the coex packets to device
* @common: Pointer to the driver private structure.
*
* Return: None.
*/
static void rsi_coex_scheduler_thread(struct rsi_common *common)
{
int status = 0;
struct rsi_coex_ctrl_block *coex_cb =
(struct rsi_coex_ctrl_block *)common->coex_cb;
u32 timeout = EVENT_WAIT_FOREVER;
do {
status = rsi_wait_event(&coex_cb->coex_tx_thread.event,
timeout);
if (status < 0)
break;
rsi_reset_event(&coex_cb->coex_tx_thread.event);
status = redpine_set_clr_tx_intention(common, BT_ZB_ID, 1);
if (!status)
rsi_coex_sched_tx_pkts(coex_cb);
else
redpine_dbg(ERR_ZONE, "%s,%d: Failed to get tx_access\n",
__func__, __LINE__);
redpine_set_clr_tx_intention(common, BT_ZB_ID, 0);
} while (atomic_read(&coex_cb->coex_tx_thread.thread_done) == 0);
complete_and_exit(&coex_cb->coex_tx_thread.completion, 0);
}
int rsi_coex_recv_pkt(struct rsi_common *common, u8 *msg)
{
u16 msg_type = msg[2];
if (msg_type == COMMON_CARD_READY_IND) {
common->hibernate_resume = false;
redpine_dbg(INFO_ZONE, "COMMON CARD READY RECEIVED\n");
rsi_handle_card_ready(common, msg);
} else if (msg_type == SLEEP_NOTIFY_IND) {
redpine_dbg(INFO_ZONE, "\n\n sleep notify RECEIVED\n");
rsi_mgmt_pkt_recv(common, msg);
}
return 0;
}
int rsi_coex_send_pkt(void *priv,
struct sk_buff *skb,
u8 hal_queue)
{
struct rsi_common *common = (struct rsi_common *)priv;
struct rsi_coex_ctrl_block *coex_cb =
(struct rsi_coex_ctrl_block *)common->coex_cb;
struct skb_info *tx_params = NULL;
int status = 0;
/* Add pkt to queue if not WLAN packet */
if (hal_queue != RSI_WLAN_Q) {
skb_queue_tail(&coex_cb->coex_tx_qs[hal_queue], skb);
rsi_set_event(&coex_cb->coex_tx_thread.event);
return status;
}
if (common->iface_down) {
tx_params = (struct skb_info *)&IEEE80211_SKB_CB(skb)->driver_data;
if (!(tx_params->flags & INTERNAL_MGMT_PKT)) {
rsi_indicate_tx_status(common->priv, skb, -EINVAL);
return 0;
}
}
/* Send packet to hal */
if (skb->priority == MGMT_SOFT_Q)
status = rsi_send_mgmt_pkt(common, skb);
else
status = rsi_send_data_pkt(common, skb);
return 0;
}
int rsi_coex_init(struct rsi_common *common)
{
struct rsi_coex_ctrl_block *coex_cb = NULL;
int cnt;
coex_cb = kzalloc(sizeof(*coex_cb), GFP_KERNEL);
if (!coex_cb)
return -ENOMEM;
common->coex_cb = (void *)coex_cb;
coex_cb->priv = common;
sema_init(&coex_cb->tx_bus_lock, 1);
/* Initialize co-ex queues */
for (cnt = 0; cnt < NUM_COEX_TX_QUEUES; cnt++)
skb_queue_head_init(&coex_cb->coex_tx_qs[cnt]);
rsi_init_event(&coex_cb->coex_tx_thread.event);
/* Initialize co-ex thread */
if (rsi_create_kthread(common,
&coex_cb->coex_tx_thread,
rsi_coex_scheduler_thread,
"Coex-Tx-Thread")) {
redpine_dbg(ERR_ZONE, "%s: Unable to init tx thrd\n", __func__);
goto err;
}
return 0;
err:
return -EINVAL;
}
void rsi_coex_deinit(struct rsi_common *common)
{
int cnt;
struct rsi_coex_ctrl_block *coex_cb =
(struct rsi_coex_ctrl_block *)common->coex_cb;
/* Stop the coex tx thread */
rsi_kill_thread(&coex_cb->coex_tx_thread);
/* Empty the coex queue */
for (cnt = 0; cnt < NUM_COEX_TX_QUEUES; cnt++)
skb_queue_purge(&coex_cb->coex_tx_qs[cnt]);
/* Free the coex control block */
kfree(coex_cb);
}
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (c) 2017 Redpine Signals Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION). HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include "rsi_main.h"
#include "rsi_gpio.h"
/**
* redpine_gpio_deinit(): to de-initialize gpio
* @return:
* @params:
*/
void redpine_gpio_deinit(struct rsi_common *common)
{
gpio_free(common->ulp_gpio_read);
gpio_free(common->ulp_gpio_write);
}
EXPORT_SYMBOL_GPL(redpine_gpio_deinit);
/**
* redpine_gpio_init(): to initialize gpio
* @return:
* @params:
*/
void redpine_gpio_init(struct rsi_common *common)
{
int rc = 0;
char *read_gpio = "device_status";
char *write_gpio = "host_intention";
/* gpio_free() is dangerous to use.FIXME*/
gpio_free(common->ulp_gpio_read);
gpio_free(common->ulp_gpio_write);
rc = gpio_request(common->ulp_gpio_write, write_gpio);
if (rc) {
redpine_dbg(ERR_ZONE, "%s: %s setup failed with err: %d\n",
__func__, write_gpio, rc);
return;
}
rc = gpio_request(common->ulp_gpio_read, read_gpio);
if (rc) {
redpine_dbg(ERR_ZONE, "%s: %s setup failed with err: %d\n",
__func__, read_gpio, rc);
return;
}
rc = gpio_direction_output(common->ulp_gpio_write, 0);
if (rc) {
redpine_dbg(ERR_ZONE, "%s: failed to set %s direction, err: %d\n",
__func__, write_gpio, rc);
return;
}
rc = gpio_direction_input(common->ulp_gpio_read);
if (rc) {
redpine_dbg(ERR_ZONE, "%s: failed to set %s direction, err: %d\n",
__func__, read_gpio, rc);
return;
}
}
EXPORT_SYMBOL_GPL(redpine_gpio_init);
/**
* redpine_set_host_status() - This function is used to toggle host gpio.
*
* @value: The value of the host gpio either TRUE or FALSE.
*
* Return: None.
*/
void redpine_set_host_status(int value, struct rsi_common *common)
{
__gpio_set_value(common->ulp_gpio_write, value);
}
EXPORT_SYMBOL_GPL(redpine_set_host_status);
/**
* redpine_get_device_status() - This function is used to read the LMAC gpio to find
* the LMAC sleep status.
*
* Return: True if gpio status high, false if gpio status low.
*/
int redpine_get_device_status(struct rsi_common *common)
{
return __gpio_get_value(common->ulp_gpio_read);
}
EXPORT_SYMBOL_GPL(redpine_get_device_status);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (c) 2017 Redpine Signals Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION). HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <linux/etherdevice.h>
#include <linux/if.h>
#include <linux/version.h>
#include "rsi_debugfs.h"
#include "rsi_mgmt.h"
#include "rsi_common.h"
#include "rsi_ps.h"
#include "rsi_gpio.h"
/**
* str_psstate() - return the ps state in string format.
*
* @state - PS state.
*
* return: PS state in string format.
*/
char *str_psstate(enum ps_state state)
{
switch (state) {
case PS_NONE:
return "PS_NONE";
case PS_DISABLE_REQ_SENT:
return "PS_DISABLE_REQ_SENT";
case PS_ENABLE_REQ_SENT:
return "PS_ENABLE_REQ_SENT";
case PS_ENABLED:
return "PS_ENABLED";
default:
return "INVALID_STATE";
}
return "INVALID_STATE";
}
/**
* rsi_modify_ps_state() - Modify PS state to a new state.
*
* @adapter: pointer to rsi_hw structure.
* @nstate: new PS state.
*
* return: new state.
*/
static inline void rsi_modify_ps_state(struct rsi_hw *adapter,
enum ps_state nstate)
{
redpine_dbg(INFO_ZONE, "PS state changed %s => %s\n",
str_psstate(adapter->ps_state),
str_psstate(nstate));
adapter->ps_state = nstate;
}
/**
* redpine_default_ps_params() - Initalization of default powersave parameters.
*
* @adapter: pointer to rsi_hw structure.
*
* return: void.
*/
void redpine_default_ps_params(struct rsi_hw *adapter)
{
struct rsi_ps_info *ps_info = &adapter->ps_info;
ps_info->enabled = true;
ps_info->sleep_type = redpine_ps_sleep_type;
ps_info->tx_threshold = 0;
ps_info->rx_threshold = 0;
ps_info->tx_hysterisis = 0;
ps_info->rx_hysterisis = 0;
ps_info->monitor_interval = 0;
ps_info->listen_interval_duration = 0;
ps_info->num_bcns_per_lis_int = 0;
ps_info->dtim_interval_duration = 0;
ps_info->num_dtims_per_sleep = 1;
ps_info->deep_sleep_wakeup_period = 100;
ps_info->uapsd_wakeup_period = RSI_UAPSD_WAKEUP_PERIOD;
}
EXPORT_SYMBOL_GPL(redpine_default_ps_params);
/**
* rsi_enable_ps() - enable power save
*
* @adapter: Pointer to rsi_hw structure.
*
* return: void.
*/
void rsi_enable_ps(struct rsi_hw *adapter)
{
if (rsi_send_ps_request(adapter, true)) {
redpine_dbg(ERR_ZONE,
"%s: Failed to send PS request to device\n",
__func__);
return;
}
rsi_modify_ps_state(adapter, PS_ENABLE_REQ_SENT);
}
/**
* rsi_disable_ps() - disable power save
*
* @adapter: Pointer to rsi_hw structure.
*
* return: void.
*/
void rsi_disable_ps(struct rsi_hw *adapter)
{
if (rsi_send_ps_request(adapter, false)) {
redpine_dbg(ERR_ZONE,
"%s: Failed to send PS request to device\n",
__func__);
return;
}
rsi_modify_ps_state(adapter, PS_DISABLE_REQ_SENT);
}
/**
* rsi_conf_uapsd() - configures UAPSD powersave.
*
* @adapter - Pointer to rsi_hw structure.
*
* return: void.
*/
void rsi_conf_uapsd(struct rsi_hw *adapter)
{
if (adapter->ps_state != PS_ENABLED)
return;
if (rsi_send_ps_request(adapter, false)) {
redpine_dbg(ERR_ZONE,
"%s: Failed to send PS request to device\n",
__func__);
return;
}
if (rsi_send_ps_request(adapter, true)) {
redpine_dbg(ERR_ZONE,
"%s: Failed to send PS request to device\n",
__func__);
}
}
/**
* rsi_handle_ps_confirm() - Processes powersave confirmation.
*
* @adapter - Pointer to rsi_hw structure.
* @msg - Recevied buffer.
*
* return: 0 on success.
*/
int rsi_handle_ps_confirm(struct rsi_hw *adapter, u8 *msg)
{
u16 cfm_type = 0;
cfm_type = *(u16 *)&msg[PS_CONFIRM_INDEX];
switch (cfm_type) {
case SLEEP_REQUEST:
if (adapter->ps_state == PS_ENABLE_REQ_SENT)
rsi_modify_ps_state(adapter, PS_ENABLED);