blob: b6d5c2140902116b6cd6d4f9a07e6f3a9ecc6c1f [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 );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +0530360 hdd_context_t *pHddCtx = NULL;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530361
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 );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +0530423 hdd_context_t *pHddCtx = NULL;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530424
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 );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +0530553 hdd_context_t *pHddCtx = NULL;
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 );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +0530737 hdd_context_t *pHddCtx = NULL;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530738
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__);
Padma, Santhosh Kumardff2fb92015-12-15 19:52:17 +0530989 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
Jeff Johnson295189b2012-06-20 16:38:30 -0700990 {
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 );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +05301432 hdd_context_t *pHddCtx = NULL;
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 );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +05301799 hdd_context_t *pHddCtx = NULL;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301800
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301801 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301802 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301803 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1804 FL("pVosContext is NULL"));
1805 return VOS_STATUS_E_FAILURE;
1806 }
1807
1808 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
1809 if (NULL == pHddCtx)
1810 {
1811 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301812 FL("HddCtx is NULL"));
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301813 return VOS_STATUS_E_FAILURE;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301814 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001815
1816 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001817 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001818
1819 // free any context records that we still have linked
1820 while (!list_empty(&pAdapter->hddWmmStatus.wmmContextList))
1821 {
1822 pQosContext = list_first_entry(&pAdapter->hddWmmStatus.wmmContextList,
1823 hdd_wmm_qos_context_t, node);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08001824#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07001825 hdd_wmm_disable_inactivity_timer(pQosContext);
1826#endif
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301827 mutex_lock(&pHddCtx->wmmLock);
Anand N Sunkad4b25a2f2014-11-13 16:01:08 +05301828 if (pQosContext->handle == HDD_WMM_HANDLE_IMPLICIT
1829 && pQosContext->magic == HDD_WMM_CTX_MAGIC)
1830 {
1831
Anand N Sunkad860e5ea2015-03-30 14:41:51 +05301832 vos_flush_work(&pQosContext->wmmAcSetupImplicitQos);
Anand N Sunkad4b25a2f2014-11-13 16:01:08 +05301833 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301834 mutex_unlock(&pHddCtx->wmmLock);
Anand N Sunkad860e5ea2015-03-30 14:41:51 +05301835
Jeff Johnson295189b2012-06-20 16:38:30 -07001836 hdd_wmm_free_context(pQosContext);
1837 }
1838
1839 return VOS_STATUS_SUCCESS;
1840}
1841
1842/**============================================================================
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301843 @brief hdd_is_dhcp_packet() - Function which will check OS packet for
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301844 DHCP packet
1845
1846 @param skb : [in] pointer to OS packet (sk_buff)
1847 @return : VOS_TRUE if the OS packet is DHCP packet
1848 : otherwise VOS_FALSE
1849 ===========================================================================*/
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301850v_BOOL_t hdd_is_dhcp_packet(struct sk_buff *skb)
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301851{
1852 if (*((u16*)((u8*)skb->data+34)) == DHCP_SOURCE_PORT ||
1853 *((u16*)((u8*)skb->data+34)) == DHCP_DESTINATION_PORT)
1854 return VOS_TRUE;
1855
1856 return VOS_FALSE;
1857}
1858
1859/**============================================================================
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301860 @brief hdd_skb_is_eapol_or_wai_packet() - Function which will check OS packet
1861 for Eapol/Wapi packet
1862
1863 @param skb : [in] pointer to OS packet (sk_buff)
1864 @return : VOS_TRUE if the OS packet is an Eapol or a Wapi packet
1865 : otherwise VOS_FALSE
1866 ===========================================================================*/
1867v_BOOL_t hdd_skb_is_eapol_or_wai_packet(struct sk_buff *skb)
1868{
1869 if ((*((u16*)((u8*)skb->data+HDD_ETHERTYPE_802_1_X_FRAME_OFFSET))
1870 == vos_cpu_to_be16(HDD_ETHERTYPE_802_1_X))
1871#ifdef FEATURE_WLAN_WAPI
1872 || (*((u16*)((u8*)skb->data+HDD_ETHERTYPE_802_1_X_FRAME_OFFSET))
1873 == vos_cpu_to_be16(HDD_ETHERTYPE_WAI))
1874#endif
1875 )
1876 return VOS_TRUE;
1877
1878 return VOS_FALSE;
1879}
1880
1881/**============================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07001882 @brief hdd_wmm_classify_pkt() - Function which will classify an OS packet
1883 into a WMM AC based on either 802.1Q or DSCP
1884
1885 @param pAdapter : [in] pointer to adapter context
1886 @param skb : [in] pointer to OS packet (sk_buff)
1887 @param pAcType : [out] pointer to WMM AC type of OS packet
1888
1889 @return : None
1890 ===========================================================================*/
1891v_VOID_t hdd_wmm_classify_pkt ( hdd_adapter_t* pAdapter,
1892 struct sk_buff *skb,
1893 WLANTL_ACEnumType* pAcType,
1894 sme_QosWmmUpType *pUserPri)
1895{
1896 unsigned char * pPkt;
1897 union generic_ethhdr *pHdr;
1898 struct iphdr *pIpHdr;
1899 unsigned char tos;
1900 unsigned char dscp;
1901 sme_QosWmmUpType userPri;
1902 WLANTL_ACEnumType acType;
1903
1904 // this code is executed for every packet therefore
1905 // all debug code is kept conditional
1906
1907#ifdef HDD_WMM_DEBUG
1908 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001909 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001910#endif // HDD_WMM_DEBUG
1911
1912 pPkt = skb->data;
1913 pHdr = (union generic_ethhdr *)pPkt;
1914
1915#ifdef HDD_WMM_DEBUG
1916 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1917 "%s: proto/length is 0x%04x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001918 __func__, pHdr->eth_II.h_proto);
Jeff Johnson295189b2012-06-20 16:38:30 -07001919#endif // HDD_WMM_DEBUG
1920
1921 if (HDD_WMM_CLASSIFICATION_DSCP == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
1922 {
1923 if (pHdr->eth_II.h_proto == htons(ETH_P_IP))
1924 {
1925 // case 1: Ethernet II IP packet
1926 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_II)];
1927 tos = pIpHdr->tos;
1928#ifdef HDD_WMM_DEBUG
1929 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1930 "%s: Ethernet II IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001931 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001932#endif // HDD_WMM_DEBUG
1933
1934 }
1935 else if ((ntohs(pHdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
1936 (pHdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
1937 (pHdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
1938 (pHdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1939 (pHdr->eth_8023.h_proto == htons(ETH_P_IP)))
1940 {
1941 // case 2: 802.3 LLC/SNAP IP packet
1942 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];
1943 tos = pIpHdr->tos;
1944#ifdef HDD_WMM_DEBUG
1945 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1946 "%s: 802.3 LLC/SNAP IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001947 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001948#endif // HDD_WMM_DEBUG
1949 }
1950 else if (pHdr->eth_II.h_proto == htons(ETH_P_8021Q))
1951 {
1952 // VLAN tagged
1953
1954 if (pHdr->eth_IIv.h_vlan_encapsulated_proto == htons(ETH_P_IP))
1955 {
1956 // case 3: Ethernet II vlan-tagged IP packet
1957 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_IIv)];
1958 tos = pIpHdr->tos;
1959#ifdef HDD_WMM_DEBUG
1960 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1961 "%s: Ethernet II VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001962 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001963#endif // HDD_WMM_DEBUG
1964 }
1965 else if ((ntohs(pHdr->eth_IIv.h_vlan_encapsulated_proto) < WLAN_MIN_PROTO) &&
1966 (pHdr->eth_8023v.h_snap.dsap == WLAN_SNAP_DSAP) &&
1967 (pHdr->eth_8023v.h_snap.ssap == WLAN_SNAP_SSAP) &&
1968 (pHdr->eth_8023v.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1969 (pHdr->eth_8023v.h_proto == htons(ETH_P_IP)))
1970 {
1971 // case 4: 802.3 LLC/SNAP vlan-tagged IP packet
1972 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023v)];
1973 tos = pIpHdr->tos;
1974#ifdef HDD_WMM_DEBUG
1975 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1976 "%s: 802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001977 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001978#endif // HDD_WMM_DEBUG
1979 }
1980 else
1981 {
1982 // default
1983#ifdef HDD_WMM_DEBUG
1984 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1985 "%s: VLAN tagged Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001986 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001987#endif // HDD_WMM_DEBUG
1988 tos = 0;
1989 }
1990 }
1991 else
1992 {
Hanumantha Reddy Pothulaee001fc2015-05-26 15:21:53 +05301993 v_BOOL_t toggleArpBDRates =
1994 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->toggleArpBDRates;
Jeff Johnson295189b2012-06-20 16:38:30 -07001995 // default
1996#ifdef HDD_WMM_DEBUG
1997 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1998 "%s: Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001999 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002000#endif // HDD_WMM_DEBUG
2001 //Give the highest priority to 802.1x packet
2002 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
2003 tos = 0xC0;
Sachin Ahujaf51bfac2015-09-24 21:46:16 +05302004 else if (toggleArpBDRates &&
Hanumantha Reddy Pothulaee001fc2015-05-26 15:21:53 +05302005 pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_ARP))
2006 {
2007 tos = TID3;
2008 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002009 else
2010 tos = 0;
2011 }
2012
2013 dscp = (tos>>2) & 0x3f;
Kumar Anand82c009f2014-05-29 00:29:42 -07002014 userPri = pAdapter->hddWmmDscpToUpMap[dscp];
2015
Jeff Johnson295189b2012-06-20 16:38:30 -07002016#ifdef HDD_WMM_DEBUG
2017 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2018 "%s: tos is %d, dscp is %d, up is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002019 __func__, tos, dscp, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07002020#endif // HDD_WMM_DEBUG
2021
2022 }
2023 else if (HDD_WMM_CLASSIFICATION_802_1Q == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
2024 {
2025 if (pHdr->eth_IIv.h_vlan_proto == htons(ETH_P_8021Q))
2026 {
2027 // VLAN tagged
2028 userPri = (ntohs(pHdr->eth_IIv.h_vlan_TCI)>>13) & 0x7;
2029#ifdef HDD_WMM_DEBUG
2030 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2031 "%s: Tagged frame, UP is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002032 __func__, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07002033#endif // HDD_WMM_DEBUG
2034 }
2035 else
2036 {
2037 // not VLAN tagged, use default
2038#ifdef HDD_WMM_DEBUG
2039 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2040 "%s: Untagged frame, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002041 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002042#endif // HDD_WMM_DEBUG
2043 //Give the highest priority to 802.1x packet
2044 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
2045 userPri = SME_QOS_WMM_UP_VO;
2046 else
2047 userPri = SME_QOS_WMM_UP_BE;
2048 }
2049 }
2050 else
2051 {
2052 // default
2053#ifdef HDD_WMM_DEBUG
2054 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2055 "%s: Unknown classification scheme, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002056 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002057#endif // HDD_WMM_DEBUG
2058 userPri = SME_QOS_WMM_UP_BE;
2059 }
2060
2061 acType = hddWmmUpToAcMap[userPri];
2062
2063#ifdef HDD_WMM_DEBUG
2064 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2065 "%s: UP is %d, AC is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002066 __func__, userPri, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002067#endif // HDD_WMM_DEBUG
2068
2069 *pUserPri = userPri;
2070 *pAcType = acType;
2071
2072 return;
2073}
2074
2075/**============================================================================
2076 @brief hdd_hostapd_select_quueue() - Function which will classify the packet
2077 according to linux qdisc expectation.
2078
2079
2080 @param dev : [in] pointer to net_device structure
2081 @param skb : [in] pointer to os packet
2082
2083 @return : Qdisc queue index
2084 ===========================================================================*/
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05302085v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb
2086#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
2087 , void *accel_priv
2088#endif
2089#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
2090 , select_queue_fallback_t fallbac
2091#endif
2092)
Jeff Johnson295189b2012-06-20 16:38:30 -07002093{
2094 WLANTL_ACEnumType ac;
2095 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
2096 v_USHORT_t queueIndex;
2097 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
2098 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
2099 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002100 v_U8_t STAId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302101 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2102 ptSapContext pSapCtx = NULL;
Mukul Sharmabd6b9482015-06-19 16:43:57 +05302103 int status = 0;
Mukul Sharma986109f2015-04-20 22:29:39 +05302104
Mukul Sharmabd6b9482015-06-19 16:43:57 +05302105 status = wlan_hdd_validate_context(pHddCtx);
2106 if (status !=0 )
2107 {
2108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2109 FL("called during WDReset/unload"));
Mukul Sharma986109f2015-04-20 22:29:39 +05302110 skb->priority = SME_QOS_WMM_UP_BE;
2111 return HDD_LINUX_AC_BE;
2112 }
2113
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302114 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2115 if(pSapCtx == NULL){
Mukul Sharmabd6b9482015-06-19 16:43:57 +05302116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302117 FL("psapCtx is NULL"));
Nirav Shah7e3c8132015-06-22 23:51:42 +05302118 STAId = HDD_WLAN_INVALID_STA_ID;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302119 goto done;
2120 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002121 /*Get the Station ID*/
Nirav Shah7e3c8132015-06-22 23:51:42 +05302122 STAId = hdd_sta_id_find_from_mac_addr(pAdapter, pDestMacAddress);
2123 if (STAId == HDD_WLAN_INVALID_STA_ID) {
2124 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
2125 "%s: Failed to find right station", __func__);
2126 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07002127 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002128
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302129 spin_lock_bh( &pSapCtx->staInfo_lock );
2130 if (FALSE == vos_is_macaddr_equal(&pSapCtx->aStaInfo[STAId].macAddrSTA, pDestMacAddress))
Jeff Johnson295189b2012-06-20 16:38:30 -07002131 {
Agarwal Ashisha64c9542014-03-04 00:14:43 +05302132 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002133 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002134
Nirav Shah7e3c8132015-06-22 23:51:42 +05302135 STAId = HDD_WLAN_INVALID_STA_ID;
Jeff Johnson295189b2012-06-20 16:38:30 -07002136 goto release_lock;
2137 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302138 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 -07002139 {
2140 /* Get the user priority from IP header & corresponding AC */
2141 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05302142 //If 3/4th of Tx queue is used then place the DHCP packet in VOICE AC queue
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302143 if (pSapCtx->aStaInfo[STAId].vosLowResource && hdd_is_dhcp_packet(skb))
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05302144 {
2145 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2146 "%s: Making priority of DHCP packet as VOICE", __func__);
2147 up = SME_QOS_WMM_UP_VO;
2148 ac = hddWmmUpToAcMap[up];
2149 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002150 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002151
2152release_lock:
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302153 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07002154done:
2155 skb->priority = up;
Mukul Sharmad82cb7d2014-07-03 14:53:30 +05302156 if(skb->priority < SME_QOS_WMM_UP_MAX)
2157 queueIndex = hddLinuxUpToAcMap[skb->priority];
2158 else
2159 {
2160 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2161 "%s: up=%d is going beyond max value", __func__, up);
2162 queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
2163 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002164
2165 return queueIndex;
2166}
2167
2168/**============================================================================
2169 @brief hdd_wmm_select_quueue() - Function which will classify the packet
2170 according to linux qdisc expectation.
2171
2172
2173 @param dev : [in] pointer to net_device structure
2174 @param skb : [in] pointer to os packet
2175
2176 @return : Qdisc queue index
2177 ===========================================================================*/
2178v_U16_t hdd_wmm_select_queue(struct net_device * dev, struct sk_buff *skb)
2179{
2180 WLANTL_ACEnumType ac;
Shailender Karmuchia734f332013-04-19 14:02:48 -07002181 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002182 v_USHORT_t queueIndex;
Jeff Johnson295189b2012-06-20 16:38:30 -07002183 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma6bb6cdd2015-06-19 17:23:23 +05302184 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2185 int status = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002186
Mukul Sharma6bb6cdd2015-06-19 17:23:23 +05302187 status = wlan_hdd_validate_context(pHddCtx);
2188 if (status !=0) {
Kiet Lam40009862014-02-13 12:33:22 -08002189 skb->priority = SME_QOS_WMM_UP_BE;
2190 return HDD_LINUX_AC_BE;
2191 }
2192
Shailender Karmuchia734f332013-04-19 14:02:48 -07002193 /*Get the Station ID*/
2194 if (WLAN_HDD_IBSS == pAdapter->device_mode)
2195 {
Shailender Karmuchia734f332013-04-19 14:02:48 -07002196 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
Nirav Shah7e3c8132015-06-22 23:51:42 +05302197 v_U8_t STAId;
Shailender Karmuchia734f332013-04-19 14:02:48 -07002198
Nirav Shah7e3c8132015-06-22 23:51:42 +05302199 STAId = hdd_sta_id_find_from_mac_addr(pAdapter, pDestMacAddress);
2200 if ((STAId == HDD_WLAN_INVALID_STA_ID) &&
2201 !vos_is_macaddr_broadcast( pDestMacAddress ) &&
2202 !vos_is_macaddr_group(pDestMacAddress))
Shailender Karmuchia734f332013-04-19 14:02:48 -07002203 {
Nirav Shah7e3c8132015-06-22 23:51:42 +05302204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnsonb9fb9ce2013-05-03 08:11:02 -07002205 "%s: Failed to find right station pDestMacAddress: "
2206 MAC_ADDRESS_STR , __func__,
2207 MAC_ADDR_ARRAY(pDestMacAddress->bytes));
Nirav Shah7e3c8132015-06-22 23:51:42 +05302208 goto done;
Shailender Karmuchia734f332013-04-19 14:02:48 -07002209 }
2210 }
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302211 /* All traffic will get equal opportuniy to transmit data frames. */
2212 /* Get the user priority from IP header & corresponding AC */
2213 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302214
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302215 /* If 3/4th of BE AC Tx queue is full,
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302216 * then place the DHCP packet in VOICE AC queue.
2217 * Doing this for IBSS alone, since for STA interface
2218 * types, these packets will be queued to the new queue.
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302219 */
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302220 if ((WLAN_HDD_IBSS == pAdapter->device_mode) &&
2221 pAdapter->isVosLowResource && hdd_is_dhcp_packet(skb))
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302222 {
2223 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2224 "%s: BestEffort Tx Queue is 3/4th full"
2225 " Make DHCP packet's pri as VO", __func__);
2226 up = SME_QOS_WMM_UP_VO;
2227 ac = hddWmmUpToAcMap[up];
Jeff Johnson295189b2012-06-20 16:38:30 -07002228 }
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302229
Shailender Karmuchia734f332013-04-19 14:02:48 -07002230done:
Jeff Johnson295189b2012-06-20 16:38:30 -07002231 skb->priority = up;
Mukul Sharmad82cb7d2014-07-03 14:53:30 +05302232 if(skb->priority < SME_QOS_WMM_UP_MAX)
2233 queueIndex = hddLinuxUpToAcMap[skb->priority];
2234 else
2235 {
2236 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2237 "%s: up=%d is going beyond max value", __func__, up);
2238 queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
2239 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002240
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302241 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
2242 (hdd_is_dhcp_packet(skb) ||
2243 hdd_skb_is_eapol_or_wai_packet(skb)))
2244 {
2245 /* If the packet is a DHCP packet or a Eapol packet or
2246 * a Wapi packet, then queue it to the new queue for
2247 * STA interfaces alone.
2248 */
2249 queueIndex = WLANTL_AC_HIGH_PRIO;
2250 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2251 "%s: up=%d QIndex:%d", __func__, up, queueIndex);
2252 }
2253
Jeff Johnson295189b2012-06-20 16:38:30 -07002254 return queueIndex;
2255}
2256
Kiet Lamf040f472013-11-20 21:15:23 +05302257/**==========================================================================
2258 @brief hdd_wmm_acquire_access_required() - Function which will determine
2259 acquire admittance for a WMM AC is required or not based on psb configuration
2260 done in framework
2261
2262 @param pAdapter : [in] pointer to adapter structure
2263
2264 @param acType : [in] WMM AC type of OS packet
2265
2266 @return : void
2267 ===========================================================================*/
2268void hdd_wmm_acquire_access_required(hdd_adapter_t *pAdapter,
2269 WLANTL_ACEnumType acType)
2270{
2271/* Each bit in the LSB nibble indicates 1 AC.
2272 * Clearing the particular bit in LSB nibble to indicate
2273 * access required
2274 */
2275 switch(acType)
2276 {
2277 case WLANTL_AC_BK:
2278 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BK_CHANGED_MASK; /* clear first bit */
2279 break;
2280 case WLANTL_AC_BE:
2281 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BE_CHANGED_MASK; /* clear second bit */
2282 break;
2283 case WLANTL_AC_VI:
2284 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VI_CHANGED_MASK; /* clear third bit */
2285 break;
2286 case WLANTL_AC_VO:
2287 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VO_CHANGED_MASK; /* clear fourth bit */
2288 break;
2289 default:
2290 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2291 "%s: Invalid AC Type", __func__);
2292 break;
2293 }
2294}
2295
Jeff Johnson295189b2012-06-20 16:38:30 -07002296/**============================================================================
2297 @brief hdd_wmm_acquire_access() - Function which will attempt to acquire
2298 admittance for a WMM AC
2299
2300 @param pAdapter : [in] pointer to adapter context
2301 @param acType : [in] WMM AC type of OS packet
2302 @param pGranted : [out] pointer to boolean flag when indicates if access
2303 has been granted or not
2304
2305 @return : VOS_STATUS_SUCCESS if succssful
2306 : other values if failure
2307 ===========================================================================*/
2308VOS_STATUS hdd_wmm_acquire_access( hdd_adapter_t* pAdapter,
2309 WLANTL_ACEnumType acType,
2310 v_BOOL_t * pGranted )
2311{
2312 hdd_wmm_qos_context_t *pQosContext;
2313
2314 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002315 "%s: Entered for AC %d", __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002316
2317 if (!hdd_wmm_is_active(pAdapter) || !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
2318 {
2319 // either we don't want QoS or the AP doesn't support QoS
2320 // or we don't want to do implicit QoS
2321 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002322 "%s: QoS not configured on both ends ", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002323
2324 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2325 *pGranted = VOS_TRUE;
2326 return VOS_STATUS_SUCCESS;
2327 }
2328
2329 // do we already have an implicit QoS request pending for this AC?
2330 if ((pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded) ||
2331 (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessPending))
2332 {
2333 // request already pending so we need to wait for that response
2334 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2335 "%s: Implicit QoS for TL AC %d already scheduled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002336 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002337
2338 *pGranted = VOS_FALSE;
2339 return VOS_STATUS_SUCCESS;
2340 }
2341
2342 // did we already fail to establish implicit QoS for this AC?
2343 // (if so, access should have been granted when the failure was handled)
2344 if (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessFailed)
2345 {
2346 // request previously failed
2347 // allow access, but we'll be downgraded
2348 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2349 "%s: Implicit QoS for TL AC %d previously failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002350 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002351
2352 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2353 *pGranted = VOS_TRUE;
2354 return VOS_STATUS_SUCCESS;
2355 }
2356
2357 // we need to establish implicit QoS
2358 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2359 "%s: Need to schedule implicit QoS for TL AC %d, pAdapter is %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002360 __func__, acType, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002361
2362 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded = VOS_TRUE;
2363
Mohit Khanna217ea8d2012-09-11 17:42:42 -07002364 pQosContext = kmalloc(sizeof(*pQosContext), GFP_ATOMIC);
Jeff Johnson295189b2012-06-20 16:38:30 -07002365 if (NULL == pQosContext)
2366 {
2367 // no memory for QoS context. Nothing we can do but let data flow
2368 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002369 "%s: Unable to allocate context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002370 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2371 *pGranted = VOS_TRUE;
2372 return VOS_STATUS_SUCCESS;
2373 }
2374
2375 pQosContext->acType = acType;
2376 pQosContext->pAdapter = pAdapter;
2377 pQosContext->qosFlowId = 0;
2378 pQosContext->handle = HDD_WMM_HANDLE_IMPLICIT;
2379 pQosContext->magic = HDD_WMM_CTX_MAGIC;
Anand N Sunkaddc63c792015-06-03 14:33:24 +05302380 vos_init_work(&pQosContext->wmmAcSetupImplicitQos,
Jeff Johnson295189b2012-06-20 16:38:30 -07002381 hdd_wmm_do_implicit_qos);
2382
2383 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2384 "%s: Scheduling work for AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002385 __func__, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002386
2387 schedule_work(&pQosContext->wmmAcSetupImplicitQos);
2388
2389 // caller will need to wait until the work takes place and
2390 // TSPEC negotiation completes
2391 *pGranted = VOS_FALSE;
2392 return VOS_STATUS_SUCCESS;
2393}
2394
2395/**============================================================================
2396 @brief hdd_wmm_assoc() - Function which will handle the housekeeping
2397 required by WMM when association takes place
2398
2399 @param pAdapter : [in] pointer to adapter context
2400 @param pRoamInfo: [in] pointer to roam information
2401 @param eBssType : [in] type of BSS
2402
2403 @return : VOS_STATUS_SUCCESS if succssful
2404 : other values if failure
2405 ===========================================================================*/
2406VOS_STATUS hdd_wmm_assoc( hdd_adapter_t* pAdapter,
2407 tCsrRoamInfo *pRoamInfo,
2408 eCsrRoamBssType eBssType )
2409{
2410 tANI_U8 uapsdMask;
2411 VOS_STATUS status;
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002412 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002413
2414 // when we associate we need to notify TL if it needs to enable
2415 // UAPSD for any access categories
2416
2417 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002418 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002419
2420 if (pRoamInfo->fReassocReq)
2421 {
2422 // when we reassociate we should continue to use whatever
2423 // parameters were previously established. if we are
2424 // reassociating due to a U-APSD change for a particular
2425 // Access Category, then the change will be communicated
2426 // to HDD via the QoS callback associated with the given
2427 // flow, and U-APSD parameters will be updated there
2428
2429 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002430 "%s: Reassoc so no work, Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002431
2432 return VOS_STATUS_SUCCESS;
2433 }
2434
2435 // get the negotiated UAPSD Mask
2436 uapsdMask = pRoamInfo->u.pConnectedProfile->modifyProfileFields.uapsd_mask;
2437
2438 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002439 "%s: U-APSD mask is 0x%02x", __func__, (int) uapsdMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002440
2441 if (uapsdMask & HDD_AC_VO)
2442 {
2443 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2444 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2445 WLANTL_AC_VO,
2446 7,
2447 7,
2448 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv,
2449 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv,
2450 WLANTL_BI_DIR );
2451
2452 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2453 }
2454
2455 if (uapsdMask & HDD_AC_VI)
2456 {
2457 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2458 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2459 WLANTL_AC_VI,
2460 5,
2461 5,
2462 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv,
2463 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv,
2464 WLANTL_BI_DIR );
2465
2466 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2467 }
2468
2469 if (uapsdMask & HDD_AC_BK)
2470 {
2471 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2472 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2473 WLANTL_AC_BK,
2474 2,
2475 2,
2476 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv,
2477 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv,
2478 WLANTL_BI_DIR );
2479
2480 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2481 }
2482
2483 if (uapsdMask & HDD_AC_BE)
2484 {
2485 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2486 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2487 WLANTL_AC_BE,
2488 3,
2489 3,
2490 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv,
2491 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv,
2492 WLANTL_BI_DIR );
2493
2494 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2495 }
Kumar Anand82c009f2014-05-29 00:29:42 -07002496
2497 status = sme_UpdateDSCPtoUPMapping(pHddCtx->hHal,
2498 pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId);
2499
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002500 if (!VOS_IS_STATUS_SUCCESS( status ))
2501 {
Kumar Anand82c009f2014-05-29 00:29:42 -07002502 hdd_wmm_init( pAdapter );
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002503 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002504
2505 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002506 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002507
2508 return VOS_STATUS_SUCCESS;
2509}
2510
2511
2512
2513static const v_U8_t acmMaskBit[WLANTL_MAX_AC] =
2514 {
2515 0x4, /* WLANTL_AC_BK */
2516 0x8, /* WLANTL_AC_BE */
2517 0x2, /* WLANTL_AC_VI */
2518 0x1 /* WLANTL_AC_VO */
2519 };
2520
2521/**============================================================================
2522 @brief hdd_wmm_connect() - Function which will handle the housekeeping
2523 required by WMM when a connection is established
2524
2525 @param pAdapter : [in] pointer to adapter context
2526 @param pRoamInfo: [in] pointer to roam information
2527 @param eBssType : [in] type of BSS
2528
2529 @return : VOS_STATUS_SUCCESS if succssful
2530 : other values if failure
2531 ===========================================================================*/
2532VOS_STATUS hdd_wmm_connect( hdd_adapter_t* pAdapter,
2533 tCsrRoamInfo *pRoamInfo,
2534 eCsrRoamBssType eBssType )
2535{
2536 int ac;
2537 v_BOOL_t qap;
2538 v_BOOL_t qosConnection;
2539 v_U8_t acmMask;
2540
2541 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002542 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002543
2544 if ((eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) &&
2545 pRoamInfo &&
2546 pRoamInfo->u.pConnectedProfile)
2547 {
2548 qap = pRoamInfo->u.pConnectedProfile->qap;
2549 qosConnection = pRoamInfo->u.pConnectedProfile->qosConnection;
2550 acmMask = pRoamInfo->u.pConnectedProfile->acm_mask;
2551 }
2552 else
2553 {
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05302554 /* TODO: if a non-qos IBSS peer joins the group make qap and qosConnection false.
2555 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002556 qap = VOS_TRUE;
2557 qosConnection = VOS_TRUE;
2558 acmMask = 0x0;
2559 }
2560
2561 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2562 "%s: qap is %d, qosConnection is %d, acmMask is 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002563 __func__, qap, qosConnection, acmMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002564
2565 pAdapter->hddWmmStatus.wmmQap = qap;
2566 pAdapter->hddWmmStatus.wmmQosConnection = qosConnection;
2567
2568 for (ac = 0; ac < WLANTL_MAX_AC; ac++)
2569 {
2570 if (qap &&
2571 qosConnection &&
2572 (acmMask & acmMaskBit[ac]))
2573 {
2574 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2575 "%s: ac %d on",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002576 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002577
2578 // admission is required
2579 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_TRUE;
Padma, Santhosh Kumar73f22252015-05-05 11:59:24 +05302580 //Mark wmmAcAccessAllowed as True if implicit Qos is disabled as there
2581 //is no need to hold packets in queue during hdd_tx_fetch_packet_cbk
2582 if (!(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
2583 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed =
2584 VOS_TRUE;
2585 else
2586 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed =
2587 VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002588 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessGranted = VOS_FALSE;
Mukul Sharma74a01e52014-07-21 15:14:23 +05302589
2590 /* Making TSPEC invalid here so downgrading can be happen while roaming
2591 * It is expected this will be SET in hdd_wmm_sme_callback,once sme is
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302592 * done with the AddTspec.Here we avoid 11r and ccx based association.
2593 This change is done only when reassoc to different AP.
Mukul Sharma74a01e52014-07-21 15:14:23 +05302594 */
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2596 FL( "fReassocReq = %d"
2597#if defined (FEATURE_WLAN_ESE)
2598 "isESEAssoc = %d"
2599#endif
2600#if defined (WLAN_FEATURE_VOWIFI_11R)
2601 "is11rAssoc = %d"
2602#endif
2603 ),
2604 pRoamInfo->fReassocReq
2605#if defined (FEATURE_WLAN_ESE)
2606 ,pRoamInfo->isESEAssoc
2607#endif
2608#if defined (WLAN_FEATURE_VOWIFI_11R)
2609 ,pRoamInfo->is11rAssoc
2610#endif
2611 );
2612
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302613 if ( !pRoamInfo->fReassocReq
Mukul Sharma74a01e52014-07-21 15:14:23 +05302614#if defined (WLAN_FEATURE_VOWIFI_11R)
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302615 &&
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302616 !pRoamInfo->is11rAssoc
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302617#endif
Mukul Sharma74a01e52014-07-21 15:14:23 +05302618#if defined (FEATURE_WLAN_ESE)
2619 &&
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302620 !pRoamInfo->isESEAssoc
Mukul Sharma74a01e52014-07-21 15:14:23 +05302621#endif
2622 )
Mukul Sharma74a01e52014-07-21 15:14:23 +05302623 {
2624 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcTspecValid = VOS_FALSE;
2625 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002626 }
2627 else
2628 {
2629 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2630 "%s: ac %d off",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002631 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002632 // admission is not required so access is allowed
2633 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_FALSE;
2634 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_TRUE;
2635 }
2636
2637 }
2638
2639 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002640 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002641
2642 return VOS_STATUS_SUCCESS;
2643}
2644
2645/**============================================================================
2646 @brief hdd_wmm_get_uapsd_mask() - Function which will calculate the
2647 initial value of the UAPSD mask based upon the device configuration
2648
2649 @param pAdapter : [in] pointer to adapter context
2650 @param pUapsdMask: [in] pointer to where the UAPSD Mask is to be stored
2651
2652 @return : VOS_STATUS_SUCCESS if succssful
2653 : other values if failure
2654 ===========================================================================*/
2655VOS_STATUS hdd_wmm_get_uapsd_mask( hdd_adapter_t* pAdapter,
2656 tANI_U8 *pUapsdMask )
2657{
2658 tANI_U8 uapsdMask;
2659
2660 if (HDD_WMM_USER_MODE_NO_QOS == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
2661 {
2662 // no QOS then no UAPSD
2663 uapsdMask = 0;
2664 }
2665 else
2666 {
2667 // start with the default mask
2668 uapsdMask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
2669
2670 // disable UAPSD for any ACs with a 0 Service Interval
2671 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv == 0 )
2672 {
2673 uapsdMask &= ~HDD_AC_VO;
2674 }
2675
2676 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv == 0 )
2677 {
2678 uapsdMask &= ~HDD_AC_VI;
2679 }
2680
2681 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv == 0 )
2682 {
2683 uapsdMask &= ~HDD_AC_BK;
2684 }
2685
2686 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv == 0 )
2687 {
2688 uapsdMask &= ~HDD_AC_BE;
2689 }
2690 }
2691
2692 // return calculated mask
2693 *pUapsdMask = uapsdMask;
2694 return VOS_STATUS_SUCCESS;
2695}
2696
2697
2698/**============================================================================
2699 @brief hdd_wmm_is_active() - Function which will determine if WMM is
2700 active on the current connection
2701
2702 @param pAdapter : [in] pointer to adapter context
2703
2704 @return : VOS_TRUE if WMM is enabled
2705 : VOS_FALSE if WMM is not enabled
2706 ===========================================================================*/
2707v_BOOL_t hdd_wmm_is_active( hdd_adapter_t* pAdapter )
2708{
2709 if ((!pAdapter->hddWmmStatus.wmmQosConnection) ||
2710 (!pAdapter->hddWmmStatus.wmmQap))
2711 {
2712 return VOS_FALSE;
2713 }
2714 else
2715 {
2716 return VOS_TRUE;
2717 }
2718}
2719
2720/**============================================================================
2721 @brief hdd_wmm_addts() - Function which will add a traffic spec at the
2722 request of an application
2723
2724 @param pAdapter : [in] pointer to adapter context
2725 @param handle : [in] handle to uniquely identify a TS
2726 @param pTspec : [in] pointer to the traffic spec
2727
2728 @return : HDD_WLAN_WMM_STATUS_*
2729 ===========================================================================*/
2730hdd_wlan_wmm_status_e hdd_wmm_addts( hdd_adapter_t* pAdapter,
2731 v_U32_t handle,
2732 sme_QosWmmTspecInfo* pTspec )
2733{
2734 hdd_wmm_qos_context_t *pQosContext;
2735 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2736#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2737 sme_QosStatusType smeStatus;
2738#endif
2739 v_BOOL_t found = VOS_FALSE;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302740 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +05302741 hdd_context_t *pHddCtx = NULL;
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302742
2743 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302744 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302745 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2746 FL("pVosContext is NULL"));
2747 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302748 }
2749
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302750 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
2751 if (NULL == pHddCtx)
2752 {
2753 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2754 FL("HddCtx is NULL"));
2755 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2756 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002757
2758 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002759 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002760
2761 // see if a context already exists with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302762 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002763 list_for_each_entry(pQosContext,
2764 &pAdapter->hddWmmStatus.wmmContextList,
2765 node)
2766 {
2767 if (pQosContext->handle == handle)
2768 {
2769 found = VOS_TRUE;
2770 break;
2771 }
2772 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302773 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002774 if (found)
2775 {
2776 // record with that handle already exists
2777 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2778 "%s: Record already exists with handle 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002779 __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002780
2781 /* Application is trying to modify some of the Tspec params. Allow it */
2782 smeStatus = sme_QosModifyReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2783 pTspec,
2784 pQosContext->qosFlowId);
2785
2786 // need to check the return value and act appropriately
2787 switch (smeStatus)
2788 {
2789 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
2790 status = HDD_WLAN_WMM_STATUS_MODIFY_PENDING;
2791 break;
2792 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2793 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
2794 break;
2795 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
2796 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
2797 break;
2798 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
2799 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
2800 break;
2801 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
2802 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2803 break;
2804 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2805 status = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2806 break;
2807 default:
2808 // we didn't get back one of the SME_QOS_STATUS_MODIFY_* status codes
2809 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002810 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002811 VOS_ASSERT(0);
2812 return HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2813 }
2814
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302815 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05302816 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
2817 {
2818 pQosContext->lastStatus = status;
2819 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302820 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002821 return status;
2822 }
2823
2824 pQosContext = kmalloc(sizeof(*pQosContext), GFP_KERNEL);
2825 if (NULL == pQosContext)
2826 {
2827 // no memory for QoS context. Nothing we can do
2828 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002829 "%s: Unable to allocate QoS context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002830 return HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE;
2831 }
2832
2833 // we assume the tspec has already been validated by the caller
2834
2835 pQosContext->handle = handle;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08002836 if (pTspec->ts_info.up < HDD_WMM_UP_TO_AC_MAP_SIZE)
2837 pQosContext->acType = hddWmmUpToAcMap[pTspec->ts_info.up];
2838 else {
2839 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2840 "%s: ts_info.up (%d) larger than max value (%d), "
2841 "use default acType (%d)",
2842 __func__, pTspec->ts_info.up,
2843 HDD_WMM_UP_TO_AC_MAP_SIZE - 1, hddWmmUpToAcMap[0]);
2844 pQosContext->acType = hddWmmUpToAcMap[0];
2845 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302846
Jeff Johnson295189b2012-06-20 16:38:30 -07002847 pQosContext->pAdapter = pAdapter;
2848 pQosContext->qosFlowId = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002849
2850 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2851 "%s: Setting up QoS, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002852 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002853
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302854 mutex_lock(&pHddCtx->wmmLock);
2855 pQosContext->magic = HDD_WMM_CTX_MAGIC;
Jeff Johnson295189b2012-06-20 16:38:30 -07002856 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302857 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002858
2859#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2860 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2861 pAdapter->sessionId,
2862 pTspec,
2863 hdd_wmm_sme_callback,
2864 pQosContext,
2865 pTspec->ts_info.up,
2866 &pQosContext->qosFlowId);
2867
2868 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2869 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002870 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002871
2872 // need to check the return value and act appropriately
2873 switch (smeStatus)
2874 {
2875 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
2876 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2877 break;
2878 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2879 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
2880 break;
2881 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
2882 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
2883 break;
2884 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
2885 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2886 break;
2887 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
2888 hdd_wmm_free_context(pQosContext);
2889 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
2890 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
2891 // we can't tell the difference between when a request fails because
2892 // AP rejected it versus when SME encounterd an internal error
2893 hdd_wmm_free_context(pQosContext);
2894 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2895 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2896 hdd_wmm_free_context(pQosContext);
2897 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2898 default:
2899 // we didn't get back one of the SME_QOS_STATUS_SETUP_* status codes
2900 hdd_wmm_free_context(pQosContext);
2901 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002902 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002903 VOS_ASSERT(0);
2904 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2905 }
2906#endif
2907
2908 // we were successful, save the status
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302909 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05302910 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
2911 {
2912 pQosContext->lastStatus = status;
2913 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302914 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002915
2916 return status;
2917}
2918
2919/**============================================================================
2920 @brief hdd_wmm_delts() - Function which will delete a traffic spec at the
2921 request of an application
2922
2923 @param pAdapter : [in] pointer to adapter context
2924 @param handle : [in] handle to uniquely identify a TS
2925
2926 @return : HDD_WLAN_WMM_STATUS_*
2927 ===========================================================================*/
2928hdd_wlan_wmm_status_e hdd_wmm_delts( hdd_adapter_t* pAdapter,
2929 v_U32_t handle )
2930{
2931 hdd_wmm_qos_context_t *pQosContext;
2932 v_BOOL_t found = VOS_FALSE;
2933 WLANTL_ACEnumType acType = 0;
2934 v_U32_t qosFlowId = 0;
2935 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2936#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2937 sme_QosStatusType smeStatus;
2938#endif
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302939 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +05302940 hdd_context_t *pHddCtx = NULL;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302941
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302942 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302943 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302944 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2945 FL("pVosContext is NULL"));
2946 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2947 }
2948
2949 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
2950 if (NULL == pHddCtx)
2951 {
2952 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302953 FL("HddCtx is NULL"));
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302954 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302955 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002956
2957 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002958 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002959
2960 // locate the context with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302961 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002962 list_for_each_entry(pQosContext,
2963 &pAdapter->hddWmmStatus.wmmContextList,
2964 node)
2965 {
2966 if (pQosContext->handle == handle)
2967 {
2968 found = VOS_TRUE;
2969 acType = pQosContext->acType;
2970 qosFlowId = pQosContext->qosFlowId;
2971 break;
2972 }
2973 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302974 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002975
2976 if (VOS_FALSE == found)
2977 {
2978 // we didn't find the handle
2979 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002980 "%s: handle 0x%x not found", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002981 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2982 }
2983
2984
2985 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2986 "%s: found handle 0x%x, flow %d, AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002987 __func__, handle, qosFlowId, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002988
2989#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2990 smeStatus = sme_QosReleaseReq( WLAN_HDD_GET_HAL_CTX(pAdapter), qosFlowId );
2991
2992 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2993 "%s: SME flow %d released, SME status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002994 __func__, qosFlowId, smeStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07002995
2996 switch(smeStatus)
2997 {
2998 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
2999 // this flow is the only one on that AC, so go ahead and update
3000 // our TSPEC state for the AC
3001 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcTspecValid = VOS_FALSE;
3002
3003 // need to tell TL to stop trigger timer, etc
3004 hdd_wmm_disable_tl_uapsd(pQosContext);
3005
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003006#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07003007 // disable the inactivity timer
3008 hdd_wmm_disable_inactivity_timer(pQosContext);
3009#endif
3010 // we are done with this context
3011 hdd_wmm_free_context(pQosContext);
3012
3013 // SME must not fire any more callbacks for this flow since the context
3014 // is no longer valid
3015
3016 return HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
3017
3018 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
3019 // do nothing as we will get a response from SME
3020 status = HDD_WLAN_WMM_STATUS_RELEASE_PENDING;
3021 break;
3022
3023 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
3024 // nothing we can do with the existing flow except leave it
3025 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
3026 break;
3027
3028 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
3029 // nothing we can do with the existing flow except leave it
3030 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
3031
3032 default:
3033 // we didn't get back one of the SME_QOS_STATUS_RELEASE_* status codes
3034 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003035 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07003036 VOS_ASSERT(0);
3037 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
3038 }
3039
3040#endif
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303041 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05303042 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
3043 {
3044 pQosContext->lastStatus = status;
3045 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303046 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003047 return status;
3048}
3049
3050/**============================================================================
3051 @brief hdd_wmm_checkts() - Function which will return the status of a traffic
3052 spec at the request of an application
3053
3054 @param pAdapter : [in] pointer to adapter context
3055 @param handle : [in] handle to uniquely identify a TS
3056
3057 @return : HDD_WLAN_WMM_STATUS_*
3058 ===========================================================================*/
3059hdd_wlan_wmm_status_e hdd_wmm_checkts( hdd_adapter_t* pAdapter,
3060 v_U32_t handle )
3061{
3062 hdd_wmm_qos_context_t *pQosContext;
3063 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303064 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +05303065 hdd_context_t *pHddCtx = NULL;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303066
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303067 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303068 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303069 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
3070 FL("pVosContext is NULL"));
3071 return HDD_WLAN_WMM_STATUS_LOST;
3072 }
3073
3074 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
3075 if (NULL == pHddCtx)
3076 {
3077 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303078 FL("HddCtx is NULL"));
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303079 return HDD_WLAN_WMM_STATUS_LOST;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303080 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003081
3082 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003083 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07003084
3085 // locate the context with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303086 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003087 list_for_each_entry(pQosContext,
3088 &pAdapter->hddWmmStatus.wmmContextList,
3089 node)
3090 {
3091 if (pQosContext->handle == handle)
3092 {
3093 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
3094 "%s: found handle 0x%x, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003095 __func__, handle, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07003096
3097 status = pQosContext->lastStatus;
3098 break;
3099 }
3100 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303101 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003102 return status;
3103}