blob: 6d2141187c715e689d8f9b24dc548c959ce94cc1 [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
103// UAPSD Mask bits
104// (Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored)
105#define HDD_AC_VO 0x1
106#define HDD_AC_VI 0x2
107#define HDD_AC_BK 0x4
108#define HDD_AC_BE 0x8
109
110#define WLAN_HDD_MAX_DSCP 0x3f
111
112static sme_QosWmmUpType hddWmmDscpToUpMap[WLAN_HDD_MAX_DSCP+1];
113
114const v_U8_t hddWmmUpToAcMap[] = {
115 WLANTL_AC_BE,
116 WLANTL_AC_BK,
117 WLANTL_AC_BK,
118 WLANTL_AC_BE,
119 WLANTL_AC_VI,
120 WLANTL_AC_VI,
121 WLANTL_AC_VO,
122 WLANTL_AC_VO
123};
124
125//Linux based UP -> AC Mapping
126const v_U8_t hddLinuxUpToAcMap[8] = {
127 HDD_LINUX_AC_BE,
128 HDD_LINUX_AC_BK,
129 HDD_LINUX_AC_BK,
130 HDD_LINUX_AC_BE,
131 HDD_LINUX_AC_VI,
132 HDD_LINUX_AC_VI,
133 HDD_LINUX_AC_VO,
134 HDD_LINUX_AC_VO
135};
136
137#ifndef WLAN_MDM_CODE_REDUCTION_OPT
138/**
139 @brief hdd_wmm_enable_tl_uapsd() - function which decides whether and
140 how to update UAPSD parameters in TL
141
142 @param pQosContext : [in] the pointer the QoS instance control block
143
144 @return
145 None
146*/
147static void hdd_wmm_enable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
148{
149 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
150 WLANTL_ACEnumType acType = pQosContext->acType;
151 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
152 VOS_STATUS status;
153 v_U32_t service_interval;
154 v_U32_t suspension_interval;
155 sme_QosWmmDirType direction;
156
157
158 // The TSPEC must be valid
159 if (pAc->wmmAcTspecValid == VOS_FALSE)
160 {
161 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
162 "%s: Invoked with invalid TSPEC",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700163 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700164 return;
165 }
166
167 // determine the service interval
168 if (pAc->wmmAcTspecInfo.min_service_interval)
169 {
170 service_interval = pAc->wmmAcTspecInfo.min_service_interval;
171 }
172 else if (pAc->wmmAcTspecInfo.max_service_interval)
173 {
174 service_interval = pAc->wmmAcTspecInfo.max_service_interval;
175 }
176 else
177 {
178 // no service interval is present in the TSPEC
179 // this is OK, there just won't be U-APSD
180 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
181 "%s: No service interval supplied",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700182 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700183 return;
184 }
185
186 // determine the suspension interval & direction
187 suspension_interval = pAc->wmmAcTspecInfo.suspension_interval;
188 direction = pAc->wmmAcTspecInfo.ts_info.direction;
189
190 // if we have previously enabled U-APSD, have any params changed?
191 if ((pAc->wmmAcUapsdInfoValid) &&
192 (pAc->wmmAcUapsdServiceInterval == service_interval) &&
193 (pAc->wmmAcUapsdSuspensionInterval == suspension_interval) &&
194 (pAc->wmmAcUapsdDirection == direction))
195 {
196 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
197 "%s: No change in U-APSD parameters",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700198 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700199 return;
200 }
201
202 // are we in the appropriate power save modes?
203 if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_BEACON_MODE_POWER_SAVE))
204 {
205 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
206 "%s: BMPS is not enabled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700207 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700208 return;
209 }
210
211 if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_UAPSD_MODE_POWER_SAVE))
212 {
213 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
214 "%s: U-APSD is not enabled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700215 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700216 return;
217 }
218
219 // everything is in place to notify TL
220 status = WLANTL_EnableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
221 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
222 acType,
223 pAc->wmmAcTspecInfo.ts_info.tid,
224 pAc->wmmAcTspecInfo.ts_info.up,
225 service_interval,
226 suspension_interval,
227 direction);
228
229 if ( !VOS_IS_STATUS_SUCCESS( status ) )
230 {
231 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
232 "%s: Failed to enable U-APSD for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700233 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700234 return;
235 }
236
237 // stash away the parameters that were used
238 pAc->wmmAcUapsdInfoValid = VOS_TRUE;
239 pAc->wmmAcUapsdServiceInterval = service_interval;
240 pAc->wmmAcUapsdSuspensionInterval = suspension_interval;
241 pAc->wmmAcUapsdDirection = direction;
242
243 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
244 "%s: Enabled UAPSD in TL srv_int=%ld "
245 "susp_int=%ld dir=%d AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700246 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700247 service_interval,
248 suspension_interval,
249 direction,
250 acType);
251
252}
253
254/**
255 @brief hdd_wmm_disable_tl_uapsd() - function which decides whether
256 to disable UAPSD parameters in TL
257
258 @param pQosContext : [in] the pointer the QoS instance control block
259
260 @return
261 None
262*/
263static void hdd_wmm_disable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
264{
265 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
266 WLANTL_ACEnumType acType = pQosContext->acType;
267 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
268 VOS_STATUS status;
269
270
271 // have we previously enabled UAPSD?
272 if (pAc->wmmAcUapsdInfoValid == VOS_TRUE)
273 {
274 status = WLANTL_DisableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
275 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
276 acType);
277
278 if ( !VOS_IS_STATUS_SUCCESS( status ) )
279 {
280 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
281 "%s: Failed to disable U-APSD for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700282 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700283 }
284 else
285 {
286 // TL no longer has valid UAPSD info
287 pAc->wmmAcUapsdInfoValid = VOS_FALSE;
288 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
289 "%s: Disabled UAPSD in TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700290 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700291 acType);
292 }
293 }
294}
295
296#endif
297
298/**
299 @brief hdd_wmm_free_context() - function which frees a QoS context
300
301 @param pQosContext : [in] the pointer the QoS instance control block
302
303 @return
304 None
305*/
306static void hdd_wmm_free_context (hdd_wmm_qos_context_t* pQosContext)
307{
308 hdd_adapter_t* pAdapter;
309
310 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
311 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700312 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700313
314 if (unlikely((NULL == pQosContext) ||
315 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
316 {
317 // must have been freed in another thread
318 return;
319 }
320
321 // get pointer to the adapter context
322 pAdapter = pQosContext->pAdapter;
323
324 // take the wmmLock since we're manipulating the context list
325 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
326
327 // make sure nobody thinks this is a valid context
328 pQosContext->magic = 0;
329
330 // unlink the context
331 list_del(&pQosContext->node);
332
333 // done manipulating the list
334 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
335
336 // reclaim memory
337 kfree(pQosContext);
338
339}
340
341#ifndef WLAN_MDM_CODE_REDUCTION_OPT
342/**
343 @brief hdd_wmm_notify_app() - function which notifies an application
344 changes in state of it flow
345
346 @param pQosContext : [in] the pointer the QoS instance control block
347
348 @return
349 None
350*/
351#define MAX_NOTIFY_LEN 50
352static void hdd_wmm_notify_app (hdd_wmm_qos_context_t* pQosContext)
353{
354 hdd_adapter_t* pAdapter;
355 union iwreq_data wrqu;
356 char buf[MAX_NOTIFY_LEN+1];
357
358 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
359 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700360 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700361
362 if (unlikely((NULL == pQosContext) ||
363 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
364 {
365 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
366 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700367 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700368 return;
369 }
370
371
372 // create the event
373 memset(&wrqu, 0, sizeof(wrqu));
374 memset(buf, 0, sizeof(buf));
375
376 snprintf(buf, MAX_NOTIFY_LEN, "QCOM: TS change[%u: %u]",
377 (unsigned int)pQosContext->handle,
378 (unsigned int)pQosContext->lastStatus);
379
380 wrqu.data.pointer = buf;
381 wrqu.data.length = strlen(buf);
382
383 // get pointer to the adapter
384 pAdapter = pQosContext->pAdapter;
385
386 // send the event
387 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700388 "%s: Sending [%s]", __func__, buf);
Jeff Johnson295189b2012-06-20 16:38:30 -0700389 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
390}
391
392
393/**
394 @brief hdd_wmm_is_access_allowed() - function which determines if access
395 is allowed for the given AC. this is designed to be called during SME
396 callback processing since that is when access can be granted or removed
397
398 @param pAdapter : [in] pointer to adapter context
399 @param pAc : [in] pointer to the per-AC status
400
401 @return : VOS_TRUE - access is allowed
402 : VOS_FALSE - access is not allowed
403 None
404*/
405static v_BOOL_t hdd_wmm_is_access_allowed(hdd_adapter_t* pAdapter,
406 hdd_wmm_ac_status_t* pAc)
407{
408 // if we don't want QoS or the AP doesn't support QoS
409 // or we don't want to do implicit QoS
410 // or if AP doesn't require admission for this AC
411 // then we have access
412 if (!hdd_wmm_is_active(pAdapter) ||
413 !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled ||
414 !pAc->wmmAcAccessRequired)
415 {
416 return VOS_TRUE;
417 }
418
419 // if implicit QoS has already completed, successfully or not,
420 // then access is allowed
421 if (pAc->wmmAcAccessGranted || pAc->wmmAcAccessFailed)
422 {
423 return VOS_TRUE;
424 }
425
426 // admission is required and implicit QoS hasn't completed
427 // however explicit QoS may have completed and we'll have
428 // a Tspec
429 // if we don't have a Tspec then access is not allowed
430 if (!pAc->wmmAcTspecValid)
431 {
432 return VOS_FALSE;
433 }
434
435 // we have a Tspec -- does it allow upstream or bidirectional traffic?
436 // if it only allows downstream traffic then access is not allowed
437 if (pAc->wmmAcTspecInfo.ts_info.direction == SME_QOS_WMM_TS_DIR_DOWNLINK)
438 {
439 return VOS_FALSE;
440 }
441
442 // we meet all of the criteria for access
443 return VOS_TRUE;
444}
445
446#ifdef FEATURE_WLAN_CCX
447/**
448 @brief hdd_wmm_inactivity_timer_cb() - timer handler function which is
449 called for every inactivity interval per AC. This function gets the
450 current transmitted packets on the given AC, and checks if there where
451 any TX activity from the previous interval. If there was no traffic
452 then it would delete the TS that was negotiated on that AC.
453
454 @param pUserData : [in] pointer to pQosContext
455
456 @return : NONE
457*/
458void hdd_wmm_inactivity_timer_cb( v_PVOID_t pUserData )
459{
460 hdd_wmm_qos_context_t* pQosContext = (hdd_wmm_qos_context_t*)pUserData;
461 hdd_adapter_t* pAdapter;
462 hdd_wmm_ac_status_t *pAc;
463 hdd_wlan_wmm_status_e status;
464 VOS_STATUS vos_status;
465 v_U32_t currentTrafficCnt = 0;
466 WLANTL_ACEnumType acType = pQosContext->acType;
467
468 pAdapter = pQosContext->pAdapter;
469 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
470
471 // Get the Tx stats for this AC.
472 currentTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];
473
474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
475 FL("WMM inactivity Timer for AC=%d, currentCnt=%d, prevCnt=%d\n"),
476 acType, (int)currentTrafficCnt, (int)pAc->wmmPrevTrafficCnt);
477 if (pAc->wmmPrevTrafficCnt == currentTrafficCnt)
478 {
479 // If there is no traffic activity, delete the TSPEC for this AC
480 status = hdd_wmm_delts(pAdapter, pQosContext->handle);
481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
482 FL("Deleted TS on AC %d, due to inactivity with status = %d!!!"),
483 acType, status);
484 }
485 else
486 {
487 pAc->wmmPrevTrafficCnt = currentTrafficCnt;
488 if (pAc->wmmInactivityTimer.state == VOS_TIMER_STATE_STOPPED)
489 {
490 // Restart the timer
491 vos_status = vos_timer_start(&pAc->wmmInactivityTimer, pAc->wmmInactivityTime);
492 if (!VOS_IS_STATUS_SUCCESS(vos_status))
493 {
494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
495 FL("Restarting inactivity timer failed on AC %d"), acType);
496 }
497 }
498 else
499 {
500 VOS_ASSERT(vos_timer_getCurrentState(
501 &pAc->wmmInactivityTimer) == VOS_TIMER_STATE_STOPPED);
502 }
503 }
504
505 return;
506}
507
508
509/**
510 @brief hdd_wmm_enable_inactivity_timer() - function to enable the
511 traffic inactivity timer for the given AC, if the inactivity_interval
512 specified in the ADDTS parameters is non-zero
513
514 @param pQosContext : [in] pointer to pQosContext
515 @param inactivityTime: [in] value of the inactivity interval in millisecs
516
517 @return : VOS_STATUS_E_FAILURE
518 VOS_STATUS_SUCCESS
519*/
520VOS_STATUS hdd_wmm_enable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext, v_U32_t inactivityTime)
521{
522 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
523 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
524 WLANTL_ACEnumType acType = pQosContext->acType;
525 hdd_wmm_ac_status_t *pAc;
526
527 pAdapter = pQosContext->pAdapter;
528 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
529
530
531 // If QoS-Tspec is successfully setup and if the inactivity timer is non-zero,
532 // a traffic inactivity timer needs to be started for the given AC
533 vos_status = vos_timer_init(
534 &pAc->wmmInactivityTimer,
535 VOS_TIMER_TYPE_SW,
536 hdd_wmm_inactivity_timer_cb,
537 (v_PVOID_t)pQosContext );
538 if ( !VOS_IS_STATUS_SUCCESS(vos_status))
539 {
540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
541 FL("Initializing inactivity timer failed on AC %d"), acType);
542 return vos_status;
543 }
544
545 // Start the inactivity timer
546 vos_status = vos_timer_start(
547 &pAc->wmmInactivityTimer,
548 inactivityTime);
549 if ( !VOS_IS_STATUS_SUCCESS(vos_status))
550 {
551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
552 FL("Starting inactivity timer failed on AC %d"), acType);
553 return vos_status;
554 }
555 pAc->wmmInactivityTime = inactivityTime;
556 // Initialize the current tx traffic count on this AC
557 pAc->wmmPrevTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];
558
559 return vos_status;
560}
561
562/**
563 @brief hdd_wmm_enable_inactivity_timer() - function to disable the
564 traffic inactivity timer for the given AC. This would be called when
565 deleting the TS.
566
567 @param pQosContext : [in] pointer to pQosContext
568
569 @return : VOS_STATUS_E_FAILURE
570 VOS_STATUS_SUCCESS
571*/
572VOS_STATUS hdd_wmm_disable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext)
573{
574 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
575 WLANTL_ACEnumType acType = pQosContext->acType;
576 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
577 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
578
579 // Clear the timer and the counter
580 pAc->wmmInactivityTime = 0;
581 pAc->wmmPrevTrafficCnt = 0;
582 vos_timer_stop(&pAc->wmmInactivityTimer);
583 vos_status = vos_timer_destroy(&pAc->wmmInactivityTimer);
584
585 return vos_status;
586}
587#endif // FEATURE_WLAN_CCX
588
589/**
590 @brief hdd_wmm_sme_callback() - callback registered by HDD with SME for receiving
591 QoS notifications. Even though this function has a static scope it gets called
592 externally through some function pointer magic (so there is a need for
593 rigorous parameter checking)
594
595 @param hHal : [in] the HAL handle
596 @param HddCtx : [in] the HDD specified handle
597 @param pCurrentQosInfo : [in] the TSPEC params
598 @param SmeStatus : [in] the QoS related SME status
599
600 @return
601 eHAL_STATUS_SUCCESS if all good, eHAL_STATUS_FAILURE otherwise
602*/
603static eHalStatus hdd_wmm_sme_callback (tHalHandle hHal,
604 void * hddCtx,
605 sme_QosWmmTspecInfo* pCurrentQosInfo,
606 sme_QosStatusType smeStatus,
607 v_U32_t qosFlowId)
608{
609 hdd_wmm_qos_context_t* pQosContext = hddCtx;
610 hdd_adapter_t* pAdapter;
611 WLANTL_ACEnumType acType;
612 hdd_wmm_ac_status_t *pAc;
613 VOS_STATUS status;
614
615 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
616 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700617 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700618
619 if (unlikely((NULL == pQosContext) ||
620 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
621 {
622 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
623 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700624 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700625 return eHAL_STATUS_FAILURE;
626 }
627
628 pAdapter = pQosContext->pAdapter;
629 acType = pQosContext->acType;
630 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
631
632 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
633 "%s: status %d flowid %d info %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700634 __func__, smeStatus, qosFlowId, pCurrentQosInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -0700635
636 switch (smeStatus)
637 {
638
639 case SME_QOS_STATUS_SETUP_SUCCESS_IND:
640 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
641 "%s: Setup is complete",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700642 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700643
644 // there will always be a TSPEC returned with this status, even if
645 // a TSPEC is not exchanged OTA
646 if (pCurrentQosInfo)
647 {
648 pAc->wmmAcTspecValid = VOS_TRUE;
649 memcpy(&pAc->wmmAcTspecInfo,
650 pCurrentQosInfo,
651 sizeof(pAc->wmmAcTspecInfo));
652 }
653
654 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
655 {
656
657 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
658 "%s: Implicit Qos, notifying TL for TL AC %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700659 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700660
661 // this was triggered by implicit QoS so we know packets are pending
662 // update state
663 pAc->wmmAcAccessAllowed = VOS_TRUE;
664 pAc->wmmAcAccessGranted = VOS_TRUE;
665 pAc->wmmAcAccessPending = VOS_FALSE;
666
667 // notify TL that packets are pending
668 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
669 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
670 acType );
671
672 if ( !VOS_IS_STATUS_SUCCESS( status ) )
673 {
674 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
675 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700676 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700677 }
678 }
679 else
680 {
681 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
682 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700683 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700684
685 // this was triggered by an application
686 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
687 hdd_wmm_notify_app(pQosContext);
688 }
689
690#ifdef FEATURE_WLAN_CCX
691 // Check if the inactivity interval is specified
Jeff Johnson8795e422013-04-03 08:59:22 -0700692 if (pCurrentQosInfo && pCurrentQosInfo->inactivity_interval) {
Jeff Johnson295189b2012-06-20 16:38:30 -0700693 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
694 "%s: Inactivity timer value = %d for AC=%d\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700695 __func__, pCurrentQosInfo->inactivity_interval, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700696 hdd_wmm_enable_inactivity_timer(pQosContext, pCurrentQosInfo->inactivity_interval);
697 }
698#endif // FEATURE_WLAN_CCX
699
700 // notify TL to enable trigger frames if necessary
701 hdd_wmm_enable_tl_uapsd(pQosContext);
702
703 break;
704
705 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
706 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
707 "%s: Setup is complete (U-APSD set previously)",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700708 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700709
710 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
711 {
712
713 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
714 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700715 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700716
717 // this was triggered by implicit QoS so we know packets are pending
718 // update state
719 pAc->wmmAcAccessAllowed = VOS_TRUE;
720 pAc->wmmAcAccessGranted = VOS_TRUE;
721 pAc->wmmAcAccessPending = VOS_FALSE;
722
723 // notify TL that packets are pending
724 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
725 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
726 acType );
727
728 if ( !VOS_IS_STATUS_SUCCESS( status ) )
729 {
730 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
731 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700732 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700733 }
734 }
735 else
736 {
737 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
738 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700739 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700740
741 // this was triggered by an application
742 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
743 hdd_wmm_notify_app(pQosContext);
744 }
745
746 break;
747
748 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
749 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
750 "%s: Setup failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700751 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700752 // QoS setup failed
753
754 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
755 {
756
757 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
758 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700759 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700760
761 // we note the failure, but we also mark access as allowed so that
762 // the packets will flow. Note that the MAC will "do the right thing"
763 pAc->wmmAcAccessPending = VOS_FALSE;
764 pAc->wmmAcAccessFailed = VOS_TRUE;
765 pAc->wmmAcAccessAllowed = VOS_TRUE;
766
767 // this was triggered by implicit QoS so we know packets are pending
768 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
769 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
770 acType );
771
772 if ( !VOS_IS_STATUS_SUCCESS( status ) )
773 {
774 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
775 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700776 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700777 }
778 }
779 else
780 {
781 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
782 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700783 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700784
785 // this was triggered by an application
786 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED;
787 hdd_wmm_notify_app(pQosContext);
788 }
789
790 /* Setting up QoS Failed, QoS context can be released.
791 * SME is releasing this flow information and if HDD doen't release this context,
792 * next time if application uses the same handle to set-up QoS, HDD (as it has
793 * QoS context for this handle) will issue Modify QoS request to SME but SME will
794 * reject as no it has no information for this flow.
795 */
796 hdd_wmm_free_context(pQosContext);
797 break;
798
799 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
800 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
801 "%s: Setup Invalid Params, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700802 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700803 // QoS setup failed
804
805 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
806 {
807
808 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
809 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700810 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700811
812 // we note the failure, but we also mark access as allowed so that
813 // the packets will flow. Note that the MAC will "do the right thing"
814 pAc->wmmAcAccessPending = VOS_FALSE;
815 pAc->wmmAcAccessFailed = VOS_TRUE;
816 pAc->wmmAcAccessAllowed = VOS_TRUE;
817
818 // this was triggered by implicit QoS so we know packets are pending
819 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
820 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
821 acType );
822
823 if ( !VOS_IS_STATUS_SUCCESS( status ) )
824 {
825 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
826 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700827 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700828 }
829 }
830 else
831 {
832 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
833 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700834 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700835
836 // this was triggered by an application
837 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
838 hdd_wmm_notify_app(pQosContext);
839 }
840 break;
841
842 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
843 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
844 "%s: Setup failed, not a QoS AP\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700845 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700846 if (!HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
847 {
848 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
849 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700850 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700851
852 // this was triggered by an application
853 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
854 hdd_wmm_notify_app(pQosContext);
855 }
856 break;
857
858 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
859 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
860 "%s: Setup pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700861 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700862 // not a callback status -- ignore if we get it
863 break;
864
865 case SME_QOS_STATUS_SETUP_MODIFIED_IND:
866 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
867 "%s: Setup modified",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700868 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700869 if (pCurrentQosInfo)
870 {
871 // update the TSPEC
872 pAc->wmmAcTspecValid = VOS_TRUE;
873 memcpy(&pAc->wmmAcTspecInfo,
874 pCurrentQosInfo,
875 sizeof(pAc->wmmAcTspecInfo));
876
877 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
878 {
879 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
880 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700881 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700882
883 // this was triggered by an application
884 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFIED;
885 hdd_wmm_notify_app(pQosContext);
886 }
887
888 // need to tell TL to update its UAPSD handling
889 hdd_wmm_enable_tl_uapsd(pQosContext);
890 }
891 break;
892
893 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
894 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
895 {
896
897 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
898 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700899 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700900
901 // this was triggered by implicit QoS so we know packets are pending
902 pAc->wmmAcAccessPending = VOS_FALSE;
903 pAc->wmmAcAccessGranted = VOS_TRUE;
904 pAc->wmmAcAccessAllowed = VOS_TRUE;
905
906 // notify TL that packets are pending
907 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
908 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
909 acType );
910
911 if ( !VOS_IS_STATUS_SUCCESS( status ) )
912 {
913 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
914 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700915 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700916 }
917 }
918 else
919 {
920 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
921 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700922 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700923
924 // this was triggered by an application
925 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
926 hdd_wmm_notify_app(pQosContext);
927 }
928 break;
929
930 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
931 // nothing to do for now
932 break;
933
934 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED:
935 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
936 "%s: Setup successful but U-APSD failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700937 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700938
939 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
940 {
941
942 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
943 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700944 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700945
946 // QoS setup was successful but setting U=APSD failed
947 // Since the OTA part of the request was successful, we don't mark
948 // this as a failure.
949 // the packets will flow. Note that the MAC will "do the right thing"
950 pAc->wmmAcAccessGranted = VOS_TRUE;
951 pAc->wmmAcAccessAllowed = VOS_TRUE;
952 pAc->wmmAcAccessFailed = VOS_FALSE;
953 pAc->wmmAcAccessPending = VOS_FALSE;
954
955 // this was triggered by implicit QoS so we know packets are pending
956 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
957 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
958 acType );
959
960 if ( !VOS_IS_STATUS_SUCCESS( status ) )
961 {
962 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
963 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700964 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700965 }
966 }
967 else
968 {
969 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
970 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700971 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700972
973 // this was triggered by an application
974 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_UAPSD_SET_FAILED;
975 hdd_wmm_notify_app(pQosContext);
976 }
977
978 // Since U-APSD portion failed disabled trigger frame generation
979 hdd_wmm_disable_tl_uapsd(pQosContext);
980
981 break;
982
983 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
984 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
985 "%s: Release is complete",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700986 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700987
988 if (pCurrentQosInfo)
989 {
990 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
991 "%s: flows still active",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700992 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700993
994 // there is still at least one flow active for this AC
995 // so update the AC state
996 memcpy(&pAc->wmmAcTspecInfo,
997 pCurrentQosInfo,
998 sizeof(pAc->wmmAcTspecInfo));
999
1000 // need to tell TL to update its UAPSD handling
1001 hdd_wmm_enable_tl_uapsd(pQosContext);
1002 }
1003 else
1004 {
1005 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1006 "%s: last flow",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001007 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001008
1009 // this is the last flow active for this AC so update the AC state
1010 pAc->wmmAcTspecValid = VOS_FALSE;
1011
1012 // need to tell TL to update its UAPSD handling
1013 hdd_wmm_disable_tl_uapsd(pQosContext);
1014 }
1015
1016 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1017 {
1018 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1019 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001020 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001021
1022 // this was triggered by an application
1023 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
1024 hdd_wmm_notify_app(pQosContext);
1025 }
1026
1027 // we are done with this flow
1028 hdd_wmm_free_context(pQosContext);
1029 break;
1030
1031 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
1032 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1033 "%s: Release failure",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001034 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001035
1036 // we don't need to update our state or TL since nothing has changed
1037 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1038 {
1039 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1040 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001041 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001042
1043 // this was triggered by an application
1044 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
1045 hdd_wmm_notify_app(pQosContext);
1046 }
1047
1048 break;
1049
1050 case SME_QOS_STATUS_RELEASE_QOS_LOST_IND:
1051 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1052 "%s: QOS Lost indication received",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001053 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001054
1055 // current TSPEC is no longer valid
1056 pAc->wmmAcTspecValid = VOS_FALSE;
1057
1058 // need to tell TL to update its UAPSD handling
1059 hdd_wmm_disable_tl_uapsd(pQosContext);
1060
1061 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
1062 {
1063 // we no longer have implicit access granted
1064 pAc->wmmAcAccessGranted = VOS_FALSE;
1065 pAc->wmmAcAccessFailed = VOS_FALSE;
1066 }
1067 else
1068 {
1069 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1070 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001071 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001072
1073 // this was triggered by an application
1074 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_LOST;
1075 hdd_wmm_notify_app(pQosContext);
1076 }
1077
1078 // we are done with this flow
1079 hdd_wmm_free_context(pQosContext);
1080 break;
1081
1082 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
1083 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1084 "%s: Release pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001085 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001086 // not a callback status -- ignore if we get it
1087 break;
1088
1089 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
1090 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1091 "%s: Release Invalid Params",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001092 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001093 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1094 {
1095 // this was triggered by an application
1096 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
1097 hdd_wmm_notify_app(pQosContext);
1098 }
1099 break;
1100
1101 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND:
1102 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1103 "%s: Modification is complete, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001104 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001105
1106 // there will always be a TSPEC returned with this status, even if
1107 // a TSPEC is not exchanged OTA
1108 if (pCurrentQosInfo)
1109 {
1110 pAc->wmmAcTspecValid = VOS_TRUE;
1111 memcpy(&pAc->wmmAcTspecInfo,
1112 pCurrentQosInfo,
1113 sizeof(pAc->wmmAcTspecInfo));
1114 }
1115
1116 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1117 {
1118 // this was triggered by an application
1119 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS;
1120 hdd_wmm_notify_app(pQosContext);
1121 }
1122
1123 // notify TL to enable trigger frames if necessary
1124 hdd_wmm_enable_tl_uapsd(pQosContext);
1125
1126 break;
1127
1128 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
1129 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1130 {
1131 // this was triggered by an application
1132 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
1133 hdd_wmm_notify_app(pQosContext);
1134 }
1135 break;
1136
1137 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
1138 // the flow modification failed so we'll leave in place
1139 // whatever existed beforehand
1140
1141 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1142 {
1143 // this was triggered by an application
1144 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
1145 hdd_wmm_notify_app(pQosContext);
1146 }
1147 break;
1148
1149 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
1150 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1151 "%s: modification pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001152 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001153 // not a callback status -- ignore if we get it
1154 break;
1155
1156 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1157 // the flow modification was successful but no QoS changes required
1158
1159 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1160 {
1161 // this was triggered by an application
1162 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
1163 hdd_wmm_notify_app(pQosContext);
1164 }
1165 break;
1166
1167 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
1168 // invalid params -- notify the application
1169 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1170 {
1171 // this was triggered by an application
1172 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
1173 hdd_wmm_notify_app(pQosContext);
1174 }
1175 break;
1176
1177 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_PENDING:
1178 // nothing to do for now. when APSD is established we'll have work to do
1179 break;
1180
1181 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED:
1182 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1183 "%s: Modify successful but U-APSD failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001184 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001185
1186 // QoS modification was successful but setting U=APSD failed.
1187 // This will always be an explicit QoS instance, so all we can
1188 // do is notify the application and let it clean up.
1189 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1190 {
1191 // this was triggered by an application
1192 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_UAPSD_SET_FAILED;
1193 hdd_wmm_notify_app(pQosContext);
1194 }
1195
1196 // Since U-APSD portion failed disabled trigger frame generation
1197 hdd_wmm_disable_tl_uapsd(pQosContext);
1198
1199 break;
1200
1201 case SME_QOS_STATUS_HANDING_OFF:
1202 // no roaming so we won't see this
1203 break;
1204
1205 case SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND:
1206 // need to tell TL to stop trigger frame generation
1207 hdd_wmm_disable_tl_uapsd(pQosContext);
1208 break;
1209
1210 case SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND:
1211 // need to tell TL to start sending trigger frames again
1212 hdd_wmm_enable_tl_uapsd(pQosContext);
1213 break;
1214
1215 default:
1216 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1217 "%s: unexpected SME Status=%d\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001218 __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07001219 VOS_ASSERT(0);
1220 }
1221
1222 // our access to the particular access category may have changed.
1223 // some of the implicit QoS cases above may have already set this
1224 // prior to invoking TL (so that we will properly service the
1225 // Tx queues) but let's consistently handle all cases here
1226 pAc->wmmAcAccessAllowed = hdd_wmm_is_access_allowed(pAdapter, pAc);
1227
1228 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1229 "%s: complete, access for TL AC %d is%sallowed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001230 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001231 acType,
1232 pAc->wmmAcAccessAllowed ? " " : " not ");
1233
1234 return eHAL_STATUS_SUCCESS;
1235}
1236#endif
1237
1238/**============================================================================
1239 @brief hdd_wmm_do_implicit_qos() - Function which will attempt to setup
1240 QoS for any AC requiring it
1241
1242 @param work : [in] pointer to work structure
1243
1244 @return : void
1245 ===========================================================================*/
1246static void hdd_wmm_do_implicit_qos(struct work_struct *work)
1247{
1248 hdd_wmm_qos_context_t* pQosContext =
1249 container_of(work, hdd_wmm_qos_context_t, wmmAcSetupImplicitQos);
1250 hdd_adapter_t* pAdapter;
1251 WLANTL_ACEnumType acType;
1252 hdd_wmm_ac_status_t *pAc;
1253#ifndef WLAN_MDM_CODE_REDUCTION_OPT
1254 VOS_STATUS status;
1255 sme_QosStatusType smeStatus;
1256#endif
1257 sme_QosWmmTspecInfo qosInfo;
1258
1259 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1260 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001261 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001262
1263 if (unlikely(HDD_WMM_CTX_MAGIC != pQosContext->magic))
1264 {
1265 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1266 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001267 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001268 return;
1269 }
1270
1271 pAdapter = pQosContext->pAdapter;
1272 acType = pQosContext->acType;
1273 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1274
1275 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1276 "%s: pAdapter %p acType %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001277 __func__, pAdapter, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001278
1279 if (!pAc->wmmAcAccessNeeded)
1280 {
1281 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1282 "%s: AC %d doesn't need service",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001283 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001284 pQosContext->magic = 0;
1285 kfree(pQosContext);
1286 return;
1287 }
1288
1289 pAc->wmmAcAccessPending = VOS_TRUE;
1290 pAc->wmmAcAccessNeeded = VOS_FALSE;
1291
1292 memset(&qosInfo, 0, sizeof(qosInfo));
1293
1294 switch (acType)
1295 {
1296 case WLANTL_AC_VO:
1297 qosInfo.ts_info.up = SME_QOS_WMM_UP_VO;
1298 qosInfo.ts_info.psb = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask & 0x01;
1299 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVo;
1300 qosInfo.ts_info.tid = 255;
1301 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVo;
1302 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVo;
1303 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv;
1304 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVo;
1305 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVo;
1306 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv;
1307 break;
1308 case WLANTL_AC_VI:
1309 qosInfo.ts_info.up = SME_QOS_WMM_UP_VI;
1310 qosInfo.ts_info.psb = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask & 0x02;
1311 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVi;
1312 qosInfo.ts_info.tid = 255;
1313 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVi;
1314 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVi;
1315 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv;
1316 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVi;
1317 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVi;
1318 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv;
1319 break;
1320 default:
1321 case WLANTL_AC_BE:
1322 qosInfo.ts_info.up = SME_QOS_WMM_UP_BE;
1323 qosInfo.ts_info.psb = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask & 0x08;
1324 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;
1335 qosInfo.ts_info.psb = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask & 0x04;
1336 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBk;
1337 qosInfo.ts_info.tid = 255;
1338 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBk;
1339 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBk;
1340 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv;
1341 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBk;
1342 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBk;
1343 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv;
1344 break;
1345 }
1346#ifdef FEATURE_WLAN_CCX
1347 qosInfo.inactivity_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraInactivityInterval;
1348#endif
1349 qosInfo.ts_info.burst_size_defn = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->burstSizeDefinition;
1350
1351 switch ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->tsInfoAckPolicy)
1352 {
1353 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK:
1354 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1355 break;
1356
1357 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
1358 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
1359 break;
1360
1361 default:
1362 // unknown
1363 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1364 }
1365
1366 if(qosInfo.ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK)
1367 {
1368 if(!sme_QosIsTSInfoAckPolicyValid((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter), &qosInfo, pAdapter->sessionId))
1369 {
1370 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1371 }
1372 }
1373
1374 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
1375 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
1376 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
1377
1378#ifndef WLAN_MDM_CODE_REDUCTION_OPT
1379 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
1380 pAdapter->sessionId,
1381 &qosInfo,
1382 hdd_wmm_sme_callback,
1383 pQosContext,
1384 qosInfo.ts_info.up,
1385 &pQosContext->qosFlowId);
1386
1387 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1388 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001389 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001390
1391 // need to check the return values and act appropriately
1392 switch (smeStatus)
1393 {
1394 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
1395 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
1396 // setup is pending, so no more work to do now.
1397 // all further work will be done in hdd_wmm_sme_callback()
1398 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1399 "%s: Setup is pending, no further work",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001400 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001401
1402 break;
1403
1404
1405 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
1406 // we can't tell the difference between when a request fails because
1407 // AP rejected it versus when SME encountered an internal error
1408
1409 // in either case SME won't ever reference this context so
1410 // free the record
1411 hdd_wmm_free_context(pQosContext);
1412
1413 // fall through and start packets flowing
1414 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1415 // no ACM in effect, no need to setup U-APSD
1416 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
1417 // no ACM in effect, U-APSD is desired but was already setup
1418
1419 // for these cases everything is already setup so we can
1420 // signal TL that it has work to do
1421 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1422 "%s: Setup is complete, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001423 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001424
1425 pAc->wmmAcAccessAllowed = VOS_TRUE;
1426 pAc->wmmAcAccessGranted = VOS_TRUE;
1427 pAc->wmmAcAccessPending = VOS_FALSE;
1428
1429 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1430 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
1431 acType );
1432
1433 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1434 {
1435 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1436 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001437 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -07001438 }
1439
1440 break;
1441
1442
1443 default:
1444 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1445 "%s: unexpected SME Status=%d\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001446 __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07001447 VOS_ASSERT(0);
1448 }
1449#endif
1450
1451}
1452
1453/**============================================================================
1454 @brief hdd_wmm_init() - Function which will initialize the WMM configuation
1455 and status to an initial state. The configuration can later be overwritten
1456 via application APIs
1457
1458 @param pHddCtx : [in] pointer to HDD context
1459
1460 @return : VOS_STATUS_SUCCESS if succssful
1461 : other values if failure
1462
1463 ===========================================================================*/
1464VOS_STATUS hdd_wmm_init ( hdd_context_t* pHddCtx )
1465{
1466 v_U8_t dscp;
1467
1468 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001469 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001470
1471 // DSCP to User Priority Lookup Table
1472 for (dscp = 0; dscp <= WLAN_HDD_MAX_DSCP; dscp++)
1473 {
1474 hddWmmDscpToUpMap[dscp] = SME_QOS_WMM_UP_BE;
1475 }
1476 hddWmmDscpToUpMap[8] = SME_QOS_WMM_UP_BK;
1477 hddWmmDscpToUpMap[16] = SME_QOS_WMM_UP_RESV;
1478 hddWmmDscpToUpMap[24] = SME_QOS_WMM_UP_EE;
1479 hddWmmDscpToUpMap[32] = SME_QOS_WMM_UP_CL;
1480 hddWmmDscpToUpMap[40] = SME_QOS_WMM_UP_VI;
1481 hddWmmDscpToUpMap[48] = SME_QOS_WMM_UP_VO;
1482 hddWmmDscpToUpMap[56] = SME_QOS_WMM_UP_NC;
1483
1484 return VOS_STATUS_SUCCESS;
1485}
1486
1487/**============================================================================
1488 @brief hdd_wmm_adapter_init() - Function which will initialize the WMM configuation
1489 and status to an initial state. The configuration can later be overwritten
1490 via application APIs
1491
1492 @param pAdapter : [in] pointer to Adapter context
1493
1494 @return : VOS_STATUS_SUCCESS if succssful
1495 : other values if failure
1496
1497 ===========================================================================*/
1498VOS_STATUS hdd_wmm_adapter_init( hdd_adapter_t *pAdapter )
1499{
1500 hdd_wmm_ac_status_t *pAcStatus;
1501 WLANTL_ACEnumType acType;
1502
1503 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001504 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001505
1506 pAdapter->hddWmmStatus.wmmQap = VOS_FALSE;
1507 INIT_LIST_HEAD(&pAdapter->hddWmmStatus.wmmContextList);
1508 mutex_init(&pAdapter->hddWmmStatus.wmmLock);
1509
1510 for (acType = 0; acType < WLANTL_MAX_AC; acType++)
1511 {
1512 pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1513 pAcStatus->wmmAcAccessRequired = VOS_FALSE;
1514 pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
1515 pAcStatus->wmmAcAccessPending = VOS_FALSE;
1516 pAcStatus->wmmAcAccessFailed = VOS_FALSE;
1517 pAcStatus->wmmAcAccessGranted = VOS_FALSE;
1518 pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
1519 pAcStatus->wmmAcTspecValid = VOS_FALSE;
1520 pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
1521 }
1522
1523 return VOS_STATUS_SUCCESS;
1524}
1525/**============================================================================
1526 @brief hdd_wmm_close() - Function which will perform any necessary work to
1527 to clean up the WMM functionality prior to the kernel module unload
1528
1529 @param pAdapter : [in] pointer to adapter context
1530
1531 @return : VOS_STATUS_SUCCESS if succssful
1532 : other values if failure
1533
1534 ===========================================================================*/
1535VOS_STATUS hdd_wmm_adapter_close ( hdd_adapter_t* pAdapter )
1536{
1537 hdd_wmm_qos_context_t* pQosContext;
1538
1539 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001540 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001541
1542 // free any context records that we still have linked
1543 while (!list_empty(&pAdapter->hddWmmStatus.wmmContextList))
1544 {
1545 pQosContext = list_first_entry(&pAdapter->hddWmmStatus.wmmContextList,
1546 hdd_wmm_qos_context_t, node);
1547#ifdef FEATURE_WLAN_CCX
1548 hdd_wmm_disable_inactivity_timer(pQosContext);
1549#endif
1550 hdd_wmm_free_context(pQosContext);
1551 }
1552
1553 return VOS_STATUS_SUCCESS;
1554}
1555
1556/**============================================================================
1557 @brief hdd_wmm_classify_pkt() - Function which will classify an OS packet
1558 into a WMM AC based on either 802.1Q or DSCP
1559
1560 @param pAdapter : [in] pointer to adapter context
1561 @param skb : [in] pointer to OS packet (sk_buff)
1562 @param pAcType : [out] pointer to WMM AC type of OS packet
1563
1564 @return : None
1565 ===========================================================================*/
1566v_VOID_t hdd_wmm_classify_pkt ( hdd_adapter_t* pAdapter,
1567 struct sk_buff *skb,
1568 WLANTL_ACEnumType* pAcType,
1569 sme_QosWmmUpType *pUserPri)
1570{
1571 unsigned char * pPkt;
1572 union generic_ethhdr *pHdr;
1573 struct iphdr *pIpHdr;
1574 unsigned char tos;
1575 unsigned char dscp;
1576 sme_QosWmmUpType userPri;
1577 WLANTL_ACEnumType acType;
1578
1579 // this code is executed for every packet therefore
1580 // all debug code is kept conditional
1581
1582#ifdef HDD_WMM_DEBUG
1583 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001584 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001585#endif // HDD_WMM_DEBUG
1586
1587 pPkt = skb->data;
1588 pHdr = (union generic_ethhdr *)pPkt;
1589
1590#ifdef HDD_WMM_DEBUG
1591 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1592 "%s: proto/length is 0x%04x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001593 __func__, pHdr->eth_II.h_proto);
Jeff Johnson295189b2012-06-20 16:38:30 -07001594#endif // HDD_WMM_DEBUG
1595
1596 if (HDD_WMM_CLASSIFICATION_DSCP == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
1597 {
1598 if (pHdr->eth_II.h_proto == htons(ETH_P_IP))
1599 {
1600 // case 1: Ethernet II IP packet
1601 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_II)];
1602 tos = pIpHdr->tos;
1603#ifdef HDD_WMM_DEBUG
1604 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1605 "%s: Ethernet II IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001606 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001607#endif // HDD_WMM_DEBUG
1608
1609 }
1610 else if ((ntohs(pHdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
1611 (pHdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
1612 (pHdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
1613 (pHdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1614 (pHdr->eth_8023.h_proto == htons(ETH_P_IP)))
1615 {
1616 // case 2: 802.3 LLC/SNAP IP packet
1617 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];
1618 tos = pIpHdr->tos;
1619#ifdef HDD_WMM_DEBUG
1620 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1621 "%s: 802.3 LLC/SNAP IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001622 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001623#endif // HDD_WMM_DEBUG
1624 }
1625 else if (pHdr->eth_II.h_proto == htons(ETH_P_8021Q))
1626 {
1627 // VLAN tagged
1628
1629 if (pHdr->eth_IIv.h_vlan_encapsulated_proto == htons(ETH_P_IP))
1630 {
1631 // case 3: Ethernet II vlan-tagged IP packet
1632 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_IIv)];
1633 tos = pIpHdr->tos;
1634#ifdef HDD_WMM_DEBUG
1635 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1636 "%s: Ethernet II VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001637 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001638#endif // HDD_WMM_DEBUG
1639 }
1640 else if ((ntohs(pHdr->eth_IIv.h_vlan_encapsulated_proto) < WLAN_MIN_PROTO) &&
1641 (pHdr->eth_8023v.h_snap.dsap == WLAN_SNAP_DSAP) &&
1642 (pHdr->eth_8023v.h_snap.ssap == WLAN_SNAP_SSAP) &&
1643 (pHdr->eth_8023v.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1644 (pHdr->eth_8023v.h_proto == htons(ETH_P_IP)))
1645 {
1646 // case 4: 802.3 LLC/SNAP vlan-tagged IP packet
1647 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023v)];
1648 tos = pIpHdr->tos;
1649#ifdef HDD_WMM_DEBUG
1650 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1651 "%s: 802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001652 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001653#endif // HDD_WMM_DEBUG
1654 }
1655 else
1656 {
1657 // default
1658#ifdef HDD_WMM_DEBUG
1659 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1660 "%s: VLAN tagged Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001661 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001662#endif // HDD_WMM_DEBUG
1663 tos = 0;
1664 }
1665 }
1666 else
1667 {
1668 // default
1669#ifdef HDD_WMM_DEBUG
1670 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1671 "%s: Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001672 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001673#endif // HDD_WMM_DEBUG
1674 //Give the highest priority to 802.1x packet
1675 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
1676 tos = 0xC0;
1677 else
1678 tos = 0;
1679 }
1680
1681 dscp = (tos>>2) & 0x3f;
1682 userPri = hddWmmDscpToUpMap[dscp];
1683
1684#ifdef HDD_WMM_DEBUG
1685 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1686 "%s: tos is %d, dscp is %d, up is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001687 __func__, tos, dscp, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07001688#endif // HDD_WMM_DEBUG
1689
1690 }
1691 else if (HDD_WMM_CLASSIFICATION_802_1Q == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
1692 {
1693 if (pHdr->eth_IIv.h_vlan_proto == htons(ETH_P_8021Q))
1694 {
1695 // VLAN tagged
1696 userPri = (ntohs(pHdr->eth_IIv.h_vlan_TCI)>>13) & 0x7;
1697#ifdef HDD_WMM_DEBUG
1698 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1699 "%s: Tagged frame, UP is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001700 __func__, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07001701#endif // HDD_WMM_DEBUG
1702 }
1703 else
1704 {
1705 // not VLAN tagged, use default
1706#ifdef HDD_WMM_DEBUG
1707 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1708 "%s: Untagged frame, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001709 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001710#endif // HDD_WMM_DEBUG
1711 //Give the highest priority to 802.1x packet
1712 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
1713 userPri = SME_QOS_WMM_UP_VO;
1714 else
1715 userPri = SME_QOS_WMM_UP_BE;
1716 }
1717 }
1718 else
1719 {
1720 // default
1721#ifdef HDD_WMM_DEBUG
1722 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1723 "%s: Unknown classification scheme, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001724 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001725#endif // HDD_WMM_DEBUG
1726 userPri = SME_QOS_WMM_UP_BE;
1727 }
1728
1729 acType = hddWmmUpToAcMap[userPri];
1730
1731#ifdef HDD_WMM_DEBUG
1732 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1733 "%s: UP is %d, AC is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001734 __func__, userPri, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001735#endif // HDD_WMM_DEBUG
1736
1737 *pUserPri = userPri;
1738 *pAcType = acType;
1739
1740 return;
1741}
1742
1743/**============================================================================
1744 @brief hdd_hostapd_select_quueue() - Function which will classify the packet
1745 according to linux qdisc expectation.
1746
1747
1748 @param dev : [in] pointer to net_device structure
1749 @param skb : [in] pointer to os packet
1750
1751 @return : Qdisc queue index
1752 ===========================================================================*/
1753v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb)
1754{
1755 WLANTL_ACEnumType ac;
1756 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
1757 v_USHORT_t queueIndex;
1758 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
1759 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
1760 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001761 v_U8_t STAId;
1762 v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
1763
1764 /*Get the Station ID*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001765 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &STAId))
1766 {
Madan Mohan Koyyalamudif1d39952012-10-31 15:18:40 -07001767 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001768 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001769 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1770 goto done;
1771 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001772
1773 spin_lock_bh( &pAdapter->staInfo_lock );
1774 if (FALSE == vos_is_macaddr_equal(&pAdapter->aStaInfo[STAId].macAddrSTA, pDestMacAddress))
1775 {
1776 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001777 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001778
1779 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1780 goto release_lock;
1781 }
1782 if (pAdapter->aStaInfo[STAId].isUsed && pAdapter->aStaInfo[STAId].isQosEnabled && (HDD_WMM_USER_MODE_NO_QOS != pHddCtx->cfg_ini->WmmMode))
1783 {
1784 /* Get the user priority from IP header & corresponding AC */
1785 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
1786 }
1787 *pSTAId = STAId;
1788
1789release_lock:
1790 spin_unlock_bh( &pAdapter->staInfo_lock );
1791done:
1792 skb->priority = up;
1793 queueIndex = hddLinuxUpToAcMap[skb->priority];
1794
1795 return queueIndex;
1796}
1797
1798/**============================================================================
1799 @brief hdd_wmm_select_quueue() - Function which will classify the packet
1800 according to linux qdisc expectation.
1801
1802
1803 @param dev : [in] pointer to net_device structure
1804 @param skb : [in] pointer to os packet
1805
1806 @return : Qdisc queue index
1807 ===========================================================================*/
1808v_U16_t hdd_wmm_select_queue(struct net_device * dev, struct sk_buff *skb)
1809{
1810 WLANTL_ACEnumType ac;
Shailender Karmuchia734f332013-04-19 14:02:48 -07001811 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001812 v_USHORT_t queueIndex;
Jeff Johnson295189b2012-06-20 16:38:30 -07001813 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1814
Shailender Karmuchia734f332013-04-19 14:02:48 -07001815 /*Get the Station ID*/
1816 if (WLAN_HDD_IBSS == pAdapter->device_mode)
1817 {
1818 v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
1819 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
1820
1821 if ( VOS_STATUS_SUCCESS !=
1822 hdd_Ibss_GetStaId(&pAdapter->sessionCtx.station,
1823 pDestMacAddress, pSTAId))
1824 {
1825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1826 "%s: Failed to find right station pDestMacAddress: "
1827 MAC_ADDRESS_STR , MAC_ADDR_ARRAY(pDestMacAddress),__func__);
1828 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1829 goto done;
1830 }
1831 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001832 // if we don't want QoS or the AP doesn't support Qos
1833 // All traffic will get equal opportuniy to transmit data frames.
1834 if( hdd_wmm_is_active(pAdapter) ) {
1835 /* Get the user priority from IP header & corresponding AC */
1836 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
1837 }
Shailender Karmuchia734f332013-04-19 14:02:48 -07001838done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001839 skb->priority = up;
1840 queueIndex = hddLinuxUpToAcMap[skb->priority];
1841
1842 return queueIndex;
1843}
1844
1845/**============================================================================
1846 @brief hdd_wmm_acquire_access() - Function which will attempt to acquire
1847 admittance for a WMM AC
1848
1849 @param pAdapter : [in] pointer to adapter context
1850 @param acType : [in] WMM AC type of OS packet
1851 @param pGranted : [out] pointer to boolean flag when indicates if access
1852 has been granted or not
1853
1854 @return : VOS_STATUS_SUCCESS if succssful
1855 : other values if failure
1856 ===========================================================================*/
1857VOS_STATUS hdd_wmm_acquire_access( hdd_adapter_t* pAdapter,
1858 WLANTL_ACEnumType acType,
1859 v_BOOL_t * pGranted )
1860{
1861 hdd_wmm_qos_context_t *pQosContext;
1862
1863 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001864 "%s: Entered for AC %d", __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001865
1866 if (!hdd_wmm_is_active(pAdapter) || !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
1867 {
1868 // either we don't want QoS or the AP doesn't support QoS
1869 // or we don't want to do implicit QoS
1870 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001871 "%s: QoS not configured on both ends ", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001872
1873 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
1874 *pGranted = VOS_TRUE;
1875 return VOS_STATUS_SUCCESS;
1876 }
1877
1878 // do we already have an implicit QoS request pending for this AC?
1879 if ((pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded) ||
1880 (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessPending))
1881 {
1882 // request already pending so we need to wait for that response
1883 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1884 "%s: Implicit QoS for TL AC %d already scheduled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001885 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001886
1887 *pGranted = VOS_FALSE;
1888 return VOS_STATUS_SUCCESS;
1889 }
1890
1891 // did we already fail to establish implicit QoS for this AC?
1892 // (if so, access should have been granted when the failure was handled)
1893 if (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessFailed)
1894 {
1895 // request previously failed
1896 // allow access, but we'll be downgraded
1897 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1898 "%s: Implicit QoS for TL AC %d previously failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001899 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001900
1901 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
1902 *pGranted = VOS_TRUE;
1903 return VOS_STATUS_SUCCESS;
1904 }
1905
1906 // we need to establish implicit QoS
1907 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1908 "%s: Need to schedule implicit QoS for TL AC %d, pAdapter is %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001909 __func__, acType, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001910
1911 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded = VOS_TRUE;
1912
Mohit Khanna217ea8d2012-09-11 17:42:42 -07001913 pQosContext = kmalloc(sizeof(*pQosContext), GFP_ATOMIC);
Jeff Johnson295189b2012-06-20 16:38:30 -07001914 if (NULL == pQosContext)
1915 {
1916 // no memory for QoS context. Nothing we can do but let data flow
1917 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001918 "%s: Unable to allocate context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001919 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
1920 *pGranted = VOS_TRUE;
1921 return VOS_STATUS_SUCCESS;
1922 }
1923
1924 pQosContext->acType = acType;
1925 pQosContext->pAdapter = pAdapter;
1926 pQosContext->qosFlowId = 0;
1927 pQosContext->handle = HDD_WMM_HANDLE_IMPLICIT;
1928 pQosContext->magic = HDD_WMM_CTX_MAGIC;
1929 INIT_WORK(&pQosContext->wmmAcSetupImplicitQos,
1930 hdd_wmm_do_implicit_qos);
1931
1932 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1933 "%s: Scheduling work for AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001934 __func__, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001935
1936 schedule_work(&pQosContext->wmmAcSetupImplicitQos);
1937
1938 // caller will need to wait until the work takes place and
1939 // TSPEC negotiation completes
1940 *pGranted = VOS_FALSE;
1941 return VOS_STATUS_SUCCESS;
1942}
1943
1944/**============================================================================
1945 @brief hdd_wmm_assoc() - Function which will handle the housekeeping
1946 required by WMM when association takes place
1947
1948 @param pAdapter : [in] pointer to adapter context
1949 @param pRoamInfo: [in] pointer to roam information
1950 @param eBssType : [in] type of BSS
1951
1952 @return : VOS_STATUS_SUCCESS if succssful
1953 : other values if failure
1954 ===========================================================================*/
1955VOS_STATUS hdd_wmm_assoc( hdd_adapter_t* pAdapter,
1956 tCsrRoamInfo *pRoamInfo,
1957 eCsrRoamBssType eBssType )
1958{
1959 tANI_U8 uapsdMask;
1960 VOS_STATUS status;
1961
1962 // when we associate we need to notify TL if it needs to enable
1963 // UAPSD for any access categories
1964
1965 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001966 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001967
1968 if (pRoamInfo->fReassocReq)
1969 {
1970 // when we reassociate we should continue to use whatever
1971 // parameters were previously established. if we are
1972 // reassociating due to a U-APSD change for a particular
1973 // Access Category, then the change will be communicated
1974 // to HDD via the QoS callback associated with the given
1975 // flow, and U-APSD parameters will be updated there
1976
1977 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001978 "%s: Reassoc so no work, Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001979
1980 return VOS_STATUS_SUCCESS;
1981 }
1982
1983 // get the negotiated UAPSD Mask
1984 uapsdMask = pRoamInfo->u.pConnectedProfile->modifyProfileFields.uapsd_mask;
1985
1986 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001987 "%s: U-APSD mask is 0x%02x", __func__, (int) uapsdMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07001988
1989 if (uapsdMask & HDD_AC_VO)
1990 {
1991 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1992 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
1993 WLANTL_AC_VO,
1994 7,
1995 7,
1996 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv,
1997 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv,
1998 WLANTL_BI_DIR );
1999
2000 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2001 }
2002
2003 if (uapsdMask & HDD_AC_VI)
2004 {
2005 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2006 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2007 WLANTL_AC_VI,
2008 5,
2009 5,
2010 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv,
2011 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv,
2012 WLANTL_BI_DIR );
2013
2014 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2015 }
2016
2017 if (uapsdMask & HDD_AC_BK)
2018 {
2019 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2020 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2021 WLANTL_AC_BK,
2022 2,
2023 2,
2024 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv,
2025 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv,
2026 WLANTL_BI_DIR );
2027
2028 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2029 }
2030
2031 if (uapsdMask & HDD_AC_BE)
2032 {
2033 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2034 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2035 WLANTL_AC_BE,
2036 3,
2037 3,
2038 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv,
2039 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv,
2040 WLANTL_BI_DIR );
2041
2042 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2043 }
2044
2045 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002046 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002047
2048 return VOS_STATUS_SUCCESS;
2049}
2050
2051
2052
2053static const v_U8_t acmMaskBit[WLANTL_MAX_AC] =
2054 {
2055 0x4, /* WLANTL_AC_BK */
2056 0x8, /* WLANTL_AC_BE */
2057 0x2, /* WLANTL_AC_VI */
2058 0x1 /* WLANTL_AC_VO */
2059 };
2060
2061/**============================================================================
2062 @brief hdd_wmm_connect() - Function which will handle the housekeeping
2063 required by WMM when a connection is established
2064
2065 @param pAdapter : [in] pointer to adapter context
2066 @param pRoamInfo: [in] pointer to roam information
2067 @param eBssType : [in] type of BSS
2068
2069 @return : VOS_STATUS_SUCCESS if succssful
2070 : other values if failure
2071 ===========================================================================*/
2072VOS_STATUS hdd_wmm_connect( hdd_adapter_t* pAdapter,
2073 tCsrRoamInfo *pRoamInfo,
2074 eCsrRoamBssType eBssType )
2075{
2076 int ac;
2077 v_BOOL_t qap;
2078 v_BOOL_t qosConnection;
2079 v_U8_t acmMask;
2080
2081 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002082 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002083
2084 if ((eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) &&
2085 pRoamInfo &&
2086 pRoamInfo->u.pConnectedProfile)
2087 {
2088 qap = pRoamInfo->u.pConnectedProfile->qap;
2089 qosConnection = pRoamInfo->u.pConnectedProfile->qosConnection;
2090 acmMask = pRoamInfo->u.pConnectedProfile->acm_mask;
2091 }
2092 else
2093 {
2094 qap = VOS_TRUE;
2095 qosConnection = VOS_TRUE;
2096 acmMask = 0x0;
2097 }
2098
2099 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2100 "%s: qap is %d, qosConnection is %d, acmMask is 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002101 __func__, qap, qosConnection, acmMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002102
2103 pAdapter->hddWmmStatus.wmmQap = qap;
2104 pAdapter->hddWmmStatus.wmmQosConnection = qosConnection;
2105
2106 for (ac = 0; ac < WLANTL_MAX_AC; ac++)
2107 {
2108 if (qap &&
2109 qosConnection &&
2110 (acmMask & acmMaskBit[ac]))
2111 {
2112 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2113 "%s: ac %d on",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002114 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002115
2116 // admission is required
2117 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_TRUE;
2118 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_FALSE;
2119 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessGranted = VOS_FALSE;
2120 }
2121 else
2122 {
2123 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2124 "%s: ac %d off",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002125 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002126 // admission is not required so access is allowed
2127 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_FALSE;
2128 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_TRUE;
2129 }
2130
2131 }
2132
2133 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002134 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002135
2136 return VOS_STATUS_SUCCESS;
2137}
2138
2139/**============================================================================
2140 @brief hdd_wmm_get_uapsd_mask() - Function which will calculate the
2141 initial value of the UAPSD mask based upon the device configuration
2142
2143 @param pAdapter : [in] pointer to adapter context
2144 @param pUapsdMask: [in] pointer to where the UAPSD Mask is to be stored
2145
2146 @return : VOS_STATUS_SUCCESS if succssful
2147 : other values if failure
2148 ===========================================================================*/
2149VOS_STATUS hdd_wmm_get_uapsd_mask( hdd_adapter_t* pAdapter,
2150 tANI_U8 *pUapsdMask )
2151{
2152 tANI_U8 uapsdMask;
2153
2154 if (HDD_WMM_USER_MODE_NO_QOS == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
2155 {
2156 // no QOS then no UAPSD
2157 uapsdMask = 0;
2158 }
2159 else
2160 {
2161 // start with the default mask
2162 uapsdMask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
2163
2164 // disable UAPSD for any ACs with a 0 Service Interval
2165 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv == 0 )
2166 {
2167 uapsdMask &= ~HDD_AC_VO;
2168 }
2169
2170 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv == 0 )
2171 {
2172 uapsdMask &= ~HDD_AC_VI;
2173 }
2174
2175 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv == 0 )
2176 {
2177 uapsdMask &= ~HDD_AC_BK;
2178 }
2179
2180 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv == 0 )
2181 {
2182 uapsdMask &= ~HDD_AC_BE;
2183 }
2184 }
2185
2186 // return calculated mask
2187 *pUapsdMask = uapsdMask;
2188 return VOS_STATUS_SUCCESS;
2189}
2190
2191
2192/**============================================================================
2193 @brief hdd_wmm_is_active() - Function which will determine if WMM is
2194 active on the current connection
2195
2196 @param pAdapter : [in] pointer to adapter context
2197
2198 @return : VOS_TRUE if WMM is enabled
2199 : VOS_FALSE if WMM is not enabled
2200 ===========================================================================*/
2201v_BOOL_t hdd_wmm_is_active( hdd_adapter_t* pAdapter )
2202{
2203 if ((!pAdapter->hddWmmStatus.wmmQosConnection) ||
2204 (!pAdapter->hddWmmStatus.wmmQap))
2205 {
2206 return VOS_FALSE;
2207 }
2208 else
2209 {
2210 return VOS_TRUE;
2211 }
2212}
2213
2214/**============================================================================
2215 @brief hdd_wmm_addts() - Function which will add a traffic spec at the
2216 request of an application
2217
2218 @param pAdapter : [in] pointer to adapter context
2219 @param handle : [in] handle to uniquely identify a TS
2220 @param pTspec : [in] pointer to the traffic spec
2221
2222 @return : HDD_WLAN_WMM_STATUS_*
2223 ===========================================================================*/
2224hdd_wlan_wmm_status_e hdd_wmm_addts( hdd_adapter_t* pAdapter,
2225 v_U32_t handle,
2226 sme_QosWmmTspecInfo* pTspec )
2227{
2228 hdd_wmm_qos_context_t *pQosContext;
2229 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2230#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2231 sme_QosStatusType smeStatus;
2232#endif
2233 v_BOOL_t found = VOS_FALSE;
2234
2235 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002236 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002237
2238 // see if a context already exists with the given handle
2239 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2240 list_for_each_entry(pQosContext,
2241 &pAdapter->hddWmmStatus.wmmContextList,
2242 node)
2243 {
2244 if (pQosContext->handle == handle)
2245 {
2246 found = VOS_TRUE;
2247 break;
2248 }
2249 }
2250 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2251 if (found)
2252 {
2253 // record with that handle already exists
2254 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2255 "%s: Record already exists with handle 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002256 __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002257
2258 /* Application is trying to modify some of the Tspec params. Allow it */
2259 smeStatus = sme_QosModifyReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2260 pTspec,
2261 pQosContext->qosFlowId);
2262
2263 // need to check the return value and act appropriately
2264 switch (smeStatus)
2265 {
2266 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
2267 status = HDD_WLAN_WMM_STATUS_MODIFY_PENDING;
2268 break;
2269 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2270 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
2271 break;
2272 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
2273 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
2274 break;
2275 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
2276 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
2277 break;
2278 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
2279 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2280 break;
2281 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2282 status = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2283 break;
2284 default:
2285 // we didn't get back one of the SME_QOS_STATUS_MODIFY_* status codes
2286 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302287 "%s: unexpected SME Status=%d\n", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002288 VOS_ASSERT(0);
2289 return HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2290 }
2291
2292 // we were successful, save the status
2293 pQosContext->lastStatus = status;
2294 return status;
2295 }
2296
2297 pQosContext = kmalloc(sizeof(*pQosContext), GFP_KERNEL);
2298 if (NULL == pQosContext)
2299 {
2300 // no memory for QoS context. Nothing we can do
2301 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002302 "%s: Unable to allocate QoS context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002303 return HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE;
2304 }
2305
2306 // we assume the tspec has already been validated by the caller
2307
2308 pQosContext->handle = handle;
2309 pQosContext->acType = hddWmmUpToAcMap[pTspec->ts_info.up];
2310 pQosContext->pAdapter = pAdapter;
2311 pQosContext->qosFlowId = 0;
2312 pQosContext->magic = HDD_WMM_CTX_MAGIC;
2313
2314 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2315 "%s: Setting up QoS, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002316 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002317
2318 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2319 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
2320 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2321
2322#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2323 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2324 pAdapter->sessionId,
2325 pTspec,
2326 hdd_wmm_sme_callback,
2327 pQosContext,
2328 pTspec->ts_info.up,
2329 &pQosContext->qosFlowId);
2330
2331 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2332 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002333 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002334
2335 // need to check the return value and act appropriately
2336 switch (smeStatus)
2337 {
2338 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
2339 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2340 break;
2341 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2342 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
2343 break;
2344 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
2345 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
2346 break;
2347 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
2348 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2349 break;
2350 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
2351 hdd_wmm_free_context(pQosContext);
2352 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
2353 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
2354 // we can't tell the difference between when a request fails because
2355 // AP rejected it versus when SME encounterd an internal error
2356 hdd_wmm_free_context(pQosContext);
2357 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2358 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2359 hdd_wmm_free_context(pQosContext);
2360 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2361 default:
2362 // we didn't get back one of the SME_QOS_STATUS_SETUP_* status codes
2363 hdd_wmm_free_context(pQosContext);
2364 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302365 "%s: unexpected SME Status=%d\n", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002366 VOS_ASSERT(0);
2367 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2368 }
2369#endif
2370
2371 // we were successful, save the status
2372 pQosContext->lastStatus = status;
2373
2374 return status;
2375}
2376
2377/**============================================================================
2378 @brief hdd_wmm_delts() - Function which will delete a traffic spec at the
2379 request of an application
2380
2381 @param pAdapter : [in] pointer to adapter context
2382 @param handle : [in] handle to uniquely identify a TS
2383
2384 @return : HDD_WLAN_WMM_STATUS_*
2385 ===========================================================================*/
2386hdd_wlan_wmm_status_e hdd_wmm_delts( hdd_adapter_t* pAdapter,
2387 v_U32_t handle )
2388{
2389 hdd_wmm_qos_context_t *pQosContext;
2390 v_BOOL_t found = VOS_FALSE;
2391 WLANTL_ACEnumType acType = 0;
2392 v_U32_t qosFlowId = 0;
2393 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2394#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2395 sme_QosStatusType smeStatus;
2396#endif
2397
2398 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002399 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002400
2401 // locate the context with the given handle
2402 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2403 list_for_each_entry(pQosContext,
2404 &pAdapter->hddWmmStatus.wmmContextList,
2405 node)
2406 {
2407 if (pQosContext->handle == handle)
2408 {
2409 found = VOS_TRUE;
2410 acType = pQosContext->acType;
2411 qosFlowId = pQosContext->qosFlowId;
2412 break;
2413 }
2414 }
2415 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2416
2417 if (VOS_FALSE == found)
2418 {
2419 // we didn't find the handle
2420 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002421 "%s: handle 0x%x not found", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002422 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2423 }
2424
2425
2426 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2427 "%s: found handle 0x%x, flow %d, AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002428 __func__, handle, qosFlowId, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002429
2430#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2431 smeStatus = sme_QosReleaseReq( WLAN_HDD_GET_HAL_CTX(pAdapter), qosFlowId );
2432
2433 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2434 "%s: SME flow %d released, SME status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002435 __func__, qosFlowId, smeStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07002436
2437 switch(smeStatus)
2438 {
2439 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
2440 // this flow is the only one on that AC, so go ahead and update
2441 // our TSPEC state for the AC
2442 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcTspecValid = VOS_FALSE;
2443
2444 // need to tell TL to stop trigger timer, etc
2445 hdd_wmm_disable_tl_uapsd(pQosContext);
2446
2447#ifdef FEATURE_WLAN_CCX
2448 // disable the inactivity timer
2449 hdd_wmm_disable_inactivity_timer(pQosContext);
2450#endif
2451 // we are done with this context
2452 hdd_wmm_free_context(pQosContext);
2453
2454 // SME must not fire any more callbacks for this flow since the context
2455 // is no longer valid
2456
2457 return HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
2458
2459 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
2460 // do nothing as we will get a response from SME
2461 status = HDD_WLAN_WMM_STATUS_RELEASE_PENDING;
2462 break;
2463
2464 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
2465 // nothing we can do with the existing flow except leave it
2466 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2467 break;
2468
2469 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
2470 // nothing we can do with the existing flow except leave it
2471 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2472
2473 default:
2474 // we didn't get back one of the SME_QOS_STATUS_RELEASE_* status codes
2475 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302476 "%s: unexpected SME Status=%d\n", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002477 VOS_ASSERT(0);
2478 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2479 }
2480
2481#endif
2482 pQosContext->lastStatus = status;
2483 return status;
2484}
2485
2486/**============================================================================
2487 @brief hdd_wmm_checkts() - Function which will return the status of a traffic
2488 spec at the request of an application
2489
2490 @param pAdapter : [in] pointer to adapter context
2491 @param handle : [in] handle to uniquely identify a TS
2492
2493 @return : HDD_WLAN_WMM_STATUS_*
2494 ===========================================================================*/
2495hdd_wlan_wmm_status_e hdd_wmm_checkts( hdd_adapter_t* pAdapter,
2496 v_U32_t handle )
2497{
2498 hdd_wmm_qos_context_t *pQosContext;
2499 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST;
2500
2501 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002502 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002503
2504 // locate the context with the given handle
2505 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2506 list_for_each_entry(pQosContext,
2507 &pAdapter->hddWmmStatus.wmmContextList,
2508 node)
2509 {
2510 if (pQosContext->handle == handle)
2511 {
2512 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2513 "%s: found handle 0x%x, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002514 __func__, handle, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002515
2516 status = pQosContext->lastStatus;
2517 break;
2518 }
2519 }
2520 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2521 return status;
2522}