blob: 31744922c696ce533283bd9462a90fd67f7594b1 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam842dad02014-02-18 18:44:02 -080021
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028/*============================================================================
29 @file wlan_hdd_wmm.c
30
31 This module (wlan_hdd_wmm.h interface + wlan_hdd_wmm.c implementation)
32 houses all the logic for WMM in HDD.
33
34 On the control path, it has the logic to setup QoS, modify QoS and delete
35 QoS (QoS here refers to a TSPEC). The setup QoS comes in two flavors: an
36 explicit application invoked and an internal HDD invoked. The implicit QoS
37 is for applications that do NOT call the custom QCT WLAN OIDs for QoS but
38 which DO mark their traffic for priortization. It also has logic to start,
39 update and stop the U-APSD trigger frame generation. It also has logic to
40 read WMM related config parameters from the registry.
41
42 On the data path, it has the logic to figure out the WMM AC of an egress
43 packet and when to signal TL to serve a particular AC queue. It also has the
44 logic to retrieve a packet based on WMM priority in response to a fetch from
45 TL.
46
47 The remaining functions are utility functions for information hiding.
48
49
50 Copyright (c) 2008-9 QUALCOMM Incorporated.
51 All Rights Reserved.
52 Qualcomm Confidential and Proprietary
53============================================================================*/
54
55/*---------------------------------------------------------------------------
56 Include files
57 -------------------------------------------------------------------------*/
58#include <wlan_hdd_tx_rx.h>
59#include <wlan_hdd_dp_utils.h>
60#include <wlan_hdd_wmm.h>
61#include <wlan_hdd_ether.h>
62#include <linux/netdevice.h>
63#include <linux/skbuff.h>
64#include <linux/etherdevice.h>
65#include <linux/if_vlan.h>
66#include <linux/ip.h>
67#include <linux/semaphore.h>
68#include <wlan_hdd_hostapd.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070069#include <wlan_hdd_softap_tx_rx.h>
Kiet Lam40009862014-02-13 12:33:22 -080070#include <vos_sched.h>
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
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080096#define HDD_WMM_UP_TO_AC_MAP_SIZE 8
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -070097
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
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800434#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700435/**
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}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800575#endif // FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700576
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
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800678#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700679 // 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 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800686#endif // FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700687
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 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08001386#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07001387 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
Kumar Anand82c009f2014-05-29 00:29:42 -07001498 @param pAdapter : [in] pointer to Adapter context
Jeff Johnson295189b2012-06-20 16:38:30 -07001499
Kumar Anand82c009f2014-05-29 00:29:42 -07001500 @return : VOS_STATUS_SUCCESS if successful
Jeff Johnson295189b2012-06-20 16:38:30 -07001501 : other values if failure
1502
1503 ===========================================================================*/
Kumar Anand82c009f2014-05-29 00:29:42 -07001504VOS_STATUS hdd_wmm_init ( hdd_adapter_t *pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07001505{
Kumar Anand82c009f2014-05-29 00:29:42 -07001506 sme_QosWmmUpType* hddWmmDscpToUpMap = pAdapter->hddWmmDscpToUpMap;
Jeff Johnson295189b2012-06-20 16:38:30 -07001507 v_U8_t dscp;
1508
1509 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001510 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001511
1512 // DSCP to User Priority Lookup Table
1513 for (dscp = 0; dscp <= WLAN_HDD_MAX_DSCP; dscp++)
1514 {
1515 hddWmmDscpToUpMap[dscp] = SME_QOS_WMM_UP_BE;
1516 }
1517 hddWmmDscpToUpMap[8] = SME_QOS_WMM_UP_BK;
1518 hddWmmDscpToUpMap[16] = SME_QOS_WMM_UP_RESV;
1519 hddWmmDscpToUpMap[24] = SME_QOS_WMM_UP_EE;
1520 hddWmmDscpToUpMap[32] = SME_QOS_WMM_UP_CL;
1521 hddWmmDscpToUpMap[40] = SME_QOS_WMM_UP_VI;
1522 hddWmmDscpToUpMap[48] = SME_QOS_WMM_UP_VO;
1523 hddWmmDscpToUpMap[56] = SME_QOS_WMM_UP_NC;
Jeff Johnson295189b2012-06-20 16:38:30 -07001524 return VOS_STATUS_SUCCESS;
1525}
1526
1527/**============================================================================
1528 @brief hdd_wmm_adapter_init() - Function which will initialize the WMM configuation
1529 and status to an initial state. The configuration can later be overwritten
1530 via application APIs
1531
1532 @param pAdapter : [in] pointer to Adapter context
1533
1534 @return : VOS_STATUS_SUCCESS if succssful
1535 : other values if failure
1536
1537 ===========================================================================*/
1538VOS_STATUS hdd_wmm_adapter_init( hdd_adapter_t *pAdapter )
1539{
1540 hdd_wmm_ac_status_t *pAcStatus;
1541 WLANTL_ACEnumType acType;
1542
1543 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001544 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001545
1546 pAdapter->hddWmmStatus.wmmQap = VOS_FALSE;
1547 INIT_LIST_HEAD(&pAdapter->hddWmmStatus.wmmContextList);
1548 mutex_init(&pAdapter->hddWmmStatus.wmmLock);
1549
1550 for (acType = 0; acType < WLANTL_MAX_AC; acType++)
1551 {
1552 pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1553 pAcStatus->wmmAcAccessRequired = VOS_FALSE;
1554 pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
1555 pAcStatus->wmmAcAccessPending = VOS_FALSE;
1556 pAcStatus->wmmAcAccessFailed = VOS_FALSE;
1557 pAcStatus->wmmAcAccessGranted = VOS_FALSE;
1558 pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
1559 pAcStatus->wmmAcTspecValid = VOS_FALSE;
1560 pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
1561 }
Kiet Lamf040f472013-11-20 21:15:23 +05301562 // Invalid value(0xff) to indicate psb not configured through framework initially.
1563 pAdapter->configuredPsb = HDD_PSB_CFG_INVALID;
Jeff Johnson295189b2012-06-20 16:38:30 -07001564
1565 return VOS_STATUS_SUCCESS;
1566}
Madan Mohan Koyyalamudi70c52d32013-08-07 14:42:16 +05301567
1568/**============================================================================
1569 @brief hdd_wmm_adapter_clear() - Function which will clear the WMM status
1570 for all the ACs
1571
1572 @param pAdapter : [in] pointer to Adapter context
1573
1574 @return : VOS_STATUS_SUCCESS if succssful
1575 : other values if failure
1576
1577 ===========================================================================*/
1578VOS_STATUS hdd_wmm_adapter_clear( hdd_adapter_t *pAdapter )
1579{
1580 hdd_wmm_ac_status_t *pAcStatus;
1581 WLANTL_ACEnumType acType;
1582 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1583 "%s: Entered", __func__);
1584 for (acType = 0; acType < WLANTL_MAX_AC; acType++)
1585 {
1586 pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1587 pAcStatus->wmmAcAccessRequired = VOS_FALSE;
1588 pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
1589 pAcStatus->wmmAcAccessPending = VOS_FALSE;
1590 pAcStatus->wmmAcAccessFailed = VOS_FALSE;
1591 pAcStatus->wmmAcAccessGranted = VOS_FALSE;
1592 pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
1593 pAcStatus->wmmAcTspecValid = VOS_FALSE;
1594 pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
1595 }
1596 return VOS_STATUS_SUCCESS;
1597}
1598
Jeff Johnson295189b2012-06-20 16:38:30 -07001599/**============================================================================
1600 @brief hdd_wmm_close() - Function which will perform any necessary work to
1601 to clean up the WMM functionality prior to the kernel module unload
1602
1603 @param pAdapter : [in] pointer to adapter context
1604
1605 @return : VOS_STATUS_SUCCESS if succssful
1606 : other values if failure
1607
1608 ===========================================================================*/
1609VOS_STATUS hdd_wmm_adapter_close ( hdd_adapter_t* pAdapter )
1610{
1611 hdd_wmm_qos_context_t* pQosContext;
1612
1613 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001614 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001615
1616 // free any context records that we still have linked
1617 while (!list_empty(&pAdapter->hddWmmStatus.wmmContextList))
1618 {
1619 pQosContext = list_first_entry(&pAdapter->hddWmmStatus.wmmContextList,
1620 hdd_wmm_qos_context_t, node);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08001621#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07001622 hdd_wmm_disable_inactivity_timer(pQosContext);
1623#endif
Sameer Thalappilbee426e2013-10-30 10:30:30 -07001624#ifdef WLAN_OPEN_SOURCE
1625 cancel_work_sync(&pQosContext->wmmAcSetupImplicitQos);
1626#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001627 hdd_wmm_free_context(pQosContext);
1628 }
1629
1630 return VOS_STATUS_SUCCESS;
1631}
1632
1633/**============================================================================
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301634 @brief is_dhcp_packet() - Function which will check OS packet for
1635 DHCP packet
1636
1637 @param skb : [in] pointer to OS packet (sk_buff)
1638 @return : VOS_TRUE if the OS packet is DHCP packet
1639 : otherwise VOS_FALSE
1640 ===========================================================================*/
1641v_BOOL_t is_dhcp_packet(struct sk_buff *skb)
1642{
1643 if (*((u16*)((u8*)skb->data+34)) == DHCP_SOURCE_PORT ||
1644 *((u16*)((u8*)skb->data+34)) == DHCP_DESTINATION_PORT)
1645 return VOS_TRUE;
1646
1647 return VOS_FALSE;
1648}
1649
1650/**============================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07001651 @brief hdd_wmm_classify_pkt() - Function which will classify an OS packet
1652 into a WMM AC based on either 802.1Q or DSCP
1653
1654 @param pAdapter : [in] pointer to adapter context
1655 @param skb : [in] pointer to OS packet (sk_buff)
1656 @param pAcType : [out] pointer to WMM AC type of OS packet
1657
1658 @return : None
1659 ===========================================================================*/
1660v_VOID_t hdd_wmm_classify_pkt ( hdd_adapter_t* pAdapter,
1661 struct sk_buff *skb,
1662 WLANTL_ACEnumType* pAcType,
1663 sme_QosWmmUpType *pUserPri)
1664{
1665 unsigned char * pPkt;
1666 union generic_ethhdr *pHdr;
1667 struct iphdr *pIpHdr;
1668 unsigned char tos;
1669 unsigned char dscp;
1670 sme_QosWmmUpType userPri;
1671 WLANTL_ACEnumType acType;
1672
1673 // this code is executed for every packet therefore
1674 // all debug code is kept conditional
1675
1676#ifdef HDD_WMM_DEBUG
1677 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001678 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001679#endif // HDD_WMM_DEBUG
1680
1681 pPkt = skb->data;
1682 pHdr = (union generic_ethhdr *)pPkt;
1683
1684#ifdef HDD_WMM_DEBUG
1685 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1686 "%s: proto/length is 0x%04x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001687 __func__, pHdr->eth_II.h_proto);
Jeff Johnson295189b2012-06-20 16:38:30 -07001688#endif // HDD_WMM_DEBUG
1689
1690 if (HDD_WMM_CLASSIFICATION_DSCP == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
1691 {
1692 if (pHdr->eth_II.h_proto == htons(ETH_P_IP))
1693 {
1694 // case 1: Ethernet II IP packet
1695 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_II)];
1696 tos = pIpHdr->tos;
1697#ifdef HDD_WMM_DEBUG
1698 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1699 "%s: Ethernet II IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001700 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001701#endif // HDD_WMM_DEBUG
1702
1703 }
1704 else if ((ntohs(pHdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
1705 (pHdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
1706 (pHdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
1707 (pHdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1708 (pHdr->eth_8023.h_proto == htons(ETH_P_IP)))
1709 {
1710 // case 2: 802.3 LLC/SNAP IP packet
1711 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];
1712 tos = pIpHdr->tos;
1713#ifdef HDD_WMM_DEBUG
1714 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1715 "%s: 802.3 LLC/SNAP IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001716 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001717#endif // HDD_WMM_DEBUG
1718 }
1719 else if (pHdr->eth_II.h_proto == htons(ETH_P_8021Q))
1720 {
1721 // VLAN tagged
1722
1723 if (pHdr->eth_IIv.h_vlan_encapsulated_proto == htons(ETH_P_IP))
1724 {
1725 // case 3: Ethernet II vlan-tagged IP packet
1726 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_IIv)];
1727 tos = pIpHdr->tos;
1728#ifdef HDD_WMM_DEBUG
1729 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1730 "%s: Ethernet II VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001731 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001732#endif // HDD_WMM_DEBUG
1733 }
1734 else if ((ntohs(pHdr->eth_IIv.h_vlan_encapsulated_proto) < WLAN_MIN_PROTO) &&
1735 (pHdr->eth_8023v.h_snap.dsap == WLAN_SNAP_DSAP) &&
1736 (pHdr->eth_8023v.h_snap.ssap == WLAN_SNAP_SSAP) &&
1737 (pHdr->eth_8023v.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1738 (pHdr->eth_8023v.h_proto == htons(ETH_P_IP)))
1739 {
1740 // case 4: 802.3 LLC/SNAP vlan-tagged IP packet
1741 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023v)];
1742 tos = pIpHdr->tos;
1743#ifdef HDD_WMM_DEBUG
1744 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1745 "%s: 802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001746 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001747#endif // HDD_WMM_DEBUG
1748 }
1749 else
1750 {
1751 // default
1752#ifdef HDD_WMM_DEBUG
1753 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1754 "%s: VLAN tagged Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001755 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001756#endif // HDD_WMM_DEBUG
1757 tos = 0;
1758 }
1759 }
1760 else
1761 {
1762 // default
1763#ifdef HDD_WMM_DEBUG
1764 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1765 "%s: Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001766 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001767#endif // HDD_WMM_DEBUG
1768 //Give the highest priority to 802.1x packet
1769 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
1770 tos = 0xC0;
1771 else
1772 tos = 0;
1773 }
1774
1775 dscp = (tos>>2) & 0x3f;
Kumar Anand82c009f2014-05-29 00:29:42 -07001776 userPri = pAdapter->hddWmmDscpToUpMap[dscp];
1777
Jeff Johnson295189b2012-06-20 16:38:30 -07001778#ifdef HDD_WMM_DEBUG
1779 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1780 "%s: tos is %d, dscp is %d, up is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001781 __func__, tos, dscp, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07001782#endif // HDD_WMM_DEBUG
1783
1784 }
1785 else if (HDD_WMM_CLASSIFICATION_802_1Q == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
1786 {
1787 if (pHdr->eth_IIv.h_vlan_proto == htons(ETH_P_8021Q))
1788 {
1789 // VLAN tagged
1790 userPri = (ntohs(pHdr->eth_IIv.h_vlan_TCI)>>13) & 0x7;
1791#ifdef HDD_WMM_DEBUG
1792 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1793 "%s: Tagged frame, UP is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001794 __func__, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07001795#endif // HDD_WMM_DEBUG
1796 }
1797 else
1798 {
1799 // not VLAN tagged, use default
1800#ifdef HDD_WMM_DEBUG
1801 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1802 "%s: Untagged frame, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001803 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001804#endif // HDD_WMM_DEBUG
1805 //Give the highest priority to 802.1x packet
1806 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
1807 userPri = SME_QOS_WMM_UP_VO;
1808 else
1809 userPri = SME_QOS_WMM_UP_BE;
1810 }
1811 }
1812 else
1813 {
1814 // default
1815#ifdef HDD_WMM_DEBUG
1816 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1817 "%s: Unknown classification scheme, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001818 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001819#endif // HDD_WMM_DEBUG
1820 userPri = SME_QOS_WMM_UP_BE;
1821 }
1822
1823 acType = hddWmmUpToAcMap[userPri];
1824
1825#ifdef HDD_WMM_DEBUG
1826 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1827 "%s: UP is %d, AC is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001828 __func__, userPri, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001829#endif // HDD_WMM_DEBUG
1830
1831 *pUserPri = userPri;
1832 *pAcType = acType;
1833
1834 return;
1835}
1836
1837/**============================================================================
1838 @brief hdd_hostapd_select_quueue() - Function which will classify the packet
1839 according to linux qdisc expectation.
1840
1841
1842 @param dev : [in] pointer to net_device structure
1843 @param skb : [in] pointer to os packet
1844
1845 @return : Qdisc queue index
1846 ===========================================================================*/
1847v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb)
1848{
1849 WLANTL_ACEnumType ac;
1850 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
1851 v_USHORT_t queueIndex;
1852 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
1853 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
1854 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001855 v_U8_t STAId;
1856 v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
1857
1858 /*Get the Station ID*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001859 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &STAId))
1860 {
Agarwal Ashisha64c9542014-03-04 00:14:43 +05301861 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001862 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001863 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1864 goto done;
1865 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001866
1867 spin_lock_bh( &pAdapter->staInfo_lock );
1868 if (FALSE == vos_is_macaddr_equal(&pAdapter->aStaInfo[STAId].macAddrSTA, pDestMacAddress))
1869 {
Agarwal Ashisha64c9542014-03-04 00:14:43 +05301870 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001871 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001872
1873 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1874 goto release_lock;
1875 }
1876 if (pAdapter->aStaInfo[STAId].isUsed && pAdapter->aStaInfo[STAId].isQosEnabled && (HDD_WMM_USER_MODE_NO_QOS != pHddCtx->cfg_ini->WmmMode))
1877 {
1878 /* Get the user priority from IP header & corresponding AC */
1879 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301880 //If 3/4th of Tx queue is used then place the DHCP packet in VOICE AC queue
1881 if (pAdapter->aStaInfo[STAId].vosLowResource && is_dhcp_packet(skb))
1882 {
1883 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1884 "%s: Making priority of DHCP packet as VOICE", __func__);
1885 up = SME_QOS_WMM_UP_VO;
1886 ac = hddWmmUpToAcMap[up];
1887 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001888 }
1889 *pSTAId = STAId;
1890
1891release_lock:
1892 spin_unlock_bh( &pAdapter->staInfo_lock );
1893done:
1894 skb->priority = up;
Mukul Sharmad82cb7d2014-07-03 14:53:30 +05301895 if(skb->priority < SME_QOS_WMM_UP_MAX)
1896 queueIndex = hddLinuxUpToAcMap[skb->priority];
1897 else
1898 {
1899 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1900 "%s: up=%d is going beyond max value", __func__, up);
1901 queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
1902 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001903
1904 return queueIndex;
1905}
1906
1907/**============================================================================
1908 @brief hdd_wmm_select_quueue() - Function which will classify the packet
1909 according to linux qdisc expectation.
1910
1911
1912 @param dev : [in] pointer to net_device structure
1913 @param skb : [in] pointer to os packet
1914
1915 @return : Qdisc queue index
1916 ===========================================================================*/
1917v_U16_t hdd_wmm_select_queue(struct net_device * dev, struct sk_buff *skb)
1918{
1919 WLANTL_ACEnumType ac;
Shailender Karmuchia734f332013-04-19 14:02:48 -07001920 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001921 v_USHORT_t queueIndex;
Jeff Johnson295189b2012-06-20 16:38:30 -07001922 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1923
Kiet Lam40009862014-02-13 12:33:22 -08001924 if (isWDresetInProgress()) {
1925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1926 FL("called during WDReset"));
1927 skb->priority = SME_QOS_WMM_UP_BE;
1928 return HDD_LINUX_AC_BE;
1929 }
1930
Shailender Karmuchia734f332013-04-19 14:02:48 -07001931 /*Get the Station ID*/
1932 if (WLAN_HDD_IBSS == pAdapter->device_mode)
1933 {
1934 v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
1935 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
1936
1937 if ( VOS_STATUS_SUCCESS !=
1938 hdd_Ibss_GetStaId(&pAdapter->sessionCtx.station,
1939 pDestMacAddress, pSTAId))
1940 {
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05301941 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1942 if ( !vos_is_macaddr_broadcast( pDestMacAddress ) &&
1943 !vos_is_macaddr_group(pDestMacAddress))
1944 {
1945 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnsonb9fb9ce2013-05-03 08:11:02 -07001946 "%s: Failed to find right station pDestMacAddress: "
1947 MAC_ADDRESS_STR , __func__,
1948 MAC_ADDR_ARRAY(pDestMacAddress->bytes));
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05301949 goto done;
1950 }
Shailender Karmuchia734f332013-04-19 14:02:48 -07001951 }
1952 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001953 // if we don't want QoS or the AP doesn't support Qos
1954 // All traffic will get equal opportuniy to transmit data frames.
1955 if( hdd_wmm_is_active(pAdapter) ) {
1956 /* Get the user priority from IP header & corresponding AC */
1957 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301958 //If 3/4th of BE AC Tx queue is full, then place the DHCP packet in VOICE AC queue
1959 if (pAdapter->isVosLowResource && is_dhcp_packet(skb))
1960 {
1961 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
Rashmi Ramanna36578582014-02-05 16:12:31 +05301962 "%s: BestEffort Tx Queue is 3/4th full"
1963 " Make DHCP packet's pri as VO", __func__);
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301964 up = SME_QOS_WMM_UP_VO;
1965 ac = hddWmmUpToAcMap[up];
1966 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001967 }
Shailender Karmuchia734f332013-04-19 14:02:48 -07001968done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001969 skb->priority = up;
Mukul Sharmad82cb7d2014-07-03 14:53:30 +05301970 if(skb->priority < SME_QOS_WMM_UP_MAX)
1971 queueIndex = hddLinuxUpToAcMap[skb->priority];
1972 else
1973 {
1974 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1975 "%s: up=%d is going beyond max value", __func__, up);
1976 queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
1977 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001978
1979 return queueIndex;
1980}
1981
Kiet Lamf040f472013-11-20 21:15:23 +05301982/**==========================================================================
1983 @brief hdd_wmm_acquire_access_required() - Function which will determine
1984 acquire admittance for a WMM AC is required or not based on psb configuration
1985 done in framework
1986
1987 @param pAdapter : [in] pointer to adapter structure
1988
1989 @param acType : [in] WMM AC type of OS packet
1990
1991 @return : void
1992 ===========================================================================*/
1993void hdd_wmm_acquire_access_required(hdd_adapter_t *pAdapter,
1994 WLANTL_ACEnumType acType)
1995{
1996/* Each bit in the LSB nibble indicates 1 AC.
1997 * Clearing the particular bit in LSB nibble to indicate
1998 * access required
1999 */
2000 switch(acType)
2001 {
2002 case WLANTL_AC_BK:
2003 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BK_CHANGED_MASK; /* clear first bit */
2004 break;
2005 case WLANTL_AC_BE:
2006 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BE_CHANGED_MASK; /* clear second bit */
2007 break;
2008 case WLANTL_AC_VI:
2009 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VI_CHANGED_MASK; /* clear third bit */
2010 break;
2011 case WLANTL_AC_VO:
2012 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VO_CHANGED_MASK; /* clear fourth bit */
2013 break;
2014 default:
2015 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2016 "%s: Invalid AC Type", __func__);
2017 break;
2018 }
2019}
2020
Jeff Johnson295189b2012-06-20 16:38:30 -07002021/**============================================================================
2022 @brief hdd_wmm_acquire_access() - Function which will attempt to acquire
2023 admittance for a WMM AC
2024
2025 @param pAdapter : [in] pointer to adapter context
2026 @param acType : [in] WMM AC type of OS packet
2027 @param pGranted : [out] pointer to boolean flag when indicates if access
2028 has been granted or not
2029
2030 @return : VOS_STATUS_SUCCESS if succssful
2031 : other values if failure
2032 ===========================================================================*/
2033VOS_STATUS hdd_wmm_acquire_access( hdd_adapter_t* pAdapter,
2034 WLANTL_ACEnumType acType,
2035 v_BOOL_t * pGranted )
2036{
2037 hdd_wmm_qos_context_t *pQosContext;
2038
2039 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002040 "%s: Entered for AC %d", __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002041
2042 if (!hdd_wmm_is_active(pAdapter) || !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
2043 {
2044 // either we don't want QoS or the AP doesn't support QoS
2045 // or we don't want to do implicit QoS
2046 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002047 "%s: QoS not configured on both ends ", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002048
2049 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2050 *pGranted = VOS_TRUE;
2051 return VOS_STATUS_SUCCESS;
2052 }
2053
2054 // do we already have an implicit QoS request pending for this AC?
2055 if ((pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded) ||
2056 (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessPending))
2057 {
2058 // request already pending so we need to wait for that response
2059 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2060 "%s: Implicit QoS for TL AC %d already scheduled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002061 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002062
2063 *pGranted = VOS_FALSE;
2064 return VOS_STATUS_SUCCESS;
2065 }
2066
2067 // did we already fail to establish implicit QoS for this AC?
2068 // (if so, access should have been granted when the failure was handled)
2069 if (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessFailed)
2070 {
2071 // request previously failed
2072 // allow access, but we'll be downgraded
2073 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2074 "%s: Implicit QoS for TL AC %d previously failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002075 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002076
2077 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2078 *pGranted = VOS_TRUE;
2079 return VOS_STATUS_SUCCESS;
2080 }
2081
2082 // we need to establish implicit QoS
2083 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2084 "%s: Need to schedule implicit QoS for TL AC %d, pAdapter is %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002085 __func__, acType, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002086
2087 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded = VOS_TRUE;
2088
Mohit Khanna217ea8d2012-09-11 17:42:42 -07002089 pQosContext = kmalloc(sizeof(*pQosContext), GFP_ATOMIC);
Jeff Johnson295189b2012-06-20 16:38:30 -07002090 if (NULL == pQosContext)
2091 {
2092 // no memory for QoS context. Nothing we can do but let data flow
2093 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002094 "%s: Unable to allocate context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002095 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2096 *pGranted = VOS_TRUE;
2097 return VOS_STATUS_SUCCESS;
2098 }
2099
2100 pQosContext->acType = acType;
2101 pQosContext->pAdapter = pAdapter;
2102 pQosContext->qosFlowId = 0;
2103 pQosContext->handle = HDD_WMM_HANDLE_IMPLICIT;
2104 pQosContext->magic = HDD_WMM_CTX_MAGIC;
2105 INIT_WORK(&pQosContext->wmmAcSetupImplicitQos,
2106 hdd_wmm_do_implicit_qos);
2107
2108 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2109 "%s: Scheduling work for AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002110 __func__, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002111
2112 schedule_work(&pQosContext->wmmAcSetupImplicitQos);
2113
2114 // caller will need to wait until the work takes place and
2115 // TSPEC negotiation completes
2116 *pGranted = VOS_FALSE;
2117 return VOS_STATUS_SUCCESS;
2118}
2119
2120/**============================================================================
2121 @brief hdd_wmm_assoc() - Function which will handle the housekeeping
2122 required by WMM when association takes place
2123
2124 @param pAdapter : [in] pointer to adapter context
2125 @param pRoamInfo: [in] pointer to roam information
2126 @param eBssType : [in] type of BSS
2127
2128 @return : VOS_STATUS_SUCCESS if succssful
2129 : other values if failure
2130 ===========================================================================*/
2131VOS_STATUS hdd_wmm_assoc( hdd_adapter_t* pAdapter,
2132 tCsrRoamInfo *pRoamInfo,
2133 eCsrRoamBssType eBssType )
2134{
2135 tANI_U8 uapsdMask;
2136 VOS_STATUS status;
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002137 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002138
2139 // when we associate we need to notify TL if it needs to enable
2140 // UAPSD for any access categories
2141
2142 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002143 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002144
2145 if (pRoamInfo->fReassocReq)
2146 {
2147 // when we reassociate we should continue to use whatever
2148 // parameters were previously established. if we are
2149 // reassociating due to a U-APSD change for a particular
2150 // Access Category, then the change will be communicated
2151 // to HDD via the QoS callback associated with the given
2152 // flow, and U-APSD parameters will be updated there
2153
2154 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002155 "%s: Reassoc so no work, Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002156
2157 return VOS_STATUS_SUCCESS;
2158 }
2159
2160 // get the negotiated UAPSD Mask
2161 uapsdMask = pRoamInfo->u.pConnectedProfile->modifyProfileFields.uapsd_mask;
2162
2163 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002164 "%s: U-APSD mask is 0x%02x", __func__, (int) uapsdMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002165
2166 if (uapsdMask & HDD_AC_VO)
2167 {
2168 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2169 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2170 WLANTL_AC_VO,
2171 7,
2172 7,
2173 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv,
2174 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv,
2175 WLANTL_BI_DIR );
2176
2177 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2178 }
2179
2180 if (uapsdMask & HDD_AC_VI)
2181 {
2182 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2183 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2184 WLANTL_AC_VI,
2185 5,
2186 5,
2187 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv,
2188 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv,
2189 WLANTL_BI_DIR );
2190
2191 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2192 }
2193
2194 if (uapsdMask & HDD_AC_BK)
2195 {
2196 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2197 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2198 WLANTL_AC_BK,
2199 2,
2200 2,
2201 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv,
2202 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv,
2203 WLANTL_BI_DIR );
2204
2205 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2206 }
2207
2208 if (uapsdMask & HDD_AC_BE)
2209 {
2210 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2211 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2212 WLANTL_AC_BE,
2213 3,
2214 3,
2215 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv,
2216 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv,
2217 WLANTL_BI_DIR );
2218
2219 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2220 }
Kumar Anand82c009f2014-05-29 00:29:42 -07002221
2222 status = sme_UpdateDSCPtoUPMapping(pHddCtx->hHal,
2223 pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId);
2224
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002225 if (!VOS_IS_STATUS_SUCCESS( status ))
2226 {
Kumar Anand82c009f2014-05-29 00:29:42 -07002227 hdd_wmm_init( pAdapter );
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002228 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002229
2230 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002231 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002232
2233 return VOS_STATUS_SUCCESS;
2234}
2235
2236
2237
2238static const v_U8_t acmMaskBit[WLANTL_MAX_AC] =
2239 {
2240 0x4, /* WLANTL_AC_BK */
2241 0x8, /* WLANTL_AC_BE */
2242 0x2, /* WLANTL_AC_VI */
2243 0x1 /* WLANTL_AC_VO */
2244 };
2245
2246/**============================================================================
2247 @brief hdd_wmm_connect() - Function which will handle the housekeeping
2248 required by WMM when a connection is established
2249
2250 @param pAdapter : [in] pointer to adapter context
2251 @param pRoamInfo: [in] pointer to roam information
2252 @param eBssType : [in] type of BSS
2253
2254 @return : VOS_STATUS_SUCCESS if succssful
2255 : other values if failure
2256 ===========================================================================*/
2257VOS_STATUS hdd_wmm_connect( hdd_adapter_t* pAdapter,
2258 tCsrRoamInfo *pRoamInfo,
2259 eCsrRoamBssType eBssType )
2260{
2261 int ac;
2262 v_BOOL_t qap;
2263 v_BOOL_t qosConnection;
2264 v_U8_t acmMask;
2265
2266 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002267 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002268
2269 if ((eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) &&
2270 pRoamInfo &&
2271 pRoamInfo->u.pConnectedProfile)
2272 {
2273 qap = pRoamInfo->u.pConnectedProfile->qap;
2274 qosConnection = pRoamInfo->u.pConnectedProfile->qosConnection;
2275 acmMask = pRoamInfo->u.pConnectedProfile->acm_mask;
2276 }
2277 else
2278 {
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05302279 /* TODO: if a non-qos IBSS peer joins the group make qap and qosConnection false.
2280 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002281 qap = VOS_TRUE;
2282 qosConnection = VOS_TRUE;
2283 acmMask = 0x0;
2284 }
2285
2286 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2287 "%s: qap is %d, qosConnection is %d, acmMask is 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002288 __func__, qap, qosConnection, acmMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002289
2290 pAdapter->hddWmmStatus.wmmQap = qap;
2291 pAdapter->hddWmmStatus.wmmQosConnection = qosConnection;
2292
2293 for (ac = 0; ac < WLANTL_MAX_AC; ac++)
2294 {
2295 if (qap &&
2296 qosConnection &&
2297 (acmMask & acmMaskBit[ac]))
2298 {
2299 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2300 "%s: ac %d on",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002301 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002302
2303 // admission is required
2304 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_TRUE;
2305 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_FALSE;
2306 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessGranted = VOS_FALSE;
2307 }
2308 else
2309 {
2310 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2311 "%s: ac %d off",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002312 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002313 // admission is not required so access is allowed
2314 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_FALSE;
2315 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_TRUE;
2316 }
2317
2318 }
2319
2320 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002321 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002322
2323 return VOS_STATUS_SUCCESS;
2324}
2325
2326/**============================================================================
2327 @brief hdd_wmm_get_uapsd_mask() - Function which will calculate the
2328 initial value of the UAPSD mask based upon the device configuration
2329
2330 @param pAdapter : [in] pointer to adapter context
2331 @param pUapsdMask: [in] pointer to where the UAPSD Mask is to be stored
2332
2333 @return : VOS_STATUS_SUCCESS if succssful
2334 : other values if failure
2335 ===========================================================================*/
2336VOS_STATUS hdd_wmm_get_uapsd_mask( hdd_adapter_t* pAdapter,
2337 tANI_U8 *pUapsdMask )
2338{
2339 tANI_U8 uapsdMask;
2340
2341 if (HDD_WMM_USER_MODE_NO_QOS == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
2342 {
2343 // no QOS then no UAPSD
2344 uapsdMask = 0;
2345 }
2346 else
2347 {
2348 // start with the default mask
2349 uapsdMask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
2350
2351 // disable UAPSD for any ACs with a 0 Service Interval
2352 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv == 0 )
2353 {
2354 uapsdMask &= ~HDD_AC_VO;
2355 }
2356
2357 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv == 0 )
2358 {
2359 uapsdMask &= ~HDD_AC_VI;
2360 }
2361
2362 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv == 0 )
2363 {
2364 uapsdMask &= ~HDD_AC_BK;
2365 }
2366
2367 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv == 0 )
2368 {
2369 uapsdMask &= ~HDD_AC_BE;
2370 }
2371 }
2372
2373 // return calculated mask
2374 *pUapsdMask = uapsdMask;
2375 return VOS_STATUS_SUCCESS;
2376}
2377
2378
2379/**============================================================================
2380 @brief hdd_wmm_is_active() - Function which will determine if WMM is
2381 active on the current connection
2382
2383 @param pAdapter : [in] pointer to adapter context
2384
2385 @return : VOS_TRUE if WMM is enabled
2386 : VOS_FALSE if WMM is not enabled
2387 ===========================================================================*/
2388v_BOOL_t hdd_wmm_is_active( hdd_adapter_t* pAdapter )
2389{
2390 if ((!pAdapter->hddWmmStatus.wmmQosConnection) ||
2391 (!pAdapter->hddWmmStatus.wmmQap))
2392 {
2393 return VOS_FALSE;
2394 }
2395 else
2396 {
2397 return VOS_TRUE;
2398 }
2399}
2400
2401/**============================================================================
2402 @brief hdd_wmm_addts() - Function which will add a traffic spec at the
2403 request of an application
2404
2405 @param pAdapter : [in] pointer to adapter context
2406 @param handle : [in] handle to uniquely identify a TS
2407 @param pTspec : [in] pointer to the traffic spec
2408
2409 @return : HDD_WLAN_WMM_STATUS_*
2410 ===========================================================================*/
2411hdd_wlan_wmm_status_e hdd_wmm_addts( hdd_adapter_t* pAdapter,
2412 v_U32_t handle,
2413 sme_QosWmmTspecInfo* pTspec )
2414{
2415 hdd_wmm_qos_context_t *pQosContext;
2416 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2417#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2418 sme_QosStatusType smeStatus;
2419#endif
2420 v_BOOL_t found = VOS_FALSE;
2421
2422 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002423 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002424
2425 // see if a context already exists with the given handle
2426 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2427 list_for_each_entry(pQosContext,
2428 &pAdapter->hddWmmStatus.wmmContextList,
2429 node)
2430 {
2431 if (pQosContext->handle == handle)
2432 {
2433 found = VOS_TRUE;
2434 break;
2435 }
2436 }
2437 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2438 if (found)
2439 {
2440 // record with that handle already exists
2441 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2442 "%s: Record already exists with handle 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002443 __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002444
2445 /* Application is trying to modify some of the Tspec params. Allow it */
2446 smeStatus = sme_QosModifyReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2447 pTspec,
2448 pQosContext->qosFlowId);
2449
2450 // need to check the return value and act appropriately
2451 switch (smeStatus)
2452 {
2453 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
2454 status = HDD_WLAN_WMM_STATUS_MODIFY_PENDING;
2455 break;
2456 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2457 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
2458 break;
2459 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
2460 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
2461 break;
2462 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
2463 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
2464 break;
2465 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
2466 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2467 break;
2468 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2469 status = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2470 break;
2471 default:
2472 // we didn't get back one of the SME_QOS_STATUS_MODIFY_* status codes
2473 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002474 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002475 VOS_ASSERT(0);
2476 return HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2477 }
2478
2479 // we were successful, save the status
2480 pQosContext->lastStatus = status;
2481 return status;
2482 }
2483
2484 pQosContext = kmalloc(sizeof(*pQosContext), GFP_KERNEL);
2485 if (NULL == pQosContext)
2486 {
2487 // no memory for QoS context. Nothing we can do
2488 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002489 "%s: Unable to allocate QoS context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002490 return HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE;
2491 }
2492
2493 // we assume the tspec has already been validated by the caller
2494
2495 pQosContext->handle = handle;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08002496 if (pTspec->ts_info.up < HDD_WMM_UP_TO_AC_MAP_SIZE)
2497 pQosContext->acType = hddWmmUpToAcMap[pTspec->ts_info.up];
2498 else {
2499 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2500 "%s: ts_info.up (%d) larger than max value (%d), "
2501 "use default acType (%d)",
2502 __func__, pTspec->ts_info.up,
2503 HDD_WMM_UP_TO_AC_MAP_SIZE - 1, hddWmmUpToAcMap[0]);
2504 pQosContext->acType = hddWmmUpToAcMap[0];
2505 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002506 pQosContext->pAdapter = pAdapter;
2507 pQosContext->qosFlowId = 0;
2508 pQosContext->magic = HDD_WMM_CTX_MAGIC;
2509
2510 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2511 "%s: Setting up QoS, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002512 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002513
2514 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2515 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
2516 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2517
2518#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2519 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2520 pAdapter->sessionId,
2521 pTspec,
2522 hdd_wmm_sme_callback,
2523 pQosContext,
2524 pTspec->ts_info.up,
2525 &pQosContext->qosFlowId);
2526
2527 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2528 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002529 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002530
2531 // need to check the return value and act appropriately
2532 switch (smeStatus)
2533 {
2534 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
2535 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2536 break;
2537 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2538 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
2539 break;
2540 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
2541 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
2542 break;
2543 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
2544 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2545 break;
2546 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
2547 hdd_wmm_free_context(pQosContext);
2548 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
2549 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
2550 // we can't tell the difference between when a request fails because
2551 // AP rejected it versus when SME encounterd an internal error
2552 hdd_wmm_free_context(pQosContext);
2553 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2554 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2555 hdd_wmm_free_context(pQosContext);
2556 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2557 default:
2558 // we didn't get back one of the SME_QOS_STATUS_SETUP_* status codes
2559 hdd_wmm_free_context(pQosContext);
2560 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002561 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002562 VOS_ASSERT(0);
2563 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2564 }
2565#endif
2566
2567 // we were successful, save the status
2568 pQosContext->lastStatus = status;
2569
2570 return status;
2571}
2572
2573/**============================================================================
2574 @brief hdd_wmm_delts() - Function which will delete a traffic spec at the
2575 request of an application
2576
2577 @param pAdapter : [in] pointer to adapter context
2578 @param handle : [in] handle to uniquely identify a TS
2579
2580 @return : HDD_WLAN_WMM_STATUS_*
2581 ===========================================================================*/
2582hdd_wlan_wmm_status_e hdd_wmm_delts( hdd_adapter_t* pAdapter,
2583 v_U32_t handle )
2584{
2585 hdd_wmm_qos_context_t *pQosContext;
2586 v_BOOL_t found = VOS_FALSE;
2587 WLANTL_ACEnumType acType = 0;
2588 v_U32_t qosFlowId = 0;
2589 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2590#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2591 sme_QosStatusType smeStatus;
2592#endif
2593
2594 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002595 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002596
2597 // locate the context with the given handle
2598 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2599 list_for_each_entry(pQosContext,
2600 &pAdapter->hddWmmStatus.wmmContextList,
2601 node)
2602 {
2603 if (pQosContext->handle == handle)
2604 {
2605 found = VOS_TRUE;
2606 acType = pQosContext->acType;
2607 qosFlowId = pQosContext->qosFlowId;
2608 break;
2609 }
2610 }
2611 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2612
2613 if (VOS_FALSE == found)
2614 {
2615 // we didn't find the handle
2616 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002617 "%s: handle 0x%x not found", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002618 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2619 }
2620
2621
2622 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2623 "%s: found handle 0x%x, flow %d, AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002624 __func__, handle, qosFlowId, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002625
2626#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2627 smeStatus = sme_QosReleaseReq( WLAN_HDD_GET_HAL_CTX(pAdapter), qosFlowId );
2628
2629 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2630 "%s: SME flow %d released, SME status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002631 __func__, qosFlowId, smeStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07002632
2633 switch(smeStatus)
2634 {
2635 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
2636 // this flow is the only one on that AC, so go ahead and update
2637 // our TSPEC state for the AC
2638 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcTspecValid = VOS_FALSE;
2639
2640 // need to tell TL to stop trigger timer, etc
2641 hdd_wmm_disable_tl_uapsd(pQosContext);
2642
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002643#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07002644 // disable the inactivity timer
2645 hdd_wmm_disable_inactivity_timer(pQosContext);
2646#endif
2647 // we are done with this context
2648 hdd_wmm_free_context(pQosContext);
2649
2650 // SME must not fire any more callbacks for this flow since the context
2651 // is no longer valid
2652
2653 return HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
2654
2655 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
2656 // do nothing as we will get a response from SME
2657 status = HDD_WLAN_WMM_STATUS_RELEASE_PENDING;
2658 break;
2659
2660 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
2661 // nothing we can do with the existing flow except leave it
2662 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2663 break;
2664
2665 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
2666 // nothing we can do with the existing flow except leave it
2667 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2668
2669 default:
2670 // we didn't get back one of the SME_QOS_STATUS_RELEASE_* status codes
2671 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002672 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002673 VOS_ASSERT(0);
2674 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2675 }
2676
2677#endif
2678 pQosContext->lastStatus = status;
2679 return status;
2680}
2681
2682/**============================================================================
2683 @brief hdd_wmm_checkts() - Function which will return the status of a traffic
2684 spec at the request of an application
2685
2686 @param pAdapter : [in] pointer to adapter context
2687 @param handle : [in] handle to uniquely identify a TS
2688
2689 @return : HDD_WLAN_WMM_STATUS_*
2690 ===========================================================================*/
2691hdd_wlan_wmm_status_e hdd_wmm_checkts( hdd_adapter_t* pAdapter,
2692 v_U32_t handle )
2693{
2694 hdd_wmm_qos_context_t *pQosContext;
2695 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST;
2696
2697 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002698 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002699
2700 // locate the context with the given handle
2701 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2702 list_for_each_entry(pQosContext,
2703 &pAdapter->hddWmmStatus.wmmContextList,
2704 node)
2705 {
2706 if (pQosContext->handle == handle)
2707 {
2708 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2709 "%s: found handle 0x%x, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002710 __func__, handle, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002711
2712 status = pQosContext->lastStatus;
2713 break;
2714 }
2715 }
2716 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2717 return status;
2718}