qcacld-3.0: Featurize some vendor commands

Featurize some vendor commands to compile out when not needed.

Change-Id: I6757b5764930efbd9cd1c7ab74e5990e96267421
CRs-Fixed: 2270461
This commit is contained in:
Qiwei Cai 2018-07-26 15:50:22 +08:00 • committed by nshrivas
commit e689a26cd8
36 changed files with 7245 additions and 6358 deletions

53
Kbuild
View file

@ -166,6 +166,46 @@ ifeq ($(CONFIG_WLAN_FEATURE_PACKET_FILTERING), y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_packet_filter.o
endif
ifeq ($(CONFIG_FEATURE_RSSI_MONITOR), y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_rssi_monitor.o
endif
ifeq ($(CONFIG_FEATURE_BSS_TRANSITION), y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_bss_transition.o
endif
ifeq ($(CONFIG_FEATURE_STATION_INFO), y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_station_info.o
endif
ifeq ($(CONFIG_FEATURE_TX_POWER), y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_tx_power.o
endif
ifeq ($(CONFIG_FEATURE_OTA_TEST), y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_ota_test.o
endif
ifeq ($(CONFIG_FEATURE_ACTIVE_TOS), y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_active_tos.o
endif
ifeq ($(CONFIG_FEATURE_SAR_LIMITS), y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sar_limits.o
endif
ifeq ($(CONFIG_FEATURE_CONCURRENCY_MATRIX), y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_concurrency_matrix.o
endif
ifeq ($(CONFIG_FEATURE_SAP_COND_CHAN_SWITCH), y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sap_cond_chan_switch.o
endif
ifeq ($(CONFIG_FEATURE_P2P_LISTEN_OFFLOAD), y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_p2p_listen_offload.o
endif
########### Driver Synchronization Core (DSC) ###########
DSC_DIR := components/dsc
DSC_INC_DIR := $(DSC_DIR)/inc
@ -2093,12 +2133,23 @@ ifeq ($(CONFIG_QCA6290_11AX), y)
cppflags-y += -DQCA_WIFI_QCA6290_11AX
endif
cppflags-$(CONFIG_WLAN_FEATURE_11AX) += -DWLAN_FEATURE_11AX
cppflags-$(CONFIG_WLAN_FEATURE_11AX) += -DWLAN_FEATURE_11AX_BSS_COLOR
cppflags-$(CONFIG_LITHIUM) += -DFEATURE_AST
# Vendor Commands
cppflags-$(CONFIG_FEATURE_RSSI_MONITOR) += -DFEATURE_RSSI_MONITOR
cppflags-$(CONFIG_FEATURE_BSS_TRANSITION) += -DFEATURE_BSS_TRANSITION
cppflags-$(CONFIG_FEATURE_STATION_INFO) += -DFEATURE_STATION_INFO
cppflags-$(CONFIG_FEATURE_TX_POWER) += -DFEATURE_TX_POWER
cppflags-$(CONFIG_FEATURE_OTA_TEST) += -DFEATURE_OTA_TEST
cppflags-$(CONFIG_FEATURE_ACTIVE_TOS) += -DFEATURE_ACTIVE_TOS
cppflags-$(CONFIG_FEATURE_SAR_LIMITS) += -DFEATURE_SAR_LIMITS
cppflags-$(CONFIG_FEATURE_CONCURRENCY_MATRIX) += -DFEATURE_CONCURRENCY_MATRIX
cppflags-$(CONFIG_FEATURE_SAP_COND_CHAN_SWITCH) += -DFEATURE_SAP_COND_CHAN_SWITCH
cppflags-$(CONFIG_FEATURE_P2P_LISTEN_OFFLOAD) += -DFEATURE_P2P_LISTEN_OFFLOAD
# Dummy flag for WIN/MCL converged data path compilation
cppflags-y += -DDP_PRINT_ENABLE=0
cppflags-y += -DATH_SUPPORT_WRAP=0

View file

@ -573,6 +573,18 @@ CONFIG_FEATURE_MONITOR_MODE_SUPPORT := y
CONFIG_WLAN_FEATURE_TWT := y
CONFIG_WLAN_FEATURE_BMI := y
#Flags to enable/disable vendor commands
CONFIG_FEATURE_RSSI_MONITOR := y
CONFIG_FEATURE_BSS_TRANSITION := y
CONFIG_FEATURE_STATION_INFO := y
CONFIG_FEATURE_TX_POWER := y
CONFIG_FEATURE_OTA_TEST := y
CONFIG_FEATURE_ACTIVE_TOS := y
CONFIG_FEATURE_SAR_LIMITS := y
CONFIG_FEATURE_CONCURRENCY_MATRIX := y
CONFIG_FEATURE_SAP_COND_CHAN_SWITCH := y
CONFIG_FEATURE_P2P_LISTEN_OFFLOAD := y
ifeq ($(CONFIG_HELIUMPLUS), y)
ifneq ($(CONFIG_FORCE_ALLOC_FROM_DMA_ZONE), y)
CONFIG_ENABLE_DEBUG_ADDRESS_MARKING := y

View file

@ -3,7 +3,7 @@
#features not required for GENOA IOT, compilation errors are there.
CONFIG_SUPPORT_11AX := y
CONFIG_160MHZ_SUPPORT := y
CONFIG_FEATURE_STATS_EXT := y
CONFIG_FEATURE_STATS_EXT := n
CONFIG_QCA_IBSS_SUPPORT := y
#required features
@ -114,6 +114,18 @@ CONFIG_WLAN_FEATURE_SAE := y
CONFIG_CHNL_MATRIX_RESTRICTION := n
CONFIG_WLAN_FEATURE_BMI := n
#Flags to enable/disable vendor commands
CONFIG_FEATURE_RSSI_MONITOR := n
CONFIG_FEATURE_BSS_TRANSITION := n
CONFIG_FEATURE_STATION_INFO := n
CONFIG_FEATURE_TX_POWER := n
CONFIG_FEATURE_OTA_TEST := n
CONFIG_FEATURE_ACTIVE_TOS := n
CONFIG_FEATURE_SAR_LIMITS := y
CONFIG_FEATURE_CONCURRENCY_MATRIX := n
CONFIG_FEATURE_SAP_COND_CHAN_SWITCH := n
CONFIG_FEATURE_P2P_LISTEN_OFFLOAD := n
ifeq ($(CONFIG_ARCH_SDM845), y)
ifeq ($(CONFIG_IPA_OFFLOAD), y)
CONFIG_ENABLE_SMMU_S1_TRANSLATION := y

View file

@ -1631,36 +1631,6 @@ enum hdd_sta_smps_param {
HDD_STA_SMPS_PARAM_DTIM_1CHRX_ENABLE = 5
};
/**
* tos - Type of service requested by the application
* TOS_BK: Back ground traffic
* TOS_BE: Best effort traffic
* TOS_VI: Video traffic
* TOS_VO: Voice traffic
*/
enum tos {
TOS_BK = 0,
TOS_BE = 1,
TOS_VI = 2,
TOS_VO = 3,
};
#define HDD_AC_BK_BIT 1
#define HDD_AC_BE_BIT 2
#define HDD_AC_VI_BIT 4
#define HDD_AC_VO_BIT 8
#define HDD_MAX_OFF_CHAN_TIME_FOR_VO 20
#define HDD_MAX_OFF_CHAN_TIME_FOR_VI 20
#define HDD_MAX_OFF_CHAN_TIME_FOR_BE 40
#define HDD_MAX_OFF_CHAN_TIME_FOR_BK 40
#define HDD_MAX_AC 4
#define HDD_MAX_OFF_CHAN_ENTRIES 2
#define HDD_AC_BIT_INDX 0
#define HDD_DWELL_TIME_INDX 1
/**
* enum RX_OFFLOAD - Receive offload modes
* @CFG_LRO_ENABLED: Large Rx offload
@ -2931,22 +2901,6 @@ void hdd_restart_sap(struct hdd_adapter *ap_adapter);
void hdd_check_and_restart_sap_with_non_dfs_acs(void);
bool hdd_set_connection_in_progress(bool value);
/**
* wlan_hdd_sap_get_valid_channellist() - Get SAPs valid channel list
* @ap_adapter: adapter
* @channel_count: valid channel count
* @channel_list: valid channel list
* @band: frequency band
*
* This API returns valid channel list for SAP after removing nol and
* channel which lies outside of configuration.
*
* Return: Zero on success, non-zero on failure
*/
int wlan_hdd_sap_get_valid_channellist(struct hdd_adapter *adapter,
uint32_t *channel_count,
uint8_t *channel_list,
enum band_info band);
/**
* wlan_hdd_init_chan_info() - initialize channel info variables
* @hdd_ctx: hdd ctx
@ -3211,19 +3165,6 @@ void hdd_dp_trace_init(struct hdd_config *config) {}
void hdd_set_rx_mode_rps(bool enable);
/**
* hdd_set_limit_off_chan_for_tos() - set limit off-chan command parameters
* @adapter: pointer adapter context
* @tos: type of service
* @status: status of the traffic (active/inactive)
*
* This function updates the limit off-channel command parameters to WMA
*
* Return: 0 on success or non zero value on failure
*/
int hdd_set_limit_off_chan_for_tos(struct hdd_adapter *adapter, enum tos tos,
bool is_tos_active);
/**
* hdd_drv_ops_inactivity_handler() - Timeout handler for driver ops
* inactivity timer

View file

@ -123,30 +123,6 @@ void wlan_hdd_roc_request_dequeue(struct work_struct *work);
int wlan_hdd_set_power_save(struct hdd_adapter *adapter,
struct p2p_ps_config *ps_config);
/**
* wlan_hdd_listen_offload_start() - hdd set listen offload start
* @adapter: adapter context
* @params: listen offload parameters
*
* This function sets listen offload start parameters.
*
* Return: 0 - success
* others - failure
*/
int wlan_hdd_listen_offload_start(struct hdd_adapter *adapter,
struct sir_p2p_lo_start *params);
/**
* wlan_hdd_listen_offload_stop() - hdd set listen offload stop
* @adapter: adapter context
*
* This function sets listen offload stop parameters.
*
* Return: 0 - success
* others - failure
*/
int wlan_hdd_listen_offload_stop(struct hdd_adapter *adapter);
/**
* wlan_hdd_set_mas() - Function to set MAS value to FW
* @adapter: Pointer to HDD adapter

View file

@ -0,0 +1,227 @@
/*
* Copyright (c) 2012-2018 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: wlan_hdd_active_tos.c
*
* WLAN active tos functions
*
*/
#include <wlan_hdd_includes.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <wlan_hdd_active_tos.h>
/**
* tos - Type of service requested by the application
* TOS_BK: Back ground traffic
* TOS_BE: Best effort traffic
* TOS_VI: Video traffic
* TOS_VO: Voice traffic
*/
enum tos {
TOS_BK = 0,
TOS_BE = 1,
TOS_VI = 2,
TOS_VO = 3,
};
#define HDD_AC_BK_BIT 1
#define HDD_AC_BE_BIT 2
#define HDD_AC_VI_BIT 4
#define HDD_AC_VO_BIT 8
#define HDD_MAX_OFF_CHAN_TIME_FOR_VO 20
#define HDD_MAX_OFF_CHAN_TIME_FOR_VI 20
#define HDD_MAX_OFF_CHAN_TIME_FOR_BE 40
#define HDD_MAX_OFF_CHAN_TIME_FOR_BK 40
#define HDD_MAX_AC 4
#define HDD_MAX_OFF_CHAN_ENTRIES 2
#define HDD_AC_BIT_INDX 0
#define HDD_DWELL_TIME_INDX 1
static int limit_off_chan_tbl[HDD_MAX_AC][HDD_MAX_OFF_CHAN_ENTRIES] = {
{ HDD_AC_BK_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_BK },
{ HDD_AC_BE_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_BE },
{ HDD_AC_VI_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_VI },
{ HDD_AC_VO_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_VO },
};
static const struct nla_policy
wlan_hdd_set_limit_off_channel_param_policy
[QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS_MAX + 1] = {
[QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS] = {.type = NLA_U8 },
[QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS_START] = {.type = NLA_U8 },
};
/**
* hdd_set_limit_off_chan_for_tos() - set limit off-channel command parameters
* @adapter: HDD adapter
* @tos: type of service
* @is_tos_active: status of the traffic
*
* Return: 0 on success and non zero value on failure
*/
static int
hdd_set_limit_off_chan_for_tos(struct hdd_adapter *adapter,
enum tos tos,
bool is_tos_active)
{
int ac_bit;
struct hdd_context *hdd_ctx;
uint32_t max_off_chan_time = 0;
QDF_STATUS status;
int ret;
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
ret = wlan_hdd_validate_context(hdd_ctx);
if (ret < 0)
return ret;
ac_bit = limit_off_chan_tbl[tos][HDD_AC_BIT_INDX];
if (is_tos_active)
adapter->active_ac |= ac_bit;
else
adapter->active_ac &= ~ac_bit;
if (adapter->active_ac) {
if (adapter->active_ac & HDD_AC_VO_BIT) {
max_off_chan_time =
limit_off_chan_tbl[TOS_VO][HDD_DWELL_TIME_INDX];
policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
PM_LATENCY);
} else if (adapter->active_ac & HDD_AC_VI_BIT) {
max_off_chan_time =
limit_off_chan_tbl[TOS_VI][HDD_DWELL_TIME_INDX];
policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
PM_LATENCY);
} else {
/*ignore this command if only BE/BK is active */
is_tos_active = false;
policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
hdd_ctx->config->conc_system_pref);
}
} else {
/* No active tos */
policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
hdd_ctx->config->conc_system_pref);
}
status = sme_send_limit_off_channel_params(hdd_ctx->mac_handle,
adapter->session_id,
is_tos_active,
max_off_chan_time,
hdd_ctx->config->nRestTimeConc,
true);
if (!QDF_IS_STATUS_SUCCESS(status)) {
hdd_err("failed to set limit off chan params");
ret = -EINVAL;
}
return ret;
}
/**
* __wlan_hdd_cfg80211_set_limit_offchan_param() - set limit off-channel cmd
* parameters
* @wiphy: pointer to wireless wiphy structure.
* @wdev: pointer to wireless_dev structure.
* @data: pointer to limit off-channel command parameters.
* @data_len: the length in byte of limit off-channel command parameters.
*
* This is called when application wants to limit the off channel time due to
* active voip traffic.
*
* Return: An error code or 0 on success.
*/
static int
__wlan_hdd_cfg80211_set_limit_offchan_param(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS_MAX + 1];
struct net_device *dev = wdev->netdev;
struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
int ret = 0;
uint8_t tos;
uint8_t tos_status;
hdd_enter();
ret = wlan_hdd_validate_context(hdd_ctx);
if (ret < 0)
return ret;
if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS_MAX,
data, data_len,
wlan_hdd_set_limit_off_channel_param_policy)) {
hdd_err("Invalid ATTR");
return -EINVAL;
}
if (!tb[QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS]) {
hdd_err("attr tos failed");
goto fail;
}
tos = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS]);
if (tos >= HDD_MAX_AC) {
hdd_err("tos value %d exceeded Max value %d",
tos, HDD_MAX_AC);
goto fail;
}
hdd_debug("tos %d", tos);
if (!tb[QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS_START]) {
hdd_err("attr tos active failed");
goto fail;
}
tos_status = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS_START]);
hdd_debug("tos status %d", tos_status);
ret = hdd_set_limit_off_chan_for_tos(adapter, tos, tos_status);
fail:
return ret;
}
int wlan_hdd_cfg80211_set_limit_offchan_param(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data, int data_len)
{
int ret;
cds_ssr_protect(__func__);
ret = __wlan_hdd_cfg80211_set_limit_offchan_param(wiphy, wdev, data,
data_len);
cds_ssr_unprotect(__func__);
return ret;
}

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2012-2018 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.
*/
#ifndef __WLAN_HDD_ACTIVE_TOS_H
#define __WLAN_HDD_ACTIVE_TOS_H
/**
* DOC: wlan_hdd_active_tos_h
*
* WLAN Host Device Driver ACTIVE TOS API specification
*/
#ifdef FEATURE_ACTIVE_TOS
/**
* wlan_hdd_cfg80211_set_limit_offchan_param() - set limit off-channel cmd
* parameters
* @wiphy: pointer to wireless wiphy structure.
* @wdev: pointer to wireless_dev structure.
* @data: pointer to limit off-channel command parameters.
* @data_len: the length in byte of limit off-channel command parameters.
*
* This is called when application wants to limit the off channel time due to
* active voip traffic.
*
* Return: An error code or 0 on success.
*/
int wlan_hdd_cfg80211_set_limit_offchan_param(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data, int data_len);
#define FEATURE_ACTIVE_TOS_VENDOR_COMMANDS \
{ \
.info.vendor_id = QCA_NL80211_VENDOR_ID, \
.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ACTIVE_TOS, \
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
WIPHY_VENDOR_CMD_NEED_NETDEV | \
WIPHY_VENDOR_CMD_NEED_RUNNING, \
.doit = wlan_hdd_cfg80211_set_limit_offchan_param \
},
#else /* FEATURE_ACTIVE_TOS */
#define FEATURE_ACTIVE_TOS_VENDOR_COMMANDS
#endif /* FEATURE_ACTIVE_TOS */
#endif /* __WLAN_HDD_ACTIVE_TOS_H */

