qcacld-3.0: hdd: Refactor the Green AP feature

Refactor the hdd portion of the Green AP feature so that it can be
easily excluded when the feature is not enabled.

Change-Id: I986c5ab7640b3182a12bef93748affefba067251
CRs-Fixed: 2216247
This commit is contained in:
Jeff Johnson 2018-03-31 13:33:54 -07:00 • committed by nshrivas
commit 8bb6111e1f
7 changed files with 317 additions and 157 deletions

4
Kbuild
View file

@ -500,6 +500,10 @@ ifeq ($(CONFIG_WLAN_FEATURE_FIPS), y)
HDD_OBJS+= $(HDD_SRC_DIR)/wlan_hdd_fips.o
endif
ifeq ($(CONFIG_QCACLD_FEATURE_GREEN_AP),y)
HDD_OBJS+= $(HDD_SRC_DIR)/wlan_hdd_green_ap.o
endif
ifeq ($(CONFIG_WLAN_FEATURE_LPSS),y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_lpass.o
endif

View file

@ -1939,18 +1939,6 @@ enum {
* Function declarations and documentation
*/
/**
* hdd_green_ap_start_state_mc() - to start green AP state mc based on
* present concurrency and state of green AP state machine.
* @hdd_ctx: hdd context
* @mode: device mode
* @is_session_start: BSS start/stop
*
* Return: 0 - success, < 0 - failure
*/
int hdd_green_ap_start_state_mc(struct hdd_context *hdd_ctx,
enum QDF_OPMODE mode, bool is_session_start);
int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter,
uint32_t chan_number,
enum phy_ch_width chan_bw);

View file

@ -47,6 +47,7 @@
#include "wlan_hdd_tdls.h"
#include "sme_api.h"
#include "wlan_hdd_hostapd.h"
#include <wlan_hdd_green_ap.h>
#include <wlan_hdd_ipa.h>
#include "wlan_hdd_lpass.h"
#include <wlan_logging_sock_svc.h>

View file

@ -0,0 +1,193 @@
/*
* 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_green_ap.c
*
* WLAN Host Device Driver Green AP implementation
*
*/
#include <wlan_hdd_green_ap.h>
#include <wlan_hdd_main.h>
#include <wlan_policy_mgr_api.h>
#include <wlan_green_ap_ucfg_api.h>
/**
* hdd_green_ap_check_enable() - to check whether to enable green ap or not
* @hdd_ctx: hdd context
* @enable_green_ap: 1 - enable green ap enabled, 0 - disbale green ap
*
* Return: 0 - success, < 0 - failure
*/
static int hdd_green_ap_check_enable(struct hdd_context *hdd_ctx,
bool *enable_green_ap)
{
uint8_t num_sessions, mode;
QDF_STATUS status;
for (mode = 0;
mode < QDF_MAX_NO_OF_MODE;
mode++) {
if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE)
continue;
status = policy_mgr_mode_specific_num_active_sessions(
hdd_ctx->hdd_psoc, mode, &num_sessions);
hdd_debug("No. of active sessions for mode: %d is %d",
mode, num_sessions);
if (status != QDF_STATUS_SUCCESS) {
hdd_err("Failed to get num sessions for mode: %d",
mode);
return -EINVAL;
} else if (num_sessions) {
*enable_green_ap = false;
return 0;
}
}
*enable_green_ap = true;
return 0;
}
void hdd_green_ap_add_sta(struct hdd_context *hdd_ctx)
{
wlan_green_ap_add_sta(hdd_ctx->hdd_pdev);
}
void hdd_green_ap_del_sta(struct hdd_context *hdd_ctx)
{
wlan_green_ap_del_sta(hdd_ctx->hdd_pdev);
}
int hdd_green_ap_enable_egap(struct hdd_context *hdd_ctx)
{
QDF_STATUS status;
status = ucfg_green_ap_enable_egap(hdd_ctx->hdd_pdev);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_debug("enhance green ap is not enabled, status %d",
status);
return qdf_status_to_os_return(status);
}
return 0;
}
int hdd_green_ap_update_config(struct hdd_context *hdd_ctx)
{
struct green_ap_user_cfg green_ap_cfg;
struct hdd_config *cfg = hdd_ctx->config;
QDF_STATUS status;
green_ap_cfg.host_enable_egap = cfg->enable_egap;
green_ap_cfg.egap_inactivity_time = cfg->egap_inact_time;
green_ap_cfg.egap_wait_time = cfg->egap_wait_time;
green_ap_cfg.egap_feature_flags = cfg->egap_feature_flag;
status = ucfg_green_ap_update_user_config(hdd_ctx->hdd_pdev,
&green_ap_cfg);
if (status != QDF_STATUS_SUCCESS) {
hdd_err("failed to update green ap user configuration");
return -EINVAL;
}
return 0;
}
int hdd_green_ap_start_state_mc(struct hdd_context *hdd_ctx,
enum QDF_OPMODE mode, bool is_session_start)
{
struct hdd_config *cfg;
bool enable_green_ap = false;
uint8_t num_sap_sessions = 0, num_p2p_go_sessions = 0, ret = 0;
cfg = hdd_ctx->config;
if (!cfg) {
hdd_err("NULL hdd config");
return -EINVAL;
}
if (!cfg->enable2x2 || !cfg->enableGreenAP) {
hdd_info("Green AP support not present: enable2x2: %d, enableGreenAp: %d",
cfg->enable2x2, cfg->enableGreenAP);
return 0;
}
policy_mgr_mode_specific_num_active_sessions(hdd_ctx->hdd_psoc,
QDF_SAP_MODE,
&num_sap_sessions);
policy_mgr_mode_specific_num_active_sessions(hdd_ctx->hdd_psoc,
QDF_P2P_GO_MODE,
&num_p2p_go_sessions);
switch (mode) {
case QDF_STA_MODE:
case QDF_P2P_CLIENT_MODE:
case QDF_IBSS_MODE:
if (!num_sap_sessions && !num_p2p_go_sessions)
return 0;
if (is_session_start) {
hdd_debug("Disabling Green AP");
ucfg_green_ap_set_ps_config(hdd_ctx->hdd_pdev,
false);
wlan_green_ap_stop(hdd_ctx->hdd_pdev);
} else {
ret = hdd_green_ap_check_enable(hdd_ctx,
&enable_green_ap);
if (!ret) {
if (enable_green_ap) {
hdd_debug("Enabling Green AP");
ucfg_green_ap_set_ps_config(
hdd_ctx->hdd_pdev, true);
wlan_green_ap_start(hdd_ctx->hdd_pdev);
}
} else {
hdd_err("Failed to check Green AP enable status");
}
}
break;
case QDF_SAP_MODE:
case QDF_P2P_GO_MODE:
if (is_session_start) {
ret = hdd_green_ap_check_enable(hdd_ctx,
&enable_green_ap);
if (!ret) {
if (enable_green_ap) {
hdd_debug("Enabling Green AP");
ucfg_green_ap_set_ps_config(
hdd_ctx->hdd_pdev, true);
wlan_green_ap_start(hdd_ctx->hdd_pdev);
}
} else {
hdd_err("Failed to check Green AP enable status");
}
} else {
if (!num_sap_sessions && !num_p2p_go_sessions) {
hdd_debug("Disabling Green AP");
ucfg_green_ap_set_ps_config(hdd_ctx->hdd_pdev,
false);
wlan_green_ap_stop(hdd_ctx->hdd_pdev);
}
}
break;
default:
break;
}
return ret;
}

