blob: 084eda99be6855939062a0785da930cde5b6d4e6 [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 {
1993 // default
1994#ifdef HDD_WMM_DEBUG
1995 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1996 "%s: Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001997 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001998#endif // HDD_WMM_DEBUG
1999 //Give the highest priority to 802.1x packet
2000 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
2001 tos = 0xC0;
2002 else
2003 tos = 0;
2004 }
2005
2006 dscp = (tos>>2) & 0x3f;
Kumar Anand82c009f2014-05-29 00:29:42 -07002007 userPri = pAdapter->hddWmmDscpToUpMap[dscp];
2008
Jeff Johnson295189b2012-06-20 16:38:30 -07002009#ifdef HDD_WMM_DEBUG
2010 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2011 "%s: tos is %d, dscp is %d, up is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002012 __func__, tos, dscp, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07002013#endif // HDD_WMM_DEBUG
2014
2015 }
2016 else if (HDD_WMM_CLASSIFICATION_802_1Q == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
2017 {
2018 if (pHdr->eth_IIv.h_vlan_proto == htons(ETH_P_8021Q))
2019 {
2020 // VLAN tagged
2021 userPri = (ntohs(pHdr->eth_IIv.h_vlan_TCI)>>13) & 0x7;
2022#ifdef HDD_WMM_DEBUG
2023 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2024 "%s: Tagged frame, UP is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002025 __func__, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07002026#endif // HDD_WMM_DEBUG
2027 }
2028 else
2029 {
2030 // not VLAN tagged, use default
2031#ifdef HDD_WMM_DEBUG
2032 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2033 "%s: Untagged frame, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002034 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002035#endif // HDD_WMM_DEBUG
2036 //Give the highest priority to 802.1x packet
2037 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
2038 userPri = SME_QOS_WMM_UP_VO;
2039 else
2040 userPri = SME_QOS_WMM_UP_BE;
2041 }
2042 }
2043 else
2044 {
2045 // default
2046#ifdef HDD_WMM_DEBUG
2047 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2048 "%s: Unknown classification scheme, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002049 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002050#endif // HDD_WMM_DEBUG
2051 userPri = SME_QOS_WMM_UP_BE;
2052 }
2053
2054 acType = hddWmmUpToAcMap[userPri];
2055
2056#ifdef HDD_WMM_DEBUG
2057 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2058 "%s: UP is %d, AC is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002059 __func__, userPri, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002060#endif // HDD_WMM_DEBUG
2061
2062 *pUserPri = userPri;
2063 *pAcType = acType;
2064
2065 return;
2066}
2067
2068/**============================================================================
2069 @brief hdd_hostapd_select_quueue() - Function which will classify the packet
2070 according to linux qdisc expectation.
2071
2072
2073 @param dev : [in] pointer to net_device structure
2074 @param skb : [in] pointer to os packet
2075
2076 @return : Qdisc queue index
2077 ===========================================================================*/
2078v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb)
2079{
2080 WLANTL_ACEnumType ac;
2081 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
2082 v_USHORT_t queueIndex;
2083 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
2084 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
2085 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002086 v_U8_t STAId;
2087 v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302088 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2089 ptSapContext pSapCtx = NULL;
2090 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2091 if(pSapCtx == NULL){
2092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2093 FL("psapCtx is NULL"));
2094 *pSTAId = HDD_WLAN_INVALID_STA_ID;
2095 goto done;
2096 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002097 /*Get the Station ID*/
Jeff Johnson295189b2012-06-20 16:38:30 -07002098 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &STAId))
2099 {
Agarwal Ashisha64c9542014-03-04 00:14:43 +05302100 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002101 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002102 *pSTAId = HDD_WLAN_INVALID_STA_ID;
2103 goto done;
2104 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002105
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302106 spin_lock_bh( &pSapCtx->staInfo_lock );
2107 if (FALSE == vos_is_macaddr_equal(&pSapCtx->aStaInfo[STAId].macAddrSTA, pDestMacAddress))
Jeff Johnson295189b2012-06-20 16:38:30 -07002108 {
Agarwal Ashisha64c9542014-03-04 00:14:43 +05302109 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002110 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002111
2112 *pSTAId = HDD_WLAN_INVALID_STA_ID;
2113 goto release_lock;
2114 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302115 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 -07002116 {
2117 /* Get the user priority from IP header & corresponding AC */
2118 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05302119 //If 3/4th of Tx queue is used then place the DHCP packet in VOICE AC queue
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302120 if (pSapCtx->aStaInfo[STAId].vosLowResource && hdd_is_dhcp_packet(skb))
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05302121 {
2122 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2123 "%s: Making priority of DHCP packet as VOICE", __func__);
2124 up = SME_QOS_WMM_UP_VO;
2125 ac = hddWmmUpToAcMap[up];
2126 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002127 }
2128 *pSTAId = STAId;
2129
2130release_lock:
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302131 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07002132done:
2133 skb->priority = up;
Mukul Sharmad82cb7d2014-07-03 14:53:30 +05302134 if(skb->priority < SME_QOS_WMM_UP_MAX)
2135 queueIndex = hddLinuxUpToAcMap[skb->priority];
2136 else
2137 {
2138 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2139 "%s: up=%d is going beyond max value", __func__, up);
2140 queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
2141 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002142
2143 return queueIndex;
2144}
2145
2146/**============================================================================
2147 @brief hdd_wmm_select_quueue() - Function which will classify the packet
2148 according to linux qdisc expectation.
2149
2150
2151 @param dev : [in] pointer to net_device structure
2152 @param skb : [in] pointer to os packet
2153
2154 @return : Qdisc queue index
2155 ===========================================================================*/
2156v_U16_t hdd_wmm_select_queue(struct net_device * dev, struct sk_buff *skb)
2157{
2158 WLANTL_ACEnumType ac;
Shailender Karmuchia734f332013-04-19 14:02:48 -07002159 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002160 v_USHORT_t queueIndex;
Jeff Johnson295189b2012-06-20 16:38:30 -07002161 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2162
Siddharth Bhal4f6694f2015-02-27 17:24:21 +05302163 if (vos_is_logp_in_progress(VOS_MODULE_ID_HDD, NULL)) {
Kiet Lam40009862014-02-13 12:33:22 -08002164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2165 FL("called during WDReset"));
2166 skb->priority = SME_QOS_WMM_UP_BE;
2167 return HDD_LINUX_AC_BE;
2168 }
2169
Shailender Karmuchia734f332013-04-19 14:02:48 -07002170 /*Get the Station ID*/
2171 if (WLAN_HDD_IBSS == pAdapter->device_mode)
2172 {
2173 v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
2174 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
2175
2176 if ( VOS_STATUS_SUCCESS !=
2177 hdd_Ibss_GetStaId(&pAdapter->sessionCtx.station,
2178 pDestMacAddress, pSTAId))
2179 {
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05302180 *pSTAId = HDD_WLAN_INVALID_STA_ID;
2181 if ( !vos_is_macaddr_broadcast( pDestMacAddress ) &&
2182 !vos_is_macaddr_group(pDestMacAddress))
2183 {
2184 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnsonb9fb9ce2013-05-03 08:11:02 -07002185 "%s: Failed to find right station pDestMacAddress: "
2186 MAC_ADDRESS_STR , __func__,
2187 MAC_ADDR_ARRAY(pDestMacAddress->bytes));
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05302188 goto done;
2189 }
Shailender Karmuchia734f332013-04-19 14:02:48 -07002190 }
2191 }
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302192 /* All traffic will get equal opportuniy to transmit data frames. */
2193 /* Get the user priority from IP header & corresponding AC */
2194 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302195
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302196 /* If 3/4th of BE AC Tx queue is full,
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302197 * then place the DHCP packet in VOICE AC queue.
2198 * Doing this for IBSS alone, since for STA interface
2199 * types, these packets will be queued to the new queue.
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302200 */
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302201 if ((WLAN_HDD_IBSS == pAdapter->device_mode) &&
2202 pAdapter->isVosLowResource && hdd_is_dhcp_packet(skb))
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302203 {
2204 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2205 "%s: BestEffort Tx Queue is 3/4th full"
2206 " Make DHCP packet's pri as VO", __func__);
2207 up = SME_QOS_WMM_UP_VO;
2208 ac = hddWmmUpToAcMap[up];
Jeff Johnson295189b2012-06-20 16:38:30 -07002209 }
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302210
Shailender Karmuchia734f332013-04-19 14:02:48 -07002211done:
Jeff Johnson295189b2012-06-20 16:38:30 -07002212 skb->priority = up;
Mukul Sharmad82cb7d2014-07-03 14:53:30 +05302213 if(skb->priority < SME_QOS_WMM_UP_MAX)
2214 queueIndex = hddLinuxUpToAcMap[skb->priority];
2215 else
2216 {
2217 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2218 "%s: up=%d is going beyond max value", __func__, up);
2219 queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
2220 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002221
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302222 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
2223 (hdd_is_dhcp_packet(skb) ||
2224 hdd_skb_is_eapol_or_wai_packet(skb)))
2225 {
2226 /* If the packet is a DHCP packet or a Eapol packet or
2227 * a Wapi packet, then queue it to the new queue for
2228 * STA interfaces alone.
2229 */
2230 queueIndex = WLANTL_AC_HIGH_PRIO;
2231 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2232 "%s: up=%d QIndex:%d", __func__, up, queueIndex);
2233 }
2234
Jeff Johnson295189b2012-06-20 16:38:30 -07002235 return queueIndex;
2236}
2237
Kiet Lamf040f472013-11-20 21:15:23 +05302238/**==========================================================================
2239 @brief hdd_wmm_acquire_access_required() - Function which will determine
2240 acquire admittance for a WMM AC is required or not based on psb configuration
2241 done in framework
2242
2243 @param pAdapter : [in] pointer to adapter structure
2244
2245 @param acType : [in] WMM AC type of OS packet
2246
2247 @return : void
2248 ===========================================================================*/
2249void hdd_wmm_acquire_access_required(hdd_adapter_t *pAdapter,
2250 WLANTL_ACEnumType acType)
2251{
2252/* Each bit in the LSB nibble indicates 1 AC.
2253 * Clearing the particular bit in LSB nibble to indicate
2254 * access required
2255 */
2256 switch(acType)
2257 {
2258 case WLANTL_AC_BK:
2259 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BK_CHANGED_MASK; /* clear first bit */
2260 break;
2261 case WLANTL_AC_BE:
2262 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BE_CHANGED_MASK; /* clear second bit */
2263 break;
2264 case WLANTL_AC_VI:
2265 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VI_CHANGED_MASK; /* clear third bit */
2266 break;
2267 case WLANTL_AC_VO:
2268 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VO_CHANGED_MASK; /* clear fourth bit */
2269 break;
2270 default:
2271 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2272 "%s: Invalid AC Type", __func__);
2273 break;
2274 }
2275}
2276
Jeff Johnson295189b2012-06-20 16:38:30 -07002277/**============================================================================
2278 @brief hdd_wmm_acquire_access() - Function which will attempt to acquire
2279 admittance for a WMM AC
2280
2281 @param pAdapter : [in] pointer to adapter context
2282 @param acType : [in] WMM AC type of OS packet
2283 @param pGranted : [out] pointer to boolean flag when indicates if access
2284 has been granted or not
2285
2286 @return : VOS_STATUS_SUCCESS if succssful
2287 : other values if failure
2288 ===========================================================================*/
2289VOS_STATUS hdd_wmm_acquire_access( hdd_adapter_t* pAdapter,
2290 WLANTL_ACEnumType acType,
2291 v_BOOL_t * pGranted )
2292{
2293 hdd_wmm_qos_context_t *pQosContext;
2294
2295 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002296 "%s: Entered for AC %d", __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002297
2298 if (!hdd_wmm_is_active(pAdapter) || !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
2299 {
2300 // either we don't want QoS or the AP doesn't support QoS
2301 // or we don't want to do implicit QoS
2302 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002303 "%s: QoS not configured on both ends ", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002304
2305 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2306 *pGranted = VOS_TRUE;
2307 return VOS_STATUS_SUCCESS;
2308 }
2309
2310 // do we already have an implicit QoS request pending for this AC?
2311 if ((pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded) ||
2312 (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessPending))
2313 {
2314 // request already pending so we need to wait for that response
2315 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2316 "%s: Implicit QoS for TL AC %d already scheduled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002317 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002318
2319 *pGranted = VOS_FALSE;
2320 return VOS_STATUS_SUCCESS;
2321 }
2322
2323 // did we already fail to establish implicit QoS for this AC?
2324 // (if so, access should have been granted when the failure was handled)
2325 if (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessFailed)
2326 {
2327 // request previously failed
2328 // allow access, but we'll be downgraded
2329 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2330 "%s: Implicit QoS for TL AC %d previously failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002331 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002332
2333 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2334 *pGranted = VOS_TRUE;
2335 return VOS_STATUS_SUCCESS;
2336 }
2337
2338 // we need to establish implicit QoS
2339 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2340 "%s: Need to schedule implicit QoS for TL AC %d, pAdapter is %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002341 __func__, acType, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002342
2343 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded = VOS_TRUE;
2344
Mohit Khanna217ea8d2012-09-11 17:42:42 -07002345 pQosContext = kmalloc(sizeof(*pQosContext), GFP_ATOMIC);
Jeff Johnson295189b2012-06-20 16:38:30 -07002346 if (NULL == pQosContext)
2347 {
2348 // no memory for QoS context. Nothing we can do but let data flow
2349 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002350 "%s: Unable to allocate context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002351 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2352 *pGranted = VOS_TRUE;
2353 return VOS_STATUS_SUCCESS;
2354 }
2355
2356 pQosContext->acType = acType;
2357 pQosContext->pAdapter = pAdapter;
2358 pQosContext->qosFlowId = 0;
2359 pQosContext->handle = HDD_WMM_HANDLE_IMPLICIT;
2360 pQosContext->magic = HDD_WMM_CTX_MAGIC;
2361 INIT_WORK(&pQosContext->wmmAcSetupImplicitQos,
2362 hdd_wmm_do_implicit_qos);
2363
2364 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2365 "%s: Scheduling work for AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002366 __func__, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002367
2368 schedule_work(&pQosContext->wmmAcSetupImplicitQos);
2369
2370 // caller will need to wait until the work takes place and
2371 // TSPEC negotiation completes
2372 *pGranted = VOS_FALSE;
2373 return VOS_STATUS_SUCCESS;
2374}
2375
2376/**============================================================================
2377 @brief hdd_wmm_assoc() - Function which will handle the housekeeping
2378 required by WMM when association takes place
2379
2380 @param pAdapter : [in] pointer to adapter context
2381 @param pRoamInfo: [in] pointer to roam information
2382 @param eBssType : [in] type of BSS
2383
2384 @return : VOS_STATUS_SUCCESS if succssful
2385 : other values if failure
2386 ===========================================================================*/
2387VOS_STATUS hdd_wmm_assoc( hdd_adapter_t* pAdapter,
2388 tCsrRoamInfo *pRoamInfo,
2389 eCsrRoamBssType eBssType )
2390{
2391 tANI_U8 uapsdMask;
2392 VOS_STATUS status;
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002393 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002394
2395 // when we associate we need to notify TL if it needs to enable
2396 // UAPSD for any access categories
2397
2398 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002399 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002400
2401 if (pRoamInfo->fReassocReq)
2402 {
2403 // when we reassociate we should continue to use whatever
2404 // parameters were previously established. if we are
2405 // reassociating due to a U-APSD change for a particular
2406 // Access Category, then the change will be communicated
2407 // to HDD via the QoS callback associated with the given
2408 // flow, and U-APSD parameters will be updated there
2409
2410 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002411 "%s: Reassoc so no work, Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002412
2413 return VOS_STATUS_SUCCESS;
2414 }
2415
2416 // get the negotiated UAPSD Mask
2417 uapsdMask = pRoamInfo->u.pConnectedProfile->modifyProfileFields.uapsd_mask;
2418
2419 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002420 "%s: U-APSD mask is 0x%02x", __func__, (int) uapsdMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002421
2422 if (uapsdMask & HDD_AC_VO)
2423 {
2424 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2425 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2426 WLANTL_AC_VO,
2427 7,
2428 7,
2429 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv,
2430 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv,
2431 WLANTL_BI_DIR );
2432
2433 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2434 }
2435
2436 if (uapsdMask & HDD_AC_VI)
2437 {
2438 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2439 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2440 WLANTL_AC_VI,
2441 5,
2442 5,
2443 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv,
2444 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv,
2445 WLANTL_BI_DIR );
2446
2447 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2448 }
2449
2450 if (uapsdMask & HDD_AC_BK)
2451 {
2452 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2453 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2454 WLANTL_AC_BK,
2455 2,
2456 2,
2457 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv,
2458 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv,
2459 WLANTL_BI_DIR );
2460
2461 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2462 }
2463
2464 if (uapsdMask & HDD_AC_BE)
2465 {
2466 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2467 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2468 WLANTL_AC_BE,
2469 3,
2470 3,
2471 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv,
2472 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv,
2473 WLANTL_BI_DIR );
2474
2475 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2476 }
Kumar Anand82c009f2014-05-29 00:29:42 -07002477
2478 status = sme_UpdateDSCPtoUPMapping(pHddCtx->hHal,
2479 pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId);
2480
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002481 if (!VOS_IS_STATUS_SUCCESS( status ))
2482 {
Kumar Anand82c009f2014-05-29 00:29:42 -07002483 hdd_wmm_init( pAdapter );
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002484 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002485
2486 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002487 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002488
2489 return VOS_STATUS_SUCCESS;
2490}
2491
2492
2493
2494static const v_U8_t acmMaskBit[WLANTL_MAX_AC] =
2495 {
2496 0x4, /* WLANTL_AC_BK */
2497 0x8, /* WLANTL_AC_BE */
2498 0x2, /* WLANTL_AC_VI */
2499 0x1 /* WLANTL_AC_VO */
2500 };
2501
2502/**============================================================================
2503 @brief hdd_wmm_connect() - Function which will handle the housekeeping
2504 required by WMM when a connection is established
2505
2506 @param pAdapter : [in] pointer to adapter context
2507 @param pRoamInfo: [in] pointer to roam information
2508 @param eBssType : [in] type of BSS
2509
2510 @return : VOS_STATUS_SUCCESS if succssful
2511 : other values if failure
2512 ===========================================================================*/
2513VOS_STATUS hdd_wmm_connect( hdd_adapter_t* pAdapter,
2514 tCsrRoamInfo *pRoamInfo,
2515 eCsrRoamBssType eBssType )
2516{
2517 int ac;
2518 v_BOOL_t qap;
2519 v_BOOL_t qosConnection;
2520 v_U8_t acmMask;
2521
2522 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002523 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002524
2525 if ((eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) &&
2526 pRoamInfo &&
2527 pRoamInfo->u.pConnectedProfile)
2528 {
2529 qap = pRoamInfo->u.pConnectedProfile->qap;
2530 qosConnection = pRoamInfo->u.pConnectedProfile->qosConnection;
2531 acmMask = pRoamInfo->u.pConnectedProfile->acm_mask;
2532 }
2533 else
2534 {
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05302535 /* TODO: if a non-qos IBSS peer joins the group make qap and qosConnection false.
2536 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002537 qap = VOS_TRUE;
2538 qosConnection = VOS_TRUE;
2539 acmMask = 0x0;
2540 }
2541
2542 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2543 "%s: qap is %d, qosConnection is %d, acmMask is 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002544 __func__, qap, qosConnection, acmMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002545
2546 pAdapter->hddWmmStatus.wmmQap = qap;
2547 pAdapter->hddWmmStatus.wmmQosConnection = qosConnection;
2548
2549 for (ac = 0; ac < WLANTL_MAX_AC; ac++)
2550 {
2551 if (qap &&
2552 qosConnection &&
2553 (acmMask & acmMaskBit[ac]))
2554 {
2555 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2556 "%s: ac %d on",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002557 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002558
2559 // admission is required
2560 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_TRUE;
2561 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_FALSE;
2562 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessGranted = VOS_FALSE;
Mukul Sharma74a01e52014-07-21 15:14:23 +05302563
2564 /* Making TSPEC invalid here so downgrading can be happen while roaming
2565 * It is expected this will be SET in hdd_wmm_sme_callback,once sme is
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302566 * done with the AddTspec.Here we avoid 11r and ccx based association.
2567 This change is done only when reassoc to different AP.
Mukul Sharma74a01e52014-07-21 15:14:23 +05302568 */
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2570 FL( "fReassocReq = %d"
2571#if defined (FEATURE_WLAN_ESE)
2572 "isESEAssoc = %d"
2573#endif
2574#if defined (WLAN_FEATURE_VOWIFI_11R)
2575 "is11rAssoc = %d"
2576#endif
2577 ),
2578 pRoamInfo->fReassocReq
2579#if defined (FEATURE_WLAN_ESE)
2580 ,pRoamInfo->isESEAssoc
2581#endif
2582#if defined (WLAN_FEATURE_VOWIFI_11R)
2583 ,pRoamInfo->is11rAssoc
2584#endif
2585 );
2586
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302587 if ( !pRoamInfo->fReassocReq
Mukul Sharma74a01e52014-07-21 15:14:23 +05302588#if defined (WLAN_FEATURE_VOWIFI_11R)
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302589 &&
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302590 !pRoamInfo->is11rAssoc
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302591#endif
Mukul Sharma74a01e52014-07-21 15:14:23 +05302592#if defined (FEATURE_WLAN_ESE)
2593 &&
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302594 !pRoamInfo->isESEAssoc
Mukul Sharma74a01e52014-07-21 15:14:23 +05302595#endif
2596 )
Mukul Sharma74a01e52014-07-21 15:14:23 +05302597 {
2598 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcTspecValid = VOS_FALSE;
2599 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002600 }
2601 else
2602 {
2603 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2604 "%s: ac %d off",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002605 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002606 // admission is not required so access is allowed
2607 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_FALSE;
2608 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_TRUE;
2609 }
2610
2611 }
2612
2613 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002614 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002615
2616 return VOS_STATUS_SUCCESS;
2617}
2618
2619/**============================================================================
2620 @brief hdd_wmm_get_uapsd_mask() - Function which will calculate the
2621 initial value of the UAPSD mask based upon the device configuration
2622
2623 @param pAdapter : [in] pointer to adapter context
2624 @param pUapsdMask: [in] pointer to where the UAPSD Mask is to be stored
2625
2626 @return : VOS_STATUS_SUCCESS if succssful
2627 : other values if failure
2628 ===========================================================================*/
2629VOS_STATUS hdd_wmm_get_uapsd_mask( hdd_adapter_t* pAdapter,
2630 tANI_U8 *pUapsdMask )
2631{
2632 tANI_U8 uapsdMask;
2633
2634 if (HDD_WMM_USER_MODE_NO_QOS == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
2635 {
2636 // no QOS then no UAPSD
2637 uapsdMask = 0;
2638 }
2639 else
2640 {
2641 // start with the default mask
2642 uapsdMask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
2643
2644 // disable UAPSD for any ACs with a 0 Service Interval
2645 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv == 0 )
2646 {
2647 uapsdMask &= ~HDD_AC_VO;
2648 }
2649
2650 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv == 0 )
2651 {
2652 uapsdMask &= ~HDD_AC_VI;
2653 }
2654
2655 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv == 0 )
2656 {
2657 uapsdMask &= ~HDD_AC_BK;
2658 }
2659
2660 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv == 0 )
2661 {
2662 uapsdMask &= ~HDD_AC_BE;
2663 }
2664 }
2665
2666 // return calculated mask
2667 *pUapsdMask = uapsdMask;
2668 return VOS_STATUS_SUCCESS;
2669}
2670
2671
2672/**============================================================================
2673 @brief hdd_wmm_is_active() - Function which will determine if WMM is
2674 active on the current connection
2675
2676 @param pAdapter : [in] pointer to adapter context
2677
2678 @return : VOS_TRUE if WMM is enabled
2679 : VOS_FALSE if WMM is not enabled
2680 ===========================================================================*/
2681v_BOOL_t hdd_wmm_is_active( hdd_adapter_t* pAdapter )
2682{
2683 if ((!pAdapter->hddWmmStatus.wmmQosConnection) ||
2684 (!pAdapter->hddWmmStatus.wmmQap))
2685 {
2686 return VOS_FALSE;
2687 }
2688 else
2689 {
2690 return VOS_TRUE;
2691 }
2692}
2693
2694/**============================================================================
2695 @brief hdd_wmm_addts() - Function which will add a traffic spec at the
2696 request of an application
2697
2698 @param pAdapter : [in] pointer to adapter context
2699 @param handle : [in] handle to uniquely identify a TS
2700 @param pTspec : [in] pointer to the traffic spec
2701
2702 @return : HDD_WLAN_WMM_STATUS_*
2703 ===========================================================================*/
2704hdd_wlan_wmm_status_e hdd_wmm_addts( hdd_adapter_t* pAdapter,
2705 v_U32_t handle,
2706 sme_QosWmmTspecInfo* pTspec )
2707{
2708 hdd_wmm_qos_context_t *pQosContext;
2709 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2710#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2711 sme_QosStatusType smeStatus;
2712#endif
2713 v_BOOL_t found = VOS_FALSE;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302714 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
2715 hdd_context_t *pHddCtx;
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302716
2717 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302718 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302719 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2720 FL("pVosContext is NULL"));
2721 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302722 }
2723
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302724 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
2725 if (NULL == pHddCtx)
2726 {
2727 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2728 FL("HddCtx is NULL"));
2729 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2730 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002731
2732 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002733 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002734
2735 // see if a context already exists with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302736 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002737 list_for_each_entry(pQosContext,
2738 &pAdapter->hddWmmStatus.wmmContextList,
2739 node)
2740 {
2741 if (pQosContext->handle == handle)
2742 {
2743 found = VOS_TRUE;
2744 break;
2745 }
2746 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302747 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002748 if (found)
2749 {
2750 // record with that handle already exists
2751 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2752 "%s: Record already exists with handle 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002753 __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002754
2755 /* Application is trying to modify some of the Tspec params. Allow it */
2756 smeStatus = sme_QosModifyReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2757 pTspec,
2758 pQosContext->qosFlowId);
2759
2760 // need to check the return value and act appropriately
2761 switch (smeStatus)
2762 {
2763 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
2764 status = HDD_WLAN_WMM_STATUS_MODIFY_PENDING;
2765 break;
2766 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2767 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
2768 break;
2769 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
2770 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
2771 break;
2772 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
2773 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
2774 break;
2775 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
2776 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2777 break;
2778 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2779 status = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2780 break;
2781 default:
2782 // we didn't get back one of the SME_QOS_STATUS_MODIFY_* status codes
2783 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002784 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002785 VOS_ASSERT(0);
2786 return HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2787 }
2788
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302789 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05302790 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
2791 {
2792 pQosContext->lastStatus = status;
2793 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302794 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002795 return status;
2796 }
2797
2798 pQosContext = kmalloc(sizeof(*pQosContext), GFP_KERNEL);
2799 if (NULL == pQosContext)
2800 {
2801 // no memory for QoS context. Nothing we can do
2802 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002803 "%s: Unable to allocate QoS context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002804 return HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE;
2805 }
2806
2807 // we assume the tspec has already been validated by the caller
2808
2809 pQosContext->handle = handle;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08002810 if (pTspec->ts_info.up < HDD_WMM_UP_TO_AC_MAP_SIZE)
2811 pQosContext->acType = hddWmmUpToAcMap[pTspec->ts_info.up];
2812 else {
2813 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2814 "%s: ts_info.up (%d) larger than max value (%d), "
2815 "use default acType (%d)",
2816 __func__, pTspec->ts_info.up,
2817 HDD_WMM_UP_TO_AC_MAP_SIZE - 1, hddWmmUpToAcMap[0]);
2818 pQosContext->acType = hddWmmUpToAcMap[0];
2819 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302820
Jeff Johnson295189b2012-06-20 16:38:30 -07002821 pQosContext->pAdapter = pAdapter;
2822 pQosContext->qosFlowId = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002823
2824 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2825 "%s: Setting up QoS, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002826 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002827
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302828 mutex_lock(&pHddCtx->wmmLock);
2829 pQosContext->magic = HDD_WMM_CTX_MAGIC;
Jeff Johnson295189b2012-06-20 16:38:30 -07002830 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302831 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002832
2833#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2834 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2835 pAdapter->sessionId,
2836 pTspec,
2837 hdd_wmm_sme_callback,
2838 pQosContext,
2839 pTspec->ts_info.up,
2840 &pQosContext->qosFlowId);
2841
2842 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2843 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002844 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002845
2846 // need to check the return value and act appropriately
2847 switch (smeStatus)
2848 {
2849 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
2850 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2851 break;
2852 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2853 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
2854 break;
2855 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
2856 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
2857 break;
2858 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
2859 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2860 break;
2861 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
2862 hdd_wmm_free_context(pQosContext);
2863 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
2864 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
2865 // we can't tell the difference between when a request fails because
2866 // AP rejected it versus when SME encounterd an internal error
2867 hdd_wmm_free_context(pQosContext);
2868 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2869 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2870 hdd_wmm_free_context(pQosContext);
2871 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2872 default:
2873 // we didn't get back one of the SME_QOS_STATUS_SETUP_* status codes
2874 hdd_wmm_free_context(pQosContext);
2875 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002876 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002877 VOS_ASSERT(0);
2878 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2879 }
2880#endif
2881
2882 // we were successful, save the status
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302883 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05302884 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
2885 {
2886 pQosContext->lastStatus = status;
2887 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302888 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002889
2890 return status;
2891}
2892
2893/**============================================================================
2894 @brief hdd_wmm_delts() - Function which will delete a traffic spec at the
2895 request of an application
2896
2897 @param pAdapter : [in] pointer to adapter context
2898 @param handle : [in] handle to uniquely identify a TS
2899
2900 @return : HDD_WLAN_WMM_STATUS_*
2901 ===========================================================================*/
2902hdd_wlan_wmm_status_e hdd_wmm_delts( hdd_adapter_t* pAdapter,
2903 v_U32_t handle )
2904{
2905 hdd_wmm_qos_context_t *pQosContext;
2906 v_BOOL_t found = VOS_FALSE;
2907 WLANTL_ACEnumType acType = 0;
2908 v_U32_t qosFlowId = 0;
2909 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2910#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2911 sme_QosStatusType smeStatus;
2912#endif
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302913 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
2914 hdd_context_t *pHddCtx;
2915
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302916 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302917 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302918 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2919 FL("pVosContext is NULL"));
2920 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2921 }
2922
2923 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
2924 if (NULL == pHddCtx)
2925 {
2926 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302927 FL("HddCtx is NULL"));
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302928 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302929 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002930
2931 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002932 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002933
2934 // locate the context with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302935 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002936 list_for_each_entry(pQosContext,
2937 &pAdapter->hddWmmStatus.wmmContextList,
2938 node)
2939 {
2940 if (pQosContext->handle == handle)
2941 {
2942 found = VOS_TRUE;
2943 acType = pQosContext->acType;
2944 qosFlowId = pQosContext->qosFlowId;
2945 break;
2946 }
2947 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302948 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002949
2950 if (VOS_FALSE == found)
2951 {
2952 // we didn't find the handle
2953 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002954 "%s: handle 0x%x not found", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002955 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2956 }
2957
2958
2959 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2960 "%s: found handle 0x%x, flow %d, AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002961 __func__, handle, qosFlowId, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002962
2963#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2964 smeStatus = sme_QosReleaseReq( WLAN_HDD_GET_HAL_CTX(pAdapter), qosFlowId );
2965
2966 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2967 "%s: SME flow %d released, SME status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002968 __func__, qosFlowId, smeStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07002969
2970 switch(smeStatus)
2971 {
2972 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
2973 // this flow is the only one on that AC, so go ahead and update
2974 // our TSPEC state for the AC
2975 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcTspecValid = VOS_FALSE;
2976
2977 // need to tell TL to stop trigger timer, etc
2978 hdd_wmm_disable_tl_uapsd(pQosContext);
2979
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002980#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07002981 // disable the inactivity timer
2982 hdd_wmm_disable_inactivity_timer(pQosContext);
2983#endif
2984 // we are done with this context
2985 hdd_wmm_free_context(pQosContext);
2986
2987 // SME must not fire any more callbacks for this flow since the context
2988 // is no longer valid
2989
2990 return HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
2991
2992 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
2993 // do nothing as we will get a response from SME
2994 status = HDD_WLAN_WMM_STATUS_RELEASE_PENDING;
2995 break;
2996
2997 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
2998 // nothing we can do with the existing flow except leave it
2999 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
3000 break;
3001
3002 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
3003 // nothing we can do with the existing flow except leave it
3004 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
3005
3006 default:
3007 // we didn't get back one of the SME_QOS_STATUS_RELEASE_* status codes
3008 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003009 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07003010 VOS_ASSERT(0);
3011 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
3012 }
3013
3014#endif
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303015 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05303016 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
3017 {
3018 pQosContext->lastStatus = status;
3019 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303020 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003021 return status;
3022}
3023
3024/**============================================================================
3025 @brief hdd_wmm_checkts() - Function which will return the status of a traffic
3026 spec at the request of an application
3027
3028 @param pAdapter : [in] pointer to adapter context
3029 @param handle : [in] handle to uniquely identify a TS
3030
3031 @return : HDD_WLAN_WMM_STATUS_*
3032 ===========================================================================*/
3033hdd_wlan_wmm_status_e hdd_wmm_checkts( hdd_adapter_t* pAdapter,
3034 v_U32_t handle )
3035{
3036 hdd_wmm_qos_context_t *pQosContext;
3037 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303038 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
3039 hdd_context_t *pHddCtx;
3040
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303041 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303042 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303043 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
3044 FL("pVosContext is NULL"));
3045 return HDD_WLAN_WMM_STATUS_LOST;
3046 }
3047
3048 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
3049 if (NULL == pHddCtx)
3050 {
3051 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303052 FL("HddCtx is NULL"));
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303053 return HDD_WLAN_WMM_STATUS_LOST;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303054 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003055
3056 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003057 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07003058
3059 // locate the context with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303060 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003061 list_for_each_entry(pQosContext,
3062 &pAdapter->hddWmmStatus.wmmContextList,
3063 node)
3064 {
3065 if (pQosContext->handle == handle)
3066 {
3067 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
3068 "%s: found handle 0x%x, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003069 __func__, handle, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07003070
3071 status = pQosContext->lastStatus;
3072 break;
3073 }
3074 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303075 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003076 return status;
3077}