View file

@ -0,0 +1,270 @@
/*
* Copyright (c) 2012-2018 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: wlan_hdd_bss_transition.c
*
* WLAN bss transition functions
*
*/
#include <wlan_hdd_includes.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <wlan_hdd_bss_transition.h>
/**
* wlan_hdd_is_bt_in_progress() - check if bt activity is in progress
* @hdd_ctx : HDD context
*
* Return: true if BT activity is in progress else false
*/
static bool wlan_hdd_is_bt_in_progress(struct hdd_context *hdd_ctx)
{
if (hdd_ctx->bt_a2dp_active || hdd_ctx->bt_vo_active)
return true;
return false;
}
/**
* wlan_hdd_fill_btm_resp() - Fill bss candidate response buffer
* @reply_skb : pointer to reply_skb
* @info : bss candidate information
* @index : attribute type index for nla_next_start()
*
* Return : 0 on success and errno on failure
*/
static int wlan_hdd_fill_btm_resp(struct sk_buff *reply_skb,
struct bss_candidate_info *info,
int index)
{
struct nlattr *attr;
attr = nla_nest_start(reply_skb, index);
if (!attr) {
hdd_err("nla_nest_start failed");
kfree_skb(reply_skb);
return -EINVAL;
}
if (nla_put(reply_skb,
QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_BSSID,
ETH_ALEN, info->bssid.bytes) ||
nla_put_u32(reply_skb,
QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_STATUS,
info->status)) {
hdd_err("nla_put failed");
kfree_skb(reply_skb);
return -EINVAL;
}
nla_nest_end(reply_skb, attr);
return 0;
}
/**
* __wlan_hdd_cfg80211_fetch_bss_transition_status() - fetch bss transition
* status
* @wiphy : WIPHY structure pointer
* @wdev : Wireless device structure pointer
* @data : Pointer to the data received
* @data_len : Length of the data received
*
* This function is used to fetch transition status for candidate bss. The
* transition status is either accept or reason for reject.
*
* Return : 0 on success and errno on failure
*/
static int
__wlan_hdd_cfg80211_fetch_bss_transition_status(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data, int data_len)
{
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
struct nlattr *tb_msg[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_MAX + 1];
uint8_t transition_reason;
struct nlattr *attr;
struct sk_buff *reply_skb;
int rem, j;
int ret;
bool is_bt_in_progress;
struct bss_candidate_info candidate_info[MAX_CANDIDATE_INFO];
uint16_t nof_candidates, i = 0;
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
struct net_device *dev = wdev->netdev;
struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
struct hdd_station_ctx *hdd_sta_ctx =
WLAN_HDD_GET_STATION_CTX_PTR(adapter);
mac_handle_t mac_handle;
const struct nla_policy
btm_params_policy[QCA_WLAN_VENDOR_ATTR_MAX + 1] = {
[QCA_WLAN_VENDOR_ATTR_BTM_MBO_TRANSITION_REASON] = {
.type = NLA_U8},
[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO] = {
.type = NLA_NESTED},
};
const struct nla_policy
btm_cand_list_policy[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_MAX + 1]
= {[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_BSSID] = {
.len = QDF_MAC_ADDR_SIZE},
[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_STATUS] = {
.type = NLA_U32},
};
hdd_enter();
if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
hdd_err("Command not allowed in FTM mode");
return -EINVAL;
}
ret = wlan_hdd_validate_context(hdd_ctx);
if (ret)
return ret;
if (adapter->device_mode != QDF_STA_MODE ||
hdd_sta_ctx->conn_info.connState != eConnectionState_Associated) {
hdd_err("Command is either not invoked for STA mode (device mode: %d) or STA is not associated (Connection state: %d)",
adapter->device_mode, hdd_sta_ctx->conn_info.connState);
return -EINVAL;
}
ret = wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data,
data_len, btm_params_policy);
if (ret) {
hdd_err("Attribute parse failed");
return -EINVAL;
}
if (!tb[QCA_WLAN_VENDOR_ATTR_BTM_MBO_TRANSITION_REASON] ||
!tb[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO]) {
hdd_err("Missing attributes");
return -EINVAL;
}
transition_reason = nla_get_u8(
tb[QCA_WLAN_VENDOR_ATTR_BTM_MBO_TRANSITION_REASON]);
nla_for_each_nested(attr,
tb[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO],
rem) {
ret = wlan_cfg80211_nla_parse_nested(tb_msg,
QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_MAX,
attr, btm_cand_list_policy);
if (ret) {
hdd_err("Attribute parse failed");
return -EINVAL;
}
if (!tb_msg[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_BSSID]) {
hdd_err("Missing BSSID attribute");
return -EINVAL;
}
qdf_mem_copy((void *)candidate_info[i].bssid.bytes,
nla_data(tb_msg[
QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_BSSID]),
QDF_MAC_ADDR_SIZE);
i++;
if (i == MAX_CANDIDATE_INFO)
break;
}
/*
* Determine status for each candidate and fill in the status field.
* Also arrange the candidates in the order of preference.
*/
nof_candidates = i;
is_bt_in_progress = wlan_hdd_is_bt_in_progress(hdd_ctx);
mac_handle = hdd_ctx->mac_handle;
ret = sme_get_bss_transition_status(mac_handle, transition_reason,
&hdd_sta_ctx->conn_info.bssId,
candidate_info,
nof_candidates,
is_bt_in_progress);
if (ret)
return -EINVAL;
/* Prepare the reply and send it to userspace */
reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
((QDF_MAC_ADDR_SIZE + sizeof(uint32_t)) *
nof_candidates) + NLMSG_HDRLEN);
if (!reply_skb) {
hdd_err("reply buffer alloc failed");
return -ENOMEM;
}
attr = nla_nest_start(reply_skb,
QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO);
if (!attr) {
hdd_err("nla_nest_start failed");
kfree_skb(reply_skb);
return -EINVAL;
}
/*
* Order candidates as - accepted candidate list followed by rejected
* candidate list
*/
for (i = 0, j = 0; i < nof_candidates; i++) {
/* copy accepted candidate list */
if (candidate_info[i].status == QCA_STATUS_ACCEPT) {
if (wlan_hdd_fill_btm_resp(reply_skb,
&candidate_info[i], j))
return -EINVAL;
j++;
}
}
for (i = 0; i < nof_candidates; i++) {
/* copy rejected candidate list */
if (candidate_info[i].status != QCA_STATUS_ACCEPT) {
if (wlan_hdd_fill_btm_resp(reply_skb,
&candidate_info[i], j))
return -EINVAL;
j++;
}
}
nla_nest_end(reply_skb, attr);
hdd_exit();
return cfg80211_vendor_cmd_reply(reply_skb);
}
int wlan_hdd_cfg80211_fetch_bss_transition_status(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
int ret;
cds_ssr_protect(__func__);
ret = __wlan_hdd_cfg80211_fetch_bss_transition_status(wiphy, wdev,
data, data_len);
cds_ssr_unprotect(__func__);
return ret;
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 2012-2018 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.
*/
#ifndef __WLAN_HDD_BSS_TRANSITION_H
#define __WLAN_HDD_BSS_TRANSITION_H
/**
* DOC: wlan_hdd_bss_transition_h
*
* WLAN Host Device Driver BSS transition API specification
*/
#ifdef FEATURE_BSS_TRANSITION
/**
* wlan_hdd_cfg80211_fetch_bss_transition_status() - fetch bss transition status
* @wiphy: WIPHY structure pointer
* @wdev: Wireless device structure pointer
* @data: Pointer to the data received
* @data_len: Length of the data received
*
* This function is used to fetch transition status for candidate bss. The
* transition status is either accept or reason for reject.
*
* Return: 0 on success and errno on failure
*/
int
wlan_hdd_cfg80211_fetch_bss_transition_status(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data, int data_len);
#define FEATURE_BSS_TRANSITION_VENDOR_COMMANDS \
{ \
.info.vendor_id = QCA_NL80211_VENDOR_ID, \
.info.subcmd = \
QCA_NL80211_VENDOR_SUBCMD_FETCH_BSS_TRANSITION_STATUS, \
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
WIPHY_VENDOR_CMD_NEED_NETDEV | \
WIPHY_VENDOR_CMD_NEED_RUNNING, \
.doit = wlan_hdd_cfg80211_fetch_bss_transition_status \
},
#else /* FEATURE_BSS_TRANSITION */
#define FEATURE_BSS_TRANSITION_VENDOR_COMMANDS
#endif /* FEATURE_BSS_TRANSITION */
#endif /* __WLAN_HDD_BSS_TRANSITION_H */

File diff suppressed because it is too large Load diff

View file

@ -369,19 +369,6 @@ void wlan_hdd_cfg80211_extscan_callback(hdd_handle_t hdd_handle,
void wlan_hdd_rso_cmd_status_cb(hdd_handle_t hdd_handle,
struct rso_cmd_status *rso_status);
/**
* hdd_rssi_threshold_breached() - rssi breached NL event
* @hdd_handle: HDD handle
* @data: rssi breached event data
*
* This function reads the rssi breached event %data and fill in the skb with
* NL attributes and send up the NL event.
*
* Return: none
*/
void hdd_rssi_threshold_breached(hdd_handle_t hdd_handle,
struct rssi_breach_event *data);
struct cfg80211_bss *
wlan_hdd_cfg80211_update_bss_list(struct hdd_adapter *adapter,
tSirMacAddr bssid);

View file

@ -0,0 +1,144 @@
/*
* Copyright (c) 2012-2018 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: wlan_hdd_concurrency_matrix.c
*
* WLAN concurrency matrix functions
*
*/
#include <wlan_hdd_includes.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <wlan_hdd_concurrency_matrix.h>
#define CDS_MAX_FEATURE_SET 8
#define MAX_CONCURRENT_MATRIX \
QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
static const struct nla_policy
wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
[MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
};
/**
* __wlan_hdd_cfg80211_get_concurrency_matrix() - to retrieve concurrency matrix
* @wiphy: pointer phy adapter
* @wdev: pointer to wireless device structure
* @data: pointer to data buffer
* @data_len: length of data
*
* This routine will give concurrency matrix
*
* Return: int status code
*/
static int
__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
uint32_t feature_set_matrix[CDS_MAX_FEATURE_SET] = {0};
uint8_t i, feature_sets, max_feature_sets;
struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
struct sk_buff *reply_skb;
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
int ret;
hdd_enter_dev(wdev->netdev);
if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
hdd_err("Command not allowed in FTM mode");
return -EPERM;
}
ret = wlan_hdd_validate_context(hdd_ctx);
if (ret)
return ret;
if (wlan_cfg80211_nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
wlan_hdd_get_concurrency_matrix_policy)) {
hdd_err("Invalid ATTR");
return -EINVAL;
}
/* Parse and fetch max feature set */
if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
hdd_err("Attr max feature set size failed");
return -EINVAL;
}
max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
hdd_debug("Max feature set size: %d", max_feature_sets);
/* Fill feature combination matrix */
feature_sets = 0;
feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
WIFI_FEATURE_P2P;
feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
WIFI_FEATURE_NAN;
/* Add more feature combinations here */
feature_sets = QDF_MIN(feature_sets, max_feature_sets);
hdd_debug("Number of feature sets: %d", feature_sets);
hdd_debug("Feature set matrix");
for (i = 0; i < feature_sets; i++)
hdd_debug("[%d] 0x%02X", i, feature_set_matrix[i]);
reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
sizeof(u32) * feature_sets + NLMSG_HDRLEN);
if (!reply_skb) {
hdd_err("Feature set matrix: buffer alloc fail");
return -ENOMEM;
}
if (nla_put_u32(reply_skb,
QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
feature_sets) ||
nla_put(reply_skb,
QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
sizeof(u32) * feature_sets,
feature_set_matrix)) {
hdd_err("nla put fail");
kfree_skb(reply_skb);
return -EINVAL;
}
return cfg80211_vendor_cmd_reply(reply_skb);
}
#undef MAX_CONCURRENT_MATRIX
#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
int wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
int ret;
cds_ssr_protect(__func__);
ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev,
data, data_len);
cds_ssr_unprotect(__func__);
return ret;
}

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2012-2018 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.
*/
#ifndef __WLAN_HDD_CONCURRENCY_MATRIX_H
#define __WLAN_HDD_CONCURRENCY_MATRIX_H
/**
* DOC: wlan_hdd_concurrency_matrix_h
*
* WLAN Host Device Driver concurrency matrix API specification
*/
#ifdef FEATURE_CONCURRENCY_MATRIX
/**
* wlan_hdd_cfg80211_get_concurrency_matrix() - get concurrency matrix
* @wiphy: pointer to wireless wiphy structure.
* @wdev: pointer to wireless_dev structure.
* @data: Pointer to the data to be passed via vendor interface
* @data_len:Length of the data to be passed
*
* Retrieves the concurrency feature set matrix
*
* Return: 0 on success, negative errno on failure
*/
int wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len);
#define FEATURE_CONCURRENCY_MATRIX_VENDOR_COMMANDS \
{ \
.info.vendor_id = QCA_NL80211_VENDOR_ID, \
.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,\
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,\
.doit = wlan_hdd_cfg80211_get_concurrency_matrix \
},
#else /* FEATURE_CONCURRENCY_MATRIX */
#define FEATURE_CONCURRENCY_MATRIX_VENDOR_COMMANDS
#endif /* FEATURE_CONCURRENCY_MATRIX */
#endif /* __WLAN_HDD_CONCURRENCY_MATRIX_H */

