blob: 3ae56d35321528f81630e5aa9a1ac46504e1e878 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002 * Copyright (c) 2012-2014 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
50 Copyright (c) 2008-9 QUALCOMM Incorporated.
51 All Rights Reserved.
52 Qualcomm Confidential and Proprietary
53============================================================================*/
54
55/*---------------------------------------------------------------------------
56 Include files
57 -------------------------------------------------------------------------*/
58#include <wlan_hdd_tx_rx.h>
59#include <wlan_hdd_dp_utils.h>
60#include <wlan_hdd_wmm.h>
61#include <wlan_hdd_ether.h>
62#include <linux/netdevice.h>
63#include <linux/skbuff.h>
64#include <linux/etherdevice.h>
65#include <linux/if_vlan.h>
66#include <linux/ip.h>
67#include <linux/semaphore.h>
68#include <wlan_hdd_hostapd.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070069#include <wlan_hdd_softap_tx_rx.h>
Kiet Lam40009862014-02-13 12:33:22 -080070#include <vos_sched.h>
Mukul Sharma74a01e52014-07-21 15:14:23 +053071#include "sme_Api.h"
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053072#include "sapInternal.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070073// change logging behavior based upon debug flag
74#ifdef HDD_WMM_DEBUG
75#define WMM_TRACE_LEVEL_FATAL VOS_TRACE_LEVEL_FATAL
76#define WMM_TRACE_LEVEL_ERROR VOS_TRACE_LEVEL_FATAL
77#define WMM_TRACE_LEVEL_WARN VOS_TRACE_LEVEL_FATAL
78#define WMM_TRACE_LEVEL_INFO VOS_TRACE_LEVEL_FATAL
79#define WMM_TRACE_LEVEL_INFO_HIGH VOS_TRACE_LEVEL_FATAL
80#define WMM_TRACE_LEVEL_INFO_LOW VOS_TRACE_LEVEL_FATAL
81#else
82#define WMM_TRACE_LEVEL_FATAL VOS_TRACE_LEVEL_FATAL
83#define WMM_TRACE_LEVEL_ERROR VOS_TRACE_LEVEL_ERROR
84#define WMM_TRACE_LEVEL_WARN VOS_TRACE_LEVEL_WARN
85#define WMM_TRACE_LEVEL_INFO VOS_TRACE_LEVEL_INFO
86#define WMM_TRACE_LEVEL_INFO_HIGH VOS_TRACE_LEVEL_INFO_HIGH
87#define WMM_TRACE_LEVEL_INFO_LOW VOS_TRACE_LEVEL_INFO_LOW
88#endif
89
90
Jeff Johnson295189b2012-06-20 16:38:30 -070091#define WLAN_HDD_MAX_DSCP 0x3f
92
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +053093// DHCP Port number
94#define DHCP_SOURCE_PORT 0x4400
95#define DHCP_DESTINATION_PORT 0x4300
96
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080097#define HDD_WMM_UP_TO_AC_MAP_SIZE 8
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -070098
Jeff Johnson295189b2012-06-20 16:38:30 -070099const v_U8_t hddWmmUpToAcMap[] = {
100 WLANTL_AC_BE,
101 WLANTL_AC_BK,
102 WLANTL_AC_BK,
103 WLANTL_AC_BE,
104 WLANTL_AC_VI,
105 WLANTL_AC_VI,
106 WLANTL_AC_VO,
107 WLANTL_AC_VO
108};
109
110//Linux based UP -> AC Mapping
111const v_U8_t hddLinuxUpToAcMap[8] = {
112 HDD_LINUX_AC_BE,
113 HDD_LINUX_AC_BK,
114 HDD_LINUX_AC_BK,
115 HDD_LINUX_AC_BE,
116 HDD_LINUX_AC_VI,
117 HDD_LINUX_AC_VI,
118 HDD_LINUX_AC_VO,
119 HDD_LINUX_AC_VO
120};
121
122#ifndef WLAN_MDM_CODE_REDUCTION_OPT
123/**
124 @brief hdd_wmm_enable_tl_uapsd() - function which decides whether and
125 how to update UAPSD parameters in TL
126
127 @param pQosContext : [in] the pointer the QoS instance control block
128
129 @return
130 None
131*/
132static void hdd_wmm_enable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
133{
134 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
135 WLANTL_ACEnumType acType = pQosContext->acType;
136 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
137 VOS_STATUS status;
138 v_U32_t service_interval;
139 v_U32_t suspension_interval;
140 sme_QosWmmDirType direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530141 v_BOOL_t psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700142
143
144 // The TSPEC must be valid
145 if (pAc->wmmAcTspecValid == VOS_FALSE)
146 {
147 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
148 "%s: Invoked with invalid TSPEC",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700149 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700150 return;
151 }
152
153 // determine the service interval
154 if (pAc->wmmAcTspecInfo.min_service_interval)
155 {
156 service_interval = pAc->wmmAcTspecInfo.min_service_interval;
157 }
158 else if (pAc->wmmAcTspecInfo.max_service_interval)
159 {
160 service_interval = pAc->wmmAcTspecInfo.max_service_interval;
161 }
162 else
163 {
164 // no service interval is present in the TSPEC
165 // this is OK, there just won't be U-APSD
166 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
167 "%s: No service interval supplied",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700168 __func__);
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530169 service_interval = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700170 }
171
172 // determine the suspension interval & direction
173 suspension_interval = pAc->wmmAcTspecInfo.suspension_interval;
174 direction = pAc->wmmAcTspecInfo.ts_info.direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530175 psb = pAc->wmmAcTspecInfo.ts_info.psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700176
177 // if we have previously enabled U-APSD, have any params changed?
178 if ((pAc->wmmAcUapsdInfoValid) &&
179 (pAc->wmmAcUapsdServiceInterval == service_interval) &&
180 (pAc->wmmAcUapsdSuspensionInterval == suspension_interval) &&
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530181 (pAc->wmmAcUapsdDirection == direction) &&
182 (pAc->wmmAcIsUapsdEnabled == psb))
Jeff Johnson295189b2012-06-20 16:38:30 -0700183 {
184 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
185 "%s: No change in U-APSD parameters",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700186 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700187 return;
188 }
189
190 // are we in the appropriate power save modes?
191 if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_BEACON_MODE_POWER_SAVE))
192 {
193 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
194 "%s: BMPS is not enabled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700195 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700196 return;
197 }
198
199 if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_UAPSD_MODE_POWER_SAVE))
200 {
201 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
202 "%s: U-APSD is not enabled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700203 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700204 return;
205 }
206
207 // everything is in place to notify TL
208 status = WLANTL_EnableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
209 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
210 acType,
211 pAc->wmmAcTspecInfo.ts_info.tid,
212 pAc->wmmAcTspecInfo.ts_info.up,
213 service_interval,
214 suspension_interval,
215 direction);
216
217 if ( !VOS_IS_STATUS_SUCCESS( status ) )
218 {
219 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
220 "%s: Failed to enable U-APSD for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700221 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700222 return;
223 }
224
225 // stash away the parameters that were used
226 pAc->wmmAcUapsdInfoValid = VOS_TRUE;
227 pAc->wmmAcUapsdServiceInterval = service_interval;
228 pAc->wmmAcUapsdSuspensionInterval = suspension_interval;
229 pAc->wmmAcUapsdDirection = direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530230 pAc->wmmAcIsUapsdEnabled = psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700231
232 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700233 "%s: Enabled UAPSD in TL srv_int=%d "
234 "susp_int=%d dir=%d AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700235 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700236 service_interval,
237 suspension_interval,
238 direction,
239 acType);
240
241}
242
243/**
244 @brief hdd_wmm_disable_tl_uapsd() - function which decides whether
245 to disable UAPSD parameters in TL
246
247 @param pQosContext : [in] the pointer the QoS instance control block
248
249 @return
250 None
251*/
252static void hdd_wmm_disable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
253{
254 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
255 WLANTL_ACEnumType acType = pQosContext->acType;
256 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
257 VOS_STATUS status;
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530258 v_U32_t service_interval;
259 v_U32_t suspension_interval;
260 v_U8_t uapsd_mask;
261 v_U8_t ActiveTspec = INVALID_TSPEC;
Jeff Johnson295189b2012-06-20 16:38:30 -0700262
263 // have we previously enabled UAPSD?
264 if (pAc->wmmAcUapsdInfoValid == VOS_TRUE)
265 {
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530266 uapsd_mask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
Jeff Johnson295189b2012-06-20 16:38:30 -0700267
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530268 //Finding uapsd_mask as per AC
269 uapsd_mask = uapsd_mask & (1 << (WLANTL_AC_VO - acType));
270
271 sme_QosTspecActive((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter), acType,
272 pAdapter->sessionId, &ActiveTspec);
273
274 //Call WLANTL_EnableUAPSDForAC only when static uapsd mask is present and
275 // no active tspecs. TODO: Need to change naming convention as Enable
276 // UAPSD function is called in hdd_wmm_disable_tl_uapsd. Purpose of
277 // calling WLANTL_EnableUAPSDForAC is to update UAPSD intervals to fw
278
279 if(uapsd_mask && !ActiveTspec)
Jeff Johnson295189b2012-06-20 16:38:30 -0700280 {
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530281 switch(acType)
282 {
283 case WLANTL_AC_VO:
284 service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv;
285 suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv;
286 break;
287 case WLANTL_AC_VI:
288 service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv;
289 suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv;
290 break;
291 case WLANTL_AC_BE:
292 service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv;
293 suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv;
294 break;
295 case WLANTL_AC_BK:
296 service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv;
297 suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv;
298 break;
299 }
300
301 status = WLANTL_EnableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
302 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
303 acType,
304 pAc->wmmAcTspecInfo.ts_info.tid,
305 pAc->wmmAcTspecInfo.ts_info.up,
306 service_interval,
307 suspension_interval,
308 pAc->wmmAcTspecInfo.ts_info.direction);
309
310 if ( !VOS_IS_STATUS_SUCCESS( status ) )
311 {
312 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
313 "%s: Failed to update U-APSD params for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700314 __func__, acType );
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530315 }
316 else
317 {
318 // TL no longer has valid UAPSD info
319 pAc->wmmAcUapsdInfoValid = VOS_FALSE;
320 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
321 "%s: Updated UAPSD params in TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700322 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 acType);
Padma, Santhosh Kumar859d3712014-11-13 18:00:41 +0530324 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700325 }
326 }
327}
328
329#endif
330
331/**
332 @brief hdd_wmm_free_context() - function which frees a QoS context
333
334 @param pQosContext : [in] the pointer the QoS instance control block
335
336 @return
337 None
338*/
339static void hdd_wmm_free_context (hdd_wmm_qos_context_t* pQosContext)
340{
341 hdd_adapter_t* pAdapter;
342
343 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
344 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700345 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700346
347 if (unlikely((NULL == pQosContext) ||
348 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
349 {
350 // must have been freed in another thread
351 return;
352 }
353
354 // get pointer to the adapter context
355 pAdapter = pQosContext->pAdapter;
356
357 // take the wmmLock since we're manipulating the context list
358 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
359
360 // make sure nobody thinks this is a valid context
361 pQosContext->magic = 0;
362
363 // unlink the context
364 list_del(&pQosContext->node);
365
366 // done manipulating the list
367 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
368
369 // reclaim memory
370 kfree(pQosContext);
371
372}
373
374#ifndef WLAN_MDM_CODE_REDUCTION_OPT
375/**
376 @brief hdd_wmm_notify_app() - function which notifies an application
377 changes in state of it flow
378
379 @param pQosContext : [in] the pointer the QoS instance control block
380
381 @return
382 None
383*/
384#define MAX_NOTIFY_LEN 50
385static void hdd_wmm_notify_app (hdd_wmm_qos_context_t* pQosContext)
386{
387 hdd_adapter_t* pAdapter;
388 union iwreq_data wrqu;
389 char buf[MAX_NOTIFY_LEN+1];
390
391 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
392 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700393 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700394
395 if (unlikely((NULL == pQosContext) ||
396 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
397 {
398 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
399 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700400 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700401 return;
402 }
403
404
405 // create the event
406 memset(&wrqu, 0, sizeof(wrqu));
407 memset(buf, 0, sizeof(buf));
408
409 snprintf(buf, MAX_NOTIFY_LEN, "QCOM: TS change[%u: %u]",
410 (unsigned int)pQosContext->handle,
411 (unsigned int)pQosContext->lastStatus);
412
413 wrqu.data.pointer = buf;
414 wrqu.data.length = strlen(buf);
415
416 // get pointer to the adapter
417 pAdapter = pQosContext->pAdapter;
418
419 // send the event
420 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700421 "%s: Sending [%s]", __func__, buf);
Jeff Johnson295189b2012-06-20 16:38:30 -0700422 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
423}
424
425
426/**
427 @brief hdd_wmm_is_access_allowed() - function which determines if access
428 is allowed for the given AC. this is designed to be called during SME
429 callback processing since that is when access can be granted or removed
430
431 @param pAdapter : [in] pointer to adapter context
432 @param pAc : [in] pointer to the per-AC status
433
434 @return : VOS_TRUE - access is allowed
435 : VOS_FALSE - access is not allowed
436 None
437*/
438static v_BOOL_t hdd_wmm_is_access_allowed(hdd_adapter_t* pAdapter,
439 hdd_wmm_ac_status_t* pAc)
440{
441 // if we don't want QoS or the AP doesn't support QoS
442 // or we don't want to do implicit QoS
443 // or if AP doesn't require admission for this AC
444 // then we have access
445 if (!hdd_wmm_is_active(pAdapter) ||
446 !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled ||
447 !pAc->wmmAcAccessRequired)
448 {
449 return VOS_TRUE;
450 }
451
452 // if implicit QoS has already completed, successfully or not,
453 // then access is allowed
454 if (pAc->wmmAcAccessGranted || pAc->wmmAcAccessFailed)
455 {
456 return VOS_TRUE;
457 }
458
459 // admission is required and implicit QoS hasn't completed
460 // however explicit QoS may have completed and we'll have
461 // a Tspec
462 // if we don't have a Tspec then access is not allowed
463 if (!pAc->wmmAcTspecValid)
464 {
465 return VOS_FALSE;
466 }
467
468 // we have a Tspec -- does it allow upstream or bidirectional traffic?
469 // if it only allows downstream traffic then access is not allowed
470 if (pAc->wmmAcTspecInfo.ts_info.direction == SME_QOS_WMM_TS_DIR_DOWNLINK)
471 {
472 return VOS_FALSE;
473 }
474
475 // we meet all of the criteria for access
476 return VOS_TRUE;
477}
478
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800479#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700480/**
481 @brief hdd_wmm_inactivity_timer_cb() - timer handler function which is
482 called for every inactivity interval per AC. This function gets the
483 current transmitted packets on the given AC, and checks if there where
484 any TX activity from the previous interval. If there was no traffic
485 then it would delete the TS that was negotiated on that AC.
486
487 @param pUserData : [in] pointer to pQosContext
488
489 @return : NONE
490*/
491void hdd_wmm_inactivity_timer_cb( v_PVOID_t pUserData )
492{
493 hdd_wmm_qos_context_t* pQosContext = (hdd_wmm_qos_context_t*)pUserData;
494 hdd_adapter_t* pAdapter;
495 hdd_wmm_ac_status_t *pAc;
496 hdd_wlan_wmm_status_e status;
497 VOS_STATUS vos_status;
498 v_U32_t currentTrafficCnt = 0;
499 WLANTL_ACEnumType acType = pQosContext->acType;
500
501 pAdapter = pQosContext->pAdapter;
502 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
503
504 // Get the Tx stats for this AC.
505 currentTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];
506
507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800508 FL("WMM inactivity Timer for AC=%d, currentCnt=%d, prevCnt=%d"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700509 acType, (int)currentTrafficCnt, (int)pAc->wmmPrevTrafficCnt);
510 if (pAc->wmmPrevTrafficCnt == currentTrafficCnt)
511 {
512 // If there is no traffic activity, delete the TSPEC for this AC
513 status = hdd_wmm_delts(pAdapter, pQosContext->handle);
514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
515 FL("Deleted TS on AC %d, due to inactivity with status = %d!!!"),
516 acType, status);
517 }
518 else
519 {
520 pAc->wmmPrevTrafficCnt = currentTrafficCnt;
521 if (pAc->wmmInactivityTimer.state == VOS_TIMER_STATE_STOPPED)
522 {
523 // Restart the timer
524 vos_status = vos_timer_start(&pAc->wmmInactivityTimer, pAc->wmmInactivityTime);
525 if (!VOS_IS_STATUS_SUCCESS(vos_status))
526 {
527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
528 FL("Restarting inactivity timer failed on AC %d"), acType);
529 }
530 }
531 else
532 {
533 VOS_ASSERT(vos_timer_getCurrentState(
534 &pAc->wmmInactivityTimer) == VOS_TIMER_STATE_STOPPED);
535 }
536 }
537
538 return;
539}
540
541
542/**
543 @brief hdd_wmm_enable_inactivity_timer() - function to enable the
544 traffic inactivity timer for the given AC, if the inactivity_interval
545 specified in the ADDTS parameters is non-zero
546
547 @param pQosContext : [in] pointer to pQosContext
548 @param inactivityTime: [in] value of the inactivity interval in millisecs
549
550 @return : VOS_STATUS_E_FAILURE
551 VOS_STATUS_SUCCESS
552*/
553VOS_STATUS hdd_wmm_enable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext, v_U32_t inactivityTime)
554{
555 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
556 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
557 WLANTL_ACEnumType acType = pQosContext->acType;
558 hdd_wmm_ac_status_t *pAc;
559
560 pAdapter = pQosContext->pAdapter;
561 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
562
563
564 // If QoS-Tspec is successfully setup and if the inactivity timer is non-zero,
565 // a traffic inactivity timer needs to be started for the given AC
566 vos_status = vos_timer_init(
567 &pAc->wmmInactivityTimer,
568 VOS_TIMER_TYPE_SW,
569 hdd_wmm_inactivity_timer_cb,
570 (v_PVOID_t)pQosContext );
571 if ( !VOS_IS_STATUS_SUCCESS(vos_status))
572 {
573 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
574 FL("Initializing inactivity timer failed on AC %d"), acType);
575 return vos_status;
576 }
577
578 // Start the inactivity timer
579 vos_status = vos_timer_start(
580 &pAc->wmmInactivityTimer,
581 inactivityTime);
582 if ( !VOS_IS_STATUS_SUCCESS(vos_status))
583 {
584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
585 FL("Starting inactivity timer failed on AC %d"), acType);
586 return vos_status;
587 }
588 pAc->wmmInactivityTime = inactivityTime;
589 // Initialize the current tx traffic count on this AC
590 pAc->wmmPrevTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];
591
592 return vos_status;
593}
594
595/**
596 @brief hdd_wmm_enable_inactivity_timer() - function to disable the
597 traffic inactivity timer for the given AC. This would be called when
598 deleting the TS.
599
600 @param pQosContext : [in] pointer to pQosContext
601
602 @return : VOS_STATUS_E_FAILURE
603 VOS_STATUS_SUCCESS
604*/
605VOS_STATUS hdd_wmm_disable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext)
606{
607 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
608 WLANTL_ACEnumType acType = pQosContext->acType;
609 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
610 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
611
612 // Clear the timer and the counter
613 pAc->wmmInactivityTime = 0;
614 pAc->wmmPrevTrafficCnt = 0;
615 vos_timer_stop(&pAc->wmmInactivityTimer);
616 vos_status = vos_timer_destroy(&pAc->wmmInactivityTimer);
617
618 return vos_status;
619}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800620#endif // FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700621
622/**
623 @brief hdd_wmm_sme_callback() - callback registered by HDD with SME for receiving
624 QoS notifications. Even though this function has a static scope it gets called
625 externally through some function pointer magic (so there is a need for
626 rigorous parameter checking)
627
628 @param hHal : [in] the HAL handle
629 @param HddCtx : [in] the HDD specified handle
630 @param pCurrentQosInfo : [in] the TSPEC params
631 @param SmeStatus : [in] the QoS related SME status
632
633 @return
634 eHAL_STATUS_SUCCESS if all good, eHAL_STATUS_FAILURE otherwise
635*/
636static eHalStatus hdd_wmm_sme_callback (tHalHandle hHal,
637 void * hddCtx,
638 sme_QosWmmTspecInfo* pCurrentQosInfo,
639 sme_QosStatusType smeStatus,
640 v_U32_t qosFlowId)
641{
642 hdd_wmm_qos_context_t* pQosContext = hddCtx;
643 hdd_adapter_t* pAdapter;
644 WLANTL_ACEnumType acType;
645 hdd_wmm_ac_status_t *pAc;
646 VOS_STATUS status;
647
648 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
649 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700650 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700651
652 if (unlikely((NULL == pQosContext) ||
653 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
654 {
655 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
656 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700657 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700658 return eHAL_STATUS_FAILURE;
659 }
660
661 pAdapter = pQosContext->pAdapter;
662 acType = pQosContext->acType;
663 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
664
665 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
666 "%s: status %d flowid %d info %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700667 __func__, smeStatus, qosFlowId, pCurrentQosInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -0700668
669 switch (smeStatus)
670 {
671
672 case SME_QOS_STATUS_SETUP_SUCCESS_IND:
673 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
674 "%s: Setup is complete",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700675 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700676
677 // there will always be a TSPEC returned with this status, even if
678 // a TSPEC is not exchanged OTA
679 if (pCurrentQosInfo)
680 {
681 pAc->wmmAcTspecValid = VOS_TRUE;
682 memcpy(&pAc->wmmAcTspecInfo,
683 pCurrentQosInfo,
684 sizeof(pAc->wmmAcTspecInfo));
685 }
686
687 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
688 {
689
690 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
691 "%s: Implicit Qos, notifying TL for TL AC %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700692 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700693
694 // this was triggered by implicit QoS so we know packets are pending
695 // update state
696 pAc->wmmAcAccessAllowed = VOS_TRUE;
697 pAc->wmmAcAccessGranted = VOS_TRUE;
698 pAc->wmmAcAccessPending = VOS_FALSE;
699
700 // notify TL that packets are pending
701 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
702 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
703 acType );
704
705 if ( !VOS_IS_STATUS_SUCCESS( status ) )
706 {
707 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
708 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700709 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700710 }
711 }
712 else
713 {
714 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
715 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700716 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700717
718 // this was triggered by an application
719 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
720 hdd_wmm_notify_app(pQosContext);
721 }
722
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800723#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700724 // Check if the inactivity interval is specified
Jeff Johnson8795e422013-04-03 08:59:22 -0700725 if (pCurrentQosInfo && pCurrentQosInfo->inactivity_interval) {
Jeff Johnson295189b2012-06-20 16:38:30 -0700726 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800727 "%s: Inactivity timer value = %d for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700728 __func__, pCurrentQosInfo->inactivity_interval, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700729 hdd_wmm_enable_inactivity_timer(pQosContext, pCurrentQosInfo->inactivity_interval);
730 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800731#endif // FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700732
733 // notify TL to enable trigger frames if necessary
734 hdd_wmm_enable_tl_uapsd(pQosContext);
735
736 break;
737
738 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
739 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
740 "%s: Setup is complete (U-APSD set previously)",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700741 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700742
743 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
744 {
745
746 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
747 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700748 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700749
750 // this was triggered by implicit QoS so we know packets are pending
751 // update state
752 pAc->wmmAcAccessAllowed = VOS_TRUE;
753 pAc->wmmAcAccessGranted = VOS_TRUE;
754 pAc->wmmAcAccessPending = VOS_FALSE;
755
756 // notify TL that packets are pending
757 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
758 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
759 acType );
760
761 if ( !VOS_IS_STATUS_SUCCESS( status ) )
762 {
763 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
764 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700765 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700766 }
767 }
768 else
769 {
770 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
771 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700772 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700773
774 // this was triggered by an application
775 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
776 hdd_wmm_notify_app(pQosContext);
777 }
778
779 break;
780
781 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
782 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
783 "%s: Setup failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700784 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700785 // QoS setup failed
786
787 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
788 {
789
790 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
791 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700792 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700793
794 // we note the failure, but we also mark access as allowed so that
795 // the packets will flow. Note that the MAC will "do the right thing"
796 pAc->wmmAcAccessPending = VOS_FALSE;
797 pAc->wmmAcAccessFailed = VOS_TRUE;
798 pAc->wmmAcAccessAllowed = VOS_TRUE;
799
800 // this was triggered by implicit QoS so we know packets are pending
801 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
802 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
803 acType );
804
805 if ( !VOS_IS_STATUS_SUCCESS( status ) )
806 {
807 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
808 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700809 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700810 }
811 }
812 else
813 {
814 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
815 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700816 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700817
818 // this was triggered by an application
819 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED;
820 hdd_wmm_notify_app(pQosContext);
821 }
822
823 /* Setting up QoS Failed, QoS context can be released.
824 * SME is releasing this flow information and if HDD doen't release this context,
825 * next time if application uses the same handle to set-up QoS, HDD (as it has
826 * QoS context for this handle) will issue Modify QoS request to SME but SME will
827 * reject as no it has no information for this flow.
828 */
829 hdd_wmm_free_context(pQosContext);
830 break;
831
832 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
833 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
834 "%s: Setup Invalid Params, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700835 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700836 // QoS setup failed
837
838 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
839 {
840
841 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
842 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700843 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700844
845 // we note the failure, but we also mark access as allowed so that
846 // the packets will flow. Note that the MAC will "do the right thing"
847 pAc->wmmAcAccessPending = VOS_FALSE;
848 pAc->wmmAcAccessFailed = VOS_TRUE;
849 pAc->wmmAcAccessAllowed = VOS_TRUE;
850
851 // this was triggered by implicit QoS so we know packets are pending
852 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
853 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
854 acType );
855
856 if ( !VOS_IS_STATUS_SUCCESS( status ) )
857 {
858 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
859 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700860 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700861 }
862 }
863 else
864 {
865 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
866 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700867 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700868
869 // this was triggered by an application
870 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
871 hdd_wmm_notify_app(pQosContext);
872 }
873 break;
874
875 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
876 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800877 "%s: Setup failed, not a QoS AP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700878 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700879 if (!HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
880 {
881 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
882 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700883 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700884
885 // this was triggered by an application
886 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
887 hdd_wmm_notify_app(pQosContext);
888 }
889 break;
890
891 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
892 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
893 "%s: Setup pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700894 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700895 // not a callback status -- ignore if we get it
896 break;
897
898 case SME_QOS_STATUS_SETUP_MODIFIED_IND:
899 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
900 "%s: Setup modified",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700901 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700902 if (pCurrentQosInfo)
903 {
904 // update the TSPEC
905 pAc->wmmAcTspecValid = VOS_TRUE;
906 memcpy(&pAc->wmmAcTspecInfo,
907 pCurrentQosInfo,
908 sizeof(pAc->wmmAcTspecInfo));
909
910 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
911 {
912 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
913 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700914 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700915
916 // this was triggered by an application
917 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFIED;
918 hdd_wmm_notify_app(pQosContext);
919 }
920
921 // need to tell TL to update its UAPSD handling
922 hdd_wmm_enable_tl_uapsd(pQosContext);
923 }
924 break;
925
926 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
927 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
928 {
929
930 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
931 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700932 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700933
934 // this was triggered by implicit QoS so we know packets are pending
935 pAc->wmmAcAccessPending = VOS_FALSE;
936 pAc->wmmAcAccessGranted = VOS_TRUE;
937 pAc->wmmAcAccessAllowed = VOS_TRUE;
938
939 // notify TL that packets are pending
940 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
941 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
942 acType );
943
944 if ( !VOS_IS_STATUS_SUCCESS( status ) )
945 {
946 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
947 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700948 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700949 }
950 }
951 else
952 {
953 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
954 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700955 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700956
957 // this was triggered by an application
958 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
959 hdd_wmm_notify_app(pQosContext);
960 }
961 break;
962
963 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
964 // nothing to do for now
965 break;
966
967 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED:
968 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
969 "%s: Setup successful but U-APSD failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700970 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700971
972 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
973 {
974
975 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
976 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700977 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700978
979 // QoS setup was successful but setting U=APSD failed
980 // Since the OTA part of the request was successful, we don't mark
981 // this as a failure.
982 // the packets will flow. Note that the MAC will "do the right thing"
983 pAc->wmmAcAccessGranted = VOS_TRUE;
984 pAc->wmmAcAccessAllowed = VOS_TRUE;
985 pAc->wmmAcAccessFailed = VOS_FALSE;
986 pAc->wmmAcAccessPending = VOS_FALSE;
987
988 // this was triggered by implicit QoS so we know packets are pending
989 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
990 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
991 acType );
992
993 if ( !VOS_IS_STATUS_SUCCESS( status ) )
994 {
995 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
996 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700997 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700998 }
999 }
1000 else
1001 {
1002 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1003 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001004 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001005
1006 // this was triggered by an application
1007 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_UAPSD_SET_FAILED;
1008 hdd_wmm_notify_app(pQosContext);
1009 }
1010
1011 // Since U-APSD portion failed disabled trigger frame generation
1012 hdd_wmm_disable_tl_uapsd(pQosContext);
1013
1014 break;
1015
1016 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
1017 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1018 "%s: Release is complete",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001019 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001020
1021 if (pCurrentQosInfo)
1022 {
1023 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1024 "%s: flows still active",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001025 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001026
1027 // there is still at least one flow active for this AC
1028 // so update the AC state
1029 memcpy(&pAc->wmmAcTspecInfo,
1030 pCurrentQosInfo,
1031 sizeof(pAc->wmmAcTspecInfo));
1032
1033 // need to tell TL to update its UAPSD handling
1034 hdd_wmm_enable_tl_uapsd(pQosContext);
1035 }
1036 else
1037 {
1038 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1039 "%s: last flow",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001040 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001041
1042 // this is the last flow active for this AC so update the AC state
1043 pAc->wmmAcTspecValid = VOS_FALSE;
1044
1045 // need to tell TL to update its UAPSD handling
1046 hdd_wmm_disable_tl_uapsd(pQosContext);
1047 }
1048
1049 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1050 {
1051 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1052 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001053 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001054
1055 // this was triggered by an application
1056 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
1057 hdd_wmm_notify_app(pQosContext);
1058 }
1059
1060 // we are done with this flow
1061 hdd_wmm_free_context(pQosContext);
1062 break;
1063
1064 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
1065 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1066 "%s: Release failure",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001067 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001068
1069 // we don't need to update our state or TL since nothing has changed
1070 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1071 {
1072 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1073 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001074 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001075
1076 // this was triggered by an application
1077 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
1078 hdd_wmm_notify_app(pQosContext);
1079 }
1080
1081 break;
1082
1083 case SME_QOS_STATUS_RELEASE_QOS_LOST_IND:
1084 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1085 "%s: QOS Lost indication received",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001086 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001087
1088 // current TSPEC is no longer valid
1089 pAc->wmmAcTspecValid = VOS_FALSE;
1090
1091 // need to tell TL to update its UAPSD handling
1092 hdd_wmm_disable_tl_uapsd(pQosContext);
1093
1094 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
1095 {
1096 // we no longer have implicit access granted
1097 pAc->wmmAcAccessGranted = VOS_FALSE;
1098 pAc->wmmAcAccessFailed = VOS_FALSE;
1099 }
1100 else
1101 {
1102 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1103 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001104 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001105
1106 // this was triggered by an application
1107 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_LOST;
1108 hdd_wmm_notify_app(pQosContext);
1109 }
1110
1111 // we are done with this flow
1112 hdd_wmm_free_context(pQosContext);
1113 break;
1114
1115 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
1116 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1117 "%s: Release pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001118 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001119 // not a callback status -- ignore if we get it
1120 break;
1121
1122 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
1123 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1124 "%s: Release Invalid Params",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001125 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001126 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1127 {
1128 // this was triggered by an application
1129 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
1130 hdd_wmm_notify_app(pQosContext);
1131 }
1132 break;
1133
1134 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND:
1135 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1136 "%s: Modification is complete, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001137 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001138
1139 // there will always be a TSPEC returned with this status, even if
1140 // a TSPEC is not exchanged OTA
1141 if (pCurrentQosInfo)
1142 {
1143 pAc->wmmAcTspecValid = VOS_TRUE;
1144 memcpy(&pAc->wmmAcTspecInfo,
1145 pCurrentQosInfo,
1146 sizeof(pAc->wmmAcTspecInfo));
1147 }
1148
1149 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1150 {
1151 // this was triggered by an application
1152 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS;
1153 hdd_wmm_notify_app(pQosContext);
1154 }
1155
1156 // notify TL to enable trigger frames if necessary
1157 hdd_wmm_enable_tl_uapsd(pQosContext);
1158
1159 break;
1160
1161 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
1162 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1163 {
1164 // this was triggered by an application
1165 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
1166 hdd_wmm_notify_app(pQosContext);
1167 }
1168 break;
1169
1170 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
1171 // the flow modification failed so we'll leave in place
1172 // whatever existed beforehand
1173
1174 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1175 {
1176 // this was triggered by an application
1177 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
1178 hdd_wmm_notify_app(pQosContext);
1179 }
1180 break;
1181
1182 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
1183 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1184 "%s: modification pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001185 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001186 // not a callback status -- ignore if we get it
1187 break;
1188
1189 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1190 // the flow modification was successful but no QoS changes required
1191
1192 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1193 {
1194 // this was triggered by an application
1195 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
1196 hdd_wmm_notify_app(pQosContext);
1197 }
1198 break;
1199
1200 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
1201 // invalid params -- notify the application
1202 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1203 {
1204 // this was triggered by an application
1205 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
1206 hdd_wmm_notify_app(pQosContext);
1207 }
1208 break;
1209
1210 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_PENDING:
1211 // nothing to do for now. when APSD is established we'll have work to do
1212 break;
1213
1214 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED:
1215 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1216 "%s: Modify successful but U-APSD failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001217 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001218
1219 // QoS modification was successful but setting U=APSD failed.
1220 // This will always be an explicit QoS instance, so all we can
1221 // do is notify the application and let it clean up.
1222 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1223 {
1224 // this was triggered by an application
1225 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_UAPSD_SET_FAILED;
1226 hdd_wmm_notify_app(pQosContext);
1227 }
1228
1229 // Since U-APSD portion failed disabled trigger frame generation
1230 hdd_wmm_disable_tl_uapsd(pQosContext);
1231
1232 break;
1233
1234 case SME_QOS_STATUS_HANDING_OFF:
1235 // no roaming so we won't see this
1236 break;
1237
1238 case SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND:
1239 // need to tell TL to stop trigger frame generation
1240 hdd_wmm_disable_tl_uapsd(pQosContext);
1241 break;
1242
1243 case SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND:
1244 // need to tell TL to start sending trigger frames again
1245 hdd_wmm_enable_tl_uapsd(pQosContext);
1246 break;
1247
1248 default:
1249 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001250 "%s: unexpected SME Status=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001251 __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07001252 VOS_ASSERT(0);
1253 }
1254
1255 // our access to the particular access category may have changed.
1256 // some of the implicit QoS cases above may have already set this
1257 // prior to invoking TL (so that we will properly service the
1258 // Tx queues) but let's consistently handle all cases here
1259 pAc->wmmAcAccessAllowed = hdd_wmm_is_access_allowed(pAdapter, pAc);
1260
1261 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1262 "%s: complete, access for TL AC %d is%sallowed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001263 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001264 acType,
1265 pAc->wmmAcAccessAllowed ? " " : " not ");
1266
1267 return eHAL_STATUS_SUCCESS;
1268}
1269#endif
1270
Kiet Lamf040f472013-11-20 21:15:23 +05301271/**========================================================================
1272 @brief hdd_wmmps_helper() - Function to set uapsd psb dynamically
1273
1274 @param pAdapter : [in] pointer to adapter structure
1275
1276 @param ptr : [in] pointer to command buffer
1277
1278 @return : Zero on success, appropriate error on failure.
1279 =======================================================================*/
1280int hdd_wmmps_helper(hdd_adapter_t *pAdapter, tANI_U8 *ptr)
1281{
1282 if (NULL == pAdapter)
1283 {
1284 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1285 "%s: pAdapter is NULL", __func__);
1286 return -EINVAL;
1287 }
1288 if (NULL == ptr)
1289 {
1290 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1291 "%s: ptr is NULL", __func__);
1292 return -EINVAL;
1293 }
1294 /* convert ASCII to integer */
1295 pAdapter->configuredPsb = ptr[9] - '0';
1296 pAdapter->psbChanged = HDD_PSB_CHANGED;
1297
1298 return 0;
1299}
1300
Jeff Johnson295189b2012-06-20 16:38:30 -07001301/**============================================================================
1302 @brief hdd_wmm_do_implicit_qos() - Function which will attempt to setup
1303 QoS for any AC requiring it
1304
1305 @param work : [in] pointer to work structure
1306
1307 @return : void
1308 ===========================================================================*/
1309static void hdd_wmm_do_implicit_qos(struct work_struct *work)
1310{
1311 hdd_wmm_qos_context_t* pQosContext =
1312 container_of(work, hdd_wmm_qos_context_t, wmmAcSetupImplicitQos);
1313 hdd_adapter_t* pAdapter;
1314 WLANTL_ACEnumType acType;
1315 hdd_wmm_ac_status_t *pAc;
1316#ifndef WLAN_MDM_CODE_REDUCTION_OPT
1317 VOS_STATUS status;
1318 sme_QosStatusType smeStatus;
1319#endif
1320 sme_QosWmmTspecInfo qosInfo;
1321
1322 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1323 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001324 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001325
1326 if (unlikely(HDD_WMM_CTX_MAGIC != pQosContext->magic))
1327 {
1328 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1329 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001330 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001331 return;
1332 }
1333
1334 pAdapter = pQosContext->pAdapter;
1335 acType = pQosContext->acType;
1336 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1337
1338 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1339 "%s: pAdapter %p acType %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001340 __func__, pAdapter, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001341
1342 if (!pAc->wmmAcAccessNeeded)
1343 {
1344 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1345 "%s: AC %d doesn't need service",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001346 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001347 pQosContext->magic = 0;
1348 kfree(pQosContext);
1349 return;
1350 }
1351
1352 pAc->wmmAcAccessPending = VOS_TRUE;
1353 pAc->wmmAcAccessNeeded = VOS_FALSE;
1354
1355 memset(&qosInfo, 0, sizeof(qosInfo));
1356
Kiet Lamf040f472013-11-20 21:15:23 +05301357 qosInfo.ts_info.psb = pAdapter->configuredPsb;
1358
Jeff Johnson295189b2012-06-20 16:38:30 -07001359 switch (acType)
1360 {
1361 case WLANTL_AC_VO:
1362 qosInfo.ts_info.up = SME_QOS_WMM_UP_VO;
Kiet Lamf040f472013-11-20 21:15:23 +05301363 /* Check if there is any valid configuration from framework */
1364 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1365 {
1366 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1367 SME_QOS_UAPSD_VO) ? 1 : 0;
1368 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001369 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVo;
1370 qosInfo.ts_info.tid = 255;
1371 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVo;
1372 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVo;
1373 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv;
1374 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVo;
1375 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVo;
1376 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv;
1377 break;
1378 case WLANTL_AC_VI:
1379 qosInfo.ts_info.up = SME_QOS_WMM_UP_VI;
Kiet Lamf040f472013-11-20 21:15:23 +05301380 /* Check if there is any valid configuration from framework */
1381 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1382 {
1383 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1384 SME_QOS_UAPSD_VI) ? 1 : 0;
1385 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001386 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVi;
1387 qosInfo.ts_info.tid = 255;
1388 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVi;
1389 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVi;
1390 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv;
1391 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVi;
1392 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVi;
1393 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv;
1394 break;
1395 default:
1396 case WLANTL_AC_BE:
1397 qosInfo.ts_info.up = SME_QOS_WMM_UP_BE;
Kiet Lamf040f472013-11-20 21:15:23 +05301398 /* Check if there is any valid configuration from framework */
1399 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1400 {
1401 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1402 SME_QOS_UAPSD_BE) ? 1 : 0;
1403 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001404 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBe;
1405 qosInfo.ts_info.tid = 255;
1406 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBe;
1407 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBe;
1408 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv;
1409 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBe;
1410 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBe;
1411 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv;
1412 break;
1413 case WLANTL_AC_BK:
1414 qosInfo.ts_info.up = SME_QOS_WMM_UP_BK;
Kiet Lamf040f472013-11-20 21:15:23 +05301415 /* Check if there is any valid configuration from framework */
1416 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1417 {
1418 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1419 SME_QOS_UAPSD_BK) ? 1 : 0;
1420 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001421 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBk;
1422 qosInfo.ts_info.tid = 255;
1423 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBk;
1424 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBk;
1425 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv;
1426 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBk;
1427 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBk;
1428 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv;
1429 break;
1430 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08001431#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07001432 qosInfo.inactivity_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraInactivityInterval;
1433#endif
1434 qosInfo.ts_info.burst_size_defn = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->burstSizeDefinition;
1435
1436 switch ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->tsInfoAckPolicy)
1437 {
1438 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK:
1439 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1440 break;
1441
1442 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
1443 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
1444 break;
1445
1446 default:
1447 // unknown
1448 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1449 }
1450
1451 if(qosInfo.ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK)
1452 {
1453 if(!sme_QosIsTSInfoAckPolicyValid((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter), &qosInfo, pAdapter->sessionId))
1454 {
1455 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1456 }
1457 }
1458
1459 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
1460 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
1461 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
1462
1463#ifndef WLAN_MDM_CODE_REDUCTION_OPT
1464 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
1465 pAdapter->sessionId,
1466 &qosInfo,
1467 hdd_wmm_sme_callback,
1468 pQosContext,
1469 qosInfo.ts_info.up,
1470 &pQosContext->qosFlowId);
1471
1472 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1473 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001474 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001475
1476 // need to check the return values and act appropriately
1477 switch (smeStatus)
1478 {
1479 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
1480 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
1481 // setup is pending, so no more work to do now.
1482 // all further work will be done in hdd_wmm_sme_callback()
1483 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1484 "%s: Setup is pending, no further work",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001485 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001486
1487 break;
1488
1489
1490 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
1491 // we can't tell the difference between when a request fails because
1492 // AP rejected it versus when SME encountered an internal error
1493
1494 // in either case SME won't ever reference this context so
1495 // free the record
1496 hdd_wmm_free_context(pQosContext);
1497
1498 // fall through and start packets flowing
1499 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1500 // no ACM in effect, no need to setup U-APSD
1501 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
1502 // no ACM in effect, U-APSD is desired but was already setup
1503
1504 // for these cases everything is already setup so we can
1505 // signal TL that it has work to do
1506 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1507 "%s: Setup is complete, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001508 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001509
1510 pAc->wmmAcAccessAllowed = VOS_TRUE;
1511 pAc->wmmAcAccessGranted = VOS_TRUE;
1512 pAc->wmmAcAccessPending = VOS_FALSE;
1513
1514 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1515 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
1516 acType );
1517
1518 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1519 {
1520 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1521 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001522 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -07001523 }
1524
1525 break;
1526
1527
1528 default:
1529 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001530 "%s: unexpected SME Status=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001531 __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07001532 VOS_ASSERT(0);
1533 }
1534#endif
1535
1536}
1537
1538/**============================================================================
1539 @brief hdd_wmm_init() - Function which will initialize the WMM configuation
1540 and status to an initial state. The configuration can later be overwritten
1541 via application APIs
1542
Kumar Anand82c009f2014-05-29 00:29:42 -07001543 @param pAdapter : [in] pointer to Adapter context
Jeff Johnson295189b2012-06-20 16:38:30 -07001544
Kumar Anand82c009f2014-05-29 00:29:42 -07001545 @return : VOS_STATUS_SUCCESS if successful
Jeff Johnson295189b2012-06-20 16:38:30 -07001546 : other values if failure
1547
1548 ===========================================================================*/
Kumar Anand82c009f2014-05-29 00:29:42 -07001549VOS_STATUS hdd_wmm_init ( hdd_adapter_t *pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07001550{
Kumar Anand82c009f2014-05-29 00:29:42 -07001551 sme_QosWmmUpType* hddWmmDscpToUpMap = pAdapter->hddWmmDscpToUpMap;
Jeff Johnson295189b2012-06-20 16:38:30 -07001552 v_U8_t dscp;
1553
1554 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001555 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001556
1557 // DSCP to User Priority Lookup Table
1558 for (dscp = 0; dscp <= WLAN_HDD_MAX_DSCP; dscp++)
1559 {
1560 hddWmmDscpToUpMap[dscp] = SME_QOS_WMM_UP_BE;
1561 }
1562 hddWmmDscpToUpMap[8] = SME_QOS_WMM_UP_BK;
1563 hddWmmDscpToUpMap[16] = SME_QOS_WMM_UP_RESV;
1564 hddWmmDscpToUpMap[24] = SME_QOS_WMM_UP_EE;
1565 hddWmmDscpToUpMap[32] = SME_QOS_WMM_UP_CL;
1566 hddWmmDscpToUpMap[40] = SME_QOS_WMM_UP_VI;
1567 hddWmmDscpToUpMap[48] = SME_QOS_WMM_UP_VO;
1568 hddWmmDscpToUpMap[56] = SME_QOS_WMM_UP_NC;
Jeff Johnson295189b2012-06-20 16:38:30 -07001569 return VOS_STATUS_SUCCESS;
1570}
1571
1572/**============================================================================
1573 @brief hdd_wmm_adapter_init() - Function which will initialize the WMM configuation
1574 and status to an initial state. The configuration can later be overwritten
1575 via application APIs
1576
1577 @param pAdapter : [in] pointer to Adapter context
1578
1579 @return : VOS_STATUS_SUCCESS if succssful
1580 : other values if failure
1581
1582 ===========================================================================*/
1583VOS_STATUS hdd_wmm_adapter_init( hdd_adapter_t *pAdapter )
1584{
1585 hdd_wmm_ac_status_t *pAcStatus;
1586 WLANTL_ACEnumType acType;
1587
1588 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001589 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001590
1591 pAdapter->hddWmmStatus.wmmQap = VOS_FALSE;
1592 INIT_LIST_HEAD(&pAdapter->hddWmmStatus.wmmContextList);
1593 mutex_init(&pAdapter->hddWmmStatus.wmmLock);
1594
1595 for (acType = 0; acType < WLANTL_MAX_AC; acType++)
1596 {
1597 pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1598 pAcStatus->wmmAcAccessRequired = VOS_FALSE;
1599 pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
1600 pAcStatus->wmmAcAccessPending = VOS_FALSE;
1601 pAcStatus->wmmAcAccessFailed = VOS_FALSE;
1602 pAcStatus->wmmAcAccessGranted = VOS_FALSE;
1603 pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
1604 pAcStatus->wmmAcTspecValid = VOS_FALSE;
1605 pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
1606 }
Kiet Lamf040f472013-11-20 21:15:23 +05301607 // Invalid value(0xff) to indicate psb not configured through framework initially.
1608 pAdapter->configuredPsb = HDD_PSB_CFG_INVALID;
Jeff Johnson295189b2012-06-20 16:38:30 -07001609
1610 return VOS_STATUS_SUCCESS;
1611}
Madan Mohan Koyyalamudi70c52d32013-08-07 14:42:16 +05301612
1613/**============================================================================
1614 @brief hdd_wmm_adapter_clear() - Function which will clear the WMM status
1615 for all the ACs
1616
1617 @param pAdapter : [in] pointer to Adapter context
1618
1619 @return : VOS_STATUS_SUCCESS if succssful
1620 : other values if failure
1621
1622 ===========================================================================*/
1623VOS_STATUS hdd_wmm_adapter_clear( hdd_adapter_t *pAdapter )
1624{
1625 hdd_wmm_ac_status_t *pAcStatus;
1626 WLANTL_ACEnumType acType;
1627 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1628 "%s: Entered", __func__);
1629 for (acType = 0; acType < WLANTL_MAX_AC; acType++)
1630 {
1631 pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1632 pAcStatus->wmmAcAccessRequired = VOS_FALSE;
1633 pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
1634 pAcStatus->wmmAcAccessPending = VOS_FALSE;
1635 pAcStatus->wmmAcAccessFailed = VOS_FALSE;
1636 pAcStatus->wmmAcAccessGranted = VOS_FALSE;
1637 pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
1638 pAcStatus->wmmAcTspecValid = VOS_FALSE;
1639 pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
1640 }
1641 return VOS_STATUS_SUCCESS;
1642}
1643
Jeff Johnson295189b2012-06-20 16:38:30 -07001644/**============================================================================
1645 @brief hdd_wmm_close() - Function which will perform any necessary work to
1646 to clean up the WMM functionality prior to the kernel module unload
1647
1648 @param pAdapter : [in] pointer to adapter context
1649
1650 @return : VOS_STATUS_SUCCESS if succssful
1651 : other values if failure
1652
1653 ===========================================================================*/
1654VOS_STATUS hdd_wmm_adapter_close ( hdd_adapter_t* pAdapter )
1655{
1656 hdd_wmm_qos_context_t* pQosContext;
1657
1658 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001659 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001660
1661 // free any context records that we still have linked
1662 while (!list_empty(&pAdapter->hddWmmStatus.wmmContextList))
1663 {
1664 pQosContext = list_first_entry(&pAdapter->hddWmmStatus.wmmContextList,
1665 hdd_wmm_qos_context_t, node);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08001666#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07001667 hdd_wmm_disable_inactivity_timer(pQosContext);
1668#endif
Sameer Thalappilbee426e2013-10-30 10:30:30 -07001669#ifdef WLAN_OPEN_SOURCE
Anand N Sunkad4b25a2f2014-11-13 16:01:08 +05301670 if (pQosContext->handle == HDD_WMM_HANDLE_IMPLICIT
1671 && pQosContext->magic == HDD_WMM_CTX_MAGIC)
1672 {
1673
Sameer Thalappilbee426e2013-10-30 10:30:30 -07001674 cancel_work_sync(&pQosContext->wmmAcSetupImplicitQos);
Anand N Sunkad4b25a2f2014-11-13 16:01:08 +05301675 }
Sameer Thalappilbee426e2013-10-30 10:30:30 -07001676#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001677 hdd_wmm_free_context(pQosContext);
1678 }
1679
1680 return VOS_STATUS_SUCCESS;
1681}
1682
1683/**============================================================================
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301684 @brief is_dhcp_packet() - Function which will check OS packet for
1685 DHCP packet
1686
1687 @param skb : [in] pointer to OS packet (sk_buff)
1688 @return : VOS_TRUE if the OS packet is DHCP packet
1689 : otherwise VOS_FALSE
1690 ===========================================================================*/
1691v_BOOL_t is_dhcp_packet(struct sk_buff *skb)
1692{
1693 if (*((u16*)((u8*)skb->data+34)) == DHCP_SOURCE_PORT ||
1694 *((u16*)((u8*)skb->data+34)) == DHCP_DESTINATION_PORT)
1695 return VOS_TRUE;
1696
1697 return VOS_FALSE;
1698}
1699
1700/**============================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07001701 @brief hdd_wmm_classify_pkt() - Function which will classify an OS packet
1702 into a WMM AC based on either 802.1Q or DSCP
1703
1704 @param pAdapter : [in] pointer to adapter context
1705 @param skb : [in] pointer to OS packet (sk_buff)
1706 @param pAcType : [out] pointer to WMM AC type of OS packet
1707
1708 @return : None
1709 ===========================================================================*/
1710v_VOID_t hdd_wmm_classify_pkt ( hdd_adapter_t* pAdapter,
1711 struct sk_buff *skb,
1712 WLANTL_ACEnumType* pAcType,
1713 sme_QosWmmUpType *pUserPri)
1714{
1715 unsigned char * pPkt;
1716 union generic_ethhdr *pHdr;
1717 struct iphdr *pIpHdr;
1718 unsigned char tos;
1719 unsigned char dscp;
1720 sme_QosWmmUpType userPri;
1721 WLANTL_ACEnumType acType;
1722
1723 // this code is executed for every packet therefore
1724 // all debug code is kept conditional
1725
1726#ifdef HDD_WMM_DEBUG
1727 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001728 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001729#endif // HDD_WMM_DEBUG
1730
1731 pPkt = skb->data;
1732 pHdr = (union generic_ethhdr *)pPkt;
1733
1734#ifdef HDD_WMM_DEBUG
1735 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1736 "%s: proto/length is 0x%04x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001737 __func__, pHdr->eth_II.h_proto);
Jeff Johnson295189b2012-06-20 16:38:30 -07001738#endif // HDD_WMM_DEBUG
1739
1740 if (HDD_WMM_CLASSIFICATION_DSCP == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
1741 {
1742 if (pHdr->eth_II.h_proto == htons(ETH_P_IP))
1743 {
1744 // case 1: Ethernet II IP packet
1745 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_II)];
1746 tos = pIpHdr->tos;
1747#ifdef HDD_WMM_DEBUG
1748 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1749 "%s: Ethernet II IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001750 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001751#endif // HDD_WMM_DEBUG
1752
1753 }
1754 else if ((ntohs(pHdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
1755 (pHdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
1756 (pHdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
1757 (pHdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1758 (pHdr->eth_8023.h_proto == htons(ETH_P_IP)))
1759 {
1760 // case 2: 802.3 LLC/SNAP IP packet
1761 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];
1762 tos = pIpHdr->tos;
1763#ifdef HDD_WMM_DEBUG
1764 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1765 "%s: 802.3 LLC/SNAP IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001766 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001767#endif // HDD_WMM_DEBUG
1768 }
1769 else if (pHdr->eth_II.h_proto == htons(ETH_P_8021Q))
1770 {
1771 // VLAN tagged
1772
1773 if (pHdr->eth_IIv.h_vlan_encapsulated_proto == htons(ETH_P_IP))
1774 {
1775 // case 3: Ethernet II vlan-tagged IP packet
1776 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_IIv)];
1777 tos = pIpHdr->tos;
1778#ifdef HDD_WMM_DEBUG
1779 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1780 "%s: Ethernet II VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001781 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001782#endif // HDD_WMM_DEBUG
1783 }
1784 else if ((ntohs(pHdr->eth_IIv.h_vlan_encapsulated_proto) < WLAN_MIN_PROTO) &&
1785 (pHdr->eth_8023v.h_snap.dsap == WLAN_SNAP_DSAP) &&
1786 (pHdr->eth_8023v.h_snap.ssap == WLAN_SNAP_SSAP) &&
1787 (pHdr->eth_8023v.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1788 (pHdr->eth_8023v.h_proto == htons(ETH_P_IP)))
1789 {
1790 // case 4: 802.3 LLC/SNAP vlan-tagged IP packet
1791 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023v)];
1792 tos = pIpHdr->tos;
1793#ifdef HDD_WMM_DEBUG
1794 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1795 "%s: 802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001796 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001797#endif // HDD_WMM_DEBUG
1798 }
1799 else
1800 {
1801 // default
1802#ifdef HDD_WMM_DEBUG
1803 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1804 "%s: VLAN tagged Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001805 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001806#endif // HDD_WMM_DEBUG
1807 tos = 0;
1808 }
1809 }
1810 else
1811 {
1812 // default
1813#ifdef HDD_WMM_DEBUG
1814 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1815 "%s: Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001816 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001817#endif // HDD_WMM_DEBUG
1818 //Give the highest priority to 802.1x packet
1819 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
1820 tos = 0xC0;
1821 else
1822 tos = 0;
1823 }
1824
1825 dscp = (tos>>2) & 0x3f;
Kumar Anand82c009f2014-05-29 00:29:42 -07001826 userPri = pAdapter->hddWmmDscpToUpMap[dscp];
1827
Jeff Johnson295189b2012-06-20 16:38:30 -07001828#ifdef HDD_WMM_DEBUG
1829 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1830 "%s: tos is %d, dscp is %d, up is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001831 __func__, tos, dscp, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07001832#endif // HDD_WMM_DEBUG
1833
1834 }
1835 else if (HDD_WMM_CLASSIFICATION_802_1Q == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
1836 {
1837 if (pHdr->eth_IIv.h_vlan_proto == htons(ETH_P_8021Q))
1838 {
1839 // VLAN tagged
1840 userPri = (ntohs(pHdr->eth_IIv.h_vlan_TCI)>>13) & 0x7;
1841#ifdef HDD_WMM_DEBUG
1842 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1843 "%s: Tagged frame, UP is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001844 __func__, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07001845#endif // HDD_WMM_DEBUG
1846 }
1847 else
1848 {
1849 // not VLAN tagged, use default
1850#ifdef HDD_WMM_DEBUG
1851 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1852 "%s: Untagged frame, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001853 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001854#endif // HDD_WMM_DEBUG
1855 //Give the highest priority to 802.1x packet
1856 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
1857 userPri = SME_QOS_WMM_UP_VO;
1858 else
1859 userPri = SME_QOS_WMM_UP_BE;
1860 }
1861 }
1862 else
1863 {
1864 // default
1865#ifdef HDD_WMM_DEBUG
1866 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1867 "%s: Unknown classification scheme, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001868 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001869#endif // HDD_WMM_DEBUG
1870 userPri = SME_QOS_WMM_UP_BE;
1871 }
1872
1873 acType = hddWmmUpToAcMap[userPri];
1874
1875#ifdef HDD_WMM_DEBUG
1876 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1877 "%s: UP is %d, AC is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001878 __func__, userPri, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001879#endif // HDD_WMM_DEBUG
1880
1881 *pUserPri = userPri;
1882 *pAcType = acType;
1883
1884 return;
1885}
1886
1887/**============================================================================
1888 @brief hdd_hostapd_select_quueue() - Function which will classify the packet
1889 according to linux qdisc expectation.
1890
1891
1892 @param dev : [in] pointer to net_device structure
1893 @param skb : [in] pointer to os packet
1894
1895 @return : Qdisc queue index
1896 ===========================================================================*/
1897v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb)
1898{
1899 WLANTL_ACEnumType ac;
1900 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
1901 v_USHORT_t queueIndex;
1902 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
1903 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
1904 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001905 v_U8_t STAId;
1906 v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301907 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1908 ptSapContext pSapCtx = NULL;
1909 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1910 if(pSapCtx == NULL){
1911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1912 FL("psapCtx is NULL"));
1913 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1914 goto done;
1915 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001916 /*Get the Station ID*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001917 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &STAId))
1918 {
Agarwal Ashisha64c9542014-03-04 00:14:43 +05301919 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001920 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001921 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1922 goto done;
1923 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001924
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301925 spin_lock_bh( &pSapCtx->staInfo_lock );
1926 if (FALSE == vos_is_macaddr_equal(&pSapCtx->aStaInfo[STAId].macAddrSTA, pDestMacAddress))
Jeff Johnson295189b2012-06-20 16:38:30 -07001927 {
Agarwal Ashisha64c9542014-03-04 00:14:43 +05301928 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001929 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001930
1931 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1932 goto release_lock;
1933 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301934 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 -07001935 {
1936 /* Get the user priority from IP header & corresponding AC */
1937 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301938 //If 3/4th of Tx queue is used then place the DHCP packet in VOICE AC queue
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301939 if (pSapCtx->aStaInfo[STAId].vosLowResource && is_dhcp_packet(skb))
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301940 {
1941 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1942 "%s: Making priority of DHCP packet as VOICE", __func__);
1943 up = SME_QOS_WMM_UP_VO;
1944 ac = hddWmmUpToAcMap[up];
1945 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001946 }
1947 *pSTAId = STAId;
1948
1949release_lock:
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301950 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001951done:
1952 skb->priority = up;
Mukul Sharmad82cb7d2014-07-03 14:53:30 +05301953 if(skb->priority < SME_QOS_WMM_UP_MAX)
1954 queueIndex = hddLinuxUpToAcMap[skb->priority];
1955 else
1956 {
1957 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1958 "%s: up=%d is going beyond max value", __func__, up);
1959 queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
1960 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001961
1962 return queueIndex;
1963}
1964
1965/**============================================================================
1966 @brief hdd_wmm_select_quueue() - Function which will classify the packet
1967 according to linux qdisc expectation.
1968
1969
1970 @param dev : [in] pointer to net_device structure
1971 @param skb : [in] pointer to os packet
1972
1973 @return : Qdisc queue index
1974 ===========================================================================*/
1975v_U16_t hdd_wmm_select_queue(struct net_device * dev, struct sk_buff *skb)
1976{
1977 WLANTL_ACEnumType ac;
Shailender Karmuchia734f332013-04-19 14:02:48 -07001978 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001979 v_USHORT_t queueIndex;
Jeff Johnson295189b2012-06-20 16:38:30 -07001980 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1981
Kiet Lam40009862014-02-13 12:33:22 -08001982 if (isWDresetInProgress()) {
1983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1984 FL("called during WDReset"));
1985 skb->priority = SME_QOS_WMM_UP_BE;
1986 return HDD_LINUX_AC_BE;
1987 }
1988
Shailender Karmuchia734f332013-04-19 14:02:48 -07001989 /*Get the Station ID*/
1990 if (WLAN_HDD_IBSS == pAdapter->device_mode)
1991 {
1992 v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
1993 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
1994
1995 if ( VOS_STATUS_SUCCESS !=
1996 hdd_Ibss_GetStaId(&pAdapter->sessionCtx.station,
1997 pDestMacAddress, pSTAId))
1998 {
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05301999 *pSTAId = HDD_WLAN_INVALID_STA_ID;
2000 if ( !vos_is_macaddr_broadcast( pDestMacAddress ) &&
2001 !vos_is_macaddr_group(pDestMacAddress))
2002 {
2003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnsonb9fb9ce2013-05-03 08:11:02 -07002004 "%s: Failed to find right station pDestMacAddress: "
2005 MAC_ADDRESS_STR , __func__,
2006 MAC_ADDR_ARRAY(pDestMacAddress->bytes));
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05302007 goto done;
2008 }
Shailender Karmuchia734f332013-04-19 14:02:48 -07002009 }
2010 }
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302011 /* All traffic will get equal opportuniy to transmit data frames. */
2012 /* Get the user priority from IP header & corresponding AC */
2013 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
2014 /* If 3/4th of BE AC Tx queue is full,
2015 * then place the DHCP packet in VOICE AC queue
2016 */
2017 if (pAdapter->isVosLowResource && is_dhcp_packet(skb))
2018 {
2019 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
2020 "%s: BestEffort Tx Queue is 3/4th full"
2021 " Make DHCP packet's pri as VO", __func__);
2022 up = SME_QOS_WMM_UP_VO;
2023 ac = hddWmmUpToAcMap[up];
Jeff Johnson295189b2012-06-20 16:38:30 -07002024 }
Shailender Karmuchia734f332013-04-19 14:02:48 -07002025done:
Jeff Johnson295189b2012-06-20 16:38:30 -07002026 skb->priority = up;
Mukul Sharmad82cb7d2014-07-03 14:53:30 +05302027 if(skb->priority < SME_QOS_WMM_UP_MAX)
2028 queueIndex = hddLinuxUpToAcMap[skb->priority];
2029 else
2030 {
2031 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2032 "%s: up=%d is going beyond max value", __func__, up);
2033 queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
2034 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002035
2036 return queueIndex;
2037}
2038
Kiet Lamf040f472013-11-20 21:15:23 +05302039/**==========================================================================
2040 @brief hdd_wmm_acquire_access_required() - Function which will determine
2041 acquire admittance for a WMM AC is required or not based on psb configuration
2042 done in framework
2043
2044 @param pAdapter : [in] pointer to adapter structure
2045
2046 @param acType : [in] WMM AC type of OS packet
2047
2048 @return : void
2049 ===========================================================================*/
2050void hdd_wmm_acquire_access_required(hdd_adapter_t *pAdapter,
2051 WLANTL_ACEnumType acType)
2052{
2053/* Each bit in the LSB nibble indicates 1 AC.
2054 * Clearing the particular bit in LSB nibble to indicate
2055 * access required
2056 */
2057 switch(acType)
2058 {
2059 case WLANTL_AC_BK:
2060 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BK_CHANGED_MASK; /* clear first bit */
2061 break;
2062 case WLANTL_AC_BE:
2063 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BE_CHANGED_MASK; /* clear second bit */
2064 break;
2065 case WLANTL_AC_VI:
2066 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VI_CHANGED_MASK; /* clear third bit */
2067 break;
2068 case WLANTL_AC_VO:
2069 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VO_CHANGED_MASK; /* clear fourth bit */
2070 break;
2071 default:
2072 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2073 "%s: Invalid AC Type", __func__);
2074 break;
2075 }
2076}
2077
Jeff Johnson295189b2012-06-20 16:38:30 -07002078/**============================================================================
2079 @brief hdd_wmm_acquire_access() - Function which will attempt to acquire
2080 admittance for a WMM AC
2081
2082 @param pAdapter : [in] pointer to adapter context
2083 @param acType : [in] WMM AC type of OS packet
2084 @param pGranted : [out] pointer to boolean flag when indicates if access
2085 has been granted or not
2086
2087 @return : VOS_STATUS_SUCCESS if succssful
2088 : other values if failure
2089 ===========================================================================*/
2090VOS_STATUS hdd_wmm_acquire_access( hdd_adapter_t* pAdapter,
2091 WLANTL_ACEnumType acType,
2092 v_BOOL_t * pGranted )
2093{
2094 hdd_wmm_qos_context_t *pQosContext;
2095
2096 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002097 "%s: Entered for AC %d", __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002098
2099 if (!hdd_wmm_is_active(pAdapter) || !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
2100 {
2101 // either we don't want QoS or the AP doesn't support QoS
2102 // or we don't want to do implicit QoS
2103 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002104 "%s: QoS not configured on both ends ", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002105
2106 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2107 *pGranted = VOS_TRUE;
2108 return VOS_STATUS_SUCCESS;
2109 }
2110
2111 // do we already have an implicit QoS request pending for this AC?
2112 if ((pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded) ||
2113 (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessPending))
2114 {
2115 // request already pending so we need to wait for that response
2116 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2117 "%s: Implicit QoS for TL AC %d already scheduled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002118 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002119
2120 *pGranted = VOS_FALSE;
2121 return VOS_STATUS_SUCCESS;
2122 }
2123
2124 // did we already fail to establish implicit QoS for this AC?
2125 // (if so, access should have been granted when the failure was handled)
2126 if (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessFailed)
2127 {
2128 // request previously failed
2129 // allow access, but we'll be downgraded
2130 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2131 "%s: Implicit QoS for TL AC %d previously failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002132 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002133
2134 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2135 *pGranted = VOS_TRUE;
2136 return VOS_STATUS_SUCCESS;
2137 }
2138
2139 // we need to establish implicit QoS
2140 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2141 "%s: Need to schedule implicit QoS for TL AC %d, pAdapter is %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002142 __func__, acType, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002143
2144 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded = VOS_TRUE;
2145
Mohit Khanna217ea8d2012-09-11 17:42:42 -07002146 pQosContext = kmalloc(sizeof(*pQosContext), GFP_ATOMIC);
Jeff Johnson295189b2012-06-20 16:38:30 -07002147 if (NULL == pQosContext)
2148 {
2149 // no memory for QoS context. Nothing we can do but let data flow
2150 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002151 "%s: Unable to allocate context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002152 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2153 *pGranted = VOS_TRUE;
2154 return VOS_STATUS_SUCCESS;
2155 }
2156
2157 pQosContext->acType = acType;
2158 pQosContext->pAdapter = pAdapter;
2159 pQosContext->qosFlowId = 0;
2160 pQosContext->handle = HDD_WMM_HANDLE_IMPLICIT;
2161 pQosContext->magic = HDD_WMM_CTX_MAGIC;
2162 INIT_WORK(&pQosContext->wmmAcSetupImplicitQos,
2163 hdd_wmm_do_implicit_qos);
2164
2165 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2166 "%s: Scheduling work for AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002167 __func__, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002168
2169 schedule_work(&pQosContext->wmmAcSetupImplicitQos);
2170
2171 // caller will need to wait until the work takes place and
2172 // TSPEC negotiation completes
2173 *pGranted = VOS_FALSE;
2174 return VOS_STATUS_SUCCESS;
2175}
2176
2177/**============================================================================
2178 @brief hdd_wmm_assoc() - Function which will handle the housekeeping
2179 required by WMM when association takes place
2180
2181 @param pAdapter : [in] pointer to adapter context
2182 @param pRoamInfo: [in] pointer to roam information
2183 @param eBssType : [in] type of BSS
2184
2185 @return : VOS_STATUS_SUCCESS if succssful
2186 : other values if failure
2187 ===========================================================================*/
2188VOS_STATUS hdd_wmm_assoc( hdd_adapter_t* pAdapter,
2189 tCsrRoamInfo *pRoamInfo,
2190 eCsrRoamBssType eBssType )
2191{
2192 tANI_U8 uapsdMask;
2193 VOS_STATUS status;
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002194 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002195
2196 // when we associate we need to notify TL if it needs to enable
2197 // UAPSD for any access categories
2198
2199 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002200 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002201
2202 if (pRoamInfo->fReassocReq)
2203 {
2204 // when we reassociate we should continue to use whatever
2205 // parameters were previously established. if we are
2206 // reassociating due to a U-APSD change for a particular
2207 // Access Category, then the change will be communicated
2208 // to HDD via the QoS callback associated with the given
2209 // flow, and U-APSD parameters will be updated there
2210
2211 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002212 "%s: Reassoc so no work, Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002213
2214 return VOS_STATUS_SUCCESS;
2215 }
2216
2217 // get the negotiated UAPSD Mask
2218 uapsdMask = pRoamInfo->u.pConnectedProfile->modifyProfileFields.uapsd_mask;
2219
2220 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002221 "%s: U-APSD mask is 0x%02x", __func__, (int) uapsdMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002222
2223 if (uapsdMask & HDD_AC_VO)
2224 {
2225 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2226 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2227 WLANTL_AC_VO,
2228 7,
2229 7,
2230 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv,
2231 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv,
2232 WLANTL_BI_DIR );
2233
2234 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2235 }
2236
2237 if (uapsdMask & HDD_AC_VI)
2238 {
2239 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2240 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2241 WLANTL_AC_VI,
2242 5,
2243 5,
2244 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv,
2245 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv,
2246 WLANTL_BI_DIR );
2247
2248 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2249 }
2250
2251 if (uapsdMask & HDD_AC_BK)
2252 {
2253 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2254 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2255 WLANTL_AC_BK,
2256 2,
2257 2,
2258 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv,
2259 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv,
2260 WLANTL_BI_DIR );
2261
2262 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2263 }
2264
2265 if (uapsdMask & HDD_AC_BE)
2266 {
2267 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2268 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2269 WLANTL_AC_BE,
2270 3,
2271 3,
2272 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv,
2273 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv,
2274 WLANTL_BI_DIR );
2275
2276 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2277 }
Kumar Anand82c009f2014-05-29 00:29:42 -07002278
2279 status = sme_UpdateDSCPtoUPMapping(pHddCtx->hHal,
2280 pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId);
2281
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002282 if (!VOS_IS_STATUS_SUCCESS( status ))
2283 {
Kumar Anand82c009f2014-05-29 00:29:42 -07002284 hdd_wmm_init( pAdapter );
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002285 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002286
2287 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002288 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002289
2290 return VOS_STATUS_SUCCESS;
2291}
2292
2293
2294
2295static const v_U8_t acmMaskBit[WLANTL_MAX_AC] =
2296 {
2297 0x4, /* WLANTL_AC_BK */
2298 0x8, /* WLANTL_AC_BE */
2299 0x2, /* WLANTL_AC_VI */
2300 0x1 /* WLANTL_AC_VO */
2301 };
2302
2303/**============================================================================
2304 @brief hdd_wmm_connect() - Function which will handle the housekeeping
2305 required by WMM when a connection is established
2306
2307 @param pAdapter : [in] pointer to adapter context
2308 @param pRoamInfo: [in] pointer to roam information
2309 @param eBssType : [in] type of BSS
2310
2311 @return : VOS_STATUS_SUCCESS if succssful
2312 : other values if failure
2313 ===========================================================================*/
2314VOS_STATUS hdd_wmm_connect( hdd_adapter_t* pAdapter,
2315 tCsrRoamInfo *pRoamInfo,
2316 eCsrRoamBssType eBssType )
2317{
2318 int ac;
2319 v_BOOL_t qap;
2320 v_BOOL_t qosConnection;
2321 v_U8_t acmMask;
2322
2323 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002324 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002325
2326 if ((eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) &&
2327 pRoamInfo &&
2328 pRoamInfo->u.pConnectedProfile)
2329 {
2330 qap = pRoamInfo->u.pConnectedProfile->qap;
2331 qosConnection = pRoamInfo->u.pConnectedProfile->qosConnection;
2332 acmMask = pRoamInfo->u.pConnectedProfile->acm_mask;
2333 }
2334 else
2335 {
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05302336 /* TODO: if a non-qos IBSS peer joins the group make qap and qosConnection false.
2337 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002338 qap = VOS_TRUE;
2339 qosConnection = VOS_TRUE;
2340 acmMask = 0x0;
2341 }
2342
2343 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2344 "%s: qap is %d, qosConnection is %d, acmMask is 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002345 __func__, qap, qosConnection, acmMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002346
2347 pAdapter->hddWmmStatus.wmmQap = qap;
2348 pAdapter->hddWmmStatus.wmmQosConnection = qosConnection;
2349
2350 for (ac = 0; ac < WLANTL_MAX_AC; ac++)
2351 {
2352 if (qap &&
2353 qosConnection &&
2354 (acmMask & acmMaskBit[ac]))
2355 {
2356 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2357 "%s: ac %d on",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002358 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002359
2360 // admission is required
2361 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_TRUE;
2362 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_FALSE;
2363 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessGranted = VOS_FALSE;
Mukul Sharma74a01e52014-07-21 15:14:23 +05302364
2365 /* Making TSPEC invalid here so downgrading can be happen while roaming
2366 * It is expected this will be SET in hdd_wmm_sme_callback,once sme is
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302367 * done with the AddTspec.Here we avoid 11r and ccx based association.
2368 This change is done only when reassoc to different AP.
Mukul Sharma74a01e52014-07-21 15:14:23 +05302369 */
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2371 FL( "fReassocReq = %d"
2372#if defined (FEATURE_WLAN_ESE)
2373 "isESEAssoc = %d"
2374#endif
2375#if defined (WLAN_FEATURE_VOWIFI_11R)
2376 "is11rAssoc = %d"
2377#endif
2378 ),
2379 pRoamInfo->fReassocReq
2380#if defined (FEATURE_WLAN_ESE)
2381 ,pRoamInfo->isESEAssoc
2382#endif
2383#if defined (WLAN_FEATURE_VOWIFI_11R)
2384 ,pRoamInfo->is11rAssoc
2385#endif
2386 );
2387
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302388 if ( !pRoamInfo->fReassocReq
Mukul Sharma74a01e52014-07-21 15:14:23 +05302389#if defined (WLAN_FEATURE_VOWIFI_11R)
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302390 &&
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302391 !pRoamInfo->is11rAssoc
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302392#endif
Mukul Sharma74a01e52014-07-21 15:14:23 +05302393#if defined (FEATURE_WLAN_ESE)
2394 &&
Mukul Sharma9ca96b22014-11-15 19:40:04 +05302395 !pRoamInfo->isESEAssoc
Mukul Sharma74a01e52014-07-21 15:14:23 +05302396#endif
2397 )
Mukul Sharma74a01e52014-07-21 15:14:23 +05302398 {
2399 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcTspecValid = VOS_FALSE;
2400 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002401 }
2402 else
2403 {
2404 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2405 "%s: ac %d off",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002406 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002407 // admission is not required so access is allowed
2408 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_FALSE;
2409 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_TRUE;
2410 }
2411
2412 }
2413
2414 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002415 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002416
2417 return VOS_STATUS_SUCCESS;
2418}
2419
2420/**============================================================================
2421 @brief hdd_wmm_get_uapsd_mask() - Function which will calculate the
2422 initial value of the UAPSD mask based upon the device configuration
2423
2424 @param pAdapter : [in] pointer to adapter context
2425 @param pUapsdMask: [in] pointer to where the UAPSD Mask is to be stored
2426
2427 @return : VOS_STATUS_SUCCESS if succssful
2428 : other values if failure
2429 ===========================================================================*/
2430VOS_STATUS hdd_wmm_get_uapsd_mask( hdd_adapter_t* pAdapter,
2431 tANI_U8 *pUapsdMask )
2432{
2433 tANI_U8 uapsdMask;
2434
2435 if (HDD_WMM_USER_MODE_NO_QOS == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
2436 {
2437 // no QOS then no UAPSD
2438 uapsdMask = 0;
2439 }
2440 else
2441 {
2442 // start with the default mask
2443 uapsdMask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
2444
2445 // disable UAPSD for any ACs with a 0 Service Interval
2446 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv == 0 )
2447 {
2448 uapsdMask &= ~HDD_AC_VO;
2449 }
2450
2451 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv == 0 )
2452 {
2453 uapsdMask &= ~HDD_AC_VI;
2454 }
2455
2456 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv == 0 )
2457 {
2458 uapsdMask &= ~HDD_AC_BK;
2459 }
2460
2461 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv == 0 )
2462 {
2463 uapsdMask &= ~HDD_AC_BE;
2464 }
2465 }
2466
2467 // return calculated mask
2468 *pUapsdMask = uapsdMask;
2469 return VOS_STATUS_SUCCESS;
2470}
2471
2472
2473/**============================================================================
2474 @brief hdd_wmm_is_active() - Function which will determine if WMM is
2475 active on the current connection
2476
2477 @param pAdapter : [in] pointer to adapter context
2478
2479 @return : VOS_TRUE if WMM is enabled
2480 : VOS_FALSE if WMM is not enabled
2481 ===========================================================================*/
2482v_BOOL_t hdd_wmm_is_active( hdd_adapter_t* pAdapter )
2483{
2484 if ((!pAdapter->hddWmmStatus.wmmQosConnection) ||
2485 (!pAdapter->hddWmmStatus.wmmQap))
2486 {
2487 return VOS_FALSE;
2488 }
2489 else
2490 {
2491 return VOS_TRUE;
2492 }
2493}
2494
2495/**============================================================================
2496 @brief hdd_wmm_addts() - Function which will add a traffic spec at the
2497 request of an application
2498
2499 @param pAdapter : [in] pointer to adapter context
2500 @param handle : [in] handle to uniquely identify a TS
2501 @param pTspec : [in] pointer to the traffic spec
2502
2503 @return : HDD_WLAN_WMM_STATUS_*
2504 ===========================================================================*/
2505hdd_wlan_wmm_status_e hdd_wmm_addts( hdd_adapter_t* pAdapter,
2506 v_U32_t handle,
2507 sme_QosWmmTspecInfo* pTspec )
2508{
2509 hdd_wmm_qos_context_t *pQosContext;
2510 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2511#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2512 sme_QosStatusType smeStatus;
2513#endif
2514 v_BOOL_t found = VOS_FALSE;
2515
2516 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002517 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002518
2519 // see if a context already exists with the given handle
2520 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2521 list_for_each_entry(pQosContext,
2522 &pAdapter->hddWmmStatus.wmmContextList,
2523 node)
2524 {
2525 if (pQosContext->handle == handle)
2526 {
2527 found = VOS_TRUE;
2528 break;
2529 }
2530 }
2531 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2532 if (found)
2533 {
2534 // record with that handle already exists
2535 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2536 "%s: Record already exists with handle 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002537 __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002538
2539 /* Application is trying to modify some of the Tspec params. Allow it */
2540 smeStatus = sme_QosModifyReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2541 pTspec,
2542 pQosContext->qosFlowId);
2543
2544 // need to check the return value and act appropriately
2545 switch (smeStatus)
2546 {
2547 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
2548 status = HDD_WLAN_WMM_STATUS_MODIFY_PENDING;
2549 break;
2550 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2551 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
2552 break;
2553 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
2554 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
2555 break;
2556 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
2557 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
2558 break;
2559 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
2560 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2561 break;
2562 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2563 status = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2564 break;
2565 default:
2566 // we didn't get back one of the SME_QOS_STATUS_MODIFY_* status codes
2567 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002568 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002569 VOS_ASSERT(0);
2570 return HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2571 }
2572
c_hpothu48e31712014-12-23 16:59:03 +05302573 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2574 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
2575 {
2576 pQosContext->lastStatus = status;
2577 }
2578 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002579 return status;
2580 }
2581
2582 pQosContext = kmalloc(sizeof(*pQosContext), GFP_KERNEL);
2583 if (NULL == pQosContext)
2584 {
2585 // no memory for QoS context. Nothing we can do
2586 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002587 "%s: Unable to allocate QoS context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002588 return HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE;
2589 }
2590
2591 // we assume the tspec has already been validated by the caller
2592
2593 pQosContext->handle = handle;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08002594 if (pTspec->ts_info.up < HDD_WMM_UP_TO_AC_MAP_SIZE)
2595 pQosContext->acType = hddWmmUpToAcMap[pTspec->ts_info.up];
2596 else {
2597 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2598 "%s: ts_info.up (%d) larger than max value (%d), "
2599 "use default acType (%d)",
2600 __func__, pTspec->ts_info.up,
2601 HDD_WMM_UP_TO_AC_MAP_SIZE - 1, hddWmmUpToAcMap[0]);
2602 pQosContext->acType = hddWmmUpToAcMap[0];
2603 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002604 pQosContext->pAdapter = pAdapter;
2605 pQosContext->qosFlowId = 0;
2606 pQosContext->magic = HDD_WMM_CTX_MAGIC;
2607
2608 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2609 "%s: Setting up QoS, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002610 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002611
2612 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2613 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
2614 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2615
2616#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2617 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2618 pAdapter->sessionId,
2619 pTspec,
2620 hdd_wmm_sme_callback,
2621 pQosContext,
2622 pTspec->ts_info.up,
2623 &pQosContext->qosFlowId);
2624
2625 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2626 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002627 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002628
2629 // need to check the return value and act appropriately
2630 switch (smeStatus)
2631 {
2632 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
2633 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2634 break;
2635 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2636 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
2637 break;
2638 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
2639 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
2640 break;
2641 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
2642 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2643 break;
2644 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
2645 hdd_wmm_free_context(pQosContext);
2646 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
2647 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
2648 // we can't tell the difference between when a request fails because
2649 // AP rejected it versus when SME encounterd an internal error
2650 hdd_wmm_free_context(pQosContext);
2651 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2652 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2653 hdd_wmm_free_context(pQosContext);
2654 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2655 default:
2656 // we didn't get back one of the SME_QOS_STATUS_SETUP_* status codes
2657 hdd_wmm_free_context(pQosContext);
2658 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002659 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002660 VOS_ASSERT(0);
2661 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2662 }
2663#endif
2664
2665 // we were successful, save the status
c_hpothu48e31712014-12-23 16:59:03 +05302666 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2667 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
2668 {
2669 pQosContext->lastStatus = status;
2670 }
2671 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002672
2673 return status;
2674}
2675
2676/**============================================================================
2677 @brief hdd_wmm_delts() - Function which will delete a traffic spec at the
2678 request of an application
2679
2680 @param pAdapter : [in] pointer to adapter context
2681 @param handle : [in] handle to uniquely identify a TS
2682
2683 @return : HDD_WLAN_WMM_STATUS_*
2684 ===========================================================================*/
2685hdd_wlan_wmm_status_e hdd_wmm_delts( hdd_adapter_t* pAdapter,
2686 v_U32_t handle )
2687{
2688 hdd_wmm_qos_context_t *pQosContext;
2689 v_BOOL_t found = VOS_FALSE;
2690 WLANTL_ACEnumType acType = 0;
2691 v_U32_t qosFlowId = 0;
2692 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2693#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2694 sme_QosStatusType smeStatus;
2695#endif
2696
2697 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002698 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002699
2700 // locate the context with the given handle
2701 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2702 list_for_each_entry(pQosContext,
2703 &pAdapter->hddWmmStatus.wmmContextList,
2704 node)
2705 {
2706 if (pQosContext->handle == handle)
2707 {
2708 found = VOS_TRUE;
2709 acType = pQosContext->acType;
2710 qosFlowId = pQosContext->qosFlowId;
2711 break;
2712 }
2713 }
2714 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2715
2716 if (VOS_FALSE == found)
2717 {
2718 // we didn't find the handle
2719 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002720 "%s: handle 0x%x not found", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002721 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2722 }
2723
2724
2725 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2726 "%s: found handle 0x%x, flow %d, AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002727 __func__, handle, qosFlowId, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002728
2729#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2730 smeStatus = sme_QosReleaseReq( WLAN_HDD_GET_HAL_CTX(pAdapter), qosFlowId );
2731
2732 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2733 "%s: SME flow %d released, SME status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002734 __func__, qosFlowId, smeStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07002735
2736 switch(smeStatus)
2737 {
2738 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
2739 // this flow is the only one on that AC, so go ahead and update
2740 // our TSPEC state for the AC
2741 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcTspecValid = VOS_FALSE;
2742
2743 // need to tell TL to stop trigger timer, etc
2744 hdd_wmm_disable_tl_uapsd(pQosContext);
2745
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002746#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07002747 // disable the inactivity timer
2748 hdd_wmm_disable_inactivity_timer(pQosContext);
2749#endif
2750 // we are done with this context
2751 hdd_wmm_free_context(pQosContext);
2752
2753 // SME must not fire any more callbacks for this flow since the context
2754 // is no longer valid
2755
2756 return HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
2757
2758 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
2759 // do nothing as we will get a response from SME
2760 status = HDD_WLAN_WMM_STATUS_RELEASE_PENDING;
2761 break;
2762
2763 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
2764 // nothing we can do with the existing flow except leave it
2765 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2766 break;
2767
2768 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
2769 // nothing we can do with the existing flow except leave it
2770 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2771
2772 default:
2773 // we didn't get back one of the SME_QOS_STATUS_RELEASE_* status codes
2774 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002775 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002776 VOS_ASSERT(0);
2777 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2778 }
2779
2780#endif
c_hpothu48e31712014-12-23 16:59:03 +05302781 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2782 if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
2783 {
2784 pQosContext->lastStatus = status;
2785 }
2786 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002787 return status;
2788}
2789
2790/**============================================================================
2791 @brief hdd_wmm_checkts() - Function which will return the status of a traffic
2792 spec at the request of an application
2793
2794 @param pAdapter : [in] pointer to adapter context
2795 @param handle : [in] handle to uniquely identify a TS
2796
2797 @return : HDD_WLAN_WMM_STATUS_*
2798 ===========================================================================*/
2799hdd_wlan_wmm_status_e hdd_wmm_checkts( hdd_adapter_t* pAdapter,
2800 v_U32_t handle )
2801{
2802 hdd_wmm_qos_context_t *pQosContext;
2803 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST;
2804
2805 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002806 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002807
2808 // locate the context with the given handle
2809 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2810 list_for_each_entry(pQosContext,
2811 &pAdapter->hddWmmStatus.wmmContextList,
2812 node)
2813 {
2814 if (pQosContext->handle == handle)
2815 {
2816 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2817 "%s: found handle 0x%x, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002818 __func__, handle, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002819
2820 status = pQosContext->lastStatus;
2821 break;
2822 }
2823 }
2824 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2825 return status;
2826}