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 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 94 #define MAX_COOKIE_ID 256 95 96 QDF_STATUS ucfg_green_ap_ll_ps(struct wlan_objmgr_pdev *pdev, 97 struct wlan_objmgr_vdev *vdev, 98 enum wlan_green_ap_ll_ps_state state, 99 uint32_t bcn_interval, 100 uint64_t *cookie_id) 101 { 102 struct wlan_pdev_green_ap_ctx *green_ap_ctx; 103 struct wlan_lmac_if_green_ap_tx_ops *green_ap_tx_ops; 104 struct green_ap_ll_ps_cmd_param green_ap_ll_ps_params; 105 106 if (!pdev) { 107 green_ap_err("pdev context passed is NULL"); 108 return QDF_STATUS_E_INVAL; 109 } 110 111 green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj( 112 pdev, WLAN_UMAC_COMP_GREEN_AP); 113 if (!green_ap_ctx) { 114 green_ap_err("green ap context obtained is NULL"); 115 return QDF_STATUS_E_FAILURE; 116 } 117 118 green_ap_tx_ops = wlan_psoc_get_green_ap_tx_ops(green_ap_ctx); 119 if (!green_ap_tx_ops) { 120 green_ap_err("green ap tx ops obtained are NULL"); 121 return QDF_STATUS_E_FAILURE; 122 } 123 124 if (!green_ap_tx_ops->ll_ps) { 125 green_ap_err("tx op for sending green ap ll pwr save is NULL"); 126 return QDF_STATUS_E_FAILURE; 127 } 128 129 green_ap_ctx->vdev = vdev; 130 green_ap_ll_ps_params.state = state; 131 green_ap_ll_ps_params.bcn_interval = bcn_interval; 132 133 if (state) 134 green_ap_ll_ps_params.bcn_interval *= 135 green_ap_ctx->bcn_mult; 136 137 green_ap_ll_ps_params.cookie = 138 wlan_green_ap_get_cookie_id( 139 green_ap_ctx, 140 (enum wlan_green_ap_ll_ps_state)state); 141 142 *cookie_id = green_ap_ll_ps_params.cookie; 143 144 return green_ap_tx_ops->ll_ps(vdev, &green_ap_ll_ps_params); 145 } 146 #endif 147 148 QDF_STATUS ucfg_green_ap_get_ps_config(struct wlan_objmgr_pdev *pdev, 149 uint8_t *ps_enable) 150 { 151 struct wlan_pdev_green_ap_ctx *green_ap_ctx; 152 153 if (!pdev) { 154 green_ap_err("pdev context passed is NULL"); 155 return QDF_STATUS_E_INVAL; 156 } 157 158 green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj( 159 pdev, WLAN_UMAC_COMP_GREEN_AP); 160 161 if (!green_ap_ctx) { 162 green_ap_err("green ap context obtained is NULL"); 163 return QDF_STATUS_E_FAILURE; 164 } 165 166 qdf_spin_lock_bh(&green_ap_ctx->lock); 167 if (wlan_is_egap_enabled(green_ap_ctx)) { 168 qdf_spin_unlock_bh(&green_ap_ctx->lock); 169 return QDF_STATUS_SUCCESS; 170 } 171 172 *ps_enable = green_ap_ctx->ps_enable; 173 qdf_spin_unlock_bh(&green_ap_ctx->lock); 174 175 return QDF_STATUS_SUCCESS; 176 } 177 178 QDF_STATUS ucfg_green_ap_set_transition_time(struct wlan_objmgr_pdev *pdev, 179 uint32_t val) 180 { 181 struct wlan_pdev_green_ap_ctx *green_ap_ctx; 182 183 if (!pdev) { 184 green_ap_err("pdev context passed is NULL"); 185 return QDF_STATUS_E_INVAL; 186 } 187 188 green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj( 189 pdev, WLAN_UMAC_COMP_GREEN_AP); 190 191 if (!green_ap_ctx) { 192 green_ap_err("green ap context obtained is NULL"); 193 return QDF_STATUS_E_FAILURE; 194 } 195 196 qdf_spin_lock_bh(&green_ap_ctx->lock); 197 if (wlan_is_egap_enabled(green_ap_ctx)) { 198 qdf_spin_unlock_bh(&green_ap_ctx->lock); 199 return QDF_STATUS_SUCCESS; 200 } 201 202 green_ap_ctx->ps_trans_time = val; 203 qdf_spin_unlock_bh(&green_ap_ctx->lock); 204 205 return QDF_STATUS_SUCCESS; 206 } 207 208 QDF_STATUS ucfg_green_ap_get_transition_time(struct wlan_objmgr_pdev *pdev, 209 uint32_t *ps_trans_time) 210 { 211 struct wlan_pdev_green_ap_ctx *green_ap_ctx; 212 213 if (!pdev) { 214 green_ap_err("pdev context passed is NULL"); 215 return QDF_STATUS_E_INVAL; 216 } 217 218 green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj( 219 pdev, WLAN_UMAC_COMP_GREEN_AP); 220 221 if (!green_ap_ctx) { 222 green_ap_err("green ap context obtained is NULL"); 223 return QDF_STATUS_E_FAILURE; 224 } 225 226 qdf_spin_lock_bh(&green_ap_ctx->lock); 227 if (wlan_is_egap_enabled(green_ap_ctx)) { 228 qdf_spin_unlock_bh(&green_ap_ctx->lock); 229 return QDF_STATUS_SUCCESS; 230 } 231 232 *ps_trans_time = green_ap_ctx->ps_trans_time; 233 qdf_spin_unlock_bh(&green_ap_ctx->lock); 234 235 return QDF_STATUS_SUCCESS; 236 } 237 238 QDF_STATUS ucfg_green_ap_config(struct wlan_objmgr_pdev *pdev, uint8_t val) 239 { 240 241 uint8_t flag; 242 243 if (wlan_green_ap_get_capab(pdev) == QDF_STATUS_E_NOSUPPORT) { 244 green_ap_err("GreenAP not supported on radio\n"); 245 return QDF_STATUS_E_NOSUPPORT; 246 } 247 248 if (val) { 249 struct wlan_pdev_green_ap_ctx *green_ap_ctx; 250 251 wlan_objmgr_pdev_iterate_obj_list(pdev, 252 WLAN_VDEV_OP, 253 wlan_green_ap_check_mode, 254 &flag, 0, WLAN_GREEN_AP_ID); 255 if (flag == 1) { 256 green_ap_err("Radio not in AP/RE mode." 257 "Feature not supported"); 258 return QDF_STATUS_E_NOSUPPORT; 259 } 260 261 green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(pdev, 262 WLAN_UMAC_COMP_GREEN_AP); 263 264 if (!green_ap_ctx) { 265 green_ap_err("green ap context obtained is NULL"); 266 return QDF_STATUS_E_NOSUPPORT; 267 } 268 269 ucfg_green_ap_set_ps_config(pdev, val); 270 271 if (wlan_util_is_vdev_active(pdev, WLAN_GREEN_AP_ID) == 272 QDF_STATUS_SUCCESS) 273 wlan_green_ap_start(pdev); 274 } else { 275 wlan_green_ap_stop(pdev); 276 } 277 278 return QDF_STATUS_SUCCESS; 279 } 280 281 void ucfg_green_ap_enable_debug_prints(struct wlan_objmgr_pdev *pdev, 282 uint32_t val) 283 { 284 struct wlan_pdev_green_ap_ctx *green_ap_ctx; 285 286 green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj( 287 pdev, WLAN_UMAC_COMP_GREEN_AP); 288 289 if (!green_ap_ctx) { 290 green_ap_err("green ap context obtained is NULL"); 291 return; 292 } 293 294 green_ap_ctx->dbg_enable = val; 295 } 296 297 bool ucfg_green_ap_get_debug_prints(struct wlan_objmgr_pdev *pdev) 298 { 299 struct wlan_pdev_green_ap_ctx *green_ap_ctx; 300 301 green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj( 302 pdev, WLAN_UMAC_COMP_GREEN_AP); 303 304 if (!green_ap_ctx) { 305 green_ap_err("green ap context obtained is NULL"); 306 return false; 307 } 308 309 return green_ap_ctx->dbg_enable; 310 } 311 312