blob: 40f59f819499b9f252d5036b785a80667f171da0 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/*============================================================================
43 @file wlan_hdd_wmm.c
44
45 This module (wlan_hdd_wmm.h interface + wlan_hdd_wmm.c implementation)
46 houses all the logic for WMM in HDD.
47
48 On the control path, it has the logic to setup QoS, modify QoS and delete
49 QoS (QoS here refers to a TSPEC). The setup QoS comes in two flavors: an
50 explicit application invoked and an internal HDD invoked. The implicit QoS
51 is for applications that do NOT call the custom QCT WLAN OIDs for QoS but
52 which DO mark their traffic for priortization. It also has logic to start,
53 update and stop the U-APSD trigger frame generation. It also has logic to
54 read WMM related config parameters from the registry.
55
56 On the data path, it has the logic to figure out the WMM AC of an egress
57 packet and when to signal TL to serve a particular AC queue. It also has the
58 logic to retrieve a packet based on WMM priority in response to a fetch from
59 TL.
60
61 The remaining functions are utility functions for information hiding.
62
63
64 Copyright (c) 2008-9 QUALCOMM Incorporated.
65 All Rights Reserved.
66 Qualcomm Confidential and Proprietary
67============================================================================*/
68
69/*---------------------------------------------------------------------------
70 Include files
71 -------------------------------------------------------------------------*/
72#include <wlan_hdd_tx_rx.h>
73#include <wlan_hdd_dp_utils.h>
74#include <wlan_hdd_wmm.h>
75#include <wlan_hdd_ether.h>
76#include <linux/netdevice.h>
77#include <linux/skbuff.h>
78#include <linux/etherdevice.h>
79#include <linux/if_vlan.h>
80#include <linux/ip.h>
81#include <linux/semaphore.h>
82#include <wlan_hdd_hostapd.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070083#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070084
85// change logging behavior based upon debug flag
86#ifdef HDD_WMM_DEBUG
87#define WMM_TRACE_LEVEL_FATAL VOS_TRACE_LEVEL_FATAL
88#define WMM_TRACE_LEVEL_ERROR VOS_TRACE_LEVEL_FATAL
89#define WMM_TRACE_LEVEL_WARN VOS_TRACE_LEVEL_FATAL
90#define WMM_TRACE_LEVEL_INFO VOS_TRACE_LEVEL_FATAL
91#define WMM_TRACE_LEVEL_INFO_HIGH VOS_TRACE_LEVEL_FATAL
92#define WMM_TRACE_LEVEL_INFO_LOW VOS_TRACE_LEVEL_FATAL
93#else
94#define WMM_TRACE_LEVEL_FATAL VOS_TRACE_LEVEL_FATAL
95#define WMM_TRACE_LEVEL_ERROR VOS_TRACE_LEVEL_ERROR
96#define WMM_TRACE_LEVEL_WARN VOS_TRACE_LEVEL_WARN
97#define WMM_TRACE_LEVEL_INFO VOS_TRACE_LEVEL_INFO
98#define WMM_TRACE_LEVEL_INFO_HIGH VOS_TRACE_LEVEL_INFO_HIGH
99#define WMM_TRACE_LEVEL_INFO_LOW VOS_TRACE_LEVEL_INFO_LOW
100#endif
101
102
Jeff Johnson295189b2012-06-20 16:38:30 -0700103#define WLAN_HDD_MAX_DSCP 0x3f
104
105static sme_QosWmmUpType hddWmmDscpToUpMap[WLAN_HDD_MAX_DSCP+1];
106
107const v_U8_t hddWmmUpToAcMap[] = {
108 WLANTL_AC_BE,
109 WLANTL_AC_BK,
110 WLANTL_AC_BK,
111 WLANTL_AC_BE,
112 WLANTL_AC_VI,
113 WLANTL_AC_VI,
114 WLANTL_AC_VO,
115 WLANTL_AC_VO
116};
117
118//Linux based UP -> AC Mapping
119const v_U8_t hddLinuxUpToAcMap[8] = {
120 HDD_LINUX_AC_BE,
121 HDD_LINUX_AC_BK,
122 HDD_LINUX_AC_BK,
123 HDD_LINUX_AC_BE,
124 HDD_LINUX_AC_VI,
125 HDD_LINUX_AC_VI,
126 HDD_LINUX_AC_VO,
127 HDD_LINUX_AC_VO
128};
129
130#ifndef WLAN_MDM_CODE_REDUCTION_OPT
131/**
132 @brief hdd_wmm_enable_tl_uapsd() - function which decides whether and
133 how to update UAPSD parameters in TL
134
135 @param pQosContext : [in] the pointer the QoS instance control block
136
137 @return
138 None
139*/
140static void hdd_wmm_enable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
141{
142 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
143 WLANTL_ACEnumType acType = pQosContext->acType;
144 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
145 VOS_STATUS status;
146 v_U32_t service_interval;
147 v_U32_t suspension_interval;
148 sme_QosWmmDirType direction;
149
150
151 // The TSPEC must be valid
152 if (pAc->wmmAcTspecValid == VOS_FALSE)
153 {
154 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
155 "%s: Invoked with invalid TSPEC",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700156 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700157 return;
158 }
159
160 // determine the service interval
161 if (pAc->wmmAcTspecInfo.min_service_interval)
162 {
163 service_interval = pAc->wmmAcTspecInfo.min_service_interval;
164 }
165 else if (pAc->wmmAcTspecInfo.max_service_interval)
166 {
167 service_interval = pAc->wmmAcTspecInfo.max_service_interval;
168 }
169 else
170 {
171 // no service interval is present in the TSPEC
172 // this is OK, there just won't be U-APSD
173 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
174 "%s: No service interval supplied",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700175 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700176 return;
177 }
178
179 // determine the suspension interval & direction
180 suspension_interval = pAc->wmmAcTspecInfo.suspension_interval;
181 direction = pAc->wmmAcTspecInfo.ts_info.direction;
182
183 // if we have previously enabled U-APSD, have any params changed?
184 if ((pAc->wmmAcUapsdInfoValid) &&
185 (pAc->wmmAcUapsdServiceInterval == service_interval) &&
186 (pAc->wmmAcUapsdSuspensionInterval == suspension_interval) &&
187 (pAc->wmmAcUapsdDirection == direction))
188 {
189 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
190 "%s: No change in U-APSD parameters",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700191 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700192 return;
193 }
194
195 // are we in the appropriate power save modes?
196 if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_BEACON_MODE_POWER_SAVE))
197 {
198 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
199 "%s: BMPS is not enabled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700200 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700201 return;
202 }
203
204 if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_UAPSD_MODE_POWER_SAVE))
205 {
206 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
207 "%s: U-APSD is not enabled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700208 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700209 return;
210 }
211
212 // everything is in place to notify TL
213 status = WLANTL_EnableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
214 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
215 acType,
216 pAc->wmmAcTspecInfo.ts_info.tid,
217 pAc->wmmAcTspecInfo.ts_info.up,
218 service_interval,
219 suspension_interval,
220 direction);
221
222 if ( !VOS_IS_STATUS_SUCCESS( status ) )
223 {
224 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
225 "%s: Failed to enable U-APSD for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700226 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700227 return;
228 }
229
230 // stash away the parameters that were used
231 pAc->wmmAcUapsdInfoValid = VOS_TRUE;
232 pAc->wmmAcUapsdServiceInterval = service_interval;
233 pAc->wmmAcUapsdSuspensionInterval = suspension_interval;
234 pAc->wmmAcUapsdDirection = direction;
235
236 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
237 "%s: Enabled UAPSD in TL srv_int=%ld "
238 "susp_int=%ld dir=%d AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700239 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700240 service_interval,
241 suspension_interval,
242 direction,
243 acType);
244
245}
246
247/**
248 @brief hdd_wmm_disable_tl_uapsd() - function which decides whether
249 to disable UAPSD parameters in TL
250
251 @param pQosContext : [in] the pointer the QoS instance control block
252
253 @return
254 None
255*/
256static void hdd_wmm_disable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
257{
258 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
259 WLANTL_ACEnumType acType = pQosContext->acType;
260 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
261 VOS_STATUS status;
262
263
264 // have we previously enabled UAPSD?
265 if (pAc->wmmAcUapsdInfoValid == VOS_TRUE)
266 {
267 status = WLANTL_DisableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
268 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
269 acType);
270
271 if ( !VOS_IS_STATUS_SUCCESS( status ) )
272 {
273 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
274 "%s: Failed to disable U-APSD for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700275 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700276 }
277 else
278 {
279 // TL no longer has valid UAPSD info
280 pAc->wmmAcUapsdInfoValid = VOS_FALSE;
281 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
282 "%s: Disabled UAPSD in TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700283 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700284 acType);
285 }
286 }
287}
288
289#endif
290
291/**
292 @brief hdd_wmm_free_context() - function which frees a QoS context
293
294 @param pQosContext : [in] the pointer the QoS instance control block
295
296 @return
297 None
298*/
299static void hdd_wmm_free_context (hdd_wmm_qos_context_t* pQosContext)
300{
301 hdd_adapter_t* pAdapter;
302
303 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
304 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700305 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700306
307 if (unlikely((NULL == pQosContext) ||
308 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
309 {
310 // must have been freed in another thread
311 return;
312 }
313
314 // get pointer to the adapter context
315 pAdapter = pQosContext->pAdapter;
316
317 // take the wmmLock since we're manipulating the context list
318 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
319
320 // make sure nobody thinks this is a valid context
321 pQosContext->magic = 0;
322
323 // unlink the context
324 list_del(&pQosContext->node);
325
326 // done manipulating the list
327 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
328
329 // reclaim memory
330 kfree(pQosContext);
331
332}
333
334#ifndef WLAN_MDM_CODE_REDUCTION_OPT
335/**
336 @brief hdd_wmm_notify_app() - function which notifies an application
337 changes in state of it flow
338
339 @param pQosContext : [in] the pointer the QoS instance control block
340
341 @return
342 None
343*/
344#define MAX_NOTIFY_LEN 50
345static void hdd_wmm_notify_app (hdd_wmm_qos_context_t* pQosContext)
346{
347 hdd_adapter_t* pAdapter;
348 union iwreq_data wrqu;
349 char buf[MAX_NOTIFY_LEN+1];
350
351 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
352 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700353 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700354
355 if (unlikely((NULL == pQosContext) ||
356 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
357 {
358 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
359 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700360 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700361 return;
362 }
363
364
365 // create the event
366 memset(&wrqu, 0, sizeof(wrqu));
367 memset(buf, 0, sizeof(buf));
368
369 snprintf(buf, MAX_NOTIFY_LEN, "QCOM: TS change[%u: %u]",
370 (unsigned int)pQosContext->handle,
371 (unsigned int)pQosContext->lastStatus);
372
373 wrqu.data.pointer = buf;
374 wrqu.data.length = strlen(buf);
375
376 // get pointer to the adapter
377 pAdapter = pQosContext->pAdapter;
378
379 // send the event
380 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700381 "%s: Sending [%s]", __func__, buf);
Jeff Johnson295189b2012-06-20 16:38:30 -0700382 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
383}
384
385
386/**
387 @brief hdd_wmm_is_access_allowed() - function which determines if access
388 is allowed for the given AC. this is designed to be called during SME
389 callback processing since that is when access can be granted or removed
390
391 @param pAdapter : [in] pointer to adapter context
392 @param pAc : [in] pointer to the per-AC status
393
394 @return : VOS_TRUE - access is allowed
395 : VOS_FALSE - access is not allowed
396 None
397*/
398static v_BOOL_t hdd_wmm_is_access_allowed(hdd_adapter_t* pAdapter,
399 hdd_wmm_ac_status_t* pAc)
400{
401 // if we don't want QoS or the AP doesn't support QoS
402 // or we don't want to do implicit QoS
403 // or if AP doesn't require admission for this AC
404 // then we have access
405 if (!hdd_wmm_is_active(pAdapter) ||
406 !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled ||
407 !pAc->wmmAcAccessRequired)
408 {
409 return VOS_TRUE;
410 }
411
412 // if implicit QoS has already completed, successfully or not,
413 // then access is allowed
414 if (pAc->wmmAcAccessGranted || pAc->wmmAcAccessFailed)
415 {
416 return VOS_TRUE;
417 }
418
419 // admission is required and implicit QoS hasn't completed
420 // however explicit QoS may have completed and we'll have
421 // a Tspec
422 // if we don't have a Tspec then access is not allowed
423 if (!pAc->wmmAcTspecValid)
424 {
425 return VOS_FALSE;
426 }
427
428 // we have a Tspec -- does it allow upstream or bidirectional traffic?
429 // if it only allows downstream traffic then access is not allowed
430 if (pAc->wmmAcTspecInfo.ts_info.direction == SME_QOS_WMM_TS_DIR_DOWNLINK)
431 {
432 return VOS_FALSE;
433 }
434
435 // we meet all of the criteria for access
436 return VOS_TRUE;
437}
438
439#ifdef FEATURE_WLAN_CCX
440/**
441 @brief hdd_wmm_inactivity_timer_cb() - timer handler function which is
442 called for every inactivity interval per AC. This function gets the
443 current transmitted packets on the given AC, and checks if there where
444 any TX activity from the previous interval. If there was no traffic
445 then it would delete the TS that was negotiated on that AC.
446
447 @param pUserData : [in] pointer to pQosContext
448
449 @return : NONE
450*/
451void hdd_wmm_inactivity_timer_cb( v_PVOID_t pUserData )
452{
453 hdd_wmm_qos_context_t* pQosContext = (hdd_wmm_qos_context_t*)pUserData;
454 hdd_adapter_t* pAdapter;
455 hdd_wmm_ac_status_t *pAc;
456 hdd_wlan_wmm_status_e status;
457 VOS_STATUS vos_status;
458 v_U32_t currentTrafficCnt = 0;
459 WLANTL_ACEnumType acType = pQosContext->acType;
460
461 pAdapter = pQosContext->pAdapter;
462 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
463
464 // Get the Tx stats for this AC.
465 currentTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];
466
467 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
468 FL("WMM inactivity Timer for AC=%d, currentCnt=%d, prevCnt=%d\n"),
469 acType, (int)currentTrafficCnt, (int)pAc->wmmPrevTrafficCnt);
470 if (pAc->wmmPrevTrafficCnt == currentTrafficCnt)
471 {
472 // If there is no traffic activity, delete the TSPEC for this AC
473 status = hdd_wmm_delts(pAdapter, pQosContext->handle);
474 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
475 FL("Deleted TS on AC %d, due to inactivity with status = %d!!!"),
476 acType, status);
477 }
478 else
479 {
480 pAc->wmmPrevTrafficCnt = currentTrafficCnt;
481 if (pAc->wmmInactivityTimer.state == VOS_TIMER_STATE_STOPPED)
482 {
483 // Restart the timer
484 vos_status = vos_timer_start(&pAc->wmmInactivityTimer, pAc->wmmInactivityTime);
485 if (!VOS_IS_STATUS_SUCCESS(vos_status))
486 {
487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
488 FL("Restarting inactivity timer failed on AC %d"), acType);
489 }
490 }
491 else
492 {
493 VOS_ASSERT(vos_timer_getCurrentState(
494 &pAc->wmmInactivityTimer) == VOS_TIMER_STATE_STOPPED);
495 }
496 }
497
498 return;
499}
500
501
502/**
503 @brief hdd_wmm_enable_inactivity_timer() - function to enable the
504 traffic inactivity timer for the given AC, if the inactivity_interval
505 specified in the ADDTS parameters is non-zero
506
507 @param pQosContext : [in] pointer to pQosContext
508 @param inactivityTime: [in] value of the inactivity interval in millisecs
509
510 @return : VOS_STATUS_E_FAILURE
511 VOS_STATUS_SUCCESS
512*/
513VOS_STATUS hdd_wmm_enable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext, v_U32_t inactivityTime)
514{
515 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
516 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
517 WLANTL_ACEnumType acType = pQosContext->acType;
518 hdd_wmm_ac_status_t *pAc;
519
520 pAdapter = pQosContext->pAdapter;
521 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
522
523
524 // If QoS-Tspec is successfully setup and if the inactivity timer is non-zero,
525 // a traffic inactivity timer needs to be started for the given AC
526 vos_status = vos_timer_init(
527 &pAc->wmmInactivityTimer,
528 VOS_TIMER_TYPE_SW,
529 hdd_wmm_inactivity_timer_cb,
530 (v_PVOID_t)pQosContext );
531 if ( !VOS_IS_STATUS_SUCCESS(vos_status))
532 {
533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
534 FL("Initializing inactivity timer failed on AC %d"), acType);
535 return vos_status;
536 }
537
538 // Start the inactivity timer
539 vos_status = vos_timer_start(
540 &pAc->wmmInactivityTimer,
541 inactivityTime);
542 if ( !VOS_IS_STATUS_SUCCESS(vos_status))
543 {
544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
545 FL("Starting inactivity timer failed on AC %d"), acType);
546 return vos_status;
547 }
548 pAc->wmmInactivityTime = inactivityTime;
549 // Initialize the current tx traffic count on this AC
550 pAc->wmmPrevTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];
551
552 return vos_status;
553}
554
555/**
556 @brief hdd_wmm_enable_inactivity_timer() - function to disable the
557 traffic inactivity timer for the given AC. This would be called when
558 deleting the TS.
559
560 @param pQosContext : [in] pointer to pQosContext
561
562 @return : VOS_STATUS_E_FAILURE
563 VOS_STATUS_SUCCESS
564*/
565VOS_STATUS hdd_wmm_disable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext)
566{
567 hdd_adapter_t* pAdapter = pQosContext->pAdapter;
568 WLANTL_ACEnumType acType = pQosContext->acType;
569 hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
570 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
571
572 // Clear the timer and the counter
573 pAc->wmmInactivityTime = 0;
574 pAc->wmmPrevTrafficCnt = 0;
575 vos_timer_stop(&pAc->wmmInactivityTimer);
576 vos_status = vos_timer_destroy(&pAc->wmmInactivityTimer);
577
578 return vos_status;
579}
580#endif // FEATURE_WLAN_CCX
581
582/**
583 @brief hdd_wmm_sme_callback() - callback registered by HDD with SME for receiving
584 QoS notifications. Even though this function has a static scope it gets called
585 externally through some function pointer magic (so there is a need for
586 rigorous parameter checking)
587
588 @param hHal : [in] the HAL handle
589 @param HddCtx : [in] the HDD specified handle
590 @param pCurrentQosInfo : [in] the TSPEC params
591 @param SmeStatus : [in] the QoS related SME status
592
593 @return
594 eHAL_STATUS_SUCCESS if all good, eHAL_STATUS_FAILURE otherwise
595*/
596static eHalStatus hdd_wmm_sme_callback (tHalHandle hHal,
597 void * hddCtx,
598 sme_QosWmmTspecInfo* pCurrentQosInfo,
599 sme_QosStatusType smeStatus,
600 v_U32_t qosFlowId)
601{
602 hdd_wmm_qos_context_t* pQosContext = hddCtx;
603 hdd_adapter_t* pAdapter;
604 WLANTL_ACEnumType acType;
605 hdd_wmm_ac_status_t *pAc;
606 VOS_STATUS status;
607
608 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
609 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700610 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700611
612 if (unlikely((NULL == pQosContext) ||
613 (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
614 {
615 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
616 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700617 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700618 return eHAL_STATUS_FAILURE;
619 }
620
621 pAdapter = pQosContext->pAdapter;
622 acType = pQosContext->acType;
623 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
624
625 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
626 "%s: status %d flowid %d info %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700627 __func__, smeStatus, qosFlowId, pCurrentQosInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -0700628
629 switch (smeStatus)
630 {
631
632 case SME_QOS_STATUS_SETUP_SUCCESS_IND:
633 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
634 "%s: Setup is complete",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700635 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700636
637 // there will always be a TSPEC returned with this status, even if
638 // a TSPEC is not exchanged OTA
639 if (pCurrentQosInfo)
640 {
641 pAc->wmmAcTspecValid = VOS_TRUE;
642 memcpy(&pAc->wmmAcTspecInfo,
643 pCurrentQosInfo,
644 sizeof(pAc->wmmAcTspecInfo));
645 }
646
647 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
648 {
649
650 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
651 "%s: Implicit Qos, notifying TL for TL AC %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700652 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700653
654 // this was triggered by implicit QoS so we know packets are pending
655 // update state
656 pAc->wmmAcAccessAllowed = VOS_TRUE;
657 pAc->wmmAcAccessGranted = VOS_TRUE;
658 pAc->wmmAcAccessPending = VOS_FALSE;
659
660 // notify TL that packets are pending
661 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
662 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
663 acType );
664
665 if ( !VOS_IS_STATUS_SUCCESS( status ) )
666 {
667 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
668 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700669 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700670 }
671 }
672 else
673 {
674 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
675 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700676 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700677
678 // this was triggered by an application
679 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
680 hdd_wmm_notify_app(pQosContext);
681 }
682
683#ifdef FEATURE_WLAN_CCX
684 // Check if the inactivity interval is specified
Jeff Johnson8795e422013-04-03 08:59:22 -0700685 if (pCurrentQosInfo && pCurrentQosInfo->inactivity_interval) {
Jeff Johnson295189b2012-06-20 16:38:30 -0700686 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
687 "%s: Inactivity timer value = %d for AC=%d\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700688 __func__, pCurrentQosInfo->inactivity_interval, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700689 hdd_wmm_enable_inactivity_timer(pQosContext, pCurrentQosInfo->inactivity_interval);
690 }
691#endif // FEATURE_WLAN_CCX
692
693 // notify TL to enable trigger frames if necessary
694 hdd_wmm_enable_tl_uapsd(pQosContext);
695
696 break;
697
698 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
699 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
700 "%s: Setup is complete (U-APSD set previously)",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700701 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700702
703 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
704 {
705
706 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
707 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700708 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700709
710 // this was triggered by implicit QoS so we know packets are pending
711 // update state
712 pAc->wmmAcAccessAllowed = VOS_TRUE;
713 pAc->wmmAcAccessGranted = VOS_TRUE;
714 pAc->wmmAcAccessPending = VOS_FALSE;
715
716 // notify TL that packets are pending
717 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
718 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
719 acType );
720
721 if ( !VOS_IS_STATUS_SUCCESS( status ) )
722 {
723 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
724 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700725 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700726 }
727 }
728 else
729 {
730 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
731 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700732 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700733
734 // this was triggered by an application
735 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
736 hdd_wmm_notify_app(pQosContext);
737 }
738
739 break;
740
741 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
742 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
743 "%s: Setup failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700744 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700745 // QoS setup failed
746
747 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
748 {
749
750 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
751 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700752 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700753
754 // we note the failure, but we also mark access as allowed so that
755 // the packets will flow. Note that the MAC will "do the right thing"
756 pAc->wmmAcAccessPending = VOS_FALSE;
757 pAc->wmmAcAccessFailed = VOS_TRUE;
758 pAc->wmmAcAccessAllowed = VOS_TRUE;
759
760 // this was triggered by implicit QoS so we know packets are pending
761 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
762 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
763 acType );
764
765 if ( !VOS_IS_STATUS_SUCCESS( status ) )
766 {
767 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
768 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700769 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700770 }
771 }
772 else
773 {
774 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
775 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700776 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700777
778 // this was triggered by an application
779 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED;
780 hdd_wmm_notify_app(pQosContext);
781 }
782
783 /* Setting up QoS Failed, QoS context can be released.
784 * SME is releasing this flow information and if HDD doen't release this context,
785 * next time if application uses the same handle to set-up QoS, HDD (as it has
786 * QoS context for this handle) will issue Modify QoS request to SME but SME will
787 * reject as no it has no information for this flow.
788 */
789 hdd_wmm_free_context(pQosContext);
790 break;
791
792 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
793 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
794 "%s: Setup Invalid Params, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700795 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700796 // QoS setup failed
797
798 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
799 {
800
801 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
802 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700803 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700804
805 // we note the failure, but we also mark access as allowed so that
806 // the packets will flow. Note that the MAC will "do the right thing"
807 pAc->wmmAcAccessPending = VOS_FALSE;
808 pAc->wmmAcAccessFailed = VOS_TRUE;
809 pAc->wmmAcAccessAllowed = VOS_TRUE;
810
811 // this was triggered by implicit QoS so we know packets are pending
812 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
813 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
814 acType );
815
816 if ( !VOS_IS_STATUS_SUCCESS( status ) )
817 {
818 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
819 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700820 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700821 }
822 }
823 else
824 {
825 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
826 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700827 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700828
829 // this was triggered by an application
830 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
831 hdd_wmm_notify_app(pQosContext);
832 }
833 break;
834
835 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
836 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
837 "%s: Setup failed, not a QoS AP\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700838 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700839 if (!HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
840 {
841 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
842 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700843 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700844
845 // this was triggered by an application
846 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
847 hdd_wmm_notify_app(pQosContext);
848 }
849 break;
850
851 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
852 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
853 "%s: Setup pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700854 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700855 // not a callback status -- ignore if we get it
856 break;
857
858 case SME_QOS_STATUS_SETUP_MODIFIED_IND:
859 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
860 "%s: Setup modified",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700861 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700862 if (pCurrentQosInfo)
863 {
864 // update the TSPEC
865 pAc->wmmAcTspecValid = VOS_TRUE;
866 memcpy(&pAc->wmmAcTspecInfo,
867 pCurrentQosInfo,
868 sizeof(pAc->wmmAcTspecInfo));
869
870 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
871 {
872 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
873 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700874 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700875
876 // this was triggered by an application
877 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFIED;
878 hdd_wmm_notify_app(pQosContext);
879 }
880
881 // need to tell TL to update its UAPSD handling
882 hdd_wmm_enable_tl_uapsd(pQosContext);
883 }
884 break;
885
886 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
887 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
888 {
889
890 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
891 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700892 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700893
894 // this was triggered by implicit QoS so we know packets are pending
895 pAc->wmmAcAccessPending = VOS_FALSE;
896 pAc->wmmAcAccessGranted = VOS_TRUE;
897 pAc->wmmAcAccessAllowed = VOS_TRUE;
898
899 // notify TL that packets are pending
900 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
901 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
902 acType );
903
904 if ( !VOS_IS_STATUS_SUCCESS( status ) )
905 {
906 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
907 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700908 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700909 }
910 }
911 else
912 {
913 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
914 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700915 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700916
917 // this was triggered by an application
918 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
919 hdd_wmm_notify_app(pQosContext);
920 }
921 break;
922
923 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
924 // nothing to do for now
925 break;
926
927 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED:
928 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
929 "%s: Setup successful but U-APSD failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700930 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700931
932 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
933 {
934
935 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
936 "%s: Implicit Qos, notifying TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700937 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700938
939 // QoS setup was successful but setting U=APSD failed
940 // Since the OTA part of the request was successful, we don't mark
941 // this as a failure.
942 // the packets will flow. Note that the MAC will "do the right thing"
943 pAc->wmmAcAccessGranted = VOS_TRUE;
944 pAc->wmmAcAccessAllowed = VOS_TRUE;
945 pAc->wmmAcAccessFailed = VOS_FALSE;
946 pAc->wmmAcAccessPending = VOS_FALSE;
947
948 // this was triggered by implicit QoS so we know packets are pending
949 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
950 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
951 acType );
952
953 if ( !VOS_IS_STATUS_SUCCESS( status ) )
954 {
955 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
956 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700957 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -0700958 }
959 }
960 else
961 {
962 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
963 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700964 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700965
966 // this was triggered by an application
967 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_UAPSD_SET_FAILED;
968 hdd_wmm_notify_app(pQosContext);
969 }
970
971 // Since U-APSD portion failed disabled trigger frame generation
972 hdd_wmm_disable_tl_uapsd(pQosContext);
973
974 break;
975
976 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
977 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
978 "%s: Release is complete",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700979 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700980
981 if (pCurrentQosInfo)
982 {
983 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
984 "%s: flows still active",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700985 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700986
987 // there is still at least one flow active for this AC
988 // so update the AC state
989 memcpy(&pAc->wmmAcTspecInfo,
990 pCurrentQosInfo,
991 sizeof(pAc->wmmAcTspecInfo));
992
993 // need to tell TL to update its UAPSD handling
994 hdd_wmm_enable_tl_uapsd(pQosContext);
995 }
996 else
997 {
998 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
999 "%s: last flow",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001000 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001001
1002 // this is the last flow active for this AC so update the AC state
1003 pAc->wmmAcTspecValid = VOS_FALSE;
1004
1005 // need to tell TL to update its UAPSD handling
1006 hdd_wmm_disable_tl_uapsd(pQosContext);
1007 }
1008
1009 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1010 {
1011 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1012 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001013 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001014
1015 // this was triggered by an application
1016 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
1017 hdd_wmm_notify_app(pQosContext);
1018 }
1019
1020 // we are done with this flow
1021 hdd_wmm_free_context(pQosContext);
1022 break;
1023
1024 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
1025 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1026 "%s: Release failure",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001027 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001028
1029 // we don't need to update our state or TL since nothing has changed
1030 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1031 {
1032 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1033 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001034 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001035
1036 // this was triggered by an application
1037 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
1038 hdd_wmm_notify_app(pQosContext);
1039 }
1040
1041 break;
1042
1043 case SME_QOS_STATUS_RELEASE_QOS_LOST_IND:
1044 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1045 "%s: QOS Lost indication received",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001046 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001047
1048 // current TSPEC is no longer valid
1049 pAc->wmmAcTspecValid = VOS_FALSE;
1050
1051 // need to tell TL to update its UAPSD handling
1052 hdd_wmm_disable_tl_uapsd(pQosContext);
1053
1054 if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
1055 {
1056 // we no longer have implicit access granted
1057 pAc->wmmAcAccessGranted = VOS_FALSE;
1058 pAc->wmmAcAccessFailed = VOS_FALSE;
1059 }
1060 else
1061 {
1062 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1063 "%s: Explicit Qos, notifying userspace",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001064 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001065
1066 // this was triggered by an application
1067 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_LOST;
1068 hdd_wmm_notify_app(pQosContext);
1069 }
1070
1071 // we are done with this flow
1072 hdd_wmm_free_context(pQosContext);
1073 break;
1074
1075 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
1076 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1077 "%s: Release pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001078 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001079 // not a callback status -- ignore if we get it
1080 break;
1081
1082 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
1083 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1084 "%s: Release Invalid Params",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001085 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001086 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1087 {
1088 // this was triggered by an application
1089 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
1090 hdd_wmm_notify_app(pQosContext);
1091 }
1092 break;
1093
1094 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND:
1095 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1096 "%s: Modification is complete, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001097 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001098
1099 // there will always be a TSPEC returned with this status, even if
1100 // a TSPEC is not exchanged OTA
1101 if (pCurrentQosInfo)
1102 {
1103 pAc->wmmAcTspecValid = VOS_TRUE;
1104 memcpy(&pAc->wmmAcTspecInfo,
1105 pCurrentQosInfo,
1106 sizeof(pAc->wmmAcTspecInfo));
1107 }
1108
1109 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1110 {
1111 // this was triggered by an application
1112 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS;
1113 hdd_wmm_notify_app(pQosContext);
1114 }
1115
1116 // notify TL to enable trigger frames if necessary
1117 hdd_wmm_enable_tl_uapsd(pQosContext);
1118
1119 break;
1120
1121 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
1122 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1123 {
1124 // this was triggered by an application
1125 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
1126 hdd_wmm_notify_app(pQosContext);
1127 }
1128 break;
1129
1130 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
1131 // the flow modification failed so we'll leave in place
1132 // whatever existed beforehand
1133
1134 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1135 {
1136 // this was triggered by an application
1137 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
1138 hdd_wmm_notify_app(pQosContext);
1139 }
1140 break;
1141
1142 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
1143 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1144 "%s: modification pending",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001145 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001146 // not a callback status -- ignore if we get it
1147 break;
1148
1149 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1150 // the flow modification was successful but no QoS changes required
1151
1152 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1153 {
1154 // this was triggered by an application
1155 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
1156 hdd_wmm_notify_app(pQosContext);
1157 }
1158 break;
1159
1160 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
1161 // invalid params -- notify the application
1162 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1163 {
1164 // this was triggered by an application
1165 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
1166 hdd_wmm_notify_app(pQosContext);
1167 }
1168 break;
1169
1170 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_PENDING:
1171 // nothing to do for now. when APSD is established we'll have work to do
1172 break;
1173
1174 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED:
1175 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1176 "%s: Modify successful but U-APSD failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001177 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001178
1179 // QoS modification was successful but setting U=APSD failed.
1180 // This will always be an explicit QoS instance, so all we can
1181 // do is notify the application and let it clean up.
1182 if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
1183 {
1184 // this was triggered by an application
1185 pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_UAPSD_SET_FAILED;
1186 hdd_wmm_notify_app(pQosContext);
1187 }
1188
1189 // Since U-APSD portion failed disabled trigger frame generation
1190 hdd_wmm_disable_tl_uapsd(pQosContext);
1191
1192 break;
1193
1194 case SME_QOS_STATUS_HANDING_OFF:
1195 // no roaming so we won't see this
1196 break;
1197
1198 case SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND:
1199 // need to tell TL to stop trigger frame generation
1200 hdd_wmm_disable_tl_uapsd(pQosContext);
1201 break;
1202
1203 case SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND:
1204 // need to tell TL to start sending trigger frames again
1205 hdd_wmm_enable_tl_uapsd(pQosContext);
1206 break;
1207
1208 default:
1209 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1210 "%s: unexpected SME Status=%d\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001211 __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07001212 VOS_ASSERT(0);
1213 }
1214
1215 // our access to the particular access category may have changed.
1216 // some of the implicit QoS cases above may have already set this
1217 // prior to invoking TL (so that we will properly service the
1218 // Tx queues) but let's consistently handle all cases here
1219 pAc->wmmAcAccessAllowed = hdd_wmm_is_access_allowed(pAdapter, pAc);
1220
1221 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1222 "%s: complete, access for TL AC %d is%sallowed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001223 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07001224 acType,
1225 pAc->wmmAcAccessAllowed ? " " : " not ");
1226
1227 return eHAL_STATUS_SUCCESS;
1228}
1229#endif
1230
1231/**============================================================================
1232 @brief hdd_wmm_do_implicit_qos() - Function which will attempt to setup
1233 QoS for any AC requiring it
1234
1235 @param work : [in] pointer to work structure
1236
1237 @return : void
1238 ===========================================================================*/
1239static void hdd_wmm_do_implicit_qos(struct work_struct *work)
1240{
1241 hdd_wmm_qos_context_t* pQosContext =
1242 container_of(work, hdd_wmm_qos_context_t, wmmAcSetupImplicitQos);
1243 hdd_adapter_t* pAdapter;
1244 WLANTL_ACEnumType acType;
1245 hdd_wmm_ac_status_t *pAc;
1246#ifndef WLAN_MDM_CODE_REDUCTION_OPT
1247 VOS_STATUS status;
1248 sme_QosStatusType smeStatus;
1249#endif
1250 sme_QosWmmTspecInfo qosInfo;
1251
1252 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1253 "%s: Entered, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001254 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001255
1256 if (unlikely(HDD_WMM_CTX_MAGIC != pQosContext->magic))
1257 {
1258 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1259 "%s: Invalid QoS Context",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001260 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001261 return;
1262 }
1263
1264 pAdapter = pQosContext->pAdapter;
1265 acType = pQosContext->acType;
1266 pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1267
1268 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1269 "%s: pAdapter %p acType %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001270 __func__, pAdapter, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001271
1272 if (!pAc->wmmAcAccessNeeded)
1273 {
1274 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1275 "%s: AC %d doesn't need service",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001276 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001277 pQosContext->magic = 0;
1278 kfree(pQosContext);
1279 return;
1280 }
1281
1282 pAc->wmmAcAccessPending = VOS_TRUE;
1283 pAc->wmmAcAccessNeeded = VOS_FALSE;
1284
1285 memset(&qosInfo, 0, sizeof(qosInfo));
1286
1287 switch (acType)
1288 {
1289 case WLANTL_AC_VO:
1290 qosInfo.ts_info.up = SME_QOS_WMM_UP_VO;
1291 qosInfo.ts_info.psb = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask & 0x01;
1292 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVo;
1293 qosInfo.ts_info.tid = 255;
1294 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVo;
1295 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVo;
1296 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv;
1297 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVo;
1298 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVo;
1299 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv;
1300 break;
1301 case WLANTL_AC_VI:
1302 qosInfo.ts_info.up = SME_QOS_WMM_UP_VI;
1303 qosInfo.ts_info.psb = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask & 0x02;
1304 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVi;
1305 qosInfo.ts_info.tid = 255;
1306 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVi;
1307 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVi;
1308 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv;
1309 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVi;
1310 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVi;
1311 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv;
1312 break;
1313 default:
1314 case WLANTL_AC_BE:
1315 qosInfo.ts_info.up = SME_QOS_WMM_UP_BE;
1316 qosInfo.ts_info.psb = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask & 0x08;
1317 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBe;
1318 qosInfo.ts_info.tid = 255;
1319 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBe;
1320 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBe;
1321 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv;
1322 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBe;
1323 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBe;
1324 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv;
1325 break;
1326 case WLANTL_AC_BK:
1327 qosInfo.ts_info.up = SME_QOS_WMM_UP_BK;
1328 qosInfo.ts_info.psb = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask & 0x04;
1329 qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBk;
1330 qosInfo.ts_info.tid = 255;
1331 qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBk;
1332 qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBk;
1333 qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv;
1334 qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBk;
1335 qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBk;
1336 qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv;
1337 break;
1338 }
1339#ifdef FEATURE_WLAN_CCX
1340 qosInfo.inactivity_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraInactivityInterval;
1341#endif
1342 qosInfo.ts_info.burst_size_defn = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->burstSizeDefinition;
1343
1344 switch ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->tsInfoAckPolicy)
1345 {
1346 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK:
1347 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1348 break;
1349
1350 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
1351 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
1352 break;
1353
1354 default:
1355 // unknown
1356 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1357 }
1358
1359 if(qosInfo.ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK)
1360 {
1361 if(!sme_QosIsTSInfoAckPolicyValid((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter), &qosInfo, pAdapter->sessionId))
1362 {
1363 qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1364 }
1365 }
1366
1367 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
1368 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
1369 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
1370
1371#ifndef WLAN_MDM_CODE_REDUCTION_OPT
1372 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
1373 pAdapter->sessionId,
1374 &qosInfo,
1375 hdd_wmm_sme_callback,
1376 pQosContext,
1377 qosInfo.ts_info.up,
1378 &pQosContext->qosFlowId);
1379
1380 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1381 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001382 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001383
1384 // need to check the return values and act appropriately
1385 switch (smeStatus)
1386 {
1387 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
1388 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
1389 // setup is pending, so no more work to do now.
1390 // all further work will be done in hdd_wmm_sme_callback()
1391 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1392 "%s: Setup is pending, no further work",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001393 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001394
1395 break;
1396
1397
1398 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
1399 // we can't tell the difference between when a request fails because
1400 // AP rejected it versus when SME encountered an internal error
1401
1402 // in either case SME won't ever reference this context so
1403 // free the record
1404 hdd_wmm_free_context(pQosContext);
1405
1406 // fall through and start packets flowing
1407 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1408 // no ACM in effect, no need to setup U-APSD
1409 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
1410 // no ACM in effect, U-APSD is desired but was already setup
1411
1412 // for these cases everything is already setup so we can
1413 // signal TL that it has work to do
1414 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1415 "%s: Setup is complete, notify TL",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001416 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001417
1418 pAc->wmmAcAccessAllowed = VOS_TRUE;
1419 pAc->wmmAcAccessGranted = VOS_TRUE;
1420 pAc->wmmAcAccessPending = VOS_FALSE;
1421
1422 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1423 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
1424 acType );
1425
1426 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1427 {
1428 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1429 "%s: Failed to signal TL for AC=%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001430 __func__, acType );
Jeff Johnson295189b2012-06-20 16:38:30 -07001431 }
1432
1433 break;
1434
1435
1436 default:
1437 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1438 "%s: unexpected SME Status=%d\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001439 __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07001440 VOS_ASSERT(0);
1441 }
1442#endif
1443
1444}
1445
1446/**============================================================================
1447 @brief hdd_wmm_init() - Function which will initialize the WMM configuation
1448 and status to an initial state. The configuration can later be overwritten
1449 via application APIs
1450
1451 @param pHddCtx : [in] pointer to HDD context
1452
1453 @return : VOS_STATUS_SUCCESS if succssful
1454 : other values if failure
1455
1456 ===========================================================================*/
1457VOS_STATUS hdd_wmm_init ( hdd_context_t* pHddCtx )
1458{
1459 v_U8_t dscp;
1460
1461 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001462 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001463
1464 // DSCP to User Priority Lookup Table
1465 for (dscp = 0; dscp <= WLAN_HDD_MAX_DSCP; dscp++)
1466 {
1467 hddWmmDscpToUpMap[dscp] = SME_QOS_WMM_UP_BE;
1468 }
1469 hddWmmDscpToUpMap[8] = SME_QOS_WMM_UP_BK;
1470 hddWmmDscpToUpMap[16] = SME_QOS_WMM_UP_RESV;
1471 hddWmmDscpToUpMap[24] = SME_QOS_WMM_UP_EE;
1472 hddWmmDscpToUpMap[32] = SME_QOS_WMM_UP_CL;
1473 hddWmmDscpToUpMap[40] = SME_QOS_WMM_UP_VI;
1474 hddWmmDscpToUpMap[48] = SME_QOS_WMM_UP_VO;
1475 hddWmmDscpToUpMap[56] = SME_QOS_WMM_UP_NC;
1476
1477 return VOS_STATUS_SUCCESS;
1478}
1479
1480/**============================================================================
1481 @brief hdd_wmm_adapter_init() - Function which will initialize the WMM configuation
1482 and status to an initial state. The configuration can later be overwritten
1483 via application APIs
1484
1485 @param pAdapter : [in] pointer to Adapter context
1486
1487 @return : VOS_STATUS_SUCCESS if succssful
1488 : other values if failure
1489
1490 ===========================================================================*/
1491VOS_STATUS hdd_wmm_adapter_init( hdd_adapter_t *pAdapter )
1492{
1493 hdd_wmm_ac_status_t *pAcStatus;
1494 WLANTL_ACEnumType acType;
1495
1496 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001497 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001498
1499 pAdapter->hddWmmStatus.wmmQap = VOS_FALSE;
1500 INIT_LIST_HEAD(&pAdapter->hddWmmStatus.wmmContextList);
1501 mutex_init(&pAdapter->hddWmmStatus.wmmLock);
1502
1503 for (acType = 0; acType < WLANTL_MAX_AC; acType++)
1504 {
1505 pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
1506 pAcStatus->wmmAcAccessRequired = VOS_FALSE;
1507 pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
1508 pAcStatus->wmmAcAccessPending = VOS_FALSE;
1509 pAcStatus->wmmAcAccessFailed = VOS_FALSE;
1510 pAcStatus->wmmAcAccessGranted = VOS_FALSE;
1511 pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
1512 pAcStatus->wmmAcTspecValid = VOS_FALSE;
1513 pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
1514 }
1515
1516 return VOS_STATUS_SUCCESS;
1517}
1518/**============================================================================
1519 @brief hdd_wmm_close() - Function which will perform any necessary work to
1520 to clean up the WMM functionality prior to the kernel module unload
1521
1522 @param pAdapter : [in] pointer to adapter context
1523
1524 @return : VOS_STATUS_SUCCESS if succssful
1525 : other values if failure
1526
1527 ===========================================================================*/
1528VOS_STATUS hdd_wmm_adapter_close ( hdd_adapter_t* pAdapter )
1529{
1530 hdd_wmm_qos_context_t* pQosContext;
1531
1532 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001533 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001534
1535 // free any context records that we still have linked
1536 while (!list_empty(&pAdapter->hddWmmStatus.wmmContextList))
1537 {
1538 pQosContext = list_first_entry(&pAdapter->hddWmmStatus.wmmContextList,
1539 hdd_wmm_qos_context_t, node);
1540#ifdef FEATURE_WLAN_CCX
1541 hdd_wmm_disable_inactivity_timer(pQosContext);
1542#endif
1543 hdd_wmm_free_context(pQosContext);
1544 }
1545
1546 return VOS_STATUS_SUCCESS;
1547}
1548
1549/**============================================================================
1550 @brief hdd_wmm_classify_pkt() - Function which will classify an OS packet
1551 into a WMM AC based on either 802.1Q or DSCP
1552
1553 @param pAdapter : [in] pointer to adapter context
1554 @param skb : [in] pointer to OS packet (sk_buff)
1555 @param pAcType : [out] pointer to WMM AC type of OS packet
1556
1557 @return : None
1558 ===========================================================================*/
1559v_VOID_t hdd_wmm_classify_pkt ( hdd_adapter_t* pAdapter,
1560 struct sk_buff *skb,
1561 WLANTL_ACEnumType* pAcType,
1562 sme_QosWmmUpType *pUserPri)
1563{
1564 unsigned char * pPkt;
1565 union generic_ethhdr *pHdr;
1566 struct iphdr *pIpHdr;
1567 unsigned char tos;
1568 unsigned char dscp;
1569 sme_QosWmmUpType userPri;
1570 WLANTL_ACEnumType acType;
1571
1572 // this code is executed for every packet therefore
1573 // all debug code is kept conditional
1574
1575#ifdef HDD_WMM_DEBUG
1576 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001577 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001578#endif // HDD_WMM_DEBUG
1579
1580 pPkt = skb->data;
1581 pHdr = (union generic_ethhdr *)pPkt;
1582
1583#ifdef HDD_WMM_DEBUG
1584 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1585 "%s: proto/length is 0x%04x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001586 __func__, pHdr->eth_II.h_proto);
Jeff Johnson295189b2012-06-20 16:38:30 -07001587#endif // HDD_WMM_DEBUG
1588
1589 if (HDD_WMM_CLASSIFICATION_DSCP == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
1590 {
1591 if (pHdr->eth_II.h_proto == htons(ETH_P_IP))
1592 {
1593 // case 1: Ethernet II IP packet
1594 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_II)];
1595 tos = pIpHdr->tos;
1596#ifdef HDD_WMM_DEBUG
1597 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1598 "%s: Ethernet II IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001599 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001600#endif // HDD_WMM_DEBUG
1601
1602 }
1603 else if ((ntohs(pHdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
1604 (pHdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
1605 (pHdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
1606 (pHdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1607 (pHdr->eth_8023.h_proto == htons(ETH_P_IP)))
1608 {
1609 // case 2: 802.3 LLC/SNAP IP packet
1610 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];
1611 tos = pIpHdr->tos;
1612#ifdef HDD_WMM_DEBUG
1613 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1614 "%s: 802.3 LLC/SNAP IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001615 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001616#endif // HDD_WMM_DEBUG
1617 }
1618 else if (pHdr->eth_II.h_proto == htons(ETH_P_8021Q))
1619 {
1620 // VLAN tagged
1621
1622 if (pHdr->eth_IIv.h_vlan_encapsulated_proto == htons(ETH_P_IP))
1623 {
1624 // case 3: Ethernet II vlan-tagged IP packet
1625 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_IIv)];
1626 tos = pIpHdr->tos;
1627#ifdef HDD_WMM_DEBUG
1628 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1629 "%s: Ethernet II VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001630 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001631#endif // HDD_WMM_DEBUG
1632 }
1633 else if ((ntohs(pHdr->eth_IIv.h_vlan_encapsulated_proto) < WLAN_MIN_PROTO) &&
1634 (pHdr->eth_8023v.h_snap.dsap == WLAN_SNAP_DSAP) &&
1635 (pHdr->eth_8023v.h_snap.ssap == WLAN_SNAP_SSAP) &&
1636 (pHdr->eth_8023v.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1637 (pHdr->eth_8023v.h_proto == htons(ETH_P_IP)))
1638 {
1639 // case 4: 802.3 LLC/SNAP vlan-tagged IP packet
1640 pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023v)];
1641 tos = pIpHdr->tos;
1642#ifdef HDD_WMM_DEBUG
1643 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1644 "%s: 802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001645 __func__, tos);
Jeff Johnson295189b2012-06-20 16:38:30 -07001646#endif // HDD_WMM_DEBUG
1647 }
1648 else
1649 {
1650 // default
1651#ifdef HDD_WMM_DEBUG
1652 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1653 "%s: VLAN tagged Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001654 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001655#endif // HDD_WMM_DEBUG
1656 tos = 0;
1657 }
1658 }
1659 else
1660 {
1661 // default
1662#ifdef HDD_WMM_DEBUG
1663 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1664 "%s: Unhandled Protocol, using default tos",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001665 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001666#endif // HDD_WMM_DEBUG
1667 //Give the highest priority to 802.1x packet
1668 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
1669 tos = 0xC0;
1670 else
1671 tos = 0;
1672 }
1673
1674 dscp = (tos>>2) & 0x3f;
1675 userPri = hddWmmDscpToUpMap[dscp];
1676
1677#ifdef HDD_WMM_DEBUG
1678 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1679 "%s: tos is %d, dscp is %d, up is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001680 __func__, tos, dscp, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07001681#endif // HDD_WMM_DEBUG
1682
1683 }
1684 else if (HDD_WMM_CLASSIFICATION_802_1Q == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
1685 {
1686 if (pHdr->eth_IIv.h_vlan_proto == htons(ETH_P_8021Q))
1687 {
1688 // VLAN tagged
1689 userPri = (ntohs(pHdr->eth_IIv.h_vlan_TCI)>>13) & 0x7;
1690#ifdef HDD_WMM_DEBUG
1691 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1692 "%s: Tagged frame, UP is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001693 __func__, userPri);
Jeff Johnson295189b2012-06-20 16:38:30 -07001694#endif // HDD_WMM_DEBUG
1695 }
1696 else
1697 {
1698 // not VLAN tagged, use default
1699#ifdef HDD_WMM_DEBUG
1700 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
1701 "%s: Untagged frame, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001702 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001703#endif // HDD_WMM_DEBUG
1704 //Give the highest priority to 802.1x packet
1705 if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
1706 userPri = SME_QOS_WMM_UP_VO;
1707 else
1708 userPri = SME_QOS_WMM_UP_BE;
1709 }
1710 }
1711 else
1712 {
1713 // default
1714#ifdef HDD_WMM_DEBUG
1715 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
1716 "%s: Unknown classification scheme, using default UP",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001717 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001718#endif // HDD_WMM_DEBUG
1719 userPri = SME_QOS_WMM_UP_BE;
1720 }
1721
1722 acType = hddWmmUpToAcMap[userPri];
1723
1724#ifdef HDD_WMM_DEBUG
1725 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1726 "%s: UP is %d, AC is %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001727 __func__, userPri, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001728#endif // HDD_WMM_DEBUG
1729
1730 *pUserPri = userPri;
1731 *pAcType = acType;
1732
1733 return;
1734}
1735
1736/**============================================================================
1737 @brief hdd_hostapd_select_quueue() - Function which will classify the packet
1738 according to linux qdisc expectation.
1739
1740
1741 @param dev : [in] pointer to net_device structure
1742 @param skb : [in] pointer to os packet
1743
1744 @return : Qdisc queue index
1745 ===========================================================================*/
1746v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb)
1747{
1748 WLANTL_ACEnumType ac;
1749 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
1750 v_USHORT_t queueIndex;
1751 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
1752 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
1753 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001754 v_U8_t STAId;
1755 v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
1756
1757 /*Get the Station ID*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001758 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &STAId))
1759 {
Madan Mohan Koyyalamudif1d39952012-10-31 15:18:40 -07001760 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001761 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001762 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1763 goto done;
1764 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001765
1766 spin_lock_bh( &pAdapter->staInfo_lock );
1767 if (FALSE == vos_is_macaddr_equal(&pAdapter->aStaInfo[STAId].macAddrSTA, pDestMacAddress))
1768 {
1769 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001770 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001771
1772 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1773 goto release_lock;
1774 }
1775 if (pAdapter->aStaInfo[STAId].isUsed && pAdapter->aStaInfo[STAId].isQosEnabled && (HDD_WMM_USER_MODE_NO_QOS != pHddCtx->cfg_ini->WmmMode))
1776 {
1777 /* Get the user priority from IP header & corresponding AC */
1778 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
1779 }
1780 *pSTAId = STAId;
1781
1782release_lock:
1783 spin_unlock_bh( &pAdapter->staInfo_lock );
1784done:
1785 skb->priority = up;
1786 queueIndex = hddLinuxUpToAcMap[skb->priority];
1787
1788 return queueIndex;
1789}
1790
1791/**============================================================================
1792 @brief hdd_wmm_select_quueue() - Function which will classify the packet
1793 according to linux qdisc expectation.
1794
1795
1796 @param dev : [in] pointer to net_device structure
1797 @param skb : [in] pointer to os packet
1798
1799 @return : Qdisc queue index
1800 ===========================================================================*/
1801v_U16_t hdd_wmm_select_queue(struct net_device * dev, struct sk_buff *skb)
1802{
1803 WLANTL_ACEnumType ac;
Shailender Karmuchia734f332013-04-19 14:02:48 -07001804 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001805 v_USHORT_t queueIndex;
Jeff Johnson295189b2012-06-20 16:38:30 -07001806 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1807
Shailender Karmuchia734f332013-04-19 14:02:48 -07001808 /*Get the Station ID*/
1809 if (WLAN_HDD_IBSS == pAdapter->device_mode)
1810 {
1811 v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
1812 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
1813
1814 if ( VOS_STATUS_SUCCESS !=
1815 hdd_Ibss_GetStaId(&pAdapter->sessionCtx.station,
1816 pDestMacAddress, pSTAId))
1817 {
1818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnsonb9fb9ce2013-05-03 08:11:02 -07001819 "%s: Failed to find right station pDestMacAddress: "
1820 MAC_ADDRESS_STR , __func__,
1821 MAC_ADDR_ARRAY(pDestMacAddress->bytes));
Shailender Karmuchia734f332013-04-19 14:02:48 -07001822 *pSTAId = HDD_WLAN_INVALID_STA_ID;
1823 goto done;
1824 }
1825 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001826 // if we don't want QoS or the AP doesn't support Qos
1827 // All traffic will get equal opportuniy to transmit data frames.
1828 if( hdd_wmm_is_active(pAdapter) ) {
1829 /* Get the user priority from IP header & corresponding AC */
1830 hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
1831 }
Shailender Karmuchia734f332013-04-19 14:02:48 -07001832done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001833 skb->priority = up;
1834 queueIndex = hddLinuxUpToAcMap[skb->priority];
1835
1836 return queueIndex;
1837}
1838
1839/**============================================================================
1840 @brief hdd_wmm_acquire_access() - Function which will attempt to acquire
1841 admittance for a WMM AC
1842
1843 @param pAdapter : [in] pointer to adapter context
1844 @param acType : [in] WMM AC type of OS packet
1845 @param pGranted : [out] pointer to boolean flag when indicates if access
1846 has been granted or not
1847
1848 @return : VOS_STATUS_SUCCESS if succssful
1849 : other values if failure
1850 ===========================================================================*/
1851VOS_STATUS hdd_wmm_acquire_access( hdd_adapter_t* pAdapter,
1852 WLANTL_ACEnumType acType,
1853 v_BOOL_t * pGranted )
1854{
1855 hdd_wmm_qos_context_t *pQosContext;
1856
1857 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001858 "%s: Entered for AC %d", __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001859
1860 if (!hdd_wmm_is_active(pAdapter) || !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
1861 {
1862 // either we don't want QoS or the AP doesn't support QoS
1863 // or we don't want to do implicit QoS
1864 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001865 "%s: QoS not configured on both ends ", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001866
1867 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
1868 *pGranted = VOS_TRUE;
1869 return VOS_STATUS_SUCCESS;
1870 }
1871
1872 // do we already have an implicit QoS request pending for this AC?
1873 if ((pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded) ||
1874 (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessPending))
1875 {
1876 // request already pending so we need to wait for that response
1877 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1878 "%s: Implicit QoS for TL AC %d already scheduled",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001879 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001880
1881 *pGranted = VOS_FALSE;
1882 return VOS_STATUS_SUCCESS;
1883 }
1884
1885 // did we already fail to establish implicit QoS for this AC?
1886 // (if so, access should have been granted when the failure was handled)
1887 if (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessFailed)
1888 {
1889 // request previously failed
1890 // allow access, but we'll be downgraded
1891 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
1892 "%s: Implicit QoS for TL AC %d previously failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001893 __func__, acType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001894
1895 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
1896 *pGranted = VOS_TRUE;
1897 return VOS_STATUS_SUCCESS;
1898 }
1899
1900 // we need to establish implicit QoS
1901 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1902 "%s: Need to schedule implicit QoS for TL AC %d, pAdapter is %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001903 __func__, acType, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001904
1905 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded = VOS_TRUE;
1906
Mohit Khanna217ea8d2012-09-11 17:42:42 -07001907 pQosContext = kmalloc(sizeof(*pQosContext), GFP_ATOMIC);
Jeff Johnson295189b2012-06-20 16:38:30 -07001908 if (NULL == pQosContext)
1909 {
1910 // no memory for QoS context. Nothing we can do but let data flow
1911 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001912 "%s: Unable to allocate context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001913 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
1914 *pGranted = VOS_TRUE;
1915 return VOS_STATUS_SUCCESS;
1916 }
1917
1918 pQosContext->acType = acType;
1919 pQosContext->pAdapter = pAdapter;
1920 pQosContext->qosFlowId = 0;
1921 pQosContext->handle = HDD_WMM_HANDLE_IMPLICIT;
1922 pQosContext->magic = HDD_WMM_CTX_MAGIC;
1923 INIT_WORK(&pQosContext->wmmAcSetupImplicitQos,
1924 hdd_wmm_do_implicit_qos);
1925
1926 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
1927 "%s: Scheduling work for AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001928 __func__, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001929
1930 schedule_work(&pQosContext->wmmAcSetupImplicitQos);
1931
1932 // caller will need to wait until the work takes place and
1933 // TSPEC negotiation completes
1934 *pGranted = VOS_FALSE;
1935 return VOS_STATUS_SUCCESS;
1936}
1937
1938/**============================================================================
1939 @brief hdd_wmm_assoc() - Function which will handle the housekeeping
1940 required by WMM when association takes place
1941
1942 @param pAdapter : [in] pointer to adapter context
1943 @param pRoamInfo: [in] pointer to roam information
1944 @param eBssType : [in] type of BSS
1945
1946 @return : VOS_STATUS_SUCCESS if succssful
1947 : other values if failure
1948 ===========================================================================*/
1949VOS_STATUS hdd_wmm_assoc( hdd_adapter_t* pAdapter,
1950 tCsrRoamInfo *pRoamInfo,
1951 eCsrRoamBssType eBssType )
1952{
1953 tANI_U8 uapsdMask;
1954 VOS_STATUS status;
1955
1956 // when we associate we need to notify TL if it needs to enable
1957 // UAPSD for any access categories
1958
1959 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001960 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001961
1962 if (pRoamInfo->fReassocReq)
1963 {
1964 // when we reassociate we should continue to use whatever
1965 // parameters were previously established. if we are
1966 // reassociating due to a U-APSD change for a particular
1967 // Access Category, then the change will be communicated
1968 // to HDD via the QoS callback associated with the given
1969 // flow, and U-APSD parameters will be updated there
1970
1971 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001972 "%s: Reassoc so no work, Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001973
1974 return VOS_STATUS_SUCCESS;
1975 }
1976
1977 // get the negotiated UAPSD Mask
1978 uapsdMask = pRoamInfo->u.pConnectedProfile->modifyProfileFields.uapsd_mask;
1979
1980 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001981 "%s: U-APSD mask is 0x%02x", __func__, (int) uapsdMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07001982
1983 if (uapsdMask & HDD_AC_VO)
1984 {
1985 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1986 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
1987 WLANTL_AC_VO,
1988 7,
1989 7,
1990 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv,
1991 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv,
1992 WLANTL_BI_DIR );
1993
1994 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
1995 }
1996
1997 if (uapsdMask & HDD_AC_VI)
1998 {
1999 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2000 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2001 WLANTL_AC_VI,
2002 5,
2003 5,
2004 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv,
2005 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv,
2006 WLANTL_BI_DIR );
2007
2008 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2009 }
2010
2011 if (uapsdMask & HDD_AC_BK)
2012 {
2013 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2014 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2015 WLANTL_AC_BK,
2016 2,
2017 2,
2018 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv,
2019 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv,
2020 WLANTL_BI_DIR );
2021
2022 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2023 }
2024
2025 if (uapsdMask & HDD_AC_BE)
2026 {
2027 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2028 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
2029 WLANTL_AC_BE,
2030 3,
2031 3,
2032 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv,
2033 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv,
2034 WLANTL_BI_DIR );
2035
2036 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
2037 }
2038
2039 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002040 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002041
2042 return VOS_STATUS_SUCCESS;
2043}
2044
2045
2046
2047static const v_U8_t acmMaskBit[WLANTL_MAX_AC] =
2048 {
2049 0x4, /* WLANTL_AC_BK */
2050 0x8, /* WLANTL_AC_BE */
2051 0x2, /* WLANTL_AC_VI */
2052 0x1 /* WLANTL_AC_VO */
2053 };
2054
2055/**============================================================================
2056 @brief hdd_wmm_connect() - Function which will handle the housekeeping
2057 required by WMM when a connection is established
2058
2059 @param pAdapter : [in] pointer to adapter context
2060 @param pRoamInfo: [in] pointer to roam information
2061 @param eBssType : [in] type of BSS
2062
2063 @return : VOS_STATUS_SUCCESS if succssful
2064 : other values if failure
2065 ===========================================================================*/
2066VOS_STATUS hdd_wmm_connect( hdd_adapter_t* pAdapter,
2067 tCsrRoamInfo *pRoamInfo,
2068 eCsrRoamBssType eBssType )
2069{
2070 int ac;
2071 v_BOOL_t qap;
2072 v_BOOL_t qosConnection;
2073 v_U8_t acmMask;
2074
2075 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002076 "%s: Entered", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002077
2078 if ((eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) &&
2079 pRoamInfo &&
2080 pRoamInfo->u.pConnectedProfile)
2081 {
2082 qap = pRoamInfo->u.pConnectedProfile->qap;
2083 qosConnection = pRoamInfo->u.pConnectedProfile->qosConnection;
2084 acmMask = pRoamInfo->u.pConnectedProfile->acm_mask;
2085 }
2086 else
2087 {
2088 qap = VOS_TRUE;
2089 qosConnection = VOS_TRUE;
2090 acmMask = 0x0;
2091 }
2092
2093 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2094 "%s: qap is %d, qosConnection is %d, acmMask is 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002095 __func__, qap, qosConnection, acmMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002096
2097 pAdapter->hddWmmStatus.wmmQap = qap;
2098 pAdapter->hddWmmStatus.wmmQosConnection = qosConnection;
2099
2100 for (ac = 0; ac < WLANTL_MAX_AC; ac++)
2101 {
2102 if (qap &&
2103 qosConnection &&
2104 (acmMask & acmMaskBit[ac]))
2105 {
2106 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2107 "%s: ac %d on",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002108 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002109
2110 // admission is required
2111 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_TRUE;
2112 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_FALSE;
2113 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessGranted = VOS_FALSE;
2114 }
2115 else
2116 {
2117 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2118 "%s: ac %d off",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002119 __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002120 // admission is not required so access is allowed
2121 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_FALSE;
2122 pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_TRUE;
2123 }
2124
2125 }
2126
2127 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002128 "%s: Exiting", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002129
2130 return VOS_STATUS_SUCCESS;
2131}
2132
2133/**============================================================================
2134 @brief hdd_wmm_get_uapsd_mask() - Function which will calculate the
2135 initial value of the UAPSD mask based upon the device configuration
2136
2137 @param pAdapter : [in] pointer to adapter context
2138 @param pUapsdMask: [in] pointer to where the UAPSD Mask is to be stored
2139
2140 @return : VOS_STATUS_SUCCESS if succssful
2141 : other values if failure
2142 ===========================================================================*/
2143VOS_STATUS hdd_wmm_get_uapsd_mask( hdd_adapter_t* pAdapter,
2144 tANI_U8 *pUapsdMask )
2145{
2146 tANI_U8 uapsdMask;
2147
2148 if (HDD_WMM_USER_MODE_NO_QOS == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
2149 {
2150 // no QOS then no UAPSD
2151 uapsdMask = 0;
2152 }
2153 else
2154 {
2155 // start with the default mask
2156 uapsdMask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
2157
2158 // disable UAPSD for any ACs with a 0 Service Interval
2159 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv == 0 )
2160 {
2161 uapsdMask &= ~HDD_AC_VO;
2162 }
2163
2164 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv == 0 )
2165 {
2166 uapsdMask &= ~HDD_AC_VI;
2167 }
2168
2169 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv == 0 )
2170 {
2171 uapsdMask &= ~HDD_AC_BK;
2172 }
2173
2174 if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv == 0 )
2175 {
2176 uapsdMask &= ~HDD_AC_BE;
2177 }
2178 }
2179
2180 // return calculated mask
2181 *pUapsdMask = uapsdMask;
2182 return VOS_STATUS_SUCCESS;
2183}
2184
2185
2186/**============================================================================
2187 @brief hdd_wmm_is_active() - Function which will determine if WMM is
2188 active on the current connection
2189
2190 @param pAdapter : [in] pointer to adapter context
2191
2192 @return : VOS_TRUE if WMM is enabled
2193 : VOS_FALSE if WMM is not enabled
2194 ===========================================================================*/
2195v_BOOL_t hdd_wmm_is_active( hdd_adapter_t* pAdapter )
2196{
2197 if ((!pAdapter->hddWmmStatus.wmmQosConnection) ||
2198 (!pAdapter->hddWmmStatus.wmmQap))
2199 {
2200 return VOS_FALSE;
2201 }
2202 else
2203 {
2204 return VOS_TRUE;
2205 }
2206}
2207
2208/**============================================================================
2209 @brief hdd_wmm_addts() - Function which will add a traffic spec at the
2210 request of an application
2211
2212 @param pAdapter : [in] pointer to adapter context
2213 @param handle : [in] handle to uniquely identify a TS
2214 @param pTspec : [in] pointer to the traffic spec
2215
2216 @return : HDD_WLAN_WMM_STATUS_*
2217 ===========================================================================*/
2218hdd_wlan_wmm_status_e hdd_wmm_addts( hdd_adapter_t* pAdapter,
2219 v_U32_t handle,
2220 sme_QosWmmTspecInfo* pTspec )
2221{
2222 hdd_wmm_qos_context_t *pQosContext;
2223 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2224#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2225 sme_QosStatusType smeStatus;
2226#endif
2227 v_BOOL_t found = VOS_FALSE;
2228
2229 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002230 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002231
2232 // see if a context already exists with the given handle
2233 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2234 list_for_each_entry(pQosContext,
2235 &pAdapter->hddWmmStatus.wmmContextList,
2236 node)
2237 {
2238 if (pQosContext->handle == handle)
2239 {
2240 found = VOS_TRUE;
2241 break;
2242 }
2243 }
2244 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2245 if (found)
2246 {
2247 // record with that handle already exists
2248 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
2249 "%s: Record already exists with handle 0x%x",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002250 __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002251
2252 /* Application is trying to modify some of the Tspec params. Allow it */
2253 smeStatus = sme_QosModifyReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2254 pTspec,
2255 pQosContext->qosFlowId);
2256
2257 // need to check the return value and act appropriately
2258 switch (smeStatus)
2259 {
2260 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
2261 status = HDD_WLAN_WMM_STATUS_MODIFY_PENDING;
2262 break;
2263 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2264 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
2265 break;
2266 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
2267 status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
2268 break;
2269 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
2270 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
2271 break;
2272 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
2273 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2274 break;
2275 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2276 status = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2277 break;
2278 default:
2279 // we didn't get back one of the SME_QOS_STATUS_MODIFY_* status codes
2280 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302281 "%s: unexpected SME Status=%d\n", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002282 VOS_ASSERT(0);
2283 return HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2284 }
2285
2286 // we were successful, save the status
2287 pQosContext->lastStatus = status;
2288 return status;
2289 }
2290
2291 pQosContext = kmalloc(sizeof(*pQosContext), GFP_KERNEL);
2292 if (NULL == pQosContext)
2293 {
2294 // no memory for QoS context. Nothing we can do
2295 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002296 "%s: Unable to allocate QoS context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002297 return HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE;
2298 }
2299
2300 // we assume the tspec has already been validated by the caller
2301
2302 pQosContext->handle = handle;
2303 pQosContext->acType = hddWmmUpToAcMap[pTspec->ts_info.up];
2304 pQosContext->pAdapter = pAdapter;
2305 pQosContext->qosFlowId = 0;
2306 pQosContext->magic = HDD_WMM_CTX_MAGIC;
2307
2308 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2309 "%s: Setting up QoS, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002310 __func__, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002311
2312 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2313 list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
2314 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2315
2316#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2317 smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
2318 pAdapter->sessionId,
2319 pTspec,
2320 hdd_wmm_sme_callback,
2321 pQosContext,
2322 pTspec->ts_info.up,
2323 &pQosContext->qosFlowId);
2324
2325 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
2326 "%s: sme_QosSetupReq returned %d flowid %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002327 __func__, smeStatus, pQosContext->qosFlowId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002328
2329 // need to check the return value and act appropriately
2330 switch (smeStatus)
2331 {
2332 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
2333 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2334 break;
2335 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2336 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
2337 break;
2338 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
2339 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
2340 break;
2341 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
2342 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2343 break;
2344 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
2345 hdd_wmm_free_context(pQosContext);
2346 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
2347 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
2348 // we can't tell the difference between when a request fails because
2349 // AP rejected it versus when SME encounterd an internal error
2350 hdd_wmm_free_context(pQosContext);
2351 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2352 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2353 hdd_wmm_free_context(pQosContext);
2354 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2355 default:
2356 // we didn't get back one of the SME_QOS_STATUS_SETUP_* status codes
2357 hdd_wmm_free_context(pQosContext);
2358 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302359 "%s: unexpected SME Status=%d\n", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002360 VOS_ASSERT(0);
2361 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2362 }
2363#endif
2364
2365 // we were successful, save the status
2366 pQosContext->lastStatus = status;
2367
2368 return status;
2369}
2370
2371/**============================================================================
2372 @brief hdd_wmm_delts() - Function which will delete a traffic spec at the
2373 request of an application
2374
2375 @param pAdapter : [in] pointer to adapter context
2376 @param handle : [in] handle to uniquely identify a TS
2377
2378 @return : HDD_WLAN_WMM_STATUS_*
2379 ===========================================================================*/
2380hdd_wlan_wmm_status_e hdd_wmm_delts( hdd_adapter_t* pAdapter,
2381 v_U32_t handle )
2382{
2383 hdd_wmm_qos_context_t *pQosContext;
2384 v_BOOL_t found = VOS_FALSE;
2385 WLANTL_ACEnumType acType = 0;
2386 v_U32_t qosFlowId = 0;
2387 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
2388#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2389 sme_QosStatusType smeStatus;
2390#endif
2391
2392 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002393 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002394
2395 // locate the context with the given handle
2396 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2397 list_for_each_entry(pQosContext,
2398 &pAdapter->hddWmmStatus.wmmContextList,
2399 node)
2400 {
2401 if (pQosContext->handle == handle)
2402 {
2403 found = VOS_TRUE;
2404 acType = pQosContext->acType;
2405 qosFlowId = pQosContext->qosFlowId;
2406 break;
2407 }
2408 }
2409 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2410
2411 if (VOS_FALSE == found)
2412 {
2413 // we didn't find the handle
2414 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002415 "%s: handle 0x%x not found", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002416 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2417 }
2418
2419
2420 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2421 "%s: found handle 0x%x, flow %d, AC %d, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002422 __func__, handle, qosFlowId, acType, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002423
2424#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2425 smeStatus = sme_QosReleaseReq( WLAN_HDD_GET_HAL_CTX(pAdapter), qosFlowId );
2426
2427 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2428 "%s: SME flow %d released, SME status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002429 __func__, qosFlowId, smeStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07002430
2431 switch(smeStatus)
2432 {
2433 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
2434 // this flow is the only one on that AC, so go ahead and update
2435 // our TSPEC state for the AC
2436 pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcTspecValid = VOS_FALSE;
2437
2438 // need to tell TL to stop trigger timer, etc
2439 hdd_wmm_disable_tl_uapsd(pQosContext);
2440
2441#ifdef FEATURE_WLAN_CCX
2442 // disable the inactivity timer
2443 hdd_wmm_disable_inactivity_timer(pQosContext);
2444#endif
2445 // we are done with this context
2446 hdd_wmm_free_context(pQosContext);
2447
2448 // SME must not fire any more callbacks for this flow since the context
2449 // is no longer valid
2450
2451 return HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
2452
2453 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
2454 // do nothing as we will get a response from SME
2455 status = HDD_WLAN_WMM_STATUS_RELEASE_PENDING;
2456 break;
2457
2458 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
2459 // nothing we can do with the existing flow except leave it
2460 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2461 break;
2462
2463 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
2464 // nothing we can do with the existing flow except leave it
2465 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2466
2467 default:
2468 // we didn't get back one of the SME_QOS_STATUS_RELEASE_* status codes
2469 VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302470 "%s: unexpected SME Status=%d\n", __func__, smeStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -07002471 VOS_ASSERT(0);
2472 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2473 }
2474
2475#endif
2476 pQosContext->lastStatus = status;
2477 return status;
2478}
2479
2480/**============================================================================
2481 @brief hdd_wmm_checkts() - Function which will return the status of a traffic
2482 spec at the request of an application
2483
2484 @param pAdapter : [in] pointer to adapter context
2485 @param handle : [in] handle to uniquely identify a TS
2486
2487 @return : HDD_WLAN_WMM_STATUS_*
2488 ===========================================================================*/
2489hdd_wlan_wmm_status_e hdd_wmm_checkts( hdd_adapter_t* pAdapter,
2490 v_U32_t handle )
2491{
2492 hdd_wmm_qos_context_t *pQosContext;
2493 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST;
2494
2495 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002496 "%s: Entered with handle 0x%x", __func__, handle);
Jeff Johnson295189b2012-06-20 16:38:30 -07002497
2498 // locate the context with the given handle
2499 mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
2500 list_for_each_entry(pQosContext,
2501 &pAdapter->hddWmmStatus.wmmContextList,
2502 node)
2503 {
2504 if (pQosContext->handle == handle)
2505 {
2506 VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
2507 "%s: found handle 0x%x, context %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002508 __func__, handle, pQosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002509
2510 status = pQosContext->lastStatus;
2511 break;
2512 }
2513 }
2514 mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
2515 return status;
2516}