View file

@ -138,6 +138,7 @@
#include "wlan_mlme_main.h"
#include "wlan_p2p_cfg_api.h"
#include "wlan_tdls_cfg_api.h"
#include <wlan_hdd_rssi_monitor.h>
#ifdef CNSS_GENL
#include <net/cnss_nl.h>
@ -300,13 +301,6 @@ static const struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = {
[QDF_MODULE_ID_CONFIG] = {QDF_TRACE_LEVEL_ALL},
};
int limit_off_chan_tbl[HDD_MAX_AC][HDD_MAX_OFF_CHAN_ENTRIES] = {
{ HDD_AC_BK_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_BK },
{ HDD_AC_BE_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_BE },
{ HDD_AC_VI_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_VI },
{ HDD_AC_VO_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_VO },
};
struct notifier_block hdd_netdev_notifier;
struct notifier_block system_reboot_notifier;
@ -14129,76 +14123,6 @@ int hdd_get_rssi_snr_by_bssid(struct hdd_adapter *adapter, const uint8_t *bssid,
return 0;
}
/**
* hdd_set_limit_off_chan_for_tos() - set limit off-channel command parameters
* @adapter - HDD adapter
* @tos - type of service
* @status - status of the traffic
*
* Return: 0 on success and non zero value on failure
*/
int hdd_set_limit_off_chan_for_tos(struct hdd_adapter *adapter, enum tos tos,
bool is_tos_active)
{
int ac_bit;
struct hdd_context *hdd_ctx;
uint32_t max_off_chan_time = 0;
QDF_STATUS status;
int ret;
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
ret = wlan_hdd_validate_context(hdd_ctx);
if (ret < 0) {
hdd_err("failed to set limit off chan params");
return ret;
}
ac_bit = limit_off_chan_tbl[tos][HDD_AC_BIT_INDX];
if (is_tos_active)
adapter->active_ac |= ac_bit;
else
adapter->active_ac &= ~ac_bit;
if (adapter->active_ac) {
if (adapter->active_ac & HDD_AC_VO_BIT) {
max_off_chan_time =
limit_off_chan_tbl[TOS_VO][HDD_DWELL_TIME_INDX];
policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
PM_LATENCY);
} else if (adapter->active_ac & HDD_AC_VI_BIT) {
max_off_chan_time =
limit_off_chan_tbl[TOS_VI][HDD_DWELL_TIME_INDX];
policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
PM_LATENCY);
} else {
/*ignore this command if only BE/BK is active */
is_tos_active = false;
policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
hdd_ctx->config->conc_system_pref);
}
} else {
/* No active tos */
policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
hdd_ctx->config->conc_system_pref);
}
status = sme_send_limit_off_channel_params(hdd_ctx->mac_handle,
adapter->session_id,
is_tos_active,
max_off_chan_time,
hdd_ctx->config->nRestTimeConc,
true);
if (!QDF_IS_STATUS_SUCCESS(status)) {
hdd_err("failed to set limit off chan params");
ret = -EINVAL;
}
return ret;
}
/**
* hdd_reset_limit_off_chan() - reset limit off-channel command parameters
* @adapter - HDD adapter

View file

@ -0,0 +1,142 @@
/*
* Copyright (c) 2012-2018 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: wlan_hdd_ota_test.c
*
* WLAN OTA test functions
*
*/
#include <wlan_hdd_includes.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <sme_power_save_api.h>
#include <wlan_hdd_ota_test.h>
static const struct
nla_policy
qca_wlan_vendor_ota_test_policy
[QCA_WLAN_VENDOR_ATTR_OTA_TEST_MAX + 1] = {
[QCA_WLAN_VENDOR_ATTR_OTA_TEST_ENABLE] = {.type = NLA_U8 },
};
/**
* __wlan_hdd_cfg80211_set_ota_test() - enable/disable OTA test
* @wiphy: Pointer to wireless phy
* @wdev: Pointer to wireless device
* @data: Pointer to data
* @data_len: Data length
*
* Return: 0 on success, negative errno on failure
*/
static int __wlan_hdd_cfg80211_set_ota_test(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
struct net_device *dev = wdev->netdev;
struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_OTA_TEST_MAX + 1];
uint8_t ota_enable = 0;
QDF_STATUS status;
uint32_t current_roam_state;
mac_handle_t mac_handle;
hdd_enter_dev(dev);
if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
hdd_err("Command not allowed in FTM mode");
return -EPERM;
}
if (wlan_hdd_validate_context(hdd_ctx) != 0)
return -EINVAL;
if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_OTA_TEST_MAX,
data, data_len,
qca_wlan_vendor_ota_test_policy)) {
hdd_err("invalid attr");
return -EINVAL;
}
if (!tb[QCA_WLAN_VENDOR_ATTR_OTA_TEST_ENABLE]) {
hdd_err("attr ota test failed");
return -EINVAL;
}
ota_enable = nla_get_u8(
tb[QCA_WLAN_VENDOR_ATTR_OTA_TEST_ENABLE]);
hdd_debug(" OTA test enable = %d", ota_enable);
if (ota_enable != 1) {
hdd_err("Invalid value, only enable test mode is supported!");
return -EINVAL;
}
mac_handle = hdd_ctx->mac_handle;
current_roam_state =
sme_get_current_roam_state(mac_handle, adapter->session_id);
status = sme_stop_roaming(mac_handle, adapter->session_id,
eCsrHddIssued);
if (status != QDF_STATUS_SUCCESS) {
hdd_err("Enable/Disable roaming failed");
return -EINVAL;
}
status = sme_ps_enable_disable(mac_handle, adapter->session_id,
SME_PS_DISABLE);
if (status != QDF_STATUS_SUCCESS) {
hdd_err("Enable/Disable power save failed");
/* restore previous roaming setting */
if (current_roam_state == eCSR_ROAMING_STATE_JOINING ||
current_roam_state == eCSR_ROAMING_STATE_JOINED)
status = sme_start_roaming(mac_handle,
adapter->session_id,
eCsrHddIssued);
else if (current_roam_state == eCSR_ROAMING_STATE_STOP ||
current_roam_state == eCSR_ROAMING_STATE_IDLE)
status = sme_stop_roaming(mac_handle,
adapter->session_id,
eCsrHddIssued);
if (status != QDF_STATUS_SUCCESS)
hdd_err("Restoring roaming state failed");
return -EINVAL;
}
return 0;
}
int wlan_hdd_cfg80211_set_ota_test(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
int ret;
cds_ssr_protect(__func__);
ret = __wlan_hdd_cfg80211_set_ota_test(wiphy, wdev, data, data_len);
cds_ssr_unprotect(__func__);
return ret;
}

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2012-2018 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.
*/
#ifndef __WLAN_HDD_OTA_TEST_H
#define __WLAN_HDD_OTA_TEST_H
/**
* DOC: wlan_hdd_ota_test_h
*
* WLAN Host Device Driver OTA test API specification
*/
#ifdef FEATURE_OTA_TEST
/**
* wlan_hdd_cfg80211_set_ota_test () - Enable or disable OTA test
* @wiphy: Pointer to wireless phy
* @wdev: Pointer to wireless device
* @data: Pointer to data
* @data_len: Data length
*
* Return: 0 on success, negative errno on failure
*/
int wlan_hdd_cfg80211_set_ota_test(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len);
#define FEATURE_OTA_TEST_VENDOR_COMMANDS \
{ \
.info.vendor_id = QCA_NL80211_VENDOR_ID, \
.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OTA_TEST, \
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
WIPHY_VENDOR_CMD_NEED_NETDEV | \
WIPHY_VENDOR_CMD_NEED_RUNNING, \
.doit = wlan_hdd_cfg80211_set_ota_test \
},
#else /* FEATURE_OTA_TEST */
#define FEATURE_OTA_TEST_VENDOR_COMMANDS
#endif /* FEATURE_OTA_TEST */
#endif /* __WLAN_HDD_OTA_TEST_H */

View file