View file

@ -0,0 +1,114 @@
/*
* 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.
*/
#if !defined(WLAN_HDD_GREEN_AP_H)
#define WLAN_HDD_GREEN_AP_H
#include "qdf_types.h"
struct hdd_context;
#ifdef WLAN_SUPPORT_GREEN_AP
/**
* hdd_green_ap_add_sta() - Notify Green AP on STA association
* @hdd_ctx: Global HDD context
*
* Call this function when new node is associated
*
* Return: void
*/
void hdd_green_ap_add_sta(struct hdd_context *hdd_ctx);
/**
* hdd_green_ap_del_sta() - Notify Green AP on STA disassociation
* @hdd_ctx: Global HDD context
*
* Call this function when new node is disassociated
*
* Return: void
*/
void hdd_green_ap_del_sta(struct hdd_context *hdd_ctx);
/**
* hdd_green_ap_enable_egap() - Enable Enhanced Green AP
* @hdd_ctx: Global HDD context
*
* This function will enable the Enhanced Green AP feature if it is supported
* by the Green AP component.
*
* Return: 0 on success, negative errno on any failure
*/
int hdd_green_ap_enable_egap(struct hdd_context *hdd_ctx);
/**
* hdd_green_ap_update_config() - Update Green AP component configuration
* @hdd_ctx: Global HDD context
*
* This function will take the static Green AP configuration and apply it
* to the Green AP component.
*
* Return: 0 on success, negative errno on any failure
*/
int hdd_green_ap_update_config(struct hdd_context *hdd_ctx);
/**
* hdd_green_ap_start_state_mc() - to start green AP state mc based on
* present concurrency and state of green AP state machine.
* @hdd_ctx: hdd context
* @mode: device mode
* @is_session_start: BSS start/stop
*
* Return: 0 on success, negative errno on any failure
*/
int hdd_green_ap_start_state_mc(struct hdd_context *hdd_ctx,
enum QDF_OPMODE mode, bool is_session_start);
#else /* WLAN_SUPPORT_GREEN_AP */
static inline
void hdd_green_ap_add_sta(struct hdd_context *hdd_ctx)
{
}
static inline
void hdd_green_ap_del_sta(struct hdd_context *hdd_ctx)
{
}
static inline
int hdd_green_ap_enable_egap(struct hdd_context *hdd_ctx)
{
return 0;
}
static inline
int hdd_green_ap_update_config(struct hdd_context *hdd_ctx)
{
return 0;
}
static inline
int hdd_green_ap_start_state_mc(struct hdd_context *hdd_ctx,
enum QDF_OPMODE mode, bool is_session_start)
{
return 0;
}
#endif /* WLAN_SUPPORT_GREEN_AP */
#endif /* !defined(WLAN_HDD_GREEN_AP_H) */

