blob: 0c0866026aa0da5fb67a055d6172d16b64b9777d [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam842dad02014-02-18 18:44:02 -080021
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028/*============================================================================
29 @file wlan_hdd_wmm.c
30
31 This module (wlan_hdd_wmm.h interface + wlan_hdd_wmm.c implementation)
32 houses all the logic for WMM in HDD.
33
34 On the control path, it has the logic to setup QoS, modify QoS and delete
35 QoS (QoS here refers to a TSPEC). The setup QoS comes in two flavors: an
36 explicit application invoked and an internal HDD invoked. The implicit QoS
37 is for applications that do NOT call the custom QCT WLAN OIDs for QoS but
38 which DO mark their traffic for priortization. It also has logic to start,
39 update and stop the U-APSD trigger frame generation. It also has logic to
40 read WMM related config parameters from the registry.
41
42 On the data path, it has the logic to figure out the WMM AC of an egress
43 packet and when to signal TL to serve a particular AC queue. It also has the
44 logic to retrieve a packet based on WMM priority in response to a fetch from
45 TL.
46
47 The remaining functions are utility functions for information hiding.
48
49
50 Copyright (c) 2008-9 QUALCOMM Incorporated.
51 All Rights Reserved.
52 Qualcomm Confidential and Proprietary
53============================================================================*/
54
55/*---------------------------------------------------------------------------
56 Include files
57 -------------------------------------------------------------------------*/
58#include <wlan_hdd_tx_rx.h>
59#include <wlan_hdd_dp_utils.h>
60#include <wlan_hdd_wmm.h>
61#include <wlan_hdd_ether.h>
62#include <linux/netdevice.h>
63#include <linux/skbuff.h>
64#include <linux/etherdevice.h>
65#include <linux/if_vlan.h>
66#include <linux/ip.h>
67#include <linux/semaphore.h>
68#include <wlan_hdd_hostapd.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070069#include <wlan_hdd_softap_tx_rx.h>
Kiet Lam40009862014-02-13 12:33:22 -080070#include <vos_sched.h>
Mukul Sharma74a01e52014-07-21 15:14:23 +053071#include "sme_Api.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070072
73// change logging behavior based upon debug flag
74#ifdef HDD_WMM_DEBUG
75#define WMM_TRACE_LEVEL_FATAL VOS_TRACE_LEVEL_FATAL
76#define WMM_TRACE_LEVEL_ERROR VOS_TRACE_LEVEL_FATAL
77#define WMM_TRACE_LEVEL_WARN VOS_TRACE_LEVEL_FATAL
78#define WMM_TRACE_LEVEL_INFO VOS_TRACE_LEVEL_FATAL
79#define WMM_TRACE_LEVEL_INFO_HIGH VOS_TRACE_LEVEL_FATAL
80#define WMM_TRACE_LEVEL_INFO_LOW VOS_TRACE_LEVEL_FATAL
81#else
82#define WMM_TRACE_LEVEL_FATAL VOS_TRACE_LEVEL_FATAL
83#define WMM_TRACE_LEVEL_ERROR VOS_TRACE_LEVEL_ERROR
84#define WMM_TRACE_LEVEL_WARN VOS_TRACE_LEVEL_WARN
85#define WMM_TRACE_LEVEL_INFO VOS_TRACE_LEVEL_INFO
86#define WMM_TRACE_LEVEL_INFO_HIGH VOS_TRACE_LEVEL_INFO_HIGH
87#define WMM_TRACE_LEVEL_INFO_LOW VOS_TRACE_LEVEL_INFO_LOW
88#endif
89
90
Jeff Johnson295189b2012-06-20 16:38:30 -070091#define WLAN_HDD_MAX_DSCP 0x3f
92
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +053093// DHCP Port number
94#define DHCP_SOURCE_PORT 0x4400
95#define DHCP_DESTINATION_PORT 0x4300
96
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080097#define HDD_WMM_UP_TO_AC_MAP_SIZE 8
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -070098
Jeff Johnson295189b2012-06-20 16:38:30 -070099const v_U8_t hddWmmUpToAcMap[] = {
100 WLANTL_AC_BE,
101 WLANTL_AC_BK,
102 WLANTL_AC_BK,
103 WLANTL_AC_BE,
104 WLANTL_AC_VI,
105 WLANTL_AC_VI,
106 WLANTL_AC_VO,
107 WLANTL_AC_VO
108};
109
110//Linux based UP -> AC Mapping
111const v_U8_t hddLinuxUpToAcMap[8] = {
112 HDD_LINUX_AC_BE,
113 HDD_LINUX_AC_BK,
114 HDD_LINUX_AC_BK,
115 HDD_LINUX_AC_BE,
116 HDD_LINUX_AC_VI,
117 HDD_LINUX_AC_VI,
118 HDD_LINUX_AC_VO,
119 HDD_LINUX_AC_VO
120};
121
122#ifndef WLAN_MDM_CODE_REDUCTION_OPT
123/**
124 @brief hdd_wmm_enable_tl_uapsd() - function which decides whether and
125 how to update UAPSD parameters in TL
126
127 @param pQosContext : [in] the pointer the QoS instance control block
128
129 @return
130 None
131*/
132static void hdd_wmm_enable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
133{
134 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
135 WLANTL_ACEnumType acType = pQosContext->acType;
136 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
137 VOS_STATUS status;
138 v_U32_t service_interval;
139 v_U32_t suspension_interval;
140 sme_QosWmmDirType direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530141 v_BOOL_t psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700142
143
144 // The TSPEC must be valid
145 if (pAc->wmmAcTspecValid == VOS_FALSE)
146 {
147 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
148 "%s: Invoked with invalid TSPEC",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700149 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700150 return;
151 }
152
153 // determine the service interval
154 if (pAc->wmmAcTspecInfo.min_service_interval)
155 {
156 service_interval = pAc->wmmAcTspecInfo.min_service_interval;
157 }
158 else if (pAc->wmmAcTspecInfo.max_service_interval)
159 {
160 service_interval = pAc->wmmAcTspecInfo.max_service_interval;
161 }
162 else
163 {
164 // no service interval is present in the TSPEC
165 // this is OK, there just won't be U-APSD
166 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
167 "%s: No service interval supplied",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700168 __func__);
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530169 service_interval = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700170 }
171
172 // determine the suspension interval & direction
173 suspension_interval = pAc->wmmAcTspecInfo.suspension_interval;
174 direction = pAc->wmmAcTspecInfo.ts_info.direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530175 psb = pAc->wmmAcTspecInfo.ts_info.psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700176
177 // if we have previously enabled U-APSD, have any params changed?
178 if ((pAc->wmmAcUapsdInfoValid) &&
179 (pAc->wmmAcUapsdServiceInterval == service_interval) &&
180 (pAc->wmmAcUapsdSuspensionInterval == suspension_interval) &&
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530181 (pAc->wmmAcUapsdDirection == direction) &&
182 (pAc->wmmAcIsUapsdEnabled == psb))
Jeff Johnson295189b2012-06-20 16:38:30 -0700183 {
184 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
185 "%s: No change in U-APSD parameters",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700186 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700187 return;
188 }
189
190 // are we in the appropriate power save modes?
191 if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_BEACON_MODE_POWER_SAVE))
192 {
193 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
194 "%s: BMPS is not enabled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700195 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700196 return;
197 }
198
199 if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_UAPSD_MODE_POWER_SAVE))
200 {
201 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
202 "%s: U-APSD is not enabled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700203 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700204 return;
205 }
206
207 // everything is in place to notify TL
208 status = WLANTL_EnableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
209 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
210 acType,
211 pAc->wmmAcTspecInfo.ts_info.tid,
212 pAc->wmmAcTspecInfo.ts_info.up,
213 service_interval,
214 suspension_interval,
215 direction);
216
217 if ( !VOS_IS_STATUS_SUCCESS( status ) )
218 {
219 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
220 "%s: Failed to enable U-APSD for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700221 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700222 return;
223 }
224
225 // stash away the parameters that were used
226 pAc->wmmAcUapsdInfoValid = VOS_TRUE;
227 pAc->wmmAcUapsdServiceInterval = service_interval;
228 pAc->wmmAcUapsdSuspensionInterval = suspension_interval;
229 pAc->wmmAcUapsdDirection = direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530230 pAc->wmmAcIsUapsdEnabled = psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700231
232 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700233 "%s: Enabled UAPSD in TL srv_int=%d "
234 "susp_int=%d dir=%d AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700235 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700236 service_interval,
237 suspension_interval,
238 direction,
239 acType);
240
241}
242
243/**
244 @brief hdd_wmm_disable_tl_uapsd() - function which decides whether
245 to disable UAPSD parameters in TL
246
247 @param pQosContext : [in] the pointer the QoS instance control block
248
249 @return
250 None
251*/
252static void hdd_wmm_disable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
253{
254 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
255 WLANTL_ACEnumType acType = pQosContext->acType;
256 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
257 VOS_STATUS status;
258
259
260 // have we previously enabled UAPSD?
261 if (pAc->wmmAcUapsdInfoValid == VOS_TRUE)
262 {
263 status = WLANTL_DisableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
264 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
265 acType);
266
267 if ( !VOS_IS_STATUS_SUCCESS( status ) )
268 {
269 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
270 "%s: Failed to disable U-APSD for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700271 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700272 }
273 else
274 {
275 // TL no longer has valid UAPSD info
276 pAc->wmmAcUapsdInfoValid = VOS_FALSE;
277 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
278 "%s: Disabled UAPSD in TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700279 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700280 acType);
281 }
282 }
283}
284
285#endif
286
287/**
288 @brief hdd_wmm_free_context() - function which frees a QoS context
289
290 @param pQosContext : [in] the pointer the QoS instance control block
291
292 @return
293 None
294*/
295static void hdd_wmm_free_context (hdd_wmm_qos_context_t* pQosContext)
296{
297 hdd_adapter_t* pAdapter;
298
299 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
300 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700301 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700302
303 if (unlikely((NULL == pQosContext) ||
304 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
305 {
306 // must have been freed in another thread
307 return;
308 }
309
310 // get pointer to the adapter context
311 pAdapter = pQosContext->pAdapter;
312
313 // take the wmmLock since we're manipulating the context list
314 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
315
316 // make sure nobody thinks this is a valid context
317 pQosContext->magic = 0;
318
319 // unlink the context
320 list_del(&pQosContext->node);
321
322 // done manipulating the list
323 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
324
325 // reclaim memory
326 kfree(pQosContext);
327
328}
329
330#ifndef WLAN_MDM_CODE_REDUCTION_OPT
331/**
332 @brief hdd_wmm_notify_app() - function which notifies an application
333 changes in state of it flow
334
335 @param pQosContext : [in] the pointer the QoS instance control block
336
337 @return
338 None
339*/
340#define MAX_NOTIFY_LEN 50
341static void hdd_wmm_notify_app (hdd_wmm_qos_context_t* pQosContext)
342{
343 hdd_adapter_t* pAdapter;
344 union iwreq_data wrqu;
345 char buf[MAX_NOTIFY_LEN+1];
346
347 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
348 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700349 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700350
351 if (unlikely((NULL == pQosContext) ||
352 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
353 {
354 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
355 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700356 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700357 return;
358 }
359
360
361 // create the event
362 memset(&wrqu, 0, sizeof(wrqu));
363 memset(buf, 0, sizeof(buf));
364
365 snprintf(buf, MAX_NOTIFY_LEN, "QCOM: TS change[%u: %u]",
366 (unsigned int)pQosContext->handle,
367 (unsigned int)pQosContext->lastStatus);
368
369 wrqu.data.pointer = buf;
370 wrqu.data.length = strlen(buf);
371
372 // get pointer to the adapter
373 pAdapter = pQosContext->pAdapter;
374
375 // send the event
376 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700377 "%s: Sending [%s]", __func__, buf);
Jeff Johnson295189b2012-06-20 16:38:30 -0700378 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
379}
380
381
382/**
383 @brief hdd_wmm_is_access_allowed() - function which determines if access
384 is allowed for the given AC. this is designed to be called during SME
385 callback processing since that is when access can be granted or removed
386
387 @param pAdapter : [in] pointer to adapter context
388 @param pAc : [in] pointer to the per-AC status
389
390 @return : VOS_TRUE - access is allowed
391 : VOS_FALSE - access is not allowed
392 None
393*/
394static v_BOOL_t hdd_wmm_is_access_allowed(hdd_adapter_t* pAdapter,
395 hdd_wmm_ac_status_t* pAc)
396{
397 // if we don't want QoS or the AP doesn't support QoS
398 // or we don't want to do implicit QoS
399 // or if AP doesn't require admission for this AC
400 // then we have access
401 if (!hdd_wmm_is_active(pAdapter) ||
402 !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled ||
403 !pAc->wmmAcAccessRequired)
404 {
405 return VOS_TRUE;
406 }
407
408 // if implicit QoS has already completed, successfully or not,
409 // then access is allowed
410 if (pAc->wmmAcAccessGranted || pAc->wmmAcAccessFailed)
411 {
412 return VOS_TRUE;
413 }
414
415 // admission is required and implicit QoS hasn't completed
416 // however explicit QoS may have completed and we'll have
417 // a Tspec
418 // if we don't have a Tspec then access is not allowed
419 if (!pAc->wmmAcTspecValid)
420 {
421 return VOS_FALSE;
422 }
423
424 // we have a Tspec -- does it allow upstream or bidirectional traffic?
425 // if it only allows downstream traffic then access is not allowed
426 if (pAc->wmmAcTspecInfo.ts_info.direction == SME_QOS_WMM_TS_DIR_DOWNLINK)
427 {
428 return VOS_FALSE;
429 }
430
431 // we meet all of the criteria for access
432 return VOS_TRUE;
433}
434
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800435#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700436/**
437 @brief hdd_wmm_inactivity_timer_cb() - timer handler function which is
438 called for every inactivity interval per AC. This function gets the
439 current transmitted packets on the given AC, and checks if there where
440 any TX activity from the previous interval. If there was no traffic
441 then it would delete the TS that was negotiated on that AC.
442
443 @param pUserData : [in] pointer to pQosContext
444
445 @return : NONE
446*/
447void hdd_wmm_inactivity_timer_cb( v_PVOID_t pUserData )
448{
449 hdd_wmm_qos_context_t* pQosContext = (hdd_wmm_qos_context_t*)pUserData;
450 hdd_adapter_t* pAdapter;
451 hdd_wmm_ac_status_t *pAc;
452 hdd_wlan_wmm_status_e status;
453 VOS_STATUS vos_status;
454 v_U32_t currentTrafficCnt = 0;
455 WLANTL_ACEnumType acType = pQosContext->acType;
456
457 pAdapter = pQosContext->pAdapter;
458 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
459
460 // Get the Tx stats for this AC.
461 currentTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];
462
463 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800464 FL("WMM inactivity Timer for AC=%d, currentCnt=%d, prevCnt=%d"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700465 acType, (int)currentTrafficCnt, (int)pAc->wmmPrevTrafficCnt);
466 if (pAc->wmmPrevTrafficCnt == currentTrafficCnt)
467 {
468 // If there is no traffic activity, delete the TSPEC for this AC
469 status = hdd_wmm_delts(pAdapter, pQosContext->handle);
470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
471 FL("Deleted TS on AC %d, due to inactivity with status = %d!!!"),
472 acType, status);
473 }
474 else
475 {
476 pAc->wmmPrevTrafficCnt = currentTrafficCnt;
477 if (pAc->wmmInactivityTimer.state == VOS_TIMER_STATE_STOPPED)
478 {
479 // Restart the timer
480 vos_status = vos_timer_start(&pAc->wmmInactivityTimer, pAc->wmmInactivityTime);
481 if (!VOS_IS_STATUS_SUCCESS(vos_status))
482 {
483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
484 FL("Restarting inactivity timer failed on AC %d"), acType);
485 }
486 }
487 else
488 {
489 VOS_ASSERT(vos_timer_getCurrentState(
490 &pAc->wmmInactivityTimer) == VOS_TIMER_STATE_STOPPED);
491 }
492 }
493
494 return;
495}
496
497
498/**
499 @brief hdd_wmm_enable_inactivity_timer() - function to enable the
500 traffic inactivity timer for the given AC, if the inactivity_interval
501 specified in the ADDTS parameters is non-zero
502
503 @param pQosContext : [in] pointer to pQosContext
504 @param inactivityTime: [in] value of the inactivity interval in millisecs
505
506 @return : VOS_STATUS_E_FAILURE
507 VOS_STATUS_SUCCESS
508*/
509VOS_STATUS hdd_wmm_enable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext, v_U32_t inactivityTime)
510{
511 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
512 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
513 WLANTL_ACEnumType acType = pQosContext->acType;
514 hdd_wmm_ac_status_t *pAc;
515
516 pAdapter = pQosContext->pAdapter;
517 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
518
519
520 // If QoS-Tspec is successfully setup and if the inactivity timer is non-zero,
521 // a traffic inactivity timer needs to be started for the given AC
522 vos_status = vos_timer_init(
523 &pAc->wmmInactivityTimer,
524 VOS_TIMER_TYPE_SW,
525 hdd_wmm_inactivity_timer_cb,
526 (v_PVOID_t)pQosContext );
527 if ( !VOS_IS_STATUS_SUCCESS(vos_status))
528 {
529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
530 FL("Initializing inactivity timer failed on AC %d"), acType);
531 return vos_status;
532 }
533
534 // Start the inactivity timer
535 vos_status = vos_timer_start(
536 &pAc->wmmInactivityTimer,
537 inactivityTime);
538 if ( !VOS_IS_STATUS_SUCCESS(vos_status))
539 {
540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
541 FL("Starting inactivity timer failed on AC %d"), acType);
542 return vos_status;
543 }
544 pAc->wmmInactivityTime = inactivityTime;
545 // Initialize the current tx traffic count on this AC
546 pAc->wmmPrevTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];
547
548 return vos_status;
549}
550
551/**
552 @brief hdd_wmm_enable_inactivity_timer() - function to disable the
553 traffic inactivity timer for the given AC. This would be called when
554 deleting the TS.
555
556 @param pQosContext : [in] pointer to pQosContext
557
558 @return : VOS_STATUS_E_FAILURE
559 VOS_STATUS_SUCCESS
560*/
561VOS_STATUS hdd_wmm_disable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext)
562{
563 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
564 WLANTL_ACEnumType acType = pQosContext->acType;
565 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
566 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
567
568 // Clear the timer and the counter
569 pAc->wmmInactivityTime = 0;
570 pAc->wmmPrevTrafficCnt = 0;
571 vos_timer_stop(&pAc->wmmInactivityTimer);
572 vos_status = vos_timer_destroy(&pAc->wmmInactivityTimer);
573
574 return vos_status;
575}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800576#endif // FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700577
578/**
579 @brief hdd_wmm_sme_callback() - callback registered by HDD with SME for receiving
580 QoS notifications. Even though this function has a static scope it gets called
581 externally through some function pointer magic (so there is a need for
582 rigorous parameter checking)
583
584 @param hHal : [in] the HAL handle
585 @param HddCtx : [in] the HDD specified handle
586 @param pCurrentQosInfo : [in] the TSPEC params
587 @param SmeStatus : [in] the QoS related SME status
588
589 @return
590 eHAL_STATUS_SUCCESS if all good, eHAL_STATUS_FAILURE otherwise
591*/
592static eHalStatus hdd_wmm_sme_callback (tHalHandle hHal,
593 void * hddCtx,
594 sme_QosWmmTspecInfo* pCurrentQosInfo,
595 sme_QosStatusType smeStatus,
596 v_U32_t qosFlowId)
597{
598 hdd_wmm_qos_context_t* pQosContext = hddCtx;
599 hdd_adapter_t* pAdapter;
600 WLANTL_ACEnumType acType;
601 hdd_wmm_ac_status_t *pAc;
602 VOS_STATUS status;
603
604 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
605 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700606 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700607
608 if (unlikely((NULL == pQosContext) ||
609 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
610 {
611 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
612 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700613 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700614 return eHAL_STATUS_FAILURE;
615 }
616
617 pAdapter = pQosContext->pAdapter;
618 acType = pQosContext->acType;
619 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
620
621 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
622 "%s: status %d flowid %d info %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700623 __func__, smeStatus, qosFlowId, pCurrentQosInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -0700624
625 switch (smeStatus)
626 {
627
628 case SME_QOS_STATUS_SETUP_SUCCESS_IND:
629 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
630 "%s: Setup is complete",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700631 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700632
633 // there will always be a TSPEC returned with this status, even if
634 // a TSPEC is not exchanged OTA
635 if (pCurrentQosInfo)
636 {
637 pAc->wmmAcTspecValid = VOS_TRUE;
638 memcpy(&pAc->wmmAcTspecInfo,
639 pCurrentQosInfo,
640 sizeof(pAc->wmmAcTspecInfo));
641 }
642
643 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
644 {
645
646 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
647 "%s: Implicit Qos, notifying TL for TL AC %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700648 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700649
650 // this was triggered by implicit QoS so we know packets are pending
651 // update state
652 pAc->wmmAcAccessAllowed = VOS_TRUE;
653 pAc->wmmAcAccessGranted = VOS_TRUE;
654 pAc->wmmAcAccessPending = VOS_FALSE;
655
656 // notify TL that packets are pending
657 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
658 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
659 acType );
660
661 if ( !VOS_IS_STATUS_SUCCESS( status ) )
662 {
663 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
664 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700665 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700666 }
667 }
668 else
669 {
670 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
671 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700672 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700673
674 // this was triggered by an application
675 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
676 hdd_wmm_notify_app(pQosContext);
677 }
678
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800679#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700680 // Check if the inactivity interval is specified
Jeff Johnson8795e422013-04-03 08:59:22 -0700681 if (pCurrentQosInfo && pCurrentQosInfo->inactivity_interval) {
Jeff Johnson295189b2012-06-20 16:38:30 -0700682 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800683 "%s: Inactivity timer value = %d for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700684 __func__, pCurrentQosInfo->inactivity_interval, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700685 hdd_wmm_enable_inactivity_timer(pQosContext, pCurrentQosInfo->inactivity_interval);
686 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800687#endif // FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700688
689 // notify TL to enable trigger frames if necessary
690 hdd_wmm_enable_tl_uapsd(pQosContext);
691
692 break;
693
694 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
695 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
696 "%s: Setup is complete (U-APSD set previously)",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700697 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700698
699 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
700 {
701
702 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
703 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700704 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700705
706 // this was triggered by implicit QoS so we know packets are pending
707 // update state
708 pAc->wmmAcAccessAllowed = VOS_TRUE;
709 pAc->wmmAcAccessGranted = VOS_TRUE;
710 pAc->wmmAcAccessPending = VOS_FALSE;
711
712 // notify TL that packets are pending
713 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
714 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
715 acType );
716
717 if ( !VOS_IS_STATUS_SUCCESS( status ) )
718 {
719 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
720 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700721 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700722 }
723 }
724 else
725 {
726 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
727 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700728 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700729
730 // this was triggered by an application
731 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
732 hdd_wmm_notify_app(pQosContext);
733 }
734
735 break;
736
737 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
738 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
739 "%s: Setup failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700740 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700741 // QoS setup failed
742
743 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
744 {
745
746 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
747 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700748 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700749
750 // we note the failure, but we also mark access as allowed so that
751 // the packets will flow. Note that the MAC will "do the right thing"
752 pAc->wmmAcAccessPending = VOS_FALSE;
753 pAc->wmmAcAccessFailed = VOS_TRUE;
754 pAc->wmmAcAccessAllowed = VOS_TRUE;
755
756 // this was triggered by implicit QoS so we know packets are pending
757 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
758 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
759 acType );
760
761 if ( !VOS_IS_STATUS_SUCCESS( status ) )
762 {
763 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
764 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700765 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700766 }
767 }
768 else
769 {
770 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
771 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700772 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700773
774 // this was triggered by an application
775 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED;
776 hdd_wmm_notify_app(pQosContext);
777 }
778
779 /* Setting up QoS Failed, QoS context can be released.
780 * SME is releasing this flow information and if HDD doen't release this context,
781 * next time if application uses the same handle to set-up QoS, HDD (as it has
782 * QoS context for this handle) will issue Modify QoS request to SME but SME will
783 * reject as no it has no information for this flow.
784 */
785 hdd_wmm_free_context(pQosContext);
786 break;
787
788 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
789 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
790 "%s: Setup Invalid Params, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700791 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700792 // QoS setup failed
793
794 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
795 {
796
797 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
798 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700799 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700800
801 // we note the failure, but we also mark access as allowed so that
802 // the packets will flow. Note that the MAC will "do the right thing"
803 pAc->wmmAcAccessPending = VOS_FALSE;
804 pAc->wmmAcAccessFailed = VOS_TRUE;
805 pAc->wmmAcAccessAllowed = VOS_TRUE;
806
807 // this was triggered by implicit QoS so we know packets are pending
808 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
809 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
810 acType );
811
812 if ( !VOS_IS_STATUS_SUCCESS( status ) )
813 {
814 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
815 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700816 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700817 }
818 }
819 else
820 {
821 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
822 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700823 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700824
825 // this was triggered by an application
826 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
827 hdd_wmm_notify_app(pQosContext);
828 }
829 break;
830
831 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
832 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800833 "%s: Setup failed, not a QoS AP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700834 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700835 if (!HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
836 {
837 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
838 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700839 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700840
841 // this was triggered by an application
842 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
843 hdd_wmm_notify_app(pQosContext);
844 }
845 break;
846
847 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
848 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
849 "%s: Setup pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700850 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700851 // not a callback status -- ignore if we get it
852 break;
853
854 case SME_QOS_STATUS_SETUP_MODIFIED_IND:
855 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
856 "%s: Setup modified",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700857 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700858 if (pCurrentQosInfo)
859 {
860 // update the TSPEC
861 pAc->wmmAcTspecValid = VOS_TRUE;
862 memcpy(&pAc->wmmAcTspecInfo,
863 pCurrentQosInfo,
864 sizeof(pAc->wmmAcTspecInfo));
865
866 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
867 {
868 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
869 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700870 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700871
872 // this was triggered by an application
873 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFIED;
874 hdd_wmm_notify_app(pQosContext);
875 }
876
877 // need to tell TL to update its UAPSD handling
878 hdd_wmm_enable_tl_uapsd(pQosContext);
879 }
880 break;
881
882 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
883 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
884 {
885
886 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
887 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700888 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700889
890 // this was triggered by implicit QoS so we know packets are pending
891 pAc->wmmAcAccessPending = VOS_FALSE;
892 pAc->wmmAcAccessGranted = VOS_TRUE;
893 pAc->wmmAcAccessAllowed = VOS_TRUE;
894
895 // notify TL that packets are pending
896 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
897 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
898 acType );
899
900 if ( !VOS_IS_STATUS_SUCCESS( status ) )
901 {
902 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
903 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700904 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700905 }
906 }
907 else
908 {
909 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
910 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700911 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700912
913 // this was triggered by an application
914 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
915 hdd_wmm_notify_app(pQosContext);
916 }
917 break;
918
919 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
920 // nothing to do for now
921 break;
922
923 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED:
924 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
925 "%s: Setup successful but U-APSD failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700926 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700927
928 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
929 {
930
931 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
932 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700933 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700934
935 // QoS setup was successful but setting U=APSD failed
936 // Since the OTA part of the request was successful, we don't mark
937 // this as a failure.
938 // the packets will flow. Note that the MAC will "do the right thing"
939 pAc->wmmAcAccessGranted = VOS_TRUE;
940 pAc->wmmAcAccessAllowed = VOS_TRUE;
941 pAc->wmmAcAccessFailed = VOS_FALSE;
942 pAc->wmmAcAccessPending = VOS_FALSE;
943
944 // this was triggered by implicit QoS so we know packets are pending
945 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
946 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
947 acType );
948
949 if ( !VOS_IS_STATUS_SUCCESS( status ) )
950 {
951 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
952 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700953 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700954 }
955 }
956 else
957 {
958 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
959 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700960 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700961
962 // this was triggered by an application
963 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_UAPSD_SET_FAILED;
964 hdd_wmm_notify_app(pQosContext);
965 }
966
967 // Since U-APSD portion failed disabled trigger frame generation
968 hdd_wmm_disable_tl_uapsd(pQosContext);
969
970 break;
971
972 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
973 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
974 "%s: Release is complete",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700975 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700976
977 if (pCurrentQosInfo)
978 {
979 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
980 "%s: flows still active",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700981 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700982
983 // there is still at least one flow active for this AC
984 // so update the AC state
985 memcpy(&pAc->wmmAcTspecInfo,
986 pCurrentQosInfo,
987 sizeof(pAc->wmmAcTspecInfo));
988
989 // need to tell TL to update its UAPSD handling
990 hdd_wmm_enable_tl_uapsd(pQosContext);
991 }
992 else
993 {
994 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
995 "%s: last flow",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700996 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700997
998 // this is the last flow active for this AC so update the AC state
999 pAc->wmmAcTspecValid = VOS_FALSE;
1000
1001 // need to tell TL to update its UAPSD handling
1002 hdd_wmm_disable_tl_uapsd(pQosContext);
1003 }
1004
1005 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1006 {
1007 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1008 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001009 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001010
1011 // this was triggered by an application
1012 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
1013 hdd_wmm_notify_app(pQosContext);
1014 }
1015
1016 // we are done with this flow
1017 hdd_wmm_free_context(pQosContext);
1018 break;
1019
1020 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
1021 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1022 "%s: Release failure",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001023 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001024
1025 // we don't need to update our state or TL since nothing has changed
1026 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1027 {
1028 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1029 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001030 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001031
1032 // this was triggered by an application
1033 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
1034 hdd_wmm_notify_app(pQosContext);
1035 }
1036
1037 break;
1038
1039 case SME_QOS_STATUS_RELEASE_QOS_LOST_IND:
1040 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1041 "%s: QOS Lost indication received",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001042 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001043
1044 // current TSPEC is no longer valid
1045 pAc->wmmAcTspecValid = VOS_FALSE;
1046
1047 // need to tell TL to update its UAPSD handling
1048 hdd_wmm_disable_tl_uapsd(pQosContext);
1049
1050 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
1051 {
1052 // we no longer have implicit access granted
1053 pAc->wmmAcAccessGranted = VOS_FALSE;
1054 pAc->wmmAcAccessFailed = VOS_FALSE;
1055 }
1056 else
1057 {
1058 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1059 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001060 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001061
1062 // this was triggered by an application
1063 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_LOST;
1064 hdd_wmm_notify_app(pQosContext);
1065 }
1066
1067 // we are done with this flow
1068 hdd_wmm_free_context(pQosContext);
1069 break;
1070
1071 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
1072 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1073 "%s: Release pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001074 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001075 // not a callback status -- ignore if we get it
1076 break;
1077
1078 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
1079 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1080 "%s: Release Invalid Params",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001081 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001082 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1083 {
1084 // this was triggered by an application
1085 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
1086 hdd_wmm_notify_app(pQosContext);
1087 }
1088 break;
1089
1090 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND:
1091 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1092 "%s: Modification is complete, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001093 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001094
1095 // there will always be a TSPEC returned with this status, even if
1096 // a TSPEC is not exchanged OTA
1097 if (pCurrentQosInfo)
1098 {
1099 pAc->wmmAcTspecValid = VOS_TRUE;
1100 memcpy(&pAc->wmmAcTspecInfo,
1101 pCurrentQosInfo,
1102 sizeof(pAc->wmmAcTspecInfo));
1103 }
1104
1105 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1106 {
1107 // this was triggered by an application
1108 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS;
1109 hdd_wmm_notify_app(pQosContext);
1110 }
1111
1112 // notify TL to enable trigger frames if necessary
1113 hdd_wmm_enable_tl_uapsd(pQosContext);
1114
1115 break;
1116
1117 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
1118 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1119 {
1120 // this was triggered by an application
1121 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
1122 hdd_wmm_notify_app(pQosContext);
1123 }
1124 break;
1125
1126 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
1127 // the flow modification failed so we'll leave in place
1128 // whatever existed beforehand
1129
1130 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1131 {
1132 // this was triggered by an application
1133 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
1134 hdd_wmm_notify_app(pQosContext);
1135 }
1136 break;
1137
1138 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
1139 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1140 "%s: modification pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001141 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001142 // not a callback status -- ignore if we get it
1143 break;
1144
1145 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1146 // the flow modification was successful but no QoS changes required
1147
1148 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1149 {
1150 // this was triggered by an application
1151 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
1152 hdd_wmm_notify_app(pQosContext);
1153 }
1154 break;
1155
1156 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
1157 // invalid params -- notify the application
1158 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1159 {
1160 // this was triggered by an application
1161 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
1162 hdd_wmm_notify_app(pQosContext);
1163 }
1164 break;
1165
1166 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_PENDING:
1167 // nothing to do for now. when APSD is established we'll have work to do
1168 break;
1169
1170 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED:
1171 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1172 "%s: Modify successful but U-APSD failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001173 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001174
1175 // QoS modification was successful but setting U=APSD failed.
1176 // This will always be an explicit QoS instance, so all we can
1177 // do is notify the application and let it clean up.
1178 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1179 {
1180 // this was triggered by an application
1181 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_UAPSD_SET_FAILED;
1182 hdd_wmm_notify_app(pQosContext);
1183 }
1184
1185 // Since U-APSD portion failed disabled trigger frame generation
1186 hdd_wmm_disable_tl_uapsd(pQosContext);
1187
1188 break;
1189
1190 case SME_QOS_STATUS_HANDING_OFF:
1191 // no roaming so we won't see this
1192 break;
1193
1194 case SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND:
1195 // need to tell TL to stop trigger frame generation
1196 hdd_wmm_disable_tl_uapsd(pQosContext);
1197 break;
1198
1199 case SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND:
1200 // need to tell TL to start sending trigger frames again
1201 hdd_wmm_enable_tl_uapsd(pQosContext);
1202 break;
1203
1204 default:
1205 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001206 "%s: unexpected SME Status=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001207 __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07001208 VOS_ASSERT(0);
1209 }
1210
1211 // our access to the particular access category may have changed.
1212 // some of the implicit QoS cases above may have already set this
1213 // prior to invoking TL (so that we will properly service the
1214 // Tx queues) but let's consistently handle all cases here
1215 pAc->wmmAcAccessAllowed = hdd_wmm_is_access_allowed(pAdapter, pAc);
1216
1217 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1218 "%s: complete, access for TL AC %d is%sallowed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001219 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001220 acType,
1221 pAc->wmmAcAccessAllowed ? " " : " not ");
1222
1223 return eHAL_STATUS_SUCCESS;
1224}
1225#endif
1226
Kiet Lamf040f472013-11-20 21:15:23 +05301227/**========================================================================
1228 @brief hdd_wmmps_helper() - Function to set uapsd psb dynamically
1229
1230 @param pAdapter : [in] pointer to adapter structure
1231
1232 @param ptr : [in] pointer to command buffer
1233
1234 @return : Zero on success, appropriate error on failure.
1235 =======================================================================*/
1236int hdd_wmmps_helper(hdd_adapter_t *pAdapter, tANI_U8 *ptr)
1237{
1238 if (NULL == pAdapter)
1239 {
1240 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1241 "%s: pAdapter is NULL", __func__);
1242 return -EINVAL;
1243 }
1244 if (NULL == ptr)
1245 {
1246 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1247 "%s: ptr is NULL", __func__);
1248 return -EINVAL;
1249 }
1250 /* convert ASCII to integer */
1251 pAdapter->configuredPsb = ptr[9] - '0';
1252 pAdapter->psbChanged = HDD_PSB_CHANGED;
1253
1254 return 0;
1255}
1256
Jeff Johnson295189b2012-06-20 16:38:30 -07001257/**============================================================================
1258 @brief hdd_wmm_do_implicit_qos() - Function which will attempt to setup
1259 QoS for any AC requiring it
1260
1261 @param work : [in] pointer to work structure
1262
1263 @return : void
1264 ===========================================================================*/
1265static void hdd_wmm_do_implicit_qos(struct work_struct *work)
1266{
1267 hdd_wmm_qos_context_t* pQosContext =
1268 container_of(work, hdd_wmm_qos_context_t, wmmAcSetupImplicitQos);
1269 hdd_adapter_t* pAdapter;
1270 WLANTL_ACEnumType acType;
1271 hdd_wmm_ac_status_t *pAc;
1272#ifndef WLAN_MDM_CODE_REDUCTION_OPT
1273 VOS_STATUS status;
1274 sme_QosStatusType smeStatus;
1275#endif
1276 sme_QosWmmTspecInfo qosInfo;
1277
1278 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1279 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001280 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001281
1282 if (unlikely(HDD_WMM_CTX_MAGIC != pQosContext->magic))
1283 {
1284 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1285 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001286 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001287 return;
1288 }
1289
1290 pAdapter = pQosContext->pAdapter;
1291 acType = pQosContext->acType;
1292 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1293
1294 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1295 "%s: pAdapter %p acType %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001296 __func__, pAdapter, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001297
1298 if (!pAc->wmmAcAccessNeeded)
1299 {
1300 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1301 "%s: AC %d doesn't need service",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001302 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001303 pQosContext->magic = 0;
1304 kfree(pQosContext);
1305 return;
1306 }
1307
1308 pAc->wmmAcAccessPending = VOS_TRUE;
1309 pAc->wmmAcAccessNeeded = VOS_FALSE;
1310
1311 memset(&qosInfo, 0, sizeof(qosInfo));
1312
Kiet Lamf040f472013-11-20 21:15:23 +05301313 qosInfo.ts_info.psb = pAdapter->configuredPsb;
1314
Jeff Johnson295189b2012-06-20 16:38:30 -07001315 switch (acType)
1316 {
1317 case WLANTL_AC_VO:
1318 qosInfo.ts_info.up = SME_QOS_WMM_UP_VO;
Kiet Lamf040f472013-11-20 21:15:23 +05301319 /* Check if there is any valid configuration from framework */
1320 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1321 {
1322 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1323 SME_QOS_UAPSD_VO) ? 1 : 0;
1324 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001325 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVo;
1326 qosInfo.ts_info.tid = 255;
1327 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVo;
1328 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVo;
1329 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv;
1330 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVo;
1331 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVo;
1332 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv;
1333 break;
1334 case WLANTL_AC_VI:
1335 qosInfo.ts_info.up = SME_QOS_WMM_UP_VI;
Kiet Lamf040f472013-11-20 21:15:23 +05301336 /* Check if there is any valid configuration from framework */
1337 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1338 {
1339 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1340 SME_QOS_UAPSD_VI) ? 1 : 0;
1341 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001342 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVi;
1343 qosInfo.ts_info.tid = 255;
1344 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVi;
1345 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVi;
1346 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv;
1347 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVi;
1348 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVi;
1349 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv;
1350 break;
1351 default:
1352 case WLANTL_AC_BE:
1353 qosInfo.ts_info.up = SME_QOS_WMM_UP_BE;
Kiet Lamf040f472013-11-20 21:15:23 +05301354 /* Check if there is any valid configuration from framework */
1355 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1356 {
1357 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1358 SME_QOS_UAPSD_BE) ? 1 : 0;
1359 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001360 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBe;
1361 qosInfo.ts_info.tid = 255;
1362 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBe;
1363 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBe;
1364 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv;
1365 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBe;
1366 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBe;
1367 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv;
1368 break;
1369 case WLANTL_AC_BK:
1370 qosInfo.ts_info.up = SME_QOS_WMM_UP_BK;
Kiet Lamf040f472013-11-20 21:15:23 +05301371 /* Check if there is any valid configuration from framework */
1372 if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
1373 {
1374 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1375 SME_QOS_UAPSD_BK) ? 1 : 0;
1376 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001377 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBk;
1378 qosInfo.ts_info.tid = 255;
1379 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBk;
1380 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBk;
1381 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv;
1382 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBk;
1383 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBk;
1384 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv;
1385 break;
1386 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08001387#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07001388 qosInfo.inactivity_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraInactivityInterval;
1389#endif
1390 qosInfo.ts_info.burst_size_defn = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->burstSizeDefinition;
1391
1392 switch ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->tsInfoAckPolicy)
1393 {
1394 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK:
1395 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1396 break;
1397
1398 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
1399 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
1400 break;
1401
1402 default:
1403 // unknown
1404 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1405 }
1406
1407 if(qosInfo.ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK)
1408 {
1409 if(!sme_QosIsTSInfoAckPolicyValid((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter), &qosInfo, pAdapter->sessionId))
1410 {
1411 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1412 }
1413 }
1414
1415 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
1416 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
1417 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
1418
1419#ifndef WLAN_MDM_CODE_REDUCTION_OPT
1420 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
1421 pAdapter->sessionId,
1422 &qosInfo,
1423 hdd_wmm_sme_callback,
1424 pQosContext,
1425 qosInfo.ts_info.up,
1426 &pQosContext->qosFlowId);
1427
1428 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1429 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001430 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001431
1432 // need to check the return values and act appropriately
1433 switch (smeStatus)
1434 {
1435 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
1436 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
1437 // setup is pending, so no more work to do now.
1438 // all further work will be done in hdd_wmm_sme_callback()
1439 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1440 "%s: Setup is pending, no further work",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001441 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001442
1443 break;
1444
1445
1446 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
1447 // we can't tell the difference between when a request fails because
1448 // AP rejected it versus when SME encountered an internal error
1449
1450 // in either case SME won't ever reference this context so
1451 // free the record
1452 hdd_wmm_free_context(pQosContext);
1453
1454 // fall through and start packets flowing
1455 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1456 // no ACM in effect, no need to setup U-APSD
1457 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
1458 // no ACM in effect, U-APSD is desired but was already setup
1459
1460 // for these cases everything is already setup so we can
1461 // signal TL that it has work to do
1462 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1463 "%s: Setup is complete, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001464 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001465
1466 pAc->wmmAcAccessAllowed = VOS_TRUE;
1467 pAc->wmmAcAccessGranted = VOS_TRUE;
1468 pAc->wmmAcAccessPending = VOS_FALSE;
1469
1470 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1471 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
1472 acType );
1473
1474 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1475 {
1476 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1477 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001478 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -07001479 }
1480
1481 break;
1482
1483
1484 default:
1485 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001486 "%s: unexpected SME Status=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001487 __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07001488 VOS_ASSERT(0);
1489 }
1490#endif
1491
1492}
1493
1494/**============================================================================
1495 @brief hdd_wmm_init() - Function which will initialize the WMM configuation
1496 and status to an initial state. The configuration can later be overwritten
1497 via application APIs
1498
Kumar Anand82c009f2014-05-29 00:29:42 -07001499 @param pAdapter : [in] pointer to Adapter context
Jeff Johnson295189b2012-06-20 16:38:30 -07001500
Kumar Anand82c009f2014-05-29 00:29:42 -07001501 @return : VOS_STATUS_SUCCESS if successful
Jeff Johnson295189b2012-06-20 16:38:30 -07001502 : other values if failure
1503
1504 ===========================================================================*/
Kumar Anand82c009f2014-05-29 00:29:42 -07001505VOS_STATUS hdd_wmm_init ( hdd_adapter_t *pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07001506{
Kumar Anand82c009f2014-05-29 00:29:42 -07001507 sme_QosWmmUpType* hddWmmDscpToUpMap = pAdapter->hddWmmDscpToUpMap;
Jeff Johnson295189b2012-06-20 16:38:30 -07001508 v_U8_t dscp;
1509
1510 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001511 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001512
1513 // DSCP to User Priority Lookup Table
1514 for (dscp = 0; dscp <= WLAN_HDD_MAX_DSCP; dscp++)
1515 {
1516 hddWmmDscpToUpMap[dscp] = SME_QOS_WMM_UP_BE;
1517 }
1518 hddWmmDscpToUpMap[8] = SME_QOS_WMM_UP_BK;
1519 hddWmmDscpToUpMap[16] = SME_QOS_WMM_UP_RESV;
1520 hddWmmDscpToUpMap[24] = SME_QOS_WMM_UP_EE;
1521 hddWmmDscpToUpMap[32] = SME_QOS_WMM_UP_CL;
1522 hddWmmDscpToUpMap[40] = SME_QOS_WMM_UP_VI;
1523 hddWmmDscpToUpMap[48] = SME_QOS_WMM_UP_VO;
1524 hddWmmDscpToUpMap[56] = SME_QOS_WMM_UP_NC;
Jeff Johnson295189b2012-06-20 16:38:30 -07001525 return VOS_STATUS_SUCCESS;
1526}
1527
1528/**============================================================================
1529 @brief hdd_wmm_adapter_init() - Function which will initialize the WMM configuation
1530 and status to an initial state. The configuration can later be overwritten
1531 via application APIs
1532
1533 @param pAdapter : [in] pointer to Adapter context
1534
1535 @return : VOS_STATUS_SUCCESS if succssful
1536 : other values if failure
1537
1538 ===========================================================================*/
1539VOS_STATUS hdd_wmm_adapter_init( hdd_adapter_t *pAdapter )
1540{
1541 hdd_wmm_ac_status_t *pAcStatus;
1542 WLANTL_ACEnumType acType;
1543
1544 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001545 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001546
1547 pAdapter->hddWmmStatus.wmmQap = VOS_FALSE;
1548 INIT_LIST_HEAD(&pAdapter->hddWmmStatus.wmmContextList);
1549 mutex_init(&pAdapter->hddWmmStatus.wmmLock);
1550
1551 for (acType = 0; acType < WLANTL_MAX_AC; acType++)
1552 {
1553 pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1554 pAcStatus->wmmAcAccessRequired = VOS_FALSE;
1555 pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
1556 pAcStatus->wmmAcAccessPending = VOS_FALSE;
1557 pAcStatus->wmmAcAccessFailed = VOS_FALSE;
1558 pAcStatus->wmmAcAccessGranted = VOS_FALSE;
1559 pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
1560 pAcStatus->wmmAcTspecValid = VOS_FALSE;
1561 pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
1562 }
Kiet Lamf040f472013-11-20 21:15:23 +05301563 // Invalid value(0xff) to indicate psb not configured through framework initially.
1564 pAdapter->configuredPsb = HDD_PSB_CFG_INVALID;
Jeff Johnson295189b2012-06-20 16:38:30 -07001565
1566 return VOS_STATUS_SUCCESS;
1567}
Madan Mohan Koyyalamudi70c52d32013-08-07 14:42:16 +05301568
1569/**============================================================================
1570 @brief hdd_wmm_adapter_clear() - Function which will clear the WMM status
1571 for all the ACs
1572
1573 @param pAdapter : [in] pointer to Adapter context
1574
1575 @return : VOS_STATUS_SUCCESS if succssful
1576 : other values if failure
1577
1578 ===========================================================================*/
1579VOS_STATUS hdd_wmm_adapter_clear( hdd_adapter_t *pAdapter )
1580{
1581 hdd_wmm_ac_status_t *pAcStatus;
1582 WLANTL_ACEnumType acType;
1583 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1584 "%s: Entered", __func__);
1585 for (acType = 0; acType < WLANTL_MAX_AC; acType++)
1586 {
1587 pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1588 pAcStatus->wmmAcAccessRequired = VOS_FALSE;
1589 pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
1590 pAcStatus->wmmAcAccessPending = VOS_FALSE;
1591 pAcStatus->wmmAcAccessFailed = VOS_FALSE;
1592 pAcStatus->wmmAcAccessGranted = VOS_FALSE;
1593 pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
1594 pAcStatus->wmmAcTspecValid = VOS_FALSE;
1595 pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
1596 }
1597 return VOS_STATUS_SUCCESS;
1598}
1599
Jeff Johnson295189b2012-06-20 16:38:30 -07001600/**============================================================================
1601 @brief hdd_wmm_close() - Function which will perform any necessary work to
1602 to clean up the WMM functionality prior to the kernel module unload
1603
1604 @param pAdapter : [in] pointer to adapter context
1605
1606 @return : VOS_STATUS_SUCCESS if succssful
1607 : other values if failure
1608
1609 ===========================================================================*/
1610VOS_STATUS hdd_wmm_adapter_close ( hdd_adapter_t* pAdapter )
1611{
1612 hdd_wmm_qos_context_t* pQosContext;
1613
1614 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001615 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001616
1617 // free any context records that we still have linked
1618 while (!list_empty(&pAdapter->hddWmmStatus.wmmContextList))
1619 {
1620 pQosContext = list_first_entry(&pAdapter->hddWmmStatus.wmmContextList,
1621 hdd_wmm_qos_context_t, node);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08001622#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07001623 hdd_wmm_disable_inactivity_timer(pQosContext);
1624#endif
Sameer Thalappilbee426e2013-10-30 10:30:30 -07001625#ifdef WLAN_OPEN_SOURCE
1626 cancel_work_sync(&pQosContext->wmmAcSetupImplicitQos);
1627#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001628 hdd_wmm_free_context(pQosContext);
1629 }
1630
1631 return VOS_STATUS_SUCCESS;
1632}
1633
1634/**============================================================================
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301635 @brief is_dhcp_packet() - Function which will check OS packet for
1636 DHCP packet
1637
1638 @param skb : [in] pointer to OS packet (sk_buff)
1639 @return : VOS_TRUE if the OS packet is DHCP packet
1640 : otherwise VOS_FALSE
1641 ===========================================================================*/
1642v_BOOL_t is_dhcp_packet(struct sk_buff *skb)
1643{
1644 if (*((u16*)((u8*)skb->data+34)) == DHCP_SOURCE_PORT ||
1645 *((u16*)((u8*)skb->data+34)) == DHCP_DESTINATION_PORT)
1646 return VOS_TRUE;
1647
1648 return VOS_FALSE;
1649}
1650
1651/**============================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07001652 @brief hdd_wmm_classify_pkt() - Function which will classify an OS packet
1653 into a WMM AC based on either 802.1Q or DSCP
1654
1655 @param pAdapter : [in] pointer to adapter context
1656 @param skb : [in] pointer to OS packet (sk_buff)
1657 @param pAcType : [out] pointer to WMM AC type of OS packet
1658
1659 @return : None
1660 ===========================================================================*/
1661v_VOID_t hdd_wmm_classify_pkt ( hdd_adapter_t* pAdapter,
1662 struct sk_buff *skb,
1663 WLANTL_ACEnumType* pAcType,
1664 sme_QosWmmUpType *pUserPri)
1665{
1666 unsigned char * pPkt;
1667 union generic_ethhdr *pHdr;
1668 struct iphdr *pIpHdr;
1669 unsigned char tos;
1670 unsigned char dscp;
1671 sme_QosWmmUpType userPri;
1672 WLANTL_ACEnumType acType;
1673
1674 // this code is executed for every packet therefore
1675 // all debug code is kept conditional
1676
1677#ifdef HDD_WMM_DEBUG
1678 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001679 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001680#endif // HDD_WMM_DEBUG
1681
1682 pPkt = skb->data;
1683 pHdr = (union generic_ethhdr *)pPkt;
1684
1685#ifdef HDD_WMM_DEBUG
1686 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1687 "%s: proto/length is 0x%04x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001688 __func__, pHdr->eth_II.h_proto);
Jeff Johnson295189b2012-06-20 16:38:30 -07001689#endif // HDD_WMM_DEBUG
1690
1691 if (HDD_WMM_CLASSIFICATION_DSCP == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
1692 {
1693 if (pHdr->eth_II.h_proto == htons(ETH_P_IP))
1694 {
1695 // case 1: Ethernet II IP packet
1696 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_II)];
1697 tos = pIpHdr->tos;
1698#ifdef HDD_WMM_DEBUG
1699 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1700 "%s: Ethernet II IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001701 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001702#endif // HDD_WMM_DEBUG
1703
1704 }
1705 else if ((ntohs(pHdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
1706 (pHdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
1707 (pHdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
1708 (pHdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1709 (pHdr->eth_8023.h_proto == htons(ETH_P_IP)))
1710 {
1711 // case 2: 802.3 LLC/SNAP IP packet
1712 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];
1713 tos = pIpHdr->tos;
1714#ifdef HDD_WMM_DEBUG
1715 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1716 "%s: 802.3 LLC/SNAP IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001717 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001718#endif // HDD_WMM_DEBUG
1719 }
1720 else if (pHdr->eth_II.h_proto == htons(ETH_P_8021Q))
1721 {
1722 // VLAN tagged
1723
1724 if (pHdr->eth_IIv.h_vlan_encapsulated_proto == htons(ETH_P_IP))
1725 {
1726 // case 3: Ethernet II vlan-tagged IP packet
1727 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_IIv)];
1728 tos = pIpHdr->tos;
1729#ifdef HDD_WMM_DEBUG
1730 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1731 "%s: Ethernet II VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001732 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001733#endif // HDD_WMM_DEBUG
1734 }
1735 else if ((ntohs(pHdr->eth_IIv.h_vlan_encapsulated_proto) < WLAN_MIN_PROTO) &&
1736 (pHdr->eth_8023v.h_snap.dsap == WLAN_SNAP_DSAP) &&
1737 (pHdr->eth_8023v.h_snap.ssap == WLAN_SNAP_SSAP) &&
1738 (pHdr->eth_8023v.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1739 (pHdr->eth_8023v.h_proto == htons(ETH_P_IP)))
1740 {
1741 // case 4: 802.3 LLC/SNAP vlan-tagged IP packet
1742 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023v)];
1743 tos = pIpHdr->tos;
1744#ifdef HDD_WMM_DEBUG
1745 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1746 "%s: 802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001747 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001748#endif // HDD_WMM_DEBUG
1749 }
1750 else
1751 {
1752 // default
1753#ifdef HDD_WMM_DEBUG
1754 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1755 "%s: VLAN tagged Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001756 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001757#endif // HDD_WMM_DEBUG
1758 tos = 0;
1759 }
1760 }
1761 else
1762 {
1763 // default
1764#ifdef HDD_WMM_DEBUG
1765 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1766 "%s: Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001767 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001768#endif // HDD_WMM_DEBUG
1769 //Give the highest priority to 802.1x packet
1770 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
1771 tos = 0xC0;
1772 else
1773 tos = 0;
1774 }
1775
1776 dscp = (tos>>2) & 0x3f;
Kumar Anand82c009f2014-05-29 00:29:42 -07001777 userPri = pAdapter->hddWmmDscpToUpMap[dscp];
1778
Jeff Johnson295189b2012-06-20 16:38:30 -07001779#ifdef HDD_WMM_DEBUG
1780 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1781 "%s: tos is %d, dscp is %d, up is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001782 __func__, tos, dscp, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07001783#endif // HDD_WMM_DEBUG
1784
1785 }
1786 else if (HDD_WMM_CLASSIFICATION_802_1Q == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
1787 {
1788 if (pHdr->eth_IIv.h_vlan_proto == htons(ETH_P_8021Q))
1789 {
1790 // VLAN tagged
1791 userPri = (ntohs(pHdr->eth_IIv.h_vlan_TCI)>>13) & 0x7;
1792#ifdef HDD_WMM_DEBUG
1793 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1794 "%s: Tagged frame, UP is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001795 __func__, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07001796#endif // HDD_WMM_DEBUG
1797 }
1798 else
1799 {
1800 // not VLAN tagged, use default
1801#ifdef HDD_WMM_DEBUG
1802 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1803 "%s: Untagged frame, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001804 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001805#endif // HDD_WMM_DEBUG
1806 //Give the highest priority to 802.1x packet
1807 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
1808 userPri = SME_QOS_WMM_UP_VO;
1809 else
1810 userPri = SME_QOS_WMM_UP_BE;
1811 }
1812 }
1813 else
1814 {
1815 // default
1816#ifdef HDD_WMM_DEBUG
1817 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1818 "%s: Unknown classification scheme, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001819 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001820#endif // HDD_WMM_DEBUG
1821 userPri = SME_QOS_WMM_UP_BE;
1822 }
1823
1824 acType = hddWmmUpToAcMap[userPri];
1825
1826#ifdef HDD_WMM_DEBUG
1827 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1828 "%s: UP is %d, AC is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001829 __func__, userPri, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001830#endif // HDD_WMM_DEBUG
1831
1832 *pUserPri = userPri;
1833 *pAcType = acType;
1834
1835 return;
1836}
1837
1838/**============================================================================
1839 @brief hdd_hostapd_select_quueue() - Function which will classify the packet
1840 according to linux qdisc expectation.
1841
1842
1843 @param dev : [in] pointer to net_device structure
1844 @param skb : [in] pointer to os packet
1845
1846 @return : Qdisc queue index
1847 ===========================================================================*/
1848v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb)
1849{
1850 WLANTL_ACEnumType ac;
1851 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
1852 v_USHORT_t queueIndex;
1853 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
1854 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
1855 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001856 v_U8_t STAId;
1857 v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
1858
1859 /*Get the Station ID*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001860 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &STAId))
1861 {
Agarwal Ashisha64c9542014-03-04 00:14:43 +05301862 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001863 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001864 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1865 goto done;
1866 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001867
1868 spin_lock_bh( &pAdapter->staInfo_lock );
1869 if (FALSE == vos_is_macaddr_equal(&pAdapter->aStaInfo[STAId].macAddrSTA, pDestMacAddress))
1870 {
Agarwal Ashisha64c9542014-03-04 00:14:43 +05301871 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001872 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001873
1874 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1875 goto release_lock;
1876 }
1877 if (pAdapter->aStaInfo[STAId].isUsed && pAdapter->aStaInfo[STAId].isQosEnabled && (HDD_WMM_USER_MODE_NO_QOS != pHddCtx->cfg_ini->WmmMode))
1878 {
1879 /* Get the user priority from IP header & corresponding AC */
1880 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301881 //If 3/4th of Tx queue is used then place the DHCP packet in VOICE AC queue
1882 if (pAdapter->aStaInfo[STAId].vosLowResource && is_dhcp_packet(skb))
1883 {
1884 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1885 "%s: Making priority of DHCP packet as VOICE", __func__);
1886 up = SME_QOS_WMM_UP_VO;
1887 ac = hddWmmUpToAcMap[up];
1888 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001889 }
1890 *pSTAId = STAId;
1891
1892release_lock:
1893 spin_unlock_bh( &pAdapter->staInfo_lock );
1894done:
1895 skb->priority = up;
Mukul Sharmad82cb7d2014-07-03 14:53:30 +05301896 if(skb->priority < SME_QOS_WMM_UP_MAX)
1897 queueIndex = hddLinuxUpToAcMap[skb->priority];
1898 else
1899 {
1900 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1901 "%s: up=%d is going beyond max value", __func__, up);
1902 queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
1903 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001904
1905 return queueIndex;
1906}
1907
1908/**============================================================================
1909 @brief hdd_wmm_select_quueue() - Function which will classify the packet
1910 according to linux qdisc expectation.
1911
1912
1913 @param dev : [in] pointer to net_device structure
1914 @param skb : [in] pointer to os packet
1915
1916 @return : Qdisc queue index
1917 ===========================================================================*/
1918v_U16_t hdd_wmm_select_queue(struct net_device * dev, struct sk_buff *skb)
1919{
1920 WLANTL_ACEnumType ac;
Shailender Karmuchia734f332013-04-19 14:02:48 -07001921 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001922 v_USHORT_t queueIndex;
Jeff Johnson295189b2012-06-20 16:38:30 -07001923 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1924
Kiet Lam40009862014-02-13 12:33:22 -08001925 if (isWDresetInProgress()) {
1926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1927 FL("called during WDReset"));
1928 skb->priority = SME_QOS_WMM_UP_BE;
1929 return HDD_LINUX_AC_BE;
1930 }
1931
Shailender Karmuchia734f332013-04-19 14:02:48 -07001932 /*Get the Station ID*/
1933 if (WLAN_HDD_IBSS == pAdapter->device_mode)
1934 {
1935 v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
1936 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
1937
1938 if ( VOS_STATUS_SUCCESS !=
1939 hdd_Ibss_GetStaId(&pAdapter->sessionCtx.station,
1940 pDestMacAddress, pSTAId))
1941 {
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05301942 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1943 if ( !vos_is_macaddr_broadcast( pDestMacAddress ) &&
1944 !vos_is_macaddr_group(pDestMacAddress))
1945 {
1946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnsonb9fb9ce2013-05-03 08:11:02 -07001947 "%s: Failed to find right station pDestMacAddress: "
1948 MAC_ADDRESS_STR , __func__,
1949 MAC_ADDR_ARRAY(pDestMacAddress->bytes));
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05301950 goto done;
1951 }
Shailender Karmuchia734f332013-04-19 14:02:48 -07001952 }
1953 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001954 // if we don't want QoS or the AP doesn't support Qos
1955 // All traffic will get equal opportuniy to transmit data frames.
1956 if( hdd_wmm_is_active(pAdapter) ) {
1957 /* Get the user priority from IP header & corresponding AC */
1958 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301959 //If 3/4th of BE AC Tx queue is full, then place the DHCP packet in VOICE AC queue
1960 if (pAdapter->isVosLowResource && is_dhcp_packet(skb))
1961 {
1962 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
Rashmi Ramanna36578582014-02-05 16:12:31 +05301963 "%s: BestEffort Tx Queue is 3/4th full"
1964 " Make DHCP packet's pri as VO", __func__);
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301965 up = SME_QOS_WMM_UP_VO;
1966 ac = hddWmmUpToAcMap[up];
1967 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001968 }
Shailender Karmuchia734f332013-04-19 14:02:48 -07001969done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001970 skb->priority = up;
Mukul Sharmad82cb7d2014-07-03 14:53:30 +05301971 if(skb->priority < SME_QOS_WMM_UP_MAX)
1972 queueIndex = hddLinuxUpToAcMap[skb->priority];
1973 else
1974 {
1975 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1976 "%s: up=%d is going beyond max value", __func__, up);
1977 queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
1978 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001979
1980 return queueIndex;
1981}
1982
Kiet Lamf040f472013-11-20 21:15:23 +05301983/**==========================================================================
1984 @brief hdd_wmm_acquire_access_required() - Function which will determine
1985 acquire admittance for a WMM AC is required or not based on psb configuration
1986 done in framework
1987
1988 @param pAdapter : [in] pointer to adapter structure
1989
1990 @param acType : [in] WMM AC type of OS packet
1991
1992 @return : void
1993 ===========================================================================*/
1994void hdd_wmm_acquire_access_required(hdd_adapter_t *pAdapter,
1995 WLANTL_ACEnumType acType)
1996{
1997/* Each bit in the LSB nibble indicates 1 AC.
1998 * Clearing the particular bit in LSB nibble to indicate
1999 * access required
2000 */
2001 switch(acType)
2002 {
2003 case WLANTL_AC_BK:
2004 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BK_CHANGED_MASK; /* clear first bit */
2005 break;
2006 case WLANTL_AC_BE:
2007 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BE_CHANGED_MASK; /* clear second bit */
2008 break;
2009 case WLANTL_AC_VI:
2010 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VI_CHANGED_MASK; /* clear third bit */
2011 break;
2012 case WLANTL_AC_VO:
2013 pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VO_CHANGED_MASK; /* clear fourth bit */
2014 break;
2015 default:
2016 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2017 "%s: Invalid AC Type", __func__);
2018 break;
2019 }
2020}
2021
Jeff Johnson295189b2012-06-20 16:38:30 -07002022/**============================================================================
2023 @brief hdd_wmm_acquire_access() - Function which will attempt to acquire
2024 admittance for a WMM AC
2025
2026 @param pAdapter : [in] pointer to adapter context
2027 @param acType : [in] WMM AC type of OS packet
2028 @param pGranted : [out] pointer to boolean flag when indicates if access
2029 has been granted or not
2030
2031 @return : VOS_STATUS_SUCCESS if succssful
2032 : other values if failure
2033 ===========================================================================*/
2034VOS_STATUS hdd_wmm_acquire_access( hdd_adapter_t* pAdapter,
2035 WLANTL_ACEnumType acType,
2036 v_BOOL_t * pGranted )
2037{
2038 hdd_wmm_qos_context_t *pQosContext;
2039
2040 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002041 "%s: Entered for AC %d", __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002042
2043 if (!hdd_wmm_is_active(pAdapter) || !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
2044 {
2045 // either we don't want QoS or the AP doesn't support QoS
2046 // or we don't want to do implicit QoS
2047 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002048 "%s: QoS not configured on both ends ", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002049
2050 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2051 *pGranted = VOS_TRUE;
2052 return VOS_STATUS_SUCCESS;
2053 }
2054
2055 // do we already have an implicit QoS request pending for this AC?
2056 if ((pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded) ||
2057 (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessPending))
2058 {
2059 // request already pending so we need to wait for that response
2060 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2061 "%s: Implicit QoS for TL AC %d already scheduled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002062 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002063
2064 *pGranted = VOS_FALSE;
2065 return VOS_STATUS_SUCCESS;
2066 }
2067
2068 // did we already fail to establish implicit QoS for this AC?
2069 // (if so, access should have been granted when the failure was handled)
2070 if (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessFailed)
2071 {
2072 // request previously failed
2073 // allow access, but we'll be downgraded
2074 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2075 "%s: Implicit QoS for TL AC %d previously failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002076 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002077
2078 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2079 *pGranted = VOS_TRUE;
2080 return VOS_STATUS_SUCCESS;
2081 }
2082
2083 // we need to establish implicit QoS
2084 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2085 "%s: Need to schedule implicit QoS for TL AC %d, pAdapter is %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002086 __func__, acType, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002087
2088 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded = VOS_TRUE;
2089
Mohit Khanna217ea8d2012-09-11 17:42:42 -07002090 pQosContext = kmalloc(sizeof(*pQosContext), GFP_ATOMIC);
Jeff Johnson295189b2012-06-20 16:38:30 -07002091 if (NULL == pQosContext)
2092 {
2093 // no memory for QoS context. Nothing we can do but let data flow
2094 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002095 "%s: Unable to allocate context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002096 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
2097 *pGranted = VOS_TRUE;
2098 return VOS_STATUS_SUCCESS;
2099 }
2100
2101 pQosContext->acType = acType;
2102 pQosContext->pAdapter = pAdapter;
2103 pQosContext->qosFlowId = 0;
2104 pQosContext->handle = HDD_WMM_HANDLE_IMPLICIT;
2105 pQosContext->magic = HDD_WMM_CTX_MAGIC;
2106 INIT_WORK(&pQosContext->wmmAcSetupImplicitQos,
2107 hdd_wmm_do_implicit_qos);
2108
2109 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2110 "%s: Scheduling work for AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002111 __func__, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002112
2113 schedule_work(&pQosContext->wmmAcSetupImplicitQos);
2114
2115 // caller will need to wait until the work takes place and
2116 // TSPEC negotiation completes
2117 *pGranted = VOS_FALSE;
2118 return VOS_STATUS_SUCCESS;
2119}
2120
2121/**============================================================================
2122 @brief hdd_wmm_assoc() - Function which will handle the housekeeping
2123 required by WMM when association takes place
2124
2125 @param pAdapter : [in] pointer to adapter context
2126 @param pRoamInfo: [in] pointer to roam information
2127 @param eBssType : [in] type of BSS
2128
2129 @return : VOS_STATUS_SUCCESS if succssful
2130 : other values if failure
2131 ===========================================================================*/
2132VOS_STATUS hdd_wmm_assoc( hdd_adapter_t* pAdapter,
2133 tCsrRoamInfo *pRoamInfo,
2134 eCsrRoamBssType eBssType )
2135{
2136 tANI_U8 uapsdMask;
2137 VOS_STATUS status;
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002138 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002139
2140 // when we associate we need to notify TL if it needs to enable
2141 // UAPSD for any access categories
2142
2143 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002144 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002145
2146 if (pRoamInfo->fReassocReq)
2147 {
2148 // when we reassociate we should continue to use whatever
2149 // parameters were previously established. if we are
2150 // reassociating due to a U-APSD change for a particular
2151 // Access Category, then the change will be communicated
2152 // to HDD via the QoS callback associated with the given
2153 // flow, and U-APSD parameters will be updated there
2154
2155 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002156 "%s: Reassoc so no work, Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002157
2158 return VOS_STATUS_SUCCESS;
2159 }
2160
2161 // get the negotiated UAPSD Mask
2162 uapsdMask = pRoamInfo->u.pConnectedProfile->modifyProfileFields.uapsd_mask;
2163
2164 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002165 "%s: U-APSD mask is 0x%02x", __func__, (int) uapsdMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002166
2167 if (uapsdMask & HDD_AC_VO)
2168 {
2169 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2170 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2171 WLANTL_AC_VO,
2172 7,
2173 7,
2174 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv,
2175 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv,
2176 WLANTL_BI_DIR );
2177
2178 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2179 }
2180
2181 if (uapsdMask & HDD_AC_VI)
2182 {
2183 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2184 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2185 WLANTL_AC_VI,
2186 5,
2187 5,
2188 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv,
2189 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv,
2190 WLANTL_BI_DIR );
2191
2192 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2193 }
2194
2195 if (uapsdMask & HDD_AC_BK)
2196 {
2197 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2198 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2199 WLANTL_AC_BK,
2200 2,
2201 2,
2202 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv,
2203 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv,
2204 WLANTL_BI_DIR );
2205
2206 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2207 }
2208
2209 if (uapsdMask & HDD_AC_BE)
2210 {
2211 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2212 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2213 WLANTL_AC_BE,
2214 3,
2215 3,
2216 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv,
2217 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv,
2218 WLANTL_BI_DIR );
2219
2220 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2221 }
Kumar Anand82c009f2014-05-29 00:29:42 -07002222
2223 status = sme_UpdateDSCPtoUPMapping(pHddCtx->hHal,
2224 pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId);
2225
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002226 if (!VOS_IS_STATUS_SUCCESS( status ))
2227 {
Kumar Anand82c009f2014-05-29 00:29:42 -07002228 hdd_wmm_init( pAdapter );
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002229 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002230
2231 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002232 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002233
2234 return VOS_STATUS_SUCCESS;
2235}
2236
2237
2238
2239static const v_U8_t acmMaskBit[WLANTL_MAX_AC] =
2240 {
2241 0x4, /* WLANTL_AC_BK */
2242 0x8, /* WLANTL_AC_BE */
2243 0x2, /* WLANTL_AC_VI */
2244 0x1 /* WLANTL_AC_VO */
2245 };
2246
2247/**============================================================================
2248 @brief hdd_wmm_connect() - Function which will handle the housekeeping
2249 required by WMM when a connection is established
2250
2251 @param pAdapter : [in] pointer to adapter context
2252 @param pRoamInfo: [in] pointer to roam information
2253 @param eBssType : [in] type of BSS
2254
2255 @return : VOS_STATUS_SUCCESS if succssful
2256 : other values if failure
2257 ===========================================================================*/
2258VOS_STATUS hdd_wmm_connect( hdd_adapter_t* pAdapter,
2259 tCsrRoamInfo *pRoamInfo,
2260 eCsrRoamBssType eBssType )
2261{
2262 int ac;
2263 v_BOOL_t qap;
2264 v_BOOL_t qosConnection;
2265 v_U8_t acmMask;
2266
2267 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002268 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002269
2270 if ((eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) &&
2271 pRoamInfo &&
2272 pRoamInfo->u.pConnectedProfile)
2273 {
2274 qap = pRoamInfo->u.pConnectedProfile->qap;
2275 qosConnection = pRoamInfo->u.pConnectedProfile->qosConnection;
2276 acmMask = pRoamInfo->u.pConnectedProfile->acm_mask;
2277 }
2278 else
2279 {
Abhishek Singh1c21c4d2014-04-25 16:40:19 +05302280 /* TODO: if a non-qos IBSS peer joins the group make qap and qosConnection false.
2281 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002282 qap = VOS_TRUE;
2283 qosConnection = VOS_TRUE;
2284 acmMask = 0x0;
2285 }
2286
2287 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2288 "%s: qap is %d, qosConnection is %d, acmMask is 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002289 __func__, qap, qosConnection, acmMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002290
2291 pAdapter->hddWmmStatus.wmmQap = qap;
2292 pAdapter->hddWmmStatus.wmmQosConnection = qosConnection;
2293
2294 for (ac = 0; ac < WLANTL_MAX_AC; ac++)
2295 {
2296 if (qap &&
2297 qosConnection &&
2298 (acmMask & acmMaskBit[ac]))
2299 {
2300 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2301 "%s: ac %d on",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002302 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002303
2304 // admission is required
2305 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_TRUE;
2306 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_FALSE;
2307 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessGranted = VOS_FALSE;
Mukul Sharma74a01e52014-07-21 15:14:23 +05302308
2309 /* Making TSPEC invalid here so downgrading can be happen while roaming
2310 * It is expected this will be SET in hdd_wmm_sme_callback,once sme is
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302311 * done with the AddTspec.Here we avoid 11r and ccx based association.
2312 This change is done only when reassoc to different AP.
Mukul Sharma74a01e52014-07-21 15:14:23 +05302313 */
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302314 if ( !pRoamInfo->fReassocReq
Mukul Sharma74a01e52014-07-21 15:14:23 +05302315#if defined (WLAN_FEATURE_VOWIFI_11R)
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302316 &&
2317 pRoamInfo->u.pConnectedProfile->AuthType != eCSR_AUTH_TYPE_FT_RSN &&
Mukul Sharma74a01e52014-07-21 15:14:23 +05302318 pRoamInfo->u.pConnectedProfile->AuthType != eCSR_AUTH_TYPE_FT_RSN_PSK
Padma, Santhosh Kumard02afd62014-11-04 12:16:06 +05302319#endif
Mukul Sharma74a01e52014-07-21 15:14:23 +05302320#if defined (FEATURE_WLAN_ESE)
2321 &&
2322 pRoamInfo->u.pConnectedProfile->AuthType != eCSR_AUTH_TYPE_CCKM_WPA &&
2323 pRoamInfo->u.pConnectedProfile->AuthType != eCSR_AUTH_TYPE_CCKM_RSN
2324#endif
2325 )
Mukul Sharma74a01e52014-07-21 15:14:23 +05302326 {
2327 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcTspecValid = VOS_FALSE;
2328 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002329 }
2330 else
2331 {
2332 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2333 "%s: ac %d off",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002334 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002335 // admission is not required so access is allowed
2336 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_FALSE;
2337 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_TRUE;
2338 }
2339
2340 }
2341
2342 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002343 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002344
2345 return VOS_STATUS_SUCCESS;
2346}
2347
2348/**============================================================================
2349 @brief hdd_wmm_get_uapsd_mask() - Function which will calculate the
2350 initial value of the UAPSD mask based upon the device configuration
2351
2352 @param pAdapter : [in] pointer to adapter context
2353 @param pUapsdMask: [in] pointer to where the UAPSD Mask is to be stored
2354
2355 @return : VOS_STATUS_SUCCESS if succssful
2356 : other values if failure
2357 ===========================================================================*/
2358VOS_STATUS hdd_wmm_get_uapsd_mask( hdd_adapter_t* pAdapter,
2359 tANI_U8 *pUapsdMask )
2360{
2361 tANI_U8 uapsdMask;
2362
2363 if (HDD_WMM_USER_MODE_NO_QOS == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
2364 {
2365 // no QOS then no UAPSD
2366 uapsdMask = 0;
2367 }
2368 else
2369 {
2370 // start with the default mask
2371 uapsdMask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
2372
2373 // disable UAPSD for any ACs with a 0 Service Interval
2374 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv == 0 )
2375 {
2376 uapsdMask &= ~HDD_AC_VO;
2377 }
2378
2379 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv == 0 )
2380 {
2381 uapsdMask &= ~HDD_AC_VI;
2382 }
2383
2384 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv == 0 )
2385 {
2386 uapsdMask &= ~HDD_AC_BK;
2387 }
2388
2389 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv == 0 )
2390 {
2391 uapsdMask &= ~HDD_AC_BE;
2392 }
2393 }
2394
2395 // return calculated mask
2396 *pUapsdMask = uapsdMask;
2397 return VOS_STATUS_SUCCESS;
2398}
2399
2400
2401/**============================================================================
2402 @brief hdd_wmm_is_active() - Function which will determine if WMM is
2403 active on the current connection
2404
2405 @param pAdapter : [in] pointer to adapter context
2406
2407 @return : VOS_TRUE if WMM is enabled
2408 : VOS_FALSE if WMM is not enabled
2409 ===========================================================================*/
2410v_BOOL_t hdd_wmm_is_active( hdd_adapter_t* pAdapter )
2411{
2412 if ((!pAdapter->hddWmmStatus.wmmQosConnection) ||
2413 (!pAdapter->hddWmmStatus.wmmQap))
2414 {
2415 return VOS_FALSE;
2416 }
2417 else
2418 {
2419 return VOS_TRUE;
2420 }
2421}
2422
2423/**============================================================================
2424 @brief hdd_wmm_addts() - Function which will add a traffic spec at the
2425 request of an application
2426
2427 @param pAdapter : [in] pointer to adapter context
2428 @param handle : [in] handle to uniquely identify a TS
2429 @param pTspec : [in] pointer to the traffic spec
2430
2431 @return : HDD_WLAN_WMM_STATUS_*
2432 ===========================================================================*/
2433hdd_wlan_wmm_status_e hdd_wmm_addts( hdd_adapter_t* pAdapter,
2434 v_U32_t handle,
2435 sme_QosWmmTspecInfo* pTspec )
2436{
2437 hdd_wmm_qos_context_t *pQosContext;
2438 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2439#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2440 sme_QosStatusType smeStatus;
2441#endif
2442 v_BOOL_t found = VOS_FALSE;
2443
2444 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002445 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002446
2447 // see if a context already exists with the given handle
2448 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2449 list_for_each_entry(pQosContext,
2450 &pAdapter->hddWmmStatus.wmmContextList,
2451 node)
2452 {
2453 if (pQosContext->handle == handle)
2454 {
2455 found = VOS_TRUE;
2456 break;
2457 }
2458 }
2459 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2460 if (found)
2461 {
2462 // record with that handle already exists
2463 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2464 "%s: Record already exists with handle 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002465 __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002466
2467 /* Application is trying to modify some of the Tspec params. Allow it */
2468 smeStatus = sme_QosModifyReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2469 pTspec,
2470 pQosContext->qosFlowId);
2471
2472 // need to check the return value and act appropriately
2473 switch (smeStatus)
2474 {
2475 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
2476 status = HDD_WLAN_WMM_STATUS_MODIFY_PENDING;
2477 break;
2478 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2479 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
2480 break;
2481 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
2482 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
2483 break;
2484 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
2485 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
2486 break;
2487 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
2488 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2489 break;
2490 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2491 status = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2492 break;
2493 default:
2494 // we didn't get back one of the SME_QOS_STATUS_MODIFY_* status codes
2495 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002496 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002497 VOS_ASSERT(0);
2498 return HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2499 }
2500
2501 // we were successful, save the status
2502 pQosContext->lastStatus = status;
2503 return status;
2504 }
2505
2506 pQosContext = kmalloc(sizeof(*pQosContext), GFP_KERNEL);
2507 if (NULL == pQosContext)
2508 {
2509 // no memory for QoS context. Nothing we can do
2510 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002511 "%s: Unable to allocate QoS context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002512 return HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE;
2513 }
2514
2515 // we assume the tspec has already been validated by the caller
2516
2517 pQosContext->handle = handle;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08002518 if (pTspec->ts_info.up < HDD_WMM_UP_TO_AC_MAP_SIZE)
2519 pQosContext->acType = hddWmmUpToAcMap[pTspec->ts_info.up];
2520 else {
2521 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2522 "%s: ts_info.up (%d) larger than max value (%d), "
2523 "use default acType (%d)",
2524 __func__, pTspec->ts_info.up,
2525 HDD_WMM_UP_TO_AC_MAP_SIZE - 1, hddWmmUpToAcMap[0]);
2526 pQosContext->acType = hddWmmUpToAcMap[0];
2527 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002528 pQosContext->pAdapter = pAdapter;
2529 pQosContext->qosFlowId = 0;
2530 pQosContext->magic = HDD_WMM_CTX_MAGIC;
2531
2532 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2533 "%s: Setting up QoS, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002534 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002535
2536 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2537 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
2538 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2539
2540#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2541 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2542 pAdapter->sessionId,
2543 pTspec,
2544 hdd_wmm_sme_callback,
2545 pQosContext,
2546 pTspec->ts_info.up,
2547 &pQosContext->qosFlowId);
2548
2549 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2550 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002551 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002552
2553 // need to check the return value and act appropriately
2554 switch (smeStatus)
2555 {
2556 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
2557 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2558 break;
2559 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2560 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
2561 break;
2562 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
2563 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
2564 break;
2565 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
2566 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2567 break;
2568 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
2569 hdd_wmm_free_context(pQosContext);
2570 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
2571 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
2572 // we can't tell the difference between when a request fails because
2573 // AP rejected it versus when SME encounterd an internal error
2574 hdd_wmm_free_context(pQosContext);
2575 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2576 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2577 hdd_wmm_free_context(pQosContext);
2578 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2579 default:
2580 // we didn't get back one of the SME_QOS_STATUS_SETUP_* status codes
2581 hdd_wmm_free_context(pQosContext);
2582 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002583 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002584 VOS_ASSERT(0);
2585 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2586 }
2587#endif
2588
2589 // we were successful, save the status
2590 pQosContext->lastStatus = status;
2591
2592 return status;
2593}
2594
2595/**============================================================================
2596 @brief hdd_wmm_delts() - Function which will delete a traffic spec at the
2597 request of an application
2598
2599 @param pAdapter : [in] pointer to adapter context
2600 @param handle : [in] handle to uniquely identify a TS
2601
2602 @return : HDD_WLAN_WMM_STATUS_*
2603 ===========================================================================*/
2604hdd_wlan_wmm_status_e hdd_wmm_delts( hdd_adapter_t* pAdapter,
2605 v_U32_t handle )
2606{
2607 hdd_wmm_qos_context_t *pQosContext;
2608 v_BOOL_t found = VOS_FALSE;
2609 WLANTL_ACEnumType acType = 0;
2610 v_U32_t qosFlowId = 0;
2611 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2612#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2613 sme_QosStatusType smeStatus;
2614#endif
2615
2616 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002617 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002618
2619 // locate the context with the given handle
2620 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2621 list_for_each_entry(pQosContext,
2622 &pAdapter->hddWmmStatus.wmmContextList,
2623 node)
2624 {
2625 if (pQosContext->handle == handle)
2626 {
2627 found = VOS_TRUE;
2628 acType = pQosContext->acType;
2629 qosFlowId = pQosContext->qosFlowId;
2630 break;
2631 }
2632 }
2633 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2634
2635 if (VOS_FALSE == found)
2636 {
2637 // we didn't find the handle
2638 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002639 "%s: handle 0x%x not found", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002640 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2641 }
2642
2643
2644 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2645 "%s: found handle 0x%x, flow %d, AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002646 __func__, handle, qosFlowId, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002647
2648#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2649 smeStatus = sme_QosReleaseReq( WLAN_HDD_GET_HAL_CTX(pAdapter), qosFlowId );
2650
2651 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2652 "%s: SME flow %d released, SME status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002653 __func__, qosFlowId, smeStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07002654
2655 switch(smeStatus)
2656 {
2657 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
2658 // this flow is the only one on that AC, so go ahead and update
2659 // our TSPEC state for the AC
2660 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcTspecValid = VOS_FALSE;
2661
2662 // need to tell TL to stop trigger timer, etc
2663 hdd_wmm_disable_tl_uapsd(pQosContext);
2664
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002665#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07002666 // disable the inactivity timer
2667 hdd_wmm_disable_inactivity_timer(pQosContext);
2668#endif
2669 // we are done with this context
2670 hdd_wmm_free_context(pQosContext);
2671
2672 // SME must not fire any more callbacks for this flow since the context
2673 // is no longer valid
2674
2675 return HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
2676
2677 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
2678 // do nothing as we will get a response from SME
2679 status = HDD_WLAN_WMM_STATUS_RELEASE_PENDING;
2680 break;
2681
2682 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
2683 // nothing we can do with the existing flow except leave it
2684 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2685 break;
2686
2687 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
2688 // nothing we can do with the existing flow except leave it
2689 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2690
2691 default:
2692 // we didn't get back one of the SME_QOS_STATUS_RELEASE_* status codes
2693 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002694 "%s: unexpected SME Status=%d", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002695 VOS_ASSERT(0);
2696 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2697 }
2698
2699#endif
2700 pQosContext->lastStatus = status;
2701 return status;
2702}
2703
2704/**============================================================================
2705 @brief hdd_wmm_checkts() - Function which will return the status of a traffic
2706 spec at the request of an application
2707
2708 @param pAdapter : [in] pointer to adapter context
2709 @param handle : [in] handle to uniquely identify a TS
2710
2711 @return : HDD_WLAN_WMM_STATUS_*
2712 ===========================================================================*/
2713hdd_wlan_wmm_status_e hdd_wmm_checkts( hdd_adapter_t* pAdapter,
2714 v_U32_t handle )
2715{
2716 hdd_wmm_qos_context_t *pQosContext;
2717 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST;
2718
2719 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002720 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002721
2722 // locate the context with the given handle
2723 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2724 list_for_each_entry(pQosContext,
2725 &pAdapter->hddWmmStatus.wmmContextList,
2726 node)
2727 {
2728 if (pQosContext->handle == handle)
2729 {
2730 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2731 "%s: found handle 0x%x, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002732 __func__, handle, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002733
2734 status = pQosContext->lastStatus;
2735 break;
2736 }
2737 }
2738 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2739 return status;
2740}