@ -1040,70 +1040,6 @@ int wlan_hdd_set_power_save(struct hdd_adapter *adapter,
return qdf_status_to_os_return(status);
}
int wlan_hdd_listen_offload_start(struct hdd_adapter *adapter,
struct sir_p2p_lo_start *params)
{
struct wlan_objmgr_psoc *psoc;
struct p2p_lo_start lo_start;
struct hdd_context *hdd_ctx;
QDF_STATUS status;
if (!adapter || !params) {
hdd_err("null param, adapter:%pK, params:%pK",
adapter, params);
return -EINVAL;
}
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
psoc = hdd_ctx->hdd_psoc;
if (!psoc) {
hdd_err("psoc is null");
return -EINVAL;
}
lo_start.vdev_id = params->vdev_id;
lo_start.ctl_flags = params->ctl_flags;
lo_start.freq = params->freq;
lo_start.period = params->period;
lo_start.interval = params->interval;
lo_start.count = params->count;
lo_start.device_types = params->device_types;
lo_start.dev_types_len = params->dev_types_len;
lo_start.probe_resp_tmplt = params->probe_resp_tmplt;
lo_start.probe_resp_len = params->probe_resp_len;
status = ucfg_p2p_lo_start(psoc, &lo_start);
hdd_debug("p2p listen offload start, status:%d", status);
return qdf_status_to_os_return(status);
}
int wlan_hdd_listen_offload_stop(struct hdd_adapter *adapter)
{
struct wlan_objmgr_psoc *psoc;
struct hdd_context *hdd_ctx;
uint32_t vdev_id;
QDF_STATUS status;
if (!adapter) {
hdd_err("adapter is null, adapter:%pK", adapter);
return -EINVAL;
}
vdev_id = (uint32_t)adapter->session_id;
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
psoc = hdd_ctx->hdd_psoc;
if (!psoc) {
hdd_err("psoc is null");
return -EINVAL;
}
status = ucfg_p2p_lo_stop(psoc, vdev_id);
hdd_debug("p2p listen offload stop, status:%d", status);
return qdf_status_to_os_return(status);
}
/**
* wlan_hdd_update_mcc_adaptive_scheduler() - Function to update
* MAS value to FW

View file

@ -0,0 +1,347 @@
/*
* Copyright (c) 2012-2018 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: wlan_hdd_vendor_p2p_listen_offload.c
*
* WLAN p2p listen offload functions
*
*/
#include <wlan_hdd_includes.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <wlan_hdd_p2p.h>
#include <wlan_p2p_ucfg_api.h>
#include <wlan_hdd_p2p_listen_offload.h>
/* P2P listen offload device types parameters length in bytes */
#define P2P_LO_MAX_REQ_DEV_TYPE_COUNT (10)
#define P2P_LO_WPS_DEV_TYPE_LEN (8)
#define P2P_LO_DEV_TYPE_MAX_LEN \
(P2P_LO_MAX_REQ_DEV_TYPE_COUNT * P2P_LO_WPS_DEV_TYPE_LEN)
static const struct nla_policy
p2p_listen_offload_policy[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_MAX + 1] = {
[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_CHANNEL] = { .type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_PERIOD] = { .type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_INTERVAL] = {
.type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_COUNT] = { .type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_DEVICE_TYPES] = {
.type = NLA_BINARY,
.len = P2P_LO_DEV_TYPE_MAX_LEN },
[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_VENDOR_IE] = {
.type = NLA_BINARY,
.len = MAX_GENIE_LEN },
[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_CTRL_FLAG] = {
.type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_CHANNEL] = { .type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON] = {
.type = NLA_U8 },
};
/**
* wlan_hdd_listen_offload_start() - hdd set listen offload start
* @adapter: adapter context
* @params: listen offload parameters
*
* This function sets listen offload start parameters.
*
* Return: 0 on success, others on failure
*/
static int wlan_hdd_listen_offload_start(struct hdd_adapter *adapter,
struct sir_p2p_lo_start *params)
{
struct wlan_objmgr_psoc *psoc;
struct p2p_lo_start lo_start;
struct hdd_context *hdd_ctx;
QDF_STATUS status;
if (!adapter || !params) {
hdd_err("null param, adapter:%pK, params:%pK",
adapter, params);
return -EINVAL;
}
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
psoc = hdd_ctx->hdd_psoc;
if (!psoc) {
hdd_err("psoc is null");
return -EINVAL;
}
lo_start.vdev_id = params->vdev_id;
lo_start.ctl_flags = params->ctl_flags;
lo_start.freq = params->freq;
lo_start.period = params->period;
lo_start.interval = params->interval;
lo_start.count = params->count;
lo_start.device_types = params->device_types;
lo_start.dev_types_len = params->dev_types_len;
lo_start.probe_resp_tmplt = params->probe_resp_tmplt;
lo_start.probe_resp_len = params->probe_resp_len;
status = ucfg_p2p_lo_start(psoc, &lo_start);
hdd_debug("p2p listen offload start, status:%d", status);
return qdf_status_to_os_return(status);
}
/**
* __wlan_hdd_cfg80211_p2p_lo_start () - start P2P Listen Offload
* @wiphy: Pointer to wireless phy
* @wdev: Pointer to wireless device
* @data: Pointer to data
* @data_len: Data length
*
* This function is to process the p2p listen offload start vendor
* command. It parses the input parameters and invoke WMA API to
* send the command to firmware.
*
* Return: 0 on success, negative errno on failure
*/
static int __wlan_hdd_cfg80211_p2p_lo_start(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
int ret;
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
struct net_device *dev = wdev->netdev;
struct hdd_adapter *adapter;
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_MAX + 1];
struct sir_p2p_lo_start params;
hdd_enter_dev(dev);
ret = wlan_hdd_validate_context(hdd_ctx);
if (ret)
return ret;
if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
hdd_err("Command not allowed in FTM mode");
return -EPERM;
}
adapter = WLAN_HDD_GET_PRIV_PTR(dev);
if ((adapter->device_mode != QDF_P2P_DEVICE_MODE) &&
(adapter->device_mode != QDF_P2P_CLIENT_MODE) &&
(adapter->device_mode != QDF_P2P_GO_MODE)) {
hdd_err("Invalid device mode %d", adapter->device_mode);
return -EINVAL;
}
if (wlan_cfg80211_nla_parse(tb,
QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_MAX,
data, data_len,
p2p_listen_offload_policy)) {
hdd_err("Invalid ATTR");
return -EINVAL;
}
memset(&params, 0, sizeof(params));
if (!tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_CTRL_FLAG])
params.ctl_flags = 1; /* set to default value */
else
params.ctl_flags = nla_get_u32(tb
[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_CTRL_FLAG]);
if (!tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_CHANNEL] ||
!tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_PERIOD] ||
!tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_INTERVAL] ||
!tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_COUNT] ||
!tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_DEVICE_TYPES] ||
!tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_VENDOR_IE]) {
hdd_err("Attribute parsing failed");
return -EINVAL;
}
params.vdev_id = adapter->session_id;
params.freq = nla_get_u32(tb
[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_CHANNEL]);
if ((params.freq != 2412) && (params.freq != 2437) &&
(params.freq != 2462)) {
hdd_err("Invalid listening channel: %d", params.freq);
return -EINVAL;
}
params.period = nla_get_u32(tb
[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_PERIOD]);
if (!((params.period > 0) && (params.period < UINT_MAX))) {
hdd_err("Invalid period: %d", params.period);
return -EINVAL;
}
params.interval = nla_get_u32(tb
[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_INTERVAL]);
if (!((params.interval > 0) && (params.interval < UINT_MAX))) {
hdd_err("Invalid interval: %d", params.interval);
return -EINVAL;
}
params.count = nla_get_u32(tb
[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_COUNT]);
if (!((params.count >= 0) && (params.count < UINT_MAX))) {
hdd_err("Invalid count: %d", params.count);
return -EINVAL;
}
params.device_types = nla_data(tb
[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_DEVICE_TYPES]);
if (!params.device_types) {
hdd_err("Invalid device types");
return -EINVAL;
}
params.dev_types_len = nla_len(tb
[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_DEVICE_TYPES]);
/* device type length has to be multiple of P2P_LO_WPS_DEV_TYPE_LEN */
if (0 != (params.dev_types_len % P2P_LO_WPS_DEV_TYPE_LEN)) {
hdd_err("Invalid device type length: %d", params.dev_types_len);
return -EINVAL;
}
params.probe_resp_tmplt = nla_data(tb
[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_VENDOR_IE]);
if (!params.probe_resp_tmplt) {
hdd_err("Invalid probe response template");
return -EINVAL;
}
/*
* IEs minimum length should be 2 bytes: 1 byte for element id
* and 1 byte for element id length.
*/
params.probe_resp_len = nla_len(tb
[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_VENDOR_IE]);
if (params.probe_resp_len < MIN_GENIE_LEN) {
hdd_err("Invalid probe resp template length: %d",
params.probe_resp_len);
return -EINVAL;
}
hdd_debug("P2P LO params: freq=%d, period=%d, interval=%d, count=%d",
params.freq, params.period, params.interval, params.count);
return wlan_hdd_listen_offload_start(adapter, &params);
}
int wlan_hdd_cfg80211_p2p_lo_start(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
int ret;
cds_ssr_protect(__func__);
ret = __wlan_hdd_cfg80211_p2p_lo_start(wiphy, wdev,
data, data_len);
cds_ssr_unprotect(__func__);
return ret;
}
/**
* wlan_hdd_listen_offload_stop() - hdd set listen offload stop
* @adapter: adapter context
*
* This function sets listen offload stop parameters.
*
* Return: 0 on success, others on failure
*/
static int wlan_hdd_listen_offload_stop(struct hdd_adapter *adapter)
{
struct wlan_objmgr_psoc *psoc;
struct hdd_context *hdd_ctx;
uint32_t vdev_id;
QDF_STATUS status;
if (!adapter) {
hdd_err("adapter is null, adapter:%pK", adapter);
return -EINVAL;
}
vdev_id = (uint32_t)adapter->session_id;
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
psoc = hdd_ctx->hdd_psoc;
if (!psoc) {
hdd_err("psoc is null");
return -EINVAL;
}
status = ucfg_p2p_lo_stop(psoc, vdev_id);
hdd_debug("p2p listen offload stop, status:%d", status);
return qdf_status_to_os_return(status);
}
/**
* __wlan_hdd_cfg80211_p2p_lo_stop () - stop P2P Listen Offload
* @wiphy: Pointer to wireless phy
* @wdev: Pointer to wireless device
* @data: Pointer to data
* @data_len: Data length
*
* This function is to process the p2p listen offload stop vendor
* command. It invokes WMA API to send command to firmware.
*
* Return: 0 on success, negative errno on failure
*/
static int __wlan_hdd_cfg80211_p2p_lo_stop(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
struct hdd_adapter *adapter;
struct net_device *dev = wdev->netdev;
if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
hdd_err("Command not allowed in FTM mode");
return -EPERM;
}
adapter = WLAN_HDD_GET_PRIV_PTR(dev);
if ((adapter->device_mode != QDF_P2P_DEVICE_MODE) &&
(adapter->device_mode != QDF_P2P_CLIENT_MODE) &&
(adapter->device_mode != QDF_P2P_GO_MODE)) {
hdd_err("Invalid device mode");
return -EINVAL;
}
return wlan_hdd_listen_offload_stop(adapter);
}
int wlan_hdd_cfg80211_p2p_lo_stop(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
int ret;
cds_ssr_protect(__func__);
ret = __wlan_hdd_cfg80211_p2p_lo_stop(wiphy, wdev,
data, data_len);
cds_ssr_unprotect(__func__);
return ret;
}

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 2012-2018 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.
*/
#ifndef __WLAN_HDD_P2P_LISTEN_OFFLOAD_H
#define __WLAN_HDD_P2P_LISTEN_OFFLOAD_H
/**
* DOC: wlan_hdd_p2p_listen_offload_h
*
* WLAN Host Device Driver p2p listen offload API specification
*/
#ifdef FEATURE_P2P_LISTEN_OFFLOAD
/**
* __wlan_hdd_cfg80211_p2p_lo_start() - start P2P Listen Offload
* @wiphy: Pointer to wireless phy
* @wdev: Pointer to wireless device
* @data: Pointer to data
* @data_len: Data length
*
* This function is to process the p2p listen offload start vendor
* command. It parses the input parameters and invoke WMA API to
* send the command to firmware.
*
* Return: 0 on success, negative errno on failure
*/
int wlan_hdd_cfg80211_p2p_lo_start(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len);
/**
* wlan_hdd_cfg80211_p2p_lo_stop() - stop P2P Listen Offload
* @wiphy: Pointer to wireless phy
* @wdev: Pointer to wireless device
* @data: Pointer to data
* @data_len: Data length
*
* This function inovkes internal __wlan_hdd_cfg80211_p2p_lo_stop()
* to process p2p listen offload stop vendor command.
*
* Return: 0 on success, negative errno on failure
*/
int wlan_hdd_cfg80211_p2p_lo_stop(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len);
#define FEATURE_P2P_LISTEN_OFFLOAD_VENDOR_COMMANDS \
{ \
.info.vendor_id = QCA_NL80211_VENDOR_ID, \
.info.subcmd = \
QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_START, \
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
WIPHY_VENDOR_CMD_NEED_NETDEV | \
WIPHY_VENDOR_CMD_NEED_RUNNING, \
.doit = wlan_hdd_cfg80211_p2p_lo_start \
}, \
{ \
.info.vendor_id = QCA_NL80211_VENDOR_ID, \
.info.subcmd = \
QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_STOP, \
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
WIPHY_VENDOR_CMD_NEED_NETDEV | \
WIPHY_VENDOR_CMD_NEED_RUNNING, \
.doit = wlan_hdd_cfg80211_p2p_lo_stop \
},
#else /* FEATURE_P2P_LISTEN_OFFLOAD */
#define FEATURE_P2P_LISTEN_OFFLOAD_VENDOR_COMMANDS
#endif /* FEATURE_P2P_LISTEN_OFFLOAD */
#endif /* __WLAN_HDD_P2P_LISTEN_OFFLOAD_H */

View file

