| /* |
| * Copyright (c) 2017-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: This file contains green ap north bound interface definitions |
| */ |
| |
| #include <qdf_status.h> |
| #include <wlan_green_ap_ucfg_api.h> |
| #include <../../core/src/wlan_green_ap_main_i.h> |
| |
| QDF_STATUS ucfg_green_ap_update_user_config( |
| struct wlan_objmgr_pdev *pdev, |
| struct green_ap_user_cfg *green_ap_cfg) |
| { |
| struct wlan_pdev_green_ap_ctx *green_ap_ctx; |
| struct wlan_green_ap_egap_params *egap_params; |
| |
| 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; |
| } |
| |
| qdf_spin_lock_bh(&green_ap_ctx->lock); |
| egap_params = &green_ap_ctx->egap_params; |
| |
| egap_params->host_enable_egap = green_ap_cfg->host_enable_egap; |
| egap_params->egap_inactivity_time = green_ap_cfg->egap_inactivity_time; |
| egap_params->egap_wait_time = green_ap_cfg->egap_wait_time; |
| egap_params->egap_feature_flags = green_ap_cfg->egap_feature_flags; |
| qdf_spin_unlock_bh(&green_ap_ctx->lock); |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS ucfg_green_ap_enable_egap(struct wlan_objmgr_pdev *pdev) |
| { |
| struct wlan_pdev_green_ap_ctx *green_ap_ctx; |
| struct wlan_lmac_if_green_ap_tx_ops *green_ap_tx_ops; |
| |
| 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_tx_ops = wlan_psoc_get_green_ap_tx_ops(green_ap_ctx); |
| if (!green_ap_tx_ops) { |
| green_ap_err("green ap tx ops obtained are NULL"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| if (!green_ap_tx_ops->enable_egap) { |
| green_ap_err("tx op for sending enbale/disable green ap is NULL"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| return green_ap_tx_ops->enable_egap(pdev, &green_ap_ctx->egap_params); |
| } |
| |
| QDF_STATUS ucfg_green_ap_target_config(struct wlan_objmgr_pdev *pdev, |
| bool fw_egap_support) |
| { |
| 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; |
| } |
| |
| qdf_spin_lock_bh(&green_ap_ctx->lock); |
| green_ap_ctx->egap_params.fw_egap_support = fw_egap_support; |
| qdf_spin_unlock_bh(&green_ap_ctx->lock); |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS ucfg_green_ap_set_ps_config(struct wlan_objmgr_pdev *pdev, |
| uint8_t value) |
| { |
| 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; |
| } |
| |
| qdf_spin_lock_bh(&green_ap_ctx->lock); |
| if (wlan_is_egap_enabled(green_ap_ctx)) { |
| qdf_spin_unlock_bh(&green_ap_ctx->lock); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| green_ap_ctx->ps_enable = value; |
| qdf_spin_unlock_bh(&green_ap_ctx->lock); |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS ucfg_green_ap_get_ps_config(struct wlan_objmgr_pdev *pdev, |
| uint8_t *ps_enable) |
| { |
| 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; |
| } |
| |
| qdf_spin_lock_bh(&green_ap_ctx->lock); |
| if (wlan_is_egap_enabled(green_ap_ctx)) { |
| qdf_spin_unlock_bh(&green_ap_ctx->lock); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| *ps_enable = green_ap_ctx->ps_enable; |
| qdf_spin_unlock_bh(&green_ap_ctx->lock); |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS ucfg_green_ap_set_transition_time(struct wlan_objmgr_pdev *pdev, |
| uint32_t val) |
| { |
| 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; |
| } |
| |
| qdf_spin_lock_bh(&green_ap_ctx->lock); |
| if (wlan_is_egap_enabled(green_ap_ctx)) { |
| qdf_spin_unlock_bh(&green_ap_ctx->lock); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| green_ap_ctx->ps_trans_time = val; |
| qdf_spin_unlock_bh(&green_ap_ctx->lock); |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS ucfg_green_ap_get_transition_time(struct wlan_objmgr_pdev *pdev, |
| uint32_t *ps_trans_time) |
| { |
| 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; |
| } |
| |
| qdf_spin_lock_bh(&green_ap_ctx->lock); |
| if (wlan_is_egap_enabled(green_ap_ctx)) { |
| qdf_spin_unlock_bh(&green_ap_ctx->lock); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| *ps_trans_time = green_ap_ctx->ps_trans_time; |
| qdf_spin_unlock_bh(&green_ap_ctx->lock); |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS ucfg_green_ap_config(struct wlan_objmgr_pdev *pdev, uint8_t val) |
| { |
| |
| uint8_t flag; |
| |
| if (wlan_green_ap_get_capab(pdev) == QDF_STATUS_E_NOSUPPORT) { |
| green_ap_err("GreenAP not supported on radio\n"); |
| return QDF_STATUS_E_NOSUPPORT; |
| } |
| |
| if (val) { |
| struct wlan_pdev_green_ap_ctx *green_ap_ctx; |
| wlan_objmgr_pdev_iterate_obj_list(pdev, |
| WLAN_VDEV_OP, |
| wlan_green_ap_check_mode, |
| &flag, 0, WLAN_OBJMGR_ID); |
| if (flag == 1) { |
| green_ap_err("Radio not in AP mode." |
| "Feature not supported"); |
| return QDF_STATUS_E_NOSUPPORT; |
| } |
| |
| 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_NOSUPPORT; |
| } |
| |
| ucfg_green_ap_set_ps_config(pdev, val); |
| |
| if (wlan_util_is_vap_active(pdev) == QDF_STATUS_SUCCESS) |
| wlan_green_ap_start(pdev); |
| } else { |
| wlan_green_ap_stop(pdev); |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| void ucfg_green_ap_enable_debug_prints(struct wlan_objmgr_pdev *pdev, |
| uint32_t val) |
| { |
| struct wlan_pdev_green_ap_ctx *green_ap_ctx; |
| |
| 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; |
| } |
| |
| green_ap_ctx->dbg_enable = val; |
| } |
| |
| bool ucfg_green_ap_get_debug_prints(struct wlan_objmgr_pdev *pdev) |
| { |
| struct wlan_pdev_green_ap_ctx *green_ap_ctx; |
| |
| 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 false; |
| } |
| |
| return green_ap_ctx->dbg_enable; |
| } |
| |