blob: a08ce2bdb4ecdeec98e9183e4b1dc0aed05609d0 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
2 * Copyright (c) 2015 The Linux Foundation. All rights reserved.
3 *
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 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28#include "sme_power_save.h"
29#include "sme_power_save_api.h"
30#include "sms_debug.h"
31#include "cdf_memory.h"
32#include "cdf_types.h"
33#include "wma_types.h"
34#include "wmm_apsd.h"
35#include "cfg_api.h"
36#include "csr_inside_api.h"
37
38/**
39 * sme_post_ps_msg_to_wma(): post message to WMA.
40 * @type: type
41 * @body: body pointer
42 *
43 * Return: CDF_STATUS
44 */
45CDF_STATUS sme_post_ps_msg_to_wma(uint16_t type, void *body)
46{
47 cds_msg_t msg;
48
49 msg.type = type;
50 msg.reserved = 0;
51 msg.bodyptr = body;
52 msg.bodyval = 0;
53
54 if (CDF_STATUS_SUCCESS != cds_mq_post_message(
55 CDF_MODULE_ID_WMA, &msg)) {
56 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
57 "%s: Posting message %d failed",
58 __func__, type);
59 cdf_mem_free(body);
60 return CDF_STATUS_E_FAILURE;
61 }
62 return CDF_STATUS_SUCCESS;
63}
64
65/**
66 * sme_ps_enable_ps_req_params(): enables power save req params
67 * @mac_ctx: global mac context
68 * @session_id: session id
69 *
70 * Return: CDF_STATUS
71 */
72CDF_STATUS sme_ps_enable_ps_req_params(tpAniSirGlobal mac_ctx,
73 uint32_t session_id)
74{
75 struct sEnablePsParams *enable_ps_req_params;
76 CDF_STATUS status = CDF_STATUS_SUCCESS;
77
78 enable_ps_req_params = cdf_mem_malloc(sizeof(*enable_ps_req_params));
79 if (NULL == enable_ps_req_params) {
80 sms_log(mac_ctx, LOGE,
81 FL("Memory allocation failed for enable_ps_req_params"));
82 return CDF_STATUS_E_NOMEM;
83 }
84 enable_ps_req_params->psSetting = eSIR_ADDON_NOTHING;
85 enable_ps_req_params->sessionid = session_id;
86
87 status = sme_post_ps_msg_to_wma(WMA_ENTER_PS_REQ, enable_ps_req_params);
88 if (!CDF_IS_STATUS_SUCCESS(status))
89 return CDF_STATUS_E_FAILURE;
90 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
91 FL("Message WMA_ENTER_PS_REQ Successfully sent to WMA"));
92 return CDF_STATUS_SUCCESS;
93}
94
95/**
96 * sme_ps_disable_ps_req_params(): Disable power save req params
97 * @mac_ctx: global mac context
98 * @session_id: session id
99 *
100 * Return: CDF_STATUS
101 */
102CDF_STATUS sme_ps_disable_ps_req_params(tpAniSirGlobal mac_ctx,
103 uint32_t session_id)
104{
105 struct sDisablePsParams *disable_ps_req_params;
106 CDF_STATUS status = CDF_STATUS_SUCCESS;
107
108 disable_ps_req_params = cdf_mem_malloc(sizeof(*disable_ps_req_params));
109 if (NULL == disable_ps_req_params) {
110 sms_log(mac_ctx, LOGE,
111 FL("Memory allocation failed for sDisablePsParams"));
112 return CDF_STATUS_E_NOMEM;
113 }
114
115 disable_ps_req_params->psSetting = eSIR_ADDON_NOTHING;
116 disable_ps_req_params->sessionid = session_id;
117
118 status = sme_post_ps_msg_to_wma(WMA_EXIT_PS_REQ, disable_ps_req_params);
119 if (!CDF_IS_STATUS_SUCCESS(status))
120 return CDF_STATUS_E_FAILURE;
121 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
122 FL("Message WMA_EXIT_PS_REQ Successfully sent to WMA"));
123 return CDF_STATUS_SUCCESS;
124}
125
126/**
127 * sme_ps_enable_uapsd_req_params(): enables UASPD req params
128 * @mac_ctx: global mac context
129 * @session_id: session id
130 *
131 * Return: CDF_STATUS
132 */
133CDF_STATUS sme_ps_enable_uapsd_req_params(tpAniSirGlobal mac_ctx,
134 uint32_t session_id)
135{
136
137 struct sEnableUapsdParams *enable_uapsd_req_params;
138 uint8_t uapsd_delivery_mask = 0;
139 uint8_t uapsd_trigger_mask = 0;
140 struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
141 struct ps_params *ps_param = &ps_global_info->ps_params[session_id];
142 CDF_STATUS status = CDF_STATUS_SUCCESS;
143
144 enable_uapsd_req_params =
145 cdf_mem_malloc(sizeof(*enable_uapsd_req_params));
146 if (NULL == enable_uapsd_req_params) {
147 sms_log(mac_ctx, LOGE,
148 FL("Memory allocation failed for enable_uapsd_req_params"));
149 return CDF_STATUS_E_NOMEM;
150 }
151
152
153 uapsd_delivery_mask =
154 ps_param->uapsd_per_ac_bit_mask |
155 ps_param->uapsd_per_ac_delivery_enable_mask;
156
157 uapsd_trigger_mask =
158 ps_param->uapsd_per_ac_bit_mask |
159 ps_param->uapsd_per_ac_trigger_enable_mask;
160
161
162 enable_uapsd_req_params->uapsdParams.bkDeliveryEnabled =
163 LIM_UAPSD_GET(ACBK, uapsd_delivery_mask);
164
165 enable_uapsd_req_params->uapsdParams.beDeliveryEnabled =
166 LIM_UAPSD_GET(ACBE, uapsd_delivery_mask);
167
168 enable_uapsd_req_params->uapsdParams.viDeliveryEnabled =
169 LIM_UAPSD_GET(ACVI, uapsd_delivery_mask);
170
171 enable_uapsd_req_params->uapsdParams.voDeliveryEnabled =
172 LIM_UAPSD_GET(ACVO, uapsd_delivery_mask);
173
174 enable_uapsd_req_params->uapsdParams.bkTriggerEnabled =
175 LIM_UAPSD_GET(ACBK, uapsd_trigger_mask);
176
177 enable_uapsd_req_params->uapsdParams.beTriggerEnabled =
178 LIM_UAPSD_GET(ACBE, uapsd_trigger_mask);
179
180 enable_uapsd_req_params->uapsdParams.viTriggerEnabled =
181 LIM_UAPSD_GET(ACVI, uapsd_trigger_mask);
182
183 enable_uapsd_req_params->uapsdParams.voTriggerEnabled =
184 LIM_UAPSD_GET(ACVO, uapsd_trigger_mask);
185
186 enable_uapsd_req_params->sessionid = session_id;
187
188 status = sme_post_ps_msg_to_wma(WMA_ENABLE_UAPSD_REQ,
189 enable_uapsd_req_params);
190 if (!CDF_IS_STATUS_SUCCESS(status))
191 return CDF_STATUS_E_FAILURE;
192
193 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
194 FL("Msg WMA_ENABLE_UAPSD_REQ Successfully sent to WMA"));
195 return CDF_STATUS_SUCCESS;
196}
197
198/**
199 * sme_ps_disable_uapsd_req_params(): disables UASPD req params
200 * @mac_ctx: global mac context
201 * @session_id: session id
202 *
203 * Return: CDF_STATUS
204 */
205CDF_STATUS sme_ps_disable_uapsd_req_params(tpAniSirGlobal mac_ctx,
206 uint32_t session_id)
207{
208 struct sDisableUapsdParams *disable_uapsd_req_params;
209 CDF_STATUS status = CDF_STATUS_SUCCESS;
210
211 disable_uapsd_req_params =
212 cdf_mem_malloc(sizeof(*disable_uapsd_req_params));
213 if (NULL == disable_uapsd_req_params) {
214 sms_log(mac_ctx, LOGE,
215 FL("Memory allocation failed for disable_uapsd_req_params"));
216 return CDF_STATUS_E_NOMEM;
217 }
218
219 disable_uapsd_req_params->sessionid = session_id;
220 status = sme_post_ps_msg_to_wma(WMA_DISABLE_UAPSD_REQ,
221 disable_uapsd_req_params);
222 if (!CDF_IS_STATUS_SUCCESS(status))
223 return CDF_STATUS_E_FAILURE;
224
225 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
226 FL("Message WMA_DISABLE_UAPSD_REQ Successfully sent to WMA"));
227 return CDF_STATUS_SUCCESS;
228}
229
230/**
231 * sme_ps_enter_wowl_req_params(): enable WOWL req Parama
232 * @mac_ctx: global mac context
233 * @session_id: session id
234 *
235 * Return: CDF_STATUS
236 */
237CDF_STATUS sme_ps_enter_wowl_req_params(tpAniSirGlobal mac_ctx,
238 uint32_t session_id)
239{
240 struct sSirHalWowlEnterParams *hal_wowl_params;
241 struct sSirSmeWowlEnterParams *sme_wowl_params;
242 uint32_t cfg_value = 0;
243 struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
244
245 sme_wowl_params =
246 &ps_global_info->ps_params[session_id].wowl_enter_params;
247
248 hal_wowl_params = cdf_mem_malloc(sizeof(*hal_wowl_params));
249 if (NULL == hal_wowl_params) {
250 sms_log(mac_ctx, LOGP,
251 FL("Fail to allocate memory for Enter Wowl Request "));
252 return CDF_STATUS_E_NOMEM;
253 }
254 cdf_mem_set((uint8_t *) hal_wowl_params, sizeof(*hal_wowl_params), 0);
255
256 /* fill in the message field */
257 hal_wowl_params->ucMagicPktEnable = sme_wowl_params->ucMagicPktEnable;
258 hal_wowl_params->ucPatternFilteringEnable =
259 sme_wowl_params->ucPatternFilteringEnable;
260 cdf_mem_copy((uint8_t *) hal_wowl_params->magicPtrn,
261 (uint8_t *) sme_wowl_params->magicPtrn,
262 sizeof(tSirMacAddr));
263
264#ifdef WLAN_WAKEUP_EVENTS
265 hal_wowl_params->ucWoWEAPIDRequestEnable =
266 sme_wowl_params->ucWoWEAPIDRequestEnable;
267 hal_wowl_params->ucWoWEAPOL4WayEnable =
268 sme_wowl_params->ucWoWEAPOL4WayEnable;
269 hal_wowl_params->ucWowNetScanOffloadMatch =
270 sme_wowl_params->ucWowNetScanOffloadMatch;
271 hal_wowl_params->ucWowGTKRekeyError =
272 sme_wowl_params->ucWowGTKRekeyError;
273 hal_wowl_params->ucWoWBSSConnLoss =
274 sme_wowl_params->ucWoWBSSConnLoss;
275#endif /* WLAN_WAKEUP_EVENTS */
276
277 if (wlan_cfg_get_int
278 (mac_ctx, WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE,
279 &cfg_value) != eSIR_SUCCESS) {
280 sms_log(mac_ctx, LOGP,
281 FL("cfgGet failed for WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE"));
282 goto end;
283 }
284 hal_wowl_params->ucUcastPatternFilteringEnable = (uint8_t) cfg_value;
285
286 if (wlan_cfg_get_int
287 (mac_ctx, WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE,
288 &cfg_value) != eSIR_SUCCESS) {
289 sms_log(mac_ctx, LOGP,
290 FL("cfgGet failed for WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE"));
291 goto end;
292 }
293 hal_wowl_params->ucWowChnlSwitchRcv = (uint8_t) cfg_value;
294
295 if (wlan_cfg_get_int
296 (mac_ctx, WNI_CFG_WOWLAN_DEAUTH_ENABLE, &cfg_value) !=
297 eSIR_SUCCESS) {
298 sms_log(mac_ctx, LOGP,
299 FL("cfgGet failed for WNI_CFG_WOWLAN_DEAUTH_ENABLE "));
300 goto end;
301 }
302 hal_wowl_params->ucWowDeauthRcv = (uint8_t) cfg_value;
303
304 if (wlan_cfg_get_int
305 (mac_ctx, WNI_CFG_WOWLAN_DISASSOC_ENABLE, &cfg_value) !=
306 eSIR_SUCCESS) {
307 sms_log(mac_ctx, LOGP,
308 FL("cfgGet failed for WNI_CFG_WOWLAN_DISASSOC_ENABLE "));
309 goto end;
310 }
311 hal_wowl_params->ucWowDisassocRcv = (uint8_t) cfg_value;
312
313 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_WOWLAN_MAX_MISSED_BEACON,
314 &cfg_value) != eSIR_SUCCESS) {
315 sms_log(mac_ctx, LOGP,
316 FL("cfgGet failed for WNI_CFG_WOWLAN_MAX_MISSED_BEACON "));
317 goto end;
318 }
319 hal_wowl_params->ucWowMaxMissedBeacons = (uint8_t) cfg_value;
320
321 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD,
322 &cfg_value) != eSIR_SUCCESS) {
323 sms_log(mac_ctx, LOGP,
324 FL("cfgGet failed for WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD "));
325 goto end;
326 }
327 hal_wowl_params->ucWowMaxSleepUsec = (uint8_t) cfg_value;
328
329 hal_wowl_params->sessionId = sme_wowl_params->sessionId;
330
331 if (CDF_STATUS_SUCCESS == sme_post_ps_msg_to_wma(WMA_WOWL_ENTER_REQ,
332 hal_wowl_params)){
333 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
334 FL("Msg WMA_WOWL_ENTER_REQ Successfully sent to WMA"));
335 return CDF_STATUS_SUCCESS;
336 } else
337 goto end;
338
339end:
340 if (hal_wowl_params != NULL)
341 cdf_mem_free(hal_wowl_params);
342 return CDF_STATUS_E_FAILURE;
343}
344
345/**
346 * sme_ps_exit_wowl_req_params(): Exit WOWL req params
347 * @mac_ctx: global mac context
348 * @session_id: session id
349 *
350 * Return: CDF_STATUS
351 */
352CDF_STATUS sme_ps_exit_wowl_req_params(tpAniSirGlobal mac_ctx,
353 uint32_t session_id)
354{
355 struct sSirHalWowlExitParams *hal_wowl_msg;
356 hal_wowl_msg = cdf_mem_malloc(sizeof(*hal_wowl_msg));
357 if (NULL == hal_wowl_msg) {
358 sms_log(mac_ctx, LOGP,
359 FL("Fail to allocate memory for WoWLAN Add Bcast Pattern "));
360 return CDF_STATUS_E_NOMEM;
361 }
362 cdf_mem_set((uint8_t *) hal_wowl_msg,
363 sizeof(*hal_wowl_msg), 0);
364 hal_wowl_msg->sessionId = session_id;
365
366 if (CDF_STATUS_SUCCESS == sme_post_ps_msg_to_wma(WMA_WOWL_EXIT_REQ,
367 hal_wowl_msg)){
368 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
369 FL("Msg WMA_WOWL_EXIT_REQ Successfully sent to WMA"));
370 return CDF_STATUS_SUCCESS;
371 }
372 if (hal_wowl_msg != NULL)
373 cdf_mem_free(hal_wowl_msg);
374 return CDF_STATUS_E_FAILURE;
375}
376
377/**
378 * sme_ps_process_command(): Sme process power save messages
379 * and pass messages to WMA.
380 * @mac_ctx: global mac context
381 * @session_id: session id
382 * sme_ps_cmd: power save message
383 *
384 * Return: CDF_STATUS
385 */
386CDF_STATUS sme_ps_process_command(tpAniSirGlobal mac_ctx, uint32_t session_id,
387 enum sme_ps_cmd command)
388{
389 CDF_STATUS status = CDF_STATUS_SUCCESS;
390
391 if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
392 sms_log(mac_ctx, LOGE, "Invalid Session_id %x", session_id);
393 return eSIR_FAILURE;
394 }
395 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
396 FL("Power Save command %d"), command);
397 switch (command) {
398 case SME_PS_ENABLE:
399 status = sme_ps_enable_ps_req_params(mac_ctx, session_id);
400 break;
401 case SME_PS_DISABLE:
402 status = sme_ps_disable_ps_req_params(mac_ctx, session_id);
403 break;
404 case SME_PS_UAPSD_ENABLE:
405 status = sme_ps_enable_uapsd_req_params(mac_ctx, session_id);
406 break;
407 case SME_PS_UAPSD_DISABLE:
408 status = sme_ps_disable_uapsd_req_params(mac_ctx, session_id);
409 break;
410 case SME_PS_WOWL_ENTER:
411 status = sme_ps_enter_wowl_req_params(mac_ctx, session_id);
412 break;
413 case SME_PS_WOWL_EXIT:
414 status = sme_ps_exit_wowl_req_params(mac_ctx, session_id);
415 break;
416
417 default:
418 sms_log(mac_ctx, LOGE, FL("Invalid command type %d"),
419 command);
420 status = CDF_STATUS_E_FAILURE;
421 break;
422 }
423 if (status != CDF_STATUS_SUCCESS) {
424 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
425 FL("Not able to enter in PS, Command: %d"), command);
426 }
427 return status;
428}
429
430/**
431 * sme_enable_sta_ps_check(): Checks if it is ok to enable power save or not.
432 * @mac_ctx: global mac context
433 * @session_id: session id
434 *
435 *Pre Condition for enabling sta mode power save
436 *1) Sta Mode Ps should be enabled in ini file.
437 *2) Session should be in infra mode and in connected state.
438 *
439 * Return: CDF_STATUS
440 */
441CDF_STATUS sme_enable_sta_ps_check(tpAniSirGlobal mac_ctx, uint32_t session_id)
442{
443 struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
444
445 /* Check if Sta Ps is enabled. */
446 if (!ps_global_info->ps_enabled) {
447 sms_log(mac_ctx, LOG1,
448 "Cannot initiate PS. PS is disabled in ini");
449 return CDF_STATUS_E_FAILURE;
450 }
451
452 /* Check whether the given session is Infra and in Connected State */
453 if (!csr_is_conn_state_connected_infra(mac_ctx, session_id)) {
454 sms_log(mac_ctx, LOGE, "Sta not infra/connected state %d",
455 session_id);
456 return CDF_STATUS_E_FAILURE;
457 }
458 return CDF_STATUS_SUCCESS;
459
460}
461
462/**
463 * sme_ps_enable_disable(): function to enable/disable PS.
464 * @hal_ctx: global hal_handle
465 * @session_id: session id
466 * sme_ps_cmd: power save message
467 *
468 * Return: CDF_STATUS
469 */
470CDF_STATUS sme_ps_enable_disable(tHalHandle hal_ctx, uint32_t session_id,
471 enum sme_ps_cmd command)
472{
473 CDF_STATUS status = CDF_STATUS_E_FAILURE;
474 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
475 status = sme_enable_sta_ps_check(mac_ctx, session_id);
476 if (status != CDF_STATUS_SUCCESS)
477 return status;
478 status = sme_ps_process_command(mac_ctx, session_id, command);
479 return status;
480}
481
482/**
483 * sme_ps_uapsd_enable(): function to enable UAPSD.
484 * @hal_ctx: global hal_handle
485 * @session_id: session id
486 *
487 * Return: CDF_STATUS
488 */
489CDF_STATUS sme_ps_uapsd_enable(tHalHandle hal_ctx, uint32_t session_id)
490{
491
492 CDF_STATUS status = CDF_STATUS_E_FAILURE;
493 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
494 status = sme_enable_sta_ps_check(mac_ctx, session_id);
495 if (status != CDF_STATUS_SUCCESS)
496 return status;
497 status = sme_ps_process_command(mac_ctx, session_id,
498 SME_PS_UAPSD_ENABLE);
499 if (status == CDF_STATUS_SUCCESS)
500 sme_offload_qos_process_into_uapsd_mode(mac_ctx, session_id);
501
502 return status;
503}
504
505/**
506 * sme_ps_uapsd_disable(): function to disable UAPSD.
507 * @hal_ctx: global hal_handle
508 * @session_id: session id
509 *
510 * Return: CDF_STATUS
511 */
512CDF_STATUS sme_ps_uapsd_disable(tHalHandle hal_ctx, uint32_t session_id)
513{
514
515 CDF_STATUS status = CDF_STATUS_E_FAILURE;
516 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
517 status = sme_enable_sta_ps_check(mac_ctx, session_id);
518 if (status != CDF_STATUS_SUCCESS)
519 return status;
520 status = sme_ps_process_command(mac_ctx, session_id,
521 SME_PS_UAPSD_DISABLE);
522 if (status == CDF_STATUS_SUCCESS)
523 sme_offload_qos_process_out_of_uapsd_mode(mac_ctx, session_id);
524
525 return status;
526}
527
528/**
529 * sme_set_tspec_uapsd_mask_per_session(): set tspec UAPSD mask per session
530 * @mac_ctx: global mac context
531 * @ts_info: tspec info.
532 * @session_id: session id
533 *
534 * Return: CDF_STATUS
535 */
536void sme_set_tspec_uapsd_mask_per_session(tpAniSirGlobal mac_ctx,
537 tSirMacTSInfo *ts_info,
538 uint8_t session_id)
539{
540 uint8_t user_prio = (uint8_t) ts_info->traffic.userPrio;
541 uint16_t direction = ts_info->traffic.direction;
542 uint8_t ac = upToAc(user_prio);
543 struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
544 struct ps_params *ps_param = &ps_global_info->ps_params[session_id];
545 sms_log(mac_ctx, LOGE, FL("Set UAPSD mask for AC %d, dir %d, action=%d")
546 , ac, direction, ts_info->traffic.psb);
547
548 /* Converting AC to appropriate Uapsd Bit Mask
549 * AC_BE(0) --> UAPSD_BITOFFSET_ACVO(3)
550 * AC_BK(1) --> UAPSD_BITOFFSET_ACVO(2)
551 * AC_VI(2) --> UAPSD_BITOFFSET_ACVO(1)
552 * AC_VO(3) --> UAPSD_BITOFFSET_ACVO(0)
553 */
554 ac = ((~ac) & 0x3);
555 if (ts_info->traffic.psb) {
556 if (direction == SIR_MAC_DIRECTION_UPLINK)
557 ps_param->uapsd_per_ac_trigger_enable_mask |=
558 (1 << ac);
559 else if (direction == SIR_MAC_DIRECTION_DNLINK)
560 ps_param->uapsd_per_ac_delivery_enable_mask |=
561 (1 << ac);
562 else if (direction == SIR_MAC_DIRECTION_BIDIR) {
563 ps_param->uapsd_per_ac_trigger_enable_mask |=
564 (1 << ac);
565 ps_param->uapsd_per_ac_delivery_enable_mask |=
566 (1 << ac);
567 }
568 } else {
569 if (direction == SIR_MAC_DIRECTION_UPLINK)
570 ps_param->uapsd_per_ac_trigger_enable_mask &=
571 ~(1 << ac);
572 else if (direction == SIR_MAC_DIRECTION_DNLINK)
573 ps_param->uapsd_per_ac_delivery_enable_mask &=
574 ~(1 << ac);
575 else if (direction == SIR_MAC_DIRECTION_BIDIR) {
576 ps_param->uapsd_per_ac_trigger_enable_mask &=
577 ~(1 << ac);
578 ps_param->uapsd_per_ac_delivery_enable_mask &=
579 ~(1 << ac);
580 }
581 }
582
583 /*
584 * ADDTS success, so AC is now admitted. We shall now use the default
585 * EDCA parameters as advertised by AP and send the updated EDCA params
586 * to HAL.
587 */
588 if (direction == SIR_MAC_DIRECTION_UPLINK) {
589 ps_param->ac_admit_mask[SIR_MAC_DIRECTION_UPLINK] |=
590 (1 << ac);
591 } else if (direction == SIR_MAC_DIRECTION_DNLINK) {
592 ps_param->ac_admit_mask[SIR_MAC_DIRECTION_DNLINK] |=
593 (1 << ac);
594 } else if (direction == SIR_MAC_DIRECTION_BIDIR) {
595 ps_param->ac_admit_mask[SIR_MAC_DIRECTION_UPLINK] |=
596 (1 << ac);
597 ps_param->ac_admit_mask[SIR_MAC_DIRECTION_DNLINK] |=
598 (1 << ac);
599 }
600
601 sms_log(mac_ctx, LOG1,
602 FL("New ps_param->uapsd_per_ac_trigger_enable_mask = 0x%x "),
603 ps_param->uapsd_per_ac_trigger_enable_mask);
604 sms_log(mac_ctx, LOG1,
605 FL("New ps_param->uapsd_per_ac_delivery_enable_mask = 0x%x "),
606 ps_param->uapsd_per_ac_delivery_enable_mask);
607 sms_log(mac_ctx, LOG1,
608 FL("New ps_param->ac_admit_mask[SIR_MAC_DIRECTION_UPLINK] = 0x%x "),
609 ps_param->ac_admit_mask[SIR_MAC_DIRECTION_UPLINK]);
610 return;
611}
612
613/**
614 * sme_ps_start_uapsd(): function to start UAPSD.
615 * @hal_ctx: global hal_handle
616 * @session_id: session id
617 * @uapsd_start_ind_cb: uapsd start indiation cb
618 * @callback_context: callback context
619 *
620 * Return: CDF_STATUS
621 */
622CDF_STATUS sme_ps_start_uapsd(tHalHandle hal_ctx, uint32_t session_id,
623 uapsd_start_indication_cb uapsd_start_ind_cb,
624 void *callback_context)
625{
626 CDF_STATUS status = CDF_STATUS_E_FAILURE;
627 status = sme_ps_uapsd_enable(hal_ctx, session_id);
628 return status;
629}
630
631#ifdef FEATURE_WLAN_SCAN_PNO
632static tSirRetStatus
633sme_populate_mac_header(tpAniSirGlobal mac_ctx,
634 uint8_t *bd,
635 uint8_t type,
636 uint8_t sub_type,
637 tSirMacAddr peer_addr, tSirMacAddr self_mac_addr)
638{
639 tSirRetStatus status_code = eSIR_SUCCESS;
640 tpSirMacMgmtHdr mac_hdr;
641
642 /* / Prepare MAC management header */
643 mac_hdr = (tpSirMacMgmtHdr) (bd);
644
645 /* Prepare FC */
646 mac_hdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
647 mac_hdr->fc.type = type;
648 mac_hdr->fc.subType = sub_type;
649
650 /* Prepare Address 1 */
651 cdf_mem_copy((uint8_t *) mac_hdr->da, (uint8_t *) peer_addr,
652 sizeof(tSirMacAddr));
653
654 sir_copy_mac_addr(mac_hdr->sa, self_mac_addr);
655
656 /* Prepare Address 3 */
657 cdf_mem_copy((uint8_t *) mac_hdr->bssId, (uint8_t *) peer_addr,
658 sizeof(tSirMacAddr));
659 return status_code;
660} /*** sme_populate_mac_header() ***/
661
662static tSirRetStatus
663sme_prepare_probe_req_template(tpAniSirGlobal mac_ctx,
664 uint8_t channel_num,
665 uint32_t dot11mode,
666 tSirMacAddr self_mac_addr,
667 uint8_t *frame,
668 uint16_t *pus_len, tCsrRoamSession *psession)
669{
670 tDot11fProbeRequest pr;
671 uint32_t status, bytes, payload;
672 tSirRetStatus sir_status;
673 /*Bcast tx */
674 tSirMacAddr bss_id = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
675 /**
676 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
677 * and then hand it off to 'dot11f_pack_probe_request' (for
678 * serialization). We start by zero-initializing the structure:
679 */
680 cdf_mem_set((uint8_t *) &pr, sizeof(pr), 0);
681
682 populate_dot11f_supp_rates(mac_ctx, channel_num, &pr.SuppRates, NULL);
683
684 if (WNI_CFG_DOT11_MODE_11B != dot11mode) {
685 populate_dot11f_ext_supp_rates1(mac_ctx, channel_num,
686 &pr.ExtSuppRates);
687 }
688
689 if (IS_DOT11_MODE_HT(dot11mode)) {
690 populate_dot11f_ht_caps(mac_ctx, NULL, &pr.HTCaps);
691 pr.HTCaps.advCodingCap = psession->htConfig.ht_rx_ldpc;
692 pr.HTCaps.txSTBC = psession->htConfig.ht_tx_stbc;
693 pr.HTCaps.rxSTBC = psession->htConfig.ht_rx_stbc;
694 if (!psession->htConfig.ht_sgi)
695 pr.HTCaps.shortGI20MHz = pr.HTCaps.shortGI40MHz = 0;
696 }
697 /**
698 * That's it-- now we pack it. First, how much space are we going to
699 * need?
700 */
701 status = dot11f_get_packed_probe_request_size(mac_ctx, &pr, &payload);
702 if (DOT11F_FAILED(status)) {
703 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
704 FL("Failed to calculate the packed size for a Probe Request (0x%08x)."),
705 status);
706
707 /* We'll fall back on the worst case scenario: */
708 payload = sizeof(tDot11fProbeRequest);
709 } else if (DOT11F_WARNED(status)) {
710 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
711 FL("There were warnings while calculating the packed size for a Probe Request (0x%08x)."),
712 status);
713 }
714
715 bytes = payload + sizeof(tSirMacMgmtHdr);
716
717 /* Prepare outgoing frame */
718 cdf_mem_set(frame, bytes, 0);
719
720 /* Next, we fill out the buffer descriptor: */
721 sir_status = sme_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
722 SIR_MAC_MGMT_PROBE_REQ, bss_id,
723 self_mac_addr);
724
725 if (eSIR_SUCCESS != sir_status) {
726 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
727 FL("Failed to populate the buffer descriptor for a Probe Request (%d)."),
728 sir_status);
729 return sir_status; /* allocated! */
730 }
731 /* That done, pack the Probe Request: */
732 status = dot11f_pack_probe_request(mac_ctx, &pr, frame +
733 sizeof(tSirMacMgmtHdr),
734 payload, &payload);
735 if (DOT11F_FAILED(status)) {
736 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
737 "Failed to pack a Probe Request (0x%08x).", status);
738 return eSIR_FAILURE; /* allocated! */
739 } else if (DOT11F_WARNED(status)) {
740 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
741 "There were warnings while packing a Probe Request");
742 }
743
744 *pus_len = payload + sizeof(tSirMacMgmtHdr);
745 return eSIR_SUCCESS;
746} /* End sme_prepare_probe_req_template. */
747
748CDF_STATUS sme_set_ps_preferred_network_list(tHalHandle hal_ctx,
749 tpSirPNOScanReq request,
750 uint8_t session_id,
751 preferred_network_found_ind_cb callback_routine,
752 void *callback_context)
753{
754 tpSirPNOScanReq request_buf;
755 cds_msg_t msg;
756 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
757 tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
758 uint8_t uc_dot11_mode;
759
760 if (NULL == session) {
761 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
762 "%s: session is NULL", __func__);
763 return CDF_STATUS_E_FAILURE;
764 }
765 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
766 "%s: SSID = 0x%08x%08x%08x%08x%08x%08x%08x%08x, 0x%08x%08x%08x%08x%08x%08x%08x%08x", __func__,
767 *((uint32_t *) &request->aNetworks[0].ssId.ssId[0]),
768 *((uint32_t *) &request->aNetworks[0].ssId.ssId[4]),
769 *((uint32_t *) &request->aNetworks[0].ssId.ssId[8]),
770 *((uint32_t *) &request->aNetworks[0].ssId.ssId[12]),
771 *((uint32_t *) &request->aNetworks[0].ssId.ssId[16]),
772 *((uint32_t *) &request->aNetworks[0].ssId.ssId[20]),
773 *((uint32_t *) &request->aNetworks[0].ssId.ssId[24]),
774 *((uint32_t *) &request->aNetworks[0].ssId.ssId[28]),
775 *((uint32_t *) &request->aNetworks[1].ssId.ssId[0]),
776 *((uint32_t *) &request->aNetworks[1].ssId.ssId[4]),
777 *((uint32_t *) &request->aNetworks[1].ssId.ssId[8]),
778 *((uint32_t *) &request->aNetworks[1].ssId.ssId[12]),
779 *((uint32_t *) &request->aNetworks[1].ssId.ssId[16]),
780 *((uint32_t *) &request->aNetworks[1].ssId.ssId[20]),
781 *((uint32_t *) &request->aNetworks[1].ssId.ssId[24]),
782 *((uint32_t *) &request->aNetworks[1].ssId.ssId[28]));
783
784 if (!session) {
785 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
786 "%s: session is NULL", __func__);
787 return CDF_STATUS_E_FAILURE;
788 }
789
790 request_buf = cdf_mem_malloc(sizeof(tSirPNOScanReq));
791 if (NULL == request_buf) {
792 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
793 FL("Not able to allocate memory for PNO request"));
794 return CDF_STATUS_E_NOMEM;
795 }
796
797 cdf_mem_copy(request_buf, request, sizeof(tSirPNOScanReq));
798
799 /*Must translate the mode first */
800 uc_dot11_mode = (uint8_t) csr_translate_to_wni_cfg_dot11_mode(mac_ctx,
801 csr_find_best_phy_mode
802 (mac_ctx,
803 mac_ctx->roam.
804 configParam.
805 phyMode));
806
807 /*Prepare a probe request for 2.4GHz band and one for 5GHz band */
808 if (eSIR_SUCCESS ==
809 sme_prepare_probe_req_template(mac_ctx,
810 SIR_PNO_24G_DEFAULT_CH,
811 uc_dot11_mode, session->selfMacAddr.bytes,
812 request_buf->p24GProbeTemplate,
813 &request_buf->us24GProbeTemplateLen,
814 session)) {
815 /* Append IE passed by supplicant(if any)
816 * to probe request
817 */
818 if ((0 < request->us24GProbeTemplateLen) &&
819 ((request_buf->us24GProbeTemplateLen +
820 request->us24GProbeTemplateLen) <
821 SIR_PNO_MAX_PB_REQ_SIZE)) {
822 cdf_mem_copy((uint8_t *) &request_buf->
823 p24GProbeTemplate +
824 request_buf->us24GProbeTemplateLen,
825 (uint8_t *) &request->p24GProbeTemplate,
826 request->us24GProbeTemplateLen);
827 request_buf->us24GProbeTemplateLen +=
828 request->us24GProbeTemplateLen;
829 CDF_TRACE(CDF_MODULE_ID_SME,
830 CDF_TRACE_LEVEL_INFO,
831 FL("request->us24GProbeTemplateLen = %d"),
832 request->us24GProbeTemplateLen);
833 } else {
834 CDF_TRACE(CDF_MODULE_ID_SME,
835 CDF_TRACE_LEVEL_INFO,
836 FL("Extra ie discarded on 2.4G, IE len = %d"),
837 request->us24GProbeTemplateLen);
838 }
839 }
840
841 if (eSIR_SUCCESS ==
842 sme_prepare_probe_req_template(mac_ctx,
843 SIR_PNO_5G_DEFAULT_CH, uc_dot11_mode,
844 session->selfMacAddr.bytes,
845 request_buf->p5GProbeTemplate,
846 &request_buf->us5GProbeTemplateLen,
847 session)) {
848 /* Append IE passed by supplicant(if any)
849 * to probe request
850 */
851 if ((0 < request->us5GProbeTemplateLen) &&
852 ((request_buf->us5GProbeTemplateLen +
853 request->us5GProbeTemplateLen) <
854 SIR_PNO_MAX_PB_REQ_SIZE)) {
855 cdf_mem_copy((uint8_t *) &request_buf->
856 p5GProbeTemplate +
857 request_buf->us5GProbeTemplateLen,
858 (uint8_t *) &request->p5GProbeTemplate,
859 request->us5GProbeTemplateLen);
860 request_buf->us5GProbeTemplateLen +=
861 request->us5GProbeTemplateLen;
862 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
863 FL("request_buf->us5GProbeTemplateLen = %d"),
864 request->us5GProbeTemplateLen);
865 } else {
866 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
867 FL("Extra IE discarded on 5G, IE length = %d"),
868 request->us5GProbeTemplateLen);
869 }
870 }
871
872 if (mac_ctx->pnoOffload) {
873 if (request_buf->enable)
874 session->pnoStarted = true;
875 else
876 session->pnoStarted = false;
877
878 request_buf->sessionId = session_id;
879 }
880
881 msg.type = WMA_SET_PNO_REQ;
882 msg.reserved = 0;
883 msg.bodyptr = request_buf;
884 if (!CDF_IS_STATUS_SUCCESS
885 (cds_mq_post_message(CDF_MODULE_ID_WMA, &msg))) {
886 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
887 FL("Not able to post WMA_SET_PNO_REQ message to WMA"));
888 cdf_mem_free(request_buf);
889 return CDF_STATUS_E_FAILURE;
890 }
891
892 /* Cache the Preferred Network Found Indication callback information */
893 mac_ctx->sme.pref_netw_found_cb =
894 callback_routine;
895 mac_ctx->sme.preferred_network_found_ind_cb_ctx =
896 callback_context;
897
898 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO, "-%s", __func__);
899
900 return CDF_STATUS_SUCCESS;
901}
902#endif /* FEATURE_WLAN_SCAN_PNO */
903
904/**
905 * sme_set_ps_host_offload(): Set the host offload feature.
906 * @hal_ctx - The handle returned by mac_open.
907 * @request - Pointer to the offload request.
908 *
909 * Return CDF_STATUS
910 * CDF_STATUS_E_FAILURE Cannot set the offload.
911 * CDF_STATUS_SUCCESS Request accepted.
912 */
913CDF_STATUS sme_set_ps_host_offload(tHalHandle hal_ctx,
914 tpSirHostOffloadReq request,
915 uint8_t session_id)
916{
917 tpSirHostOffloadReq request_buf;
918 cds_msg_t msg;
919 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
920 tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
921
922 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
923 "%s: IP address = %d.%d.%d.%d", __func__,
924 request->params.hostIpv4Addr[0],
925 request->params.hostIpv4Addr[1],
926 request->params.hostIpv4Addr[2],
927 request->params.hostIpv4Addr[3]);
928
929 if (NULL == session) {
930 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
931 "%s: SESSION not Found", __func__);
932 return CDF_STATUS_E_FAILURE;
933 }
934
935 request_buf = cdf_mem_malloc(sizeof(tSirHostOffloadReq));
936 if (NULL == request_buf) {
937 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
938 FL("Not able to allocate memory for host offload request"));
939 return CDF_STATUS_E_NOMEM;
940 }
941
942 cdf_mem_copy(request->bssId, session->connectedProfile.bssid.bytes,
943 sizeof(tSirMacAddr));
944
945 cdf_mem_copy(request_buf, request, sizeof(tSirHostOffloadReq));
946
947 msg.type = WMA_SET_HOST_OFFLOAD;
948 msg.reserved = 0;
949 msg.bodyptr = request_buf;
950 if (CDF_STATUS_SUCCESS !=
951 cds_mq_post_message(CDF_MODULE_ID_WMA, &msg)) {
952 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
953 FL("Not able to post WMA_SET_HOST_OFFLOAD msg to WMA"));
954 cdf_mem_free(request_buf);
955 return CDF_STATUS_E_FAILURE;
956 }
957
958 return CDF_STATUS_SUCCESS;
959}
960
961#ifdef WLAN_NS_OFFLOAD
962/**
963 * sme_set_ps_ns_offload(): Set the host offload feature.
964 * @hal_ctx - The handle returned by mac_open.
965 * @request - Pointer to the offload request.
966 *
967 * Return CDF_STATUS
968 * CDF_STATUS_E_FAILURE Cannot set the offload.
969 * CDF_STATUS_SUCCESS Request accepted.
970 */
971CDF_STATUS sme_set_ps_ns_offload(tHalHandle hal_ctx,
972 tpSirHostOffloadReq request,
973 uint8_t session_id)
974{
975 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
976 tpSirHostOffloadReq request_buf;
977 cds_msg_t msg;
978 tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
979
980 if (NULL == session) {
981 sms_log(mac_ctx, LOGE, FL("Session not found "));
982 return CDF_STATUS_E_FAILURE;
983 }
984
985 cdf_mem_copy(request->bssId, session->connectedProfile.bssid.bytes,
986 sizeof(tSirMacAddr));
987
988 request_buf = cdf_mem_malloc(sizeof(*request_buf));
989 if (NULL == request_buf) {
990 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
991 FL("Not able to allocate memory for NS offload request"));
992 return CDF_STATUS_E_NOMEM;
993 }
994 *request_buf = *request;
995
996 msg.type = WMA_SET_NS_OFFLOAD;
997 msg.reserved = 0;
998 msg.bodyptr = request_buf;
999 if (CDF_STATUS_SUCCESS !=
1000 cds_mq_post_message(CDF_MODULE_ID_WMA, &msg)) {
1001 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
1002 FL("Not able to post SIR_HAL_SET_HOST_OFFLOAD message to HAL"));
1003 cdf_mem_free(request_buf);
1004 return CDF_STATUS_E_FAILURE;
1005 }
1006
1007 return CDF_STATUS_SUCCESS;
1008}
1009
1010#endif /* WLAN_NS_OFFLOAD */
1011/* -------------------------------------------------------------------- */
1012/**
1013 * sme_post_pe_message
1014 *
1015 * FUNCTION:
1016 * Post a message to the pmm message queue
1017 *
1018 * LOGIC:
1019 *
1020 * ASSUMPTIONS:
1021 *
1022 * NOTE:
1023 *
1024 * @param msg pointer to message
1025 * @return None
1026 */
1027
1028tSirRetStatus sme_post_pe_message(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
1029{
1030 CDF_STATUS cdf_status;
1031 cdf_status = cds_mq_post_message(CDS_MQ_ID_PE, (cds_msg_t *) msg);
1032 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1033 sms_log(mac_ctx, LOGP,
1034 FL("cds_mq_post_message failed with status code %d"),
1035 cdf_status);
1036 return eSIR_FAILURE;
1037 }
1038
1039 return eSIR_SUCCESS;
1040}
1041
1042CDF_STATUS sme_ps_enable_auto_ps_timer(tHalHandle hal_ctx,
1043 uint32_t session_id,
1044 bool is_reassoc)
1045{
1046 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
1047 struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
1048 struct ps_params *ps_param = &ps_global_info->ps_params[session_id];
1049 CDF_STATUS cdf_status;
1050 uint32_t timer_value;
1051
1052 if (is_reassoc)
1053 timer_value = AUTO_PS_ENTRY_TIMER_DEFAULT_VALUE;
1054 else
1055 timer_value = AUTO_DEFERRED_PS_ENTRY_TIMER_DEFAULT_VALUE;
1056
1057 sms_log(mac_ctx, LOGE, FL("Start auto_ps_timer for %d is_reassoc:%d "),
1058 timer_value, is_reassoc);
1059
1060 cdf_status = cdf_mc_timer_start(&ps_param->auto_ps_enable_timer,
1061 timer_value);
1062 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1063 if (CDF_STATUS_E_ALREADY == cdf_status) {
1064 /* Consider this ok since the timer is already started*/
1065 sms_log(mac_ctx, LOGW,
1066 FL("auto_ps_timer is already started"));
1067 } else {
1068 sms_log(mac_ctx, LOGP,
1069 FL("Cannot start auto_ps_timer"));
1070 return CDF_STATUS_E_FAILURE;
1071 }
1072 }
1073 return CDF_STATUS_SUCCESS;
1074}
1075
1076CDF_STATUS sme_ps_disable_auto_ps_timer(tHalHandle hal_ctx,
1077 uint32_t session_id)
1078{
1079 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
1080 struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
1081 struct ps_params *ps_param = &ps_global_info->ps_params[session_id];
1082 /*
1083 * Stop the auto ps entry timer if runnin
1084 */
1085 if (CDF_TIMER_STATE_RUNNING ==
1086 cdf_mc_timer_get_current_state(
1087 &ps_param->auto_ps_enable_timer)) {
1088 sms_log(mac_ctx, LOGE,
1089 FL("Stop auto_ps_enable_timer Timer for session ID:%d "),
1090 session_id);
1091 cdf_mc_timer_stop(&ps_param->auto_ps_enable_timer);
1092 }
1093 return CDF_STATUS_SUCCESS;
1094}
1095
1096
1097CDF_STATUS sme_ps_open(tHalHandle hal_ctx)
1098{
1099
1100 uint32_t i;
1101 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
1102
1103 sms_log(mac_ctx, LOG1, FL("Enter"));
1104
1105 for (i = 0; i < MAX_SME_SESSIONS; i++) {
1106 if (CDF_STATUS_SUCCESS != sme_ps_open_per_session(hal_ctx, i)) {
1107 sms_log(mac_ctx, LOGE,
1108 FL("PMC Init Failed for session %d"), i);
1109 return CDF_STATUS_E_FAILURE;
1110 }
1111 }
1112 return CDF_STATUS_SUCCESS;
1113}
1114
1115
1116CDF_STATUS sme_ps_open_per_session(tHalHandle hal_ctx, uint32_t session_id)
1117{
1118 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
1119 struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
1120 struct ps_params *ps_param = &ps_global_info->ps_params[session_id];
1121 ps_param->session_id = session_id;
1122 ps_param->mac_ctx = mac_ctx;
1123
1124 sms_log(mac_ctx, LOG1, FL("Enter"));
1125 /* Allocate a timer to enable ps automatically */
1126 if (!CDF_IS_STATUS_SUCCESS(cdf_mc_timer_init(
1127 &ps_param->auto_ps_enable_timer,
1128 CDF_TIMER_TYPE_SW,
1129 sme_auto_ps_entry_timer_expired,
1130 ps_param))) {
1131 sms_log(mac_ctx, LOGE,
1132 FL("Cannot allocate timer for auto ps entry"));
1133 return CDF_STATUS_E_FAILURE;
1134 }
1135 return CDF_STATUS_SUCCESS;
1136
1137}
1138
1139void sme_auto_ps_entry_timer_expired(void *data)
1140{
1141 struct ps_params *ps_params = (struct ps_params *)data;
1142 tpAniSirGlobal mac_ctx = (tpAniSirGlobal)ps_params->mac_ctx;
1143 uint32_t session_id = ps_params->session_id;
1144 CDF_STATUS status = CDF_STATUS_SUCCESS;
1145 status = sme_enable_sta_ps_check(mac_ctx, session_id);
1146
1147 if (CDF_STATUS_SUCCESS == status) {
1148 sme_ps_enable_disable((tHalHandle)mac_ctx, session_id,
1149 SME_PS_ENABLE);
1150 } else {
1151 status =
1152 cdf_mc_timer_start(&ps_params->auto_ps_enable_timer,
1153 AUTO_PS_ENTRY_TIMER_DEFAULT_VALUE);
1154 if (!CDF_IS_STATUS_SUCCESS(status)
1155 && (CDF_STATUS_E_ALREADY != status)) {
1156 sms_log(mac_ctx, LOGP,
1157 FL("Cannot start traffic timer"));
1158 }
1159 }
1160}
1161
1162CDF_STATUS sme_ps_close(tHalHandle hal_ctx)
1163{
1164 uint32_t i;
1165 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
1166
1167 sms_log(mac_ctx, LOG2, FL("Enter"));
1168
1169 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++)
1170 sme_ps_close_per_session(hal_ctx, i);
1171 return CDF_STATUS_SUCCESS;
1172}
1173
1174CDF_STATUS sme_ps_close_per_session(tHalHandle hal_ctx, uint32_t session_id)
1175{
1176
1177 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
1178 struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
1179 struct ps_params *ps_param = &ps_global_info->ps_params[session_id];
1180 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
1181
1182 /*
1183 * Stop the auto ps entry timer if running
1184 */
1185 if (CDF_TIMER_STATE_RUNNING ==
1186 cdf_mc_timer_get_current_state(
1187 &ps_param->auto_ps_enable_timer)) {
1188 cdf_mc_timer_stop(&ps_param->auto_ps_enable_timer);
1189 }
1190 cdf_status =
1191 cdf_mc_timer_destroy(&ps_param->auto_ps_enable_timer);
1192 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
1193 sms_log(mac_ctx, LOGE, FL("Cannot deallocate suto PS timer"));
1194 return cdf_status;
1195}
1196
1197CDF_STATUS sme_is_auto_ps_timer_running(tHalHandle hal_ctx,
1198 uint32_t session_id)
1199{
1200 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
1201 struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
1202 struct ps_params *ps_param = &ps_global_info->ps_params[session_id];
1203 bool status = false;
1204 /*
1205 * Check if the auto ps entry timer if running
1206 */
1207 if (CDF_TIMER_STATE_RUNNING ==
1208 cdf_mc_timer_get_current_state(
1209 &ps_param->auto_ps_enable_timer)) {
1210 status = true;
1211 }
1212 return status;
1213}
1214