@ -0,0 +1,222 @@
/*
* Copyright (c) 2012-2018 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: wlan_hdd_rssi_monitor.c
*
* WLAN rssi monitoring functions
*
*/
#include <wlan_hdd_includes.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <wlan_hdd_ext_scan.h>
#include <wlan_hdd_rssi_monitor.h>
/*
* define short names for the global vendor params
* used by __wlan_hdd_cfg80211_monitor_rssi()
*/
#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
/**
* __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
* @wiphy: Pointer to wireless phy
* @wdev: Pointer to wireless device
* @data: Pointer to data
* @data_len: Data length
*
* Return: 0 on success, negative errno on failure
*/
static int
__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
struct net_device *dev = wdev->netdev;
struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
struct nlattr *tb[PARAM_MAX + 1];
struct rssi_monitor_req req;
QDF_STATUS status;
int ret;
uint32_t control;
mac_handle_t mac_handle;
static const struct nla_policy policy[PARAM_MAX + 1] = {
[PARAM_REQUEST_ID] = { .type = NLA_U32 },
[PARAM_CONTROL] = { .type = NLA_U32 },
[PARAM_MIN_RSSI] = { .type = NLA_S8 },
[PARAM_MAX_RSSI] = { .type = NLA_S8 },
};
hdd_enter_dev(dev);
if (wlan_hdd_validate_session_id(adapter->session_id)) {
hdd_err("invalid session id: %d", adapter->session_id);
return -EINVAL;
}
ret = wlan_hdd_validate_context(hdd_ctx);
if (ret)
return ret;
if (!hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
hdd_err("Not in Connected state!");
return -ENOTSUPP;
}
if (wlan_cfg80211_nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
hdd_err("Invalid ATTR");
return -EINVAL;
}
if (!tb[PARAM_REQUEST_ID]) {
hdd_err("attr request id failed");
return -EINVAL;
}
if (!tb[PARAM_CONTROL]) {
hdd_err("attr control failed");
return -EINVAL;
}
req.request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
req.session_id = adapter->session_id;
control = nla_get_u32(tb[PARAM_CONTROL]);
if (control == QCA_WLAN_RSSI_MONITORING_START) {
req.control = true;
if (!tb[PARAM_MIN_RSSI]) {
hdd_err("attr min rssi failed");
return -EINVAL;
}
if (!tb[PARAM_MAX_RSSI]) {
hdd_err("attr max rssi failed");
return -EINVAL;
}
req.min_rssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
req.max_rssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
if (!(req.min_rssi < req.max_rssi)) {
hdd_warn("min_rssi: %d must be less than max_rssi: %d",
req.min_rssi, req.max_rssi);
return -EINVAL;
}
hdd_debug("Min_rssi: %d Max_rssi: %d",
req.min_rssi, req.max_rssi);
} else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
req.control = false;
} else {
hdd_err("Invalid control cmd: %d", control);
return -EINVAL;
}
hdd_debug("Request Id: %u Session_id: %d Control: %d",
req.request_id, req.session_id, req.control);
mac_handle = hdd_ctx->mac_handle;
status = sme_set_rssi_monitoring(mac_handle, &req);
if (!QDF_IS_STATUS_SUCCESS(status)) {
hdd_err("sme_set_rssi_monitoring failed(err=%d)", status);
return -EINVAL;
}
return 0;
}
/*
* done with short names for the global vendor params
* used by __wlan_hdd_cfg80211_monitor_rssi()
*/
#undef PARAM_MAX
#undef PARAM_CONTROL
#undef PARAM_REQUEST_ID
#undef PARAM_MAX_RSSI
#undef PARAM_MIN_RSSI
int
wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
const void *data, int data_len)
{
int ret;
cds_ssr_protect(__func__);
ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
cds_ssr_unprotect(__func__);
return ret;
}
void hdd_rssi_threshold_breached(hdd_handle_t hdd_handle,
struct rssi_breach_event *data)
{
struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
struct sk_buff *skb;
hdd_enter();
if (wlan_hdd_validate_context(hdd_ctx))
return;
if (!data) {
hdd_err("data is null");
return;
}
skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
NULL,
EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
GFP_KERNEL);
if (!skb) {
hdd_err("mem alloc failed");
return;
}
hdd_debug("Req Id: %u Current rssi: %d",
data->request_id, data->curr_rssi);
hdd_debug("Current BSSID: "MAC_ADDRESS_STR,
MAC_ADDR_ARRAY(data->curr_bssid.bytes));
if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
data->request_id) ||
nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
data->curr_rssi)) {
hdd_err("nla put fail");
goto fail;
}
cfg80211_vendor_event(skb, GFP_KERNEL);
return;
fail:
kfree_skb(skb);
}

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 2012-2018 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.
*/
#ifndef __WLAN_HDD_RSSI_MONITOR_H
#define __WLAN_HDD_RSSI_MONITOR_H
/**
* DOC: wlan_hdd_rssi_monitor_h
*
* WLAN Host Device Driver RSSI monitoring API specification
*/
#ifdef FEATURE_RSSI_MONITOR
/**
* wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
* @wiphy: wiphy structure pointer
* @wdev: Wireless device structure pointer
* @data: Pointer to the data received
* @data_len: Length of @data
*
* Return: 0 on success; errno on failure
*/
int
wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
const void *data, int data_len);
/**
* hdd_rssi_threshold_breached() - rssi breached NL event
* @hdd_handle: HDD handle
* @data: rssi breached event data
*
* This function reads the rssi breached event %data and fill in the skb with
* NL attributes and send up the NL event.
*
* Return: none
*/
void hdd_rssi_threshold_breached(hdd_handle_t hdd_handle,
struct rssi_breach_event *data);
#define FEATURE_RSSI_MONITOR_VENDOR_EVENTS \
[QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = { \
.vendor_id = QCA_NL80211_VENDOR_ID, \
.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI \
},
#define FEATURE_RSSI_MONITOR_VENDOR_COMMANDS \
{ \
.info.vendor_id = QCA_NL80211_VENDOR_ID, \
.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI, \
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
WIPHY_VENDOR_CMD_NEED_NETDEV | \
WIPHY_VENDOR_CMD_NEED_RUNNING, \
.doit = wlan_hdd_cfg80211_monitor_rssi \
},
#else /* FEATURE_RSSI_MONITOR */
static inline
void hdd_rssi_threshold_breached(hdd_handle_t hdd_handle,
struct rssi_breach_event *data)
{
}
#define FEATURE_RSSI_MONITOR_VENDOR_EVENTS
#define FEATURE_RSSI_MONITOR_VENDOR_COMMANDS
#endif /* FEATURE_RSSI_MONITOR */
#endif /* __WLAN_HDD_RSSI_MONITOR_H */

View file

@ -0,0 +1,518 @@
/*
* Copyright (c) 2012-2018 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: wlan_hdd_sap_cond_chan_switch.c
*
* WLAN SAP conditional channel switch functions
*
*/
#include <wlan_hdd_includes.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <cds_utils.h>
#include <qdf_str.h>
#include <wlan_hdd_sap_cond_chan_switch.h>
/**
* wlan_hdd_set_pre_cac_status() - Set the pre cac status
* @pre_cac_adapter: AP adapter used for pre cac
* @status: Status (true or false)
* @handle: Global handle
*
* Sets the status of pre cac i.e., whether the pre cac is active or not
*
* Return: Zero on success, non-zero on failure
*/
static int wlan_hdd_set_pre_cac_status(struct hdd_adapter *pre_cac_adapter,
bool status, mac_handle_t handle)
{
QDF_STATUS ret;
ret = wlan_sap_set_pre_cac_status(
WLAN_HDD_GET_SAP_CTX_PTR(pre_cac_adapter), status, handle);
if (QDF_IS_STATUS_ERROR(ret))
return -EINVAL;
return 0;
}
/**
* wlan_hdd_set_chan_before_pre_cac() - Save the channel before pre cac
* @ap_adapter: AP adapter
* @chan_before_pre_cac: Channel
*
* Saves the channel which the AP was beaconing on before moving to the pre
* cac channel. If radar is detected on the pre cac channel, this saved
* channel will be used for AP operations.
*
* Return: Zero on success, non-zero on failure
*/
static int wlan_hdd_set_chan_before_pre_cac(struct hdd_adapter *ap_adapter,
uint8_t chan_before_pre_cac)
{
QDF_STATUS ret;
ret = wlan_sap_set_chan_before_pre_cac(
WLAN_HDD_GET_SAP_CTX_PTR(ap_adapter), chan_before_pre_cac);
if (QDF_IS_STATUS_ERROR(ret))
return -EINVAL;
return 0;
}
/**
* wlan_hdd_validate_and_get_pre_cac_ch() - Validate and get pre cac channel
* @hdd_ctx: HDD context
* @ap_adapter: AP adapter
* @channel: Channel requested by userspace
* @pre_cac_chan: Pointer to the pre CAC channel
*
* Validates the channel provided by userspace. If user provided channel 0,
* a valid outdoor channel must be selected from the regulatory channel.
*
* Return: Zero on success and non zero value on error
*/
static int wlan_hdd_validate_and_get_pre_cac_ch(struct hdd_context *hdd_ctx,
struct hdd_adapter *ap_adapter,
uint8_t channel,
uint8_t *pre_cac_chan)
{
uint32_t i;
QDF_STATUS status;
uint32_t weight_len = 0;
uint32_t len = WNI_CFG_VALID_CHANNEL_LIST_LEN;
uint8_t channel_list[QDF_MAX_NUM_CHAN] = {0};
uint8_t pcl_weights[QDF_MAX_NUM_CHAN] = {0};
mac_handle_t mac_handle;
if (channel == 0) {
/* Channel is not obtained from PCL because PCL may not have
* the entire channel list. For example: if SAP is up on
* channel 6 and PCL is queried for the next SAP interface,
* if SCC is preferred, the PCL will contain only the channel
* 6. But, we are in need of a DFS channel. So, going with the
* first channel from the valid channel list.
*/
status = policy_mgr_get_valid_chans(hdd_ctx->hdd_psoc,
channel_list, &len);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_err("Failed to get channel list");
return -EINVAL;
}
policy_mgr_update_with_safe_channel_list(hdd_ctx->hdd_psoc,
channel_list, &len,
pcl_weights,
weight_len);
for (i = 0; i < len; i++) {
if (wlan_reg_is_dfs_ch(hdd_ctx->hdd_pdev,
channel_list[i])) {
*pre_cac_chan = channel_list[i];
break;
}
}
if (*pre_cac_chan == 0) {
hdd_err("unable to find outdoor channel");
return -EINVAL;
}
} else {
/* Only when driver selects a channel, check is done for
* unnsafe and NOL channels. When user provides a fixed channel
* the user is expected to take care of this.
*/
mac_handle = hdd_ctx->mac_handle;
if (!sme_is_channel_valid(mac_handle, channel) ||
!wlan_reg_is_dfs_ch(hdd_ctx->hdd_pdev, channel)) {
hdd_err("Invalid channel for pre cac:%d", channel);
return -EINVAL;
}
*pre_cac_chan = channel;
}
hdd_debug("selected pre cac channel:%d", *pre_cac_chan);
return 0;
}
/**
* wlan_hdd_request_pre_cac() - Start pre CAC in the driver
* @channel: Channel option provided by userspace
*
* Sets the driver to the required hardware mode and start an adapter for
* pre CAC which will mimic an AP.
*
* Return: Zero on success, non-zero value on error
*/
int wlan_hdd_request_pre_cac(uint8_t channel)
{
uint8_t pre_cac_chan = 0, *mac_addr;
struct hdd_context *hdd_ctx;
int ret;
struct hdd_adapter *ap_adapter, *pre_cac_adapter;
struct hdd_ap_ctx *hdd_ap_ctx;
QDF_STATUS status;
struct wiphy *wiphy;
struct net_device *dev;
struct cfg80211_chan_def chandef;
enum nl80211_channel_type channel_type;
uint32_t freq;
struct ieee80211_channel *chan;
mac_handle_t mac_handle;
bool val;
hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
if (wlan_hdd_validate_context(hdd_ctx) != 0)
return -EINVAL;
if (policy_mgr_get_connection_count(hdd_ctx->hdd_psoc) > 1) {
hdd_err("pre cac not allowed in concurrency");
return -EINVAL;
}
ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
if (!ap_adapter) {
hdd_err("unable to get SAP adapter");
return -EINVAL;
}
mac_handle = hdd_ctx->mac_handle;
val = wlan_sap_is_pre_cac_active(mac_handle);
if (val) {
hdd_err("pre cac is already in progress");
return -EINVAL;
}
hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
if (!hdd_ap_ctx) {
hdd_err("SAP context is NULL");
return -EINVAL;
}
if (wlan_reg_is_dfs_ch(hdd_ctx->hdd_pdev,
hdd_ap_ctx->operating_channel)) {
hdd_err("SAP is already on DFS channel:%d",
hdd_ap_ctx->operating_channel);
return -EINVAL;
}
if (!WLAN_REG_IS_24GHZ_CH(hdd_ap_ctx->operating_channel)) {
hdd_err("pre CAC alllowed only when SAP is in 2.4GHz:%d",
hdd_ap_ctx->operating_channel);
return -EINVAL;
}
mac_addr = wlan_hdd_get_intf_addr(hdd_ctx);
if (!mac_addr) {
hdd_err("can't add virtual intf: Not getting valid mac addr");
return -EINVAL;
}
hdd_debug("channel:%d", channel);
ret = wlan_hdd_validate_and_get_pre_cac_ch(hdd_ctx, ap_adapter, channel,
&pre_cac_chan);
if (ret != 0) {
hdd_err("can't validate pre-cac channel");
goto release_intf_addr_and_return_failure;
}
hdd_debug("starting pre cac SAP adapter");
/* Starting a SAP adapter:
* Instead of opening an adapter, we could just do a SME open session
* for AP type. But, start BSS would still need an adapter.
* So, this option is not taken.
*
* hdd open adapter is going to register this precac interface with
* user space. This interface though exposed to user space will be in
* DOWN state. Consideration was done to avoid this registration to the
* user space. But, as part of SAP operations multiple events are sent
* to user space. Some of these events received from unregistered
* interface was causing crashes. So, retaining the registration.
*
* So, this interface would remain registered and will remain in DOWN
* state for the CAC duration. We will add notes in the feature
* announcement to not use this temporary interface for any activity
* from user space.
*/
pre_cac_adapter = hdd_open_adapter(hdd_ctx, QDF_SAP_MODE, "precac%d",
mac_addr, NET_NAME_UNKNOWN, true);
if (!pre_cac_adapter) {
hdd_err("error opening the pre cac adapter");
goto release_intf_addr_and_return_failure;
}
/*
* This interface is internally created by the driver. So, no interface
* up comes for this interface from user space and hence starting
* the adapter internally.
*/
if (hdd_start_adapter(pre_cac_adapter)) {
hdd_err("error starting the pre cac adapter");
goto close_pre_cac_adapter;
}
hdd_debug("preparing for start ap/bss on the pre cac adapter");
wiphy = hdd_ctx->wiphy;
dev = pre_cac_adapter->dev;
/* Since this is only a dummy interface lets us use the IEs from the
* other active SAP interface. In regular scenarios, these IEs would
* come from the user space entity
*/
pre_cac_adapter->session.ap.beacon = qdf_mem_malloc(
sizeof(*ap_adapter->session.ap.beacon));
if (!pre_cac_adapter->session.ap.beacon) {
hdd_err("failed to alloc mem for beacon");
goto stop_close_pre_cac_adapter;
}
qdf_mem_copy(pre_cac_adapter->session.ap.beacon,
ap_adapter->session.ap.beacon,
sizeof(*pre_cac_adapter->session.ap.beacon));
pre_cac_adapter->session.ap.sap_config.ch_width_orig =
ap_adapter->session.ap.sap_config.ch_width_orig;
pre_cac_adapter->session.ap.sap_config.authType =
ap_adapter->session.ap.sap_config.authType;
/* Premise is that on moving from 2.4GHz to 5GHz, the SAP will continue
* to operate on the same bandwidth as that of the 2.4GHz operations.
* Only bandwidths 20MHz/40MHz are possible on 2.4GHz band.
*/
switch (ap_adapter->session.ap.sap_config.ch_width_orig) {
case CH_WIDTH_20MHZ:
channel_type = NL80211_CHAN_HT20;
break;
case CH_WIDTH_40MHZ:
if (ap_adapter->session.ap.sap_config.sec_ch >
ap_adapter->session.ap.sap_config.channel)
channel_type = NL80211_CHAN_HT40PLUS;
else
channel_type = NL80211_CHAN_HT40MINUS;
break;
default:
channel_type = NL80211_CHAN_NO_HT;
break;
}
freq = cds_chan_to_freq(pre_cac_chan);
chan = ieee80211_get_channel(wiphy, freq);
if (!chan) {
hdd_err("channel converion failed");
goto stop_close_pre_cac_adapter;
}
cfg80211_chandef_create(&chandef, chan, channel_type);
hdd_debug("orig width:%d channel_type:%d freq:%d",
ap_adapter->session.ap.sap_config.ch_width_orig,
channel_type, freq);
/*
* Doing update after opening and starting pre-cac adapter will make
* sure that driver won't do hardware mode change if there are any
* initial hick-ups or issues in pre-cac adapter's configuration.
* Since current SAP is in 2.4GHz and pre CAC channel is in 5GHz, this
* connection update should result in DBS mode
*/
status = policy_mgr_update_and_wait_for_connection_update(
hdd_ctx->hdd_psoc,
ap_adapter->session_id,
pre_cac_chan,
POLICY_MGR_UPDATE_REASON_PRE_CAC);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_err("error in moving to DBS mode");
goto stop_close_pre_cac_adapter;
}
ret = wlan_hdd_set_channel(wiphy, dev, &chandef, channel_type);
if (ret != 0) {
hdd_err("failed to set channel");
goto stop_close_pre_cac_adapter;
}
status = wlan_hdd_cfg80211_start_bss(pre_cac_adapter, NULL,
PRE_CAC_SSID, qdf_str_len(PRE_CAC_SSID),
NL80211_HIDDEN_SSID_NOT_IN_USE, false);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_err("start bss failed");
goto stop_close_pre_cac_adapter;
}
/*
* The pre cac status is set here. But, it would not be reset explicitly
* anywhere, since after the pre cac success/failure, the pre cac
* adapter itself would be removed.
*/
ret = wlan_hdd_set_pre_cac_status(pre_cac_adapter, true, mac_handle);
if (ret != 0) {
hdd_err("failed to set pre cac status");
goto stop_close_pre_cac_adapter;
}
ret = wlan_hdd_set_chan_before_pre_cac(ap_adapter,
hdd_ap_ctx->operating_channel);
if (ret != 0) {
hdd_err("failed to set channel before pre cac");
goto stop_close_pre_cac_adapter;
}
ap_adapter->pre_cac_chan = pre_cac_chan;
return 0;
stop_close_pre_cac_adapter:
hdd_stop_adapter(hdd_ctx, pre_cac_adapter);
qdf_mem_free(pre_cac_adapter->session.ap.beacon);
pre_cac_adapter->session.ap.beacon = NULL;
close_pre_cac_adapter:
hdd_close_adapter(hdd_ctx, pre_cac_adapter, false);
release_intf_addr_and_return_failure:
/*
* Release the interface address as the adapter
* failed to start, if you don't release then next
* adapter which is trying to come wouldn't get valid
* mac address. Remember we have limited pool of mac addresses
*/
wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
return -EINVAL;
}
/**
* __wlan_hdd_cfg80211_conditional_chan_switch() - Conditional channel switch
* @wiphy: Pointer to wireless phy
* @wdev: Pointer to wireless device
* @data: Pointer to data
* @data_len: Data length
*
* Processes the conditional channel switch request and invokes the helper
* APIs to process the channel switch request.
*
* Return: 0 on success, negative errno on failure
*/
static int
__wlan_hdd_cfg80211_conditional_chan_switch(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
int ret;
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
struct net_device *dev = wdev->netdev;
struct hdd_adapter *adapter;
struct nlattr
*tb[QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_MAX + 1];
uint32_t freq_len, i;
uint32_t *freq;
uint8_t chans[QDF_MAX_NUM_CHAN] = {0};
hdd_enter_dev(dev);
ret = wlan_hdd_validate_context(hdd_ctx);
if (ret)
return ret;
if (!hdd_ctx->config->enableDFSMasterCap) {
hdd_err("DFS master capability is not present in the driver");
return -EINVAL;
}
if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
hdd_err("Command not allowed in FTM mode");
return -EPERM;
}
adapter = WLAN_HDD_GET_PRIV_PTR(dev);
if (adapter->device_mode != QDF_SAP_MODE) {
hdd_err("Invalid device mode %d", adapter->device_mode);
return -EINVAL;
}
/*
* audit note: it is ok to pass a NULL policy here since only
* one attribute is parsed which is array of frequencies and
* it is explicitly validated for both under read and over read
*/
if (wlan_cfg80211_nla_parse(tb,
QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_MAX,
data, data_len, NULL)) {
hdd_err("Invalid ATTR");
return -EINVAL;
}
if (!tb[QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_FREQ_LIST]) {
hdd_err("Frequency list is missing");
return -EINVAL;
}
freq_len = nla_len(
tb[QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_FREQ_LIST])/
sizeof(uint32_t);
if (freq_len > QDF_MAX_NUM_CHAN) {
hdd_err("insufficient space to hold channels");
return -ENOMEM;
}
hdd_debug("freq_len=%d", freq_len);
freq = nla_data(
tb[QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_FREQ_LIST]);
for (i = 0; i < freq_len; i++) {
if (freq[i] == 0)
chans[i] = 0;
else
chans[i] = ieee80211_frequency_to_channel(freq[i]);
hdd_debug("freq[%d]=%d", i, freq[i]);
}
/*
* The input frequency list from user space is designed to be a
* priority based frequency list. This is only to accommodate any
* future request. But, current requirement is only to perform CAC
* on a single channel. So, the first entry from the list is picked.
*
* If channel is zero, any channel in the available outdoor regulatory
* domain will be selected.
*/
ret = wlan_hdd_request_pre_cac(chans[0]);
if (ret) {
hdd_err("pre cac request failed with reason:%d", ret);
return ret;
}
return 0;
}
int wlan_hdd_cfg80211_conditional_chan_switch(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
int ret;
cds_ssr_protect(__func__);
ret = __wlan_hdd_cfg80211_conditional_chan_switch(wiphy, wdev,
data, data_len);
cds_ssr_unprotect(__func__);
return ret;
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 2012-2018 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.
*/
#ifndef __WLAN_HDD_SAP_COND_CHAN_SWITCH_H
#define __WLAN_HDD_SAP_COND_CHAN_SWITCH_H
/**
* DOC: wlan_hdd_sap_cond_chan_switch_h
*
* WLAN Host Device Driver SAP conditional channel switch API specification
*/
#ifdef FEATURE_SAP_COND_CHAN_SWITCH
/**
* wlan_hdd_cfg80211_conditional_chan_switch() - SAP conditional channel switch
* @wiphy: Pointer to wireless phy
* @wdev: Pointer to wireless device
* @data: Pointer to data
* @data_len: Data length
*
* Invokes internal API __wlan_hdd_cfg80211_conditional_chan_switch()
* to process the conditional channel switch request.
*
* Return: 0 on success, negative errno on failure
*/
int wlan_hdd_cfg80211_conditional_chan_switch(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len);
#define FEATURE_SAP_COND_CHAN_SWITCH_VENDOR_COMMANDS \
{ \
.info.vendor_id = QCA_NL80211_VENDOR_ID, \
.info.subcmd = \
QCA_NL80211_VENDOR_SUBCMD_SAP_CONDITIONAL_CHAN_SWITCH, \
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
WIPHY_VENDOR_CMD_NEED_NETDEV | \
WIPHY_VENDOR_CMD_NEED_RUNNING, \
.doit = wlan_hdd_cfg80211_conditional_chan_switch \
},
#else /* FEATURE_SAP_COND_CHAN_SWITCH */
#define FEATURE_SAP_COND_CHAN_SWITCH_VENDOR_COMMANDS
#endif /* FEATURE_SAP_COND_CHAN_SWITCH */
#endif /* __WLAN_HDD_SAP_COND_CHAN_SWITCH_H */

View file

@ -0,0 +1,320 @@
/*
* Copyright (c) 2012-2018 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: wlan_hdd_vendor_sar_limits.c
*
* WLAN SAR limits functions
*
*/
#include <wlan_hdd_includes.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <wlan_osif_request_manager.h>
#include <wlan_hdd_sar_limits.h>
#define WLAN_WAIT_TIME_SAR 5000
/**
* hdd_sar_context - hdd sar context
* @event: sar limit event
*/
struct hdd_sar_context {
struct sar_limit_event event;
};
static u32 hdd_sar_wmi_to_nl_enable(uint32_t wmi_value)
{
switch (wmi_value) {
default:
case WMI_SAR_FEATURE_OFF:
return QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE;
case WMI_SAR_FEATURE_ON_SET_0:
return QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0;
case WMI_SAR_FEATURE_ON_SET_1:
return QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF1;
case WMI_SAR_FEATURE_ON_SET_2:
return QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF2;
case WMI_SAR_FEATURE_ON_SET_3:
return QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF3;
case WMI_SAR_FEATURE_ON_SET_4:
return QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF4;
case WMI_SAR_FEATURE_ON_USER_DEFINED:
return QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_USER;
case WMI_SAR_FEATURE_ON_SAR_V2_0:
return QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_V2_0;
}
}
static u32 hdd_sar_wmi_to_nl_band(uint32_t wmi_value)
{
switch (wmi_value) {
default:
case WMI_SAR_2G_ID:
return HDD_NL80211_BAND_2GHZ;
case WMI_SAR_5G_ID:
return HDD_NL80211_BAND_5GHZ;
}
}
static u32 hdd_sar_wmi_to_nl_modulation(uint32_t wmi_value)
{
switch (wmi_value) {
default:
case WMI_SAR_MOD_CCK:
return QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_CCK;
case WMI_SAR_MOD_OFDM:
return QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_OFDM;
}
}
/**
* hdd_sar_cb () - sar response message handler
* @cookie: hdd request cookie
* @event: sar response event
*
* Return: none
*/
static void hdd_sar_cb(void *cookie,
struct sar_limit_event *event)
{
struct osif_request *request;
struct hdd_sar_context *context;
hdd_enter();
if (!event) {
hdd_err("response is NULL");
return;
}
request = osif_request_get(cookie);
if (!request) {
hdd_debug("Obsolete request");
return;
}
context = osif_request_priv(request);
context->event = *event;
osif_request_complete(request);
osif_request_put(request);
hdd_exit();
}
static uint32_t hdd_sar_get_response_len(const struct sar_limit_event *event)
{
uint32_t len;
uint32_t row_len;
len = NLMSG_HDRLEN;
/* QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE */
len += NLA_HDRLEN + sizeof(u32);
/* QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS */
len += NLA_HDRLEN + sizeof(u32);
/* nest */
row_len = NLA_HDRLEN;
/* QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_BAND */
row_len += NLA_HDRLEN + sizeof(u32);
/* QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN */
row_len += NLA_HDRLEN + sizeof(u32);
/* QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION */
row_len += NLA_HDRLEN + sizeof(u32);
/* QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT */
row_len += NLA_HDRLEN + sizeof(u32);
/* QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC */
len += NLA_HDRLEN + (row_len * event->num_limit_rows);
return len;
}
static int hdd_sar_fill_response(struct sk_buff *skb,
const struct sar_limit_event *event)
{
int errno;
u32 value;
u32 attr;
struct nlattr *nla_spec_attr;
struct nlattr *nla_row_attr;
uint32_t row;
const struct sar_limit_event_row *event_row;
attr = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE;
value = hdd_sar_wmi_to_nl_enable(event->sar_enable);
errno = nla_put_u32(skb, attr, value);
if (errno)
return errno;
attr = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS;
value = event->num_limit_rows;
errno = nla_put_u32(skb, attr, value);
if (errno)
return errno;
attr = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC;
nla_spec_attr = nla_nest_start(skb, attr);
if (!nla_spec_attr)
return -EINVAL;
for (row = 0, event_row = event->sar_limit_row;
row < event->num_limit_rows;
row++, event_row++) {
nla_row_attr = nla_nest_start(skb, attr);
if (!nla_row_attr)
return -EINVAL;
attr = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_BAND;
value = hdd_sar_wmi_to_nl_band(event_row->band_id);
errno = nla_put_u32(skb, attr, value);
if (errno)
return errno;
attr = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN;
value = event_row->chain_id;
errno = nla_put_u32(skb, attr, value);
if (errno)
return errno;
attr = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION;
value = hdd_sar_wmi_to_nl_modulation(event_row->mod_id);
errno = nla_put_u32(skb, attr, value);
if (errno)
return errno;
attr = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT;
value = event_row->limit_value;
errno = nla_put_u32(skb, attr, value);
if (errno)
return errno;
nla_nest_end(skb, nla_row_attr);
}
nla_nest_end(skb, nla_spec_attr);
return 0;
}
static int hdd_sar_send_response(struct wiphy *wiphy,
const struct sar_limit_event *event)
{
uint32_t len;
struct sk_buff *skb;
int errno;
len = hdd_sar_get_response_len(event);
skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, len);
if (!skb) {
hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
return -ENOMEM;
}
errno = hdd_sar_fill_response(skb, event);
if (errno) {
kfree_skb(skb);
return errno;
}
return cfg80211_vendor_cmd_reply(skb);
}
/**
* __wlan_hdd_get_sar_power_limits() - Get SAR power limits
* @wiphy: Pointer to wireless phy
* @wdev: Pointer to wireless device
* @data: Pointer to data
* @data_len: Length of @data
*
* This function is used to retrieve Specific Absorption Rate limit specs.
*
* Return: 0 on success, negative errno on failure
*/
static int __wlan_hdd_get_sar_power_limits(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data, int data_len)
{
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
struct osif_request *request;
struct hdd_sar_context *context;
mac_handle_t mac_handle;
void *cookie;
QDF_STATUS status;
int ret;
static const struct osif_request_params params = {
.priv_size = sizeof(*context),
.timeout_ms = WLAN_WAIT_TIME_SAR,
};
hdd_enter();
if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
hdd_err("Command not allowed in FTM mode");
return -EPERM;
}
if (wlan_hdd_validate_context(hdd_ctx))
return -EINVAL;
request = osif_request_alloc(&params);
if (!request) {
hdd_err("Request allocation failure");
return -ENOMEM;
}
cookie = osif_request_cookie(request);
mac_handle = hdd_ctx->mac_handle;
status = sme_get_sar_power_limits(mac_handle, hdd_sar_cb, cookie);
if (!QDF_IS_STATUS_SUCCESS(status)) {
hdd_err("Unable to post sar message");
ret = -EINVAL;
goto cleanup;
}
ret = osif_request_wait_for_response(request);
if (ret) {
hdd_err("Target response timed out");
goto cleanup;
}
context = osif_request_priv(request);
ret = hdd_sar_send_response(wiphy, &context->event);
cleanup:
osif_request_put(request);
return ret;
}
int wlan_hdd_cfg80211_get_sar_power_limits(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
int ret;
cds_ssr_protect(__func__);
ret = __wlan_hdd_get_sar_power_limits(wiphy, wdev, data, data_len);
cds_ssr_unprotect(__func__);
return ret;
}

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2012-2018 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.
*/
#ifndef __WLAN_HDD_SAR_LIMITS_H
#define __WLAN_HDD_SAR_LIMITS_H
/**
* DOC: wlan_hdd_sar_limits_h
*
* WLAN Host Device Driver SAR limits API specification
*/
#ifdef FEATURE_SAR_LIMITS
/**
* wlan_hdd_cfg80211_get_sar_power_limits() - Get SAR power limits
* @wiphy: Pointer to wireless phy
* @wdev: Pointer to wireless device
* @data: Pointer to data
* @data_len: Length of @data
*
* Wrapper function of __wlan_hdd_cfg80211_get_sar_power_limits()
*
* Return: 0 on success, negative errno on failure
*/
int wlan_hdd_cfg80211_get_sar_power_limits(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len);
#define FEATURE_SAR_LIMITS_VENDOR_COMMANDS \
{ \
.info.vendor_id = QCA_NL80211_VENDOR_ID, \
.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SAR_LIMITS, \
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
WIPHY_VENDOR_CMD_NEED_RUNNING, \
.doit = wlan_hdd_cfg80211_get_sar_power_limits \
},
#else /* FEATURE_SAR_LIMITS */
#define FEATURE_SAR_LIMITS_VENDOR_COMMANDS
#endif /* FEATURE_SAR_LIMITS */
#endif /* __WLAN_HDD_SAR_LIMITS_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2012-2018 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.
*/
#ifndef __WLAN_HDD_STATION_INFO_H
#define __WLAN_HDD_STATION_INFO_H
/**
* DOC: wlan_hdd_station_info_h
*
* WLAN Host Device Driver STATION info API specification
*/
#ifdef FEATURE_STATION_INFO
/**
* wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
* @wiphy: corestack handler
* @wdev: wireless device
* @data: data
* @data_len: data length
*
* Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
* Validate cmd attributes and send the station info to upper layers.
*
* Return: Success(0) or reason code for failure
*/
int32_t hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len);
#define FEATURE_STATION_INFO_VENDOR_COMMANDS \
{ \
.info.vendor_id = QCA_NL80211_VENDOR_ID, \
.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION, \
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
WIPHY_VENDOR_CMD_NEED_NETDEV | \
WIPHY_VENDOR_CMD_NEED_RUNNING, \
.doit = hdd_cfg80211_get_station_cmd \
},
#else /* FEATURE_STATION_INFO */
#define FEATURE_STATION_INFO_VENDOR_COMMANDS
#endif /* FEATURE_STATION_INFO */
#endif /* __WLAN_HDD_STATION_INFO_H */

