blob: e3420ff8af3234b5f6f9ae91399bd839d10ffa99 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Tushnim Bhattacharyya9028cc72017-03-09 13:10:49 -08002 * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/**
23 * DOC: wlan_hdd_green_ap.c
24 *
25 * WLAN Host Device Driver Green AP implementation
26 *
27 */
28
29/* Include Files */
30#include <wlan_hdd_main.h>
31#include <wlan_hdd_misc.h>
32#include "wlan_hdd_green_ap.h"
33#include "wma_api.h"
Tushnim Bhattacharyya9028cc72017-03-09 13:10:49 -080034#include "wlan_policy_mgr_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080035
36#define GREEN_AP_PS_ON_TIME (0)
37#define GREEN_AP_PS_DELAY_TIME (20)
38
39/**
40 * enum hdd_green_ap_ps_state - Green-AP power save states
41 * @GREEN_AP_PS_IDLE_STATE: the Green_AP is not enabled
42 * @GREEN_AP_PS_OFF_STATE: in Power Saving OFF state
43 * @GREEN_AP_PS_WAIT_STATE: in transition to Power Saving ON state
44 * @GREEN_AP_PS_ON_STATE: in Power Saving ON state
45 */
46enum hdd_green_ap_ps_state {
47 GREEN_AP_PS_IDLE_STATE = 1,
48 GREEN_AP_PS_OFF_STATE,
49 GREEN_AP_PS_WAIT_STATE,
50 GREEN_AP_PS_ON_STATE,
51};
52
53/**
54 * enum hdd_green_ap_event - Green-AP power save events
55 * @GREEN_AP_PS_START_EVENT: event to indicate to enable Green_AP
56 * @GREEN_AP_PS_START_EVENT: event to indicate to disable Green_AP
57 * @GREEN_AP_ADD_STA_EVENT: event to indicate a new STA connected
58 * @GREEN_AP_DEL_STA_EVENT: event to indicate a STA disconnected
59 * @GREEN_AP_PS_ON_EVENT: event to indicate to enter Power Saving state
60 * @GREEN_AP_PS_WAIT_EVENT: event to indicate in the transition to Power Saving
61 */
62enum hdd_green_ap_event {
63 GREEN_AP_PS_START_EVENT = 1,
64 GREEN_AP_PS_STOP_EVENT,
65 GREEN_AP_ADD_STA_EVENT,
66 GREEN_AP_DEL_STA_EVENT,
67 GREEN_AP_PS_ON_EVENT,
68 GREEN_AP_PS_WAIT_EVENT,
69};
70
71/**
72 * struct hdd_green_ap_ctx - Green-AP context
73 * @ps_enable: Whether or not Green AP is enabled
74 * @ps_on_time: Amount of time to stay in Green AP power saving state
75 * @ps_delay_time: Amount of time to delay when changing states
76 * @num_nodes: Number of connected clients
77 * @ps_state: Current state
78 * @ps_event: Event to trigger when timer expires
79 * @ps_timer: Event timer
Ryan Hsu3c8f79f2015-12-02 16:45:09 -080080 * @egap_support: Enhanced Green AP support flag
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080081 */
82struct hdd_green_ap_ctx {
83 uint8_t ps_enable;
84 uint32_t ps_on_time;
85 uint32_t ps_delay_time;
86 uint32_t num_nodes;
87
88 enum hdd_green_ap_ps_state ps_state;
89 enum hdd_green_ap_event ps_event;
90
Anurag Chouhan210db072016-02-22 18:42:15 +053091 qdf_mc_timer_t ps_timer;
Ryan Hsu3c8f79f2015-12-02 16:45:09 -080092
93 bool egap_support;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080094};
95
96/**
Jeff Johnsona7e5eed2016-09-28 15:19:13 -070097 * hdd_green_ap_update() - update the current State and Event
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080098 * @hdd_ctx: Global HDD context
99 * @state: New state
100 * @event: New event
101 *
102 * Return: none
103 */
Jeff Johnson82797b62017-08-11 15:31:27 -0700104static void hdd_green_ap_update(struct hdd_context *hdd_ctx,
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700105 enum hdd_green_ap_ps_state state,
106 enum hdd_green_ap_event event)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800107{
108 struct hdd_green_ap_ctx *green_ap = hdd_ctx->green_ap_ctx;
109
110 green_ap->ps_state = state;
111 green_ap->ps_event = event;
112}
113
114/**
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700115 * hdd_green_ap_enable() - Send Green AP configuration to firmware
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800116 * @adapter: Adapter upon which Green AP is being configured
117 * @enable: Flag which indicates if Green AP is being enabled or disabled
118 *
119 * Return: 0 upon success, non-zero upon failure
120 */
Jeff Johnson9a7136d2017-08-29 14:33:56 -0700121static int hdd_green_ap_enable(struct hdd_adapter *adapter, uint8_t enable)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800122{
123 int ret;
124
Srinivas Girigowdaf8926d92017-03-06 16:36:51 -0800125 hdd_debug("Set Green-AP val: %d", enable);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800126
Jeff Johnson1b780e42017-10-31 14:11:45 -0700127 ret = wma_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800128 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID,
129 enable, DBG_CMD);
130
131 return ret;
132}
133
134/**
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700135 * hdd_green_ap_mc() - Green AP state machine
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800136 * @hdd_ctx: HDD global context
137 * @event: New event being processed
138 *
139 * Return: none
140 */
Jeff Johnson82797b62017-08-11 15:31:27 -0700141static void hdd_green_ap_mc(struct hdd_context *hdd_ctx,
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700142 enum hdd_green_ap_event event)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800143{
144 struct hdd_green_ap_ctx *green_ap;
Jeff Johnson9a7136d2017-08-29 14:33:56 -0700145 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800146
147 green_ap = hdd_ctx->green_ap_ctx;
148 if (green_ap == NULL)
149 return;
150
Srinivas Girigowdaf8926d92017-03-06 16:36:51 -0800151 hdd_debug("Green-AP event: %d, state: %d, num_nodes: %d",
Jeff Johnson417af552015-11-09 15:15:01 -0800152 event, green_ap->ps_state, green_ap->num_nodes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800153
154 /* handle the green ap ps event */
155 switch (event) {
156 case GREEN_AP_PS_START_EVENT:
157 green_ap->ps_enable = 1;
158 break;
159
160 case GREEN_AP_PS_STOP_EVENT:
bings612b9c42016-11-07 10:52:03 +0800161 green_ap->ps_enable = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800162 break;
163
164 case GREEN_AP_ADD_STA_EVENT:
165 green_ap->num_nodes++;
166 break;
167
168 case GREEN_AP_DEL_STA_EVENT:
169 if (green_ap->num_nodes)
170 green_ap->num_nodes--;
171 break;
172
173 case GREEN_AP_PS_ON_EVENT:
174 case GREEN_AP_PS_WAIT_EVENT:
175 break;
176
177 default:
Srinivas Girigowdaf8926d92017-03-06 16:36:51 -0800178 hdd_err("Invalid event: %d", event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800179 break;
180 }
181
bings612b9c42016-11-07 10:52:03 +0800182 adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
183 if (adapter == NULL) {
184 hdd_err("Green-AP no SAP adapter");
185 goto done;
186 }
187
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800188 /* Confirm that power save is enabled before doing state transitions */
189 if (!green_ap->ps_enable) {
Srinivas Girigowdaf8926d92017-03-06 16:36:51 -0800190 hdd_debug("Green-AP is disabled");
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700191 hdd_green_ap_update(hdd_ctx,
bings612b9c42016-11-07 10:52:03 +0800192 GREEN_AP_PS_OFF_STATE,
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700193 GREEN_AP_PS_WAIT_EVENT);
bings612b9c42016-11-07 10:52:03 +0800194 if (hdd_green_ap_enable(adapter, 0))
195 hdd_err("failed to set green ap mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800196 goto done;
197 }
198
199 /* handle the green ap ps state */
200 switch (green_ap->ps_state) {
201 case GREEN_AP_PS_IDLE_STATE:
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700202 hdd_green_ap_update(hdd_ctx,
203 GREEN_AP_PS_OFF_STATE,
204 GREEN_AP_PS_WAIT_EVENT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800205 break;
206
207 case GREEN_AP_PS_OFF_STATE:
208 if (!green_ap->num_nodes) {
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700209 hdd_green_ap_update(hdd_ctx,
210 GREEN_AP_PS_WAIT_STATE,
211 GREEN_AP_PS_WAIT_EVENT);
Anurag Chouhan210db072016-02-22 18:42:15 +0530212 qdf_mc_timer_start(&green_ap->ps_timer,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800213 green_ap->ps_delay_time);
214 }
215 break;
216
217 case GREEN_AP_PS_WAIT_STATE:
218 if (!green_ap->num_nodes) {
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700219 hdd_green_ap_update(hdd_ctx,
220 GREEN_AP_PS_ON_STATE,
221 GREEN_AP_PS_WAIT_EVENT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800222
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700223 hdd_green_ap_enable(adapter, 1);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800224
225 if (green_ap->ps_on_time) {
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700226 hdd_green_ap_update(hdd_ctx,
227 0,
228 GREEN_AP_PS_WAIT_EVENT);
Anurag Chouhan210db072016-02-22 18:42:15 +0530229 qdf_mc_timer_start(&green_ap->ps_timer,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800230 green_ap->ps_on_time);
231 }
232 } else {
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700233 hdd_green_ap_update(hdd_ctx,
234 GREEN_AP_PS_OFF_STATE,
235 GREEN_AP_PS_WAIT_EVENT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800236 }
237 break;
238
239 case GREEN_AP_PS_ON_STATE:
240 if (green_ap->num_nodes) {
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700241 if (hdd_green_ap_enable(adapter, 0)) {
Jeff Johnson417af552015-11-09 15:15:01 -0800242 hdd_err("FAILED TO SET GREEN-AP mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800243 goto done;
244 }
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700245 hdd_green_ap_update(hdd_ctx,
246 GREEN_AP_PS_OFF_STATE,
247 GREEN_AP_PS_WAIT_EVENT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800248 } else if ((green_ap->ps_event == GREEN_AP_PS_WAIT_EVENT)
249 && (green_ap->ps_on_time)) {
250
251 /* ps_on_time timeout, switch to ps off */
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700252 hdd_green_ap_update(hdd_ctx,
253 GREEN_AP_PS_WAIT_STATE,
254 GREEN_AP_PS_ON_EVENT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800255
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700256 if (hdd_green_ap_enable(adapter, 0)) {
Jeff Johnson417af552015-11-09 15:15:01 -0800257 hdd_err("FAILED TO SET GREEN-AP mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800258 goto done;
259 }
260
Anurag Chouhan210db072016-02-22 18:42:15 +0530261 qdf_mc_timer_start(&green_ap->ps_timer,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800262 green_ap->ps_delay_time);
263 }
264 break;
265
266 default:
Jeff Johnson417af552015-11-09 15:15:01 -0800267 hdd_err("invalid state %d", green_ap->ps_state);
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700268 hdd_green_ap_update(hdd_ctx, GREEN_AP_PS_OFF_STATE,
269 GREEN_AP_PS_WAIT_EVENT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800270 break;
271 }
272
273done:
274 return;
275}
276
277/**
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700278 * hdd_green_ap_timer_fn() - Green AP Timer handler
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800279 * @ctx: Global HDD context
280 *
281 * Return: none
282 */
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700283static void hdd_green_ap_timer_fn(void *ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800284{
Jeff Johnson82797b62017-08-11 15:31:27 -0700285 struct hdd_context *hdd_ctx = ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800286 struct hdd_green_ap_ctx *green_ap;
287
Abhishek Singh23edd1c2016-05-05 11:56:06 +0530288 if (wlan_hdd_validate_context(hdd_ctx))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800289 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800290
291 green_ap = hdd_ctx->green_ap_ctx;
292 if (green_ap)
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700293 hdd_green_ap_mc(hdd_ctx, green_ap->ps_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800294}
295
296/**
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700297 * hdd_green_ap_attach() - Attach Green AP context to HDD context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800298 * @hdd_ctx: Global HDD contect
299 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530300 * Return: QDF_STATUS_SUCCESS on success, otherwise QDF_STATUS_E_** error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800301 */
Jeff Johnson82797b62017-08-11 15:31:27 -0700302static QDF_STATUS hdd_green_ap_attach(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800303{
304 struct hdd_green_ap_ctx *green_ap;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530305 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800306
307 ENTER();
308
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530309 green_ap = qdf_mem_malloc(sizeof(*green_ap));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800310 if (!green_ap) {
Srinivas Girigowdaf8926d92017-03-06 16:36:51 -0800311 hdd_err("Memory allocation for Green-AP failed!");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530312 status = QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800313 goto error;
314 }
315
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800316 green_ap->ps_state = GREEN_AP_PS_OFF_STATE;
317 green_ap->ps_event = 0;
318 green_ap->num_nodes = 0;
319 green_ap->ps_on_time = GREEN_AP_PS_ON_TIME;
320 green_ap->ps_delay_time = GREEN_AP_PS_DELAY_TIME;
321
Anurag Chouhan210db072016-02-22 18:42:15 +0530322 qdf_mc_timer_init(&green_ap->ps_timer,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530323 QDF_TIMER_TYPE_SW,
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700324 hdd_green_ap_timer_fn, hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800325
326error:
327 hdd_ctx->green_ap_ctx = green_ap;
328
329 EXIT();
330 return status;
331}
332
333/**
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700334 * hdd_green_ap_deattach() - Detach Green AP context from HDD context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800335 * @hdd_ctx: Global HDD contect
336 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530337 * Return: QDF_STATUS_SUCCESS on success, otherwise QDF_STATUS_E_** error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800338 */
Jeff Johnson82797b62017-08-11 15:31:27 -0700339static QDF_STATUS hdd_green_ap_deattach(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800340{
341 struct hdd_green_ap_ctx *green_ap = hdd_ctx->green_ap_ctx;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530342 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800343
344 ENTER();
345
346 if (green_ap == NULL) {
Srinivas Girigowdaf8926d92017-03-06 16:36:51 -0800347 hdd_debug("Green-AP is not enabled");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530348 status = QDF_STATUS_E_NOSUPPORT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800349 goto done;
350 }
351
352 /* check if the timer status is destroyed */
Anurag Chouhan210db072016-02-22 18:42:15 +0530353 if (QDF_TIMER_STATE_RUNNING ==
354 qdf_mc_timer_get_current_state(&green_ap->ps_timer))
355 qdf_mc_timer_stop(&green_ap->ps_timer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800356
357 /* Destroy the Green AP timer */
Anurag Chouhan210db072016-02-22 18:42:15 +0530358 if (!QDF_IS_STATUS_SUCCESS(qdf_mc_timer_destroy(&green_ap->ps_timer)))
Srinivas Girigowdaf8926d92017-03-06 16:36:51 -0800359 hdd_debug("Cannot deallocate Green-AP's timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800360
361 /* release memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530362 qdf_mem_zero(green_ap, sizeof(*green_ap));
363 qdf_mem_free(green_ap);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800364 hdd_ctx->green_ap_ctx = NULL;
365
366done:
367
368 EXIT();
369 return status;
370}
371
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700372/*
373 * hdd_green_ap_init() - Initialize Green AP feature
374 * (public function documented in wlan_hdd_green_ap.h)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800375 */
Jeff Johnson82797b62017-08-11 15:31:27 -0700376void hdd_green_ap_init(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800377{
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700378 if (!QDF_IS_STATUS_SUCCESS(hdd_green_ap_attach(hdd_ctx)))
Jeff Johnson417af552015-11-09 15:15:01 -0800379 hdd_err("Failed to allocate Green-AP resource");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800380}
381
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700382/*
383 * hdd_green_ap_deinit() - De-initialize Green AP feature
384 * (public function documented in wlan_hdd_green_ap.h)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800385 */
Jeff Johnson82797b62017-08-11 15:31:27 -0700386void hdd_green_ap_deinit(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800387{
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700388 if (!QDF_IS_STATUS_SUCCESS(hdd_green_ap_deattach(hdd_ctx)))
Jeff Johnson417af552015-11-09 15:15:01 -0800389 hdd_err("Cannot deallocate Green-AP resource");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800390}
391
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700392/*
bings612b9c42016-11-07 10:52:03 +0800393 * hdd_is_egap_enabled() - Get Enhance Green AP feature status
394 * @fw_egap_support: flag whether firmware supports egap or not
395 * @cfg: pointer to the struct hdd_config
396 *
397 * Return: true if firmware, feature_flag and ini are all enabled the egap
398 */
399static bool hdd_is_egap_enabled(bool fw_egap_support, struct hdd_config *cfg)
400{
401 /* check if the firmware and ini are both enabled the egap,
402 * and also the feature_flag enable.
403 */
404 if (fw_egap_support && cfg->enable_egap &&
405 cfg->egap_feature_flag)
406 return true;
407 return false;
408}
409
410/*
411 * hdd_enable_egap() - Enable Enhance Green AP
412 * @hdd_ctx: HDD global context
413 *
414 * Return: 0 on success, negative errno on failure
415 */
Jeff Johnson82797b62017-08-11 15:31:27 -0700416int hdd_enable_egap(struct hdd_context *hdd_ctx)
bings612b9c42016-11-07 10:52:03 +0800417{
418 struct hdd_config *cfg;
419
420 if (!hdd_ctx) {
421 hdd_err("hdd context is NULL");
422 return -EINVAL;
423 }
424
425 cfg = hdd_ctx->config;
426
427 if (!cfg) {
428 hdd_err("hdd cfg is NULL");
429 return -EINVAL;
430 }
431
432 if (!hdd_ctx->green_ap_ctx) {
433 hdd_err("green ap context is NULL");
434 return -EINVAL;
435 }
436
437 if (!hdd_is_egap_enabled(hdd_ctx->green_ap_ctx->egap_support,
438 hdd_ctx->config))
439 return -ENOTSUPP;
440
441 if (QDF_STATUS_SUCCESS != sme_send_egap_conf_params(cfg->enable_egap,
442 cfg->egap_inact_time,
443 cfg->egap_wait_time,
444 cfg->egap_feature_flag))
445 return -EINVAL;
446 return 0;
447}
448
449/*
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700450 * hdd_green_ap_start_bss() - Notify Green AP of Start BSS event
451 * (public function documented in wlan_hdd_green_ap.h)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800452 */
Jeff Johnson82797b62017-08-11 15:31:27 -0700453void hdd_green_ap_start_bss(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800454{
bings612b9c42016-11-07 10:52:03 +0800455 struct hdd_config *cfg;
456
457 if (!hdd_ctx) {
458 hdd_err("hdd context is NULL");
459 return;
460 }
461
462 cfg = hdd_ctx->config;
463
464 if (!cfg) {
465 hdd_err("hdd cfg is NULL");
466 return;
467 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800468
Ganesh Kondabattinib07874f2016-11-03 17:31:16 +0530469 if (!hdd_ctx->green_ap_ctx) {
470 hdd_err("Green AP is not enabled. green_ap_ctx = NULL");
bings612b9c42016-11-07 10:52:03 +0800471 return;
Ganesh Kondabattinib07874f2016-11-03 17:31:16 +0530472 }
473
bings612b9c42016-11-07 10:52:03 +0800474 if (hdd_is_egap_enabled(hdd_ctx->green_ap_ctx->egap_support,
475 hdd_ctx->config))
476 return;
Ryan Hsucb118cf2015-11-09 16:03:53 -0800477
Ganesh Kondabattinie3531842016-11-04 10:51:29 +0530478 if ((hdd_ctx->concurrency_mode & QDF_SAP_MASK) &&
479 !(hdd_ctx->concurrency_mode & (QDF_SAP_MASK)) &&
480 cfg->enable2x2 && cfg->enableGreenAP) {
Srinivas Girigowdaf8926d92017-03-06 16:36:51 -0800481 hdd_debug("Green AP enabled - sta_con: %d, 2x2: %d, GAP: %d",
Ganesh Kondabattinie3531842016-11-04 10:51:29 +0530482 QDF_STA_MASK & hdd_ctx->concurrency_mode,
483 cfg->enable2x2, cfg->enableGreenAP);
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700484 hdd_green_ap_mc(hdd_ctx, GREEN_AP_PS_START_EVENT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800485 } else {
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700486 hdd_green_ap_mc(hdd_ctx, GREEN_AP_PS_STOP_EVENT);
Srinivas Girigowdaf8926d92017-03-06 16:36:51 -0800487 hdd_debug("Green-AP: is disabled, due to sta_concurrency: %d, enable2x2: %d, enableGreenAP: %d",
Anurag Chouhan6d760662016-02-20 16:05:43 +0530488 QDF_STA_MASK & hdd_ctx->concurrency_mode,
Jeff Johnson417af552015-11-09 15:15:01 -0800489 cfg->enable2x2, cfg->enableGreenAP);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800490 }
491}
492
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700493/*
494 * hdd_green_ap_stop_bss() - Notify Green AP of Stop BSS event
495 * (public function documented in wlan_hdd_green_ap.h)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800496 */
Jeff Johnson82797b62017-08-11 15:31:27 -0700497void hdd_green_ap_stop_bss(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800498{
bings612b9c42016-11-07 10:52:03 +0800499 struct hdd_config *cfg;
500
501 if (!hdd_ctx) {
502 hdd_err("hdd context is NULL");
503 return;
504 }
505
506 cfg = hdd_ctx->config;
507
508 if (!cfg) {
509 hdd_err("hdd cfg is NULL");
510 return;
511 }
512
513 if (!hdd_ctx->green_ap_ctx) {
514 hdd_err("Green AP is not enabled. green_ap_ctx = NULL");
515 return;
516 }
517
518 if (hdd_is_egap_enabled(hdd_ctx->green_ap_ctx->egap_support,
519 hdd_ctx->config))
520 return;
521
522 /* For AP+AP mode, only trigger GREEN_AP_PS_STOP_EVENT, when the
523 * last AP stops.
524 */
525
526 if (1 == (hdd_ctx->no_of_open_sessions[QDF_SAP_MODE]))
527 hdd_green_ap_mc(hdd_ctx, GREEN_AP_PS_STOP_EVENT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800528}
529
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700530/*
531 * hdd_green_ap_add_sta() - Notify Green AP of Add Station event
532 * (public function documented in wlan_hdd_green_ap.h)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800533 */
Jeff Johnson82797b62017-08-11 15:31:27 -0700534void hdd_green_ap_add_sta(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800535{
bings612b9c42016-11-07 10:52:03 +0800536 struct hdd_config *cfg;
537
538 if (!hdd_ctx) {
539 hdd_err("hdd context is NULL");
540 return;
541 }
542
543 cfg = hdd_ctx->config;
544
545 if (!cfg) {
546 hdd_err("hdd cfg is NULL");
547 return;
548 }
549
550 if (!hdd_ctx->green_ap_ctx) {
551 hdd_err("Green AP is not enabled. green_ap_ctx = NULL");
552 return;
553 }
554
555 if (hdd_is_egap_enabled(hdd_ctx->green_ap_ctx->egap_support,
556 hdd_ctx->config))
557 return;
558
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700559 hdd_green_ap_mc(hdd_ctx, GREEN_AP_ADD_STA_EVENT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800560}
561
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700562/*
563 * hdd_green_ap_del_sta() - Notify Green AP of Delete Station event
564 * (public function documented in wlan_hdd_green_ap.h)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800565 */
Jeff Johnson82797b62017-08-11 15:31:27 -0700566void hdd_green_ap_del_sta(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800567{
bings612b9c42016-11-07 10:52:03 +0800568 struct hdd_config *cfg;
569
570 if (!hdd_ctx) {
571 hdd_err("hdd context is NULL");
572 return;
573 }
574
575 cfg = hdd_ctx->config;
576
577 if (!cfg) {
578 hdd_err("hdd cfg is NULL");
579 return;
580 }
581
582 if (!hdd_ctx->green_ap_ctx) {
583 hdd_err("Green AP is not enabled. green_ap_ctx = NULL");
584 return;
585 }
586
587 if (hdd_is_egap_enabled(hdd_ctx->green_ap_ctx->egap_support,
588 hdd_ctx->config))
589 return;
590
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700591 hdd_green_ap_mc(hdd_ctx, GREEN_AP_DEL_STA_EVENT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800592}
Ryan Hsu3c8f79f2015-12-02 16:45:09 -0800593
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700594/*
595 * hdd_green_ap_target_config() - Handle Green AP target configuration
596 * (public function documented in wlan_hdd_green_ap.h)
Ryan Hsu3c8f79f2015-12-02 16:45:09 -0800597 *
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700598 * Implementation notes:
599 * Target indicates whether or not Enhanced Green AP (EGAP) is supported
Ryan Hsu3c8f79f2015-12-02 16:45:09 -0800600 */
Jeff Johnson82797b62017-08-11 15:31:27 -0700601void hdd_green_ap_target_config(struct hdd_context *hdd_ctx,
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700602 struct wma_tgt_cfg *target_config)
Ryan Hsu3c8f79f2015-12-02 16:45:09 -0800603{
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700604 struct hdd_green_ap_ctx *green_ap = hdd_ctx->green_ap_ctx;
Ryan Hsu3c8f79f2015-12-02 16:45:09 -0800605
Jeff Johnsona7e5eed2016-09-28 15:19:13 -0700606 green_ap->egap_support = target_config->egap_support;
Ryan Hsu3c8f79f2015-12-02 16:45:09 -0800607}