blob: a675e01f500f915a394f78532c0098b8aebd8f1b [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam842dad02014-02-18 18:44:02 -080021
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028/*============================================================================
29 @file wlan_hdd_wmm.c
30
31 This module (wlan_hdd_wmm.h interface + wlan_hdd_wmm.c implementation)
32 houses all the logic for WMM in HDD.
33
34 On the control path, it has the logic to setup QoS, modify QoS and delete
35 QoS (QoS here refers to a TSPEC). The setup QoS comes in two flavors: an
36 explicit application invoked and an internal HDD invoked. The implicit QoS
37 is for applications that do NOT call the custom QCT WLAN OIDs for QoS but
38 which DO mark their traffic for priortization. It also has logic to start,
39 update and stop the U-APSD trigger frame generation. It also has logic to
40 read WMM related config parameters from the registry.
41
42 On the data path, it has the logic to figure out the WMM AC of an egress
43 packet and when to signal TL to serve a particular AC queue. It also has the
44 logic to retrieve a packet based on WMM priority in response to a fetch from
45 TL.
46
47 The remaining functions are utility functions for information hiding.
48
49
Jeff Johnson295189b2012-06-20 16:38:30 -070050============================================================================*/
51
52/*---------------------------------------------------------------------------
53 Include files
54 -------------------------------------------------------------------------*/
55#include <wlan_hdd_tx_rx.h>
56#include <wlan_hdd_dp_utils.h>
57#include <wlan_hdd_wmm.h>
58#include <wlan_hdd_ether.h>
59#include <linux/netdevice.h>
60#include <linux/skbuff.h>
61#include <linux/etherdevice.h>
62#include <linux/if_vlan.h>
63#include <linux/ip.h>
64#include <linux/semaphore.h>
65#include <wlan_hdd_hostapd.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <wlan_hdd_softap_tx_rx.h>
Kiet Lam40009862014-02-13 12:33:22 -080067#include <vos_sched.h>
Mukul Sharma74a01e52014-07-21 15:14:23 +053068#include "sme_Api.h"
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053069#include "sapInternal.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070070// change logging behavior based upon debug flag
71#ifdef HDD_WMM_DEBUG
72#define WMM_TRACE_LEVEL_FATAL VOS_TRACE_LEVEL_FATAL
73#define WMM_TRACE_LEVEL_ERROR VOS_TRACE_LEVEL_FATAL
74#define WMM_TRACE_LEVEL_WARN VOS_TRACE_LEVEL_FATAL
75#define WMM_TRACE_LEVEL_INFO VOS_TRACE_LEVEL_FATAL
76#define WMM_TRACE_LEVEL_INFO_HIGH VOS_TRACE_LEVEL_FATAL
77#define WMM_TRACE_LEVEL_INFO_LOW VOS_TRACE_LEVEL_FATAL
78#else
79#define WMM_TRACE_LEVEL_FATAL VOS_TRACE_LEVEL_FATAL
80#define WMM_TRACE_LEVEL_ERROR VOS_TRACE_LEVEL_ERROR
81#define WMM_TRACE_LEVEL_WARN VOS_TRACE_LEVEL_WARN
82#define WMM_TRACE_LEVEL_INFO VOS_TRACE_LEVEL_INFO
83#define WMM_TRACE_LEVEL_INFO_HIGH VOS_TRACE_LEVEL_INFO_HIGH
84#define WMM_TRACE_LEVEL_INFO_LOW VOS_TRACE_LEVEL_INFO_LOW
85#endif
86
87
Jeff Johnson295189b2012-06-20 16:38:30 -070088#define WLAN_HDD_MAX_DSCP 0x3f
89
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +053090// DHCP Port number
91#define DHCP_SOURCE_PORT 0x4400
92#define DHCP_DESTINATION_PORT 0x4300
93
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080094#define HDD_WMM_UP_TO_AC_MAP_SIZE 8
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -070095
Jeff Johnson295189b2012-06-20 16:38:30 -070096const v_U8_t hddWmmUpToAcMap[] = {
97 WLANTL_AC_BE,
98 WLANTL_AC_BK,
99 WLANTL_AC_BK,
100 WLANTL_AC_BE,
101 WLANTL_AC_VI,
102 WLANTL_AC_VI,
103 WLANTL_AC_VO,
104 WLANTL_AC_VO
105};
106
107//Linux based UP -> AC Mapping
108const v_U8_t hddLinuxUpToAcMap[8] = {
109 HDD_LINUX_AC_BE,
110 HDD_LINUX_AC_BK,
111 HDD_LINUX_AC_BK,
112 HDD_LINUX_AC_BE,
113 HDD_LINUX_AC_VI,
114 HDD_LINUX_AC_VI,
115 HDD_LINUX_AC_VO,
116 HDD_LINUX_AC_VO
117};
118
119#ifndef WLAN_MDM_CODE_REDUCTION_OPT
120/**
121 @brief hdd_wmm_enable_tl_uapsd() - function which decides whether and
122 how to update UAPSD parameters in TL
123
124 @param pQosContext : [in] the pointer the QoS instance control block
125
126 @return
127 None
128*/
129static void hdd_wmm_enable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
130{
131 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
132 WLANTL_ACEnumType acType = pQosContext->acType;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530133 hdd_wmm_ac_status_t *pAc = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700134 VOS_STATUS status;
135 v_U32_t service_interval;
136 v_U32_t suspension_interval;
137 sme_QosWmmDirType direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530138 v_BOOL_t psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700139
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530140 if (acType >= WLANTL_MAX_AC)
141 {
142 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
143 "%s: Invalid AC: %d", __func__, acType);
144 return;
145 }
146
147 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
Jeff Johnson295189b2012-06-20 16:38:30 -0700148
149 // The TSPEC must be valid
150 if (pAc->wmmAcTspecValid == VOS_FALSE)
151 {
152 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
153 "%s: Invoked with invalid TSPEC",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700154 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700155 return;
156 }
157
158 // determine the service interval
159 if (pAc->wmmAcTspecInfo.min_service_interval)
160 {
161 service_interval = pAc->wmmAcTspecInfo.min_service_interval;
162 }
163 else if (pAc->wmmAcTspecInfo.max_service_interval)
164 {
165 service_interval = pAc->wmmAcTspecInfo.max_service_interval;
166 }
167 else
168 {
169 // no service interval is present in the TSPEC
170 // this is OK, there just won't be U-APSD
171 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
172 "%s: No service interval supplied",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700173 __func__);
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530174 service_interval = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700175 }
176
177 // determine the suspension interval & direction
178 suspension_interval = pAc->wmmAcTspecInfo.suspension_interval;
179 direction = pAc->wmmAcTspecInfo.ts_info.direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530180 psb = pAc->wmmAcTspecInfo.ts_info.psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700181
182 // if we have previously enabled U-APSD, have any params changed?
183 if ((pAc->wmmAcUapsdInfoValid) &&
184 (pAc->wmmAcUapsdServiceInterval == service_interval) &&
185 (pAc->wmmAcUapsdSuspensionInterval == suspension_interval) &&
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530186 (pAc->wmmAcUapsdDirection == direction) &&
187 (pAc->wmmAcIsUapsdEnabled == psb))
Jeff Johnson295189b2012-06-20 16:38:30 -0700188 {
189 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
190 "%s: No change in U-APSD parameters",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700191 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700192 return;
193 }
194
195 // are we in the appropriate power save modes?
196 if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_BEACON_MODE_POWER_SAVE))
197 {
198 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
199 "%s: BMPS is not enabled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700200 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700201 return;
202 }
203
204 if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_UAPSD_MODE_POWER_SAVE))
205 {
206 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
207 "%s: U-APSD is not enabled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700208 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700209 return;
210 }
211
212 // everything is in place to notify TL
213 status = WLANTL_EnableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
214 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
215 acType,
216 pAc->wmmAcTspecInfo.ts_info.tid,
217 pAc->wmmAcTspecInfo.ts_info.up,
218 service_interval,
219 suspension_interval,
220 direction);
221
222 if ( !VOS_IS_STATUS_SUCCESS( status ) )
223 {
224 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
225 "%s: Failed to enable U-APSD for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700226 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700227 return;
228 }
229
230 // stash away the parameters that were used
231 pAc->wmmAcUapsdInfoValid = VOS_TRUE;
232 pAc->wmmAcUapsdServiceInterval = service_interval;
233 pAc->wmmAcUapsdSuspensionInterval = suspension_interval;
234 pAc->wmmAcUapsdDirection = direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530235 pAc->wmmAcIsUapsdEnabled = psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700236
237 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700238 "%s: Enabled UAPSD in TL srv_int=%d "
239 "susp_int=%d dir=%d AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700240 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700241 service_interval,
242 suspension_interval,
243 direction,
244 acType);
245
246}
247
248/**
249 @brief hdd_wmm_disable_tl_uapsd() - function which decides whether
250 to disable UAPSD parameters in TL
251
252 @param pQosContext : [in] the pointer the QoS instance control block
253
254 @return
255 None
256*/
257static void hdd_wmm_disable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
258{
259 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
260 WLANTL_ACEnumType acType = pQosContext->acType;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530261 hdd_wmm_ac_status_t *pAc = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700262 VOS_STATUS status;
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530263 v_U32_t service_interval;
264 v_U32_t suspension_interval;
265 v_U8_t uapsd_mask;
266 v_U8_t ActiveTspec = INVALID_TSPEC;
Jeff Johnson295189b2012-06-20 16:38:30 -0700267
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530268 if (acType >= WLANTL_MAX_AC)
269 {
270 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
271 "%s: Invalid AC: %d", __func__, acType);
272 return;
273 }
274
275 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
276
Jeff Johnson295189b2012-06-20 16:38:30 -0700277 // have we previously enabled UAPSD?
278 if (pAc->wmmAcUapsdInfoValid == VOS_TRUE)
279 {
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530280 uapsd_mask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
Jeff Johnson295189b2012-06-20 16:38:30 -0700281
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530282 //Finding uapsd_mask as per AC
283 uapsd_mask = uapsd_mask & (1 << (WLANTL_AC_VO - acType));
284
285 sme_QosTspecActive((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter), acType,
286 pAdapter->sessionId, &ActiveTspec);
287
288 //Call WLANTL_EnableUAPSDForAC only when static uapsd mask is present and
289 // no active tspecs. TODO: Need to change naming convention as Enable
290 // UAPSD function is called in hdd_wmm_disable_tl_uapsd. Purpose of
291 // calling WLANTL_EnableUAPSDForAC is to update UAPSD intervals to fw
292
293 if(uapsd_mask && !ActiveTspec)
Jeff Johnson295189b2012-06-20 16:38:30 -0700294 {
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530295 switch(acType)
296 {
297 case WLANTL_AC_VO:
298 service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv;
299 suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv;
300 break;
301 case WLANTL_AC_VI:
302 service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv;
303 suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv;
304 break;
305 case WLANTL_AC_BE:
306 service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv;
307 suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv;
308 break;
309 case WLANTL_AC_BK:
310 service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv;
311 suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv;
312 break;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530313 default:
314 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
315 "%s: Invalid AC %d", __func__, acType );
316 return;
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530317 }
318
319 status = WLANTL_EnableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
320 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
321 acType,
322 pAc->wmmAcTspecInfo.ts_info.tid,
323 pAc->wmmAcTspecInfo.ts_info.up,
324 service_interval,
325 suspension_interval,
326 pAc->wmmAcTspecInfo.ts_info.direction);
327
328 if ( !VOS_IS_STATUS_SUCCESS( status ) )
329 {
330 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
331 "%s: Failed to update U-APSD params for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700332 __func__, acType );
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530333 }
334 else
335 {
336 // TL no longer has valid UAPSD info
337 pAc->wmmAcUapsdInfoValid = VOS_FALSE;
338 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
339 "%s: Updated UAPSD params in TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700340 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700341 acType);
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530342 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700343 }
344 }
345}
346
347#endif
348
349/**
350 @brief hdd_wmm_free_context() - function which frees a QoS context
351
352 @param pQosContext : [in] the pointer the QoS instance control block
353
354 @return
355 None
356*/
357static void hdd_wmm_free_context (hdd_wmm_qos_context_t* pQosContext)
358{
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530359 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
360 hdd_context_t *pHddCtx;
361
362 if (NULL != pVosContext)
363 {
364 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
365 if (NULL == pHddCtx)
366 {
367 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
368 FL("HddCtx is NULL"));
369 return;
370 }
371 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700372
373 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
374 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700375 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700376
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530377 // take the wmmLock since we're manipulating the context list
378 mutex_lock(&pHddCtx->wmmLock);
379
Jeff Johnson295189b2012-06-20 16:38:30 -0700380 if (unlikely((NULL == pQosContext) ||
381 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
382 {
383 // must have been freed in another thread
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530384 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700385 return;
386 }
387
Jeff Johnson295189b2012-06-20 16:38:30 -0700388 // make sure nobody thinks this is a valid context
389 pQosContext->magic = 0;
390
391 // unlink the context
392 list_del(&pQosContext->node);
393
394 // done manipulating the list
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530395 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700396
397 // reclaim memory
398 kfree(pQosContext);
399
400}
401
402#ifndef WLAN_MDM_CODE_REDUCTION_OPT
403/**
404 @brief hdd_wmm_notify_app() - function which notifies an application
405 changes in state of it flow
406
407 @param pQosContext : [in] the pointer the QoS instance control block
408
409 @return
410 None
411*/
412#define MAX_NOTIFY_LEN 50
413static void hdd_wmm_notify_app (hdd_wmm_qos_context_t* pQosContext)
414{
415 hdd_adapter_t* pAdapter;
416 union iwreq_data wrqu;
417 char buf[MAX_NOTIFY_LEN+1];
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530418 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
419 hdd_context_t *pHddCtx;
420
421 if (NULL != pVosContext)
422 {
423 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
424 if (NULL == pHddCtx)
425 {
426 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
427 FL("HddCtx is NULL"));
428 return;
429 }
430 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700431
432 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
433 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700434 __func__, pQosContext);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530435 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700436 if (unlikely((NULL == pQosContext) ||
437 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
438 {
439 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
440 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700441 __func__);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530442 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700443 return;
444 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530445 // get pointer to the adapter
446 pAdapter = pQosContext->pAdapter;
447 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700448
449 // create the event
450 memset(&wrqu, 0, sizeof(wrqu));
451 memset(buf, 0, sizeof(buf));
452
453 snprintf(buf, MAX_NOTIFY_LEN, "QCOM: TS change[%u: %u]",
454 (unsigned int)pQosContext->handle,
455 (unsigned int)pQosContext->lastStatus);
456
457 wrqu.data.pointer = buf;
458 wrqu.data.length = strlen(buf);
459
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530460
Jeff Johnson295189b2012-06-20 16:38:30 -0700461
462 // send the event
463 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700464 "%s: Sending [%s]", __func__, buf);
Jeff Johnson295189b2012-06-20 16:38:30 -0700465 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
466}
467
468
469/**
470 @brief hdd_wmm_is_access_allowed() - function which determines if access
471 is allowed for the given AC. this is designed to be called during SME
472 callback processing since that is when access can be granted or removed
473
474 @param pAdapter : [in] pointer to adapter context
475 @param pAc : [in] pointer to the per-AC status
476
477 @return : VOS_TRUE - access is allowed
478 : VOS_FALSE - access is not allowed
479 None
480*/
481static v_BOOL_t hdd_wmm_is_access_allowed(hdd_adapter_t* pAdapter,
482 hdd_wmm_ac_status_t* pAc)
483{
484 // if we don't want QoS or the AP doesn't support QoS
485 // or we don't want to do implicit QoS
486 // or if AP doesn't require admission for this AC
487 // then we have access
488 if (!hdd_wmm_is_active(pAdapter) ||
489 !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled ||
490 !pAc->wmmAcAccessRequired)
491 {
492 return VOS_TRUE;
493 }
494
495 // if implicit QoS has already completed, successfully or not,
496 // then access is allowed
497 if (pAc->wmmAcAccessGranted || pAc->wmmAcAccessFailed)
498 {
499 return VOS_TRUE;
500 }
501
502 // admission is required and implicit QoS hasn't completed
503 // however explicit QoS may have completed and we'll have
504 // a Tspec
505 // if we don't have a Tspec then access is not allowed
506 if (!pAc->wmmAcTspecValid)
507 {
508 return VOS_FALSE;
509 }
510
511 // we have a Tspec -- does it allow upstream or bidirectional traffic?
512 // if it only allows downstream traffic then access is not allowed
513 if (pAc->wmmAcTspecInfo.ts_info.direction == SME_QOS_WMM_TS_DIR_DOWNLINK)
514 {
515 return VOS_FALSE;
516 }
517
518 // we meet all of the criteria for access
519 return VOS_TRUE;
520}
521
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800522#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700523/**
524 @brief hdd_wmm_inactivity_timer_cb() - timer handler function which is
525 called for every inactivity interval per AC. This function gets the
526 current transmitted packets on the given AC, and checks if there where
527 any TX activity from the previous interval. If there was no traffic
528 then it would delete the TS that was negotiated on that AC.
529
530 @param pUserData : [in] pointer to pQosContext
531
532 @return : NONE
533*/
534void hdd_wmm_inactivity_timer_cb( v_PVOID_t pUserData )
535{
536 hdd_wmm_qos_context_t* pQosContext = (hdd_wmm_qos_context_t*)pUserData;
537 hdd_adapter_t* pAdapter;
538 hdd_wmm_ac_status_t *pAc;
539 hdd_wlan_wmm_status_e status;
540 VOS_STATUS vos_status;
541 v_U32_t currentTrafficCnt = 0;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530542 WLANTL_ACEnumType acType = 0;
543 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
544 hdd_context_t *pHddCtx;
545 if (NULL != pVosContext)
546 {
547 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
548 if (NULL == pHddCtx)
549 {
550 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
551 FL("HddCtx is NULL"));
552 return;
553 }
554 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700555
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530556 mutex_lock(&pHddCtx->wmmLock);
557 if (unlikely((NULL == pQosContext) ||
558 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
559 {
560 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
561 "%s: Invalid QoS Context",
562 __func__);
563 mutex_unlock(&pHddCtx->wmmLock);
564 return;
565 }
566 mutex_unlock(&pHddCtx->wmmLock);
567
568 acType = pQosContext->acType;
Jeff Johnson295189b2012-06-20 16:38:30 -0700569 pAdapter = pQosContext->pAdapter;
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +0530570 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
571 {
572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
573 FL("invalid pAdapter: %p"), pAdapter);
574 return;
575 }
576
Jeff Johnson295189b2012-06-20 16:38:30 -0700577 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
578
579 // Get the Tx stats for this AC.
580 currentTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];
581
582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800583 FL("WMM inactivity Timer for AC=%d, currentCnt=%d, prevCnt=%d"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700584 acType, (int)currentTrafficCnt, (int)pAc->wmmPrevTrafficCnt);
585 if (pAc->wmmPrevTrafficCnt == currentTrafficCnt)
586 {
587 // If there is no traffic activity, delete the TSPEC for this AC
588 status = hdd_wmm_delts(pAdapter, pQosContext->handle);
589 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
590 FL("Deleted TS on AC %d, due to inactivity with status = %d!!!"),
591 acType, status);
592 }
593 else
594 {
595 pAc->wmmPrevTrafficCnt = currentTrafficCnt;
596 if (pAc->wmmInactivityTimer.state == VOS_TIMER_STATE_STOPPED)
597 {
598 // Restart the timer
599 vos_status = vos_timer_start(&pAc->wmmInactivityTimer, pAc->wmmInactivityTime);
600 if (!VOS_IS_STATUS_SUCCESS(vos_status))
601 {
602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
603 FL("Restarting inactivity timer failed on AC %d"), acType);
604 }
605 }
606 else
607 {
608 VOS_ASSERT(vos_timer_getCurrentState(
609 &pAc->wmmInactivityTimer) == VOS_TIMER_STATE_STOPPED);
610 }
611 }
612
613 return;
614}
615
616
617/**
618 @brief hdd_wmm_enable_inactivity_timer() - function to enable the
619 traffic inactivity timer for the given AC, if the inactivity_interval
620 specified in the ADDTS parameters is non-zero
621
622 @param pQosContext : [in] pointer to pQosContext
623 @param inactivityTime: [in] value of the inactivity interval in millisecs
624
625 @return : VOS_STATUS_E_FAILURE
626 VOS_STATUS_SUCCESS
627*/
628VOS_STATUS hdd_wmm_enable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext, v_U32_t inactivityTime)
629{
630 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
631 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
632 WLANTL_ACEnumType acType = pQosContext->acType;
633 hdd_wmm_ac_status_t *pAc;
634
635 pAdapter = pQosContext->pAdapter;
636 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
637
638
639 // If QoS-Tspec is successfully setup and if the inactivity timer is non-zero,
640 // a traffic inactivity timer needs to be started for the given AC
641 vos_status = vos_timer_init(
642 &pAc->wmmInactivityTimer,
643 VOS_TIMER_TYPE_SW,
644 hdd_wmm_inactivity_timer_cb,
645 (v_PVOID_t)pQosContext );
646 if ( !VOS_IS_STATUS_SUCCESS(vos_status))
647 {
648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
649 FL("Initializing inactivity timer failed on AC %d"), acType);
650 return vos_status;
651 }
652
653 // Start the inactivity timer
654 vos_status = vos_timer_start(
655 &pAc->wmmInactivityTimer,
656 inactivityTime);
657 if ( !VOS_IS_STATUS_SUCCESS(vos_status))
658 {
659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
660 FL("Starting inactivity timer failed on AC %d"), acType);
661 return vos_status;
662 }
663 pAc->wmmInactivityTime = inactivityTime;
664 // Initialize the current tx traffic count on this AC
665 pAc->wmmPrevTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];
666
667 return vos_status;
668}
669
670/**
671 @brief hdd_wmm_enable_inactivity_timer() - function to disable the
672 traffic inactivity timer for the given AC. This would be called when
673 deleting the TS.
674
675 @param pQosContext : [in] pointer to pQosContext
676
677 @return : VOS_STATUS_E_FAILURE
678 VOS_STATUS_SUCCESS
679*/
680VOS_STATUS hdd_wmm_disable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext)
681{
682 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
683 WLANTL_ACEnumType acType = pQosContext->acType;
684 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
685 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
686
687 // Clear the timer and the counter
688 pAc->wmmInactivityTime = 0;
689 pAc->wmmPrevTrafficCnt = 0;
690 vos_timer_stop(&pAc->wmmInactivityTimer);
691 vos_status = vos_timer_destroy(&pAc->wmmInactivityTimer);
692
693 return vos_status;
694}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800695#endif // FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700696
697/**
698 @brief hdd_wmm_sme_callback() - callback registered by HDD with SME for receiving
699 QoS notifications. Even though this function has a static scope it gets called
700 externally through some function pointer magic (so there is a need for
701 rigorous parameter checking)
702
703 @param hHal : [in] the HAL handle
704 @param HddCtx : [in] the HDD specified handle
705 @param pCurrentQosInfo : [in] the TSPEC params
706 @param SmeStatus : [in] the QoS related SME status
707
708 @return
709 eHAL_STATUS_SUCCESS if all good, eHAL_STATUS_FAILURE otherwise
710*/
711static eHalStatus hdd_wmm_sme_callback (tHalHandle hHal,
712 void * hddCtx,
713 sme_QosWmmTspecInfo* pCurrentQosInfo,
714 sme_QosStatusType smeStatus,
715 v_U32_t qosFlowId)
716{
717 hdd_wmm_qos_context_t* pQosContext = hddCtx;
718 hdd_adapter_t* pAdapter;
719 WLANTL_ACEnumType acType;
720 hdd_wmm_ac_status_t *pAc;
721 VOS_STATUS status;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530722 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
723 hdd_context_t *pHddCtx;
724
725 if (NULL != pVosContext)
726 {
727 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
728 if (NULL == pHddCtx)
729 {
730 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
731 FL("HddCtx is NULL"));
732 return eHAL_STATUS_FAILURE;
733 }
734 }
735
Jeff Johnson295189b2012-06-20 16:38:30 -0700736
737 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
738 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700739 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700740
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530741 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700742 if (unlikely((NULL == pQosContext) ||
743 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
744 {
745 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
746 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700747 __func__);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530748 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700749 return eHAL_STATUS_FAILURE;
750 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530751 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700752
753 pAdapter = pQosContext->pAdapter;
754 acType = pQosContext->acType;
755 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
756
757 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
758 "%s: status %d flowid %d info %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700759 __func__, smeStatus, qosFlowId, pCurrentQosInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -0700760
761 switch (smeStatus)
762 {
763
764 case SME_QOS_STATUS_SETUP_SUCCESS_IND:
765 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
766 "%s: Setup is complete",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700767 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700768
769 // there will always be a TSPEC returned with this status, even if
770 // a TSPEC is not exchanged OTA
771 if (pCurrentQosInfo)
772 {
773 pAc->wmmAcTspecValid = VOS_TRUE;
774 memcpy(&pAc->wmmAcTspecInfo,
775 pCurrentQosInfo,
776 sizeof(pAc->wmmAcTspecInfo));
777 }
778
779 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
780 {
781
782 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
783 "%s: Implicit Qos, notifying TL for TL AC %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700784 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700785
786 // this was triggered by implicit QoS so we know packets are pending
787 // update state
788 pAc->wmmAcAccessAllowed = VOS_TRUE;
789 pAc->wmmAcAccessGranted = VOS_TRUE;
790 pAc->wmmAcAccessPending = VOS_FALSE;
791
792 // notify TL that packets are pending
793 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
794 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
795 acType );
796
797 if ( !VOS_IS_STATUS_SUCCESS( status ) )
798 {
799 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
800 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700801 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700802 }
803 }
804 else
805 {
806 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
807 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700808 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700809
810 // this was triggered by an application
811 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
812 hdd_wmm_notify_app(pQosContext);
813 }
814
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800815#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700816 // Check if the inactivity interval is specified
Jeff Johnson8795e422013-04-03 08:59:22 -0700817 if (pCurrentQosInfo && pCurrentQosInfo->inactivity_interval) {
Jeff Johnson295189b2012-06-20 16:38:30 -0700818 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800819 "%s: Inactivity timer value = %d for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700820 __func__, pCurrentQosInfo->inactivity_interval, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700821 hdd_wmm_enable_inactivity_timer(pQosContext, pCurrentQosInfo->inactivity_interval);
822 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800823#endif // FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700824
825 // notify TL to enable trigger frames if necessary
826 hdd_wmm_enable_tl_uapsd(pQosContext);
827
828 break;
829
830 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
831 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
832 "%s: Setup is complete (U-APSD set previously)",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700833 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700834
835 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
836 {
837
838 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
839 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700840 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700841
842 // this was triggered by implicit QoS so we know packets are pending
843 // update state
844 pAc->wmmAcAccessAllowed = VOS_TRUE;
845 pAc->wmmAcAccessGranted = VOS_TRUE;
846 pAc->wmmAcAccessPending = VOS_FALSE;
847
848 // notify TL that packets are pending
849 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
850 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
851 acType );
852
853 if ( !VOS_IS_STATUS_SUCCESS( status ) )
854 {
855 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
856 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700857 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700858 }
859 }
860 else
861 {
862 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
863 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700864 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700865
866 // this was triggered by an application
867 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
868 hdd_wmm_notify_app(pQosContext);
869 }
870
871 break;
872
873 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
874 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
875 "%s: Setup failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700876 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700877 // QoS setup failed
878
879 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
880 {
881
882 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
883 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700884 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700885
886 // we note the failure, but we also mark access as allowed so that
887 // the packets will flow. Note that the MAC will "do the right thing"
888 pAc->wmmAcAccessPending = VOS_FALSE;
889 pAc->wmmAcAccessFailed = VOS_TRUE;
890 pAc->wmmAcAccessAllowed = VOS_TRUE;
891
892 // this was triggered by implicit QoS so we know packets are pending
893 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
894 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
895 acType );
896
897 if ( !VOS_IS_STATUS_SUCCESS( status ) )
898 {
899 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
900 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700901 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700902 }
903 }
904 else
905 {
906 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
907 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700908 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700909
910 // this was triggered by an application
911 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED;
912 hdd_wmm_notify_app(pQosContext);
913 }
914
915 /* Setting up QoS Failed, QoS context can be released.
916 * SME is releasing this flow information and if HDD doen't release this context,
917 * next time if application uses the same handle to set-up QoS, HDD (as it has
918 * QoS context for this handle) will issue Modify QoS request to SME but SME will
919 * reject as no it has no information for this flow.
920 */
921 hdd_wmm_free_context(pQosContext);
922 break;
923
924 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
925 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
926 "%s: Setup Invalid Params, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700927 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700928 // QoS setup failed
929
930 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
931 {
932
933 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
934 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700935 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700936
937 // we note the failure, but we also mark access as allowed so that
938 // the packets will flow. Note that the MAC will "do the right thing"
939 pAc->wmmAcAccessPending = VOS_FALSE;
940 pAc->wmmAcAccessFailed = VOS_TRUE;
941 pAc->wmmAcAccessAllowed = VOS_TRUE;
942
943 // this was triggered by implicit QoS so we know packets are pending
944 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
945 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
946 acType );
947
948 if ( !VOS_IS_STATUS_SUCCESS( status ) )
949 {
950 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
951 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700952 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700953 }
954 }
955 else
956 {
957 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
958 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700959 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700960
961 // this was triggered by an application
962 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
963 hdd_wmm_notify_app(pQosContext);
964 }
965 break;
966
967 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
968 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800969 "%s: Setup failed, not a QoS AP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700970 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700971 if (!HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
972 {
973 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
974 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700975 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700976
977 // this was triggered by an application
978 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
979 hdd_wmm_notify_app(pQosContext);
980 }
981 break;
982
983 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
984 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
985 "%s: Setup pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700986 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700987 // not a callback status -- ignore if we get it
988 break;
989
990 case SME_QOS_STATUS_SETUP_MODIFIED_IND:
991 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
992 "%s: Setup modified",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700993 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700994 if (pCurrentQosInfo)
995 {
996 // update the TSPEC
997 pAc->wmmAcTspecValid = VOS_TRUE;
998 memcpy(&pAc->wmmAcTspecInfo,
999 pCurrentQosInfo,
1000 sizeof(pAc->wmmAcTspecInfo));
1001
1002 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1003 {
1004 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1005 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001006 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001007
1008 // this was triggered by an application
1009 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFIED;
1010 hdd_wmm_notify_app(pQosContext);
1011 }
1012
1013 // need to tell TL to update its UAPSD handling
1014 hdd_wmm_enable_tl_uapsd(pQosContext);
1015 }
1016 break;
1017
1018 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1019 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
1020 {
1021
1022 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1023 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001024 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001025
1026 // this was triggered by implicit QoS so we know packets are pending
1027 pAc->wmmAcAccessPending = VOS_FALSE;
1028 pAc->wmmAcAccessGranted = VOS_TRUE;
1029 pAc->wmmAcAccessAllowed = VOS_TRUE;
1030
1031 // notify TL that packets are pending
1032 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1033 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
1034 acType );
1035
1036 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1037 {
1038 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1039 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001040 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -07001041 }
1042 }
1043 else
1044 {
1045 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1046 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001047 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001048
1049 // this was triggered by an application
1050 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
1051 hdd_wmm_notify_app(pQosContext);
1052 }
1053 break;
1054
1055 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
1056 // nothing to do for now
1057 break;
1058
1059 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED:
1060 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1061 "%s: Setup successful but U-APSD failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001062 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001063
1064 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
1065 {
1066
1067 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1068 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001069 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001070
1071 // QoS setup was successful but setting U=APSD failed
1072 // Since the OTA part of the request was successful, we don't mark
1073 // this as a failure.
1074 // the packets will flow. Note that the MAC will "do the right thing"
1075 pAc->wmmAcAccessGranted = VOS_TRUE;
1076 pAc->wmmAcAccessAllowed = VOS_TRUE;
1077 pAc->wmmAcAccessFailed = VOS_FALSE;
1078 pAc->wmmAcAccessPending = VOS_FALSE;
1079
1080 // this was triggered by implicit QoS so we know packets are pending
1081 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1082 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
1083 acType );
1084
1085 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1086 {
1087 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1088 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001089 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -07001090 }
1091 }
1092 else
1093 {
1094 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1095 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001096 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001097
1098 // this was triggered by an application
1099 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_UAPSD_SET_FAILED;
1100 hdd_wmm_notify_app(pQosContext);
1101 }
1102
1103 // Since U-APSD portion failed disabled trigger frame generation
1104 hdd_wmm_disable_tl_uapsd(pQosContext);
1105
1106 break;
1107
1108 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
1109 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1110 "%s: Release is complete",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001111 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001112
1113 if (pCurrentQosInfo)
1114 {
1115 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1116 "%s: flows still active",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001117 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001118
1119 // there is still at least one flow active for this AC
1120 // so update the AC state
1121 memcpy(&pAc->wmmAcTspecInfo,
1122 pCurrentQosInfo,
1123 sizeof(pAc->wmmAcTspecInfo));
1124
1125 // need to tell TL to update its UAPSD handling
1126 hdd_wmm_enable_tl_uapsd(pQosContext);
1127 }
1128 else
1129 {
1130 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1131 "%s: last flow",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001132 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001133
1134 // this is the last flow active for this AC so update the AC state
1135 pAc->wmmAcTspecValid = VOS_FALSE;
1136
1137 // need to tell TL to update its UAPSD handling
1138 hdd_wmm_disable_tl_uapsd(pQosContext);
1139 }
1140
1141 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1142 {
1143 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1144 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001145 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001146
1147 // this was triggered by an application
1148 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
1149 hdd_wmm_notify_app(pQosContext);
1150 }
1151
1152 // we are done with this flow
1153 hdd_wmm_free_context(pQosContext);
1154 break;
1155
1156 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
1157 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1158 "%s: Release failure",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001159 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001160
1161 // we don't need to update our state or TL since nothing has changed
1162 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1163 {
1164 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1165 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001166 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001167
1168 // this was triggered by an application
1169 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
1170 hdd_wmm_notify_app(pQosContext);
1171 }
1172
1173 break;
1174
1175 case SME_QOS_STATUS_RELEASE_QOS_LOST_IND:
1176 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1177 "%s: QOS Lost indication received",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001178 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001179
1180 // current TSPEC is no longer valid
1181 pAc->wmmAcTspecValid = VOS_FALSE;
1182
1183 // need to tell TL to update its UAPSD handling
1184 hdd_wmm_disable_tl_uapsd(pQosContext);
1185
1186 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
1187 {
1188 // we no longer have implicit access granted
1189 pAc->wmmAcAccessGranted = VOS_FALSE;
1190 pAc->wmmAcAccessFailed = VOS_FALSE;
1191 }
1192 else
1193 {
1194 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1195 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001196 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001197
1198 // this was triggered by an application
1199 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_LOST;
1200 hdd_wmm_notify_app(pQosContext);
1201 }
1202
1203 // we are done with this flow
1204 hdd_wmm_free_context(pQosContext);
1205 break;
1206
1207 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
1208 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1209 "%s: Release pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001210 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001211 // not a callback status -- ignore if we get it
1212 break;
1213
1214 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
1215 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1216 "%s: Release Invalid Params",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001217 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001218 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1219 {
1220 // this was triggered by an application
1221 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
1222 hdd_wmm_notify_app(pQosContext);
1223 }
1224 break;
1225
1226 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND:
1227 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1228 "%s: Modification is complete, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001229 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001230
1231 // there will always be a TSPEC returned with this status, even if
1232 // a TSPEC is not exchanged OTA
1233 if (pCurrentQosInfo)
1234 {
1235 pAc->wmmAcTspecValid = VOS_TRUE;
1236 memcpy(&pAc->wmmAcTspecInfo,
1237 pCurrentQosInfo,
1238 sizeof(pAc->wmmAcTspecInfo));
1239 }
1240
1241 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1242 {
1243 // this was triggered by an application
1244 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS;
1245 hdd_wmm_notify_app(pQosContext);
1246 }
1247
1248 // notify TL to enable trigger frames if necessary
1249 hdd_wmm_enable_tl_uapsd(pQosContext);
1250
1251 break;
1252
1253 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
1254 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1255 {
1256 // this was triggered by an application
1257 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
1258 hdd_wmm_notify_app(pQosContext);
1259 }
1260 break;
1261
1262 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
1263 // the flow modification failed so we'll leave in place
1264 // whatever existed beforehand
1265
1266 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1267 {
1268 // this was triggered by an application
1269 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
1270 hdd_wmm_notify_app(pQosContext);
1271 }
1272 break;
1273
1274 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
1275 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1276 "%s: modification pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001277 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001278 // not a callback status -- ignore if we get it
1279 break;
1280
1281 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1282 // the flow modification was successful but no QoS changes required
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_SUCCESS_NO_ACM_NO_UAPSD;
1288 hdd_wmm_notify_app(pQosContext);
1289 }
1290 break;
1291
1292 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
1293 // invalid params -- notify the application
1294 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1295 {
1296 // this was triggered by an application
1297 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
1298 hdd_wmm_notify_app(pQosContext);
1299 }
1300 break;
1301
1302 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_PENDING:
1303 // nothing to do for now. when APSD is established we'll have work to do
1304 break;
1305
1306 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED:
1307 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1308 "%s: Modify successful but U-APSD failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001309 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001310
1311 // QoS modification was successful but setting U=APSD failed.
1312 // This will always be an explicit QoS instance, so all we can
1313 // do is notify the application and let it clean up.
1314 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1315 {
1316 // this was triggered by an application
1317 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_UAPSD_SET_FAILED;
1318 hdd_wmm_notify_app(pQosContext);
1319 }
1320
1321 // Since U-APSD portion failed disabled trigger frame generation
1322 hdd_wmm_disable_tl_uapsd(pQosContext);
1323
1324 break;
1325
1326 case SME_QOS_STATUS_HANDING_OFF:
1327 // no roaming so we won't see this
1328 break;
1329
1330 case SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND:
1331 // need to tell TL to stop trigger frame generation
1332 hdd_wmm_disable_tl_uapsd(pQosContext);
1333 break;
1334
1335 case SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND:
1336 // need to tell TL to start sending trigger frames again
1337 hdd_wmm_enable_tl_uapsd(pQosContext);
1338 break;
1339
1340 default:
1341 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001342 "%s: unexpected SME Status=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001343 __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07001344 VOS_ASSERT(0);
1345 }
1346
1347 // our access to the particular access category may have changed.
1348 // some of the implicit QoS cases above may have already set this
1349 // prior to invoking TL (so that we will properly service the
1350 // Tx queues) but let's consistently handle all cases here
1351 pAc->wmmAcAccessAllowed = hdd_wmm_is_access_allowed(pAdapter, pAc);
1352
1353 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1354 "%s: complete, access for TL AC %d is%sallowed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001355 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001356 acType,
1357 pAc->wmmAcAccessAllowed ? " " : " not ");
1358
1359 return eHAL_STATUS_SUCCESS;
1360}
1361#endif
1362
Kiet Lamf040f472013-11-20 21:15:23 +05301363/**========================================================================
1364 @brief hdd_wmmps_helper() - Function to set uapsd psb dynamically
1365
1366 @param pAdapter : [in] pointer to adapter structure
1367
1368 @param ptr : [in] pointer to command buffer
1369
1370 @return : Zero on success, appropriate error on failure.
1371 =======================================================================*/
1372int hdd_wmmps_helper(hdd_adapter_t *pAdapter, tANI_U8 *ptr)
1373{
1374 if (NULL == pAdapter)
1375 {
1376 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1377 "%s: pAdapter is NULL", __func__);
1378 return -EINVAL;
1379 }
1380 if (NULL == ptr)
1381 {
1382 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1383 "%s: ptr is NULL", __func__);
1384 return -EINVAL;
1385 }
1386 /* convert ASCII to integer */
1387 pAdapter->configuredPsb = ptr[9] - '0';
1388 pAdapter->psbChanged = HDD_PSB_CHANGED;
1389
1390 return 0;
1391}
1392
Jeff Johnson295189b2012-06-20 16:38:30 -07001393/**============================================================================
1394 @brief hdd_wmm_do_implicit_qos() - Function which will attempt to setup
1395 QoS for any AC requiring it
1396
1397 @param work : [in] pointer to work structure
1398
1399 @return : void
1400 ===========================================================================*/
Mukul Sharmaec9dcc62015-02-24 18:00:04 +05301401static void __hdd_wmm_do_implicit_qos(struct work_struct *work)
Jeff Johnson295189b2012-06-20 16:38:30 -07001402{
1403 hdd_wmm_qos_context_t* pQosContext =
1404 container_of(work, hdd_wmm_qos_context_t, wmmAcSetupImplicitQos);
1405 hdd_adapter_t* pAdapter;
1406 WLANTL_ACEnumType acType;
1407 hdd_wmm_ac_status_t *pAc;
1408#ifndef WLAN_MDM_CODE_REDUCTION_OPT
1409 VOS_STATUS status;
1410 sme_QosStatusType smeStatus;
1411#endif
1412 sme_QosWmmTspecInfo qosInfo;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301413 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
1414 hdd_context_t *pHddCtx;
Mukul Sharmaec9dcc62015-02-24 18:00:04 +05301415 int ret = 0;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301416
1417 if (NULL != pVosContext)
1418 {
1419 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
1420 if (NULL == pHddCtx)
1421 {
1422 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1423 FL("HddCtx is NULL"));
1424 return;
1425 }
1426 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001427
Mukul Sharmaec9dcc62015-02-24 18:00:04 +05301428 ret = wlan_hdd_validate_context(pHddCtx);
1429 if (0 != ret)
1430 {
1431 hddLog(LOGE, FL("HDD context is invalid"));
1432 return;
1433 }
1434
Jeff Johnson295189b2012-06-20 16:38:30 -07001435 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1436 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001437 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001438
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301439 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001440 if (unlikely(HDD_WMM_CTX_MAGIC != pQosContext->magic))
1441 {
1442 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1443 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001444 __func__);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301445 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001446 return;
1447 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301448 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001449
1450 pAdapter = pQosContext->pAdapter;
1451 acType = pQosContext->acType;
1452 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1453
1454 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1455 "%s: pAdapter %p acType %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001456 __func__, pAdapter, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001457
1458 if (!pAc->wmmAcAccessNeeded)
1459 {
1460 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1461 "%s: AC %d doesn't need service",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001462 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001463 pQosContext->magic = 0;
1464 kfree(pQosContext);
1465 return;
1466 }
1467
1468 pAc->wmmAcAccessPending = VOS_TRUE;
1469 pAc->wmmAcAccessNeeded = VOS_FALSE;
1470
1471 memset(&qosInfo, 0, sizeof(qosInfo));
1472
Kiet Lamf040f472013-11-20 21:15:23 +05301473 qosInfo.ts_info.psb = pAdapter->configuredPsb;
1474
Jeff Johnson295189b2012-06-20 16:38:30 -07001475 switch (acType)
1476 {
1477 case WLANTL_AC_VO:
1478 qosInfo.ts_info.up = SME_QOS_WMM_UP_VO;
Kiet Lamf040f472013-11-20 21:15:23 +05301479 /* Check if there is any valid configuration from framework */
1480 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1481 {
1482 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1483 SME_QOS_UAPSD_VO) ? 1 : 0;
1484 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001485 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVo;
1486 qosInfo.ts_info.tid = 255;
1487 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVo;
1488 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVo;
1489 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv;
1490 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVo;
1491 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVo;
1492 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv;
1493 break;
1494 case WLANTL_AC_VI:
1495 qosInfo.ts_info.up = SME_QOS_WMM_UP_VI;
Kiet Lamf040f472013-11-20 21:15:23 +05301496 /* Check if there is any valid configuration from framework */
1497 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1498 {
1499 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1500 SME_QOS_UAPSD_VI) ? 1 : 0;
1501 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001502 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVi;
1503 qosInfo.ts_info.tid = 255;
1504 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVi;
1505 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVi;
1506 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv;
1507 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVi;
1508 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVi;
1509 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv;
1510 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07001511 case WLANTL_AC_BE:
1512 qosInfo.ts_info.up = SME_QOS_WMM_UP_BE;
Kiet Lamf040f472013-11-20 21:15:23 +05301513 /* Check if there is any valid configuration from framework */
1514 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1515 {
1516 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1517 SME_QOS_UAPSD_BE) ? 1 : 0;
1518 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001519 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBe;
1520 qosInfo.ts_info.tid = 255;
1521 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBe;
1522 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBe;
1523 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv;
1524 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBe;
1525 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBe;
1526 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv;
1527 break;
1528 case WLANTL_AC_BK:
1529 qosInfo.ts_info.up = SME_QOS_WMM_UP_BK;
Kiet Lamf040f472013-11-20 21:15:23 +05301530 /* Check if there is any valid configuration from framework */
1531 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1532 {
1533 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1534 SME_QOS_UAPSD_BK) ? 1 : 0;
1535 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001536 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBk;
1537 qosInfo.ts_info.tid = 255;
1538 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBk;
1539 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBk;
1540 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv;
1541 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBk;
1542 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBk;
1543 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv;
1544 break;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301545 default:
1546 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1547 "%s: Invalid AC %d", __func__, acType );
1548 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001549 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08001550#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07001551 qosInfo.inactivity_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraInactivityInterval;
1552#endif
1553 qosInfo.ts_info.burst_size_defn = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->burstSizeDefinition;
1554
1555 switch ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->tsInfoAckPolicy)
1556 {
1557 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK:
1558 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1559 break;
1560
1561 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
1562 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
1563 break;
1564
1565 default:
1566 // unknown
1567 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1568 }
1569
1570 if(qosInfo.ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK)
1571 {
1572 if(!sme_QosIsTSInfoAckPolicyValid((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter), &qosInfo, pAdapter->sessionId))
1573 {
1574 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1575 }
1576 }
1577
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301578 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001579 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301580 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001581
1582#ifndef WLAN_MDM_CODE_REDUCTION_OPT
1583 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
1584 pAdapter->sessionId,
1585 &qosInfo,
1586 hdd_wmm_sme_callback,
1587 pQosContext,
1588 qosInfo.ts_info.up,
1589 &pQosContext->qosFlowId);
1590
1591 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1592 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001593 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001594
1595 // need to check the return values and act appropriately
1596 switch (smeStatus)
1597 {
1598 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
1599 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
1600 // setup is pending, so no more work to do now.
1601 // all further work will be done in hdd_wmm_sme_callback()
1602 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1603 "%s: Setup is pending, no further work",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001604 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001605
1606 break;
1607
1608
1609 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
1610 // we can't tell the difference between when a request fails because
1611 // AP rejected it versus when SME encountered an internal error
1612
1613 // in either case SME won't ever reference this context so
1614 // free the record
1615 hdd_wmm_free_context(pQosContext);
1616
1617 // fall through and start packets flowing
1618 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1619 // no ACM in effect, no need to setup U-APSD
1620 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
1621 // no ACM in effect, U-APSD is desired but was already setup
1622
1623 // for these cases everything is already setup so we can
1624 // signal TL that it has work to do
1625 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1626 "%s: Setup is complete, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001627 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001628
1629 pAc->wmmAcAccessAllowed = VOS_TRUE;
1630 pAc->wmmAcAccessGranted = VOS_TRUE;
1631 pAc->wmmAcAccessPending = VOS_FALSE;
1632
1633 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1634 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
1635 acType );
1636
1637 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1638 {
1639 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1640 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001641 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -07001642 }
1643
1644 break;
1645
1646
1647 default:
1648 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001649 "%s: unexpected SME Status=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001650 __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07001651 VOS_ASSERT(0);
1652 }
1653#endif
1654
1655}
1656
Mukul Sharmaec9dcc62015-02-24 18:00:04 +05301657static void hdd_wmm_do_implicit_qos(struct work_struct *work)
1658{
1659 vos_ssr_protect(__func__);
1660 __hdd_wmm_do_implicit_qos( work );
1661 vos_ssr_unprotect(__func__);
1662}
1663
Jeff Johnson295189b2012-06-20 16:38:30 -07001664/**============================================================================
1665 @brief hdd_wmm_init() - Function which will initialize the WMM configuation
1666 and status to an initial state. The configuration can later be overwritten
1667 via application APIs
1668
Kumar Anand82c009f2014-05-29 00:29:42 -07001669 @param pAdapter : [in] pointer to Adapter context
Jeff Johnson295189b2012-06-20 16:38:30 -07001670
Kumar Anand82c009f2014-05-29 00:29:42 -07001671 @return : VOS_STATUS_SUCCESS if successful
Jeff Johnson295189b2012-06-20 16:38:30 -07001672 : other values if failure
1673
1674 ===========================================================================*/
Kumar Anand82c009f2014-05-29 00:29:42 -07001675VOS_STATUS hdd_wmm_init ( hdd_adapter_t *pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07001676{
Kumar Anand82c009f2014-05-29 00:29:42 -07001677 sme_QosWmmUpType* hddWmmDscpToUpMap = pAdapter->hddWmmDscpToUpMap;
Jeff Johnson295189b2012-06-20 16:38:30 -07001678 v_U8_t dscp;
1679
1680 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001681 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001682
1683 // DSCP to User Priority Lookup Table
1684 for (dscp = 0; dscp <= WLAN_HDD_MAX_DSCP; dscp++)
1685 {
1686 hddWmmDscpToUpMap[dscp] = SME_QOS_WMM_UP_BE;
1687 }
1688 hddWmmDscpToUpMap[8] = SME_QOS_WMM_UP_BK;
1689 hddWmmDscpToUpMap[16] = SME_QOS_WMM_UP_RESV;
1690 hddWmmDscpToUpMap[24] = SME_QOS_WMM_UP_EE;
1691 hddWmmDscpToUpMap[32] = SME_QOS_WMM_UP_CL;
1692 hddWmmDscpToUpMap[40] = SME_QOS_WMM_UP_VI;
1693 hddWmmDscpToUpMap[48] = SME_QOS_WMM_UP_VO;
1694 hddWmmDscpToUpMap[56] = SME_QOS_WMM_UP_NC;
Jeff Johnson295189b2012-06-20 16:38:30 -07001695 return VOS_STATUS_SUCCESS;
1696}
1697
1698/**============================================================================
1699 @brief hdd_wmm_adapter_init() - Function which will initialize the WMM configuation
1700 and status to an initial state. The configuration can later be overwritten
1701 via application APIs
1702
1703 @param pAdapter : [in] pointer to Adapter context
1704
1705 @return : VOS_STATUS_SUCCESS if succssful
1706 : other values if failure
1707
1708 ===========================================================================*/
1709VOS_STATUS hdd_wmm_adapter_init( hdd_adapter_t *pAdapter )
1710{
1711 hdd_wmm_ac_status_t *pAcStatus;
1712 WLANTL_ACEnumType acType;
1713
1714 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001715 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001716
1717 pAdapter->hddWmmStatus.wmmQap = VOS_FALSE;
1718 INIT_LIST_HEAD(&pAdapter->hddWmmStatus.wmmContextList);
Jeff Johnson295189b2012-06-20 16:38:30 -07001719
1720 for (acType = 0; acType < WLANTL_MAX_AC; acType++)
1721 {
1722 pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1723 pAcStatus->wmmAcAccessRequired = VOS_FALSE;
1724 pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
1725 pAcStatus->wmmAcAccessPending = VOS_FALSE;
1726 pAcStatus->wmmAcAccessFailed = VOS_FALSE;
1727 pAcStatus->wmmAcAccessGranted = VOS_FALSE;
1728 pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
1729 pAcStatus->wmmAcTspecValid = VOS_FALSE;
1730 pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
1731 }
Kiet Lamf040f472013-11-20 21:15:23 +05301732 // Invalid value(0xff) to indicate psb not configured through framework initially.
1733 pAdapter->configuredPsb = HDD_PSB_CFG_INVALID;
Jeff Johnson295189b2012-06-20 16:38:30 -07001734
1735 return VOS_STATUS_SUCCESS;
1736}
Madan Mohan Koyyalamudi70c52d32013-08-07 14:42:16 +05301737
1738/**============================================================================
1739 @brief hdd_wmm_adapter_clear() - Function which will clear the WMM status
1740 for all the ACs
1741
1742 @param pAdapter : [in] pointer to Adapter context
1743
1744 @return : VOS_STATUS_SUCCESS if succssful
1745 : other values if failure
1746
1747 ===========================================================================*/
1748VOS_STATUS hdd_wmm_adapter_clear( hdd_adapter_t *pAdapter )
1749{
1750 hdd_wmm_ac_status_t *pAcStatus;
1751 WLANTL_ACEnumType acType;
1752 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1753 "%s: Entered", __func__);
1754 for (acType = 0; acType < WLANTL_MAX_AC; acType++)
1755 {
1756 pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1757 pAcStatus->wmmAcAccessRequired = VOS_FALSE;
1758 pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
1759 pAcStatus->wmmAcAccessPending = VOS_FALSE;
1760 pAcStatus->wmmAcAccessFailed = VOS_FALSE;
1761 pAcStatus->wmmAcAccessGranted = VOS_FALSE;
1762 pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
1763 pAcStatus->wmmAcTspecValid = VOS_FALSE;
1764 pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
1765 }
1766 return VOS_STATUS_SUCCESS;
1767}
1768
Jeff Johnson295189b2012-06-20 16:38:30 -07001769/**============================================================================
1770 @brief hdd_wmm_close() - Function which will perform any necessary work to
1771 to clean up the WMM functionality prior to the kernel module unload
1772
1773 @param pAdapter : [in] pointer to adapter context
1774
1775 @return : VOS_STATUS_SUCCESS if succssful
1776 : other values if failure
1777
1778 ===========================================================================*/
1779VOS_STATUS hdd_wmm_adapter_close ( hdd_adapter_t* pAdapter )
1780{
1781 hdd_wmm_qos_context_t* pQosContext;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301782 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
1783 hdd_context_t *pHddCtx;
1784
1785 if (NULL != pVosContext)
1786 {
1787 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
1788 if (NULL == pHddCtx)
1789 {
1790 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1791 FL("HddCtx is NULL"));
1792 return VOS_STATUS_E_FAILURE;
1793 }
1794 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001795
1796 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001797 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001798
1799 // free any context records that we still have linked
1800 while (!list_empty(&pAdapter->hddWmmStatus.wmmContextList))
1801 {
1802 pQosContext = list_first_entry(&pAdapter->hddWmmStatus.wmmContextList,
1803 hdd_wmm_qos_context_t, node);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08001804#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07001805 hdd_wmm_disable_inactivity_timer(pQosContext);
1806#endif
Sameer Thalappilbee426e2013-10-30 10:30:30 -07001807#ifdef WLAN_OPEN_SOURCE
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301808 mutex_lock(&pHddCtx->wmmLock);
Anand N Sunkad4b25a2f2014-11-13 16:01:08 +05301809 if (pQosContext->handle == HDD_WMM_HANDLE_IMPLICIT
1810 && pQosContext->magic == HDD_WMM_CTX_MAGIC)
1811 {
1812
Sameer Thalappilbee426e2013-10-30 10:30:30 -07001813 cancel_work_sync(&pQosContext->wmmAcSetupImplicitQos);
Anand N Sunkad4b25a2f2014-11-13 16:01:08 +05301814 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301815 mutex_unlock(&pHddCtx->wmmLock);
Sameer Thalappilbee426e2013-10-30 10:30:30 -07001816#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001817 hdd_wmm_free_context(pQosContext);
1818 }
1819
1820 return VOS_STATUS_SUCCESS;
1821}
1822
1823/**============================================================================
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301824 @brief hdd_is_dhcp_packet() - Function which will check OS packet for
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301825 DHCP packet
1826
1827 @param skb : [in] pointer to OS packet (sk_buff)
1828 @return : VOS_TRUE if the OS packet is DHCP packet
1829 : otherwise VOS_FALSE
1830 ===========================================================================*/
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301831v_BOOL_t hdd_is_dhcp_packet(struct sk_buff *skb)
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301832{
1833 if (*((u16*)((u8*)skb->data+34)) == DHCP_SOURCE_PORT ||
1834 *((u16*)((u8*)skb->data+34)) == DHCP_DESTINATION_PORT)
1835 return VOS_TRUE;
1836
1837 return VOS_FALSE;
1838}
1839
1840/**============================================================================
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301841 @brief hdd_skb_is_eapol_or_wai_packet() - Function which will check OS packet
1842 for Eapol/Wapi packet
1843
1844 @param skb : [in] pointer to OS packet (sk_buff)
1845 @return : VOS_TRUE if the OS packet is an Eapol or a Wapi packet
1846 : otherwise VOS_FALSE
1847 ===========================================================================*/
1848v_BOOL_t hdd_skb_is_eapol_or_wai_packet(struct sk_buff *skb)
1849{
1850 if ((*((u16*)((u8*)skb->data+HDD_ETHERTYPE_802_1_X_FRAME_OFFSET))
1851 == vos_cpu_to_be16(HDD_ETHERTYPE_802_1_X))
1852#ifdef FEATURE_WLAN_WAPI
1853 || (*((u16*)((u8*)skb->data+HDD_ETHERTYPE_802_1_X_FRAME_OFFSET))
1854 == vos_cpu_to_be16(HDD_ETHERTYPE_WAI))
1855#endif
1856 )
1857 return VOS_TRUE;
1858
1859 return VOS_FALSE;
1860}
1861
1862/**============================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07001863 @brief hdd_wmm_classify_pkt() - Function which will classify an OS packet
1864 into a WMM AC based on either 802.1Q or DSCP
1865
1866 @param pAdapter : [in] pointer to adapter context
1867 @param skb : [in] pointer to OS packet (sk_buff)
1868 @param pAcType : [out] pointer to WMM AC type of OS packet
1869
1870 @return : None
1871 ===========================================================================*/
1872v_VOID_t hdd_wmm_classify_pkt ( hdd_adapter_t* pAdapter,
1873 struct sk_buff *skb,
1874 WLANTL_ACEnumType* pAcType,
1875 sme_QosWmmUpType *pUserPri)
1876{
1877 unsigned char * pPkt;
1878 union generic_ethhdr *pHdr;
1879 struct iphdr *pIpHdr;
1880 unsigned char tos;
1881 unsigned char dscp;
1882 sme_QosWmmUpType userPri;
1883 WLANTL_ACEnumType acType;
1884
1885 // this code is executed for every packet therefore
1886 // all debug code is kept conditional
1887
1888#ifdef HDD_WMM_DEBUG
1889 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001890 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001891#endif // HDD_WMM_DEBUG
1892
1893 pPkt = skb->data;
1894 pHdr = (union generic_ethhdr *)pPkt;
1895
1896#ifdef HDD_WMM_DEBUG
1897 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1898 "%s: proto/length is 0x%04x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001899 __func__, pHdr->eth_II.h_proto);
Jeff Johnson295189b2012-06-20 16:38:30 -07001900#endif // HDD_WMM_DEBUG
1901
1902 if (HDD_WMM_CLASSIFICATION_DSCP == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
1903 {
1904 if (pHdr->eth_II.h_proto == htons(ETH_P_IP))
1905 {
1906 // case 1: Ethernet II IP packet
1907 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_II)];
1908 tos = pIpHdr->tos;
1909#ifdef HDD_WMM_DEBUG
1910 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1911 "%s: Ethernet II IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001912 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001913#endif // HDD_WMM_DEBUG
1914
1915 }
1916 else if ((ntohs(pHdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
1917 (pHdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
1918 (pHdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
1919 (pHdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1920 (pHdr->eth_8023.h_proto == htons(ETH_P_IP)))
1921 {
1922 // case 2: 802.3 LLC/SNAP IP packet
1923 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];
1924 tos = pIpHdr->tos;
1925#ifdef HDD_WMM_DEBUG
1926 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1927 "%s: 802.3 LLC/SNAP IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001928 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001929#endif // HDD_WMM_DEBUG
1930 }
1931 else if (pHdr->eth_II.h_proto == htons(ETH_P_8021Q))
1932 {
1933 // VLAN tagged
1934
1935 if (pHdr->eth_IIv.h_vlan_encapsulated_proto == htons(ETH_P_IP))
1936 {
1937 // case 3: Ethernet II vlan-tagged IP packet
1938 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_IIv)];
1939 tos = pIpHdr->tos;
1940#ifdef HDD_WMM_DEBUG
1941 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1942 "%s: Ethernet II VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001943 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001944#endif // HDD_WMM_DEBUG
1945 }
1946 else if ((ntohs(pHdr->eth_IIv.h_vlan_encapsulated_proto) < WLAN_MIN_PROTO) &&
1947 (pHdr->eth_8023v.h_snap.dsap == WLAN_SNAP_DSAP) &&
1948 (pHdr->eth_8023v.h_snap.ssap == WLAN_SNAP_SSAP) &&
1949 (pHdr->eth_8023v.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1950 (pHdr->eth_8023v.h_proto == htons(ETH_P_IP)))
1951 {
1952 // case 4: 802.3 LLC/SNAP vlan-tagged IP packet
1953 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023v)];
1954 tos = pIpHdr->tos;
1955#ifdef HDD_WMM_DEBUG
1956 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1957 "%s: 802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001958 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001959#endif // HDD_WMM_DEBUG
1960 }
1961 else
1962 {
1963 // default
1964#ifdef HDD_WMM_DEBUG
1965 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1966 "%s: VLAN tagged Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001967 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001968#endif // HDD_WMM_DEBUG
1969 tos = 0;
1970 }
1971 }
1972 else
1973 {
1974 // default
1975#ifdef HDD_WMM_DEBUG
1976 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1977 "%s: Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001978 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001979#endif // HDD_WMM_DEBUG
1980 //Give the highest priority to 802.1x packet
1981 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
1982 tos = 0xC0;
1983 else
1984 tos = 0;
1985 }
1986
1987 dscp = (tos>>2) & 0x3f;
Kumar Anand82c009f2014-05-29 00:29:42 -07001988 userPri = pAdapter->hddWmmDscpToUpMap[dscp];
1989
Jeff Johnson295189b2012-06-20 16:38:30 -07001990#ifdef HDD_WMM_DEBUG
1991 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1992 "%s: tos is %d, dscp is %d, up is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001993 __func__, tos, dscp, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07001994#endif // HDD_WMM_DEBUG
1995
1996 }
1997 else if (HDD_WMM_CLASSIFICATION_802_1Q == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
1998 {
1999 if (pHdr->eth_IIv.h_vlan_proto == htons(ETH_P_8021Q))
2000 {
2001 // VLAN tagged
2002 userPri = (ntohs(pHdr->eth_IIv.h_vlan_TCI)>>13) & 0x7;
2003#ifdef HDD_WMM_DEBUG
2004 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2005 "%s: Tagged frame, UP is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002006 __func__, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07002007#endif // HDD_WMM_DEBUG
2008 }
2009 else
2010 {
2011 // not VLAN tagged, use default
2012#ifdef HDD_WMM_DEBUG
2013 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2014 "%s: Untagged frame, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002015 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002016#endif // HDD_WMM_DEBUG
2017 //Give the highest priority to 802.1x packet
2018 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
2019 userPri = SME_QOS_WMM_UP_VO;
2020 else
2021 userPri = SME_QOS_WMM_UP_BE;
2022 }
2023 }
2024 else
2025 {
2026 // default
2027#ifdef HDD_WMM_DEBUG
2028 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2029 "%s: Unknown classification scheme, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002030 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002031#endif // HDD_WMM_DEBUG
2032 userPri = SME_QOS_WMM_UP_BE;
2033 }
2034
2035 acType = hddWmmUpToAcMap[userPri];
2036
2037#ifdef HDD_WMM_DEBUG
2038 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2039 "%s: UP is %d, AC is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002040 __func__, userPri, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002041#endif // HDD_WMM_DEBUG
2042
2043 *pUserPri = userPri;
2044 *pAcType = acType;
2045
2046 return;
2047}
2048
2049/**============================================================================
2050 @brief hdd_hostapd_select_quueue() - Function which will classify the packet
2051 according to linux qdisc expectation.
2052
2053
2054 @param dev : [in] pointer to net_device structure
2055 @param skb : [in] pointer to os packet
2056
2057 @return : Qdisc queue index
2058 ===========================================================================*/
2059v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb)
2060{
2061 WLANTL_ACEnumType ac;
2062 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
2063 v_USHORT_t queueIndex;
2064 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
2065 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
2066 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002067 v_U8_t STAId;
2068 v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302069 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2070 ptSapContext pSapCtx = NULL;
2071 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2072 if(pSapCtx == NULL){
2073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2074 FL("psapCtx is NULL"));
2075 *pSTAId = HDD_WLAN_INVALID_STA_ID;
2076 goto done;
2077 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002078 /*Get the Station ID*/
Jeff Johnson295189b2012-06-20 16:38:30 -07002079 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &STAId))
2080 {
Agarwal Ashisha64c9542014-03-04 00:14:43 +05302081 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002082 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002083 *pSTAId = HDD_WLAN_INVALID_STA_ID;
2084 goto done;
2085 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002086
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302087 spin_lock_bh( &pSapCtx->staInfo_lock );
2088 if (FALSE == vos_is_macaddr_equal(&pSapCtx->aStaInfo[STAId].macAddrSTA, pDestMacAddress))
Jeff Johnson295189b2012-06-20 16:38:30 -07002089 {
Agarwal Ashisha64c9542014-03-04 00:14:43 +05302090 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002091 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002092
2093 *pSTAId = HDD_WLAN_INVALID_STA_ID;
2094 goto release_lock;
2095 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302096 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 -07002097 {
2098 /* Get the user priority from IP header & corresponding AC */
2099 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05302100 //If 3/4th of Tx queue is used then place the DHCP packet in VOICE AC queue
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302101 if (pSapCtx->aStaInfo[STAId].vosLowResource && hdd_is_dhcp_packet(skb))
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05302102 {
2103 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2104 "%s: Making priority of DHCP packet as VOICE", __func__);
2105 up = SME_QOS_WMM_UP_VO;
2106 ac = hddWmmUpToAcMap[up];
2107 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002108 }
2109 *pSTAId = STAId;
2110
2111release_lock:
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302112 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07002113done:
2114 skb->priority = up;
Mukul Sharmad82cb7d2014-07-03 14:53:30 +05302115 if(skb->priority < SME_QOS_WMM_UP_MAX)
2116 queueIndex = hddLinuxUpToAcMap[skb->priority];
2117 else
2118 {
2119 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2120 "%s: up=%d is going beyond max value", __func__, up);
2121 queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
2122 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002123
2124 return queueIndex;
2125}
2126
2127/**============================================================================
2128 @brief hdd_wmm_select_quueue() - Function which will classify the packet
2129 according to linux qdisc expectation.
2130
2131
2132 @param dev : [in] pointer to net_device structure
2133 @param skb : [in] pointer to os packet
2134
2135 @return : Qdisc queue index
2136 ===========================================================================*/
2137v_U16_t hdd_wmm_select_queue(struct net_device * dev, struct sk_buff *skb)
2138{
2139 WLANTL_ACEnumType ac;
Shailender Karmuchia734f332013-04-19 14:02:48 -07002140 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002141 v_USHORT_t queueIndex;
Jeff Johnson295189b2012-06-20 16:38:30 -07002142 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2143
Siddharth Bhal4f6694f2015-02-27 17:24:21 +05302144 if (vos_is_logp_in_progress(VOS_MODULE_ID_HDD, NULL)) {
Kiet Lam40009862014-02-13 12:33:22 -08002145 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2146 FL("called during WDReset"));
2147 skb->priority = SME_QOS_WMM_UP_BE;
2148 return HDD_LINUX_AC_BE;
2149 }
2150
Shailender Karmuchia734f332013-04-19 14:02:48 -07002151 /*Get the Station ID*/
2152 if (WLAN_HDD_IBSS == pAdapter->device_mode)
2153 {
2154 v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
2155 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
2156
2157 if ( VOS_STATUS_SUCCESS !=
2158 hdd_Ibss_GetStaId(&pAdapter->sessionCtx.station,
2159 pDestMacAddress, pSTAId))
2160 {
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05302161 *pSTAId = HDD_WLAN_INVALID_STA_ID;
2162 if ( !vos_is_macaddr_broadcast( pDestMacAddress ) &&
2163 !vos_is_macaddr_group(pDestMacAddress))
2164 {
2165 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnsonb9fb9ce2013-05-03 08:11:02 -07002166 "%s: Failed to find right station pDestMacAddress: "
2167 MAC_ADDRESS_STR , __func__,
2168 MAC_ADDR_ARRAY(pDestMacAddress->bytes));
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05302169 goto done;
2170 }
Shailender Karmuchia734f332013-04-19 14:02:48 -07002171 }
2172 }
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302173 /* All traffic will get equal opportuniy to transmit data frames. */
2174 /* Get the user priority from IP header & corresponding AC */
2175 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302176
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302177 /* If 3/4th of BE AC Tx queue is full,
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302178 * then place the DHCP packet in VOICE AC queue.
2179 * Doing this for IBSS alone, since for STA interface
2180 * types, these packets will be queued to the new queue.
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302181 */
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302182 if ((WLAN_HDD_IBSS == pAdapter->device_mode) &&
2183 pAdapter->isVosLowResource && hdd_is_dhcp_packet(skb))
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302184 {
2185 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2186 "%s: BestEffort Tx Queue is 3/4th full"
2187 " Make DHCP packet's pri as VO", __func__);
2188 up = SME_QOS_WMM_UP_VO;
2189 ac = hddWmmUpToAcMap[up];
Jeff Johnson295189b2012-06-20 16:38:30 -07002190 }
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302191
Shailender Karmuchia734f332013-04-19 14:02:48 -07002192done:
Jeff Johnson295189b2012-06-20 16:38:30 -07002193 skb->priority = up;
Mukul Sharmad82cb7d2014-07-03 14:53:30 +05302194 if(skb->priority < SME_QOS_WMM_UP_MAX)
2195 queueIndex = hddLinuxUpToAcMap[skb->priority];
2196 else
2197 {
2198 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2199 "%s: up=%d is going beyond max value", __func__, up);
2200 queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
2201 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002202
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302203 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
2204 (hdd_is_dhcp_packet(skb) ||
2205 hdd_skb_is_eapol_or_wai_packet(skb)))
2206 {
2207 /* If the packet is a DHCP packet or a Eapol packet or
2208 * a Wapi packet, then queue it to the new queue for
2209 * STA interfaces alone.
2210 */
2211 queueIndex = WLANTL_AC_HIGH_PRIO;
2212 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2213 "%s: up=%d QIndex:%d", __func__, up, queueIndex);
2214 }
2215
Jeff Johnson295189b2012-06-20 16:38:30 -07002216 return queueIndex;
2217}
2218
Kiet Lamf040f472013-11-20 21:15:23 +05302219/**==========================================================================
2220 @brief hdd_wmm_acquire_access_required() - Function which will determine
2221 acquire admittance for a WMM AC is required or not based on psb configuration
2222 done in framework
2223
2224 @param pAdapter : [in] pointer to adapter structure
2225
2226 @param acType : [in] WMM AC type of OS packet
2227
2228 @return : void
2229 ===========================================================================*/
2230void hdd_wmm_acquire_access_required(hdd_adapter_t *pAdapter,
2231 WLANTL_ACEnumType acType)
2232{
2233/* Each bit in the LSB nibble indicates 1 AC.
2234 * Clearing the particular bit in LSB nibble to indicate
2235 * access required
2236 */
2237 switch(acType)
2238 {
2239 case WLANTL_AC_BK:
2240 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BK_CHANGED_MASK; /* clear first bit */
2241 break;
2242 case WLANTL_AC_BE:
2243 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BE_CHANGED_MASK; /* clear second bit */
2244 break;
2245 case WLANTL_AC_VI:
2246 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VI_CHANGED_MASK; /* clear third bit */
2247 break;
2248 case WLANTL_AC_VO:
2249 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VO_CHANGED_MASK; /* clear fourth bit */
2250 break;
2251 default:
2252 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2253 "%s: Invalid AC Type", __func__);
2254 break;
2255 }
2256}
2257
Jeff Johnson295189b2012-06-20 16:38:30 -07002258/**============================================================================
2259 @brief hdd_wmm_acquire_access() - Function which will attempt to acquire
2260 admittance for a WMM AC
2261
2262 @param pAdapter : [in] pointer to adapter context
2263 @param acType : [in] WMM AC type of OS packet
2264 @param pGranted : [out] pointer to boolean flag when indicates if access
2265 has been granted or not
2266
2267 @return : VOS_STATUS_SUCCESS if succssful
2268 : other values if failure
2269 ===========================================================================*/
2270VOS_STATUS hdd_wmm_acquire_access( hdd_adapter_t* pAdapter,
2271 WLANTL_ACEnumType acType,
2272 v_BOOL_t * pGranted )
2273{
2274 hdd_wmm_qos_context_t *pQosContext;
2275
2276 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002277 "%s: Entered for AC %d", __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002278
2279 if (!hdd_wmm_is_active(pAdapter) || !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
2280 {
2281 // either we don't want QoS or the AP doesn't support QoS
2282 // or we don't want to do implicit QoS
2283 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002284 "%s: QoS not configured on both ends ", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002285
2286 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2287 *pGranted = VOS_TRUE;
2288 return VOS_STATUS_SUCCESS;
2289 }
2290
2291 // do we already have an implicit QoS request pending for this AC?
2292 if ((pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded) ||
2293 (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessPending))
2294 {
2295 // request already pending so we need to wait for that response
2296 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2297 "%s: Implicit QoS for TL AC %d already scheduled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002298 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002299
2300 *pGranted = VOS_FALSE;
2301 return VOS_STATUS_SUCCESS;
2302 }
2303
2304 // did we already fail to establish implicit QoS for this AC?
2305 // (if so, access should have been granted when the failure was handled)
2306 if (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessFailed)
2307 {
2308 // request previously failed
2309 // allow access, but we'll be downgraded
2310 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2311 "%s: Implicit QoS for TL AC %d previously failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002312 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002313
2314 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2315 *pGranted = VOS_TRUE;
2316 return VOS_STATUS_SUCCESS;
2317 }
2318
2319 // we need to establish implicit QoS
2320 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2321 "%s: Need to schedule implicit QoS for TL AC %d, pAdapter is %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002322 __func__, acType, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002323
2324 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded = VOS_TRUE;
2325
Mohit Khanna217ea8d2012-09-11 17:42:42 -07002326 pQosContext = kmalloc(sizeof(*pQosContext), GFP_ATOMIC);
Jeff Johnson295189b2012-06-20 16:38:30 -07002327 if (NULL == pQosContext)
2328 {
2329 // no memory for QoS context. Nothing we can do but let data flow
2330 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002331 "%s: Unable to allocate context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002332 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2333 *pGranted = VOS_TRUE;
2334 return VOS_STATUS_SUCCESS;
2335 }
2336
2337 pQosContext->acType = acType;
2338 pQosContext->pAdapter = pAdapter;
2339 pQosContext->qosFlowId = 0;
2340 pQosContext->handle = HDD_WMM_HANDLE_IMPLICIT;
2341 pQosContext->magic = HDD_WMM_CTX_MAGIC;
2342 INIT_WORK(&pQosContext->wmmAcSetupImplicitQos,
2343 hdd_wmm_do_implicit_qos);
2344
2345 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2346 "%s: Scheduling work for AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002347 __func__, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002348
2349 schedule_work(&pQosContext->wmmAcSetupImplicitQos);
2350
2351 // caller will need to wait until the work takes place and
2352 // TSPEC negotiation completes
2353 *pGranted = VOS_FALSE;
2354 return VOS_STATUS_SUCCESS;
2355}
2356
2357/**============================================================================
2358 @brief hdd_wmm_assoc() - Function which will handle the housekeeping
2359 required by WMM when association takes place
2360
2361 @param pAdapter : [in] pointer to adapter context
2362 @param pRoamInfo: [in] pointer to roam information
2363 @param eBssType : [in] type of BSS
2364
2365 @return : VOS_STATUS_SUCCESS if succssful
2366 : other values if failure
2367 ===========================================================================*/
2368VOS_STATUS hdd_wmm_assoc( hdd_adapter_t* pAdapter,
2369 tCsrRoamInfo *pRoamInfo,
2370 eCsrRoamBssType eBssType )
2371{
2372 tANI_U8 uapsdMask;
2373 VOS_STATUS status;
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002374 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002375
2376 // when we associate we need to notify TL if it needs to enable
2377 // UAPSD for any access categories
2378
2379 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002380 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002381
2382 if (pRoamInfo->fReassocReq)
2383 {
2384 // when we reassociate we should continue to use whatever
2385 // parameters were previously established. if we are
2386 // reassociating due to a U-APSD change for a particular
2387 // Access Category, then the change will be communicated
2388 // to HDD via the QoS callback associated with the given
2389 // flow, and U-APSD parameters will be updated there
2390
2391 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002392 "%s: Reassoc so no work, Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002393
2394 return VOS_STATUS_SUCCESS;
2395 }
2396
2397 // get the negotiated UAPSD Mask
2398 uapsdMask = pRoamInfo->u.pConnectedProfile->modifyProfileFields.uapsd_mask;
2399
2400 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002401 "%s: U-APSD mask is 0x%02x", __func__, (int) uapsdMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002402
2403 if (uapsdMask & HDD_AC_VO)
2404 {
2405 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2406 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2407 WLANTL_AC_VO,
2408 7,
2409 7,
2410 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv,
2411 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv,
2412 WLANTL_BI_DIR );
2413
2414 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2415 }
2416
2417 if (uapsdMask & HDD_AC_VI)
2418 {
2419 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2420 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2421 WLANTL_AC_VI,
2422 5,
2423 5,
2424 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv,
2425 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv,
2426 WLANTL_BI_DIR );
2427
2428 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2429 }
2430
2431 if (uapsdMask & HDD_AC_BK)
2432 {
2433 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2434 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2435 WLANTL_AC_BK,
2436 2,
2437 2,
2438 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv,
2439 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv,
2440 WLANTL_BI_DIR );
2441
2442 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2443 }
2444
2445 if (uapsdMask & HDD_AC_BE)
2446 {
2447 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2448 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2449 WLANTL_AC_BE,
2450 3,
2451 3,
2452 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv,
2453 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv,
2454 WLANTL_BI_DIR );
2455
2456 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2457 }
Kumar Anand82c009f2014-05-29 00:29:42 -07002458
2459 status = sme_UpdateDSCPtoUPMapping(pHddCtx->hHal,
2460 pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId);
2461
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002462 if (!VOS_IS_STATUS_SUCCESS( status ))
2463 {
Kumar Anand82c009f2014-05-29 00:29:42 -07002464 hdd_wmm_init( pAdapter );
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002465 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002466
2467 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002468 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002469
2470 return VOS_STATUS_SUCCESS;
2471}
2472
2473
2474
2475static const v_U8_t acmMaskBit[WLANTL_MAX_AC] =
2476 {
2477 0x4, /* WLANTL_AC_BK */
2478 0x8, /* WLANTL_AC_BE */
2479 0x2, /* WLANTL_AC_VI */
2480 0x1 /* WLANTL_AC_VO */
2481 };
2482
2483/**============================================================================
2484 @brief hdd_wmm_connect() - Function which will handle the housekeeping
2485 required by WMM when a connection is established
2486
2487 @param pAdapter : [in] pointer to adapter context
2488 @param pRoamInfo: [in] pointer to roam information
2489 @param eBssType : [in] type of BSS
2490
2491 @return : VOS_STATUS_SUCCESS if succssful
2492 : other values if failure
2493 ===========================================================================*/
2494VOS_STATUS hdd_wmm_connect( hdd_adapter_t* pAdapter,
2495 tCsrRoamInfo *pRoamInfo,
2496 eCsrRoamBssType eBssType )
2497{
2498 int ac;
2499 v_BOOL_t qap;
2500 v_BOOL_t qosConnection;
2501 v_U8_t acmMask;
2502
2503 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002504 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002505
2506 if ((eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) &&
2507 pRoamInfo &&
2508 pRoamInfo->u.pConnectedProfile)
2509 {
2510 qap = pRoamInfo->u.pConnectedProfile->qap;
2511 qosConnection = pRoamInfo->u.pConnectedProfile->qosConnection;
2512 acmMask = pRoamInfo->u.pConnectedProfile->acm_mask;
2513 }
2514 else
2515 {
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05302516 /* TODO: if a non-qos IBSS peer joins the group make qap and qosConnection false.
2517 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002518 qap = VOS_TRUE;
2519 qosConnection = VOS_TRUE;
2520 acmMask = 0x0;
2521 }
2522
2523 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2524 "%s: qap is %d, qosConnection is %d, acmMask is 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002525 __func__, qap, qosConnection, acmMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002526
2527 pAdapter->hddWmmStatus.wmmQap = qap;
2528 pAdapter->hddWmmStatus.wmmQosConnection = qosConnection;
2529
2530 for (ac = 0; ac < WLANTL_MAX_AC; ac++)
2531 {
2532 if (qap &&
2533 qosConnection &&
2534 (acmMask & acmMaskBit[ac]))
2535 {
2536 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2537 "%s: ac %d on",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002538 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002539
2540 // admission is required
2541 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_TRUE;
2542 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_FALSE;
2543 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessGranted = VOS_FALSE;
Mukul Sharma74a01e52014-07-21 15:14:23 +05302544
2545 /* Making TSPEC invalid here so downgrading can be happen while roaming
2546 * It is expected this will be SET in hdd_wmm_sme_callback,once sme is
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302547 * done with the AddTspec.Here we avoid 11r and ccx based association.
2548 This change is done only when reassoc to different AP.
Mukul Sharma74a01e52014-07-21 15:14:23 +05302549 */
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2551 FL( "fReassocReq = %d"
2552#if defined (FEATURE_WLAN_ESE)
2553 "isESEAssoc = %d"
2554#endif
2555#if defined (WLAN_FEATURE_VOWIFI_11R)
2556 "is11rAssoc = %d"
2557#endif
2558 ),
2559 pRoamInfo->fReassocReq
2560#if defined (FEATURE_WLAN_ESE)
2561 ,pRoamInfo->isESEAssoc
2562#endif
2563#if defined (WLAN_FEATURE_VOWIFI_11R)
2564 ,pRoamInfo->is11rAssoc
2565#endif
2566 );
2567
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302568 if ( !pRoamInfo->fReassocReq
Mukul Sharma74a01e52014-07-21 15:14:23 +05302569#if defined (WLAN_FEATURE_VOWIFI_11R)
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302570 &&
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302571 !pRoamInfo->is11rAssoc
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302572#endif
Mukul Sharma74a01e52014-07-21 15:14:23 +05302573#if defined (FEATURE_WLAN_ESE)
2574 &&
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302575 !pRoamInfo->isESEAssoc
Mukul Sharma74a01e52014-07-21 15:14:23 +05302576#endif
2577 )
Mukul Sharma74a01e52014-07-21 15:14:23 +05302578 {
2579 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcTspecValid = VOS_FALSE;
2580 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002581 }
2582 else
2583 {
2584 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2585 "%s: ac %d off",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002586 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002587 // admission is not required so access is allowed
2588 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_FALSE;
2589 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_TRUE;
2590 }
2591
2592 }
2593
2594 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002595 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002596
2597 return VOS_STATUS_SUCCESS;
2598}
2599
2600/**============================================================================
2601 @brief hdd_wmm_get_uapsd_mask() - Function which will calculate the
2602 initial value of the UAPSD mask based upon the device configuration
2603
2604 @param pAdapter : [in] pointer to adapter context
2605 @param pUapsdMask: [in] pointer to where the UAPSD Mask is to be stored
2606
2607 @return : VOS_STATUS_SUCCESS if succssful
2608 : other values if failure
2609 ===========================================================================*/
2610VOS_STATUS hdd_wmm_get_uapsd_mask( hdd_adapter_t* pAdapter,
2611 tANI_U8 *pUapsdMask )
2612{
2613 tANI_U8 uapsdMask;
2614
2615 if (HDD_WMM_USER_MODE_NO_QOS == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
2616 {
2617 // no QOS then no UAPSD
2618 uapsdMask = 0;
2619 }
2620 else
2621 {
2622 // start with the default mask
2623 uapsdMask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
2624
2625 // disable UAPSD for any ACs with a 0 Service Interval
2626 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv == 0 )
2627 {
2628 uapsdMask &= ~HDD_AC_VO;
2629 }
2630
2631 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv == 0 )
2632 {
2633 uapsdMask &= ~HDD_AC_VI;
2634 }
2635
2636 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv == 0 )
2637 {
2638 uapsdMask &= ~HDD_AC_BK;
2639 }
2640
2641 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv == 0 )
2642 {
2643 uapsdMask &= ~HDD_AC_BE;
2644 }
2645 }
2646
2647 // return calculated mask
2648 *pUapsdMask = uapsdMask;
2649 return VOS_STATUS_SUCCESS;
2650}
2651
2652
2653/**============================================================================
2654 @brief hdd_wmm_is_active() - Function which will determine if WMM is
2655 active on the current connection
2656
2657 @param pAdapter : [in] pointer to adapter context
2658
2659 @return : VOS_TRUE if WMM is enabled
2660 : VOS_FALSE if WMM is not enabled
2661 ===========================================================================*/
2662v_BOOL_t hdd_wmm_is_active( hdd_adapter_t* pAdapter )
2663{
2664 if ((!pAdapter->hddWmmStatus.wmmQosConnection) ||
2665 (!pAdapter->hddWmmStatus.wmmQap))
2666 {
2667 return VOS_FALSE;
2668 }
2669 else
2670 {
2671 return VOS_TRUE;
2672 }
2673}
2674
2675/**============================================================================
2676 @brief hdd_wmm_addts() - Function which will add a traffic spec at the
2677 request of an application
2678
2679 @param pAdapter : [in] pointer to adapter context
2680 @param handle : [in] handle to uniquely identify a TS
2681 @param pTspec : [in] pointer to the traffic spec
2682
2683 @return : HDD_WLAN_WMM_STATUS_*
2684 ===========================================================================*/
2685hdd_wlan_wmm_status_e hdd_wmm_addts( hdd_adapter_t* pAdapter,
2686 v_U32_t handle,
2687 sme_QosWmmTspecInfo* pTspec )
2688{
2689 hdd_wmm_qos_context_t *pQosContext;
2690 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2691#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2692 sme_QosStatusType smeStatus;
2693#endif
2694 v_BOOL_t found = VOS_FALSE;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302695 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
2696 hdd_context_t *pHddCtx;
2697 if (NULL != pVosContext)
2698 {
2699 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
2700 if (NULL == pHddCtx)
2701 {
2702 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2703 FL("HddCtx is NULL"));
2704 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2705 }
2706 }
2707
Jeff Johnson295189b2012-06-20 16:38:30 -07002708
2709 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002710 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002711
2712 // see if a context already exists with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302713 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002714 list_for_each_entry(pQosContext,
2715 &pAdapter->hddWmmStatus.wmmContextList,
2716 node)
2717 {
2718 if (pQosContext->handle == handle)
2719 {
2720 found = VOS_TRUE;
2721 break;
2722 }
2723 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302724 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002725 if (found)
2726 {
2727 // record with that handle already exists
2728 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2729 "%s: Record already exists with handle 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002730 __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002731
2732 /* Application is trying to modify some of the Tspec params. Allow it */
2733 smeStatus = sme_QosModifyReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2734 pTspec,
2735 pQosContext->qosFlowId);
2736
2737 // need to check the return value and act appropriately
2738 switch (smeStatus)
2739 {
2740 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
2741 status = HDD_WLAN_WMM_STATUS_MODIFY_PENDING;
2742 break;
2743 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2744 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
2745 break;
2746 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
2747 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
2748 break;
2749 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
2750 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
2751 break;
2752 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
2753 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2754 break;
2755 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2756 status = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2757 break;
2758 default:
2759 // we didn't get back one of the SME_QOS_STATUS_MODIFY_* status codes
2760 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002761 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002762 VOS_ASSERT(0);
2763 return HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2764 }
2765
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302766 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05302767 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
2768 {
2769 pQosContext->lastStatus = status;
2770 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302771 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002772 return status;
2773 }
2774
2775 pQosContext = kmalloc(sizeof(*pQosContext), GFP_KERNEL);
2776 if (NULL == pQosContext)
2777 {
2778 // no memory for QoS context. Nothing we can do
2779 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002780 "%s: Unable to allocate QoS context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002781 return HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE;
2782 }
2783
2784 // we assume the tspec has already been validated by the caller
2785
2786 pQosContext->handle = handle;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08002787 if (pTspec->ts_info.up < HDD_WMM_UP_TO_AC_MAP_SIZE)
2788 pQosContext->acType = hddWmmUpToAcMap[pTspec->ts_info.up];
2789 else {
2790 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2791 "%s: ts_info.up (%d) larger than max value (%d), "
2792 "use default acType (%d)",
2793 __func__, pTspec->ts_info.up,
2794 HDD_WMM_UP_TO_AC_MAP_SIZE - 1, hddWmmUpToAcMap[0]);
2795 pQosContext->acType = hddWmmUpToAcMap[0];
2796 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302797
Jeff Johnson295189b2012-06-20 16:38:30 -07002798 pQosContext->pAdapter = pAdapter;
2799 pQosContext->qosFlowId = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002800
2801 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2802 "%s: Setting up QoS, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002803 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002804
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302805 mutex_lock(&pHddCtx->wmmLock);
2806 pQosContext->magic = HDD_WMM_CTX_MAGIC;
Jeff Johnson295189b2012-06-20 16:38:30 -07002807 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302808 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002809
2810#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2811 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2812 pAdapter->sessionId,
2813 pTspec,
2814 hdd_wmm_sme_callback,
2815 pQosContext,
2816 pTspec->ts_info.up,
2817 &pQosContext->qosFlowId);
2818
2819 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2820 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002821 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002822
2823 // need to check the return value and act appropriately
2824 switch (smeStatus)
2825 {
2826 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
2827 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2828 break;
2829 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2830 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
2831 break;
2832 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
2833 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
2834 break;
2835 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
2836 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2837 break;
2838 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
2839 hdd_wmm_free_context(pQosContext);
2840 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
2841 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
2842 // we can't tell the difference between when a request fails because
2843 // AP rejected it versus when SME encounterd an internal error
2844 hdd_wmm_free_context(pQosContext);
2845 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2846 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2847 hdd_wmm_free_context(pQosContext);
2848 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2849 default:
2850 // we didn't get back one of the SME_QOS_STATUS_SETUP_* status codes
2851 hdd_wmm_free_context(pQosContext);
2852 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002853 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002854 VOS_ASSERT(0);
2855 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2856 }
2857#endif
2858
2859 // we were successful, save the status
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302860 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05302861 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
2862 {
2863 pQosContext->lastStatus = status;
2864 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302865 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002866
2867 return status;
2868}
2869
2870/**============================================================================
2871 @brief hdd_wmm_delts() - Function which will delete a traffic spec at the
2872 request of an application
2873
2874 @param pAdapter : [in] pointer to adapter context
2875 @param handle : [in] handle to uniquely identify a TS
2876
2877 @return : HDD_WLAN_WMM_STATUS_*
2878 ===========================================================================*/
2879hdd_wlan_wmm_status_e hdd_wmm_delts( hdd_adapter_t* pAdapter,
2880 v_U32_t handle )
2881{
2882 hdd_wmm_qos_context_t *pQosContext;
2883 v_BOOL_t found = VOS_FALSE;
2884 WLANTL_ACEnumType acType = 0;
2885 v_U32_t qosFlowId = 0;
2886 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2887#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2888 sme_QosStatusType smeStatus;
2889#endif
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302890 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
2891 hdd_context_t *pHddCtx;
2892
2893 if (NULL != pVosContext)
2894 {
2895 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
2896 if (NULL == pHddCtx)
2897 {
2898 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2899 FL("HddCtx is NULL"));
2900 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2901 }
2902 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002903
2904 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002905 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002906
2907 // locate the context with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302908 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002909 list_for_each_entry(pQosContext,
2910 &pAdapter->hddWmmStatus.wmmContextList,
2911 node)
2912 {
2913 if (pQosContext->handle == handle)
2914 {
2915 found = VOS_TRUE;
2916 acType = pQosContext->acType;
2917 qosFlowId = pQosContext->qosFlowId;
2918 break;
2919 }
2920 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302921 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002922
2923 if (VOS_FALSE == found)
2924 {
2925 // we didn't find the handle
2926 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002927 "%s: handle 0x%x not found", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002928 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2929 }
2930
2931
2932 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2933 "%s: found handle 0x%x, flow %d, AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002934 __func__, handle, qosFlowId, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002935
2936#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2937 smeStatus = sme_QosReleaseReq( WLAN_HDD_GET_HAL_CTX(pAdapter), qosFlowId );
2938
2939 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2940 "%s: SME flow %d released, SME status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002941 __func__, qosFlowId, smeStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07002942
2943 switch(smeStatus)
2944 {
2945 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
2946 // this flow is the only one on that AC, so go ahead and update
2947 // our TSPEC state for the AC
2948 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcTspecValid = VOS_FALSE;
2949
2950 // need to tell TL to stop trigger timer, etc
2951 hdd_wmm_disable_tl_uapsd(pQosContext);
2952
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002953#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07002954 // disable the inactivity timer
2955 hdd_wmm_disable_inactivity_timer(pQosContext);
2956#endif
2957 // we are done with this context
2958 hdd_wmm_free_context(pQosContext);
2959
2960 // SME must not fire any more callbacks for this flow since the context
2961 // is no longer valid
2962
2963 return HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
2964
2965 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
2966 // do nothing as we will get a response from SME
2967 status = HDD_WLAN_WMM_STATUS_RELEASE_PENDING;
2968 break;
2969
2970 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
2971 // nothing we can do with the existing flow except leave it
2972 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2973 break;
2974
2975 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
2976 // nothing we can do with the existing flow except leave it
2977 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2978
2979 default:
2980 // we didn't get back one of the SME_QOS_STATUS_RELEASE_* status codes
2981 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002982 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002983 VOS_ASSERT(0);
2984 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2985 }
2986
2987#endif
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302988 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05302989 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
2990 {
2991 pQosContext->lastStatus = status;
2992 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302993 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002994 return status;
2995}
2996
2997/**============================================================================
2998 @brief hdd_wmm_checkts() - Function which will return the status of a traffic
2999 spec at the request of an application
3000
3001 @param pAdapter : [in] pointer to adapter context
3002 @param handle : [in] handle to uniquely identify a TS
3003
3004 @return : HDD_WLAN_WMM_STATUS_*
3005 ===========================================================================*/
3006hdd_wlan_wmm_status_e hdd_wmm_checkts( hdd_adapter_t* pAdapter,
3007 v_U32_t handle )
3008{
3009 hdd_wmm_qos_context_t *pQosContext;
3010 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303011 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
3012 hdd_context_t *pHddCtx;
3013
3014 if (NULL != pVosContext)
3015 {
3016 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
3017 if (NULL == pHddCtx)
3018 {
3019 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
3020 FL("HddCtx is NULL"));
3021 return HDD_WLAN_WMM_STATUS_LOST;
3022 }
3023 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003024
3025 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003026 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07003027
3028 // locate the context with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303029 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003030 list_for_each_entry(pQosContext,
3031 &pAdapter->hddWmmStatus.wmmContextList,
3032 node)
3033 {
3034 if (pQosContext->handle == handle)
3035 {
3036 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
3037 "%s: found handle 0x%x, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003038 __func__, handle, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07003039
3040 status = pQosContext->lastStatus;
3041 break;
3042 }
3043 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303044 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003045 return status;
3046}