summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;