View file

@ -0,0 +1,192 @@
/*
* Copyright (c) 2012-2018 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: wlan_hdd_tx_power.c
*
* WLAN tx power setting functions
*
*/
#include <wlan_hdd_includes.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <wma_api.h>
#include <wlan_hdd_tx_power.h>
#define MAX_TXPOWER_SCALE 4
static const struct nla_policy
txpower_scale_policy[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_MAX + 1] = {
[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE] = { .type = NLA_U8 },
};
/**
* __wlan_hdd_cfg80211_txpower_scale () - txpower scaling
* @wiphy: Pointer to wireless phy
* @wdev: Pointer to wireless device
* @data: Pointer to data
* @data_len: Data length
*
* Return: 0 on success, negative errno on failure
*/
static int __wlan_hdd_cfg80211_txpower_scale(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
struct net_device *dev = wdev->netdev;
struct hdd_adapter *adapter;
int ret;
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_MAX + 1];
uint8_t scale_value;
QDF_STATUS status;
hdd_enter_dev(dev);
ret = wlan_hdd_validate_context(hdd_ctx);
if (ret)
return ret;
adapter = WLAN_HDD_GET_PRIV_PTR(dev);
if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_MAX,
data, data_len, txpower_scale_policy)) {
hdd_err("Invalid ATTR");
return -EINVAL;
}
if (!tb[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE]) {
hdd_err("attr tx power scale failed");
return -EINVAL;
}
scale_value = nla_get_u8(tb
[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE]);
if (scale_value > MAX_TXPOWER_SCALE) {
hdd_err("Invalid tx power scale level");
return -EINVAL;
}
status = wma_set_tx_power_scale(adapter->session_id, scale_value);
if (status != QDF_STATUS_SUCCESS) {
hdd_err("Set tx power scale failed");
return -EINVAL;
}
return 0;
}
int wlan_hdd_cfg80211_txpower_scale(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
int ret;
cds_ssr_protect(__func__);
ret = __wlan_hdd_cfg80211_txpower_scale(wiphy, wdev,
data, data_len);
cds_ssr_unprotect(__func__);
return ret;
}
static const struct nla_policy txpower_scale_decr_db_policy
[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB_MAX + 1] = {
[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB] = { .type = NLA_U8 },
};
/**
* __wlan_hdd_cfg80211_txpower_scale_decr_db () - txpower scaling
* @wiphy: Pointer to wireless phy
* @wdev: Pointer to wireless device
* @data: Pointer to data
* @data_len: Data length
*
* Return: 0 on success, negative errno on failure
*/
static int
__wlan_hdd_cfg80211_txpower_scale_decr_db(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
struct net_device *dev = wdev->netdev;
struct hdd_adapter *adapter;
int ret;
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB_MAX + 1];
uint8_t scale_value;
QDF_STATUS status;
hdd_enter_dev(dev);
ret = wlan_hdd_validate_context(hdd_ctx);
if (ret)
return ret;
adapter = WLAN_HDD_GET_PRIV_PTR(dev);
if (wlan_cfg80211_nla_parse(tb,
QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB_MAX,
data, data_len,
txpower_scale_decr_db_policy)) {
hdd_err("Invalid ATTR");
return -EINVAL;
}
if (!tb[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB]) {
hdd_err("attr tx power decrease db value failed");
return -EINVAL;
}
scale_value = nla_get_u8(tb
[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB]);
status = wma_set_tx_power_scale_decr_db(adapter->session_id,
scale_value);
if (status != QDF_STATUS_SUCCESS) {
hdd_err("Set tx power decrease db failed");
return -EINVAL;
}
return 0;
}
int wlan_hdd_cfg80211_txpower_scale_decr_db(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
int ret;
cds_ssr_protect(__func__);
ret = __wlan_hdd_cfg80211_txpower_scale_decr_db(wiphy, wdev,
data, data_len);
cds_ssr_unprotect(__func__);
return ret;
}

