blob: 1861e6d381951e90dac32a00d11499ec538a34ca [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;
2094 v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302095 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2096 ptSapContext pSapCtx = NULL;
Mukul Sharmabd6b9482015-06-19 16:43:57 +05302097 int status = 0;
Mukul Sharma986109f2015-04-20 22:29:39 +05302098
Mukul Sharmabd6b9482015-06-19 16:43:57 +05302099 status = wlan_hdd_validate_context(pHddCtx);
2100 if (status !=0 )
2101 {
2102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2103 FL("called during WDReset/unload"));
Mukul Sharma986109f2015-04-20 22:29:39 +05302104 skb->priority = SME_QOS_WMM_UP_BE;
2105 return HDD_LINUX_AC_BE;
2106 }
2107
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302108 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2109 if(pSapCtx == NULL){
Mukul Sharmabd6b9482015-06-19 16:43:57 +05302110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302111 FL("psapCtx is NULL"));
2112 *pSTAId = HDD_WLAN_INVALID_STA_ID;
2113 goto done;
2114 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002115 /*Get the Station ID*/
Jeff Johnson295189b2012-06-20 16:38:30 -07002116 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &STAId))
2117 {
Agarwal Ashisha64c9542014-03-04 00:14:43 +05302118 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002119 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002120 *pSTAId = HDD_WLAN_INVALID_STA_ID;
2121 goto done;
2122 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002123
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302124 spin_lock_bh( &pSapCtx->staInfo_lock );
2125 if (FALSE == vos_is_macaddr_equal(&pSapCtx->aStaInfo[STAId].macAddrSTA, pDestMacAddress))
Jeff Johnson295189b2012-06-20 16:38:30 -07002126 {
Agarwal Ashisha64c9542014-03-04 00:14:43 +05302127 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002128 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002129
2130 *pSTAId = HDD_WLAN_INVALID_STA_ID;
2131 goto release_lock;
2132 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302133 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 -07002134 {
2135 /* Get the user priority from IP header & corresponding AC */
2136 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05302137 //If 3/4th of Tx queue is used then place the DHCP packet in VOICE AC queue
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302138 if (pSapCtx->aStaInfo[STAId].vosLowResource && hdd_is_dhcp_packet(skb))
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05302139 {
2140 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2141 "%s: Making priority of DHCP packet as VOICE", __func__);
2142 up = SME_QOS_WMM_UP_VO;
2143 ac = hddWmmUpToAcMap[up];
2144 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002145 }
2146 *pSTAId = STAId;
2147
2148release_lock:
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302149 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07002150done:
2151 skb->priority = up;
Mukul Sharmad82cb7d2014-07-03 14:53:30 +05302152 if(skb->priority < SME_QOS_WMM_UP_MAX)
2153 queueIndex = hddLinuxUpToAcMap[skb->priority];
2154 else
2155 {
2156 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2157 "%s: up=%d is going beyond max value", __func__, up);
2158 queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
2159 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002160
2161 return queueIndex;
2162}
2163
2164/**============================================================================
2165 @brief hdd_wmm_select_quueue() - Function which will classify the packet
2166 according to linux qdisc expectation.
2167
2168
2169 @param dev : [in] pointer to net_device structure
2170 @param skb : [in] pointer to os packet
2171
2172 @return : Qdisc queue index
2173 ===========================================================================*/
2174v_U16_t hdd_wmm_select_queue(struct net_device * dev, struct sk_buff *skb)
2175{
2176 WLANTL_ACEnumType ac;
Shailender Karmuchia734f332013-04-19 14:02:48 -07002177 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002178 v_USHORT_t queueIndex;
Jeff Johnson295189b2012-06-20 16:38:30 -07002179 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2180
Siddharth Bhal4f6694f2015-02-27 17:24:21 +05302181 if (vos_is_logp_in_progress(VOS_MODULE_ID_HDD, NULL)) {
Kiet Lam40009862014-02-13 12:33:22 -08002182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2183 FL("called during WDReset"));
2184 skb->priority = SME_QOS_WMM_UP_BE;
2185 return HDD_LINUX_AC_BE;
2186 }
2187
Shailender Karmuchia734f332013-04-19 14:02:48 -07002188 /*Get the Station ID*/
2189 if (WLAN_HDD_IBSS == pAdapter->device_mode)
2190 {
2191 v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
2192 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
2193
2194 if ( VOS_STATUS_SUCCESS !=
2195 hdd_Ibss_GetStaId(&pAdapter->sessionCtx.station,
2196 pDestMacAddress, pSTAId))
2197 {
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05302198 *pSTAId = HDD_WLAN_INVALID_STA_ID;
2199 if ( !vos_is_macaddr_broadcast( pDestMacAddress ) &&
2200 !vos_is_macaddr_group(pDestMacAddress))
2201 {
2202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnsonb9fb9ce2013-05-03 08:11:02 -07002203 "%s: Failed to find right station pDestMacAddress: "
2204 MAC_ADDRESS_STR , __func__,
2205 MAC_ADDR_ARRAY(pDestMacAddress->bytes));
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05302206 goto done;
2207 }
Shailender Karmuchia734f332013-04-19 14:02:48 -07002208 }
2209 }
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302210 /* All traffic will get equal opportuniy to transmit data frames. */
2211 /* Get the user priority from IP header & corresponding AC */
2212 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302213
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302214 /* If 3/4th of BE AC Tx queue is full,
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302215 * then place the DHCP packet in VOICE AC queue.
2216 * Doing this for IBSS alone, since for STA interface
2217 * types, these packets will be queued to the new queue.
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302218 */
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302219 if ((WLAN_HDD_IBSS == pAdapter->device_mode) &&
2220 pAdapter->isVosLowResource && hdd_is_dhcp_packet(skb))
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302221 {
2222 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2223 "%s: BestEffort Tx Queue is 3/4th full"
2224 " Make DHCP packet's pri as VO", __func__);
2225 up = SME_QOS_WMM_UP_VO;
2226 ac = hddWmmUpToAcMap[up];
Jeff Johnson295189b2012-06-20 16:38:30 -07002227 }
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302228
Shailender Karmuchia734f332013-04-19 14:02:48 -07002229done:
Jeff Johnson295189b2012-06-20 16:38:30 -07002230 skb->priority = up;
Mukul Sharmad82cb7d2014-07-03 14:53:30 +05302231 if(skb->priority < SME_QOS_WMM_UP_MAX)
2232 queueIndex = hddLinuxUpToAcMap[skb->priority];
2233 else
2234 {
2235 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2236 "%s: up=%d is going beyond max value", __func__, up);
2237 queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
2238 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002239
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302240 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
2241 (hdd_is_dhcp_packet(skb) ||
2242 hdd_skb_is_eapol_or_wai_packet(skb)))
2243 {
2244 /* If the packet is a DHCP packet or a Eapol packet or
2245 * a Wapi packet, then queue it to the new queue for
2246 * STA interfaces alone.
2247 */
2248 queueIndex = WLANTL_AC_HIGH_PRIO;
2249 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2250 "%s: up=%d QIndex:%d", __func__, up, queueIndex);
2251 }
2252
Jeff Johnson295189b2012-06-20 16:38:30 -07002253 return queueIndex;
2254}
2255
Kiet Lamf040f472013-11-20 21:15:23 +05302256/**==========================================================================
2257 @brief hdd_wmm_acquire_access_required() - Function which will determine
2258 acquire admittance for a WMM AC is required or not based on psb configuration
2259 done in framework
2260
2261 @param pAdapter : [in] pointer to adapter structure
2262
2263 @param acType : [in] WMM AC type of OS packet
2264
2265 @return : void
2266 ===========================================================================*/
2267void hdd_wmm_acquire_access_required(hdd_adapter_t *pAdapter,
2268 WLANTL_ACEnumType acType)
2269{
2270/* Each bit in the LSB nibble indicates 1 AC.
2271 * Clearing the particular bit in LSB nibble to indicate
2272 * access required
2273 */
2274 switch(acType)
2275 {
2276 case WLANTL_AC_BK:
2277 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BK_CHANGED_MASK; /* clear first bit */
2278 break;
2279 case WLANTL_AC_BE:
2280 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BE_CHANGED_MASK; /* clear second bit */
2281 break;
2282 case WLANTL_AC_VI:
2283 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VI_CHANGED_MASK; /* clear third bit */
2284 break;
2285 case WLANTL_AC_VO:
2286 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VO_CHANGED_MASK; /* clear fourth bit */
2287 break;
2288 default:
2289 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2290 "%s: Invalid AC Type", __func__);
2291 break;
2292 }
2293}
2294
Jeff Johnson295189b2012-06-20 16:38:30 -07002295/**============================================================================
2296 @brief hdd_wmm_acquire_access() - Function which will attempt to acquire
2297 admittance for a WMM AC
2298
2299 @param pAdapter : [in] pointer to adapter context
2300 @param acType : [in] WMM AC type of OS packet
2301 @param pGranted : [out] pointer to boolean flag when indicates if access
2302 has been granted or not
2303
2304 @return : VOS_STATUS_SUCCESS if succssful
2305 : other values if failure
2306 ===========================================================================*/
2307VOS_STATUS hdd_wmm_acquire_access( hdd_adapter_t* pAdapter,
2308 WLANTL_ACEnumType acType,
2309 v_BOOL_t * pGranted )
2310{
2311 hdd_wmm_qos_context_t *pQosContext;
2312
2313 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002314 "%s: Entered for AC %d", __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002315
2316 if (!hdd_wmm_is_active(pAdapter) || !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
2317 {
2318 // either we don't want QoS or the AP doesn't support QoS
2319 // or we don't want to do implicit QoS
2320 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002321 "%s: QoS not configured on both ends ", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002322
2323 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2324 *pGranted = VOS_TRUE;
2325 return VOS_STATUS_SUCCESS;
2326 }
2327
2328 // do we already have an implicit QoS request pending for this AC?
2329 if ((pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded) ||
2330 (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessPending))
2331 {
2332 // request already pending so we need to wait for that response
2333 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2334 "%s: Implicit QoS for TL AC %d already scheduled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002335 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002336
2337 *pGranted = VOS_FALSE;
2338 return VOS_STATUS_SUCCESS;
2339 }
2340
2341 // did we already fail to establish implicit QoS for this AC?
2342 // (if so, access should have been granted when the failure was handled)
2343 if (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessFailed)
2344 {
2345 // request previously failed
2346 // allow access, but we'll be downgraded
2347 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2348 "%s: Implicit QoS for TL AC %d previously failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002349 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002350
2351 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2352 *pGranted = VOS_TRUE;
2353 return VOS_STATUS_SUCCESS;
2354 }
2355
2356 // we need to establish implicit QoS
2357 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2358 "%s: Need to schedule implicit QoS for TL AC %d, pAdapter is %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002359 __func__, acType, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002360
2361 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded = VOS_TRUE;
2362
Mohit Khanna217ea8d2012-09-11 17:42:42 -07002363 pQosContext = kmalloc(sizeof(*pQosContext), GFP_ATOMIC);
Jeff Johnson295189b2012-06-20 16:38:30 -07002364 if (NULL == pQosContext)
2365 {
2366 // no memory for QoS context. Nothing we can do but let data flow
2367 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002368 "%s: Unable to allocate context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002369 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2370 *pGranted = VOS_TRUE;
2371 return VOS_STATUS_SUCCESS;
2372 }
2373
2374 pQosContext->acType = acType;
2375 pQosContext->pAdapter = pAdapter;
2376 pQosContext->qosFlowId = 0;
2377 pQosContext->handle = HDD_WMM_HANDLE_IMPLICIT;
2378 pQosContext->magic = HDD_WMM_CTX_MAGIC;
Anand N Sunkaddc63c792015-06-03 14:33:24 +05302379 vos_init_work(&pQosContext->wmmAcSetupImplicitQos,
Jeff Johnson295189b2012-06-20 16:38:30 -07002380 hdd_wmm_do_implicit_qos);
2381
2382 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2383 "%s: Scheduling work for AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002384 __func__, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002385
2386 schedule_work(&pQosContext->wmmAcSetupImplicitQos);
2387
2388 // caller will need to wait until the work takes place and
2389 // TSPEC negotiation completes
2390 *pGranted = VOS_FALSE;
2391 return VOS_STATUS_SUCCESS;
2392}
2393
2394/**============================================================================
2395 @brief hdd_wmm_assoc() - Function which will handle the housekeeping
2396 required by WMM when association takes place
2397
2398 @param pAdapter : [in] pointer to adapter context
2399 @param pRoamInfo: [in] pointer to roam information
2400 @param eBssType : [in] type of BSS
2401
2402 @return : VOS_STATUS_SUCCESS if succssful
2403 : other values if failure
2404 ===========================================================================*/
2405VOS_STATUS hdd_wmm_assoc( hdd_adapter_t* pAdapter,
2406 tCsrRoamInfo *pRoamInfo,
2407 eCsrRoamBssType eBssType )
2408{
2409 tANI_U8 uapsdMask;
2410 VOS_STATUS status;
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002411 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002412
2413 // when we associate we need to notify TL if it needs to enable
2414 // UAPSD for any access categories
2415
2416 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002417 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002418
2419 if (pRoamInfo->fReassocReq)
2420 {
2421 // when we reassociate we should continue to use whatever
2422 // parameters were previously established. if we are
2423 // reassociating due to a U-APSD change for a particular
2424 // Access Category, then the change will be communicated
2425 // to HDD via the QoS callback associated with the given
2426 // flow, and U-APSD parameters will be updated there
2427
2428 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002429 "%s: Reassoc so no work, Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002430
2431 return VOS_STATUS_SUCCESS;
2432 }
2433
2434 // get the negotiated UAPSD Mask
2435 uapsdMask = pRoamInfo->u.pConnectedProfile->modifyProfileFields.uapsd_mask;
2436
2437 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002438 "%s: U-APSD mask is 0x%02x", __func__, (int) uapsdMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002439
2440 if (uapsdMask & HDD_AC_VO)
2441 {
2442 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2443 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2444 WLANTL_AC_VO,
2445 7,
2446 7,
2447 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv,
2448 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv,
2449 WLANTL_BI_DIR );
2450
2451 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2452 }
2453
2454 if (uapsdMask & HDD_AC_VI)
2455 {
2456 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2457 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2458 WLANTL_AC_VI,
2459 5,
2460 5,
2461 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv,
2462 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv,
2463 WLANTL_BI_DIR );
2464
2465 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2466 }
2467
2468 if (uapsdMask & HDD_AC_BK)
2469 {
2470 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2471 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2472 WLANTL_AC_BK,
2473 2,
2474 2,
2475 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv,
2476 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv,
2477 WLANTL_BI_DIR );
2478
2479 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2480 }
2481
2482 if (uapsdMask & HDD_AC_BE)
2483 {
2484 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2485 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2486 WLANTL_AC_BE,
2487 3,
2488 3,
2489 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv,
2490 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv,
2491 WLANTL_BI_DIR );
2492
2493 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2494 }
Kumar Anand82c009f2014-05-29 00:29:42 -07002495
2496 status = sme_UpdateDSCPtoUPMapping(pHddCtx->hHal,
2497 pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId);
2498
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002499 if (!VOS_IS_STATUS_SUCCESS( status ))
2500 {
Kumar Anand82c009f2014-05-29 00:29:42 -07002501 hdd_wmm_init( pAdapter );
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002502 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002503
2504 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002505 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002506
2507 return VOS_STATUS_SUCCESS;
2508}
2509
2510
2511
2512static const v_U8_t acmMaskBit[WLANTL_MAX_AC] =
2513 {
2514 0x4, /* WLANTL_AC_BK */
2515 0x8, /* WLANTL_AC_BE */
2516 0x2, /* WLANTL_AC_VI */
2517 0x1 /* WLANTL_AC_VO */
2518 };
2519
2520/**============================================================================
2521 @brief hdd_wmm_connect() - Function which will handle the housekeeping
2522 required by WMM when a connection is established
2523
2524 @param pAdapter : [in] pointer to adapter context
2525 @param pRoamInfo: [in] pointer to roam information
2526 @param eBssType : [in] type of BSS
2527
2528 @return : VOS_STATUS_SUCCESS if succssful
2529 : other values if failure
2530 ===========================================================================*/
2531VOS_STATUS hdd_wmm_connect( hdd_adapter_t* pAdapter,
2532 tCsrRoamInfo *pRoamInfo,
2533 eCsrRoamBssType eBssType )
2534{
2535 int ac;
2536 v_BOOL_t qap;
2537 v_BOOL_t qosConnection;
2538 v_U8_t acmMask;
2539
2540 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002541 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002542
2543 if ((eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) &&
2544 pRoamInfo &&
2545 pRoamInfo->u.pConnectedProfile)
2546 {
2547 qap = pRoamInfo->u.pConnectedProfile->qap;
2548 qosConnection = pRoamInfo->u.pConnectedProfile->qosConnection;
2549 acmMask = pRoamInfo->u.pConnectedProfile->acm_mask;
2550 }
2551 else
2552 {
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05302553 /* TODO: if a non-qos IBSS peer joins the group make qap and qosConnection false.
2554 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002555 qap = VOS_TRUE;
2556 qosConnection = VOS_TRUE;
2557 acmMask = 0x0;
2558 }
2559
2560 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2561 "%s: qap is %d, qosConnection is %d, acmMask is 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002562 __func__, qap, qosConnection, acmMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002563
2564 pAdapter->hddWmmStatus.wmmQap = qap;
2565 pAdapter->hddWmmStatus.wmmQosConnection = qosConnection;
2566
2567 for (ac = 0; ac < WLANTL_MAX_AC; ac++)
2568 {
2569 if (qap &&
2570 qosConnection &&
2571 (acmMask & acmMaskBit[ac]))
2572 {
2573 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2574 "%s: ac %d on",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002575 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002576
2577 // admission is required
2578 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_TRUE;
Padma, Santhosh Kumar73f22252015-05-05 11:59:24 +05302579 //Mark wmmAcAccessAllowed as True if implicit Qos is disabled as there
2580 //is no need to hold packets in queue during hdd_tx_fetch_packet_cbk
2581 if (!(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
2582 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed =
2583 VOS_TRUE;
2584 else
2585 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed =
2586 VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002587 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessGranted = VOS_FALSE;
Mukul Sharma74a01e52014-07-21 15:14:23 +05302588
2589 /* Making TSPEC invalid here so downgrading can be happen while roaming
2590 * It is expected this will be SET in hdd_wmm_sme_callback,once sme is
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302591 * done with the AddTspec.Here we avoid 11r and ccx based association.
2592 This change is done only when reassoc to different AP.
Mukul Sharma74a01e52014-07-21 15:14:23 +05302593 */
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2595 FL( "fReassocReq = %d"
2596#if defined (FEATURE_WLAN_ESE)
2597 "isESEAssoc = %d"
2598#endif
2599#if defined (WLAN_FEATURE_VOWIFI_11R)
2600 "is11rAssoc = %d"
2601#endif
2602 ),
2603 pRoamInfo->fReassocReq
2604#if defined (FEATURE_WLAN_ESE)
2605 ,pRoamInfo->isESEAssoc
2606#endif
2607#if defined (WLAN_FEATURE_VOWIFI_11R)
2608 ,pRoamInfo->is11rAssoc
2609#endif
2610 );
2611
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302612 if ( !pRoamInfo->fReassocReq
Mukul Sharma74a01e52014-07-21 15:14:23 +05302613#if defined (WLAN_FEATURE_VOWIFI_11R)
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302614 &&
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302615 !pRoamInfo->is11rAssoc
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302616#endif
Mukul Sharma74a01e52014-07-21 15:14:23 +05302617#if defined (FEATURE_WLAN_ESE)
2618 &&
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302619 !pRoamInfo->isESEAssoc
Mukul Sharma74a01e52014-07-21 15:14:23 +05302620#endif
2621 )
Mukul Sharma74a01e52014-07-21 15:14:23 +05302622 {
2623 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcTspecValid = VOS_FALSE;
2624 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002625 }
2626 else
2627 {
2628 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2629 "%s: ac %d off",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002630 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002631 // admission is not required so access is allowed
2632 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_FALSE;
2633 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_TRUE;
2634 }
2635
2636 }
2637
2638 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002639 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002640
2641 return VOS_STATUS_SUCCESS;
2642}
2643
2644/**============================================================================
2645 @brief hdd_wmm_get_uapsd_mask() - Function which will calculate the
2646 initial value of the UAPSD mask based upon the device configuration
2647
2648 @param pAdapter : [in] pointer to adapter context
2649 @param pUapsdMask: [in] pointer to where the UAPSD Mask is to be stored
2650
2651 @return : VOS_STATUS_SUCCESS if succssful
2652 : other values if failure
2653 ===========================================================================*/
2654VOS_STATUS hdd_wmm_get_uapsd_mask( hdd_adapter_t* pAdapter,
2655 tANI_U8 *pUapsdMask )
2656{
2657 tANI_U8 uapsdMask;
2658
2659 if (HDD_WMM_USER_MODE_NO_QOS == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
2660 {
2661 // no QOS then no UAPSD
2662 uapsdMask = 0;
2663 }
2664 else
2665 {
2666 // start with the default mask
2667 uapsdMask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
2668
2669 // disable UAPSD for any ACs with a 0 Service Interval
2670 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv == 0 )
2671 {
2672 uapsdMask &= ~HDD_AC_VO;
2673 }
2674
2675 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv == 0 )
2676 {
2677 uapsdMask &= ~HDD_AC_VI;
2678 }
2679
2680 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv == 0 )
2681 {
2682 uapsdMask &= ~HDD_AC_BK;
2683 }
2684
2685 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv == 0 )
2686 {
2687 uapsdMask &= ~HDD_AC_BE;
2688 }
2689 }
2690
2691 // return calculated mask
2692 *pUapsdMask = uapsdMask;
2693 return VOS_STATUS_SUCCESS;
2694}
2695
2696
2697/**============================================================================
2698 @brief hdd_wmm_is_active() - Function which will determine if WMM is
2699 active on the current connection
2700
2701 @param pAdapter : [in] pointer to adapter context
2702
2703 @return : VOS_TRUE if WMM is enabled
2704 : VOS_FALSE if WMM is not enabled
2705 ===========================================================================*/
2706v_BOOL_t hdd_wmm_is_active( hdd_adapter_t* pAdapter )
2707{
2708 if ((!pAdapter->hddWmmStatus.wmmQosConnection) ||
2709 (!pAdapter->hddWmmStatus.wmmQap))
2710 {
2711 return VOS_FALSE;
2712 }
2713 else
2714 {
2715 return VOS_TRUE;
2716 }
2717}
2718
2719/**============================================================================
2720 @brief hdd_wmm_addts() - Function which will add a traffic spec at the
2721 request of an application
2722
2723 @param pAdapter : [in] pointer to adapter context
2724 @param handle : [in] handle to uniquely identify a TS
2725 @param pTspec : [in] pointer to the traffic spec
2726
2727 @return : HDD_WLAN_WMM_STATUS_*
2728 ===========================================================================*/
2729hdd_wlan_wmm_status_e hdd_wmm_addts( hdd_adapter_t* pAdapter,
2730 v_U32_t handle,
2731 sme_QosWmmTspecInfo* pTspec )
2732{
2733 hdd_wmm_qos_context_t *pQosContext;
2734 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2735#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2736 sme_QosStatusType smeStatus;
2737#endif
2738 v_BOOL_t found = VOS_FALSE;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302739 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
2740 hdd_context_t *pHddCtx;
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302741
2742 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302743 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302744 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2745 FL("pVosContext is NULL"));
2746 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302747 }
2748
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302749 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
2750 if (NULL == pHddCtx)
2751 {
2752 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2753 FL("HddCtx is NULL"));
2754 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2755 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002756
2757 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002758 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002759
2760 // see if a context already exists with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302761 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002762 list_for_each_entry(pQosContext,
2763 &pAdapter->hddWmmStatus.wmmContextList,
2764 node)
2765 {
2766 if (pQosContext->handle == handle)
2767 {
2768 found = VOS_TRUE;
2769 break;
2770 }
2771 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302772 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002773 if (found)
2774 {
2775 // record with that handle already exists
2776 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2777 "%s: Record already exists with handle 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002778 __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002779
2780 /* Application is trying to modify some of the Tspec params. Allow it */
2781 smeStatus = sme_QosModifyReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2782 pTspec,
2783 pQosContext->qosFlowId);
2784
2785 // need to check the return value and act appropriately
2786 switch (smeStatus)
2787 {
2788 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
2789 status = HDD_WLAN_WMM_STATUS_MODIFY_PENDING;
2790 break;
2791 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2792 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
2793 break;
2794 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
2795 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
2796 break;
2797 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
2798 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
2799 break;
2800 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
2801 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2802 break;
2803 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2804 status = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2805 break;
2806 default:
2807 // we didn't get back one of the SME_QOS_STATUS_MODIFY_* status codes
2808 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002809 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002810 VOS_ASSERT(0);
2811 return HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2812 }
2813
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302814 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05302815 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
2816 {
2817 pQosContext->lastStatus = status;
2818 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302819 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002820 return status;
2821 }
2822
2823 pQosContext = kmalloc(sizeof(*pQosContext), GFP_KERNEL);
2824 if (NULL == pQosContext)
2825 {
2826 // no memory for QoS context. Nothing we can do
2827 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002828 "%s: Unable to allocate QoS context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002829 return HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE;
2830 }
2831
2832 // we assume the tspec has already been validated by the caller
2833
2834 pQosContext->handle = handle;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08002835 if (pTspec->ts_info.up < HDD_WMM_UP_TO_AC_MAP_SIZE)
2836 pQosContext->acType = hddWmmUpToAcMap[pTspec->ts_info.up];
2837 else {
2838 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2839 "%s: ts_info.up (%d) larger than max value (%d), "
2840 "use default acType (%d)",
2841 __func__, pTspec->ts_info.up,
2842 HDD_WMM_UP_TO_AC_MAP_SIZE - 1, hddWmmUpToAcMap[0]);
2843 pQosContext->acType = hddWmmUpToAcMap[0];
2844 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302845
Jeff Johnson295189b2012-06-20 16:38:30 -07002846 pQosContext->pAdapter = pAdapter;
2847 pQosContext->qosFlowId = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002848
2849 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2850 "%s: Setting up QoS, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002851 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002852
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302853 mutex_lock(&pHddCtx->wmmLock);
2854 pQosContext->magic = HDD_WMM_CTX_MAGIC;
Jeff Johnson295189b2012-06-20 16:38:30 -07002855 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302856 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002857
2858#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2859 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2860 pAdapter->sessionId,
2861 pTspec,
2862 hdd_wmm_sme_callback,
2863 pQosContext,
2864 pTspec->ts_info.up,
2865 &pQosContext->qosFlowId);
2866
2867 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2868 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002869 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002870
2871 // need to check the return value and act appropriately
2872 switch (smeStatus)
2873 {
2874 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
2875 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2876 break;
2877 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2878 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
2879 break;
2880 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
2881 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
2882 break;
2883 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
2884 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2885 break;
2886 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
2887 hdd_wmm_free_context(pQosContext);
2888 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
2889 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
2890 // we can't tell the difference between when a request fails because
2891 // AP rejected it versus when SME encounterd an internal error
2892 hdd_wmm_free_context(pQosContext);
2893 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2894 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2895 hdd_wmm_free_context(pQosContext);
2896 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2897 default:
2898 // we didn't get back one of the SME_QOS_STATUS_SETUP_* status codes
2899 hdd_wmm_free_context(pQosContext);
2900 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002901 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002902 VOS_ASSERT(0);
2903 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2904 }
2905#endif
2906
2907 // we were successful, save the status
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302908 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05302909 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
2910 {
2911 pQosContext->lastStatus = status;
2912 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302913 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002914
2915 return status;
2916}
2917
2918/**============================================================================
2919 @brief hdd_wmm_delts() - Function which will delete a traffic spec at the
2920 request of an application
2921
2922 @param pAdapter : [in] pointer to adapter context
2923 @param handle : [in] handle to uniquely identify a TS
2924
2925 @return : HDD_WLAN_WMM_STATUS_*
2926 ===========================================================================*/
2927hdd_wlan_wmm_status_e hdd_wmm_delts( hdd_adapter_t* pAdapter,
2928 v_U32_t handle )
2929{
2930 hdd_wmm_qos_context_t *pQosContext;
2931 v_BOOL_t found = VOS_FALSE;
2932 WLANTL_ACEnumType acType = 0;
2933 v_U32_t qosFlowId = 0;
2934 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2935#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2936 sme_QosStatusType smeStatus;
2937#endif
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302938 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
2939 hdd_context_t *pHddCtx;
2940
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302941 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302942 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302943 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2944 FL("pVosContext is NULL"));
2945 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2946 }
2947
2948 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
2949 if (NULL == pHddCtx)
2950 {
2951 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302952 FL("HddCtx is NULL"));
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302953 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302954 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002955
2956 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002957 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002958
2959 // locate the context with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302960 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002961 list_for_each_entry(pQosContext,
2962 &pAdapter->hddWmmStatus.wmmContextList,
2963 node)
2964 {
2965 if (pQosContext->handle == handle)
2966 {
2967 found = VOS_TRUE;
2968 acType = pQosContext->acType;
2969 qosFlowId = pQosContext->qosFlowId;
2970 break;
2971 }
2972 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302973 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002974
2975 if (VOS_FALSE == found)
2976 {
2977 // we didn't find the handle
2978 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002979 "%s: handle 0x%x not found", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002980 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2981 }
2982
2983
2984 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2985 "%s: found handle 0x%x, flow %d, AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002986 __func__, handle, qosFlowId, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002987
2988#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2989 smeStatus = sme_QosReleaseReq( WLAN_HDD_GET_HAL_CTX(pAdapter), qosFlowId );
2990
2991 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2992 "%s: SME flow %d released, SME status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002993 __func__, qosFlowId, smeStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07002994
2995 switch(smeStatus)
2996 {
2997 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
2998 // this flow is the only one on that AC, so go ahead and update
2999 // our TSPEC state for the AC
3000 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcTspecValid = VOS_FALSE;
3001
3002 // need to tell TL to stop trigger timer, etc
3003 hdd_wmm_disable_tl_uapsd(pQosContext);
3004
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003005#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07003006 // disable the inactivity timer
3007 hdd_wmm_disable_inactivity_timer(pQosContext);
3008#endif
3009 // we are done with this context
3010 hdd_wmm_free_context(pQosContext);
3011
3012 // SME must not fire any more callbacks for this flow since the context
3013 // is no longer valid
3014
3015 return HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
3016
3017 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
3018 // do nothing as we will get a response from SME
3019 status = HDD_WLAN_WMM_STATUS_RELEASE_PENDING;
3020 break;
3021
3022 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
3023 // nothing we can do with the existing flow except leave it
3024 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
3025 break;
3026
3027 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
3028 // nothing we can do with the existing flow except leave it
3029 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
3030
3031 default:
3032 // we didn't get back one of the SME_QOS_STATUS_RELEASE_* status codes
3033 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003034 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07003035 VOS_ASSERT(0);
3036 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
3037 }
3038
3039#endif
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303040 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05303041 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
3042 {
3043 pQosContext->lastStatus = status;
3044 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303045 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003046 return status;
3047}
3048
3049/**============================================================================
3050 @brief hdd_wmm_checkts() - Function which will return the status of a traffic
3051 spec at the request of an application
3052
3053 @param pAdapter : [in] pointer to adapter context
3054 @param handle : [in] handle to uniquely identify a TS
3055
3056 @return : HDD_WLAN_WMM_STATUS_*
3057 ===========================================================================*/
3058hdd_wlan_wmm_status_e hdd_wmm_checkts( hdd_adapter_t* pAdapter,
3059 v_U32_t handle )
3060{
3061 hdd_wmm_qos_context_t *pQosContext;
3062 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303063 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
3064 hdd_context_t *pHddCtx;
3065
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303066 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303067 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303068 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
3069 FL("pVosContext is NULL"));
3070 return HDD_WLAN_WMM_STATUS_LOST;
3071 }
3072
3073 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
3074 if (NULL == pHddCtx)
3075 {
3076 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303077 FL("HddCtx is NULL"));
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303078 return HDD_WLAN_WMM_STATUS_LOST;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303079 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003080
3081 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003082 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07003083
3084 // locate the context with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303085 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003086 list_for_each_entry(pQosContext,
3087 &pAdapter->hddWmmStatus.wmmContextList,
3088 node)
3089 {
3090 if (pQosContext->handle == handle)
3091 {
3092 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
3093 "%s: found handle 0x%x, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003094 __func__, handle, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07003095
3096 status = pQosContext->lastStatus;
3097 break;
3098 }
3099 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303100 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003101 return status;
3102}