From aeb2e4b2addd52bb698e418c62e5d850fc27900f Mon Sep 17 00:00:00 2001 From: Aakanksha Doda Date: Wed, 15 May 2019 13:38:11 +0530 Subject: [PATCH] qcacmn: Antenna power save when 1x1 client is connected Enable Green AP when only 1x1 clients are connected. Change-Id: I5dd180bb56eaba337454dbe1d3a7f8135be9102f --- umac/green_ap/core/src/wlan_green_ap_main.c | 35 +++++++++-- umac/green_ap/core/src/wlan_green_ap_main_i.h | 10 ++- .../dispatcher/inc/wlan_green_ap_api.h | 26 +++++++- .../dispatcher/src/wlan_green_ap_api.c | 62 +++++++++++++++++++ .../dispatcher/src/wlan_green_ap_ucfg_api.c | 7 ++- 5 files changed, 131 insertions(+), 9 deletions(-) diff --git a/umac/green_ap/core/src/wlan_green_ap_main.c b/umac/green_ap/core/src/wlan_green_ap_main.c index 492778aff7fa..f0fc6b768d4c 100644 --- a/umac/green_ap/core/src/wlan_green_ap_main.c +++ b/umac/green_ap/core/src/wlan_green_ap_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 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 @@ -183,6 +183,15 @@ QDF_STATUS wlan_green_ap_state_mc(struct wlan_pdev_green_ap_ctx *green_ap_ctx, green_ap_ctx->num_nodes--; break; + case WLAN_GREEN_AP_ADD_MULTISTREAM_STA_EVENT: + green_ap_ctx->num_nodes_multistream++; + break; + + case WLAN_GREEN_AP_DEL_MULTISTREAM_STA_EVENT: + if (green_ap_ctx->num_nodes_multistream) + green_ap_ctx->num_nodes_multistream--; + break; + case WLAN_GREEN_AP_PS_START_EVENT: case WLAN_GREEN_AP_PS_STOP_EVENT: case WLAN_GREEN_AP_PS_ON_EVENT: @@ -216,8 +225,13 @@ QDF_STATUS wlan_green_ap_state_mc(struct wlan_pdev_green_ap_ctx *green_ap_ctx, /* handle the green ap ps state */ switch (green_ap_ctx->ps_state) { case WLAN_GREEN_AP_PS_IDLE_STATE: - if (green_ap_ctx->num_nodes) { - /* Active nodes present, Switchoff the power save */ + if ((green_ap_ctx->num_nodes && + green_ap_ctx->ps_mode == WLAN_GREEN_AP_MODE_NO_STA) || + (green_ap_ctx->num_nodes_multistream && + green_ap_ctx->ps_mode == WLAN_GREEN_AP_MODE_NUM_STREAM)) { + /* + * Multistream nodes present, switchoff the power save + */ green_ap_info("Transition to OFF from IDLE"); wlan_green_ap_ps_event_state_update( green_ap_ctx, @@ -236,7 +250,10 @@ QDF_STATUS wlan_green_ap_state_mc(struct wlan_pdev_green_ap_ctx *green_ap_ctx, break; case WLAN_GREEN_AP_PS_OFF_STATE: - if (!green_ap_ctx->num_nodes) { + if ((!green_ap_ctx->num_nodes && + green_ap_ctx->ps_mode == WLAN_GREEN_AP_MODE_NO_STA) || + (!green_ap_ctx->num_nodes_multistream && + green_ap_ctx->ps_mode == WLAN_GREEN_AP_MODE_NUM_STREAM)) { green_ap_info("Transition to WAIT from OFF"); wlan_green_ap_ps_event_state_update( green_ap_ctx, @@ -248,7 +265,10 @@ QDF_STATUS wlan_green_ap_state_mc(struct wlan_pdev_green_ap_ctx *green_ap_ctx, break; case WLAN_GREEN_AP_PS_WAIT_STATE: - if (!green_ap_ctx->num_nodes) { + if ((!green_ap_ctx->num_nodes && + green_ap_ctx->ps_mode == WLAN_GREEN_AP_MODE_NO_STA) || + (!green_ap_ctx->num_nodes_multistream && + green_ap_ctx->ps_mode == WLAN_GREEN_AP_MODE_NUM_STREAM)) { if ((channel == 0) || (channel_flags == 0)) { /* * Stay in the current state and restart the @@ -282,7 +302,10 @@ QDF_STATUS wlan_green_ap_state_mc(struct wlan_pdev_green_ap_ctx *green_ap_ctx, break; case WLAN_GREEN_AP_PS_ON_STATE: - if (green_ap_ctx->num_nodes) { + if ((green_ap_ctx->num_nodes && + green_ap_ctx->ps_mode == WLAN_GREEN_AP_MODE_NO_STA) || + (green_ap_ctx->num_nodes_multistream && + green_ap_ctx->ps_mode == WLAN_GREEN_AP_MODE_NUM_STREAM)) { qdf_timer_stop(&green_ap_ctx->ps_timer); if (green_ap_tx_ops->ps_on_off_send( green_ap_ctx->pdev, false, pdev_id)) { diff --git a/umac/green_ap/core/src/wlan_green_ap_main_i.h b/umac/green_ap/core/src/wlan_green_ap_main_i.h index b29205e4c88b..664531d2a5f9 100644 --- a/umac/green_ap/core/src/wlan_green_ap_main_i.h +++ b/umac/green_ap/core/src/wlan_green_ap_main_i.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 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 @@ -83,6 +83,8 @@ enum wlan_green_ap_ps_state { * @WLAN_GREEN_AP_PS_STOP_EVENT - Stop * @WLAN_GREEN_AP_ADD_STA_EVENT - Sta assoc * @WLAN_GREEN_AP_DEL_STA_EVENT - Sta disassoc + * @WLAN_GREEN_AP_ADD_MULTISTREAM_STA_EVENT - Multistream sta assoc + * @WLAN_GREEN_AP_DEL_MULTISTREAM_STA_EVENT - Multistream sta disassoc * @WLAN_GREEN_AP_PS_ON_EVENT - PS on * @WLAN_GREEN_AP_PS_OFF_EVENT - PS off */ @@ -91,6 +93,8 @@ enum wlan_green_ap_ps_event { WLAN_GREEN_AP_PS_STOP_EVENT, WLAN_GREEN_AP_ADD_STA_EVENT, WLAN_GREEN_AP_DEL_STA_EVENT, + WLAN_GREEN_AP_ADD_MULTISTREAM_STA_EVENT, + WLAN_GREEN_AP_DEL_MULTISTREAM_STA_EVENT, WLAN_GREEN_AP_PS_ON_EVENT, WLAN_GREEN_AP_PS_WAIT_EVENT, }; @@ -99,9 +103,11 @@ enum wlan_green_ap_ps_event { * struct wlan_pdev_green_ap_ctx - green ap context * @pdev - Pdev pointer * @ps_enable - Enable PS + * @ps_mode - No sta or Multistream sta mode * @ps_on_time - PS on time, once enabled * @ps_trans_time - PS transition time * @num_nodes - Number of nodes associated to radio + * @num_nodes_multistream - Multistream nodes associated to radio * @ps_state - PS state * @ps_event - PS event * @ps_timer - Timer @@ -111,9 +117,11 @@ enum wlan_green_ap_ps_event { struct wlan_pdev_green_ap_ctx { struct wlan_objmgr_pdev *pdev; uint8_t ps_enable; + uint8_t ps_mode; uint8_t ps_on_time; uint32_t ps_trans_time; uint32_t num_nodes; + uint32_t num_nodes_multistream; enum wlan_green_ap_ps_state ps_state; enum wlan_green_ap_ps_event ps_event; qdf_timer_t ps_timer; diff --git a/umac/green_ap/dispatcher/inc/wlan_green_ap_api.h b/umac/green_ap/dispatcher/inc/wlan_green_ap_api.h index a4877bd53a1a..70eb59520871 100644 --- a/umac/green_ap/dispatcher/inc/wlan_green_ap_api.h +++ b/umac/green_ap/dispatcher/inc/wlan_green_ap_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 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 @@ -27,6 +27,10 @@ #include #include +/* Green ap mode of operation */ +#define WLAN_GREEN_AP_MODE_NO_STA 1 /* PS if no sta connected */ +#define WLAN_GREEN_AP_MODE_NUM_STREAM 2 /* PS if 1x1 clients only connected */ + /** * struct wlan_green_ap_egap_params - enhance green ap params * @fw_egap_support: fw enhance green ap support @@ -109,6 +113,16 @@ QDF_STATUS wlan_green_ap_pdev_open(struct wlan_objmgr_pdev *pdev); */ QDF_STATUS wlan_green_ap_add_sta(struct wlan_objmgr_pdev *pdev); +/** + * wlan_green_ap_add_multistream_sta() - On association + * @pdev: pdev pointer + * + * Call this function when new multistream node is associated + * + * Return: Success or Failure + */ +QDF_STATUS wlan_green_ap_add_multistream_sta(struct wlan_objmgr_pdev *pdev); + /** * wlan_green_ap_del_sta() - On disassociation * @pdev: pdev pointer @@ -119,6 +133,16 @@ QDF_STATUS wlan_green_ap_add_sta(struct wlan_objmgr_pdev *pdev); */ QDF_STATUS wlan_green_ap_del_sta(struct wlan_objmgr_pdev *pdev); +/** + * wlan_green_ap_del_multistream_sta() - On disassociation + * @pdev: pdev pointer + * + * Call this function when new multistream node is disassociated + * + * Return: Success or Failure + */ +QDF_STATUS wlan_green_ap_del_multistream_sta(struct wlan_objmgr_pdev *pdev); + /** * wlan_green_ap_is_ps_enabled() - is power save enabled * @pdev: pdev pointer diff --git a/umac/green_ap/dispatcher/src/wlan_green_ap_api.c b/umac/green_ap/dispatcher/src/wlan_green_ap_api.c index e8cb23645d60..70cd45b0b1d7 100644 --- a/umac/green_ap/dispatcher/src/wlan_green_ap_api.c +++ b/umac/green_ap/dispatcher/src/wlan_green_ap_api.c @@ -80,7 +80,9 @@ static QDF_STATUS wlan_green_ap_pdev_obj_create_notification( green_ap_ctx->ps_state = WLAN_GREEN_AP_PS_IDLE_STATE; green_ap_ctx->ps_event = WLAN_GREEN_AP_PS_WAIT_EVENT; + green_ap_ctx->ps_mode = WLAN_GREEN_AP_MODE_NO_STA; green_ap_ctx->num_nodes = 0; + green_ap_ctx->num_nodes_multistream = 0; green_ap_ctx->ps_on_time = WLAN_GREEN_AP_PS_ON_TIME; green_ap_ctx->ps_trans_time = WLAN_GREEN_AP_PS_TRANS_TIME; @@ -361,6 +363,36 @@ QDF_STATUS wlan_green_ap_add_sta(struct wlan_objmgr_pdev *pdev) WLAN_GREEN_AP_ADD_STA_EVENT); } +QDF_STATUS wlan_green_ap_add_multistream_sta(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_pdev_green_ap_ctx *green_ap_ctx; + + if (!pdev) { + green_ap_err("pdev context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj( + pdev, WLAN_UMAC_COMP_GREEN_AP); + if (!green_ap_ctx) { + green_ap_err("green ap context obtained is NULL"); + return QDF_STATUS_E_FAILURE; + } + + green_ap_debug("Green AP add multistream sta received"); + + qdf_spin_lock_bh(&green_ap_ctx->lock); + if (wlan_is_egap_enabled(green_ap_ctx)) { + qdf_spin_unlock_bh(&green_ap_ctx->lock); + green_ap_debug("enhanced green ap support is enabled"); + return QDF_STATUS_SUCCESS; + } + qdf_spin_unlock_bh(&green_ap_ctx->lock); + + return wlan_green_ap_state_mc(green_ap_ctx, + WLAN_GREEN_AP_ADD_MULTISTREAM_STA_EVENT); +} + QDF_STATUS wlan_green_ap_del_sta(struct wlan_objmgr_pdev *pdev) { struct wlan_pdev_green_ap_ctx *green_ap_ctx; @@ -391,6 +423,36 @@ QDF_STATUS wlan_green_ap_del_sta(struct wlan_objmgr_pdev *pdev) WLAN_GREEN_AP_DEL_STA_EVENT); } +QDF_STATUS wlan_green_ap_del_multistream_sta(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_pdev_green_ap_ctx *green_ap_ctx; + + if (!pdev) { + green_ap_err("pdev context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj( + pdev, WLAN_UMAC_COMP_GREEN_AP); + if (!green_ap_ctx) { + green_ap_err("green ap context obtained is NULL"); + return QDF_STATUS_E_FAILURE; + } + + green_ap_debug("Green AP del multistream sta received"); + + qdf_spin_lock_bh(&green_ap_ctx->lock); + if (wlan_is_egap_enabled(green_ap_ctx)) { + qdf_spin_unlock_bh(&green_ap_ctx->lock); + green_ap_info("enhanced green ap support is enabled"); + return QDF_STATUS_SUCCESS; + } + qdf_spin_unlock_bh(&green_ap_ctx->lock); + + return wlan_green_ap_state_mc(green_ap_ctx, + WLAN_GREEN_AP_DEL_MULTISTREAM_STA_EVENT); +} + bool wlan_green_ap_is_ps_enabled(struct wlan_objmgr_pdev *pdev) { struct wlan_pdev_green_ap_ctx *green_ap_ctx; diff --git a/umac/green_ap/dispatcher/src/wlan_green_ap_ucfg_api.c b/umac/green_ap/dispatcher/src/wlan_green_ap_ucfg_api.c index 1885fa089c1b..5d84587eb11f 100644 --- a/umac/green_ap/dispatcher/src/wlan_green_ap_ucfg_api.c +++ b/umac/green_ap/dispatcher/src/wlan_green_ap_ucfg_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 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 @@ -79,6 +79,11 @@ QDF_STATUS ucfg_green_ap_set_ps_config(struct wlan_objmgr_pdev *pdev, } green_ap_ctx->ps_enable = value; + if (value == WLAN_GREEN_AP_MODE_NUM_STREAM) + green_ap_ctx->ps_mode = WLAN_GREEN_AP_MODE_NUM_STREAM; + else + green_ap_ctx->ps_mode = WLAN_GREEN_AP_MODE_NO_STA; + qdf_spin_unlock_bh(&green_ap_ctx->lock); return QDF_STATUS_SUCCESS;