summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbings <bings@codeaurora.org>2016-09-30 15:51:20 +0800
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2016-10-20 12:05:09 +0530
commit722dbda3670b3f8c8842aa51d4dd92c74b1ae5a0 (patch)
treeb06e7e1d1bc9c9af98708bf2020b49d2251aca04
parent75e81cdfb0d0efd88126cf5cdc2fd929e771dec3 (diff)
qcacld-2.0: Enable green AP for AP stand alone and EGAP disabled
When EGAP is enabled, configure EGAP parameters to firmware, and do nothing for GAP. When EGAP is disabled, need refine GAP in below situation. AP+STA concurrency mode When starts STA in case of AP existence, GREEN_AP_PS_STOP_EVENT will be triggered, at this time need to set green_ap->ps_enable as 0 and send firmware WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID with value 0. When stops STA in case of AP existence, abandon using of GREEN_AP_PS_IDLE_STATE, because once in GREEN_AP_PS_IDLE_STATE, more than one GREEN_AP_PS_START_EVENT are needed to achieve the GREEN_AP_PS_ON_STATE. Use GREEN_AP_PS_OFF_STATE instead. AP mode Remove hdd_wlan_green_ap_start_bss/hdd_wlan_green_ap_stop_bss in eSAP_START_BSS_EVENT/eSAP_STOP_BSS_EVENT, becasue SME session id is invalid in the context of eSAP_STOP_BSS_EVENT. Add hdd_wlan_green_ap_start_bss/hdd_wlan_green_ap_stop_bss in __wlan_hdd_cfg80211_start_ap/__wlan_hdd_cfg80211_stop_ap instead. AP+AP mode In hdd_wlan_green_ap_stop_bss, only trigger GREEN_AP_PS_STOP_EVENT when the last AP stops. Change-Id: Ifbf09b870b919d2bd155887bf17a494be07f97b4 CRs-Fixed: 1069300
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h4
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c7
-rw-r--r--CORE/HDD/src/wlan_hdd_hostapd.c4
-rw-r--r--CORE/HDD/src/wlan_hdd_main.c183
4 files changed, 153 insertions, 45 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index d79201fc1ade..065a8685ab8e 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -2050,6 +2050,7 @@ void hdd_wlan_green_ap_start_bss(hdd_context_t *hdd_ctx);
void hdd_wlan_green_ap_stop_bss(struct hdd_context_s *hdd_ctx);
void hdd_wlan_green_ap_add_sta(struct hdd_context_s *hdd_ctx);
void hdd_wlan_green_ap_del_sta(struct hdd_context_s *hdd_ctx);
+int hdd_wlan_enable_egap(struct hdd_context_s *hdd_ctx);
#else
static inline void hdd_wlan_green_ap_init(struct hdd_context_s *hdd_ctx) {}
static inline void hdd_wlan_green_ap_deinit(struct hdd_context_s *hdd_ctx) {}
@@ -2057,6 +2058,9 @@ static inline void hdd_wlan_green_ap_start_bss(hdd_context_t *hdd_ctx) {}
static inline void hdd_wlan_green_ap_stop_bss(struct hdd_context_s *hdd_ctx) {}
static inline void hdd_wlan_green_ap_add_sta(struct hdd_context_s *hdd_ctx) {}
static inline void hdd_wlan_green_ap_del_sta(struct hdd_context_s *hdd_ctx) {}
+static inline int hdd_wlan_enable_egap(struct hdd_context_s *hdd_ctx) {
+ return -EINVAL;
+}
#endif
#ifdef WLAN_FEATURE_STATS_EXT
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index e583aff0b6db..99a57d1e5265 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -14749,6 +14749,9 @@ static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
hdd_device_mode_to_string(pAdapter->device_mode),
pAdapter->device_mode);
+ if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
+ hdd_wlan_green_ap_stop_bss(pHddCtx);
+
status = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
staAdapter = pAdapterNode->pAdapter;
@@ -14962,6 +14965,10 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Reached max concurrent connections"));
return -EINVAL;
}
+
+ if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
+ hdd_wlan_green_ap_start_bss(pHddCtx);
+
if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
hdd_adapter_t *pP2pAdapter = NULL;
pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index 3ab859ebb1f1..97e3a3072411 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -1522,8 +1522,6 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa
pHostapdState->bssState = BSS_START;
- hdd_wlan_green_ap_start_bss(pHddCtx);
-
/* Set default key index */
VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
"%s: default key index %hu", __func__,
@@ -1634,8 +1632,6 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa
hdd_hostapd_channel_allow_suspend(pHostapdAdapter,
pHddApCtx->operatingChannel);
- hdd_wlan_green_ap_stop_bss(pHddCtx);
-
//Free up Channel List incase if it is set
sapCleanupChannelList(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 8b8ad2313a2c..b54d27322ca7 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -532,8 +532,7 @@ void hdd_wlan_green_ap_mc(hdd_context_t *pHddCtx,
break;
case GREEN_AP_PS_STOP_EVENT:
- if (!(hdd_get_concurrency_mode() & VOS_SAP))
- green_ap->ps_enable = 0;
+ green_ap->ps_enable = 0;
break;
case GREEN_AP_ADD_STA_EVENT:
@@ -554,14 +553,6 @@ void hdd_wlan_green_ap_mc(hdd_context_t *pHddCtx,
break;
}
- /* Confirm that power save is enabled before doing state transitions */
- if (!green_ap->ps_enable) {
- hddLog(VOS_TRACE_LEVEL_INFO, FL("Green-AP is disabled"));
- hdd_wlan_green_ap_update(pHddCtx,
- GREEN_AP_PS_IDLE_STATE, GREEN_AP_PS_WAIT_EVENT);
- goto done;
- }
-
pAdapter = hdd_get_adapter (pHddCtx, WLAN_HDD_SOFTAP );
if (pAdapter == NULL) {
@@ -569,6 +560,16 @@ void hdd_wlan_green_ap_mc(hdd_context_t *pHddCtx,
goto done;
}
+ /* Confirm that power save is enabled before doing state transitions */
+ if (!green_ap->ps_enable) {
+ hddLog(VOS_TRACE_LEVEL_INFO, FL("green ap is disabled"));
+ hdd_wlan_green_ap_update(pHddCtx,
+ GREEN_AP_PS_OFF_STATE, GREEN_AP_PS_WAIT_EVENT);
+ if (hdd_wlan_green_ap_enable(pAdapter, 0))
+ hddLog(LOGE, FL("failed to set green ap mode"));
+ goto done;
+ }
+
/* handle the green ap ps state */
switch(green_ap->ps_state) {
case GREEN_AP_PS_IDLE_STATE:
@@ -678,6 +679,65 @@ void wlan_hdd_set_egap_support(hdd_context_t *hdd_ctx, struct hdd_tgt_cfg *cfg)
}
/**
+ * hdd_wlan_is_egap_enabled() - Get Enhance Green AP feature status
+ * @fw_egap_support: flag whether firmware supports egap or not
+ * @cfg: pointer to the struct hdd_config_t
+ *
+ * Return: true if firmware, feature_flag and ini are all enabled the egap
+ */
+static bool hdd_wlan_is_egap_enabled(bool fw_egap_support, hdd_config_t *cfg)
+{
+ /* check if the firmware and ini are both enabled the egap,
+ * and also the feature_flag enable.
+ */
+ if (fw_egap_support && cfg->enable_egap &&
+ cfg->egap_feature_flag)
+ return true;
+
+ return false;
+}
+
+
+/**
+ * hdd_wlan_enable_egap() - Enable Enhance Green AP
+ * @hdd_ctx: HDD global context
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int hdd_wlan_enable_egap(struct hdd_context_s *hdd_ctx)
+{
+ hdd_config_t *cfg;
+
+ if (!hdd_ctx) {
+ hddLog(LOGE, FL("hdd context is NULL"));
+ return -EINVAL;
+ }
+
+ cfg = hdd_ctx->cfg_ini;
+
+ if (!cfg) {
+ hddLog(LOGE, FL("hdd cfg is NULL"));
+ return -EINVAL;
+ }
+
+ if (!hdd_ctx->green_ap_ctx) {
+ hddLog(LOGE, FL("green ap context is NULL"));
+ return -EINVAL;
+ }
+
+ if (!hdd_wlan_is_egap_enabled(hdd_ctx->green_ap_ctx->egap_support,
+ hdd_ctx->cfg_ini))
+ return -ENOTSUPP;
+
+ if (VOS_STATUS_SUCCESS != sme_send_egap_conf_params(cfg->enable_egap,
+ cfg->egap_inact_time,
+ cfg->egap_wait_time,
+ cfg->egap_feature_flag))
+ return -EINVAL;
+ return 0;
+}
+
+/**
* hdd_wlan_green_ap_start_bss() - Notify Green AP of Start BSS event
* @hdd_ctx: HDD global context
*
@@ -689,45 +749,24 @@ void hdd_wlan_green_ap_start_bss(struct hdd_context_s *hdd_ctx)
if (!hdd_ctx) {
hddLog(LOGE, FL("hdd context is NULL"));
- goto exit;
+ return;
}
cfg = hdd_ctx->cfg_ini;
if (!cfg) {
hddLog(LOGE, FL("hdd cfg is NULL"));
- goto exit;
+ return;
}
if (!hdd_ctx->green_ap_ctx) {
- hddLog(LOGE,
- FL("Green AP is not enabled. green_ap_ctx = NULL"));
- goto exit;
+ hddLog(LOGE, FL("green ap context is NULL"));
+ return;
}
- /* check if the firmware and ini are both enabled the egap,
- * and also the feature_flag enable, then we enable the egap
- */
- if (hdd_ctx->green_ap_ctx->egap_support && cfg->enable_egap &&
- cfg->egap_feature_flag) {
- hddLog(LOG1,
- FL("Set EGAP - enabled: %d, flag: %x, inact_time: %d, wait_time: %d"),
- cfg->enable_egap,
- cfg->egap_feature_flag,
- cfg->egap_inact_time,
- cfg->egap_wait_time);
- if (!sme_send_egap_conf_params(cfg->enable_egap,
- cfg->egap_inact_time,
- cfg->egap_wait_time,
- cfg->egap_feature_flag)) {
- /* EGAP is enabled, disable host GAP */
- hdd_wlan_green_ap_mc(hdd_ctx, GREEN_AP_PS_STOP_EVENT);
- goto exit;
- }
- /* fall through, if send_egap_conf_params() failed,
- * then check host GAP and enable it accordingly
- */
- }
+ if (hdd_wlan_is_egap_enabled(hdd_ctx->green_ap_ctx->egap_support,
+ hdd_ctx->cfg_ini))
+ return;
if ((hdd_ctx->concurrency_mode & VOS_SAP) &&
!(hdd_ctx->concurrency_mode & (~VOS_SAP)) &&
@@ -744,8 +783,6 @@ void hdd_wlan_green_ap_start_bss(struct hdd_context_s *hdd_ctx)
(VOS_STA & hdd_ctx->concurrency_mode),
cfg->enable2x2, cfg->enableGreenAP);
}
-exit:
- return;
}
/**
@@ -756,7 +793,30 @@ exit:
*/
void hdd_wlan_green_ap_stop_bss(struct hdd_context_s *hdd_ctx)
{
- hdd_wlan_green_ap_mc(hdd_ctx, GREEN_AP_PS_STOP_EVENT);
+ if (!hdd_ctx) {
+ hddLog(LOGE, FL("hdd context is NULL"));
+ return;
+ }
+
+ if (!hdd_ctx->cfg_ini) {
+ hddLog(LOGE, FL("hdd cfg is NULL"));
+ return;
+ }
+
+ if (!hdd_ctx->green_ap_ctx) {
+ hddLog(LOGE, FL("green ap context is NULL"));
+ return;
+ }
+
+ if (hdd_wlan_is_egap_enabled(hdd_ctx->green_ap_ctx->egap_support,
+ hdd_ctx->cfg_ini))
+ return;
+
+ /* For AP+AP mode, only trigger GREEN_AP_PS_STOP_EVENT, when the
+ * last AP stops.
+ */
+ if (1 == (hdd_ctx->no_of_open_sessions[VOS_STA_SAP_MODE]))
+ hdd_wlan_green_ap_mc(hdd_ctx, GREEN_AP_PS_STOP_EVENT);
}
/**
@@ -767,6 +827,25 @@ void hdd_wlan_green_ap_stop_bss(struct hdd_context_s *hdd_ctx)
*/
void hdd_wlan_green_ap_add_sta(struct hdd_context_s *hdd_ctx)
{
+ if (!hdd_ctx) {
+ hddLog(LOGE, FL("hdd context is NULL"));
+ return;
+ }
+
+ if (!hdd_ctx->cfg_ini) {
+ hddLog(LOGE, FL("hdd cfg is NULL"));
+ return;
+ }
+
+ if (!hdd_ctx->green_ap_ctx) {
+ hddLog(LOGE, FL("green ap context is NULL"));
+ return;
+ }
+
+ if (hdd_wlan_is_egap_enabled(hdd_ctx->green_ap_ctx->egap_support,
+ hdd_ctx->cfg_ini))
+ return;
+
hdd_wlan_green_ap_mc(hdd_ctx, GREEN_AP_ADD_STA_EVENT);
}
@@ -778,6 +857,25 @@ void hdd_wlan_green_ap_add_sta(struct hdd_context_s *hdd_ctx)
*/
void hdd_wlan_green_ap_del_sta(struct hdd_context_s *hdd_ctx)
{
+ if (!hdd_ctx) {
+ hddLog(LOGE, FL("hdd context is NULL"));
+ return;
+ }
+
+ if (!hdd_ctx->cfg_ini) {
+ hddLog(LOGE, FL("hdd cfg is NULL"));
+ return;
+ }
+
+ if (!hdd_ctx->green_ap_ctx) {
+ hddLog(LOGE, FL("green ap context is NULL"));
+ return;
+ }
+
+ if (hdd_wlan_is_egap_enabled(hdd_ctx->green_ap_ctx->egap_support,
+ hdd_ctx->cfg_ini))
+ return;
+
hdd_wlan_green_ap_mc(hdd_ctx, GREEN_AP_DEL_STA_EVENT);
}
@@ -15709,6 +15807,9 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc)
set_value, PDEV_CMD);
}
+ if (hdd_wlan_enable_egap(pHddCtx))
+ hddLog(LOGE, FL("enhance green ap is not enabled"));
+
wlan_comp.status = 0;
complete(&wlan_comp.wlan_start_comp);
goto success;