View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2012-2018 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.
*/
#ifndef __WLAN_HDD_TX_POWER_H
#define __WLAN_HDD_TX_POWER_H
/**
* DOC: wlan_hdd_tx_power_h
*
* WLAN Host Device Driver TX power setting API specification
*/
#ifdef FEATURE_TX_POWER
/**
* wlan_hdd_cfg80211_txpower_scale () - txpower scaling
* @wiphy: Pointer to wireless phy
* @wdev: Pointer to wireless device
* @data: Pointer to data
* @data_len: Data length
*
* Return: 0 on success, negative errno on failure
*/
int wlan_hdd_cfg80211_txpower_scale(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len);
/**
* wlan_hdd_cfg80211_txpower_scale_decr_db () - txpower scaling
* @wiphy: Pointer to wireless phy
* @wdev: Pointer to wireless device
* @data: Pointer to data
* @data_len: Data length
*
* Return: 0 on success, negative errno on failure
*/
int wlan_hdd_cfg80211_txpower_scale_decr_db(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len);
#define FEATURE_TX_POWER_VENDOR_COMMANDS \
{ \
.info.vendor_id = QCA_NL80211_VENDOR_ID, \
.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE, \
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
WIPHY_VENDOR_CMD_NEED_NETDEV | \
WIPHY_VENDOR_CMD_NEED_RUNNING, \
.doit = wlan_hdd_cfg80211_txpower_scale \
}, \
{ \
.info.vendor_id = QCA_NL80211_VENDOR_ID, \
.info.subcmd = \
QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE_DECR_DB, \
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
WIPHY_VENDOR_CMD_NEED_NETDEV | \
WIPHY_VENDOR_CMD_NEED_RUNNING, \
.doit = wlan_hdd_cfg80211_txpower_scale_decr_db \
},
#else /* FEATURE_TX_POWER */
#define FEATURE_TX_POWER_VENDOR_COMMANDS
#endif /* FEATURE_TX_POWER */
#endif /* __WLAN_HDD_TX_POWER_H */

View file