View file

@ -48,6 +48,7 @@
#include <wlan_hdd_includes.h>
#include <qc_sap_ioctl.h>
#include <wlan_hdd_hostapd.h>
#include <wlan_hdd_green_ap.h>
#include <sap_api.h>
#include <sap_internal.h>
#include <wlan_hdd_softap_tx_rx.h>
@ -89,7 +90,6 @@
#include "wlan_utility.h"
#include <wlan_p2p_ucfg_api.h>
#include "sir_api.h"
#include <wlan_green_ap_ucfg_api.h>
#include "sme_api.h"
#include "wlan_hdd_regulatory.h"
#include <wlan_ipa_ucfg_api.h>
@ -2181,7 +2181,7 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
hdd_err("Peer object "MAC_ADDRESS_STR" add fails!",
MAC_ADDR_ARRAY(event->staMac.bytes));
wlan_green_ap_add_sta(hdd_ctx->hdd_pdev);
hdd_green_ap_add_sta(hdd_ctx);
break;
case eSAP_STA_DISASSOC_EVENT:
@ -2293,7 +2293,7 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
hdd_bus_bw_compute_timer_try_stop(hdd_ctx);
}
#endif
wlan_green_ap_del_sta(hdd_ctx->hdd_pdev);
hdd_green_ap_del_sta(hdd_ctx);
break;
case eSAP_WPS_PBC_PROBE_REQ_EVENT:

View file

