blob: 9c2ad342caa4f63efb1e53c373ab4b2ed2e08529 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Sravan Kumar Kairamf9f95122017-01-18 20:54:05 +05302 * Copyright (c) 2012-2017 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
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +053087// DHCP Port number
88#define DHCP_SOURCE_PORT 0x4400
89#define DHCP_DESTINATION_PORT 0x4300
90
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080091#define HDD_WMM_UP_TO_AC_MAP_SIZE 8
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -070092
Sravan Kumar Kairamd9ded562016-11-13 15:21:49 +053093#define IPv6_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5],\
94 (a)[6], (a)[7], (a)[8], (a)[9], (a)[10], (a)[11], (a)[12], (a)[13],\
95 (a)[14], (a)[15]
96#define IPv6_ADDR_STR "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:"\
97 "%02x%02x:%02x%02x"
98
Jeff Johnson295189b2012-06-20 16:38:30 -070099const v_U8_t hddWmmUpToAcMap[] = {
100 WLANTL_AC_BE,
101 WLANTL_AC_BK,
102 WLANTL_AC_BK,
103 WLANTL_AC_BE,
104 WLANTL_AC_VI,
105 WLANTL_AC_VI,
106 WLANTL_AC_VO,
107 WLANTL_AC_VO
108};
109
110//Linux based UP -> AC Mapping
111const v_U8_t hddLinuxUpToAcMap[8] = {
112 HDD_LINUX_AC_BE,
113 HDD_LINUX_AC_BK,
114 HDD_LINUX_AC_BK,
115 HDD_LINUX_AC_BE,
116 HDD_LINUX_AC_VI,
117 HDD_LINUX_AC_VI,
118 HDD_LINUX_AC_VO,
119 HDD_LINUX_AC_VO
120};
121
122#ifndef WLAN_MDM_CODE_REDUCTION_OPT
123/**
124 @brief hdd_wmm_enable_tl_uapsd() - function which decides whether and
125 how to update UAPSD parameters in TL
126
127 @param pQosContext : [in] the pointer the QoS instance control block
128
129 @return
130 None
131*/
132static void hdd_wmm_enable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
133{
134 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
135 WLANTL_ACEnumType acType = pQosContext->acType;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530136 hdd_wmm_ac_status_t *pAc = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700137 VOS_STATUS status;
138 v_U32_t service_interval;
139 v_U32_t suspension_interval;
140 sme_QosWmmDirType direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530141 v_BOOL_t psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700142
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530143 if (acType >= WLANTL_MAX_AC)
144 {
145 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
146 "%s: Invalid AC: %d", __func__, acType);
147 return;
148 }
149
150 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
Jeff Johnson295189b2012-06-20 16:38:30 -0700151
152 // The TSPEC must be valid
153 if (pAc->wmmAcTspecValid == VOS_FALSE)
154 {
155 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
156 "%s: Invoked with invalid TSPEC",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700157 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700158 return;
159 }
160
161 // determine the service interval
162 if (pAc->wmmAcTspecInfo.min_service_interval)
163 {
164 service_interval = pAc->wmmAcTspecInfo.min_service_interval;
165 }
166 else if (pAc->wmmAcTspecInfo.max_service_interval)
167 {
168 service_interval = pAc->wmmAcTspecInfo.max_service_interval;
169 }
170 else
171 {
172 // no service interval is present in the TSPEC
173 // this is OK, there just won't be U-APSD
174 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
175 "%s: No service interval supplied",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700176 __func__);
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530177 service_interval = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700178 }
179
180 // determine the suspension interval & direction
181 suspension_interval = pAc->wmmAcTspecInfo.suspension_interval;
182 direction = pAc->wmmAcTspecInfo.ts_info.direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530183 psb = pAc->wmmAcTspecInfo.ts_info.psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700184
185 // if we have previously enabled U-APSD, have any params changed?
186 if ((pAc->wmmAcUapsdInfoValid) &&
187 (pAc->wmmAcUapsdServiceInterval == service_interval) &&
188 (pAc->wmmAcUapsdSuspensionInterval == suspension_interval) &&
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530189 (pAc->wmmAcUapsdDirection == direction) &&
190 (pAc->wmmAcIsUapsdEnabled == psb))
Jeff Johnson295189b2012-06-20 16:38:30 -0700191 {
192 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
193 "%s: No change in U-APSD parameters",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700194 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700195 return;
196 }
197
198 // are we in the appropriate power save modes?
199 if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_BEACON_MODE_POWER_SAVE))
200 {
201 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
202 "%s: BMPS is not enabled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700203 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700204 return;
205 }
206
207 if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_UAPSD_MODE_POWER_SAVE))
208 {
209 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
210 "%s: U-APSD is not enabled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700211 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700212 return;
213 }
214
215 // everything is in place to notify TL
216 status = WLANTL_EnableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
217 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
218 acType,
219 pAc->wmmAcTspecInfo.ts_info.tid,
220 pAc->wmmAcTspecInfo.ts_info.up,
221 service_interval,
222 suspension_interval,
223 direction);
224
225 if ( !VOS_IS_STATUS_SUCCESS( status ) )
226 {
227 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
228 "%s: Failed to enable U-APSD for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700229 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700230 return;
231 }
232
233 // stash away the parameters that were used
234 pAc->wmmAcUapsdInfoValid = VOS_TRUE;
235 pAc->wmmAcUapsdServiceInterval = service_interval;
236 pAc->wmmAcUapsdSuspensionInterval = suspension_interval;
237 pAc->wmmAcUapsdDirection = direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530238 pAc->wmmAcIsUapsdEnabled = psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700239
240 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700241 "%s: Enabled UAPSD in TL srv_int=%d "
242 "susp_int=%d dir=%d AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700243 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 service_interval,
245 suspension_interval,
246 direction,
247 acType);
248
249}
250
251/**
252 @brief hdd_wmm_disable_tl_uapsd() - function which decides whether
253 to disable UAPSD parameters in TL
254
255 @param pQosContext : [in] the pointer the QoS instance control block
256
257 @return
258 None
259*/
260static void hdd_wmm_disable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
261{
262 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
263 WLANTL_ACEnumType acType = pQosContext->acType;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530264 hdd_wmm_ac_status_t *pAc = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700265 VOS_STATUS status;
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530266 v_U32_t service_interval;
267 v_U32_t suspension_interval;
268 v_U8_t uapsd_mask;
269 v_U8_t ActiveTspec = INVALID_TSPEC;
Jeff Johnson295189b2012-06-20 16:38:30 -0700270
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530271 if (acType >= WLANTL_MAX_AC)
272 {
273 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
274 "%s: Invalid AC: %d", __func__, acType);
275 return;
276 }
277
278 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
279
Jeff Johnson295189b2012-06-20 16:38:30 -0700280 // have we previously enabled UAPSD?
281 if (pAc->wmmAcUapsdInfoValid == VOS_TRUE)
282 {
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530283 uapsd_mask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
Jeff Johnson295189b2012-06-20 16:38:30 -0700284
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530285 //Finding uapsd_mask as per AC
286 uapsd_mask = uapsd_mask & (1 << (WLANTL_AC_VO - acType));
287
288 sme_QosTspecActive((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter), acType,
289 pAdapter->sessionId, &ActiveTspec);
290
291 //Call WLANTL_EnableUAPSDForAC only when static uapsd mask is present and
292 // no active tspecs. TODO: Need to change naming convention as Enable
293 // UAPSD function is called in hdd_wmm_disable_tl_uapsd. Purpose of
294 // calling WLANTL_EnableUAPSDForAC is to update UAPSD intervals to fw
295
296 if(uapsd_mask && !ActiveTspec)
Jeff Johnson295189b2012-06-20 16:38:30 -0700297 {
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530298 switch(acType)
299 {
300 case WLANTL_AC_VO:
301 service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv;
302 suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv;
303 break;
304 case WLANTL_AC_VI:
305 service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv;
306 suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv;
307 break;
308 case WLANTL_AC_BE:
309 service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv;
310 suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv;
311 break;
312 case WLANTL_AC_BK:
313 service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv;
314 suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv;
315 break;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530316 default:
317 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
318 "%s: Invalid AC %d", __func__, acType );
319 return;
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530320 }
321
322 status = WLANTL_EnableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
323 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
324 acType,
325 pAc->wmmAcTspecInfo.ts_info.tid,
326 pAc->wmmAcTspecInfo.ts_info.up,
327 service_interval,
328 suspension_interval,
329 pAc->wmmAcTspecInfo.ts_info.direction);
330
331 if ( !VOS_IS_STATUS_SUCCESS( status ) )
332 {
333 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
334 "%s: Failed to update U-APSD params for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700335 __func__, acType );
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530336 }
337 else
338 {
339 // TL no longer has valid UAPSD info
340 pAc->wmmAcUapsdInfoValid = VOS_FALSE;
341 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
342 "%s: Updated UAPSD params in TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700343 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700344 acType);
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530345 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700346 }
347 }
348}
349
350#endif
351
352/**
353 @brief hdd_wmm_free_context() - function which frees a QoS context
354
355 @param pQosContext : [in] the pointer the QoS instance control block
356
357 @return
358 None
359*/
360static void hdd_wmm_free_context (hdd_wmm_qos_context_t* pQosContext)
361{
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530362 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +0530363 hdd_context_t *pHddCtx = NULL;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530364
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530365 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530366 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530367 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
368 FL("pVosContext is NULL"));
369 return;
370 }
371
372 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
373 if (NULL == pHddCtx)
374 {
375 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
376 FL("HddCtx is NULL"));
377 return;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530378 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700379
380 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -0700381 "%s: Entered, context %pK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700382 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700383
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530384 // take the wmmLock since we're manipulating the context list
385 mutex_lock(&pHddCtx->wmmLock);
386
Jeff Johnson295189b2012-06-20 16:38:30 -0700387 if (unlikely((NULL == pQosContext) ||
388 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
389 {
390 // must have been freed in another thread
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530391 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700392 return;
393 }
394
Jeff Johnson295189b2012-06-20 16:38:30 -0700395 // make sure nobody thinks this is a valid context
396 pQosContext->magic = 0;
397
398 // unlink the context
399 list_del(&pQosContext->node);
400
401 // done manipulating the list
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530402 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700403
404 // reclaim memory
405 kfree(pQosContext);
406
407}
408
409#ifndef WLAN_MDM_CODE_REDUCTION_OPT
410/**
411 @brief hdd_wmm_notify_app() - function which notifies an application
412 changes in state of it flow
413
414 @param pQosContext : [in] the pointer the QoS instance control block
415
416 @return
417 None
418*/
419#define MAX_NOTIFY_LEN 50
420static void hdd_wmm_notify_app (hdd_wmm_qos_context_t* pQosContext)
421{
422 hdd_adapter_t* pAdapter;
423 union iwreq_data wrqu;
424 char buf[MAX_NOTIFY_LEN+1];
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530425 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +0530426 hdd_context_t *pHddCtx = NULL;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530427
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530428 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530429 {
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530430 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530431 FL("pVosContext is NULL"));
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530432 return;
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530433 }
434
435 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
436 if (NULL == pHddCtx)
437 {
438 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
439 FL("HddCtx is NULL"));
440 return;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530441 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700442
443 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -0700444 "%s: Entered, context %pK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700445 __func__, pQosContext);
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530446
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530447 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700448 if (unlikely((NULL == pQosContext) ||
449 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
450 {
Hema Aparna Medicharla8bb6f782015-03-09 12:35:05 +0530451 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700452 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
453 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700454 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700455 return;
456 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530457 // get pointer to the adapter
458 pAdapter = pQosContext->pAdapter;
459 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700460
461 // create the event
462 memset(&wrqu, 0, sizeof(wrqu));
463 memset(buf, 0, sizeof(buf));
464
465 snprintf(buf, MAX_NOTIFY_LEN, "QCOM: TS change[%u: %u]",
466 (unsigned int)pQosContext->handle,
467 (unsigned int)pQosContext->lastStatus);
468
469 wrqu.data.pointer = buf;
470 wrqu.data.length = strlen(buf);
471
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530472
Jeff Johnson295189b2012-06-20 16:38:30 -0700473
474 // send the event
475 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700476 "%s: Sending [%s]", __func__, buf);
Jeff Johnson295189b2012-06-20 16:38:30 -0700477 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
478}
479
480
481/**
482 @brief hdd_wmm_is_access_allowed() - function which determines if access
483 is allowed for the given AC. this is designed to be called during SME
484 callback processing since that is when access can be granted or removed
485
486 @param pAdapter : [in] pointer to adapter context
487 @param pAc : [in] pointer to the per-AC status
488
489 @return : VOS_TRUE - access is allowed
490 : VOS_FALSE - access is not allowed
491 None
492*/
493static v_BOOL_t hdd_wmm_is_access_allowed(hdd_adapter_t* pAdapter,
494 hdd_wmm_ac_status_t* pAc)
495{
496 // if we don't want QoS or the AP doesn't support QoS
497 // or we don't want to do implicit QoS
498 // or if AP doesn't require admission for this AC
499 // then we have access
500 if (!hdd_wmm_is_active(pAdapter) ||
501 !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled ||
502 !pAc->wmmAcAccessRequired)
503 {
504 return VOS_TRUE;
505 }
506
507 // if implicit QoS has already completed, successfully or not,
508 // then access is allowed
509 if (pAc->wmmAcAccessGranted || pAc->wmmAcAccessFailed)
510 {
511 return VOS_TRUE;
512 }
513
514 // admission is required and implicit QoS hasn't completed
515 // however explicit QoS may have completed and we'll have
516 // a Tspec
517 // if we don't have a Tspec then access is not allowed
518 if (!pAc->wmmAcTspecValid)
519 {
520 return VOS_FALSE;
521 }
522
523 // we have a Tspec -- does it allow upstream or bidirectional traffic?
524 // if it only allows downstream traffic then access is not allowed
525 if (pAc->wmmAcTspecInfo.ts_info.direction == SME_QOS_WMM_TS_DIR_DOWNLINK)
526 {
527 return VOS_FALSE;
528 }
529
530 // we meet all of the criteria for access
531 return VOS_TRUE;
532}
533
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800534#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700535/**
536 @brief hdd_wmm_inactivity_timer_cb() - timer handler function which is
537 called for every inactivity interval per AC. This function gets the
538 current transmitted packets on the given AC, and checks if there where
539 any TX activity from the previous interval. If there was no traffic
540 then it would delete the TS that was negotiated on that AC.
541
542 @param pUserData : [in] pointer to pQosContext
543
544 @return : NONE
545*/
546void hdd_wmm_inactivity_timer_cb( v_PVOID_t pUserData )
547{
548 hdd_wmm_qos_context_t* pQosContext = (hdd_wmm_qos_context_t*)pUserData;
549 hdd_adapter_t* pAdapter;
550 hdd_wmm_ac_status_t *pAc;
551 hdd_wlan_wmm_status_e status;
552 VOS_STATUS vos_status;
553 v_U32_t currentTrafficCnt = 0;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530554 WLANTL_ACEnumType acType = 0;
555 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +0530556 hdd_context_t *pHddCtx = NULL;
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +0530557
558 ENTER();
559 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530560 {
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +0530561 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
562 "%s: Invalid VOS Context", __func__);
563 return;
564 }
565
566 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
567 if (0 != (wlan_hdd_validate_context(pHddCtx)))
568 {
569 return;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530570 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700571
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530572 mutex_lock(&pHddCtx->wmmLock);
573 if (unlikely((NULL == pQosContext) ||
574 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
575 {
Hema Aparna Medicharla8bb6f782015-03-09 12:35:05 +0530576 mutex_unlock(&pHddCtx->wmmLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530577 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
578 "%s: Invalid QoS Context",
579 __func__);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530580 return;
581 }
582 mutex_unlock(&pHddCtx->wmmLock);
583
584 acType = pQosContext->acType;
Jeff Johnson295189b2012-06-20 16:38:30 -0700585 pAdapter = pQosContext->pAdapter;
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +0530586 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
587 {
588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -0700589 FL("invalid pAdapter: %pK"), pAdapter);
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +0530590 return;
591 }
592
Jeff Johnson295189b2012-06-20 16:38:30 -0700593 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
594
595 // Get the Tx stats for this AC.
596 currentTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];
597
598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800599 FL("WMM inactivity Timer for AC=%d, currentCnt=%d, prevCnt=%d"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700600 acType, (int)currentTrafficCnt, (int)pAc->wmmPrevTrafficCnt);
601 if (pAc->wmmPrevTrafficCnt == currentTrafficCnt)
602 {
603 // If there is no traffic activity, delete the TSPEC for this AC
604 status = hdd_wmm_delts(pAdapter, pQosContext->handle);
605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
606 FL("Deleted TS on AC %d, due to inactivity with status = %d!!!"),
607 acType, status);
608 }
609 else
610 {
611 pAc->wmmPrevTrafficCnt = currentTrafficCnt;
612 if (pAc->wmmInactivityTimer.state == VOS_TIMER_STATE_STOPPED)
613 {
614 // Restart the timer
615 vos_status = vos_timer_start(&pAc->wmmInactivityTimer, pAc->wmmInactivityTime);
616 if (!VOS_IS_STATUS_SUCCESS(vos_status))
617 {
618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
619 FL("Restarting inactivity timer failed on AC %d"), acType);
620 }
621 }
622 else
623 {
624 VOS_ASSERT(vos_timer_getCurrentState(
625 &pAc->wmmInactivityTimer) == VOS_TIMER_STATE_STOPPED);
626 }
627 }
628
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +0530629 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -0700630 return;
631}
632
633
634/**
635 @brief hdd_wmm_enable_inactivity_timer() - function to enable the
636 traffic inactivity timer for the given AC, if the inactivity_interval
637 specified in the ADDTS parameters is non-zero
638
639 @param pQosContext : [in] pointer to pQosContext
640 @param inactivityTime: [in] value of the inactivity interval in millisecs
641
642 @return : VOS_STATUS_E_FAILURE
643 VOS_STATUS_SUCCESS
644*/
645VOS_STATUS hdd_wmm_enable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext, v_U32_t inactivityTime)
646{
647 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
648 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
649 WLANTL_ACEnumType acType = pQosContext->acType;
650 hdd_wmm_ac_status_t *pAc;
651
652 pAdapter = pQosContext->pAdapter;
653 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
654
655
656 // If QoS-Tspec is successfully setup and if the inactivity timer is non-zero,
657 // a traffic inactivity timer needs to be started for the given AC
658 vos_status = vos_timer_init(
659 &pAc->wmmInactivityTimer,
660 VOS_TIMER_TYPE_SW,
661 hdd_wmm_inactivity_timer_cb,
662 (v_PVOID_t)pQosContext );
663 if ( !VOS_IS_STATUS_SUCCESS(vos_status))
664 {
665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
666 FL("Initializing inactivity timer failed on AC %d"), acType);
667 return vos_status;
668 }
669
670 // Start the inactivity timer
671 vos_status = vos_timer_start(
672 &pAc->wmmInactivityTimer,
673 inactivityTime);
674 if ( !VOS_IS_STATUS_SUCCESS(vos_status))
675 {
676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
677 FL("Starting inactivity timer failed on AC %d"), acType);
678 return vos_status;
679 }
680 pAc->wmmInactivityTime = inactivityTime;
681 // Initialize the current tx traffic count on this AC
682 pAc->wmmPrevTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];
683
684 return vos_status;
685}
686
687/**
688 @brief hdd_wmm_enable_inactivity_timer() - function to disable the
689 traffic inactivity timer for the given AC. This would be called when
690 deleting the TS.
691
692 @param pQosContext : [in] pointer to pQosContext
693
694 @return : VOS_STATUS_E_FAILURE
695 VOS_STATUS_SUCCESS
696*/
697VOS_STATUS hdd_wmm_disable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext)
698{
699 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
700 WLANTL_ACEnumType acType = pQosContext->acType;
701 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
702 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
703
704 // Clear the timer and the counter
705 pAc->wmmInactivityTime = 0;
706 pAc->wmmPrevTrafficCnt = 0;
707 vos_timer_stop(&pAc->wmmInactivityTimer);
708 vos_status = vos_timer_destroy(&pAc->wmmInactivityTimer);
709
710 return vos_status;
711}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800712#endif // FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700713
714/**
715 @brief hdd_wmm_sme_callback() - callback registered by HDD with SME for receiving
716 QoS notifications. Even though this function has a static scope it gets called
717 externally through some function pointer magic (so there is a need for
718 rigorous parameter checking)
719
720 @param hHal : [in] the HAL handle
721 @param HddCtx : [in] the HDD specified handle
722 @param pCurrentQosInfo : [in] the TSPEC params
723 @param SmeStatus : [in] the QoS related SME status
724
725 @return
726 eHAL_STATUS_SUCCESS if all good, eHAL_STATUS_FAILURE otherwise
727*/
728static eHalStatus hdd_wmm_sme_callback (tHalHandle hHal,
729 void * hddCtx,
730 sme_QosWmmTspecInfo* pCurrentQosInfo,
731 sme_QosStatusType smeStatus,
732 v_U32_t qosFlowId)
733{
734 hdd_wmm_qos_context_t* pQosContext = hddCtx;
735 hdd_adapter_t* pAdapter;
736 WLANTL_ACEnumType acType;
737 hdd_wmm_ac_status_t *pAc;
738 VOS_STATUS status;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530739 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +0530740 hdd_context_t *pHddCtx = NULL;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530741
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530742 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530743 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530744 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
745 FL("pVosContext is NULL"));
746 return eHAL_STATUS_FAILURE;
747 }
748
749 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
750 if (NULL == pHddCtx)
751 {
752 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530753 FL("HddCtx is NULL"));
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530754 return eHAL_STATUS_FAILURE;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530755 }
756
Jeff Johnson295189b2012-06-20 16:38:30 -0700757
758 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -0700759 "%s: Entered, context %pK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700760 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700761
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530762 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700763 if (unlikely((NULL == pQosContext) ||
764 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
765 {
Hema Aparna Medicharla8bb6f782015-03-09 12:35:05 +0530766 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700767 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
768 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700769 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700770 return eHAL_STATUS_FAILURE;
771 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530772 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700773
774 pAdapter = pQosContext->pAdapter;
775 acType = pQosContext->acType;
776 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
777
778 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -0700779 "%s: status %d flowid %d info %pK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700780 __func__, smeStatus, qosFlowId, pCurrentQosInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -0700781
782 switch (smeStatus)
783 {
784
785 case SME_QOS_STATUS_SETUP_SUCCESS_IND:
786 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
787 "%s: Setup is complete",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700788 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700789
790 // there will always be a TSPEC returned with this status, even if
791 // a TSPEC is not exchanged OTA
792 if (pCurrentQosInfo)
793 {
794 pAc->wmmAcTspecValid = VOS_TRUE;
795 memcpy(&pAc->wmmAcTspecInfo,
796 pCurrentQosInfo,
797 sizeof(pAc->wmmAcTspecInfo));
798 }
799
800 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
801 {
802
803 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
804 "%s: Implicit Qos, notifying TL for TL AC %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700805 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700806
807 // this was triggered by implicit QoS so we know packets are pending
808 // update state
809 pAc->wmmAcAccessAllowed = VOS_TRUE;
810 pAc->wmmAcAccessGranted = VOS_TRUE;
811 pAc->wmmAcAccessPending = VOS_FALSE;
812
813 // notify TL that packets are pending
814 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
815 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
816 acType );
817
818 if ( !VOS_IS_STATUS_SUCCESS( status ) )
819 {
820 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
821 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700822 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700823 }
824 }
825 else
826 {
827 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
828 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700829 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700830
831 // this was triggered by an application
832 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
833 hdd_wmm_notify_app(pQosContext);
834 }
835
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800836#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700837 // Check if the inactivity interval is specified
Jeff Johnson8795e422013-04-03 08:59:22 -0700838 if (pCurrentQosInfo && pCurrentQosInfo->inactivity_interval) {
Jeff Johnson295189b2012-06-20 16:38:30 -0700839 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800840 "%s: Inactivity timer value = %d for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700841 __func__, pCurrentQosInfo->inactivity_interval, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700842 hdd_wmm_enable_inactivity_timer(pQosContext, pCurrentQosInfo->inactivity_interval);
843 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800844#endif // FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700845
846 // notify TL to enable trigger frames if necessary
847 hdd_wmm_enable_tl_uapsd(pQosContext);
848
849 break;
850
851 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
852 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
853 "%s: Setup is complete (U-APSD set previously)",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700854 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700855
856 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
857 {
858
859 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
860 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700861 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700862
863 // this was triggered by implicit QoS so we know packets are pending
864 // update state
865 pAc->wmmAcAccessAllowed = VOS_TRUE;
866 pAc->wmmAcAccessGranted = VOS_TRUE;
867 pAc->wmmAcAccessPending = VOS_FALSE;
868
869 // notify TL that packets are pending
870 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
871 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
872 acType );
873
874 if ( !VOS_IS_STATUS_SUCCESS( status ) )
875 {
876 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
877 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700878 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700879 }
880 }
881 else
882 {
883 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
884 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700885 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700886
887 // this was triggered by an application
888 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
889 hdd_wmm_notify_app(pQosContext);
890 }
891
892 break;
893
894 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
895 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
896 "%s: Setup failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700897 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700898 // QoS setup failed
899
900 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
901 {
902
903 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
904 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700905 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700906
907 // we note the failure, but we also mark access as allowed so that
908 // the packets will flow. Note that the MAC will "do the right thing"
909 pAc->wmmAcAccessPending = VOS_FALSE;
910 pAc->wmmAcAccessFailed = VOS_TRUE;
911 pAc->wmmAcAccessAllowed = VOS_TRUE;
912
913 // this was triggered by implicit QoS so we know packets are pending
914 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
915 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
916 acType );
917
918 if ( !VOS_IS_STATUS_SUCCESS( status ) )
919 {
920 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
921 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700922 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700923 }
924 }
925 else
926 {
927 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
928 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700929 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700930
931 // this was triggered by an application
932 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED;
933 hdd_wmm_notify_app(pQosContext);
934 }
935
Yeshwanth Sriram Guntuka7005c762019-02-20 16:37:47 +0530936#ifdef FEATURE_WLAN_ESE
937 hdd_wmm_disable_inactivity_timer(pQosContext);
938#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700939 /* Setting up QoS Failed, QoS context can be released.
940 * SME is releasing this flow information and if HDD doen't release this context,
941 * next time if application uses the same handle to set-up QoS, HDD (as it has
942 * QoS context for this handle) will issue Modify QoS request to SME but SME will
943 * reject as no it has no information for this flow.
944 */
945 hdd_wmm_free_context(pQosContext);
946 break;
947
948 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
949 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
950 "%s: Setup Invalid Params, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700951 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700952 // QoS setup failed
953
954 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
955 {
956
957 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
958 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700959 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700960
961 // we note the failure, but we also mark access as allowed so that
962 // the packets will flow. Note that the MAC will "do the right thing"
963 pAc->wmmAcAccessPending = VOS_FALSE;
964 pAc->wmmAcAccessFailed = VOS_TRUE;
965 pAc->wmmAcAccessAllowed = VOS_TRUE;
966
967 // this was triggered by implicit QoS so we know packets are pending
968 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
969 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
970 acType );
971
972 if ( !VOS_IS_STATUS_SUCCESS( status ) )
973 {
974 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
975 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700976 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700977 }
978 }
979 else
980 {
981 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
982 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700983 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700984
985 // this was triggered by an application
986 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
987 hdd_wmm_notify_app(pQosContext);
988 }
989 break;
990
991 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
992 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800993 "%s: Setup failed, not a QoS AP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700994 __func__);
Padma, Santhosh Kumardff2fb92015-12-15 19:52:17 +0530995 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
Jeff Johnson295189b2012-06-20 16:38:30 -0700996 {
997 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
998 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700999 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001000
1001 // this was triggered by an application
1002 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
1003 hdd_wmm_notify_app(pQosContext);
1004 }
1005 break;
1006
1007 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
1008 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1009 "%s: Setup pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001010 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001011 // not a callback status -- ignore if we get it
1012 break;
1013
1014 case SME_QOS_STATUS_SETUP_MODIFIED_IND:
1015 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1016 "%s: Setup modified",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001017 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001018 if (pCurrentQosInfo)
1019 {
1020 // update the TSPEC
1021 pAc->wmmAcTspecValid = VOS_TRUE;
1022 memcpy(&pAc->wmmAcTspecInfo,
1023 pCurrentQosInfo,
1024 sizeof(pAc->wmmAcTspecInfo));
1025
1026 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1027 {
1028 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1029 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001030 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001031
1032 // this was triggered by an application
1033 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFIED;
1034 hdd_wmm_notify_app(pQosContext);
1035 }
1036
1037 // need to tell TL to update its UAPSD handling
1038 hdd_wmm_enable_tl_uapsd(pQosContext);
1039 }
1040 break;
1041
1042 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1043 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
1044 {
1045
1046 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1047 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001048 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001049
1050 // this was triggered by implicit QoS so we know packets are pending
1051 pAc->wmmAcAccessPending = VOS_FALSE;
1052 pAc->wmmAcAccessGranted = VOS_TRUE;
1053 pAc->wmmAcAccessAllowed = VOS_TRUE;
1054
1055 // notify TL that packets are pending
1056 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1057 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
1058 acType );
1059
1060 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1061 {
1062 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1063 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001064 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -07001065 }
1066 }
1067 else
1068 {
1069 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1070 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001071 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001072
1073 // this was triggered by an application
1074 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
1075 hdd_wmm_notify_app(pQosContext);
1076 }
1077 break;
1078
1079 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
1080 // nothing to do for now
1081 break;
1082
1083 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED:
1084 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1085 "%s: Setup successful but U-APSD failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001086 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001087
1088 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
1089 {
1090
1091 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1092 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001093 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001094
1095 // QoS setup was successful but setting U=APSD failed
1096 // Since the OTA part of the request was successful, we don't mark
1097 // this as a failure.
1098 // the packets will flow. Note that the MAC will "do the right thing"
1099 pAc->wmmAcAccessGranted = VOS_TRUE;
1100 pAc->wmmAcAccessAllowed = VOS_TRUE;
1101 pAc->wmmAcAccessFailed = VOS_FALSE;
1102 pAc->wmmAcAccessPending = VOS_FALSE;
1103
1104 // this was triggered by implicit QoS so we know packets are pending
1105 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1106 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
1107 acType );
1108
1109 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1110 {
1111 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1112 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001113 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -07001114 }
1115 }
1116 else
1117 {
1118 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1119 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001120 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001121
1122 // this was triggered by an application
1123 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_UAPSD_SET_FAILED;
1124 hdd_wmm_notify_app(pQosContext);
1125 }
1126
1127 // Since U-APSD portion failed disabled trigger frame generation
1128 hdd_wmm_disable_tl_uapsd(pQosContext);
1129
1130 break;
1131
1132 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
1133 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1134 "%s: Release is complete",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001135 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001136
1137 if (pCurrentQosInfo)
1138 {
1139 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1140 "%s: flows still active",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001141 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001142
1143 // there is still at least one flow active for this AC
1144 // so update the AC state
1145 memcpy(&pAc->wmmAcTspecInfo,
1146 pCurrentQosInfo,
1147 sizeof(pAc->wmmAcTspecInfo));
1148
1149 // need to tell TL to update its UAPSD handling
1150 hdd_wmm_enable_tl_uapsd(pQosContext);
1151 }
1152 else
1153 {
1154 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1155 "%s: last flow",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001156 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001157
1158 // this is the last flow active for this AC so update the AC state
1159 pAc->wmmAcTspecValid = VOS_FALSE;
1160
1161 // need to tell TL to update its UAPSD handling
1162 hdd_wmm_disable_tl_uapsd(pQosContext);
1163 }
1164
1165 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1166 {
1167 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1168 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001169 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001170
1171 // this was triggered by an application
1172 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
1173 hdd_wmm_notify_app(pQosContext);
1174 }
1175
Yeshwanth Sriram Guntuka7005c762019-02-20 16:37:47 +05301176#ifdef FEATURE_WLAN_ESE
1177 hdd_wmm_disable_inactivity_timer(pQosContext);
1178#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001179 // we are done with this flow
1180 hdd_wmm_free_context(pQosContext);
1181 break;
1182
1183 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
1184 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1185 "%s: Release failure",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001186 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001187
1188 // we don't need to update our state or TL since nothing has changed
1189 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1190 {
1191 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1192 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001193 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001194
1195 // this was triggered by an application
1196 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
1197 hdd_wmm_notify_app(pQosContext);
1198 }
1199
1200 break;
1201
1202 case SME_QOS_STATUS_RELEASE_QOS_LOST_IND:
1203 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1204 "%s: QOS Lost indication received",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001205 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001206
1207 // current TSPEC is no longer valid
1208 pAc->wmmAcTspecValid = VOS_FALSE;
1209
1210 // need to tell TL to update its UAPSD handling
1211 hdd_wmm_disable_tl_uapsd(pQosContext);
1212
1213 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
1214 {
1215 // we no longer have implicit access granted
1216 pAc->wmmAcAccessGranted = VOS_FALSE;
1217 pAc->wmmAcAccessFailed = VOS_FALSE;
1218 }
1219 else
1220 {
1221 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1222 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001223 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001224
1225 // this was triggered by an application
1226 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_LOST;
1227 hdd_wmm_notify_app(pQosContext);
1228 }
1229
Yeshwanth Sriram Guntuka7005c762019-02-20 16:37:47 +05301230#ifdef FEATURE_WLAN_ESE
1231 hdd_wmm_disable_inactivity_timer(pQosContext);
1232#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001233 // we are done with this flow
1234 hdd_wmm_free_context(pQosContext);
1235 break;
1236
1237 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
1238 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1239 "%s: Release pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001240 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001241 // not a callback status -- ignore if we get it
1242 break;
1243
1244 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
1245 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1246 "%s: Release Invalid Params",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001247 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001248 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1249 {
1250 // this was triggered by an application
1251 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
1252 hdd_wmm_notify_app(pQosContext);
1253 }
1254 break;
1255
1256 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND:
1257 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1258 "%s: Modification is complete, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001259 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001260
1261 // there will always be a TSPEC returned with this status, even if
1262 // a TSPEC is not exchanged OTA
1263 if (pCurrentQosInfo)
1264 {
1265 pAc->wmmAcTspecValid = VOS_TRUE;
1266 memcpy(&pAc->wmmAcTspecInfo,
1267 pCurrentQosInfo,
1268 sizeof(pAc->wmmAcTspecInfo));
1269 }
1270
1271 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1272 {
1273 // this was triggered by an application
1274 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS;
1275 hdd_wmm_notify_app(pQosContext);
1276 }
1277
1278 // notify TL to enable trigger frames if necessary
1279 hdd_wmm_enable_tl_uapsd(pQosContext);
1280
1281 break;
1282
1283 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
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_UAPSD_EXISTING;
1288 hdd_wmm_notify_app(pQosContext);
1289 }
1290 break;
1291
1292 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
1293 // the flow modification failed so we'll leave in place
1294 // whatever existed beforehand
1295
1296 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1297 {
1298 // this was triggered by an application
1299 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
1300 hdd_wmm_notify_app(pQosContext);
1301 }
1302 break;
1303
1304 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
1305 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1306 "%s: modification pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001307 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001308 // not a callback status -- ignore if we get it
1309 break;
1310
1311 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1312 // the flow modification was successful but no QoS changes required
1313
1314 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1315 {
1316 // this was triggered by an application
1317 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
1318 hdd_wmm_notify_app(pQosContext);
1319 }
1320 break;
1321
1322 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
1323 // invalid params -- notify the application
1324 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1325 {
1326 // this was triggered by an application
1327 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
1328 hdd_wmm_notify_app(pQosContext);
1329 }
1330 break;
1331
1332 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_PENDING:
1333 // nothing to do for now. when APSD is established we'll have work to do
1334 break;
1335
1336 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED:
1337 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1338 "%s: Modify successful but U-APSD failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001339 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001340
1341 // QoS modification was successful but setting U=APSD failed.
1342 // This will always be an explicit QoS instance, so all we can
1343 // do is notify the application and let it clean up.
1344 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1345 {
1346 // this was triggered by an application
1347 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_UAPSD_SET_FAILED;
1348 hdd_wmm_notify_app(pQosContext);
1349 }
1350
1351 // Since U-APSD portion failed disabled trigger frame generation
1352 hdd_wmm_disable_tl_uapsd(pQosContext);
1353
1354 break;
1355
1356 case SME_QOS_STATUS_HANDING_OFF:
1357 // no roaming so we won't see this
1358 break;
1359
1360 case SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND:
1361 // need to tell TL to stop trigger frame generation
1362 hdd_wmm_disable_tl_uapsd(pQosContext);
1363 break;
1364
1365 case SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND:
1366 // need to tell TL to start sending trigger frames again
1367 hdd_wmm_enable_tl_uapsd(pQosContext);
1368 break;
1369
1370 default:
1371 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001372 "%s: unexpected SME Status=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001373 __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07001374 VOS_ASSERT(0);
1375 }
1376
1377 // our access to the particular access category may have changed.
1378 // some of the implicit QoS cases above may have already set this
1379 // prior to invoking TL (so that we will properly service the
1380 // Tx queues) but let's consistently handle all cases here
1381 pAc->wmmAcAccessAllowed = hdd_wmm_is_access_allowed(pAdapter, pAc);
1382
1383 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1384 "%s: complete, access for TL AC %d is%sallowed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001385 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001386 acType,
1387 pAc->wmmAcAccessAllowed ? " " : " not ");
1388
1389 return eHAL_STATUS_SUCCESS;
1390}
1391#endif
1392
Kiet Lamf040f472013-11-20 21:15:23 +05301393/**========================================================================
1394 @brief hdd_wmmps_helper() - Function to set uapsd psb dynamically
1395
1396 @param pAdapter : [in] pointer to adapter structure
1397
1398 @param ptr : [in] pointer to command buffer
1399
1400 @return : Zero on success, appropriate error on failure.
1401 =======================================================================*/
1402int hdd_wmmps_helper(hdd_adapter_t *pAdapter, tANI_U8 *ptr)
1403{
1404 if (NULL == pAdapter)
1405 {
1406 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1407 "%s: pAdapter is NULL", __func__);
1408 return -EINVAL;
1409 }
1410 if (NULL == ptr)
1411 {
1412 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1413 "%s: ptr is NULL", __func__);
1414 return -EINVAL;
1415 }
1416 /* convert ASCII to integer */
1417 pAdapter->configuredPsb = ptr[9] - '0';
1418 pAdapter->psbChanged = HDD_PSB_CHANGED;
1419
1420 return 0;
1421}
1422
Jeff Johnson295189b2012-06-20 16:38:30 -07001423/**============================================================================
1424 @brief hdd_wmm_do_implicit_qos() - Function which will attempt to setup
1425 QoS for any AC requiring it
1426
1427 @param work : [in] pointer to work structure
1428
1429 @return : void
1430 ===========================================================================*/
Mukul Sharmaec9dcc62015-02-24 18:00:04 +05301431static void __hdd_wmm_do_implicit_qos(struct work_struct *work)
Jeff Johnson295189b2012-06-20 16:38:30 -07001432{
1433 hdd_wmm_qos_context_t* pQosContext =
1434 container_of(work, hdd_wmm_qos_context_t, wmmAcSetupImplicitQos);
1435 hdd_adapter_t* pAdapter;
1436 WLANTL_ACEnumType acType;
1437 hdd_wmm_ac_status_t *pAc;
1438#ifndef WLAN_MDM_CODE_REDUCTION_OPT
1439 VOS_STATUS status;
1440 sme_QosStatusType smeStatus;
1441#endif
1442 sme_QosWmmTspecInfo qosInfo;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301443 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +05301444 hdd_context_t *pHddCtx = NULL;
Mukul Sharmaec9dcc62015-02-24 18:00:04 +05301445 int ret = 0;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301446
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301447 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301448 {
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301449 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301450 FL("pVosContext is NULL"));
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301451 return;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301452 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001453
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301454 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
1455
Mukul Sharmaec9dcc62015-02-24 18:00:04 +05301456 ret = wlan_hdd_validate_context(pHddCtx);
1457 if (0 != ret)
1458 {
1459 hddLog(LOGE, FL("HDD context is invalid"));
1460 return;
1461 }
1462
Jeff Johnson295189b2012-06-20 16:38:30 -07001463 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001464 "%s: Entered, context %pK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001465 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001466
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301467 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001468 if (unlikely(HDD_WMM_CTX_MAGIC != pQosContext->magic))
1469 {
Hema Aparna Medicharla8bb6f782015-03-09 12:35:05 +05301470 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001471 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1472 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001473 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001474 return;
1475 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301476 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001477
1478 pAdapter = pQosContext->pAdapter;
1479 acType = pQosContext->acType;
1480 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1481
1482 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001483 "%s: pAdapter %pK acType %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001484 __func__, pAdapter, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001485
1486 if (!pAc->wmmAcAccessNeeded)
1487 {
1488 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1489 "%s: AC %d doesn't need service",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001490 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001491 pQosContext->magic = 0;
1492 kfree(pQosContext);
1493 return;
1494 }
1495
1496 pAc->wmmAcAccessPending = VOS_TRUE;
1497 pAc->wmmAcAccessNeeded = VOS_FALSE;
1498
1499 memset(&qosInfo, 0, sizeof(qosInfo));
1500
Kiet Lamf040f472013-11-20 21:15:23 +05301501 qosInfo.ts_info.psb = pAdapter->configuredPsb;
1502
Jeff Johnson295189b2012-06-20 16:38:30 -07001503 switch (acType)
1504 {
1505 case WLANTL_AC_VO:
1506 qosInfo.ts_info.up = SME_QOS_WMM_UP_VO;
Kiet Lamf040f472013-11-20 21:15:23 +05301507 /* Check if there is any valid configuration from framework */
1508 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1509 {
1510 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1511 SME_QOS_UAPSD_VO) ? 1 : 0;
1512 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001513 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVo;
1514 qosInfo.ts_info.tid = 255;
1515 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVo;
1516 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVo;
1517 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv;
1518 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVo;
1519 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVo;
1520 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv;
1521 break;
1522 case WLANTL_AC_VI:
1523 qosInfo.ts_info.up = SME_QOS_WMM_UP_VI;
Kiet Lamf040f472013-11-20 21:15:23 +05301524 /* Check if there is any valid configuration from framework */
1525 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1526 {
1527 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1528 SME_QOS_UAPSD_VI) ? 1 : 0;
1529 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001530 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVi;
1531 qosInfo.ts_info.tid = 255;
1532 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVi;
1533 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVi;
1534 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv;
1535 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVi;
1536 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVi;
1537 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv;
1538 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07001539 case WLANTL_AC_BE:
1540 qosInfo.ts_info.up = SME_QOS_WMM_UP_BE;
Kiet Lamf040f472013-11-20 21:15:23 +05301541 /* Check if there is any valid configuration from framework */
1542 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1543 {
1544 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1545 SME_QOS_UAPSD_BE) ? 1 : 0;
1546 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001547 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBe;
1548 qosInfo.ts_info.tid = 255;
1549 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBe;
1550 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBe;
1551 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv;
1552 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBe;
1553 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBe;
1554 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv;
1555 break;
1556 case WLANTL_AC_BK:
1557 qosInfo.ts_info.up = SME_QOS_WMM_UP_BK;
Kiet Lamf040f472013-11-20 21:15:23 +05301558 /* Check if there is any valid configuration from framework */
1559 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1560 {
1561 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1562 SME_QOS_UAPSD_BK) ? 1 : 0;
1563 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001564 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBk;
1565 qosInfo.ts_info.tid = 255;
1566 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBk;
1567 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBk;
1568 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv;
1569 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBk;
1570 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBk;
1571 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv;
1572 break;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301573 default:
1574 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1575 "%s: Invalid AC %d", __func__, acType );
1576 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001577 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08001578#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07001579 qosInfo.inactivity_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraInactivityInterval;
1580#endif
1581 qosInfo.ts_info.burst_size_defn = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->burstSizeDefinition;
1582
1583 switch ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->tsInfoAckPolicy)
1584 {
1585 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK:
1586 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1587 break;
1588
1589 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
1590 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
1591 break;
1592
1593 default:
1594 // unknown
1595 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1596 }
1597
1598 if(qosInfo.ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK)
1599 {
1600 if(!sme_QosIsTSInfoAckPolicyValid((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter), &qosInfo, pAdapter->sessionId))
1601 {
1602 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1603 }
1604 }
1605
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301606 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001607 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301608 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001609
1610#ifndef WLAN_MDM_CODE_REDUCTION_OPT
1611 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
1612 pAdapter->sessionId,
1613 &qosInfo,
1614 hdd_wmm_sme_callback,
1615 pQosContext,
1616 qosInfo.ts_info.up,
1617 &pQosContext->qosFlowId);
1618
1619 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1620 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001621 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001622
1623 // need to check the return values and act appropriately
1624 switch (smeStatus)
1625 {
1626 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
1627 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
1628 // setup is pending, so no more work to do now.
1629 // all further work will be done in hdd_wmm_sme_callback()
1630 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1631 "%s: Setup is pending, no further work",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001632 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001633
1634 break;
1635
1636
1637 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
1638 // we can't tell the difference between when a request fails because
1639 // AP rejected it versus when SME encountered an internal error
1640
1641 // in either case SME won't ever reference this context so
1642 // free the record
1643 hdd_wmm_free_context(pQosContext);
1644
1645 // fall through and start packets flowing
1646 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1647 // no ACM in effect, no need to setup U-APSD
1648 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
1649 // no ACM in effect, U-APSD is desired but was already setup
1650
1651 // for these cases everything is already setup so we can
1652 // signal TL that it has work to do
1653 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1654 "%s: Setup is complete, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001655 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001656
1657 pAc->wmmAcAccessAllowed = VOS_TRUE;
1658 pAc->wmmAcAccessGranted = VOS_TRUE;
1659 pAc->wmmAcAccessPending = VOS_FALSE;
1660
1661 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1662 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
1663 acType );
1664
1665 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1666 {
1667 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1668 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001669 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -07001670 }
1671
1672 break;
1673
1674
1675 default:
1676 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001677 "%s: unexpected SME Status=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001678 __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07001679 VOS_ASSERT(0);
1680 }
1681#endif
1682
1683}
1684
Mukul Sharmaec9dcc62015-02-24 18:00:04 +05301685static void hdd_wmm_do_implicit_qos(struct work_struct *work)
1686{
1687 vos_ssr_protect(__func__);
1688 __hdd_wmm_do_implicit_qos( work );
1689 vos_ssr_unprotect(__func__);
1690}
1691
Jeff Johnson295189b2012-06-20 16:38:30 -07001692/**============================================================================
1693 @brief hdd_wmm_init() - Function which will initialize the WMM configuation
1694 and status to an initial state. The configuration can later be overwritten
1695 via application APIs
1696
Kumar Anand82c009f2014-05-29 00:29:42 -07001697 @param pAdapter : [in] pointer to Adapter context
Jeff Johnson295189b2012-06-20 16:38:30 -07001698
Kumar Anand82c009f2014-05-29 00:29:42 -07001699 @return : VOS_STATUS_SUCCESS if successful
Jeff Johnson295189b2012-06-20 16:38:30 -07001700 : other values if failure
1701
1702 ===========================================================================*/
Kumar Anand82c009f2014-05-29 00:29:42 -07001703VOS_STATUS hdd_wmm_init ( hdd_adapter_t *pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07001704{
Kumar Anand82c009f2014-05-29 00:29:42 -07001705 sme_QosWmmUpType* hddWmmDscpToUpMap = pAdapter->hddWmmDscpToUpMap;
Jeff Johnson295189b2012-06-20 16:38:30 -07001706 v_U8_t dscp;
1707
1708 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001709 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001710
1711 // DSCP to User Priority Lookup Table
Abhishek Ambure863e3052019-12-12 12:25:52 +05301712 for (dscp = 0; dscp <= WLAN_MAX_DSCP; dscp++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001713 {
1714 hddWmmDscpToUpMap[dscp] = SME_QOS_WMM_UP_BE;
1715 }
1716 hddWmmDscpToUpMap[8] = SME_QOS_WMM_UP_BK;
1717 hddWmmDscpToUpMap[16] = SME_QOS_WMM_UP_RESV;
1718 hddWmmDscpToUpMap[24] = SME_QOS_WMM_UP_EE;
1719 hddWmmDscpToUpMap[32] = SME_QOS_WMM_UP_CL;
1720 hddWmmDscpToUpMap[40] = SME_QOS_WMM_UP_VI;
1721 hddWmmDscpToUpMap[48] = SME_QOS_WMM_UP_VO;
1722 hddWmmDscpToUpMap[56] = SME_QOS_WMM_UP_NC;
Jeff Johnson295189b2012-06-20 16:38:30 -07001723 return VOS_STATUS_SUCCESS;
1724}
1725
1726/**============================================================================
1727 @brief hdd_wmm_adapter_init() - Function which will initialize the WMM configuation
1728 and status to an initial state. The configuration can later be overwritten
1729 via application APIs
1730
1731 @param pAdapter : [in] pointer to Adapter context
1732
1733 @return : VOS_STATUS_SUCCESS if succssful
1734 : other values if failure
1735
1736 ===========================================================================*/
1737VOS_STATUS hdd_wmm_adapter_init( hdd_adapter_t *pAdapter )
1738{
1739 hdd_wmm_ac_status_t *pAcStatus;
1740 WLANTL_ACEnumType acType;
1741
1742 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001743 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001744
1745 pAdapter->hddWmmStatus.wmmQap = VOS_FALSE;
1746 INIT_LIST_HEAD(&pAdapter->hddWmmStatus.wmmContextList);
Jeff Johnson295189b2012-06-20 16:38:30 -07001747
1748 for (acType = 0; acType < WLANTL_MAX_AC; acType++)
1749 {
1750 pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1751 pAcStatus->wmmAcAccessRequired = VOS_FALSE;
1752 pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
1753 pAcStatus->wmmAcAccessPending = VOS_FALSE;
1754 pAcStatus->wmmAcAccessFailed = VOS_FALSE;
1755 pAcStatus->wmmAcAccessGranted = VOS_FALSE;
1756 pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
1757 pAcStatus->wmmAcTspecValid = VOS_FALSE;
1758 pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
1759 }
Kiet Lamf040f472013-11-20 21:15:23 +05301760 // Invalid value(0xff) to indicate psb not configured through framework initially.
1761 pAdapter->configuredPsb = HDD_PSB_CFG_INVALID;
Jeff Johnson295189b2012-06-20 16:38:30 -07001762
1763 return VOS_STATUS_SUCCESS;
1764}
Madan Mohan Koyyalamudi70c52d32013-08-07 14:42:16 +05301765
1766/**============================================================================
1767 @brief hdd_wmm_adapter_clear() - Function which will clear the WMM status
1768 for all the ACs
1769
1770 @param pAdapter : [in] pointer to Adapter context
1771
1772 @return : VOS_STATUS_SUCCESS if succssful
1773 : other values if failure
1774
1775 ===========================================================================*/
1776VOS_STATUS hdd_wmm_adapter_clear( hdd_adapter_t *pAdapter )
1777{
1778 hdd_wmm_ac_status_t *pAcStatus;
1779 WLANTL_ACEnumType acType;
1780 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1781 "%s: Entered", __func__);
1782 for (acType = 0; acType < WLANTL_MAX_AC; acType++)
1783 {
1784 pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1785 pAcStatus->wmmAcAccessRequired = VOS_FALSE;
1786 pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
1787 pAcStatus->wmmAcAccessPending = VOS_FALSE;
1788 pAcStatus->wmmAcAccessFailed = VOS_FALSE;
1789 pAcStatus->wmmAcAccessGranted = VOS_FALSE;
1790 pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
1791 pAcStatus->wmmAcTspecValid = VOS_FALSE;
1792 pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
1793 }
1794 return VOS_STATUS_SUCCESS;
1795}
1796
Jeff Johnson295189b2012-06-20 16:38:30 -07001797/**============================================================================
1798 @brief hdd_wmm_close() - Function which will perform any necessary work to
1799 to clean up the WMM functionality prior to the kernel module unload
1800
1801 @param pAdapter : [in] pointer to adapter context
1802
1803 @return : VOS_STATUS_SUCCESS if succssful
1804 : other values if failure
1805
1806 ===========================================================================*/
1807VOS_STATUS hdd_wmm_adapter_close ( hdd_adapter_t* pAdapter )
1808{
1809 hdd_wmm_qos_context_t* pQosContext;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301810 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +05301811 hdd_context_t *pHddCtx = NULL;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301812
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301813 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301814 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301815 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1816 FL("pVosContext is NULL"));
1817 return VOS_STATUS_E_FAILURE;
1818 }
1819
1820 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
1821 if (NULL == pHddCtx)
1822 {
1823 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301824 FL("HddCtx is NULL"));
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301825 return VOS_STATUS_E_FAILURE;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301826 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001827
1828 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001829 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001830
1831 // free any context records that we still have linked
1832 while (!list_empty(&pAdapter->hddWmmStatus.wmmContextList))
1833 {
1834 pQosContext = list_first_entry(&pAdapter->hddWmmStatus.wmmContextList,
1835 hdd_wmm_qos_context_t, node);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08001836#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07001837 hdd_wmm_disable_inactivity_timer(pQosContext);
1838#endif
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301839 mutex_lock(&pHddCtx->wmmLock);
Anand N Sunkad4b25a2f2014-11-13 16:01:08 +05301840 if (pQosContext->handle == HDD_WMM_HANDLE_IMPLICIT
1841 && pQosContext->magic == HDD_WMM_CTX_MAGIC)
1842 {
1843
Anand N Sunkad860e5ea2015-03-30 14:41:51 +05301844 vos_flush_work(&pQosContext->wmmAcSetupImplicitQos);
Anand N Sunkad4b25a2f2014-11-13 16:01:08 +05301845 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301846 mutex_unlock(&pHddCtx->wmmLock);
Anand N Sunkad860e5ea2015-03-30 14:41:51 +05301847
Jeff Johnson295189b2012-06-20 16:38:30 -07001848 hdd_wmm_free_context(pQosContext);
1849 }
1850
1851 return VOS_STATUS_SUCCESS;
1852}
1853
1854/**============================================================================
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301855 @brief hdd_is_dhcp_packet() - Function which will check OS packet for
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301856 DHCP packet
1857
1858 @param skb : [in] pointer to OS packet (sk_buff)
1859 @return : VOS_TRUE if the OS packet is DHCP packet
1860 : otherwise VOS_FALSE
1861 ===========================================================================*/
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301862v_BOOL_t hdd_is_dhcp_packet(struct sk_buff *skb)
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301863{
1864 if (*((u16*)((u8*)skb->data+34)) == DHCP_SOURCE_PORT ||
1865 *((u16*)((u8*)skb->data+34)) == DHCP_DESTINATION_PORT)
1866 return VOS_TRUE;
1867
1868 return VOS_FALSE;
1869}
1870
1871/**============================================================================
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301872 @brief hdd_skb_is_eapol_or_wai_packet() - Function which will check OS packet
1873 for Eapol/Wapi packet
1874
1875 @param skb : [in] pointer to OS packet (sk_buff)
1876 @return : VOS_TRUE if the OS packet is an Eapol or a Wapi packet
1877 : otherwise VOS_FALSE
1878 ===========================================================================*/
1879v_BOOL_t hdd_skb_is_eapol_or_wai_packet(struct sk_buff *skb)
1880{
1881 if ((*((u16*)((u8*)skb->data+HDD_ETHERTYPE_802_1_X_FRAME_OFFSET))
1882 == vos_cpu_to_be16(HDD_ETHERTYPE_802_1_X))
1883#ifdef FEATURE_WLAN_WAPI
1884 || (*((u16*)((u8*)skb->data+HDD_ETHERTYPE_802_1_X_FRAME_OFFSET))
1885 == vos_cpu_to_be16(HDD_ETHERTYPE_WAI))
1886#endif
1887 )
1888 return VOS_TRUE;
1889
1890 return VOS_FALSE;
1891}
1892
1893/**============================================================================
Sravan Kumar Kairamd9ded562016-11-13 15:21:49 +05301894 @brief hdd_log_ip_addr() - Function to log IP header src and dst address
1895 @param skb : [in] pointer to OS packet (sk_buff)
1896 @return : none
1897 ===========================================================================*/
1898void hdd_log_ip_addr(struct sk_buff *skb)
1899{
1900 union generic_ethhdr *pHdr;
1901 struct iphdr *pIpHdr;
1902 unsigned char * pPkt;
1903 char *buf;
1904
1905 pPkt = skb->data;
1906 pHdr = (union generic_ethhdr *)pPkt;
1907
1908 if (pHdr->eth_II.h_proto == htons(ETH_P_IP))
1909 {
1910 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_II)];
1911
1912 buf = (char *)&pIpHdr->saddr;
1913 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1914 "%s: src addr %d:%d:%d:%d", __func__,
1915 buf[0], buf[1], buf[2], buf[3]);
1916
1917 buf = (char *)&pIpHdr->daddr;
1918 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1919 "%s: dst addr %d:%d:%d:%d", __func__,
1920 buf[0], buf[1], buf[2], buf[3]);
1921 }
1922 else if (pHdr->eth_II.h_proto == htons(ETH_P_IPV6))
1923 {
1924 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];
1925
1926 buf = (char *)&pIpHdr->saddr;
1927 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1928 "%s: src addr "IPv6_ADDR_STR, __func__, IPv6_ADDR_ARRAY(buf));
1929
1930 buf = (char *)&pIpHdr->daddr;
1931 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1932 "%s: dst addr "IPv6_ADDR_STR, __func__, IPv6_ADDR_ARRAY(buf));
1933 }
1934 else if ((ntohs(pHdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
1935 (pHdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
1936 (pHdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
1937 (pHdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL))
1938 {
1939 if (pHdr->eth_8023.h_proto == htons(ETH_P_IP))
1940 {
1941 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];
1942
1943 buf = (char *)&pIpHdr->saddr;
1944 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1945 "%s: src addr %d:%d:%d:%d", __func__,
1946 buf[0], buf[1], buf[2], buf[3]);
1947
1948 buf = (char *)&pIpHdr->daddr;
1949 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1950 "%s: dst addr %d:%d:%d:%d", __func__,
1951 buf[0], buf[1], buf[2], buf[3]);
1952 }
1953 else if (pHdr->eth_8023.h_proto == htons(ETH_P_IPV6))
1954 {
1955 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];
1956
1957 buf = (char *)&pIpHdr->saddr;
1958 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1959 "%s: src addr "IPv6_ADDR_STR, __func__, IPv6_ADDR_ARRAY(buf));
1960
1961 buf = (char *)&pIpHdr->daddr;
1962 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1963 "%s: dst addr "IPv6_ADDR_STR, __func__, IPv6_ADDR_ARRAY(buf));
1964 }
1965 }
1966}
1967
1968/**============================================================================
Sravan Kumar Kairamf9f95122017-01-18 20:54:05 +05301969 @brief hdd_get_arp_src_ip() - Function to get ARP src IP addr
1970 @param skb : [in] pointer to OS packet (sk_buff)
1971 @return : IP addr
1972 ===========================================================================*/
1973uint32_t hdd_get_arp_src_ip(struct sk_buff *skb)
1974{
1975 struct arphdr *arp;
1976 unsigned char *arp_ptr;
1977 uint32_t src_ip;
1978
1979#define ARP_HDR_SIZE ( sizeof(__be16)*3 + sizeof(unsigned char)*2 )
1980#define ARP_SENDER_HW_ADDRESS_SZ (6)
1981#define ARP_SENDER_IP_ADDRESS_SZ (4)
1982
1983 arp = (struct arphdr *)skb->data;
1984
1985 arp_ptr = (unsigned char *)arp + ARP_HDR_SIZE;
1986 arp_ptr += ARP_SENDER_HW_ADDRESS_SZ;
1987
1988 memcpy(&src_ip, arp_ptr, ARP_SENDER_IP_ADDRESS_SZ);
1989
1990 src_ip=ntohl(src_ip);
1991
1992 return src_ip;
1993
1994#undef ARP_HDR_SIZE
1995#undef ARP_SENDER_HW_ADDRESS_SZ
1996#undef ARP_SENDER_IP_ADDRESS_SZ
1997}
1998
1999/**============================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07002000 @brief hdd_wmm_classify_pkt() - Function which will classify an OS packet
2001 into a WMM AC based on either 802.1Q or DSCP
2002
2003 @param pAdapter : [in] pointer to adapter context
2004 @param skb : [in] pointer to OS packet (sk_buff)
2005 @param pAcType : [out] pointer to WMM AC type of OS packet
2006
2007 @return : None
2008 ===========================================================================*/
2009v_VOID_t hdd_wmm_classify_pkt ( hdd_adapter_t* pAdapter,
2010 struct sk_buff *skb,
2011 WLANTL_ACEnumType* pAcType,
2012 sme_QosWmmUpType *pUserPri)
2013{
2014 unsigned char * pPkt;
2015 union generic_ethhdr *pHdr;
2016 struct iphdr *pIpHdr;
2017 unsigned char tos;
2018 unsigned char dscp;
2019 sme_QosWmmUpType userPri;
2020 WLANTL_ACEnumType acType;
2021
2022 // this code is executed for every packet therefore
2023 // all debug code is kept conditional
2024
2025#ifdef HDD_WMM_DEBUG
2026 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002027 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002028#endif // HDD_WMM_DEBUG
2029
2030 pPkt = skb->data;
2031 pHdr = (union generic_ethhdr *)pPkt;
2032
2033#ifdef HDD_WMM_DEBUG
2034 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2035 "%s: proto/length is 0x%04x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002036 __func__, pHdr->eth_II.h_proto);
Jeff Johnson295189b2012-06-20 16:38:30 -07002037#endif // HDD_WMM_DEBUG
2038
2039 if (HDD_WMM_CLASSIFICATION_DSCP == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
2040 {
2041 if (pHdr->eth_II.h_proto == htons(ETH_P_IP))
2042 {
2043 // case 1: Ethernet II IP packet
2044 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_II)];
2045 tos = pIpHdr->tos;
2046#ifdef HDD_WMM_DEBUG
2047 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2048 "%s: Ethernet II IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002049 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07002050#endif // HDD_WMM_DEBUG
2051
2052 }
2053 else if ((ntohs(pHdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
2054 (pHdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
2055 (pHdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
2056 (pHdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) &&
2057 (pHdr->eth_8023.h_proto == htons(ETH_P_IP)))
2058 {
2059 // case 2: 802.3 LLC/SNAP IP packet
2060 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];
2061 tos = pIpHdr->tos;
2062#ifdef HDD_WMM_DEBUG
2063 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2064 "%s: 802.3 LLC/SNAP IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002065 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07002066#endif // HDD_WMM_DEBUG
2067 }
2068 else if (pHdr->eth_II.h_proto == htons(ETH_P_8021Q))
2069 {
2070 // VLAN tagged
2071
2072 if (pHdr->eth_IIv.h_vlan_encapsulated_proto == htons(ETH_P_IP))
2073 {
2074 // case 3: Ethernet II vlan-tagged IP packet
2075 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_IIv)];
2076 tos = pIpHdr->tos;
2077#ifdef HDD_WMM_DEBUG
2078 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2079 "%s: Ethernet II VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002080 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07002081#endif // HDD_WMM_DEBUG
2082 }
2083 else if ((ntohs(pHdr->eth_IIv.h_vlan_encapsulated_proto) < WLAN_MIN_PROTO) &&
2084 (pHdr->eth_8023v.h_snap.dsap == WLAN_SNAP_DSAP) &&
2085 (pHdr->eth_8023v.h_snap.ssap == WLAN_SNAP_SSAP) &&
2086 (pHdr->eth_8023v.h_snap.ctrl == WLAN_SNAP_CTRL) &&
2087 (pHdr->eth_8023v.h_proto == htons(ETH_P_IP)))
2088 {
2089 // case 4: 802.3 LLC/SNAP vlan-tagged IP packet
2090 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023v)];
2091 tos = pIpHdr->tos;
2092#ifdef HDD_WMM_DEBUG
2093 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2094 "%s: 802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002095 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07002096#endif // HDD_WMM_DEBUG
2097 }
2098 else
2099 {
2100 // default
2101#ifdef HDD_WMM_DEBUG
2102 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2103 "%s: VLAN tagged Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002104 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002105#endif // HDD_WMM_DEBUG
2106 tos = 0;
2107 }
2108 }
2109 else
2110 {
Hanumantha Reddy Pothulaee001fc2015-05-26 15:21:53 +05302111 v_BOOL_t toggleArpBDRates =
2112 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->toggleArpBDRates;
Jeff Johnson295189b2012-06-20 16:38:30 -07002113 // default
2114#ifdef HDD_WMM_DEBUG
2115 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2116 "%s: Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002117 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002118#endif // HDD_WMM_DEBUG
2119 //Give the highest priority to 802.1x packet
2120 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
2121 tos = 0xC0;
Sachin Ahujaf51bfac2015-09-24 21:46:16 +05302122 else if (toggleArpBDRates &&
Hanumantha Reddy Pothulaee001fc2015-05-26 15:21:53 +05302123 pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_ARP))
2124 {
2125 tos = TID3;
2126 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002127 else
2128 tos = 0;
2129 }
2130
2131 dscp = (tos>>2) & 0x3f;
Kumar Anand82c009f2014-05-29 00:29:42 -07002132 userPri = pAdapter->hddWmmDscpToUpMap[dscp];
2133
Jeff Johnson295189b2012-06-20 16:38:30 -07002134#ifdef HDD_WMM_DEBUG
2135 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2136 "%s: tos is %d, dscp is %d, up is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002137 __func__, tos, dscp, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07002138#endif // HDD_WMM_DEBUG
2139
2140 }
2141 else if (HDD_WMM_CLASSIFICATION_802_1Q == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
2142 {
2143 if (pHdr->eth_IIv.h_vlan_proto == htons(ETH_P_8021Q))
2144 {
2145 // VLAN tagged
2146 userPri = (ntohs(pHdr->eth_IIv.h_vlan_TCI)>>13) & 0x7;
2147#ifdef HDD_WMM_DEBUG
2148 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2149 "%s: Tagged frame, UP is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002150 __func__, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07002151#endif // HDD_WMM_DEBUG
2152 }
2153 else
2154 {
2155 // not VLAN tagged, use default
2156#ifdef HDD_WMM_DEBUG
2157 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2158 "%s: Untagged frame, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002159 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002160#endif // HDD_WMM_DEBUG
2161 //Give the highest priority to 802.1x packet
2162 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
2163 userPri = SME_QOS_WMM_UP_VO;
2164 else
2165 userPri = SME_QOS_WMM_UP_BE;
2166 }
2167 }
2168 else
2169 {
2170 // default
2171#ifdef HDD_WMM_DEBUG
2172 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2173 "%s: Unknown classification scheme, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002174 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002175#endif // HDD_WMM_DEBUG
2176 userPri = SME_QOS_WMM_UP_BE;
2177 }
2178
2179 acType = hddWmmUpToAcMap[userPri];
2180
2181#ifdef HDD_WMM_DEBUG
2182 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2183 "%s: UP is %d, AC is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002184 __func__, userPri, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002185#endif // HDD_WMM_DEBUG
2186
2187 *pUserPri = userPri;
2188 *pAcType = acType;
2189
2190 return;
2191}
2192
2193/**============================================================================
2194 @brief hdd_hostapd_select_quueue() - Function which will classify the packet
2195 according to linux qdisc expectation.
2196
2197
2198 @param dev : [in] pointer to net_device structure
2199 @param skb : [in] pointer to os packet
2200
2201 @return : Qdisc queue index
2202 ===========================================================================*/
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05302203v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb
2204#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
2205 , void *accel_priv
2206#endif
2207#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
2208 , select_queue_fallback_t fallbac
2209#endif
2210)
Jeff Johnson295189b2012-06-20 16:38:30 -07002211{
2212 WLANTL_ACEnumType ac;
2213 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
2214 v_USHORT_t queueIndex;
2215 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
2216 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
2217 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002218 v_U8_t STAId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302219 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2220 ptSapContext pSapCtx = NULL;
Mukul Sharmabd6b9482015-06-19 16:43:57 +05302221 int status = 0;
Mukul Sharma986109f2015-04-20 22:29:39 +05302222
Mukul Sharmabd6b9482015-06-19 16:43:57 +05302223 status = wlan_hdd_validate_context(pHddCtx);
2224 if (status !=0 )
2225 {
2226 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2227 FL("called during WDReset/unload"));
Mukul Sharma986109f2015-04-20 22:29:39 +05302228 skb->priority = SME_QOS_WMM_UP_BE;
2229 return HDD_LINUX_AC_BE;
2230 }
2231
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302232 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2233 if(pSapCtx == NULL){
Mukul Sharmabd6b9482015-06-19 16:43:57 +05302234 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302235 FL("psapCtx is NULL"));
Nirav Shah7e3c8132015-06-22 23:51:42 +05302236 STAId = HDD_WLAN_INVALID_STA_ID;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302237 goto done;
2238 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002239 /*Get the Station ID*/
Nirav Shah7e3c8132015-06-22 23:51:42 +05302240 STAId = hdd_sta_id_find_from_mac_addr(pAdapter, pDestMacAddress);
Manjeet Singh7a883622016-11-21 19:02:08 +05302241 if (STAId == HDD_WLAN_INVALID_STA_ID || STAId >= WLAN_MAX_STA_COUNT) {
Nirav Shah7e3c8132015-06-22 23:51:42 +05302242 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
2243 "%s: Failed to find right station", __func__);
2244 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07002245 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002246
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302247 spin_lock_bh( &pSapCtx->staInfo_lock );
2248 if (FALSE == vos_is_macaddr_equal(&pSapCtx->aStaInfo[STAId].macAddrSTA, pDestMacAddress))
Jeff Johnson295189b2012-06-20 16:38:30 -07002249 {
Agarwal Ashisha64c9542014-03-04 00:14:43 +05302250 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002251 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002252
Nirav Shah7e3c8132015-06-22 23:51:42 +05302253 STAId = HDD_WLAN_INVALID_STA_ID;
Jeff Johnson295189b2012-06-20 16:38:30 -07002254 goto release_lock;
2255 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302256 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 -07002257 {
2258 /* Get the user priority from IP header & corresponding AC */
2259 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05302260 //If 3/4th of Tx queue is used then place the DHCP packet in VOICE AC queue
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302261 if (pSapCtx->aStaInfo[STAId].vosLowResource && hdd_is_dhcp_packet(skb))
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05302262 {
2263 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2264 "%s: Making priority of DHCP packet as VOICE", __func__);
2265 up = SME_QOS_WMM_UP_VO;
2266 ac = hddWmmUpToAcMap[up];
2267 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002268 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002269
2270release_lock:
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302271 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07002272done:
2273 skb->priority = up;
Mukul Sharmad82cb7d2014-07-03 14:53:30 +05302274 if(skb->priority < SME_QOS_WMM_UP_MAX)
2275 queueIndex = hddLinuxUpToAcMap[skb->priority];
2276 else
2277 {
2278 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2279 "%s: up=%d is going beyond max value", __func__, up);
2280 queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
2281 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002282
2283 return queueIndex;
2284}
2285
2286/**============================================================================
2287 @brief hdd_wmm_select_quueue() - Function which will classify the packet
2288 according to linux qdisc expectation.
2289
2290
2291 @param dev : [in] pointer to net_device structure
2292 @param skb : [in] pointer to os packet
2293
2294 @return : Qdisc queue index
2295 ===========================================================================*/
2296v_U16_t hdd_wmm_select_queue(struct net_device * dev, struct sk_buff *skb)
2297{
2298 WLANTL_ACEnumType ac;
Shailender Karmuchia734f332013-04-19 14:02:48 -07002299 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002300 v_USHORT_t queueIndex;
Jeff Johnson295189b2012-06-20 16:38:30 -07002301 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma6bb6cdd2015-06-19 17:23:23 +05302302 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2303 int status = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002304
Mukul Sharma6bb6cdd2015-06-19 17:23:23 +05302305 status = wlan_hdd_validate_context(pHddCtx);
2306 if (status !=0) {
Kiet Lam40009862014-02-13 12:33:22 -08002307 skb->priority = SME_QOS_WMM_UP_BE;
2308 return HDD_LINUX_AC_BE;
2309 }
2310
Shailender Karmuchia734f332013-04-19 14:02:48 -07002311 /*Get the Station ID*/
2312 if (WLAN_HDD_IBSS == pAdapter->device_mode)
2313 {
Shailender Karmuchia734f332013-04-19 14:02:48 -07002314 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
Nirav Shah7e3c8132015-06-22 23:51:42 +05302315 v_U8_t STAId;
Shailender Karmuchia734f332013-04-19 14:02:48 -07002316
Nirav Shah7e3c8132015-06-22 23:51:42 +05302317 STAId = hdd_sta_id_find_from_mac_addr(pAdapter, pDestMacAddress);
2318 if ((STAId == HDD_WLAN_INVALID_STA_ID) &&
2319 !vos_is_macaddr_broadcast( pDestMacAddress ) &&
2320 !vos_is_macaddr_group(pDestMacAddress))
Shailender Karmuchia734f332013-04-19 14:02:48 -07002321 {
Nirav Shah7e3c8132015-06-22 23:51:42 +05302322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnsonb9fb9ce2013-05-03 08:11:02 -07002323 "%s: Failed to find right station pDestMacAddress: "
2324 MAC_ADDRESS_STR , __func__,
2325 MAC_ADDR_ARRAY(pDestMacAddress->bytes));
Nirav Shah7e3c8132015-06-22 23:51:42 +05302326 goto done;
Shailender Karmuchia734f332013-04-19 14:02:48 -07002327 }
2328 }
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302329 /* All traffic will get equal opportuniy to transmit data frames. */
2330 /* Get the user priority from IP header & corresponding AC */
2331 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302332
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302333 /* If 3/4th of BE AC Tx queue is full,
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302334 * then place the DHCP packet in VOICE AC queue.
2335 * Doing this for IBSS alone, since for STA interface
2336 * types, these packets will be queued to the new queue.
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302337 */
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302338 if ((WLAN_HDD_IBSS == pAdapter->device_mode) &&
2339 pAdapter->isVosLowResource && hdd_is_dhcp_packet(skb))
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302340 {
2341 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2342 "%s: BestEffort Tx Queue is 3/4th full"
2343 " Make DHCP packet's pri as VO", __func__);
2344 up = SME_QOS_WMM_UP_VO;
2345 ac = hddWmmUpToAcMap[up];
Jeff Johnson295189b2012-06-20 16:38:30 -07002346 }
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302347
Shailender Karmuchia734f332013-04-19 14:02:48 -07002348done:
Jeff Johnson295189b2012-06-20 16:38:30 -07002349 skb->priority = up;
Mukul Sharmad82cb7d2014-07-03 14:53:30 +05302350 if(skb->priority < SME_QOS_WMM_UP_MAX)
2351 queueIndex = hddLinuxUpToAcMap[skb->priority];
2352 else
2353 {
2354 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2355 "%s: up=%d is going beyond max value", __func__, up);
2356 queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
2357 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002358
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302359 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
2360 (hdd_is_dhcp_packet(skb) ||
2361 hdd_skb_is_eapol_or_wai_packet(skb)))
2362 {
2363 /* If the packet is a DHCP packet or a Eapol packet or
2364 * a Wapi packet, then queue it to the new queue for
2365 * STA interfaces alone.
2366 */
2367 queueIndex = WLANTL_AC_HIGH_PRIO;
2368 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2369 "%s: up=%d QIndex:%d", __func__, up, queueIndex);
2370 }
2371
Jeff Johnson295189b2012-06-20 16:38:30 -07002372 return queueIndex;
2373}
2374
Kiet Lamf040f472013-11-20 21:15:23 +05302375/**==========================================================================
2376 @brief hdd_wmm_acquire_access_required() - Function which will determine
2377 acquire admittance for a WMM AC is required or not based on psb configuration
2378 done in framework
2379
2380 @param pAdapter : [in] pointer to adapter structure
2381
2382 @param acType : [in] WMM AC type of OS packet
2383
2384 @return : void
2385 ===========================================================================*/
2386void hdd_wmm_acquire_access_required(hdd_adapter_t *pAdapter,
2387 WLANTL_ACEnumType acType)
2388{
2389/* Each bit in the LSB nibble indicates 1 AC.
2390 * Clearing the particular bit in LSB nibble to indicate
2391 * access required
2392 */
2393 switch(acType)
2394 {
2395 case WLANTL_AC_BK:
2396 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BK_CHANGED_MASK; /* clear first bit */
2397 break;
2398 case WLANTL_AC_BE:
2399 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BE_CHANGED_MASK; /* clear second bit */
2400 break;
2401 case WLANTL_AC_VI:
2402 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VI_CHANGED_MASK; /* clear third bit */
2403 break;
2404 case WLANTL_AC_VO:
2405 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VO_CHANGED_MASK; /* clear fourth bit */
2406 break;
2407 default:
2408 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2409 "%s: Invalid AC Type", __func__);
2410 break;
2411 }
2412}
2413
Jeff Johnson295189b2012-06-20 16:38:30 -07002414/**============================================================================
2415 @brief hdd_wmm_acquire_access() - Function which will attempt to acquire
2416 admittance for a WMM AC
2417
2418 @param pAdapter : [in] pointer to adapter context
2419 @param acType : [in] WMM AC type of OS packet
2420 @param pGranted : [out] pointer to boolean flag when indicates if access
2421 has been granted or not
2422
2423 @return : VOS_STATUS_SUCCESS if succssful
2424 : other values if failure
2425 ===========================================================================*/
2426VOS_STATUS hdd_wmm_acquire_access( hdd_adapter_t* pAdapter,
2427 WLANTL_ACEnumType acType,
2428 v_BOOL_t * pGranted )
2429{
2430 hdd_wmm_qos_context_t *pQosContext;
2431
2432 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002433 "%s: Entered for AC %d", __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002434
2435 if (!hdd_wmm_is_active(pAdapter) || !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
2436 {
2437 // either we don't want QoS or the AP doesn't support QoS
2438 // or we don't want to do implicit QoS
2439 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002440 "%s: QoS not configured on both ends ", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002441
2442 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2443 *pGranted = VOS_TRUE;
2444 return VOS_STATUS_SUCCESS;
2445 }
2446
2447 // do we already have an implicit QoS request pending for this AC?
2448 if ((pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded) ||
2449 (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessPending))
2450 {
2451 // request already pending so we need to wait for that response
2452 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2453 "%s: Implicit QoS for TL AC %d already scheduled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002454 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002455
2456 *pGranted = VOS_FALSE;
2457 return VOS_STATUS_SUCCESS;
2458 }
2459
2460 // did we already fail to establish implicit QoS for this AC?
2461 // (if so, access should have been granted when the failure was handled)
2462 if (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessFailed)
2463 {
2464 // request previously failed
2465 // allow access, but we'll be downgraded
2466 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2467 "%s: Implicit QoS for TL AC %d previously failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002468 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002469
2470 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2471 *pGranted = VOS_TRUE;
2472 return VOS_STATUS_SUCCESS;
2473 }
2474
2475 // we need to establish implicit QoS
2476 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07002477 "%s: Need to schedule implicit QoS for TL AC %d, pAdapter is %pK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002478 __func__, acType, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002479
2480 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded = VOS_TRUE;
2481
Mohit Khanna217ea8d2012-09-11 17:42:42 -07002482 pQosContext = kmalloc(sizeof(*pQosContext), GFP_ATOMIC);
Jeff Johnson295189b2012-06-20 16:38:30 -07002483 if (NULL == pQosContext)
2484 {
2485 // no memory for QoS context. Nothing we can do but let data flow
2486 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002487 "%s: Unable to allocate context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002488 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2489 *pGranted = VOS_TRUE;
2490 return VOS_STATUS_SUCCESS;
2491 }
2492
2493 pQosContext->acType = acType;
2494 pQosContext->pAdapter = pAdapter;
2495 pQosContext->qosFlowId = 0;
2496 pQosContext->handle = HDD_WMM_HANDLE_IMPLICIT;
2497 pQosContext->magic = HDD_WMM_CTX_MAGIC;
Anand N Sunkaddc63c792015-06-03 14:33:24 +05302498 vos_init_work(&pQosContext->wmmAcSetupImplicitQos,
Jeff Johnson295189b2012-06-20 16:38:30 -07002499 hdd_wmm_do_implicit_qos);
2500
2501 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07002502 "%s: Scheduling work for AC %d, context %pK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002503 __func__, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002504
2505 schedule_work(&pQosContext->wmmAcSetupImplicitQos);
2506
2507 // caller will need to wait until the work takes place and
2508 // TSPEC negotiation completes
2509 *pGranted = VOS_FALSE;
2510 return VOS_STATUS_SUCCESS;
2511}
2512
2513/**============================================================================
2514 @brief hdd_wmm_assoc() - Function which will handle the housekeeping
2515 required by WMM when association takes place
2516
2517 @param pAdapter : [in] pointer to adapter context
2518 @param pRoamInfo: [in] pointer to roam information
2519 @param eBssType : [in] type of BSS
2520
2521 @return : VOS_STATUS_SUCCESS if succssful
2522 : other values if failure
2523 ===========================================================================*/
2524VOS_STATUS hdd_wmm_assoc( hdd_adapter_t* pAdapter,
2525 tCsrRoamInfo *pRoamInfo,
2526 eCsrRoamBssType eBssType )
2527{
2528 tANI_U8 uapsdMask;
2529 VOS_STATUS status;
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002530 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002531
2532 // when we associate we need to notify TL if it needs to enable
2533 // UAPSD for any access categories
2534
2535 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002536 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002537
2538 if (pRoamInfo->fReassocReq)
2539 {
2540 // when we reassociate we should continue to use whatever
2541 // parameters were previously established. if we are
2542 // reassociating due to a U-APSD change for a particular
2543 // Access Category, then the change will be communicated
2544 // to HDD via the QoS callback associated with the given
2545 // flow, and U-APSD parameters will be updated there
2546
2547 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002548 "%s: Reassoc so no work, Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002549
2550 return VOS_STATUS_SUCCESS;
2551 }
2552
2553 // get the negotiated UAPSD Mask
2554 uapsdMask = pRoamInfo->u.pConnectedProfile->modifyProfileFields.uapsd_mask;
2555
2556 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002557 "%s: U-APSD mask is 0x%02x", __func__, (int) uapsdMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002558
2559 if (uapsdMask & HDD_AC_VO)
2560 {
2561 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2562 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2563 WLANTL_AC_VO,
2564 7,
2565 7,
2566 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv,
2567 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv,
2568 WLANTL_BI_DIR );
2569
2570 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2571 }
2572
2573 if (uapsdMask & HDD_AC_VI)
2574 {
2575 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2576 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2577 WLANTL_AC_VI,
2578 5,
2579 5,
2580 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv,
2581 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv,
2582 WLANTL_BI_DIR );
2583
2584 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2585 }
2586
2587 if (uapsdMask & HDD_AC_BK)
2588 {
2589 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2590 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2591 WLANTL_AC_BK,
2592 2,
2593 2,
2594 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv,
2595 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv,
2596 WLANTL_BI_DIR );
2597
2598 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2599 }
2600
2601 if (uapsdMask & HDD_AC_BE)
2602 {
2603 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2604 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2605 WLANTL_AC_BE,
2606 3,
2607 3,
2608 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv,
2609 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv,
2610 WLANTL_BI_DIR );
2611
2612 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2613 }
Kumar Anand82c009f2014-05-29 00:29:42 -07002614
2615 status = sme_UpdateDSCPtoUPMapping(pHddCtx->hHal,
2616 pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId);
2617
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002618 if (!VOS_IS_STATUS_SUCCESS( status ))
2619 {
Kumar Anand82c009f2014-05-29 00:29:42 -07002620 hdd_wmm_init( pAdapter );
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002621 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002622
2623 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002624 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002625
2626 return VOS_STATUS_SUCCESS;
2627}
2628
2629
2630
2631static const v_U8_t acmMaskBit[WLANTL_MAX_AC] =
2632 {
2633 0x4, /* WLANTL_AC_BK */
2634 0x8, /* WLANTL_AC_BE */
2635 0x2, /* WLANTL_AC_VI */
2636 0x1 /* WLANTL_AC_VO */
2637 };
2638
2639/**============================================================================
2640 @brief hdd_wmm_connect() - Function which will handle the housekeeping
2641 required by WMM when a connection is established
2642
2643 @param pAdapter : [in] pointer to adapter context
2644 @param pRoamInfo: [in] pointer to roam information
2645 @param eBssType : [in] type of BSS
2646
2647 @return : VOS_STATUS_SUCCESS if succssful
2648 : other values if failure
2649 ===========================================================================*/
2650VOS_STATUS hdd_wmm_connect( hdd_adapter_t* pAdapter,
2651 tCsrRoamInfo *pRoamInfo,
2652 eCsrRoamBssType eBssType )
2653{
2654 int ac;
2655 v_BOOL_t qap;
2656 v_BOOL_t qosConnection;
2657 v_U8_t acmMask;
2658
2659 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002660 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002661
2662 if ((eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) &&
2663 pRoamInfo &&
2664 pRoamInfo->u.pConnectedProfile)
2665 {
2666 qap = pRoamInfo->u.pConnectedProfile->qap;
2667 qosConnection = pRoamInfo->u.pConnectedProfile->qosConnection;
2668 acmMask = pRoamInfo->u.pConnectedProfile->acm_mask;
2669 }
2670 else
2671 {
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05302672 /* TODO: if a non-qos IBSS peer joins the group make qap and qosConnection false.
2673 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002674 qap = VOS_TRUE;
2675 qosConnection = VOS_TRUE;
2676 acmMask = 0x0;
2677 }
2678
2679 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2680 "%s: qap is %d, qosConnection is %d, acmMask is 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002681 __func__, qap, qosConnection, acmMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002682
2683 pAdapter->hddWmmStatus.wmmQap = qap;
2684 pAdapter->hddWmmStatus.wmmQosConnection = qosConnection;
2685
2686 for (ac = 0; ac < WLANTL_MAX_AC; ac++)
2687 {
2688 if (qap &&
2689 qosConnection &&
2690 (acmMask & acmMaskBit[ac]))
2691 {
2692 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2693 "%s: ac %d on",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002694 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002695
2696 // admission is required
2697 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_TRUE;
Padma, Santhosh Kumar73f22252015-05-05 11:59:24 +05302698 //Mark wmmAcAccessAllowed as True if implicit Qos is disabled as there
2699 //is no need to hold packets in queue during hdd_tx_fetch_packet_cbk
2700 if (!(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
2701 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed =
2702 VOS_TRUE;
2703 else
2704 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed =
2705 VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002706 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessGranted = VOS_FALSE;
Mukul Sharma74a01e52014-07-21 15:14:23 +05302707
2708 /* Making TSPEC invalid here so downgrading can be happen while roaming
2709 * It is expected this will be SET in hdd_wmm_sme_callback,once sme is
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302710 * done with the AddTspec.Here we avoid 11r and ccx based association.
2711 This change is done only when reassoc to different AP.
Mukul Sharma74a01e52014-07-21 15:14:23 +05302712 */
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2714 FL( "fReassocReq = %d"
2715#if defined (FEATURE_WLAN_ESE)
2716 "isESEAssoc = %d"
2717#endif
2718#if defined (WLAN_FEATURE_VOWIFI_11R)
2719 "is11rAssoc = %d"
2720#endif
2721 ),
2722 pRoamInfo->fReassocReq
2723#if defined (FEATURE_WLAN_ESE)
2724 ,pRoamInfo->isESEAssoc
2725#endif
2726#if defined (WLAN_FEATURE_VOWIFI_11R)
2727 ,pRoamInfo->is11rAssoc
2728#endif
2729 );
2730
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302731 if ( !pRoamInfo->fReassocReq
Mukul Sharma74a01e52014-07-21 15:14:23 +05302732#if defined (WLAN_FEATURE_VOWIFI_11R)
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302733 &&
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302734 !pRoamInfo->is11rAssoc
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302735#endif
Mukul Sharma74a01e52014-07-21 15:14:23 +05302736#if defined (FEATURE_WLAN_ESE)
2737 &&
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302738 !pRoamInfo->isESEAssoc
Mukul Sharma74a01e52014-07-21 15:14:23 +05302739#endif
2740 )
Mukul Sharma74a01e52014-07-21 15:14:23 +05302741 {
2742 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcTspecValid = VOS_FALSE;
2743 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002744 }
2745 else
2746 {
2747 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2748 "%s: ac %d off",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002749 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002750 // admission is not required so access is allowed
2751 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_FALSE;
2752 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_TRUE;
2753 }
2754
2755 }
2756
2757 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002758 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002759
2760 return VOS_STATUS_SUCCESS;
2761}
2762
2763/**============================================================================
2764 @brief hdd_wmm_get_uapsd_mask() - Function which will calculate the
2765 initial value of the UAPSD mask based upon the device configuration
2766
2767 @param pAdapter : [in] pointer to adapter context
2768 @param pUapsdMask: [in] pointer to where the UAPSD Mask is to be stored
2769
2770 @return : VOS_STATUS_SUCCESS if succssful
2771 : other values if failure
2772 ===========================================================================*/
2773VOS_STATUS hdd_wmm_get_uapsd_mask( hdd_adapter_t* pAdapter,
2774 tANI_U8 *pUapsdMask )
2775{
2776 tANI_U8 uapsdMask;
2777
2778 if (HDD_WMM_USER_MODE_NO_QOS == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
2779 {
2780 // no QOS then no UAPSD
2781 uapsdMask = 0;
2782 }
2783 else
2784 {
2785 // start with the default mask
2786 uapsdMask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
2787
2788 // disable UAPSD for any ACs with a 0 Service Interval
2789 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv == 0 )
2790 {
2791 uapsdMask &= ~HDD_AC_VO;
2792 }
2793
2794 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv == 0 )
2795 {
2796 uapsdMask &= ~HDD_AC_VI;
2797 }
2798
2799 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv == 0 )
2800 {
2801 uapsdMask &= ~HDD_AC_BK;
2802 }
2803
2804 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv == 0 )
2805 {
2806 uapsdMask &= ~HDD_AC_BE;
2807 }
2808 }
2809
2810 // return calculated mask
2811 *pUapsdMask = uapsdMask;
2812 return VOS_STATUS_SUCCESS;
2813}
2814
2815
2816/**============================================================================
2817 @brief hdd_wmm_is_active() - Function which will determine if WMM is
2818 active on the current connection
2819
2820 @param pAdapter : [in] pointer to adapter context
2821
2822 @return : VOS_TRUE if WMM is enabled
2823 : VOS_FALSE if WMM is not enabled
2824 ===========================================================================*/
2825v_BOOL_t hdd_wmm_is_active( hdd_adapter_t* pAdapter )
2826{
2827 if ((!pAdapter->hddWmmStatus.wmmQosConnection) ||
2828 (!pAdapter->hddWmmStatus.wmmQap))
2829 {
2830 return VOS_FALSE;
2831 }
2832 else
2833 {
2834 return VOS_TRUE;
2835 }
2836}
2837
2838/**============================================================================
2839 @brief hdd_wmm_addts() - Function which will add a traffic spec at the
2840 request of an application
2841
2842 @param pAdapter : [in] pointer to adapter context
2843 @param handle : [in] handle to uniquely identify a TS
2844 @param pTspec : [in] pointer to the traffic spec
2845
2846 @return : HDD_WLAN_WMM_STATUS_*
2847 ===========================================================================*/
2848hdd_wlan_wmm_status_e hdd_wmm_addts( hdd_adapter_t* pAdapter,
2849 v_U32_t handle,
2850 sme_QosWmmTspecInfo* pTspec )
2851{
2852 hdd_wmm_qos_context_t *pQosContext;
2853 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2854#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2855 sme_QosStatusType smeStatus;
2856#endif
2857 v_BOOL_t found = VOS_FALSE;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302858 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +05302859 hdd_context_t *pHddCtx = NULL;
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302860
2861 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302862 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302863 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2864 FL("pVosContext is NULL"));
2865 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302866 }
2867
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302868 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
2869 if (NULL == pHddCtx)
2870 {
2871 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2872 FL("HddCtx is NULL"));
2873 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2874 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002875
2876 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002877 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002878
2879 // see if a context already exists with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302880 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002881 list_for_each_entry(pQosContext,
2882 &pAdapter->hddWmmStatus.wmmContextList,
2883 node)
2884 {
2885 if (pQosContext->handle == handle)
2886 {
2887 found = VOS_TRUE;
2888 break;
2889 }
2890 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302891 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002892 if (found)
2893 {
2894 // record with that handle already exists
2895 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2896 "%s: Record already exists with handle 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002897 __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002898
2899 /* Application is trying to modify some of the Tspec params. Allow it */
2900 smeStatus = sme_QosModifyReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2901 pTspec,
2902 pQosContext->qosFlowId);
2903
2904 // need to check the return value and act appropriately
2905 switch (smeStatus)
2906 {
2907 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
2908 status = HDD_WLAN_WMM_STATUS_MODIFY_PENDING;
2909 break;
2910 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2911 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
2912 break;
2913 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
2914 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
2915 break;
2916 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
2917 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
2918 break;
2919 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
2920 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2921 break;
2922 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2923 status = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2924 break;
2925 default:
2926 // we didn't get back one of the SME_QOS_STATUS_MODIFY_* status codes
2927 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002928 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002929 VOS_ASSERT(0);
2930 return HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2931 }
2932
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302933 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05302934 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
2935 {
2936 pQosContext->lastStatus = status;
2937 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302938 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002939 return status;
2940 }
2941
2942 pQosContext = kmalloc(sizeof(*pQosContext), GFP_KERNEL);
2943 if (NULL == pQosContext)
2944 {
2945 // no memory for QoS context. Nothing we can do
2946 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002947 "%s: Unable to allocate QoS context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002948 return HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE;
2949 }
2950
2951 // we assume the tspec has already been validated by the caller
2952
2953 pQosContext->handle = handle;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08002954 if (pTspec->ts_info.up < HDD_WMM_UP_TO_AC_MAP_SIZE)
2955 pQosContext->acType = hddWmmUpToAcMap[pTspec->ts_info.up];
2956 else {
2957 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2958 "%s: ts_info.up (%d) larger than max value (%d), "
2959 "use default acType (%d)",
2960 __func__, pTspec->ts_info.up,
2961 HDD_WMM_UP_TO_AC_MAP_SIZE - 1, hddWmmUpToAcMap[0]);
2962 pQosContext->acType = hddWmmUpToAcMap[0];
2963 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302964
Jeff Johnson295189b2012-06-20 16:38:30 -07002965 pQosContext->pAdapter = pAdapter;
2966 pQosContext->qosFlowId = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002967
2968 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07002969 "%s: Setting up QoS, context %pK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002970 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002971
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302972 mutex_lock(&pHddCtx->wmmLock);
2973 pQosContext->magic = HDD_WMM_CTX_MAGIC;
Jeff Johnson295189b2012-06-20 16:38:30 -07002974 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302975 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002976
2977#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2978 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2979 pAdapter->sessionId,
2980 pTspec,
2981 hdd_wmm_sme_callback,
2982 pQosContext,
2983 pTspec->ts_info.up,
2984 &pQosContext->qosFlowId);
2985
2986 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2987 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002988 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002989
2990 // need to check the return value and act appropriately
2991 switch (smeStatus)
2992 {
2993 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
2994 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2995 break;
2996 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2997 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
2998 break;
2999 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
3000 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
3001 break;
3002 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
3003 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
3004 break;
3005 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
3006 hdd_wmm_free_context(pQosContext);
3007 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
3008 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
3009 // we can't tell the difference between when a request fails because
3010 // AP rejected it versus when SME encounterd an internal error
3011 hdd_wmm_free_context(pQosContext);
3012 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
3013 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
3014 hdd_wmm_free_context(pQosContext);
3015 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
3016 default:
3017 // we didn't get back one of the SME_QOS_STATUS_SETUP_* status codes
3018 hdd_wmm_free_context(pQosContext);
3019 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003020 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07003021 VOS_ASSERT(0);
3022 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
3023 }
3024#endif
3025
3026 // we were successful, save the status
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303027 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05303028 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
3029 {
3030 pQosContext->lastStatus = status;
3031 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303032 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003033
3034 return status;
3035}
3036
3037/**============================================================================
3038 @brief hdd_wmm_delts() - Function which will delete a traffic spec at the
3039 request of an application
3040
3041 @param pAdapter : [in] pointer to adapter context
3042 @param handle : [in] handle to uniquely identify a TS
3043
3044 @return : HDD_WLAN_WMM_STATUS_*
3045 ===========================================================================*/
3046hdd_wlan_wmm_status_e hdd_wmm_delts( hdd_adapter_t* pAdapter,
3047 v_U32_t handle )
3048{
3049 hdd_wmm_qos_context_t *pQosContext;
3050 v_BOOL_t found = VOS_FALSE;
3051 WLANTL_ACEnumType acType = 0;
3052 v_U32_t qosFlowId = 0;
3053 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
3054#ifndef WLAN_MDM_CODE_REDUCTION_OPT
3055 sme_QosStatusType smeStatus;
3056#endif
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303057 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +05303058 hdd_context_t *pHddCtx = NULL;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303059
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303060 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303061 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303062 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
3063 FL("pVosContext is NULL"));
3064 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
3065 }
3066
3067 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
3068 if (NULL == pHddCtx)
3069 {
3070 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303071 FL("HddCtx is NULL"));
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303072 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303073 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003074
3075 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003076 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07003077
3078 // locate the context with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303079 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003080 list_for_each_entry(pQosContext,
3081 &pAdapter->hddWmmStatus.wmmContextList,
3082 node)
3083 {
3084 if (pQosContext->handle == handle)
3085 {
3086 found = VOS_TRUE;
3087 acType = pQosContext->acType;
3088 qosFlowId = pQosContext->qosFlowId;
3089 break;
3090 }
3091 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303092 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003093
3094 if (VOS_FALSE == found)
3095 {
3096 // we didn't find the handle
3097 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003098 "%s: handle 0x%x not found", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07003099 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
3100 }
3101
3102
3103 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07003104 "%s: found handle 0x%x, flow %d, AC %d, context %pK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003105 __func__, handle, qosFlowId, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07003106
3107#ifndef WLAN_MDM_CODE_REDUCTION_OPT
3108 smeStatus = sme_QosReleaseReq( WLAN_HDD_GET_HAL_CTX(pAdapter), qosFlowId );
3109
3110 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
3111 "%s: SME flow %d released, SME status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003112 __func__, qosFlowId, smeStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07003113
3114 switch(smeStatus)
3115 {
3116 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
3117 // this flow is the only one on that AC, so go ahead and update
3118 // our TSPEC state for the AC
3119 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcTspecValid = VOS_FALSE;
3120
3121 // need to tell TL to stop trigger timer, etc
3122 hdd_wmm_disable_tl_uapsd(pQosContext);
3123
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003124#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07003125 // disable the inactivity timer
3126 hdd_wmm_disable_inactivity_timer(pQosContext);
3127#endif
3128 // we are done with this context
3129 hdd_wmm_free_context(pQosContext);
3130
3131 // SME must not fire any more callbacks for this flow since the context
3132 // is no longer valid
3133
3134 return HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
3135
3136 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
3137 // do nothing as we will get a response from SME
3138 status = HDD_WLAN_WMM_STATUS_RELEASE_PENDING;
3139 break;
3140
3141 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
3142 // nothing we can do with the existing flow except leave it
3143 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
3144 break;
3145
3146 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
3147 // nothing we can do with the existing flow except leave it
3148 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
3149
3150 default:
3151 // we didn't get back one of the SME_QOS_STATUS_RELEASE_* status codes
3152 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003153 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07003154 VOS_ASSERT(0);
3155 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
3156 }
3157
3158#endif
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303159 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05303160 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
3161 {
3162 pQosContext->lastStatus = status;
3163 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303164 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003165 return status;
3166}
3167
3168/**============================================================================
3169 @brief hdd_wmm_checkts() - Function which will return the status of a traffic
3170 spec at the request of an application
3171
3172 @param pAdapter : [in] pointer to adapter context
3173 @param handle : [in] handle to uniquely identify a TS
3174
3175 @return : HDD_WLAN_WMM_STATUS_*
3176 ===========================================================================*/
3177hdd_wlan_wmm_status_e hdd_wmm_checkts( hdd_adapter_t* pAdapter,
3178 v_U32_t handle )
3179{
3180 hdd_wmm_qos_context_t *pQosContext;
3181 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303182 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +05303183 hdd_context_t *pHddCtx = NULL;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303184
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303185 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303186 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303187 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
3188 FL("pVosContext is NULL"));
3189 return HDD_WLAN_WMM_STATUS_LOST;
3190 }
3191
3192 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
3193 if (NULL == pHddCtx)
3194 {
3195 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303196 FL("HddCtx is NULL"));
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303197 return HDD_WLAN_WMM_STATUS_LOST;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303198 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003199
3200 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003201 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07003202
3203 // locate the context with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303204 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003205 list_for_each_entry(pQosContext,
3206 &pAdapter->hddWmmStatus.wmmContextList,
3207 node)
3208 {
3209 if (pQosContext->handle == handle)
3210 {
3211 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07003212 "%s: found handle 0x%x, context %pK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003213 __func__, handle, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07003214
3215 status = pQosContext->lastStatus;
3216 break;
3217 }
3218 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303219 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003220 return status;
3221}