1 /* 2 * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: This file contains green ap north bound interface definitions 22 */ 23 24 #include <qdf_status.h> 25 #include <wlan_green_ap_ucfg_api.h> 26 #include <../../core/src/wlan_green_ap_main_i.h> 27 28 QDF_STATUS ucfg_green_ap_enable_egap(struct wlan_objmgr_pdev *pdev) 29 { 30 struct wlan_pdev_green_ap_ctx *green_ap_ctx; 31 struct wlan_lmac_if_green_ap_tx_ops *green_ap_tx_ops; 32 33 if (!pdev) { 34 green_ap_err("pdev context passed is NULL"); 35 return QDF_STATUS_E_INVAL; 36 } 37 38 green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj( 39 pdev, WLAN_UMAC_COMP_GREEN_AP); 40 if (!green_ap_ctx) { 41 green_ap_err("green ap context obtained is NULL"); 42 return QDF_STATUS_E_FAILURE; 43 } 44 45 green_ap_tx_ops = wlan_psoc_get_green_ap_tx_ops(green_ap_ctx); 46 if (!green_ap_tx_ops) { 47 green_ap_err("green ap tx ops obtained are NULL"); 48 return QDF_STATUS_E_FAILURE; 49 } 50 51 if (!green_ap_tx_ops->enable_egap) { 52 green_ap_err("tx op for sending enable/disable green ap is NULL"); 53 return QDF_STATUS_E_FAILURE; 54 } 55 56 return green_ap_tx_ops->enable_egap(pdev, &green_ap_ctx->egap_params); 57 } 58 59 QDF_STATUS ucfg_green_ap_set_ps_config(struct wlan_objmgr_pdev *pdev, 60 uint8_t value) 61 { 62 struct wlan_pdev_green_ap_ctx *green_ap_ctx; 63 64 if (!pdev) { 65 green_ap_err("pdev context passed is NULL"); 66 return QDF_STATUS_E_INVAL; 67 } 68 69 green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj( 70 pdev, WLAN_UMAC_COMP_GREEN_AP); 71 if (!green_ap_ctx) { 72 green_ap_err("green ap context obtained is NULL"); 73 return QDF_STATUS_E_FAILURE; 74 } 75 76 qdf_spin_lock_bh(&green_ap_ctx->lock); 77 if (wlan_is_egap_enabled(green_ap_ctx)) { 78 qdf_spin_unlock_bh(&green_ap_ctx->lock); 79 return QDF_STATUS_SUCCESS; 80 } 81 82 green_ap_ctx->ps_enable = value; 83 if (value == WLAN_GREEN_AP_MODE_NUM_STREAM) 84 green_ap_ctx->ps_mode = WLAN_GREEN_AP_MODE_NUM_STREAM; 85 else 86 green_ap_ctx->ps_mode = WLAN_GREEN_AP_MODE_NO_STA; 87 88 qdf_spin_unlock_bh(&green_ap_ctx->lock); 89 90 return QDF_STATUS_SUCCESS; 91 } 92 93 QDF_STATUS ucfg_green_ap_get_ps_config(struct wlan_objmgr_pdev *pdev, 94 uint8_t *ps_enable) 95 { 96 struct wlan_pdev_green_ap_ctx *green_ap_ctx; 97 98 if (!pdev) { 99 green_ap_err("pdev context passed is NULL"); 100 return QDF_STATUS_E_INVAL; 101 } 102 103 green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj( 104 pdev, WLAN_UMAC_COMP_GREEN_AP); 105 106 if (!green_ap_ctx) { 107 green_ap_err("green ap context obtained is NULL"); 108 return QDF_STATUS_E_FAILURE; 109 } 110 111 qdf_spin_lock_bh(&green_ap_ctx->lock); 112 if (wlan_is_egap_enabled(green_ap_ctx)) { 113 qdf_spin_unlock_bh(&green_ap_ctx->lock); 114 return QDF_STATUS_SUCCESS; 115 } 116 117 *ps_enable = green_ap_ctx->ps_enable; 118 qdf_spin_unlock_bh(&green_ap_ctx->lock); 119 120 return QDF_STATUS_SUCCESS; 121 } 122 123 QDF_STATUS ucfg_green_ap_set_transition_time(struct wlan_objmgr_pdev *pdev, 124 uint32_t val) 125 { 126 struct wlan_pdev_green_ap_ctx *green_ap_ctx; 127 128 if (!pdev) { 129 green_ap_err("pdev context passed is NULL"); 130 return QDF_STATUS_E_INVAL; 131 } 132 133 green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj( 134 pdev, WLAN_UMAC_COMP_GREEN_AP); 135 136 if (!green_ap_ctx) { 137 green_ap_err("green ap context obtained is NULL"); 138 return QDF_STATUS_E_FAILURE; 139 } 140 141 qdf_spin_lock_bh(&green_ap_ctx->lock); 142 if (wlan_is_egap_enabled(green_ap_ctx)) { 143 qdf_spin_unlock_bh(&green_ap_ctx->lock); 144 return QDF_STATUS_SUCCESS; 145 } 146 147 green_ap_ctx->ps_trans_time = val; 148 qdf_spin_unlock_bh(&green_ap_ctx->lock); 149 150 return QDF_STATUS_SUCCESS; 151 } 152 153 QDF_STATUS ucfg_green_ap_get_transition_time(struct wlan_objmgr_pdev *pdev, 154 uint32_t *ps_trans_time) 155 { 156 struct wlan_pdev_green_ap_ctx *green_ap_ctx; 157 158 if (!pdev) { 159 green_ap_err("pdev context passed is NULL"); 160 return QDF_STATUS_E_INVAL; 161 } 162 163 green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj( 164 pdev, WLAN_UMAC_COMP_GREEN_AP); 165 166 if (!green_ap_ctx) { 167 green_ap_err("green ap context obtained is NULL"); 168 return QDF_STATUS_E_FAILURE; 169 } 170 171 qdf_spin_lock_bh(&green_ap_ctx->lock); 172 if (wlan_is_egap_enabled(green_ap_ctx)) { 173 qdf_spin_unlock_bh(&green_ap_ctx->lock); 174 return QDF_STATUS_SUCCESS; 175 } 176 177 *ps_trans_time = green_ap_ctx->ps_trans_time; 178 qdf_spin_unlock_bh(&green_ap_ctx->lock); 179 180 return QDF_STATUS_SUCCESS; 181 } 182 183 QDF_STATUS ucfg_green_ap_config(struct wlan_objmgr_pdev *pdev, uint8_t val) 184 { 185 186 uint8_t flag; 187 188 if (wlan_green_ap_get_capab(pdev) == QDF_STATUS_E_NOSUPPORT) { 189 green_ap_err("GreenAP not supported on radio\n"); 190 return QDF_STATUS_E_NOSUPPORT; 191 } 192 193 if (val) { 194 struct wlan_pdev_green_ap_ctx *green_ap_ctx; 195 196 wlan_objmgr_pdev_iterate_obj_list(pdev, 197 WLAN_VDEV_OP, 198 wlan_green_ap_check_mode, 199 &flag, 0, WLAN_GREEN_AP_ID); 200 if (flag == 1) { 201 green_ap_err("Radio not in AP/RE mode." 202 "Feature not supported"); 203 return QDF_STATUS_E_NOSUPPORT; 204 } 205 206 green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(pdev, 207 WLAN_UMAC_COMP_GREEN_AP); 208 209 if (!green_ap_ctx) { 210 green_ap_err("green ap context obtained is NULL"); 211 return QDF_STATUS_E_NOSUPPORT; 212 } 213 214 ucfg_green_ap_set_ps_config(pdev, val); 215 216 if (wlan_util_is_vdev_active(pdev, WLAN_GREEN_AP_ID) == 217 QDF_STATUS_SUCCESS) 218 wlan_green_ap_start(pdev); 219 } else { 220 wlan_green_ap_stop(pdev); 221 } 222 223 return QDF_STATUS_SUCCESS; 224 } 225 226 void ucfg_green_ap_enable_debug_prints(struct wlan_objmgr_pdev *pdev, 227 uint32_t val) 228 { 229 struct wlan_pdev_green_ap_ctx *green_ap_ctx; 230 231 green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj( 232 pdev, WLAN_UMAC_COMP_GREEN_AP); 233 234 if (!green_ap_ctx) { 235 green_ap_err("green ap context obtained is NULL"); 236 return; 237 } 238 239 green_ap_ctx->dbg_enable = val; 240 } 241 242 bool ucfg_green_ap_get_debug_prints(struct wlan_objmgr_pdev *pdev) 243 { 244 struct wlan_pdev_green_ap_ctx *green_ap_ctx; 245 246 green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj( 247 pdev, WLAN_UMAC_COMP_GREEN_AP); 248 249 if (!green_ap_ctx) { 250 green_ap_err("green ap context obtained is NULL"); 251 return false; 252 } 253 254 return green_ap_ctx->dbg_enable; 255 } 256 257