@ -1525,6 +1525,7 @@ QDF_STATUS wlan_sap_update_next_channel(struct sap_context *sap_ctx,
return QDF_STATUS_SUCCESS;
}
#ifdef FEATURE_SAP_COND_CHAN_SWITCH
QDF_STATUS wlan_sap_set_pre_cac_status(struct sap_context *sap_ctx,
bool status, tHalHandle handle)
{
@ -1561,6 +1562,7 @@ QDF_STATUS wlan_sap_set_chan_before_pre_cac(struct sap_context *sap_ctx,
sap_ctx->chan_before_pre_cac = chan_before_pre_cac;
return QDF_STATUS_SUCCESS;
}
#endif /* FEATURE_SAP_COND_CHAN_SWITCH */
QDF_STATUS wlan_sap_set_pre_cac_complete_status(struct sap_context *sap_ctx,
bool status)

View file

@ -910,12 +910,27 @@ QDF_STATUS sme_ap_disable_intra_bss_fwd(tHalHandle hHal, uint8_t sessionId,
QDF_STATUS sme_get_channel_bonding_mode5_g(tHalHandle hHal, uint32_t *mode);
QDF_STATUS sme_get_channel_bonding_mode24_g(tHalHandle hHal, uint32_t *mode);
#ifdef WLAN_FEATURE_STATS_EXT
/**
* sme_send_unit_test_cmd() - send unit test command to lower layer
* @session_id: sme session id to be filled while forming the command
* @module_id: module id given by user to be filled in the command
* @arg_count: number of argument count
* @arg: pointer to argument list
*
* This API exposed to HDD layer which takes the argument from user and sends
* down to lower layer for further processing
*
* Return: QDF_STATUS based on overall success
*/
QDF_STATUS sme_send_unit_test_cmd(uint32_t vdev_id, uint32_t module_id,
uint32_t arg_count, uint32_t *arg);
typedef struct sStatsExtRequestReq {
uint32_t request_data_len;
uint8_t *request_data;
} tStatsExtRequestReq, *tpStatsExtRequestReq;
#ifdef WLAN_FEATURE_STATS_EXT
/**
* sme_stats_ext_register_callback() - Register stats ext callback
* @mac_handle: Opaque handle to the MAC context
@ -951,23 +966,19 @@ void sme_stats_ext2_register_callback(tHalHandle hal_handle,
QDF_STATUS sme_stats_ext_request(uint8_t session_id,
tpStatsExtRequestReq input);
#else
static inline void
sme_stats_ext_register_callback(mac_handle_t mac_handle,
stats_ext_cb callback)
{
}
static inline void
sme_stats_ext2_register_callback(tHalHandle hal_handle,
stats_ext2_cb callback)
{
}
#endif /* WLAN_FEATURE_STATS_EXT */
/**
* sme_send_unit_test_cmd() - send unit test command to lower layer
* @session_id: sme session id to be filled while forming the command
* @module_id: module id given by user to be filled in the command
* @arg_count: number of argument count
* @arg: pointer to argument list
*
* This API exposed to HDD layer which takes the argument from user and sends
* down to lower layer for further processing
*
* Return: QDF_STATUS based on overall success
*/
QDF_STATUS sme_send_unit_test_cmd(uint32_t vdev_id, uint32_t module_id,
uint32_t arg_count, uint32_t *arg);
QDF_STATUS sme_update_dfs_scan_mode(tHalHandle hHal,
uint8_t sessionId,
uint8_t allowDFSChannelRoam);
@ -1182,6 +1193,7 @@ QDF_STATUS sme_disable_uapsd_for_ac(uint8_t sta_id,
sme_ac_enum_type ac,
uint32_t sessionId);
#ifdef FEATURE_RSSI_MONITOR
QDF_STATUS sme_set_rssi_monitoring(tHalHandle hal,
struct rssi_monitor_req *input);
@ -1196,7 +1208,14 @@ QDF_STATUS sme_set_rssi_monitoring(tHalHandle hal,
*/
QDF_STATUS sme_set_rssi_threshold_breached_cb(mac_handle_t mac_handle,
rssi_threshold_breached_cb cb);
#else /* FEATURE_RSSI_MONITOR */
static inline
QDF_STATUS sme_set_rssi_threshold_breached_cb(mac_handle_t mac_handle,
rssi_threshold_breached_cb cb)
{
return QDF_STATUS_SUCCESS;
}
#endif
/**
* sme_reset_rssi_threshold_breached_cb() - Reset RSSI threshold breached
* callback

View file

@ -12995,35 +12995,6 @@ QDF_STATUS sme_set_nud_debug_stats_cb(tHalHandle hal,
return status;
}
QDF_STATUS sme_set_rssi_threshold_breached_cb(mac_handle_t mac_handle,
rssi_threshold_breached_cb cb)
{
QDF_STATUS status;
tpAniSirGlobal mac;
mac = MAC_CONTEXT(mac_handle);
if (!mac) {
sme_err("Invalid mac context");
return QDF_STATUS_E_INVAL;
}
status = sme_acquire_global_lock(&mac->sme);
if (!QDF_IS_STATUS_SUCCESS(status)) {
sme_err("sme_acquire_global_lock failed!(status=%d)",
status);
return status;
}
mac->sme.rssi_threshold_breached_cb = cb;
sme_release_global_lock(&mac->sme);
return status;
}
QDF_STATUS sme_reset_rssi_threshold_breached_cb(mac_handle_t mac_handle)
{
return sme_set_rssi_threshold_breached_cb(mac_handle, NULL);
}
/**
* sme_is_any_session_in_connected_state() - SME wrapper API to
* check if any session is in connected state or not.
@ -13066,6 +13037,7 @@ QDF_STATUS sme_set_chip_pwr_save_fail_cb(mac_handle_t mac_handle,
return status;
}
#ifdef FEATURE_RSSI_MONITOR
/**
* sme_set_rssi_monitoring() - set rssi monitoring
* @hal: global hal handle
@ -13113,6 +13085,36 @@ QDF_STATUS sme_set_rssi_monitoring(tHalHandle hal,
return status;
}
QDF_STATUS sme_set_rssi_threshold_breached_cb(mac_handle_t mac_handle,
rssi_threshold_breached_cb cb)
{
QDF_STATUS status;
tpAniSirGlobal mac;
mac = MAC_CONTEXT(mac_handle);
if (!mac) {
sme_err("Invalid mac context");
return QDF_STATUS_E_INVAL;
}
status = sme_acquire_global_lock(&mac->sme);
if (!QDF_IS_STATUS_SUCCESS(status)) {
sme_err("sme_acquire_global_lock failed!(status=%d)",
status);
return status;
}
mac->sme.rssi_threshold_breached_cb = cb;
sme_release_global_lock(&mac->sme);
return status;
}
#endif /* FEATURE_RSSI_MONITOR */
QDF_STATUS sme_reset_rssi_threshold_breached_cb(mac_handle_t mac_handle)
{
return sme_set_rssi_threshold_breached_cb(mac_handle, NULL);
}
/*
* sme_pdev_set_pcl() - Send WMI_PDEV_SET_PCL_CMDID to the WMA
* @hal: Handle returned by macOpen
@ -15708,6 +15710,16 @@ QDF_STATUS sme_send_limit_off_channel_params(tHalHandle hal, uint8_t vdev_id,
return QDF_STATUS_SUCCESS;
}
uint32_t sme_unpack_rsn_ie(tHalHandle hal, uint8_t *buf,
uint8_t buf_len, tDot11fIERSN *rsn_ie,
bool append_ie)
{
tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
return dot11f_unpack_ie_rsn(mac_ctx, buf, buf_len, rsn_ie, append_ie);
}
#ifdef FEATURE_BSS_TRANSITION
/**
* sme_get_status_for_candidate() - Get bss transition status for candidate
* @hal: Handle for HAL
@ -15806,15 +15818,6 @@ static bool sme_get_status_for_candidate(tHalHandle hal,
return false;
}
uint32_t sme_unpack_rsn_ie(tHalHandle hal, uint8_t *buf,
uint8_t buf_len, tDot11fIERSN *rsn_ie,
bool append_ie)
{
tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
return dot11f_unpack_ie_rsn(mac_ctx, buf, buf_len, rsn_ie, append_ie);
}
/**
* wlan_hdd_get_bss_transition_status() - get bss transition status all cadidates
* @adapter : Pointer to adapter
@ -15896,6 +15899,7 @@ free:
return status;
}
#endif /* FEATURE_BSS_TRANSITION */
void sme_enable_roaming_on_connected_sta(tHalHandle hal)
{

View file

@ -1729,8 +1729,17 @@ QDF_STATUS wma_update_vdev_tbl(tp_wma_handle wma_handle, uint8_t vdev_id,
void wma_send_flush_logs_to_fw(tp_wma_handle wma_handle);
void wma_log_completion_timeout(void *data);
#ifdef FEATURE_RSSI_MONITOR
QDF_STATUS wma_set_rssi_monitoring(tp_wma_handle wma,
struct rssi_monitor_req *req);
struct rssi_monitor_req *req);
#else /* FEATURE_RSSI_MONITOR */
static inline
QDF_STATUS wma_set_rssi_monitoring(tp_wma_handle wma,
struct rssi_monitor_req *req)
{
return QDF_STATUS_SUCCESS;
}
#endif /* FEATURE_RSSI_MONITOR */
QDF_STATUS wma_send_pdev_set_pcl_cmd(tp_wma_handle wma_handle,
struct wmi_pcl_chan_weights *msg);

View file

@ -1094,8 +1094,17 @@ QDF_STATUS wma_set_tdls_offchan_mode(WMA_HANDLE wma_handle,
void wma_set_vdev_mgmt_rate(tp_wma_handle wma, uint8_t vdev_id);
void wma_set_sap_keepalive(tp_wma_handle wma, uint8_t vdev_id);
#ifdef FEATURE_RSSI_MONITOR
int wma_rssi_breached_event_handler(void *handle,
u_int8_t *cmd_param_info, u_int32_t len);
#else /* FEATURE_RSSI_MONITOR */
static inline
int wma_rssi_breached_event_handler(void *handle,
u_int8_t *cmd_param_info, u_int32_t len)
{
return 0;
}
#endif /* FEATURE_RSSI_MONITOR */
QDF_STATUS wma_process_set_ie_info(tp_wma_handle wma,
struct vdev_ie_info *ie_info);

View file

@ -1690,6 +1690,7 @@ QDF_STATUS wma_set_smps_params(tp_wma_handle wma, uint8_t vdev_id,
return ret;
}
#ifdef FEATURE_TX_POWER
/**
* wma_set_tx_power_scale() - set tx power scale
* @vdev_id: vdev id
@ -1751,3 +1752,5 @@ QDF_STATUS wma_set_tx_power_scale_decr_db(uint8_t vdev_id, int value)
return ret;
}
#endif /* FEATURE_TX_POWER */

View file

@ -2853,6 +2853,37 @@ void wma_set_ric_req(tp_wma_handle wma, void *msg, uint8_t is_add_ts)
}
#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
#ifdef FEATURE_RSSI_MONITOR
/**
* wma_set_rssi_monitoring() - set rssi monitoring
* @handle: WMA handle
* @req: rssi monitoring request structure
*
* This function reads the incoming @req and fill in the destination
* WMI structure and send down the rssi monitoring configs down to the firmware
*
* Return: 0 on success; error number otherwise
*/
QDF_STATUS wma_set_rssi_monitoring(tp_wma_handle wma,
struct rssi_monitor_req *req)
{
struct rssi_monitor_param params = {0};
if (!wma) {
WMA_LOGE("%s: wma handle is NULL", __func__);
return QDF_STATUS_E_INVAL;
}
params.request_id = req->request_id;
params.session_id = req->session_id;
params.min_rssi = req->min_rssi;
params.max_rssi = req->max_rssi;
params.control = req->control;
return wmi_unified_set_rssi_monitoring_cmd(wma->wmi_handle,
&params);
}
/**
* wma_rssi_breached_event_handler() - rssi breached event handler
* @handle: wma handle
@ -2890,13 +2921,14 @@ int wma_rssi_breached_event_handler(void *handle,
WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->bssid, rssi.curr_bssid.bytes);
WMA_LOGD("%s: req_id: %u vdev_id: %d curr_rssi: %d", __func__,
rssi.request_id, rssi.session_id, rssi.curr_rssi);
rssi.request_id, rssi.session_id, rssi.curr_rssi);
WMA_LOGI("%s: curr_bssid: %pM", __func__, rssi.curr_bssid.bytes);
mac->sme.rssi_threshold_breached_cb(mac->hdd_handle, &rssi);
WMA_LOGD("%s: Invoke HDD rssi breached callback", __func__);
return 0;
}
#endif /* FEATURE_RSSI_MONITOR */
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
/**
@ -5268,37 +5300,6 @@ int wma_roam_event_callback(WMA_HANDLE handle, uint8_t *event_buf,
return 0;
}
/**
* wma_set_rssi_monitoring() - set rssi monitoring
* @handle: WMA handle
* @req: rssi monitoring request structure
*
* This function reads the incoming @req and fill in the destination
* WMI structure and send down the rssi monitoring configs down to the firmware
*
* Return: 0 on success; error number otherwise
*/
QDF_STATUS wma_set_rssi_monitoring(tp_wma_handle wma,
struct rssi_monitor_req *req)
{
struct rssi_monitor_param params = {0};
if (!wma) {
WMA_LOGE("%s: wma handle is NULL", __func__);
return QDF_STATUS_E_INVAL;
}
params.request_id = req->request_id;
params.session_id = req->session_id;
params.min_rssi = req->min_rssi;
params.max_rssi = req->max_rssi;
params.control = req->control;
return wmi_unified_set_rssi_monitoring_cmd(wma->wmi_handle,
&params);
}
#ifdef FEATURE_LFR_SUBNET_DETECTION
/**
* wma_set_gateway_params() - set gateway parameters