qcacld-3.0: User MCC quota setting

Set the MCC quota for a given interface.

Change-Id: I313cdf1673f8fc5f50a049d429c0d88fd213e66f
CRs-Fixed: 3106146
这个提交包含在:
Madhvapathi Sriram
2021-12-09 15:17:22 +05:30
提交者 Madan Koyyalamudi
父节点 ec454ae3e5
当前提交 79e13b55ab
修改 13 个文件,包含 675 行新增23 行删除

11
Kbuild
查看文件

@@ -507,6 +507,10 @@ ifeq ($(CONFIG_QCACLD_WLAN_CONNECTIVITY_LOGGING), y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_connectivity_logging.o
endif
ifeq ($(CONFIG_WLAN_FEATURE_MCC_QUOTA), y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_mcc_quota.o
endif
$(call add-wlan-objs,hdd,$(HDD_OBJS))
###### OSIF_SYNC ########
@@ -4329,6 +4333,13 @@ endif
cppflags-$(CONFIG_WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET) += -DWLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET
ifeq ($(CONFIG_WLAN_FEATURE_MCC_QUOTA), y)
cppflags-y += -DWLAN_FEATURE_MCC_QUOTA
ifdef CONFIG_WLAN_MCC_MIN_CHANNEL_QUOTA
ccflags-y += -DWLAN_MCC_MIN_CHANNEL_QUOTA=$(CONFIG_WLAN_MCC_MIN_CHANNEL_QUOTA)
endif
endif
KBUILD_CPPFLAGS += $(cppflags-y)
# Currently, for versions of gcc which support it, the kernel Makefile

查看文件

@@ -2483,7 +2483,6 @@ mlme_init_dot11_mode_cfg(struct wlan_objmgr_psoc *psoc,
/**
* mlme_iot_parse_aggr_info - parse aggr related items in ini
*
* @psoc: PSOC pointer
* @iot: IOT related CFG items
*
@@ -2589,7 +2588,6 @@ end:
/**
* mlme_iot_parse_aggr_info - parse IOT related items in ini
*
* @psoc: PSOC pointer
* @iot: IOT related CFG items
*
@@ -2604,7 +2602,6 @@ mlme_init_iot_cfg(struct wlan_objmgr_psoc *psoc,
/**
* mlme_init_dual_sta_config - Initialize dual sta configuratons
*
* @gen: Generic CFG config items
*
* Return: None
@@ -2617,6 +2614,26 @@ mlme_init_dual_sta_config(struct wlan_mlme_generic *gen)
QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED;
}
#ifdef WLAN_FEATURE_MCC_QUOTA
/**
* mlme_init_user_mcc_quota_config - Initialize mcc quota
* @gen: Generic CFG config items
*
* Return: None
*/
static void
mlme_init_user_mcc_quota_config(struct wlan_mlme_generic *gen)
{
gen->user_mcc_quota.quota = 0;
gen->user_mcc_quota.op_mode = QDF_MAX_NO_OF_MODE;
gen->user_mcc_quota.vdev_id = WLAN_UMAC_VDEV_ID_MAX;
}
#else
static void
mlme_init_user_mcc_quota_config(struct wlan_mlme_generic *gen)
{
}
#endif
QDF_STATUS mlme_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc)
{
struct wlan_mlme_psoc_ext_obj *mlme_obj;
@@ -2672,6 +2689,7 @@ QDF_STATUS mlme_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc)
mlme_init_ratemask_cfg(psoc, &mlme_cfg->ratemask_cfg);
mlme_init_iot_cfg(psoc, &mlme_cfg->iot);
mlme_init_dual_sta_config(&mlme_cfg->gen);
mlme_init_user_mcc_quota_config(&mlme_cfg->gen);
return status;
}

查看文件

@@ -761,7 +761,6 @@ QDF_STATUS wlan_mlme_get_sap_chan_switch_rate_enabled(struct wlan_objmgr_psoc
/**
* wlan_mlme_get_sap_force_11n_for_11ac() - get the sap 11n for 11ac
*
* @psoc: pointer to psoc object
* @value: Value that needs to be set from the caller
*
@@ -772,7 +771,6 @@ QDF_STATUS wlan_mlme_get_sap_force_11n_for_11ac(struct wlan_objmgr_psoc
/**
* wlan_mlme_get_go_force_11n_for_11ac() - get the go 11n for 11ac
*
* @psoc: pointer to psoc object
* @value: Value that needs to be set from the caller
*
@@ -783,7 +781,6 @@ QDF_STATUS wlan_mlme_get_go_force_11n_for_11ac(struct wlan_objmgr_psoc
/**
* wlan_mlme_is_go_11ac_override() - Override 11ac bandwdith for P2P GO
*
* @psoc: pointer to psoc object
* @value: pointer to the value which will be filled for the caller
*
@@ -794,7 +791,6 @@ QDF_STATUS wlan_mlme_is_go_11ac_override(struct wlan_objmgr_psoc *psoc,
/**
* wlan_mlme_is_sap_11ac_override() - Override 11ac bandwdith for SAP
*
* @psoc: pointer to psoc object
* @value: pointer to the value which will be filled for the caller
*
@@ -805,7 +801,6 @@ QDF_STATUS wlan_mlme_is_sap_11ac_override(struct wlan_objmgr_psoc *psoc,
/**
* wlan_mlme_set_go_11ac_override() - set override 11ac bandwdith for P2P GO
*
* @psoc: pointer to psoc object
* @value: pointer to the value which will be filled for the caller
*
@@ -816,7 +811,6 @@ QDF_STATUS wlan_mlme_set_go_11ac_override(struct wlan_objmgr_psoc *psoc,
/**
* wlan_mlme_set_sap_11ac_override() - set override 11ac bandwdith for SAP
*
* @psoc: pointer to psoc object
* @value: pointer to the value which will be filled for the caller
*
@@ -946,7 +940,6 @@ QDF_STATUS wlan_mlme_cfg_get_enable_ul_ofdm(struct wlan_objmgr_psoc *psoc,
/**
* mlme_update_tgt_he_caps_in_cfg() - Update tgt he cap in mlme component
*
* @psoc: pointer to psoc object
* @cfg: pointer to config params from target
*
@@ -962,7 +955,6 @@ QDF_STATUS mlme_update_tgt_he_caps_in_cfg(struct wlan_objmgr_psoc *psoc,
#ifdef WLAN_FEATURE_11BE
/**
* mlme_update_tgt_eht_caps_in_cfg() - Update tgt eht cap in mlme component
*
* @psoc: pointer to psoc object
* @cfg: pointer to config params from target
*
@@ -2262,7 +2254,6 @@ wlan_mlme_is_relaxed_6ghz_conn_policy_enabled(struct wlan_objmgr_psoc *psoc,
/**
* wlan_mlme_get_sta_miracast_mcc_rest_time() - Get STA/MIRACAST MCC rest time
*
* @psoc: pointer to psoc object
* @value: value which needs to filled by API
*
@@ -2276,7 +2267,6 @@ wlan_mlme_get_sta_miracast_mcc_rest_time(struct wlan_objmgr_psoc *psoc,
/**
* wlan_mlme_get_scan_probe_unicast_ra() - Get scan probe unicast RA cfg
*
* @psoc: pointer to psoc object
* @value: value which needs to filled by API
*
@@ -2290,7 +2280,6 @@ wlan_mlme_get_scan_probe_unicast_ra(struct wlan_objmgr_psoc *psoc,
/**
* wlan_mlme_set_scan_probe_unicast_ra() - Set scan probe unicast RA cfg
*
* @psoc: pointer to psoc object
* @value: set value
*
@@ -2304,7 +2293,6 @@ wlan_mlme_set_scan_probe_unicast_ra(struct wlan_objmgr_psoc *psoc,
/**
* wlan_mlme_get_sap_mcc_chnl_avoid() - Check if SAP MCC needs to be avoided
*
* @psoc: pointer to psoc object
* @value: value which needs to filled by API
*
@@ -2318,7 +2306,6 @@ wlan_mlme_get_sap_mcc_chnl_avoid(struct wlan_objmgr_psoc *psoc,
uint8_t *value);
/**
* wlan_mlme_get_mcc_bcast_prob_resp() - Get broadcast probe rsp in MCC
*
* @psoc: pointer to psoc object
* @value: value which needs to filled by API
*
@@ -2333,7 +2320,6 @@ wlan_mlme_get_mcc_bcast_prob_resp(struct wlan_objmgr_psoc *psoc,
uint8_t *value);
/**
* wlan_mlme_get_mcc_rts_cts_prot() - To get RTS-CTS protection in MCC.
*
* @psoc: pointer to psoc object
* @value: value which needs to filled by API
*
@@ -2348,7 +2334,6 @@ wlan_mlme_get_mcc_rts_cts_prot(struct wlan_objmgr_psoc *psoc,
uint8_t *value);
/**
* wlan_mlme_get_mcc_feature() - To find out to enable/disable MCC feature
*
* @psoc: pointer to psoc object
* @value: value which needs to filled by API
*
@@ -3396,7 +3381,6 @@ bool mlme_get_user_ps(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id);
#ifdef WLAN_FEATURE_P2P_P2P_STA
/**
* wlan_mlme_get_p2p_p2p_conc_support() - Get p2p+p2p conc support
*
* @psoc: pointer to psoc object
* @val : value
*
@@ -3421,7 +3405,6 @@ enum phy_ch_width mlme_get_vht_ch_width(void);
/**
* wlan_mlme_get_mgmt_hw_tx_retry_count() - Get mgmt frame hw tx retry count
*
* @psoc: pointer to psoc object
* @frm_type: frame type of the query
*
@@ -3433,7 +3416,6 @@ wlan_mlme_get_mgmt_hw_tx_retry_count(struct wlan_objmgr_psoc *psoc,
/**
* wlan_mlme_get_tx_retry_multiplier() - Get the tx retry multiplier percentage
*
* @psoc: pointer to psoc object
* @tx_retry_multiplier: pointer to hold user config value of
* tx_retry_multiplier
@@ -3469,4 +3451,54 @@ QDF_STATUS
wlan_mlme_update_ratemask_params(struct wlan_objmgr_vdev *vdev,
uint8_t num_ratemask,
struct config_ratemask_params *rate_params);
#ifdef WLAN_FEATURE_MCC_QUOTA
/**
* wlan_mlme_set_user_mcc_quota() - set the user mcc quota in mlme
* @psoc: pointer to psoc object
* @quota: pointer to user set mcc quota object
*
* Return: QDF Status
*/
QDF_STATUS wlan_mlme_set_user_mcc_quota(struct wlan_objmgr_psoc *psoc,
struct wlan_user_mcc_quota *quota);
/**
* wlan_mlme_get_user_mcc_quota() - Get the user mcc quota from mlme
* @psoc: pointer to psoc object
* @quota: pointer to user set mcc quota object
*
* Return: QDF Status
*/
QDF_STATUS wlan_mlme_get_user_mcc_quota(struct wlan_objmgr_psoc *psoc,
struct wlan_user_mcc_quota *quota);
/**
* wlan_mlme_get_user_mcc_duty_cycle_percentage() - Get user mcc duty cycle
* @psoc: pointer to psoc object
*
* Return: MCC duty cycle if MCC exists for the user MCC quota, else 0
*/
uint32_t
wlan_mlme_get_user_mcc_duty_cycle_percentage(struct wlan_objmgr_psoc *psoc);
#else
static inline QDF_STATUS
wlan_mlme_set_user_mcc_quota(struct wlan_objmgr_psoc *psoc,
struct wlan_user_mcc_quota *quota)
{
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS
wlan_mlme_get_user_mcc_quota(struct wlan_objmgr_psoc *psoc,
struct wlan_user_mcc_quota *quota)
{
return QDF_STATUS_E_NOSUPPORT;
}
static inline uint32_t
wlan_mlme_get_user_mcc_duty_cycle_percentage(struct wlan_objmgr_psoc *psoc)
{
return 0;
}
#endif /* WLAN_FEATURE_MCC_QUOTA */
#endif /* _WLAN_MLME_API_H_ */

查看文件

@@ -1290,6 +1290,18 @@ enum mlme_cfg_frame_type {
#define MAX_MGMT_HW_TX_RETRY_COUNT 127
/**
* struct wlan_user_mcc_quota - User MCC quota configuration
* @op_mode: Mode for which MCC quota needs to be applied
* @quota: User MCC quota value
* @vdev_id: Intended VDEV id for the quota
*/
struct wlan_user_mcc_quota {
enum QDF_OPMODE op_mode;
uint8_t quota;
uint8_t vdev_id;
};
/* struct wlan_mlme_generic - Generic CFG config items
*
* @band_capability: HW Band Capability - Both or 2.4G only or 5G only
@@ -1391,6 +1403,9 @@ struct wlan_mlme_generic {
#ifdef CONFIG_BAND_6GHZ
bool relaxed_6ghz_conn_policy;
#endif
#ifdef WLAN_FEATURE_MCC_QUOTA
struct wlan_user_mcc_quota user_mcc_quota;
#endif
};
/*

查看文件

@@ -4443,7 +4443,6 @@ bool ucfg_mlme_get_coex_unsafe_chan_reg_disable(
*
* Return: QDF_STATUS
*/
static inline QDF_STATUS
ucfg_set_ratemask_params(struct wlan_objmgr_vdev *vdev,
uint8_t num_ratemask,
@@ -4452,4 +4451,54 @@ ucfg_set_ratemask_params(struct wlan_objmgr_vdev *vdev,
return wlan_mlme_update_ratemask_params(vdev, num_ratemask,
rate_params);
}
/*
* ucfg_mlme_set_user_mcc_quota() - Set the user set mcc quota in mlme
* value
* @psoc: pointer to psoc object
* @quota: pointer to user mcc quota object
*
* Return: QDF Status
*/
static inline
QDF_STATUS ucfg_mlme_set_user_mcc_quota(struct wlan_objmgr_psoc *psoc,
struct wlan_user_mcc_quota *quota)
{
return wlan_mlme_set_user_mcc_quota(psoc, quota);
}
/**
* ucfg_mlme_get_user_mcc_quota() - Get the user set mcc quota from mlme
* value
* @psoc: pointer to psoc object
* @quota: pointer to user mcc quota object
*
* Return: QDF Status
*/
static inline
QDF_STATUS ucfg_mlme_get_user_mcc_quota(struct wlan_objmgr_psoc *psoc,
struct wlan_user_mcc_quota *quota)
{
return wlan_mlme_get_user_mcc_quota(psoc, quota);
}
/**
* ucfg_mlme_get_user_mcc_quota_percentage() - Get user mcc quota percentage
* duty-cycle for a i/f type or mode
* @psoc: pointer to psoc object
*
* MCC duty-cycle value in below format
* ******************************************************
* |bit 31-24 | bit 23-16 | bits 15-8 |bits 7-0 |
* | Unused | Quota for | chan. # for |chan. # for|
* | | 1st chan | 1st chan. |2nd chan. |
* *****************************************************
*
* Return: primary iface MCC duty-cycle value
*/
static inline
uint32_t ucfg_mlme_get_user_mcc_quota_percentage(struct wlan_objmgr_psoc *psoc)
{
return wlan_mlme_get_user_mcc_duty_cycle_percentage(psoc);
}
#endif /* _WLAN_MLME_UCFG_API_H_ */

查看文件

@@ -5462,3 +5462,133 @@ wlan_mlme_update_ratemask_params(struct wlan_objmgr_vdev *vdev,
}
return QDF_STATUS_SUCCESS;
}
#ifdef WLAN_FEATURE_MCC_QUOTA
#define WLAN_MCC_MIN_QUOTA 10 /* in %age */
#define WLAN_MCC_MAX_QUOTA 90 /* in %age */
QDF_STATUS wlan_mlme_set_user_mcc_quota(struct wlan_objmgr_psoc *psoc,
struct wlan_user_mcc_quota *quota)
{
struct wlan_mlme_psoc_ext_obj *mlme_obj;
if (!quota)
return QDF_STATUS_E_NULL_VALUE;
mlme_obj = mlme_get_psoc_ext_obj(psoc);
if (!mlme_obj)
return QDF_STATUS_E_FAILURE;
if (quota->quota < WLAN_MCC_MIN_QUOTA)
quota->quota = WLAN_MCC_MIN_QUOTA;
else if (quota->quota > WLAN_MCC_MAX_QUOTA)
quota->quota = WLAN_MCC_MAX_QUOTA;
mlme_obj->cfg.gen.user_mcc_quota.quota = quota->quota;
mlme_obj->cfg.gen.user_mcc_quota.op_mode = quota->op_mode;
mlme_obj->cfg.gen.user_mcc_quota.vdev_id = quota->vdev_id;
mlme_debug("quota : %u, op_mode : %d, vdev_id : %u",
quota->quota, quota->op_mode, quota->vdev_id);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS wlan_mlme_get_user_mcc_quota(struct wlan_objmgr_psoc *psoc,
struct wlan_user_mcc_quota *quota)
{
struct wlan_mlme_psoc_ext_obj *mlme_obj;
if (!quota)
return QDF_STATUS_E_NULL_VALUE;
mlme_obj = mlme_get_psoc_ext_obj(psoc);
if (!mlme_obj)
return QDF_STATUS_E_FAILURE;
quota->quota = mlme_obj->cfg.gen.user_mcc_quota.quota;
quota->op_mode = mlme_obj->cfg.gen.user_mcc_quota.op_mode;
quota->vdev_id = mlme_obj->cfg.gen.user_mcc_quota.vdev_id;
return QDF_STATUS_SUCCESS;
}
uint32_t
wlan_mlme_get_user_mcc_duty_cycle_percentage(struct wlan_objmgr_psoc *psoc)
{
uint32_t mcc_freq, ch_freq, quota_value;
struct wlan_user_mcc_quota quota;
uint8_t operating_channel;
int status;
quota.vdev_id = WLAN_UMAC_VDEV_ID_MAX;
quota.quota = 0;
if (QDF_IS_STATUS_ERROR(wlan_mlme_get_user_mcc_quota(psoc, &quota))) {
mlme_debug("Error getting user quota set");
return 0;
}
if (quota.vdev_id == WLAN_UMAC_VDEV_ID_MAX || quota.quota == 0) {
mlme_debug("Invalid quota : vdev %u, quota %u",
quota.vdev_id, quota.quota);
return 0;
}
status = policy_mgr_get_chan_by_session_id(psoc, quota.vdev_id,
&ch_freq);
if (QDF_IS_STATUS_ERROR(status)) {
mlme_debug("Could not get vdev %u chan", quota.vdev_id);
return 0;
}
mcc_freq = policy_mgr_get_mcc_operating_channel(psoc, quota.vdev_id);
if (mcc_freq == INVALID_CHANNEL_ID)
return 0;
operating_channel = wlan_freq_to_chan(ch_freq);
if (!operating_channel) {
mlme_debug("Primary op channel is invalid");
return 0;
}
/*
* The channel numbers for both adapters and the time
* quota for the 1st adapter, i.e., one specified in cmd
* are formatted as a bit vector
* ******************************************************
* |bit 31-24 | bit 23-16 | bits 15-8 |bits 7-0 |
* | Unused | Quota for | chan. # for |chan. # for|
* | | 1st chan | 1st chan. |2nd chan. |
* ******************************************************
*/
mlme_debug("Opmode (%d) vdev (%u) channel %u and quota %u",
quota.op_mode, quota.vdev_id,
operating_channel, quota.quota);
quota_value = quota.quota;
/* Move the time quota for first channel to bits 15-8 */
quota_value = quota_value << 8;
/*
* Store the channel number of 1st channel at bits 7-0
* of the bit vector
*/
quota_value |= operating_channel;
operating_channel = wlan_freq_to_chan(mcc_freq);
if (!operating_channel) {
mlme_debug("Secondary op channel is invalid");
return 0;
}
/*
* Now move the time quota and channel number of the
* 1st adapter to bits 23-16 and bits 15-8 of the bit
* vector, respectively.
*/
quota_value = quota_value << 8;
/*
* Set the channel number for 2nd MCC vdev at bits
* 7-0 of set_value
*/
quota_value |= operating_channel;
mlme_debug("quota value:%x", quota_value);
return quota_value;
}
#endif /* WLAN_FEATURE_MCC_QUOTA */

查看文件

@@ -3748,6 +3748,21 @@ void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind);
*/
struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx,
const char *iface_name);
/**
* hdd_get_adapter_by_ifindex() - Return adapter associated with an ifndex
* @hdd_ctx: hdd context.
* @if_index: netdev interface index
*
* This function is used to get the adapter associated with a netdev with the
* given interface index.
*
* Return: adapter pointer if found, NULL otherwise
*
*/
struct hdd_adapter *hdd_get_adapter_by_ifindex(struct hdd_context *hdd_ctx,
uint32_t if_index);
enum phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width);
/**

查看文件

@@ -178,6 +178,7 @@
#include "wlan_pkt_capture_ucfg_api.h"
#include "os_if_pkt_capture.h"
#include "wlan_hdd_son.h"
#include "wlan_hdd_mcc_quota.h"
#define g_mode_rates_size (12)
#define a_mode_rates_size (8)
@@ -17639,6 +17640,7 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_MAX)
},
#endif
FEATURE_MCC_QUOTA_VENDOR_COMMANDS
};
struct hdd_context *hdd_cfg80211_wiphy_alloc(void)

查看文件

@@ -107,6 +107,7 @@
#include <wlan_mlo_mgr_ap.h>
#endif
#include "wlan_hdd_son.h"
#include "wlan_hdd_mcc_quota.h"
#define ACS_SCAN_EXPIRY_TIMEOUT_S 4
@@ -2154,6 +2155,8 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event,
hdd_err("qdf_event_set failed! status: %d", qdf_status);
goto stopbss;
}
wlan_hdd_apply_user_mcc_quota(adapter);
break; /* Event will be sent after Switch-Case stmt */
case eSAP_STOP_BSS_EVENT:

查看文件

@@ -9375,6 +9375,27 @@ struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx,
return NULL;
}
struct hdd_adapter *hdd_get_adapter_by_ifindex(struct hdd_context *hdd_ctx,
uint32_t if_index)
{
struct hdd_adapter *adapter, *next_adapter = NULL;
wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER;
hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
dbgid) {
if (adapter->dev->ifindex == if_index) {
hdd_adapter_dev_put_debug(adapter, dbgid);
if (next_adapter)
hdd_adapter_dev_put_debug(next_adapter,
dbgid);
return adapter;
}
hdd_adapter_dev_put_debug(adapter, dbgid);
}
return NULL;
}
/**
* hdd_get_adapter() - to get adapter matching the mode
* @hdd_ctx: hdd context

查看文件

@@ -0,0 +1,241 @@
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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_mcc_quota.c
*
* WLAN Host Device Driver MCC quota feature cfg80211 APIs implementation
*
*/
#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/etherdevice.h>
#include <linux/wireless.h>
#include "osif_sync.h"
#include <wlan_hdd_includes.h>
#include <net/cfg80211.h>
#include "sme_api.h"
#include "wlan_hdd_cfg80211.h"
#include "wlan_hdd_hostapd.h"
#include "wlan_hdd_main.h"
#include "wlan_hdd_mcc_quota.h"
#include "wlan_hdd_trace.h"
#include "qdf_str.h"
#include "qdf_trace.h"
#include "qdf_types.h"
#include "wlan_policy_mgr_api.h"
#include <qca_vendor.h>
#include "wlan_utility.h"
#include "wlan_policy_mgr_ucfg.h"
#include "wlan_mlme_ucfg_api.h"
#include "wlan_mlme_public_struct.h"
#include "wlan_hdd_object_manager.h"
#include "sme_api.h"
const struct nla_policy
set_mcc_quota_policy[QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_MAX + 1] = {
[QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_TYPE] = { .type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_ENTRIES] =
VENDOR_NLA_POLICY_NESTED(set_mcc_quota_policy),
[QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_FREQ] = {
.type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_TIME_PERCENTAGE] = {
.type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_IFINDEX] = { .type = NLA_U32 },
};
int wlan_hdd_set_mcc_adaptive_sched(struct wlan_objmgr_psoc *psoc, bool enable)
{
bool enable_mcc_adaptive_sch;
hdd_debug("enable : %d", enable);
ucfg_policy_mgr_get_mcc_adaptive_sch(psoc, &enable_mcc_adaptive_sch);
if (enable_mcc_adaptive_sch) {
ucfg_policy_mgr_set_dynamic_mcc_adaptive_sch(psoc, enable);
if (QDF_IS_STATUS_ERROR(sme_set_mas(enable))) {
hdd_err("Fail to config mcc adaptive sched.");
return -EINVAL;
}
}
return 0;
}
int wlan_hdd_cfg80211_set_mcc_quota(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *attr,
int attr_len)
{
struct hdd_adapter *if_adapter;
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_MAX + 1];
struct nlattr *quota_entries[QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_MAX + 1];
struct nlattr *curr_attr;
struct wlan_objmgr_psoc *psoc;
uint32_t duty_cycle, cmd_id, quota_type, rem_bytes, entries, if_idx;
struct wlan_user_mcc_quota mcc_quota;
int att_id, rc;
hdd_enter();
if (wlan_hdd_validate_context(hdd_ctx))
return -EINVAL;
psoc = hdd_ctx->psoc;
if (!psoc)
return -EINVAL;
if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_MAX,
attr, attr_len, set_mcc_quota_policy)) {
hdd_err("Error parsing attributes");
return -EINVAL;
}
cmd_id = QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_TYPE;
if (!tb[cmd_id]) {
hdd_err("Quota type not specified");
return -EINVAL;
}
quota_type = nla_get_u32(tb[cmd_id]);
if (quota_type != QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_FIXED &&
quota_type != QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_CLEAR) {
hdd_err("Quota type is not valid %u", quota_type);
return -EINVAL;
}
if (quota_type == QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_CLEAR) {
/* Remove quota, enable MCC adaptive scheduling */
if (wlan_hdd_set_mcc_adaptive_sched(hdd_ctx->psoc, true))
return -EAGAIN;
mcc_quota.op_mode = QDF_MAX_NO_OF_MODE;
mcc_quota.vdev_id = WLAN_UMAC_VDEV_ID_MAX;
ucfg_mlme_set_user_mcc_quota(psoc, &mcc_quota);
return 0;
}
cmd_id = QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_ENTRIES;
if (!tb[cmd_id]) {
hdd_err("No entries present");
return -EINVAL;
}
entries = 0;
nla_for_each_nested(curr_attr, tb[cmd_id], rem_bytes) {
if (entries > 0) {
hdd_debug("Only one entry permitted");
hdd_debug("Entry (%d) for (%u) is ignored",
entries, nla_type(curr_attr));
entries++;
continue;
}
rc = wlan_cfg80211_nla_parse_nested(quota_entries,
QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_MAX,
curr_attr,
set_mcc_quota_policy);
if (rc) {
hdd_err("Entry parse error %d", rc);
return -EINVAL;
}
att_id = QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_IFINDEX;
if (!quota_entries[att_id]) {
hdd_err("if_index not specified");
return -EINVAL;
}
if_idx = nla_get_u32(quota_entries[att_id]);
if (if_idx == 0) {
hdd_debug("Invalid if_index");
return -EINVAL;
}
if_adapter = hdd_get_adapter_by_ifindex(hdd_ctx, if_idx);
if (!if_adapter) {
hdd_err("interface (%u) not found", if_idx);
return -EINVAL;
}
if (wlan_hdd_validate_vdev_id(if_adapter->vdev_id))
return -EINVAL;
att_id = QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_TIME_PERCENTAGE;
if (!quota_entries[att_id]) {
hdd_err("Quota not specified");
return -EINVAL;
}
mcc_quota.quota = nla_get_u32(quota_entries[att_id]);
mcc_quota.vdev_id = if_adapter->vdev_id;
mcc_quota.op_mode = if_adapter->device_mode;
entries++;
}
if (entries == 0) {
hdd_err("No entries found");
return -EINVAL;
}
ucfg_mlme_set_user_mcc_quota(psoc, &mcc_quota);
duty_cycle = ucfg_mlme_get_user_mcc_quota_percentage(psoc);
if (duty_cycle == 0) {
hdd_debug("Quota will be configured when MCC scenario exists");
return 0;
}
if (wlan_hdd_set_mcc_adaptive_sched(hdd_ctx->psoc, false))
return -EAGAIN;
if (wlan_hdd_send_mcc_vdev_quota(if_adapter, duty_cycle))
return -EINVAL;
return 0;
}
int wlan_hdd_apply_user_mcc_quota(struct hdd_adapter *adapter)
{
struct hdd_context *hdd_ctx;
uint32_t quota_val;
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
if (!hdd_ctx)
return -EINVAL;
quota_val =
ucfg_mlme_get_user_mcc_quota_percentage(hdd_ctx->psoc);
if (quota_val == 0) {
hdd_debug("no mcc/quota for mode %d, vdev_id : %u",
adapter->device_mode, adapter->vdev_id);
return 0;
}
if (wlan_hdd_set_mcc_adaptive_sched(hdd_ctx->psoc, false))
return 0;
if (wlan_hdd_send_mcc_vdev_quota(adapter, quota_val)) {
hdd_info("Could not send quota");
wlan_hdd_set_mcc_adaptive_sched(hdd_ctx->psoc, true);
}
return 0;
}

