blob: 40f87b5160c2231ae61d7794c8ce89127a59e82c [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam842dad02014-02-18 18:44:02 -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/*============================================================================
29 @file wlan_hdd_wmm.c
30
31 This module (wlan_hdd_wmm.h interface + wlan_hdd_wmm.c implementation)
32 houses all the logic for WMM in HDD.
33
34 On the control path, it has the logic to setup QoS, modify QoS and delete
35 QoS (QoS here refers to a TSPEC). The setup QoS comes in two flavors: an
36 explicit application invoked and an internal HDD invoked. The implicit QoS
37 is for applications that do NOT call the custom QCT WLAN OIDs for QoS but
38 which DO mark their traffic for priortization. It also has logic to start,
39 update and stop the U-APSD trigger frame generation. It also has logic to
40 read WMM related config parameters from the registry.
41
42 On the data path, it has the logic to figure out the WMM AC of an egress
43 packet and when to signal TL to serve a particular AC queue. It also has the
44 logic to retrieve a packet based on WMM priority in response to a fetch from
45 TL.
46
47 The remaining functions are utility functions for information hiding.
48
49
Jeff Johnson295189b2012-06-20 16:38:30 -070050============================================================================*/
51
52/*---------------------------------------------------------------------------
53 Include files
54 -------------------------------------------------------------------------*/
55#include <wlan_hdd_tx_rx.h>
56#include <wlan_hdd_dp_utils.h>
57#include <wlan_hdd_wmm.h>
58#include <wlan_hdd_ether.h>
59#include <linux/netdevice.h>
60#include <linux/skbuff.h>
61#include <linux/etherdevice.h>
62#include <linux/if_vlan.h>
63#include <linux/ip.h>
64#include <linux/semaphore.h>
65#include <wlan_hdd_hostapd.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <wlan_hdd_softap_tx_rx.h>
Kiet Lam40009862014-02-13 12:33:22 -080067#include <vos_sched.h>
Mukul Sharma74a01e52014-07-21 15:14:23 +053068#include "sme_Api.h"
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053069#include "sapInternal.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070070// change logging behavior based upon debug flag
71#ifdef HDD_WMM_DEBUG
72#define WMM_TRACE_LEVEL_FATAL VOS_TRACE_LEVEL_FATAL
73#define WMM_TRACE_LEVEL_ERROR VOS_TRACE_LEVEL_FATAL
74#define WMM_TRACE_LEVEL_WARN VOS_TRACE_LEVEL_FATAL
75#define WMM_TRACE_LEVEL_INFO VOS_TRACE_LEVEL_FATAL
76#define WMM_TRACE_LEVEL_INFO_HIGH VOS_TRACE_LEVEL_FATAL
77#define WMM_TRACE_LEVEL_INFO_LOW VOS_TRACE_LEVEL_FATAL
78#else
79#define WMM_TRACE_LEVEL_FATAL VOS_TRACE_LEVEL_FATAL
80#define WMM_TRACE_LEVEL_ERROR VOS_TRACE_LEVEL_ERROR
81#define WMM_TRACE_LEVEL_WARN VOS_TRACE_LEVEL_WARN
82#define WMM_TRACE_LEVEL_INFO VOS_TRACE_LEVEL_INFO
83#define WMM_TRACE_LEVEL_INFO_HIGH VOS_TRACE_LEVEL_INFO_HIGH
84#define WMM_TRACE_LEVEL_INFO_LOW VOS_TRACE_LEVEL_INFO_LOW
85#endif
86
87
Jeff Johnson295189b2012-06-20 16:38:30 -070088#define WLAN_HDD_MAX_DSCP 0x3f
89
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +053090// DHCP Port number
91#define DHCP_SOURCE_PORT 0x4400
92#define DHCP_DESTINATION_PORT 0x4300
93
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080094#define HDD_WMM_UP_TO_AC_MAP_SIZE 8
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -070095
Jeff Johnson295189b2012-06-20 16:38:30 -070096const v_U8_t hddWmmUpToAcMap[] = {
97 WLANTL_AC_BE,
98 WLANTL_AC_BK,
99 WLANTL_AC_BK,
100 WLANTL_AC_BE,
101 WLANTL_AC_VI,
102 WLANTL_AC_VI,
103 WLANTL_AC_VO,
104 WLANTL_AC_VO
105};
106
107//Linux based UP -> AC Mapping
108const v_U8_t hddLinuxUpToAcMap[8] = {
109 HDD_LINUX_AC_BE,
110 HDD_LINUX_AC_BK,
111 HDD_LINUX_AC_BK,
112 HDD_LINUX_AC_BE,
113 HDD_LINUX_AC_VI,
114 HDD_LINUX_AC_VI,
115 HDD_LINUX_AC_VO,
116 HDD_LINUX_AC_VO
117};
118
119#ifndef WLAN_MDM_CODE_REDUCTION_OPT
120/**
121 @brief hdd_wmm_enable_tl_uapsd() - function which decides whether and
122 how to update UAPSD parameters in TL
123
124 @param pQosContext : [in] the pointer the QoS instance control block
125
126 @return
127 None
128*/
129static void hdd_wmm_enable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
130{
131 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
132 WLANTL_ACEnumType acType = pQosContext->acType;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530133 hdd_wmm_ac_status_t *pAc = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700134 VOS_STATUS status;
135 v_U32_t service_interval;
136 v_U32_t suspension_interval;
137 sme_QosWmmDirType direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530138 v_BOOL_t psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700139
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530140 if (acType >= WLANTL_MAX_AC)
141 {
142 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
143 "%s: Invalid AC: %d", __func__, acType);
144 return;
145 }
146
147 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
Jeff Johnson295189b2012-06-20 16:38:30 -0700148
149 // The TSPEC must be valid
150 if (pAc->wmmAcTspecValid == VOS_FALSE)
151 {
152 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
153 "%s: Invoked with invalid TSPEC",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700154 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700155 return;
156 }
157
158 // determine the service interval
159 if (pAc->wmmAcTspecInfo.min_service_interval)
160 {
161 service_interval = pAc->wmmAcTspecInfo.min_service_interval;
162 }
163 else if (pAc->wmmAcTspecInfo.max_service_interval)
164 {
165 service_interval = pAc->wmmAcTspecInfo.max_service_interval;
166 }
167 else
168 {
169 // no service interval is present in the TSPEC
170 // this is OK, there just won't be U-APSD
171 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
172 "%s: No service interval supplied",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700173 __func__);
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530174 service_interval = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700175 }
176
177 // determine the suspension interval & direction
178 suspension_interval = pAc->wmmAcTspecInfo.suspension_interval;
179 direction = pAc->wmmAcTspecInfo.ts_info.direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530180 psb = pAc->wmmAcTspecInfo.ts_info.psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700181
182 // if we have previously enabled U-APSD, have any params changed?
183 if ((pAc->wmmAcUapsdInfoValid) &&
184 (pAc->wmmAcUapsdServiceInterval == service_interval) &&
185 (pAc->wmmAcUapsdSuspensionInterval == suspension_interval) &&
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530186 (pAc->wmmAcUapsdDirection == direction) &&
187 (pAc->wmmAcIsUapsdEnabled == psb))
Jeff Johnson295189b2012-06-20 16:38:30 -0700188 {
189 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
190 "%s: No change in U-APSD parameters",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700191 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700192 return;
193 }
194
195 // are we in the appropriate power save modes?
196 if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_BEACON_MODE_POWER_SAVE))
197 {
198 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
199 "%s: BMPS is not enabled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700200 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700201 return;
202 }
203
204 if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_UAPSD_MODE_POWER_SAVE))
205 {
206 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
207 "%s: U-APSD is not enabled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700208 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700209 return;
210 }
211
212 // everything is in place to notify TL
213 status = WLANTL_EnableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
214 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
215 acType,
216 pAc->wmmAcTspecInfo.ts_info.tid,
217 pAc->wmmAcTspecInfo.ts_info.up,
218 service_interval,
219 suspension_interval,
220 direction);
221
222 if ( !VOS_IS_STATUS_SUCCESS( status ) )
223 {
224 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
225 "%s: Failed to enable U-APSD for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700226 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700227 return;
228 }
229
230 // stash away the parameters that were used
231 pAc->wmmAcUapsdInfoValid = VOS_TRUE;
232 pAc->wmmAcUapsdServiceInterval = service_interval;
233 pAc->wmmAcUapsdSuspensionInterval = suspension_interval;
234 pAc->wmmAcUapsdDirection = direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530235 pAc->wmmAcIsUapsdEnabled = psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700236
237 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700238 "%s: Enabled UAPSD in TL srv_int=%d "
239 "susp_int=%d dir=%d AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700240 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700241 service_interval,
242 suspension_interval,
243 direction,
244 acType);
245
246}
247
248/**
249 @brief hdd_wmm_disable_tl_uapsd() - function which decides whether
250 to disable UAPSD parameters in TL
251
252 @param pQosContext : [in] the pointer the QoS instance control block
253
254 @return
255 None
256*/
257static void hdd_wmm_disable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
258{
259 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
260 WLANTL_ACEnumType acType = pQosContext->acType;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530261 hdd_wmm_ac_status_t *pAc = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700262 VOS_STATUS status;
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530263 v_U32_t service_interval;
264 v_U32_t suspension_interval;
265 v_U8_t uapsd_mask;
266 v_U8_t ActiveTspec = INVALID_TSPEC;
Jeff Johnson295189b2012-06-20 16:38:30 -0700267
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530268 if (acType >= WLANTL_MAX_AC)
269 {
270 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
271 "%s: Invalid AC: %d", __func__, acType);
272 return;
273 }
274
275 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
276
Jeff Johnson295189b2012-06-20 16:38:30 -0700277 // have we previously enabled UAPSD?
278 if (pAc->wmmAcUapsdInfoValid == VOS_TRUE)
279 {
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530280 uapsd_mask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
Jeff Johnson295189b2012-06-20 16:38:30 -0700281
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530282 //Finding uapsd_mask as per AC
283 uapsd_mask = uapsd_mask & (1 << (WLANTL_AC_VO - acType));
284
285 sme_QosTspecActive((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter), acType,
286 pAdapter->sessionId, &ActiveTspec);
287
288 //Call WLANTL_EnableUAPSDForAC only when static uapsd mask is present and
289 // no active tspecs. TODO: Need to change naming convention as Enable
290 // UAPSD function is called in hdd_wmm_disable_tl_uapsd. Purpose of
291 // calling WLANTL_EnableUAPSDForAC is to update UAPSD intervals to fw
292
293 if(uapsd_mask && !ActiveTspec)
Jeff Johnson295189b2012-06-20 16:38:30 -0700294 {
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530295 switch(acType)
296 {
297 case WLANTL_AC_VO:
298 service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv;
299 suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv;
300 break;
301 case WLANTL_AC_VI:
302 service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv;
303 suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv;
304 break;
305 case WLANTL_AC_BE:
306 service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv;
307 suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv;
308 break;
309 case WLANTL_AC_BK:
310 service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv;
311 suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv;
312 break;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530313 default:
314 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
315 "%s: Invalid AC %d", __func__, acType );
316 return;
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530317 }
318
319 status = WLANTL_EnableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
320 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
321 acType,
322 pAc->wmmAcTspecInfo.ts_info.tid,
323 pAc->wmmAcTspecInfo.ts_info.up,
324 service_interval,
325 suspension_interval,
326 pAc->wmmAcTspecInfo.ts_info.direction);
327
328 if ( !VOS_IS_STATUS_SUCCESS( status ) )
329 {
330 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
331 "%s: Failed to update U-APSD params for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700332 __func__, acType );
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530333 }
334 else
335 {
336 // TL no longer has valid UAPSD info
337 pAc->wmmAcUapsdInfoValid = VOS_FALSE;
338 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
339 "%s: Updated UAPSD params in TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700340 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700341 acType);
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530342 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700343 }
344 }
345}
346
347#endif
348
349/**
350 @brief hdd_wmm_free_context() - function which frees a QoS context
351
352 @param pQosContext : [in] the pointer the QoS instance control block
353
354 @return
355 None
356*/
357static void hdd_wmm_free_context (hdd_wmm_qos_context_t* pQosContext)
358{
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530359 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
360 hdd_context_t *pHddCtx;
361
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530362 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530363 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530364 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
365 FL("pVosContext is NULL"));
366 return;
367 }
368
369 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
370 if (NULL == pHddCtx)
371 {
372 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
373 FL("HddCtx is NULL"));
374 return;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530375 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700376
377 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
378 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700379 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700380
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530381 // take the wmmLock since we're manipulating the context list
382 mutex_lock(&pHddCtx->wmmLock);
383
Jeff Johnson295189b2012-06-20 16:38:30 -0700384 if (unlikely((NULL == pQosContext) ||
385 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
386 {
387 // must have been freed in another thread
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530388 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700389 return;
390 }
391
Jeff Johnson295189b2012-06-20 16:38:30 -0700392 // make sure nobody thinks this is a valid context
393 pQosContext->magic = 0;
394
395 // unlink the context
396 list_del(&pQosContext->node);
397
398 // done manipulating the list
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530399 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700400
401 // reclaim memory
402 kfree(pQosContext);
403
404}
405
406#ifndef WLAN_MDM_CODE_REDUCTION_OPT
407/**
408 @brief hdd_wmm_notify_app() - function which notifies an application
409 changes in state of it flow
410
411 @param pQosContext : [in] the pointer the QoS instance control block
412
413 @return
414 None
415*/
416#define MAX_NOTIFY_LEN 50
417static void hdd_wmm_notify_app (hdd_wmm_qos_context_t* pQosContext)
418{
419 hdd_adapter_t* pAdapter;
420 union iwreq_data wrqu;
421 char buf[MAX_NOTIFY_LEN+1];
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530422 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
423 hdd_context_t *pHddCtx;
424
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530425 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530426 {
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530427 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530428 FL("pVosContext is NULL"));
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530429 return;
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530430 }
431
432 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
433 if (NULL == pHddCtx)
434 {
435 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
436 FL("HddCtx is NULL"));
437 return;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530438 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700439
440 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
441 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700442 __func__, pQosContext);
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530443
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530444 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700445 if (unlikely((NULL == pQosContext) ||
446 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
447 {
Hema Aparna Medicharla8bb6f782015-03-09 12:35:05 +0530448 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700449 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
450 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700451 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700452 return;
453 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530454 // get pointer to the adapter
455 pAdapter = pQosContext->pAdapter;
456 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700457
458 // create the event
459 memset(&wrqu, 0, sizeof(wrqu));
460 memset(buf, 0, sizeof(buf));
461
462 snprintf(buf, MAX_NOTIFY_LEN, "QCOM: TS change[%u: %u]",
463 (unsigned int)pQosContext->handle,
464 (unsigned int)pQosContext->lastStatus);
465
466 wrqu.data.pointer = buf;
467 wrqu.data.length = strlen(buf);
468
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530469
Jeff Johnson295189b2012-06-20 16:38:30 -0700470
471 // send the event
472 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700473 "%s: Sending [%s]", __func__, buf);
Jeff Johnson295189b2012-06-20 16:38:30 -0700474 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
475}
476
477
478/**
479 @brief hdd_wmm_is_access_allowed() - function which determines if access
480 is allowed for the given AC. this is designed to be called during SME
481 callback processing since that is when access can be granted or removed
482
483 @param pAdapter : [in] pointer to adapter context
484 @param pAc : [in] pointer to the per-AC status
485
486 @return : VOS_TRUE - access is allowed
487 : VOS_FALSE - access is not allowed
488 None
489*/
490static v_BOOL_t hdd_wmm_is_access_allowed(hdd_adapter_t* pAdapter,
491 hdd_wmm_ac_status_t* pAc)
492{
493 // if we don't want QoS or the AP doesn't support QoS
494 // or we don't want to do implicit QoS
495 // or if AP doesn't require admission for this AC
496 // then we have access
497 if (!hdd_wmm_is_active(pAdapter) ||
498 !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled ||
499 !pAc->wmmAcAccessRequired)
500 {
501 return VOS_TRUE;
502 }
503
504 // if implicit QoS has already completed, successfully or not,
505 // then access is allowed
506 if (pAc->wmmAcAccessGranted || pAc->wmmAcAccessFailed)
507 {
508 return VOS_TRUE;
509 }
510
511 // admission is required and implicit QoS hasn't completed
512 // however explicit QoS may have completed and we'll have
513 // a Tspec
514 // if we don't have a Tspec then access is not allowed
515 if (!pAc->wmmAcTspecValid)
516 {
517 return VOS_FALSE;
518 }
519
520 // we have a Tspec -- does it allow upstream or bidirectional traffic?
521 // if it only allows downstream traffic then access is not allowed
522 if (pAc->wmmAcTspecInfo.ts_info.direction == SME_QOS_WMM_TS_DIR_DOWNLINK)
523 {
524 return VOS_FALSE;
525 }
526
527 // we meet all of the criteria for access
528 return VOS_TRUE;
529}
530
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800531#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700532/**
533 @brief hdd_wmm_inactivity_timer_cb() - timer handler function which is
534 called for every inactivity interval per AC. This function gets the
535 current transmitted packets on the given AC, and checks if there where
536 any TX activity from the previous interval. If there was no traffic
537 then it would delete the TS that was negotiated on that AC.
538
539 @param pUserData : [in] pointer to pQosContext
540
541 @return : NONE
542*/
543void hdd_wmm_inactivity_timer_cb( v_PVOID_t pUserData )
544{
545 hdd_wmm_qos_context_t* pQosContext = (hdd_wmm_qos_context_t*)pUserData;
546 hdd_adapter_t* pAdapter;
547 hdd_wmm_ac_status_t *pAc;
548 hdd_wlan_wmm_status_e status;
549 VOS_STATUS vos_status;
550 v_U32_t currentTrafficCnt = 0;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530551 WLANTL_ACEnumType acType = 0;
552 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
553 hdd_context_t *pHddCtx;
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +0530554
555 ENTER();
556 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530557 {
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +0530558 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
559 "%s: Invalid VOS Context", __func__);
560 return;
561 }
562
563 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
564 if (0 != (wlan_hdd_validate_context(pHddCtx)))
565 {
566 return;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530567 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700568
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530569 mutex_lock(&pHddCtx->wmmLock);
570 if (unlikely((NULL == pQosContext) ||
571 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
572 {
Hema Aparna Medicharla8bb6f782015-03-09 12:35:05 +0530573 mutex_unlock(&pHddCtx->wmmLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530574 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
575 "%s: Invalid QoS Context",
576 __func__);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530577 return;
578 }
579 mutex_unlock(&pHddCtx->wmmLock);
580
581 acType = pQosContext->acType;
Jeff Johnson295189b2012-06-20 16:38:30 -0700582 pAdapter = pQosContext->pAdapter;
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +0530583 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
584 {
585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
586 FL("invalid pAdapter: %p"), pAdapter);
587 return;
588 }
589
Jeff Johnson295189b2012-06-20 16:38:30 -0700590 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
591
592 // Get the Tx stats for this AC.
593 currentTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];
594
595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800596 FL("WMM inactivity Timer for AC=%d, currentCnt=%d, prevCnt=%d"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700597 acType, (int)currentTrafficCnt, (int)pAc->wmmPrevTrafficCnt);
598 if (pAc->wmmPrevTrafficCnt == currentTrafficCnt)
599 {
600 // If there is no traffic activity, delete the TSPEC for this AC
601 status = hdd_wmm_delts(pAdapter, pQosContext->handle);
602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
603 FL("Deleted TS on AC %d, due to inactivity with status = %d!!!"),
604 acType, status);
605 }
606 else
607 {
608 pAc->wmmPrevTrafficCnt = currentTrafficCnt;
609 if (pAc->wmmInactivityTimer.state == VOS_TIMER_STATE_STOPPED)
610 {
611 // Restart the timer
612 vos_status = vos_timer_start(&pAc->wmmInactivityTimer, pAc->wmmInactivityTime);
613 if (!VOS_IS_STATUS_SUCCESS(vos_status))
614 {
615 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
616 FL("Restarting inactivity timer failed on AC %d"), acType);
617 }
618 }
619 else
620 {
621 VOS_ASSERT(vos_timer_getCurrentState(
622 &pAc->wmmInactivityTimer) == VOS_TIMER_STATE_STOPPED);
623 }
624 }
625
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +0530626 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -0700627 return;
628}
629
630
631/**
632 @brief hdd_wmm_enable_inactivity_timer() - function to enable the
633 traffic inactivity timer for the given AC, if the inactivity_interval
634 specified in the ADDTS parameters is non-zero
635
636 @param pQosContext : [in] pointer to pQosContext
637 @param inactivityTime: [in] value of the inactivity interval in millisecs
638
639 @return : VOS_STATUS_E_FAILURE
640 VOS_STATUS_SUCCESS
641*/
642VOS_STATUS hdd_wmm_enable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext, v_U32_t inactivityTime)
643{
644 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
645 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
646 WLANTL_ACEnumType acType = pQosContext->acType;
647 hdd_wmm_ac_status_t *pAc;
648
649 pAdapter = pQosContext->pAdapter;
650 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
651
652
653 // If QoS-Tspec is successfully setup and if the inactivity timer is non-zero,
654 // a traffic inactivity timer needs to be started for the given AC
655 vos_status = vos_timer_init(
656 &pAc->wmmInactivityTimer,
657 VOS_TIMER_TYPE_SW,
658 hdd_wmm_inactivity_timer_cb,
659 (v_PVOID_t)pQosContext );
660 if ( !VOS_IS_STATUS_SUCCESS(vos_status))
661 {
662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
663 FL("Initializing inactivity timer failed on AC %d"), acType);
664 return vos_status;
665 }
666
667 // Start the inactivity timer
668 vos_status = vos_timer_start(
669 &pAc->wmmInactivityTimer,
670 inactivityTime);
671 if ( !VOS_IS_STATUS_SUCCESS(vos_status))
672 {
673 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
674 FL("Starting inactivity timer failed on AC %d"), acType);
675 return vos_status;
676 }
677 pAc->wmmInactivityTime = inactivityTime;
678 // Initialize the current tx traffic count on this AC
679 pAc->wmmPrevTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];
680
681 return vos_status;
682}
683
684/**
685 @brief hdd_wmm_enable_inactivity_timer() - function to disable the
686 traffic inactivity timer for the given AC. This would be called when
687 deleting the TS.
688
689 @param pQosContext : [in] pointer to pQosContext
690
691 @return : VOS_STATUS_E_FAILURE
692 VOS_STATUS_SUCCESS
693*/
694VOS_STATUS hdd_wmm_disable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext)
695{
696 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
697 WLANTL_ACEnumType acType = pQosContext->acType;
698 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
699 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
700
701 // Clear the timer and the counter
702 pAc->wmmInactivityTime = 0;
703 pAc->wmmPrevTrafficCnt = 0;
704 vos_timer_stop(&pAc->wmmInactivityTimer);
705 vos_status = vos_timer_destroy(&pAc->wmmInactivityTimer);
706
707 return vos_status;
708}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800709#endif // FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700710
711/**
712 @brief hdd_wmm_sme_callback() - callback registered by HDD with SME for receiving
713 QoS notifications. Even though this function has a static scope it gets called
714 externally through some function pointer magic (so there is a need for
715 rigorous parameter checking)
716
717 @param hHal : [in] the HAL handle
718 @param HddCtx : [in] the HDD specified handle
719 @param pCurrentQosInfo : [in] the TSPEC params
720 @param SmeStatus : [in] the QoS related SME status
721
722 @return
723 eHAL_STATUS_SUCCESS if all good, eHAL_STATUS_FAILURE otherwise
724*/
725static eHalStatus hdd_wmm_sme_callback (tHalHandle hHal,
726 void * hddCtx,
727 sme_QosWmmTspecInfo* pCurrentQosInfo,
728 sme_QosStatusType smeStatus,
729 v_U32_t qosFlowId)
730{
731 hdd_wmm_qos_context_t* pQosContext = hddCtx;
732 hdd_adapter_t* pAdapter;
733 WLANTL_ACEnumType acType;
734 hdd_wmm_ac_status_t *pAc;
735 VOS_STATUS status;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530736 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
737 hdd_context_t *pHddCtx;
738
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530739 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530740 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530741 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
742 FL("pVosContext is NULL"));
743 return eHAL_STATUS_FAILURE;
744 }
745
746 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
747 if (NULL == pHddCtx)
748 {
749 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530750 FL("HddCtx is NULL"));
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530751 return eHAL_STATUS_FAILURE;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530752 }
753
Jeff Johnson295189b2012-06-20 16:38:30 -0700754
755 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
756 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700757 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700758
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530759 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700760 if (unlikely((NULL == pQosContext) ||
761 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
762 {
Hema Aparna Medicharla8bb6f782015-03-09 12:35:05 +0530763 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700764 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
765 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700766 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700767 return eHAL_STATUS_FAILURE;
768 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530769 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700770
771 pAdapter = pQosContext->pAdapter;
772 acType = pQosContext->acType;
773 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
774
775 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
776 "%s: status %d flowid %d info %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700777 __func__, smeStatus, qosFlowId, pCurrentQosInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -0700778
779 switch (smeStatus)
780 {
781
782 case SME_QOS_STATUS_SETUP_SUCCESS_IND:
783 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
784 "%s: Setup is complete",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700785 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700786
787 // there will always be a TSPEC returned with this status, even if
788 // a TSPEC is not exchanged OTA
789 if (pCurrentQosInfo)
790 {
791 pAc->wmmAcTspecValid = VOS_TRUE;
792 memcpy(&pAc->wmmAcTspecInfo,
793 pCurrentQosInfo,
794 sizeof(pAc->wmmAcTspecInfo));
795 }
796
797 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
798 {
799
800 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
801 "%s: Implicit Qos, notifying TL for TL AC %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700802 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700803
804 // this was triggered by implicit QoS so we know packets are pending
805 // update state
806 pAc->wmmAcAccessAllowed = VOS_TRUE;
807 pAc->wmmAcAccessGranted = VOS_TRUE;
808 pAc->wmmAcAccessPending = VOS_FALSE;
809
810 // notify TL that packets are pending
811 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
812 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
813 acType );
814
815 if ( !VOS_IS_STATUS_SUCCESS( status ) )
816 {
817 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
818 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700819 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700820 }
821 }
822 else
823 {
824 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
825 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700826 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700827
828 // this was triggered by an application
829 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
830 hdd_wmm_notify_app(pQosContext);
831 }
832
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800833#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700834 // Check if the inactivity interval is specified
Jeff Johnson8795e422013-04-03 08:59:22 -0700835 if (pCurrentQosInfo && pCurrentQosInfo->inactivity_interval) {
Jeff Johnson295189b2012-06-20 16:38:30 -0700836 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800837 "%s: Inactivity timer value = %d for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700838 __func__, pCurrentQosInfo->inactivity_interval, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700839 hdd_wmm_enable_inactivity_timer(pQosContext, pCurrentQosInfo->inactivity_interval);
840 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800841#endif // FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700842
843 // notify TL to enable trigger frames if necessary
844 hdd_wmm_enable_tl_uapsd(pQosContext);
845
846 break;
847
848 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
849 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
850 "%s: Setup is complete (U-APSD set previously)",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700851 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700852
853 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
854 {
855
856 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
857 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700858 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700859
860 // this was triggered by implicit QoS so we know packets are pending
861 // update state
862 pAc->wmmAcAccessAllowed = VOS_TRUE;
863 pAc->wmmAcAccessGranted = VOS_TRUE;
864 pAc->wmmAcAccessPending = VOS_FALSE;
865
866 // notify TL that packets are pending
867 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
868 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
869 acType );
870
871 if ( !VOS_IS_STATUS_SUCCESS( status ) )
872 {
873 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
874 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700875 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700876 }
877 }
878 else
879 {
880 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
881 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700882 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700883
884 // this was triggered by an application
885 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
886 hdd_wmm_notify_app(pQosContext);
887 }
888
889 break;
890
891 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
892 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
893 "%s: Setup failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700894 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700895 // QoS setup failed
896
897 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
898 {
899
900 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
901 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700902 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700903
904 // we note the failure, but we also mark access as allowed so that
905 // the packets will flow. Note that the MAC will "do the right thing"
906 pAc->wmmAcAccessPending = VOS_FALSE;
907 pAc->wmmAcAccessFailed = VOS_TRUE;
908 pAc->wmmAcAccessAllowed = VOS_TRUE;
909
910 // this was triggered by implicit QoS so we know packets are pending
911 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
912 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
913 acType );
914
915 if ( !VOS_IS_STATUS_SUCCESS( status ) )
916 {
917 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
918 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700919 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700920 }
921 }
922 else
923 {
924 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
925 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700926 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700927
928 // this was triggered by an application
929 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED;
930 hdd_wmm_notify_app(pQosContext);
931 }
932
933 /* Setting up QoS Failed, QoS context can be released.
934 * SME is releasing this flow information and if HDD doen't release this context,
935 * next time if application uses the same handle to set-up QoS, HDD (as it has
936 * QoS context for this handle) will issue Modify QoS request to SME but SME will
937 * reject as no it has no information for this flow.
938 */
939 hdd_wmm_free_context(pQosContext);
940 break;
941
942 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
943 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
944 "%s: Setup Invalid Params, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700945 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700946 // QoS setup failed
947
948 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
949 {
950
951 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
952 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700953 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700954
955 // we note the failure, but we also mark access as allowed so that
956 // the packets will flow. Note that the MAC will "do the right thing"
957 pAc->wmmAcAccessPending = VOS_FALSE;
958 pAc->wmmAcAccessFailed = VOS_TRUE;
959 pAc->wmmAcAccessAllowed = VOS_TRUE;
960
961 // this was triggered by implicit QoS so we know packets are pending
962 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
963 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
964 acType );
965
966 if ( !VOS_IS_STATUS_SUCCESS( status ) )
967 {
968 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
969 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700970 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700971 }
972 }
973 else
974 {
975 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
976 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700977 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700978
979 // this was triggered by an application
980 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
981 hdd_wmm_notify_app(pQosContext);
982 }
983 break;
984
985 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
986 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800987 "%s: Setup failed, not a QoS AP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700988 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700989 if (!HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
990 {
991 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
992 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700993 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700994
995 // this was triggered by an application
996 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
997 hdd_wmm_notify_app(pQosContext);
998 }
999 break;
1000
1001 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
1002 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1003 "%s: Setup pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001004 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001005 // not a callback status -- ignore if we get it
1006 break;
1007
1008 case SME_QOS_STATUS_SETUP_MODIFIED_IND:
1009 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1010 "%s: Setup modified",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001011 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001012 if (pCurrentQosInfo)
1013 {
1014 // update the TSPEC
1015 pAc->wmmAcTspecValid = VOS_TRUE;
1016 memcpy(&pAc->wmmAcTspecInfo,
1017 pCurrentQosInfo,
1018 sizeof(pAc->wmmAcTspecInfo));
1019
1020 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1021 {
1022 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1023 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001024 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001025
1026 // this was triggered by an application
1027 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFIED;
1028 hdd_wmm_notify_app(pQosContext);
1029 }
1030
1031 // need to tell TL to update its UAPSD handling
1032 hdd_wmm_enable_tl_uapsd(pQosContext);
1033 }
1034 break;
1035
1036 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1037 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
1038 {
1039
1040 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1041 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001042 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001043
1044 // this was triggered by implicit QoS so we know packets are pending
1045 pAc->wmmAcAccessPending = VOS_FALSE;
1046 pAc->wmmAcAccessGranted = VOS_TRUE;
1047 pAc->wmmAcAccessAllowed = VOS_TRUE;
1048
1049 // notify TL that packets are pending
1050 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1051 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
1052 acType );
1053
1054 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1055 {
1056 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1057 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001058 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -07001059 }
1060 }
1061 else
1062 {
1063 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1064 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001065 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001066
1067 // this was triggered by an application
1068 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
1069 hdd_wmm_notify_app(pQosContext);
1070 }
1071 break;
1072
1073 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
1074 // nothing to do for now
1075 break;
1076
1077 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED:
1078 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1079 "%s: Setup successful but U-APSD failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001080 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001081
1082 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
1083 {
1084
1085 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1086 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001087 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001088
1089 // QoS setup was successful but setting U=APSD failed
1090 // Since the OTA part of the request was successful, we don't mark
1091 // this as a failure.
1092 // the packets will flow. Note that the MAC will "do the right thing"
1093 pAc->wmmAcAccessGranted = VOS_TRUE;
1094 pAc->wmmAcAccessAllowed = VOS_TRUE;
1095 pAc->wmmAcAccessFailed = VOS_FALSE;
1096 pAc->wmmAcAccessPending = VOS_FALSE;
1097
1098 // this was triggered by implicit QoS so we know packets are pending
1099 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1100 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
1101 acType );
1102
1103 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1104 {
1105 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1106 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001107 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -07001108 }
1109 }
1110 else
1111 {
1112 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1113 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001114 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001115
1116 // this was triggered by an application
1117 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_UAPSD_SET_FAILED;
1118 hdd_wmm_notify_app(pQosContext);
1119 }
1120
1121 // Since U-APSD portion failed disabled trigger frame generation
1122 hdd_wmm_disable_tl_uapsd(pQosContext);
1123
1124 break;
1125
1126 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
1127 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1128 "%s: Release is complete",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001129 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001130
1131 if (pCurrentQosInfo)
1132 {
1133 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1134 "%s: flows still active",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001135 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001136
1137 // there is still at least one flow active for this AC
1138 // so update the AC state
1139 memcpy(&pAc->wmmAcTspecInfo,
1140 pCurrentQosInfo,
1141 sizeof(pAc->wmmAcTspecInfo));
1142
1143 // need to tell TL to update its UAPSD handling
1144 hdd_wmm_enable_tl_uapsd(pQosContext);
1145 }
1146 else
1147 {
1148 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1149 "%s: last flow",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001150 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001151
1152 // this is the last flow active for this AC so update the AC state
1153 pAc->wmmAcTspecValid = VOS_FALSE;
1154
1155 // need to tell TL to update its UAPSD handling
1156 hdd_wmm_disable_tl_uapsd(pQosContext);
1157 }
1158
1159 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1160 {
1161 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1162 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001163 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001164
1165 // this was triggered by an application
1166 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
1167 hdd_wmm_notify_app(pQosContext);
1168 }
1169
1170 // we are done with this flow
1171 hdd_wmm_free_context(pQosContext);
1172 break;
1173
1174 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
1175 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1176 "%s: Release failure",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001177 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001178
1179 // we don't need to update our state or TL since nothing has changed
1180 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1181 {
1182 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1183 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001184 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001185
1186 // this was triggered by an application
1187 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
1188 hdd_wmm_notify_app(pQosContext);
1189 }
1190
1191 break;
1192
1193 case SME_QOS_STATUS_RELEASE_QOS_LOST_IND:
1194 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1195 "%s: QOS Lost indication received",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001196 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001197
1198 // current TSPEC is no longer valid
1199 pAc->wmmAcTspecValid = VOS_FALSE;
1200
1201 // need to tell TL to update its UAPSD handling
1202 hdd_wmm_disable_tl_uapsd(pQosContext);
1203
1204 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
1205 {
1206 // we no longer have implicit access granted
1207 pAc->wmmAcAccessGranted = VOS_FALSE;
1208 pAc->wmmAcAccessFailed = VOS_FALSE;
1209 }
1210 else
1211 {
1212 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1213 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001214 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001215
1216 // this was triggered by an application
1217 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_LOST;
1218 hdd_wmm_notify_app(pQosContext);
1219 }
1220
1221 // we are done with this flow
1222 hdd_wmm_free_context(pQosContext);
1223 break;
1224
1225 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
1226 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1227 "%s: Release pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001228 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001229 // not a callback status -- ignore if we get it
1230 break;
1231
1232 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
1233 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1234 "%s: Release Invalid Params",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001235 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001236 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1237 {
1238 // this was triggered by an application
1239 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
1240 hdd_wmm_notify_app(pQosContext);
1241 }
1242 break;
1243
1244 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND:
1245 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1246 "%s: Modification is complete, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001247 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001248
1249 // there will always be a TSPEC returned with this status, even if
1250 // a TSPEC is not exchanged OTA
1251 if (pCurrentQosInfo)
1252 {
1253 pAc->wmmAcTspecValid = VOS_TRUE;
1254 memcpy(&pAc->wmmAcTspecInfo,
1255 pCurrentQosInfo,
1256 sizeof(pAc->wmmAcTspecInfo));
1257 }
1258
1259 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1260 {
1261 // this was triggered by an application
1262 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS;
1263 hdd_wmm_notify_app(pQosContext);
1264 }
1265
1266 // notify TL to enable trigger frames if necessary
1267 hdd_wmm_enable_tl_uapsd(pQosContext);
1268
1269 break;
1270
1271 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
1272 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1273 {
1274 // this was triggered by an application
1275 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
1276 hdd_wmm_notify_app(pQosContext);
1277 }
1278 break;
1279
1280 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
1281 // the flow modification failed so we'll leave in place
1282 // whatever existed beforehand
1283
1284 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1285 {
1286 // this was triggered by an application
1287 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
1288 hdd_wmm_notify_app(pQosContext);
1289 }
1290 break;
1291
1292 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
1293 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1294 "%s: modification pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001295 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001296 // not a callback status -- ignore if we get it
1297 break;
1298
1299 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1300 // the flow modification was successful but no QoS changes required
1301
1302 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1303 {
1304 // this was triggered by an application
1305 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
1306 hdd_wmm_notify_app(pQosContext);
1307 }
1308 break;
1309
1310 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
1311 // invalid params -- notify the application
1312 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1313 {
1314 // this was triggered by an application
1315 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
1316 hdd_wmm_notify_app(pQosContext);
1317 }
1318 break;
1319
1320 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_PENDING:
1321 // nothing to do for now. when APSD is established we'll have work to do
1322 break;
1323
1324 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED:
1325 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1326 "%s: Modify successful but U-APSD failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001327 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001328
1329 // QoS modification was successful but setting U=APSD failed.
1330 // This will always be an explicit QoS instance, so all we can
1331 // do is notify the application and let it clean up.
1332 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1333 {
1334 // this was triggered by an application
1335 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_UAPSD_SET_FAILED;
1336 hdd_wmm_notify_app(pQosContext);
1337 }
1338
1339 // Since U-APSD portion failed disabled trigger frame generation
1340 hdd_wmm_disable_tl_uapsd(pQosContext);
1341
1342 break;
1343
1344 case SME_QOS_STATUS_HANDING_OFF:
1345 // no roaming so we won't see this
1346 break;
1347
1348 case SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND:
1349 // need to tell TL to stop trigger frame generation
1350 hdd_wmm_disable_tl_uapsd(pQosContext);
1351 break;
1352
1353 case SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND:
1354 // need to tell TL to start sending trigger frames again
1355 hdd_wmm_enable_tl_uapsd(pQosContext);
1356 break;
1357
1358 default:
1359 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001360 "%s: unexpected SME Status=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001361 __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07001362 VOS_ASSERT(0);
1363 }
1364
1365 // our access to the particular access category may have changed.
1366 // some of the implicit QoS cases above may have already set this
1367 // prior to invoking TL (so that we will properly service the
1368 // Tx queues) but let's consistently handle all cases here
1369 pAc->wmmAcAccessAllowed = hdd_wmm_is_access_allowed(pAdapter, pAc);
1370
1371 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1372 "%s: complete, access for TL AC %d is%sallowed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001373 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001374 acType,
1375 pAc->wmmAcAccessAllowed ? " " : " not ");
1376
1377 return eHAL_STATUS_SUCCESS;
1378}
1379#endif
1380
Kiet Lamf040f472013-11-20 21:15:23 +05301381/**========================================================================
1382 @brief hdd_wmmps_helper() - Function to set uapsd psb dynamically
1383
1384 @param pAdapter : [in] pointer to adapter structure
1385
1386 @param ptr : [in] pointer to command buffer
1387
1388 @return : Zero on success, appropriate error on failure.
1389 =======================================================================*/
1390int hdd_wmmps_helper(hdd_adapter_t *pAdapter, tANI_U8 *ptr)
1391{
1392 if (NULL == pAdapter)
1393 {
1394 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1395 "%s: pAdapter is NULL", __func__);
1396 return -EINVAL;
1397 }
1398 if (NULL == ptr)
1399 {
1400 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1401 "%s: ptr is NULL", __func__);
1402 return -EINVAL;
1403 }
1404 /* convert ASCII to integer */
1405 pAdapter->configuredPsb = ptr[9] - '0';
1406 pAdapter->psbChanged = HDD_PSB_CHANGED;
1407
1408 return 0;
1409}
1410
Jeff Johnson295189b2012-06-20 16:38:30 -07001411/**============================================================================
1412 @brief hdd_wmm_do_implicit_qos() - Function which will attempt to setup
1413 QoS for any AC requiring it
1414
1415 @param work : [in] pointer to work structure
1416
1417 @return : void
1418 ===========================================================================*/
Mukul Sharmaec9dcc62015-02-24 18:00:04 +05301419static void __hdd_wmm_do_implicit_qos(struct work_struct *work)
Jeff Johnson295189b2012-06-20 16:38:30 -07001420{
1421 hdd_wmm_qos_context_t* pQosContext =
1422 container_of(work, hdd_wmm_qos_context_t, wmmAcSetupImplicitQos);
1423 hdd_adapter_t* pAdapter;
1424 WLANTL_ACEnumType acType;
1425 hdd_wmm_ac_status_t *pAc;
1426#ifndef WLAN_MDM_CODE_REDUCTION_OPT
1427 VOS_STATUS status;
1428 sme_QosStatusType smeStatus;
1429#endif
1430 sme_QosWmmTspecInfo qosInfo;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301431 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
1432 hdd_context_t *pHddCtx;
Mukul Sharmaec9dcc62015-02-24 18:00:04 +05301433 int ret = 0;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301434
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301435 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301436 {
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301437 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301438 FL("pVosContext is NULL"));
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301439 return;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301440 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001441
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301442 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
1443
Mukul Sharmaec9dcc62015-02-24 18:00:04 +05301444 ret = wlan_hdd_validate_context(pHddCtx);
1445 if (0 != ret)
1446 {
1447 hddLog(LOGE, FL("HDD context is invalid"));
1448 return;
1449 }
1450
Jeff Johnson295189b2012-06-20 16:38:30 -07001451 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1452 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001453 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001454
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301455 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001456 if (unlikely(HDD_WMM_CTX_MAGIC != pQosContext->magic))
1457 {
Hema Aparna Medicharla8bb6f782015-03-09 12:35:05 +05301458 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001459 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1460 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001461 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001462 return;
1463 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301464 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001465
1466 pAdapter = pQosContext->pAdapter;
1467 acType = pQosContext->acType;
1468 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1469
1470 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1471 "%s: pAdapter %p acType %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001472 __func__, pAdapter, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001473
1474 if (!pAc->wmmAcAccessNeeded)
1475 {
1476 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1477 "%s: AC %d doesn't need service",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001478 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001479 pQosContext->magic = 0;
1480 kfree(pQosContext);
1481 return;
1482 }
1483
1484 pAc->wmmAcAccessPending = VOS_TRUE;
1485 pAc->wmmAcAccessNeeded = VOS_FALSE;
1486
1487 memset(&qosInfo, 0, sizeof(qosInfo));
1488
Kiet Lamf040f472013-11-20 21:15:23 +05301489 qosInfo.ts_info.psb = pAdapter->configuredPsb;
1490
Jeff Johnson295189b2012-06-20 16:38:30 -07001491 switch (acType)
1492 {
1493 case WLANTL_AC_VO:
1494 qosInfo.ts_info.up = SME_QOS_WMM_UP_VO;
Kiet Lamf040f472013-11-20 21:15:23 +05301495 /* Check if there is any valid configuration from framework */
1496 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1497 {
1498 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1499 SME_QOS_UAPSD_VO) ? 1 : 0;
1500 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001501 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVo;
1502 qosInfo.ts_info.tid = 255;
1503 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVo;
1504 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVo;
1505 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv;
1506 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVo;
1507 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVo;
1508 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv;
1509 break;
1510 case WLANTL_AC_VI:
1511 qosInfo.ts_info.up = SME_QOS_WMM_UP_VI;
Kiet Lamf040f472013-11-20 21:15:23 +05301512 /* Check if there is any valid configuration from framework */
1513 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1514 {
1515 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1516 SME_QOS_UAPSD_VI) ? 1 : 0;
1517 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001518 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVi;
1519 qosInfo.ts_info.tid = 255;
1520 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVi;
1521 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVi;
1522 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv;
1523 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVi;
1524 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVi;
1525 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv;
1526 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07001527 case WLANTL_AC_BE:
1528 qosInfo.ts_info.up = SME_QOS_WMM_UP_BE;
Kiet Lamf040f472013-11-20 21:15:23 +05301529 /* Check if there is any valid configuration from framework */
1530 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1531 {
1532 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1533 SME_QOS_UAPSD_BE) ? 1 : 0;
1534 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001535 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBe;
1536 qosInfo.ts_info.tid = 255;
1537 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBe;
1538 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBe;
1539 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv;
1540 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBe;
1541 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBe;
1542 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv;
1543 break;
1544 case WLANTL_AC_BK:
1545 qosInfo.ts_info.up = SME_QOS_WMM_UP_BK;
Kiet Lamf040f472013-11-20 21:15:23 +05301546 /* Check if there is any valid configuration from framework */
1547 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1548 {
1549 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1550 SME_QOS_UAPSD_BK) ? 1 : 0;
1551 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001552 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBk;
1553 qosInfo.ts_info.tid = 255;
1554 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBk;
1555 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBk;
1556 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv;
1557 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBk;
1558 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBk;
1559 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv;
1560 break;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301561 default:
1562 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1563 "%s: Invalid AC %d", __func__, acType );
1564 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001565 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08001566#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07001567 qosInfo.inactivity_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraInactivityInterval;
1568#endif
1569 qosInfo.ts_info.burst_size_defn = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->burstSizeDefinition;
1570
1571 switch ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->tsInfoAckPolicy)
1572 {
1573 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK:
1574 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1575 break;
1576
1577 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
1578 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
1579 break;
1580
1581 default:
1582 // unknown
1583 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1584 }
1585
1586 if(qosInfo.ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK)
1587 {
1588 if(!sme_QosIsTSInfoAckPolicyValid((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter), &qosInfo, pAdapter->sessionId))
1589 {
1590 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1591 }
1592 }
1593
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301594 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001595 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301596 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001597
1598#ifndef WLAN_MDM_CODE_REDUCTION_OPT
1599 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
1600 pAdapter->sessionId,
1601 &qosInfo,
1602 hdd_wmm_sme_callback,
1603 pQosContext,
1604 qosInfo.ts_info.up,
1605 &pQosContext->qosFlowId);
1606
1607 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1608 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001609 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001610
1611 // need to check the return values and act appropriately
1612 switch (smeStatus)
1613 {
1614 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
1615 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
1616 // setup is pending, so no more work to do now.
1617 // all further work will be done in hdd_wmm_sme_callback()
1618 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1619 "%s: Setup is pending, no further work",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001620 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001621
1622 break;
1623
1624
1625 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
1626 // we can't tell the difference between when a request fails because
1627 // AP rejected it versus when SME encountered an internal error
1628
1629 // in either case SME won't ever reference this context so
1630 // free the record
1631 hdd_wmm_free_context(pQosContext);
1632
1633 // fall through and start packets flowing
1634 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1635 // no ACM in effect, no need to setup U-APSD
1636 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
1637 // no ACM in effect, U-APSD is desired but was already setup
1638
1639 // for these cases everything is already setup so we can
1640 // signal TL that it has work to do
1641 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1642 "%s: Setup is complete, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001643 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001644
1645 pAc->wmmAcAccessAllowed = VOS_TRUE;
1646 pAc->wmmAcAccessGranted = VOS_TRUE;
1647 pAc->wmmAcAccessPending = VOS_FALSE;
1648
1649 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1650 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
1651 acType );
1652
1653 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1654 {
1655 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1656 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001657 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -07001658 }
1659
1660 break;
1661
1662
1663 default:
1664 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001665 "%s: unexpected SME Status=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001666 __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07001667 VOS_ASSERT(0);
1668 }
1669#endif
1670
1671}
1672
Mukul Sharmaec9dcc62015-02-24 18:00:04 +05301673static void hdd_wmm_do_implicit_qos(struct work_struct *work)
1674{
1675 vos_ssr_protect(__func__);
1676 __hdd_wmm_do_implicit_qos( work );
1677 vos_ssr_unprotect(__func__);
1678}
1679
Jeff Johnson295189b2012-06-20 16:38:30 -07001680/**============================================================================
1681 @brief hdd_wmm_init() - Function which will initialize the WMM configuation
1682 and status to an initial state. The configuration can later be overwritten
1683 via application APIs
1684
Kumar Anand82c009f2014-05-29 00:29:42 -07001685 @param pAdapter : [in] pointer to Adapter context
Jeff Johnson295189b2012-06-20 16:38:30 -07001686
Kumar Anand82c009f2014-05-29 00:29:42 -07001687 @return : VOS_STATUS_SUCCESS if successful
Jeff Johnson295189b2012-06-20 16:38:30 -07001688 : other values if failure
1689
1690 ===========================================================================*/
Kumar Anand82c009f2014-05-29 00:29:42 -07001691VOS_STATUS hdd_wmm_init ( hdd_adapter_t *pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07001692{
Kumar Anand82c009f2014-05-29 00:29:42 -07001693 sme_QosWmmUpType* hddWmmDscpToUpMap = pAdapter->hddWmmDscpToUpMap;
Jeff Johnson295189b2012-06-20 16:38:30 -07001694 v_U8_t dscp;
1695
1696 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001697 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001698
1699 // DSCP to User Priority Lookup Table
1700 for (dscp = 0; dscp <= WLAN_HDD_MAX_DSCP; dscp++)
1701 {
1702 hddWmmDscpToUpMap[dscp] = SME_QOS_WMM_UP_BE;
1703 }
1704 hddWmmDscpToUpMap[8] = SME_QOS_WMM_UP_BK;
1705 hddWmmDscpToUpMap[16] = SME_QOS_WMM_UP_RESV;
1706 hddWmmDscpToUpMap[24] = SME_QOS_WMM_UP_EE;
1707 hddWmmDscpToUpMap[32] = SME_QOS_WMM_UP_CL;
1708 hddWmmDscpToUpMap[40] = SME_QOS_WMM_UP_VI;
1709 hddWmmDscpToUpMap[48] = SME_QOS_WMM_UP_VO;
1710 hddWmmDscpToUpMap[56] = SME_QOS_WMM_UP_NC;
Jeff Johnson295189b2012-06-20 16:38:30 -07001711 return VOS_STATUS_SUCCESS;
1712}
1713
1714/**============================================================================
1715 @brief hdd_wmm_adapter_init() - Function which will initialize the WMM configuation
1716 and status to an initial state. The configuration can later be overwritten
1717 via application APIs
1718
1719 @param pAdapter : [in] pointer to Adapter context
1720
1721 @return : VOS_STATUS_SUCCESS if succssful
1722 : other values if failure
1723
1724 ===========================================================================*/
1725VOS_STATUS hdd_wmm_adapter_init( hdd_adapter_t *pAdapter )
1726{
1727 hdd_wmm_ac_status_t *pAcStatus;
1728 WLANTL_ACEnumType acType;
1729
1730 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001731 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001732
1733 pAdapter->hddWmmStatus.wmmQap = VOS_FALSE;
1734 INIT_LIST_HEAD(&pAdapter->hddWmmStatus.wmmContextList);
Jeff Johnson295189b2012-06-20 16:38:30 -07001735
1736 for (acType = 0; acType < WLANTL_MAX_AC; acType++)
1737 {
1738 pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1739 pAcStatus->wmmAcAccessRequired = VOS_FALSE;
1740 pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
1741 pAcStatus->wmmAcAccessPending = VOS_FALSE;
1742 pAcStatus->wmmAcAccessFailed = VOS_FALSE;
1743 pAcStatus->wmmAcAccessGranted = VOS_FALSE;
1744 pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
1745 pAcStatus->wmmAcTspecValid = VOS_FALSE;
1746 pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
1747 }
Kiet Lamf040f472013-11-20 21:15:23 +05301748 // Invalid value(0xff) to indicate psb not configured through framework initially.
1749 pAdapter->configuredPsb = HDD_PSB_CFG_INVALID;
Jeff Johnson295189b2012-06-20 16:38:30 -07001750
1751 return VOS_STATUS_SUCCESS;
1752}
Madan Mohan Koyyalamudi70c52d32013-08-07 14:42:16 +05301753
1754/**============================================================================
1755 @brief hdd_wmm_adapter_clear() - Function which will clear the WMM status
1756 for all the ACs
1757
1758 @param pAdapter : [in] pointer to Adapter context
1759
1760 @return : VOS_STATUS_SUCCESS if succssful
1761 : other values if failure
1762
1763 ===========================================================================*/
1764VOS_STATUS hdd_wmm_adapter_clear( hdd_adapter_t *pAdapter )
1765{
1766 hdd_wmm_ac_status_t *pAcStatus;
1767 WLANTL_ACEnumType acType;
1768 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1769 "%s: Entered", __func__);
1770 for (acType = 0; acType < WLANTL_MAX_AC; acType++)
1771 {
1772 pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1773 pAcStatus->wmmAcAccessRequired = VOS_FALSE;
1774 pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
1775 pAcStatus->wmmAcAccessPending = VOS_FALSE;
1776 pAcStatus->wmmAcAccessFailed = VOS_FALSE;
1777 pAcStatus->wmmAcAccessGranted = VOS_FALSE;
1778 pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
1779 pAcStatus->wmmAcTspecValid = VOS_FALSE;
1780 pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
1781 }
1782 return VOS_STATUS_SUCCESS;
1783}
1784
Jeff Johnson295189b2012-06-20 16:38:30 -07001785/**============================================================================
1786 @brief hdd_wmm_close() - Function which will perform any necessary work to
1787 to clean up the WMM functionality prior to the kernel module unload
1788
1789 @param pAdapter : [in] pointer to adapter context
1790
1791 @return : VOS_STATUS_SUCCESS if succssful
1792 : other values if failure
1793
1794 ===========================================================================*/
1795VOS_STATUS hdd_wmm_adapter_close ( hdd_adapter_t* pAdapter )
1796{
1797 hdd_wmm_qos_context_t* pQosContext;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301798 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
1799 hdd_context_t *pHddCtx;
1800
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301801 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301802 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301803 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1804 FL("pVosContext is NULL"));
1805 return VOS_STATUS_E_FAILURE;
1806 }
1807
1808 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
1809 if (NULL == pHddCtx)
1810 {
1811 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301812 FL("HddCtx is NULL"));
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301813 return VOS_STATUS_E_FAILURE;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301814 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001815
1816 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001817 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001818
1819 // free any context records that we still have linked
1820 while (!list_empty(&pAdapter->hddWmmStatus.wmmContextList))
1821 {
1822 pQosContext = list_first_entry(&pAdapter->hddWmmStatus.wmmContextList,
1823 hdd_wmm_qos_context_t, node);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08001824#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07001825 hdd_wmm_disable_inactivity_timer(pQosContext);
1826#endif
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301827 mutex_lock(&pHddCtx->wmmLock);
Anand N Sunkad4b25a2f2014-11-13 16:01:08 +05301828 if (pQosContext->handle == HDD_WMM_HANDLE_IMPLICIT
1829 && pQosContext->magic == HDD_WMM_CTX_MAGIC)
1830 {
1831
Anand N Sunkad860e5ea2015-03-30 14:41:51 +05301832 vos_flush_work(&pQosContext->wmmAcSetupImplicitQos);
Anand N Sunkad4b25a2f2014-11-13 16:01:08 +05301833 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301834 mutex_unlock(&pHddCtx->wmmLock);
Anand N Sunkad860e5ea2015-03-30 14:41:51 +05301835
Jeff Johnson295189b2012-06-20 16:38:30 -07001836 hdd_wmm_free_context(pQosContext);
1837 }
1838
1839 return VOS_STATUS_SUCCESS;
1840}
1841
1842/**============================================================================
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301843 @brief hdd_is_dhcp_packet() - Function which will check OS packet for
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301844 DHCP packet
1845
1846 @param skb : [in] pointer to OS packet (sk_buff)
1847 @return : VOS_TRUE if the OS packet is DHCP packet
1848 : otherwise VOS_FALSE
1849 ===========================================================================*/
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301850v_BOOL_t hdd_is_dhcp_packet(struct sk_buff *skb)
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301851{
1852 if (*((u16*)((u8*)skb->data+34)) == DHCP_SOURCE_PORT ||
1853 *((u16*)((u8*)skb->data+34)) == DHCP_DESTINATION_PORT)
1854 return VOS_TRUE;
1855
1856 return VOS_FALSE;
1857}
1858
1859/**============================================================================
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301860 @brief hdd_skb_is_eapol_or_wai_packet() - Function which will check OS packet
1861 for Eapol/Wapi packet
1862
1863 @param skb : [in] pointer to OS packet (sk_buff)
1864 @return : VOS_TRUE if the OS packet is an Eapol or a Wapi packet
1865 : otherwise VOS_FALSE
1866 ===========================================================================*/
1867v_BOOL_t hdd_skb_is_eapol_or_wai_packet(struct sk_buff *skb)
1868{
1869 if ((*((u16*)((u8*)skb->data+HDD_ETHERTYPE_802_1_X_FRAME_OFFSET))
1870 == vos_cpu_to_be16(HDD_ETHERTYPE_802_1_X))
1871#ifdef FEATURE_WLAN_WAPI
1872 || (*((u16*)((u8*)skb->data+HDD_ETHERTYPE_802_1_X_FRAME_OFFSET))
1873 == vos_cpu_to_be16(HDD_ETHERTYPE_WAI))
1874#endif
1875 )
1876 return VOS_TRUE;
1877
1878 return VOS_FALSE;
1879}
1880
1881/**============================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07001882 @brief hdd_wmm_classify_pkt() - Function which will classify an OS packet
1883 into a WMM AC based on either 802.1Q or DSCP
1884
1885 @param pAdapter : [in] pointer to adapter context
1886 @param skb : [in] pointer to OS packet (sk_buff)
1887 @param pAcType : [out] pointer to WMM AC type of OS packet
1888
1889 @return : None
1890 ===========================================================================*/
1891v_VOID_t hdd_wmm_classify_pkt ( hdd_adapter_t* pAdapter,
1892 struct sk_buff *skb,
1893 WLANTL_ACEnumType* pAcType,
1894 sme_QosWmmUpType *pUserPri)
1895{
1896 unsigned char * pPkt;
1897 union generic_ethhdr *pHdr;
1898 struct iphdr *pIpHdr;
1899 unsigned char tos;
1900 unsigned char dscp;
1901 sme_QosWmmUpType userPri;
1902 WLANTL_ACEnumType acType;
1903
1904 // this code is executed for every packet therefore
1905 // all debug code is kept conditional
1906
1907#ifdef HDD_WMM_DEBUG
1908 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001909 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001910#endif // HDD_WMM_DEBUG
1911
1912 pPkt = skb->data;
1913 pHdr = (union generic_ethhdr *)pPkt;
1914
1915#ifdef HDD_WMM_DEBUG
1916 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1917 "%s: proto/length is 0x%04x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001918 __func__, pHdr->eth_II.h_proto);
Jeff Johnson295189b2012-06-20 16:38:30 -07001919#endif // HDD_WMM_DEBUG
1920
1921 if (HDD_WMM_CLASSIFICATION_DSCP == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
1922 {
1923 if (pHdr->eth_II.h_proto == htons(ETH_P_IP))
1924 {
1925 // case 1: Ethernet II IP packet
1926 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_II)];
1927 tos = pIpHdr->tos;
1928#ifdef HDD_WMM_DEBUG
1929 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1930 "%s: Ethernet II IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001931 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001932#endif // HDD_WMM_DEBUG
1933
1934 }
1935 else if ((ntohs(pHdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
1936 (pHdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
1937 (pHdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
1938 (pHdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1939 (pHdr->eth_8023.h_proto == htons(ETH_P_IP)))
1940 {
1941 // case 2: 802.3 LLC/SNAP IP packet
1942 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];
1943 tos = pIpHdr->tos;
1944#ifdef HDD_WMM_DEBUG
1945 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1946 "%s: 802.3 LLC/SNAP IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001947 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001948#endif // HDD_WMM_DEBUG
1949 }
1950 else if (pHdr->eth_II.h_proto == htons(ETH_P_8021Q))
1951 {
1952 // VLAN tagged
1953
1954 if (pHdr->eth_IIv.h_vlan_encapsulated_proto == htons(ETH_P_IP))
1955 {
1956 // case 3: Ethernet II vlan-tagged IP packet
1957 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_IIv)];
1958 tos = pIpHdr->tos;
1959#ifdef HDD_WMM_DEBUG
1960 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1961 "%s: Ethernet II VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001962 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001963#endif // HDD_WMM_DEBUG
1964 }
1965 else if ((ntohs(pHdr->eth_IIv.h_vlan_encapsulated_proto) < WLAN_MIN_PROTO) &&
1966 (pHdr->eth_8023v.h_snap.dsap == WLAN_SNAP_DSAP) &&
1967 (pHdr->eth_8023v.h_snap.ssap == WLAN_SNAP_SSAP) &&
1968 (pHdr->eth_8023v.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1969 (pHdr->eth_8023v.h_proto == htons(ETH_P_IP)))
1970 {
1971 // case 4: 802.3 LLC/SNAP vlan-tagged IP packet
1972 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023v)];
1973 tos = pIpHdr->tos;
1974#ifdef HDD_WMM_DEBUG
1975 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1976 "%s: 802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001977 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001978#endif // HDD_WMM_DEBUG
1979 }
1980 else
1981 {
1982 // default
1983#ifdef HDD_WMM_DEBUG
1984 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1985 "%s: VLAN tagged Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001986 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001987#endif // HDD_WMM_DEBUG
1988 tos = 0;
1989 }
1990 }
1991 else
1992 {
Hanumantha Reddy Pothulaee001fc2015-05-26 15:21:53 +05301993 v_BOOL_t toggleArpBDRates =
1994 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->toggleArpBDRates;
Jeff Johnson295189b2012-06-20 16:38:30 -07001995 // default
1996#ifdef HDD_WMM_DEBUG
1997 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1998 "%s: Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001999 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002000#endif // HDD_WMM_DEBUG
2001 //Give the highest priority to 802.1x packet
2002 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
2003 tos = 0xC0;
Hanumantha Reddy Pothulaee001fc2015-05-26 15:21:53 +05302004 else if (TRUE == toggleArpBDRates &&
2005 pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_ARP))
2006 {
2007 tos = TID3;
2008 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002009 else
2010 tos = 0;
2011 }
2012
2013 dscp = (tos>>2) & 0x3f;
Kumar Anand82c009f2014-05-29 00:29:42 -07002014 userPri = pAdapter->hddWmmDscpToUpMap[dscp];
2015
Jeff Johnson295189b2012-06-20 16:38:30 -07002016#ifdef HDD_WMM_DEBUG
2017 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2018 "%s: tos is %d, dscp is %d, up is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002019 __func__, tos, dscp, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07002020#endif // HDD_WMM_DEBUG
2021
2022 }
2023 else if (HDD_WMM_CLASSIFICATION_802_1Q == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
2024 {
2025 if (pHdr->eth_IIv.h_vlan_proto == htons(ETH_P_8021Q))
2026 {
2027 // VLAN tagged
2028 userPri = (ntohs(pHdr->eth_IIv.h_vlan_TCI)>>13) & 0x7;
2029#ifdef HDD_WMM_DEBUG
2030 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2031 "%s: Tagged frame, UP is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002032 __func__, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07002033#endif // HDD_WMM_DEBUG
2034 }
2035 else
2036 {
2037 // not VLAN tagged, use default
2038#ifdef HDD_WMM_DEBUG
2039 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2040 "%s: Untagged frame, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002041 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002042#endif // HDD_WMM_DEBUG
2043 //Give the highest priority to 802.1x packet
2044 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
2045 userPri = SME_QOS_WMM_UP_VO;
2046 else
2047 userPri = SME_QOS_WMM_UP_BE;
2048 }
2049 }
2050 else
2051 {
2052 // default
2053#ifdef HDD_WMM_DEBUG
2054 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2055 "%s: Unknown classification scheme, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002056 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002057#endif // HDD_WMM_DEBUG
2058 userPri = SME_QOS_WMM_UP_BE;
2059 }
2060
2061 acType = hddWmmUpToAcMap[userPri];
2062
2063#ifdef HDD_WMM_DEBUG
2064 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2065 "%s: UP is %d, AC is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002066 __func__, userPri, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002067#endif // HDD_WMM_DEBUG
2068
2069 *pUserPri = userPri;
2070 *pAcType = acType;
2071
2072 return;
2073}
2074
2075/**============================================================================
2076 @brief hdd_hostapd_select_quueue() - Function which will classify the packet
2077 according to linux qdisc expectation.
2078
2079
2080 @param dev : [in] pointer to net_device structure
2081 @param skb : [in] pointer to os packet
2082
2083 @return : Qdisc queue index
2084 ===========================================================================*/
2085v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb)
2086{
2087 WLANTL_ACEnumType ac;
2088 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
2089 v_USHORT_t queueIndex;
2090 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
2091 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
2092 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002093 v_U8_t STAId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302094 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2095 ptSapContext pSapCtx = NULL;
Mukul Sharmabd6b9482015-06-19 16:43:57 +05302096 int status = 0;
Mukul Sharma986109f2015-04-20 22:29:39 +05302097
Mukul Sharmabd6b9482015-06-19 16:43:57 +05302098 status = wlan_hdd_validate_context(pHddCtx);
2099 if (status !=0 )
2100 {
2101 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2102 FL("called during WDReset/unload"));
Mukul Sharma986109f2015-04-20 22:29:39 +05302103 skb->priority = SME_QOS_WMM_UP_BE;
2104 return HDD_LINUX_AC_BE;
2105 }
2106
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302107 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2108 if(pSapCtx == NULL){
Mukul Sharmabd6b9482015-06-19 16:43:57 +05302109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302110 FL("psapCtx is NULL"));
Nirav Shah7e3c8132015-06-22 23:51:42 +05302111 STAId = HDD_WLAN_INVALID_STA_ID;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302112 goto done;
2113 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002114 /*Get the Station ID*/
Nirav Shah7e3c8132015-06-22 23:51:42 +05302115 STAId = hdd_sta_id_find_from_mac_addr(pAdapter, pDestMacAddress);
2116 if (STAId == HDD_WLAN_INVALID_STA_ID) {
2117 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
2118 "%s: Failed to find right station", __func__);
2119 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07002120 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002121
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302122 spin_lock_bh( &pSapCtx->staInfo_lock );
2123 if (FALSE == vos_is_macaddr_equal(&pSapCtx->aStaInfo[STAId].macAddrSTA, pDestMacAddress))
Jeff Johnson295189b2012-06-20 16:38:30 -07002124 {
Agarwal Ashisha64c9542014-03-04 00:14:43 +05302125 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002126 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002127
Nirav Shah7e3c8132015-06-22 23:51:42 +05302128 STAId = HDD_WLAN_INVALID_STA_ID;
Jeff Johnson295189b2012-06-20 16:38:30 -07002129 goto release_lock;
2130 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302131 if (pSapCtx->aStaInfo[STAId].isUsed && pSapCtx->aStaInfo[STAId].isQosEnabled && (HDD_WMM_USER_MODE_NO_QOS != pHddCtx->cfg_ini->WmmMode))
Jeff Johnson295189b2012-06-20 16:38:30 -07002132 {
2133 /* Get the user priority from IP header & corresponding AC */
2134 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05302135 //If 3/4th of Tx queue is used then place the DHCP packet in VOICE AC queue
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302136 if (pSapCtx->aStaInfo[STAId].vosLowResource && hdd_is_dhcp_packet(skb))
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05302137 {
2138 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2139 "%s: Making priority of DHCP packet as VOICE", __func__);
2140 up = SME_QOS_WMM_UP_VO;
2141 ac = hddWmmUpToAcMap[up];
2142 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002143 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002144
2145release_lock:
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302146 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07002147done:
2148 skb->priority = up;
Mukul Sharmad82cb7d2014-07-03 14:53:30 +05302149 if(skb->priority < SME_QOS_WMM_UP_MAX)
2150 queueIndex = hddLinuxUpToAcMap[skb->priority];
2151 else
2152 {
2153 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2154 "%s: up=%d is going beyond max value", __func__, up);
2155 queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
2156 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002157
2158 return queueIndex;
2159}
2160
2161/**============================================================================
2162 @brief hdd_wmm_select_quueue() - Function which will classify the packet
2163 according to linux qdisc expectation.
2164
2165
2166 @param dev : [in] pointer to net_device structure
2167 @param skb : [in] pointer to os packet
2168
2169 @return : Qdisc queue index
2170 ===========================================================================*/
2171v_U16_t hdd_wmm_select_queue(struct net_device * dev, struct sk_buff *skb)
2172{
2173 WLANTL_ACEnumType ac;
Shailender Karmuchia734f332013-04-19 14:02:48 -07002174 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002175 v_USHORT_t queueIndex;
Jeff Johnson295189b2012-06-20 16:38:30 -07002176 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma6bb6cdd2015-06-19 17:23:23 +05302177 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2178 int status = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002179
Mukul Sharma6bb6cdd2015-06-19 17:23:23 +05302180 status = wlan_hdd_validate_context(pHddCtx);
2181 if (status !=0) {
Kiet Lam40009862014-02-13 12:33:22 -08002182 skb->priority = SME_QOS_WMM_UP_BE;
2183 return HDD_LINUX_AC_BE;
2184 }
2185
Shailender Karmuchia734f332013-04-19 14:02:48 -07002186 /*Get the Station ID*/
2187 if (WLAN_HDD_IBSS == pAdapter->device_mode)
2188 {
Shailender Karmuchia734f332013-04-19 14:02:48 -07002189 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
Nirav Shah7e3c8132015-06-22 23:51:42 +05302190 v_U8_t STAId;
Shailender Karmuchia734f332013-04-19 14:02:48 -07002191
Nirav Shah7e3c8132015-06-22 23:51:42 +05302192 STAId = hdd_sta_id_find_from_mac_addr(pAdapter, pDestMacAddress);
2193 if ((STAId == HDD_WLAN_INVALID_STA_ID) &&
2194 !vos_is_macaddr_broadcast( pDestMacAddress ) &&
2195 !vos_is_macaddr_group(pDestMacAddress))
Shailender Karmuchia734f332013-04-19 14:02:48 -07002196 {
Nirav Shah7e3c8132015-06-22 23:51:42 +05302197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnsonb9fb9ce2013-05-03 08:11:02 -07002198 "%s: Failed to find right station pDestMacAddress: "
2199 MAC_ADDRESS_STR , __func__,
2200 MAC_ADDR_ARRAY(pDestMacAddress->bytes));
Nirav Shah7e3c8132015-06-22 23:51:42 +05302201 goto done;
Shailender Karmuchia734f332013-04-19 14:02:48 -07002202 }
2203 }
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302204 /* All traffic will get equal opportuniy to transmit data frames. */
2205 /* Get the user priority from IP header & corresponding AC */
2206 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302207
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302208 /* If 3/4th of BE AC Tx queue is full,
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302209 * then place the DHCP packet in VOICE AC queue.
2210 * Doing this for IBSS alone, since for STA interface
2211 * types, these packets will be queued to the new queue.
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302212 */
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302213 if ((WLAN_HDD_IBSS == pAdapter->device_mode) &&
2214 pAdapter->isVosLowResource && hdd_is_dhcp_packet(skb))
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302215 {
2216 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2217 "%s: BestEffort Tx Queue is 3/4th full"
2218 " Make DHCP packet's pri as VO", __func__);
2219 up = SME_QOS_WMM_UP_VO;
2220 ac = hddWmmUpToAcMap[up];
Jeff Johnson295189b2012-06-20 16:38:30 -07002221 }
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302222
Shailender Karmuchia734f332013-04-19 14:02:48 -07002223done:
Jeff Johnson295189b2012-06-20 16:38:30 -07002224 skb->priority = up;
Mukul Sharmad82cb7d2014-07-03 14:53:30 +05302225 if(skb->priority < SME_QOS_WMM_UP_MAX)
2226 queueIndex = hddLinuxUpToAcMap[skb->priority];
2227 else
2228 {
2229 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2230 "%s: up=%d is going beyond max value", __func__, up);
2231 queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
2232 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002233
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302234 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
2235 (hdd_is_dhcp_packet(skb) ||
2236 hdd_skb_is_eapol_or_wai_packet(skb)))
2237 {
2238 /* If the packet is a DHCP packet or a Eapol packet or
2239 * a Wapi packet, then queue it to the new queue for
2240 * STA interfaces alone.
2241 */
2242 queueIndex = WLANTL_AC_HIGH_PRIO;
2243 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2244 "%s: up=%d QIndex:%d", __func__, up, queueIndex);
2245 }
2246
Jeff Johnson295189b2012-06-20 16:38:30 -07002247 return queueIndex;
2248}
2249
Kiet Lamf040f472013-11-20 21:15:23 +05302250/**==========================================================================
2251 @brief hdd_wmm_acquire_access_required() - Function which will determine
2252 acquire admittance for a WMM AC is required or not based on psb configuration
2253 done in framework
2254
2255 @param pAdapter : [in] pointer to adapter structure
2256
2257 @param acType : [in] WMM AC type of OS packet
2258
2259 @return : void
2260 ===========================================================================*/
2261void hdd_wmm_acquire_access_required(hdd_adapter_t *pAdapter,
2262 WLANTL_ACEnumType acType)
2263{
2264/* Each bit in the LSB nibble indicates 1 AC.
2265 * Clearing the particular bit in LSB nibble to indicate
2266 * access required
2267 */
2268 switch(acType)
2269 {
2270 case WLANTL_AC_BK:
2271 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BK_CHANGED_MASK; /* clear first bit */
2272 break;
2273 case WLANTL_AC_BE:
2274 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BE_CHANGED_MASK; /* clear second bit */
2275 break;
2276 case WLANTL_AC_VI:
2277 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VI_CHANGED_MASK; /* clear third bit */
2278 break;
2279 case WLANTL_AC_VO:
2280 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VO_CHANGED_MASK; /* clear fourth bit */
2281 break;
2282 default:
2283 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2284 "%s: Invalid AC Type", __func__);
2285 break;
2286 }
2287}
2288
Jeff Johnson295189b2012-06-20 16:38:30 -07002289/**============================================================================
2290 @brief hdd_wmm_acquire_access() - Function which will attempt to acquire
2291 admittance for a WMM AC
2292
2293 @param pAdapter : [in] pointer to adapter context
2294 @param acType : [in] WMM AC type of OS packet
2295 @param pGranted : [out] pointer to boolean flag when indicates if access
2296 has been granted or not
2297
2298 @return : VOS_STATUS_SUCCESS if succssful
2299 : other values if failure
2300 ===========================================================================*/
2301VOS_STATUS hdd_wmm_acquire_access( hdd_adapter_t* pAdapter,
2302 WLANTL_ACEnumType acType,
2303 v_BOOL_t * pGranted )
2304{
2305 hdd_wmm_qos_context_t *pQosContext;
2306
2307 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002308 "%s: Entered for AC %d", __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002309
2310 if (!hdd_wmm_is_active(pAdapter) || !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
2311 {
2312 // either we don't want QoS or the AP doesn't support QoS
2313 // or we don't want to do implicit QoS
2314 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002315 "%s: QoS not configured on both ends ", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002316
2317 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2318 *pGranted = VOS_TRUE;
2319 return VOS_STATUS_SUCCESS;
2320 }
2321
2322 // do we already have an implicit QoS request pending for this AC?
2323 if ((pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded) ||
2324 (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessPending))
2325 {
2326 // request already pending so we need to wait for that response
2327 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2328 "%s: Implicit QoS for TL AC %d already scheduled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002329 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002330
2331 *pGranted = VOS_FALSE;
2332 return VOS_STATUS_SUCCESS;
2333 }
2334
2335 // did we already fail to establish implicit QoS for this AC?
2336 // (if so, access should have been granted when the failure was handled)
2337 if (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessFailed)
2338 {
2339 // request previously failed
2340 // allow access, but we'll be downgraded
2341 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2342 "%s: Implicit QoS for TL AC %d previously failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002343 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002344
2345 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2346 *pGranted = VOS_TRUE;
2347 return VOS_STATUS_SUCCESS;
2348 }
2349
2350 // we need to establish implicit QoS
2351 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2352 "%s: Need to schedule implicit QoS for TL AC %d, pAdapter is %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002353 __func__, acType, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002354
2355 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded = VOS_TRUE;
2356
Mohit Khanna217ea8d2012-09-11 17:42:42 -07002357 pQosContext = kmalloc(sizeof(*pQosContext), GFP_ATOMIC);
Jeff Johnson295189b2012-06-20 16:38:30 -07002358 if (NULL == pQosContext)
2359 {
2360 // no memory for QoS context. Nothing we can do but let data flow
2361 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002362 "%s: Unable to allocate context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002363 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2364 *pGranted = VOS_TRUE;
2365 return VOS_STATUS_SUCCESS;
2366 }
2367
2368 pQosContext->acType = acType;
2369 pQosContext->pAdapter = pAdapter;
2370 pQosContext->qosFlowId = 0;
2371 pQosContext->handle = HDD_WMM_HANDLE_IMPLICIT;
2372 pQosContext->magic = HDD_WMM_CTX_MAGIC;
Anand N Sunkaddc63c792015-06-03 14:33:24 +05302373 vos_init_work(&pQosContext->wmmAcSetupImplicitQos,
Jeff Johnson295189b2012-06-20 16:38:30 -07002374 hdd_wmm_do_implicit_qos);
2375
2376 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2377 "%s: Scheduling work for AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002378 __func__, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002379
2380 schedule_work(&pQosContext->wmmAcSetupImplicitQos);
2381
2382 // caller will need to wait until the work takes place and
2383 // TSPEC negotiation completes
2384 *pGranted = VOS_FALSE;
2385 return VOS_STATUS_SUCCESS;
2386}
2387
2388/**============================================================================
2389 @brief hdd_wmm_assoc() - Function which will handle the housekeeping
2390 required by WMM when association takes place
2391
2392 @param pAdapter : [in] pointer to adapter context
2393 @param pRoamInfo: [in] pointer to roam information
2394 @param eBssType : [in] type of BSS
2395
2396 @return : VOS_STATUS_SUCCESS if succssful
2397 : other values if failure
2398 ===========================================================================*/
2399VOS_STATUS hdd_wmm_assoc( hdd_adapter_t* pAdapter,
2400 tCsrRoamInfo *pRoamInfo,
2401 eCsrRoamBssType eBssType )
2402{
2403 tANI_U8 uapsdMask;
2404 VOS_STATUS status;
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002405 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002406
2407 // when we associate we need to notify TL if it needs to enable
2408 // UAPSD for any access categories
2409
2410 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002411 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002412
2413 if (pRoamInfo->fReassocReq)
2414 {
2415 // when we reassociate we should continue to use whatever
2416 // parameters were previously established. if we are
2417 // reassociating due to a U-APSD change for a particular
2418 // Access Category, then the change will be communicated
2419 // to HDD via the QoS callback associated with the given
2420 // flow, and U-APSD parameters will be updated there
2421
2422 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002423 "%s: Reassoc so no work, Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002424
2425 return VOS_STATUS_SUCCESS;
2426 }
2427
2428 // get the negotiated UAPSD Mask
2429 uapsdMask = pRoamInfo->u.pConnectedProfile->modifyProfileFields.uapsd_mask;
2430
2431 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002432 "%s: U-APSD mask is 0x%02x", __func__, (int) uapsdMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002433
2434 if (uapsdMask & HDD_AC_VO)
2435 {
2436 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2437 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2438 WLANTL_AC_VO,
2439 7,
2440 7,
2441 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv,
2442 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv,
2443 WLANTL_BI_DIR );
2444
2445 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2446 }
2447
2448 if (uapsdMask & HDD_AC_VI)
2449 {
2450 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2451 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2452 WLANTL_AC_VI,
2453 5,
2454 5,
2455 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv,
2456 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv,
2457 WLANTL_BI_DIR );
2458
2459 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2460 }
2461
2462 if (uapsdMask & HDD_AC_BK)
2463 {
2464 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2465 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2466 WLANTL_AC_BK,
2467 2,
2468 2,
2469 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv,
2470 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv,
2471 WLANTL_BI_DIR );
2472
2473 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2474 }
2475
2476 if (uapsdMask & HDD_AC_BE)
2477 {
2478 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2479 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2480 WLANTL_AC_BE,
2481 3,
2482 3,
2483 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv,
2484 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv,
2485 WLANTL_BI_DIR );
2486
2487 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2488 }
Kumar Anand82c009f2014-05-29 00:29:42 -07002489
2490 status = sme_UpdateDSCPtoUPMapping(pHddCtx->hHal,
2491 pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId);
2492
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002493 if (!VOS_IS_STATUS_SUCCESS( status ))
2494 {
Kumar Anand82c009f2014-05-29 00:29:42 -07002495 hdd_wmm_init( pAdapter );
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002496 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002497
2498 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002499 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002500
2501 return VOS_STATUS_SUCCESS;
2502}
2503
2504
2505
2506static const v_U8_t acmMaskBit[WLANTL_MAX_AC] =
2507 {
2508 0x4, /* WLANTL_AC_BK */
2509 0x8, /* WLANTL_AC_BE */
2510 0x2, /* WLANTL_AC_VI */
2511 0x1 /* WLANTL_AC_VO */
2512 };
2513
2514/**============================================================================
2515 @brief hdd_wmm_connect() - Function which will handle the housekeeping
2516 required by WMM when a connection is established
2517
2518 @param pAdapter : [in] pointer to adapter context
2519 @param pRoamInfo: [in] pointer to roam information
2520 @param eBssType : [in] type of BSS
2521
2522 @return : VOS_STATUS_SUCCESS if succssful
2523 : other values if failure
2524 ===========================================================================*/
2525VOS_STATUS hdd_wmm_connect( hdd_adapter_t* pAdapter,
2526 tCsrRoamInfo *pRoamInfo,
2527 eCsrRoamBssType eBssType )
2528{
2529 int ac;
2530 v_BOOL_t qap;
2531 v_BOOL_t qosConnection;
2532 v_U8_t acmMask;
2533
2534 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002535 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002536
2537 if ((eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) &&
2538 pRoamInfo &&
2539 pRoamInfo->u.pConnectedProfile)
2540 {
2541 qap = pRoamInfo->u.pConnectedProfile->qap;
2542 qosConnection = pRoamInfo->u.pConnectedProfile->qosConnection;
2543 acmMask = pRoamInfo->u.pConnectedProfile->acm_mask;
2544 }
2545 else
2546 {
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05302547 /* TODO: if a non-qos IBSS peer joins the group make qap and qosConnection false.
2548 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002549 qap = VOS_TRUE;
2550 qosConnection = VOS_TRUE;
2551 acmMask = 0x0;
2552 }
2553
2554 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2555 "%s: qap is %d, qosConnection is %d, acmMask is 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002556 __func__, qap, qosConnection, acmMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002557
2558 pAdapter->hddWmmStatus.wmmQap = qap;
2559 pAdapter->hddWmmStatus.wmmQosConnection = qosConnection;
2560
2561 for (ac = 0; ac < WLANTL_MAX_AC; ac++)
2562 {
2563 if (qap &&
2564 qosConnection &&
2565 (acmMask & acmMaskBit[ac]))
2566 {
2567 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2568 "%s: ac %d on",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002569 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002570
2571 // admission is required
2572 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_TRUE;
Padma, Santhosh Kumar73f22252015-05-05 11:59:24 +05302573 //Mark wmmAcAccessAllowed as True if implicit Qos is disabled as there
2574 //is no need to hold packets in queue during hdd_tx_fetch_packet_cbk
2575 if (!(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
2576 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed =
2577 VOS_TRUE;
2578 else
2579 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed =
2580 VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002581 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessGranted = VOS_FALSE;
Mukul Sharma74a01e52014-07-21 15:14:23 +05302582
2583 /* Making TSPEC invalid here so downgrading can be happen while roaming
2584 * It is expected this will be SET in hdd_wmm_sme_callback,once sme is
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302585 * done with the AddTspec.Here we avoid 11r and ccx based association.
2586 This change is done only when reassoc to different AP.
Mukul Sharma74a01e52014-07-21 15:14:23 +05302587 */
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302588 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2589 FL( "fReassocReq = %d"
2590#if defined (FEATURE_WLAN_ESE)
2591 "isESEAssoc = %d"
2592#endif
2593#if defined (WLAN_FEATURE_VOWIFI_11R)
2594 "is11rAssoc = %d"
2595#endif
2596 ),
2597 pRoamInfo->fReassocReq
2598#if defined (FEATURE_WLAN_ESE)
2599 ,pRoamInfo->isESEAssoc
2600#endif
2601#if defined (WLAN_FEATURE_VOWIFI_11R)
2602 ,pRoamInfo->is11rAssoc
2603#endif
2604 );
2605
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302606 if ( !pRoamInfo->fReassocReq
Mukul Sharma74a01e52014-07-21 15:14:23 +05302607#if defined (WLAN_FEATURE_VOWIFI_11R)
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302608 &&
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302609 !pRoamInfo->is11rAssoc
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302610#endif
Mukul Sharma74a01e52014-07-21 15:14:23 +05302611#if defined (FEATURE_WLAN_ESE)
2612 &&
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302613 !pRoamInfo->isESEAssoc
Mukul Sharma74a01e52014-07-21 15:14:23 +05302614#endif
2615 )
Mukul Sharma74a01e52014-07-21 15:14:23 +05302616 {
2617 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcTspecValid = VOS_FALSE;
2618 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002619 }
2620 else
2621 {
2622 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2623 "%s: ac %d off",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002624 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002625 // admission is not required so access is allowed
2626 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_FALSE;
2627 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_TRUE;
2628 }
2629
2630 }
2631
2632 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002633 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002634
2635 return VOS_STATUS_SUCCESS;
2636}
2637
2638/**============================================================================
2639 @brief hdd_wmm_get_uapsd_mask() - Function which will calculate the
2640 initial value of the UAPSD mask based upon the device configuration
2641
2642 @param pAdapter : [in] pointer to adapter context
2643 @param pUapsdMask: [in] pointer to where the UAPSD Mask is to be stored
2644
2645 @return : VOS_STATUS_SUCCESS if succssful
2646 : other values if failure
2647 ===========================================================================*/
2648VOS_STATUS hdd_wmm_get_uapsd_mask( hdd_adapter_t* pAdapter,
2649 tANI_U8 *pUapsdMask )
2650{
2651 tANI_U8 uapsdMask;
2652
2653 if (HDD_WMM_USER_MODE_NO_QOS == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
2654 {
2655 // no QOS then no UAPSD
2656 uapsdMask = 0;
2657 }
2658 else
2659 {
2660 // start with the default mask
2661 uapsdMask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
2662
2663 // disable UAPSD for any ACs with a 0 Service Interval
2664 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv == 0 )
2665 {
2666 uapsdMask &= ~HDD_AC_VO;
2667 }
2668
2669 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv == 0 )
2670 {
2671 uapsdMask &= ~HDD_AC_VI;
2672 }
2673
2674 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv == 0 )
2675 {
2676 uapsdMask &= ~HDD_AC_BK;
2677 }
2678
2679 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv == 0 )
2680 {
2681 uapsdMask &= ~HDD_AC_BE;
2682 }
2683 }
2684
2685 // return calculated mask
2686 *pUapsdMask = uapsdMask;
2687 return VOS_STATUS_SUCCESS;
2688}
2689
2690
2691/**============================================================================
2692 @brief hdd_wmm_is_active() - Function which will determine if WMM is
2693 active on the current connection
2694
2695 @param pAdapter : [in] pointer to adapter context
2696
2697 @return : VOS_TRUE if WMM is enabled
2698 : VOS_FALSE if WMM is not enabled
2699 ===========================================================================*/
2700v_BOOL_t hdd_wmm_is_active( hdd_adapter_t* pAdapter )
2701{
2702 if ((!pAdapter->hddWmmStatus.wmmQosConnection) ||
2703 (!pAdapter->hddWmmStatus.wmmQap))
2704 {
2705 return VOS_FALSE;
2706 }
2707 else
2708 {
2709 return VOS_TRUE;
2710 }
2711}
2712
2713/**============================================================================
2714 @brief hdd_wmm_addts() - Function which will add a traffic spec at the
2715 request of an application
2716
2717 @param pAdapter : [in] pointer to adapter context
2718 @param handle : [in] handle to uniquely identify a TS
2719 @param pTspec : [in] pointer to the traffic spec
2720
2721 @return : HDD_WLAN_WMM_STATUS_*
2722 ===========================================================================*/
2723hdd_wlan_wmm_status_e hdd_wmm_addts( hdd_adapter_t* pAdapter,
2724 v_U32_t handle,
2725 sme_QosWmmTspecInfo* pTspec )
2726{
2727 hdd_wmm_qos_context_t *pQosContext;
2728 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2729#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2730 sme_QosStatusType smeStatus;
2731#endif
2732 v_BOOL_t found = VOS_FALSE;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302733 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
2734 hdd_context_t *pHddCtx;
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302735
2736 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302737 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302738 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2739 FL("pVosContext is NULL"));
2740 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302741 }
2742
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302743 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
2744 if (NULL == pHddCtx)
2745 {
2746 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2747 FL("HddCtx is NULL"));
2748 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2749 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002750
2751 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002752 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002753
2754 // see if a context already exists with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302755 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002756 list_for_each_entry(pQosContext,
2757 &pAdapter->hddWmmStatus.wmmContextList,
2758 node)
2759 {
2760 if (pQosContext->handle == handle)
2761 {
2762 found = VOS_TRUE;
2763 break;
2764 }
2765 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302766 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002767 if (found)
2768 {
2769 // record with that handle already exists
2770 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2771 "%s: Record already exists with handle 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002772 __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002773
2774 /* Application is trying to modify some of the Tspec params. Allow it */
2775 smeStatus = sme_QosModifyReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2776 pTspec,
2777 pQosContext->qosFlowId);
2778
2779 // need to check the return value and act appropriately
2780 switch (smeStatus)
2781 {
2782 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
2783 status = HDD_WLAN_WMM_STATUS_MODIFY_PENDING;
2784 break;
2785 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2786 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
2787 break;
2788 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
2789 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
2790 break;
2791 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
2792 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
2793 break;
2794 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
2795 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2796 break;
2797 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2798 status = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2799 break;
2800 default:
2801 // we didn't get back one of the SME_QOS_STATUS_MODIFY_* status codes
2802 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002803 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002804 VOS_ASSERT(0);
2805 return HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2806 }
2807
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302808 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05302809 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
2810 {
2811 pQosContext->lastStatus = status;
2812 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302813 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002814 return status;
2815 }
2816
2817 pQosContext = kmalloc(sizeof(*pQosContext), GFP_KERNEL);
2818 if (NULL == pQosContext)
2819 {
2820 // no memory for QoS context. Nothing we can do
2821 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002822 "%s: Unable to allocate QoS context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002823 return HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE;
2824 }
2825
2826 // we assume the tspec has already been validated by the caller
2827
2828 pQosContext->handle = handle;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08002829 if (pTspec->ts_info.up < HDD_WMM_UP_TO_AC_MAP_SIZE)
2830 pQosContext->acType = hddWmmUpToAcMap[pTspec->ts_info.up];
2831 else {
2832 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2833 "%s: ts_info.up (%d) larger than max value (%d), "
2834 "use default acType (%d)",
2835 __func__, pTspec->ts_info.up,
2836 HDD_WMM_UP_TO_AC_MAP_SIZE - 1, hddWmmUpToAcMap[0]);
2837 pQosContext->acType = hddWmmUpToAcMap[0];
2838 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302839
Jeff Johnson295189b2012-06-20 16:38:30 -07002840 pQosContext->pAdapter = pAdapter;
2841 pQosContext->qosFlowId = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002842
2843 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2844 "%s: Setting up QoS, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002845 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002846
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302847 mutex_lock(&pHddCtx->wmmLock);
2848 pQosContext->magic = HDD_WMM_CTX_MAGIC;
Jeff Johnson295189b2012-06-20 16:38:30 -07002849 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302850 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002851
2852#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2853 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2854 pAdapter->sessionId,
2855 pTspec,
2856 hdd_wmm_sme_callback,
2857 pQosContext,
2858 pTspec->ts_info.up,
2859 &pQosContext->qosFlowId);
2860
2861 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2862 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002863 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002864
2865 // need to check the return value and act appropriately
2866 switch (smeStatus)
2867 {
2868 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
2869 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2870 break;
2871 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2872 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
2873 break;
2874 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
2875 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
2876 break;
2877 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
2878 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2879 break;
2880 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
2881 hdd_wmm_free_context(pQosContext);
2882 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
2883 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
2884 // we can't tell the difference between when a request fails because
2885 // AP rejected it versus when SME encounterd an internal error
2886 hdd_wmm_free_context(pQosContext);
2887 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2888 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2889 hdd_wmm_free_context(pQosContext);
2890 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2891 default:
2892 // we didn't get back one of the SME_QOS_STATUS_SETUP_* status codes
2893 hdd_wmm_free_context(pQosContext);
2894 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002895 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002896 VOS_ASSERT(0);
2897 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2898 }
2899#endif
2900
2901 // we were successful, save the status
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302902 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05302903 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
2904 {
2905 pQosContext->lastStatus = status;
2906 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302907 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002908
2909 return status;
2910}
2911
2912/**============================================================================
2913 @brief hdd_wmm_delts() - Function which will delete a traffic spec at the
2914 request of an application
2915
2916 @param pAdapter : [in] pointer to adapter context
2917 @param handle : [in] handle to uniquely identify a TS
2918
2919 @return : HDD_WLAN_WMM_STATUS_*
2920 ===========================================================================*/
2921hdd_wlan_wmm_status_e hdd_wmm_delts( hdd_adapter_t* pAdapter,
2922 v_U32_t handle )
2923{
2924 hdd_wmm_qos_context_t *pQosContext;
2925 v_BOOL_t found = VOS_FALSE;
2926 WLANTL_ACEnumType acType = 0;
2927 v_U32_t qosFlowId = 0;
2928 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2929#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2930 sme_QosStatusType smeStatus;
2931#endif
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302932 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
2933 hdd_context_t *pHddCtx;
2934
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302935 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302936 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302937 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2938 FL("pVosContext is NULL"));
2939 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2940 }
2941
2942 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
2943 if (NULL == pHddCtx)
2944 {
2945 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302946 FL("HddCtx is NULL"));
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302947 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302948 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002949
2950 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002951 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002952
2953 // locate the context with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302954 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002955 list_for_each_entry(pQosContext,
2956 &pAdapter->hddWmmStatus.wmmContextList,
2957 node)
2958 {
2959 if (pQosContext->handle == handle)
2960 {
2961 found = VOS_TRUE;
2962 acType = pQosContext->acType;
2963 qosFlowId = pQosContext->qosFlowId;
2964 break;
2965 }
2966 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302967 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002968
2969 if (VOS_FALSE == found)
2970 {
2971 // we didn't find the handle
2972 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002973 "%s: handle 0x%x not found", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002974 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2975 }
2976
2977
2978 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2979 "%s: found handle 0x%x, flow %d, AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002980 __func__, handle, qosFlowId, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002981
2982#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2983 smeStatus = sme_QosReleaseReq( WLAN_HDD_GET_HAL_CTX(pAdapter), qosFlowId );
2984
2985 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2986 "%s: SME flow %d released, SME status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002987 __func__, qosFlowId, smeStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07002988
2989 switch(smeStatus)
2990 {
2991 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
2992 // this flow is the only one on that AC, so go ahead and update
2993 // our TSPEC state for the AC
2994 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcTspecValid = VOS_FALSE;
2995
2996 // need to tell TL to stop trigger timer, etc
2997 hdd_wmm_disable_tl_uapsd(pQosContext);
2998
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002999#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07003000 // disable the inactivity timer
3001 hdd_wmm_disable_inactivity_timer(pQosContext);
3002#endif
3003 // we are done with this context
3004 hdd_wmm_free_context(pQosContext);
3005
3006 // SME must not fire any more callbacks for this flow since the context
3007 // is no longer valid
3008
3009 return HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
3010
3011 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
3012 // do nothing as we will get a response from SME
3013 status = HDD_WLAN_WMM_STATUS_RELEASE_PENDING;
3014 break;
3015
3016 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
3017 // nothing we can do with the existing flow except leave it
3018 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
3019 break;
3020
3021 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
3022 // nothing we can do with the existing flow except leave it
3023 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
3024
3025 default:
3026 // we didn't get back one of the SME_QOS_STATUS_RELEASE_* status codes
3027 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003028 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07003029 VOS_ASSERT(0);
3030 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
3031 }
3032
3033#endif
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303034 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05303035 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
3036 {
3037 pQosContext->lastStatus = status;
3038 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303039 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003040 return status;
3041}
3042
3043/**============================================================================
3044 @brief hdd_wmm_checkts() - Function which will return the status of a traffic
3045 spec at the request of an application
3046
3047 @param pAdapter : [in] pointer to adapter context
3048 @param handle : [in] handle to uniquely identify a TS
3049
3050 @return : HDD_WLAN_WMM_STATUS_*
3051 ===========================================================================*/
3052hdd_wlan_wmm_status_e hdd_wmm_checkts( hdd_adapter_t* pAdapter,
3053 v_U32_t handle )
3054{
3055 hdd_wmm_qos_context_t *pQosContext;
3056 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303057 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
3058 hdd_context_t *pHddCtx;
3059
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303060 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303061 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303062 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
3063 FL("pVosContext is NULL"));
3064 return HDD_WLAN_WMM_STATUS_LOST;
3065 }
3066
3067 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
3068 if (NULL == pHddCtx)
3069 {
3070 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303071 FL("HddCtx is NULL"));
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303072 return HDD_WLAN_WMM_STATUS_LOST;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303073 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003074
3075 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003076 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07003077
3078 // locate the context with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303079 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003080 list_for_each_entry(pQosContext,
3081 &pAdapter->hddWmmStatus.wmmContextList,
3082 node)
3083 {
3084 if (pQosContext->handle == handle)
3085 {
3086 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
3087 "%s: found handle 0x%x, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003088 __func__, handle, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07003089
3090 status = pQosContext->lastStatus;
3091 break;
3092 }
3093 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303094 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003095 return status;
3096}