blob: 206a4f5404220872c7a5ec647b8053dcfbe3222e [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
3 *
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>
Jeff Johnson295189b2012-06-20 16:38:30 -070071
72// change logging behavior based upon debug flag
73#ifdef HDD_WMM_DEBUG
74#define WMM_TRACE_LEVEL_FATAL VOS_TRACE_LEVEL_FATAL
75#define WMM_TRACE_LEVEL_ERROR VOS_TRACE_LEVEL_FATAL
76#define WMM_TRACE_LEVEL_WARN VOS_TRACE_LEVEL_FATAL
77#define WMM_TRACE_LEVEL_INFO VOS_TRACE_LEVEL_FATAL
78#define WMM_TRACE_LEVEL_INFO_HIGH VOS_TRACE_LEVEL_FATAL
79#define WMM_TRACE_LEVEL_INFO_LOW VOS_TRACE_LEVEL_FATAL
80#else
81#define WMM_TRACE_LEVEL_FATAL VOS_TRACE_LEVEL_FATAL
82#define WMM_TRACE_LEVEL_ERROR VOS_TRACE_LEVEL_ERROR
83#define WMM_TRACE_LEVEL_WARN VOS_TRACE_LEVEL_WARN
84#define WMM_TRACE_LEVEL_INFO VOS_TRACE_LEVEL_INFO
85#define WMM_TRACE_LEVEL_INFO_HIGH VOS_TRACE_LEVEL_INFO_HIGH
86#define WMM_TRACE_LEVEL_INFO_LOW VOS_TRACE_LEVEL_INFO_LOW
87#endif
88
89
Jeff Johnson295189b2012-06-20 16:38:30 -070090#define WLAN_HDD_MAX_DSCP 0x3f
91
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +053092// DHCP Port number
93#define DHCP_SOURCE_PORT 0x4400
94#define DHCP_DESTINATION_PORT 0x4300
95
Jeff Johnson295189b2012-06-20 16:38:30 -070096static sme_QosWmmUpType hddWmmDscpToUpMap[WLAN_HDD_MAX_DSCP+1];
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080097#define HDD_WMM_UP_TO_AC_MAP_SIZE 8
Jeff Johnson295189b2012-06-20 16:38:30 -070098const v_U8_t hddWmmUpToAcMap[] = {
99 WLANTL_AC_BE,
100 WLANTL_AC_BK,
101 WLANTL_AC_BK,
102 WLANTL_AC_BE,
103 WLANTL_AC_VI,
104 WLANTL_AC_VI,
105 WLANTL_AC_VO,
106 WLANTL_AC_VO
107};
108
109//Linux based UP -> AC Mapping
110const v_U8_t hddLinuxUpToAcMap[8] = {
111 HDD_LINUX_AC_BE,
112 HDD_LINUX_AC_BK,
113 HDD_LINUX_AC_BK,
114 HDD_LINUX_AC_BE,
115 HDD_LINUX_AC_VI,
116 HDD_LINUX_AC_VI,
117 HDD_LINUX_AC_VO,
118 HDD_LINUX_AC_VO
119};
120
121#ifndef WLAN_MDM_CODE_REDUCTION_OPT
122/**
123 @brief hdd_wmm_enable_tl_uapsd() - function which decides whether and
124 how to update UAPSD parameters in TL
125
126 @param pQosContext : [in] the pointer the QoS instance control block
127
128 @return
129 None
130*/
131static void hdd_wmm_enable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
132{
133 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
134 WLANTL_ACEnumType acType = pQosContext->acType;
135 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
136 VOS_STATUS status;
137 v_U32_t service_interval;
138 v_U32_t suspension_interval;
139 sme_QosWmmDirType direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530140 v_BOOL_t psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700141
142
143 // The TSPEC must be valid
144 if (pAc->wmmAcTspecValid == VOS_FALSE)
145 {
146 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
147 "%s: Invoked with invalid TSPEC",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700148 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700149 return;
150 }
151
152 // determine the service interval
153 if (pAc->wmmAcTspecInfo.min_service_interval)
154 {
155 service_interval = pAc->wmmAcTspecInfo.min_service_interval;
156 }
157 else if (pAc->wmmAcTspecInfo.max_service_interval)
158 {
159 service_interval = pAc->wmmAcTspecInfo.max_service_interval;
160 }
161 else
162 {
163 // no service interval is present in the TSPEC
164 // this is OK, there just won't be U-APSD
165 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
166 "%s: No service interval supplied",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700167 __func__);
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530168 service_interval = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700169 }
170
171 // determine the suspension interval & direction
172 suspension_interval = pAc->wmmAcTspecInfo.suspension_interval;
173 direction = pAc->wmmAcTspecInfo.ts_info.direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530174 psb = pAc->wmmAcTspecInfo.ts_info.psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700175
176 // if we have previously enabled U-APSD, have any params changed?
177 if ((pAc->wmmAcUapsdInfoValid) &&
178 (pAc->wmmAcUapsdServiceInterval == service_interval) &&
179 (pAc->wmmAcUapsdSuspensionInterval == suspension_interval) &&
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530180 (pAc->wmmAcUapsdDirection == direction) &&
181 (pAc->wmmAcIsUapsdEnabled == psb))
Jeff Johnson295189b2012-06-20 16:38:30 -0700182 {
183 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
184 "%s: No change in U-APSD parameters",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700185 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700186 return;
187 }
188
189 // are we in the appropriate power save modes?
190 if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_BEACON_MODE_POWER_SAVE))
191 {
192 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
193 "%s: BMPS is not enabled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700194 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700195 return;
196 }
197
198 if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_UAPSD_MODE_POWER_SAVE))
199 {
200 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
201 "%s: U-APSD is not enabled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700202 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700203 return;
204 }
205
206 // everything is in place to notify TL
207 status = WLANTL_EnableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
208 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
209 acType,
210 pAc->wmmAcTspecInfo.ts_info.tid,
211 pAc->wmmAcTspecInfo.ts_info.up,
212 service_interval,
213 suspension_interval,
214 direction);
215
216 if ( !VOS_IS_STATUS_SUCCESS( status ) )
217 {
218 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
219 "%s: Failed to enable U-APSD for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700220 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700221 return;
222 }
223
224 // stash away the parameters that were used
225 pAc->wmmAcUapsdInfoValid = VOS_TRUE;
226 pAc->wmmAcUapsdServiceInterval = service_interval;
227 pAc->wmmAcUapsdSuspensionInterval = suspension_interval;
228 pAc->wmmAcUapsdDirection = direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530229 pAc->wmmAcIsUapsdEnabled = psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700230
231 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700232 "%s: Enabled UAPSD in TL srv_int=%d "
233 "susp_int=%d dir=%d AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700234 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700235 service_interval,
236 suspension_interval,
237 direction,
238 acType);
239
240}
241
242/**
243 @brief hdd_wmm_disable_tl_uapsd() - function which decides whether
244 to disable UAPSD parameters in TL
245
246 @param pQosContext : [in] the pointer the QoS instance control block
247
248 @return
249 None
250*/
251static void hdd_wmm_disable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
252{
253 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
254 WLANTL_ACEnumType acType = pQosContext->acType;
255 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
256 VOS_STATUS status;
257
258
259 // have we previously enabled UAPSD?
260 if (pAc->wmmAcUapsdInfoValid == VOS_TRUE)
261 {
262 status = WLANTL_DisableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
263 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
264 acType);
265
266 if ( !VOS_IS_STATUS_SUCCESS( status ) )
267 {
268 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
269 "%s: Failed to disable U-APSD for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700270 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700271 }
272 else
273 {
274 // TL no longer has valid UAPSD info
275 pAc->wmmAcUapsdInfoValid = VOS_FALSE;
276 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
277 "%s: Disabled UAPSD in TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700278 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700279 acType);
280 }
281 }
282}
283
284#endif
285
286/**
287 @brief hdd_wmm_free_context() - function which frees a QoS context
288
289 @param pQosContext : [in] the pointer the QoS instance control block
290
291 @return
292 None
293*/
294static void hdd_wmm_free_context (hdd_wmm_qos_context_t* pQosContext)
295{
296 hdd_adapter_t* pAdapter;
297
298 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
299 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700300 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700301
302 if (unlikely((NULL == pQosContext) ||
303 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
304 {
305 // must have been freed in another thread
306 return;
307 }
308
309 // get pointer to the adapter context
310 pAdapter = pQosContext->pAdapter;
311
312 // take the wmmLock since we're manipulating the context list
313 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
314
315 // make sure nobody thinks this is a valid context
316 pQosContext->magic = 0;
317
318 // unlink the context
319 list_del(&pQosContext->node);
320
321 // done manipulating the list
322 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
323
324 // reclaim memory
325 kfree(pQosContext);
326
327}
328
329#ifndef WLAN_MDM_CODE_REDUCTION_OPT
330/**
331 @brief hdd_wmm_notify_app() - function which notifies an application
332 changes in state of it flow
333
334 @param pQosContext : [in] the pointer the QoS instance control block
335
336 @return
337 None
338*/
339#define MAX_NOTIFY_LEN 50
340static void hdd_wmm_notify_app (hdd_wmm_qos_context_t* pQosContext)
341{
342 hdd_adapter_t* pAdapter;
343 union iwreq_data wrqu;
344 char buf[MAX_NOTIFY_LEN+1];
345
346 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
347 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700348 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700349
350 if (unlikely((NULL == pQosContext) ||
351 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
352 {
353 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
354 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700355 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700356 return;
357 }
358
359
360 // create the event
361 memset(&wrqu, 0, sizeof(wrqu));
362 memset(buf, 0, sizeof(buf));
363
364 snprintf(buf, MAX_NOTIFY_LEN, "QCOM: TS change[%u: %u]",
365 (unsigned int)pQosContext->handle,
366 (unsigned int)pQosContext->lastStatus);
367
368 wrqu.data.pointer = buf;
369 wrqu.data.length = strlen(buf);
370
371 // get pointer to the adapter
372 pAdapter = pQosContext->pAdapter;
373
374 // send the event
375 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700376 "%s: Sending [%s]", __func__, buf);
Jeff Johnson295189b2012-06-20 16:38:30 -0700377 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
378}
379
380
381/**
382 @brief hdd_wmm_is_access_allowed() - function which determines if access
383 is allowed for the given AC. this is designed to be called during SME
384 callback processing since that is when access can be granted or removed
385
386 @param pAdapter : [in] pointer to adapter context
387 @param pAc : [in] pointer to the per-AC status
388
389 @return : VOS_TRUE - access is allowed
390 : VOS_FALSE - access is not allowed
391 None
392*/
393static v_BOOL_t hdd_wmm_is_access_allowed(hdd_adapter_t* pAdapter,
394 hdd_wmm_ac_status_t* pAc)
395{
396 // if we don't want QoS or the AP doesn't support QoS
397 // or we don't want to do implicit QoS
398 // or if AP doesn't require admission for this AC
399 // then we have access
400 if (!hdd_wmm_is_active(pAdapter) ||
401 !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled ||
402 !pAc->wmmAcAccessRequired)
403 {
404 return VOS_TRUE;
405 }
406
407 // if implicit QoS has already completed, successfully or not,
408 // then access is allowed
409 if (pAc->wmmAcAccessGranted || pAc->wmmAcAccessFailed)
410 {
411 return VOS_TRUE;
412 }
413
414 // admission is required and implicit QoS hasn't completed
415 // however explicit QoS may have completed and we'll have
416 // a Tspec
417 // if we don't have a Tspec then access is not allowed
418 if (!pAc->wmmAcTspecValid)
419 {
420 return VOS_FALSE;
421 }
422
423 // we have a Tspec -- does it allow upstream or bidirectional traffic?
424 // if it only allows downstream traffic then access is not allowed
425 if (pAc->wmmAcTspecInfo.ts_info.direction == SME_QOS_WMM_TS_DIR_DOWNLINK)
426 {
427 return VOS_FALSE;
428 }
429
430 // we meet all of the criteria for access
431 return VOS_TRUE;
432}
433
434#ifdef FEATURE_WLAN_CCX
435/**
436 @brief hdd_wmm_inactivity_timer_cb() - timer handler function which is
437 called for every inactivity interval per AC. This function gets the
438 current transmitted packets on the given AC, and checks if there where
439 any TX activity from the previous interval. If there was no traffic
440 then it would delete the TS that was negotiated on that AC.
441
442 @param pUserData : [in] pointer to pQosContext
443
444 @return : NONE
445*/
446void hdd_wmm_inactivity_timer_cb( v_PVOID_t pUserData )
447{
448 hdd_wmm_qos_context_t* pQosContext = (hdd_wmm_qos_context_t*)pUserData;
449 hdd_adapter_t* pAdapter;
450 hdd_wmm_ac_status_t *pAc;
451 hdd_wlan_wmm_status_e status;
452 VOS_STATUS vos_status;
453 v_U32_t currentTrafficCnt = 0;
454 WLANTL_ACEnumType acType = pQosContext->acType;
455
456 pAdapter = pQosContext->pAdapter;
457 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
458
459 // Get the Tx stats for this AC.
460 currentTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];
461
462 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800463 FL("WMM inactivity Timer for AC=%d, currentCnt=%d, prevCnt=%d"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700464 acType, (int)currentTrafficCnt, (int)pAc->wmmPrevTrafficCnt);
465 if (pAc->wmmPrevTrafficCnt == currentTrafficCnt)
466 {
467 // If there is no traffic activity, delete the TSPEC for this AC
468 status = hdd_wmm_delts(pAdapter, pQosContext->handle);
469 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
470 FL("Deleted TS on AC %d, due to inactivity with status = %d!!!"),
471 acType, status);
472 }
473 else
474 {
475 pAc->wmmPrevTrafficCnt = currentTrafficCnt;
476 if (pAc->wmmInactivityTimer.state == VOS_TIMER_STATE_STOPPED)
477 {
478 // Restart the timer
479 vos_status = vos_timer_start(&pAc->wmmInactivityTimer, pAc->wmmInactivityTime);
480 if (!VOS_IS_STATUS_SUCCESS(vos_status))
481 {
482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
483 FL("Restarting inactivity timer failed on AC %d"), acType);
484 }
485 }
486 else
487 {
488 VOS_ASSERT(vos_timer_getCurrentState(
489 &pAc->wmmInactivityTimer) == VOS_TIMER_STATE_STOPPED);
490 }
491 }
492
493 return;
494}
495
496
497/**
498 @brief hdd_wmm_enable_inactivity_timer() - function to enable the
499 traffic inactivity timer for the given AC, if the inactivity_interval
500 specified in the ADDTS parameters is non-zero
501
502 @param pQosContext : [in] pointer to pQosContext
503 @param inactivityTime: [in] value of the inactivity interval in millisecs
504
505 @return : VOS_STATUS_E_FAILURE
506 VOS_STATUS_SUCCESS
507*/
508VOS_STATUS hdd_wmm_enable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext, v_U32_t inactivityTime)
509{
510 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
511 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
512 WLANTL_ACEnumType acType = pQosContext->acType;
513 hdd_wmm_ac_status_t *pAc;
514
515 pAdapter = pQosContext->pAdapter;
516 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
517
518
519 // If QoS-Tspec is successfully setup and if the inactivity timer is non-zero,
520 // a traffic inactivity timer needs to be started for the given AC
521 vos_status = vos_timer_init(
522 &pAc->wmmInactivityTimer,
523 VOS_TIMER_TYPE_SW,
524 hdd_wmm_inactivity_timer_cb,
525 (v_PVOID_t)pQosContext );
526 if ( !VOS_IS_STATUS_SUCCESS(vos_status))
527 {
528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
529 FL("Initializing inactivity timer failed on AC %d"), acType);
530 return vos_status;
531 }
532
533 // Start the inactivity timer
534 vos_status = vos_timer_start(
535 &pAc->wmmInactivityTimer,
536 inactivityTime);
537 if ( !VOS_IS_STATUS_SUCCESS(vos_status))
538 {
539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
540 FL("Starting inactivity timer failed on AC %d"), acType);
541 return vos_status;
542 }
543 pAc->wmmInactivityTime = inactivityTime;
544 // Initialize the current tx traffic count on this AC
545 pAc->wmmPrevTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];
546
547 return vos_status;
548}
549
550/**
551 @brief hdd_wmm_enable_inactivity_timer() - function to disable the
552 traffic inactivity timer for the given AC. This would be called when
553 deleting the TS.
554
555 @param pQosContext : [in] pointer to pQosContext
556
557 @return : VOS_STATUS_E_FAILURE
558 VOS_STATUS_SUCCESS
559*/
560VOS_STATUS hdd_wmm_disable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext)
561{
562 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
563 WLANTL_ACEnumType acType = pQosContext->acType;
564 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
565 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
566
567 // Clear the timer and the counter
568 pAc->wmmInactivityTime = 0;
569 pAc->wmmPrevTrafficCnt = 0;
570 vos_timer_stop(&pAc->wmmInactivityTimer);
571 vos_status = vos_timer_destroy(&pAc->wmmInactivityTimer);
572
573 return vos_status;
574}
575#endif // FEATURE_WLAN_CCX
576
577/**
578 @brief hdd_wmm_sme_callback() - callback registered by HDD with SME for receiving
579 QoS notifications. Even though this function has a static scope it gets called
580 externally through some function pointer magic (so there is a need for
581 rigorous parameter checking)
582
583 @param hHal : [in] the HAL handle
584 @param HddCtx : [in] the HDD specified handle
585 @param pCurrentQosInfo : [in] the TSPEC params
586 @param SmeStatus : [in] the QoS related SME status
587
588 @return
589 eHAL_STATUS_SUCCESS if all good, eHAL_STATUS_FAILURE otherwise
590*/
591static eHalStatus hdd_wmm_sme_callback (tHalHandle hHal,
592 void * hddCtx,
593 sme_QosWmmTspecInfo* pCurrentQosInfo,
594 sme_QosStatusType smeStatus,
595 v_U32_t qosFlowId)
596{
597 hdd_wmm_qos_context_t* pQosContext = hddCtx;
598 hdd_adapter_t* pAdapter;
599 WLANTL_ACEnumType acType;
600 hdd_wmm_ac_status_t *pAc;
601 VOS_STATUS status;
602
603 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
604 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700605 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700606
607 if (unlikely((NULL == pQosContext) ||
608 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
609 {
610 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
611 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700612 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700613 return eHAL_STATUS_FAILURE;
614 }
615
616 pAdapter = pQosContext->pAdapter;
617 acType = pQosContext->acType;
618 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
619
620 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
621 "%s: status %d flowid %d info %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700622 __func__, smeStatus, qosFlowId, pCurrentQosInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -0700623
624 switch (smeStatus)
625 {
626
627 case SME_QOS_STATUS_SETUP_SUCCESS_IND:
628 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
629 "%s: Setup is complete",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700630 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700631
632 // there will always be a TSPEC returned with this status, even if
633 // a TSPEC is not exchanged OTA
634 if (pCurrentQosInfo)
635 {
636 pAc->wmmAcTspecValid = VOS_TRUE;
637 memcpy(&pAc->wmmAcTspecInfo,
638 pCurrentQosInfo,
639 sizeof(pAc->wmmAcTspecInfo));
640 }
641
642 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
643 {
644
645 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
646 "%s: Implicit Qos, notifying TL for TL AC %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700647 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700648
649 // this was triggered by implicit QoS so we know packets are pending
650 // update state
651 pAc->wmmAcAccessAllowed = VOS_TRUE;
652 pAc->wmmAcAccessGranted = VOS_TRUE;
653 pAc->wmmAcAccessPending = VOS_FALSE;
654
655 // notify TL that packets are pending
656 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
657 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
658 acType );
659
660 if ( !VOS_IS_STATUS_SUCCESS( status ) )
661 {
662 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
663 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700664 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700665 }
666 }
667 else
668 {
669 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
670 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700671 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700672
673 // this was triggered by an application
674 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
675 hdd_wmm_notify_app(pQosContext);
676 }
677
678#ifdef FEATURE_WLAN_CCX
679 // Check if the inactivity interval is specified
Jeff Johnson8795e422013-04-03 08:59:22 -0700680 if (pCurrentQosInfo && pCurrentQosInfo->inactivity_interval) {
Jeff Johnson295189b2012-06-20 16:38:30 -0700681 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800682 "%s: Inactivity timer value = %d for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700683 __func__, pCurrentQosInfo->inactivity_interval, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700684 hdd_wmm_enable_inactivity_timer(pQosContext, pCurrentQosInfo->inactivity_interval);
685 }
686#endif // FEATURE_WLAN_CCX
687
688 // notify TL to enable trigger frames if necessary
689 hdd_wmm_enable_tl_uapsd(pQosContext);
690
691 break;
692
693 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
694 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
695 "%s: Setup is complete (U-APSD set previously)",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700696 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700697
698 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
699 {
700
701 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
702 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700703 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700704
705 // this was triggered by implicit QoS so we know packets are pending
706 // update state
707 pAc->wmmAcAccessAllowed = VOS_TRUE;
708 pAc->wmmAcAccessGranted = VOS_TRUE;
709 pAc->wmmAcAccessPending = VOS_FALSE;
710
711 // notify TL that packets are pending
712 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
713 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
714 acType );
715
716 if ( !VOS_IS_STATUS_SUCCESS( status ) )
717 {
718 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
719 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700720 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700721 }
722 }
723 else
724 {
725 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
726 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700727 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700728
729 // this was triggered by an application
730 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
731 hdd_wmm_notify_app(pQosContext);
732 }
733
734 break;
735
736 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
737 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
738 "%s: Setup failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700739 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700740 // QoS setup failed
741
742 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
743 {
744
745 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
746 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700747 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700748
749 // we note the failure, but we also mark access as allowed so that
750 // the packets will flow. Note that the MAC will "do the right thing"
751 pAc->wmmAcAccessPending = VOS_FALSE;
752 pAc->wmmAcAccessFailed = VOS_TRUE;
753 pAc->wmmAcAccessAllowed = VOS_TRUE;
754
755 // this was triggered by implicit QoS so we know packets are pending
756 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
757 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
758 acType );
759
760 if ( !VOS_IS_STATUS_SUCCESS( status ) )
761 {
762 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
763 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700764 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700765 }
766 }
767 else
768 {
769 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
770 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700771 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700772
773 // this was triggered by an application
774 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED;
775 hdd_wmm_notify_app(pQosContext);
776 }
777
778 /* Setting up QoS Failed, QoS context can be released.
779 * SME is releasing this flow information and if HDD doen't release this context,
780 * next time if application uses the same handle to set-up QoS, HDD (as it has
781 * QoS context for this handle) will issue Modify QoS request to SME but SME will
782 * reject as no it has no information for this flow.
783 */
784 hdd_wmm_free_context(pQosContext);
785 break;
786
787 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
788 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
789 "%s: Setup Invalid Params, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700790 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700791 // QoS setup failed
792
793 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
794 {
795
796 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
797 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700798 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700799
800 // we note the failure, but we also mark access as allowed so that
801 // the packets will flow. Note that the MAC will "do the right thing"
802 pAc->wmmAcAccessPending = VOS_FALSE;
803 pAc->wmmAcAccessFailed = VOS_TRUE;
804 pAc->wmmAcAccessAllowed = VOS_TRUE;
805
806 // this was triggered by implicit QoS so we know packets are pending
807 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
808 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
809 acType );
810
811 if ( !VOS_IS_STATUS_SUCCESS( status ) )
812 {
813 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
814 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700815 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700816 }
817 }
818 else
819 {
820 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
821 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700822 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700823
824 // this was triggered by an application
825 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
826 hdd_wmm_notify_app(pQosContext);
827 }
828 break;
829
830 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
831 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800832 "%s: Setup failed, not a QoS AP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700833 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700834 if (!HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
835 {
836 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
837 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700838 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700839
840 // this was triggered by an application
841 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
842 hdd_wmm_notify_app(pQosContext);
843 }
844 break;
845
846 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
847 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
848 "%s: Setup pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700849 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700850 // not a callback status -- ignore if we get it
851 break;
852
853 case SME_QOS_STATUS_SETUP_MODIFIED_IND:
854 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
855 "%s: Setup modified",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700856 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700857 if (pCurrentQosInfo)
858 {
859 // update the TSPEC
860 pAc->wmmAcTspecValid = VOS_TRUE;
861 memcpy(&pAc->wmmAcTspecInfo,
862 pCurrentQosInfo,
863 sizeof(pAc->wmmAcTspecInfo));
864
865 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
866 {
867 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
868 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700869 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700870
871 // this was triggered by an application
872 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFIED;
873 hdd_wmm_notify_app(pQosContext);
874 }
875
876 // need to tell TL to update its UAPSD handling
877 hdd_wmm_enable_tl_uapsd(pQosContext);
878 }
879 break;
880
881 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
882 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
883 {
884
885 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
886 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700887 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700888
889 // this was triggered by implicit QoS so we know packets are pending
890 pAc->wmmAcAccessPending = VOS_FALSE;
891 pAc->wmmAcAccessGranted = VOS_TRUE;
892 pAc->wmmAcAccessAllowed = VOS_TRUE;
893
894 // notify TL that packets are pending
895 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
896 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
897 acType );
898
899 if ( !VOS_IS_STATUS_SUCCESS( status ) )
900 {
901 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
902 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700903 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700904 }
905 }
906 else
907 {
908 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
909 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700910 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700911
912 // this was triggered by an application
913 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
914 hdd_wmm_notify_app(pQosContext);
915 }
916 break;
917
918 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
919 // nothing to do for now
920 break;
921
922 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED:
923 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
924 "%s: Setup successful but U-APSD failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700925 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700926
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 // QoS setup was successful but setting U=APSD failed
935 // Since the OTA part of the request was successful, we don't mark
936 // this as a failure.
937 // the packets will flow. Note that the MAC will "do the right thing"
938 pAc->wmmAcAccessGranted = VOS_TRUE;
939 pAc->wmmAcAccessAllowed = VOS_TRUE;
940 pAc->wmmAcAccessFailed = VOS_FALSE;
941 pAc->wmmAcAccessPending = VOS_FALSE;
942
943 // this was triggered by implicit QoS so we know packets are pending
944 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
945 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
946 acType );
947
948 if ( !VOS_IS_STATUS_SUCCESS( status ) )
949 {
950 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
951 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700952 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700953 }
954 }
955 else
956 {
957 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
958 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700959 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700960
961 // this was triggered by an application
962 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_UAPSD_SET_FAILED;
963 hdd_wmm_notify_app(pQosContext);
964 }
965
966 // Since U-APSD portion failed disabled trigger frame generation
967 hdd_wmm_disable_tl_uapsd(pQosContext);
968
969 break;
970
971 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
972 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
973 "%s: Release is complete",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700974 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700975
976 if (pCurrentQosInfo)
977 {
978 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
979 "%s: flows still active",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700980 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700981
982 // there is still at least one flow active for this AC
983 // so update the AC state
984 memcpy(&pAc->wmmAcTspecInfo,
985 pCurrentQosInfo,
986 sizeof(pAc->wmmAcTspecInfo));
987
988 // need to tell TL to update its UAPSD handling
989 hdd_wmm_enable_tl_uapsd(pQosContext);
990 }
991 else
992 {
993 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
994 "%s: last flow",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700995 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700996
997 // this is the last flow active for this AC so update the AC state
998 pAc->wmmAcTspecValid = VOS_FALSE;
999
1000 // need to tell TL to update its UAPSD handling
1001 hdd_wmm_disable_tl_uapsd(pQosContext);
1002 }
1003
1004 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1005 {
1006 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1007 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001008 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001009
1010 // this was triggered by an application
1011 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
1012 hdd_wmm_notify_app(pQosContext);
1013 }
1014
1015 // we are done with this flow
1016 hdd_wmm_free_context(pQosContext);
1017 break;
1018
1019 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
1020 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1021 "%s: Release failure",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001022 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001023
1024 // we don't need to update our state or TL since nothing has changed
1025 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1026 {
1027 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1028 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001029 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001030
1031 // this was triggered by an application
1032 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
1033 hdd_wmm_notify_app(pQosContext);
1034 }
1035
1036 break;
1037
1038 case SME_QOS_STATUS_RELEASE_QOS_LOST_IND:
1039 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1040 "%s: QOS Lost indication received",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001041 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001042
1043 // current TSPEC is no longer valid
1044 pAc->wmmAcTspecValid = VOS_FALSE;
1045
1046 // need to tell TL to update its UAPSD handling
1047 hdd_wmm_disable_tl_uapsd(pQosContext);
1048
1049 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
1050 {
1051 // we no longer have implicit access granted
1052 pAc->wmmAcAccessGranted = VOS_FALSE;
1053 pAc->wmmAcAccessFailed = VOS_FALSE;
1054 }
1055 else
1056 {
1057 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1058 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001059 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001060
1061 // this was triggered by an application
1062 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_LOST;
1063 hdd_wmm_notify_app(pQosContext);
1064 }
1065
1066 // we are done with this flow
1067 hdd_wmm_free_context(pQosContext);
1068 break;
1069
1070 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
1071 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1072 "%s: Release pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001073 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001074 // not a callback status -- ignore if we get it
1075 break;
1076
1077 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
1078 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1079 "%s: Release Invalid Params",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001080 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001081 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1082 {
1083 // this was triggered by an application
1084 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
1085 hdd_wmm_notify_app(pQosContext);
1086 }
1087 break;
1088
1089 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND:
1090 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1091 "%s: Modification is complete, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001092 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001093
1094 // there will always be a TSPEC returned with this status, even if
1095 // a TSPEC is not exchanged OTA
1096 if (pCurrentQosInfo)
1097 {
1098 pAc->wmmAcTspecValid = VOS_TRUE;
1099 memcpy(&pAc->wmmAcTspecInfo,
1100 pCurrentQosInfo,
1101 sizeof(pAc->wmmAcTspecInfo));
1102 }
1103
1104 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1105 {
1106 // this was triggered by an application
1107 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS;
1108 hdd_wmm_notify_app(pQosContext);
1109 }
1110
1111 // notify TL to enable trigger frames if necessary
1112 hdd_wmm_enable_tl_uapsd(pQosContext);
1113
1114 break;
1115
1116 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
1117 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1118 {
1119 // this was triggered by an application
1120 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
1121 hdd_wmm_notify_app(pQosContext);
1122 }
1123 break;
1124
1125 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
1126 // the flow modification failed so we'll leave in place
1127 // whatever existed beforehand
1128
1129 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1130 {
1131 // this was triggered by an application
1132 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
1133 hdd_wmm_notify_app(pQosContext);
1134 }
1135 break;
1136
1137 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
1138 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1139 "%s: modification pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001140 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001141 // not a callback status -- ignore if we get it
1142 break;
1143
1144 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1145 // the flow modification was successful but no QoS changes required
1146
1147 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1148 {
1149 // this was triggered by an application
1150 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
1151 hdd_wmm_notify_app(pQosContext);
1152 }
1153 break;
1154
1155 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
1156 // invalid params -- notify the application
1157 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1158 {
1159 // this was triggered by an application
1160 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
1161 hdd_wmm_notify_app(pQosContext);
1162 }
1163 break;
1164
1165 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_PENDING:
1166 // nothing to do for now. when APSD is established we'll have work to do
1167 break;
1168
1169 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED:
1170 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1171 "%s: Modify successful but U-APSD failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001172 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001173
1174 // QoS modification was successful but setting U=APSD failed.
1175 // This will always be an explicit QoS instance, so all we can
1176 // do is notify the application and let it clean up.
1177 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1178 {
1179 // this was triggered by an application
1180 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_UAPSD_SET_FAILED;
1181 hdd_wmm_notify_app(pQosContext);
1182 }
1183
1184 // Since U-APSD portion failed disabled trigger frame generation
1185 hdd_wmm_disable_tl_uapsd(pQosContext);
1186
1187 break;
1188
1189 case SME_QOS_STATUS_HANDING_OFF:
1190 // no roaming so we won't see this
1191 break;
1192
1193 case SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND:
1194 // need to tell TL to stop trigger frame generation
1195 hdd_wmm_disable_tl_uapsd(pQosContext);
1196 break;
1197
1198 case SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND:
1199 // need to tell TL to start sending trigger frames again
1200 hdd_wmm_enable_tl_uapsd(pQosContext);
1201 break;
1202
1203 default:
1204 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001205 "%s: unexpected SME Status=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001206 __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07001207 VOS_ASSERT(0);
1208 }
1209
1210 // our access to the particular access category may have changed.
1211 // some of the implicit QoS cases above may have already set this
1212 // prior to invoking TL (so that we will properly service the
1213 // Tx queues) but let's consistently handle all cases here
1214 pAc->wmmAcAccessAllowed = hdd_wmm_is_access_allowed(pAdapter, pAc);
1215
1216 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1217 "%s: complete, access for TL AC %d is%sallowed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001218 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001219 acType,
1220 pAc->wmmAcAccessAllowed ? " " : " not ");
1221
1222 return eHAL_STATUS_SUCCESS;
1223}
1224#endif
1225
Kiet Lamf040f472013-11-20 21:15:23 +05301226/**========================================================================
1227 @brief hdd_wmmps_helper() - Function to set uapsd psb dynamically
1228
1229 @param pAdapter : [in] pointer to adapter structure
1230
1231 @param ptr : [in] pointer to command buffer
1232
1233 @return : Zero on success, appropriate error on failure.
1234 =======================================================================*/
1235int hdd_wmmps_helper(hdd_adapter_t *pAdapter, tANI_U8 *ptr)
1236{
1237 if (NULL == pAdapter)
1238 {
1239 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1240 "%s: pAdapter is NULL", __func__);
1241 return -EINVAL;
1242 }
1243 if (NULL == ptr)
1244 {
1245 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1246 "%s: ptr is NULL", __func__);
1247 return -EINVAL;
1248 }
1249 /* convert ASCII to integer */
1250 pAdapter->configuredPsb = ptr[9] - '0';
1251 pAdapter->psbChanged = HDD_PSB_CHANGED;
1252
1253 return 0;
1254}
1255
Jeff Johnson295189b2012-06-20 16:38:30 -07001256/**============================================================================
1257 @brief hdd_wmm_do_implicit_qos() - Function which will attempt to setup
1258 QoS for any AC requiring it
1259
1260 @param work : [in] pointer to work structure
1261
1262 @return : void
1263 ===========================================================================*/
1264static void hdd_wmm_do_implicit_qos(struct work_struct *work)
1265{
1266 hdd_wmm_qos_context_t* pQosContext =
1267 container_of(work, hdd_wmm_qos_context_t, wmmAcSetupImplicitQos);
1268 hdd_adapter_t* pAdapter;
1269 WLANTL_ACEnumType acType;
1270 hdd_wmm_ac_status_t *pAc;
1271#ifndef WLAN_MDM_CODE_REDUCTION_OPT
1272 VOS_STATUS status;
1273 sme_QosStatusType smeStatus;
1274#endif
1275 sme_QosWmmTspecInfo qosInfo;
1276
1277 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1278 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001279 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001280
1281 if (unlikely(HDD_WMM_CTX_MAGIC != pQosContext->magic))
1282 {
1283 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1284 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001285 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001286 return;
1287 }
1288
1289 pAdapter = pQosContext->pAdapter;
1290 acType = pQosContext->acType;
1291 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1292
1293 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1294 "%s: pAdapter %p acType %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001295 __func__, pAdapter, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001296
1297 if (!pAc->wmmAcAccessNeeded)
1298 {
1299 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1300 "%s: AC %d doesn't need service",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001301 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001302 pQosContext->magic = 0;
1303 kfree(pQosContext);
1304 return;
1305 }
1306
1307 pAc->wmmAcAccessPending = VOS_TRUE;
1308 pAc->wmmAcAccessNeeded = VOS_FALSE;
1309
1310 memset(&qosInfo, 0, sizeof(qosInfo));
1311
Kiet Lamf040f472013-11-20 21:15:23 +05301312 qosInfo.ts_info.psb = pAdapter->configuredPsb;
1313
Jeff Johnson295189b2012-06-20 16:38:30 -07001314 switch (acType)
1315 {
1316 case WLANTL_AC_VO:
1317 qosInfo.ts_info.up = SME_QOS_WMM_UP_VO;
Kiet Lamf040f472013-11-20 21:15:23 +05301318 /* Check if there is any valid configuration from framework */
1319 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1320 {
1321 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1322 SME_QOS_UAPSD_VO) ? 1 : 0;
1323 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001324 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVo;
1325 qosInfo.ts_info.tid = 255;
1326 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVo;
1327 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVo;
1328 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv;
1329 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVo;
1330 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVo;
1331 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv;
1332 break;
1333 case WLANTL_AC_VI:
1334 qosInfo.ts_info.up = SME_QOS_WMM_UP_VI;
Kiet Lamf040f472013-11-20 21:15:23 +05301335 /* Check if there is any valid configuration from framework */
1336 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1337 {
1338 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1339 SME_QOS_UAPSD_VI) ? 1 : 0;
1340 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001341 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVi;
1342 qosInfo.ts_info.tid = 255;
1343 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVi;
1344 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVi;
1345 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv;
1346 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVi;
1347 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVi;
1348 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv;
1349 break;
1350 default:
1351 case WLANTL_AC_BE:
1352 qosInfo.ts_info.up = SME_QOS_WMM_UP_BE;
Kiet Lamf040f472013-11-20 21:15:23 +05301353 /* Check if there is any valid configuration from framework */
1354 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1355 {
1356 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1357 SME_QOS_UAPSD_BE) ? 1 : 0;
1358 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001359 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBe;
1360 qosInfo.ts_info.tid = 255;
1361 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBe;
1362 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBe;
1363 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv;
1364 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBe;
1365 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBe;
1366 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv;
1367 break;
1368 case WLANTL_AC_BK:
1369 qosInfo.ts_info.up = SME_QOS_WMM_UP_BK;
Kiet Lamf040f472013-11-20 21:15:23 +05301370 /* Check if there is any valid configuration from framework */
1371 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1372 {
1373 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1374 SME_QOS_UAPSD_BK) ? 1 : 0;
1375 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001376 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBk;
1377 qosInfo.ts_info.tid = 255;
1378 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBk;
1379 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBk;
1380 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv;
1381 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBk;
1382 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBk;
1383 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv;
1384 break;
1385 }
1386#ifdef FEATURE_WLAN_CCX
1387 qosInfo.inactivity_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraInactivityInterval;
1388#endif
1389 qosInfo.ts_info.burst_size_defn = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->burstSizeDefinition;
1390
1391 switch ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->tsInfoAckPolicy)
1392 {
1393 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK:
1394 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1395 break;
1396
1397 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
1398 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
1399 break;
1400
1401 default:
1402 // unknown
1403 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1404 }
1405
1406 if(qosInfo.ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK)
1407 {
1408 if(!sme_QosIsTSInfoAckPolicyValid((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter), &qosInfo, pAdapter->sessionId))
1409 {
1410 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1411 }
1412 }
1413
1414 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
1415 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
1416 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
1417
1418#ifndef WLAN_MDM_CODE_REDUCTION_OPT
1419 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
1420 pAdapter->sessionId,
1421 &qosInfo,
1422 hdd_wmm_sme_callback,
1423 pQosContext,
1424 qosInfo.ts_info.up,
1425 &pQosContext->qosFlowId);
1426
1427 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1428 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001429 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001430
1431 // need to check the return values and act appropriately
1432 switch (smeStatus)
1433 {
1434 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
1435 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
1436 // setup is pending, so no more work to do now.
1437 // all further work will be done in hdd_wmm_sme_callback()
1438 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1439 "%s: Setup is pending, no further work",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001440 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001441
1442 break;
1443
1444
1445 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
1446 // we can't tell the difference between when a request fails because
1447 // AP rejected it versus when SME encountered an internal error
1448
1449 // in either case SME won't ever reference this context so
1450 // free the record
1451 hdd_wmm_free_context(pQosContext);
1452
1453 // fall through and start packets flowing
1454 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1455 // no ACM in effect, no need to setup U-APSD
1456 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
1457 // no ACM in effect, U-APSD is desired but was already setup
1458
1459 // for these cases everything is already setup so we can
1460 // signal TL that it has work to do
1461 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1462 "%s: Setup is complete, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001463 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001464
1465 pAc->wmmAcAccessAllowed = VOS_TRUE;
1466 pAc->wmmAcAccessGranted = VOS_TRUE;
1467 pAc->wmmAcAccessPending = VOS_FALSE;
1468
1469 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1470 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
1471 acType );
1472
1473 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1474 {
1475 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1476 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001477 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -07001478 }
1479
1480 break;
1481
1482
1483 default:
1484 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001485 "%s: unexpected SME Status=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001486 __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07001487 VOS_ASSERT(0);
1488 }
1489#endif
1490
1491}
1492
1493/**============================================================================
1494 @brief hdd_wmm_init() - Function which will initialize the WMM configuation
1495 and status to an initial state. The configuration can later be overwritten
1496 via application APIs
1497
1498 @param pHddCtx : [in] pointer to HDD context
1499
1500 @return : VOS_STATUS_SUCCESS if succssful
1501 : other values if failure
1502
1503 ===========================================================================*/
1504VOS_STATUS hdd_wmm_init ( hdd_context_t* pHddCtx )
1505{
1506 v_U8_t dscp;
1507
1508 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001509 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001510
1511 // DSCP to User Priority Lookup Table
1512 for (dscp = 0; dscp <= WLAN_HDD_MAX_DSCP; dscp++)
1513 {
1514 hddWmmDscpToUpMap[dscp] = SME_QOS_WMM_UP_BE;
1515 }
1516 hddWmmDscpToUpMap[8] = SME_QOS_WMM_UP_BK;
1517 hddWmmDscpToUpMap[16] = SME_QOS_WMM_UP_RESV;
1518 hddWmmDscpToUpMap[24] = SME_QOS_WMM_UP_EE;
1519 hddWmmDscpToUpMap[32] = SME_QOS_WMM_UP_CL;
1520 hddWmmDscpToUpMap[40] = SME_QOS_WMM_UP_VI;
1521 hddWmmDscpToUpMap[48] = SME_QOS_WMM_UP_VO;
1522 hddWmmDscpToUpMap[56] = SME_QOS_WMM_UP_NC;
Jeff Johnson295189b2012-06-20 16:38:30 -07001523 return VOS_STATUS_SUCCESS;
1524}
1525
1526/**============================================================================
1527 @brief hdd_wmm_adapter_init() - Function which will initialize the WMM configuation
1528 and status to an initial state. The configuration can later be overwritten
1529 via application APIs
1530
1531 @param pAdapter : [in] pointer to Adapter context
1532
1533 @return : VOS_STATUS_SUCCESS if succssful
1534 : other values if failure
1535
1536 ===========================================================================*/
1537VOS_STATUS hdd_wmm_adapter_init( hdd_adapter_t *pAdapter )
1538{
1539 hdd_wmm_ac_status_t *pAcStatus;
1540 WLANTL_ACEnumType acType;
1541
1542 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001543 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001544
1545 pAdapter->hddWmmStatus.wmmQap = VOS_FALSE;
1546 INIT_LIST_HEAD(&pAdapter->hddWmmStatus.wmmContextList);
1547 mutex_init(&pAdapter->hddWmmStatus.wmmLock);
1548
1549 for (acType = 0; acType < WLANTL_MAX_AC; acType++)
1550 {
1551 pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1552 pAcStatus->wmmAcAccessRequired = VOS_FALSE;
1553 pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
1554 pAcStatus->wmmAcAccessPending = VOS_FALSE;
1555 pAcStatus->wmmAcAccessFailed = VOS_FALSE;
1556 pAcStatus->wmmAcAccessGranted = VOS_FALSE;
1557 pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
1558 pAcStatus->wmmAcTspecValid = VOS_FALSE;
1559 pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
1560 }
Kiet Lamf040f472013-11-20 21:15:23 +05301561 // Invalid value(0xff) to indicate psb not configured through framework initially.
1562 pAdapter->configuredPsb = HDD_PSB_CFG_INVALID;
Jeff Johnson295189b2012-06-20 16:38:30 -07001563
1564 return VOS_STATUS_SUCCESS;
1565}
Madan Mohan Koyyalamudi70c52d32013-08-07 14:42:16 +05301566
1567/**============================================================================
1568 @brief hdd_wmm_adapter_clear() - Function which will clear the WMM status
1569 for all the ACs
1570
1571 @param pAdapter : [in] pointer to Adapter context
1572
1573 @return : VOS_STATUS_SUCCESS if succssful
1574 : other values if failure
1575
1576 ===========================================================================*/
1577VOS_STATUS hdd_wmm_adapter_clear( hdd_adapter_t *pAdapter )
1578{
1579 hdd_wmm_ac_status_t *pAcStatus;
1580 WLANTL_ACEnumType acType;
1581 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1582 "%s: Entered", __func__);
1583 for (acType = 0; acType < WLANTL_MAX_AC; acType++)
1584 {
1585 pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1586 pAcStatus->wmmAcAccessRequired = VOS_FALSE;
1587 pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
1588 pAcStatus->wmmAcAccessPending = VOS_FALSE;
1589 pAcStatus->wmmAcAccessFailed = VOS_FALSE;
1590 pAcStatus->wmmAcAccessGranted = VOS_FALSE;
1591 pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
1592 pAcStatus->wmmAcTspecValid = VOS_FALSE;
1593 pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
1594 }
1595 return VOS_STATUS_SUCCESS;
1596}
1597
Jeff Johnson295189b2012-06-20 16:38:30 -07001598/**============================================================================
1599 @brief hdd_wmm_close() - Function which will perform any necessary work to
1600 to clean up the WMM functionality prior to the kernel module unload
1601
1602 @param pAdapter : [in] pointer to adapter context
1603
1604 @return : VOS_STATUS_SUCCESS if succssful
1605 : other values if failure
1606
1607 ===========================================================================*/
1608VOS_STATUS hdd_wmm_adapter_close ( hdd_adapter_t* pAdapter )
1609{
1610 hdd_wmm_qos_context_t* pQosContext;
1611
1612 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001613 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001614
1615 // free any context records that we still have linked
1616 while (!list_empty(&pAdapter->hddWmmStatus.wmmContextList))
1617 {
1618 pQosContext = list_first_entry(&pAdapter->hddWmmStatus.wmmContextList,
1619 hdd_wmm_qos_context_t, node);
1620#ifdef FEATURE_WLAN_CCX
1621 hdd_wmm_disable_inactivity_timer(pQosContext);
1622#endif
Sameer Thalappilbee426e2013-10-30 10:30:30 -07001623#ifdef WLAN_OPEN_SOURCE
1624 cancel_work_sync(&pQosContext->wmmAcSetupImplicitQos);
1625#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001626 hdd_wmm_free_context(pQosContext);
1627 }
1628
1629 return VOS_STATUS_SUCCESS;
1630}
1631
1632/**============================================================================
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301633 @brief is_dhcp_packet() - Function which will check OS packet for
1634 DHCP packet
1635
1636 @param skb : [in] pointer to OS packet (sk_buff)
1637 @return : VOS_TRUE if the OS packet is DHCP packet
1638 : otherwise VOS_FALSE
1639 ===========================================================================*/
1640v_BOOL_t is_dhcp_packet(struct sk_buff *skb)
1641{
1642 if (*((u16*)((u8*)skb->data+34)) == DHCP_SOURCE_PORT ||
1643 *((u16*)((u8*)skb->data+34)) == DHCP_DESTINATION_PORT)
1644 return VOS_TRUE;
1645
1646 return VOS_FALSE;
1647}
1648
1649/**============================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07001650 @brief hdd_wmm_classify_pkt() - Function which will classify an OS packet
1651 into a WMM AC based on either 802.1Q or DSCP
1652
1653 @param pAdapter : [in] pointer to adapter context
1654 @param skb : [in] pointer to OS packet (sk_buff)
1655 @param pAcType : [out] pointer to WMM AC type of OS packet
1656
1657 @return : None
1658 ===========================================================================*/
1659v_VOID_t hdd_wmm_classify_pkt ( hdd_adapter_t* pAdapter,
1660 struct sk_buff *skb,
1661 WLANTL_ACEnumType* pAcType,
1662 sme_QosWmmUpType *pUserPri)
1663{
1664 unsigned char * pPkt;
1665 union generic_ethhdr *pHdr;
1666 struct iphdr *pIpHdr;
1667 unsigned char tos;
1668 unsigned char dscp;
1669 sme_QosWmmUpType userPri;
1670 WLANTL_ACEnumType acType;
1671
1672 // this code is executed for every packet therefore
1673 // all debug code is kept conditional
1674
1675#ifdef HDD_WMM_DEBUG
1676 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001677 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001678#endif // HDD_WMM_DEBUG
1679
1680 pPkt = skb->data;
1681 pHdr = (union generic_ethhdr *)pPkt;
1682
1683#ifdef HDD_WMM_DEBUG
1684 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1685 "%s: proto/length is 0x%04x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001686 __func__, pHdr->eth_II.h_proto);
Jeff Johnson295189b2012-06-20 16:38:30 -07001687#endif // HDD_WMM_DEBUG
1688
1689 if (HDD_WMM_CLASSIFICATION_DSCP == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
1690 {
1691 if (pHdr->eth_II.h_proto == htons(ETH_P_IP))
1692 {
1693 // case 1: Ethernet II IP packet
1694 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_II)];
1695 tos = pIpHdr->tos;
1696#ifdef HDD_WMM_DEBUG
1697 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1698 "%s: Ethernet II IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001699 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001700#endif // HDD_WMM_DEBUG
1701
1702 }
1703 else if ((ntohs(pHdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
1704 (pHdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
1705 (pHdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
1706 (pHdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1707 (pHdr->eth_8023.h_proto == htons(ETH_P_IP)))
1708 {
1709 // case 2: 802.3 LLC/SNAP IP packet
1710 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];
1711 tos = pIpHdr->tos;
1712#ifdef HDD_WMM_DEBUG
1713 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1714 "%s: 802.3 LLC/SNAP IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001715 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001716#endif // HDD_WMM_DEBUG
1717 }
1718 else if (pHdr->eth_II.h_proto == htons(ETH_P_8021Q))
1719 {
1720 // VLAN tagged
1721
1722 if (pHdr->eth_IIv.h_vlan_encapsulated_proto == htons(ETH_P_IP))
1723 {
1724 // case 3: Ethernet II vlan-tagged IP packet
1725 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_IIv)];
1726 tos = pIpHdr->tos;
1727#ifdef HDD_WMM_DEBUG
1728 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1729 "%s: Ethernet II VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001730 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001731#endif // HDD_WMM_DEBUG
1732 }
1733 else if ((ntohs(pHdr->eth_IIv.h_vlan_encapsulated_proto) < WLAN_MIN_PROTO) &&
1734 (pHdr->eth_8023v.h_snap.dsap == WLAN_SNAP_DSAP) &&
1735 (pHdr->eth_8023v.h_snap.ssap == WLAN_SNAP_SSAP) &&
1736 (pHdr->eth_8023v.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1737 (pHdr->eth_8023v.h_proto == htons(ETH_P_IP)))
1738 {
1739 // case 4: 802.3 LLC/SNAP vlan-tagged IP packet
1740 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023v)];
1741 tos = pIpHdr->tos;
1742#ifdef HDD_WMM_DEBUG
1743 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1744 "%s: 802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001745 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001746#endif // HDD_WMM_DEBUG
1747 }
1748 else
1749 {
1750 // default
1751#ifdef HDD_WMM_DEBUG
1752 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1753 "%s: VLAN tagged Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001754 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001755#endif // HDD_WMM_DEBUG
1756 tos = 0;
1757 }
1758 }
1759 else
1760 {
1761 // default
1762#ifdef HDD_WMM_DEBUG
1763 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1764 "%s: Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001765 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001766#endif // HDD_WMM_DEBUG
1767 //Give the highest priority to 802.1x packet
1768 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
1769 tos = 0xC0;
1770 else
1771 tos = 0;
1772 }
1773
1774 dscp = (tos>>2) & 0x3f;
1775 userPri = hddWmmDscpToUpMap[dscp];
1776
1777#ifdef HDD_WMM_DEBUG
1778 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1779 "%s: tos is %d, dscp is %d, up is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001780 __func__, tos, dscp, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07001781#endif // HDD_WMM_DEBUG
1782
1783 }
1784 else if (HDD_WMM_CLASSIFICATION_802_1Q == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
1785 {
1786 if (pHdr->eth_IIv.h_vlan_proto == htons(ETH_P_8021Q))
1787 {
1788 // VLAN tagged
1789 userPri = (ntohs(pHdr->eth_IIv.h_vlan_TCI)>>13) & 0x7;
1790#ifdef HDD_WMM_DEBUG
1791 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1792 "%s: Tagged frame, UP is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001793 __func__, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07001794#endif // HDD_WMM_DEBUG
1795 }
1796 else
1797 {
1798 // not VLAN tagged, use default
1799#ifdef HDD_WMM_DEBUG
1800 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1801 "%s: Untagged frame, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001802 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001803#endif // HDD_WMM_DEBUG
1804 //Give the highest priority to 802.1x packet
1805 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
1806 userPri = SME_QOS_WMM_UP_VO;
1807 else
1808 userPri = SME_QOS_WMM_UP_BE;
1809 }
1810 }
1811 else
1812 {
1813 // default
1814#ifdef HDD_WMM_DEBUG
1815 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1816 "%s: Unknown classification scheme, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001817 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001818#endif // HDD_WMM_DEBUG
1819 userPri = SME_QOS_WMM_UP_BE;
1820 }
1821
1822 acType = hddWmmUpToAcMap[userPri];
1823
1824#ifdef HDD_WMM_DEBUG
1825 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1826 "%s: UP is %d, AC is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001827 __func__, userPri, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001828#endif // HDD_WMM_DEBUG
1829
1830 *pUserPri = userPri;
1831 *pAcType = acType;
1832
1833 return;
1834}
1835
1836/**============================================================================
1837 @brief hdd_hostapd_select_quueue() - Function which will classify the packet
1838 according to linux qdisc expectation.
1839
1840
1841 @param dev : [in] pointer to net_device structure
1842 @param skb : [in] pointer to os packet
1843
1844 @return : Qdisc queue index
1845 ===========================================================================*/
1846v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb)
1847{
1848 WLANTL_ACEnumType ac;
1849 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
1850 v_USHORT_t queueIndex;
1851 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
1852 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
1853 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001854 v_U8_t STAId;
1855 v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
1856
1857 /*Get the Station ID*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001858 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &STAId))
1859 {
Agarwal Ashisha64c9542014-03-04 00:14:43 +05301860 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001861 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001862 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1863 goto done;
1864 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001865
1866 spin_lock_bh( &pAdapter->staInfo_lock );
1867 if (FALSE == vos_is_macaddr_equal(&pAdapter->aStaInfo[STAId].macAddrSTA, pDestMacAddress))
1868 {
Agarwal Ashisha64c9542014-03-04 00:14:43 +05301869 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001870 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001871
1872 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1873 goto release_lock;
1874 }
1875 if (pAdapter->aStaInfo[STAId].isUsed && pAdapter->aStaInfo[STAId].isQosEnabled && (HDD_WMM_USER_MODE_NO_QOS != pHddCtx->cfg_ini->WmmMode))
1876 {
1877 /* Get the user priority from IP header & corresponding AC */
1878 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301879 //If 3/4th of Tx queue is used then place the DHCP packet in VOICE AC queue
1880 if (pAdapter->aStaInfo[STAId].vosLowResource && is_dhcp_packet(skb))
1881 {
1882 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1883 "%s: Making priority of DHCP packet as VOICE", __func__);
1884 up = SME_QOS_WMM_UP_VO;
1885 ac = hddWmmUpToAcMap[up];
1886 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001887 }
1888 *pSTAId = STAId;
1889
1890release_lock:
1891 spin_unlock_bh( &pAdapter->staInfo_lock );
1892done:
1893 skb->priority = up;
1894 queueIndex = hddLinuxUpToAcMap[skb->priority];
1895
1896 return queueIndex;
1897}
1898
1899/**============================================================================
1900 @brief hdd_wmm_select_quueue() - Function which will classify the packet
1901 according to linux qdisc expectation.
1902
1903
1904 @param dev : [in] pointer to net_device structure
1905 @param skb : [in] pointer to os packet
1906
1907 @return : Qdisc queue index
1908 ===========================================================================*/
1909v_U16_t hdd_wmm_select_queue(struct net_device * dev, struct sk_buff *skb)
1910{
1911 WLANTL_ACEnumType ac;
Shailender Karmuchia734f332013-04-19 14:02:48 -07001912 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001913 v_USHORT_t queueIndex;
Jeff Johnson295189b2012-06-20 16:38:30 -07001914 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1915
Kiet Lam40009862014-02-13 12:33:22 -08001916 if (isWDresetInProgress()) {
1917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1918 FL("called during WDReset"));
1919 skb->priority = SME_QOS_WMM_UP_BE;
1920 return HDD_LINUX_AC_BE;
1921 }
1922
Shailender Karmuchia734f332013-04-19 14:02:48 -07001923 /*Get the Station ID*/
1924 if (WLAN_HDD_IBSS == pAdapter->device_mode)
1925 {
1926 v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
1927 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
1928
1929 if ( VOS_STATUS_SUCCESS !=
1930 hdd_Ibss_GetStaId(&pAdapter->sessionCtx.station,
1931 pDestMacAddress, pSTAId))
1932 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05301933 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb9fb9ce2013-05-03 08:11:02 -07001934 "%s: Failed to find right station pDestMacAddress: "
1935 MAC_ADDRESS_STR , __func__,
1936 MAC_ADDR_ARRAY(pDestMacAddress->bytes));
Shailender Karmuchia734f332013-04-19 14:02:48 -07001937 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1938 goto done;
1939 }
1940 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001941 // if we don't want QoS or the AP doesn't support Qos
1942 // All traffic will get equal opportuniy to transmit data frames.
1943 if( hdd_wmm_is_active(pAdapter) ) {
1944 /* Get the user priority from IP header & corresponding AC */
1945 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301946 //If 3/4th of BE AC Tx queue is full, then place the DHCP packet in VOICE AC queue
1947 if (pAdapter->isVosLowResource && is_dhcp_packet(skb))
1948 {
1949 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
Rashmi Ramanna36578582014-02-05 16:12:31 +05301950 "%s: BestEffort Tx Queue is 3/4th full"
1951 " Make DHCP packet's pri as VO", __func__);
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301952 up = SME_QOS_WMM_UP_VO;
1953 ac = hddWmmUpToAcMap[up];
1954 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001955 }
Shailender Karmuchia734f332013-04-19 14:02:48 -07001956done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001957 skb->priority = up;
1958 queueIndex = hddLinuxUpToAcMap[skb->priority];
1959
1960 return queueIndex;
1961}
1962
Kiet Lamf040f472013-11-20 21:15:23 +05301963/**==========================================================================
1964 @brief hdd_wmm_acquire_access_required() - Function which will determine
1965 acquire admittance for a WMM AC is required or not based on psb configuration
1966 done in framework
1967
1968 @param pAdapter : [in] pointer to adapter structure
1969
1970 @param acType : [in] WMM AC type of OS packet
1971
1972 @return : void
1973 ===========================================================================*/
1974void hdd_wmm_acquire_access_required(hdd_adapter_t *pAdapter,
1975 WLANTL_ACEnumType acType)
1976{
1977/* Each bit in the LSB nibble indicates 1 AC.
1978 * Clearing the particular bit in LSB nibble to indicate
1979 * access required
1980 */
1981 switch(acType)
1982 {
1983 case WLANTL_AC_BK:
1984 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BK_CHANGED_MASK; /* clear first bit */
1985 break;
1986 case WLANTL_AC_BE:
1987 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BE_CHANGED_MASK; /* clear second bit */
1988 break;
1989 case WLANTL_AC_VI:
1990 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VI_CHANGED_MASK; /* clear third bit */
1991 break;
1992 case WLANTL_AC_VO:
1993 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VO_CHANGED_MASK; /* clear fourth bit */
1994 break;
1995 default:
1996 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1997 "%s: Invalid AC Type", __func__);
1998 break;
1999 }
2000}
2001
Jeff Johnson295189b2012-06-20 16:38:30 -07002002/**============================================================================
2003 @brief hdd_wmm_acquire_access() - Function which will attempt to acquire
2004 admittance for a WMM AC
2005
2006 @param pAdapter : [in] pointer to adapter context
2007 @param acType : [in] WMM AC type of OS packet
2008 @param pGranted : [out] pointer to boolean flag when indicates if access
2009 has been granted or not
2010
2011 @return : VOS_STATUS_SUCCESS if succssful
2012 : other values if failure
2013 ===========================================================================*/
2014VOS_STATUS hdd_wmm_acquire_access( hdd_adapter_t* pAdapter,
2015 WLANTL_ACEnumType acType,
2016 v_BOOL_t * pGranted )
2017{
2018 hdd_wmm_qos_context_t *pQosContext;
2019
2020 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002021 "%s: Entered for AC %d", __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002022
2023 if (!hdd_wmm_is_active(pAdapter) || !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
2024 {
2025 // either we don't want QoS or the AP doesn't support QoS
2026 // or we don't want to do implicit QoS
2027 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002028 "%s: QoS not configured on both ends ", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002029
2030 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2031 *pGranted = VOS_TRUE;
2032 return VOS_STATUS_SUCCESS;
2033 }
2034
2035 // do we already have an implicit QoS request pending for this AC?
2036 if ((pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded) ||
2037 (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessPending))
2038 {
2039 // request already pending so we need to wait for that response
2040 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2041 "%s: Implicit QoS for TL AC %d already scheduled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002042 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002043
2044 *pGranted = VOS_FALSE;
2045 return VOS_STATUS_SUCCESS;
2046 }
2047
2048 // did we already fail to establish implicit QoS for this AC?
2049 // (if so, access should have been granted when the failure was handled)
2050 if (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessFailed)
2051 {
2052 // request previously failed
2053 // allow access, but we'll be downgraded
2054 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2055 "%s: Implicit QoS for TL AC %d previously failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002056 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002057
2058 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2059 *pGranted = VOS_TRUE;
2060 return VOS_STATUS_SUCCESS;
2061 }
2062
2063 // we need to establish implicit QoS
2064 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2065 "%s: Need to schedule implicit QoS for TL AC %d, pAdapter is %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002066 __func__, acType, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002067
2068 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded = VOS_TRUE;
2069
Mohit Khanna217ea8d2012-09-11 17:42:42 -07002070 pQosContext = kmalloc(sizeof(*pQosContext), GFP_ATOMIC);
Jeff Johnson295189b2012-06-20 16:38:30 -07002071 if (NULL == pQosContext)
2072 {
2073 // no memory for QoS context. Nothing we can do but let data flow
2074 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002075 "%s: Unable to allocate context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002076 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2077 *pGranted = VOS_TRUE;
2078 return VOS_STATUS_SUCCESS;
2079 }
2080
2081 pQosContext->acType = acType;
2082 pQosContext->pAdapter = pAdapter;
2083 pQosContext->qosFlowId = 0;
2084 pQosContext->handle = HDD_WMM_HANDLE_IMPLICIT;
2085 pQosContext->magic = HDD_WMM_CTX_MAGIC;
2086 INIT_WORK(&pQosContext->wmmAcSetupImplicitQos,
2087 hdd_wmm_do_implicit_qos);
2088
2089 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2090 "%s: Scheduling work for AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002091 __func__, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002092
2093 schedule_work(&pQosContext->wmmAcSetupImplicitQos);
2094
2095 // caller will need to wait until the work takes place and
2096 // TSPEC negotiation completes
2097 *pGranted = VOS_FALSE;
2098 return VOS_STATUS_SUCCESS;
2099}
2100
2101/**============================================================================
2102 @brief hdd_wmm_assoc() - Function which will handle the housekeeping
2103 required by WMM when association takes place
2104
2105 @param pAdapter : [in] pointer to adapter context
2106 @param pRoamInfo: [in] pointer to roam information
2107 @param eBssType : [in] type of BSS
2108
2109 @return : VOS_STATUS_SUCCESS if succssful
2110 : other values if failure
2111 ===========================================================================*/
2112VOS_STATUS hdd_wmm_assoc( hdd_adapter_t* pAdapter,
2113 tCsrRoamInfo *pRoamInfo,
2114 eCsrRoamBssType eBssType )
2115{
2116 tANI_U8 uapsdMask;
2117 VOS_STATUS status;
2118
2119 // when we associate we need to notify TL if it needs to enable
2120 // UAPSD for any access categories
2121
2122 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002123 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002124
2125 if (pRoamInfo->fReassocReq)
2126 {
2127 // when we reassociate we should continue to use whatever
2128 // parameters were previously established. if we are
2129 // reassociating due to a U-APSD change for a particular
2130 // Access Category, then the change will be communicated
2131 // to HDD via the QoS callback associated with the given
2132 // flow, and U-APSD parameters will be updated there
2133
2134 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002135 "%s: Reassoc so no work, Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002136
2137 return VOS_STATUS_SUCCESS;
2138 }
2139
2140 // get the negotiated UAPSD Mask
2141 uapsdMask = pRoamInfo->u.pConnectedProfile->modifyProfileFields.uapsd_mask;
2142
2143 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002144 "%s: U-APSD mask is 0x%02x", __func__, (int) uapsdMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002145
2146 if (uapsdMask & HDD_AC_VO)
2147 {
2148 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2149 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2150 WLANTL_AC_VO,
2151 7,
2152 7,
2153 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv,
2154 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv,
2155 WLANTL_BI_DIR );
2156
2157 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2158 }
2159
2160 if (uapsdMask & HDD_AC_VI)
2161 {
2162 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2163 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2164 WLANTL_AC_VI,
2165 5,
2166 5,
2167 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv,
2168 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv,
2169 WLANTL_BI_DIR );
2170
2171 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2172 }
2173
2174 if (uapsdMask & HDD_AC_BK)
2175 {
2176 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2177 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2178 WLANTL_AC_BK,
2179 2,
2180 2,
2181 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv,
2182 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv,
2183 WLANTL_BI_DIR );
2184
2185 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2186 }
2187
2188 if (uapsdMask & HDD_AC_BE)
2189 {
2190 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2191 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2192 WLANTL_AC_BE,
2193 3,
2194 3,
2195 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv,
2196 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv,
2197 WLANTL_BI_DIR );
2198
2199 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2200 }
2201
2202 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002203 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002204
2205 return VOS_STATUS_SUCCESS;
2206}
2207
2208
2209
2210static const v_U8_t acmMaskBit[WLANTL_MAX_AC] =
2211 {
2212 0x4, /* WLANTL_AC_BK */
2213 0x8, /* WLANTL_AC_BE */
2214 0x2, /* WLANTL_AC_VI */
2215 0x1 /* WLANTL_AC_VO */
2216 };
2217
2218/**============================================================================
2219 @brief hdd_wmm_connect() - Function which will handle the housekeeping
2220 required by WMM when a connection is established
2221
2222 @param pAdapter : [in] pointer to adapter context
2223 @param pRoamInfo: [in] pointer to roam information
2224 @param eBssType : [in] type of BSS
2225
2226 @return : VOS_STATUS_SUCCESS if succssful
2227 : other values if failure
2228 ===========================================================================*/
2229VOS_STATUS hdd_wmm_connect( hdd_adapter_t* pAdapter,
2230 tCsrRoamInfo *pRoamInfo,
2231 eCsrRoamBssType eBssType )
2232{
2233 int ac;
2234 v_BOOL_t qap;
2235 v_BOOL_t qosConnection;
2236 v_U8_t acmMask;
2237
2238 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002239 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002240
2241 if ((eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) &&
2242 pRoamInfo &&
2243 pRoamInfo->u.pConnectedProfile)
2244 {
2245 qap = pRoamInfo->u.pConnectedProfile->qap;
2246 qosConnection = pRoamInfo->u.pConnectedProfile->qosConnection;
2247 acmMask = pRoamInfo->u.pConnectedProfile->acm_mask;
2248 }
2249 else
2250 {
2251 qap = VOS_TRUE;
2252 qosConnection = VOS_TRUE;
2253 acmMask = 0x0;
2254 }
2255
2256 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2257 "%s: qap is %d, qosConnection is %d, acmMask is 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002258 __func__, qap, qosConnection, acmMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002259
2260 pAdapter->hddWmmStatus.wmmQap = qap;
2261 pAdapter->hddWmmStatus.wmmQosConnection = qosConnection;
2262
2263 for (ac = 0; ac < WLANTL_MAX_AC; ac++)
2264 {
2265 if (qap &&
2266 qosConnection &&
2267 (acmMask & acmMaskBit[ac]))
2268 {
2269 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2270 "%s: ac %d on",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002271 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002272
2273 // admission is required
2274 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_TRUE;
2275 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_FALSE;
2276 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessGranted = VOS_FALSE;
2277 }
2278 else
2279 {
2280 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2281 "%s: ac %d off",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002282 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002283 // admission is not required so access is allowed
2284 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_FALSE;
2285 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_TRUE;
2286 }
2287
2288 }
2289
2290 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002291 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002292
2293 return VOS_STATUS_SUCCESS;
2294}
2295
2296/**============================================================================
2297 @brief hdd_wmm_get_uapsd_mask() - Function which will calculate the
2298 initial value of the UAPSD mask based upon the device configuration
2299
2300 @param pAdapter : [in] pointer to adapter context
2301 @param pUapsdMask: [in] pointer to where the UAPSD Mask is to be stored
2302
2303 @return : VOS_STATUS_SUCCESS if succssful
2304 : other values if failure
2305 ===========================================================================*/
2306VOS_STATUS hdd_wmm_get_uapsd_mask( hdd_adapter_t* pAdapter,
2307 tANI_U8 *pUapsdMask )
2308{
2309 tANI_U8 uapsdMask;
2310
2311 if (HDD_WMM_USER_MODE_NO_QOS == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
2312 {
2313 // no QOS then no UAPSD
2314 uapsdMask = 0;
2315 }
2316 else
2317 {
2318 // start with the default mask
2319 uapsdMask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
2320
2321 // disable UAPSD for any ACs with a 0 Service Interval
2322 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv == 0 )
2323 {
2324 uapsdMask &= ~HDD_AC_VO;
2325 }
2326
2327 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv == 0 )
2328 {
2329 uapsdMask &= ~HDD_AC_VI;
2330 }
2331
2332 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv == 0 )
2333 {
2334 uapsdMask &= ~HDD_AC_BK;
2335 }
2336
2337 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv == 0 )
2338 {
2339 uapsdMask &= ~HDD_AC_BE;
2340 }
2341 }
2342
2343 // return calculated mask
2344 *pUapsdMask = uapsdMask;
2345 return VOS_STATUS_SUCCESS;
2346}
2347
2348
2349/**============================================================================
2350 @brief hdd_wmm_is_active() - Function which will determine if WMM is
2351 active on the current connection
2352
2353 @param pAdapter : [in] pointer to adapter context
2354
2355 @return : VOS_TRUE if WMM is enabled
2356 : VOS_FALSE if WMM is not enabled
2357 ===========================================================================*/
2358v_BOOL_t hdd_wmm_is_active( hdd_adapter_t* pAdapter )
2359{
2360 if ((!pAdapter->hddWmmStatus.wmmQosConnection) ||
2361 (!pAdapter->hddWmmStatus.wmmQap))
2362 {
2363 return VOS_FALSE;
2364 }
2365 else
2366 {
2367 return VOS_TRUE;
2368 }
2369}
2370
2371/**============================================================================
2372 @brief hdd_wmm_addts() - Function which will add a traffic spec at the
2373 request of an application
2374
2375 @param pAdapter : [in] pointer to adapter context
2376 @param handle : [in] handle to uniquely identify a TS
2377 @param pTspec : [in] pointer to the traffic spec
2378
2379 @return : HDD_WLAN_WMM_STATUS_*
2380 ===========================================================================*/
2381hdd_wlan_wmm_status_e hdd_wmm_addts( hdd_adapter_t* pAdapter,
2382 v_U32_t handle,
2383 sme_QosWmmTspecInfo* pTspec )
2384{
2385 hdd_wmm_qos_context_t *pQosContext;
2386 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2387#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2388 sme_QosStatusType smeStatus;
2389#endif
2390 v_BOOL_t found = VOS_FALSE;
2391
2392 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002393 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002394
2395 // see if a context already exists with the given handle
2396 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2397 list_for_each_entry(pQosContext,
2398 &pAdapter->hddWmmStatus.wmmContextList,
2399 node)
2400 {
2401 if (pQosContext->handle == handle)
2402 {
2403 found = VOS_TRUE;
2404 break;
2405 }
2406 }
2407 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2408 if (found)
2409 {
2410 // record with that handle already exists
2411 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2412 "%s: Record already exists with handle 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002413 __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002414
2415 /* Application is trying to modify some of the Tspec params. Allow it */
2416 smeStatus = sme_QosModifyReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2417 pTspec,
2418 pQosContext->qosFlowId);
2419
2420 // need to check the return value and act appropriately
2421 switch (smeStatus)
2422 {
2423 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
2424 status = HDD_WLAN_WMM_STATUS_MODIFY_PENDING;
2425 break;
2426 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2427 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
2428 break;
2429 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
2430 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
2431 break;
2432 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
2433 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
2434 break;
2435 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
2436 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2437 break;
2438 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2439 status = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2440 break;
2441 default:
2442 // we didn't get back one of the SME_QOS_STATUS_MODIFY_* status codes
2443 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002444 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002445 VOS_ASSERT(0);
2446 return HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2447 }
2448
2449 // we were successful, save the status
2450 pQosContext->lastStatus = status;
2451 return status;
2452 }
2453
2454 pQosContext = kmalloc(sizeof(*pQosContext), GFP_KERNEL);
2455 if (NULL == pQosContext)
2456 {
2457 // no memory for QoS context. Nothing we can do
2458 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002459 "%s: Unable to allocate QoS context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002460 return HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE;
2461 }
2462
2463 // we assume the tspec has already been validated by the caller
2464
2465 pQosContext->handle = handle;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08002466 if (pTspec->ts_info.up < HDD_WMM_UP_TO_AC_MAP_SIZE)
2467 pQosContext->acType = hddWmmUpToAcMap[pTspec->ts_info.up];
2468 else {
2469 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2470 "%s: ts_info.up (%d) larger than max value (%d), "
2471 "use default acType (%d)",
2472 __func__, pTspec->ts_info.up,
2473 HDD_WMM_UP_TO_AC_MAP_SIZE - 1, hddWmmUpToAcMap[0]);
2474 pQosContext->acType = hddWmmUpToAcMap[0];
2475 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002476 pQosContext->pAdapter = pAdapter;
2477 pQosContext->qosFlowId = 0;
2478 pQosContext->magic = HDD_WMM_CTX_MAGIC;
2479
2480 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2481 "%s: Setting up QoS, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002482 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002483
2484 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2485 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
2486 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2487
2488#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2489 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2490 pAdapter->sessionId,
2491 pTspec,
2492 hdd_wmm_sme_callback,
2493 pQosContext,
2494 pTspec->ts_info.up,
2495 &pQosContext->qosFlowId);
2496
2497 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2498 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002499 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002500
2501 // need to check the return value and act appropriately
2502 switch (smeStatus)
2503 {
2504 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
2505 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2506 break;
2507 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2508 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
2509 break;
2510 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
2511 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
2512 break;
2513 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
2514 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2515 break;
2516 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
2517 hdd_wmm_free_context(pQosContext);
2518 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
2519 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
2520 // we can't tell the difference between when a request fails because
2521 // AP rejected it versus when SME encounterd an internal error
2522 hdd_wmm_free_context(pQosContext);
2523 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2524 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2525 hdd_wmm_free_context(pQosContext);
2526 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2527 default:
2528 // we didn't get back one of the SME_QOS_STATUS_SETUP_* status codes
2529 hdd_wmm_free_context(pQosContext);
2530 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002531 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002532 VOS_ASSERT(0);
2533 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2534 }
2535#endif
2536
2537 // we were successful, save the status
2538 pQosContext->lastStatus = status;
2539
2540 return status;
2541}
2542
2543/**============================================================================
2544 @brief hdd_wmm_delts() - Function which will delete a traffic spec at the
2545 request of an application
2546
2547 @param pAdapter : [in] pointer to adapter context
2548 @param handle : [in] handle to uniquely identify a TS
2549
2550 @return : HDD_WLAN_WMM_STATUS_*
2551 ===========================================================================*/
2552hdd_wlan_wmm_status_e hdd_wmm_delts( hdd_adapter_t* pAdapter,
2553 v_U32_t handle )
2554{
2555 hdd_wmm_qos_context_t *pQosContext;
2556 v_BOOL_t found = VOS_FALSE;
2557 WLANTL_ACEnumType acType = 0;
2558 v_U32_t qosFlowId = 0;
2559 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2560#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2561 sme_QosStatusType smeStatus;
2562#endif
2563
2564 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002565 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002566
2567 // locate the context with the given handle
2568 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2569 list_for_each_entry(pQosContext,
2570 &pAdapter->hddWmmStatus.wmmContextList,
2571 node)
2572 {
2573 if (pQosContext->handle == handle)
2574 {
2575 found = VOS_TRUE;
2576 acType = pQosContext->acType;
2577 qosFlowId = pQosContext->qosFlowId;
2578 break;
2579 }
2580 }
2581 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2582
2583 if (VOS_FALSE == found)
2584 {
2585 // we didn't find the handle
2586 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002587 "%s: handle 0x%x not found", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002588 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2589 }
2590
2591
2592 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2593 "%s: found handle 0x%x, flow %d, AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002594 __func__, handle, qosFlowId, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002595
2596#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2597 smeStatus = sme_QosReleaseReq( WLAN_HDD_GET_HAL_CTX(pAdapter), qosFlowId );
2598
2599 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2600 "%s: SME flow %d released, SME status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002601 __func__, qosFlowId, smeStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07002602
2603 switch(smeStatus)
2604 {
2605 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
2606 // this flow is the only one on that AC, so go ahead and update
2607 // our TSPEC state for the AC
2608 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcTspecValid = VOS_FALSE;
2609
2610 // need to tell TL to stop trigger timer, etc
2611 hdd_wmm_disable_tl_uapsd(pQosContext);
2612
2613#ifdef FEATURE_WLAN_CCX
2614 // disable the inactivity timer
2615 hdd_wmm_disable_inactivity_timer(pQosContext);
2616#endif
2617 // we are done with this context
2618 hdd_wmm_free_context(pQosContext);
2619
2620 // SME must not fire any more callbacks for this flow since the context
2621 // is no longer valid
2622
2623 return HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
2624
2625 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
2626 // do nothing as we will get a response from SME
2627 status = HDD_WLAN_WMM_STATUS_RELEASE_PENDING;
2628 break;
2629
2630 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
2631 // nothing we can do with the existing flow except leave it
2632 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2633 break;
2634
2635 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
2636 // nothing we can do with the existing flow except leave it
2637 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2638
2639 default:
2640 // we didn't get back one of the SME_QOS_STATUS_RELEASE_* status codes
2641 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002642 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002643 VOS_ASSERT(0);
2644 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2645 }
2646
2647#endif
2648 pQosContext->lastStatus = status;
2649 return status;
2650}
2651
2652/**============================================================================
2653 @brief hdd_wmm_checkts() - Function which will return the status of a traffic
2654 spec at the request of an application
2655
2656 @param pAdapter : [in] pointer to adapter context
2657 @param handle : [in] handle to uniquely identify a TS
2658
2659 @return : HDD_WLAN_WMM_STATUS_*
2660 ===========================================================================*/
2661hdd_wlan_wmm_status_e hdd_wmm_checkts( hdd_adapter_t* pAdapter,
2662 v_U32_t handle )
2663{
2664 hdd_wmm_qos_context_t *pQosContext;
2665 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST;
2666
2667 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002668 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002669
2670 // locate the context with the given handle
2671 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2672 list_for_each_entry(pQosContext,
2673 &pAdapter->hddWmmStatus.wmmContextList,
2674 node)
2675 {
2676 if (pQosContext->handle == handle)
2677 {
2678 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2679 "%s: found handle 0x%x, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002680 __func__, handle, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002681
2682 status = pQosContext->lastStatus;
2683 break;
2684 }
2685 }
2686 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2687 return status;
2688}