blob: b91f0c8407fa10b7f343dfb8cbd78c5ecb74a0cd [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
87
Jeff Johnson295189b2012-06-20 16:38:30 -070088#define WLAN_HDD_MAX_DSCP 0x3f
89
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +053090// DHCP Port number
91#define DHCP_SOURCE_PORT 0x4400
92#define DHCP_DESTINATION_PORT 0x4300
93
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080094#define HDD_WMM_UP_TO_AC_MAP_SIZE 8
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -070095
Sravan Kumar Kairamd9ded562016-11-13 15:21:49 +053096#define IPv6_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5],\
97 (a)[6], (a)[7], (a)[8], (a)[9], (a)[10], (a)[11], (a)[12], (a)[13],\
98 (a)[14], (a)[15]
99#define IPv6_ADDR_STR "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:"\
100 "%02x%02x:%02x%02x"
101
Jeff Johnson295189b2012-06-20 16:38:30 -0700102const v_U8_t hddWmmUpToAcMap[] = {
103 WLANTL_AC_BE,
104 WLANTL_AC_BK,
105 WLANTL_AC_BK,
106 WLANTL_AC_BE,
107 WLANTL_AC_VI,
108 WLANTL_AC_VI,
109 WLANTL_AC_VO,
110 WLANTL_AC_VO
111};
112
113//Linux based UP -> AC Mapping
114const v_U8_t hddLinuxUpToAcMap[8] = {
115 HDD_LINUX_AC_BE,
116 HDD_LINUX_AC_BK,
117 HDD_LINUX_AC_BK,
118 HDD_LINUX_AC_BE,
119 HDD_LINUX_AC_VI,
120 HDD_LINUX_AC_VI,
121 HDD_LINUX_AC_VO,
122 HDD_LINUX_AC_VO
123};
124
125#ifndef WLAN_MDM_CODE_REDUCTION_OPT
126/**
127 @brief hdd_wmm_enable_tl_uapsd() - function which decides whether and
128 how to update UAPSD parameters in TL
129
130 @param pQosContext : [in] the pointer the QoS instance control block
131
132 @return
133 None
134*/
135static void hdd_wmm_enable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
136{
137 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
138 WLANTL_ACEnumType acType = pQosContext->acType;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530139 hdd_wmm_ac_status_t *pAc = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700140 VOS_STATUS status;
141 v_U32_t service_interval;
142 v_U32_t suspension_interval;
143 sme_QosWmmDirType direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530144 v_BOOL_t psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700145
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530146 if (acType >= WLANTL_MAX_AC)
147 {
148 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
149 "%s: Invalid AC: %d", __func__, acType);
150 return;
151 }
152
153 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
Jeff Johnson295189b2012-06-20 16:38:30 -0700154
155 // The TSPEC must be valid
156 if (pAc->wmmAcTspecValid == VOS_FALSE)
157 {
158 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
159 "%s: Invoked with invalid TSPEC",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700160 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700161 return;
162 }
163
164 // determine the service interval
165 if (pAc->wmmAcTspecInfo.min_service_interval)
166 {
167 service_interval = pAc->wmmAcTspecInfo.min_service_interval;
168 }
169 else if (pAc->wmmAcTspecInfo.max_service_interval)
170 {
171 service_interval = pAc->wmmAcTspecInfo.max_service_interval;
172 }
173 else
174 {
175 // no service interval is present in the TSPEC
176 // this is OK, there just won't be U-APSD
177 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
178 "%s: No service interval supplied",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700179 __func__);
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530180 service_interval = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700181 }
182
183 // determine the suspension interval & direction
184 suspension_interval = pAc->wmmAcTspecInfo.suspension_interval;
185 direction = pAc->wmmAcTspecInfo.ts_info.direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530186 psb = pAc->wmmAcTspecInfo.ts_info.psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700187
188 // if we have previously enabled U-APSD, have any params changed?
189 if ((pAc->wmmAcUapsdInfoValid) &&
190 (pAc->wmmAcUapsdServiceInterval == service_interval) &&
191 (pAc->wmmAcUapsdSuspensionInterval == suspension_interval) &&
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530192 (pAc->wmmAcUapsdDirection == direction) &&
193 (pAc->wmmAcIsUapsdEnabled == psb))
Jeff Johnson295189b2012-06-20 16:38:30 -0700194 {
195 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
196 "%s: No change in U-APSD parameters",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700197 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700198 return;
199 }
200
201 // are we in the appropriate power save modes?
202 if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_BEACON_MODE_POWER_SAVE))
203 {
204 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
205 "%s: BMPS is not enabled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700206 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700207 return;
208 }
209
210 if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_UAPSD_MODE_POWER_SAVE))
211 {
212 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
213 "%s: U-APSD is not enabled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700214 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700215 return;
216 }
217
218 // everything is in place to notify TL
219 status = WLANTL_EnableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
220 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
221 acType,
222 pAc->wmmAcTspecInfo.ts_info.tid,
223 pAc->wmmAcTspecInfo.ts_info.up,
224 service_interval,
225 suspension_interval,
226 direction);
227
228 if ( !VOS_IS_STATUS_SUCCESS( status ) )
229 {
230 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
231 "%s: Failed to enable U-APSD for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700232 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700233 return;
234 }
235
236 // stash away the parameters that were used
237 pAc->wmmAcUapsdInfoValid = VOS_TRUE;
238 pAc->wmmAcUapsdServiceInterval = service_interval;
239 pAc->wmmAcUapsdSuspensionInterval = suspension_interval;
240 pAc->wmmAcUapsdDirection = direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530241 pAc->wmmAcIsUapsdEnabled = psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700242
243 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700244 "%s: Enabled UAPSD in TL srv_int=%d "
245 "susp_int=%d dir=%d AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700246 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700247 service_interval,
248 suspension_interval,
249 direction,
250 acType);
251
252}
253
254/**
255 @brief hdd_wmm_disable_tl_uapsd() - function which decides whether
256 to disable UAPSD parameters in TL
257
258 @param pQosContext : [in] the pointer the QoS instance control block
259
260 @return
261 None
262*/
263static void hdd_wmm_disable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
264{
265 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
266 WLANTL_ACEnumType acType = pQosContext->acType;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530267 hdd_wmm_ac_status_t *pAc = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700268 VOS_STATUS status;
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530269 v_U32_t service_interval;
270 v_U32_t suspension_interval;
271 v_U8_t uapsd_mask;
272 v_U8_t ActiveTspec = INVALID_TSPEC;
Jeff Johnson295189b2012-06-20 16:38:30 -0700273
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530274 if (acType >= WLANTL_MAX_AC)
275 {
276 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
277 "%s: Invalid AC: %d", __func__, acType);
278 return;
279 }
280
281 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
282
Jeff Johnson295189b2012-06-20 16:38:30 -0700283 // have we previously enabled UAPSD?
284 if (pAc->wmmAcUapsdInfoValid == VOS_TRUE)
285 {
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530286 uapsd_mask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
Jeff Johnson295189b2012-06-20 16:38:30 -0700287
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530288 //Finding uapsd_mask as per AC
289 uapsd_mask = uapsd_mask & (1 << (WLANTL_AC_VO - acType));
290
291 sme_QosTspecActive((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter), acType,
292 pAdapter->sessionId, &ActiveTspec);
293
294 //Call WLANTL_EnableUAPSDForAC only when static uapsd mask is present and
295 // no active tspecs. TODO: Need to change naming convention as Enable
296 // UAPSD function is called in hdd_wmm_disable_tl_uapsd. Purpose of
297 // calling WLANTL_EnableUAPSDForAC is to update UAPSD intervals to fw
298
299 if(uapsd_mask && !ActiveTspec)
Jeff Johnson295189b2012-06-20 16:38:30 -0700300 {
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530301 switch(acType)
302 {
303 case WLANTL_AC_VO:
304 service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv;
305 suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv;
306 break;
307 case WLANTL_AC_VI:
308 service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv;
309 suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv;
310 break;
311 case WLANTL_AC_BE:
312 service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv;
313 suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv;
314 break;
315 case WLANTL_AC_BK:
316 service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv;
317 suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv;
318 break;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530319 default:
320 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
321 "%s: Invalid AC %d", __func__, acType );
322 return;
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530323 }
324
325 status = WLANTL_EnableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
326 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
327 acType,
328 pAc->wmmAcTspecInfo.ts_info.tid,
329 pAc->wmmAcTspecInfo.ts_info.up,
330 service_interval,
331 suspension_interval,
332 pAc->wmmAcTspecInfo.ts_info.direction);
333
334 if ( !VOS_IS_STATUS_SUCCESS( status ) )
335 {
336 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
337 "%s: Failed to update U-APSD params for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700338 __func__, acType );
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530339 }
340 else
341 {
342 // TL no longer has valid UAPSD info
343 pAc->wmmAcUapsdInfoValid = VOS_FALSE;
344 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
345 "%s: Updated UAPSD params in TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700346 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700347 acType);
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530348 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700349 }
350 }
351}
352
353#endif
354
355/**
356 @brief hdd_wmm_free_context() - function which frees a QoS context
357
358 @param pQosContext : [in] the pointer the QoS instance control block
359
360 @return
361 None
362*/
363static void hdd_wmm_free_context (hdd_wmm_qos_context_t* pQosContext)
364{
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530365 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +0530366 hdd_context_t *pHddCtx = NULL;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530367
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530368 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530369 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530370 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
371 FL("pVosContext is NULL"));
372 return;
373 }
374
375 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
376 if (NULL == pHddCtx)
377 {
378 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
379 FL("HddCtx is NULL"));
380 return;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530381 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700382
383 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
384 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700385 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700386
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530387 // take the wmmLock since we're manipulating the context list
388 mutex_lock(&pHddCtx->wmmLock);
389
Jeff Johnson295189b2012-06-20 16:38:30 -0700390 if (unlikely((NULL == pQosContext) ||
391 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
392 {
393 // must have been freed in another thread
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530394 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700395 return;
396 }
397
Jeff Johnson295189b2012-06-20 16:38:30 -0700398 // make sure nobody thinks this is a valid context
399 pQosContext->magic = 0;
400
401 // unlink the context
402 list_del(&pQosContext->node);
403
404 // done manipulating the list
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530405 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700406
407 // reclaim memory
408 kfree(pQosContext);
409
410}
411
412#ifndef WLAN_MDM_CODE_REDUCTION_OPT
413/**
414 @brief hdd_wmm_notify_app() - function which notifies an application
415 changes in state of it flow
416
417 @param pQosContext : [in] the pointer the QoS instance control block
418
419 @return
420 None
421*/
422#define MAX_NOTIFY_LEN 50
423static void hdd_wmm_notify_app (hdd_wmm_qos_context_t* pQosContext)
424{
425 hdd_adapter_t* pAdapter;
426 union iwreq_data wrqu;
427 char buf[MAX_NOTIFY_LEN+1];
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530428 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +0530429 hdd_context_t *pHddCtx = NULL;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530430
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530431 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530432 {
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530433 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530434 FL("pVosContext is NULL"));
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530435 return;
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530436 }
437
438 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
439 if (NULL == pHddCtx)
440 {
441 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
442 FL("HddCtx is NULL"));
443 return;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530444 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700445
446 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
447 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700448 __func__, pQosContext);
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530449
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530450 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700451 if (unlikely((NULL == pQosContext) ||
452 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
453 {
Hema Aparna Medicharla8bb6f782015-03-09 12:35:05 +0530454 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700455 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
456 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700457 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700458 return;
459 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530460 // get pointer to the adapter
461 pAdapter = pQosContext->pAdapter;
462 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700463
464 // create the event
465 memset(&wrqu, 0, sizeof(wrqu));
466 memset(buf, 0, sizeof(buf));
467
468 snprintf(buf, MAX_NOTIFY_LEN, "QCOM: TS change[%u: %u]",
469 (unsigned int)pQosContext->handle,
470 (unsigned int)pQosContext->lastStatus);
471
472 wrqu.data.pointer = buf;
473 wrqu.data.length = strlen(buf);
474
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530475
Jeff Johnson295189b2012-06-20 16:38:30 -0700476
477 // send the event
478 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700479 "%s: Sending [%s]", __func__, buf);
Jeff Johnson295189b2012-06-20 16:38:30 -0700480 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
481}
482
483
484/**
485 @brief hdd_wmm_is_access_allowed() - function which determines if access
486 is allowed for the given AC. this is designed to be called during SME
487 callback processing since that is when access can be granted or removed
488
489 @param pAdapter : [in] pointer to adapter context
490 @param pAc : [in] pointer to the per-AC status
491
492 @return : VOS_TRUE - access is allowed
493 : VOS_FALSE - access is not allowed
494 None
495*/
496static v_BOOL_t hdd_wmm_is_access_allowed(hdd_adapter_t* pAdapter,
497 hdd_wmm_ac_status_t* pAc)
498{
499 // if we don't want QoS or the AP doesn't support QoS
500 // or we don't want to do implicit QoS
501 // or if AP doesn't require admission for this AC
502 // then we have access
503 if (!hdd_wmm_is_active(pAdapter) ||
504 !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled ||
505 !pAc->wmmAcAccessRequired)
506 {
507 return VOS_TRUE;
508 }
509
510 // if implicit QoS has already completed, successfully or not,
511 // then access is allowed
512 if (pAc->wmmAcAccessGranted || pAc->wmmAcAccessFailed)
513 {
514 return VOS_TRUE;
515 }
516
517 // admission is required and implicit QoS hasn't completed
518 // however explicit QoS may have completed and we'll have
519 // a Tspec
520 // if we don't have a Tspec then access is not allowed
521 if (!pAc->wmmAcTspecValid)
522 {
523 return VOS_FALSE;
524 }
525
526 // we have a Tspec -- does it allow upstream or bidirectional traffic?
527 // if it only allows downstream traffic then access is not allowed
528 if (pAc->wmmAcTspecInfo.ts_info.direction == SME_QOS_WMM_TS_DIR_DOWNLINK)
529 {
530 return VOS_FALSE;
531 }
532
533 // we meet all of the criteria for access
534 return VOS_TRUE;
535}
536
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800537#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700538/**
539 @brief hdd_wmm_inactivity_timer_cb() - timer handler function which is
540 called for every inactivity interval per AC. This function gets the
541 current transmitted packets on the given AC, and checks if there where
542 any TX activity from the previous interval. If there was no traffic
543 then it would delete the TS that was negotiated on that AC.
544
545 @param pUserData : [in] pointer to pQosContext
546
547 @return : NONE
548*/
549void hdd_wmm_inactivity_timer_cb( v_PVOID_t pUserData )
550{
551 hdd_wmm_qos_context_t* pQosContext = (hdd_wmm_qos_context_t*)pUserData;
552 hdd_adapter_t* pAdapter;
553 hdd_wmm_ac_status_t *pAc;
554 hdd_wlan_wmm_status_e status;
555 VOS_STATUS vos_status;
556 v_U32_t currentTrafficCnt = 0;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530557 WLANTL_ACEnumType acType = 0;
558 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +0530559 hdd_context_t *pHddCtx = NULL;
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +0530560
561 ENTER();
562 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530563 {
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +0530564 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
565 "%s: Invalid VOS Context", __func__);
566 return;
567 }
568
569 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
570 if (0 != (wlan_hdd_validate_context(pHddCtx)))
571 {
572 return;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530573 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700574
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530575 mutex_lock(&pHddCtx->wmmLock);
576 if (unlikely((NULL == pQosContext) ||
577 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
578 {
Hema Aparna Medicharla8bb6f782015-03-09 12:35:05 +0530579 mutex_unlock(&pHddCtx->wmmLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530580 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
581 "%s: Invalid QoS Context",
582 __func__);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530583 return;
584 }
585 mutex_unlock(&pHddCtx->wmmLock);
586
587 acType = pQosContext->acType;
Jeff Johnson295189b2012-06-20 16:38:30 -0700588 pAdapter = pQosContext->pAdapter;
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +0530589 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
590 {
591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
592 FL("invalid pAdapter: %p"), pAdapter);
593 return;
594 }
595
Jeff Johnson295189b2012-06-20 16:38:30 -0700596 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
597
598 // Get the Tx stats for this AC.
599 currentTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];
600
601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800602 FL("WMM inactivity Timer for AC=%d, currentCnt=%d, prevCnt=%d"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700603 acType, (int)currentTrafficCnt, (int)pAc->wmmPrevTrafficCnt);
604 if (pAc->wmmPrevTrafficCnt == currentTrafficCnt)
605 {
606 // If there is no traffic activity, delete the TSPEC for this AC
607 status = hdd_wmm_delts(pAdapter, pQosContext->handle);
608 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
609 FL("Deleted TS on AC %d, due to inactivity with status = %d!!!"),
610 acType, status);
611 }
612 else
613 {
614 pAc->wmmPrevTrafficCnt = currentTrafficCnt;
615 if (pAc->wmmInactivityTimer.state == VOS_TIMER_STATE_STOPPED)
616 {
617 // Restart the timer
618 vos_status = vos_timer_start(&pAc->wmmInactivityTimer, pAc->wmmInactivityTime);
619 if (!VOS_IS_STATUS_SUCCESS(vos_status))
620 {
621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
622 FL("Restarting inactivity timer failed on AC %d"), acType);
623 }
624 }
625 else
626 {
627 VOS_ASSERT(vos_timer_getCurrentState(
628 &pAc->wmmInactivityTimer) == VOS_TIMER_STATE_STOPPED);
629 }
630 }
631
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +0530632 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -0700633 return;
634}
635
636
637/**
638 @brief hdd_wmm_enable_inactivity_timer() - function to enable the
639 traffic inactivity timer for the given AC, if the inactivity_interval
640 specified in the ADDTS parameters is non-zero
641
642 @param pQosContext : [in] pointer to pQosContext
643 @param inactivityTime: [in] value of the inactivity interval in millisecs
644
645 @return : VOS_STATUS_E_FAILURE
646 VOS_STATUS_SUCCESS
647*/
648VOS_STATUS hdd_wmm_enable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext, v_U32_t inactivityTime)
649{
650 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
651 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
652 WLANTL_ACEnumType acType = pQosContext->acType;
653 hdd_wmm_ac_status_t *pAc;
654
655 pAdapter = pQosContext->pAdapter;
656 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
657
658
659 // If QoS-Tspec is successfully setup and if the inactivity timer is non-zero,
660 // a traffic inactivity timer needs to be started for the given AC
661 vos_status = vos_timer_init(
662 &pAc->wmmInactivityTimer,
663 VOS_TIMER_TYPE_SW,
664 hdd_wmm_inactivity_timer_cb,
665 (v_PVOID_t)pQosContext );
666 if ( !VOS_IS_STATUS_SUCCESS(vos_status))
667 {
668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
669 FL("Initializing inactivity timer failed on AC %d"), acType);
670 return vos_status;
671 }
672
673 // Start the inactivity timer
674 vos_status = vos_timer_start(
675 &pAc->wmmInactivityTimer,
676 inactivityTime);
677 if ( !VOS_IS_STATUS_SUCCESS(vos_status))
678 {
679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
680 FL("Starting inactivity timer failed on AC %d"), acType);
681 return vos_status;
682 }
683 pAc->wmmInactivityTime = inactivityTime;
684 // Initialize the current tx traffic count on this AC
685 pAc->wmmPrevTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];
686
687 return vos_status;
688}
689
690/**
691 @brief hdd_wmm_enable_inactivity_timer() - function to disable the
692 traffic inactivity timer for the given AC. This would be called when
693 deleting the TS.
694
695 @param pQosContext : [in] pointer to pQosContext
696
697 @return : VOS_STATUS_E_FAILURE
698 VOS_STATUS_SUCCESS
699*/
700VOS_STATUS hdd_wmm_disable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext)
701{
702 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
703 WLANTL_ACEnumType acType = pQosContext->acType;
704 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
705 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
706
707 // Clear the timer and the counter
708 pAc->wmmInactivityTime = 0;
709 pAc->wmmPrevTrafficCnt = 0;
710 vos_timer_stop(&pAc->wmmInactivityTimer);
711 vos_status = vos_timer_destroy(&pAc->wmmInactivityTimer);
712
713 return vos_status;
714}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800715#endif // FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700716
717/**
718 @brief hdd_wmm_sme_callback() - callback registered by HDD with SME for receiving
719 QoS notifications. Even though this function has a static scope it gets called
720 externally through some function pointer magic (so there is a need for
721 rigorous parameter checking)
722
723 @param hHal : [in] the HAL handle
724 @param HddCtx : [in] the HDD specified handle
725 @param pCurrentQosInfo : [in] the TSPEC params
726 @param SmeStatus : [in] the QoS related SME status
727
728 @return
729 eHAL_STATUS_SUCCESS if all good, eHAL_STATUS_FAILURE otherwise
730*/
731static eHalStatus hdd_wmm_sme_callback (tHalHandle hHal,
732 void * hddCtx,
733 sme_QosWmmTspecInfo* pCurrentQosInfo,
734 sme_QosStatusType smeStatus,
735 v_U32_t qosFlowId)
736{
737 hdd_wmm_qos_context_t* pQosContext = hddCtx;
738 hdd_adapter_t* pAdapter;
739 WLANTL_ACEnumType acType;
740 hdd_wmm_ac_status_t *pAc;
741 VOS_STATUS status;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530742 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +0530743 hdd_context_t *pHddCtx = NULL;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530744
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530745 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530746 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530747 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
748 FL("pVosContext is NULL"));
749 return eHAL_STATUS_FAILURE;
750 }
751
752 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
753 if (NULL == pHddCtx)
754 {
755 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530756 FL("HddCtx is NULL"));
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +0530757 return eHAL_STATUS_FAILURE;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530758 }
759
Jeff Johnson295189b2012-06-20 16:38:30 -0700760
761 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
762 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700763 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700764
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530765 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700766 if (unlikely((NULL == pQosContext) ||
767 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
768 {
Hema Aparna Medicharla8bb6f782015-03-09 12:35:05 +0530769 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700770 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
771 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700772 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700773 return eHAL_STATUS_FAILURE;
774 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +0530775 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700776
777 pAdapter = pQosContext->pAdapter;
778 acType = pQosContext->acType;
779 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
780
781 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
782 "%s: status %d flowid %d info %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700783 __func__, smeStatus, qosFlowId, pCurrentQosInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -0700784
785 switch (smeStatus)
786 {
787
788 case SME_QOS_STATUS_SETUP_SUCCESS_IND:
789 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
790 "%s: Setup is complete",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700791 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700792
793 // there will always be a TSPEC returned with this status, even if
794 // a TSPEC is not exchanged OTA
795 if (pCurrentQosInfo)
796 {
797 pAc->wmmAcTspecValid = VOS_TRUE;
798 memcpy(&pAc->wmmAcTspecInfo,
799 pCurrentQosInfo,
800 sizeof(pAc->wmmAcTspecInfo));
801 }
802
803 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
804 {
805
806 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
807 "%s: Implicit Qos, notifying TL for TL AC %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700808 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700809
810 // this was triggered by implicit QoS so we know packets are pending
811 // update state
812 pAc->wmmAcAccessAllowed = VOS_TRUE;
813 pAc->wmmAcAccessGranted = VOS_TRUE;
814 pAc->wmmAcAccessPending = VOS_FALSE;
815
816 // notify TL that packets are pending
817 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
818 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
819 acType );
820
821 if ( !VOS_IS_STATUS_SUCCESS( status ) )
822 {
823 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
824 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700825 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700826 }
827 }
828 else
829 {
830 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
831 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700832 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700833
834 // this was triggered by an application
835 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
836 hdd_wmm_notify_app(pQosContext);
837 }
838
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800839#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700840 // Check if the inactivity interval is specified
Jeff Johnson8795e422013-04-03 08:59:22 -0700841 if (pCurrentQosInfo && pCurrentQosInfo->inactivity_interval) {
Jeff Johnson295189b2012-06-20 16:38:30 -0700842 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800843 "%s: Inactivity timer value = %d for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700844 __func__, pCurrentQosInfo->inactivity_interval, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700845 hdd_wmm_enable_inactivity_timer(pQosContext, pCurrentQosInfo->inactivity_interval);
846 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800847#endif // FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700848
849 // notify TL to enable trigger frames if necessary
850 hdd_wmm_enable_tl_uapsd(pQosContext);
851
852 break;
853
854 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
855 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
856 "%s: Setup is complete (U-APSD set previously)",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700857 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700858
859 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
860 {
861
862 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
863 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700864 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700865
866 // this was triggered by implicit QoS so we know packets are pending
867 // update state
868 pAc->wmmAcAccessAllowed = VOS_TRUE;
869 pAc->wmmAcAccessGranted = VOS_TRUE;
870 pAc->wmmAcAccessPending = VOS_FALSE;
871
872 // notify TL that packets are pending
873 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
874 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
875 acType );
876
877 if ( !VOS_IS_STATUS_SUCCESS( status ) )
878 {
879 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
880 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700881 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700882 }
883 }
884 else
885 {
886 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
887 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700888 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700889
890 // this was triggered by an application
891 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
892 hdd_wmm_notify_app(pQosContext);
893 }
894
895 break;
896
897 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
898 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
899 "%s: Setup failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700900 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700901 // QoS setup failed
902
903 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
904 {
905
906 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
907 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700908 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700909
910 // we note the failure, but we also mark access as allowed so that
911 // the packets will flow. Note that the MAC will "do the right thing"
912 pAc->wmmAcAccessPending = VOS_FALSE;
913 pAc->wmmAcAccessFailed = VOS_TRUE;
914 pAc->wmmAcAccessAllowed = VOS_TRUE;
915
916 // this was triggered by implicit QoS so we know packets are pending
917 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
918 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
919 acType );
920
921 if ( !VOS_IS_STATUS_SUCCESS( status ) )
922 {
923 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
924 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700925 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700926 }
927 }
928 else
929 {
930 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
931 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700932 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700933
934 // this was triggered by an application
935 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED;
936 hdd_wmm_notify_app(pQosContext);
937 }
938
939 /* 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
1176 // we are done with this flow
1177 hdd_wmm_free_context(pQosContext);
1178 break;
1179
1180 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
1181 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1182 "%s: Release failure",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001183 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001184
1185 // we don't need to update our state or TL since nothing has changed
1186 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1187 {
1188 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1189 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001190 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001191
1192 // this was triggered by an application
1193 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
1194 hdd_wmm_notify_app(pQosContext);
1195 }
1196
1197 break;
1198
1199 case SME_QOS_STATUS_RELEASE_QOS_LOST_IND:
1200 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1201 "%s: QOS Lost indication received",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001202 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001203
1204 // current TSPEC is no longer valid
1205 pAc->wmmAcTspecValid = VOS_FALSE;
1206
1207 // need to tell TL to update its UAPSD handling
1208 hdd_wmm_disable_tl_uapsd(pQosContext);
1209
1210 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
1211 {
1212 // we no longer have implicit access granted
1213 pAc->wmmAcAccessGranted = VOS_FALSE;
1214 pAc->wmmAcAccessFailed = VOS_FALSE;
1215 }
1216 else
1217 {
1218 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1219 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001220 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001221
1222 // this was triggered by an application
1223 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_LOST;
1224 hdd_wmm_notify_app(pQosContext);
1225 }
1226
1227 // we are done with this flow
1228 hdd_wmm_free_context(pQosContext);
1229 break;
1230
1231 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
1232 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1233 "%s: Release pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001234 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001235 // not a callback status -- ignore if we get it
1236 break;
1237
1238 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
1239 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1240 "%s: Release Invalid Params",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001241 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001242 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1243 {
1244 // this was triggered by an application
1245 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
1246 hdd_wmm_notify_app(pQosContext);
1247 }
1248 break;
1249
1250 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND:
1251 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1252 "%s: Modification is complete, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001253 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001254
1255 // there will always be a TSPEC returned with this status, even if
1256 // a TSPEC is not exchanged OTA
1257 if (pCurrentQosInfo)
1258 {
1259 pAc->wmmAcTspecValid = VOS_TRUE;
1260 memcpy(&pAc->wmmAcTspecInfo,
1261 pCurrentQosInfo,
1262 sizeof(pAc->wmmAcTspecInfo));
1263 }
1264
1265 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1266 {
1267 // this was triggered by an application
1268 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS;
1269 hdd_wmm_notify_app(pQosContext);
1270 }
1271
1272 // notify TL to enable trigger frames if necessary
1273 hdd_wmm_enable_tl_uapsd(pQosContext);
1274
1275 break;
1276
1277 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
1278 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1279 {
1280 // this was triggered by an application
1281 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
1282 hdd_wmm_notify_app(pQosContext);
1283 }
1284 break;
1285
1286 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
1287 // the flow modification failed so we'll leave in place
1288 // whatever existed beforehand
1289
1290 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1291 {
1292 // this was triggered by an application
1293 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
1294 hdd_wmm_notify_app(pQosContext);
1295 }
1296 break;
1297
1298 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
1299 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1300 "%s: modification pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001301 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001302 // not a callback status -- ignore if we get it
1303 break;
1304
1305 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1306 // the flow modification was successful but no QoS changes required
1307
1308 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1309 {
1310 // this was triggered by an application
1311 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
1312 hdd_wmm_notify_app(pQosContext);
1313 }
1314 break;
1315
1316 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
1317 // invalid params -- notify the application
1318 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1319 {
1320 // this was triggered by an application
1321 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
1322 hdd_wmm_notify_app(pQosContext);
1323 }
1324 break;
1325
1326 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_PENDING:
1327 // nothing to do for now. when APSD is established we'll have work to do
1328 break;
1329
1330 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED:
1331 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1332 "%s: Modify successful but U-APSD failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001333 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001334
1335 // QoS modification was successful but setting U=APSD failed.
1336 // This will always be an explicit QoS instance, so all we can
1337 // do is notify the application and let it clean up.
1338 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1339 {
1340 // this was triggered by an application
1341 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_UAPSD_SET_FAILED;
1342 hdd_wmm_notify_app(pQosContext);
1343 }
1344
1345 // Since U-APSD portion failed disabled trigger frame generation
1346 hdd_wmm_disable_tl_uapsd(pQosContext);
1347
1348 break;
1349
1350 case SME_QOS_STATUS_HANDING_OFF:
1351 // no roaming so we won't see this
1352 break;
1353
1354 case SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND:
1355 // need to tell TL to stop trigger frame generation
1356 hdd_wmm_disable_tl_uapsd(pQosContext);
1357 break;
1358
1359 case SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND:
1360 // need to tell TL to start sending trigger frames again
1361 hdd_wmm_enable_tl_uapsd(pQosContext);
1362 break;
1363
1364 default:
1365 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001366 "%s: unexpected SME Status=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001367 __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07001368 VOS_ASSERT(0);
1369 }
1370
1371 // our access to the particular access category may have changed.
1372 // some of the implicit QoS cases above may have already set this
1373 // prior to invoking TL (so that we will properly service the
1374 // Tx queues) but let's consistently handle all cases here
1375 pAc->wmmAcAccessAllowed = hdd_wmm_is_access_allowed(pAdapter, pAc);
1376
1377 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1378 "%s: complete, access for TL AC %d is%sallowed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001379 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001380 acType,
1381 pAc->wmmAcAccessAllowed ? " " : " not ");
1382
1383 return eHAL_STATUS_SUCCESS;
1384}
1385#endif
1386
Kiet Lamf040f472013-11-20 21:15:23 +05301387/**========================================================================
1388 @brief hdd_wmmps_helper() - Function to set uapsd psb dynamically
1389
1390 @param pAdapter : [in] pointer to adapter structure
1391
1392 @param ptr : [in] pointer to command buffer
1393
1394 @return : Zero on success, appropriate error on failure.
1395 =======================================================================*/
1396int hdd_wmmps_helper(hdd_adapter_t *pAdapter, tANI_U8 *ptr)
1397{
1398 if (NULL == pAdapter)
1399 {
1400 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1401 "%s: pAdapter is NULL", __func__);
1402 return -EINVAL;
1403 }
1404 if (NULL == ptr)
1405 {
1406 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1407 "%s: ptr is NULL", __func__);
1408 return -EINVAL;
1409 }
1410 /* convert ASCII to integer */
1411 pAdapter->configuredPsb = ptr[9] - '0';
1412 pAdapter->psbChanged = HDD_PSB_CHANGED;
1413
1414 return 0;
1415}
1416
Jeff Johnson295189b2012-06-20 16:38:30 -07001417/**============================================================================
1418 @brief hdd_wmm_do_implicit_qos() - Function which will attempt to setup
1419 QoS for any AC requiring it
1420
1421 @param work : [in] pointer to work structure
1422
1423 @return : void
1424 ===========================================================================*/
Mukul Sharmaec9dcc62015-02-24 18:00:04 +05301425static void __hdd_wmm_do_implicit_qos(struct work_struct *work)
Jeff Johnson295189b2012-06-20 16:38:30 -07001426{
1427 hdd_wmm_qos_context_t* pQosContext =
1428 container_of(work, hdd_wmm_qos_context_t, wmmAcSetupImplicitQos);
1429 hdd_adapter_t* pAdapter;
1430 WLANTL_ACEnumType acType;
1431 hdd_wmm_ac_status_t *pAc;
1432#ifndef WLAN_MDM_CODE_REDUCTION_OPT
1433 VOS_STATUS status;
1434 sme_QosStatusType smeStatus;
1435#endif
1436 sme_QosWmmTspecInfo qosInfo;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301437 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +05301438 hdd_context_t *pHddCtx = NULL;
Mukul Sharmaec9dcc62015-02-24 18:00:04 +05301439 int ret = 0;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301440
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301441 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301442 {
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301443 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301444 FL("pVosContext is NULL"));
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301445 return;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301446 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001447
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301448 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
1449
Mukul Sharmaec9dcc62015-02-24 18:00:04 +05301450 ret = wlan_hdd_validate_context(pHddCtx);
1451 if (0 != ret)
1452 {
1453 hddLog(LOGE, FL("HDD context is invalid"));
1454 return;
1455 }
1456
Jeff Johnson295189b2012-06-20 16:38:30 -07001457 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1458 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001459 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001460
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301461 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001462 if (unlikely(HDD_WMM_CTX_MAGIC != pQosContext->magic))
1463 {
Hema Aparna Medicharla8bb6f782015-03-09 12:35:05 +05301464 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001465 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1466 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001467 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001468 return;
1469 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301470 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001471
1472 pAdapter = pQosContext->pAdapter;
1473 acType = pQosContext->acType;
1474 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1475
1476 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1477 "%s: pAdapter %p acType %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001478 __func__, pAdapter, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001479
1480 if (!pAc->wmmAcAccessNeeded)
1481 {
1482 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1483 "%s: AC %d doesn't need service",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001484 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001485 pQosContext->magic = 0;
1486 kfree(pQosContext);
1487 return;
1488 }
1489
1490 pAc->wmmAcAccessPending = VOS_TRUE;
1491 pAc->wmmAcAccessNeeded = VOS_FALSE;
1492
1493 memset(&qosInfo, 0, sizeof(qosInfo));
1494
Kiet Lamf040f472013-11-20 21:15:23 +05301495 qosInfo.ts_info.psb = pAdapter->configuredPsb;
1496
Jeff Johnson295189b2012-06-20 16:38:30 -07001497 switch (acType)
1498 {
1499 case WLANTL_AC_VO:
1500 qosInfo.ts_info.up = SME_QOS_WMM_UP_VO;
Kiet Lamf040f472013-11-20 21:15:23 +05301501 /* Check if there is any valid configuration from framework */
1502 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1503 {
1504 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1505 SME_QOS_UAPSD_VO) ? 1 : 0;
1506 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001507 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVo;
1508 qosInfo.ts_info.tid = 255;
1509 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVo;
1510 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVo;
1511 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv;
1512 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVo;
1513 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVo;
1514 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv;
1515 break;
1516 case WLANTL_AC_VI:
1517 qosInfo.ts_info.up = SME_QOS_WMM_UP_VI;
Kiet Lamf040f472013-11-20 21:15:23 +05301518 /* Check if there is any valid configuration from framework */
1519 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1520 {
1521 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1522 SME_QOS_UAPSD_VI) ? 1 : 0;
1523 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001524 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVi;
1525 qosInfo.ts_info.tid = 255;
1526 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVi;
1527 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVi;
1528 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv;
1529 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVi;
1530 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVi;
1531 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv;
1532 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07001533 case WLANTL_AC_BE:
1534 qosInfo.ts_info.up = SME_QOS_WMM_UP_BE;
Kiet Lamf040f472013-11-20 21:15:23 +05301535 /* Check if there is any valid configuration from framework */
1536 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1537 {
1538 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1539 SME_QOS_UAPSD_BE) ? 1 : 0;
1540 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001541 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBe;
1542 qosInfo.ts_info.tid = 255;
1543 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBe;
1544 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBe;
1545 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv;
1546 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBe;
1547 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBe;
1548 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv;
1549 break;
1550 case WLANTL_AC_BK:
1551 qosInfo.ts_info.up = SME_QOS_WMM_UP_BK;
Kiet Lamf040f472013-11-20 21:15:23 +05301552 /* Check if there is any valid configuration from framework */
1553 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1554 {
1555 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1556 SME_QOS_UAPSD_BK) ? 1 : 0;
1557 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001558 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBk;
1559 qosInfo.ts_info.tid = 255;
1560 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBk;
1561 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBk;
1562 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv;
1563 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBk;
1564 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBk;
1565 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv;
1566 break;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301567 default:
1568 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1569 "%s: Invalid AC %d", __func__, acType );
1570 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001571 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08001572#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07001573 qosInfo.inactivity_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraInactivityInterval;
1574#endif
1575 qosInfo.ts_info.burst_size_defn = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->burstSizeDefinition;
1576
1577 switch ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->tsInfoAckPolicy)
1578 {
1579 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK:
1580 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1581 break;
1582
1583 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
1584 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
1585 break;
1586
1587 default:
1588 // unknown
1589 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1590 }
1591
1592 if(qosInfo.ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK)
1593 {
1594 if(!sme_QosIsTSInfoAckPolicyValid((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter), &qosInfo, pAdapter->sessionId))
1595 {
1596 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1597 }
1598 }
1599
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301600 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001601 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301602 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001603
1604#ifndef WLAN_MDM_CODE_REDUCTION_OPT
1605 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
1606 pAdapter->sessionId,
1607 &qosInfo,
1608 hdd_wmm_sme_callback,
1609 pQosContext,
1610 qosInfo.ts_info.up,
1611 &pQosContext->qosFlowId);
1612
1613 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1614 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001615 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001616
1617 // need to check the return values and act appropriately
1618 switch (smeStatus)
1619 {
1620 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
1621 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
1622 // setup is pending, so no more work to do now.
1623 // all further work will be done in hdd_wmm_sme_callback()
1624 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1625 "%s: Setup is pending, no further work",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001626 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001627
1628 break;
1629
1630
1631 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
1632 // we can't tell the difference between when a request fails because
1633 // AP rejected it versus when SME encountered an internal error
1634
1635 // in either case SME won't ever reference this context so
1636 // free the record
1637 hdd_wmm_free_context(pQosContext);
1638
1639 // fall through and start packets flowing
1640 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1641 // no ACM in effect, no need to setup U-APSD
1642 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
1643 // no ACM in effect, U-APSD is desired but was already setup
1644
1645 // for these cases everything is already setup so we can
1646 // signal TL that it has work to do
1647 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1648 "%s: Setup is complete, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001649 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001650
1651 pAc->wmmAcAccessAllowed = VOS_TRUE;
1652 pAc->wmmAcAccessGranted = VOS_TRUE;
1653 pAc->wmmAcAccessPending = VOS_FALSE;
1654
1655 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1656 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
1657 acType );
1658
1659 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1660 {
1661 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1662 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001663 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -07001664 }
1665
1666 break;
1667
1668
1669 default:
1670 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001671 "%s: unexpected SME Status=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001672 __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07001673 VOS_ASSERT(0);
1674 }
1675#endif
1676
1677}
1678
Mukul Sharmaec9dcc62015-02-24 18:00:04 +05301679static void hdd_wmm_do_implicit_qos(struct work_struct *work)
1680{
1681 vos_ssr_protect(__func__);
1682 __hdd_wmm_do_implicit_qos( work );
1683 vos_ssr_unprotect(__func__);
1684}
1685
Jeff Johnson295189b2012-06-20 16:38:30 -07001686/**============================================================================
1687 @brief hdd_wmm_init() - Function which will initialize the WMM configuation
1688 and status to an initial state. The configuration can later be overwritten
1689 via application APIs
1690
Kumar Anand82c009f2014-05-29 00:29:42 -07001691 @param pAdapter : [in] pointer to Adapter context
Jeff Johnson295189b2012-06-20 16:38:30 -07001692
Kumar Anand82c009f2014-05-29 00:29:42 -07001693 @return : VOS_STATUS_SUCCESS if successful
Jeff Johnson295189b2012-06-20 16:38:30 -07001694 : other values if failure
1695
1696 ===========================================================================*/
Kumar Anand82c009f2014-05-29 00:29:42 -07001697VOS_STATUS hdd_wmm_init ( hdd_adapter_t *pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07001698{
Kumar Anand82c009f2014-05-29 00:29:42 -07001699 sme_QosWmmUpType* hddWmmDscpToUpMap = pAdapter->hddWmmDscpToUpMap;
Jeff Johnson295189b2012-06-20 16:38:30 -07001700 v_U8_t dscp;
1701
1702 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001703 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001704
1705 // DSCP to User Priority Lookup Table
1706 for (dscp = 0; dscp <= WLAN_HDD_MAX_DSCP; dscp++)
1707 {
1708 hddWmmDscpToUpMap[dscp] = SME_QOS_WMM_UP_BE;
1709 }
1710 hddWmmDscpToUpMap[8] = SME_QOS_WMM_UP_BK;
1711 hddWmmDscpToUpMap[16] = SME_QOS_WMM_UP_RESV;
1712 hddWmmDscpToUpMap[24] = SME_QOS_WMM_UP_EE;
1713 hddWmmDscpToUpMap[32] = SME_QOS_WMM_UP_CL;
1714 hddWmmDscpToUpMap[40] = SME_QOS_WMM_UP_VI;
1715 hddWmmDscpToUpMap[48] = SME_QOS_WMM_UP_VO;
1716 hddWmmDscpToUpMap[56] = SME_QOS_WMM_UP_NC;
Jeff Johnson295189b2012-06-20 16:38:30 -07001717 return VOS_STATUS_SUCCESS;
1718}
1719
1720/**============================================================================
1721 @brief hdd_wmm_adapter_init() - Function which will initialize the WMM configuation
1722 and status to an initial state. The configuration can later be overwritten
1723 via application APIs
1724
1725 @param pAdapter : [in] pointer to Adapter context
1726
1727 @return : VOS_STATUS_SUCCESS if succssful
1728 : other values if failure
1729
1730 ===========================================================================*/
1731VOS_STATUS hdd_wmm_adapter_init( hdd_adapter_t *pAdapter )
1732{
1733 hdd_wmm_ac_status_t *pAcStatus;
1734 WLANTL_ACEnumType acType;
1735
1736 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001737 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001738
1739 pAdapter->hddWmmStatus.wmmQap = VOS_FALSE;
1740 INIT_LIST_HEAD(&pAdapter->hddWmmStatus.wmmContextList);
Jeff Johnson295189b2012-06-20 16:38:30 -07001741
1742 for (acType = 0; acType < WLANTL_MAX_AC; acType++)
1743 {
1744 pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1745 pAcStatus->wmmAcAccessRequired = VOS_FALSE;
1746 pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
1747 pAcStatus->wmmAcAccessPending = VOS_FALSE;
1748 pAcStatus->wmmAcAccessFailed = VOS_FALSE;
1749 pAcStatus->wmmAcAccessGranted = VOS_FALSE;
1750 pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
1751 pAcStatus->wmmAcTspecValid = VOS_FALSE;
1752 pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
1753 }
Kiet Lamf040f472013-11-20 21:15:23 +05301754 // Invalid value(0xff) to indicate psb not configured through framework initially.
1755 pAdapter->configuredPsb = HDD_PSB_CFG_INVALID;
Jeff Johnson295189b2012-06-20 16:38:30 -07001756
1757 return VOS_STATUS_SUCCESS;
1758}
Madan Mohan Koyyalamudi70c52d32013-08-07 14:42:16 +05301759
1760/**============================================================================
1761 @brief hdd_wmm_adapter_clear() - Function which will clear the WMM status
1762 for all the ACs
1763
1764 @param pAdapter : [in] pointer to Adapter context
1765
1766 @return : VOS_STATUS_SUCCESS if succssful
1767 : other values if failure
1768
1769 ===========================================================================*/
1770VOS_STATUS hdd_wmm_adapter_clear( hdd_adapter_t *pAdapter )
1771{
1772 hdd_wmm_ac_status_t *pAcStatus;
1773 WLANTL_ACEnumType acType;
1774 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1775 "%s: Entered", __func__);
1776 for (acType = 0; acType < WLANTL_MAX_AC; acType++)
1777 {
1778 pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1779 pAcStatus->wmmAcAccessRequired = VOS_FALSE;
1780 pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
1781 pAcStatus->wmmAcAccessPending = VOS_FALSE;
1782 pAcStatus->wmmAcAccessFailed = VOS_FALSE;
1783 pAcStatus->wmmAcAccessGranted = VOS_FALSE;
1784 pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
1785 pAcStatus->wmmAcTspecValid = VOS_FALSE;
1786 pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
1787 }
1788 return VOS_STATUS_SUCCESS;
1789}
1790
Jeff Johnson295189b2012-06-20 16:38:30 -07001791/**============================================================================
1792 @brief hdd_wmm_close() - Function which will perform any necessary work to
1793 to clean up the WMM functionality prior to the kernel module unload
1794
1795 @param pAdapter : [in] pointer to adapter context
1796
1797 @return : VOS_STATUS_SUCCESS if succssful
1798 : other values if failure
1799
1800 ===========================================================================*/
1801VOS_STATUS hdd_wmm_adapter_close ( hdd_adapter_t* pAdapter )
1802{
1803 hdd_wmm_qos_context_t* pQosContext;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301804 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +05301805 hdd_context_t *pHddCtx = NULL;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301806
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301807 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301808 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301809 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1810 FL("pVosContext is NULL"));
1811 return VOS_STATUS_E_FAILURE;
1812 }
1813
1814 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
1815 if (NULL == pHddCtx)
1816 {
1817 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301818 FL("HddCtx is NULL"));
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05301819 return VOS_STATUS_E_FAILURE;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301820 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001821
1822 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001823 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001824
1825 // free any context records that we still have linked
1826 while (!list_empty(&pAdapter->hddWmmStatus.wmmContextList))
1827 {
1828 pQosContext = list_first_entry(&pAdapter->hddWmmStatus.wmmContextList,
1829 hdd_wmm_qos_context_t, node);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08001830#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07001831 hdd_wmm_disable_inactivity_timer(pQosContext);
1832#endif
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301833 mutex_lock(&pHddCtx->wmmLock);
Anand N Sunkad4b25a2f2014-11-13 16:01:08 +05301834 if (pQosContext->handle == HDD_WMM_HANDLE_IMPLICIT
1835 && pQosContext->magic == HDD_WMM_CTX_MAGIC)
1836 {
1837
Anand N Sunkad860e5ea2015-03-30 14:41:51 +05301838 vos_flush_work(&pQosContext->wmmAcSetupImplicitQos);
Anand N Sunkad4b25a2f2014-11-13 16:01:08 +05301839 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05301840 mutex_unlock(&pHddCtx->wmmLock);
Anand N Sunkad860e5ea2015-03-30 14:41:51 +05301841
Jeff Johnson295189b2012-06-20 16:38:30 -07001842 hdd_wmm_free_context(pQosContext);
1843 }
1844
1845 return VOS_STATUS_SUCCESS;
1846}
1847
1848/**============================================================================
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301849 @brief hdd_is_dhcp_packet() - Function which will check OS packet for
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301850 DHCP packet
1851
1852 @param skb : [in] pointer to OS packet (sk_buff)
1853 @return : VOS_TRUE if the OS packet is DHCP packet
1854 : otherwise VOS_FALSE
1855 ===========================================================================*/
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301856v_BOOL_t hdd_is_dhcp_packet(struct sk_buff *skb)
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301857{
1858 if (*((u16*)((u8*)skb->data+34)) == DHCP_SOURCE_PORT ||
1859 *((u16*)((u8*)skb->data+34)) == DHCP_DESTINATION_PORT)
1860 return VOS_TRUE;
1861
1862 return VOS_FALSE;
1863}
1864
1865/**============================================================================
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301866 @brief hdd_skb_is_eapol_or_wai_packet() - Function which will check OS packet
1867 for Eapol/Wapi packet
1868
1869 @param skb : [in] pointer to OS packet (sk_buff)
1870 @return : VOS_TRUE if the OS packet is an Eapol or a Wapi packet
1871 : otherwise VOS_FALSE
1872 ===========================================================================*/
1873v_BOOL_t hdd_skb_is_eapol_or_wai_packet(struct sk_buff *skb)
1874{
1875 if ((*((u16*)((u8*)skb->data+HDD_ETHERTYPE_802_1_X_FRAME_OFFSET))
1876 == vos_cpu_to_be16(HDD_ETHERTYPE_802_1_X))
1877#ifdef FEATURE_WLAN_WAPI
1878 || (*((u16*)((u8*)skb->data+HDD_ETHERTYPE_802_1_X_FRAME_OFFSET))
1879 == vos_cpu_to_be16(HDD_ETHERTYPE_WAI))
1880#endif
1881 )
1882 return VOS_TRUE;
1883
1884 return VOS_FALSE;
1885}
1886
1887/**============================================================================
Sravan Kumar Kairamd9ded562016-11-13 15:21:49 +05301888 @brief hdd_log_ip_addr() - Function to log IP header src and dst address
1889 @param skb : [in] pointer to OS packet (sk_buff)
1890 @return : none
1891 ===========================================================================*/
1892void hdd_log_ip_addr(struct sk_buff *skb)
1893{
1894 union generic_ethhdr *pHdr;
1895 struct iphdr *pIpHdr;
1896 unsigned char * pPkt;
1897 char *buf;
1898
1899 pPkt = skb->data;
1900 pHdr = (union generic_ethhdr *)pPkt;
1901
1902 if (pHdr->eth_II.h_proto == htons(ETH_P_IP))
1903 {
1904 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_II)];
1905
1906 buf = (char *)&pIpHdr->saddr;
1907 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1908 "%s: src addr %d:%d:%d:%d", __func__,
1909 buf[0], buf[1], buf[2], buf[3]);
1910
1911 buf = (char *)&pIpHdr->daddr;
1912 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1913 "%s: dst addr %d:%d:%d:%d", __func__,
1914 buf[0], buf[1], buf[2], buf[3]);
1915 }
1916 else if (pHdr->eth_II.h_proto == htons(ETH_P_IPV6))
1917 {
1918 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];
1919
1920 buf = (char *)&pIpHdr->saddr;
1921 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1922 "%s: src addr "IPv6_ADDR_STR, __func__, IPv6_ADDR_ARRAY(buf));
1923
1924 buf = (char *)&pIpHdr->daddr;
1925 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1926 "%s: dst addr "IPv6_ADDR_STR, __func__, IPv6_ADDR_ARRAY(buf));
1927 }
1928 else if ((ntohs(pHdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
1929 (pHdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
1930 (pHdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
1931 (pHdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL))
1932 {
1933 if (pHdr->eth_8023.h_proto == htons(ETH_P_IP))
1934 {
1935 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];
1936
1937 buf = (char *)&pIpHdr->saddr;
1938 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1939 "%s: src addr %d:%d:%d:%d", __func__,
1940 buf[0], buf[1], buf[2], buf[3]);
1941
1942 buf = (char *)&pIpHdr->daddr;
1943 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1944 "%s: dst addr %d:%d:%d:%d", __func__,
1945 buf[0], buf[1], buf[2], buf[3]);
1946 }
1947 else if (pHdr->eth_8023.h_proto == htons(ETH_P_IPV6))
1948 {
1949 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];
1950
1951 buf = (char *)&pIpHdr->saddr;
1952 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1953 "%s: src addr "IPv6_ADDR_STR, __func__, IPv6_ADDR_ARRAY(buf));
1954
1955 buf = (char *)&pIpHdr->daddr;
1956 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1957 "%s: dst addr "IPv6_ADDR_STR, __func__, IPv6_ADDR_ARRAY(buf));
1958 }
1959 }
1960}
1961
1962/**============================================================================
Sravan Kumar Kairamf9f95122017-01-18 20:54:05 +05301963 @brief hdd_get_arp_src_ip() - Function to get ARP src IP addr
1964 @param skb : [in] pointer to OS packet (sk_buff)
1965 @return : IP addr
1966 ===========================================================================*/
1967uint32_t hdd_get_arp_src_ip(struct sk_buff *skb)
1968{
1969 struct arphdr *arp;
1970 unsigned char *arp_ptr;
1971 uint32_t src_ip;
1972
1973#define ARP_HDR_SIZE ( sizeof(__be16)*3 + sizeof(unsigned char)*2 )
1974#define ARP_SENDER_HW_ADDRESS_SZ (6)
1975#define ARP_SENDER_IP_ADDRESS_SZ (4)
1976
1977 arp = (struct arphdr *)skb->data;
1978
1979 arp_ptr = (unsigned char *)arp + ARP_HDR_SIZE;
1980 arp_ptr += ARP_SENDER_HW_ADDRESS_SZ;
1981
1982 memcpy(&src_ip, arp_ptr, ARP_SENDER_IP_ADDRESS_SZ);
1983
1984 src_ip=ntohl(src_ip);
1985
1986 return src_ip;
1987
1988#undef ARP_HDR_SIZE
1989#undef ARP_SENDER_HW_ADDRESS_SZ
1990#undef ARP_SENDER_IP_ADDRESS_SZ
1991}
1992
1993/**============================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07001994 @brief hdd_wmm_classify_pkt() - Function which will classify an OS packet
1995 into a WMM AC based on either 802.1Q or DSCP
1996
1997 @param pAdapter : [in] pointer to adapter context
1998 @param skb : [in] pointer to OS packet (sk_buff)
1999 @param pAcType : [out] pointer to WMM AC type of OS packet
2000
2001 @return : None
2002 ===========================================================================*/
2003v_VOID_t hdd_wmm_classify_pkt ( hdd_adapter_t* pAdapter,
2004 struct sk_buff *skb,
2005 WLANTL_ACEnumType* pAcType,
2006 sme_QosWmmUpType *pUserPri)
2007{
2008 unsigned char * pPkt;
2009 union generic_ethhdr *pHdr;
2010 struct iphdr *pIpHdr;
2011 unsigned char tos;
2012 unsigned char dscp;
2013 sme_QosWmmUpType userPri;
2014 WLANTL_ACEnumType acType;
2015
2016 // this code is executed for every packet therefore
2017 // all debug code is kept conditional
2018
2019#ifdef HDD_WMM_DEBUG
2020 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002021 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002022#endif // HDD_WMM_DEBUG
2023
2024 pPkt = skb->data;
2025 pHdr = (union generic_ethhdr *)pPkt;
2026
2027#ifdef HDD_WMM_DEBUG
2028 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2029 "%s: proto/length is 0x%04x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002030 __func__, pHdr->eth_II.h_proto);
Jeff Johnson295189b2012-06-20 16:38:30 -07002031#endif // HDD_WMM_DEBUG
2032
2033 if (HDD_WMM_CLASSIFICATION_DSCP == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
2034 {
2035 if (pHdr->eth_II.h_proto == htons(ETH_P_IP))
2036 {
2037 // case 1: Ethernet II IP packet
2038 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_II)];
2039 tos = pIpHdr->tos;
2040#ifdef HDD_WMM_DEBUG
2041 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2042 "%s: Ethernet II IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002043 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07002044#endif // HDD_WMM_DEBUG
2045
2046 }
2047 else if ((ntohs(pHdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
2048 (pHdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
2049 (pHdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
2050 (pHdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) &&
2051 (pHdr->eth_8023.h_proto == htons(ETH_P_IP)))
2052 {
2053 // case 2: 802.3 LLC/SNAP IP packet
2054 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];
2055 tos = pIpHdr->tos;
2056#ifdef HDD_WMM_DEBUG
2057 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2058 "%s: 802.3 LLC/SNAP IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002059 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07002060#endif // HDD_WMM_DEBUG
2061 }
2062 else if (pHdr->eth_II.h_proto == htons(ETH_P_8021Q))
2063 {
2064 // VLAN tagged
2065
2066 if (pHdr->eth_IIv.h_vlan_encapsulated_proto == htons(ETH_P_IP))
2067 {
2068 // case 3: Ethernet II vlan-tagged IP packet
2069 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_IIv)];
2070 tos = pIpHdr->tos;
2071#ifdef HDD_WMM_DEBUG
2072 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2073 "%s: Ethernet II VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002074 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07002075#endif // HDD_WMM_DEBUG
2076 }
2077 else if ((ntohs(pHdr->eth_IIv.h_vlan_encapsulated_proto) < WLAN_MIN_PROTO) &&
2078 (pHdr->eth_8023v.h_snap.dsap == WLAN_SNAP_DSAP) &&
2079 (pHdr->eth_8023v.h_snap.ssap == WLAN_SNAP_SSAP) &&
2080 (pHdr->eth_8023v.h_snap.ctrl == WLAN_SNAP_CTRL) &&
2081 (pHdr->eth_8023v.h_proto == htons(ETH_P_IP)))
2082 {
2083 // case 4: 802.3 LLC/SNAP vlan-tagged IP packet
2084 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023v)];
2085 tos = pIpHdr->tos;
2086#ifdef HDD_WMM_DEBUG
2087 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2088 "%s: 802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002089 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07002090#endif // HDD_WMM_DEBUG
2091 }
2092 else
2093 {
2094 // default
2095#ifdef HDD_WMM_DEBUG
2096 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2097 "%s: VLAN tagged Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002098 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002099#endif // HDD_WMM_DEBUG
2100 tos = 0;
2101 }
2102 }
2103 else
2104 {
Hanumantha Reddy Pothulaee001fc2015-05-26 15:21:53 +05302105 v_BOOL_t toggleArpBDRates =
2106 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->toggleArpBDRates;
Jeff Johnson295189b2012-06-20 16:38:30 -07002107 // default
2108#ifdef HDD_WMM_DEBUG
2109 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2110 "%s: Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002111 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002112#endif // HDD_WMM_DEBUG
2113 //Give the highest priority to 802.1x packet
2114 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
2115 tos = 0xC0;
Sachin Ahujaf51bfac2015-09-24 21:46:16 +05302116 else if (toggleArpBDRates &&
Hanumantha Reddy Pothulaee001fc2015-05-26 15:21:53 +05302117 pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_ARP))
2118 {
2119 tos = TID3;
2120 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002121 else
2122 tos = 0;
2123 }
2124
2125 dscp = (tos>>2) & 0x3f;
Kumar Anand82c009f2014-05-29 00:29:42 -07002126 userPri = pAdapter->hddWmmDscpToUpMap[dscp];
2127
Jeff Johnson295189b2012-06-20 16:38:30 -07002128#ifdef HDD_WMM_DEBUG
2129 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2130 "%s: tos is %d, dscp is %d, up is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002131 __func__, tos, dscp, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07002132#endif // HDD_WMM_DEBUG
2133
2134 }
2135 else if (HDD_WMM_CLASSIFICATION_802_1Q == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
2136 {
2137 if (pHdr->eth_IIv.h_vlan_proto == htons(ETH_P_8021Q))
2138 {
2139 // VLAN tagged
2140 userPri = (ntohs(pHdr->eth_IIv.h_vlan_TCI)>>13) & 0x7;
2141#ifdef HDD_WMM_DEBUG
2142 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2143 "%s: Tagged frame, UP is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002144 __func__, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07002145#endif // HDD_WMM_DEBUG
2146 }
2147 else
2148 {
2149 // not VLAN tagged, use default
2150#ifdef HDD_WMM_DEBUG
2151 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2152 "%s: Untagged frame, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002153 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002154#endif // HDD_WMM_DEBUG
2155 //Give the highest priority to 802.1x packet
2156 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
2157 userPri = SME_QOS_WMM_UP_VO;
2158 else
2159 userPri = SME_QOS_WMM_UP_BE;
2160 }
2161 }
2162 else
2163 {
2164 // default
2165#ifdef HDD_WMM_DEBUG
2166 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2167 "%s: Unknown classification scheme, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002168 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002169#endif // HDD_WMM_DEBUG
2170 userPri = SME_QOS_WMM_UP_BE;
2171 }
2172
2173 acType = hddWmmUpToAcMap[userPri];
2174
2175#ifdef HDD_WMM_DEBUG
2176 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2177 "%s: UP is %d, AC is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002178 __func__, userPri, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002179#endif // HDD_WMM_DEBUG
2180
2181 *pUserPri = userPri;
2182 *pAcType = acType;
2183
2184 return;
2185}
2186
2187/**============================================================================
2188 @brief hdd_hostapd_select_quueue() - Function which will classify the packet
2189 according to linux qdisc expectation.
2190
2191
2192 @param dev : [in] pointer to net_device structure
2193 @param skb : [in] pointer to os packet
2194
2195 @return : Qdisc queue index
2196 ===========================================================================*/
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05302197v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb
2198#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
2199 , void *accel_priv
2200#endif
2201#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
2202 , select_queue_fallback_t fallbac
2203#endif
2204)
Jeff Johnson295189b2012-06-20 16:38:30 -07002205{
2206 WLANTL_ACEnumType ac;
2207 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
2208 v_USHORT_t queueIndex;
2209 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
2210 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
2211 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002212 v_U8_t STAId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302213 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2214 ptSapContext pSapCtx = NULL;
Mukul Sharmabd6b9482015-06-19 16:43:57 +05302215 int status = 0;
Mukul Sharma986109f2015-04-20 22:29:39 +05302216
Mukul Sharmabd6b9482015-06-19 16:43:57 +05302217 status = wlan_hdd_validate_context(pHddCtx);
2218 if (status !=0 )
2219 {
2220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2221 FL("called during WDReset/unload"));
Mukul Sharma986109f2015-04-20 22:29:39 +05302222 skb->priority = SME_QOS_WMM_UP_BE;
2223 return HDD_LINUX_AC_BE;
2224 }
2225
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302226 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2227 if(pSapCtx == NULL){
Mukul Sharmabd6b9482015-06-19 16:43:57 +05302228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302229 FL("psapCtx is NULL"));
Nirav Shah7e3c8132015-06-22 23:51:42 +05302230 STAId = HDD_WLAN_INVALID_STA_ID;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302231 goto done;
2232 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002233 /*Get the Station ID*/
Nirav Shah7e3c8132015-06-22 23:51:42 +05302234 STAId = hdd_sta_id_find_from_mac_addr(pAdapter, pDestMacAddress);
Manjeet Singh7a883622016-11-21 19:02:08 +05302235 if (STAId == HDD_WLAN_INVALID_STA_ID || STAId >= WLAN_MAX_STA_COUNT) {
Nirav Shah7e3c8132015-06-22 23:51:42 +05302236 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
2237 "%s: Failed to find right station", __func__);
2238 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07002239 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002240
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302241 spin_lock_bh( &pSapCtx->staInfo_lock );
2242 if (FALSE == vos_is_macaddr_equal(&pSapCtx->aStaInfo[STAId].macAddrSTA, pDestMacAddress))
Jeff Johnson295189b2012-06-20 16:38:30 -07002243 {
Agarwal Ashisha64c9542014-03-04 00:14:43 +05302244 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002245 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002246
Nirav Shah7e3c8132015-06-22 23:51:42 +05302247 STAId = HDD_WLAN_INVALID_STA_ID;
Jeff Johnson295189b2012-06-20 16:38:30 -07002248 goto release_lock;
2249 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302250 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 -07002251 {
2252 /* Get the user priority from IP header & corresponding AC */
2253 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05302254 //If 3/4th of Tx queue is used then place the DHCP packet in VOICE AC queue
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302255 if (pSapCtx->aStaInfo[STAId].vosLowResource && hdd_is_dhcp_packet(skb))
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05302256 {
2257 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2258 "%s: Making priority of DHCP packet as VOICE", __func__);
2259 up = SME_QOS_WMM_UP_VO;
2260 ac = hddWmmUpToAcMap[up];
2261 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002262 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002263
2264release_lock:
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302265 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07002266done:
2267 skb->priority = up;
Mukul Sharmad82cb7d2014-07-03 14:53:30 +05302268 if(skb->priority < SME_QOS_WMM_UP_MAX)
2269 queueIndex = hddLinuxUpToAcMap[skb->priority];
2270 else
2271 {
2272 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2273 "%s: up=%d is going beyond max value", __func__, up);
2274 queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
2275 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002276
2277 return queueIndex;
2278}
2279
2280/**============================================================================
2281 @brief hdd_wmm_select_quueue() - Function which will classify the packet
2282 according to linux qdisc expectation.
2283
2284
2285 @param dev : [in] pointer to net_device structure
2286 @param skb : [in] pointer to os packet
2287
2288 @return : Qdisc queue index
2289 ===========================================================================*/
2290v_U16_t hdd_wmm_select_queue(struct net_device * dev, struct sk_buff *skb)
2291{
2292 WLANTL_ACEnumType ac;
Shailender Karmuchia734f332013-04-19 14:02:48 -07002293 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002294 v_USHORT_t queueIndex;
Jeff Johnson295189b2012-06-20 16:38:30 -07002295 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma6bb6cdd2015-06-19 17:23:23 +05302296 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2297 int status = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002298
Mukul Sharma6bb6cdd2015-06-19 17:23:23 +05302299 status = wlan_hdd_validate_context(pHddCtx);
2300 if (status !=0) {
Kiet Lam40009862014-02-13 12:33:22 -08002301 skb->priority = SME_QOS_WMM_UP_BE;
2302 return HDD_LINUX_AC_BE;
2303 }
2304
Shailender Karmuchia734f332013-04-19 14:02:48 -07002305 /*Get the Station ID*/
2306 if (WLAN_HDD_IBSS == pAdapter->device_mode)
2307 {
Shailender Karmuchia734f332013-04-19 14:02:48 -07002308 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
Nirav Shah7e3c8132015-06-22 23:51:42 +05302309 v_U8_t STAId;
Shailender Karmuchia734f332013-04-19 14:02:48 -07002310
Nirav Shah7e3c8132015-06-22 23:51:42 +05302311 STAId = hdd_sta_id_find_from_mac_addr(pAdapter, pDestMacAddress);
2312 if ((STAId == HDD_WLAN_INVALID_STA_ID) &&
2313 !vos_is_macaddr_broadcast( pDestMacAddress ) &&
2314 !vos_is_macaddr_group(pDestMacAddress))
Shailender Karmuchia734f332013-04-19 14:02:48 -07002315 {
Nirav Shah7e3c8132015-06-22 23:51:42 +05302316 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnsonb9fb9ce2013-05-03 08:11:02 -07002317 "%s: Failed to find right station pDestMacAddress: "
2318 MAC_ADDRESS_STR , __func__,
2319 MAC_ADDR_ARRAY(pDestMacAddress->bytes));
Nirav Shah7e3c8132015-06-22 23:51:42 +05302320 goto done;
Shailender Karmuchia734f332013-04-19 14:02:48 -07002321 }
2322 }
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302323 /* All traffic will get equal opportuniy to transmit data frames. */
2324 /* Get the user priority from IP header & corresponding AC */
2325 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302326
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302327 /* If 3/4th of BE AC Tx queue is full,
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302328 * then place the DHCP packet in VOICE AC queue.
2329 * Doing this for IBSS alone, since for STA interface
2330 * types, these packets will be queued to the new queue.
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302331 */
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302332 if ((WLAN_HDD_IBSS == pAdapter->device_mode) &&
2333 pAdapter->isVosLowResource && hdd_is_dhcp_packet(skb))
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302334 {
2335 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2336 "%s: BestEffort Tx Queue is 3/4th full"
2337 " Make DHCP packet's pri as VO", __func__);
2338 up = SME_QOS_WMM_UP_VO;
2339 ac = hddWmmUpToAcMap[up];
Jeff Johnson295189b2012-06-20 16:38:30 -07002340 }
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302341
Shailender Karmuchia734f332013-04-19 14:02:48 -07002342done:
Jeff Johnson295189b2012-06-20 16:38:30 -07002343 skb->priority = up;
Mukul Sharmad82cb7d2014-07-03 14:53:30 +05302344 if(skb->priority < SME_QOS_WMM_UP_MAX)
2345 queueIndex = hddLinuxUpToAcMap[skb->priority];
2346 else
2347 {
2348 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2349 "%s: up=%d is going beyond max value", __func__, up);
2350 queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
2351 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002352
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302353 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
2354 (hdd_is_dhcp_packet(skb) ||
2355 hdd_skb_is_eapol_or_wai_packet(skb)))
2356 {
2357 /* If the packet is a DHCP packet or a Eapol packet or
2358 * a Wapi packet, then queue it to the new queue for
2359 * STA interfaces alone.
2360 */
2361 queueIndex = WLANTL_AC_HIGH_PRIO;
2362 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2363 "%s: up=%d QIndex:%d", __func__, up, queueIndex);
2364 }
2365
Jeff Johnson295189b2012-06-20 16:38:30 -07002366 return queueIndex;
2367}
2368
Kiet Lamf040f472013-11-20 21:15:23 +05302369/**==========================================================================
2370 @brief hdd_wmm_acquire_access_required() - Function which will determine
2371 acquire admittance for a WMM AC is required or not based on psb configuration
2372 done in framework
2373
2374 @param pAdapter : [in] pointer to adapter structure
2375
2376 @param acType : [in] WMM AC type of OS packet
2377
2378 @return : void
2379 ===========================================================================*/
2380void hdd_wmm_acquire_access_required(hdd_adapter_t *pAdapter,
2381 WLANTL_ACEnumType acType)
2382{
2383/* Each bit in the LSB nibble indicates 1 AC.
2384 * Clearing the particular bit in LSB nibble to indicate
2385 * access required
2386 */
2387 switch(acType)
2388 {
2389 case WLANTL_AC_BK:
2390 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BK_CHANGED_MASK; /* clear first bit */
2391 break;
2392 case WLANTL_AC_BE:
2393 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BE_CHANGED_MASK; /* clear second bit */
2394 break;
2395 case WLANTL_AC_VI:
2396 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VI_CHANGED_MASK; /* clear third bit */
2397 break;
2398 case WLANTL_AC_VO:
2399 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VO_CHANGED_MASK; /* clear fourth bit */
2400 break;
2401 default:
2402 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2403 "%s: Invalid AC Type", __func__);
2404 break;
2405 }
2406}
2407
Jeff Johnson295189b2012-06-20 16:38:30 -07002408/**============================================================================
2409 @brief hdd_wmm_acquire_access() - Function which will attempt to acquire
2410 admittance for a WMM AC
2411
2412 @param pAdapter : [in] pointer to adapter context
2413 @param acType : [in] WMM AC type of OS packet
2414 @param pGranted : [out] pointer to boolean flag when indicates if access
2415 has been granted or not
2416
2417 @return : VOS_STATUS_SUCCESS if succssful
2418 : other values if failure
2419 ===========================================================================*/
2420VOS_STATUS hdd_wmm_acquire_access( hdd_adapter_t* pAdapter,
2421 WLANTL_ACEnumType acType,
2422 v_BOOL_t * pGranted )
2423{
2424 hdd_wmm_qos_context_t *pQosContext;
2425
2426 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002427 "%s: Entered for AC %d", __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002428
2429 if (!hdd_wmm_is_active(pAdapter) || !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
2430 {
2431 // either we don't want QoS or the AP doesn't support QoS
2432 // or we don't want to do implicit QoS
2433 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002434 "%s: QoS not configured on both ends ", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002435
2436 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2437 *pGranted = VOS_TRUE;
2438 return VOS_STATUS_SUCCESS;
2439 }
2440
2441 // do we already have an implicit QoS request pending for this AC?
2442 if ((pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded) ||
2443 (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessPending))
2444 {
2445 // request already pending so we need to wait for that response
2446 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2447 "%s: Implicit QoS for TL AC %d already scheduled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002448 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002449
2450 *pGranted = VOS_FALSE;
2451 return VOS_STATUS_SUCCESS;
2452 }
2453
2454 // did we already fail to establish implicit QoS for this AC?
2455 // (if so, access should have been granted when the failure was handled)
2456 if (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessFailed)
2457 {
2458 // request previously failed
2459 // allow access, but we'll be downgraded
2460 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2461 "%s: Implicit QoS for TL AC %d previously failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002462 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002463
2464 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2465 *pGranted = VOS_TRUE;
2466 return VOS_STATUS_SUCCESS;
2467 }
2468
2469 // we need to establish implicit QoS
2470 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2471 "%s: Need to schedule implicit QoS for TL AC %d, pAdapter is %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002472 __func__, acType, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002473
2474 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded = VOS_TRUE;
2475
Mohit Khanna217ea8d2012-09-11 17:42:42 -07002476 pQosContext = kmalloc(sizeof(*pQosContext), GFP_ATOMIC);
Jeff Johnson295189b2012-06-20 16:38:30 -07002477 if (NULL == pQosContext)
2478 {
2479 // no memory for QoS context. Nothing we can do but let data flow
2480 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002481 "%s: Unable to allocate context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002482 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2483 *pGranted = VOS_TRUE;
2484 return VOS_STATUS_SUCCESS;
2485 }
2486
2487 pQosContext->acType = acType;
2488 pQosContext->pAdapter = pAdapter;
2489 pQosContext->qosFlowId = 0;
2490 pQosContext->handle = HDD_WMM_HANDLE_IMPLICIT;
2491 pQosContext->magic = HDD_WMM_CTX_MAGIC;
Anand N Sunkaddc63c792015-06-03 14:33:24 +05302492 vos_init_work(&pQosContext->wmmAcSetupImplicitQos,
Jeff Johnson295189b2012-06-20 16:38:30 -07002493 hdd_wmm_do_implicit_qos);
2494
2495 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2496 "%s: Scheduling work for AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002497 __func__, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002498
2499 schedule_work(&pQosContext->wmmAcSetupImplicitQos);
2500
2501 // caller will need to wait until the work takes place and
2502 // TSPEC negotiation completes
2503 *pGranted = VOS_FALSE;
2504 return VOS_STATUS_SUCCESS;
2505}
2506
2507/**============================================================================
2508 @brief hdd_wmm_assoc() - Function which will handle the housekeeping
2509 required by WMM when association takes place
2510
2511 @param pAdapter : [in] pointer to adapter context
2512 @param pRoamInfo: [in] pointer to roam information
2513 @param eBssType : [in] type of BSS
2514
2515 @return : VOS_STATUS_SUCCESS if succssful
2516 : other values if failure
2517 ===========================================================================*/
2518VOS_STATUS hdd_wmm_assoc( hdd_adapter_t* pAdapter,
2519 tCsrRoamInfo *pRoamInfo,
2520 eCsrRoamBssType eBssType )
2521{
2522 tANI_U8 uapsdMask;
2523 VOS_STATUS status;
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002524 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002525
2526 // when we associate we need to notify TL if it needs to enable
2527 // UAPSD for any access categories
2528
2529 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002530 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002531
2532 if (pRoamInfo->fReassocReq)
2533 {
2534 // when we reassociate we should continue to use whatever
2535 // parameters were previously established. if we are
2536 // reassociating due to a U-APSD change for a particular
2537 // Access Category, then the change will be communicated
2538 // to HDD via the QoS callback associated with the given
2539 // flow, and U-APSD parameters will be updated there
2540
2541 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002542 "%s: Reassoc so no work, Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002543
2544 return VOS_STATUS_SUCCESS;
2545 }
2546
2547 // get the negotiated UAPSD Mask
2548 uapsdMask = pRoamInfo->u.pConnectedProfile->modifyProfileFields.uapsd_mask;
2549
2550 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002551 "%s: U-APSD mask is 0x%02x", __func__, (int) uapsdMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002552
2553 if (uapsdMask & HDD_AC_VO)
2554 {
2555 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2556 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2557 WLANTL_AC_VO,
2558 7,
2559 7,
2560 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv,
2561 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv,
2562 WLANTL_BI_DIR );
2563
2564 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2565 }
2566
2567 if (uapsdMask & HDD_AC_VI)
2568 {
2569 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2570 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2571 WLANTL_AC_VI,
2572 5,
2573 5,
2574 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv,
2575 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv,
2576 WLANTL_BI_DIR );
2577
2578 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2579 }
2580
2581 if (uapsdMask & HDD_AC_BK)
2582 {
2583 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2584 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2585 WLANTL_AC_BK,
2586 2,
2587 2,
2588 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv,
2589 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv,
2590 WLANTL_BI_DIR );
2591
2592 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2593 }
2594
2595 if (uapsdMask & HDD_AC_BE)
2596 {
2597 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2598 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2599 WLANTL_AC_BE,
2600 3,
2601 3,
2602 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv,
2603 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv,
2604 WLANTL_BI_DIR );
2605
2606 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2607 }
Kumar Anand82c009f2014-05-29 00:29:42 -07002608
2609 status = sme_UpdateDSCPtoUPMapping(pHddCtx->hHal,
2610 pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId);
2611
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002612 if (!VOS_IS_STATUS_SUCCESS( status ))
2613 {
Kumar Anand82c009f2014-05-29 00:29:42 -07002614 hdd_wmm_init( pAdapter );
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002615 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002616
2617 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002618 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002619
2620 return VOS_STATUS_SUCCESS;
2621}
2622
2623
2624
2625static const v_U8_t acmMaskBit[WLANTL_MAX_AC] =
2626 {
2627 0x4, /* WLANTL_AC_BK */
2628 0x8, /* WLANTL_AC_BE */
2629 0x2, /* WLANTL_AC_VI */
2630 0x1 /* WLANTL_AC_VO */
2631 };
2632
2633/**============================================================================
2634 @brief hdd_wmm_connect() - Function which will handle the housekeeping
2635 required by WMM when a connection is established
2636
2637 @param pAdapter : [in] pointer to adapter context
2638 @param pRoamInfo: [in] pointer to roam information
2639 @param eBssType : [in] type of BSS
2640
2641 @return : VOS_STATUS_SUCCESS if succssful
2642 : other values if failure
2643 ===========================================================================*/
2644VOS_STATUS hdd_wmm_connect( hdd_adapter_t* pAdapter,
2645 tCsrRoamInfo *pRoamInfo,
2646 eCsrRoamBssType eBssType )
2647{
2648 int ac;
2649 v_BOOL_t qap;
2650 v_BOOL_t qosConnection;
2651 v_U8_t acmMask;
2652
2653 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002654 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002655
2656 if ((eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) &&
2657 pRoamInfo &&
2658 pRoamInfo->u.pConnectedProfile)
2659 {
2660 qap = pRoamInfo->u.pConnectedProfile->qap;
2661 qosConnection = pRoamInfo->u.pConnectedProfile->qosConnection;
2662 acmMask = pRoamInfo->u.pConnectedProfile->acm_mask;
2663 }
2664 else
2665 {
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05302666 /* TODO: if a non-qos IBSS peer joins the group make qap and qosConnection false.
2667 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002668 qap = VOS_TRUE;
2669 qosConnection = VOS_TRUE;
2670 acmMask = 0x0;
2671 }
2672
2673 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2674 "%s: qap is %d, qosConnection is %d, acmMask is 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002675 __func__, qap, qosConnection, acmMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002676
2677 pAdapter->hddWmmStatus.wmmQap = qap;
2678 pAdapter->hddWmmStatus.wmmQosConnection = qosConnection;
2679
2680 for (ac = 0; ac < WLANTL_MAX_AC; ac++)
2681 {
2682 if (qap &&
2683 qosConnection &&
2684 (acmMask & acmMaskBit[ac]))
2685 {
2686 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2687 "%s: ac %d on",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002688 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002689
2690 // admission is required
2691 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_TRUE;
Padma, Santhosh Kumar73f22252015-05-05 11:59:24 +05302692 //Mark wmmAcAccessAllowed as True if implicit Qos is disabled as there
2693 //is no need to hold packets in queue during hdd_tx_fetch_packet_cbk
2694 if (!(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
2695 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed =
2696 VOS_TRUE;
2697 else
2698 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed =
2699 VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002700 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessGranted = VOS_FALSE;
Mukul Sharma74a01e52014-07-21 15:14:23 +05302701
2702 /* Making TSPEC invalid here so downgrading can be happen while roaming
2703 * It is expected this will be SET in hdd_wmm_sme_callback,once sme is
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302704 * done with the AddTspec.Here we avoid 11r and ccx based association.
2705 This change is done only when reassoc to different AP.
Mukul Sharma74a01e52014-07-21 15:14:23 +05302706 */
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2708 FL( "fReassocReq = %d"
2709#if defined (FEATURE_WLAN_ESE)
2710 "isESEAssoc = %d"
2711#endif
2712#if defined (WLAN_FEATURE_VOWIFI_11R)
2713 "is11rAssoc = %d"
2714#endif
2715 ),
2716 pRoamInfo->fReassocReq
2717#if defined (FEATURE_WLAN_ESE)
2718 ,pRoamInfo->isESEAssoc
2719#endif
2720#if defined (WLAN_FEATURE_VOWIFI_11R)
2721 ,pRoamInfo->is11rAssoc
2722#endif
2723 );
2724
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302725 if ( !pRoamInfo->fReassocReq
Mukul Sharma74a01e52014-07-21 15:14:23 +05302726#if defined (WLAN_FEATURE_VOWIFI_11R)
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302727 &&
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302728 !pRoamInfo->is11rAssoc
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302729#endif
Mukul Sharma74a01e52014-07-21 15:14:23 +05302730#if defined (FEATURE_WLAN_ESE)
2731 &&
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302732 !pRoamInfo->isESEAssoc
Mukul Sharma74a01e52014-07-21 15:14:23 +05302733#endif
2734 )
Mukul Sharma74a01e52014-07-21 15:14:23 +05302735 {
2736 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcTspecValid = VOS_FALSE;
2737 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002738 }
2739 else
2740 {
2741 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2742 "%s: ac %d off",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002743 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002744 // admission is not required so access is allowed
2745 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_FALSE;
2746 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_TRUE;
2747 }
2748
2749 }
2750
2751 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002752 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002753
2754 return VOS_STATUS_SUCCESS;
2755}
2756
2757/**============================================================================
2758 @brief hdd_wmm_get_uapsd_mask() - Function which will calculate the
2759 initial value of the UAPSD mask based upon the device configuration
2760
2761 @param pAdapter : [in] pointer to adapter context
2762 @param pUapsdMask: [in] pointer to where the UAPSD Mask is to be stored
2763
2764 @return : VOS_STATUS_SUCCESS if succssful
2765 : other values if failure
2766 ===========================================================================*/
2767VOS_STATUS hdd_wmm_get_uapsd_mask( hdd_adapter_t* pAdapter,
2768 tANI_U8 *pUapsdMask )
2769{
2770 tANI_U8 uapsdMask;
2771
2772 if (HDD_WMM_USER_MODE_NO_QOS == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
2773 {
2774 // no QOS then no UAPSD
2775 uapsdMask = 0;
2776 }
2777 else
2778 {
2779 // start with the default mask
2780 uapsdMask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
2781
2782 // disable UAPSD for any ACs with a 0 Service Interval
2783 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv == 0 )
2784 {
2785 uapsdMask &= ~HDD_AC_VO;
2786 }
2787
2788 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv == 0 )
2789 {
2790 uapsdMask &= ~HDD_AC_VI;
2791 }
2792
2793 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv == 0 )
2794 {
2795 uapsdMask &= ~HDD_AC_BK;
2796 }
2797
2798 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv == 0 )
2799 {
2800 uapsdMask &= ~HDD_AC_BE;
2801 }
2802 }
2803
2804 // return calculated mask
2805 *pUapsdMask = uapsdMask;
2806 return VOS_STATUS_SUCCESS;
2807}
2808
2809
2810/**============================================================================
2811 @brief hdd_wmm_is_active() - Function which will determine if WMM is
2812 active on the current connection
2813
2814 @param pAdapter : [in] pointer to adapter context
2815
2816 @return : VOS_TRUE if WMM is enabled
2817 : VOS_FALSE if WMM is not enabled
2818 ===========================================================================*/
2819v_BOOL_t hdd_wmm_is_active( hdd_adapter_t* pAdapter )
2820{
2821 if ((!pAdapter->hddWmmStatus.wmmQosConnection) ||
2822 (!pAdapter->hddWmmStatus.wmmQap))
2823 {
2824 return VOS_FALSE;
2825 }
2826 else
2827 {
2828 return VOS_TRUE;
2829 }
2830}
2831
2832/**============================================================================
2833 @brief hdd_wmm_addts() - Function which will add a traffic spec at the
2834 request of an application
2835
2836 @param pAdapter : [in] pointer to adapter context
2837 @param handle : [in] handle to uniquely identify a TS
2838 @param pTspec : [in] pointer to the traffic spec
2839
2840 @return : HDD_WLAN_WMM_STATUS_*
2841 ===========================================================================*/
2842hdd_wlan_wmm_status_e hdd_wmm_addts( hdd_adapter_t* pAdapter,
2843 v_U32_t handle,
2844 sme_QosWmmTspecInfo* pTspec )
2845{
2846 hdd_wmm_qos_context_t *pQosContext;
2847 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2848#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2849 sme_QosStatusType smeStatus;
2850#endif
2851 v_BOOL_t found = VOS_FALSE;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302852 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +05302853 hdd_context_t *pHddCtx = NULL;
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302854
2855 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302856 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302857 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2858 FL("pVosContext is NULL"));
2859 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302860 }
2861
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05302862 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
2863 if (NULL == pHddCtx)
2864 {
2865 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2866 FL("HddCtx is NULL"));
2867 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2868 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002869
2870 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002871 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002872
2873 // see if a context already exists with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302874 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002875 list_for_each_entry(pQosContext,
2876 &pAdapter->hddWmmStatus.wmmContextList,
2877 node)
2878 {
2879 if (pQosContext->handle == handle)
2880 {
2881 found = VOS_TRUE;
2882 break;
2883 }
2884 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302885 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002886 if (found)
2887 {
2888 // record with that handle already exists
2889 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2890 "%s: Record already exists with handle 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002891 __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002892
2893 /* Application is trying to modify some of the Tspec params. Allow it */
2894 smeStatus = sme_QosModifyReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2895 pTspec,
2896 pQosContext->qosFlowId);
2897
2898 // need to check the return value and act appropriately
2899 switch (smeStatus)
2900 {
2901 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
2902 status = HDD_WLAN_WMM_STATUS_MODIFY_PENDING;
2903 break;
2904 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2905 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
2906 break;
2907 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
2908 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
2909 break;
2910 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
2911 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
2912 break;
2913 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
2914 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2915 break;
2916 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2917 status = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2918 break;
2919 default:
2920 // we didn't get back one of the SME_QOS_STATUS_MODIFY_* status codes
2921 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002922 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002923 VOS_ASSERT(0);
2924 return HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2925 }
2926
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302927 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05302928 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
2929 {
2930 pQosContext->lastStatus = status;
2931 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302932 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002933 return status;
2934 }
2935
2936 pQosContext = kmalloc(sizeof(*pQosContext), GFP_KERNEL);
2937 if (NULL == pQosContext)
2938 {
2939 // no memory for QoS context. Nothing we can do
2940 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002941 "%s: Unable to allocate QoS context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002942 return HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE;
2943 }
2944
2945 // we assume the tspec has already been validated by the caller
2946
2947 pQosContext->handle = handle;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08002948 if (pTspec->ts_info.up < HDD_WMM_UP_TO_AC_MAP_SIZE)
2949 pQosContext->acType = hddWmmUpToAcMap[pTspec->ts_info.up];
2950 else {
2951 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2952 "%s: ts_info.up (%d) larger than max value (%d), "
2953 "use default acType (%d)",
2954 __func__, pTspec->ts_info.up,
2955 HDD_WMM_UP_TO_AC_MAP_SIZE - 1, hddWmmUpToAcMap[0]);
2956 pQosContext->acType = hddWmmUpToAcMap[0];
2957 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302958
Jeff Johnson295189b2012-06-20 16:38:30 -07002959 pQosContext->pAdapter = pAdapter;
2960 pQosContext->qosFlowId = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002961
2962 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2963 "%s: Setting up QoS, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002964 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002965
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302966 mutex_lock(&pHddCtx->wmmLock);
2967 pQosContext->magic = HDD_WMM_CTX_MAGIC;
Jeff Johnson295189b2012-06-20 16:38:30 -07002968 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302969 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002970
2971#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2972 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2973 pAdapter->sessionId,
2974 pTspec,
2975 hdd_wmm_sme_callback,
2976 pQosContext,
2977 pTspec->ts_info.up,
2978 &pQosContext->qosFlowId);
2979
2980 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2981 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002982 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002983
2984 // need to check the return value and act appropriately
2985 switch (smeStatus)
2986 {
2987 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
2988 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2989 break;
2990 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2991 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
2992 break;
2993 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
2994 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
2995 break;
2996 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
2997 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2998 break;
2999 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
3000 hdd_wmm_free_context(pQosContext);
3001 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
3002 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
3003 // we can't tell the difference between when a request fails because
3004 // AP rejected it versus when SME encounterd an internal error
3005 hdd_wmm_free_context(pQosContext);
3006 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
3007 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
3008 hdd_wmm_free_context(pQosContext);
3009 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
3010 default:
3011 // we didn't get back one of the SME_QOS_STATUS_SETUP_* status codes
3012 hdd_wmm_free_context(pQosContext);
3013 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003014 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07003015 VOS_ASSERT(0);
3016 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
3017 }
3018#endif
3019
3020 // we were successful, save the status
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303021 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05303022 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
3023 {
3024 pQosContext->lastStatus = status;
3025 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303026 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003027
3028 return status;
3029}
3030
3031/**============================================================================
3032 @brief hdd_wmm_delts() - Function which will delete a traffic spec at the
3033 request of an application
3034
3035 @param pAdapter : [in] pointer to adapter context
3036 @param handle : [in] handle to uniquely identify a TS
3037
3038 @return : HDD_WLAN_WMM_STATUS_*
3039 ===========================================================================*/
3040hdd_wlan_wmm_status_e hdd_wmm_delts( hdd_adapter_t* pAdapter,
3041 v_U32_t handle )
3042{
3043 hdd_wmm_qos_context_t *pQosContext;
3044 v_BOOL_t found = VOS_FALSE;
3045 WLANTL_ACEnumType acType = 0;
3046 v_U32_t qosFlowId = 0;
3047 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
3048#ifndef WLAN_MDM_CODE_REDUCTION_OPT
3049 sme_QosStatusType smeStatus;
3050#endif
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303051 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +05303052 hdd_context_t *pHddCtx = NULL;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303053
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303054 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303055 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303056 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
3057 FL("pVosContext is NULL"));
3058 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
3059 }
3060
3061 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
3062 if (NULL == pHddCtx)
3063 {
3064 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303065 FL("HddCtx is NULL"));
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303066 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303067 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003068
3069 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003070 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07003071
3072 // locate the context with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303073 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003074 list_for_each_entry(pQosContext,
3075 &pAdapter->hddWmmStatus.wmmContextList,
3076 node)
3077 {
3078 if (pQosContext->handle == handle)
3079 {
3080 found = VOS_TRUE;
3081 acType = pQosContext->acType;
3082 qosFlowId = pQosContext->qosFlowId;
3083 break;
3084 }
3085 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303086 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003087
3088 if (VOS_FALSE == found)
3089 {
3090 // we didn't find the handle
3091 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003092 "%s: handle 0x%x not found", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07003093 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
3094 }
3095
3096
3097 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
3098 "%s: found handle 0x%x, flow %d, AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003099 __func__, handle, qosFlowId, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07003100
3101#ifndef WLAN_MDM_CODE_REDUCTION_OPT
3102 smeStatus = sme_QosReleaseReq( WLAN_HDD_GET_HAL_CTX(pAdapter), qosFlowId );
3103
3104 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
3105 "%s: SME flow %d released, SME status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003106 __func__, qosFlowId, smeStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07003107
3108 switch(smeStatus)
3109 {
3110 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
3111 // this flow is the only one on that AC, so go ahead and update
3112 // our TSPEC state for the AC
3113 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcTspecValid = VOS_FALSE;
3114
3115 // need to tell TL to stop trigger timer, etc
3116 hdd_wmm_disable_tl_uapsd(pQosContext);
3117
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003118#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07003119 // disable the inactivity timer
3120 hdd_wmm_disable_inactivity_timer(pQosContext);
3121#endif
3122 // we are done with this context
3123 hdd_wmm_free_context(pQosContext);
3124
3125 // SME must not fire any more callbacks for this flow since the context
3126 // is no longer valid
3127
3128 return HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
3129
3130 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
3131 // do nothing as we will get a response from SME
3132 status = HDD_WLAN_WMM_STATUS_RELEASE_PENDING;
3133 break;
3134
3135 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
3136 // nothing we can do with the existing flow except leave it
3137 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
3138 break;
3139
3140 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
3141 // nothing we can do with the existing flow except leave it
3142 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
3143
3144 default:
3145 // we didn't get back one of the SME_QOS_STATUS_RELEASE_* status codes
3146 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003147 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07003148 VOS_ASSERT(0);
3149 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
3150 }
3151
3152#endif
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303153 mutex_lock(&pHddCtx->wmmLock);
c_hpothu48e31712014-12-23 16:59:03 +05303154 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
3155 {
3156 pQosContext->lastStatus = status;
3157 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303158 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003159 return status;
3160}
3161
3162/**============================================================================
3163 @brief hdd_wmm_checkts() - Function which will return the status of a traffic
3164 spec at the request of an application
3165
3166 @param pAdapter : [in] pointer to adapter context
3167 @param handle : [in] handle to uniquely identify a TS
3168
3169 @return : HDD_WLAN_WMM_STATUS_*
3170 ===========================================================================*/
3171hdd_wlan_wmm_status_e hdd_wmm_checkts( hdd_adapter_t* pAdapter,
3172 v_U32_t handle )
3173{
3174 hdd_wmm_qos_context_t *pQosContext;
3175 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303176 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
Ratnam Rachurib5cffcd2015-10-13 18:18:21 +05303177 hdd_context_t *pHddCtx = NULL;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303178
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303179 if (NULL == pVosContext)
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303180 {
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303181 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
3182 FL("pVosContext is NULL"));
3183 return HDD_WLAN_WMM_STATUS_LOST;
3184 }
3185
3186 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
3187 if (NULL == pHddCtx)
3188 {
3189 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303190 FL("HddCtx is NULL"));
Hema Aparna Medicharla2db83312015-03-09 15:58:21 +05303191 return HDD_WLAN_WMM_STATUS_LOST;
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303192 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003193
3194 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003195 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07003196
3197 // locate the context with the given handle
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303198 mutex_lock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003199 list_for_each_entry(pQosContext,
3200 &pAdapter->hddWmmStatus.wmmContextList,
3201 node)
3202 {
3203 if (pQosContext->handle == handle)
3204 {
3205 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
3206 "%s: found handle 0x%x, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003207 __func__, handle, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07003208
3209 status = pQosContext->lastStatus;
3210 break;
3211 }
3212 }
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05303213 mutex_unlock(&pHddCtx->wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07003214 return status;
3215}