@ -83,6 +83,7 @@
#endif
#include <wlan_hdd_hostapd.h>
#include <wlan_hdd_softap_tx_rx.h>
#include <wlan_hdd_green_ap.h>
#include "cfg_api.h"
#include "qwlan_version.h"
#include "wma_types.h"
@ -141,7 +142,6 @@
#include "wlan_reg_ucfg_api.h"
#include "wlan_ocb_ucfg_api.h"
#include <wlan_green_ap_ucfg_api.h>
#include <wlan_hdd_spectralscan.h>
#ifdef MODULE
#define WLAN_MODULE_NAME module_name(THIS_MODULE)
@ -312,125 +312,6 @@ void hdd_start_complete(int ret)
complete(&wlan_start_comp);
}
/**
* hdd_green_ap_check_enable() - to check whether to enable green ap or not
* @hdd_ctx: hdd context
* @enable_green_ap: 1 - enable green ap enabled, 0 - disbale green ap
*
* Return: 0 - success, < 0 - failure
*/
static int hdd_green_ap_check_enable(struct hdd_context *hdd_ctx,
bool *enable_green_ap)
{
uint8_t num_sessions, mode;
QDF_STATUS status;
for (mode = 0;
mode < QDF_MAX_NO_OF_MODE;
mode++) {
if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE)
continue;
status = policy_mgr_mode_specific_num_active_sessions(
hdd_ctx->hdd_psoc, mode, &num_sessions);
hdd_debug("No. of active sessions for mode: %d is %d",
mode, num_sessions);
if (status != QDF_STATUS_SUCCESS) {
hdd_err("Failed to get num sessions for mode: %d",
mode);
return -EINVAL;
} else if (num_sessions) {
*enable_green_ap = false;
return 0;
}
}
*enable_green_ap = true;
return 0;
}
int hdd_green_ap_start_state_mc(struct hdd_context *hdd_ctx,
enum QDF_OPMODE mode, bool is_session_start)
{
struct hdd_config *cfg;
bool enable_green_ap = false;
uint8_t num_sap_sessions = 0, num_p2p_go_sessions = 0, ret = 0;
cfg = hdd_ctx->config;
if (!cfg) {
hdd_err("NULL hdd config");
return -EINVAL;
}
if (!cfg->enable2x2 || !cfg->enableGreenAP) {
hdd_info("Green AP support not present: enable2x2: %d, enableGreenAp: %d",
cfg->enable2x2, cfg->enableGreenAP);
return 0;
}
policy_mgr_mode_specific_num_active_sessions(hdd_ctx->hdd_psoc,
QDF_SAP_MODE,
&num_sap_sessions);
policy_mgr_mode_specific_num_active_sessions(hdd_ctx->hdd_psoc,
QDF_P2P_GO_MODE,
&num_p2p_go_sessions);
switch (mode) {
case QDF_STA_MODE:
case QDF_P2P_CLIENT_MODE:
case QDF_IBSS_MODE:
if (!num_sap_sessions && !num_p2p_go_sessions)
return 0;
if (is_session_start) {
hdd_debug("Disabling Green AP");
ucfg_green_ap_set_ps_config(hdd_ctx->hdd_pdev,
false);
wlan_green_ap_stop(hdd_ctx->hdd_pdev);
} else {
ret = hdd_green_ap_check_enable(hdd_ctx,
&enable_green_ap);
if (!ret) {
if (enable_green_ap) {
hdd_debug("Enabling Green AP");
ucfg_green_ap_set_ps_config(
hdd_ctx->hdd_pdev, true);
wlan_green_ap_start(hdd_ctx->hdd_pdev);
}
} else {
hdd_err("Failed to check Green AP enable status");
}
}
break;
case QDF_SAP_MODE:
case QDF_P2P_GO_MODE:
if (is_session_start) {
ret = hdd_green_ap_check_enable(hdd_ctx,
&enable_green_ap);
if (!ret) {
if (enable_green_ap) {
hdd_debug("Enabling Green AP");
ucfg_green_ap_set_ps_config(
hdd_ctx->hdd_pdev, true);
wlan_green_ap_start(hdd_ctx->hdd_pdev);
}
} else {
hdd_err("Failed to check Green AP enable status");
}
} else {
if (!num_sap_sessions && !num_p2p_go_sessions) {
hdd_debug("Disabling Green AP");
ucfg_green_ap_set_ps_config(hdd_ctx->hdd_pdev,
false);
wlan_green_ap_stop(hdd_ctx->hdd_pdev);
}
}
break;
default:
break;
}
return ret;
}
/**
* hdd_set_rps_cpu_mask - set RPS CPU mask for interfaces
* @hdd_ctx: pointer to struct hdd_context
@ -1927,27 +1808,6 @@ static void hdd_update_ra_rate_limit(struct hdd_context *hdd_ctx,
}
#endif
static int hdd_green_ap_update_config(struct hdd_context *hdd_ctx)
{
struct green_ap_user_cfg green_ap_cfg;
struct hdd_config *cfg = hdd_ctx->config;
QDF_STATUS status;
green_ap_cfg.host_enable_egap = cfg->enable_egap;
green_ap_cfg.egap_inactivity_time = cfg->egap_inact_time;
green_ap_cfg.egap_wait_time = cfg->egap_wait_time;
green_ap_cfg.egap_feature_flags = cfg->egap_feature_flag;
status = ucfg_green_ap_update_user_config(hdd_ctx->hdd_pdev,
&green_ap_cfg);
if (status != QDF_STATUS_SUCCESS) {
hdd_err("failed to update green ap user configuration");
return -EINVAL;
}
return 0;
}
void hdd_update_tgt_cfg(void *context, void *param)
{
int ret;
@ -10193,7 +10053,7 @@ int hdd_configure_cds(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter)
goto cds_disable;
}
if (ucfg_green_ap_enable_egap(hdd_ctx->hdd_pdev))
if (hdd_green_ap_enable_egap(hdd_ctx))
hdd_debug("enhance green ap is not enabled");
if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true))