blob: ab3118db627af25da313b9354f44c42fa670b06d [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/*============================================================================
43 @file wlan_hdd_wmm.c
44
45 This module (wlan_hdd_wmm.h interface + wlan_hdd_wmm.c implementation)
46 houses all the logic for WMM in HDD.
47
48 On the control path, it has the logic to setup QoS, modify QoS and delete
49 QoS (QoS here refers to a TSPEC). The setup QoS comes in two flavors: an
50 explicit application invoked and an internal HDD invoked. The implicit QoS
51 is for applications that do NOT call the custom QCT WLAN OIDs for QoS but
52 which DO mark their traffic for priortization. It also has logic to start,
53 update and stop the U-APSD trigger frame generation. It also has logic to
54 read WMM related config parameters from the registry.
55
56 On the data path, it has the logic to figure out the WMM AC of an egress
57 packet and when to signal TL to serve a particular AC queue. It also has the
58 logic to retrieve a packet based on WMM priority in response to a fetch from
59 TL.
60
61 The remaining functions are utility functions for information hiding.
62
63
64 Copyright (c) 2008-9 QUALCOMM Incorporated.
65 All Rights Reserved.
66 Qualcomm Confidential and Proprietary
67============================================================================*/
68
69/*---------------------------------------------------------------------------
70 Include files
71 -------------------------------------------------------------------------*/
72#include <wlan_hdd_tx_rx.h>
73#include <wlan_hdd_dp_utils.h>
74#include <wlan_hdd_wmm.h>
75#include <wlan_hdd_ether.h>
76#include <linux/netdevice.h>
77#include <linux/skbuff.h>
78#include <linux/etherdevice.h>
79#include <linux/if_vlan.h>
80#include <linux/ip.h>
81#include <linux/semaphore.h>
82#include <wlan_hdd_hostapd.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070083#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070084
85// change logging behavior based upon debug flag
86#ifdef HDD_WMM_DEBUG
87#define WMM_TRACE_LEVEL_FATAL VOS_TRACE_LEVEL_FATAL
88#define WMM_TRACE_LEVEL_ERROR VOS_TRACE_LEVEL_FATAL
89#define WMM_TRACE_LEVEL_WARN VOS_TRACE_LEVEL_FATAL
90#define WMM_TRACE_LEVEL_INFO VOS_TRACE_LEVEL_FATAL
91#define WMM_TRACE_LEVEL_INFO_HIGH VOS_TRACE_LEVEL_FATAL
92#define WMM_TRACE_LEVEL_INFO_LOW VOS_TRACE_LEVEL_FATAL
93#else
94#define WMM_TRACE_LEVEL_FATAL VOS_TRACE_LEVEL_FATAL
95#define WMM_TRACE_LEVEL_ERROR VOS_TRACE_LEVEL_ERROR
96#define WMM_TRACE_LEVEL_WARN VOS_TRACE_LEVEL_WARN
97#define WMM_TRACE_LEVEL_INFO VOS_TRACE_LEVEL_INFO
98#define WMM_TRACE_LEVEL_INFO_HIGH VOS_TRACE_LEVEL_INFO_HIGH
99#define WMM_TRACE_LEVEL_INFO_LOW VOS_TRACE_LEVEL_INFO_LOW
100#endif
101
102
Jeff Johnson295189b2012-06-20 16:38:30 -0700103#define WLAN_HDD_MAX_DSCP 0x3f
104
105static sme_QosWmmUpType hddWmmDscpToUpMap[WLAN_HDD_MAX_DSCP+1];
106
107const v_U8_t hddWmmUpToAcMap[] = {
108 WLANTL_AC_BE,
109 WLANTL_AC_BK,
110 WLANTL_AC_BK,
111 WLANTL_AC_BE,
112 WLANTL_AC_VI,
113 WLANTL_AC_VI,
114 WLANTL_AC_VO,
115 WLANTL_AC_VO
116};
117
118//Linux based UP -> AC Mapping
119const v_U8_t hddLinuxUpToAcMap[8] = {
120 HDD_LINUX_AC_BE,
121 HDD_LINUX_AC_BK,
122 HDD_LINUX_AC_BK,
123 HDD_LINUX_AC_BE,
124 HDD_LINUX_AC_VI,
125 HDD_LINUX_AC_VI,
126 HDD_LINUX_AC_VO,
127 HDD_LINUX_AC_VO
128};
129
130#ifndef WLAN_MDM_CODE_REDUCTION_OPT
131/**
132 @brief hdd_wmm_enable_tl_uapsd() - function which decides whether and
133 how to update UAPSD parameters in TL
134
135 @param pQosContext : [in] the pointer the QoS instance control block
136
137 @return
138 None
139*/
140static void hdd_wmm_enable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
141{
142 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
143 WLANTL_ACEnumType acType = pQosContext->acType;
144 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
145 VOS_STATUS status;
146 v_U32_t service_interval;
147 v_U32_t suspension_interval;
148 sme_QosWmmDirType direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530149 v_BOOL_t psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700150
151
152 // The TSPEC must be valid
153 if (pAc->wmmAcTspecValid == VOS_FALSE)
154 {
155 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
156 "%s: Invoked with invalid TSPEC",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700157 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700158 return;
159 }
160
161 // determine the service interval
162 if (pAc->wmmAcTspecInfo.min_service_interval)
163 {
164 service_interval = pAc->wmmAcTspecInfo.min_service_interval;
165 }
166 else if (pAc->wmmAcTspecInfo.max_service_interval)
167 {
168 service_interval = pAc->wmmAcTspecInfo.max_service_interval;
169 }
170 else
171 {
172 // no service interval is present in the TSPEC
173 // this is OK, there just won't be U-APSD
174 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
175 "%s: No service interval supplied",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700176 __func__);
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530177 service_interval = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700178 }
179
180 // determine the suspension interval & direction
181 suspension_interval = pAc->wmmAcTspecInfo.suspension_interval;
182 direction = pAc->wmmAcTspecInfo.ts_info.direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530183 psb = pAc->wmmAcTspecInfo.ts_info.psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700184
185 // if we have previously enabled U-APSD, have any params changed?
186 if ((pAc->wmmAcUapsdInfoValid) &&
187 (pAc->wmmAcUapsdServiceInterval == service_interval) &&
188 (pAc->wmmAcUapsdSuspensionInterval == suspension_interval) &&
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530189 (pAc->wmmAcUapsdDirection == direction) &&
190 (pAc->wmmAcIsUapsdEnabled == psb))
Jeff Johnson295189b2012-06-20 16:38:30 -0700191 {
192 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
193 "%s: No change in U-APSD parameters",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700194 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700195 return;
196 }
197
198 // are we in the appropriate power save modes?
199 if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_BEACON_MODE_POWER_SAVE))
200 {
201 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
202 "%s: BMPS 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 if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_UAPSD_MODE_POWER_SAVE))
208 {
209 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
210 "%s: U-APSD is not enabled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700211 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700212 return;
213 }
214
215 // everything is in place to notify TL
216 status = WLANTL_EnableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
217 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
218 acType,
219 pAc->wmmAcTspecInfo.ts_info.tid,
220 pAc->wmmAcTspecInfo.ts_info.up,
221 service_interval,
222 suspension_interval,
223 direction);
224
225 if ( !VOS_IS_STATUS_SUCCESS( status ) )
226 {
227 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
228 "%s: Failed to enable U-APSD for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700229 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700230 return;
231 }
232
233 // stash away the parameters that were used
234 pAc->wmmAcUapsdInfoValid = VOS_TRUE;
235 pAc->wmmAcUapsdServiceInterval = service_interval;
236 pAc->wmmAcUapsdSuspensionInterval = suspension_interval;
237 pAc->wmmAcUapsdDirection = direction;
Madan Mohan Koyyalamudi198ade32013-09-29 03:52:25 +0530238 pAc->wmmAcIsUapsdEnabled = psb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700239
240 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
241 "%s: Enabled UAPSD in TL srv_int=%ld "
242 "susp_int=%ld dir=%d AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700243 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 service_interval,
245 suspension_interval,
246 direction,
247 acType);
248
249}
250
251/**
252 @brief hdd_wmm_disable_tl_uapsd() - function which decides whether
253 to disable UAPSD parameters in TL
254
255 @param pQosContext : [in] the pointer the QoS instance control block
256
257 @return
258 None
259*/
260static void hdd_wmm_disable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
261{
262 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
263 WLANTL_ACEnumType acType = pQosContext->acType;
264 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
265 VOS_STATUS status;
266
267
268 // have we previously enabled UAPSD?
269 if (pAc->wmmAcUapsdInfoValid == VOS_TRUE)
270 {
271 status = WLANTL_DisableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
272 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
273 acType);
274
275 if ( !VOS_IS_STATUS_SUCCESS( status ) )
276 {
277 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
278 "%s: Failed to disable U-APSD for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700279 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700280 }
281 else
282 {
283 // TL no longer has valid UAPSD info
284 pAc->wmmAcUapsdInfoValid = VOS_FALSE;
285 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
286 "%s: Disabled UAPSD in TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700287 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700288 acType);
289 }
290 }
291}
292
293#endif
294
295/**
296 @brief hdd_wmm_free_context() - function which frees a QoS context
297
298 @param pQosContext : [in] the pointer the QoS instance control block
299
300 @return
301 None
302*/
303static void hdd_wmm_free_context (hdd_wmm_qos_context_t* pQosContext)
304{
305 hdd_adapter_t* pAdapter;
306
307 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
308 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700309 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700310
311 if (unlikely((NULL == pQosContext) ||
312 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
313 {
314 // must have been freed in another thread
315 return;
316 }
317
318 // get pointer to the adapter context
319 pAdapter = pQosContext->pAdapter;
320
321 // take the wmmLock since we're manipulating the context list
322 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
323
324 // make sure nobody thinks this is a valid context
325 pQosContext->magic = 0;
326
327 // unlink the context
328 list_del(&pQosContext->node);
329
330 // done manipulating the list
331 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
332
333 // reclaim memory
334 kfree(pQosContext);
335
336}
337
338#ifndef WLAN_MDM_CODE_REDUCTION_OPT
339/**
340 @brief hdd_wmm_notify_app() - function which notifies an application
341 changes in state of it flow
342
343 @param pQosContext : [in] the pointer the QoS instance control block
344
345 @return
346 None
347*/
348#define MAX_NOTIFY_LEN 50
349static void hdd_wmm_notify_app (hdd_wmm_qos_context_t* pQosContext)
350{
351 hdd_adapter_t* pAdapter;
352 union iwreq_data wrqu;
353 char buf[MAX_NOTIFY_LEN+1];
354
355 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
356 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700357 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700358
359 if (unlikely((NULL == pQosContext) ||
360 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
361 {
362 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
363 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700364 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700365 return;
366 }
367
368
369 // create the event
370 memset(&wrqu, 0, sizeof(wrqu));
371 memset(buf, 0, sizeof(buf));
372
373 snprintf(buf, MAX_NOTIFY_LEN, "QCOM: TS change[%u: %u]",
374 (unsigned int)pQosContext->handle,
375 (unsigned int)pQosContext->lastStatus);
376
377 wrqu.data.pointer = buf;
378 wrqu.data.length = strlen(buf);
379
380 // get pointer to the adapter
381 pAdapter = pQosContext->pAdapter;
382
383 // send the event
384 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700385 "%s: Sending [%s]", __func__, buf);
Jeff Johnson295189b2012-06-20 16:38:30 -0700386 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
387}
388
389
390/**
391 @brief hdd_wmm_is_access_allowed() - function which determines if access
392 is allowed for the given AC. this is designed to be called during SME
393 callback processing since that is when access can be granted or removed
394
395 @param pAdapter : [in] pointer to adapter context
396 @param pAc : [in] pointer to the per-AC status
397
398 @return : VOS_TRUE - access is allowed
399 : VOS_FALSE - access is not allowed
400 None
401*/
402static v_BOOL_t hdd_wmm_is_access_allowed(hdd_adapter_t* pAdapter,
403 hdd_wmm_ac_status_t* pAc)
404{
405 // if we don't want QoS or the AP doesn't support QoS
406 // or we don't want to do implicit QoS
407 // or if AP doesn't require admission for this AC
408 // then we have access
409 if (!hdd_wmm_is_active(pAdapter) ||
410 !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled ||
411 !pAc->wmmAcAccessRequired)
412 {
413 return VOS_TRUE;
414 }
415
416 // if implicit QoS has already completed, successfully or not,
417 // then access is allowed
418 if (pAc->wmmAcAccessGranted || pAc->wmmAcAccessFailed)
419 {
420 return VOS_TRUE;
421 }
422
423 // admission is required and implicit QoS hasn't completed
424 // however explicit QoS may have completed and we'll have
425 // a Tspec
426 // if we don't have a Tspec then access is not allowed
427 if (!pAc->wmmAcTspecValid)
428 {
429 return VOS_FALSE;
430 }
431
432 // we have a Tspec -- does it allow upstream or bidirectional traffic?
433 // if it only allows downstream traffic then access is not allowed
434 if (pAc->wmmAcTspecInfo.ts_info.direction == SME_QOS_WMM_TS_DIR_DOWNLINK)
435 {
436 return VOS_FALSE;
437 }
438
439 // we meet all of the criteria for access
440 return VOS_TRUE;
441}
442
443#ifdef FEATURE_WLAN_CCX
444/**
445 @brief hdd_wmm_inactivity_timer_cb() - timer handler function which is
446 called for every inactivity interval per AC. This function gets the
447 current transmitted packets on the given AC, and checks if there where
448 any TX activity from the previous interval. If there was no traffic
449 then it would delete the TS that was negotiated on that AC.
450
451 @param pUserData : [in] pointer to pQosContext
452
453 @return : NONE
454*/
455void hdd_wmm_inactivity_timer_cb( v_PVOID_t pUserData )
456{
457 hdd_wmm_qos_context_t* pQosContext = (hdd_wmm_qos_context_t*)pUserData;
458 hdd_adapter_t* pAdapter;
459 hdd_wmm_ac_status_t *pAc;
460 hdd_wlan_wmm_status_e status;
461 VOS_STATUS vos_status;
462 v_U32_t currentTrafficCnt = 0;
463 WLANTL_ACEnumType acType = pQosContext->acType;
464
465 pAdapter = pQosContext->pAdapter;
466 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
467
468 // Get the Tx stats for this AC.
469 currentTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];
470
471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
472 FL("WMM inactivity Timer for AC=%d, currentCnt=%d, prevCnt=%d\n"),
473 acType, (int)currentTrafficCnt, (int)pAc->wmmPrevTrafficCnt);
474 if (pAc->wmmPrevTrafficCnt == currentTrafficCnt)
475 {
476 // If there is no traffic activity, delete the TSPEC for this AC
477 status = hdd_wmm_delts(pAdapter, pQosContext->handle);
478 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
479 FL("Deleted TS on AC %d, due to inactivity with status = %d!!!"),
480 acType, status);
481 }
482 else
483 {
484 pAc->wmmPrevTrafficCnt = currentTrafficCnt;
485 if (pAc->wmmInactivityTimer.state == VOS_TIMER_STATE_STOPPED)
486 {
487 // Restart the timer
488 vos_status = vos_timer_start(&pAc->wmmInactivityTimer, pAc->wmmInactivityTime);
489 if (!VOS_IS_STATUS_SUCCESS(vos_status))
490 {
491 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
492 FL("Restarting inactivity timer failed on AC %d"), acType);
493 }
494 }
495 else
496 {
497 VOS_ASSERT(vos_timer_getCurrentState(
498 &pAc->wmmInactivityTimer) == VOS_TIMER_STATE_STOPPED);
499 }
500 }
501
502 return;
503}
504
505
506/**
507 @brief hdd_wmm_enable_inactivity_timer() - function to enable the
508 traffic inactivity timer for the given AC, if the inactivity_interval
509 specified in the ADDTS parameters is non-zero
510
511 @param pQosContext : [in] pointer to pQosContext
512 @param inactivityTime: [in] value of the inactivity interval in millisecs
513
514 @return : VOS_STATUS_E_FAILURE
515 VOS_STATUS_SUCCESS
516*/
517VOS_STATUS hdd_wmm_enable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext, v_U32_t inactivityTime)
518{
519 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
520 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
521 WLANTL_ACEnumType acType = pQosContext->acType;
522 hdd_wmm_ac_status_t *pAc;
523
524 pAdapter = pQosContext->pAdapter;
525 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
526
527
528 // If QoS-Tspec is successfully setup and if the inactivity timer is non-zero,
529 // a traffic inactivity timer needs to be started for the given AC
530 vos_status = vos_timer_init(
531 &pAc->wmmInactivityTimer,
532 VOS_TIMER_TYPE_SW,
533 hdd_wmm_inactivity_timer_cb,
534 (v_PVOID_t)pQosContext );
535 if ( !VOS_IS_STATUS_SUCCESS(vos_status))
536 {
537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
538 FL("Initializing inactivity timer failed on AC %d"), acType);
539 return vos_status;
540 }
541
542 // Start the inactivity timer
543 vos_status = vos_timer_start(
544 &pAc->wmmInactivityTimer,
545 inactivityTime);
546 if ( !VOS_IS_STATUS_SUCCESS(vos_status))
547 {
548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
549 FL("Starting inactivity timer failed on AC %d"), acType);
550 return vos_status;
551 }
552 pAc->wmmInactivityTime = inactivityTime;
553 // Initialize the current tx traffic count on this AC
554 pAc->wmmPrevTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];
555
556 return vos_status;
557}
558
559/**
560 @brief hdd_wmm_enable_inactivity_timer() - function to disable the
561 traffic inactivity timer for the given AC. This would be called when
562 deleting the TS.
563
564 @param pQosContext : [in] pointer to pQosContext
565
566 @return : VOS_STATUS_E_FAILURE
567 VOS_STATUS_SUCCESS
568*/
569VOS_STATUS hdd_wmm_disable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext)
570{
571 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
572 WLANTL_ACEnumType acType = pQosContext->acType;
573 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
574 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
575
576 // Clear the timer and the counter
577 pAc->wmmInactivityTime = 0;
578 pAc->wmmPrevTrafficCnt = 0;
579 vos_timer_stop(&pAc->wmmInactivityTimer);
580 vos_status = vos_timer_destroy(&pAc->wmmInactivityTimer);
581
582 return vos_status;
583}
584#endif // FEATURE_WLAN_CCX
585
586/**
587 @brief hdd_wmm_sme_callback() - callback registered by HDD with SME for receiving
588 QoS notifications. Even though this function has a static scope it gets called
589 externally through some function pointer magic (so there is a need for
590 rigorous parameter checking)
591
592 @param hHal : [in] the HAL handle
593 @param HddCtx : [in] the HDD specified handle
594 @param pCurrentQosInfo : [in] the TSPEC params
595 @param SmeStatus : [in] the QoS related SME status
596
597 @return
598 eHAL_STATUS_SUCCESS if all good, eHAL_STATUS_FAILURE otherwise
599*/
600static eHalStatus hdd_wmm_sme_callback (tHalHandle hHal,
601 void * hddCtx,
602 sme_QosWmmTspecInfo* pCurrentQosInfo,
603 sme_QosStatusType smeStatus,
604 v_U32_t qosFlowId)
605{
606 hdd_wmm_qos_context_t* pQosContext = hddCtx;
607 hdd_adapter_t* pAdapter;
608 WLANTL_ACEnumType acType;
609 hdd_wmm_ac_status_t *pAc;
610 VOS_STATUS status;
611
612 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
613 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700614 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700615
616 if (unlikely((NULL == pQosContext) ||
617 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
618 {
619 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
620 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700621 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700622 return eHAL_STATUS_FAILURE;
623 }
624
625 pAdapter = pQosContext->pAdapter;
626 acType = pQosContext->acType;
627 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
628
629 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
630 "%s: status %d flowid %d info %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700631 __func__, smeStatus, qosFlowId, pCurrentQosInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -0700632
633 switch (smeStatus)
634 {
635
636 case SME_QOS_STATUS_SETUP_SUCCESS_IND:
637 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
638 "%s: Setup is complete",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700639 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700640
641 // there will always be a TSPEC returned with this status, even if
642 // a TSPEC is not exchanged OTA
643 if (pCurrentQosInfo)
644 {
645 pAc->wmmAcTspecValid = VOS_TRUE;
646 memcpy(&pAc->wmmAcTspecInfo,
647 pCurrentQosInfo,
648 sizeof(pAc->wmmAcTspecInfo));
649 }
650
651 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
652 {
653
654 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
655 "%s: Implicit Qos, notifying TL for TL AC %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700656 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700657
658 // this was triggered by implicit QoS so we know packets are pending
659 // update state
660 pAc->wmmAcAccessAllowed = VOS_TRUE;
661 pAc->wmmAcAccessGranted = VOS_TRUE;
662 pAc->wmmAcAccessPending = VOS_FALSE;
663
664 // notify TL that packets are pending
665 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
666 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
667 acType );
668
669 if ( !VOS_IS_STATUS_SUCCESS( status ) )
670 {
671 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
672 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700673 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700674 }
675 }
676 else
677 {
678 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
679 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700680 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700681
682 // this was triggered by an application
683 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
684 hdd_wmm_notify_app(pQosContext);
685 }
686
687#ifdef FEATURE_WLAN_CCX
688 // Check if the inactivity interval is specified
Jeff Johnson8795e422013-04-03 08:59:22 -0700689 if (pCurrentQosInfo && pCurrentQosInfo->inactivity_interval) {
Jeff Johnson295189b2012-06-20 16:38:30 -0700690 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
691 "%s: Inactivity timer value = %d for AC=%d\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700692 __func__, pCurrentQosInfo->inactivity_interval, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700693 hdd_wmm_enable_inactivity_timer(pQosContext, pCurrentQosInfo->inactivity_interval);
694 }
695#endif // FEATURE_WLAN_CCX
696
697 // notify TL to enable trigger frames if necessary
698 hdd_wmm_enable_tl_uapsd(pQosContext);
699
700 break;
701
702 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
703 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
704 "%s: Setup is complete (U-APSD set previously)",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700705 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700706
707 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
708 {
709
710 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
711 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700712 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700713
714 // this was triggered by implicit QoS so we know packets are pending
715 // update state
716 pAc->wmmAcAccessAllowed = VOS_TRUE;
717 pAc->wmmAcAccessGranted = VOS_TRUE;
718 pAc->wmmAcAccessPending = VOS_FALSE;
719
720 // notify TL that packets are pending
721 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
722 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
723 acType );
724
725 if ( !VOS_IS_STATUS_SUCCESS( status ) )
726 {
727 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
728 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700729 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700730 }
731 }
732 else
733 {
734 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
735 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700736 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700737
738 // this was triggered by an application
739 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
740 hdd_wmm_notify_app(pQosContext);
741 }
742
743 break;
744
745 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
746 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
747 "%s: Setup failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700748 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700749 // QoS setup failed
750
751 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
752 {
753
754 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
755 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700756 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700757
758 // we note the failure, but we also mark access as allowed so that
759 // the packets will flow. Note that the MAC will "do the right thing"
760 pAc->wmmAcAccessPending = VOS_FALSE;
761 pAc->wmmAcAccessFailed = VOS_TRUE;
762 pAc->wmmAcAccessAllowed = VOS_TRUE;
763
764 // this was triggered by implicit QoS so we know packets are pending
765 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
766 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
767 acType );
768
769 if ( !VOS_IS_STATUS_SUCCESS( status ) )
770 {
771 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
772 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700773 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700774 }
775 }
776 else
777 {
778 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
779 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700780 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700781
782 // this was triggered by an application
783 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED;
784 hdd_wmm_notify_app(pQosContext);
785 }
786
787 /* Setting up QoS Failed, QoS context can be released.
788 * SME is releasing this flow information and if HDD doen't release this context,
789 * next time if application uses the same handle to set-up QoS, HDD (as it has
790 * QoS context for this handle) will issue Modify QoS request to SME but SME will
791 * reject as no it has no information for this flow.
792 */
793 hdd_wmm_free_context(pQosContext);
794 break;
795
796 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
797 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
798 "%s: Setup Invalid Params, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700799 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700800 // QoS setup failed
801
802 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
803 {
804
805 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
806 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700807 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700808
809 // we note the failure, but we also mark access as allowed so that
810 // the packets will flow. Note that the MAC will "do the right thing"
811 pAc->wmmAcAccessPending = VOS_FALSE;
812 pAc->wmmAcAccessFailed = VOS_TRUE;
813 pAc->wmmAcAccessAllowed = VOS_TRUE;
814
815 // this was triggered by implicit QoS so we know packets are pending
816 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
817 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
818 acType );
819
820 if ( !VOS_IS_STATUS_SUCCESS( status ) )
821 {
822 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
823 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700824 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700825 }
826 }
827 else
828 {
829 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
830 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700831 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700832
833 // this was triggered by an application
834 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
835 hdd_wmm_notify_app(pQosContext);
836 }
837 break;
838
839 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
840 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
841 "%s: Setup failed, not a QoS AP\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700842 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700843 if (!HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
844 {
845 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
846 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700847 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700848
849 // this was triggered by an application
850 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
851 hdd_wmm_notify_app(pQosContext);
852 }
853 break;
854
855 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
856 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
857 "%s: Setup pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700858 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700859 // not a callback status -- ignore if we get it
860 break;
861
862 case SME_QOS_STATUS_SETUP_MODIFIED_IND:
863 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
864 "%s: Setup modified",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700865 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700866 if (pCurrentQosInfo)
867 {
868 // update the TSPEC
869 pAc->wmmAcTspecValid = VOS_TRUE;
870 memcpy(&pAc->wmmAcTspecInfo,
871 pCurrentQosInfo,
872 sizeof(pAc->wmmAcTspecInfo));
873
874 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
875 {
876 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
877 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700878 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700879
880 // this was triggered by an application
881 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFIED;
882 hdd_wmm_notify_app(pQosContext);
883 }
884
885 // need to tell TL to update its UAPSD handling
886 hdd_wmm_enable_tl_uapsd(pQosContext);
887 }
888 break;
889
890 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
891 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
892 {
893
894 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
895 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700896 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700897
898 // this was triggered by implicit QoS so we know packets are pending
899 pAc->wmmAcAccessPending = VOS_FALSE;
900 pAc->wmmAcAccessGranted = VOS_TRUE;
901 pAc->wmmAcAccessAllowed = VOS_TRUE;
902
903 // notify TL that packets are pending
904 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
905 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
906 acType );
907
908 if ( !VOS_IS_STATUS_SUCCESS( status ) )
909 {
910 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
911 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700912 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700913 }
914 }
915 else
916 {
917 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
918 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700919 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700920
921 // this was triggered by an application
922 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
923 hdd_wmm_notify_app(pQosContext);
924 }
925 break;
926
927 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
928 // nothing to do for now
929 break;
930
931 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED:
932 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
933 "%s: Setup successful but U-APSD failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700934 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700935
936 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
937 {
938
939 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
940 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700941 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700942
943 // QoS setup was successful but setting U=APSD failed
944 // Since the OTA part of the request was successful, we don't mark
945 // this as a failure.
946 // the packets will flow. Note that the MAC will "do the right thing"
947 pAc->wmmAcAccessGranted = VOS_TRUE;
948 pAc->wmmAcAccessAllowed = VOS_TRUE;
949 pAc->wmmAcAccessFailed = VOS_FALSE;
950 pAc->wmmAcAccessPending = VOS_FALSE;
951
952 // this was triggered by implicit QoS so we know packets are pending
953 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
954 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
955 acType );
956
957 if ( !VOS_IS_STATUS_SUCCESS( status ) )
958 {
959 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
960 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700961 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700962 }
963 }
964 else
965 {
966 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
967 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700968 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700969
970 // this was triggered by an application
971 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_UAPSD_SET_FAILED;
972 hdd_wmm_notify_app(pQosContext);
973 }
974
975 // Since U-APSD portion failed disabled trigger frame generation
976 hdd_wmm_disable_tl_uapsd(pQosContext);
977
978 break;
979
980 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
981 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
982 "%s: Release is complete",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700983 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700984
985 if (pCurrentQosInfo)
986 {
987 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
988 "%s: flows still active",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700989 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700990
991 // there is still at least one flow active for this AC
992 // so update the AC state
993 memcpy(&pAc->wmmAcTspecInfo,
994 pCurrentQosInfo,
995 sizeof(pAc->wmmAcTspecInfo));
996
997 // need to tell TL to update its UAPSD handling
998 hdd_wmm_enable_tl_uapsd(pQosContext);
999 }
1000 else
1001 {
1002 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1003 "%s: last flow",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001004 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001005
1006 // this is the last flow active for this AC so update the AC state
1007 pAc->wmmAcTspecValid = VOS_FALSE;
1008
1009 // need to tell TL to update its UAPSD handling
1010 hdd_wmm_disable_tl_uapsd(pQosContext);
1011 }
1012
1013 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1014 {
1015 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1016 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001017 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001018
1019 // this was triggered by an application
1020 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
1021 hdd_wmm_notify_app(pQosContext);
1022 }
1023
1024 // we are done with this flow
1025 hdd_wmm_free_context(pQosContext);
1026 break;
1027
1028 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
1029 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1030 "%s: Release failure",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001031 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001032
1033 // we don't need to update our state or TL since nothing has changed
1034 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1035 {
1036 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1037 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001038 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001039
1040 // this was triggered by an application
1041 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
1042 hdd_wmm_notify_app(pQosContext);
1043 }
1044
1045 break;
1046
1047 case SME_QOS_STATUS_RELEASE_QOS_LOST_IND:
1048 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1049 "%s: QOS Lost indication received",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001050 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001051
1052 // current TSPEC is no longer valid
1053 pAc->wmmAcTspecValid = VOS_FALSE;
1054
1055 // need to tell TL to update its UAPSD handling
1056 hdd_wmm_disable_tl_uapsd(pQosContext);
1057
1058 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
1059 {
1060 // we no longer have implicit access granted
1061 pAc->wmmAcAccessGranted = VOS_FALSE;
1062 pAc->wmmAcAccessFailed = VOS_FALSE;
1063 }
1064 else
1065 {
1066 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1067 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001068 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001069
1070 // this was triggered by an application
1071 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_LOST;
1072 hdd_wmm_notify_app(pQosContext);
1073 }
1074
1075 // we are done with this flow
1076 hdd_wmm_free_context(pQosContext);
1077 break;
1078
1079 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
1080 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1081 "%s: Release pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001082 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001083 // not a callback status -- ignore if we get it
1084 break;
1085
1086 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
1087 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1088 "%s: Release Invalid Params",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001089 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001090 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1091 {
1092 // this was triggered by an application
1093 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
1094 hdd_wmm_notify_app(pQosContext);
1095 }
1096 break;
1097
1098 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND:
1099 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1100 "%s: Modification is complete, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001101 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001102
1103 // there will always be a TSPEC returned with this status, even if
1104 // a TSPEC is not exchanged OTA
1105 if (pCurrentQosInfo)
1106 {
1107 pAc->wmmAcTspecValid = VOS_TRUE;
1108 memcpy(&pAc->wmmAcTspecInfo,
1109 pCurrentQosInfo,
1110 sizeof(pAc->wmmAcTspecInfo));
1111 }
1112
1113 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1114 {
1115 // this was triggered by an application
1116 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS;
1117 hdd_wmm_notify_app(pQosContext);
1118 }
1119
1120 // notify TL to enable trigger frames if necessary
1121 hdd_wmm_enable_tl_uapsd(pQosContext);
1122
1123 break;
1124
1125 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
1126 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1127 {
1128 // this was triggered by an application
1129 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
1130 hdd_wmm_notify_app(pQosContext);
1131 }
1132 break;
1133
1134 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
1135 // the flow modification failed so we'll leave in place
1136 // whatever existed beforehand
1137
1138 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1139 {
1140 // this was triggered by an application
1141 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
1142 hdd_wmm_notify_app(pQosContext);
1143 }
1144 break;
1145
1146 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
1147 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1148 "%s: modification pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001149 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001150 // not a callback status -- ignore if we get it
1151 break;
1152
1153 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1154 // the flow modification was successful but no QoS changes required
1155
1156 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1157 {
1158 // this was triggered by an application
1159 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
1160 hdd_wmm_notify_app(pQosContext);
1161 }
1162 break;
1163
1164 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
1165 // invalid params -- notify the application
1166 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1167 {
1168 // this was triggered by an application
1169 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
1170 hdd_wmm_notify_app(pQosContext);
1171 }
1172 break;
1173
1174 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_PENDING:
1175 // nothing to do for now. when APSD is established we'll have work to do
1176 break;
1177
1178 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED:
1179 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1180 "%s: Modify successful but U-APSD failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001181 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001182
1183 // QoS modification was successful but setting U=APSD failed.
1184 // This will always be an explicit QoS instance, so all we can
1185 // do is notify the application and let it clean up.
1186 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1187 {
1188 // this was triggered by an application
1189 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_UAPSD_SET_FAILED;
1190 hdd_wmm_notify_app(pQosContext);
1191 }
1192
1193 // Since U-APSD portion failed disabled trigger frame generation
1194 hdd_wmm_disable_tl_uapsd(pQosContext);
1195
1196 break;
1197
1198 case SME_QOS_STATUS_HANDING_OFF:
1199 // no roaming so we won't see this
1200 break;
1201
1202 case SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND:
1203 // need to tell TL to stop trigger frame generation
1204 hdd_wmm_disable_tl_uapsd(pQosContext);
1205 break;
1206
1207 case SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND:
1208 // need to tell TL to start sending trigger frames again
1209 hdd_wmm_enable_tl_uapsd(pQosContext);
1210 break;
1211
1212 default:
1213 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1214 "%s: unexpected SME Status=%d\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001215 __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07001216 VOS_ASSERT(0);
1217 }
1218
1219 // our access to the particular access category may have changed.
1220 // some of the implicit QoS cases above may have already set this
1221 // prior to invoking TL (so that we will properly service the
1222 // Tx queues) but let's consistently handle all cases here
1223 pAc->wmmAcAccessAllowed = hdd_wmm_is_access_allowed(pAdapter, pAc);
1224
1225 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1226 "%s: complete, access for TL AC %d is%sallowed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001227 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001228 acType,
1229 pAc->wmmAcAccessAllowed ? " " : " not ");
1230
1231 return eHAL_STATUS_SUCCESS;
1232}
1233#endif
1234
1235/**============================================================================
1236 @brief hdd_wmm_do_implicit_qos() - Function which will attempt to setup
1237 QoS for any AC requiring it
1238
1239 @param work : [in] pointer to work structure
1240
1241 @return : void
1242 ===========================================================================*/
1243static void hdd_wmm_do_implicit_qos(struct work_struct *work)
1244{
1245 hdd_wmm_qos_context_t* pQosContext =
1246 container_of(work, hdd_wmm_qos_context_t, wmmAcSetupImplicitQos);
1247 hdd_adapter_t* pAdapter;
1248 WLANTL_ACEnumType acType;
1249 hdd_wmm_ac_status_t *pAc;
1250#ifndef WLAN_MDM_CODE_REDUCTION_OPT
1251 VOS_STATUS status;
1252 sme_QosStatusType smeStatus;
1253#endif
1254 sme_QosWmmTspecInfo qosInfo;
1255
1256 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1257 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001258 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001259
1260 if (unlikely(HDD_WMM_CTX_MAGIC != pQosContext->magic))
1261 {
1262 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1263 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001264 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001265 return;
1266 }
1267
1268 pAdapter = pQosContext->pAdapter;
1269 acType = pQosContext->acType;
1270 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1271
1272 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1273 "%s: pAdapter %p acType %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001274 __func__, pAdapter, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001275
1276 if (!pAc->wmmAcAccessNeeded)
1277 {
1278 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1279 "%s: AC %d doesn't need service",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001280 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001281 pQosContext->magic = 0;
1282 kfree(pQosContext);
1283 return;
1284 }
1285
1286 pAc->wmmAcAccessPending = VOS_TRUE;
1287 pAc->wmmAcAccessNeeded = VOS_FALSE;
1288
1289 memset(&qosInfo, 0, sizeof(qosInfo));
1290
1291 switch (acType)
1292 {
1293 case WLANTL_AC_VO:
1294 qosInfo.ts_info.up = SME_QOS_WMM_UP_VO;
Madan Mohan Koyyalamudic0c62382013-08-16 23:46:14 +05301295 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1296 SME_QOS_UAPSD_VO) ? 1 : 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001297 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVo;
1298 qosInfo.ts_info.tid = 255;
1299 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVo;
1300 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVo;
1301 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv;
1302 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVo;
1303 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVo;
1304 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv;
1305 break;
1306 case WLANTL_AC_VI:
1307 qosInfo.ts_info.up = SME_QOS_WMM_UP_VI;
Madan Mohan Koyyalamudic0c62382013-08-16 23:46:14 +05301308 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1309 SME_QOS_UAPSD_VI) ? 1 : 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001310 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVi;
1311 qosInfo.ts_info.tid = 255;
1312 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVi;
1313 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVi;
1314 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv;
1315 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVi;
1316 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVi;
1317 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv;
1318 break;
1319 default:
1320 case WLANTL_AC_BE:
1321 qosInfo.ts_info.up = SME_QOS_WMM_UP_BE;
Madan Mohan Koyyalamudic0c62382013-08-16 23:46:14 +05301322 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1323 SME_QOS_UAPSD_BE) ? 1 : 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001324 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBe;
1325 qosInfo.ts_info.tid = 255;
1326 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBe;
1327 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBe;
1328 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv;
1329 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBe;
1330 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBe;
1331 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv;
1332 break;
1333 case WLANTL_AC_BK:
1334 qosInfo.ts_info.up = SME_QOS_WMM_UP_BK;
Madan Mohan Koyyalamudic0c62382013-08-16 23:46:14 +05301335 qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
1336 SME_QOS_UAPSD_BK) ? 1 : 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001337 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBk;
1338 qosInfo.ts_info.tid = 255;
1339 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBk;
1340 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBk;
1341 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv;
1342 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBk;
1343 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBk;
1344 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv;
1345 break;
1346 }
1347#ifdef FEATURE_WLAN_CCX
1348 qosInfo.inactivity_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraInactivityInterval;
1349#endif
1350 qosInfo.ts_info.burst_size_defn = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->burstSizeDefinition;
1351
1352 switch ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->tsInfoAckPolicy)
1353 {
1354 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK:
1355 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1356 break;
1357
1358 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
1359 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
1360 break;
1361
1362 default:
1363 // unknown
1364 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1365 }
1366
1367 if(qosInfo.ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK)
1368 {
1369 if(!sme_QosIsTSInfoAckPolicyValid((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter), &qosInfo, pAdapter->sessionId))
1370 {
1371 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1372 }
1373 }
1374
1375 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
1376 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
1377 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
1378
1379#ifndef WLAN_MDM_CODE_REDUCTION_OPT
1380 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
1381 pAdapter->sessionId,
1382 &qosInfo,
1383 hdd_wmm_sme_callback,
1384 pQosContext,
1385 qosInfo.ts_info.up,
1386 &pQosContext->qosFlowId);
1387
1388 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1389 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001390 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001391
1392 // need to check the return values and act appropriately
1393 switch (smeStatus)
1394 {
1395 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
1396 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
1397 // setup is pending, so no more work to do now.
1398 // all further work will be done in hdd_wmm_sme_callback()
1399 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1400 "%s: Setup is pending, no further work",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001401 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001402
1403 break;
1404
1405
1406 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
1407 // we can't tell the difference between when a request fails because
1408 // AP rejected it versus when SME encountered an internal error
1409
1410 // in either case SME won't ever reference this context so
1411 // free the record
1412 hdd_wmm_free_context(pQosContext);
1413
1414 // fall through and start packets flowing
1415 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1416 // no ACM in effect, no need to setup U-APSD
1417 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
1418 // no ACM in effect, U-APSD is desired but was already setup
1419
1420 // for these cases everything is already setup so we can
1421 // signal TL that it has work to do
1422 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1423 "%s: Setup is complete, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001424 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001425
1426 pAc->wmmAcAccessAllowed = VOS_TRUE;
1427 pAc->wmmAcAccessGranted = VOS_TRUE;
1428 pAc->wmmAcAccessPending = VOS_FALSE;
1429
1430 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1431 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
1432 acType );
1433
1434 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1435 {
1436 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1437 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001438 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -07001439 }
1440
1441 break;
1442
1443
1444 default:
1445 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1446 "%s: unexpected SME Status=%d\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001447 __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07001448 VOS_ASSERT(0);
1449 }
1450#endif
1451
1452}
1453
1454/**============================================================================
1455 @brief hdd_wmm_init() - Function which will initialize the WMM configuation
1456 and status to an initial state. The configuration can later be overwritten
1457 via application APIs
1458
1459 @param pHddCtx : [in] pointer to HDD context
1460
1461 @return : VOS_STATUS_SUCCESS if succssful
1462 : other values if failure
1463
1464 ===========================================================================*/
1465VOS_STATUS hdd_wmm_init ( hdd_context_t* pHddCtx )
1466{
1467 v_U8_t dscp;
1468
1469 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001470 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001471
1472 // DSCP to User Priority Lookup Table
1473 for (dscp = 0; dscp <= WLAN_HDD_MAX_DSCP; dscp++)
1474 {
1475 hddWmmDscpToUpMap[dscp] = SME_QOS_WMM_UP_BE;
1476 }
1477 hddWmmDscpToUpMap[8] = SME_QOS_WMM_UP_BK;
1478 hddWmmDscpToUpMap[16] = SME_QOS_WMM_UP_RESV;
1479 hddWmmDscpToUpMap[24] = SME_QOS_WMM_UP_EE;
1480 hddWmmDscpToUpMap[32] = SME_QOS_WMM_UP_CL;
1481 hddWmmDscpToUpMap[40] = SME_QOS_WMM_UP_VI;
1482 hddWmmDscpToUpMap[48] = SME_QOS_WMM_UP_VO;
1483 hddWmmDscpToUpMap[56] = SME_QOS_WMM_UP_NC;
1484
1485 return VOS_STATUS_SUCCESS;
1486}
1487
1488/**============================================================================
1489 @brief hdd_wmm_adapter_init() - Function which will initialize the WMM configuation
1490 and status to an initial state. The configuration can later be overwritten
1491 via application APIs
1492
1493 @param pAdapter : [in] pointer to Adapter context
1494
1495 @return : VOS_STATUS_SUCCESS if succssful
1496 : other values if failure
1497
1498 ===========================================================================*/
1499VOS_STATUS hdd_wmm_adapter_init( hdd_adapter_t *pAdapter )
1500{
1501 hdd_wmm_ac_status_t *pAcStatus;
1502 WLANTL_ACEnumType acType;
1503
1504 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001505 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001506
1507 pAdapter->hddWmmStatus.wmmQap = VOS_FALSE;
1508 INIT_LIST_HEAD(&pAdapter->hddWmmStatus.wmmContextList);
1509 mutex_init(&pAdapter->hddWmmStatus.wmmLock);
1510
1511 for (acType = 0; acType < WLANTL_MAX_AC; acType++)
1512 {
1513 pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1514 pAcStatus->wmmAcAccessRequired = VOS_FALSE;
1515 pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
1516 pAcStatus->wmmAcAccessPending = VOS_FALSE;
1517 pAcStatus->wmmAcAccessFailed = VOS_FALSE;
1518 pAcStatus->wmmAcAccessGranted = VOS_FALSE;
1519 pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
1520 pAcStatus->wmmAcTspecValid = VOS_FALSE;
1521 pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
1522 }
1523
1524 return VOS_STATUS_SUCCESS;
1525}
Madan Mohan Koyyalamudi70c52d32013-08-07 14:42:16 +05301526
1527/**============================================================================
1528 @brief hdd_wmm_adapter_clear() - Function which will clear the WMM status
1529 for all the ACs
1530
1531 @param pAdapter : [in] pointer to Adapter context
1532
1533 @return : VOS_STATUS_SUCCESS if succssful
1534 : other values if failure
1535
1536 ===========================================================================*/
1537VOS_STATUS hdd_wmm_adapter_clear( hdd_adapter_t *pAdapter )
1538{
1539 hdd_wmm_ac_status_t *pAcStatus;
1540 WLANTL_ACEnumType acType;
1541 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1542 "%s: Entered", __func__);
1543 for (acType = 0; acType < WLANTL_MAX_AC; acType++)
1544 {
1545 pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1546 pAcStatus->wmmAcAccessRequired = VOS_FALSE;
1547 pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
1548 pAcStatus->wmmAcAccessPending = VOS_FALSE;
1549 pAcStatus->wmmAcAccessFailed = VOS_FALSE;
1550 pAcStatus->wmmAcAccessGranted = VOS_FALSE;
1551 pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
1552 pAcStatus->wmmAcTspecValid = VOS_FALSE;
1553 pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
1554 }
1555 return VOS_STATUS_SUCCESS;
1556}
1557
Jeff Johnson295189b2012-06-20 16:38:30 -07001558/**============================================================================
1559 @brief hdd_wmm_close() - Function which will perform any necessary work to
1560 to clean up the WMM functionality prior to the kernel module unload
1561
1562 @param pAdapter : [in] pointer to adapter context
1563
1564 @return : VOS_STATUS_SUCCESS if succssful
1565 : other values if failure
1566
1567 ===========================================================================*/
1568VOS_STATUS hdd_wmm_adapter_close ( hdd_adapter_t* pAdapter )
1569{
1570 hdd_wmm_qos_context_t* pQosContext;
1571
1572 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001573 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001574
1575 // free any context records that we still have linked
1576 while (!list_empty(&pAdapter->hddWmmStatus.wmmContextList))
1577 {
1578 pQosContext = list_first_entry(&pAdapter->hddWmmStatus.wmmContextList,
1579 hdd_wmm_qos_context_t, node);
1580#ifdef FEATURE_WLAN_CCX
1581 hdd_wmm_disable_inactivity_timer(pQosContext);
1582#endif
1583 hdd_wmm_free_context(pQosContext);
1584 }
1585
1586 return VOS_STATUS_SUCCESS;
1587}
1588
1589/**============================================================================
1590 @brief hdd_wmm_classify_pkt() - Function which will classify an OS packet
1591 into a WMM AC based on either 802.1Q or DSCP
1592
1593 @param pAdapter : [in] pointer to adapter context
1594 @param skb : [in] pointer to OS packet (sk_buff)
1595 @param pAcType : [out] pointer to WMM AC type of OS packet
1596
1597 @return : None
1598 ===========================================================================*/
1599v_VOID_t hdd_wmm_classify_pkt ( hdd_adapter_t* pAdapter,
1600 struct sk_buff *skb,
1601 WLANTL_ACEnumType* pAcType,
1602 sme_QosWmmUpType *pUserPri)
1603{
1604 unsigned char * pPkt;
1605 union generic_ethhdr *pHdr;
1606 struct iphdr *pIpHdr;
1607 unsigned char tos;
1608 unsigned char dscp;
1609 sme_QosWmmUpType userPri;
1610 WLANTL_ACEnumType acType;
1611
1612 // this code is executed for every packet therefore
1613 // all debug code is kept conditional
1614
1615#ifdef HDD_WMM_DEBUG
1616 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001617 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001618#endif // HDD_WMM_DEBUG
1619
1620 pPkt = skb->data;
1621 pHdr = (union generic_ethhdr *)pPkt;
1622
1623#ifdef HDD_WMM_DEBUG
1624 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1625 "%s: proto/length is 0x%04x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001626 __func__, pHdr->eth_II.h_proto);
Jeff Johnson295189b2012-06-20 16:38:30 -07001627#endif // HDD_WMM_DEBUG
1628
1629 if (HDD_WMM_CLASSIFICATION_DSCP == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
1630 {
1631 if (pHdr->eth_II.h_proto == htons(ETH_P_IP))
1632 {
1633 // case 1: Ethernet II IP packet
1634 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_II)];
1635 tos = pIpHdr->tos;
1636#ifdef HDD_WMM_DEBUG
1637 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1638 "%s: Ethernet II IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001639 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001640#endif // HDD_WMM_DEBUG
1641
1642 }
1643 else if ((ntohs(pHdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
1644 (pHdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
1645 (pHdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
1646 (pHdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1647 (pHdr->eth_8023.h_proto == htons(ETH_P_IP)))
1648 {
1649 // case 2: 802.3 LLC/SNAP IP packet
1650 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];
1651 tos = pIpHdr->tos;
1652#ifdef HDD_WMM_DEBUG
1653 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1654 "%s: 802.3 LLC/SNAP IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001655 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001656#endif // HDD_WMM_DEBUG
1657 }
1658 else if (pHdr->eth_II.h_proto == htons(ETH_P_8021Q))
1659 {
1660 // VLAN tagged
1661
1662 if (pHdr->eth_IIv.h_vlan_encapsulated_proto == htons(ETH_P_IP))
1663 {
1664 // case 3: Ethernet II vlan-tagged IP packet
1665 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_IIv)];
1666 tos = pIpHdr->tos;
1667#ifdef HDD_WMM_DEBUG
1668 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1669 "%s: Ethernet II VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001670 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001671#endif // HDD_WMM_DEBUG
1672 }
1673 else if ((ntohs(pHdr->eth_IIv.h_vlan_encapsulated_proto) < WLAN_MIN_PROTO) &&
1674 (pHdr->eth_8023v.h_snap.dsap == WLAN_SNAP_DSAP) &&
1675 (pHdr->eth_8023v.h_snap.ssap == WLAN_SNAP_SSAP) &&
1676 (pHdr->eth_8023v.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1677 (pHdr->eth_8023v.h_proto == htons(ETH_P_IP)))
1678 {
1679 // case 4: 802.3 LLC/SNAP vlan-tagged IP packet
1680 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023v)];
1681 tos = pIpHdr->tos;
1682#ifdef HDD_WMM_DEBUG
1683 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1684 "%s: 802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001685 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001686#endif // HDD_WMM_DEBUG
1687 }
1688 else
1689 {
1690 // default
1691#ifdef HDD_WMM_DEBUG
1692 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1693 "%s: VLAN tagged Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001694 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001695#endif // HDD_WMM_DEBUG
1696 tos = 0;
1697 }
1698 }
1699 else
1700 {
1701 // default
1702#ifdef HDD_WMM_DEBUG
1703 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1704 "%s: Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001705 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001706#endif // HDD_WMM_DEBUG
1707 //Give the highest priority to 802.1x packet
1708 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
1709 tos = 0xC0;
1710 else
1711 tos = 0;
1712 }
1713
1714 dscp = (tos>>2) & 0x3f;
1715 userPri = hddWmmDscpToUpMap[dscp];
1716
1717#ifdef HDD_WMM_DEBUG
1718 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1719 "%s: tos is %d, dscp is %d, up is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001720 __func__, tos, dscp, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07001721#endif // HDD_WMM_DEBUG
1722
1723 }
1724 else if (HDD_WMM_CLASSIFICATION_802_1Q == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
1725 {
1726 if (pHdr->eth_IIv.h_vlan_proto == htons(ETH_P_8021Q))
1727 {
1728 // VLAN tagged
1729 userPri = (ntohs(pHdr->eth_IIv.h_vlan_TCI)>>13) & 0x7;
1730#ifdef HDD_WMM_DEBUG
1731 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1732 "%s: Tagged frame, UP is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001733 __func__, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07001734#endif // HDD_WMM_DEBUG
1735 }
1736 else
1737 {
1738 // not VLAN tagged, use default
1739#ifdef HDD_WMM_DEBUG
1740 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1741 "%s: Untagged frame, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001742 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001743#endif // HDD_WMM_DEBUG
1744 //Give the highest priority to 802.1x packet
1745 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
1746 userPri = SME_QOS_WMM_UP_VO;
1747 else
1748 userPri = SME_QOS_WMM_UP_BE;
1749 }
1750 }
1751 else
1752 {
1753 // default
1754#ifdef HDD_WMM_DEBUG
1755 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1756 "%s: Unknown classification scheme, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001757 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001758#endif // HDD_WMM_DEBUG
1759 userPri = SME_QOS_WMM_UP_BE;
1760 }
1761
1762 acType = hddWmmUpToAcMap[userPri];
1763
1764#ifdef HDD_WMM_DEBUG
1765 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1766 "%s: UP is %d, AC is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001767 __func__, userPri, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001768#endif // HDD_WMM_DEBUG
1769
1770 *pUserPri = userPri;
1771 *pAcType = acType;
1772
1773 return;
1774}
1775
1776/**============================================================================
1777 @brief hdd_hostapd_select_quueue() - Function which will classify the packet
1778 according to linux qdisc expectation.
1779
1780
1781 @param dev : [in] pointer to net_device structure
1782 @param skb : [in] pointer to os packet
1783
1784 @return : Qdisc queue index
1785 ===========================================================================*/
1786v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb)
1787{
1788 WLANTL_ACEnumType ac;
1789 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
1790 v_USHORT_t queueIndex;
1791 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
1792 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
1793 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001794 v_U8_t STAId;
1795 v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
1796
1797 /*Get the Station ID*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001798 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &STAId))
1799 {
Madan Mohan Koyyalamudif1d39952012-10-31 15:18:40 -07001800 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001801 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001802 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1803 goto done;
1804 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001805
1806 spin_lock_bh( &pAdapter->staInfo_lock );
1807 if (FALSE == vos_is_macaddr_equal(&pAdapter->aStaInfo[STAId].macAddrSTA, pDestMacAddress))
1808 {
1809 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001810 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001811
1812 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1813 goto release_lock;
1814 }
1815 if (pAdapter->aStaInfo[STAId].isUsed && pAdapter->aStaInfo[STAId].isQosEnabled && (HDD_WMM_USER_MODE_NO_QOS != pHddCtx->cfg_ini->WmmMode))
1816 {
1817 /* Get the user priority from IP header & corresponding AC */
1818 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
1819 }
1820 *pSTAId = STAId;
1821
1822release_lock:
1823 spin_unlock_bh( &pAdapter->staInfo_lock );
1824done:
1825 skb->priority = up;
1826 queueIndex = hddLinuxUpToAcMap[skb->priority];
1827
1828 return queueIndex;
1829}
1830
1831/**============================================================================
1832 @brief hdd_wmm_select_quueue() - Function which will classify the packet
1833 according to linux qdisc expectation.
1834
1835
1836 @param dev : [in] pointer to net_device structure
1837 @param skb : [in] pointer to os packet
1838
1839 @return : Qdisc queue index
1840 ===========================================================================*/
1841v_U16_t hdd_wmm_select_queue(struct net_device * dev, struct sk_buff *skb)
1842{
1843 WLANTL_ACEnumType ac;
Shailender Karmuchia734f332013-04-19 14:02:48 -07001844 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001845 v_USHORT_t queueIndex;
Jeff Johnson295189b2012-06-20 16:38:30 -07001846 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1847
Shailender Karmuchia734f332013-04-19 14:02:48 -07001848 /*Get the Station ID*/
1849 if (WLAN_HDD_IBSS == pAdapter->device_mode)
1850 {
1851 v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
1852 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
1853
1854 if ( VOS_STATUS_SUCCESS !=
1855 hdd_Ibss_GetStaId(&pAdapter->sessionCtx.station,
1856 pDestMacAddress, pSTAId))
1857 {
1858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnsonb9fb9ce2013-05-03 08:11:02 -07001859 "%s: Failed to find right station pDestMacAddress: "
1860 MAC_ADDRESS_STR , __func__,
1861 MAC_ADDR_ARRAY(pDestMacAddress->bytes));
Shailender Karmuchia734f332013-04-19 14:02:48 -07001862 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1863 goto done;
1864 }
1865 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001866 // if we don't want QoS or the AP doesn't support Qos
1867 // All traffic will get equal opportuniy to transmit data frames.
1868 if( hdd_wmm_is_active(pAdapter) ) {
1869 /* Get the user priority from IP header & corresponding AC */
1870 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
1871 }
Shailender Karmuchia734f332013-04-19 14:02:48 -07001872done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001873 skb->priority = up;
1874 queueIndex = hddLinuxUpToAcMap[skb->priority];
1875
1876 return queueIndex;
1877}
1878
1879/**============================================================================
1880 @brief hdd_wmm_acquire_access() - Function which will attempt to acquire
1881 admittance for a WMM AC
1882
1883 @param pAdapter : [in] pointer to adapter context
1884 @param acType : [in] WMM AC type of OS packet
1885 @param pGranted : [out] pointer to boolean flag when indicates if access
1886 has been granted or not
1887
1888 @return : VOS_STATUS_SUCCESS if succssful
1889 : other values if failure
1890 ===========================================================================*/
1891VOS_STATUS hdd_wmm_acquire_access( hdd_adapter_t* pAdapter,
1892 WLANTL_ACEnumType acType,
1893 v_BOOL_t * pGranted )
1894{
1895 hdd_wmm_qos_context_t *pQosContext;
1896
1897 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001898 "%s: Entered for AC %d", __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001899
1900 if (!hdd_wmm_is_active(pAdapter) || !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
1901 {
1902 // either we don't want QoS or the AP doesn't support QoS
1903 // or we don't want to do implicit QoS
1904 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001905 "%s: QoS not configured on both ends ", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001906
1907 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
1908 *pGranted = VOS_TRUE;
1909 return VOS_STATUS_SUCCESS;
1910 }
1911
1912 // do we already have an implicit QoS request pending for this AC?
1913 if ((pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded) ||
1914 (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessPending))
1915 {
1916 // request already pending so we need to wait for that response
1917 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1918 "%s: Implicit QoS for TL AC %d already scheduled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001919 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001920
1921 *pGranted = VOS_FALSE;
1922 return VOS_STATUS_SUCCESS;
1923 }
1924
1925 // did we already fail to establish implicit QoS for this AC?
1926 // (if so, access should have been granted when the failure was handled)
1927 if (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessFailed)
1928 {
1929 // request previously failed
1930 // allow access, but we'll be downgraded
1931 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1932 "%s: Implicit QoS for TL AC %d previously failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001933 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001934
1935 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
1936 *pGranted = VOS_TRUE;
1937 return VOS_STATUS_SUCCESS;
1938 }
1939
1940 // we need to establish implicit QoS
1941 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1942 "%s: Need to schedule implicit QoS for TL AC %d, pAdapter is %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001943 __func__, acType, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001944
1945 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded = VOS_TRUE;
1946
Mohit Khanna217ea8d2012-09-11 17:42:42 -07001947 pQosContext = kmalloc(sizeof(*pQosContext), GFP_ATOMIC);
Jeff Johnson295189b2012-06-20 16:38:30 -07001948 if (NULL == pQosContext)
1949 {
1950 // no memory for QoS context. Nothing we can do but let data flow
1951 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001952 "%s: Unable to allocate context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001953 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
1954 *pGranted = VOS_TRUE;
1955 return VOS_STATUS_SUCCESS;
1956 }
1957
1958 pQosContext->acType = acType;
1959 pQosContext->pAdapter = pAdapter;
1960 pQosContext->qosFlowId = 0;
1961 pQosContext->handle = HDD_WMM_HANDLE_IMPLICIT;
1962 pQosContext->magic = HDD_WMM_CTX_MAGIC;
1963 INIT_WORK(&pQosContext->wmmAcSetupImplicitQos,
1964 hdd_wmm_do_implicit_qos);
1965
1966 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1967 "%s: Scheduling work for AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001968 __func__, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001969
1970 schedule_work(&pQosContext->wmmAcSetupImplicitQos);
1971
1972 // caller will need to wait until the work takes place and
1973 // TSPEC negotiation completes
1974 *pGranted = VOS_FALSE;
1975 return VOS_STATUS_SUCCESS;
1976}
1977
1978/**============================================================================
1979 @brief hdd_wmm_assoc() - Function which will handle the housekeeping
1980 required by WMM when association takes place
1981
1982 @param pAdapter : [in] pointer to adapter context
1983 @param pRoamInfo: [in] pointer to roam information
1984 @param eBssType : [in] type of BSS
1985
1986 @return : VOS_STATUS_SUCCESS if succssful
1987 : other values if failure
1988 ===========================================================================*/
1989VOS_STATUS hdd_wmm_assoc( hdd_adapter_t* pAdapter,
1990 tCsrRoamInfo *pRoamInfo,
1991 eCsrRoamBssType eBssType )
1992{
1993 tANI_U8 uapsdMask;
1994 VOS_STATUS status;
1995
1996 // when we associate we need to notify TL if it needs to enable
1997 // UAPSD for any access categories
1998
1999 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002000 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002001
2002 if (pRoamInfo->fReassocReq)
2003 {
2004 // when we reassociate we should continue to use whatever
2005 // parameters were previously established. if we are
2006 // reassociating due to a U-APSD change for a particular
2007 // Access Category, then the change will be communicated
2008 // to HDD via the QoS callback associated with the given
2009 // flow, and U-APSD parameters will be updated there
2010
2011 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002012 "%s: Reassoc so no work, Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002013
2014 return VOS_STATUS_SUCCESS;
2015 }
2016
2017 // get the negotiated UAPSD Mask
2018 uapsdMask = pRoamInfo->u.pConnectedProfile->modifyProfileFields.uapsd_mask;
2019
2020 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002021 "%s: U-APSD mask is 0x%02x", __func__, (int) uapsdMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002022
2023 if (uapsdMask & HDD_AC_VO)
2024 {
2025 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2026 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2027 WLANTL_AC_VO,
2028 7,
2029 7,
2030 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv,
2031 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv,
2032 WLANTL_BI_DIR );
2033
2034 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2035 }
2036
2037 if (uapsdMask & HDD_AC_VI)
2038 {
2039 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2040 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2041 WLANTL_AC_VI,
2042 5,
2043 5,
2044 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv,
2045 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv,
2046 WLANTL_BI_DIR );
2047
2048 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2049 }
2050
2051 if (uapsdMask & HDD_AC_BK)
2052 {
2053 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2054 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2055 WLANTL_AC_BK,
2056 2,
2057 2,
2058 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv,
2059 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv,
2060 WLANTL_BI_DIR );
2061
2062 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2063 }
2064
2065 if (uapsdMask & HDD_AC_BE)
2066 {
2067 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2068 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2069 WLANTL_AC_BE,
2070 3,
2071 3,
2072 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv,
2073 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv,
2074 WLANTL_BI_DIR );
2075
2076 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2077 }
2078
2079 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002080 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002081
2082 return VOS_STATUS_SUCCESS;
2083}
2084
2085
2086
2087static const v_U8_t acmMaskBit[WLANTL_MAX_AC] =
2088 {
2089 0x4, /* WLANTL_AC_BK */
2090 0x8, /* WLANTL_AC_BE */
2091 0x2, /* WLANTL_AC_VI */
2092 0x1 /* WLANTL_AC_VO */
2093 };
2094
2095/**============================================================================
2096 @brief hdd_wmm_connect() - Function which will handle the housekeeping
2097 required by WMM when a connection is established
2098
2099 @param pAdapter : [in] pointer to adapter context
2100 @param pRoamInfo: [in] pointer to roam information
2101 @param eBssType : [in] type of BSS
2102
2103 @return : VOS_STATUS_SUCCESS if succssful
2104 : other values if failure
2105 ===========================================================================*/
2106VOS_STATUS hdd_wmm_connect( hdd_adapter_t* pAdapter,
2107 tCsrRoamInfo *pRoamInfo,
2108 eCsrRoamBssType eBssType )
2109{
2110 int ac;
2111 v_BOOL_t qap;
2112 v_BOOL_t qosConnection;
2113 v_U8_t acmMask;
2114
2115 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002116 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002117
2118 if ((eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) &&
2119 pRoamInfo &&
2120 pRoamInfo->u.pConnectedProfile)
2121 {
2122 qap = pRoamInfo->u.pConnectedProfile->qap;
2123 qosConnection = pRoamInfo->u.pConnectedProfile->qosConnection;
2124 acmMask = pRoamInfo->u.pConnectedProfile->acm_mask;
2125 }
2126 else
2127 {
2128 qap = VOS_TRUE;
2129 qosConnection = VOS_TRUE;
2130 acmMask = 0x0;
2131 }
2132
2133 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2134 "%s: qap is %d, qosConnection is %d, acmMask is 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002135 __func__, qap, qosConnection, acmMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002136
2137 pAdapter->hddWmmStatus.wmmQap = qap;
2138 pAdapter->hddWmmStatus.wmmQosConnection = qosConnection;
2139
2140 for (ac = 0; ac < WLANTL_MAX_AC; ac++)
2141 {
2142 if (qap &&
2143 qosConnection &&
2144 (acmMask & acmMaskBit[ac]))
2145 {
2146 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2147 "%s: ac %d on",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002148 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002149
2150 // admission is required
2151 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_TRUE;
2152 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_FALSE;
2153 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessGranted = VOS_FALSE;
2154 }
2155 else
2156 {
2157 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2158 "%s: ac %d off",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002159 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002160 // admission is not required so access is allowed
2161 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_FALSE;
2162 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_TRUE;
2163 }
2164
2165 }
2166
2167 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002168 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002169
2170 return VOS_STATUS_SUCCESS;
2171}
2172
2173/**============================================================================
2174 @brief hdd_wmm_get_uapsd_mask() - Function which will calculate the
2175 initial value of the UAPSD mask based upon the device configuration
2176
2177 @param pAdapter : [in] pointer to adapter context
2178 @param pUapsdMask: [in] pointer to where the UAPSD Mask is to be stored
2179
2180 @return : VOS_STATUS_SUCCESS if succssful
2181 : other values if failure
2182 ===========================================================================*/
2183VOS_STATUS hdd_wmm_get_uapsd_mask( hdd_adapter_t* pAdapter,
2184 tANI_U8 *pUapsdMask )
2185{
2186 tANI_U8 uapsdMask;
2187
2188 if (HDD_WMM_USER_MODE_NO_QOS == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
2189 {
2190 // no QOS then no UAPSD
2191 uapsdMask = 0;
2192 }
2193 else
2194 {
2195 // start with the default mask
2196 uapsdMask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
2197
2198 // disable UAPSD for any ACs with a 0 Service Interval
2199 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv == 0 )
2200 {
2201 uapsdMask &= ~HDD_AC_VO;
2202 }
2203
2204 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv == 0 )
2205 {
2206 uapsdMask &= ~HDD_AC_VI;
2207 }
2208
2209 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv == 0 )
2210 {
2211 uapsdMask &= ~HDD_AC_BK;
2212 }
2213
2214 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv == 0 )
2215 {
2216 uapsdMask &= ~HDD_AC_BE;
2217 }
2218 }
2219
2220 // return calculated mask
2221 *pUapsdMask = uapsdMask;
2222 return VOS_STATUS_SUCCESS;
2223}
2224
2225
2226/**============================================================================
2227 @brief hdd_wmm_is_active() - Function which will determine if WMM is
2228 active on the current connection
2229
2230 @param pAdapter : [in] pointer to adapter context
2231
2232 @return : VOS_TRUE if WMM is enabled
2233 : VOS_FALSE if WMM is not enabled
2234 ===========================================================================*/
2235v_BOOL_t hdd_wmm_is_active( hdd_adapter_t* pAdapter )
2236{
2237 if ((!pAdapter->hddWmmStatus.wmmQosConnection) ||
2238 (!pAdapter->hddWmmStatus.wmmQap))
2239 {
2240 return VOS_FALSE;
2241 }
2242 else
2243 {
2244 return VOS_TRUE;
2245 }
2246}
2247
2248/**============================================================================
2249 @brief hdd_wmm_addts() - Function which will add a traffic spec at the
2250 request of an application
2251
2252 @param pAdapter : [in] pointer to adapter context
2253 @param handle : [in] handle to uniquely identify a TS
2254 @param pTspec : [in] pointer to the traffic spec
2255
2256 @return : HDD_WLAN_WMM_STATUS_*
2257 ===========================================================================*/
2258hdd_wlan_wmm_status_e hdd_wmm_addts( hdd_adapter_t* pAdapter,
2259 v_U32_t handle,
2260 sme_QosWmmTspecInfo* pTspec )
2261{
2262 hdd_wmm_qos_context_t *pQosContext;
2263 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2264#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2265 sme_QosStatusType smeStatus;
2266#endif
2267 v_BOOL_t found = VOS_FALSE;
2268
2269 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002270 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002271
2272 // see if a context already exists with the given handle
2273 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2274 list_for_each_entry(pQosContext,
2275 &pAdapter->hddWmmStatus.wmmContextList,
2276 node)
2277 {
2278 if (pQosContext->handle == handle)
2279 {
2280 found = VOS_TRUE;
2281 break;
2282 }
2283 }
2284 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2285 if (found)
2286 {
2287 // record with that handle already exists
2288 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2289 "%s: Record already exists with handle 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002290 __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002291
2292 /* Application is trying to modify some of the Tspec params. Allow it */
2293 smeStatus = sme_QosModifyReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2294 pTspec,
2295 pQosContext->qosFlowId);
2296
2297 // need to check the return value and act appropriately
2298 switch (smeStatus)
2299 {
2300 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
2301 status = HDD_WLAN_WMM_STATUS_MODIFY_PENDING;
2302 break;
2303 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2304 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
2305 break;
2306 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
2307 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
2308 break;
2309 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
2310 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
2311 break;
2312 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
2313 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2314 break;
2315 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2316 status = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2317 break;
2318 default:
2319 // we didn't get back one of the SME_QOS_STATUS_MODIFY_* status codes
2320 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302321 "%s: unexpected SME Status=%d\n", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002322 VOS_ASSERT(0);
2323 return HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2324 }
2325
2326 // we were successful, save the status
2327 pQosContext->lastStatus = status;
2328 return status;
2329 }
2330
2331 pQosContext = kmalloc(sizeof(*pQosContext), GFP_KERNEL);
2332 if (NULL == pQosContext)
2333 {
2334 // no memory for QoS context. Nothing we can do
2335 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002336 "%s: Unable to allocate QoS context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002337 return HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE;
2338 }
2339
2340 // we assume the tspec has already been validated by the caller
2341
2342 pQosContext->handle = handle;
2343 pQosContext->acType = hddWmmUpToAcMap[pTspec->ts_info.up];
2344 pQosContext->pAdapter = pAdapter;
2345 pQosContext->qosFlowId = 0;
2346 pQosContext->magic = HDD_WMM_CTX_MAGIC;
2347
2348 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2349 "%s: Setting up QoS, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002350 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002351
2352 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2353 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
2354 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2355
2356#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2357 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2358 pAdapter->sessionId,
2359 pTspec,
2360 hdd_wmm_sme_callback,
2361 pQosContext,
2362 pTspec->ts_info.up,
2363 &pQosContext->qosFlowId);
2364
2365 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2366 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002367 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002368
2369 // need to check the return value and act appropriately
2370 switch (smeStatus)
2371 {
2372 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
2373 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2374 break;
2375 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2376 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
2377 break;
2378 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
2379 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
2380 break;
2381 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
2382 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2383 break;
2384 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
2385 hdd_wmm_free_context(pQosContext);
2386 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
2387 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
2388 // we can't tell the difference between when a request fails because
2389 // AP rejected it versus when SME encounterd an internal error
2390 hdd_wmm_free_context(pQosContext);
2391 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2392 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2393 hdd_wmm_free_context(pQosContext);
2394 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2395 default:
2396 // we didn't get back one of the SME_QOS_STATUS_SETUP_* status codes
2397 hdd_wmm_free_context(pQosContext);
2398 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302399 "%s: unexpected SME Status=%d\n", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002400 VOS_ASSERT(0);
2401 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2402 }
2403#endif
2404
2405 // we were successful, save the status
2406 pQosContext->lastStatus = status;
2407
2408 return status;
2409}
2410
2411/**============================================================================
2412 @brief hdd_wmm_delts() - Function which will delete a traffic spec at the
2413 request of an application
2414
2415 @param pAdapter : [in] pointer to adapter context
2416 @param handle : [in] handle to uniquely identify a TS
2417
2418 @return : HDD_WLAN_WMM_STATUS_*
2419 ===========================================================================*/
2420hdd_wlan_wmm_status_e hdd_wmm_delts( hdd_adapter_t* pAdapter,
2421 v_U32_t handle )
2422{
2423 hdd_wmm_qos_context_t *pQosContext;
2424 v_BOOL_t found = VOS_FALSE;
2425 WLANTL_ACEnumType acType = 0;
2426 v_U32_t qosFlowId = 0;
2427 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2428#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2429 sme_QosStatusType smeStatus;
2430#endif
2431
2432 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002433 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002434
2435 // locate the context with the given handle
2436 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2437 list_for_each_entry(pQosContext,
2438 &pAdapter->hddWmmStatus.wmmContextList,
2439 node)
2440 {
2441 if (pQosContext->handle == handle)
2442 {
2443 found = VOS_TRUE;
2444 acType = pQosContext->acType;
2445 qosFlowId = pQosContext->qosFlowId;
2446 break;
2447 }
2448 }
2449 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2450
2451 if (VOS_FALSE == found)
2452 {
2453 // we didn't find the handle
2454 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002455 "%s: handle 0x%x not found", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002456 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2457 }
2458
2459
2460 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2461 "%s: found handle 0x%x, flow %d, AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002462 __func__, handle, qosFlowId, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002463
2464#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2465 smeStatus = sme_QosReleaseReq( WLAN_HDD_GET_HAL_CTX(pAdapter), qosFlowId );
2466
2467 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2468 "%s: SME flow %d released, SME status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002469 __func__, qosFlowId, smeStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07002470
2471 switch(smeStatus)
2472 {
2473 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
2474 // this flow is the only one on that AC, so go ahead and update
2475 // our TSPEC state for the AC
2476 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcTspecValid = VOS_FALSE;
2477
2478 // need to tell TL to stop trigger timer, etc
2479 hdd_wmm_disable_tl_uapsd(pQosContext);
2480
2481#ifdef FEATURE_WLAN_CCX
2482 // disable the inactivity timer
2483 hdd_wmm_disable_inactivity_timer(pQosContext);
2484#endif
2485 // we are done with this context
2486 hdd_wmm_free_context(pQosContext);
2487
2488 // SME must not fire any more callbacks for this flow since the context
2489 // is no longer valid
2490
2491 return HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
2492
2493 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
2494 // do nothing as we will get a response from SME
2495 status = HDD_WLAN_WMM_STATUS_RELEASE_PENDING;
2496 break;
2497
2498 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
2499 // nothing we can do with the existing flow except leave it
2500 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2501 break;
2502
2503 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
2504 // nothing we can do with the existing flow except leave it
2505 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2506
2507 default:
2508 // we didn't get back one of the SME_QOS_STATUS_RELEASE_* status codes
2509 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302510 "%s: unexpected SME Status=%d\n", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002511 VOS_ASSERT(0);
2512 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2513 }
2514
2515#endif
2516 pQosContext->lastStatus = status;
2517 return status;
2518}
2519
2520/**============================================================================
2521 @brief hdd_wmm_checkts() - Function which will return the status of a traffic
2522 spec at the request of an application
2523
2524 @param pAdapter : [in] pointer to adapter context
2525 @param handle : [in] handle to uniquely identify a TS
2526
2527 @return : HDD_WLAN_WMM_STATUS_*
2528 ===========================================================================*/
2529hdd_wlan_wmm_status_e hdd_wmm_checkts( hdd_adapter_t* pAdapter,
2530 v_U32_t handle )
2531{
2532 hdd_wmm_qos_context_t *pQosContext;
2533 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST;
2534
2535 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002536 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002537
2538 // locate the context with the given handle
2539 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2540 list_for_each_entry(pQosContext,
2541 &pAdapter->hddWmmStatus.wmmContextList,
2542 node)
2543 {
2544 if (pQosContext->handle == handle)
2545 {
2546 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2547 "%s: found handle 0x%x, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002548 __func__, handle, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002549
2550 status = pQosContext->lastStatus;
2551 break;
2552 }
2553 }
2554 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2555 return status;
2556}