blob: 7768fb610d380f5bf9b9cc017647d0492c2ac778 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam0fb93dd2014-02-19 00:32:59 -08002 * Copyright (c) 2012-2014 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.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam0fb93dd2014-02-19 00:32:59 -080021
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
Jeff Johnson295189b2012-06-20 16:38:30 -070028/**=========================================================================
Kiet Lamaa8e15a2014-02-11 23:30:06 -080029
Jeff Johnson295189b2012-06-20 16:38:30 -070030 \file sme_Qos.c
Kiet Lamaa8e15a2014-02-11 23:30:06 -080031
Jeff Johnson295189b2012-06-20 16:38:30 -070032 \brief implementation for SME QoS APIs
Kiet Lamaa8e15a2014-02-11 23:30:06 -080033
34
Jeff Johnson295189b2012-06-20 16:38:30 -070035 ========================================================================*/
36/* $Header$ */
37/*--------------------------------------------------------------------------
38 Include Files
39 ------------------------------------------------------------------------*/
40
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnson295189b2012-06-20 16:38:30 -070042#include "aniGlobal.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44#include "smeInside.h"
45#include "vos_diag_core_event.h"
46#include "vos_diag_core_log.h"
47
48#ifdef WLAN_FEATURE_VOWIFI_11R
49#include "smsDebug.h"
50#include "utilsParser.h"
51#endif
Srinivas Girigowda5cecb202013-10-08 09:13:25 -070052#if defined(FEATURE_WLAN_CCX) && !defined(FEATURE_WLAN_CCX_UPLOAD)
Jeff Johnson295189b2012-06-20 16:38:30 -070053#include <csrCcx.h>
54#endif
55
56#ifndef WLAN_MDM_CODE_REDUCTION_OPT
57/* TODO : 6Mbps as Cisco APs seem to like only this value; analysis req. */
58#define SME_QOS_MIN_PHY_RATE 0x5B8D80
59#define SME_QOS_SURPLUS_BW_ALLOWANCE 0x2000 /* Ratio of 1.0 */
60/*---------------------------------------------------------------------------
61 Max values to bound tspec params against and avoid rollover
62---------------------------------------------------------------------------*/
63#define SME_QOS_32BIT_MAX 0xFFFFFFFF
64#define SME_QOS_16BIT_MAX 0xFFFF
65#define SME_QOS_16BIT_MSB 0x8000
66/*---------------------------------------------------------------------------
67 Adds y to x, but saturates at 32-bit max to avoid rollover
68---------------------------------------------------------------------------*/
69#define SME_QOS_BOUNDED_U32_ADD_Y_TO_X( _x, _y ) \
70 do \
71 { \
72 (_x) = ( (SME_QOS_32BIT_MAX-(_x))<(_y) ) ? \
73 (SME_QOS_32BIT_MAX) : (_x)+(_y); \
74 } while(0)
75/*---------------------------------------------------------------------------
76 As per WMM spec there could be max 2 TSPEC running on the same AC with
77 different direction. We will refer each TSPEC with an index
78---------------------------------------------------------------------------*/
79#define SME_QOS_TSPEC_INDEX_0 0
80#define SME_QOS_TSPEC_INDEX_1 1
81#define SME_QOS_TSPEC_INDEX_MAX 2
82#define SME_QOS_TSPEC_MASK_BIT_1_SET 1
83#define SME_QOS_TSPEC_MASK_BIT_2_SET 2
84#define SME_QOS_TSPEC_MASK_BIT_1_2_SET 3
85#define SME_QOS_TSPEC_MASK_CLEAR 0
86
87//which key to search on, in the flowlist (1 = flowID, 2 = AC, 4 = reason)
88#define SME_QOS_SEARCH_KEY_INDEX_1 1
89#define SME_QOS_SEARCH_KEY_INDEX_2 2
90#define SME_QOS_SEARCH_KEY_INDEX_3 4
91#define SME_QOS_SEARCH_KEY_INDEX_4 8 // ac + direction
92#define SME_QOS_SEARCH_KEY_INDEX_5 0x10 // ac + tspec_mask
93//special value for searching any Session Id
94#define SME_QOS_SEARCH_SESSION_ID_ANY CSR_ROAM_SESSION_MAX
95#define SME_QOS_ACCESS_POLICY_EDCA 1
96#define SME_QOS_MAX_TID 255
97#define SME_QOS_TSPEC_IE_LENGTH 61
98#define SME_QOS_TSPEC_IE_TYPE 2
99#define SME_QOS_MIN_FLOW_ID 1
100#define SME_QOS_MAX_FLOW_ID 0xFFFFFFFE
101#define SME_QOS_INVALID_FLOW_ID 0xFFFFFFFF
102// per the WMM Specification v1.2 Section 2.2.10
103// The Dialog Token field shall be set [...] to a non-zero value
104#define SME_QOS_MIN_DIALOG_TOKEN 1
105#define SME_QOS_MAX_DIALOG_TOKEN 0xFF
106/*--------------------------------------------------------------------------
107 Type declarations
108 ------------------------------------------------------------------------*/
109/*---------------------------------------------------------------------------
110 Enumeration of the various states in the QoS state m/c
111---------------------------------------------------------------------------*/
112typedef enum
113{
114 SME_QOS_CLOSED = 0,
115 SME_QOS_INIT,
116 SME_QOS_LINK_UP,
117 SME_QOS_REQUESTED,
118 SME_QOS_QOS_ON,
119 SME_QOS_HANDOFF,
120
121}sme_QosStates;
122/*---------------------------------------------------------------------------
Madan Mohan Koyyalamudic0a75a42013-10-07 04:20:49 +0530123 Enumeration of the various Release QoS trigger
124---------------------------------------------------------------------------*/
125typedef enum
126{
127 SME_QOS_RELEASE_DEFAULT = 0,
128 SME_QOS_RELEASE_BY_AP,
129}sme_QosRelTriggers;
130/*---------------------------------------------------------------------------
Jeff Johnson295189b2012-06-20 16:38:30 -0700131 Enumeration of the various QoS cmds
132---------------------------------------------------------------------------*/
133typedef enum
134{
135 SME_QOS_SETUP_REQ = 0,
136 SME_QOS_RELEASE_REQ,
137 SME_QOS_MODIFY_REQ,
138 SME_QOS_RESEND_REQ,
139 SME_QOS_CMD_MAX
140}sme_QosCmdType;
141/*---------------------------------------------------------------------------
142 Enumeration of the various QoS reason codes to be used in the Flow list
143---------------------------------------------------------------------------*/
144typedef enum
145{
146 SME_QOS_REASON_SETUP = 0,
147 SME_QOS_REASON_RELEASE,
148 SME_QOS_REASON_MODIFY,
149 SME_QOS_REASON_MODIFY_PENDING,
150 SME_QOS_REASON_REQ_SUCCESS,
151 SME_QOS_REASON_MAX
152}sme_QosReasonType;
153
154/*---------------------------------------------------------------------------
155 Table to map user priority passed in as an argument to appropriate Access
156 Category as specified in 802.11e/WMM
157---------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi4f2a39f2013-08-13 23:04:47 +0530158sme_QosEdcaAcType sme_QosUPtoACMap[SME_QOS_WMM_UP_MAX] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700159{
160 SME_QOS_EDCA_AC_BE, /* User Priority 0 */
161 SME_QOS_EDCA_AC_BK, /* User Priority 1 */
162 SME_QOS_EDCA_AC_BK, /* User Priority 2 */
163 SME_QOS_EDCA_AC_BE, /* User Priority 3 */
164 SME_QOS_EDCA_AC_VI, /* User Priority 4 */
165 SME_QOS_EDCA_AC_VI, /* User Priority 5 */
166 SME_QOS_EDCA_AC_VO, /* User Priority 6 */
167 SME_QOS_EDCA_AC_VO /* User Priority 7 */
168};
169
170/*---------------------------------------------------------------------------
171 Table to map access category (AC) to appropriate user priority as specified
172 in 802.11e/WMM
173 Note: there is a quantization loss here because 4 ACs are mapped to 8 UPs
174 Mapping is done for consistency
175---------------------------------------------------------------------------*/
176sme_QosWmmUpType sme_QosACtoUPMap[SME_QOS_EDCA_AC_MAX] =
177{
178 SME_QOS_WMM_UP_BE, /* AC BE */
179 SME_QOS_WMM_UP_BK, /* AC BK */
180 SME_QOS_WMM_UP_VI, /* AC VI */
181 SME_QOS_WMM_UP_VO /* AC VO */
182};
183/*---------------------------------------------------------------------------
184DESCRIPTION
185 SME QoS module's FLOW Link List structure. This list can hold information per
186 flow/request, like TSPEC params requested, which AC it is running on
187---------------------------------------------------------------------------*/
188typedef struct sme_QosFlowInfoEntry_s
189{
190 tListElem link; /* list links */
191 v_U8_t sessionId;
192 v_U8_t tspec_mask;
193 sme_QosReasonType reason;
194 v_U32_t QosFlowID;
195 sme_QosEdcaAcType ac_type;
196 sme_QosWmmTspecInfo QoSInfo;
197 void * HDDcontext;
198 sme_QosCallback QoSCallback;
199 v_BOOL_t hoRenewal;//set to TRUE while re-negotiating flows after
200 //handoff, will set to FALSE once done with
201 //the process. Helps SME to decide if at all
202 //to notify HDD/LIS for flow renewal after HO
203} sme_QosFlowInfoEntry;
204/*---------------------------------------------------------------------------
205DESCRIPTION
206 SME QoS module's setup request cmd related information structure.
207---------------------------------------------------------------------------*/
208typedef struct sme_QosSetupCmdInfo_s
209{
210 v_U32_t QosFlowID;
211 sme_QosWmmTspecInfo QoSInfo;
212 void *HDDcontext;
213 sme_QosCallback QoSCallback;
214 sme_QosWmmUpType UPType;
215 v_BOOL_t hoRenewal;//set to TRUE while re-negotiating flows after
216 //handoff, will set to FALSE once done with
217 //the process. Helps SME to decide if at all
218 //to notify HDD/LIS for flow renewal after HO
219} sme_QosSetupCmdInfo;
220/*---------------------------------------------------------------------------
221DESCRIPTION
222 SME QoS module's modify cmd related information structure.
223---------------------------------------------------------------------------*/
224typedef struct sme_QosModifyCmdInfo_s
225{
226 v_U32_t QosFlowID;
227 sme_QosEdcaAcType ac;
228 sme_QosWmmTspecInfo QoSInfo;
229} sme_QosModifyCmdInfo;
230/*---------------------------------------------------------------------------
231DESCRIPTION
232 SME QoS module's resend cmd related information structure.
233---------------------------------------------------------------------------*/
234typedef struct sme_QosResendCmdInfo_s
235{
236 v_U8_t tspecMask;
237 sme_QosEdcaAcType ac;
238 sme_QosWmmTspecInfo QoSInfo;
239} sme_QosResendCmdInfo;
240/*---------------------------------------------------------------------------
241DESCRIPTION
242 SME QoS module's release cmd related information structure.
243---------------------------------------------------------------------------*/
244typedef struct sme_QosReleaseCmdInfo_s
245{
246 v_U32_t QosFlowID;
247} sme_QosReleaseCmdInfo;
248/*---------------------------------------------------------------------------
249DESCRIPTION
250 SME QoS module's buffered cmd related information structure.
251---------------------------------------------------------------------------*/
252typedef struct sme_QosCmdInfo_s
253{
254 sme_QosCmdType command;
255 tpAniSirGlobal pMac;
256 v_U8_t sessionId;
257 union
258 {
259 sme_QosSetupCmdInfo setupCmdInfo;
260 sme_QosModifyCmdInfo modifyCmdInfo;
261 sme_QosResendCmdInfo resendCmdInfo;
262 sme_QosReleaseCmdInfo releaseCmdInfo;
263 }u;
264} sme_QosCmdInfo;
265/*---------------------------------------------------------------------------
266DESCRIPTION
267 SME QoS module's buffered cmd List structure. This list can hold information
268 related to any pending cmd from HDD
269---------------------------------------------------------------------------*/
270typedef struct sme_QosCmdInfoEntry_s
271{
272 tListElem link; /* list links */
273 sme_QosCmdInfo cmdInfo;
274} sme_QosCmdInfoEntry;
275/*---------------------------------------------------------------------------
276DESCRIPTION
277 SME QoS module's Per AC information structure. This can hold information on
278 how many flows running on the AC, the current, previous states the AC is in
279---------------------------------------------------------------------------*/
280typedef struct sme_QosACInfo_s
281{
282 v_U8_t num_flows[SME_QOS_TSPEC_INDEX_MAX];
283 sme_QosStates curr_state;
284 sme_QosStates prev_state;
285 sme_QosWmmTspecInfo curr_QoSInfo[SME_QOS_TSPEC_INDEX_MAX];
286 sme_QosWmmTspecInfo requested_QoSInfo[SME_QOS_TSPEC_INDEX_MAX];
287 v_BOOL_t reassoc_pending;//reassoc requested for APSD
288 //As per WMM spec there could be max 2 TSPEC running on the same AC with
289 //different direction. We will refer each TSPEC with an index
290 v_U8_t tspec_mask_status; //status showing if both the indices are in use
291 v_U8_t tspec_pending;//tspec negotiation going on for which index
292 v_BOOL_t hoRenewal;//set to TRUE while re-negotiating flows after
293 //handoff, will set to FALSE once done with
294 //the process. Helps SME to decide if at all
295 //to notify HDD/LIS for flow renewal after HO
296#ifdef WLAN_FEATURE_VOWIFI_11R
297 v_U8_t ricIdentifier[SME_QOS_TSPEC_INDEX_MAX];
298 /* stores the ADD TS response for each AC. The ADD TS response is formed by
299 parsing the RIC received in the the reassoc response */
300 tSirAddtsRsp addTsRsp[SME_QOS_TSPEC_INDEX_MAX];
301#endif
Madan Mohan Koyyalamudic0a75a42013-10-07 04:20:49 +0530302 sme_QosRelTriggers relTrig;
Jeff Johnson295189b2012-06-20 16:38:30 -0700303
304} sme_QosACInfo;
305/*---------------------------------------------------------------------------
306DESCRIPTION
307 SME QoS module's Per session information structure. This can hold information
308 on the state of the session
309---------------------------------------------------------------------------*/
310typedef struct sme_QosSessionInfo_s
311{
312 // what is this entry's session id
313 v_U8_t sessionId;
314 // is the session currently active
315 v_BOOL_t sessionActive;
316 // All AC info for this session
317 sme_QosACInfo ac_info[SME_QOS_EDCA_AC_MAX];
318 // Bitmask of the ACs with APSD on
319 // Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored
320 v_U8_t apsdMask;
321 // association information for this session
322 sme_QosAssocInfo assocInfo;
323 // ID assigned to our reassoc request
324 v_U32_t roamID;
325 // maintaining a powersave status in QoS module, to be fed back to PMC at
326 // times through the sme_QosPmcCheckRoutine
327 v_BOOL_t readyForPowerSave;
328 // are we in the process of handing off to a different AP
329 v_BOOL_t handoffRequested;
330 // following reassoc or AddTS has UAPSD already been requested from PMC
331 v_BOOL_t uapsdAlreadyRequested;
332 // commands that are being buffered for this session
333 tDblLinkList bufferedCommandList;
334
335#ifdef WLAN_FEATURE_VOWIFI_11R
336 v_BOOL_t ftHandoffInProgress;
337#endif
338
339} sme_QosSessionInfo;
340/*---------------------------------------------------------------------------
341DESCRIPTION
342 Search key union. We can use the flowID, ac type, or reason to find an entry
343 in the flow list
344---------------------------------------------------------------------------*/
345typedef union sme_QosSearchKey_s
346{
347 v_U32_t QosFlowID;
348 sme_QosEdcaAcType ac_type;
349 sme_QosReasonType reason;
350}sme_QosSearchKey;
351/*---------------------------------------------------------------------------
352DESCRIPTION
353 We can either use the flowID or the ac type to find an entry in the flow list.
354 The index is a bitmap telling us which key to use. Starting from LSB,
355 bit 0 - Flow ID
356 bit 1 - AC type
357---------------------------------------------------------------------------*/
358typedef struct sme_QosSearchInfo_s
359{
360 v_U8_t sessionId;
361 v_U8_t index;
362 sme_QosSearchKey key;
363 sme_QosWmmDirType direction;
364 v_U8_t tspec_mask;
365}sme_QosSearchInfo;
366/*---------------------------------------------------------------------------
367DESCRIPTION
368 SME QoS module's internal control block.
369---------------------------------------------------------------------------*/
370struct sme_QosCb_s
371{
372 //global Mac pointer
373 tpAniSirGlobal pMac;
374 //All Session Info
375 sme_QosSessionInfo sessionInfo[CSR_ROAM_SESSION_MAX];
376 //All FLOW info
377 tDblLinkList flow_list;
378 //default TSPEC params
379 sme_QosWmmTspecInfo def_QoSInfo[SME_QOS_EDCA_AC_MAX];
380 //counter for assigning Flow IDs
381 v_U32_t nextFlowId;
382 //counter for assigning Dialog Tokens
383 v_U8_t nextDialogToken;
384}sme_QosCb;
385typedef eHalStatus (*sme_QosProcessSearchEntry)(tpAniSirGlobal pMac, tListElem *pEntry);
386/*--------------------------------------------------------------------------
387 Internal function declarations
388 ------------------------------------------------------------------------*/
389sme_QosStatusType sme_QosInternalSetupReq(tpAniSirGlobal pMac,
390 v_U8_t sessionId,
391 sme_QosWmmTspecInfo * pQoSInfo,
392 sme_QosCallback QoSCallback,
393 void * HDDcontext,
394 sme_QosWmmUpType UPType,
395 v_U32_t QosFlowID,
396 v_BOOL_t buffered_cmd,
397 v_BOOL_t hoRenewal);
398sme_QosStatusType sme_QosInternalModifyReq(tpAniSirGlobal pMac,
399 sme_QosWmmTspecInfo * pQoSInfo,
400 v_U32_t QosFlowID,
401 v_BOOL_t buffered_cmd);
402sme_QosStatusType sme_QosInternalReleaseReq(tpAniSirGlobal pMac,
403 v_U32_t QosFlowID,
404 v_BOOL_t buffered_cmd);
405sme_QosStatusType sme_QosSetup(tpAniSirGlobal pMac,
406 v_U8_t sessionId,
407 sme_QosWmmTspecInfo *pTspec_Info,
408 sme_QosEdcaAcType ac);
409eHalStatus sme_QosAddTsReq(tpAniSirGlobal pMac,
410 v_U8_t sessionId,
411 sme_QosWmmTspecInfo * pTspec_Info,
412 sme_QosEdcaAcType ac);
413eHalStatus sme_QosDelTsReq(tpAniSirGlobal pMac,
414 v_U8_t sessionId,
415 sme_QosEdcaAcType ac,
416 v_U8_t tspec_mask);
417eHalStatus sme_QosProcessAddTsRsp(tpAniSirGlobal pMac, void *pMsgBuf);
418eHalStatus sme_QosProcessDelTsInd(tpAniSirGlobal pMac, void *pMsgBuf);
419eHalStatus sme_QosProcessDelTsRsp(tpAniSirGlobal pMac, void *pMsgBuf);
420eHalStatus sme_QosProcessAssocCompleteEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info);
421eHalStatus sme_QosProcessReassocReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info);
422eHalStatus sme_QosProcessReassocSuccessEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info);
423eHalStatus sme_QosProcessReassocFailureEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info);
424eHalStatus sme_QosProcessDisconnectEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info);
425eHalStatus sme_QosProcessJoinReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info);
426eHalStatus sme_QosProcessHandoffAssocReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info);
427eHalStatus sme_QosProcessHandoffSuccessEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info);
428eHalStatus sme_QosProcessHandoffFailureEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info);
429#ifdef WLAN_FEATURE_VOWIFI_11R
430eHalStatus sme_QosProcessPreauthSuccessInd(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info);
431eHalStatus sme_QosProcessSetKeySuccessInd(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info);
432eHalStatus sme_QosProcessAggrQosRsp(tpAniSirGlobal pMac, void *pMsgBuf);
433eHalStatus sme_QosFTAggrQosReq( tpAniSirGlobal pMac, v_U8_t sessionId );
434#endif
435eHalStatus sme_QosProcessAddTsSuccessRsp(tpAniSirGlobal pMac,
436 v_U8_t sessionId,
437 tSirAddtsRspInfo * pRsp);
438eHalStatus sme_QosProcessAddTsFailureRsp(tpAniSirGlobal pMac,
439 v_U8_t sessionId,
440 tSirAddtsRspInfo * pRsp);
441eHalStatus sme_QosAggregateParams(
442 sme_QosWmmTspecInfo * pInput_Tspec_Info,
443 sme_QosWmmTspecInfo * pCurrent_Tspec_Info,
444 sme_QosWmmTspecInfo * pUpdated_Tspec_Info);
445static eHalStatus sme_QosUpdateParams(v_U8_t sessionId,
446 sme_QosEdcaAcType ac,
447 v_U8_t tspec_mask,
448 sme_QosWmmTspecInfo * pTspec_Info);
449sme_QosWmmUpType sme_QosAcToUp(sme_QosEdcaAcType ac);
450sme_QosEdcaAcType sme_QosUpToAc(sme_QosWmmUpType up);
451v_BOOL_t sme_QosIsACM(tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc,
452 sme_QosEdcaAcType ac, tDot11fBeaconIEs *pIes);
453tListElem *sme_QosFindInFlowList(sme_QosSearchInfo search_key);
454eHalStatus sme_QosFindAllInFlowList(tpAniSirGlobal pMac,
455 sme_QosSearchInfo search_key,
456 sme_QosProcessSearchEntry fnp);
457static void sme_QosStateTransition(v_U8_t sessionId,
458 sme_QosEdcaAcType ac,
459 sme_QosStates new_state);
460eHalStatus sme_QosBufferCmd(sme_QosCmdInfo *pcmd, v_BOOL_t insert_head);
461static eHalStatus sme_QosProcessBufferedCmd(v_U8_t sessionId);
462eHalStatus sme_QosSaveAssocInfo(sme_QosSessionInfo *pSession, sme_QosAssocInfo *pAssoc_info);
463eHalStatus sme_QosSetupFnp(tpAniSirGlobal pMac, tListElem *pEntry);
464eHalStatus sme_QosModificationNotifyFnp(tpAniSirGlobal pMac, tListElem *pEntry);
465eHalStatus sme_QosModifyFnp(tpAniSirGlobal pMac, tListElem *pEntry);
466eHalStatus sme_QosDelTsIndFnp(tpAniSirGlobal pMac, tListElem *pEntry);
467eHalStatus sme_QosReassocSuccessEvFnp(tpAniSirGlobal pMac, tListElem *pEntry);
468eHalStatus sme_QosAddTsFailureFnp(tpAniSirGlobal pMac, tListElem *pEntry);
469eHalStatus sme_QosAddTsSuccessFnp(tpAniSirGlobal pMac, tListElem *pEntry);
470static v_BOOL_t sme_QosIsRspPending(v_U8_t sessionId, sme_QosEdcaAcType ac);
471static v_BOOL_t sme_QosIsUapsdActive(void);
472void sme_QosPmcFullPowerCallback(void *callbackContext, eHalStatus status);
473void sme_QosPmcStartUapsdCallback(void *callbackContext, eHalStatus status);
474v_BOOL_t sme_QosPmcCheckRoutine(void *callbackContext);
475void sme_QosPmcDeviceStateUpdateInd(void *callbackContext, tPmcState pmcState);
476eHalStatus sme_QosProcessOutOfUapsdMode(tpAniSirGlobal pMac);
477eHalStatus sme_QosProcessIntoUapsdMode(tpAniSirGlobal pMac);
478static eHalStatus sme_QosBufferExistingFlows(tpAniSirGlobal pMac,
479 v_U8_t sessionId);
480static eHalStatus sme_QosDeleteExistingFlows(tpAniSirGlobal pMac,
481 v_U8_t sessionId);
482static void sme_QosCleanupCtrlBlkForHandoff(tpAniSirGlobal pMac,
483 v_U8_t sessionId);
484static eHalStatus sme_QosDeleteBufferedRequests(tpAniSirGlobal pMac,
485 v_U8_t sessionId);
486v_BOOL_t sme_QosValidateRequestedParams(tpAniSirGlobal pMac,
487 sme_QosWmmTspecInfo * pQoSInfo,
488 v_U8_t sessionId);
489
490extern eHalStatus sme_AcquireGlobalLock( tSmeStruct *psSme);
491extern eHalStatus sme_ReleaseGlobalLock( tSmeStruct *psSme);
492static eHalStatus qosIssueCommand( tpAniSirGlobal pMac, v_U8_t sessionId,
493 eSmeCommandType cmdType, sme_QosWmmTspecInfo * pQoSInfo,
494 sme_QosEdcaAcType ac, v_U8_t tspec_mask );
495/*
496 sme_QosReRequestAddTS to re-send AddTS for the combined QoS request
497*/
498static sme_QosStatusType sme_QosReRequestAddTS(tpAniSirGlobal pMac,
499 v_U8_t sessionId,
500 sme_QosWmmTspecInfo * pQoSInfo,
501 sme_QosEdcaAcType ac,
502 v_U8_t tspecMask);
503static void sme_QosInitACs(tpAniSirGlobal pMac, v_U8_t sessionId);
504static eHalStatus sme_QosRequestReassoc(tpAniSirGlobal pMac, tANI_U8 sessionId,
505 tCsrRoamModifyProfileFields *pModFields,
506 v_BOOL_t fForce );
507static v_U32_t sme_QosAssignFlowId(void);
508static v_U8_t sme_QosAssignDialogToken(void);
509static eHalStatus sme_QosUpdateTspecMask(v_U8_t sessionId,
510 sme_QosSearchInfo search_key,
511 v_U8_t new_tspec_mask);
512/*--------------------------------------------------------------------------
513 External APIs definitions
514 ------------------------------------------------------------------------*/
515/* --------------------------------------------------------------------------
516 \brief sme_QosOpen() - This function must be called before any API call to
517 SME QoS module.
518 \param pMac - Pointer to the global MAC parameter structure.
519
520 \return eHalStatus
521----------------------------------------------------------------------------*/
522eHalStatus sme_QosOpen(tpAniSirGlobal pMac)
523{
524 sme_QosSessionInfo *pSession;
525 v_U8_t sessionId;
526 eHalStatus status;
527 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
528 "%s: %d: initializing SME-QoS module",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700529 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700530 //init the control block
531 //(note that this will make all sessions invalid)
532 vos_mem_zero(&sme_QosCb, sizeof(sme_QosCb));
533 sme_QosCb.pMac = pMac;
534 sme_QosCb.nextFlowId = SME_QOS_MIN_FLOW_ID;
535 sme_QosCb.nextDialogToken = SME_QOS_MIN_DIALOG_TOKEN;
536 //init flow list
537 status = csrLLOpen(pMac->hHdd, &sme_QosCb.flow_list);
538 if (!HAL_STATUS_SUCCESS(status))
539 {
540 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
541 "%s: %d: cannot initialize Flow List",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700542 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700543 return eHAL_STATUS_FAILURE;
544 }
545
546 for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; ++sessionId)
547 {
548 pSession = &sme_QosCb.sessionInfo[sessionId];
549 pSession->sessionId = sessionId;
550 // initialize the session's per-AC information
551 sme_QosInitACs(pMac, sessionId);
552 // initialize the session's buffered command list
553 status = csrLLOpen(pMac->hHdd, &pSession->bufferedCommandList);
554 if (!HAL_STATUS_SUCCESS(status))
555 {
556 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
557 "%s: %d: cannot initialize cmd list for session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700558 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700559 sessionId);
560 return eHAL_STATUS_FAILURE;
561 }
562 pSession->readyForPowerSave = VOS_TRUE;
563 }
564 //the routine registered here gets called by PMC whenever the device is about
565 //to enter one of the power save modes. PMC runs a poll with all the
566 //registered modules if device can enter powersave mode or remain full power
567 if(!HAL_STATUS_SUCCESS(
568 pmcRegisterPowerSaveCheck(pMac, sme_QosPmcCheckRoutine, pMac)))
569 {
570 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
571 "%s: %d: cannot register with pmcRegisterPowerSaveCheck()",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700572 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700573 return eHAL_STATUS_FAILURE;
574 }
575 //the routine registered here gets called by PMC whenever there is a device
576 // state change. PMC might go to full power because of many reasons and this
577 // is the way for PMC to inform all the other registered modules so that
578 // everyone is in sync.
579 if(!HAL_STATUS_SUCCESS(
580 pmcRegisterDeviceStateUpdateInd(pMac, sme_QosPmcDeviceStateUpdateInd, pMac)))
581 {
582 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
583 "%s: %d: cannot register with pmcRegisterDeviceStateUpdateInd()",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700584 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700585 return eHAL_STATUS_FAILURE;
586 }
587 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
588 "%s: %d: done initializing SME-QoS module",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700589 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700590 return eHAL_STATUS_SUCCESS;
591}
592/* --------------------------------------------------------------------------
593 \brief sme_QosClose() - To close down SME QoS module. There should not be
594 any API call into this module after calling this function until another
595 call of sme_QosOpen.
596 \param pMac - Pointer to the global MAC parameter structure.
597
598 \return eHalStatus
599----------------------------------------------------------------------------*/
600eHalStatus sme_QosClose(tpAniSirGlobal pMac)
601{
602 sme_QosSessionInfo *pSession;
603 sme_QosEdcaAcType ac;
604 v_U8_t sessionId;
605 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
606 "%s: %d: closing down SME-QoS",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700607 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700608 // deregister with PMC
609 if(!HAL_STATUS_SUCCESS(
610 pmcDeregisterDeviceStateUpdateInd(pMac, sme_QosPmcDeviceStateUpdateInd)))
611 {
612 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
613 "%s: %d: cannot deregister with pmcDeregisterDeviceStateUpdateInd()",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700614 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700615 }
616 if(!HAL_STATUS_SUCCESS(
617 pmcDeregisterPowerSaveCheck(pMac, sme_QosPmcCheckRoutine)))
618 {
619 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
620 "%s: %d: cannot deregister with pmcDeregisterPowerSaveCheck()",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700621 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700622 }
623 //cleanup control block
624 //close the flow list
625 csrLLClose(&sme_QosCb.flow_list);
626 // shut down all of the sessions
627 for(sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; ++sessionId)
628 {
629 pSession = &sme_QosCb.sessionInfo[sessionId];
630 if (pSession == NULL)
631 continue;
632
633 sme_QosInitACs(pMac, sessionId);
634 // this session doesn't require UAPSD
635 pSession->apsdMask = 0;
636
637 pSession->uapsdAlreadyRequested = VOS_FALSE;
638 pSession->handoffRequested = VOS_FALSE;
639 pSession->readyForPowerSave = VOS_TRUE;
640 pSession->roamID = 0;
641 //need to clean up buffered req
642 sme_QosDeleteBufferedRequests(pMac, sessionId);
643 //need to clean up flows
644 sme_QosDeleteExistingFlows(pMac, sessionId);
645
646 // Clean up the assoc info if already allocated
647 if (pSession->assocInfo.pBssDesc) {
648 vos_mem_free(pSession->assocInfo.pBssDesc);
649 pSession->assocInfo.pBssDesc = NULL;
650 }
651
652 // close the session's buffered command list
653 csrLLClose(&pSession->bufferedCommandList);
654 for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++)
655 {
656 sme_QosStateTransition(sessionId, ac, SME_QOS_CLOSED);
657 }
658 pSession->sessionActive = VOS_FALSE;
659 pSession->readyForPowerSave = VOS_TRUE;
660 }
661 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
662 "%s: %d: closed down QoS",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700663 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700664 return eHAL_STATUS_SUCCESS;
665}
666/*--------------------------------------------------------------------------
667 \brief sme_QosSetupReq() - The SME QoS API exposed to HDD to request for QoS
668 on a particular AC. This function should be called after a link has been
669 established, i.e. STA is associated with an AP etc. If the request involves
670 admission control on the requested AC, HDD needs to provide the necessary
671 Traffic Specification (TSPEC) parameters otherwise SME is going to use the
672 default params.
673
674 \param hHal - The handle returned by macOpen.
675 \param sessionId - sessionId returned by sme_OpenSession.
676 \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC
677 related info as defined above, provided by HDD
678 \param QoSCallback - The callback which is registered per flow while
679 requesting for QoS. Used for any notification for the
680 flow (i.e. setup success/failure/release) which needs to
681 be sent to HDD
682 \param HDDcontext - A cookie passed by HDD to be used by SME during any QoS
683 notification (through the callabck) to HDD
684 \param UPType - Useful only if HDD or any other upper layer module (BAP etc.)
685 looking for implicit QoS setup, in that
686 case, the pQoSInfo will be NULL & SME will know about the AC
687 (from the UP provided in this param) QoS is requested on
688 \param pQosFlowID - Identification per flow running on each AC generated by
689 SME.
690 It is only meaningful if the QoS setup for the flow is
691 successful
692
693 \return eHAL_STATUS_SUCCESS - Setup is successful.
694
695 Other status means Setup request failed
696 \sa
697
698 --------------------------------------------------------------------------*/
699sme_QosStatusType sme_QosSetupReq(tHalHandle hHal, tANI_U32 sessionId,
700 sme_QosWmmTspecInfo * pQoSInfo,
701 sme_QosCallback QoSCallback,
702 void * HDDcontext,
703 sme_QosWmmUpType UPType, v_U32_t * pQosFlowID)
704{
705 sme_QosSessionInfo *pSession;
706 eHalStatus lock_status = eHAL_STATUS_FAILURE;
707 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
708 sme_QosStatusType status;
709 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
710 "%s: %d: QoS Setup requested by client on session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700711 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700712 sessionId);
713 lock_status = sme_AcquireGlobalLock( &pMac->sme );
714 if ( !HAL_STATUS_SUCCESS( lock_status ) )
715 {
716 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
717 "%s: %d: Unable to obtain lock",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700718 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700719 return SME_QOS_STATUS_SETUP_FAILURE_RSP;
720 }
721 //Make sure the session is valid
722 if (!CSR_IS_SESSION_VALID( pMac, sessionId ))
723 {
724 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
725 "%s: %d: Supplied Session ID %d is invalid",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700726 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700727 sessionId);
728 status = SME_QOS_STATUS_SETUP_FAILURE_RSP;
729 }
730 else
731 {
732 //Make sure the session is active
733 pSession = &sme_QosCb.sessionInfo[sessionId];
734 if (!pSession->sessionActive)
735 {
736 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
737 "%s: %d: Supplied Session ID %d is inactive",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700738 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700739 sessionId);
740 status = SME_QOS_STATUS_SETUP_FAILURE_RSP;
741 }
742 else
743 {
744 //Assign a Flow ID
745 *pQosFlowID = sme_QosAssignFlowId();
746 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
747 "%s: %d: QoS request on session %d assigned Flow ID %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700748 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700749 sessionId, *pQosFlowID);
750 //Call the internal function for QoS setup,
751 // adding a layer of abstraction
752 status = sme_QosInternalSetupReq(pMac, (v_U8_t)sessionId, pQoSInfo,
753 QoSCallback, HDDcontext, UPType,
754 *pQosFlowID, VOS_FALSE, VOS_FALSE);
755 }
756 }
757 sme_ReleaseGlobalLock( &pMac->sme );
758 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
759 "%s: %d: QoS setup return status on session %d is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700760 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700761 sessionId, status);
762 return status;
763}
764
765/*--------------------------------------------------------------------------
766 \brief sme_QosModifyReq() - The SME QoS API exposed to HDD to request for
767 modification of certain QoS params on a flow running on a particular AC.
768 This function should be called after a link has been established, i.e. STA is
769 associated with an AP etc. & a QoS setup has been succesful for that flow.
770 If the request involves admission control on the requested AC, HDD needs to
771 provide the necessary Traffic Specification (TSPEC) parameters & SME might
772 start the renegotiation process through ADDTS.
773
774 \param hHal - The handle returned by macOpen.
775 \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC
776 related info as defined above, provided by HDD
777 \param QosFlowID - Identification per flow running on each AC generated by
778 SME.
779 It is only meaningful if the QoS setup for the flow has
780 been successful already
781
782 \return SME_QOS_STATUS_SETUP_SUCCESS_RSP - Modification is successful.
783
784 Other status means request failed
785 \sa
786
787 --------------------------------------------------------------------------*/
788sme_QosStatusType sme_QosModifyReq(tHalHandle hHal,
789 sme_QosWmmTspecInfo * pQoSInfo,
790 v_U32_t QosFlowID)
791{
792 eHalStatus lock_status = eHAL_STATUS_FAILURE;
793 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
794 sme_QosStatusType status;
795 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
796 "%s: %d: QoS Modify requested by client for Flow %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700797 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700798 QosFlowID);
799 lock_status = sme_AcquireGlobalLock( &pMac->sme );
800 if ( !HAL_STATUS_SUCCESS( lock_status ) )
801 {
802 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
803 "%s: %d: Unable to obtain lock",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700804 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700805 return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
806 }
807 //Call the internal function for QoS modify, adding a layer of abstraction
808 status = sme_QosInternalModifyReq(pMac, pQoSInfo, QosFlowID, VOS_FALSE);
809 sme_ReleaseGlobalLock( &pMac->sme );
810 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
811 "%s: %d: QoS Modify return status on Flow %d is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700812 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700813 QosFlowID, status);
814 return status;
815}
816/*--------------------------------------------------------------------------
817 \brief sme_QosReleaseReq() - The SME QoS API exposed to HDD to request for
818 releasing a QoS flow running on a particular AC. This function should be
819 called only if a QoS is set up with a valid FlowID. HDD sould invoke this
820 API only if an explicit request for QoS release has come from Application
821
822 \param hHal - The handle returned by macOpen.
823 \param QosFlowID - Identification per flow running on each AC generated by SME
824 It is only meaningful if the QoS setup for the flow is
825 successful
826
827 \return eHAL_STATUS_SUCCESS - Release is successful.
828
829 \sa
830
831 --------------------------------------------------------------------------*/
832sme_QosStatusType sme_QosReleaseReq(tHalHandle hHal, v_U32_t QosFlowID)
833{
834 eHalStatus lock_status = eHAL_STATUS_FAILURE;
835 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
836 sme_QosStatusType status;
837 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
838 "%s: %d: QoS Release requested by client for Flow %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700839 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700840 QosFlowID);
841 lock_status = sme_AcquireGlobalLock( &pMac->sme );
842 if ( !HAL_STATUS_SUCCESS( lock_status ) )
843 {
844 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
845 "%s: %d: Unable to obtain lock",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700846 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700847 return SME_QOS_STATUS_RELEASE_FAILURE_RSP;
848 }
849 //Call the internal function for QoS release, adding a layer of abstraction
850 status = sme_QosInternalReleaseReq(pMac, QosFlowID, VOS_FALSE);
851 sme_ReleaseGlobalLock( &pMac->sme );
852 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
853 "%s: %d: QoS Release return status on Flow %d is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700854 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700855 QosFlowID, status);
856 return status;
857}
858/*--------------------------------------------------------------------------
859 \brief sme_QosSetParams() - This function is used by HDD to provide the
860 default TSPEC params to SME.
861
862 \param pMac - Pointer to the global MAC parameter structure.
863 \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC
864 related info per AC as defined above, provided by HDD
865
866 \return eHAL_STATUS_SUCCESS - Setparam is successful.
867
868 \sa
869
870 --------------------------------------------------------------------------*/
871eHalStatus sme_QosSetParams(tpAniSirGlobal pMac, sme_QosWmmTspecInfo * pQoSInfo)
872{
873 sme_QosEdcaAcType ac;
874 // find the AC
875 ac = sme_QosUpToAc(pQoSInfo->ts_info.up);
876 if(SME_QOS_EDCA_AC_MAX == ac)
877 {
878 //err msg
879 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
880 "%s: %d: Invalid AC %d (via UP %d)",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700881 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700882 ac, pQoSInfo->ts_info.up );
883 return eHAL_STATUS_FAILURE;
884 }
885 //copy over the default params for this AC
886 sme_QosCb.def_QoSInfo[ac] = *pQoSInfo;
887 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
888 "%s: %d: QoS default params set for AC %d (via UP %d)",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700889 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700890 ac, pQoSInfo->ts_info.up );
891 return eHAL_STATUS_SUCCESS;
892}
893
894void qosReleaseCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand )
895{
896 vos_mem_zero( &pCommand->u.qosCmd, sizeof( tGenericQosCmd ) );
897 smeReleaseCommand( pMac, pCommand );
898}
899
900/*--------------------------------------------------------------------------
901 \brief sme_QosMsgProcessor() - sme_ProcessMsg() calls this function for the
902 messages that are handled by SME QoS module.
903
904 \param pMac - Pointer to the global MAC parameter structure.
905 \param msg_type - the type of msg passed by PE as defined in wniApi.h
906 \param pMsgBuf - a pointer to a buffer that maps to various structures base
907 on the message type.
908 The beginning of the buffer can always map to tSirSmeRsp.
909
910 \return eHAL_STATUS_SUCCESS - Validation is successful.
911
912 \sa
913
914 --------------------------------------------------------------------------*/
915eHalStatus sme_QosMsgProcessor( tpAniSirGlobal pMac, v_U16_t msg_type,
916 void *pMsgBuf)
917{
918 eHalStatus status = eHAL_STATUS_FAILURE;
919 tListElem *pEntry;
920 tSmeCmd *pCommand;
921 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
922 "%s: %d: msg = %d for QoS",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700923 __func__, __LINE__, msg_type);
Jeff Johnson295189b2012-06-20 16:38:30 -0700924 //switch on the msg type & make the state transition accordingly
925 switch(msg_type)
926 {
927 case eWNI_SME_ADDTS_RSP:
928 pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
929 if( pEntry )
930 {
931 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
932 if( eSmeCommandAddTs == pCommand->command )
933 {
934 status = sme_QosProcessAddTsRsp(pMac, pMsgBuf);
935 if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) )
936 {
937 qosReleaseCommand( pMac, pCommand );
938 }
939 smeProcessPendingQueue( pMac );
940 }
941 }
942 break;
943 case eWNI_SME_DELTS_RSP:
944 pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
945 if( pEntry )
946 {
947 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
948 if( eSmeCommandDelTs == pCommand->command )
949 {
950 status = sme_QosProcessDelTsRsp(pMac, pMsgBuf);
951 if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) )
952 {
953 qosReleaseCommand( pMac, pCommand );
954 }
955 smeProcessPendingQueue( pMac );
956 }
957 }
958 break;
959 case eWNI_SME_DELTS_IND:
960 status = sme_QosProcessDelTsInd(pMac, pMsgBuf);
961 break;
962#ifdef WLAN_FEATURE_VOWIFI_11R
963 case eWNI_SME_FT_AGGR_QOS_RSP:
964 status = sme_QosProcessAggrQosRsp(pMac, pMsgBuf);
965 break;
966#endif
967
968 default:
969 //err msg
970 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
971 "%s: %d: unknown msg type = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700972 __func__, __LINE__, msg_type);
Jeff Johnson295189b2012-06-20 16:38:30 -0700973 break;
974 }
975 return status;
976}
977/*--------------------------------------------------------------------------
978 \brief sme_QosValidateParams() - The SME QoS API exposed to CSR to validate AP
979 capabilities regarding QoS support & any other QoS parameter validation.
980
981 \param pMac - Pointer to the global MAC parameter structure.
982 \param pBssDesc - Pointer to the BSS Descriptor information passed down by
983 CSR to PE while issuing the Join request
984
985 \return eHalStatus
986
987 \sa
988
989 --------------------------------------------------------------------------*/
990eHalStatus sme_QosValidateParams(tpAniSirGlobal pMac,
991 tSirBssDescription *pBssDesc)
992{
993 tDot11fBeaconIEs *pIes = NULL;
994 eHalStatus status = eHAL_STATUS_FAILURE;
995 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
996 "%s: %d: validation for QAP & APSD",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700997 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700998 do
999 {
1000 if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIes)))
1001 {
1002 //err msg
1003 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1004 "%s: %d: csrGetParsedBssDescriptionIEs() failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001005 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001006 break;
1007 }
1008 //check if the AP is QAP & it supports APSD
1009 if( !CSR_IS_QOS_BSS(pIes) )
1010 {
1011 //err msg
1012 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1013 "%s: %d: AP doesn't support QoS",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001014 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001015
1016 break;
1017 }
1018 if(!(pIes->WMMParams.qosInfo & SME_QOS_AP_SUPPORTS_APSD) &&
1019 !(pIes->WMMInfoAp.uapsd))
1020 {
1021 //err msg
1022 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1023 "%s: %d: AP doesn't support APSD",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001024 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001025 break;
1026 }
1027 status = eHAL_STATUS_SUCCESS;
1028 }while(0);
1029 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
1030 "%s: %d: validated with status = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001031 __func__, __LINE__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07001032 if(pIes)
1033 {
1034 vos_mem_free(pIes);
1035 }
1036 return status;
1037}
1038/*--------------------------------------------------------------------------
1039 \brief sme_QosCsrEventInd() - The QoS sub-module in SME expects notifications
1040 from CSR when certain events occur as mentioned in sme_QosCsrEventIndType.
1041 \param pMac - Pointer to the global MAC parameter structure.
1042 \param ind - The event occurred of type sme_QosCsrEventIndType.
1043 \param pEvent_info - Information related to the event
1044
1045 \return eHalStatus
1046
1047 \sa
1048
1049 --------------------------------------------------------------------------*/
1050eHalStatus sme_QosCsrEventInd(tpAniSirGlobal pMac,
1051 v_U8_t sessionId,
1052 sme_QosCsrEventIndType ind,
1053 void *pEvent_info)
1054{
1055 eHalStatus status = eHAL_STATUS_FAILURE;
1056 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
1057 "%s: %d: On Session %d Event %d received from CSR",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001058 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001059 sessionId, ind );
1060 switch(ind)
1061 {
1062 case SME_QOS_CSR_ASSOC_COMPLETE:
1063 //expecting assoc info in pEvent_info
1064 status = sme_QosProcessAssocCompleteEv(pMac, sessionId, pEvent_info);
1065 break;
1066 case SME_QOS_CSR_REASSOC_REQ:
1067 //nothing expected in pEvent_info
1068 status = sme_QosProcessReassocReqEv(pMac, sessionId, pEvent_info);
1069 break;
1070 case SME_QOS_CSR_REASSOC_COMPLETE:
1071 //expecting assoc info in pEvent_info
1072 status = sme_QosProcessReassocSuccessEv(pMac, sessionId, pEvent_info);
1073 break;
1074 case SME_QOS_CSR_REASSOC_FAILURE:
1075 //nothing expected in pEvent_info
1076 status = sme_QosProcessReassocFailureEv(pMac, sessionId, pEvent_info);
1077 break;
1078 case SME_QOS_CSR_DISCONNECT_REQ:
1079 case SME_QOS_CSR_DISCONNECT_IND:
1080 //nothing expected in pEvent_info
1081 status = sme_QosProcessDisconnectEv(pMac, sessionId, pEvent_info);
1082 break;
1083 case SME_QOS_CSR_JOIN_REQ:
1084 //nothing expected in pEvent_info
1085 status = sme_QosProcessJoinReqEv(pMac, sessionId, pEvent_info);
1086 break;
1087 case SME_QOS_CSR_HANDOFF_ASSOC_REQ:
1088 //nothing expected in pEvent_info
1089 status = sme_QosProcessHandoffAssocReqEv(pMac, sessionId, pEvent_info);
1090 break;
1091 case SME_QOS_CSR_HANDOFF_COMPLETE:
1092 //nothing expected in pEvent_info
1093 status = sme_QosProcessHandoffSuccessEv(pMac, sessionId, pEvent_info);
1094 break;
1095 case SME_QOS_CSR_HANDOFF_FAILURE:
1096 //nothing expected in pEvent_info
1097 status = sme_QosProcessHandoffFailureEv(pMac, sessionId, pEvent_info);
1098 break;
1099#ifdef WLAN_FEATURE_VOWIFI_11R
1100 case SME_QOS_CSR_PREAUTH_SUCCESS_IND:
1101 status = sme_QosProcessPreauthSuccessInd(pMac, sessionId, pEvent_info);
1102 break;
Jeff Johnson43971f52012-07-17 12:26:56 -07001103#if defined(FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07001104 case SME_QOS_CSR_SET_KEY_SUCCESS_IND:
1105 status = sme_QosProcessSetKeySuccessInd(pMac, sessionId, pEvent_info);
1106 break;
1107#endif
1108#endif
1109 default:
1110 //Err msg
1111 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1112 "%s: %d: On Session %d Unknown Event %d received from CSR",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001113 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001114 sessionId, ind );
1115 break;
1116 }
1117 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
1118 "%s: %d: On Session %d processed Event %d with status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001119 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001120 sessionId, ind, status );
1121 return status;
1122}
1123/*--------------------------------------------------------------------------
1124 \brief sme_QosGetACMMask() - The QoS sub-module API to find out on which ACs
1125 AP mandates Admission Control (ACM = 1)
1126 (Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored)
1127 \param pMac - Pointer to the global MAC parameter structure.
1128 \param pSirBssDesc - The event occurred of type sme_QosCsrEventIndType.
1129
1130 \return a bit mask indicating for which ACs AP has ACM set to 1
1131
1132 \sa
1133
1134 --------------------------------------------------------------------------*/
1135v_U8_t sme_QosGetACMMask(tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes)
1136{
1137 sme_QosEdcaAcType ac;
1138 v_U8_t acm_mask = 0;
1139 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
1140 "%s: %d: invoked",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001141 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001142 for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++)
1143 {
1144 if(sme_QosIsACM(pMac, pSirBssDesc, ac, pIes))
1145 {
1146 acm_mask = acm_mask | (1 << (SME_QOS_EDCA_AC_VO - ac));
1147 }
1148
1149 }
1150 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
1151 "%s: %d: mask is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001152 __func__, __LINE__, acm_mask);
Jeff Johnson295189b2012-06-20 16:38:30 -07001153 return acm_mask;
1154}
1155/*--------------------------------------------------------------------------
1156 Internal function definitions
1157 ------------------------------------------------------------------------*/
1158/*--------------------------------------------------------------------------
1159 \brief sme_QosInternalSetupReq() - The SME QoS internal setup request handling
1160 function.
1161 If the request involves admission control on the requested AC, HDD needs to
1162 provide the necessary Traffic Specification (TSPEC) parameters otherwise SME
1163 is going to use the default params.
1164
1165 \param pMac - Pointer to the global MAC parameter structure.
1166 \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC
1167 related info as defined above, provided by HDD
1168 \param QoSCallback - The callback which is registered per flow while
1169 requesting for QoS. Used for any notification for the
1170 flow (i.e. setup success/failure/release) which needs to
1171 be sent to HDD
1172 \param HDDcontext - A cookie passed by HDD to be used by SME during any QoS
1173 notification (through the callabck) to HDD
1174 \param UPType - Useful only if HDD or any other upper layer module (BAP etc.)
1175 looking for implicit QoS setup, in that
1176 case, the pQoSInfo will be NULL & SME will know about the AC
1177 (from the UP provided in this param) QoS is requested on
1178 \param QosFlowID - Identification per flow running on each AC generated by
1179 SME.
1180 It is only meaningful if the QoS setup for the flow is
1181 successful
1182 \param buffered_cmd - tells us if the cmd was a buffered one or fresh from
1183 client
1184
1185 \return eHAL_STATUS_SUCCESS - Setup is successful.
1186
1187 Other status means Setup request failed
1188 \sa
1189
1190 --------------------------------------------------------------------------*/
1191sme_QosStatusType sme_QosInternalSetupReq(tpAniSirGlobal pMac,
1192 v_U8_t sessionId,
1193 sme_QosWmmTspecInfo * pQoSInfo,
1194 sme_QosCallback QoSCallback,
1195 void * HDDcontext,
1196 sme_QosWmmUpType UPType,
1197 v_U32_t QosFlowID,
1198 v_BOOL_t buffered_cmd,
1199 v_BOOL_t hoRenewal)
1200{
1201 sme_QosSessionInfo *pSession;
1202 sme_QosACInfo *pACInfo;
1203 sme_QosEdcaAcType ac;
1204 sme_QosWmmTspecInfo Tspec_Info;
1205 sme_QosStates new_state = SME_QOS_CLOSED;
1206 sme_QosFlowInfoEntry *pentry = NULL;
1207 sme_QosCmdInfo cmd;
1208 sme_QosStatusType status = SME_QOS_STATUS_SETUP_FAILURE_RSP;
1209 v_U8_t tmask = 0;
1210 v_U8_t new_tmask = 0;
1211 sme_QosSearchInfo search_key;
1212 v_BOOL_t bufferCommand;
1213 eHalStatus hstatus;
1214 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
1215 "%s: %d: invoked on session %d for flow %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001216 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001217 sessionId, QosFlowID);
1218 pSession = &sme_QosCb.sessionInfo[sessionId];
1219 // if caller sent an empty TSPEC, fill up with the default one
1220 if(!pQoSInfo)
1221 {
1222 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
1223 "%s: %d: caller sent an empty QoS param list, using defaults",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001224 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001225 // find the AC with UPType passed in
1226 ac = sme_QosUpToAc(UPType);
1227 if(SME_QOS_EDCA_AC_MAX == ac)
1228 {
1229 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1230 "%s: %d: invalid AC %d from UP %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001231 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001232 ac, UPType);
1233
1234 return SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP;
1235 }
1236 Tspec_Info = sme_QosCb.def_QoSInfo[ac];
1237 }
1238 else
1239 {
1240 // find the AC
1241 ac = sme_QosUpToAc(pQoSInfo->ts_info.up);
1242 if(SME_QOS_EDCA_AC_MAX == ac)
1243 {
1244 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1245 "%s: %d: invalid AC %d from UP %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001246 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001247 ac, pQoSInfo->ts_info.up);
1248
1249 return SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP;
1250 }
1251 //validate QoS params
1252 if(!sme_QosValidateRequestedParams(pMac, pQoSInfo, sessionId))
1253 {
1254 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1255 "%s: %d: invalid params",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001256 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001257 return SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP;
1258 }
1259 Tspec_Info = *pQoSInfo;
1260 }
1261 pACInfo = &pSession->ac_info[ac];
1262 // need to vote off powersave for the duration of this request
1263 pSession->readyForPowerSave = VOS_FALSE;
1264 // assume we won't have to (re)buffer the command
1265 bufferCommand = VOS_FALSE;
1266 //check to consider the following flowing scenario
1267 //Addts request is pending on one AC, while APSD requested on another which
1268 //needs a reassoc. Will buffer a request if Addts is pending on any AC,
1269 //which will safegaurd the above scenario, & also won't confuse PE with back
1270 //to back Addts or Addts followed by Reassoc
1271 if(sme_QosIsRspPending(sessionId, ac))
1272 {
1273 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
1274 "%s: %d: buffering the setup request for flow %d in state %d "
1275 "since another request is pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001276 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001277 QosFlowID, pACInfo->curr_state );
1278 bufferCommand = VOS_TRUE;
1279 }
1280 else
1281 {
1282 // make sure we are in full power so that we can issue
1283 // an AddTS or reassoc if necessary
1284 hstatus = pmcRequestFullPower(pMac, sme_QosPmcFullPowerCallback,
1285 pSession, eSME_REASON_OTHER);
1286 if( eHAL_STATUS_PMC_PENDING == hstatus )
1287 {
1288 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
1289 "%s: %d: buffering the setup request for flow %d in state %d, "
1290 "waiting for full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001291 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001292 QosFlowID, pACInfo->curr_state );
1293 bufferCommand = VOS_TRUE;
1294 }
1295 }
1296 if (bufferCommand)
1297 {
1298 // we need to buffer the command
1299 cmd.command = SME_QOS_SETUP_REQ;
1300 cmd.pMac = pMac;
1301 cmd.sessionId = sessionId;
1302 cmd.u.setupCmdInfo.HDDcontext = HDDcontext;
1303 cmd.u.setupCmdInfo.QoSInfo = Tspec_Info;
1304 cmd.u.setupCmdInfo.QoSCallback = QoSCallback;
1305 cmd.u.setupCmdInfo.UPType = UPType;
1306 cmd.u.setupCmdInfo.hoRenewal = hoRenewal;
1307 cmd.u.setupCmdInfo.QosFlowID = QosFlowID;
1308 hstatus = sme_QosBufferCmd(&cmd, buffered_cmd);
1309 if(!HAL_STATUS_SUCCESS(hstatus))
1310 {
1311 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1312 "%s: %d: couldn't buffer the setup request in state = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001313 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001314 pACInfo->curr_state );
1315 // unable to buffer the request
1316 // nothing is pending so vote powersave back on
1317 pSession->readyForPowerSave = VOS_TRUE;
1318 return SME_QOS_STATUS_SETUP_FAILURE_RSP;
1319 }
1320 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
1321 "%s: %d: Buffered setup request for flow = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001322 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001323 QosFlowID);
1324 return SME_QOS_STATUS_SETUP_REQ_PENDING_RSP;
1325 }
1326
1327 //get into the state m/c to see if the request can be granted
1328 switch(pACInfo->curr_state)
1329 {
1330 case SME_QOS_LINK_UP:
1331 //call the internal qos setup logic to decide on if the
1332 // request is NOP, or need reassoc for APSD and/or need to send out ADDTS
1333 status = sme_QosSetup(pMac, sessionId, &Tspec_Info, ac);
1334 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
1335 "%s: %d: On session %d with AC %d in state SME_QOS_LINK_UP "
1336 "sme_QosSetup returned with status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001337 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001338 sessionId, ac, status);
1339 if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP != status)
1340 {
1341 // we aren't waiting for a response from the AP
1342 // so vote powersave back on
1343 pSession->readyForPowerSave = VOS_TRUE;
1344 }
1345 if((SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status)||
1346 (SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) ||
1347 (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status))
1348 {
1349 // we received an expected "good" status
1350 //create an entry in the flow list
1351 pentry = vos_mem_malloc(sizeof(*pentry));
1352 if (!pentry)
1353 {
1354 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1355 "%s: %d: couldn't allocate memory for the new "
1356 "entry in the Flow List",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001357 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001358 return SME_QOS_STATUS_SETUP_FAILURE_RSP;
1359 }
1360 pentry->ac_type = ac;
1361 pentry->HDDcontext = HDDcontext;
1362 pentry->QoSCallback = QoSCallback;
1363 pentry->hoRenewal = hoRenewal;
1364 pentry->QosFlowID = QosFlowID;
1365 pentry->sessionId = sessionId;
1366 // since we are in state SME_QOS_LINK_UP this must be the
1367 // first TSPEC on this AC, so use index 0 (mask bit 1)
1368 pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0] = Tspec_Info;
1369 if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status)
1370 {
1371 if(pACInfo->tspec_mask_status &&
1372 !pACInfo->reassoc_pending)
1373 {
1374 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1375 "%s: %d: On session %d with AC %d in state "
1376 "SME_QOS_LINK_UP tspec_mask_status is %d "
1377 "but should not be set yet",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001378 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001379 sessionId, ac, pACInfo->tspec_mask_status);
1380 //ASSERT
1381 VOS_ASSERT(0);
1382 vos_mem_free(pentry);
1383 return SME_QOS_STATUS_SETUP_FAILURE_RSP;
1384 }
1385 pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_BIT_1_SET;
1386 if(!pACInfo->reassoc_pending)
1387 {
1388 // we didn't request for reassoc, it must be a tspec negotiation
1389 pACInfo->tspec_pending = 1;
1390 }
1391
1392 pentry->reason = SME_QOS_REASON_SETUP;
1393 new_state = SME_QOS_REQUESTED;
1394 }
1395 else
1396 {
1397 // SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP or
1398 // SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY
1399 pentry->reason = SME_QOS_REASON_REQ_SUCCESS;
1400 new_state = SME_QOS_QOS_ON;
1401 pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_BIT_1_SET;
1402 pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0] = Tspec_Info;
1403 if(buffered_cmd && !pentry->hoRenewal)
1404 {
1405 QoSCallback(pMac, HDDcontext,
1406 &pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0],
1407 status,
1408 pentry->QosFlowID);
1409 }
1410 pentry->hoRenewal = VOS_FALSE;
1411 }
1412 pACInfo->num_flows[SME_QOS_TSPEC_INDEX_0]++;
1413
1414 //indicate on which index the flow entry belongs to & add it to the
1415 //Flow List at the end
1416 pentry->tspec_mask = pACInfo->tspec_mask_status;
1417 pentry->QoSInfo = Tspec_Info;
1418 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
1419 "%s: %d: Creating entry on session %d at %p with flowID %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001420 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001421 sessionId, pentry, QosFlowID);
1422 csrLLInsertTail(&sme_QosCb.flow_list, &pentry->link, VOS_TRUE);
1423 }
1424 else
1425 {
1426 // unexpected status returned by sme_QosSetup()
1427 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1428 "%s: %d: On session %d unexpected status %d "
1429 "returned by sme_QosSetup",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001430 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001431 sessionId, status);
1432 new_state = pACInfo->curr_state;
1433 if(buffered_cmd && hoRenewal)
1434 {
1435 QoSCallback(pMac, HDDcontext,
1436 &pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0],
1437 SME_QOS_STATUS_RELEASE_QOS_LOST_IND,
1438 QosFlowID);
1439 }
1440 }
1441 break;
1442 case SME_QOS_HANDOFF:
1443 case SME_QOS_REQUESTED:
1444 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
1445 "%s: %d: Buffering setup request for flow %d in state = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001446 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001447 QosFlowID, pACInfo->curr_state );
1448 //buffer cmd
1449 cmd.command = SME_QOS_SETUP_REQ;
1450 cmd.pMac = pMac;
1451 cmd.sessionId = sessionId;
1452 cmd.u.setupCmdInfo.HDDcontext = HDDcontext;
1453 cmd.u.setupCmdInfo.QoSInfo = Tspec_Info;
1454 cmd.u.setupCmdInfo.QoSCallback = QoSCallback;
1455 cmd.u.setupCmdInfo.UPType = UPType;
1456 cmd.u.setupCmdInfo.hoRenewal = hoRenewal;
1457 cmd.u.setupCmdInfo.QosFlowID = QosFlowID;
1458 hstatus = sme_QosBufferCmd(&cmd, buffered_cmd);
1459 if(!HAL_STATUS_SUCCESS(hstatus))
1460 {
1461 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1462 "%s: %d: On session %d couldn't buffer the setup "
1463 "request for flow %d in state = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001464 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001465 sessionId, QosFlowID, pACInfo->curr_state );
1466 // unable to buffer the request
1467 // nothing is pending so vote powersave back on
1468 pSession->readyForPowerSave = VOS_TRUE;
1469 return SME_QOS_STATUS_SETUP_FAILURE_RSP;
1470 }
1471 status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP;
1472 new_state = pACInfo->curr_state;
1473 break;
1474 case SME_QOS_QOS_ON:
1475
1476 //check if multiple flows running on the ac
1477 if((pACInfo->num_flows[SME_QOS_TSPEC_INDEX_0] > 0)||
1478 (pACInfo->num_flows[SME_QOS_TSPEC_INDEX_1] > 0))
1479 {
1480 //do we need to care about the case where APSD needed on ACM = 0 below?
1481 if(CSR_IS_ADDTS_WHEN_ACMOFF_SUPPORTED(pMac) ||
1482 sme_QosIsACM(pMac, pSession->assocInfo.pBssDesc, ac, NULL))
1483 {
1484 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
1485 "%s: %d: tspec_mask_status = %d for AC = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001486 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001487 pACInfo->tspec_mask_status, ac);
1488 if(!pACInfo->tspec_mask_status)
1489 {
1490 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1491 "%s: %d: tspec_mask_status can't be 0 for ac = %d in "
1492 "state = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001493 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001494 ac, pACInfo->curr_state);
1495 //ASSERT
1496 VOS_ASSERT(0);
1497 // unable to service the request
1498 // nothing is pending so vote powersave back on
1499 pSession->readyForPowerSave = VOS_TRUE;
1500 return status;
1501 }
1502 /* Flow aggregation */
1503 if(SME_QOS_TSPEC_MASK_BIT_1_2_SET != pACInfo->tspec_mask_status)
1504 {
1505 /* Either of upstream, downstream or bidirectional flows are present */
1506 /* If either of new stream or current stream is for bidirecional, aggregate
1507 * the new stream with the current streams present and send out aggregated Tspec.*/
1508 if((Tspec_Info.ts_info.direction == SME_QOS_WMM_TS_DIR_BOTH) ||
1509 (pACInfo->curr_QoSInfo[pACInfo->tspec_mask_status - 1].
1510 ts_info.direction == SME_QOS_WMM_TS_DIR_BOTH))
1511 {
1512 // Aggregate the new stream with the current stream(s).
1513 tmask = pACInfo->tspec_mask_status;
1514 }
1515 /* None of new stream or current (aggregated) streams are for bidirectional.
1516 * Check if the new stream direction matches the current stream direction. */
1517 else if(pACInfo->curr_QoSInfo[pACInfo->tspec_mask_status - 1].
1518 ts_info.direction == Tspec_Info.ts_info.direction)
1519 {
1520 // Aggregate the new stream with the current stream(s).
1521 tmask = pACInfo->tspec_mask_status;
1522 }
1523 /* New stream is in different direction. */
1524 else
1525 {
1526 // No Aggregation. Mark the 2nd tpsec index also as active.
1527 tmask = SME_QOS_TSPEC_MASK_CLEAR;
1528 new_tmask = SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~pACInfo->tspec_mask_status;
1529 pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_BIT_1_2_SET;
1530 }
1531 }
1532 else
1533 {
1534 /* Both uplink and downlink streams are present. */
1535 /* If new stream is bidirectional, aggregate new stream with all existing
1536 * upstreams and downstreams. Send out new aggregated tpsec. */
1537 if(Tspec_Info.ts_info.direction == SME_QOS_WMM_TS_DIR_BOTH)
1538 {
1539 // Only one tspec index (0) will be in use after this aggregation.
1540 tmask = SME_QOS_TSPEC_MASK_BIT_1_2_SET;
1541 pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_BIT_1_SET;
1542 }
1543 /* New stream is also uni-directional
1544 * Find out the tsepc index with which it needs to be aggregated */
1545 else if(pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0].ts_info.direction !=
1546 Tspec_Info.ts_info.direction)
1547 {
1548 // Aggregate with 2nd tspec index
1549 tmask = SME_QOS_TSPEC_MASK_BIT_2_SET;
1550 }
1551 else
1552 {
1553 // Aggregate with 1st tspec index
1554 tmask = SME_QOS_TSPEC_MASK_BIT_1_SET;
1555 }
1556 }
1557 }
1558 else
1559 {
1560 //ACM = 0
1561 // We won't be sending a TSPEC to the AP but we still need
1562 // to aggregate to calculate trigger frame parameters
1563 tmask = SME_QOS_TSPEC_MASK_BIT_1_SET;
1564 }
1565 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
1566 "%s: %d: tmask = %d, new_tmask = %d in state = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001567 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001568 tmask, new_tmask, pACInfo->curr_state );
1569 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
1570 "%s: %d: tspec_mask_status = %d for AC = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001571 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001572 pACInfo->tspec_mask_status, ac);
1573 if(tmask)
1574 {
1575 // create the aggregate TSPEC
1576 if(tmask != SME_QOS_TSPEC_MASK_BIT_1_2_SET)
1577 {
1578 hstatus = sme_QosAggregateParams(&Tspec_Info,
1579 &pACInfo->curr_QoSInfo[tmask - 1],
1580 &pACInfo->requested_QoSInfo[tmask - 1]);
1581 }
1582 else
1583 {
1584 /* Aggregate the new bidirectional stream with the existing upstreams and
1585 * downstreams in tspec indices 0 and 1. */
1586 tmask = SME_QOS_TSPEC_MASK_BIT_1_SET;
1587
1588 if((hstatus = sme_QosAggregateParams(&Tspec_Info,
1589 &pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0],
1590 &pACInfo->requested_QoSInfo[tmask - 1]))
1591 == eHAL_STATUS_SUCCESS)
1592 {
1593 hstatus = sme_QosAggregateParams(&pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_1],
1594 &pACInfo->requested_QoSInfo[tmask - 1],
1595 NULL);
1596 }
1597 }
1598
1599 if(!HAL_STATUS_SUCCESS(hstatus))
1600 {
1601 //err msg
1602 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1603 "%s: %d: failed to aggregate params",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001604 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001605 // unable to service the request
1606 // nothing is pending so vote powersave back on
1607 pSession->readyForPowerSave = VOS_TRUE;
1608 return SME_QOS_STATUS_SETUP_FAILURE_RSP;
1609 }
1610 }
1611 else
1612 {
1613 tmask = new_tmask;
Gopichand Nakkala7c0c8c12013-04-05 12:21:03 +05301614 pACInfo->requested_QoSInfo[tmask-1] = Tspec_Info;
Jeff Johnson295189b2012-06-20 16:38:30 -07001615 }
1616 }
1617 else
1618 {
1619 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1620 "%s: %d: no flows running for ac = %d while in state = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001621 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001622 ac, pACInfo->curr_state );
1623 //ASSERT
1624 VOS_ASSERT(0);
1625 // unable to service the request
1626 // nothing is pending so vote powersave back on
1627 pSession->readyForPowerSave = VOS_TRUE;
1628 return status;
1629 }
1630 //although aggregating, make sure to request on the correct UP
1631 pACInfo->requested_QoSInfo[tmask - 1].ts_info.up = Tspec_Info.ts_info.up;
1632 status = sme_QosSetup(pMac, sessionId,
1633 &pACInfo->requested_QoSInfo[tmask - 1], ac);
1634 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
1635 "%s: %d: On session %d with AC %d in state SME_QOS_QOS_ON "
1636 "sme_QosSetup returned with status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001637 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001638 sessionId, ac, status);
1639 if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP != status)
1640 {
1641 // we aren't waiting for a response from the AP
1642 // so vote powersave back on
1643 pSession->readyForPowerSave = VOS_TRUE;
1644 }
1645 if((SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status)||
1646 (SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) ||
1647 (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status))
1648 {
1649 // we received an expected "good" status
1650 //create an entry in the flow list
1651 pentry = (sme_QosFlowInfoEntry *) vos_mem_malloc(sizeof(*pentry));
1652 if (!pentry)
1653 {
1654 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1655 "%s: %d: couldn't allocate memory for the new "
1656 "entry in the Flow List",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001657 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001658 return SME_QOS_STATUS_SETUP_FAILURE_RSP;
1659 }
1660 pentry->ac_type = ac;
1661 pentry->HDDcontext = HDDcontext;
1662 pentry->QoSCallback = QoSCallback;
1663 pentry->hoRenewal = hoRenewal;
1664 pentry->QosFlowID = QosFlowID;
1665 pentry->sessionId = sessionId;
1666 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
1667 "%s: %d: Creating flow %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001668 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001669 QosFlowID);
1670 if((SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status)||
1671 (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status))
1672 {
1673 new_state = pACInfo->curr_state;
1674 pentry->reason = SME_QOS_REASON_REQ_SUCCESS;
1675 pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0] =
1676 pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0];
1677 if(buffered_cmd && !pentry->hoRenewal)
1678 {
1679 QoSCallback(pMac, HDDcontext,
1680 &pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0],
1681 status,
1682 pentry->QosFlowID);
1683 }
1684 if(SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status)
1685 {
1686 // if we are not in handoff, then notify all flows on
1687 // this AC that the aggregate TSPEC may have changed
1688 if(!pentry->hoRenewal)
1689 {
1690 vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo));
1691 search_key.key.ac_type = ac;
1692 search_key.index = SME_QOS_SEARCH_KEY_INDEX_2;
1693 search_key.sessionId = sessionId;
1694 hstatus = sme_QosFindAllInFlowList(pMac, search_key,
1695 sme_QosSetupFnp);
1696 if(!HAL_STATUS_SUCCESS(hstatus))
1697 {
1698 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1699 "%s: %d: couldn't notify other "
1700 "entries on this AC =%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001701 __func__, __LINE__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001702 }
1703 }
1704 }
1705 pentry->hoRenewal = VOS_FALSE;
1706 }
1707 else
1708 {
1709 // SME_QOS_STATUS_SETUP_REQ_PENDING_RSP
1710 new_state = SME_QOS_REQUESTED;
1711 pentry->reason = SME_QOS_REASON_SETUP;
1712 //Need this info when addts comes back from PE to know on
1713 //which index of the AC the request was from
1714 pACInfo->tspec_pending = tmask;
1715 }
1716 pACInfo->num_flows[tmask - 1]++;
1717 //indicate on which index the flow entry belongs to & add it to the
1718 //Flow List at the end
1719 pentry->tspec_mask = tmask;
1720 pentry->QoSInfo = Tspec_Info;
1721 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
1722 "%s: %d: On session %d creating entry at %p with flowID %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001723 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001724 sessionId, pentry, QosFlowID);
1725 csrLLInsertTail(&sme_QosCb.flow_list, &pentry->link, VOS_TRUE);
1726 }
1727 else
1728 {
1729 // unexpected status returned by sme_QosSetup()
1730 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1731 "%s: %d: On session %d unexpected status %d "
1732 "returned by sme_QosSetup",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001733 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001734 sessionId, status);
1735 new_state = pACInfo->curr_state;
1736 }
1737 break;
1738 case SME_QOS_CLOSED:
1739 case SME_QOS_INIT:
1740 default:
1741 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1742 "%s: %d: setup requested in unexpected state = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001743 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001744 pACInfo->curr_state);
1745 // unable to service the request
1746 // nothing is pending so vote powersave back on
1747 pSession->readyForPowerSave = VOS_TRUE;
1748 VOS_ASSERT(0);
1749 new_state = pACInfo->curr_state;
1750 }
1751 /* if current state is same as previous no need for transistion,
1752 if we are doing reassoc & we are already in handoff state, no need to move
1753 to requested state. But make sure to set the previous state as requested
1754 state
1755 */
1756 if((new_state != pACInfo->curr_state)&&
1757 (!(pACInfo->reassoc_pending &&
1758 (SME_QOS_HANDOFF == pACInfo->curr_state))))
1759 {
1760 sme_QosStateTransition(sessionId, ac, new_state);
1761 }
1762
1763 if(pACInfo->reassoc_pending &&
1764 (SME_QOS_HANDOFF == pACInfo->curr_state))
1765 {
1766 pACInfo->prev_state = SME_QOS_REQUESTED;
1767 }
1768 if((SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) ||
1769 (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status))
1770 {
1771 (void)sme_QosProcessBufferedCmd(sessionId);
1772 }
1773 return status;
1774}
1775
1776/*--------------------------------------------------------------------------
1777 \brief sme_QosInternalModifyReq() - The SME QoS internal function to request
1778 for modification of certain QoS params on a flow running on a particular AC.
1779 If the request involves admission control on the requested AC, HDD needs to
1780 provide the necessary Traffic Specification (TSPEC) parameters & SME might
1781 start the renegotiation process through ADDTS.
1782
1783 \param pMac - Pointer to the global MAC parameter structure.
1784 \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC
1785 related info as defined above, provided by HDD
1786 \param QosFlowID - Identification per flow running on each AC generated by
1787 SME.
1788 It is only meaningful if the QoS setup for the flow has
1789 been successful already
1790
1791 \return SME_QOS_STATUS_SETUP_SUCCESS_RSP - Modification is successful.
1792
1793 Other status means request failed
1794 \sa
1795
1796 --------------------------------------------------------------------------*/
1797sme_QosStatusType sme_QosInternalModifyReq(tpAniSirGlobal pMac,
1798 sme_QosWmmTspecInfo * pQoSInfo,
1799 v_U32_t QosFlowID,
1800 v_BOOL_t buffered_cmd)
1801{
1802 tListElem *pEntry= NULL;
1803 sme_QosSessionInfo *pSession;
1804 sme_QosACInfo *pACInfo;
1805 sme_QosFlowInfoEntry *pNewEntry= NULL;
1806 sme_QosFlowInfoEntry *flow_info = NULL;
1807 sme_QosEdcaAcType ac;
1808 sme_QosStates new_state = SME_QOS_CLOSED;
1809 sme_QosStatusType status = SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
1810 sme_QosWmmTspecInfo Aggr_Tspec_Info;
1811 sme_QosSearchInfo search_key;
1812 sme_QosCmdInfo cmd;
1813 v_U8_t sessionId;
1814 v_BOOL_t bufferCommand;
1815 eHalStatus hstatus;
1816 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
1817 "%s: %d: invoked for flow %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001818 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001819 QosFlowID);
1820
1821 vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo));
1822 //set the key type & the key to be searched in the Flow List
1823 search_key.key.QosFlowID = QosFlowID;
1824 search_key.index = SME_QOS_SEARCH_KEY_INDEX_1;
1825 search_key.sessionId = SME_QOS_SEARCH_SESSION_ID_ANY;
1826 //go through the link list to find out the details on the flow
1827 pEntry = sme_QosFindInFlowList(search_key);
1828 if(!pEntry)
1829 {
1830 //Err msg
1831 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1832 "%s: %d: no match found for flowID = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001833 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001834 QosFlowID);
1835 return SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP;
1836 }
1837 // find the AC
1838 flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link );
1839 ac = flow_info->ac_type;
1840
1841 sessionId = flow_info->sessionId;
1842 pSession = &sme_QosCb.sessionInfo[sessionId];
1843 pACInfo = &pSession->ac_info[ac];
1844
1845 //validate QoS params
1846 if(!sme_QosValidateRequestedParams(pMac, pQoSInfo, sessionId))
1847 {
1848 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1849 "%s: %d: invalid params",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001850 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001851 return SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP;
1852 }
1853 // For modify, make sure that direction, TID and UP are not being altered
1854 if((pQoSInfo->ts_info.direction != flow_info->QoSInfo.ts_info.direction) ||
1855 (pQoSInfo->ts_info.up != flow_info->QoSInfo.ts_info.up) ||
1856 (pQoSInfo->ts_info.tid != flow_info->QoSInfo.ts_info.tid))
1857 {
1858 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1859 "%s: %d: Modification of direction/tid/up is not allowed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001860 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001861
1862 return SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP;
1863 }
1864 // need to vote off powersave for the duration of this request
1865 pSession->readyForPowerSave = VOS_FALSE;
1866 // assume we won't have to (re)buffer the command
1867 bufferCommand = VOS_FALSE;
1868 //check to consider the following flowing scenario
1869 //Addts request is pending on one AC, while APSD requested on another which
1870 //needs a reassoc. Will buffer a request if Addts is pending on any AC,
1871 //which will safegaurd the above scenario, & also won't confuse PE with back
1872 //to back Addts or Addts followed by Reassoc
1873 if(sme_QosIsRspPending(sessionId, ac))
1874 {
1875 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
1876 "%s: %d: buffering the modify request for flow %d in state %d "
1877 "since another request is pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001878 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001879 QosFlowID, pACInfo->curr_state );
1880 bufferCommand = VOS_TRUE;
1881 }
1882 else
1883 {
1884 // make sure we are in full power so that we can issue
1885 // an AddTS or reassoc if necessary
1886 hstatus = pmcRequestFullPower(pMac, sme_QosPmcFullPowerCallback,
1887 pSession, eSME_REASON_OTHER);
1888 if( eHAL_STATUS_PMC_PENDING == hstatus )
1889 {
1890 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
1891 "%s: %d: buffering the modify request for flow %d in state %d, "
1892 "waiting for full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001893 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001894 QosFlowID, pACInfo->curr_state );
1895 bufferCommand = VOS_TRUE;
1896 }
1897 }
1898 if (bufferCommand)
1899 {
1900 // we need to buffer the command
1901 cmd.command = SME_QOS_MODIFY_REQ;
1902 cmd.pMac = pMac;
1903 cmd.sessionId = sessionId;
1904 cmd.u.modifyCmdInfo.QosFlowID = QosFlowID;
1905 cmd.u.modifyCmdInfo.QoSInfo = *pQoSInfo;
1906 hstatus = sme_QosBufferCmd(&cmd, buffered_cmd);
1907 if(!HAL_STATUS_SUCCESS(hstatus))
1908 {
1909 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1910 "%s: %d: couldn't buffer the modify request in state = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001911 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001912 pACInfo->curr_state );
1913 // unable to buffer the request
1914 // nothing is pending so vote powersave back on
1915 pSession->readyForPowerSave = VOS_TRUE;
1916 return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
1917 }
1918 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
1919 "%s: %d: Buffered modify request for flow = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001920 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001921 QosFlowID);
1922 return SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP;
1923 }
1924 //get into the stat m/c to see if the request can be granted
1925 switch(pACInfo->curr_state)
1926 {
1927 case SME_QOS_QOS_ON:
1928 //save the new params adding a new (duplicate) entry in the Flow List
1929 //Once we have decided on OTA exchange needed or not we can delete the
1930 //original one from the List
1931 pNewEntry = (sme_QosFlowInfoEntry *) vos_mem_malloc(sizeof(*pNewEntry));
1932 if (!pNewEntry)
1933 {
1934 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1935 "%s: %d: couldn't allocate memory for the new "
1936 "entry in the Flow List",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001937 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001938 // unable to service the request
1939 // nothing is pending so vote powersave back on
1940 pSession->readyForPowerSave = VOS_TRUE;
1941 return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
1942 }
1943 pNewEntry->ac_type = ac;
1944 pNewEntry->sessionId = sessionId;
1945 pNewEntry->HDDcontext = flow_info->HDDcontext;
1946 pNewEntry->QoSCallback = flow_info->QoSCallback;
1947 pNewEntry->QosFlowID = flow_info->QosFlowID;
1948 pNewEntry->reason = SME_QOS_REASON_MODIFY_PENDING;
1949 //since it is a modify request, use the same index on which the flow
1950 //entry originally was running & add it to the Flow List at the end
1951 pNewEntry->tspec_mask = flow_info->tspec_mask;
1952 pNewEntry->QoSInfo = *pQoSInfo;
1953 //update the entry from Flow List which needed to be modified
1954 flow_info->reason = SME_QOS_REASON_MODIFY;
1955 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
1956 "%s: %d: On session %d creating modified "
1957 "entry at %p with flowID %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001958 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001959 sessionId, pNewEntry, pNewEntry->QosFlowID);
1960 //add the new entry under construction to the Flow List
1961 csrLLInsertTail(&sme_QosCb.flow_list, &pNewEntry->link, VOS_TRUE);
1962 //update TSPEC with the new param set
1963 hstatus = sme_QosUpdateParams(sessionId,
1964 ac, pNewEntry->tspec_mask,
1965 &Aggr_Tspec_Info);
1966 if(HAL_STATUS_SUCCESS(hstatus))
1967 {
1968 pACInfo->requested_QoSInfo[pNewEntry->tspec_mask -1] = Aggr_Tspec_Info;
1969 //if ACM, send out a new ADDTS
1970 status = sme_QosSetup(pMac, sessionId,
1971 &pACInfo->requested_QoSInfo[pNewEntry->tspec_mask -1],
1972 ac);
1973 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
1974 "%s: %d: On session %d with AC %d in state SME_QOS_QOS_ON "
1975 "sme_QosSetup returned with status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001976 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001977 sessionId, ac, status);
1978 if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP != status)
1979 {
1980 // we aren't waiting for a response from the AP
1981 // so vote powersave back on
1982 pSession->readyForPowerSave = VOS_TRUE;
1983 }
1984 if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status)
1985 {
1986 new_state = SME_QOS_REQUESTED;
1987 status = SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP;
1988 pACInfo->tspec_pending = pNewEntry->tspec_mask;
1989 }
1990 else if((SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) ||
1991 (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status))
1992 {
1993 new_state = SME_QOS_QOS_ON;
1994
1995 vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo));
1996 //delete the original entry in FLOW list which got modified
1997 search_key.key.ac_type = ac;
1998 search_key.index = SME_QOS_SEARCH_KEY_INDEX_2;
1999 search_key.sessionId = sessionId;
2000 hstatus = sme_QosFindAllInFlowList(pMac, search_key,
2001 sme_QosModifyFnp);
2002 if(!HAL_STATUS_SUCCESS(hstatus))
2003 {
2004 status = SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
2005 }
2006 if(SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP != status)
2007 {
2008 pACInfo->curr_QoSInfo[pNewEntry->tspec_mask -1] =
2009 pACInfo->requested_QoSInfo[pNewEntry->tspec_mask -1];
2010 if(SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status)
2011 {
2012 status = SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY;
2013 vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo));
2014 search_key.key.ac_type = ac;
2015 search_key.index = SME_QOS_SEARCH_KEY_INDEX_2;
2016 search_key.sessionId = sessionId;
2017 hstatus = sme_QosFindAllInFlowList(pMac, search_key,
2018 sme_QosModificationNotifyFnp);
2019 if(!HAL_STATUS_SUCCESS(hstatus))
2020 {
2021 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2022 "%s: %d: couldn't notify other "
2023 "entries on this AC =%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002024 __func__, __LINE__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002025 }
2026 }
2027 else if(SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status)
2028 {
2029 status = SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP;
2030 }
2031 }
2032 if(buffered_cmd)
2033 {
2034 flow_info->QoSCallback(pMac, flow_info->HDDcontext,
2035 &pACInfo->curr_QoSInfo[pNewEntry->tspec_mask -1],
2036 status,
2037 flow_info->QosFlowID);
2038 }
2039
2040 }
2041 else
2042 {
2043 // unexpected status returned by sme_QosSetup()
2044 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2045 "%s: %d: On session %d unexpected status %d "
2046 "returned by sme_QosSetup",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002047 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002048 sessionId, status);
2049 new_state = SME_QOS_QOS_ON;
2050 }
2051 }
2052 else
2053 {
2054 //err msg
2055 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2056 "%s: %d: sme_QosUpdateParams() failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002057 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002058 // unable to service the request
2059 // nothing is pending so vote powersave back on
2060 pSession->readyForPowerSave = VOS_TRUE;
2061 new_state = SME_QOS_LINK_UP;
2062 }
2063 /* if we are doing reassoc & we are already in handoff state, no need
2064 to move to requested state. But make sure to set the previous state
2065 as requested state
2066 */
2067 if(!(pACInfo->reassoc_pending &&
2068 (SME_QOS_HANDOFF == pACInfo->curr_state)))
2069 {
2070 sme_QosStateTransition(sessionId, ac, new_state);
2071 }
2072 else
2073 {
2074 pACInfo->prev_state = SME_QOS_REQUESTED;
2075 }
2076 break;
2077 case SME_QOS_HANDOFF:
2078 case SME_QOS_REQUESTED:
2079 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
2080 "%s: %d: Buffering modify request for flow %d in state = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002081 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002082 QosFlowID, pACInfo->curr_state );
2083 //buffer cmd
2084 cmd.command = SME_QOS_MODIFY_REQ;
2085 cmd.pMac = pMac;
2086 cmd.sessionId = sessionId;
2087 cmd.u.modifyCmdInfo.QosFlowID = QosFlowID;
2088 cmd.u.modifyCmdInfo.QoSInfo = *pQoSInfo;
2089 hstatus = sme_QosBufferCmd(&cmd, buffered_cmd);
2090 if(!HAL_STATUS_SUCCESS(hstatus))
2091 {
2092 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2093 "%s: %d: couldn't buffer the modify request in state = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002094 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002095 pACInfo->curr_state );
2096 // unable to buffer the request
2097 // nothing is pending so vote powersave back on
2098 pSession->readyForPowerSave = VOS_TRUE;
2099 return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
2100 }
2101 status = SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP;
2102 break;
2103 case SME_QOS_CLOSED:
2104 case SME_QOS_INIT:
2105 case SME_QOS_LINK_UP:
2106 default:
2107 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2108 "%s: %d: modify requested in unexpected state = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002109 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002110 pACInfo->curr_state);
2111 // unable to service the request
2112 // nothing is pending so vote powersave back on
2113 pSession->readyForPowerSave = VOS_TRUE;
2114 break;
2115 }
2116 if((SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) ||
2117 (SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY == status))
2118 {
2119 (void)sme_QosProcessBufferedCmd(sessionId);
2120 }
2121 return status;
2122}
2123/*--------------------------------------------------------------------------
2124 \brief sme_QosInternalReleaseReq() - The SME QoS internal function to request
2125 for releasing a QoS flow running on a particular AC.
2126
2127 \param pMac - Pointer to the global MAC parameter structure.
2128 \param QosFlowID - Identification per flow running on each AC generated by SME
2129 It is only meaningful if the QoS setup for the flow is
2130 successful
2131
2132 \return eHAL_STATUS_SUCCESS - Release is successful.
2133
2134 \sa
2135
2136 --------------------------------------------------------------------------*/
2137sme_QosStatusType sme_QosInternalReleaseReq(tpAniSirGlobal pMac,
2138 v_U32_t QosFlowID,
2139 v_BOOL_t buffered_cmd)
2140{
2141 tListElem *pEntry= NULL;
2142 sme_QosSessionInfo *pSession;
2143 sme_QosACInfo *pACInfo;
2144 sme_QosFlowInfoEntry *flow_info = NULL;
2145 sme_QosFlowInfoEntry *pDeletedFlow = NULL;
2146 sme_QosEdcaAcType ac;
2147 sme_QosStates new_state = SME_QOS_CLOSED;
2148 sme_QosStatusType status = SME_QOS_STATUS_RELEASE_FAILURE_RSP;
2149 sme_QosWmmTspecInfo Aggr_Tspec_Info;
2150 sme_QosSearchInfo search_key;
2151 sme_QosCmdInfo cmd;
2152 tCsrRoamModifyProfileFields modifyProfileFields;
2153 v_BOOL_t deltsIssued = VOS_FALSE;
2154 v_U8_t sessionId;
2155 v_BOOL_t bufferCommand;
2156 eHalStatus hstatus;
2157 v_BOOL_t biDirectionalFlowsPresent = VOS_FALSE;
2158 v_BOOL_t uplinkFlowsPresent = VOS_FALSE;
2159 v_BOOL_t downlinkFlowsPresent = VOS_FALSE;
2160 tListElem *pResult= NULL;
2161 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
2162 "%s: %d: invoked for flow %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002163 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002164 QosFlowID);
2165
2166 vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo));
2167 //set the key type & the key to be searched in the Flow List
2168 search_key.key.QosFlowID = QosFlowID;
2169 search_key.index = SME_QOS_SEARCH_KEY_INDEX_1;
2170 search_key.sessionId = SME_QOS_SEARCH_SESSION_ID_ANY;
2171 //go through the link list to find out the details on the flow
2172 pEntry = sme_QosFindInFlowList(search_key);
2173
2174 if(!pEntry)
2175 {
2176 //Err msg
2177 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2178 "%s: %d: no match found for flowID = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002179 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002180 QosFlowID);
2181 return SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP;
2182 }
2183 // find the AC
2184 flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link );
2185 ac = flow_info->ac_type;
2186 sessionId = flow_info->sessionId;
2187 pSession = &sme_QosCb.sessionInfo[sessionId];
2188 pACInfo = &pSession->ac_info[ac];
2189 // need to vote off powersave for the duration of this request
2190 pSession->readyForPowerSave = VOS_FALSE;
2191 // assume we won't have to (re)buffer the command
2192 bufferCommand = VOS_FALSE;
2193 //check to consider the following flowing scenario
2194 //Addts request is pending on one AC, while APSD requested on another which
2195 //needs a reassoc. Will buffer a request if Addts is pending on any AC,
2196 //which will safegaurd the above scenario, & also won't confuse PE with back
2197 //to back Addts or Addts followed by Reassoc
2198 if(sme_QosIsRspPending(sessionId, ac))
2199 {
2200 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
2201 "%s: %d: buffering the release request for flow %d in state %d "
2202 "since another request is pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002203 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002204 QosFlowID, pACInfo->curr_state );
2205 bufferCommand = VOS_TRUE;
2206 }
2207 else
2208 {
2209 // make sure we are in full power so that we can issue
2210 // a DelTS or reassoc if necessary
2211 hstatus = pmcRequestFullPower(pMac, sme_QosPmcFullPowerCallback,
2212 pSession, eSME_REASON_OTHER);
2213 if( eHAL_STATUS_PMC_PENDING == hstatus )
2214 {
2215 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
2216 "%s: %d: buffering the release request for flow %d in state %d, "
2217 "waiting for full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002218 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002219 QosFlowID, pACInfo->curr_state );
2220 bufferCommand = VOS_TRUE;
2221 }
2222 }
2223 if (bufferCommand)
2224 {
2225 // we need to buffer the command
2226 cmd.command = SME_QOS_RELEASE_REQ;
2227 cmd.pMac = pMac;
2228 cmd.sessionId = sessionId;
2229 cmd.u.releaseCmdInfo.QosFlowID = QosFlowID;
2230 hstatus = sme_QosBufferCmd(&cmd, buffered_cmd);
2231 if(!HAL_STATUS_SUCCESS(hstatus))
2232 {
2233 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2234 "%s: %d: couldn't buffer the release request in state = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002235 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002236 pACInfo->curr_state );
2237 // unable to buffer the request
2238 // nothing is pending so vote powersave back on
2239 pSession->readyForPowerSave = VOS_TRUE;
2240 return SME_QOS_STATUS_RELEASE_FAILURE_RSP;
2241 }
2242 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
2243 "%s: %d: Buffered release request for flow = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002244 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002245 QosFlowID);
2246 return SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP;
2247 }
2248 //get into the stat m/c to see if the request can be granted
2249 switch(pACInfo->curr_state)
2250 {
2251 case SME_QOS_QOS_ON:
2252 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
2253 "%s: %d: tspec_mask_status = %d for AC = %d with "
2254 "entry tspec_mask = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002255 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002256 pACInfo->tspec_mask_status, ac, flow_info->tspec_mask);
2257
2258 //check if multiple flows running on the ac
2259 if(pACInfo->num_flows[flow_info->tspec_mask - 1] > 1)
2260 {
2261 //don't want to include the flow in the new TSPEC on which release
2262 //is requested
2263 flow_info->reason = SME_QOS_REASON_RELEASE;
2264
2265 /* Check if the flow being released is for bi-diretional.
2266 * Following flows may present in the system.
2267 * a) bi-directional flows
2268 * b) uplink flows
2269 * c) downlink flows.
2270 * If the flow being released is for bidirectional, splitting of existing
2271 * streams into two tspec indices is required in case ff (b), (c) are present
2272 * and not (a).
2273 * In case if split occurs, all upstreams are aggregated into tspec index 0,
2274 * downstreams are aggregaed into tspec index 1 and two tspec requests for
2275 * (aggregated) upstream(s) followed by (aggregated) downstream(s) is sent
2276 * to AP. */
2277 if(flow_info->QoSInfo.ts_info.direction == SME_QOS_WMM_TS_DIR_BOTH)
2278 {
2279 vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo));
2280 //set the key type & the key to be searched in the Flow List
2281 search_key.key.ac_type = ac;
2282 search_key.index = SME_QOS_SEARCH_KEY_INDEX_4;
2283 search_key.sessionId = sessionId;
2284 search_key.direction = SME_QOS_WMM_TS_DIR_BOTH;
2285 pResult = sme_QosFindInFlowList(search_key);
2286 if(pResult)
2287 biDirectionalFlowsPresent = VOS_TRUE;
2288
2289 if(!biDirectionalFlowsPresent)
2290 {
2291 // The only existing bidirectional flow is being released
2292
2293 // Check if uplink flows exist
2294 search_key.direction = SME_QOS_WMM_TS_DIR_UPLINK;
2295 pResult = sme_QosFindInFlowList(search_key);
2296 if(pResult)
2297 uplinkFlowsPresent = VOS_TRUE;
2298
2299 // Check if downlink flows exist
2300 search_key.direction = SME_QOS_WMM_TS_DIR_DOWNLINK;
2301 pResult = sme_QosFindInFlowList(search_key);
2302 if(pResult)
2303 downlinkFlowsPresent = VOS_TRUE;
2304
2305 if(uplinkFlowsPresent && downlinkFlowsPresent)
2306 {
2307 // Need to split the uni-directional flows into SME_QOS_TSPEC_INDEX_0 and SME_QOS_TSPEC_INDEX_1
2308
2309 vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo));
2310 // Mark all downstream flows as using tspec index 1
2311 search_key.key.ac_type = ac;
2312 search_key.index = SME_QOS_SEARCH_KEY_INDEX_4;
2313 search_key.sessionId = sessionId;
2314 search_key.direction = SME_QOS_WMM_TS_DIR_DOWNLINK;
2315 sme_QosUpdateTspecMask(sessionId, search_key, SME_QOS_TSPEC_MASK_BIT_2_SET);
2316
2317 // Aggregate all downstream flows
2318 hstatus = sme_QosUpdateParams(sessionId,
2319 ac, SME_QOS_TSPEC_MASK_BIT_2_SET,
2320 &Aggr_Tspec_Info);
2321
2322 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2323 "%s: %d: On session %d buffering the AddTS request "
2324 "for AC %d in state %d as Addts is pending "
2325 "on other Tspec index of this AC",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002326 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002327 sessionId, ac, pACInfo->curr_state);
2328
2329 // Buffer the (aggregated) tspec request for downstream flows.
2330 // Please note that the (aggregated) tspec for upstream flows is sent
2331 // out by the susequent logic.
2332 cmd.command = SME_QOS_RESEND_REQ;
2333 cmd.pMac = pMac;
2334 cmd.sessionId = sessionId;
2335 cmd.u.resendCmdInfo.ac = ac;
2336 cmd.u.resendCmdInfo.tspecMask = SME_QOS_TSPEC_MASK_BIT_2_SET;
2337 cmd.u.resendCmdInfo.QoSInfo = Aggr_Tspec_Info;
2338 pACInfo->requested_QoSInfo[SME_QOS_TSPEC_MASK_BIT_2_SET - 1] = Aggr_Tspec_Info;
2339 if(!HAL_STATUS_SUCCESS(sme_QosBufferCmd(&cmd, VOS_FALSE)))
2340 {
2341 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2342 "%s: %d: On session %d unable to buffer the AddTS "
2343 "request for AC %d TSPEC %d in state %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002344 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002345 sessionId, ac, SME_QOS_TSPEC_MASK_BIT_2_SET, pACInfo->curr_state);
2346
2347 // unable to buffer the request
2348 // nothing is pending so vote powersave back on
2349 pSession->readyForPowerSave = VOS_TRUE;
2350
2351 return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
2352 }
2353 pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_BIT_1_2_SET;
2354
2355 }
2356 }
2357 }
2358
2359 /* In case of splitting of existing streams,
2360 * tspec_mask will be pointing to tspec index 0 and
2361 * aggregated tspec for upstream(s) is sent out here. */
2362 hstatus = sme_QosUpdateParams(sessionId,
2363 ac, flow_info->tspec_mask,
2364 &Aggr_Tspec_Info);
2365 if(HAL_STATUS_SUCCESS(hstatus))
2366 {
2367 pACInfo->requested_QoSInfo[flow_info->tspec_mask - 1] = Aggr_Tspec_Info;
2368 //if ACM, send out a new ADDTS
2369 status = sme_QosSetup(pMac, sessionId,
2370 &pACInfo->requested_QoSInfo[flow_info->tspec_mask - 1], ac);
2371 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
2372 "%s: %d: On session %d with AC %d in state SME_QOS_QOS_ON "
2373 "sme_QosSetup returned with status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002374 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002375 sessionId, ac, status);
2376 if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP != status)
2377 {
2378 // we aren't waiting for a response from the AP
2379 // so vote powersave back on
2380 pSession->readyForPowerSave = VOS_TRUE;
2381 }
2382 if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status)
2383 {
2384 new_state = SME_QOS_REQUESTED;
2385 status = SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP;
2386 pACInfo->tspec_pending = flow_info->tspec_mask;
2387 }
2388 else if((SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) ||
2389 (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status))
2390 {
2391 new_state = SME_QOS_QOS_ON;
2392 pACInfo->num_flows[flow_info->tspec_mask - 1]--;
2393 pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1] =
2394 pACInfo->requested_QoSInfo[flow_info->tspec_mask - 1];
2395 //delete the entry from Flow List
2396 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
2397 "%s: %d: Deleting entry at %p with flowID %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002398 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002399 flow_info, QosFlowID);
2400 csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE );
2401 pDeletedFlow = flow_info;
2402 if(SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status)
2403 {
2404 vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo));
2405 search_key.key.ac_type = ac;
2406 search_key.index = SME_QOS_SEARCH_KEY_INDEX_2;
2407 search_key.sessionId = sessionId;
2408 hstatus = sme_QosFindAllInFlowList(pMac, search_key,
2409 sme_QosSetupFnp);
2410 if(!HAL_STATUS_SUCCESS(hstatus))
2411 {
2412 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2413 "%s: %d: couldn't notify other "
2414 "entries on this AC =%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002415 __func__, __LINE__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002416 }
2417 }
2418 status = SME_QOS_STATUS_RELEASE_SUCCESS_RSP;
2419 if(buffered_cmd)
2420 {
2421 flow_info->QoSCallback(pMac, flow_info->HDDcontext,
2422 &pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1],
2423 status,
2424 flow_info->QosFlowID);
2425 }
2426 }
2427 else
2428 {
2429 // unexpected status returned by sme_QosSetup()
2430 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2431 "%s: %d: On session %d unexpected status %d "
2432 "returned by sme_QosSetup",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002433 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002434 sessionId, status);
2435 new_state = SME_QOS_LINK_UP;
2436 pACInfo->num_flows[flow_info->tspec_mask - 1]--;
2437 pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1] =
2438 pACInfo->requested_QoSInfo[flow_info->tspec_mask - 1];
2439 //delete the entry from Flow List
2440 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
2441 "%s: %d: On session %d deleting entry at "
2442 "%p with flowID %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002443 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002444 sessionId, flow_info, QosFlowID);
2445 csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE );
2446 pDeletedFlow = flow_info;
2447 if(buffered_cmd)
2448 {
2449 flow_info->QoSCallback(pMac, flow_info->HDDcontext,
2450 &pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1],
2451 status,
2452 flow_info->QosFlowID);
2453 }
2454 }
2455 }
2456 else
2457 {
2458 //err msg
2459 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2460 "%s: %d: sme_QosUpdateParams() failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002461 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002462 // unable to service the request
2463 // nothing is pending so vote powersave back on
2464 pSession->readyForPowerSave = VOS_TRUE;
2465 new_state = SME_QOS_LINK_UP;
2466 if(buffered_cmd)
2467 {
2468 flow_info->QoSCallback(pMac, flow_info->HDDcontext,
2469 &pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1],
2470 status,
2471 flow_info->QosFlowID);
2472 }
2473 }
2474 }
2475 else
2476 {
2477 // this is the only flow aggregated in this TSPEC
2478 status = SME_QOS_STATUS_RELEASE_SUCCESS_RSP;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07002479#if defined(FEATURE_WLAN_CCX) && !defined(FEATURE_WLAN_CCX_UPLOAD)
Jeff Johnson295189b2012-06-20 16:38:30 -07002480 if (ac == SME_QOS_EDCA_AC_VO)
2481 {
2482 // Indicate to neighbor roam logic of the new required VO
2483 // ac bandwidth requirement.
2484 csrNeighborRoamIndicateVoiceBW( pMac, pACInfo->curr_QoSInfo[0].peak_data_rate, FALSE );
2485 }
2486#endif
2487 //check if delts needs to be sent
2488 if(CSR_IS_ADDTS_WHEN_ACMOFF_SUPPORTED(pMac) ||
2489 sme_QosIsACM(pMac, pSession->assocInfo.pBssDesc, ac, NULL))
2490 {
2491 //check if other TSPEC for this AC is also in use
2492 if(SME_QOS_TSPEC_MASK_BIT_1_2_SET != pACInfo->tspec_mask_status)
2493 {
2494 // this is the only TSPEC active on this AC
2495 // so indicate that we no longer require APSD
2496 pSession->apsdMask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac));
2497 //Also update modifyProfileFields.uapsd_mask in CSR for consistency
2498 csrGetModifyProfileFields(pMac, flow_info->sessionId, &modifyProfileFields);
2499 modifyProfileFields.uapsd_mask = pSession->apsdMask;
2500 csrSetModifyProfileFields(pMac, flow_info->sessionId, &modifyProfileFields);
2501 if(!pSession->apsdMask)
2502 {
2503 // this session no longer needs UAPSD
2504 // do any sessions still require UAPSD?
2505 if (!sme_QosIsUapsdActive())
2506 {
2507 // No sessions require UAPSD so turn it off
2508 // (really don't care when PMC stops it)
2509 (void)pmcStopUapsd(pMac);
2510 }
2511 }
2512 }
Madan Mohan Koyyalamudic0a75a42013-10-07 04:20:49 +05302513 if (SME_QOS_RELEASE_DEFAULT == pACInfo->relTrig)
Jeff Johnson295189b2012-06-20 16:38:30 -07002514 {
Madan Mohan Koyyalamudic0a75a42013-10-07 04:20:49 +05302515 //send delts
2516 hstatus = qosIssueCommand(pMac, sessionId, eSmeCommandDelTs,
2517 NULL, ac, flow_info->tspec_mask);
2518 if(!HAL_STATUS_SUCCESS(hstatus))
2519 {
2520 //err msg
2521 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2522 "%s: %d: sme_QosDelTsReq() failed",
2523 __func__, __LINE__);
2524 status = SME_QOS_STATUS_RELEASE_FAILURE_RSP;
2525 // we won't be waiting for a response from the AP
2526 // so vote powersave back on
2527 pSession->readyForPowerSave = VOS_TRUE;
2528 }
2529 else
2530 {
2531 pACInfo->tspec_mask_status &= SME_QOS_TSPEC_MASK_BIT_1_2_SET &
2532 (~flow_info->tspec_mask);
2533 deltsIssued = VOS_TRUE;
2534 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002535 }
2536 else
2537 {
Madan Mohan Koyyalamudic0a75a42013-10-07 04:20:49 +05302538 pSession->readyForPowerSave = VOS_TRUE;
2539 pACInfo->tspec_mask_status &= SME_QOS_TSPEC_MASK_BIT_1_2_SET &
2540 (~flow_info->tspec_mask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002541 deltsIssued = VOS_TRUE;
2542 }
2543 }
2544 else if(pSession->apsdMask & (1 << (SME_QOS_EDCA_AC_VO - ac)))
2545 {
2546 //reassoc logic
2547 csrGetModifyProfileFields(pMac, sessionId, &modifyProfileFields);
2548 modifyProfileFields.uapsd_mask |= pSession->apsdMask;
2549 modifyProfileFields.uapsd_mask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac));
2550 pSession->apsdMask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac));
2551 if(!pSession->apsdMask)
2552 {
2553 // this session no longer needs UAPSD
2554 // do any sessions still require UAPSD?
2555 if (!sme_QosIsUapsdActive())
2556 {
2557 // No sessions require UAPSD so turn it off
2558 // (really don't care when PMC stops it)
2559 (void)pmcStopUapsd(pMac);
2560 }
2561 }
2562 hstatus = sme_QosRequestReassoc(pMac, sessionId,
2563 &modifyProfileFields, VOS_FALSE);
2564 if(!HAL_STATUS_SUCCESS(hstatus))
2565 {
2566 //err msg
2567 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2568 "%s: %d: Reassoc failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002569 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002570 status = SME_QOS_STATUS_RELEASE_FAILURE_RSP;
2571 // we won't be waiting for a response from the AP
2572 // so vote powersave back on
2573 pSession->readyForPowerSave = VOS_TRUE;
2574 }
2575 else
2576 {
2577 pACInfo->reassoc_pending = VOS_FALSE;//no need to wait
2578 pACInfo->prev_state = SME_QOS_LINK_UP;
2579 pACInfo->tspec_pending = 0;
2580 }
2581 }
2582 else
2583 {
2584 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
2585 "%s: %d: nothing to do for AC = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002586 __func__, __LINE__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002587 // we won't be waiting for a response from the AP
2588 // so vote powersave back on
2589 pSession->readyForPowerSave = VOS_TRUE;
2590 }
Madan Mohan Koyyalamudic0a75a42013-10-07 04:20:49 +05302591
2592 if (SME_QOS_RELEASE_BY_AP == pACInfo->relTrig)
Jeff Johnson295189b2012-06-20 16:38:30 -07002593 {
Madan Mohan Koyyalamudic0a75a42013-10-07 04:20:49 +05302594 flow_info->QoSCallback(pMac, flow_info->HDDcontext,
2595 &pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1],
2596 SME_QOS_STATUS_RELEASE_QOS_LOST_IND,
2597 flow_info->QosFlowID);
2598
2599 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
2600 "%s: %d: Deleting entry at %p with flowID %d",
2601 __func__, __LINE__,
2602 flow_info, flow_info->QosFlowID);
2603 }
2604 else if(buffered_cmd)
2605 {
2606 flow_info->QoSCallback(pMac, flow_info->HDDcontext,
Jeff Johnson295189b2012-06-20 16:38:30 -07002607 NULL,
2608 status,
2609 flow_info->QosFlowID);
2610 }
Madan Mohan Koyyalamudic0a75a42013-10-07 04:20:49 +05302611
Jeff Johnson295189b2012-06-20 16:38:30 -07002612 if(SME_QOS_STATUS_RELEASE_FAILURE_RSP == status)
2613 {
2614 break;
2615 }
2616
2617 if(((SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~flow_info->tspec_mask) > 0) &&
2618 ((SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~flow_info->tspec_mask) <=
2619 SME_QOS_TSPEC_INDEX_MAX))
2620 {
2621 if(pACInfo->num_flows[(SME_QOS_TSPEC_MASK_BIT_1_2_SET &
2622 ~flow_info->tspec_mask) - 1] > 0)
2623 {
2624 new_state = SME_QOS_QOS_ON;
2625 }
2626 else
2627 {
2628 new_state = SME_QOS_LINK_UP;
2629 }
2630 }
2631 else
2632 {
2633 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
2634 "%s: %d: Exceeded the array bounds of pACInfo->num_flows",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002635 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002636 VOS_ASSERT (0);
2637 return SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP;
2638 }
2639
2640 if(VOS_FALSE == deltsIssued)
2641 {
2642 vos_mem_zero(&pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1],
2643 sizeof(sme_QosWmmTspecInfo));
2644 }
2645 vos_mem_zero(&pACInfo->requested_QoSInfo[flow_info->tspec_mask - 1],
2646 sizeof(sme_QosWmmTspecInfo));
2647 pACInfo->num_flows[flow_info->tspec_mask - 1]--;
2648 //delete the entry from Flow List
2649 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
2650 "%s: %d: On session %d deleting entry at %p with flowID %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002651 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002652 sessionId, flow_info, QosFlowID);
2653 csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE );
2654 pDeletedFlow = flow_info;
Madan Mohan Koyyalamudic0a75a42013-10-07 04:20:49 +05302655 pACInfo->relTrig = SME_QOS_RELEASE_DEFAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07002656 }
2657 /* if we are doing reassoc & we are already in handoff state, no need
2658 to move to requested state. But make sure to set the previous state
2659 as requested state
2660 */
2661 if(SME_QOS_HANDOFF != pACInfo->curr_state)
2662 {
2663 sme_QosStateTransition(sessionId, ac, new_state);
2664 }
2665 if(pACInfo->reassoc_pending)
2666 {
2667 pACInfo->prev_state = SME_QOS_REQUESTED;
2668 }
2669 break;
2670 case SME_QOS_HANDOFF:
2671 case SME_QOS_REQUESTED:
2672 //buffer cmd
2673 cmd.command = SME_QOS_RELEASE_REQ;
2674 cmd.pMac = pMac;
2675 cmd.sessionId = sessionId;
2676 cmd.u.releaseCmdInfo.QosFlowID = QosFlowID;
2677 hstatus = sme_QosBufferCmd(&cmd, buffered_cmd);
2678 if(!HAL_STATUS_SUCCESS(hstatus))
2679 {
2680 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2681 "%s: %d: couldn't buffer the release request in state = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002682 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002683 pACInfo->curr_state );
2684 // unable to service the request
2685 // nothing is pending so vote powersave back on
2686 pSession->readyForPowerSave = VOS_TRUE;
2687 return SME_QOS_STATUS_RELEASE_FAILURE_RSP;
2688 }
2689 status = SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP;
2690 break;
2691 case SME_QOS_CLOSED:
2692 case SME_QOS_INIT:
2693 case SME_QOS_LINK_UP:
2694 default:
2695 //print error msg
2696 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2697 "%s: %d: release request in unexpected state = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002698 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002699 pACInfo->curr_state );
2700 //ASSERT
2701 VOS_ASSERT(0);
2702 // unable to service the request
2703 // nothing is pending so vote powersave back on
2704 pSession->readyForPowerSave = VOS_TRUE;
2705 break;
2706 }
2707 // if we deleted a flow, reclaim the memory
2708 if (pDeletedFlow)
2709 {
2710 vos_mem_free(pDeletedFlow);
2711 }
2712 if((SME_QOS_STATUS_RELEASE_SUCCESS_RSP == status))
2713 {
2714 (void)sme_QosProcessBufferedCmd(sessionId);
2715 }
2716 return status;
2717}
2718
2719/*--------------------------------------------------------------------------
2720 \brief sme_QosSetup() - The internal qos setup function which has the
2721 intelligence if the request is NOP, or for APSD and/or need to send out ADDTS.
2722 It also does the sanity check for QAP, AP supports APSD etc.
2723 \param pMac - Pointer to the global MAC parameter structure.
2724 \param sessionId - Session upon which setup is being performed
2725 \param pTspec_Info - Pointer to sme_QosWmmTspecInfo which contains the WMM
2726 TSPEC related info as defined above
2727 \param ac - Enumeration of the various EDCA Access Categories.
2728
2729 \return SME_QOS_STATUS_SETUP_SUCCESS_RSP if the setup is successful
2730 The logic used in the code might be confusing. Trying to cover all the cases
2731 here.
2732 AP supports App wants ACM = 1 Already set APSD Result
2733 | 0 | 0 | 0 | 0 | NO ACM NO APSD
2734 | 0 | 0 | 0 | 1 | NO ACM NO APSD/INVALID
2735 | 0 | 0 | 1 | 0 | ADDTS
2736 | 0 | 0 | 1 | 1 | ADDTS
2737 | 0 | 1 | 0 | 0 | FAILURE
2738 | 0 | 1 | 0 | 1 | INVALID
2739 | 0 | 1 | 1 | 0 | ADDTS
2740 | 0 | 1 | 1 | 1 | ADDTS
2741 | 1 | 0 | 0 | 0 | NO ACM NO APSD
2742 | 1 | 0 | 0 | 1 | NO ACM NO APSD
2743 | 1 | 0 | 1 | 0 | ADDTS
2744 | 1 | 0 | 1 | 1 | ADDTS
2745 | 1 | 1 | 0 | 0 | REASSOC
2746 | 1 | 1 | 0 | 1 | NOP: APSD SET ALREADY
2747 | 1 | 1 | 1 | 0 | ADDTS
2748 | 1 | 1 | 1 | 1 | ADDTS
2749
2750 \sa
2751
2752 --------------------------------------------------------------------------*/
2753sme_QosStatusType sme_QosSetup(tpAniSirGlobal pMac,
2754 v_U8_t sessionId,
2755 sme_QosWmmTspecInfo *pTspec_Info,
2756 sme_QosEdcaAcType ac)
2757{
2758 sme_QosSessionInfo *pSession;
2759 sme_QosACInfo *pACInfo;
2760 sme_QosStatusType status = SME_QOS_STATUS_SETUP_FAILURE_RSP;
2761 tDot11fBeaconIEs *pIes = NULL;
2762 tCsrRoamModifyProfileFields modifyProfileFields;
2763 eHalStatus hstatus;
2764 if( !CSR_IS_SESSION_VALID( pMac, sessionId ) )
2765 {
2766 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2767 "%s: %d: Session Id %d is invalid",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002768 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002769 sessionId);
2770 return status;
2771 }
2772 pSession = &sme_QosCb.sessionInfo[sessionId];
2773 if( !pSession->sessionActive )
2774 {
2775 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2776 "%s: %d: Session %d is inactive",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002777 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002778 sessionId);
2779 return status;
2780 }
2781 if(!pSession->assocInfo.pBssDesc)
2782 {
2783 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2784 "%s: %d: Session %d has an Invalid BSS Descriptor",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002785 __func__, __LINE__,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302786 sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002787 return status;
2788 }
2789 hstatus = csrGetParsedBssDescriptionIEs(pMac,
2790 pSession->assocInfo.pBssDesc,
2791 &pIes);
2792 if(!HAL_STATUS_SUCCESS(hstatus))
2793 {
2794 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2795 "%s: %d: On session %d unable to parse BSS IEs",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002796 __func__, __LINE__,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302797 sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002798 return status;
2799 }
2800
2801 /* success so pIes was allocated */
2802
2803 if( !CSR_IS_QOS_BSS(pIes) )
2804 {
2805 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2806 "%s: %d: On session %d AP doesn't support QoS",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002807 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002808 sessionId);
2809 vos_mem_free(pIes);
2810 //notify HDD through the synchronous status msg
2811 return SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP;
2812 }
Madan Mohan Koyyalamudi4f2a39f2013-08-13 23:04:47 +05302813
2814 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
Jeff Johnsonce8ad512013-10-30 12:34:42 -07002815 "%s: %d: UAPSD/PSB set %d: ", __func__, __LINE__,
Madan Mohan Koyyalamudi4f2a39f2013-08-13 23:04:47 +05302816 pTspec_Info->ts_info.psb);
Jeff Johnson295189b2012-06-20 16:38:30 -07002817
2818 pACInfo = &pSession->ac_info[ac];
2819 do
2820 {
2821 // is ACM enabled for this AC?
2822 if(CSR_IS_ADDTS_WHEN_ACMOFF_SUPPORTED(pMac) ||
2823 sme_QosIsACM(pMac, pSession->assocInfo.pBssDesc, ac, NULL))
2824 {
2825 // ACM is enabled for this AC so we must send an AddTS
2826 if(pTspec_Info->ts_info.psb &&
2827 (!pMac->pmc.uapsdEnabled ))
2828 {
2829 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
2830 "%s: %d: Request is looking for APSD but PMC doesn't "
2831 "have support for APSD",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002832 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002833 break;
2834 }
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +05302835
2836 if (pTspec_Info->ts_info.psb &&
2837 !(pIes->WMMParams.qosInfo & SME_QOS_AP_SUPPORTS_APSD) &&
2838 !(pIes->WMMInfoAp.uapsd))
2839 {
2840 // application is looking for APSD but AP doesn't support it
2841 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2842 "%s: %d: On session %d AP doesn't support APSD",
2843 __func__, __LINE__,
2844 sessionId);
2845 break;
2846 }
2847
Jeff Johnson295189b2012-06-20 16:38:30 -07002848 if(SME_QOS_MAX_TID == pTspec_Info->ts_info.tid)
2849 {
2850 //App didn't set TID, generate one
2851 pTspec_Info->ts_info.tid =
2852 (v_U8_t)(SME_QOS_WMM_UP_NC - pTspec_Info->ts_info.up);
2853 }
2854 //addts logic
2855 hstatus = qosIssueCommand(pMac, sessionId, eSmeCommandAddTs,
2856 pTspec_Info, ac, 0);
2857 if(!HAL_STATUS_SUCCESS(hstatus))
2858 {
2859 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2860 "%s: %d: sme_QosAddTsReq() failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002861 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002862 break;
2863 }
2864 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
2865 "%s: %d: On session %d AddTS on AC %d is pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002866 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002867 sessionId, ac);
2868 status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP;
2869 break;
2870 }
2871 // ACM is not enabled for this AC
2872 // Is the application looking for APSD?
2873 if(0 == pTspec_Info->ts_info.psb)
2874 {
2875 //no, we don't need APSD
2876 //but check the case, if the setup is called as a result of a release
2877 // or modify which boils down to the fact that APSD was set on this AC
2878 // but no longer needed - so we need a reassoc for the above case to
2879 // let the AP know
2880 if(pSession->apsdMask & (1 << (SME_QOS_EDCA_AC_VO - ac)))
2881 {
2882 // APSD was formerly enabled on this AC but is no longer required
2883 // so we must reassociate
2884 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
2885 "%s: %d: On session %d reassoc needed "
2886 "to disable APSD on AC %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002887 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002888 sessionId, ac);
2889 csrGetModifyProfileFields(pMac, sessionId, &modifyProfileFields);
2890 modifyProfileFields.uapsd_mask |= pSession->apsdMask;
2891 modifyProfileFields.uapsd_mask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac));
2892 hstatus = sme_QosRequestReassoc(pMac, sessionId,
2893 &modifyProfileFields, VOS_FALSE);
2894 if(!HAL_STATUS_SUCCESS(hstatus))
2895 {
2896 //err msg
2897 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2898 "%s: %d: Unable to request reassociation",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002899 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002900 break;
2901 }
2902 else
2903 {
2904 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
2905 "%s: %d: On session %d reassociation to enable "
2906 "APSD on AC %d is pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002907 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002908 sessionId, ac);
2909 status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP;
2910 pACInfo->reassoc_pending = VOS_TRUE;
2911 }
2912 }
2913 else
2914 {
2915 // we don't need APSD on this AC
2916 // and we don't currently have APSD on this AC
2917 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
2918 "%s: %d: Request is not looking for APSD & Admission "
2919 "Control isn't mandatory for the AC",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002920 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002921 //return success right away
2922 status = SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP;
2923 }
2924 break;
2925 }
2926 else if(!(pIes->WMMParams.qosInfo & SME_QOS_AP_SUPPORTS_APSD) &&
2927 !(pIes->WMMInfoAp.uapsd))
2928 {
2929 // application is looking for APSD but AP doesn't support it
2930 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2931 "%s: %d: On session %d AP doesn't support APSD",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002932 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002933 sessionId);
2934 break;
2935 }
2936 else if(pSession->apsdMask & (1 << (SME_QOS_EDCA_AC_VO - ac)))
2937 {
2938 // application is looking for APSD
2939 // and it is already enabled on this AC
2940 status = SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY;
2941 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
2942 "%s: %d: Request is looking for APSD and it is already "
2943 "set for the AC",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002944 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002945 break;
2946 }
2947 else
2948 {
2949 // application is looking for APSD
2950 // but it is not enabled on this AC
2951 // so we need to reassociate
2952 if(pMac->pmc.uapsdEnabled)
2953 {
2954 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
2955 "%s: %d: On session %d reassoc needed "
2956 "to enable APSD on AC %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002957 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002958 sessionId, ac);
2959 //reassoc logic
2960 // update the UAPSD mask to include the new
2961 // AC on which APSD is requested
2962 csrGetModifyProfileFields(pMac, sessionId, &modifyProfileFields);
2963 modifyProfileFields.uapsd_mask |= pSession->apsdMask;
2964 modifyProfileFields.uapsd_mask |= 1 << (SME_QOS_EDCA_AC_VO - ac);
2965 hstatus = sme_QosRequestReassoc(pMac, sessionId,
2966 &modifyProfileFields, VOS_FALSE);
2967 if(!HAL_STATUS_SUCCESS(hstatus))
2968 {
2969 //err msg
2970 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2971 "%s: %d: Unable to request reassociation",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002972 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002973 break;
2974 }
2975 else
2976 {
2977 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
2978 "%s: %d: On session %d reassociation to enable "
2979 "APSD on AC %d is pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002980 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07002981 sessionId, ac);
2982 status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP;
2983 pACInfo->reassoc_pending = VOS_TRUE;
2984 }
2985 }
2986 else
2987 {
2988 //err msg: no support for APSD from PMC
2989 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2990 "%s: %d: no support for APSD or BMPS from PMC",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002991 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002992 }
2993 }
2994 }while(0);
2995
2996 vos_mem_free(pIes);
2997 return status;
2998}
2999
Jeff Johnson43971f52012-07-17 12:26:56 -07003000#if defined(FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07003001/* This is a dummy function now. But the purpose of me adding this was to
3002 * delay the TSPEC processing till SET_KEY completes. This function can be
3003 * used to do any SME_QOS processing after the SET_KEY. As of now, it is
3004 * not required as we are ok with tspec getting programmed before set_key
3005 * as the roam timings are measured without tspec in reassoc!
3006 */
3007eHalStatus sme_QosProcessSetKeySuccessInd(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info)
3008{
3009 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
Jeff Johnson43971f52012-07-17 12:26:56 -07003010 "########### Set Key Complete #############");
Tushnim Bhattacharyya8436d772013-06-26 23:03:29 -07003011 (void)sme_QosProcessBufferedCmd(sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07003012 return eHAL_STATUS_SUCCESS;
3013}
Jeff Johnson43971f52012-07-17 12:26:56 -07003014#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003015
Jeff Johnson43971f52012-07-17 12:26:56 -07003016#ifdef FEATURE_WLAN_CCX
Jeff Johnson295189b2012-06-20 16:38:30 -07003017/*--------------------------------------------------------------------------
3018 \brief sme_QosCCXSaveTspecResponse() - This function saves the TSPEC
3019 parameters that came along in the TSPEC IE in the reassoc response
3020
3021 \param pMac - Pointer to the global MAC parameter structure.
3022 \param sessionId - SME session ID
3023 \param pTspec - Pointer to the TSPEC IE from the reassoc rsp
3024 \param ac - Access Category for which this TSPEC rsp is received
3025 \param tspecIndex - flow/direction
3026
3027 \return eHAL_STATUS_SUCCESS - Release is successful.
3028 --------------------------------------------------------------------------*/
3029eHalStatus sme_QosCCXSaveTspecResponse(tpAniSirGlobal pMac, v_U8_t sessionId, tDot11fIEWMMTSPEC *pTspec, v_U8_t ac, v_U8_t tspecIndex)
3030{
3031 tpSirAddtsRsp pAddtsRsp = &sme_QosCb.sessionInfo[sessionId].ac_info[ac].addTsRsp[tspecIndex];
3032
3033 ac = sme_QosUPtoACMap[pTspec->user_priority];
3034
3035 vos_mem_zero(pAddtsRsp, sizeof(tSirAddtsRsp));
3036
3037 pAddtsRsp->messageType = eWNI_SME_ADDTS_RSP;
3038 pAddtsRsp->length = sizeof(tSirAddtsRsp);
3039 pAddtsRsp->rc = eSIR_SUCCESS;
3040 pAddtsRsp->sessionId = sessionId;
3041 pAddtsRsp->rsp.dialogToken = 0;
3042 pAddtsRsp->rsp.status = eSIR_SUCCESS;
3043 pAddtsRsp->rsp.wmeTspecPresent = pTspec->present;
3044 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
3045 "%s: Copy Tspec to local data structure ac=%d, tspecIdx=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003046 __func__, ac, tspecIndex);
Jeff Johnson295189b2012-06-20 16:38:30 -07003047
3048 if (pAddtsRsp->rsp.wmeTspecPresent)
3049 {
3050 //Copy TSPEC params received in assoc response to addts response
3051 ConvertWMMTSPEC(pMac, &pAddtsRsp->rsp.tspec, pTspec);
3052 }
3053
3054 return eHAL_STATUS_SUCCESS;
3055}
3056
3057/*--------------------------------------------------------------------------
3058 \brief sme_QosCCXProcessReassocTspecRsp() - This function processes the
3059 WMM TSPEC IE in the reassoc response. Reassoc triggered as part of
3060 CCX roaming to another CCX capable AP. If the TSPEC was added before
3061 reassoc, as part of Call Admission Control, the reasso req from the
3062 STA would carry the TSPEC parameters which were already negotiated
3063 with the older AP.
3064
3065 \param pMac - Pointer to the global MAC parameter structure.
3066 \param sessionId - SME session ID
3067 \param pEven_info - Pointer to the smeJoinRsp structure
3068
3069 \return eHAL_STATUS_SUCCESS - Release is successful.
3070 --------------------------------------------------------------------------*/
3071eHalStatus sme_QosCCXProcessReassocTspecRsp(tpAniSirGlobal pMac, v_U8_t sessionId, void* pEvent_info)
3072{
3073 sme_QosSessionInfo *pSession;
3074 sme_QosACInfo *pACInfo;
3075 tDot11fIEWMMTSPEC *pTspecIE = NULL;
3076 tCsrRoamSession *pCsrSession = CSR_GET_SESSION( pMac, sessionId );
3077 tCsrRoamConnectedInfo *pCsrConnectedInfo = &pCsrSession->connectedInfo;
3078 eHalStatus status = eHAL_STATUS_FAILURE;
3079 v_U8_t ac, numTspec, cnt;
3080 v_U8_t tspec_flow_index, tspec_mask_status;
3081 v_U32_t tspecIeLen;
3082
3083 pSession = &sme_QosCb.sessionInfo[sessionId];
3084
3085 // Get the TSPEC IEs which came along with the reassoc response
3086 // from the pbFrames pointer
3087 pTspecIE = (tDot11fIEWMMTSPEC *)(pCsrConnectedInfo->pbFrames + pCsrConnectedInfo->nBeaconLength +
3088 pCsrConnectedInfo->nAssocReqLength + pCsrConnectedInfo->nAssocRspLength + pCsrConnectedInfo->nRICRspLength);
3089
3090 // Get the number of tspecs Ies in the frame, the min length
3091 // should be atleast equal to the one TSPEC IE
3092 tspecIeLen = pCsrConnectedInfo->nTspecIeLength;
3093 if (tspecIeLen < sizeof(tDot11fIEWMMTSPEC)) {
3094 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08003095 FL("CCX Tspec IE len %d less than min %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07003096 tspecIeLen, sizeof(tDot11fIEWMMTSPEC));
3097 return eHAL_STATUS_FAILURE;
3098 }
3099
3100 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08003101 "TspecLen = %d, pbFrames = %p, pTspecIE = %p",
Jeff Johnson295189b2012-06-20 16:38:30 -07003102 tspecIeLen, pCsrConnectedInfo->pbFrames, pTspecIE);
3103
3104 numTspec = (tspecIeLen)/sizeof(tDot11fIEWMMTSPEC);
3105 for(cnt=0; cnt<numTspec; cnt++) {
3106 ac = sme_QosUpToAc(pTspecIE->user_priority);
3107 pACInfo = &pSession->ac_info[ac];
3108 tspec_mask_status = pACInfo->tspec_mask_status;
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08003109 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
3110 FL("UP=%d, ac=%d, tspec_mask_status=%x"),
Jeff Johnson295189b2012-06-20 16:38:30 -07003111 pTspecIE->user_priority, ac, tspec_mask_status );
3112
3113 for (tspec_flow_index = 0; tspec_flow_index < SME_QOS_TSPEC_INDEX_MAX; tspec_flow_index++) {
3114 if (tspec_mask_status & (1 << tspec_flow_index)) {
3115 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
3116 FL("Found Tspec entry flow = %d AC = %d"),tspec_flow_index, ac);
3117 sme_QosCCXSaveTspecResponse(pMac, sessionId, pTspecIE, ac, tspec_flow_index);
3118 } else {
3119 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
3120 FL("Not found Tspec entry flow = %d AC = %d"),tspec_flow_index, ac);
3121 }
3122 }
3123 // Increment the pointer to point it to the next TSPEC IE
3124 pTspecIE++;
3125 }
3126
3127 /* Send the Aggregated QoS request to HAL */
3128 status = sme_QosFTAggrQosReq(pMac,sessionId);
3129
3130 return status;
3131}
3132
3133/*--------------------------------------------------------------------------
3134 \brief sme_QosCopyTspecInfo() - This function copies the existing TSPEC
3135 parameters from the source structure to the destination structure.
3136
3137 \param pMac - Pointer to the global MAC parameter structure.
3138 \param pTspec_Info - source structure
3139 \param pTspec - destination structure
3140
3141 \return void
3142 --------------------------------------------------------------------------*/
3143static void sme_QosCopyTspecInfo(tpAniSirGlobal pMac, sme_QosWmmTspecInfo *pTspec_Info, tSirMacTspecIE* pTspec)
3144{
3145 /* As per WMM_AC_testplan_v0.39 Minimum Service Interval, Maximum Service
3146 * Interval, Service Start Time, Suspension Interval and Delay Bound are
3147 * all intended for HCCA operation and therefore must be set to zero*/
3148 pTspec->delayBound = pTspec_Info->delay_bound;
3149 pTspec->inactInterval = pTspec_Info->inactivity_interval;
3150 pTspec->length = SME_QOS_TSPEC_IE_LENGTH;
3151 pTspec->maxBurstSz = pTspec_Info->max_burst_size;
3152 pTspec->maxMsduSz = pTspec_Info->maximum_msdu_size;
3153 pTspec->maxSvcInterval = pTspec_Info->max_service_interval;
3154 pTspec->meanDataRate = pTspec_Info->mean_data_rate;
3155 pTspec->mediumTime = pTspec_Info->medium_time;
3156 pTspec->minDataRate = pTspec_Info->min_data_rate;
3157 pTspec->minPhyRate = pTspec_Info->min_phy_rate;
3158 pTspec->minSvcInterval = pTspec_Info->min_service_interval;
3159 pTspec->nomMsduSz = pTspec_Info->nominal_msdu_size;
3160 pTspec->peakDataRate = pTspec_Info->peak_data_rate;
3161 pTspec->surplusBw = pTspec_Info->surplus_bw_allowance;
3162 pTspec->suspendInterval = pTspec_Info->suspension_interval;
3163 pTspec->svcStartTime = pTspec_Info->svc_start_time;
3164 pTspec->tsinfo.traffic.direction = pTspec_Info->ts_info.direction;
3165
3166 //Make sure UAPSD is allowed. BTC may want to disable UAPSD while keep QoS setup
3167 if (pTspec_Info->ts_info.psb && btcIsReadyForUapsd(pMac)) {
3168 pTspec->tsinfo.traffic.psb = pTspec_Info->ts_info.psb;
3169 } else {
3170 pTspec->tsinfo.traffic.psb = 0;
3171 pTspec_Info->ts_info.psb = 0;
3172 }
3173 pTspec->tsinfo.traffic.tsid = pTspec_Info->ts_info.tid;
3174 pTspec->tsinfo.traffic.userPrio = pTspec_Info->ts_info.up;
3175 pTspec->tsinfo.traffic.accessPolicy = SME_QOS_ACCESS_POLICY_EDCA;
3176 pTspec->tsinfo.traffic.burstSizeDefn = pTspec_Info->ts_info.burst_size_defn;
3177 pTspec->tsinfo.traffic.ackPolicy = pTspec_Info->ts_info.ack_policy;
3178 pTspec->type = SME_QOS_TSPEC_IE_TYPE;
3179
3180 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
3181 "%s: %d: up = %d, tid = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003182 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003183 pTspec_Info->ts_info.up,
3184 pTspec_Info->ts_info.tid);
3185}
3186
3187/*--------------------------------------------------------------------------
3188 \brief sme_QosCCxRetrieveTspecInfo() - This function is called by CSR
3189 when try to create reassoc request message to PE - csrSendSmeReassocReqMsg
3190 This functions get the existing tspec parameters to be included
3191 in the reassoc request.
3192
3193 \param pMac - Pointer to the global MAC parameter structure.
3194 \param sessionId - SME session ID
3195 \param pTspecInfo - Pointer to the structure to carry back the TSPEC parameters
3196
3197 \return v_U8_t - number of existing negotiated TSPECs
3198 --------------------------------------------------------------------------*/
3199v_U8_t sme_QosCCxRetrieveTspecInfo(tpAniSirGlobal pMac, v_U8_t sessionId, tTspecInfo *pTspecInfo)
3200{
3201 sme_QosSessionInfo *pSession;
3202 sme_QosACInfo *pACInfo;
3203 v_U8_t tspec_mask_status = 0;
3204 v_U8_t tspec_pending_status = 0;
3205 v_U8_t ac, numTspecs = 0;
3206 tTspecInfo *pDstTspec = pTspecInfo;
3207
3208 //TODO: Check if TSPEC has already been established, if not return
3209
3210 pSession = &sme_QosCb.sessionInfo[sessionId];
3211
3212 for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) {
3213 volatile v_U8_t tspec_index = 0;
3214
3215 pACInfo = &pSession->ac_info[ac];
3216 tspec_pending_status = pACInfo->tspec_pending;
3217 tspec_mask_status = pACInfo->tspec_mask_status;
3218
3219 do {
3220 if (tspec_mask_status & SME_QOS_TSPEC_MASK_BIT_1_SET) {
3221 /* If a tspec status is pending, take requested_QoSInfo for RIC request, else use curr_QoSInfo
3222 for the RIC request */
3223 if (tspec_pending_status & SME_QOS_TSPEC_MASK_BIT_1_SET) {
3224 sme_QosCopyTspecInfo(pMac, &pACInfo->requested_QoSInfo[tspec_index], &pDstTspec->tspec);
3225 } else {
3226 sme_QosCopyTspecInfo(pMac, &pACInfo->curr_QoSInfo[tspec_index], &pDstTspec->tspec);
3227 }
3228 pDstTspec->valid = TRUE;
3229 numTspecs++;
3230 pDstTspec++;
3231 }
3232 tspec_mask_status >>= 1;
3233 tspec_pending_status >>= 1;
3234 tspec_index++;
3235 } while (tspec_mask_status);
3236 }
3237
3238 return numTspecs;
3239}
3240
3241#endif
3242
3243#ifdef WLAN_FEATURE_VOWIFI_11R
3244
3245eHalStatus sme_QosCreateTspecRICIE(tpAniSirGlobal pMac, sme_QosWmmTspecInfo *pTspec_Info,
3246 v_U8_t *pRICBuffer, v_U32_t *pRICLength, v_U8_t *pRICIdentifier)
3247{
3248 tDot11fIERICDataDesc ricIE;
3249 tANI_U32 nStatus;
3250
3251 VOS_ASSERT(NULL != pRICBuffer);
3252 VOS_ASSERT(NULL != pRICLength);
3253 VOS_ASSERT(NULL != pRICIdentifier);
3254
Gopichand Nakkalad5a904e2013-03-29 01:07:54 +05303255 if (pRICBuffer == NULL || pRICIdentifier == NULL || pRICLength == NULL)
3256 return eHAL_STATUS_FAILURE;
3257
Jeff Johnson295189b2012-06-20 16:38:30 -07003258 vos_mem_zero(&ricIE, sizeof(tDot11fIERICDataDesc));
3259
3260 ricIE.present = 1;
3261 ricIE.RICData.present = 1;
3262 ricIE.RICData.resourceDescCount = 1;
3263 ricIE.RICData.statusCode = 0;
3264 ricIE.RICData.Identifier = sme_QosAssignDialogToken();
3265#ifndef USE_80211_WMMTSPEC_FOR_RIC
3266 ricIE.TSPEC.present = 1;
3267 ricIE.TSPEC.delay_bound = pTspec_Info->delay_bound;
3268 ricIE.TSPEC.inactivity_int = pTspec_Info->inactivity_interval;
3269 ricIE.TSPEC.burst_size = pTspec_Info->max_burst_size;
3270 ricIE.TSPEC.max_msdu_size = pTspec_Info->maximum_msdu_size;
3271 ricIE.TSPEC.max_service_int = pTspec_Info->max_service_interval;
3272 ricIE.TSPEC.mean_data_rate = pTspec_Info->mean_data_rate;
Madan Mohan Koyyalamudi2bf6e0c2013-08-28 11:41:04 +05303273 ricIE.TSPEC.medium_time = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003274 ricIE.TSPEC.min_data_rate = pTspec_Info->min_data_rate;
3275 ricIE.TSPEC.min_phy_rate = pTspec_Info->min_phy_rate;
3276 ricIE.TSPEC.min_service_int = pTspec_Info->min_service_interval;
3277 ricIE.TSPEC.size = pTspec_Info->nominal_msdu_size;
3278 ricIE.TSPEC.peak_data_rate = pTspec_Info->peak_data_rate;
3279 ricIE.TSPEC.surplus_bw_allowance = pTspec_Info->surplus_bw_allowance;
3280 ricIE.TSPEC.suspension_int = pTspec_Info->suspension_interval;
3281 ricIE.TSPEC.service_start_time = pTspec_Info->svc_start_time;
3282 ricIE.TSPEC.direction = pTspec_Info->ts_info.direction;
3283 //Make sure UAPSD is allowed. BTC may want to disable UAPSD while keep QoS setup
3284 if( pTspec_Info->ts_info.psb && btcIsReadyForUapsd(pMac) )
3285 {
3286 ricIE.TSPEC.psb = pTspec_Info->ts_info.psb;
3287 }
3288 else
3289 {
3290 ricIE.TSPEC.psb = 0;
3291 }
3292 ricIE.TSPEC.tsid = pTspec_Info->ts_info.tid;
3293 ricIE.TSPEC.user_priority = pTspec_Info->ts_info.up;
3294 ricIE.TSPEC.access_policy = SME_QOS_ACCESS_POLICY_EDCA;
3295
3296 *pRICIdentifier = ricIE.RICData.Identifier;
3297
3298 nStatus = dot11fPackIeRICDataDesc(pMac, &ricIE, pRICBuffer, sizeof(ricIE), pRICLength);
3299 if (DOT11F_FAILED(nStatus))
3300 {
3301 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
3302 FL("Packing of RIC Data of length %d failed with status %d"),
3303 *pRICLength, nStatus);
3304 }
3305#else // WMM TSPEC
3306 /*As per WMM_AC_testplan_v0.39 Minimum Service Interval, Maximum Service
3307 Interval, Service Start Time, Suspension Interval and Delay Bound are
3308 all intended for HCCA operation and therefore must be set to zero*/
3309 ricIE.WMMTSPEC.present = 1;
3310 ricIE.WMMTSPEC.version = 1;
3311 ricIE.WMMTSPEC.delay_bound = pTspec_Info->delay_bound;
3312 ricIE.WMMTSPEC.inactivity_int = pTspec_Info->inactivity_interval;
3313 ricIE.WMMTSPEC.burst_size = pTspec_Info->max_burst_size;
3314 ricIE.WMMTSPEC.max_msdu_size = pTspec_Info->maximum_msdu_size;
3315 ricIE.WMMTSPEC.max_service_int = pTspec_Info->max_service_interval;
3316 ricIE.WMMTSPEC.mean_data_rate = pTspec_Info->mean_data_rate;
Madan Mohan Koyyalamudi2bf6e0c2013-08-28 11:41:04 +05303317 ricIE.WMMTSPEC.medium_time = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003318 ricIE.WMMTSPEC.min_data_rate = pTspec_Info->min_data_rate;
3319 ricIE.WMMTSPEC.min_phy_rate = pTspec_Info->min_phy_rate;
3320 ricIE.WMMTSPEC.min_service_int = pTspec_Info->min_service_interval;
3321 ricIE.WMMTSPEC.size = pTspec_Info->nominal_msdu_size;
3322 ricIE.WMMTSPEC.peak_data_rate = pTspec_Info->peak_data_rate;
3323 ricIE.WMMTSPEC.surplus_bw_allowance = pTspec_Info->surplus_bw_allowance;
3324 ricIE.WMMTSPEC.suspension_int = pTspec_Info->suspension_interval;
3325 ricIE.WMMTSPEC.service_start_time = pTspec_Info->svc_start_time;
3326 ricIE.WMMTSPEC.direction = pTspec_Info->ts_info.direction;
3327 //Make sure UAPSD is allowed. BTC may want to disable UAPSD while keep QoS setup
3328 if( pTspec_Info->ts_info.psb && btcIsReadyForUapsd(pMac) )
3329 {
3330 ricIE.WMMTSPEC.psb = pTspec_Info->ts_info.psb;
3331 }
3332 else
3333 {
3334 ricIE.WMMTSPEC.psb = 0;
3335 }
3336 ricIE.WMMTSPEC.tsid = pTspec_Info->ts_info.tid;
3337 ricIE.WMMTSPEC.user_priority = pTspec_Info->ts_info.up;
3338 ricIE.WMMTSPEC.access_policy = SME_QOS_ACCESS_POLICY_EDCA;
3339
3340
3341 nStatus = dot11fPackIeRICDataDesc(pMac, &ricIE, pRICBuffer, sizeof(ricIE), pRICLength);
3342 if (DOT11F_FAILED(nStatus))
3343 {
3344 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
3345 FL("Packing of RIC Data of length %d failed with status %d"),
3346 *pRICLength, nStatus);
3347 }
3348#endif /* 80211_TSPEC */
3349 *pRICIdentifier = ricIE.RICData.Identifier;
3350 return nStatus;
3351}
3352
3353eHalStatus sme_QosProcessFTReassocReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info)
3354{
3355 sme_QosSessionInfo *pSession;
3356 sme_QosACInfo *pACInfo;
3357 v_U8_t ac, qos_requested = FALSE;
3358 v_U8_t tspec_flow_index;
3359 sme_QosFlowInfoEntry *flow_info = NULL;
3360 tListElem *pEntry= NULL;
3361
3362 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
3363 FL("Invoked on session %d"), sessionId);
3364
3365 pSession = &sme_QosCb.sessionInfo[sessionId];
3366
3367 for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++)
3368 {
3369 pACInfo = &pSession->ac_info[ac];
3370 qos_requested = FALSE;
3371
3372 for (tspec_flow_index = 0; tspec_flow_index < SME_QOS_TSPEC_INDEX_MAX; tspec_flow_index++)
3373 {
3374 /* Only in the below case, copy the AC's curr QoS Info to requested QoS info */
3375 if ((pACInfo->ricIdentifier[tspec_flow_index] && !pACInfo->tspec_pending) ||
3376 (pACInfo->tspec_mask_status & (1<<tspec_flow_index)))
3377 {
3378 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08003379 FL("Copying the currentQos to requestedQos for AC=%d, flow=%d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07003380 ac, tspec_flow_index );
3381
3382 pACInfo->requested_QoSInfo[tspec_flow_index] = pACInfo->curr_QoSInfo[tspec_flow_index];
3383 vos_mem_zero(&pACInfo->curr_QoSInfo[tspec_flow_index], sizeof(sme_QosWmmTspecInfo));
3384 qos_requested = TRUE;
3385 }
3386 }
3387
3388 // Only if the tspec is required, transition the state to
3389 // SME_QOS_REQUESTED for this AC
3390 if (qos_requested)
3391 {
3392 switch(pACInfo->curr_state)
3393 {
3394 case SME_QOS_HANDOFF:
3395 sme_QosStateTransition(sessionId, ac, SME_QOS_REQUESTED);
3396 break;
3397 default:
3398 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
3399 FL("FT Reassoc req event in unexpected state %d"), pACInfo->curr_state);
3400 VOS_ASSERT(0);
3401 }
3402 }
3403
3404 }
3405
3406 /* At this point of time, we are disconnected from the old AP, so it is safe
3407 * to reset all these session variables */
3408 pSession->apsdMask = 0;
3409 pSession->uapsdAlreadyRequested = 0;
3410 pSession->readyForPowerSave = 0;
3411
3412 /* Now change reason and HO renewal of all the flow in this session only */
3413 pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE );
3414 if(!pEntry)
3415 {
3416 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
3417 "%s: %d: Flow List empty, nothing to update",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003418 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003419 return eHAL_STATUS_FAILURE;
3420 }
3421
3422 do
3423 {
3424 flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link );
3425 if(sessionId == flow_info->sessionId)
3426 {
3427 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
3428 "%s: %d: Changing FlowID %d reason to SETUP and HO renewal to FALSE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003429 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003430 flow_info->QosFlowID);
3431 flow_info->reason = SME_QOS_REASON_SETUP;
3432 flow_info->hoRenewal = eANI_BOOLEAN_TRUE;
3433 }
3434 pEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE );
3435 } while( pEntry );
3436
3437 return eHAL_STATUS_SUCCESS;
3438}
3439
3440
3441eHalStatus sme_QosFTAggrQosReq( tpAniSirGlobal pMac, v_U8_t sessionId )
3442{
3443 tSirAggrQosReq *pMsg = NULL;
3444 sme_QosSessionInfo *pSession;
3445 eHalStatus status = eHAL_STATUS_FAILURE;
3446 int i, j = 0;
3447 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003448 "%s: %d: invoked on session %d", __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003449 sessionId);
3450
3451 pSession = &sme_QosCb.sessionInfo[sessionId];
3452
3453 pMsg = (tSirAggrQosReq *)vos_mem_malloc(sizeof(tSirAggrQosReq));
3454
3455 if (!pMsg)
3456 {
3457 //err msg
3458 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
3459 "%s: %d: couldn't allocate memory for the msg buffer",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003460 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003461
3462 return eHAL_STATUS_FAILURE;
3463 }
3464
3465 vos_mem_zero(pMsg, sizeof(tSirAggrQosReq));
3466
3467 pMsg->messageType = pal_cpu_to_be16((v_U16_t)eWNI_SME_FT_AGGR_QOS_REQ);
3468 pMsg->length = sizeof(tSirAggrQosReq);
3469 pMsg->sessionId = sessionId;
3470 pMsg->timeout = 0;
3471 pMsg->rspReqd = VOS_TRUE;
3472 vos_mem_copy( &pMsg->bssId[ 0 ],
3473 &pSession->assocInfo.pBssDesc->bssId[ 0 ],
3474 sizeof(tCsrBssid) );
3475
3476 for( i = 0; i < SME_QOS_EDCA_AC_MAX; i++ )
3477 {
3478 for( j = 0; j < SME_QOS_TSPEC_INDEX_MAX; j++ )
3479 {
3480 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08003481 FL("ac=%d, tspec_mask_staus=%x, tspec_index=%d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07003482 i, pSession->ac_info[i].tspec_mask_status, j);
3483 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08003484 FL("direction = %d"), pSession->ac_info[i].addTsRsp[j].rsp.tspec.tsinfo.traffic.direction);
Jeff Johnson295189b2012-06-20 16:38:30 -07003485 // Check if any flow is active on this AC
3486 if ((pSession->ac_info[i].tspec_mask_status) & (1 << j))
3487 {
3488 tANI_U8 direction = pSession->ac_info[i].addTsRsp[j].rsp.tspec.tsinfo.traffic.direction;
3489 if ((direction == SME_QOS_WMM_TS_DIR_UPLINK) ||
3490 (direction == SME_QOS_WMM_TS_DIR_BOTH))
3491 {
3492 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08003493 FL("Found tspec entry AC=%d, flow=%d, direction = %d"), i, j, direction);
Jeff Johnson295189b2012-06-20 16:38:30 -07003494 pMsg->aggrInfo.aggrAddTsInfo[i].dialogToken =
3495 sme_QosAssignDialogToken();
3496 pMsg->aggrInfo.aggrAddTsInfo[i].lleTspecPresent =
3497 pSession->ac_info[i].addTsRsp[j].rsp.lleTspecPresent;
3498 pMsg->aggrInfo.aggrAddTsInfo[i].numTclas =
3499 pSession->ac_info[i].addTsRsp[j].rsp.numTclas;
3500 vos_mem_copy( pMsg->aggrInfo.aggrAddTsInfo[i].tclasInfo,
3501 pSession->ac_info[i].addTsRsp[j].rsp.tclasInfo,
3502 SIR_MAC_TCLASIE_MAXNUM );
3503 pMsg->aggrInfo.aggrAddTsInfo[i].tclasProc =
3504 pSession->ac_info[i].addTsRsp[j].rsp.tclasProc;
3505 pMsg->aggrInfo.aggrAddTsInfo[i].tclasProcPresent =
3506 pSession->ac_info[i].addTsRsp[j].rsp.tclasProcPresent;
3507 pMsg->aggrInfo.aggrAddTsInfo[i].tspec =
3508 pSession->ac_info[i].addTsRsp[j].rsp.tspec;
3509 pMsg->aggrInfo.aggrAddTsInfo[i].wmeTspecPresent =
3510 pSession->ac_info[i].addTsRsp[j].rsp.wmeTspecPresent;
3511 pMsg->aggrInfo.aggrAddTsInfo[i].wsmTspecPresent =
3512 pSession->ac_info[i].addTsRsp[j].rsp.wsmTspecPresent;
3513 pMsg->aggrInfo.tspecIdx |= ( 1 << i );
3514
3515 // Mark the index for this AC as pending for response, which would be
3516 // used to validate the AddTS response from HAL->PE->SME
3517 pSession->ac_info[i].tspec_pending = (1<<j);
3518 }
3519 }
3520 }
3521 }
3522
3523 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08003524 "Sending aggregated message to HAL 0x%x", pMsg->aggrInfo.tspecIdx);
Jeff Johnson295189b2012-06-20 16:38:30 -07003525
3526 if(HAL_STATUS_SUCCESS(palSendMBMessage(pMac->hHdd, pMsg)))
3527 {
3528 status = eHAL_STATUS_SUCCESS;
3529 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
3530 "%s: %d: sent down a AGGR QoS req to PE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003531 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003532 }
3533
3534 return status;
3535}
3536
3537eHalStatus sme_QosProcessFTRICResponse(tpAniSirGlobal pMac, v_U8_t sessionId, tDot11fIERICDataDesc *pRicDataDesc, v_U8_t ac, v_U8_t tspecIndex)
3538{
3539 tANI_U8 i = 0;
3540 tpSirAddtsRsp pAddtsRsp
3541 = &sme_QosCb.sessionInfo[sessionId].ac_info[ac].addTsRsp[tspecIndex];
3542
3543 vos_mem_zero(pAddtsRsp, sizeof(tSirAddtsRsp));
3544
3545 pAddtsRsp->messageType = eWNI_SME_ADDTS_RSP;
3546 pAddtsRsp->length = sizeof(tSirAddtsRsp);
3547 pAddtsRsp->rc = pRicDataDesc->RICData.statusCode;
3548 pAddtsRsp->sessionId = sessionId;
3549 pAddtsRsp->rsp.dialogToken = pRicDataDesc->RICData.Identifier;
3550 pAddtsRsp->rsp.status = pRicDataDesc->RICData.statusCode;
3551 pAddtsRsp->rsp.wmeTspecPresent = pRicDataDesc->TSPEC.present;
3552 if (pAddtsRsp->rsp.wmeTspecPresent)
3553 {
3554 //Copy TSPEC params received in RIC response to addts response
3555 ConvertTSPEC(pMac, &pAddtsRsp->rsp.tspec, &pRicDataDesc->TSPEC);
3556 }
3557
3558 pAddtsRsp->rsp.numTclas = pRicDataDesc->num_TCLAS;
3559 if (pAddtsRsp->rsp.numTclas)
3560 {
3561 for (i = 0; i < pAddtsRsp->rsp.numTclas; i++)
3562 {
3563 //Copy TCLAS info per index to the addts response
3564 ConvertTCLAS(pMac, &pAddtsRsp->rsp.tclasInfo[i], &pRicDataDesc->TCLAS[i]);
3565 }
3566 }
3567
3568 pAddtsRsp->rsp.tclasProcPresent = pRicDataDesc->TCLASSPROC.present;
3569 if (pAddtsRsp->rsp.tclasProcPresent)
3570 pAddtsRsp->rsp.tclasProc = pRicDataDesc->TCLASSPROC.processing;
3571
3572
3573 pAddtsRsp->rsp.schedulePresent = pRicDataDesc->Schedule.present;
3574 if (pAddtsRsp->rsp.schedulePresent)
3575 {
3576 //Copy Schedule IE params to addts response
3577 ConvertSchedule(pMac, &pAddtsRsp->rsp.schedule, &pRicDataDesc->Schedule);
3578 }
3579
3580 //Need to check the below portion is a part of WMM TSPEC
3581 //Process Delay element
3582 if (pRicDataDesc->TSDelay.present)
3583 ConvertTSDelay(pMac, &pAddtsRsp->rsp.delay, &pRicDataDesc->TSDelay);
Gopichand Nakkala00f5e122013-03-19 13:51:46 +05303584
3585 //Need to call for WMMTSPEC
3586 if (pRicDataDesc->WMMTSPEC.present)
3587 {
3588 ConvertWMMTSPEC(pMac, &pAddtsRsp->rsp.tspec, &pRicDataDesc->WMMTSPEC);
3589 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003590 //return sme_QosProcessAddTsRsp(pMac, &addtsRsp);
3591 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala00f5e122013-03-19 13:51:46 +05303592}
Jeff Johnson295189b2012-06-20 16:38:30 -07003593eHalStatus sme_QosProcessAggrQosRsp(tpAniSirGlobal pMac, void *pMsgBuf)
3594{
3595 tpSirAggrQosRsp pAggrRsp = (tpSirAggrQosRsp)pMsgBuf;
3596 tSirAddtsRsp addtsRsp;
3597 eHalStatus status = eHAL_STATUS_SUCCESS;
3598 int i, j = 0;
3599 tANI_U8 sessionId = pAggrRsp->sessionId;
3600
3601 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
3602 FL("Received AGGR_QOS resp from LIM"));
3603
3604 /* Copy over the updated response information for TSPEC of all the ACs */
3605 for( i = 0; i < SIR_QOS_NUM_AC_MAX; i++ )
3606 {
3607 tANI_U8 tspec_mask_status = sme_QosCb.sessionInfo[sessionId].ac_info[i].tspec_mask_status;
3608 for( j = 0; j < SME_QOS_TSPEC_INDEX_MAX; j++ )
3609 {
3610 tANI_U8 direction = sme_QosCb.sessionInfo[sessionId].ac_info[i].
3611 addTsRsp[j].rsp.tspec.tsinfo.traffic.direction;
3612
3613 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08003614 FL("Addts rsp from LIM AC=%d, flow=%d dir=%d, tspecIdx=%x"),
Jeff Johnson295189b2012-06-20 16:38:30 -07003615 i, j, direction, pAggrRsp->aggrInfo.tspecIdx);
3616 // Check if the direction is Uplink or bi-directional
3617 if( ((1<<i) & pAggrRsp->aggrInfo.tspecIdx) &&
3618 ((tspec_mask_status) & (1<<j)) &&
3619 ((direction == SME_QOS_WMM_TS_DIR_UPLINK) ||
3620 (direction == SME_QOS_WMM_TS_DIR_BOTH)))
3621 {
3622 addtsRsp = sme_QosCb.sessionInfo[sessionId].ac_info[i].addTsRsp[j];
3623 addtsRsp.rc = pAggrRsp->aggrInfo.aggrRsp[i].status;
3624 addtsRsp.rsp.status = pAggrRsp->aggrInfo.aggrRsp[i].status;
3625 addtsRsp.rsp.tspec = pAggrRsp->aggrInfo.aggrRsp[i].tspec;
3626
3627 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05303628 FL("Processing Addts rsp from LIM AC=%d, flow=%d"), i, j);
Jeff Johnson295189b2012-06-20 16:38:30 -07003629 /* post ADD TS response for each */
3630 if (sme_QosProcessAddTsRsp(pMac, &addtsRsp) != eHAL_STATUS_SUCCESS)
3631 {
3632 status = eHAL_STATUS_FAILURE;
3633 }
3634 }
3635 }
3636 }
3637 return status;
3638}
3639
3640
3641eHalStatus sme_QosProcessFTReassocRspEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info)
3642{
3643 sme_QosSessionInfo *pSession;
3644 sme_QosACInfo *pACInfo;
3645 v_U8_t ac;
3646 v_U8_t tspec_flow_index;
3647 tDot11fIERICDataDesc *pRicDataDesc = NULL;
3648 eHalStatus status = eHAL_STATUS_SUCCESS;
3649 tCsrRoamSession *pCsrSession = CSR_GET_SESSION( pMac, sessionId );
3650 tCsrRoamConnectedInfo *pCsrConnectedInfo = &pCsrSession->connectedInfo;
Madan Mohan Koyyalamudi33ef6a22012-10-30 17:44:43 -07003651 tANI_U32 ricRspLen;
3652 /* To silence the KW tool NULL check is added */
3653 if(pCsrConnectedInfo == NULL)
3654 {
3655 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonfeddb2d2012-12-10 14:41:22 -08003656 FL("The connected info pointer is NULL"));
Madan Mohan Koyyalamudi33ef6a22012-10-30 17:44:43 -07003657 return eHAL_STATUS_FAILURE;
3658 }
3659 ricRspLen = pCsrConnectedInfo->nRICRspLength;
Jeff Johnson295189b2012-06-20 16:38:30 -07003660
3661 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
3662 "%s: %d: invoked on session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003663 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003664 sessionId);
3665
3666 pSession = &sme_QosCb.sessionInfo[sessionId];
3667
Gopichand Nakkala00f5e122013-03-19 13:51:46 +05303668 pRicDataDesc = (tDot11fIERICDataDesc *)((pCsrConnectedInfo->pbFrames) +
3669 (pCsrConnectedInfo->nBeaconLength + pCsrConnectedInfo->nAssocReqLength +
3670 pCsrConnectedInfo->nAssocRspLength));
Jeff Johnson295189b2012-06-20 16:38:30 -07003671
3672 for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++)
3673 {
3674 pACInfo = &pSession->ac_info[ac];
3675
3676 for (tspec_flow_index = 0; tspec_flow_index < SME_QOS_TSPEC_INDEX_MAX; tspec_flow_index++)
3677 {
3678 /* Only in the below case, copy the AC's curr QoS Info to requested QoS info */
3679 if (pACInfo->ricIdentifier[tspec_flow_index])
3680 {
3681
3682 if (!ricRspLen)
3683 {
3684 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
3685 FL("RIC Response not received for AC %d on TSPEC Index %d, RIC Req Identifier = %d"),
3686 ac, tspec_flow_index, pACInfo->ricIdentifier[tspec_flow_index]);
3687 VOS_ASSERT(0);
3688 }
3689 else
3690 {
3691 /* Now we got response for this identifier. Process it. */
3692 if (pRicDataDesc->present)
3693 {
3694 if (pRicDataDesc->RICData.present)
3695 {
3696 if (pRicDataDesc->RICData.Identifier != pACInfo->ricIdentifier[tspec_flow_index])
3697 {
3698 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
3699 FL("RIC response order not same as request sent. Request ID = %d, Response ID = %d"),
3700 pACInfo->ricIdentifier[tspec_flow_index], pRicDataDesc->RICData.Identifier);
3701 VOS_ASSERT(0);
3702 }
3703 else
3704 {
3705 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08003706 FL("Processing RIC Response for AC %d, TSPEC Flow index %d with RIC ID %d "),
Jeff Johnson295189b2012-06-20 16:38:30 -07003707 ac, tspec_flow_index, pRicDataDesc->RICData.Identifier);
3708 status = sme_QosProcessFTRICResponse(pMac, sessionId, pRicDataDesc, ac, tspec_flow_index);
3709 if (eHAL_STATUS_SUCCESS != status)
3710 {
3711 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08003712 FL("Failed with status %d for AC %d in TSPEC Flow index = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07003713 status, ac, tspec_flow_index);
3714 }
3715 }
3716 pRicDataDesc++;
3717 ricRspLen -= sizeof(tDot11fIERICDataDesc);
3718 }
3719 }
3720 }
3721 }
3722
3723 }
3724 }
3725
3726 if (ricRspLen)
3727 {
3728 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08003729 FL("RIC Response still follows despite traversing through all ACs. Remaining len = %d"), ricRspLen);
Jeff Johnson295189b2012-06-20 16:38:30 -07003730 VOS_ASSERT(0);
3731 }
3732
3733 /* Send the Aggregated QoS request to HAL */
3734 status = sme_QosFTAggrQosReq(pMac,sessionId);
3735
3736 return status;
3737}
3738
3739#endif /* WLAN_FEATURE_VOWIFI_11R */
3740
3741
3742
3743/*--------------------------------------------------------------------------
3744 \brief sme_QosAddTsReq() - To send down the ADDTS request with TSPEC params
3745 to PE
3746
3747
3748 \param pMac - Pointer to the global MAC parameter structure.
3749 \param sessionId - Session upon which the TSPEC should be added
3750 \param pTspec_Info - Pointer to sme_QosWmmTspecInfo which contains the WMM
3751 TSPEC related info as defined above
3752 \param ac - Enumeration of the various EDCA Access Categories.
3753 \return eHalStatus
3754
3755 \sa
3756
3757 --------------------------------------------------------------------------*/
3758eHalStatus sme_QosAddTsReq(tpAniSirGlobal pMac,
3759 v_U8_t sessionId,
3760 sme_QosWmmTspecInfo * pTspec_Info,
3761 sme_QosEdcaAcType ac)
3762{
3763 tSirAddtsReq *pMsg = NULL;
3764 sme_QosSessionInfo *pSession;
3765 eHalStatus status = eHAL_STATUS_FAILURE;
3766#ifdef FEATURE_WLAN_CCX
3767 tCsrRoamSession *pCsrSession = CSR_GET_SESSION( pMac, sessionId );
3768#endif
3769#ifdef FEATURE_WLAN_DIAG_SUPPORT
3770 WLAN_VOS_DIAG_EVENT_DEF(qos, vos_event_wlan_qos_payload_type);
3771#endif
3772 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
3773 "%s: %d: invoked on session %d for AC %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003774 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003775 sessionId, ac);
Praveen Kumar Sirisilla16c63772013-10-23 19:31:58 -07003776 if (sessionId >= CSR_ROAM_SESSION_MAX)
3777 {
3778 //err msg
3779 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
3780 "%s: %d: sessionId(%d) is invalid",
3781 __func__, __LINE__, sessionId);
3782 return eHAL_STATUS_FAILURE;
3783 }
3784
Jeff Johnson295189b2012-06-20 16:38:30 -07003785 pSession = &sme_QosCb.sessionInfo[sessionId];
3786 pMsg = (tSirAddtsReq *)vos_mem_malloc(sizeof(tSirAddtsReq));
3787 if (!pMsg)
3788 {
3789 //err msg
3790 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
3791 "%s: %d: couldn't allocate memory for the msg buffer",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003792 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003793 return eHAL_STATUS_FAILURE;
3794 }
3795 vos_mem_zero(pMsg, sizeof(tSirAddtsReq));
3796 pMsg->messageType = pal_cpu_to_be16((v_U16_t)eWNI_SME_ADDTS_REQ);
3797 pMsg->length = sizeof(tSirAddtsReq);
3798 pMsg->sessionId = sessionId;
3799 pMsg->timeout = 0;
3800 pMsg->rspReqd = VOS_TRUE;
3801 pMsg->req.dialogToken = sme_QosAssignDialogToken();
3802 /*As per WMM_AC_testplan_v0.39 Minimum Service Interval, Maximum Service
3803 Interval, Service Start Time, Suspension Interval and Delay Bound are
3804 all intended for HCCA operation and therefore must be set to zero*/
3805 pMsg->req.tspec.delayBound = 0;
3806 pMsg->req.tspec.inactInterval = pTspec_Info->inactivity_interval;
3807 pMsg->req.tspec.length = SME_QOS_TSPEC_IE_LENGTH;
3808 pMsg->req.tspec.maxBurstSz = pTspec_Info->max_burst_size;
3809 pMsg->req.tspec.maxMsduSz = pTspec_Info->maximum_msdu_size;
3810 pMsg->req.tspec.maxSvcInterval = pTspec_Info->max_service_interval;
3811 pMsg->req.tspec.meanDataRate = pTspec_Info->mean_data_rate;
3812 pMsg->req.tspec.mediumTime = pTspec_Info->medium_time;
3813 pMsg->req.tspec.minDataRate = pTspec_Info->min_data_rate;
3814 pMsg->req.tspec.minPhyRate = pTspec_Info->min_phy_rate;
3815 pMsg->req.tspec.minSvcInterval = pTspec_Info->min_service_interval;
3816 pMsg->req.tspec.nomMsduSz = pTspec_Info->nominal_msdu_size;
3817 pMsg->req.tspec.peakDataRate = pTspec_Info->peak_data_rate;
3818 pMsg->req.tspec.surplusBw = pTspec_Info->surplus_bw_allowance;
3819 pMsg->req.tspec.suspendInterval = pTspec_Info->suspension_interval;
3820 pMsg->req.tspec.svcStartTime = 0;
3821 pMsg->req.tspec.tsinfo.traffic.direction = pTspec_Info->ts_info.direction;
3822 //Make sure UAPSD is allowed. BTC may want to disable UAPSD while keep QoS setup
3823 if( pTspec_Info->ts_info.psb
3824 && btcIsReadyForUapsd(pMac)
3825 )
3826 {
3827 pMsg->req.tspec.tsinfo.traffic.psb = pTspec_Info->ts_info.psb;
3828 }
3829 else
3830 {
3831 pMsg->req.tspec.tsinfo.traffic.psb = 0;
3832 pTspec_Info->ts_info.psb = 0;
3833 }
3834 pMsg->req.tspec.tsinfo.traffic.tsid = pTspec_Info->ts_info.tid;
3835 pMsg->req.tspec.tsinfo.traffic.userPrio = pTspec_Info->ts_info.up;
3836 pMsg->req.tspec.tsinfo.traffic.accessPolicy = SME_QOS_ACCESS_POLICY_EDCA;
3837 pMsg->req.tspec.tsinfo.traffic.burstSizeDefn = pTspec_Info->ts_info.burst_size_defn;
3838 pMsg->req.tspec.tsinfo.traffic.ackPolicy = pTspec_Info->ts_info.ack_policy;
3839 pMsg->req.tspec.type = SME_QOS_TSPEC_IE_TYPE;
3840 /*Fill the BSSID pMsg->req.bssId*/
3841 if (NULL == pSession->assocInfo.pBssDesc)
3842 {
3843 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08003844 "%s: %d: BSS descriptor is NULL so we don't send request to PE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003845 __func__, __LINE__);
Jeff Johnson92686de2013-04-05 08:54:32 -07003846 vos_mem_free(pMsg);
Jeff Johnson295189b2012-06-20 16:38:30 -07003847 return eHAL_STATUS_FAILURE;
3848 }
3849 vos_mem_copy( &pMsg->bssId[ 0 ],
3850 &pSession->assocInfo.pBssDesc->bssId[ 0 ],
3851 sizeof(tCsrBssid) );
3852 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
3853 "%s: %d: up = %d, tid = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003854 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003855 pTspec_Info->ts_info.up,
3856 pTspec_Info->ts_info.tid);
3857#ifdef FEATURE_WLAN_CCX
3858 if(pCsrSession->connectedProfile.isCCXAssoc)
3859 {
3860 pMsg->req.tsrsIE.tsid = pTspec_Info->ts_info.up;
3861 pMsg->req.tsrsPresent = 1;
3862 }
3863#endif
3864 if(HAL_STATUS_SUCCESS(palSendMBMessage(pMac->hHdd, pMsg)))
3865 {
3866 status = eHAL_STATUS_SUCCESS;
3867 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
3868 "%s: %d: sent down a ADDTS req to PE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003869 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003870 //event: EVENT_WLAN_QOS
3871#ifdef FEATURE_WLAN_DIAG_SUPPORT
3872 qos.eventId = SME_QOS_DIAG_ADDTS_REQ;
3873 qos.reasonCode = SME_QOS_DIAG_USER_REQUESTED;
3874 WLAN_VOS_DIAG_EVENT_REPORT(&qos, EVENT_WLAN_QOS);
3875#endif //FEATURE_WLAN_DIAG_SUPPORT
3876 }
3877 return status;
3878}
3879/*--------------------------------------------------------------------------
3880 \brief sme_QosDelTsReq() - To send down the DELTS request with TSPEC params
3881 to PE
3882
3883
3884 \param pMac - Pointer to the global MAC parameter structure.
3885 \param sessionId - Session from which the TSPEC should be deleted
3886 \param ac - Enumeration of the various EDCA Access Categories.
3887 \param tspec_mask - on which tspec per AC, the delts is requested
3888
3889 \return eHalStatus
3890
3891 \sa
3892
3893 --------------------------------------------------------------------------*/
3894eHalStatus sme_QosDelTsReq(tpAniSirGlobal pMac,
3895 v_U8_t sessionId,
3896 sme_QosEdcaAcType ac,
3897 v_U8_t tspec_mask)
3898{
3899 sme_QosSessionInfo *pSession;
3900 sme_QosACInfo *pACInfo;
3901 tSirDeltsReq *pMsg;
3902 sme_QosWmmTspecInfo *pTspecInfo;
3903 eHalStatus status = eHAL_STATUS_FAILURE;
3904#ifdef FEATURE_WLAN_DIAG_SUPPORT
3905 WLAN_VOS_DIAG_EVENT_DEF(qos, vos_event_wlan_qos_payload_type);
3906#endif
3907 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
3908 "%s: %d: invoked on session %d for AC %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003909 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003910 sessionId, ac);
3911 pMsg = (tSirDeltsReq *)vos_mem_malloc(sizeof(tSirDeltsReq));
3912 if (!pMsg)
3913 {
3914 //err msg
3915 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
3916 "%s: %d: couldn't allocate memory for the msg buffer",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003917 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003918 return eHAL_STATUS_FAILURE;
3919 }
3920 vos_mem_zero(pMsg, sizeof(tSirDeltsReq));
3921 // get pointer to the TSPEC being deleted
3922 pSession = &sme_QosCb.sessionInfo[sessionId];
3923 pACInfo = &pSession->ac_info[ac];
3924 pTspecInfo = &pACInfo->curr_QoSInfo[tspec_mask - 1];
3925 pMsg->messageType = pal_cpu_to_be16((v_U16_t)eWNI_SME_DELTS_REQ);
3926 pMsg->length = sizeof(tSirDeltsReq);
3927 pMsg->sessionId = sessionId;
3928 pMsg->rspReqd = VOS_TRUE;
3929 pMsg->req.tspec.delayBound = pTspecInfo->delay_bound;
3930 pMsg->req.tspec.inactInterval = pTspecInfo->inactivity_interval;
3931 pMsg->req.tspec.length = SME_QOS_TSPEC_IE_LENGTH;
3932 pMsg->req.tspec.maxBurstSz = pTspecInfo->max_burst_size;
3933 pMsg->req.tspec.maxMsduSz = pTspecInfo->maximum_msdu_size;
3934 pMsg->req.tspec.maxSvcInterval = pTspecInfo->max_service_interval;
3935 pMsg->req.tspec.meanDataRate = pTspecInfo->mean_data_rate;
3936 pMsg->req.tspec.mediumTime = pTspecInfo->medium_time;
3937 pMsg->req.tspec.minDataRate = pTspecInfo->min_data_rate;
3938 pMsg->req.tspec.minPhyRate = pTspecInfo->min_phy_rate;
3939 pMsg->req.tspec.minSvcInterval = pTspecInfo->min_service_interval;
3940 pMsg->req.tspec.nomMsduSz = pTspecInfo->nominal_msdu_size;
3941 pMsg->req.tspec.peakDataRate = pTspecInfo->peak_data_rate;
3942 pMsg->req.tspec.surplusBw = pTspecInfo->surplus_bw_allowance;
3943 pMsg->req.tspec.suspendInterval = pTspecInfo->suspension_interval;
3944 pMsg->req.tspec.svcStartTime = pTspecInfo->svc_start_time;
3945 pMsg->req.tspec.tsinfo.traffic.direction = pTspecInfo->ts_info.direction;
3946 pMsg->req.tspec.tsinfo.traffic.psb = pTspecInfo->ts_info.psb;
3947 pMsg->req.tspec.tsinfo.traffic.tsid = pTspecInfo->ts_info.tid;
3948 pMsg->req.tspec.tsinfo.traffic.userPrio = pTspecInfo->ts_info.up;
3949 pMsg->req.tspec.tsinfo.traffic.accessPolicy = SME_QOS_ACCESS_POLICY_EDCA;
3950 pMsg->req.tspec.tsinfo.traffic.burstSizeDefn = pTspecInfo->ts_info.burst_size_defn;
3951 pMsg->req.tspec.tsinfo.traffic.ackPolicy = pTspecInfo->ts_info.ack_policy;
3952 pMsg->req.tspec.type = SME_QOS_TSPEC_IE_TYPE;
3953 /*Fill the BSSID pMsg->req.bssId*/
3954 if (NULL == pSession->assocInfo.pBssDesc)
3955 {
3956 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
3957 "%s: %d: BSS descriptor is NULL so we don't send request to PE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003958 __func__, __LINE__);
Gopichand Nakkalad5a904e2013-03-29 01:07:54 +05303959 vos_mem_free(pMsg);
Jeff Johnson295189b2012-06-20 16:38:30 -07003960 return eHAL_STATUS_FAILURE;
3961 }
3962 vos_mem_copy( &pMsg->bssId[ 0 ],
3963 &pSession->assocInfo.pBssDesc->bssId[ 0 ],
3964 sizeof(tCsrBssid) );
3965
3966 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
3967 "%s: %d: up = %d, tid = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003968 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003969 pTspecInfo->ts_info.up,
3970 pTspecInfo->ts_info.tid);
3971 vos_mem_zero(&pACInfo->curr_QoSInfo[tspec_mask - 1],
3972 sizeof(sme_QosWmmTspecInfo));
3973 if(HAL_STATUS_SUCCESS(palSendMBMessage(pMac->hHdd, pMsg)))
3974 {
3975 status = eHAL_STATUS_SUCCESS;
3976 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
3977 "%s: %d: sme_QosDelTsReq:Test: sent down a DELTS req to PE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003978 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003979 //event: EVENT_WLAN_QOS
3980#ifdef FEATURE_WLAN_DIAG_SUPPORT
3981 qos.eventId = SME_QOS_DIAG_DELTS;
3982 qos.reasonCode = SME_QOS_DIAG_USER_REQUESTED;
3983 WLAN_VOS_DIAG_EVENT_REPORT(&qos, EVENT_WLAN_QOS);
3984#endif //FEATURE_WLAN_DIAG_SUPPORT
3985 }
3986
3987 return status;
3988}
3989
3990
3991/*--------------------------------------------------------------------------
3992 \brief sme_QosProcessAddTsRsp() - Function to process the
3993 eWNI_SME_ADDTS_RSP came from PE
3994
3995 \param pMac - Pointer to the global MAC parameter structure.
3996 \param pMsgBuf - Pointer to the msg buffer came from PE.
3997
3998 \return eHalStatus
3999
4000 \sa
4001
4002 --------------------------------------------------------------------------*/
4003eHalStatus sme_QosProcessAddTsRsp(tpAniSirGlobal pMac, void *pMsgBuf)
4004{
4005 tpSirAddtsRsp paddts_rsp = (tpSirAddtsRsp)pMsgBuf;
4006 sme_QosSessionInfo *pSession;
4007 v_U8_t sessionId = paddts_rsp->sessionId;
4008 eHalStatus status = eHAL_STATUS_FAILURE;
4009#ifdef WLAN_FEATURE_VOWIFI_11R
4010 sme_QosWmmUpType up = (sme_QosWmmUpType)paddts_rsp->rsp.tspec.tsinfo.traffic.userPrio;
4011 sme_QosACInfo *pACInfo;
4012 sme_QosEdcaAcType ac;
4013#endif
Madan Mohan Koyyalamudie274a3b2013-08-07 16:45:02 -07004014#ifdef FEATURE_WLAN_DIAG_SUPPORT
4015 WLAN_VOS_DIAG_EVENT_DEF(qos, vos_event_wlan_qos_payload_type);
4016#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004017
4018 pSession = &sme_QosCb.sessionInfo[sessionId];
4019
4020#ifdef WLAN_FEATURE_VOWIFI_11R
4021 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
4022 "%s: %d: invoked on session %d for UP %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004023 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004024 sessionId, up);
4025
4026 ac = sme_QosUpToAc(up);
4027 if(SME_QOS_EDCA_AC_MAX == ac)
4028 {
4029 //err msg
4030 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
4031 "%s: %d: invalid AC %d from UP %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004032 __func__, __LINE__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -07004033
4034 return eHAL_STATUS_FAILURE;
4035 }
4036 pACInfo = &pSession->ac_info[ac];
4037 if (SME_QOS_HANDOFF == pACInfo->curr_state)
4038 {
4039 smsLog(pMac, LOG1, FL("ADDTS Response received for AC %d in HANDOFF State.. Dropping"), ac);
4040 pSession->readyForPowerSave = VOS_TRUE;
4041 return eHAL_STATUS_SUCCESS;
4042 }
4043#endif
4044
Jeff Johnson295189b2012-06-20 16:38:30 -07004045 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
4046 "%s: %d: Invoked on session %d with return code %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004047 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004048 sessionId, paddts_rsp->rc);
4049 // our outstanding request has been serviced
4050 // we can go into powersave
4051 pSession->readyForPowerSave = VOS_TRUE;
4052 if(paddts_rsp->rc)
4053 {
4054 //event: EVENT_WLAN_QOS
4055#ifdef FEATURE_WLAN_DIAG_SUPPORT
4056 qos.eventId = SME_QOS_DIAG_ADDTS_RSP;
4057 qos.reasonCode = SME_QOS_DIAG_ADDTS_REFUSED;
4058 WLAN_VOS_DIAG_EVENT_REPORT(&qos, EVENT_WLAN_QOS);
4059#endif //FEATURE_WLAN_DIAG_SUPPORT
4060 status = sme_QosProcessAddTsFailureRsp(pMac, sessionId, &paddts_rsp->rsp);
4061 }
4062 else
4063 {
4064 status = sme_QosProcessAddTsSuccessRsp(pMac, sessionId, &paddts_rsp->rsp);
4065 }
4066 return status;
4067}
4068/*--------------------------------------------------------------------------
4069 \brief sme_QosProcessDelTsRsp() - Function to process the
4070 eWNI_SME_DELTS_RSP came from PE
4071
4072 \param pMac - Pointer to the global MAC parameter structure.
4073 \param pMsgBuf - Pointer to the msg buffer came from PE.
4074
4075 \return eHalStatus
4076
4077 \sa
4078
4079 --------------------------------------------------------------------------*/
4080eHalStatus sme_QosProcessDelTsRsp(tpAniSirGlobal pMac, void *pMsgBuf)
4081{
4082 tpSirDeltsRsp pDeltsRsp = (tpSirDeltsRsp)pMsgBuf;
4083 sme_QosSessionInfo *pSession;
4084 v_U8_t sessionId = pDeltsRsp->sessionId;
4085 // msg
4086 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
4087 "%s: %d: Invoked on session %d with return code %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004088 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004089 sessionId, pDeltsRsp->rc);
4090 pSession = &sme_QosCb.sessionInfo[sessionId];
4091 // our outstanding request has been serviced
4092 // we can go into powersave
4093 pSession->readyForPowerSave = VOS_TRUE;
4094 (void)sme_QosProcessBufferedCmd(sessionId);
4095 return eHAL_STATUS_SUCCESS;
4096}
4097/*--------------------------------------------------------------------------
4098 \brief sme_QosProcessDelTsInd() - Function to process the
4099 eWNI_SME_DELTS_IND came from PE
4100
4101 Since it's a DELTS indication from AP, will notify all the flows running on
4102 this AC about QoS release
4103 \param pMac - Pointer to the global MAC parameter structure.
4104 \param pMsgBuf - Pointer to the msg buffer came from PE.
4105
4106 \return eHalStatus
4107
4108 \sa
4109
4110 --------------------------------------------------------------------------*/
4111eHalStatus sme_QosProcessDelTsInd(tpAniSirGlobal pMac, void *pMsgBuf)
4112{
4113 tpSirDeltsRsp pdeltsind = (tpSirDeltsRsp)pMsgBuf;
4114 sme_QosSessionInfo *pSession;
4115 sme_QosACInfo *pACInfo;
4116 v_U8_t sessionId = pdeltsind->sessionId;
4117 sme_QosEdcaAcType ac;
4118 sme_QosSearchInfo search_key;
4119 sme_QosWmmUpType up = (sme_QosWmmUpType)pdeltsind->rsp.tspec.tsinfo.traffic.userPrio;
4120#ifdef FEATURE_WLAN_DIAG_SUPPORT
4121 WLAN_VOS_DIAG_EVENT_DEF(qos, vos_event_wlan_qos_payload_type);
4122#endif
4123 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
4124 "%s: %d: Invoked on session %d for UP %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004125 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004126 sessionId, up);
4127 ac = sme_QosUpToAc(up);
4128 if(SME_QOS_EDCA_AC_MAX == ac)
4129 {
4130 //err msg
4131 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
4132 "%s: %d: invalid AC %d from UP %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004133 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004134 ac, up);
4135 return eHAL_STATUS_FAILURE;
4136 }
4137 pSession = &sme_QosCb.sessionInfo[sessionId];
4138 pACInfo = &pSession->ac_info[ac];
4139
4140 vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo));
4141 //set the key type & the key to be searched in the Flow List
4142 search_key.key.ac_type = ac;
4143 search_key.index = SME_QOS_SEARCH_KEY_INDEX_2;
4144 search_key.sessionId = sessionId;
4145 //find all Flows on the perticular AC & delete them, also send HDD indication
4146 // through the callback it registered per request
4147 if(!HAL_STATUS_SUCCESS(sme_QosFindAllInFlowList(pMac, search_key, sme_QosDelTsIndFnp)))
4148 {
4149 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
4150 "%s: %d: no match found for ac = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004151 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004152 search_key.key.ac_type);
4153 //ASSERT
4154 VOS_ASSERT(0);
4155 return eHAL_STATUS_FAILURE;
4156 }
Madan Mohan Koyyalamudic0a75a42013-10-07 04:20:49 +05304157
4158//event: EVENT_WLAN_QOS
4159#ifdef FEATURE_WLAN_DIAG_SUPPORT
Jeff Johnson295189b2012-06-20 16:38:30 -07004160 qos.eventId = SME_QOS_DIAG_DELTS;
4161 qos.reasonCode = SME_QOS_DIAG_DELTS_IND_FROM_AP;
4162 WLAN_VOS_DIAG_EVENT_REPORT(&qos, EVENT_WLAN_QOS);
4163#endif //FEATURE_WLAN_DIAG_SUPPORT
4164
Jeff Johnson295189b2012-06-20 16:38:30 -07004165 return eHAL_STATUS_SUCCESS;
4166}
4167/*--------------------------------------------------------------------------
4168 \brief sme_QosProcessAssocCompleteEv() - Function to process the
4169 SME_QOS_CSR_ASSOC_COMPLETE event indication from CSR
4170 \param pEvent_info - Pointer to relevant info from CSR.
4171
4172 \return eHalStatus
4173
4174 \sa
4175
4176 --------------------------------------------------------------------------*/
4177eHalStatus sme_QosProcessAssocCompleteEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info)
4178{
4179 sme_QosSessionInfo *pSession;
4180 sme_QosACInfo *pACInfo;
4181 eHalStatus status = eHAL_STATUS_FAILURE;
4182 sme_QosEdcaAcType ac = SME_QOS_EDCA_AC_BE;
4183 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
4184 "%s: %d: invoked on session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004185 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004186 sessionId);
4187 pSession = &sme_QosCb.sessionInfo[sessionId];
4188 if(((SME_QOS_INIT == pSession->ac_info[SME_QOS_EDCA_AC_BE].curr_state)&&
4189 (SME_QOS_INIT == pSession->ac_info[SME_QOS_EDCA_AC_BK].curr_state)&&
4190 (SME_QOS_INIT == pSession->ac_info[SME_QOS_EDCA_AC_VI].curr_state)&&
4191 (SME_QOS_INIT == pSession->ac_info[SME_QOS_EDCA_AC_VO].curr_state)) ||
4192 (pSession->handoffRequested))
4193 {
4194 //get the association info
4195 if(!pEvent_info)
4196 {
4197 //err msg
4198 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
4199 "%s: %d: pEvent_info is NULL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004200 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004201 return status;
4202 }
4203 if(!((sme_QosAssocInfo *)pEvent_info)->pBssDesc)
4204 {
4205 //err msg
4206 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
4207 "%s: %d: pBssDesc is NULL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004208 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004209 return status;
4210 }
4211 if((pSession->assocInfo.pBssDesc) &&
4212 (csrIsBssidMatch(pMac, (tCsrBssid *)&pSession->assocInfo.pBssDesc->bssId,
4213 (tCsrBssid *) &(((sme_QosAssocInfo *)pEvent_info)->pBssDesc->bssId))))
4214 {
4215 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
4216 "%s: %d: assoc with the same BSS, no update needed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004217 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004218 }
4219 else
4220 {
4221 status = sme_QosSaveAssocInfo(pSession, pEvent_info);
4222 }
4223 }
4224 else
4225 {
4226 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
4227 "%s: %d: wrong state: BE %d, BK %d, VI %d, VO %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004228 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004229 pSession->ac_info[SME_QOS_EDCA_AC_BE].curr_state,
4230 pSession->ac_info[SME_QOS_EDCA_AC_BK].curr_state,
4231 pSession->ac_info[SME_QOS_EDCA_AC_VI].curr_state,
4232 pSession->ac_info[SME_QOS_EDCA_AC_VO].curr_state);
4233 //ASSERT
4234 VOS_ASSERT(0);
4235 return status;
4236 }
4237 // the session is active
4238 pSession->sessionActive = VOS_TRUE;
4239 if(pSession->handoffRequested)
4240 {
4241 pSession->handoffRequested = VOS_FALSE;
4242 //renew all flows
4243 (void)sme_QosProcessBufferedCmd(sessionId);
4244 status = eHAL_STATUS_SUCCESS;
4245 }
4246 else
4247 {
4248 for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++)
4249 {
4250 pACInfo = &pSession->ac_info[ac];
4251 switch(pACInfo->curr_state)
4252 {
4253 case SME_QOS_INIT:
4254 sme_QosStateTransition(sessionId, ac, SME_QOS_LINK_UP);
4255 break;
4256 case SME_QOS_LINK_UP:
4257 case SME_QOS_REQUESTED:
4258 case SME_QOS_QOS_ON:
4259 case SME_QOS_HANDOFF:
4260 case SME_QOS_CLOSED:
4261 default:
4262 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
4263 "%s: %d: On session %d AC %d is in wrong state %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004264 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004265 sessionId, ac, pACInfo->curr_state);
4266 //ASSERT
4267 VOS_ASSERT(0);
4268 break;
4269 }
4270 }
4271 }
4272 return status;
4273}
4274/*--------------------------------------------------------------------------
4275 \brief sme_QosProcessReassocReqEv() - Function to process the
4276 SME_QOS_CSR_REASSOC_REQ event indication from CSR
4277 \param pEvent_info - Pointer to relevant info from CSR.
4278
4279 \return eHalStatus
4280
4281 \sa
4282
4283 --------------------------------------------------------------------------*/
4284eHalStatus sme_QosProcessReassocReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info)
4285{
4286 sme_QosSessionInfo *pSession;
4287 sme_QosACInfo *pACInfo;
4288 sme_QosEdcaAcType ac;
4289 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
4290 "%s: %d: invoked on session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004291 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004292 sessionId);
4293 pSession = &sme_QosCb.sessionInfo[sessionId];
4294
4295#ifdef WLAN_FEATURE_VOWIFI_11R
4296 if(pSession->ftHandoffInProgress)
4297 {
4298 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
4299 "%s: %d: no need for state transition, should "
4300 "already be in handoff state",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004301 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004302 VOS_ASSERT(pSession->ac_info[0].curr_state == SME_QOS_HANDOFF);
4303 VOS_ASSERT(pSession->ac_info[1].curr_state == SME_QOS_HANDOFF);
4304 VOS_ASSERT(pSession->ac_info[2].curr_state == SME_QOS_HANDOFF);
4305 VOS_ASSERT(pSession->ac_info[3].curr_state == SME_QOS_HANDOFF);
4306 sme_QosProcessFTReassocReqEv(pMac, sessionId, pEvent_info);
4307 return eHAL_STATUS_SUCCESS;
4308 }
4309#endif
4310
4311 if(pSession->handoffRequested)
4312 {
4313 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
4314 "%s: %d: no need for state transition, should "
4315 "already be in handoff state",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004316 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004317 VOS_ASSERT(pSession->ac_info[0].curr_state == SME_QOS_HANDOFF);
4318 VOS_ASSERT(pSession->ac_info[1].curr_state == SME_QOS_HANDOFF);
4319 VOS_ASSERT(pSession->ac_info[2].curr_state == SME_QOS_HANDOFF);
4320 VOS_ASSERT(pSession->ac_info[3].curr_state == SME_QOS_HANDOFF);
4321
4322 //buffer the existing flows to be renewed after handoff is done
4323 sme_QosBufferExistingFlows(pMac, sessionId);
4324 //clean up the control block partially for handoff
4325 sme_QosCleanupCtrlBlkForHandoff(pMac, sessionId);
4326 return eHAL_STATUS_SUCCESS;
4327 }
4328//TBH: Assuming both handoff algo & 11r willn't be enabled at the same time
4329#ifdef WLAN_FEATURE_VOWIFI_11R
4330 if(pSession->ftHandoffInProgress)
4331 {
4332 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
4333 "%s: %d: no need for state transition, should "
4334 "already be in handoff state",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004335 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004336 VOS_ASSERT(pSession->ac_info[0].curr_state == SME_QOS_HANDOFF);
4337 VOS_ASSERT(pSession->ac_info[1].curr_state == SME_QOS_HANDOFF);
4338 VOS_ASSERT(pSession->ac_info[2].curr_state == SME_QOS_HANDOFF);
4339 VOS_ASSERT(pSession->ac_info[3].curr_state == SME_QOS_HANDOFF);
4340
4341 sme_QosProcessFTReassocReqEv(pMac, sessionId, pEvent_info);
4342 return eHAL_STATUS_SUCCESS;
4343 }
4344#endif
4345
4346 for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++)
4347 {
4348 pACInfo = &pSession->ac_info[ac];
4349 switch(pACInfo->curr_state)
4350 {
4351 case SME_QOS_LINK_UP:
4352 case SME_QOS_REQUESTED:
4353 case SME_QOS_QOS_ON:
4354 sme_QosStateTransition(sessionId, ac, SME_QOS_HANDOFF);
4355 break;
4356 case SME_QOS_HANDOFF:
4357 //This is normal because sme_QosRequestReassoc may already change the state
4358 break;
4359 case SME_QOS_CLOSED:
4360 case SME_QOS_INIT:
4361 default:
4362 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
4363 "%s: %d: On session %d AC %d is in wrong state %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004364 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004365 sessionId, ac, pACInfo->curr_state);
4366 //ASSERT
4367 VOS_ASSERT(0);
4368 break;
4369 }
4370 }
4371 return eHAL_STATUS_SUCCESS;
4372}
4373/*--------------------------------------------------------------------------
4374 \brief sme_QosProcessReassocSuccessEv() - Function to process the
4375 SME_QOS_CSR_REASSOC_COMPLETE event indication from CSR
4376 \param pEvent_info - Pointer to relevant info from CSR.
4377
4378 \return eHalStatus
4379
4380 \sa
4381
4382 --------------------------------------------------------------------------*/
4383eHalStatus sme_QosProcessReassocSuccessEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info)
4384{
Gopichand Nakkala00f5e122013-03-19 13:51:46 +05304385
Praveen Kumar Sirisilla8bdfac42013-10-10 17:20:48 -07004386 tCsrRoamSession *pCsrRoamSession = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004387 sme_QosSessionInfo *pSession;
4388 sme_QosACInfo *pACInfo;
4389 sme_QosEdcaAcType ac, ac_index;
4390 sme_QosSearchInfo search_key;
4391 sme_QosSearchInfo search_key1;
4392 eHalStatus status = eHAL_STATUS_FAILURE;
4393 tListElem *pEntry= NULL;
4394 sme_QosFlowInfoEntry *flow_info = NULL;
4395
4396 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
4397 "%s: %d: invoked on session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004398 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004399 sessionId);
Praveen Kumar Sirisilla8bdfac42013-10-10 17:20:48 -07004400
4401 if (CSR_ROAM_SESSION_MAX <= sessionId) {
4402 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
4403 "%s: %d: invoked on session %d",
4404 __func__, __LINE__,
4405 sessionId);
4406 return status;
4407 }
4408
4409 pCsrRoamSession = CSR_GET_SESSION( pMac, sessionId );
4410
Jeff Johnson295189b2012-06-20 16:38:30 -07004411 pSession = &sme_QosCb.sessionInfo[sessionId];
4412 // our pending reassociation has completed
4413 // we can allow powersave
4414 pSession->readyForPowerSave = VOS_TRUE;
4415 //get the association info
4416 if(!pEvent_info)
4417 {
4418 //err msg
4419 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
4420 "%s: %d: pEvent_info is NULL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004421 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004422 return status;
4423 }
4424 if(!((sme_QosAssocInfo *)pEvent_info)->pBssDesc)
4425 {
4426 //err msg
4427 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
4428 "%s: %d: pBssDesc is NULL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004429 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004430 return status;
4431 }
4432 status = sme_QosSaveAssocInfo(pSession, pEvent_info);
4433 if(status)
4434 {
4435 //err msg
4436 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
4437 "%s: %d: sme_QosSaveAssocInfo() failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004438 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004439 }
4440//TBH: Assuming both handoff algo & 11r willn't be enabled at the same time
4441 if(pSession->handoffRequested)
4442 {
4443 pSession->handoffRequested = VOS_FALSE;
4444 //renew all flows
4445 (void)sme_QosProcessBufferedCmd(sessionId);
4446 return eHAL_STATUS_SUCCESS;
4447 }
4448#ifdef WLAN_FEATURE_VOWIFI_11R
4449 if (pSession->ftHandoffInProgress)
4450 {
Gopichand Nakkalacc8cf8e2013-04-25 06:03:10 -07004451 if (csrRoamIs11rAssoc(pMac))
4452 {
4453 if (pCsrRoamSession && pCsrRoamSession->connectedInfo.nRICRspLength)
4454 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004455 status = sme_QosProcessFTReassocRspEv(pMac, sessionId, pEvent_info);
4456 }
4457 }
4458#ifdef FEATURE_WLAN_CCX
4459 // If CCX association check for TSPEC IEs in the reassoc rsp frame
Gopichand Nakkalacc8cf8e2013-04-25 06:03:10 -07004460 if (csrRoamIsCCXAssoc(pMac))
4461 {
4462 if (pCsrRoamSession && pCsrRoamSession->connectedInfo.nTspecIeLength)
4463 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004464 status = sme_QosCCXProcessReassocTspecRsp(pMac, sessionId, pEvent_info);
4465 }
4466 }
4467#endif
4468 pSession->ftHandoffInProgress = VOS_FALSE;
4469 pSession->handoffRequested = VOS_FALSE;
4470 return status;
4471 }
4472#endif
4473
4474 pSession->sessionActive = VOS_TRUE;
4475 for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++)
4476 {
4477 pACInfo = &pSession->ac_info[ac];
4478 switch(pACInfo->curr_state)
4479 {
4480 case SME_QOS_HANDOFF:
4481 // return to our previous state
4482 sme_QosStateTransition(sessionId, ac, pACInfo->prev_state);
4483 //for which ac APSD (hence the reassoc) is requested
4484 if(pACInfo->reassoc_pending)
4485 {
4486 //update the apsd mask in CB - make sure to take care of the case
4487 //where we are resetting the bit in apsd_mask
4488 if(pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0].ts_info.psb)
4489 {
4490 pSession->apsdMask |= 1 << (SME_QOS_EDCA_AC_VO - ac);
4491 }
4492 else
4493 {
4494 pSession->apsdMask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac));
4495 }
4496 pACInfo->reassoc_pending = VOS_FALSE;
4497 //during setup it gets set as addts & reassoc both gets a pending flag
4498 //pACInfo->tspec_pending = 0;
4499 sme_QosStateTransition(sessionId, ac, SME_QOS_QOS_ON);
4500 // notify HDD with new Service Interval
4501 pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0] =
4502 pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0];
4503 vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo));
4504 //set the key type & the key to be searched in the Flow List
4505 search_key.key.ac_type = ac;
4506 search_key.index = SME_QOS_SEARCH_KEY_INDEX_2;
4507 search_key.sessionId = sessionId;
4508 //notify PMC that reassoc is done for APSD on certain AC??
4509
4510 vos_mem_zero(&search_key1, sizeof(sme_QosSearchInfo));
4511 //set the hoRenewal field in control block if needed
4512 search_key1.index = SME_QOS_SEARCH_KEY_INDEX_3;
4513 search_key1.key.reason = SME_QOS_REASON_SETUP;
4514 search_key1.sessionId = sessionId;
4515 for(ac_index = SME_QOS_EDCA_AC_BE; ac_index < SME_QOS_EDCA_AC_MAX; ac_index++)
4516 {
4517 pEntry = sme_QosFindInFlowList(search_key1);
4518 if(pEntry)
4519 {
4520 flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link );
4521 if(flow_info->ac_type == ac)
4522 {
4523 pACInfo->hoRenewal = flow_info->hoRenewal;
4524 break;
4525 }
4526 }
4527 }
4528 //notify HDD the success for the requested flow
4529 //notify all the other flows running on the AC that QoS got modified
4530 if(!HAL_STATUS_SUCCESS(sme_QosFindAllInFlowList(pMac, search_key, sme_QosReassocSuccessEvFnp)))
4531 {
4532 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
4533 "%s: %d: no match found for ac = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004534 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004535 search_key.key.ac_type);
4536 //ASSERT
4537 VOS_ASSERT(0);
4538 return eHAL_STATUS_FAILURE;
4539 }
4540 pACInfo->hoRenewal = VOS_FALSE;
4541 vos_mem_zero(&pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0],
4542 sizeof(sme_QosWmmTspecInfo));
4543 }
4544 status = eHAL_STATUS_SUCCESS;
4545 break;
4546 case SME_QOS_INIT:
4547 case SME_QOS_CLOSED:
4548 //NOP
4549 status = eHAL_STATUS_SUCCESS;
4550 break;
4551 case SME_QOS_LINK_UP:
4552 case SME_QOS_REQUESTED:
4553 case SME_QOS_QOS_ON:
4554 default:
4555 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
4556 "%s: %d: On session %d AC %d is in wrong state %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004557 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004558 sessionId, ac, pACInfo->curr_state);
4559 //ASSERT
4560 VOS_ASSERT(0);
4561 break;
4562 }
4563 }
4564 (void)sme_QosProcessBufferedCmd(sessionId);
4565 return status;
4566}
4567
4568/*--------------------------------------------------------------------------
4569 \brief sme_QosProcessReassocFailureEv() - Function to process the
4570 SME_QOS_CSR_REASSOC_FAILURE event indication from CSR
4571 \param pEvent_info - Pointer to relevant info from CSR.
4572
4573 \return eHalStatus
4574
4575 \sa
4576
4577 --------------------------------------------------------------------------*/
4578eHalStatus sme_QosProcessReassocFailureEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info)
4579{
4580 sme_QosSessionInfo *pSession;
4581 sme_QosACInfo *pACInfo;
4582 sme_QosEdcaAcType ac;
4583 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
4584 "%s: %d: invoked on session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004585 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004586 sessionId);
4587 pSession = &sme_QosCb.sessionInfo[sessionId];
4588 // our pending reassociation has completed
4589 // we can allow powersave
4590 pSession->readyForPowerSave = VOS_TRUE;
4591 for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++)
4592 {
4593 pACInfo = &pSession->ac_info[ac];
4594 switch(pACInfo->curr_state)
4595 {
4596 case SME_QOS_HANDOFF:
4597 sme_QosStateTransition(sessionId, ac, SME_QOS_INIT);
4598 if(pACInfo->reassoc_pending)
4599 {
4600 pACInfo->reassoc_pending = VOS_FALSE;
4601 }
4602 vos_mem_zero(&pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0],
4603 sizeof(sme_QosWmmTspecInfo));
4604 vos_mem_zero(&pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0],
4605 sizeof(sme_QosWmmTspecInfo));
4606 vos_mem_zero(&pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_1],
4607 sizeof(sme_QosWmmTspecInfo));
4608 vos_mem_zero(&pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_1],
4609 sizeof(sme_QosWmmTspecInfo));
4610 pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_CLEAR;
4611 pACInfo->tspec_pending = 0;
4612 pACInfo->num_flows[SME_QOS_TSPEC_INDEX_0] = 0;
4613 pACInfo->num_flows[SME_QOS_TSPEC_INDEX_1] = 0;
4614 break;
4615 case SME_QOS_INIT:
4616 case SME_QOS_CLOSED:
4617 //NOP
4618 break;
4619 case SME_QOS_LINK_UP:
4620 case SME_QOS_REQUESTED:
4621 case SME_QOS_QOS_ON:
4622 default:
4623 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
4624 "%s: %d: On session %d AC %d is in wrong state %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004625 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004626 sessionId, ac, pACInfo->curr_state);
4627 //ASSERT
4628 VOS_ASSERT(0);
4629 break;
4630 }
4631 }
4632 //need to clean up flows
4633 sme_QosDeleteExistingFlows(pMac, sessionId);
4634 return eHAL_STATUS_SUCCESS;
4635}
4636/*--------------------------------------------------------------------------
4637 \brief sme_QosProcessHandoffAssocReqEv() - Function to process the
4638 SME_QOS_CSR_HANDOFF_ASSOC_REQ event indication from CSR
4639 \param pEvent_info - Pointer to relevant info from CSR.
4640
4641 \return eHalStatus
4642
4643 \sa
4644
4645 --------------------------------------------------------------------------*/
4646eHalStatus sme_QosProcessHandoffAssocReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info)
4647{
4648 sme_QosSessionInfo *pSession;
4649 sme_QosACInfo *pACInfo;
4650 v_U8_t ac;
4651 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
4652 "%s: %d: invoked on session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004653 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004654 sessionId);
4655 pSession = &sme_QosCb.sessionInfo[sessionId];
4656 for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++)
4657 {
4658 pACInfo = &pSession->ac_info[ac];
4659 switch(pACInfo->curr_state)
4660 {
4661 case SME_QOS_LINK_UP:
4662 case SME_QOS_REQUESTED:
4663 case SME_QOS_QOS_ON:
4664 sme_QosStateTransition(sessionId, ac, SME_QOS_HANDOFF);
4665 break;
4666 case SME_QOS_HANDOFF:
4667 //print error msg
4668#ifdef WLAN_FEATURE_VOWIFI_11R
4669 if(pSession->ftHandoffInProgress)
4670 {
Varun Reddy Yeturuf68abd62013-02-11 14:05:06 -08004671 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004672 "%s: %d: SME_QOS_CSR_HANDOFF_ASSOC_REQ received in "
4673 "SME_QOS_HANDOFF state with FT in progress"
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004674 , __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004675 break;
4676 }
4677#endif
4678
4679 case SME_QOS_CLOSED:
4680 case SME_QOS_INIT:
4681 default:
4682 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
4683 "%s: %d: On session %d AC %d is in wrong state %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004684 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004685 sessionId, ac, pACInfo->curr_state);
4686 //ASSERT
4687 VOS_ASSERT(0);
4688 break;
4689 }
4690 }
4691 // If FT handoff is in progress, legacy handoff need not be enabled
4692 if (!pSession->ftHandoffInProgress) {
4693 pSession->handoffRequested = VOS_TRUE;
4694 }
4695 // this session no longer needs UAPSD
4696 pSession->apsdMask = 0;
4697 // do any sessions still require UAPSD?
4698 if (!sme_QosIsUapsdActive())
4699 {
4700 // No sessions require UAPSD so turn it off
4701 // (really don't care when PMC stops it)
4702 (void)pmcStopUapsd(pMac);
4703 }
4704 pSession->uapsdAlreadyRequested = VOS_FALSE;
4705 return eHAL_STATUS_SUCCESS;
4706}
4707/*--------------------------------------------------------------------------
4708 \brief sme_QosProcessHandoffSuccessEv() - Function to process the
4709 SME_QOS_CSR_HANDOFF_COMPLETE event indication from CSR
4710 \param pEvent_info - Pointer to relevant info from CSR.
4711
4712 \return eHalStatus
4713
4714 \sa
4715
4716 --------------------------------------------------------------------------*/
4717eHalStatus sme_QosProcessHandoffSuccessEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info)
4718{
4719 sme_QosSessionInfo *pSession;
4720 sme_QosACInfo *pACInfo;
4721 v_U8_t ac;
4722 eHalStatus status = eHAL_STATUS_FAILURE;
4723 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
4724 "%s: %d: invoked on session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004725 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004726 sessionId);
4727 pSession = &sme_QosCb.sessionInfo[sessionId];
4728 //go back to original state before handoff
4729 for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++)
4730 {
4731 pACInfo = &pSession->ac_info[ac];
4732 switch(pACInfo->curr_state)
4733 {
4734 case SME_QOS_HANDOFF:
4735 sme_QosStateTransition(sessionId, ac, pACInfo->prev_state);
4736 //we will retry for the requested flow(s) with the new AP
4737 if(SME_QOS_REQUESTED == pACInfo->curr_state)
4738 {
4739 pACInfo->curr_state = SME_QOS_LINK_UP;
4740 }
4741 status = eHAL_STATUS_SUCCESS;
4742 break;
4743 // FT logic, has already moved it to QOS_REQUESTED state during the
4744 // reassoc request event, which would include the Qos (TSPEC) params
4745 // in the reassoc req frame
4746 case SME_QOS_REQUESTED:
4747 break;
4748 case SME_QOS_INIT:
4749 case SME_QOS_CLOSED:
4750 case SME_QOS_LINK_UP:
4751 case SME_QOS_QOS_ON:
4752 default:
4753#ifdef WLAN_FEATURE_VOWIFI_11R
4754/* In case of 11r - RIC, we request QoS and Hand-off at the same time hence the
4755 state may be SME_QOS_REQUESTED */
4756 if( pSession->ftHandoffInProgress )
4757 break;
4758#endif
4759 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
4760 "%s: %d: On session %d AC %d is in wrong state %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004761 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004762 sessionId, ac, pACInfo->curr_state);
4763 //ASSERT
4764 VOS_ASSERT(0);
4765 break;
4766 }
4767 }
4768 return status;
4769}
4770/*--------------------------------------------------------------------------
4771 \brief sme_QosProcessHandoffFailureEv() - Function to process the
4772 SME_QOS_CSR_HANDOFF_FAILURE event indication from CSR
4773 \param pEvent_info - Pointer to relevant info from CSR.
4774
4775 \return eHalStatus
4776
4777 \sa
4778
4779 --------------------------------------------------------------------------*/
4780eHalStatus sme_QosProcessHandoffFailureEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info)
4781{
4782 sme_QosSessionInfo *pSession;
4783 sme_QosACInfo *pACInfo;
4784 v_U8_t ac;
4785 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
4786 "%s: %d: invoked on session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004787 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004788 sessionId);
4789 pSession = &sme_QosCb.sessionInfo[sessionId];
4790 for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++)
4791 {
4792 pACInfo = &pSession->ac_info[ac];
4793 switch(pACInfo->curr_state)
4794 {
4795 case SME_QOS_HANDOFF:
4796 sme_QosStateTransition(sessionId, ac, SME_QOS_INIT);
4797 //need to clean up flows: TODO
4798 vos_mem_zero(&pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0],
4799 sizeof(sme_QosWmmTspecInfo));
4800 vos_mem_zero(&pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0],
4801 sizeof(sme_QosWmmTspecInfo));
4802 vos_mem_zero(&pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_1],
4803 sizeof(sme_QosWmmTspecInfo));
4804 vos_mem_zero(&pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_1],
4805 sizeof(sme_QosWmmTspecInfo));
4806 pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_CLEAR;
4807 pACInfo->tspec_pending = 0;
4808 pACInfo->num_flows[SME_QOS_TSPEC_INDEX_0] = 0;
4809 pACInfo->num_flows[SME_QOS_TSPEC_INDEX_1] = 0;
4810 break;
4811 case SME_QOS_INIT:
4812 case SME_QOS_CLOSED:
4813 case SME_QOS_LINK_UP:
4814 case SME_QOS_REQUESTED:
4815 case SME_QOS_QOS_ON:
4816 default:
4817 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
4818 "%s: %d: On session %d AC %d is in wrong state %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004819 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004820 sessionId, ac, pACInfo->curr_state);
4821 //ASSERT
4822 VOS_ASSERT(0);
4823 break;
4824 }
4825 }
4826 //no longer in handoff
4827 pSession->handoffRequested = VOS_FALSE;
4828 //clean up the assoc info
4829 if(pSession->assocInfo.pBssDesc)
4830 {
4831 vos_mem_free(pSession->assocInfo.pBssDesc);
4832 pSession->assocInfo.pBssDesc = NULL;
4833 }
4834 return eHAL_STATUS_SUCCESS;
4835}
4836/*--------------------------------------------------------------------------
4837 \brief sme_QosProcessDisconnectEv() - Function to process the
4838 SME_QOS_CSR_DISCONNECT_REQ or SME_QOS_CSR_DISCONNECT_IND event indication
4839 from CSR
4840 \param pEvent_info - Pointer to relevant info from CSR.
4841
4842 \return eHalStatus
4843
4844 \sa
4845
4846 --------------------------------------------------------------------------*/
4847eHalStatus sme_QosProcessDisconnectEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info)
4848{
4849 sme_QosSessionInfo *pSession;
4850 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
4851 "%s: %d: invoked on session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004852 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004853 sessionId);
4854 pSession = &sme_QosCb.sessionInfo[sessionId];
4855 if((pSession->handoffRequested)
4856#ifdef WLAN_FEATURE_VOWIFI_11R
4857/* In case of 11r - RIC, we request QoS and Hand-off at the same time hence the
4858 state may be SME_QOS_REQUESTED */
4859 && !pSession->ftHandoffInProgress
4860#endif
4861 )
4862 {
4863 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
4864 "%s: %d: no need for state transition, should "
4865 "already be in handoff state",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004866 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004867 VOS_ASSERT(pSession->ac_info[0].curr_state == SME_QOS_HANDOFF);
4868 VOS_ASSERT(pSession->ac_info[1].curr_state == SME_QOS_HANDOFF);
4869 VOS_ASSERT(pSession->ac_info[2].curr_state == SME_QOS_HANDOFF);
4870 VOS_ASSERT(pSession->ac_info[3].curr_state == SME_QOS_HANDOFF);
4871 return eHAL_STATUS_SUCCESS;
4872 }
4873 sme_QosInitACs(pMac, sessionId);
4874 // this session doesn't require UAPSD
4875 pSession->apsdMask = 0;
4876 // do any sessions still require UAPSD?
4877 if (!sme_QosIsUapsdActive())
4878 {
4879 // No sessions require UAPSD so turn it off
4880 // (really don't care when PMC stops it)
4881 (void)pmcStopUapsd(pMac);
4882 }
4883 pSession->uapsdAlreadyRequested = VOS_FALSE;
4884 pSession->handoffRequested = VOS_FALSE;
4885 pSession->readyForPowerSave = VOS_TRUE;
4886 pSession->roamID = 0;
4887 //need to clean up buffered req
4888 sme_QosDeleteBufferedRequests(pMac, sessionId);
4889 //need to clean up flows
4890 sme_QosDeleteExistingFlows(pMac, sessionId);
4891 //clean up the assoc info
4892 if(pSession->assocInfo.pBssDesc)
4893 {
4894 vos_mem_free(pSession->assocInfo.pBssDesc);
4895 pSession->assocInfo.pBssDesc = NULL;
4896 }
4897 sme_QosCb.sessionInfo[sessionId].sessionActive = VOS_FALSE;
4898 return eHAL_STATUS_SUCCESS;
4899}
4900/*--------------------------------------------------------------------------
4901 \brief sme_QosProcessJoinReqEv() - Function to process the
4902 SME_QOS_CSR_JOIN_REQ event indication from CSR
4903 \param pEvent_info - Pointer to relevant info from CSR.
4904
4905 \return eHalStatus
4906
4907 \sa
4908
4909 --------------------------------------------------------------------------*/
4910eHalStatus sme_QosProcessJoinReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info)
4911{
4912 sme_QosSessionInfo *pSession;
4913 sme_QosEdcaAcType ac;
4914 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
4915 "%s: %d: invoked on session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004916 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004917 sessionId);
4918 pSession = &sme_QosCb.sessionInfo[sessionId];
4919 if(pSession->handoffRequested)
4920 {
4921 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
4922 "%s: %d: no need for state transition, should "
4923 "already be in handoff state",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004924 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004925 VOS_ASSERT(pSession->ac_info[0].curr_state == SME_QOS_HANDOFF);
4926 VOS_ASSERT(pSession->ac_info[1].curr_state == SME_QOS_HANDOFF);
4927 VOS_ASSERT(pSession->ac_info[2].curr_state == SME_QOS_HANDOFF);
4928 VOS_ASSERT(pSession->ac_info[3].curr_state == SME_QOS_HANDOFF);
4929 //buffer the existing flows to be renewed after handoff is done
4930 sme_QosBufferExistingFlows(pMac, sessionId);
4931 //clean up the control block partially for handoff
4932 sme_QosCleanupCtrlBlkForHandoff(pMac, sessionId);
4933 return eHAL_STATUS_SUCCESS;
4934 }
4935
4936 for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++)
4937 {
4938 sme_QosStateTransition(sessionId, ac, SME_QOS_INIT);
4939 }
4940 //clean up the assoc info if already set
4941 if(pSession->assocInfo.pBssDesc)
4942 {
4943 vos_mem_free(pSession->assocInfo.pBssDesc);
4944 pSession->assocInfo.pBssDesc = NULL;
4945 }
4946 return eHAL_STATUS_SUCCESS;
4947}
4948
4949#ifdef WLAN_FEATURE_VOWIFI_11R
4950/*--------------------------------------------------------------------------
4951 \brief sme_QosProcessPreauthSuccessInd() - Function to process the
4952 SME_QOS_CSR_PREAUTH_SUCCESS_IND event indication from CSR
4953
4954 \param pEvent_info - Pointer to relevant info from CSR.
4955
4956 \return eHalStatus
4957
4958 \sa
4959
4960 --------------------------------------------------------------------------*/
4961eHalStatus sme_QosProcessPreauthSuccessInd(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info)
4962{
4963 sme_QosSessionInfo *pSession;
4964 sme_QosACInfo *pACInfo;
4965 v_U8_t ac;
4966 eHalStatus status = eHAL_STATUS_SUCCESS;
4967
4968 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
4969 "%s: %d: invoked on session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004970 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004971 sessionId);
4972
4973 pSession = &sme_QosCb.sessionInfo[sessionId];
4974
4975 for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++)
4976 {
4977 pACInfo = &pSession->ac_info[ac];
4978
4979 switch(pACInfo->curr_state)
4980 {
4981 case SME_QOS_LINK_UP:
4982 case SME_QOS_REQUESTED:
4983 case SME_QOS_QOS_ON:
4984 sme_QosStateTransition(sessionId, ac, SME_QOS_HANDOFF);
4985 break;
4986 case SME_QOS_HANDOFF:
4987 //print error msg
4988 case SME_QOS_CLOSED:
4989 case SME_QOS_INIT:
4990 default:
4991 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
4992 "%s: %d: On session %d AC %d is in wrong state %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004993 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004994 sessionId, ac, pACInfo->curr_state);
4995 //ASSERT
4996 VOS_ASSERT(0);
4997 break;
4998 }
4999 }
5000
5001 pSession->ftHandoffInProgress = VOS_TRUE;
5002
5003 // Check if its a 11R roaming before preparing the RIC IEs
5004 if (csrRoamIs11rAssoc(pMac))
5005 {
5006 v_U16_t ricOffset = 0;
5007 v_U32_t ricIELength = 0;
5008 v_U8_t *ricIE;
5009 v_U8_t tspec_mask_status = 0;
5010 v_U8_t tspec_pending_status = 0;
5011
5012 /* Any Block Ack info there, should have been already filled by PE and present in this buffer
5013 and the ric_ies_length should contain the length of the whole RIC IEs. Filling of TSPEC info
5014 should start from this length */
5015 ricIE = pMac->ft.ftSmeContext.psavedFTPreAuthRsp->ric_ies;
5016 ricOffset = pMac->ft.ftSmeContext.psavedFTPreAuthRsp->ric_ies_length;
5017
5018 /* Now we have to process the currentTspeInfo inside this session and create the RIC IEs */
5019 for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++)
5020 {
5021 volatile v_U8_t tspec_index = 0;
Gopichand Nakkala5b6de582013-03-08 16:23:30 +05305022 ricIELength = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005023 pACInfo = &pSession->ac_info[ac];
5024 tspec_pending_status = pACInfo->tspec_pending;
5025 tspec_mask_status = pACInfo->tspec_mask_status;
5026 vos_mem_zero(pACInfo->ricIdentifier, SME_QOS_TSPEC_INDEX_MAX);
5027 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
5028 FL("AC %d ==> TSPEC status = %d, tspec pending = %d"),
5029 ac, tspec_mask_status, tspec_pending_status);
5030
5031 do
5032 {
5033 if (tspec_mask_status & 0x1)
5034 {
5035 /* If a tspec status is pending, take requested_QoSInfo for RIC request, else use curr_QoSInfo
5036 for the RIC request */
5037 if (tspec_pending_status & 0x1)
5038 {
5039 status = sme_QosCreateTspecRICIE(pMac, &pACInfo->requested_QoSInfo[tspec_index],
5040 ricIE + ricOffset, &ricIELength, &pACInfo->ricIdentifier[tspec_index]);
5041 }
5042 else
5043 {
5044 status = sme_QosCreateTspecRICIE(pMac, &pACInfo->curr_QoSInfo[tspec_index],
5045 ricIE + ricOffset, &ricIELength, &pACInfo->ricIdentifier[tspec_index]);
5046 }
5047 }
5048 ricOffset += ricIELength;
5049 pMac->ft.ftSmeContext.psavedFTPreAuthRsp->ric_ies_length += ricIELength;
5050
5051 tspec_mask_status >>= 1;
5052 tspec_pending_status >>= 1;
5053 tspec_index++;
5054 } while (tspec_mask_status);
5055 }
5056 }
5057 return status;
5058}
5059
5060#endif
5061
5062
5063/*--------------------------------------------------------------------------
5064 \brief sme_QosProcessAddTsFailureRsp() - Function to process the
5065 Addts request failure response came from PE
5066
5067 We will notify HDD only for the requested Flow, other Flows running on the AC
5068 stay intact
5069
5070 \param pMac - Pointer to the global MAC parameter structure.
5071 \param pRsp - Pointer to the addts response structure came from PE.
5072
5073 \return eHalStatus
5074
5075 \sa
5076
5077 --------------------------------------------------------------------------*/
5078eHalStatus sme_QosProcessAddTsFailureRsp(tpAniSirGlobal pMac,
5079 v_U8_t sessionId,
5080 tSirAddtsRspInfo * pRsp)
5081{
5082 sme_QosSessionInfo *pSession;
5083 sme_QosACInfo *pACInfo;
5084 sme_QosEdcaAcType ac;
5085 sme_QosSearchInfo search_key;
5086 v_U8_t tspec_pending;
5087 sme_QosWmmUpType up = (sme_QosWmmUpType)pRsp->tspec.tsinfo.traffic.userPrio;
5088 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
5089 "%s: %d: invoked on session %d for UP %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005090 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005091 sessionId, up);
5092 ac = sme_QosUpToAc(up);
5093 if(SME_QOS_EDCA_AC_MAX == ac)
5094 {
5095 //err msg
5096 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
5097 "%s: %d: invalid AC %d from UP %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005098 __func__, __LINE__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -07005099 return eHAL_STATUS_FAILURE;
5100 }
5101 pSession = &sme_QosCb.sessionInfo[sessionId];
5102 pACInfo = &pSession->ac_info[ac];
5103 // is there a TSPEC request pending on this AC?
5104 tspec_pending = pACInfo->tspec_pending;
5105 if(!tspec_pending)
5106 {
5107 //ASSERT
5108 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
5109 "%s: %d: On session %d an AddTS is not pending on AC %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005110 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005111 sessionId, ac);
5112 VOS_ASSERT(0);
5113 return eHAL_STATUS_FAILURE;
5114 }
5115
5116 vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo));
5117 //set the key type & the key to be searched in the Flow List
5118 search_key.key.ac_type = ac;
5119 search_key.index = SME_QOS_SEARCH_KEY_INDEX_2;
5120 search_key.sessionId = sessionId;
5121 if(!HAL_STATUS_SUCCESS(sme_QosFindAllInFlowList(pMac, search_key, sme_QosAddTsFailureFnp)))
5122 {
5123 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
5124 "%s: %d: On session %d no match found for ac = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005125 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005126 sessionId, search_key.key.ac_type);
5127 //ASSERT
5128 VOS_ASSERT(0);
5129 return eHAL_STATUS_FAILURE;
5130 }
5131 vos_mem_zero(&pACInfo->requested_QoSInfo[tspec_pending - 1],
5132 sizeof(sme_QosWmmTspecInfo));
5133
5134 if((!pACInfo->num_flows[0])&&
5135 (!pACInfo->num_flows[1]))
5136 {
5137 pACInfo->tspec_mask_status &= SME_QOS_TSPEC_MASK_BIT_1_2_SET &
5138 (~pACInfo->tspec_pending);
5139 sme_QosStateTransition(sessionId, ac, SME_QOS_LINK_UP);
5140 }
5141 else
5142 {
5143 sme_QosStateTransition(sessionId, ac, SME_QOS_QOS_ON);
5144 }
5145 pACInfo->tspec_pending = 0;
5146
5147 (void)sme_QosProcessBufferedCmd(sessionId);
5148
5149 return eHAL_STATUS_SUCCESS;
5150}
5151
5152/*--------------------------------------------------------------------------
5153 \brief sme_QosUpdateTspecMask() - Utiltity function to update the tspec.
5154 Typical usage while aggregating unidirectional flows into a bi-directional
5155 flow on AC which is running multiple flows
5156
5157 \param sessionId - Session upon which the TSPEC is being updated
5158 \param ac - Enumeration of the various EDCA Access Categories.
5159 \param old_tspec_mask - on which tspec per AC, the update is requested
5160 \param new_tspec_mask - tspec to be set for this AC
5161
5162 \return eHalStatus
5163
5164 \sa
5165
5166 --------------------------------------------------------------------------*/
5167static eHalStatus sme_QosUpdateTspecMask(v_U8_t sessionId,
5168 sme_QosSearchInfo search_key,
5169 v_U8_t new_tspec_mask)
5170{
5171 tListElem *pEntry= NULL, *pNextEntry = NULL;
5172 sme_QosFlowInfoEntry *flow_info = NULL;
5173 sme_QosSessionInfo *pSession;
5174 sme_QosACInfo *pACInfo;
5175
5176 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
5177 "%s: %d: invoked on session %d for AC %d TSPEC %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005178 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005179 sessionId, search_key.key.ac_type, new_tspec_mask);
5180
5181 pSession = &sme_QosCb.sessionInfo[sessionId];
5182
5183 if (search_key.key.ac_type < SME_QOS_EDCA_AC_MAX)
5184 {
5185 pACInfo = &pSession->ac_info[search_key.key.ac_type];
5186 }
5187 else
5188 {
5189 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
5190 "%s: %d: Exceeded the array bounds of pSession->ac_info",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005191 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005192 VOS_ASSERT (0);
5193 return eHAL_STATUS_FAILURE;
5194 }
5195
5196 pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE );
5197 if(!pEntry)
5198 {
5199 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
5200 "%s: %d: Flow List empty, nothing to update",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005201 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005202 return eHAL_STATUS_FAILURE;
5203 }
5204
5205 while( pEntry )
5206 {
5207 pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE );
5208 flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link );
5209
5210 if(search_key.sessionId == flow_info->sessionId)
5211 {
5212 if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_4)
5213 {
5214 if((search_key.key.ac_type == flow_info->ac_type) &&
5215 (search_key.direction == flow_info->QoSInfo.ts_info.direction))
5216 {
5217 //msg
5218 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
5219 "%s: %d: Flow %d matches",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005220 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005221 flow_info->QosFlowID);
5222 pACInfo->num_flows[flow_info->tspec_mask - 1]--;
5223 pACInfo->num_flows[new_tspec_mask - 1]++;
5224 flow_info->tspec_mask = new_tspec_mask;
5225 }
5226 }
5227 else if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_5)
5228 {
5229 if((search_key.key.ac_type == flow_info->ac_type) &&
5230 (search_key.tspec_mask == flow_info->tspec_mask))
5231 {
5232 //msg
5233 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
5234 "%s: %d: Flow %d matches",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005235 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005236 flow_info->QosFlowID);
5237 pACInfo->num_flows[flow_info->tspec_mask - 1]--;
5238 pACInfo->num_flows[new_tspec_mask - 1]++;
5239 flow_info->tspec_mask = new_tspec_mask;
5240 }
5241 }
5242 }
5243
5244 pEntry = pNextEntry;
5245 }
5246
5247 return eHAL_STATUS_SUCCESS;
5248}
5249/*--------------------------------------------------------------------------
5250 \brief sme_QosProcessAddTsSuccessRsp() - Function to process the
5251 Addts request success response came from PE
5252
5253 We will notify HDD with addts success for the requested Flow, & for other
5254 Flows running on the AC we will send an addts modify status
5255
5256
5257 \param pMac - Pointer to the global MAC parameter structure.
5258 \param pRsp - Pointer to the addts response structure came from PE.
5259
5260 \return eHalStatus
5261
5262 \sa
5263
5264 --------------------------------------------------------------------------*/
5265eHalStatus sme_QosProcessAddTsSuccessRsp(tpAniSirGlobal pMac,
5266 v_U8_t sessionId,
5267 tSirAddtsRspInfo * pRsp)
5268{
5269 sme_QosSessionInfo *pSession;
5270 sme_QosACInfo *pACInfo;
5271 sme_QosEdcaAcType ac, ac_index;
5272 sme_QosSearchInfo search_key;
5273 sme_QosSearchInfo search_key1;
5274 v_U8_t tspec_pending;
5275 tListElem *pEntry= NULL;
5276 sme_QosFlowInfoEntry *flow_info = NULL;
5277 sme_QosWmmUpType up = (sme_QosWmmUpType)pRsp->tspec.tsinfo.traffic.userPrio;
5278#ifdef FEATURE_WLAN_DIAG_SUPPORT
5279 WLAN_VOS_DIAG_EVENT_DEF(qos, vos_event_wlan_qos_payload_type);
5280 vos_log_qos_tspec_pkt_type *log_ptr = NULL;
5281#endif //FEATURE_WLAN_DIAG_SUPPORT
5282 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
5283 "%s: %d: invoked on session %d for UP %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005284 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005285 sessionId, up);
5286 pSession = &sme_QosCb.sessionInfo[sessionId];
5287 ac = sme_QosUpToAc(up);
5288 if(SME_QOS_EDCA_AC_MAX == ac)
5289 {
5290 //err msg
5291 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
5292 "%s: %d: invalid AC %d from UP %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005293 __func__, __LINE__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -07005294 return eHAL_STATUS_FAILURE;
5295 }
5296 pACInfo = &pSession->ac_info[ac];
5297 // is there a TSPEC request pending on this AC?
5298 tspec_pending = pACInfo->tspec_pending;
5299 if(!tspec_pending)
5300 {
5301 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
5302 "%s: %d: On session %d an AddTS is not pending on AC %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005303 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005304 sessionId, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07005305 return eHAL_STATUS_FAILURE;
5306 }
5307 //App is looking for APSD or the App which was looking for APSD has been
5308 //released, so STA re-negotiated with AP
5309 if(pACInfo->requested_QoSInfo[tspec_pending - 1].ts_info.psb)
5310 {
5311 //update the session's apsd mask
5312 pSession->apsdMask |= 1 << (SME_QOS_EDCA_AC_VO - ac);
5313 }
5314 else
5315 {
5316 if(((SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~tspec_pending) > 0) &&
5317 ((SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~tspec_pending) <=
5318 SME_QOS_TSPEC_INDEX_MAX))
5319 {
5320 if(!pACInfo->requested_QoSInfo
5321 [(SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~tspec_pending) - 1].ts_info.psb)
5322 {
5323 //update the session's apsd mask
5324 pSession->apsdMask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac));
5325 }
5326 }
5327 else
5328 {
5329 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
5330 "%s: %d: Exceeded the array bounds of pACInfo->requested_QosInfo",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005331 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005332 VOS_ASSERT (0);
5333 return eHAL_STATUS_FAILURE;
5334 }
5335 }
Hema Aparna Medicharla03aba3d2013-08-23 14:45:24 +05305336
5337 pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.burst_size_defn =
5338 pRsp->tspec.tsinfo.traffic.burstSizeDefn;
5339 pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.ack_policy =
5340 pRsp->tspec.tsinfo.traffic.ackPolicy;
5341 pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.up =
5342 pRsp->tspec.tsinfo.traffic.userPrio;
5343 pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.psb =
5344 pRsp->tspec.tsinfo.traffic.psb;
5345 pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.direction =
5346 pRsp->tspec.tsinfo.traffic.direction;
5347 pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.tid =
5348 pRsp->tspec.tsinfo.traffic.tsid;
5349 pACInfo->curr_QoSInfo[tspec_pending - 1].nominal_msdu_size =
5350 pRsp->tspec.nomMsduSz;
5351 pACInfo->curr_QoSInfo[tspec_pending - 1].maximum_msdu_size =
5352 pRsp->tspec.maxMsduSz;
5353 pACInfo->curr_QoSInfo[tspec_pending - 1].min_service_interval =
5354 pRsp->tspec.minSvcInterval;
5355 pACInfo->curr_QoSInfo[tspec_pending - 1].max_service_interval =
5356 pRsp->tspec.maxSvcInterval;
5357 pACInfo->curr_QoSInfo[tspec_pending - 1].inactivity_interval =
5358 pRsp->tspec.inactInterval;
5359 pACInfo->curr_QoSInfo[tspec_pending - 1].suspension_interval =
5360 pRsp->tspec.suspendInterval;
5361 pACInfo->curr_QoSInfo[tspec_pending - 1].svc_start_time =
5362 pRsp->tspec.svcStartTime;
5363 pACInfo->curr_QoSInfo[tspec_pending - 1].min_data_rate =
5364 pRsp->tspec.minDataRate;
5365 pACInfo->curr_QoSInfo[tspec_pending - 1].mean_data_rate =
5366 pRsp->tspec.meanDataRate;
5367 pACInfo->curr_QoSInfo[tspec_pending - 1].peak_data_rate =
5368 pRsp->tspec.peakDataRate;
5369 pACInfo->curr_QoSInfo[tspec_pending - 1].max_burst_size =
5370 pRsp->tspec.maxBurstSz;
5371 pACInfo->curr_QoSInfo[tspec_pending - 1].delay_bound =
5372 pRsp->tspec.delayBound;
5373
5374 pACInfo->curr_QoSInfo[tspec_pending - 1].min_phy_rate =
5375 pRsp->tspec.minPhyRate;
5376 pACInfo->curr_QoSInfo[tspec_pending - 1].surplus_bw_allowance =
5377 pRsp->tspec.surplusBw;
5378 pACInfo->curr_QoSInfo[tspec_pending - 1].medium_time =
5379 pRsp->tspec.mediumTime;
5380
5381 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
5382 "%s: %d: On session %d AddTspec Medium Time %d",
5383 __func__, __LINE__,
5384 sessionId, pRsp->tspec.mediumTime);
5385
Jeff Johnson295189b2012-06-20 16:38:30 -07005386 /* Check if the current flow is for bi-directional. If so, update the number of flows
5387 * to reflect that all flows are aggregated into tspec index 0. */
5388 if((pACInfo->curr_QoSInfo[pACInfo->tspec_pending - 1].ts_info.direction == SME_QOS_WMM_TS_DIR_BOTH) &&
5389 (pACInfo->num_flows[SME_QOS_TSPEC_INDEX_1] > 0))
5390 {
5391 vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo));
5392 /* update tspec_mask for all the flows having SME_QOS_TSPEC_MASK_BIT_2_SET to SME_QOS_TSPEC_MASK_BIT_1_SET */
5393 search_key.key.ac_type = ac;
5394 search_key.index = SME_QOS_SEARCH_KEY_INDEX_5;
5395 search_key.sessionId = sessionId;
5396 search_key.tspec_mask = SME_QOS_TSPEC_MASK_BIT_2_SET;
5397 sme_QosUpdateTspecMask(sessionId, search_key, SME_QOS_TSPEC_MASK_BIT_1_SET);
5398 }
5399
5400 vos_mem_zero(&search_key1, sizeof(sme_QosSearchInfo));
5401 //set the horenewal field in control block if needed
5402 search_key1.index = SME_QOS_SEARCH_KEY_INDEX_3;
5403 search_key1.key.reason = SME_QOS_REASON_SETUP;
5404 search_key1.sessionId = sessionId;
5405 for(ac_index = SME_QOS_EDCA_AC_BE; ac_index < SME_QOS_EDCA_AC_MAX; ac_index++)
5406 {
5407 pEntry = sme_QosFindInFlowList(search_key1);
5408 if(pEntry)
5409 {
5410 flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link );
5411 if(flow_info->ac_type == ac)
5412 {
5413 pACInfo->hoRenewal = flow_info->hoRenewal;
5414 break;
5415 }
5416 }
5417 }
5418 vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo));
5419 //set the key type & the key to be searched in the Flow List
5420 search_key.key.ac_type = ac;
5421 search_key.index = SME_QOS_SEARCH_KEY_INDEX_2;
5422 search_key.sessionId = sessionId;
5423 //notify HDD the success for the requested flow
5424 //notify all the other flows running on the AC that QoS got modified
5425 if(!HAL_STATUS_SUCCESS(sme_QosFindAllInFlowList(pMac, search_key, sme_QosAddTsSuccessFnp)))
5426 {
5427 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
5428 "%s: %d: On session %d no match found for ac %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005429 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005430 sessionId, search_key.key.ac_type);
5431 //ASSERT
5432 VOS_ASSERT(0);
5433 return eHAL_STATUS_FAILURE;
5434 }
5435 pACInfo->hoRenewal = VOS_FALSE;
5436 vos_mem_zero(&pACInfo->requested_QoSInfo[tspec_pending - 1],
5437 sizeof(sme_QosWmmTspecInfo));
5438 //event: EVENT_WLAN_QOS
5439#ifdef FEATURE_WLAN_DIAG_SUPPORT
5440 qos.eventId = SME_QOS_DIAG_ADDTS_RSP;
5441 qos.reasonCode = SME_QOS_DIAG_ADDTS_ADMISSION_ACCEPTED;
5442 WLAN_VOS_DIAG_EVENT_REPORT(&qos, EVENT_WLAN_QOS);
5443 WLAN_VOS_DIAG_LOG_ALLOC(log_ptr, vos_log_qos_tspec_pkt_type, LOG_WLAN_QOS_TSPEC_C);
5444 if(log_ptr)
5445 {
5446 log_ptr->delay_bound = pACInfo->curr_QoSInfo[tspec_pending - 1].delay_bound;
5447 log_ptr->inactivity_interval = pACInfo->curr_QoSInfo[tspec_pending - 1].inactivity_interval;
5448 log_ptr->max_burst_size = pACInfo->curr_QoSInfo[tspec_pending - 1].max_burst_size;
5449 log_ptr->max_service_interval = pACInfo->curr_QoSInfo[tspec_pending - 1].max_service_interval;
5450 log_ptr->maximum_msdu_size = pACInfo->curr_QoSInfo[tspec_pending - 1].maximum_msdu_size;
5451 log_ptr->mean_data_rate = pACInfo->curr_QoSInfo[tspec_pending - 1].mean_data_rate;
5452 log_ptr->medium_time = pACInfo->curr_QoSInfo[tspec_pending - 1].medium_time;
5453 log_ptr->min_data_rate = pACInfo->curr_QoSInfo[tspec_pending - 1].min_data_rate;
5454 log_ptr->min_phy_rate = pACInfo->curr_QoSInfo[tspec_pending - 1].min_phy_rate;
5455 log_ptr->min_service_interval = pACInfo->curr_QoSInfo[tspec_pending - 1].min_service_interval;
5456 log_ptr->nominal_msdu_size = pACInfo->curr_QoSInfo[tspec_pending - 1].nominal_msdu_size;
5457 log_ptr->peak_data_rate = pACInfo->curr_QoSInfo[tspec_pending - 1].peak_data_rate;
5458 log_ptr->surplus_bw_allowance = pACInfo->curr_QoSInfo[tspec_pending - 1].surplus_bw_allowance;
5459 log_ptr->suspension_interval = pACInfo->curr_QoSInfo[tspec_pending - 1].surplus_bw_allowance;
5460 log_ptr->suspension_interval = pACInfo->curr_QoSInfo[tspec_pending - 1].suspension_interval;
5461 log_ptr->svc_start_time = pACInfo->curr_QoSInfo[tspec_pending - 1].svc_start_time;
5462 log_ptr->tsinfo[0] = pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.direction << 5 |
5463 pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.tid << 1;
5464 log_ptr->tsinfo[1] = pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.up << 11 |
5465 pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.psb << 10;
5466 log_ptr->tsinfo[2] = 0;
5467 }
5468 WLAN_VOS_DIAG_LOG_REPORT(log_ptr);
5469#endif //FEATURE_WLAN_DIAG_SUPPORT
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005470#if defined(FEATURE_WLAN_CCX) && !defined(FEATURE_WLAN_CCX_UPLOAD)
Jeff Johnson295189b2012-06-20 16:38:30 -07005471 if (ac == SME_QOS_EDCA_AC_VO)
5472 {
5473 // Indicate to neighbor roam logic of the new required VO
5474 // ac bandwidth requirement.
5475 csrNeighborRoamIndicateVoiceBW( pMac, pACInfo->curr_QoSInfo[tspec_pending - 1].peak_data_rate, TRUE );
5476 }
5477#endif
5478 pACInfo->tspec_pending = 0;
5479
5480 sme_QosStateTransition(sessionId, ac, SME_QOS_QOS_ON);
5481
5482
5483 (void)sme_QosProcessBufferedCmd(sessionId);
5484 return eHAL_STATUS_SUCCESS;
5485
5486}
5487/*--------------------------------------------------------------------------
5488 \brief sme_QosAggregateParams() - Utiltity function to increament the TSPEC
5489 params per AC. Typical usage while using flow aggregation or deletion of flows
5490
5491 \param pInput_Tspec_Info - Pointer to sme_QosWmmTspecInfo which contains the
5492 WMM TSPEC related info with which pCurrent_Tspec_Info will be updated
5493 \param pCurrent_Tspec_Info - Pointer to sme_QosWmmTspecInfo which contains
5494 current the WMM TSPEC related info
5495
5496 \return eHalStatus
5497
5498 \sa
5499
5500 --------------------------------------------------------------------------*/
5501eHalStatus sme_QosAggregateParams(
5502 sme_QosWmmTspecInfo * pInput_Tspec_Info,
5503 sme_QosWmmTspecInfo * pCurrent_Tspec_Info,
5504 sme_QosWmmTspecInfo * pUpdated_Tspec_Info)
5505{
5506 sme_QosWmmTspecInfo TspecInfo;
5507 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
5508 "%s: %d: invoked",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005509 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005510 if(!pInput_Tspec_Info)
5511 {
5512 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
5513 "%s: %d: input is NULL, nothing to aggregate",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005514 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005515 return eHAL_STATUS_FAILURE;
5516 }
5517 if(!pCurrent_Tspec_Info)
5518 {
5519 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
5520 "%s: %d: Current is NULL, can't aggregate",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005521 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005522 return eHAL_STATUS_FAILURE;
5523 }
5524 vos_mem_copy(&TspecInfo, pCurrent_Tspec_Info,
5525 sizeof(sme_QosWmmTspecInfo));
Madan Mohan Koyyalamudia5643d62013-09-25 14:37:55 +05305526 TspecInfo.ts_info.psb = pInput_Tspec_Info->ts_info.psb;
Jeff Johnson295189b2012-06-20 16:38:30 -07005527 /*-------------------------------------------------------------------------
5528 APSD preference is only meaningful if service interval was set by app
5529 -------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +05305530 if(pCurrent_Tspec_Info->min_service_interval &&
5531 pInput_Tspec_Info->min_service_interval &&
5532 (pCurrent_Tspec_Info->ts_info.direction !=
5533 pInput_Tspec_Info->ts_info.direction))
Jeff Johnson295189b2012-06-20 16:38:30 -07005534 {
5535 TspecInfo.min_service_interval = VOS_MIN(
5536 pCurrent_Tspec_Info->min_service_interval,
5537 pInput_Tspec_Info->min_service_interval);
5538 }
5539 else if(pInput_Tspec_Info->min_service_interval)
5540 {
5541 TspecInfo.min_service_interval = pInput_Tspec_Info->min_service_interval;
5542 }
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +05305543 if(pCurrent_Tspec_Info->max_service_interval &&
5544 pInput_Tspec_Info->max_service_interval &&
5545 (pCurrent_Tspec_Info->ts_info.direction !=
5546 pInput_Tspec_Info->ts_info.direction))
Jeff Johnson295189b2012-06-20 16:38:30 -07005547 {
5548 TspecInfo.max_service_interval = VOS_MIN(
5549 pCurrent_Tspec_Info->max_service_interval,
5550 pInput_Tspec_Info->max_service_interval);
5551 }
5552 else
5553 {
5554 TspecInfo.max_service_interval = pInput_Tspec_Info->max_service_interval;
5555 }
5556 /*-------------------------------------------------------------------------
5557 If directions don't match, it must necessarily be both uplink and
5558 downlink
5559 -------------------------------------------------------------------------*/
5560 if(pCurrent_Tspec_Info->ts_info.direction !=
5561 pInput_Tspec_Info->ts_info.direction)
5562 {
5563 TspecInfo.ts_info.direction = SME_QOS_WMM_TS_DIR_BOTH;
5564 }
5565 /*-------------------------------------------------------------------------
5566 Max MSDU size : these sizes are `maxed'
5567 -------------------------------------------------------------------------*/
5568 TspecInfo.maximum_msdu_size = VOS_MAX(pCurrent_Tspec_Info->maximum_msdu_size,
5569 pInput_Tspec_Info->maximum_msdu_size);
5570
5571 /*-------------------------------------------------------------------------
5572 Inactivity interval : these sizes are `maxed'
5573 -------------------------------------------------------------------------*/
5574 TspecInfo.inactivity_interval = VOS_MAX(pCurrent_Tspec_Info->inactivity_interval,
5575 pInput_Tspec_Info->inactivity_interval);
5576
5577 /*-------------------------------------------------------------------------
5578 Delay bounds: min of all values
5579 Check on 0: if 0, it means initial value since delay can never be 0!!
5580 -------------------------------------------------------------------------*/
5581 if(pCurrent_Tspec_Info->delay_bound)
5582 {
5583 TspecInfo.delay_bound = VOS_MIN(pCurrent_Tspec_Info->delay_bound,
5584 pInput_Tspec_Info->delay_bound);
5585 }
5586 else
5587 {
5588 TspecInfo.delay_bound = pInput_Tspec_Info->delay_bound;
5589 }
5590 TspecInfo.max_burst_size = VOS_MAX(pCurrent_Tspec_Info->max_burst_size,
5591 pInput_Tspec_Info->max_burst_size);
5592
5593 /*-------------------------------------------------------------------------
5594 Nominal MSDU size also has a fixed bit that needs to be `handled' before
5595 aggregation
5596 This can be handled only if previous size is the same as new or both have
5597 the fixed bit set
5598 These sizes are not added: but `maxed'
5599 -------------------------------------------------------------------------*/
5600 TspecInfo.nominal_msdu_size = VOS_MAX(
5601 pCurrent_Tspec_Info->nominal_msdu_size & ~SME_QOS_16BIT_MSB,
5602 pInput_Tspec_Info->nominal_msdu_size & ~SME_QOS_16BIT_MSB);
5603
5604 if( ((pCurrent_Tspec_Info->nominal_msdu_size == 0) ||
5605 (pCurrent_Tspec_Info->nominal_msdu_size & SME_QOS_16BIT_MSB)) &&
5606 ((pInput_Tspec_Info->nominal_msdu_size == 0) ||
5607 (pInput_Tspec_Info->nominal_msdu_size & SME_QOS_16BIT_MSB)))
5608 {
5609 TspecInfo.nominal_msdu_size |= SME_QOS_16BIT_MSB;
5610 }
5611
5612 /*-------------------------------------------------------------------------
5613 Data rates:
5614 Add up the rates for aggregation
5615 -------------------------------------------------------------------------*/
5616 SME_QOS_BOUNDED_U32_ADD_Y_TO_X( TspecInfo.peak_data_rate,
5617 pInput_Tspec_Info->peak_data_rate );
5618 SME_QOS_BOUNDED_U32_ADD_Y_TO_X( TspecInfo.min_data_rate,
5619 pInput_Tspec_Info->min_data_rate );
5620 /* mean data rate = peak data rate: aggregate to be flexible on apps */
5621 SME_QOS_BOUNDED_U32_ADD_Y_TO_X( TspecInfo.mean_data_rate,
5622 pInput_Tspec_Info->mean_data_rate );
5623
5624 /*-------------------------------------------------------------------------
5625 Suspension interval : this is set to the inactivity interval since per
5626 spec it is less than or equal to inactivity interval
5627 This is not provided by app since we currently don't support the HCCA
5628 mode of operation
5629 Currently set it to 0 to avoid confusion: Cisco CCX needs ~0; spec
5630 requires inactivity interval to be > suspension interval: this could
5631 be tricky!
5632 -------------------------------------------------------------------------*/
5633 TspecInfo.suspension_interval = 0;
5634 /*-------------------------------------------------------------------------
5635 Remaining parameters do not come from app as they are very WLAN
5636 air interface specific
5637 Set meaningful values here
5638 -------------------------------------------------------------------------*/
5639 TspecInfo.medium_time = 0; /* per WMM spec */
5640 TspecInfo.min_phy_rate = SME_QOS_MIN_PHY_RATE;
5641 TspecInfo.svc_start_time = 0; /* arbitrary */
5642 TspecInfo.surplus_bw_allowance += pInput_Tspec_Info->surplus_bw_allowance;
5643 if(TspecInfo.surplus_bw_allowance > SME_QOS_SURPLUS_BW_ALLOWANCE)
5644 {
5645 TspecInfo.surplus_bw_allowance = SME_QOS_SURPLUS_BW_ALLOWANCE;
5646 }
5647 /* Set ack_policy to block ack even if one stream requests block ack policy */
5648 if((pInput_Tspec_Info->ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK) ||
5649 (pCurrent_Tspec_Info->ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK))
5650 {
5651 TspecInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
5652 }
5653
5654 if(pInput_Tspec_Info->ts_info.burst_size_defn || pCurrent_Tspec_Info->ts_info.burst_size_defn )
5655 {
5656 TspecInfo.ts_info.burst_size_defn = 1;
5657 }
5658 if(pUpdated_Tspec_Info)
5659 {
5660 vos_mem_copy(pUpdated_Tspec_Info, &TspecInfo,
5661 sizeof(sme_QosWmmTspecInfo));
5662 }
5663 else
5664 {
5665 vos_mem_copy(pCurrent_Tspec_Info, &TspecInfo,
5666 sizeof(sme_QosWmmTspecInfo));
5667 }
5668 return eHAL_STATUS_SUCCESS;
5669}
5670/*--------------------------------------------------------------------------
5671 \brief sme_QosUpdateParams() - Utiltity function to update the TSPEC
5672 params per AC. Typical usage while deleting flows on AC which is running
5673 multiple flows
5674
5675 \param sessionId - Session upon which the TSPEC is being updated
5676 \param ac - Enumeration of the various EDCA Access Categories.
5677 \param tspec_mask - on which tspec per AC, the update is requested
5678
5679 \return eHalStatus
5680
5681 \sa
5682
5683 --------------------------------------------------------------------------*/
5684static eHalStatus sme_QosUpdateParams(v_U8_t sessionId,
5685 sme_QosEdcaAcType ac,
5686 v_U8_t tspec_mask,
5687 sme_QosWmmTspecInfo * pTspec_Info)
5688{
5689 tListElem *pEntry= NULL, *pNextEntry = NULL;
5690 sme_QosSessionInfo *pSession;
5691 sme_QosACInfo *pACInfo;
5692 sme_QosFlowInfoEntry *flow_info = NULL;
5693 sme_QosWmmTspecInfo Tspec_Info;
5694 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
5695 "%s: %d: invoked on session %d for AC %d TSPEC %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005696 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005697 sessionId, ac, tspec_mask);
5698 if(!pTspec_Info)
5699 {
5700 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
5701 "%s: %d: output is NULL, can't aggregate",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005702 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005703 return eHAL_STATUS_FAILURE;
5704 }
5705 vos_mem_zero(&Tspec_Info, sizeof(sme_QosWmmTspecInfo));
5706 pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE );
5707 if(!pEntry)
5708 {
5709 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
5710 "%s: %d: Flow List empty, nothing to update",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005711 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005712 return eHAL_STATUS_FAILURE;
5713 }
5714 pSession = &sme_QosCb.sessionInfo[sessionId];
5715 pACInfo = &pSession->ac_info[ac];
5716 //init the TS info field
5717 Tspec_Info.ts_info.up = pACInfo->curr_QoSInfo[tspec_mask - 1].ts_info.up;
5718 Tspec_Info.ts_info.psb = pACInfo->curr_QoSInfo[tspec_mask - 1].ts_info.psb;
5719 Tspec_Info.ts_info.tid = pACInfo->curr_QoSInfo[tspec_mask - 1].ts_info.tid;
5720 while( pEntry )
5721 {
5722 pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE );
5723 flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link );
5724 if((sessionId == flow_info->sessionId) &&
5725 (ac == flow_info->ac_type) &&
5726 (tspec_mask == flow_info->tspec_mask))
5727 {
5728 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
5729 "%s: %d: Flow %d matches",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005730 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005731 flow_info->QosFlowID);
5732
5733 if((SME_QOS_REASON_RELEASE == flow_info->reason ) ||
5734 (SME_QOS_REASON_MODIFY == flow_info->reason))
5735 {
5736 //msg
5737 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
5738 "%s: %d: Skipping Flow %d as it is marked "
5739 "for release/modify",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005740 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005741 flow_info->QosFlowID);
5742 }
5743 else if(!HAL_STATUS_SUCCESS(sme_QosAggregateParams(&flow_info->QoSInfo,
5744 &Tspec_Info,
5745 NULL)))
5746 {
5747 //err msg
5748 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
5749 "%s: %d: sme_QosAggregateParams() failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005750 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005751 }
5752 }
5753 pEntry = pNextEntry;
5754 }
5755 // return the aggregate
5756 *pTspec_Info = Tspec_Info;
5757 return eHAL_STATUS_SUCCESS;
5758}
5759/*--------------------------------------------------------------------------
5760 \brief sme_QosAcToUp() - Utiltity function to map an AC to UP
5761 Note: there is a quantization loss here because 4 ACs are mapped to 8 UPs
5762 Mapping is done for consistency
5763 \param ac - Enumeration of the various EDCA Access Categories.
5764 \return an User Priority
5765
5766 \sa
5767
5768 --------------------------------------------------------------------------*/
5769sme_QosWmmUpType sme_QosAcToUp(sme_QosEdcaAcType ac)
5770{
5771 sme_QosWmmUpType up = SME_QOS_WMM_UP_MAX;
5772 if(ac >= 0 && ac < SME_QOS_EDCA_AC_MAX)
5773 {
5774 up = sme_QosACtoUPMap[ac];
5775 }
5776 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
5777 "%s: %d: ac = %d up = %d returned",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005778 __func__, __LINE__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -07005779 return up;
5780}
5781/*--------------------------------------------------------------------------
5782 \brief sme_QosUpToAc() - Utiltity function to map an UP to AC
5783 \param up - Enumeration of the various User priorities (UP).
5784 \return an Access Category
5785
5786 \sa
5787
5788 --------------------------------------------------------------------------*/
5789sme_QosEdcaAcType sme_QosUpToAc(sme_QosWmmUpType up)
5790{
5791 sme_QosEdcaAcType ac = SME_QOS_EDCA_AC_MAX;
5792 if(up >= 0 && up < SME_QOS_WMM_UP_MAX)
5793 {
5794 ac = sme_QosUPtoACMap[up];
5795 }
5796 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
5797 "%s: %d: up = %d ac = %d returned",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005798 __func__, __LINE__, up, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07005799 return ac;
5800}
5801/*--------------------------------------------------------------------------
5802 \brief sme_QosStateTransition() - The state transition function per AC. We
5803 save the previous state also.
5804 \param sessionId - Session upon which the state machine is running
5805 \param ac - Enumeration of the various EDCA Access Categories.
5806 \param new_state - The state FSM is moving to.
5807
5808 \return None
5809
5810 \sa
5811
5812 --------------------------------------------------------------------------*/
5813static void sme_QosStateTransition(v_U8_t sessionId,
5814 sme_QosEdcaAcType ac,
5815 sme_QosStates new_state)
5816{
5817 sme_QosSessionInfo *pSession;
5818 sme_QosACInfo *pACInfo;
5819 pSession = &sme_QosCb.sessionInfo[sessionId];
5820 pACInfo = &pSession->ac_info[ac];
5821 pACInfo->prev_state = pACInfo->curr_state;
5822 pACInfo->curr_state = new_state;
5823 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
5824 "%s: %d: On session %d new state=%d, old state=%d, for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005825 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005826 sessionId, pACInfo->curr_state, pACInfo->prev_state, ac );
5827}
5828/*--------------------------------------------------------------------------
5829 \brief sme_QosFindInFlowList() - Utility function to find an flow entry from
5830 the flow_list.
5831 \param search_key - We can either use the flowID or the ac type to find the
5832 entry in the flow list.
5833 A bitmap in sme_QosSearchInfo tells which key to use. Starting from LSB,
5834 bit 0 - Flow ID
5835 bit 1 - AC type
5836 \return the pointer to the entry in the link list
5837
5838 \sa
5839
5840 --------------------------------------------------------------------------*/
5841tListElem *sme_QosFindInFlowList(sme_QosSearchInfo search_key)
5842{
5843 tListElem *pEntry= NULL, *pNextEntry = NULL;
5844 sme_QosFlowInfoEntry *flow_info = NULL;
5845 pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE );
5846 if(!pEntry)
5847 {
5848 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
5849 "%s: %d: Flow List empty, can't search",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005850 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005851 return NULL;
5852 }
5853 while( pEntry )
5854 {
5855 pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE );
5856 flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link );
5857 if((search_key.sessionId == flow_info->sessionId) ||
5858 (search_key.sessionId == SME_QOS_SEARCH_SESSION_ID_ANY))
5859 {
5860 if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_1)
5861 {
5862 if(search_key.key.QosFlowID == flow_info->QosFlowID)
5863 {
5864 //msg
5865 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
5866 "%s: %d: match found on flowID, ending search",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005867 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005868 break;
5869 }
5870 }
5871 else if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_2)
5872 {
5873 if(search_key.key.ac_type == flow_info->ac_type)
5874 {
5875 //msg
5876 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
5877 "%s: %d: match found on ac, ending search",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005878 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005879 break;
5880 }
5881 }
5882 else if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_3)
5883 {
5884 if(search_key.key.reason == flow_info->reason)
5885 {
5886 //msg
5887 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
5888 "%s: %d: match found on reason, ending search",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005889 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005890 break;
5891 }
5892 }
5893 else if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_4)
5894 {
5895 if((search_key.key.ac_type == flow_info->ac_type) &&
5896 (search_key.direction == flow_info->QoSInfo.ts_info.direction))
5897 {
5898 //msg
5899 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
5900 "%s: %d: match found on reason, ending search",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005901 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005902
5903 break;
5904 }
5905 }
5906 }
5907 pEntry = pNextEntry;
5908 }
5909 return pEntry;
5910}
5911/*--------------------------------------------------------------------------
5912 \brief sme_QosFindAllInFlowList() - Utility function to find an flow entry
5913 from the flow_list & act on it.
5914 \param search_key - We can either use the flowID or the ac type to find the
5915 entry in the flow list.
5916 A bitmap in sme_QosSearchInfo tells which key to use. Starting from LSB,
5917 bit 0 - Flow ID
5918 bit 1 - AC type
5919 \param fnp - function pointer specifying the action type for the entry found
5920 \return eHalStatus
5921
5922 \sa
5923
5924 --------------------------------------------------------------------------*/
5925eHalStatus sme_QosFindAllInFlowList(tpAniSirGlobal pMac,
5926 sme_QosSearchInfo search_key,
5927 sme_QosProcessSearchEntry fnp)
5928{
5929 tListElem *pEntry= NULL, *pNextEntry = NULL;
5930 sme_QosSessionInfo *pSession;
5931 sme_QosFlowInfoEntry *flow_info = NULL;
5932 eHalStatus status = eHAL_STATUS_FAILURE;
5933 pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE );
5934 if(!pEntry)
5935 {
5936 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
5937 "%s: %d: Flow List empty, can't search",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005938 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005939 return eHAL_STATUS_FAILURE;
5940 }
5941 while( pEntry )
5942 {
5943 pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE );
5944 flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link );
5945 pSession = &sme_QosCb.sessionInfo[flow_info->sessionId];
5946 if((search_key.sessionId == flow_info->sessionId) ||
5947 (search_key.sessionId == SME_QOS_SEARCH_SESSION_ID_ANY))
5948 {
5949 if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_1)
5950 {
5951 if(search_key.key.QosFlowID == flow_info->QosFlowID)
5952 {
5953 //msg
5954 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
5955 "%s: %d: match found on flowID, ending search",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005956 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005957 status = fnp(pMac, pEntry);
5958 if(eHAL_STATUS_FAILURE == status)
5959 {
5960 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
5961 "%s: %d: Failed to process entry",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005962 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005963 break;
5964 }
5965 }
5966 }
5967 else if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_2)
5968 {
5969 if(search_key.key.ac_type == flow_info->ac_type)
5970 {
5971 //msg
5972 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
5973 "%s: %d: match found on ac, ending search",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005974 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005975 flow_info->hoRenewal = pSession->ac_info[flow_info->ac_type].hoRenewal;
5976 status = fnp(pMac, pEntry);
5977 if(eHAL_STATUS_FAILURE == status)
5978 {
5979 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
5980 "%s: %d: Failed to process entry",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005981 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005982 break;
5983 }
5984 }
5985 }
5986 }
5987 pEntry = pNextEntry;
5988 }
5989 return status;
5990}
5991/*--------------------------------------------------------------------------
5992 \brief sme_QosIsACM() - Utility function to check if a particular AC
5993 mandates Admission Control.
5994 \param ac - Enumeration of the various EDCA Access Categories.
5995
5996 \return VOS_TRUE if the AC mandates Admission Control
5997
5998 \sa
5999
6000 --------------------------------------------------------------------------*/
6001v_BOOL_t sme_QosIsACM(tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc,
6002 sme_QosEdcaAcType ac, tDot11fBeaconIEs *pIes)
6003{
6004 v_BOOL_t ret_val = VOS_FALSE;
6005 tDot11fBeaconIEs *pIesLocal;
6006 if(!pSirBssDesc)
6007 {
6008 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6009 "%s: %d: pSirBssDesc is NULL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006010 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006011 return VOS_FALSE;
6012 }
6013
6014 if (NULL != pIes)
6015 {
6016 /* IEs were provided so use them locally */
6017 pIesLocal = pIes;
6018 }
6019 else
6020 {
6021 /* IEs were not provided so parse them ourselves */
6022 if (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesLocal)))
6023 {
6024 //err msg
6025 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6026 "%s: %d: csrGetParsedBssDescriptionIEs() failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006027 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006028 return VOS_FALSE;
6029 }
6030
6031 /* if success then pIesLocal was allocated */
6032 }
6033
6034 if(CSR_IS_QOS_BSS(pIesLocal))
6035 {
6036 switch(ac)
6037 {
6038 case SME_QOS_EDCA_AC_BE:
6039 if(pIesLocal->WMMParams.acbe_acm) ret_val = VOS_TRUE;
6040 break;
6041 case SME_QOS_EDCA_AC_BK:
6042 if(pIesLocal->WMMParams.acbk_acm) ret_val = VOS_TRUE;
6043 break;
6044 case SME_QOS_EDCA_AC_VI:
6045 if(pIesLocal->WMMParams.acvi_acm) ret_val = VOS_TRUE;
6046 break;
6047 case SME_QOS_EDCA_AC_VO:
6048 if(pIesLocal->WMMParams.acvo_acm) ret_val = VOS_TRUE;
6049 break;
6050 default:
6051 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6052 "%s: %d: unknown AC = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006053 __func__, __LINE__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07006054 //Assert
6055 VOS_ASSERT(0);
6056 break;
6057 }
6058 }//IS_QOS_BSS
6059 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
6060 "%s: %d: ACM = %d for AC = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006061 __func__, __LINE__, ret_val, ac );
Jeff Johnson295189b2012-06-20 16:38:30 -07006062 if (NULL == pIes)
6063 {
6064 /* IEs were allocated locally so free them */
6065 vos_mem_free(pIesLocal);
6066 }
6067 return ret_val;
6068}
6069/*--------------------------------------------------------------------------
6070 \brief sme_QosBufferExistingFlows() - Utility function to buffer the existing
6071 flows in flow_list, so that we can renew them after handoff is done.
6072
6073 \return eHalStatus
6074
6075 \sa
6076
6077 --------------------------------------------------------------------------*/
6078static eHalStatus sme_QosBufferExistingFlows(tpAniSirGlobal pMac,
6079 v_U8_t sessionId)
6080{
6081 tListElem *pEntry= NULL, *pNextEntry = NULL;
6082 sme_QosSessionInfo *pSession;
6083 sme_QosFlowInfoEntry *flow_info = NULL;
6084 sme_QosCmdInfo cmd;
6085 pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE );
6086 if(!pEntry)
6087 {
Kaushik, Sushant8489f472014-01-27 11:41:22 +05306088 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
Jeff Johnson295189b2012-06-20 16:38:30 -07006089 "%s: %d: Flow List empty, nothing to buffer",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006090 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006091 return eHAL_STATUS_FAILURE;
6092 }
6093 while( pEntry )
6094 {
6095 pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE );
6096 flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link );
6097 if (flow_info->sessionId == sessionId)
6098 {
6099 if((SME_QOS_REASON_REQ_SUCCESS == flow_info->reason )||
6100 (SME_QOS_REASON_SETUP == flow_info->reason ))
6101 {
6102 cmd.command = SME_QOS_SETUP_REQ;
6103 cmd.pMac = pMac;
6104 cmd.sessionId = sessionId;
6105 cmd.u.setupCmdInfo.HDDcontext = flow_info->HDDcontext;
6106 cmd.u.setupCmdInfo.QoSInfo = flow_info->QoSInfo;
6107 cmd.u.setupCmdInfo.QoSCallback = flow_info->QoSCallback;
6108 cmd.u.setupCmdInfo.UPType = SME_QOS_WMM_UP_MAX;//shouldn't be needed
6109 cmd.u.setupCmdInfo.QosFlowID = flow_info->QosFlowID;
6110 if(SME_QOS_REASON_SETUP == flow_info->reason )
6111 {
6112 cmd.u.setupCmdInfo.hoRenewal = VOS_FALSE;
6113 }
6114 else
6115 {
6116 cmd.u.setupCmdInfo.hoRenewal = VOS_TRUE;//TODO: might need this for modify
6117 }
6118 if(!HAL_STATUS_SUCCESS(sme_QosBufferCmd(&cmd, VOS_TRUE)))
6119 {
6120 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6121 "%s: %d: couldn't buffer the setup request for "
6122 "flow %d in handoff state",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006123 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006124 flow_info->QosFlowID);
6125 }
6126 else
6127 {
6128 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
6129 "%s: %d: buffered a setup request for "
6130 "flow %d in handoff state",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006131 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006132 flow_info->QosFlowID);
6133 }
6134 }
6135 else if(SME_QOS_REASON_RELEASE == flow_info->reason )
6136 {
6137 cmd.command = SME_QOS_RELEASE_REQ;
6138 cmd.pMac = pMac;
6139 cmd.sessionId = sessionId;
6140 cmd.u.releaseCmdInfo.QosFlowID = flow_info->QosFlowID;
6141 if(!HAL_STATUS_SUCCESS(sme_QosBufferCmd(&cmd, VOS_TRUE)))
6142 {
6143 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6144 "%s: %d: couldn't buffer the release request for "
6145 "flow %d in handoff state",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006146 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006147 flow_info->QosFlowID);
6148 }
6149 else
6150 {
6151 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
6152 "%s: %d: buffered a release request for "
6153 "flow %d in handoff state",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006154 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006155 flow_info->QosFlowID);
6156 }
6157 }
6158 else if(SME_QOS_REASON_MODIFY_PENDING == flow_info->reason)
6159 {
6160 cmd.command = SME_QOS_MODIFY_REQ;
6161 cmd.pMac = pMac;
6162 cmd.sessionId = sessionId;
6163 cmd.u.modifyCmdInfo.QosFlowID = flow_info->QosFlowID;
6164 cmd.u.modifyCmdInfo.QoSInfo = flow_info->QoSInfo;
6165 if(!HAL_STATUS_SUCCESS(sme_QosBufferCmd(&cmd, VOS_TRUE)))
6166 {
6167 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6168 "%s: %d: couldn't buffer the modify request for "
6169 "flow %d in handoff state",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006170 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006171 flow_info->QosFlowID);
6172 }
6173 else
6174 {
6175 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
6176 "%s: %d: buffered a modify request for "
6177 "flow %d in handoff state",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006178 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006179 flow_info->QosFlowID);
6180 }
6181 }
6182 //delete the entry from Flow List
6183 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
6184 "%s: %d: Deleting original entry at %p with flowID %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006185 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006186 flow_info, flow_info->QosFlowID);
6187 csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE );
6188 vos_mem_free(flow_info);
6189 }
6190 pEntry = pNextEntry;
6191 }
6192 pSession = &sme_QosCb.sessionInfo[sessionId];
6193 pSession->uapsdAlreadyRequested = VOS_FALSE;
6194 return eHAL_STATUS_SUCCESS;
6195}
6196/*--------------------------------------------------------------------------
6197 \brief sme_QosDeleteExistingFlows() - Utility function to Delete the existing
6198 flows in flow_list, if we lost connectivity.
6199
6200 \return eHalStatus
6201
6202 \sa
6203
6204 --------------------------------------------------------------------------*/
6205static eHalStatus sme_QosDeleteExistingFlows(tpAniSirGlobal pMac,
6206 v_U8_t sessionId)
6207{
6208 tListElem *pEntry= NULL, *pNextEntry = NULL;
6209 sme_QosFlowInfoEntry *flow_info = NULL;
6210 pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_TRUE );
6211 if(!pEntry)
6212 {
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07006213 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
Jeff Johnson295189b2012-06-20 16:38:30 -07006214 "%s: %d: Flow List empty, nothing to delete",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006215 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006216 return eHAL_STATUS_FAILURE;
6217 }
6218 while( pEntry )
6219 {
6220 pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_TRUE );
6221 flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link );
6222 if (flow_info->sessionId == sessionId)
6223 {
6224 if((SME_QOS_REASON_REQ_SUCCESS == flow_info->reason )||
6225 (SME_QOS_REASON_SETUP == flow_info->reason )||
6226 (SME_QOS_REASON_RELEASE == flow_info->reason )||
6227 (SME_QOS_REASON_MODIFY == flow_info->reason ))
6228 {
6229 flow_info->QoSCallback(pMac, flow_info->HDDcontext,
6230 NULL,
6231 SME_QOS_STATUS_RELEASE_QOS_LOST_IND,
6232 flow_info->QosFlowID);
6233 }
6234 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
6235 "%s: %d: Deleting entry at %p with flowID %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006236 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006237 flow_info, flow_info->QosFlowID);
6238 //delete the entry from Flow List
6239 csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE );
6240 vos_mem_free(flow_info);
6241 }
6242 pEntry = pNextEntry;
6243 }
6244 return eHAL_STATUS_SUCCESS;
6245}
6246/*--------------------------------------------------------------------------
6247 \brief sme_QosBufferCmd() - Utility function to buffer a request (setup/modify/
6248 release) from client while processing another one on the same AC.
6249 \param pcmd - a pointer to the cmd structure to be saved inside the buffered
6250 cmd link list
6251
6252 \return eHalStatus
6253
6254 \sa
6255
6256 --------------------------------------------------------------------------*/
6257eHalStatus sme_QosBufferCmd(sme_QosCmdInfo *pcmd, v_BOOL_t insert_head)
6258{
6259 sme_QosSessionInfo *pSession;
6260 sme_QosCmdInfoEntry * pentry = NULL;
6261 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
6262 "%s: %d: Invoked",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006263 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006264 pentry = (sme_QosCmdInfoEntry *) vos_mem_malloc(sizeof(sme_QosCmdInfoEntry));
6265 if (!pentry)
6266 {
6267 //err msg
6268 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6269 "%s: %d: Memory allocation failure",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006270 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006271 return eHAL_STATUS_FAILURE;
6272 }
6273 // copy the entire CmdInfo
6274 pentry->cmdInfo = *pcmd;
6275
6276 pSession = &sme_QosCb.sessionInfo[pcmd->sessionId];
6277 if(insert_head)
6278 {
6279 csrLLInsertHead(&pSession->bufferedCommandList, &pentry->link, VOS_TRUE);
6280 }
6281 else
6282 {
6283 csrLLInsertTail(&pSession->bufferedCommandList, &pentry->link, VOS_TRUE);
6284 }
6285 return eHAL_STATUS_SUCCESS;
6286}
6287/*--------------------------------------------------------------------------
6288 \brief sme_QosProcessBufferedCmd() - Utility function to process a buffered
6289 request (setup/modify/release) initially came from the client.
6290
6291 \return eHalStatus
6292
6293 \sa
6294
6295 --------------------------------------------------------------------------*/
6296static eHalStatus sme_QosProcessBufferedCmd(v_U8_t sessionId)
6297{
6298 sme_QosSessionInfo *pSession;
6299 sme_QosCmdInfoEntry *pcmd = NULL;
6300 tListElem *pEntry= NULL;
6301 sme_QosStatusType hdd_status = SME_QOS_STATUS_SETUP_FAILURE_RSP;
6302 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6303 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
6304 "%s: %d: Invoked on session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006305 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006306 sessionId);
6307 pSession = &sme_QosCb.sessionInfo[sessionId];
6308 if(!csrLLIsListEmpty( &pSession->bufferedCommandList, VOS_FALSE ))
6309 {
6310 pEntry = csrLLRemoveHead( &pSession->bufferedCommandList, VOS_TRUE );
6311 if(!pEntry)
6312 {
6313 //Err msg
6314 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6315 "%s: %d: no more buffered commands on session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006316 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006317 sessionId);
6318 pSession->readyForPowerSave = VOS_TRUE;
6319 return eHAL_STATUS_FAILURE;
6320 }
6321 pcmd = GET_BASE_ADDR( pEntry, sme_QosCmdInfoEntry, link );
6322 switch(pcmd->cmdInfo.command)
6323 {
6324 case SME_QOS_SETUP_REQ:
6325 hdd_status = sme_QosInternalSetupReq(pcmd->cmdInfo.pMac,
6326 pcmd->cmdInfo.sessionId,
6327 &pcmd->cmdInfo.u.setupCmdInfo.QoSInfo,
6328 pcmd->cmdInfo.u.setupCmdInfo.QoSCallback,
6329 pcmd->cmdInfo.u.setupCmdInfo.HDDcontext,
6330 pcmd->cmdInfo.u.setupCmdInfo.UPType,
6331 pcmd->cmdInfo.u.setupCmdInfo.QosFlowID,
6332 VOS_TRUE,
6333 pcmd->cmdInfo.u.setupCmdInfo.hoRenewal);
6334 if(SME_QOS_STATUS_SETUP_FAILURE_RSP == hdd_status)
6335 {
6336 //Err msg
6337 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6338 "%s: %d: sme_QosInternalSetupReq failed on session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006339 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006340 sessionId);
6341 halStatus = eHAL_STATUS_FAILURE;
6342 }
6343 break;
6344 case SME_QOS_RELEASE_REQ:
6345 hdd_status = sme_QosInternalReleaseReq(pcmd->cmdInfo.pMac,
6346 pcmd->cmdInfo.u.releaseCmdInfo.QosFlowID,
6347 VOS_TRUE);
6348 if(SME_QOS_STATUS_RELEASE_FAILURE_RSP == hdd_status)
6349 {
6350 //Err msg
6351 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6352 "%s: %d: sme_QosInternalReleaseReq failed on session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006353 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006354 sessionId);
6355 halStatus = eHAL_STATUS_FAILURE;
6356 }
6357 break;
6358 case SME_QOS_MODIFY_REQ:
6359 hdd_status = sme_QosInternalModifyReq(pcmd->cmdInfo.pMac,
6360 &pcmd->cmdInfo.u.modifyCmdInfo.QoSInfo,
6361 pcmd->cmdInfo.u.modifyCmdInfo.QosFlowID,
6362 VOS_TRUE);
6363 if(SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP == hdd_status)
6364 {
6365 //Err msg
6366 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6367 "%s: %d: sme_QosInternalModifyReq failed on session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006368 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006369 sessionId);
6370 halStatus = eHAL_STATUS_FAILURE;
6371 }
6372 break;
6373 case SME_QOS_RESEND_REQ:
6374 hdd_status = sme_QosReRequestAddTS(pcmd->cmdInfo.pMac,
6375 pcmd->cmdInfo.sessionId,
6376 &pcmd->cmdInfo.u.resendCmdInfo.QoSInfo,
6377 pcmd->cmdInfo.u.resendCmdInfo.ac,
6378 pcmd->cmdInfo.u.resendCmdInfo.tspecMask);
6379 if(SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP == hdd_status)
6380 {
6381 //Err msg
6382 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6383 "%s: %d: sme_QosReRequestAddTS failed on session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006384 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006385 sessionId);
6386 halStatus = eHAL_STATUS_FAILURE;
6387 }
6388 break;
6389 default:
6390 //err msg
6391 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6392 "%s: %d: On session %d unknown cmd = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006393 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006394 sessionId, pcmd->cmdInfo.command);
6395 //ASSERT
6396 VOS_ASSERT(0);
6397 break;
6398 }
6399 // buffered command has been processed, reclaim the memory
6400 vos_mem_free(pcmd);
6401 }
6402 else
6403 {
6404 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
6405 "%s: %d: cmd buffer empty",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006406 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006407 pSession->readyForPowerSave = VOS_TRUE;
6408 }
6409 return halStatus;
6410}
6411/*--------------------------------------------------------------------------
6412 \brief sme_QosDeleteBufferedRequests() - Utility function to Delete the buffered
6413 requests in the buffered_cmd_list, if we lost connectivity.
6414
6415 \return eHalStatus
6416
6417 \sa
6418
6419 --------------------------------------------------------------------------*/
6420static eHalStatus sme_QosDeleteBufferedRequests(tpAniSirGlobal pMac,
6421 v_U8_t sessionId)
6422{
6423 sme_QosSessionInfo *pSession;
6424 sme_QosCmdInfoEntry *pcmd = NULL;
6425 tListElem *pEntry= NULL, *pNextEntry = NULL;
6426 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
6427 "%s: %d: Invoked on session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006428 __func__, __LINE__, sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006429 pSession = &sme_QosCb.sessionInfo[sessionId];
6430 pEntry = csrLLPeekHead( &pSession->bufferedCommandList, VOS_TRUE );
6431 if(!pEntry)
6432 {
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07006433 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
Jeff Johnson295189b2012-06-20 16:38:30 -07006434 "%s: %d: Buffered List empty, nothing to delete on session %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006435 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006436 sessionId);
6437 return eHAL_STATUS_FAILURE;
6438 }
6439 while( pEntry )
6440 {
6441 pNextEntry = csrLLNext( &pSession->bufferedCommandList, pEntry, VOS_TRUE );
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07006442 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 "%s: %d: deleting entry from buffered List",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006444 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006445 //delete the entry from Flow List
6446 csrLLRemoveEntry(&pSession->bufferedCommandList, pEntry, VOS_TRUE );
6447 // reclaim the memory
6448 pcmd = GET_BASE_ADDR( pEntry, sme_QosCmdInfoEntry, link );
6449 vos_mem_free(pcmd);
6450 pEntry = pNextEntry;
6451 }
6452 return eHAL_STATUS_SUCCESS;
6453}
6454/*--------------------------------------------------------------------------
6455 \brief sme_QosSaveAssocInfo() - Utility function to save the assoc info in the
6456 CB like BSS descritor of the AP, the profile that HDD sent down with the
6457 connect request, while CSR notifies for assoc/reassoc success.
6458 \param pAssoc_info - pointer to the assoc structure to store the BSS descritor
6459 of the AP, the profile that HDD sent down with the
6460 connect request
6461
6462 \return eHalStatus
6463
6464 \sa
6465
6466 --------------------------------------------------------------------------*/
6467eHalStatus sme_QosSaveAssocInfo(sme_QosSessionInfo *pSession, sme_QosAssocInfo *pAssoc_info)
6468{
6469 tSirBssDescription *pBssDesc = NULL;
6470 v_U32_t bssLen = 0;
6471 if(NULL == pAssoc_info)
6472 {
6473 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6474 "%s: %d: pAssoc_info is NULL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006475 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006476 return eHAL_STATUS_FAILURE;
6477 }
6478 //clean up the assoc info if already set
6479 if(pSession->assocInfo.pBssDesc)
6480 {
6481 vos_mem_free(pSession->assocInfo.pBssDesc);
6482 pSession->assocInfo.pBssDesc = NULL;
6483 }
6484 bssLen = pAssoc_info->pBssDesc->length +
6485 sizeof(pAssoc_info->pBssDesc->length);
6486 //save the bss Descriptor
6487 pBssDesc = (tSirBssDescription *)vos_mem_malloc(bssLen);
6488 if (!pBssDesc)
6489 {
6490 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6491 "%s: %d: couldn't allocate memory for the bss Descriptor",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006492 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006493 return eHAL_STATUS_FAILURE;
6494 }
6495 vos_mem_copy(pBssDesc, pAssoc_info->pBssDesc, bssLen);
6496 pSession->assocInfo.pBssDesc = pBssDesc;
6497 //save the apsd info from assoc
6498 if(pAssoc_info->pProfile)
6499 {
6500 pSession->apsdMask |= pAssoc_info->pProfile->uapsd_mask;
6501 }
6502 // [TODO] Do we need to update the global APSD bitmap?
6503 return eHAL_STATUS_SUCCESS;
6504}
6505
6506/*--------------------------------------------------------------------------
6507 \brief sme_QosSetupFnp() - Utility function (pointer) to notify other entries
6508 in FLOW list on the same AC that qos params got modified
6509 \param pMac - Pointer to the global MAC parameter structure.
6510 \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure)
6511
6512 \return eHalStatus
6513
6514 \sa
6515
6516 --------------------------------------------------------------------------*/
6517eHalStatus sme_QosSetupFnp(tpAniSirGlobal pMac, tListElem *pEntry)
6518{
6519 sme_QosSessionInfo *pSession;
6520 sme_QosACInfo *pACInfo;
6521 sme_QosFlowInfoEntry *flow_info = NULL;
6522 sme_QosStatusType hdd_status = SME_QOS_STATUS_SETUP_MODIFIED_IND;
6523 sme_QosEdcaAcType ac;
6524 if(!pEntry)
6525 {
6526 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6527 "%s: %d: Entry is NULL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006528 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006529 //ASSERT
6530 VOS_ASSERT(0);
6531 return eHAL_STATUS_FAILURE;
6532 }
6533 flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link );
6534 ac = flow_info->ac_type;
6535 pSession = &sme_QosCb.sessionInfo[flow_info->sessionId];
6536 pACInfo = &pSession->ac_info[ac];
6537 if(SME_QOS_REASON_REQ_SUCCESS == flow_info->reason)
6538 {
6539 //notify HDD, only the other Flows running on the AC
6540 flow_info->QoSCallback(pMac, flow_info->HDDcontext,
6541 &pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1],
6542 hdd_status,
6543 flow_info->QosFlowID);
6544 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
6545 "%s: %d: Entry with flowID = %d getting notified",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006546 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006547 flow_info->QosFlowID);
6548 }
6549 return eHAL_STATUS_SUCCESS;
6550}
6551/*--------------------------------------------------------------------------
6552 \brief sme_QosModificationNotifyFnp() - Utility function (pointer) to notify
6553 other entries in FLOW list on the same AC that qos params got modified
6554 \param pMac - Pointer to the global MAC parameter structure.
6555 \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure)
6556
6557 \return eHalStatus
6558
6559 \sa
6560
6561 --------------------------------------------------------------------------*/
6562eHalStatus sme_QosModificationNotifyFnp(tpAniSirGlobal pMac, tListElem *pEntry)
6563{
6564 sme_QosSessionInfo *pSession;
6565 sme_QosACInfo *pACInfo;
6566 sme_QosFlowInfoEntry *flow_info = NULL;
6567 sme_QosStatusType hdd_status = SME_QOS_STATUS_SETUP_MODIFIED_IND;
6568 sme_QosEdcaAcType ac;
6569 if(!pEntry)
6570 {
6571 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6572 "%s: %d: Entry is NULL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006573 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006574 //ASSERT
6575 VOS_ASSERT(0);
6576 return eHAL_STATUS_FAILURE;
6577 }
6578 flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link );
6579 ac = flow_info->ac_type;
6580 pSession = &sme_QosCb.sessionInfo[flow_info->sessionId];
6581 pACInfo = &pSession->ac_info[ac];
6582 if(SME_QOS_REASON_REQ_SUCCESS == flow_info->reason)
6583 {
6584 //notify HDD, only the other Flows running on the AC
6585 flow_info->QoSCallback(pMac, flow_info->HDDcontext,
6586 &pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1],
6587 hdd_status,
6588 flow_info->QosFlowID);
6589 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
6590 "%s: %d: Entry with flowID = %d getting notified",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006591 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006592 flow_info->QosFlowID);
6593 }
6594 return eHAL_STATUS_SUCCESS;
6595}
6596/*--------------------------------------------------------------------------
6597 \brief sme_QosModifyFnp() - Utility function (pointer) to delete the origianl
6598 entry in FLOW list & add the modified one
6599 \param pMac - Pointer to the global MAC parameter structure.
6600 \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure)
6601
6602 \return eHalStatus
6603
6604 \sa
6605
6606 --------------------------------------------------------------------------*/
6607eHalStatus sme_QosModifyFnp(tpAniSirGlobal pMac, tListElem *pEntry)
6608{
6609 sme_QosFlowInfoEntry *flow_info = NULL;
6610 if(!pEntry)
6611 {
6612 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6613 "%s: %d: Entry is NULL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006614 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006615 VOS_ASSERT(0);
6616 return eHAL_STATUS_FAILURE;
6617 }
6618 flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link );
6619 switch(flow_info->reason)
6620 {
6621 case SME_QOS_REASON_MODIFY_PENDING:
6622 //set the proper reason code for the new (with modified params) entry
6623 flow_info->reason = SME_QOS_REASON_REQ_SUCCESS;
6624 break;
6625 case SME_QOS_REASON_MODIFY:
6626 //delete the original entry from Flow List
6627 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
6628 "%s: %d: Deleting original entry at %p with flowID %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006629 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006630 flow_info, flow_info->QosFlowID);
6631 csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE );
6632 // reclaim the memory
6633 vos_mem_free(flow_info);
6634 break;
6635 default:
6636 break;
6637 }
6638 return eHAL_STATUS_SUCCESS;
6639}
6640/*--------------------------------------------------------------------------
6641 \brief sme_QosDelTsIndFnp() - Utility function (pointer) to find all Flows on
6642 the perticular AC & delete them, also send HDD indication through the callback
6643 it registered per request
6644 \param pMac - Pointer to the global MAC parameter structure.
6645 \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure)
6646
6647 \return eHalStatus
6648
6649 \sa
6650
6651 --------------------------------------------------------------------------*/
6652eHalStatus sme_QosDelTsIndFnp(tpAniSirGlobal pMac, tListElem *pEntry)
6653{
6654 sme_QosSessionInfo *pSession;
6655 sme_QosACInfo *pACInfo;
6656 sme_QosFlowInfoEntry *flow_info = NULL;
6657 sme_QosEdcaAcType ac;
Madan Mohan Koyyalamudic0a75a42013-10-07 04:20:49 +05306658 eHalStatus lock_status = eHAL_STATUS_FAILURE;
6659 sme_QosStatusType status;
6660
Jeff Johnson295189b2012-06-20 16:38:30 -07006661 if(!pEntry)
6662 {
6663 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6664 "%s: %d: Entry is NULL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006665 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006666 //ASSERT
6667 VOS_ASSERT(0);
6668 return eHAL_STATUS_FAILURE;
6669 }
6670 //delete the entry from Flow List
6671 flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link );
6672 ac = flow_info->ac_type;
6673 pSession = &sme_QosCb.sessionInfo[flow_info->sessionId];
6674 pACInfo = &pSession->ac_info[ac];
Madan Mohan Koyyalamudic0a75a42013-10-07 04:20:49 +05306675 pACInfo->relTrig = SME_QOS_RELEASE_BY_AP;
6676
6677 lock_status = sme_AcquireGlobalLock( &pMac->sme );
6678 if ( !HAL_STATUS_SUCCESS( lock_status ) )
6679 {
6680 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6681 "%s: %d: Unable to obtain lock",
6682 __func__, __LINE__);
6683 return SME_QOS_STATUS_RELEASE_FAILURE_RSP;
6684 }
6685 //Call the internal function for QoS release, adding a layer of abstraction
6686 status = sme_QosInternalReleaseReq(pMac, flow_info->QosFlowID, VOS_FALSE);
6687 sme_ReleaseGlobalLock( &pMac->sme );
Jeff Johnson295189b2012-06-20 16:38:30 -07006688 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
Madan Mohan Koyyalamudic0a75a42013-10-07 04:20:49 +05306689 "%s: %d: QoS Release return status on Flow %d is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006690 __func__, __LINE__,
Madan Mohan Koyyalamudic0a75a42013-10-07 04:20:49 +05306691 flow_info->QosFlowID, status);
6692
Jeff Johnson295189b2012-06-20 16:38:30 -07006693 return eHAL_STATUS_SUCCESS;
6694}
6695/*--------------------------------------------------------------------------
6696 \brief sme_QosReassocSuccessEvFnp() - Utility function (pointer) to notify HDD
6697 the success for the requested flow & notify all the other flows running on the
6698 same AC that QoS params got modified
6699 \param pMac - Pointer to the global MAC parameter structure.
6700 \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure)
6701
6702 \return eHalStatus
6703
6704 \sa
6705
6706 --------------------------------------------------------------------------*/
6707eHalStatus sme_QosReassocSuccessEvFnp(tpAniSirGlobal pMac, tListElem *pEntry)
6708{
6709 sme_QosSessionInfo *pSession;
6710 sme_QosACInfo *pACInfo;
6711 sme_QosFlowInfoEntry *flow_info = NULL;
6712 v_BOOL_t delete_entry = VOS_FALSE;
6713 sme_QosStatusType hdd_status = SME_QOS_STATUS_SETUP_FAILURE_RSP;
6714 sme_QosEdcaAcType ac;
6715 eHalStatus pmc_status = eHAL_STATUS_FAILURE;
6716 if(!pEntry)
6717 {
6718 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6719 "%s: %d: Entry is NULL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006720 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006721 //ASSERT
6722 VOS_ASSERT(0);
6723 return eHAL_STATUS_FAILURE;
6724 }
6725 flow_info = GET_BASE_ADDR(pEntry, sme_QosFlowInfoEntry, link);
6726 ac = flow_info->ac_type;
6727 pSession = &sme_QosCb.sessionInfo[flow_info->sessionId];
6728 pACInfo = &pSession->ac_info[ac];
6729 switch(flow_info->reason)
6730 {
6731 case SME_QOS_REASON_SETUP:
6732 hdd_status = SME_QOS_STATUS_SETUP_SUCCESS_IND;
6733 delete_entry = VOS_FALSE;
6734 flow_info->reason = SME_QOS_REASON_REQ_SUCCESS;
6735 //check for the case where we had to do reassoc to reset the apsd bit
6736 //for the ac - release or modify scenario
6737 if(pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0].ts_info.psb)
6738 {
6739 // notify PMC as App is looking for APSD. If we already requested
6740 // then we don't need to do anything.
6741 if(!pSession->uapsdAlreadyRequested)
6742 {
6743 // this is the first flow to detect we need PMC in UAPSD mode
6744
6745 pmc_status = pmcStartUapsd(pMac,
6746 sme_QosPmcStartUapsdCallback,
6747 pSession);
6748 // if PMC doesn't return success right away means it is yet to put
6749 // the module in BMPS state & later to UAPSD state
6750
6751 if(eHAL_STATUS_FAILURE == pmc_status)
6752 {
6753 hdd_status = SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED;
6754 //we need to always notify this case
6755 flow_info->hoRenewal = VOS_FALSE;
6756 }
6757 else if(eHAL_STATUS_PMC_PENDING == pmc_status)
6758 {
6759 // let other flows know PMC has been notified
6760 pSession->uapsdAlreadyRequested = VOS_TRUE;
6761 }
6762 // for any other pmc status we declare success
6763 }
6764 }
6765 break;
6766 case SME_QOS_REASON_RELEASE:
6767 pACInfo->num_flows[SME_QOS_TSPEC_INDEX_0]--;
6768 // fall through
6769 case SME_QOS_REASON_MODIFY:
6770 delete_entry = VOS_TRUE;
6771 break;
6772 case SME_QOS_REASON_MODIFY_PENDING:
6773 hdd_status = SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND;
6774 delete_entry = VOS_FALSE;
6775 flow_info->reason = SME_QOS_REASON_REQ_SUCCESS;
6776 if(pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0].ts_info.psb)
6777 {
6778
6779 if(!pSession->uapsdAlreadyRequested)
6780 {
6781 // this is the first flow to detect we need PMC in UAPSD mode
6782 pmc_status = pmcStartUapsd(pMac,
6783 sme_QosPmcStartUapsdCallback,
6784 pSession);
6785
6786 // if PMC doesn't return success right away means it is yet to put
6787 // the module in BMPS state & later to UAPSD state
6788 if(eHAL_STATUS_FAILURE == pmc_status)
6789 {
6790 hdd_status = SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED;
6791 // we need to always notify this case
6792 flow_info->hoRenewal = VOS_FALSE;
6793 }
6794 else if(eHAL_STATUS_PMC_PENDING == pmc_status)
6795 {
6796 pSession->uapsdAlreadyRequested = VOS_TRUE;
6797 }
6798 // for any other pmc status we declare success
6799 }
6800 }
6801 break;
6802 case SME_QOS_REASON_REQ_SUCCESS:
6803 hdd_status = SME_QOS_STATUS_SETUP_MODIFIED_IND;
6804 // fall through
6805 default:
6806 delete_entry = VOS_FALSE;
6807 break;
6808 }
6809 if(!delete_entry)
6810 {
6811 if(!flow_info->hoRenewal)
6812 {
6813 flow_info->QoSCallback(pMac, flow_info->HDDcontext,
6814 &pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0],
6815 hdd_status,
6816 flow_info->QosFlowID);
6817 }
6818 else
6819 {
6820 flow_info->hoRenewal = VOS_FALSE;
6821 }
6822 }
6823 else
6824 {
6825 //delete the entry from Flow List
6826 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
6827 "%s: %d: Deleting entry at %p with flowID %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006828 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006829 flow_info, flow_info->QosFlowID);
6830 csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE );
6831 // reclaim the memory
6832 vos_mem_free(flow_info);
6833 }
6834
6835 return eHAL_STATUS_SUCCESS;
6836}
6837/*--------------------------------------------------------------------------
6838 \brief sme_QosAddTsFailureFnp() - Utility function (pointer),
6839 if the Addts request was for for an flow setup request, delete the entry from
6840 Flow list & notify HDD
6841 if the Addts request was for downgrading of QoS params because of an flow
6842 release requested on the AC, delete the entry from Flow list & notify HDD
6843 if the Addts request was for change of QoS params because of an flow
6844 modification requested on the AC, delete the new entry from Flow list & notify
6845 HDD
6846
6847 \param pMac - Pointer to the global MAC parameter structure.
6848 \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure)
6849
6850 \return eHalStatus
6851
6852 \sa
6853
6854 --------------------------------------------------------------------------*/
6855eHalStatus sme_QosAddTsFailureFnp(tpAniSirGlobal pMac, tListElem *pEntry)
6856{
6857 sme_QosSessionInfo *pSession;
6858 sme_QosACInfo *pACInfo;
6859 sme_QosFlowInfoEntry *flow_info = NULL;
6860 v_BOOL_t inform_hdd = VOS_FALSE;
6861 sme_QosStatusType hdd_status = SME_QOS_STATUS_SETUP_FAILURE_RSP;
6862 sme_QosEdcaAcType ac;
6863 if(!pEntry)
6864 {
6865 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6866 "%s: %d: Entry is NULL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006867 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006868 //ASSERT
6869 VOS_ASSERT(0);
6870 return eHAL_STATUS_FAILURE;
6871 }
6872 flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link );
6873 ac = flow_info->ac_type;
6874 pSession = &sme_QosCb.sessionInfo[flow_info->sessionId];
6875 pACInfo = &pSession->ac_info[ac];
6876 switch(flow_info->reason)
6877 {
6878 case SME_QOS_REASON_SETUP:
6879 hdd_status = SME_QOS_STATUS_SETUP_FAILURE_RSP;
6880 pACInfo->num_flows[pACInfo->tspec_pending - 1]--;
6881 inform_hdd = VOS_TRUE;
6882 break;
6883 case SME_QOS_REASON_RELEASE:
6884 hdd_status = SME_QOS_STATUS_RELEASE_FAILURE_RSP;
6885 pACInfo->num_flows[pACInfo->tspec_pending - 1]--;
6886 inform_hdd = VOS_TRUE;
6887 break;
6888 case SME_QOS_REASON_MODIFY_PENDING:
6889 hdd_status = SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
6890 inform_hdd = VOS_TRUE;
6891 break;
6892 case SME_QOS_REASON_MODIFY:
6893 flow_info->reason = SME_QOS_REASON_REQ_SUCCESS;
6894 case SME_QOS_REASON_REQ_SUCCESS:
6895 default:
6896 inform_hdd = VOS_FALSE;
6897 break;
6898 }
6899 if(inform_hdd)
6900 {
6901 //notify HDD, only the requested Flow, other Flows running on the AC stay
6902 // intact
6903 if(!flow_info->hoRenewal)
6904 {
6905 flow_info->QoSCallback(pMac, flow_info->HDDcontext,
6906 &pACInfo->curr_QoSInfo[pACInfo->tspec_pending - 1],
6907 hdd_status,
6908 flow_info->QosFlowID);
6909 }
6910 else
6911 {
6912 flow_info->QoSCallback(pMac, flow_info->HDDcontext,
6913 &pACInfo->curr_QoSInfo[pACInfo->tspec_pending - 1],
6914 SME_QOS_STATUS_RELEASE_QOS_LOST_IND,
6915 flow_info->QosFlowID);
6916 }
6917 //delete the entry from Flow List
6918 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
6919 "%s: %d: Deleting entry at %p with flowID %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006920 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006921 flow_info, flow_info->QosFlowID);
6922 csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE );
6923 // reclaim the memory
6924 vos_mem_free(flow_info);
6925 }
6926 return eHAL_STATUS_SUCCESS;
6927}
6928/*--------------------------------------------------------------------------
6929 \brief sme_QosAddTsSuccessFnp() - Utility function (pointer),
6930 if the Addts request was for for an flow setup request, notify HDD for success
6931 for the flow & notify all the other flows running on the same AC that QoS
6932 params got modified
6933 if the Addts request was for downgrading of QoS params because of an flow
6934 release requested on the AC, delete the entry from Flow list & notify HDD
6935 if the Addts request was for change of QoS params because of an flow
6936 modification requested on the AC, delete the old entry from Flow list & notify
6937 HDD for success for the flow & notify all the other flows running on the same
6938 AC that QoS params got modified
6939 \param pMac - Pointer to the global MAC parameter structure.
6940 \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure)
6941
6942 \return eHalStatus
6943
6944 \sa
6945
6946 --------------------------------------------------------------------------*/
6947eHalStatus sme_QosAddTsSuccessFnp(tpAniSirGlobal pMac, tListElem *pEntry)
6948{
6949 sme_QosSessionInfo *pSession;
6950 sme_QosACInfo *pACInfo;
6951 sme_QosFlowInfoEntry *flow_info = NULL;
6952 v_BOOL_t inform_hdd = VOS_FALSE;
6953 v_BOOL_t delete_entry = VOS_FALSE;
6954 sme_QosStatusType hdd_status = SME_QOS_STATUS_SETUP_FAILURE_RSP;
6955 sme_QosEdcaAcType ac;
6956 eHalStatus pmc_status = eHAL_STATUS_FAILURE;
6957 tCsrRoamModifyProfileFields modifyProfileFields;
6958
6959 if(!pEntry)
6960 {
6961 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6962 "%s: %d: Entry is NULL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006963 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006964 //ASSERT
6965 VOS_ASSERT(0);
6966 return eHAL_STATUS_FAILURE;
6967 }
6968 flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link );
6969 ac = flow_info->ac_type;
6970 pSession = &sme_QosCb.sessionInfo[flow_info->sessionId];
6971 pACInfo = &pSession->ac_info[ac];
6972 if(flow_info->tspec_mask != pACInfo->tspec_pending)
6973 {
6974 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
6975 "%s: %d: No need to notify the HDD, the ADDTS "
6976 "success is not for index = %d of the AC = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006977 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006978 flow_info->tspec_mask, ac);
6979 return eHAL_STATUS_SUCCESS;
6980 }
6981 switch(flow_info->reason)
6982 {
6983 case SME_QOS_REASON_SETUP:
6984 hdd_status = SME_QOS_STATUS_SETUP_SUCCESS_IND;
6985 flow_info->reason = SME_QOS_REASON_REQ_SUCCESS;
6986 delete_entry = VOS_FALSE;
6987 inform_hdd = VOS_TRUE;
6988 // check if App is looking for APSD
6989 if(pACInfo->requested_QoSInfo[pACInfo->tspec_pending - 1].ts_info.psb)
6990 {
6991 // notify PMC as App is looking for APSD. If we already requested
6992 // then we don't need to do anything
6993 if(!pSession->uapsdAlreadyRequested)
6994 {
6995 // this is the first flow to detect we need PMC in UAPSD mode
6996 pmc_status = pmcStartUapsd(pMac,
6997 sme_QosPmcStartUapsdCallback,
6998 pSession);
6999 // if PMC doesn't return success right away means it is yet to put
7000 // the module in BMPS state & later to UAPSD state
7001 if(eHAL_STATUS_FAILURE == pmc_status)
7002 {
7003 hdd_status = SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED;
7004 // we need to always notify this case
7005 flow_info->hoRenewal = VOS_FALSE;
7006 }
7007 else if(eHAL_STATUS_PMC_PENDING == pmc_status)
7008 {
7009 // let other flows know PMC has been notified
7010 pSession->uapsdAlreadyRequested = VOS_TRUE;
7011 }
7012 // for any other pmc status we declare success
7013 }
7014 }
7015 break;
7016 case SME_QOS_REASON_RELEASE:
7017 pACInfo->num_flows[pACInfo->tspec_pending - 1]--;
7018 hdd_status = SME_QOS_STATUS_RELEASE_SUCCESS_RSP;
7019 inform_hdd = VOS_TRUE;
7020 delete_entry = VOS_TRUE;
7021 break;
7022 case SME_QOS_REASON_MODIFY:
7023 delete_entry = VOS_TRUE;
7024 inform_hdd = VOS_FALSE;
7025 break;
7026 case SME_QOS_REASON_MODIFY_PENDING:
7027 hdd_status = SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND;
7028 delete_entry = VOS_FALSE;
7029 flow_info->reason = SME_QOS_REASON_REQ_SUCCESS;
7030 inform_hdd = VOS_TRUE;
7031 //notify PMC if App is looking for APSD
7032 if(pACInfo->requested_QoSInfo[pACInfo->tspec_pending - 1].ts_info.psb)
7033 {
7034 // notify PMC as App is looking for APSD. If we already requested
7035 // then we don't need to do anything.
7036 if(!pSession->uapsdAlreadyRequested)
7037 {
7038 // this is the first flow to detect we need PMC in UAPSD mode
7039 pmc_status = pmcStartUapsd(pMac,
7040 sme_QosPmcStartUapsdCallback,
7041 pSession);
7042 // if PMC doesn't return success right away means it is yet to put
7043 // the module in BMPS state & later to UAPSD state
7044 if(eHAL_STATUS_FAILURE == pmc_status)
7045 {
7046 hdd_status = SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED;
7047 // we need to always notify this case
7048 flow_info->hoRenewal = VOS_FALSE;
7049 }
7050 else if(eHAL_STATUS_PMC_PENDING == pmc_status)
7051 {
7052 // let other flows know PMC has been notified
7053 pSession->uapsdAlreadyRequested = VOS_TRUE;
7054 }
7055 // for any other pmc status we declare success
7056 }
7057 }
7058 else
7059 {
7060 if((pACInfo->num_flows[flow_info->tspec_mask - 1] == 1) &&
7061 (SME_QOS_TSPEC_MASK_BIT_1_2_SET != pACInfo->tspec_mask_status))
7062 {
7063 // this is the only TSPEC active on this AC
7064 // so indicate that we no longer require APSD
7065 pSession->apsdMask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac));
7066 //Also update modifyProfileFields.uapsd_mask in CSR for consistency
7067 csrGetModifyProfileFields(pMac, flow_info->sessionId, &modifyProfileFields);
7068 modifyProfileFields.uapsd_mask = pSession->apsdMask;
7069 csrSetModifyProfileFields(pMac, flow_info->sessionId, &modifyProfileFields);
7070 if(!pSession->apsdMask)
7071 {
7072 // this session no longer needs UAPSD
7073 // do any sessions still require UAPSD?
7074 if (!sme_QosIsUapsdActive())
7075 {
7076 // No sessions require UAPSD so turn it off
7077 // (really don't care when PMC stops it)
7078 (void)pmcStopUapsd(pMac);
7079 }
7080 }
7081 }
7082 }
7083 break;
7084 case SME_QOS_REASON_REQ_SUCCESS:
7085 hdd_status = SME_QOS_STATUS_SETUP_MODIFIED_IND;
7086 inform_hdd = VOS_TRUE;
7087 default:
7088 delete_entry = VOS_FALSE;
7089 break;
7090 }
7091 if(inform_hdd)
7092 {
7093 if(!flow_info->hoRenewal)
7094 {
7095
7096 flow_info->QoSCallback(pMac, flow_info->HDDcontext,
7097 &pACInfo->curr_QoSInfo[pACInfo->tspec_pending - 1],
7098 hdd_status,
7099 flow_info->QosFlowID);
7100 }
7101 else
7102 {
7103 flow_info->hoRenewal = VOS_FALSE;
7104 }
7105 }
7106 if(delete_entry)
7107 {
7108 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
7109 "%s: %d: Deleting entry at %p with flowID %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007110 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007111 flow_info, flow_info->QosFlowID);
7112 //delete the entry from Flow List
7113 csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE );
7114 // reclaim the memory
7115 vos_mem_free(flow_info);
7116 }
7117
7118 return eHAL_STATUS_SUCCESS;
7119}
7120/*--------------------------------------------------------------------------
7121 \brief sme_QosIsRspPending() - Utility function to check if we are waiting
7122 for an AddTS or reassoc response on some AC other than the given AC
7123
7124 \param sessionId - Session we are interted in
7125 \param ac - Enumeration of the various EDCA Access Categories.
7126
7127 \return boolean
7128 TRUE - Response is pending on an AC
7129
7130 \sa
7131
7132 --------------------------------------------------------------------------*/
7133static v_BOOL_t sme_QosIsRspPending(v_U8_t sessionId, sme_QosEdcaAcType ac)
7134{
7135 sme_QosSessionInfo *pSession;
7136 sme_QosACInfo *pACInfo;
7137 sme_QosEdcaAcType acIndex;
7138 v_BOOL_t status = VOS_FALSE;
7139 pSession = &sme_QosCb.sessionInfo[sessionId];
7140 for(acIndex = SME_QOS_EDCA_AC_BE; acIndex < SME_QOS_EDCA_AC_MAX; acIndex++)
7141 {
7142 if(acIndex == ac)
7143 {
7144 continue;
7145 }
7146 pACInfo = &pSession->ac_info[acIndex];
7147 if((pACInfo->tspec_pending) || (pACInfo->reassoc_pending))
7148 {
7149 status = VOS_TRUE;
7150 break;
7151 }
7152 }
7153 return status;
7154}
Mukul Sharma5960ac82014-01-09 20:31:35 +05307155
7156/*--------------------------------------------------------------------------
7157 \brief sme_QosUpdateHandOff() - Function which can be called to update
7158 Hand-off state of SME QoS Session
7159 \param sessionId - session id
7160 \param updateHandOff - value True/False to update the handoff flag
7161
7162 \sa
7163
7164-------------------------------------------------------------------------*/
7165void sme_QosUpdateHandOff(v_U8_t sessionId,
7166 v_BOOL_t updateHandOff)
7167{
7168 sme_QosSessionInfo *pSession;
7169 pSession = &sme_QosCb.sessionInfo[sessionId];
7170 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
7171 "%s: %d: handoffRequested %d updateHandOff %d",
7172 __func__, __LINE__,pSession->handoffRequested,
7173 updateHandOff);
7174
7175 pSession->handoffRequested = updateHandOff;
7176
7177}
7178
Jeff Johnson295189b2012-06-20 16:38:30 -07007179/*--------------------------------------------------------------------------
7180 \brief sme_QosIsUapsdActive() - Function which can be called to determine
7181 if any sessions require PMC to be in U-APSD mode.
7182 \return boolean
7183
7184 Returns true if at least one session required PMC to be in U-APSD mode
7185 Returns false if no sessions require PMC to be in U-APSD mode
7186
7187 \sa
7188
7189 --------------------------------------------------------------------------*/
7190static v_BOOL_t sme_QosIsUapsdActive(void)
7191{
7192 sme_QosSessionInfo *pSession;
7193 v_U8_t sessionId;
7194 for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; ++sessionId)
7195 {
7196 pSession = &sme_QosCb.sessionInfo[sessionId];
7197 if ((pSession->sessionActive) && (pSession->apsdMask))
7198 {
7199 return VOS_TRUE;
7200 }
7201 }
7202 // no active sessions have U-APSD active
7203 return VOS_FALSE;
7204}
7205/*--------------------------------------------------------------------------
7206 \brief sme_QosPmcFullPowerCallback() - Callback function registered with PMC
7207 to notify SME-QoS when it puts the chip into full power
7208
7209 \param callbackContext - The context passed to PMC during pmcRequestFullPower
7210 call.
7211 \param status - eHalStatus returned by PMC.
7212
7213 \return None
7214
7215 \sa
7216
7217 --------------------------------------------------------------------------*/
7218void sme_QosPmcFullPowerCallback(void *callbackContext, eHalStatus status)
7219{
7220 sme_QosSessionInfo *pSession = callbackContext;
7221 if(HAL_STATUS_SUCCESS(status))
7222 {
7223 (void)sme_QosProcessBufferedCmd(pSession->sessionId);
7224 }
7225 else
7226 {
7227 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7228 "%s: %d: PMC failed to put the chip in Full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007229 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007230 //ASSERT
7231 VOS_ASSERT(0);
7232 }
7233}
7234
7235/*--------------------------------------------------------------------------
7236 \brief sme_QosPmcStartUAPSDCallback() - Callback function registered with PMC
7237 to notify SME-QoS when it puts the chip into UAPSD mode
7238
7239 \param callbackContext - The context passed to PMC during pmcStartUapsd call.
7240 \param status - eHalStatus returned by PMC.
7241
7242 \return None
7243
7244 \sa
7245
7246 --------------------------------------------------------------------------*/
7247void sme_QosPmcStartUapsdCallback(void *callbackContext, eHalStatus status)
7248{
7249 sme_QosSessionInfo *pSession = callbackContext;
7250 // NOTE WELL
7251 //
7252 // In the orignal QoS design the TL module was responsible for
7253 // the generation of trigger frames. When that design was in
7254 // use, we had to queue up any flows which were waiting for PMC
7255 // since we didn't want to notify HDD until PMC had changed to
7256 // UAPSD state. Otherwise HDD would provide TL with the trigger
7257 // frame parameters, and TL would start trigger frame generation
7258 // before PMC was ready. The flows were queued in various places
7259 // throughout this module, and they were dequeued here following
7260 // a successful transition to the UAPSD state by PMC.
7261 //
7262 // In the current QoS design the Firmware is responsible for the
7263 // generation of trigger frames, but the parameters are still
7264 // provided by TL via HDD. The Firmware will be notified of the
7265 // change to UAPSD state directly by PMC, at which time it will be
7266 // responsible for the generation of trigger frames. Therefore
7267 // where we used to queue up flows waiting for PMC to transition
7268 // to the UAPSD state, we now always transition directly to the
7269 // "success" state so that HDD will immediately provide the trigger
7270 // frame parameters to TL, who will in turn plumb them down to the
7271 // Firmware. That way the Firmware will have the trigger frame
7272 // parameters when it needs them
7273 // just note that there is no longer an outstanding request
7274 pSession->uapsdAlreadyRequested = VOS_FALSE;
7275}
7276/*--------------------------------------------------------------------------
7277 \brief sme_QosPmcCheckRoutine() - Function registered with PMC to check with
7278 SME-QoS whenever the device is about to enter one of the power
7279 save modes. PMC runs a poll with all the registered modules if device can
7280 enter powersave mode or remain in full power
7281
7282 \param callbackContext - The context passed to PMC during registration through
7283 pmcRegisterPowerSaveCheck.
7284 \return boolean
7285
7286 SME-QOS returns PMC true or false respectively if it wants to vote for
7287 entering power save or not
7288
7289 \sa
7290
7291 --------------------------------------------------------------------------*/
7292v_BOOL_t sme_QosPmcCheckRoutine(void *callbackContext)
7293{
7294 sme_QosSessionInfo *pSession;
7295 v_U8_t sessionId;
7296 for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; ++sessionId)
7297 {
7298 pSession = &sme_QosCb.sessionInfo[sessionId];
7299 if ((pSession->sessionActive) &&
7300 (!pSession->readyForPowerSave))
7301 {
7302 return VOS_FALSE;
7303 }
7304 }
7305 // all active sessions have voted for powersave
7306 return VOS_TRUE;
7307}
7308/*--------------------------------------------------------------------------
7309 \brief sme_QosPmcDeviceStateUpdateInd() - Callback function registered with
7310 PMC to notify SME-QoS when it changes the power state
7311
7312 \param callbackContext - The context passed to PMC during registration
7313 through pmcRegisterDeviceStateUpdateInd.
7314 \param pmcState - Current power state that PMC moved into.
7315
7316 \return None
7317
7318 \sa
7319
7320 --------------------------------------------------------------------------*/
7321void sme_QosPmcDeviceStateUpdateInd(void *callbackContext, tPmcState pmcState)
7322{
7323 eHalStatus status = eHAL_STATUS_FAILURE;
7324 tpAniSirGlobal pMac = PMAC_STRUCT( callbackContext );
7325 //check all the entries in Flow list for non-zero service interval, which will
7326 //tell us if we need to notify HDD when PMC is out of UAPSD mode or going
7327 // back to UAPSD mode
7328 switch(pmcState)
7329 {
7330 case FULL_POWER:
7331 status = sme_QosProcessOutOfUapsdMode(pMac);
7332 break;
7333 case UAPSD:
7334 status = sme_QosProcessIntoUapsdMode(pMac);
7335 break;
7336 default:
7337 status = eHAL_STATUS_SUCCESS;
7338 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7339 "%s: %d: nothing to process in PMC state %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007340 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007341 pmcState);
7342 }
7343 if(!HAL_STATUS_SUCCESS(status))
7344 {
Mohit Khanna23863762012-09-11 17:40:09 -07007345 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
Jeff Johnson295189b2012-06-20 16:38:30 -07007346 "%s: %d: ignoring Device(PMC) state change to %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007347 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007348 pmcState);
7349 }
7350
7351}
7352/*--------------------------------------------------------------------------
7353 \brief sme_QosProcessOutOfUapsdMode() - Function to notify HDD when PMC
7354 notifies SME-QoS that it moved out of UAPSD mode to FULL power
7355
7356 \param pMac - Pointer to the global MAC parameter structure.
7357 \return eHalStatus
7358
7359 \sa
7360
7361 --------------------------------------------------------------------------*/
7362eHalStatus sme_QosProcessOutOfUapsdMode(tpAniSirGlobal pMac)
7363{
7364 sme_QosSessionInfo *pSession;
7365 tListElem *pEntry= NULL, *pNextEntry = NULL;
7366 sme_QosFlowInfoEntry *flow_info = NULL;
7367
7368 pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE );
7369 if(!pEntry)
7370 {
Mohit Khanna23863762012-09-11 17:40:09 -07007371 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
Jeff Johnson295189b2012-06-20 16:38:30 -07007372 "%s: %d: Flow List empty, can't search",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007373 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007374 return eHAL_STATUS_FAILURE;
7375 }
7376 while( pEntry )
7377 {
7378 pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE );
7379 flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link );
7380 pSession = &sme_QosCb.sessionInfo[flow_info->sessionId];
7381 //only notify the flows which already successfully setup UAPSD
7382 if((flow_info->QoSInfo.max_service_interval ||
7383 flow_info->QoSInfo.min_service_interval) &&
7384 (SME_QOS_REASON_REQ_SUCCESS == flow_info->reason))
7385 {
7386 flow_info->QoSCallback(pMac, flow_info->HDDcontext,
7387 &pSession->ac_info[flow_info->ac_type].curr_QoSInfo[flow_info->tspec_mask - 1],
7388 SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND,
7389 flow_info->QosFlowID);
7390 }
7391 pEntry = pNextEntry;
7392 }
7393 return eHAL_STATUS_SUCCESS;
7394}
7395/*--------------------------------------------------------------------------
7396 \brief sme_QosProcessIntoUapsdMode() - Function to notify HDD when PMC
7397 notifies SME-QoS that it is moving into UAPSD mode
7398
7399 \param pMac - Pointer to the global MAC parameter structure.
7400 \return eHalStatus
7401
7402 \sa
7403
7404 --------------------------------------------------------------------------*/
7405eHalStatus sme_QosProcessIntoUapsdMode(tpAniSirGlobal pMac)
7406{
7407 sme_QosSessionInfo *pSession;
7408 tListElem *pEntry= NULL, *pNextEntry = NULL;
7409 sme_QosFlowInfoEntry *flow_info = NULL;
7410
7411 pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE );
7412 if(!pEntry)
7413 {
7414 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7415 "%s: %d: Flow List empty, can't search",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007416 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007417 return eHAL_STATUS_FAILURE;
7418 }
7419 while( pEntry )
7420 {
7421 pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE );
7422 flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link );
7423 pSession = &sme_QosCb.sessionInfo[flow_info->sessionId];
7424 //only notify the flows which already successfully setup UAPSD
Madan Mohan Koyyalamudi4f2a39f2013-08-13 23:04:47 +05307425 if( (flow_info->QoSInfo.ts_info.psb) &&
7426 (SME_QOS_REASON_REQ_SUCCESS == flow_info->reason) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007427 {
7428 flow_info->QoSCallback(pMac, flow_info->HDDcontext,
7429 &pSession->ac_info[flow_info->ac_type].curr_QoSInfo[flow_info->tspec_mask - 1],
7430 SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND,
7431 flow_info->QosFlowID);
7432 }
7433 pEntry = pNextEntry;
7434 }
7435 return eHAL_STATUS_SUCCESS;
7436}
7437
7438void sme_QosCleanupCtrlBlkForHandoff(tpAniSirGlobal pMac, v_U8_t sessionId)
7439{
7440 sme_QosSessionInfo *pSession;
7441 sme_QosACInfo *pACInfo;
7442 sme_QosEdcaAcType ac;
7443 pSession = &sme_QosCb.sessionInfo[sessionId];
7444 for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++)
7445 {
7446 pACInfo = &pSession->ac_info[ac];
7447 vos_mem_zero(pACInfo->curr_QoSInfo,
7448 sizeof(sme_QosWmmTspecInfo) * SME_QOS_TSPEC_INDEX_MAX);
7449 vos_mem_zero(pACInfo->requested_QoSInfo,
7450 sizeof(sme_QosWmmTspecInfo) * SME_QOS_TSPEC_INDEX_MAX);
7451 pACInfo->num_flows[0] = 0;
7452 pACInfo->num_flows[1] = 0;
7453 pACInfo->reassoc_pending = VOS_FALSE;
7454 pACInfo->tspec_mask_status = 0;
7455 pACInfo->tspec_pending = VOS_FALSE;
7456 pACInfo->hoRenewal = VOS_FALSE;
7457 pACInfo->prev_state = SME_QOS_LINK_UP;
7458 }
7459}
7460
7461/*--------------------------------------------------------------------------
7462 \brief sme_QosIsTSInfoAckPolicyValid() - The SME QoS API exposed to HDD to
7463 check if TS info ack policy field can be set to "HT-immediate block acknowledgement"
7464
7465 \param pMac - The handle returned by macOpen.
7466 \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC
7467 related info, provided by HDD
7468 \param sessionId - sessionId returned by sme_OpenSession.
7469
7470 \return VOS_TRUE - Current Association is HT association and so TS info ack policy
7471 can be set to "HT-immediate block acknowledgement"
7472
7473 \sa
7474
7475 --------------------------------------------------------------------------*/
7476v_BOOL_t sme_QosIsTSInfoAckPolicyValid(tpAniSirGlobal pMac,
7477 sme_QosWmmTspecInfo * pQoSInfo,
7478 v_U8_t sessionId)
7479{
7480 tDot11fBeaconIEs *pIes = NULL;
7481 sme_QosSessionInfo *pSession;
7482 eHalStatus hstatus;
7483 if( !CSR_IS_SESSION_VALID( pMac, sessionId ) )
7484 {
7485 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7486 "%s: %d: Session Id %d is invalid",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007487 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007488 sessionId);
7489 return VOS_FALSE;
7490 }
7491
7492 pSession = &sme_QosCb.sessionInfo[sessionId];
7493
7494 if( !pSession->sessionActive )
7495 {
7496 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7497 "%s: %d: Session %d is inactive",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007498 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007499 sessionId);
7500 return VOS_FALSE;
7501 }
7502
7503 if(!pSession->assocInfo.pBssDesc)
7504 {
7505 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7506 "%s: %d: Session %d has an Invalid BSS Descriptor",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007507 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007508 sessionId);
7509 return VOS_FALSE;
7510 }
7511
7512 hstatus = csrGetParsedBssDescriptionIEs(pMac,
7513 pSession->assocInfo.pBssDesc,
7514 &pIes);
7515 if(!HAL_STATUS_SUCCESS(hstatus))
7516 {
7517 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7518 "%s: %d: On session %d unable to parse BSS IEs",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007519 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007520 sessionId);
7521 return VOS_FALSE;
7522 }
7523
7524 /* success means pIes was allocated */
7525
7526 if(!pIes->HTCaps.present &&
7527 pQoSInfo->ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK)
7528 {
7529 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7530 "%s: %d: On session %d HT Caps aren't present but application set ack policy to HT ",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007531 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007532 sessionId);
7533
7534 vos_mem_free(pIes);
7535 return VOS_FALSE;
7536 }
7537
7538 vos_mem_free(pIes);
7539 return VOS_TRUE;
7540}
7541
7542v_BOOL_t sme_QosValidateRequestedParams(tpAniSirGlobal pMac,
7543 sme_QosWmmTspecInfo * pQoSInfo,
7544 v_U8_t sessionId)
7545{
7546 v_BOOL_t rc = VOS_FALSE;
7547
7548 do
7549 {
7550 if(SME_QOS_WMM_TS_DIR_RESV == pQoSInfo->ts_info.direction) break;
7551 if(!sme_QosIsTSInfoAckPolicyValid(pMac, pQoSInfo, sessionId)) break;
7552
7553 rc = VOS_TRUE;
7554 }while(0);
7555 return rc;
7556}
7557
7558static eHalStatus qosIssueCommand( tpAniSirGlobal pMac, v_U8_t sessionId,
7559 eSmeCommandType cmdType, sme_QosWmmTspecInfo * pQoSInfo,
7560 sme_QosEdcaAcType ac, v_U8_t tspec_mask )
7561{
7562 eHalStatus status = eHAL_STATUS_RESOURCES;
7563 tSmeCmd *pCommand = NULL;
7564 do
7565 {
7566 pCommand = smeGetCommandBuffer( pMac );
7567 if ( !pCommand )
7568 {
7569 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7570 "%s: %d: fail to get command buffer for command %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007571 __func__, __LINE__, cmdType);
Jeff Johnson295189b2012-06-20 16:38:30 -07007572 break;
7573 }
7574 pCommand->command = cmdType;
7575 pCommand->sessionId = sessionId;
7576 switch ( cmdType )
7577 {
7578 case eSmeCommandAddTs:
7579 if( pQoSInfo )
7580 {
7581 status = eHAL_STATUS_SUCCESS;
7582 pCommand->u.qosCmd.tspecInfo = *pQoSInfo;
7583 pCommand->u.qosCmd.ac = ac;
7584 }
7585 else
7586 {
7587 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7588 "%s: %d: NULL pointer passed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007589 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007590 status = eHAL_STATUS_INVALID_PARAMETER;
7591 }
7592 break;
7593 case eSmeCommandDelTs:
7594 status = eHAL_STATUS_SUCCESS;
7595 pCommand->u.qosCmd.ac = ac;
7596 pCommand->u.qosCmd.tspec_mask = tspec_mask;
7597 break;
7598 default:
7599 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7600 "%s: %d: invalid command type %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007601 __func__, __LINE__, cmdType );
Jeff Johnson295189b2012-06-20 16:38:30 -07007602 status = eHAL_STATUS_INVALID_PARAMETER;
7603 break;
7604 }
7605 } while( 0 );
7606 if( HAL_STATUS_SUCCESS( status ) && pCommand )
7607 {
7608 smePushCommand( pMac, pCommand, eANI_BOOLEAN_FALSE );
7609 }
7610 else if( pCommand )
7611 {
7612 qosReleaseCommand( pMac, pCommand );
7613 }
7614 return( status );
7615}
7616tANI_BOOLEAN qosProcessCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand )
7617{
7618 eHalStatus status = eHAL_STATUS_SUCCESS;
7619 tANI_BOOLEAN fRemoveCmd = eANI_BOOLEAN_TRUE;
7620 do
7621 {
7622 switch ( pCommand->command )
7623 {
7624 case eSmeCommandAddTs:
7625 status = sme_QosAddTsReq( pMac, (v_U8_t)pCommand->sessionId, &pCommand->u.qosCmd.tspecInfo, pCommand->u.qosCmd.ac);
7626 if( HAL_STATUS_SUCCESS( status ) )
7627 {
7628 fRemoveCmd = eANI_BOOLEAN_FALSE;
7629 status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP;
7630 }
7631 break;
7632 case eSmeCommandDelTs:
7633 status = sme_QosDelTsReq( pMac, (v_U8_t)pCommand->sessionId, pCommand->u.qosCmd.ac, pCommand->u.qosCmd.tspec_mask );
7634 if( HAL_STATUS_SUCCESS( status ) )
7635 {
7636 fRemoveCmd = eANI_BOOLEAN_FALSE;
7637 }
7638 break;
7639 default:
7640 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7641 "%s: %d: invalid command type %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007642 __func__, __LINE__, pCommand->command );
Jeff Johnson295189b2012-06-20 16:38:30 -07007643 break;
7644 }//switch
7645 } while(0);
7646 return( fRemoveCmd );
7647}
7648
7649/*
7650 sme_QosTriggerUapsdChange
7651 Invoked by BTC when UAPSD bypass is enabled or disabled
7652 We, in turn, must disable or enable UAPSD on all flows as appropriate
7653 That may require us to re-add TSPECs or to reassociate
7654*/
7655sme_QosStatusType sme_QosTriggerUapsdChange( tpAniSirGlobal pMac )
7656{
7657 sme_QosSessionInfo *pSession;
7658 sme_QosACInfo *pACInfo;
7659 v_U8_t ac, tspec1 = 0, tspec2 = 0;
7660 v_U8_t uapsd_mask;
7661 tDot11fBeaconIEs *pIesLocal;
7662 v_U8_t acm_mask;
7663 v_BOOL_t fIsUapsdNeeded;
7664 v_U8_t sessionId;
7665 v_BOOL_t addtsWhenACMNotSet = CSR_IS_ADDTS_WHEN_ACMOFF_SUPPORTED(pMac);
7666 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
7667 "%s: %d: Invoked",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007668 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007669 for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; ++sessionId)
7670 {
7671 pSession = &sme_QosCb.sessionInfo[sessionId];
7672 if( !pSession->sessionActive )
7673 {
7674 continue;
7675 }
7676 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
7677 "%s: %d: Session %d is active",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007678 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007679 sessionId);
7680 if( HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSession->assocInfo.pBssDesc, &pIesLocal)) )
7681 {
7682 // get the ACM mask
7683 acm_mask = sme_QosGetACMMask(pMac, pSession->assocInfo.pBssDesc, pIesLocal);
7684 vos_mem_free(pIesLocal);
7685 // get the uapsd mask for this session
7686 uapsd_mask = pSession->apsdMask;
7687 // unmask the bits with ACM on to avoid reassoc on them
7688 uapsd_mask &= ~acm_mask;
7689 // iterate through the ACs to determine if we need to re-add any TSPECs
7690 for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++)
7691 {
7692 pACInfo = &pSession->ac_info[ac];
7693 // Does this AC have QoS active?
7694 if( SME_QOS_QOS_ON == pACInfo->curr_state )
7695 {
7696 // Yes, QoS is active on this AC
7697 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
7698 "%s: %d: On session %d AC %d has QoS active",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007699 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007700 sessionId, ac);
7701 // Does this AC require ACM?
7702 if(( acm_mask & (1 << (SME_QOS_EDCA_AC_VO - ac)) ) || addtsWhenACMNotSet )
7703 {
7704 // Yes, so we need to re-add any TSPECS
7705 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
7706 "%s: %d: On session %d AC %d has ACM enabled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007707 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007708 sessionId, ac);
7709 // Are any TSPECs active?
7710 if( pACInfo->tspec_mask_status )
7711 {
7712 // Yes, at least 1 TSPEC is active. Are they both active?
7713 if( SME_QOS_TSPEC_MASK_BIT_1_2_SET == pACInfo->tspec_mask_status )
7714 {
7715 //both TSPECS are active
7716 tspec1 = SME_QOS_TSPEC_MASK_BIT_1_SET;
7717 tspec2 = SME_QOS_TSPEC_MASK_BIT_2_SET;
7718 }
7719 else
7720 {
7721 // only one TSPEC is active, get its mask
7722 tspec1 = SME_QOS_TSPEC_MASK_BIT_1_2_SET & pACInfo->tspec_mask_status;
7723 }
7724 // Does TSPEC 1 really require UAPSD?
Madan Mohan Koyyalamudi4f2a39f2013-08-13 23:04:47 +05307725 fIsUapsdNeeded = (v_BOOL_t)(pACInfo->curr_QoSInfo[tspec1 - 1].ts_info.psb);
Jeff Johnson295189b2012-06-20 16:38:30 -07007726 //double check whether we need to do anything
7727 if( fIsUapsdNeeded )
7728 {
7729 pACInfo->requested_QoSInfo[tspec1 - 1] =
7730 pACInfo->curr_QoSInfo[tspec1 - 1];
7731 sme_QosReRequestAddTS( pMac, sessionId,
7732 &pACInfo->requested_QoSInfo[tspec1 - 1],
7733 ac,
7734 tspec1 );
7735 }
7736 // Is TSPEC 2 active?
7737 if( tspec2 )
7738 {
7739 // Does TSPEC 2 really require UAPSD?
Madan Mohan Koyyalamudi4f2a39f2013-08-13 23:04:47 +05307740 fIsUapsdNeeded = (v_BOOL_t)(pACInfo->curr_QoSInfo[tspec2 - 1].ts_info.psb);
Jeff Johnson295189b2012-06-20 16:38:30 -07007741 if( fIsUapsdNeeded )
7742 {
7743 //No need to inform HDD
7744 //pACInfo->hoRenewal = VOS_TRUE;
7745 pACInfo->requested_QoSInfo[tspec2 - 1] =
7746 pACInfo->curr_QoSInfo[tspec2 - 1];
7747 sme_QosReRequestAddTS( pMac, sessionId,
7748 &pACInfo->requested_QoSInfo[tspec2 - 1],
7749 ac,
7750 tspec2);
7751 }
7752 }
7753 }
7754 else
7755 {
7756 // QoS is set, ACM is on, but no TSPECs -- inconsistent state
7757 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7758 "%s: %d: On session %d AC %d has QoS enabled and ACM is set, but no TSPEC",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007759 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007760 sessionId, ac);
7761 VOS_ASSERT(0);
7762 }
7763 }
7764 else
7765 {
7766 //Since ACM bit is not set, there should be only one QoS information for both directions.
Madan Mohan Koyyalamudi4f2a39f2013-08-13 23:04:47 +05307767 fIsUapsdNeeded = (v_BOOL_t)(pACInfo->curr_QoSInfo[0].ts_info.psb);
Jeff Johnson295189b2012-06-20 16:38:30 -07007768 if(fIsUapsdNeeded)
7769 {
7770 // we need UAPSD on this AC (and we may not currently have it)
7771 uapsd_mask |= 1 << (SME_QOS_EDCA_AC_VO - ac);
7772 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
7773 "%s: %d: On session %d AC %d has ACM disabled, uapsd mask now 0x%X",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007774 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007775 sessionId, ac, uapsd_mask);
7776 }
7777 }
7778 }
7779 }
7780 // do we need to reassociate?
7781 if(uapsd_mask)
7782 {
7783 tCsrRoamModifyProfileFields modifyProfileFields;
7784 //we need to do a reassoc on these AC
7785 csrGetModifyProfileFields(pMac, sessionId, &modifyProfileFields);
7786 if( btcIsReadyForUapsd(pMac) )
7787 {
7788 modifyProfileFields.uapsd_mask = uapsd_mask;
7789 }
7790 else
7791 {
7792 modifyProfileFields.uapsd_mask = 0;
7793 }
7794 //Do we need to inform HDD?
7795 if(!HAL_STATUS_SUCCESS(sme_QosRequestReassoc(pMac, sessionId, &modifyProfileFields, VOS_TRUE)))
7796 {
7797 //err msg
7798 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7799 "%s: %d: On Session %d Reassoc failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007800 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007801 sessionId);
7802 }
7803 }
7804 }
7805 else
7806 {
7807 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7808 "%s: %d: On Session %d failed to parse IEs",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007809 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007810 sessionId);
7811 }
7812 }
7813 // return status is ignored by BTC
7814 return SME_QOS_STATUS_SETUP_SUCCESS_IND;
7815}
7816
7817/*
7818 sme_QosReRequestAddTS to re-send AddTS for the combined QoS request
7819*/
7820static sme_QosStatusType sme_QosReRequestAddTS(tpAniSirGlobal pMac,
7821 v_U8_t sessionId,
7822 sme_QosWmmTspecInfo * pQoSInfo,
7823 sme_QosEdcaAcType ac,
7824 v_U8_t tspecMask)
7825{
7826 sme_QosSessionInfo *pSession;
7827 sme_QosACInfo *pACInfo;
7828 sme_QosStatusType status = SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
7829 sme_QosCmdInfo cmd;
7830 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
7831 "%s: %d: Invoked on session %d for AC %d TSPEC %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007832 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007833 sessionId, ac, tspecMask);
7834 pSession = &sme_QosCb.sessionInfo[sessionId];
7835 pACInfo = &pSession->ac_info[ac];
7836 // need to vote off powersave for the duration of this request
7837 pSession->readyForPowerSave = VOS_FALSE;
7838 //call PMC's request for power function
7839 // AND
7840 //another check is added considering the flowing scenario
7841 //Addts reqest is pending on one AC, while APSD requested on another which
7842 //needs a reassoc. Will buffer a request if Addts is pending on any AC,
7843 //which will safegaurd the above scenario, & also won't confuse PE with back
7844 //to back Addts or Addts followed by Reassoc
7845 if(sme_QosIsRspPending(sessionId, ac) ||
7846 ( eHAL_STATUS_PMC_PENDING == pmcRequestFullPower(pMac, sme_QosPmcFullPowerCallback, pSession, eSME_REASON_OTHER)))
7847 {
7848 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7849 "%s: %d: On session %d buffering the AddTS request "
7850 "for AC %d in state %d as Addts is pending "
7851 "on other AC or waiting for full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007852 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007853 sessionId, ac, pACInfo->curr_state);
7854 //buffer cmd
7855 cmd.command = SME_QOS_RESEND_REQ;
7856 cmd.pMac = pMac;
7857 cmd.sessionId = sessionId;
7858 cmd.u.resendCmdInfo.ac = ac;
7859 cmd.u.resendCmdInfo.tspecMask = tspecMask;
7860 cmd.u.resendCmdInfo.QoSInfo = *pQoSInfo;
7861 if(!HAL_STATUS_SUCCESS(sme_QosBufferCmd(&cmd, VOS_FALSE)))
7862 {
7863 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7864 "%s: %d: On session %d unable to buffer the AddTS "
7865 "request for AC %d TSPEC %d in state %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007866 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007867 sessionId, ac, tspecMask, pACInfo->curr_state);
7868 // unable to buffer the request
7869 // nothing is pending so vote powersave back on
7870 pSession->readyForPowerSave = VOS_TRUE;
7871 return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
7872 }
7873 return SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP;
7874 }
7875 //get into the stat m/c to see if the request can be granted
7876 switch(pACInfo->curr_state)
7877 {
7878 case SME_QOS_QOS_ON:
7879 {
7880 //if ACM, send out a new ADDTS
7881 pACInfo->hoRenewal = VOS_TRUE;
7882 status = sme_QosSetup(pMac, sessionId, pQoSInfo, ac);
7883 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
7884 "%s: %d: sme_QosSetup returned in SME_QOS_QOS_ON state on "
7885 "AC %d with status =%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007886 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007887 ac, status);
7888 if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP != status)
7889 {
7890 // we aren't waiting for a response from the AP
7891 // so vote powersave back on
7892 pSession->readyForPowerSave = VOS_TRUE;
7893 }
7894 if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status)
7895 {
7896 status = SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP;
7897 pACInfo->tspec_pending = tspecMask;
7898 }
7899 else if((SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) ||
7900 (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status) ||
7901 (SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING == status))
7902 {
7903 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7904 "%s: %d: UAPSD is setup already status = %d "
7905 "returned by sme_QosSetup",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007906 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007907 status);
7908 }
7909 else
7910 {
7911 //err msg
7912 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7913 "%s: %d: unexpected status = %d returned by sme_QosSetup",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007914 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007915 status);
7916 }
7917 }
7918 break;
7919 case SME_QOS_HANDOFF:
7920 case SME_QOS_REQUESTED:
7921 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7922 "%s: %d: Re-Add request in state = %d buffer the request",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007923 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007924 pACInfo->curr_state);
7925 cmd.command = SME_QOS_RESEND_REQ;
7926 cmd.pMac = pMac;
7927 cmd.sessionId = sessionId;
7928 cmd.u.resendCmdInfo.ac = ac;
7929 cmd.u.resendCmdInfo.tspecMask = tspecMask;
7930 cmd.u.resendCmdInfo.QoSInfo = *pQoSInfo;
7931 if(!HAL_STATUS_SUCCESS(sme_QosBufferCmd(&cmd, VOS_FALSE)))
7932 {
7933 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7934 "%s: %d: couldn't buffer the readd request in state = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007935 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007936 pACInfo->curr_state );
7937 // unable to buffer the request
7938 // nothing is pending so vote powersave back on
7939 pSession->readyForPowerSave = VOS_TRUE;
7940 return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
7941 }
7942 status = SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP;
7943 break;
7944 case SME_QOS_CLOSED:
7945 case SME_QOS_INIT:
7946 case SME_QOS_LINK_UP:
7947 default:
7948 //print error msg,
7949 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7950 "%s: %d: ReAdd request in unexpected state = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007951 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007952 pACInfo->curr_state );
7953 // unable to service the request
7954 // nothing is pending so vote powersave back on
7955 pSession->readyForPowerSave = VOS_TRUE;
7956 // ASSERT?
7957 break;
7958 }
7959 if((SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) ||
7960 (SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY == status))
7961 {
7962 (void)sme_QosProcessBufferedCmd(sessionId);
7963 }
7964 return (status);
7965}
7966
7967static void sme_QosInitACs(tpAniSirGlobal pMac, v_U8_t sessionId)
7968{
7969 sme_QosSessionInfo *pSession;
7970 sme_QosEdcaAcType ac;
7971 pSession = &sme_QosCb.sessionInfo[sessionId];
7972 for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++)
7973 {
7974 vos_mem_zero(&pSession->ac_info[ac], sizeof(sme_QosACInfo));
7975 sme_QosStateTransition(sessionId, ac, SME_QOS_INIT);
7976 }
7977}
7978static eHalStatus sme_QosRequestReassoc(tpAniSirGlobal pMac, tANI_U8 sessionId,
7979 tCsrRoamModifyProfileFields *pModFields,
7980 v_BOOL_t fForce )
7981{
7982 sme_QosSessionInfo *pSession;
7983 sme_QosACInfo *pACInfo;
7984 eHalStatus status;
7985 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
7986 "%s: %d: Invoked on session %d with UAPSD mask 0x%X",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007987 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007988 sessionId, pModFields->uapsd_mask);
7989 pSession = &sme_QosCb.sessionInfo[sessionId];
7990 status = csrReassoc(pMac, sessionId, pModFields, &pSession->roamID, fForce);
7991 if(HAL_STATUS_SUCCESS(status))
7992 {
7993 //Update the state to Handoff so subsequent requests are queued until
7994 // this one is finished
7995 sme_QosEdcaAcType ac;
7996 for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++)
7997 {
7998 pACInfo = &pSession->ac_info[ac];
7999 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
8000 "%s: %d: AC[%d] is in state [%d]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008001 __func__, __LINE__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008002 ac, pACInfo->curr_state );
8003 // If it is already in HANDOFF state, don't do anything since we
8004 // MUST preserve the previous state and sme_QosStateTransition
8005 // will change the previous state
8006 if(SME_QOS_HANDOFF != pACInfo->curr_state)
8007 {
8008 sme_QosStateTransition(sessionId, ac, SME_QOS_HANDOFF);
8009 }
8010 }
8011 }
8012 return status;
8013}
8014static v_U32_t sme_QosAssignFlowId(void)
8015{
8016 v_U32_t flowId;
8017 flowId = sme_QosCb.nextFlowId;
8018 if (SME_QOS_MAX_FLOW_ID == flowId)
8019 {
8020 // The Flow ID wrapped. This is obviously not a real life scenario
8021 // but handle it to keep the software test folks happy
8022 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
8023 "%s: %d: Software Test made the flow counter wrap, "
8024 "QoS may no longer be functional",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008025 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008026 sme_QosCb.nextFlowId = SME_QOS_MIN_FLOW_ID;
8027 }
8028 else
8029 {
8030 sme_QosCb.nextFlowId++;
8031 }
8032 return flowId;
8033}
8034
8035static v_U8_t sme_QosAssignDialogToken(void)
8036{
8037 v_U8_t token;
8038 token = sme_QosCb.nextDialogToken;
8039 if (SME_QOS_MAX_DIALOG_TOKEN == token)
8040 {
8041 // wrap is ok
8042 sme_QosCb.nextDialogToken = SME_QOS_MIN_DIALOG_TOKEN;
8043 }
8044 else
8045 {
8046 sme_QosCb.nextDialogToken++;
8047 }
8048 return token;
8049}
8050#endif /* WLAN_MDM_CODE_REDUCTION_OPT */