qcacld-3.0: Add interface to get / set eLNA bypass

Add interface to get / set eLNA bypass from / to firmware

Change-Id: Idf5d6a838d2596767a1fb00040457af721fba69d
CRs-Fixed: 2498525
Этот коммит содержится в:
Paul Zhang
2019-06-23 22:07:31 +08:00
коммит произвёл nshrivas
родитель d681a1def1
Коммит c9dbaeea18
19 изменённых файлов: 1644 добавлений и 5 удалений

67
os_if/fw_offload/inc/os_if_fwol.h Обычный файл
Просмотреть файл

@@ -0,0 +1,67 @@
/*
* Copyright (c) 2019 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: os_if_fwol.h
*
* This Header file provide declaration for OS interface API
*/
#ifndef __OS_IF_FWOL_H__
#define __OS_IF_FWOL_H__
#include "wlan_objmgr_vdev_obj.h"
#ifdef WLAN_FEATURE_ELNA
/**
* os_if_fwol_set_elna_bypass() - Set eLNA bypass
* @vdev: Pointer to vdev
* @attr: Pointer to struct nlattr
*
* Return: 0 on success; error number otherwise
*/
int os_if_fwol_set_elna_bypass(struct wlan_objmgr_vdev *vdev,
const struct nlattr *attr);
/**
* os_if_fwol_get_elna_bypass() - Get eLNA bypass
* @vdev: Pointer to vdev
* @skb: sk buffer to hold nl80211 attributes
* @attr: Pointer to struct nlattr
*
* Return: 0 on success; error number otherwise
*/
int os_if_fwol_get_elna_bypass(struct wlan_objmgr_vdev *vdev,
struct sk_buff *skb,
const struct nlattr *attr);
#else
static inline int os_if_fwol_set_elna_bypass(struct wlan_objmgr_vdev *vdev,
const struct nlattr *attr)
{
return 0;
}
static inline int os_if_fwol_get_elna_bypass(struct wlan_objmgr_vdev *vdev,
struct sk_buff *skb,
const struct nlattr *attr)
{
return 0;
}
#endif /* WLAN_FEATURE_ELNA */
#endif /* __OS_IF_FWOL_H__ */

133
os_if/fw_offload/src/os_if_fwol.c Обычный файл
Просмотреть файл

@@ -0,0 +1,133 @@
/*
* Copyright (c) 2019 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: defines driver functions interfacing with linux kernel
*/
#include "wlan_cfg80211.h"
#include "wlan_osif_request_manager.h"
#include "wlan_fwol_public_structs.h"
#include "wlan_fwol_ucfg_api.h"
#include "os_if_fwol.h"
#ifdef WLAN_FEATURE_ELNA
#define WLAN_WAIT_TIME_GET_ELNA_BYPASS 1500
int os_if_fwol_set_elna_bypass(struct wlan_objmgr_vdev *vdev,
const struct nlattr *attr)
{
struct set_elna_bypass_request req;
QDF_STATUS status;
req.vdev_id = vdev->vdev_objmgr.vdev_id;
req.en_dis = nla_get_u8(attr);
if (req.en_dis > 1) {
osif_err("Invalid elna_bypass value %d", req.en_dis);
return -EINVAL;
}
status = ucfg_fwol_set_elna_bypass(vdev, &req);
if (!QDF_IS_STATUS_SUCCESS(status))
osif_err("Failed to set ELNA BYPASS, %d", status);
return qdf_status_to_os_return(status);
}
struct osif_get_elna_bypass_priv {
uint8_t en_dis;
};
/**
* os_if_fwol_get_elna_bypass_callback() - Get eLNA bypass callback
* @context: Call context
* @response: Pointer to response structure
*
* Return: void
*/
static void
os_if_fwol_get_elna_bypass_callback(void *context,
struct get_elna_bypass_response *response)
{
struct osif_request *request;
struct osif_get_elna_bypass_priv *priv;
request = osif_request_get(context);
if (!request) {
osif_err("Obsolete request");
return;
}
priv = osif_request_priv(request);
priv->en_dis = response->en_dis;
osif_request_complete(request);
osif_request_put(request);
}
int os_if_fwol_get_elna_bypass(struct wlan_objmgr_vdev *vdev,
struct sk_buff *skb,
const struct nlattr *attr)
{
struct get_elna_bypass_request req;
void *cookie;
struct osif_request *request;
struct osif_get_elna_bypass_priv *priv;
static const struct osif_request_params params = {
.priv_size = sizeof(*priv),
.timeout_ms = WLAN_WAIT_TIME_GET_ELNA_BYPASS,
};
QDF_STATUS status;
int ret = 0;
req.vdev_id = vdev->vdev_objmgr.vdev_id;
request = osif_request_alloc(&params);
if (!request) {
osif_err("Request allocation failure");
return -ENOMEM;
}
cookie = osif_request_cookie(request);
status = ucfg_fwol_get_elna_bypass(vdev, &req,
os_if_fwol_get_elna_bypass_callback,
cookie);
if (!QDF_IS_STATUS_SUCCESS(status)) {
osif_err("Failed to get ELNA BYPASS, %d", status);
ret = qdf_status_to_os_return(status);
goto end;
}
ret = osif_request_wait_for_response(request);
if (ret) {
osif_err("Operation timed out");
goto end;
}
priv = osif_request_priv(request);
if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_CONFIG_ELNA_BYPASS,
priv->en_dis)) {
osif_err("put fail");
ret = -EINVAL;
}
end:
osif_request_put(request);
return ret;
}
#endif /* #ifdef WLAN_FEATURE_ELNA */