查看文件

@@ -0,0 +1,95 @@
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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_mcc_quota.h
*
* WLAN Host Device Driver MCC quota feature interface definitions
*
*/
#ifndef WLAN_HDD_MCC_QUOTA_H
#define WLAN_HDD_MCC_QUOTA_H
#include "qdf_types.h"
#include "qdf_status.h"
#include "qca_vendor.h"
#include <net/cfg80211.h>
struct hdd_context;
struct hdd_adapter;
struct wlan_objmgr_psoc;
#ifdef WLAN_FEATURE_MCC_QUOTA
extern const struct nla_policy
set_mcc_quota_policy[QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_MAX + 1];
/**
* wlan_hdd_set_mcc_adaptive_sched: Enable or disable MCC adaptive scheduling
* @hdd_ctx: HDD context
* @enable: Enable (true) or disable (false)
*
* Return: 0 for success, Non zero failure code for errors
*/
int wlan_hdd_set_mcc_adaptive_sched(struct wlan_objmgr_psoc *psoc,
bool enable);
/**
* wlan_hdd_cfg80211_set_mcc_quota() - Set user MCC quota to the target
* @wiphy: Wireless info object
* @wdev: Wireless dev object
* @attr: Command attributes
* @attr_len: Length of attributes
*
* Return: 0 on success, negative errno on failure
*/
int wlan_hdd_cfg80211_set_mcc_quota(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *attr,
int attr_len);
#define FEATURE_MCC_QUOTA_VENDOR_COMMANDS \
{ \
.info.vendor_id = QCA_NL80211_VENDOR_ID, \
.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MCC_QUOTA, \
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,\
.doit = wlan_hdd_cfg80211_set_mcc_quota, \
vendor_command_policy(set_mcc_quota_policy, \
QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_MAX) \
},
/**
* wlan_hdd_apply_user_mcc_quota() - Apply the user MCC quota to the target
* @adapter: pointer to HDD adapter object
*
* Return: 0 on succcess, errno for error
*/
int wlan_hdd_apply_user_mcc_quota(struct hdd_adapter *adapter);
#else /* WLAN_FEATURE_MCC_QUOTA */
#define FEATURE_MCC_QUOTA_VENDOR_COMMANDS
static inline int wlan_hdd_apply_user_mcc_quota(struct hdd_adapter *adapter)
{
return 0;
}
static inline int wlan_hdd_set_mcc_adaptive_sched(struct wlan_objmgr_psoc *psoc,
bool enable)
{
return 0;
}
#endif /* WLAN_FEATURE_MCC_QUOTA */
#endif /* WLAN_HDD_MCC_QUOTA_H */

查看文件

@@ -6650,6 +6650,26 @@ cm_csr_connect_done_ind(struct wlan_objmgr_vdev *vdev,
return -EAGAIN;
}
}
} else {
QDF_STATUS status = QDF_STATUS_SUCCESS;
uint32_t quota_val;
quota_val =
ucfg_mlme_get_user_mcc_quota_percentage(mac_ctx->psoc);
if (quota_val) {
if (enable_mcc_adaptive_sch) {
policy_mgr_set_dynamic_mcc_adaptive_sch(
mac_ctx->psoc, false);
status = sme_set_mas(false);
}
if (status == QDF_STATUS_SUCCESS)
sme_cli_set_command(wlan_vdev_get_id(vdev),
WMA_VDEV_MCC_SET_TIME_QUOTA,
quota_val, VDEV_CMD);
} else {
sme_debug("no applicable user mcc/quota");
}
}
/*