blob: ec69451f8eecc5c62d09b470932f83f8be608d99 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
2 * Copyright (c) 2012, Code Aurora Forum. 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
22/*
23 *
24 * Airgo Networks, Inc proprietary. All rights reserved.
25 * This file contains TSPEC and STA admit control related functions
26 * NOTE: applies only to AP builds
27 *
28 * Author: Sandesh Goel
29 * Date: 02/25/02
30 * History:-
31 * Date Modified by Modification Information
32 * --------------------------------------------------------------------
33 *
34 */
35#include "limDebug.h"
36#include "sysDef.h"
37#include "limApi.h"
38#include "cfgApi.h" // wlan_cfgGetInt()
39#include "limTrace.h"
40#include "limSendSmeRspMessages.h"
41#include "limTypes.h"
42
43
44#define ADMIT_CONTROL_LOGLEVEL LOG1
45#define ADMIT_CONTROL_POLICY_LOGLEVEL LOG1
46#define ADMIT_CONTROL_MIN_INTERVAL 1000 // min acceptable service interval 1mSec
47
48/* total available bandwidth in bps in each phy mode
49 * these should be defined in hal or dph - replace these later
50 */
51#define LIM_TOTAL_BW_11A 54000000
52#define LIM_MIN_BW_11A 6000000
53#define LIM_TOTAL_BW_11B 11000000
54#define LIM_MIN_BW_11B 1000000
55#define LIM_TOTAL_BW_11G LIM_TOTAL_BW_11A
56#define LIM_MIN_BW_11G LIM_MIN_BW_11B
57
58// conversion factors
59#define LIM_CONVERT_SIZE_BITS(numBytes) ((numBytes) * 8)
60#define LIM_CONVERT_RATE_MBPS(rate) ((rate)/1000000)
61
62/* ANI sta's support enhanced rates, so the effective medium time used is
63 * half that of other stations. This is the same as if they were requesting
64 * half the badnwidth - so we adjust ANI sta's accordingly for bandwidth
65 * calculations. Also enhanced rates apply only in case of non 11B mode.
66 */
67#define LIM_STA_BW_ADJUST(aniPeer, phyMode, bw) \
68 (((aniPeer) && ((phyMode) != WNI_CFG_PHY_MODE_11B)) \
69 ? ((bw)/2) : (bw))
70
71
72//------------------------------------------------------------------------------
73// local protos
74
75static tSirRetStatus
76limCalculateSvcInt(tpAniSirGlobal, tSirMacTspecIE *, tANI_U32 *);
77#if 0 //only EDCA is supported now
78static tSirRetStatus
79limValidateTspecHcca(tpAniSirGlobal, tSirMacTspecIE *);
80#endif
81static tSirRetStatus
82limValidateTspecEdca(tpAniSirGlobal, tSirMacTspecIE *, tpPESession);
83static tSirRetStatus
84limValidateTspec(tpAniSirGlobal, tSirMacTspecIE *, tpPESession);
85static void
86limComputeMeanBwUsed(tpAniSirGlobal, tANI_U32 *, tANI_U32, tpLimTspecInfo, tpPESession);
87static void
88limGetAvailableBw(tpAniSirGlobal, tANI_U32 *, tANI_U32 *, tANI_U32, tANI_U32);
89static tSirRetStatus
90limAdmitPolicyOversubscription(tpAniSirGlobal, tSirMacTspecIE *, tpLimAdmitPolicyInfo, tpLimTspecInfo, tpPESession);
91static tSirRetStatus
92limTspecFindByStaAddr(tpAniSirGlobal, tANI_U8 *, tSirMacTspecIE*, tpLimTspecInfo, tpLimTspecInfo *);
93static tSirRetStatus
94limValidateAccessPolicy(tpAniSirGlobal, tANI_U8, tANI_U16, tpPESession);
95
96
97/** -------------------------------------------------------------
98\fn limCalculateSvcInt
99\brief TSPEC validation and servcie interval determination
100\param tpAniSirGlobal pMac
101\param tSirMacTspecIE *pTspec
102\param tANI_U32 *pSvcInt
103\return eSirRetStatus - status of the comparison
104 -------------------------------------------------------------*/
105
106static tSirRetStatus
107limCalculateSvcInt(
108 tpAniSirGlobal pMac,
109 tSirMacTspecIE *pTspec,
110 tANI_U32 *pSvcInt)
111{
112 tANI_U32 msduSz, dataRate;
113 *pSvcInt = 0;
114
115 // if a service interval is already specified, we are done
116 if ((pTspec->minSvcInterval != 0) || (pTspec->maxSvcInterval != 0))
117 {
118 *pSvcInt = (pTspec->maxSvcInterval != 0)
119 ? pTspec->maxSvcInterval : pTspec->minSvcInterval;
120 return eSIR_SUCCESS;
121 }
122
123 /* Masking off the fixed bits according to definition of MSDU size
124 * in IEEE 802.11-2007 spec (section 7.3.2.30). Nominal MSDU size
125 * is defined as: Bit[0:14]=Size, Bit[15]=Fixed
126 */
127 if (pTspec->nomMsduSz != 0)
128 msduSz = (pTspec->nomMsduSz & 0x7fff);
129 else if (pTspec->maxMsduSz != 0)
130 msduSz = pTspec->maxMsduSz;
131 else
132 {
133 PELOGE(limLog(pMac, LOGE, FL("MsduSize not specified\n"));)
134 return eSIR_FAILURE;
135 }
136
137 /* need to calculate a reasonable service interval
138 * this is simply the msduSz/meanDataRate
139 */
140 if (pTspec->meanDataRate != 0) dataRate = pTspec->meanDataRate;
141 else if (pTspec->peakDataRate != 0) dataRate = pTspec->peakDataRate;
142 else if (pTspec->minDataRate != 0) dataRate = pTspec->minDataRate;
143 else
144 {
145 PELOGE(limLog(pMac, LOGE, FL("DataRate not specified\n"));)
146 return eSIR_FAILURE;
147 }
148
149 *pSvcInt = LIM_CONVERT_SIZE_BITS(msduSz) / LIM_CONVERT_RATE_MBPS(dataRate);
150 return eSIR_FAILURE;
151}
152
153#if 0 //only EDCA is supported now
154/** -------------------------------------------------------------
155\fn limValidateTspecHcca
156\brief validate the parameters in the hcca tspec
157 mandatory fields are derived from 11e Annex I (Table I.1)
158\param tpAniSirGlobal pMac
159\param tSirMacTspecIE *pTspec
160\return eSirRetStatus - status
161 -------------------------------------------------------------*/
162static tSirRetStatus
163limValidateTspecHcca(
164 tpAniSirGlobal pMac,
165 tSirMacTspecIE *pTspec)
166{
167 tANI_U32 maxPhyRate, minPhyRate;
168 tANI_U32 phyMode;
169
170 tSirRetStatus retval = eSIR_SUCCESS;
171 /* make sure a TSID is being requested */
172 if (pTspec->tsinfo.traffic.tsid < SIR_MAC_HCCA_TSID_MIN)
173 {
174 limLog(pMac, LOGW, FL("tsid %d must be >%d)\n"),
175 pTspec->tsinfo.traffic.tsid, SIR_MAC_HCCA_TSID_MIN);
176 retval = eSIR_FAILURE;
177 }
178 /*
179 * With Polaris, there is a limitation in that the tsid cannot be arbitary
180 * but is based on the qid. Thus, we cannot have a tspec which requests
181 * a tsid of 13 and userPrio of 7, the bottom three bits of the tsid must
182 * correspond to the userPrio
183 */
184 if (pTspec->tsinfo.traffic.userPrio !=
185 (pTspec->tsinfo.traffic.tsid - SIR_MAC_HCCA_TSID_MIN))
186 {
187 limLog(pMac, LOGE, FL("TSid=0x%x, userPrio=%d: is not allowed\n"),
188 pTspec->tsinfo.traffic.tsid, pTspec->tsinfo.traffic.userPrio);
189 retval = eSIR_FAILURE;
190 }
191 // an inactivity interval is mandatory
192 if (pTspec->inactInterval == 0)
193 {
194 PELOGW(limLog(pMac, LOGW, FL("inactInterval unspecified!\n"));)
195 retval = eSIR_FAILURE;
196 }
197 // surplus BW must be specified if a delay Bound is specified
198 if ((pTspec->delayBound != 0) && (pTspec->surplusBw == 0))
199 {
200 limLog(pMac, LOGW, FL("delayBound %d, but surplusBw unspecified!\n"),
201 pTspec->delayBound);
202 retval = eSIR_FAILURE;
203 }
204 // minPhyRate must always be specified and cannot exceed maximum supported
205 limGetPhyMode(pMac, &phyMode);
206 //limGetAvailableBw(pMac, &maxPhyRate, &minPhyRate, pMac->dph.gDphPhyMode,
207 // 1 /* bandwidth mult factor */);
208 limGetAvailableBw(pMac, &maxPhyRate, &minPhyRate, phyMode,
209 1 /* bandwidth mult factor */);
210 if ((pTspec->minPhyRate == 0)
211 || (pTspec->minPhyRate > maxPhyRate)
212 || (pTspec->minPhyRate < minPhyRate))
213 {
214 limLog(pMac, LOGW, FL("minPhyRate (%d) invalid\n"),
215 pTspec->minPhyRate);
216 retval = eSIR_FAILURE;
217 }
218 /* NOTE: we will require all Tspec's to specify a mean data rate (and so
219 * also the min and peak data rates)
220 */
221 if ((pTspec->minDataRate == 0) ||
222 (pTspec->meanDataRate == 0) ||
223 (pTspec->peakDataRate == 0))
224 {
225 limLog(pMac, LOGW, FL("DataRate must be specified (min %d, mean %d, peak %d)\n"),
226 pTspec->minDataRate, pTspec->meanDataRate, pTspec->peakDataRate);
227 retval = eSIR_FAILURE;
228 }
229
230 // mean data rate can't be more than the min phy rate
231 if (pTspec->meanDataRate > pTspec->minPhyRate)
232 {
233 limLog(pMac, LOGW, FL("Data rate (%d) is more than Phyrate %d\n"),
234 pTspec->meanDataRate, pTspec->minPhyRate);
235 return eSIR_FAILURE;
236 }
237
238 /* if the tspec specifies a service interval, we won't accept tspec's
239 * with service interval less than our allowed minimum, also either both
240 * min and max must be specified or neither should be specified (in which
241 * case, HC determines the appropriate service interval
242 */
243 if ((pTspec->minSvcInterval != 0) || (pTspec->maxSvcInterval != 0))
244 {
245 // max < min is ridiculous
246 if (pTspec->maxSvcInterval < pTspec->minSvcInterval)
247 {
248 limLog(pMac, LOGW, FL("maxSvcInt %d > minSvcInterval %d!!\n"),
249 pTspec->maxSvcInterval, pTspec->minSvcInterval);
250 retval = eSIR_FAILURE;
251 }
252 if (pTspec->maxSvcInterval < ADMIT_CONTROL_MIN_INTERVAL)
253 {
254 limLog(pMac, LOGW, FL("maxSvcInt %d must be >%d\n"),
255 pTspec->maxSvcInterval, ADMIT_CONTROL_MIN_INTERVAL);
256 retval = eSIR_FAILURE;
257 }
258 }
259 else // min and max both unspecified
260 {
261 /* no service interval is specified, so make sure the parameters
262 * needed to determine one are specified in the tspec
263 * minPhyRate, meanDataRate and nomMsduSz are needed, only nomMsduSz
264 * must be checked here since the other two are already validated
265 */
266 if (pTspec->nomMsduSz == 0)
267 {
268 PELOGW(limLog(pMac, LOGW, FL("No svcInt and no MsduSize specified\n"));)
269 retval = eSIR_FAILURE;
270 }
271 }
272
273 limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("return status %d\n"), retval);
274 return retval;
275}
276
277#endif //only edca is supported now.
278
279/** -------------------------------------------------------------
280\fn limValidateTspecEdca
281\brief validate the parameters in the edca tspec
282 mandatory fields are derived from 11e Annex I (Table I.1)
283\param tpAniSirGlobal pMac
284\param tSirMacTspecIE *pTspec
285\return eSirRetStatus - status
286 -------------------------------------------------------------*/
287static tSirRetStatus
288limValidateTspecEdca(
289 tpAniSirGlobal pMac,
290 tSirMacTspecIE *pTspec,
291 tpPESession psessionEntry)
292{
293 tANI_U32 maxPhyRate, minPhyRate;
294 tANI_U32 phyMode;
295 tSirRetStatus retval = eSIR_SUCCESS;
296
297 limGetPhyMode(pMac, &phyMode, psessionEntry);
298
299 //limGetAvailableBw(pMac, &maxPhyRate, &minPhyRate, pMac->dph.gDphPhyMode,
300 // 1 /* bandwidth mult factor */);
301 limGetAvailableBw(pMac, &maxPhyRate, &minPhyRate, phyMode,
302 1 /* bandwidth mult factor */);
303 // mandatory fields are derived from 11e Annex I (Table I.1)
304 if ((pTspec->nomMsduSz == 0) ||
305 (pTspec->meanDataRate == 0) ||
306 (pTspec->surplusBw == 0) ||
307 (pTspec->minPhyRate == 0) ||
308 (pTspec->minPhyRate > maxPhyRate))
309 {
310 limLog(pMac, LOGW, FL("Invalid EDCA Tspec: NomMsdu %d, meanDataRate %d, surplusBw %d, minPhyRate %d\n"),
311 pTspec->nomMsduSz, pTspec->meanDataRate, pTspec->surplusBw, pTspec->minPhyRate);
312 retval = eSIR_FAILURE;
313 }
314
315 limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("return status %d\n"), retval);
316 return retval;
317}
318
319/** -------------------------------------------------------------
320\fn limValidateTspec
321\brief validate the offered tspec
322\param tpAniSirGlobal pMac
323\param tSirMacTspecIE *pTspec
324\return eSirRetStatus - status
325 -------------------------------------------------------------*/
326
327static tSirRetStatus
328limValidateTspec(
329 tpAniSirGlobal pMac,
330 tSirMacTspecIE *pTspec,
331 tpPESession psessionEntry)
332{
333 tSirRetStatus retval = eSIR_SUCCESS;
334 switch (pTspec->tsinfo.traffic.accessPolicy)
335 {
336 case SIR_MAC_ACCESSPOLICY_EDCA:
337 if ((retval = limValidateTspecEdca(pMac, pTspec, psessionEntry)) != eSIR_SUCCESS)
338 PELOGW(limLog(pMac, LOGW, FL("EDCA tspec invalid\n"));)
339 break;
340
341 case SIR_MAC_ACCESSPOLICY_HCCA:
342#if 0 //Not supported right now.
343 if ((retval = limValidateTspecHcca(pMac, pTspec)) != eSIR_SUCCESS)
344 PELOGW(limLog(pMac, LOGW, FL("HCCA tspec invalid\n"));)
345 break;
346#endif
347 case SIR_MAC_ACCESSPOLICY_BOTH:
348 // TBD: should we support hybrid tspec as well?? for now, just fall through
349 default:
350 limLog(pMac, LOGW, FL("AccessType %d not supported\n"),
351 pTspec->tsinfo.traffic.accessPolicy);
352 retval = eSIR_FAILURE;
353 break;
354 }
355 return retval;
356}
357
358//-----------------------------------------------------------------------------
359// Admit Control Policy
360
361
362/** -------------------------------------------------------------
363\fn limComputeMeanBwUsed
364\brief determime the used/allocated bandwidth
365\param tpAniSirGlobal pMac
366\param tANI_U32 *pBw
367\param tANI_U32 phyMode
368\param tpLimTspecInfo pTspecInfo
369\return eSirRetStatus - status
370 -------------------------------------------------------------*/
371
372static void
373limComputeMeanBwUsed(
374 tpAniSirGlobal pMac,
375 tANI_U32 *pBw,
376 tANI_U32 phyMode,
377 tpLimTspecInfo pTspecInfo,
378 tpPESession psessionEntry)
379{
380 tANI_U32 ctspec;
381 *pBw = 0;
382 for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecInfo++)
383 {
384 if (pTspecInfo->inuse)
385 {
386 tpDphHashNode pSta = dphGetHashEntry(pMac, pTspecInfo->assocId, &psessionEntry->dph.dphHashTable);
387 if (pSta == NULL)
388 {
389 // maybe we should delete the tspec??
390 limLog(pMac, LOGE, FL("Tspec %d (assocId %d): dphNode not found\n"),
391 ctspec, pTspecInfo->assocId);
392 continue;
393 }
394 //FIXME: need to take care of taurusPeer, titanPeer, 11npeer too.
395 *pBw += LIM_STA_BW_ADJUST(pSta->aniPeer, phyMode, pTspecInfo->tspec.meanDataRate);
396 }
397 }
398}
399
400/** -------------------------------------------------------------
401\fn limGetAvailableBw
402\brief based on the phy mode and the bw_factor, determine the total bandwidth that
403 can be supported
404\param tpAniSirGlobal pMac
405\param tANI_U32 *pMaxBw
406\param tANI_U32 *pMinBw
407\param tANI_U32 phyMode
408\param tANI_U32 bw_factor
409\return eSirRetStatus - status
410 -------------------------------------------------------------*/
411
412static void
413limGetAvailableBw(
414 tpAniSirGlobal pMac,
415 tANI_U32 *pMaxBw,
416 tANI_U32 *pMinBw,
417 tANI_U32 phyMode,
418 tANI_U32 bw_factor)
419{
420 switch (phyMode)
421 {
422 case WNI_CFG_PHY_MODE_11B:
423 *pMaxBw = LIM_TOTAL_BW_11B;
424 *pMinBw = LIM_MIN_BW_11B;
425 break;
426
427 case WNI_CFG_PHY_MODE_11A:
428 *pMaxBw = LIM_TOTAL_BW_11A;
429 *pMinBw = LIM_MIN_BW_11A;
430 break;
431
432 case WNI_CFG_PHY_MODE_11G:
433 case WNI_CFG_PHY_MODE_NONE:
434 default:
435 *pMaxBw = LIM_TOTAL_BW_11G;
436 *pMinBw = LIM_MIN_BW_11G;
437 break;
438 }
439 *pMaxBw *= bw_factor;
440}
441
442/** -------------------------------------------------------------
443\fn limAdmitPolicyOversubscription
444\brief simple admission control policy based on oversubscription
445 if the total bandwidth of all admitted tspec's exceeds (factor * phy-bw) then
446 reject the tspec, else admit it. The phy-bw is the peak available bw in the
447 current phy mode. The 'factor' is the configured oversubscription factor.
448\param tpAniSirGlobal pMac
449\param tSirMacTspecIE *pTspec
450\param tpLimAdmitPolicyInfo pAdmitPolicy
451\param tpLimTspecInfo pTspecInfo
452\return eSirRetStatus - status
453 -------------------------------------------------------------*/
454
455/*
456 * simple admission control policy based on oversubscription
457 * if the total bandwidth of all admitted tspec's exceeds (factor * phy-bw) then
458 * reject the tspec, else admit it. The phy-bw is the peak available bw in the
459 * current phy mode. The 'factor' is the configured oversubscription factor.
460 */
461static tSirRetStatus
462limAdmitPolicyOversubscription(
463 tpAniSirGlobal pMac,
464 tSirMacTspecIE *pTspec,
465 tpLimAdmitPolicyInfo pAdmitPolicy,
466 tpLimTspecInfo pTspecInfo,
467 tpPESession psessionEntry)
468{
469 tANI_U32 totalbw, minbw, usedbw;
470 tANI_U32 phyMode;
471
472 // determine total bandwidth used so far
473 limGetPhyMode(pMac, &phyMode, psessionEntry);
474
475 //limComputeMeanBwUsed(pMac, &usedbw, pMac->dph.gDphPhyMode, pTspecInfo);
476 limComputeMeanBwUsed(pMac, &usedbw, phyMode, pTspecInfo, psessionEntry);
477
478 // determine how much bandwidth is available based on the current phy mode
479 //limGetAvailableBw(pMac, &totalbw, &minbw, pMac->dph.gDphPhyMode, pAdmitPolicy->bw_factor);
480 limGetAvailableBw(pMac, &totalbw, &minbw, phyMode, pAdmitPolicy->bw_factor);
481
482 if (usedbw > totalbw) // this can't possibly happen
483 return eSIR_FAILURE;
484
485 if ((totalbw - usedbw) < pTspec->meanDataRate)
486 {
487 limLog(pMac, ADMIT_CONTROL_POLICY_LOGLEVEL,
488 FL("Total BW %d, Used %d, Tspec request %d not possible\n"),
489 totalbw, usedbw, pTspec->meanDataRate);
490 return eSIR_FAILURE;
491 }
492 return eSIR_SUCCESS;
493}
494
495/** -------------------------------------------------------------
496\fn limAdmitPolicy
497\brief determine the current admit control policy and apply it for the offered tspec
498\param tpAniSirGlobal pMac
499\param tSirMacTspecIE *pTspec
500\return eSirRetStatus - status
501 -------------------------------------------------------------*/
502
503tSirRetStatus limAdmitPolicy(
504 tpAniSirGlobal pMac,
505 tSirMacTspecIE *pTspec,
506 tpPESession psessionEntry)
507{
508 tSirRetStatus retval = eSIR_FAILURE;
509 tpLimAdmitPolicyInfo pAdmitPolicy = &pMac->lim.admitPolicyInfo;
510
511 switch (pAdmitPolicy->type)
512 {
513 case WNI_CFG_ADMIT_POLICY_ADMIT_ALL:
514 retval = eSIR_SUCCESS;
515 break;
516
517 case WNI_CFG_ADMIT_POLICY_BW_FACTOR:
518 retval = limAdmitPolicyOversubscription(pMac, pTspec,
519 &pMac->lim.admitPolicyInfo, &pMac->lim.tspecInfo[0], psessionEntry);
520 if (retval != eSIR_SUCCESS)
521 PELOGE(limLog(pMac, LOGE, FL("rejected by BWFactor policy\n"));)
522 break;
523
524 case WNI_CFG_ADMIT_POLICY_REJECT_ALL:
525 retval = eSIR_FAILURE;
526 break;
527
528 default:
529 retval = eSIR_SUCCESS;
530 limLog(pMac, LOGE, FL("Admit Policy %d unknown, admitting all traffic\n"),
531 pAdmitPolicy->type);
532 break;
533 }
534 return retval;
535}
536
537/** -------------------------------------------------------------
538\fn limTspecDelete
539\brief delete the specified tspec
540\param tpAniSirGlobal pMac
541\param tpLimTspecInfo pInfo
542\return eSirRetStatus - status
543 -------------------------------------------------------------*/
544
545//-----------------------------------------------------------------------------
546// delete the specified tspec
547void limTspecDelete(tpAniSirGlobal pMac, tpLimTspecInfo pInfo)
548{
549 if (pInfo == NULL)
550 return;
551 //pierre
552 limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("tspec entry = %d\n"), pInfo->idx);
553 limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("delete tspec %08X\n"),pInfo);
554 pInfo->inuse = 0;
555
556 // clear the hcca/parameterized queue indicator
557#if 0
558 if ((pInfo->tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_UPLINK) ||
559 (pInfo->tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_BIDIR))
560 queue[pInfo->staid][pInfo->tspec.tsinfo.traffic.userPrio][SCH_UL_QUEUE].ts = 0;
561#endif
562
563 return;
564}
565
566/** -------------------------------------------------------------
567\fn limTspecFindByStaAddr
568\brief Send halMsg_AddTs to HAL
569\param tpAniSirGlobal pMac
570\param \param tANI_U8 *pAddr
571\param tSirMacTspecIE *pTspecIE
572\param tpLimTspecInfo pTspecList
573\param tpLimTspecInfo *ppInfo
574\return eSirRetStatus - status
575 -------------------------------------------------------------*/
576
577// find the specified tspec in the list
578static tSirRetStatus
579limTspecFindByStaAddr(
580 tpAniSirGlobal pMac,
581 tANI_U8 *pAddr,
582 tSirMacTspecIE *pTspecIE,
583 tpLimTspecInfo pTspecList,
584 tpLimTspecInfo *ppInfo)
585{
586 int ctspec;
587
588 *ppInfo = NULL;
589
590 for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++)
591 {
592 if ((pTspecList->inuse)
593 && (palEqualMemory( pMac->hHdd,pAddr, pTspecList->staAddr, sizeof(pTspecList->staAddr)))
594 && (palEqualMemory( pMac->hHdd,(tANI_U8 *) pTspecIE, (tANI_U8 *) &pTspecList->tspec, sizeof(tSirMacTspecIE))))
595 {
596 *ppInfo = pTspecList;
597 return eSIR_SUCCESS;
598 }
599 }
600 return eSIR_FAILURE;
601}
602
603/** -------------------------------------------------------------
604\fn limTspecFindByAssocId
605\brief find tspec with matchin staid and Tspec
606\param tpAniSirGlobal pMac
607\param tANI_U32 staid
608\param tSirMacTspecIE *pTspecIE
609\param tpLimTspecInfo pTspecList
610\param tpLimTspecInfo *ppInfo
611\return eSirRetStatus - status
612 -------------------------------------------------------------*/
613
614tSirRetStatus
615limTspecFindByAssocId(
616 tpAniSirGlobal pMac,
617 tANI_U16 assocId,
618 tSirMacTspecIE *pTspecIE,
619 tpLimTspecInfo pTspecList,
620 tpLimTspecInfo *ppInfo)
621{
622 int ctspec;
623
624 *ppInfo = NULL;
625
626 limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("Trying to find tspec entry for assocId = %d\n"), assocId);
627 limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("pTsInfo->traffic.direction = %d, pTsInfo->traffic.tsid = %d\n"),
628 pTspecIE->tsinfo.traffic.direction, pTspecIE->tsinfo.traffic.tsid);
629
630 for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++)
631 {
632 if ((pTspecList->inuse)
633 && (assocId == pTspecList->assocId)
634 && (palEqualMemory( pMac->hHdd,(tANI_U8 *) pTspecIE, (tANI_U8 *) &pTspecList->tspec, sizeof(tSirMacTspecIE))))
635 {
636 *ppInfo = pTspecList;
637 return eSIR_SUCCESS;
638 }
639 }
640 return eSIR_FAILURE;
641}
642
643/** -------------------------------------------------------------
644\fn limFindTspec
645\brief finding a TSPEC entry with assocId, tsinfo.direction and tsinfo.tsid
646\param tANI_U16 assocId
647\param tpAniSirGlobal pMac
648\param tSirMacTSInfo *pTsInfo
649\param tpLimTspecInfo pTspecList
650\param tpLimTspecInfo *ppInfo
651\return eSirRetStatus - status of the comparison
652 -------------------------------------------------------------*/
653
654tSirRetStatus
655limFindTspec(
656 tpAniSirGlobal pMac,
657 tANI_U16 assocId,
658 tSirMacTSInfo *pTsInfo,
659 tpLimTspecInfo pTspecList,
660 tpLimTspecInfo *ppInfo)
661{
662 int ctspec;
663
664 *ppInfo = NULL;
665
666 limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("Trying to find tspec entry for assocId = %d\n"), assocId);
667 limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("pTsInfo->traffic.direction = %d, pTsInfo->traffic.tsid = %d\n"),
668 pTsInfo->traffic.direction, pTsInfo->traffic.tsid);
669
670 for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++)
671 {
672 if ((pTspecList->inuse)
673 && (assocId == pTspecList->assocId)
674 && (pTsInfo->traffic.direction == pTspecList->tspec.tsinfo.traffic.direction)
675 && (pTsInfo->traffic.tsid == pTspecList->tspec.tsinfo.traffic.tsid))
676 {
677 *ppInfo = pTspecList;
678 return eSIR_SUCCESS;
679 }
680 }
681 return eSIR_FAILURE;
682}
683
684/** -------------------------------------------------------------
685\fn limTspecAdd
686\brief add or update the specified tspec to the tspec list
687\param tpAniSirGlobal pMac
688\param tANI_U8 *pAddr
689\param tANI_U16 assocId
690\param tSirMacTspecIE *pTspec
691\param tANI_U32 interval
692\param tpLimTspecInfo *ppInfo
693
694\return eSirRetStatus - status of the comparison
695 -------------------------------------------------------------*/
696
697tSirRetStatus limTspecAdd(
698 tpAniSirGlobal pMac,
699 tANI_U8 *pAddr,
700 tANI_U16 assocId,
701 tSirMacTspecIE *pTspec,
702 tANI_U32 interval,
703 tpLimTspecInfo *ppInfo)
704{
705 tpLimTspecInfo pTspecList = &pMac->lim.tspecInfo[0];
706 *ppInfo = NULL;
707
708 // validate the assocId
709 if (assocId >= pMac->lim.maxStation)
710 {
711 PELOGE(limLog(pMac, LOGE, FL("Invalid assocId 0x%x\n"), assocId);)
712 return eSIR_FAILURE;
713 }
714
715 //decide whether to add/update
716 {
717 *ppInfo = NULL;
718
719 if(eSIR_SUCCESS == limFindTspec(pMac, assocId, &pTspec->tsinfo, pTspecList, ppInfo))
720 {
721 //update this entry.
722 limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("updating TSPEC table entry = %d"),
723 (*ppInfo)->idx);
724 }
725 else
726 {
727 /* We didn't find one to update. So find a free slot in the
728 * LIM TSPEC list and add this new entry
729 */
730 tANI_U8 ctspec = 0;
731 for (ctspec = 0 , pTspecList = &pMac->lim.tspecInfo[0]; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++)
732 {
733 if (! pTspecList->inuse)
734 {
735 limLog(pMac, LOG1, FL("Found free slot in TSPEC list. Add to TSPEC table entry %d"), ctspec);
736 break;
737 }
738 }
739
740 if (ctspec >= LIM_NUM_TSPEC_MAX)
741 return eSIR_FAILURE;
742
743 //Record the new index entry
744 pTspecList->idx = ctspec;
745 }
746 }
747
748 // update the tspec info
749 pTspecList->tspec = *pTspec;
750 pTspecList->assocId = assocId;
751 palCopyMemory( pMac->hHdd, pTspecList->staAddr, pAddr, sizeof(pTspecList->staAddr));
752
753 // for edca tspec's, we are all done
754 if (pTspec->tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA)
755 {
756 pTspecList->inuse = 1;
757 *ppInfo = pTspecList;
758 limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("added entry for EDCA AccessPolicy\n"));
759 return eSIR_SUCCESS;
760 }
761
762 /*
763 * for hcca tspec's, must set the parameterized bit in the queues
764 * the 'ts' bit in the queue data structure indicates that the queue is
765 * parameterized (hcca). When the schedule is written this bit is used
766 * in the tsid field (bit 3) and the other three bits (0-2) are simply
767 * filled in as the user priority (or qid). This applies only to uplink
768 * polls where the qos control field must contain the tsid specified in the
769 * tspec.
770 */
771#if 0
772 if ((pTspec->tsinfo.traffic.direction == SIR_MAC_DIRECTION_UPLINK) ||
773 (pTspec->tsinfo.traffic.direction == SIR_MAC_DIRECTION_BIDIR))
774 queue[staid][pTspec->tsinfo.traffic.userPrio][SCH_UL_QUEUE].ts = 1;
775#endif
776 pTspecList->inuse = 1;
777 *ppInfo = pTspecList;
778 limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("added entry for HCCA AccessPolicy\n"));
779 return eSIR_SUCCESS;
780}
781
782/** -------------------------------------------------------------
783\fn limValidateAccessPolicy
784\brief Validates Access policy
785\param tpAniSirGlobal pMac
786\param tANI_U8 accessPolicy
787\param tANI_U16 assocId
788\return eSirRetStatus - status
789 -------------------------------------------------------------*/
790
791static tSirRetStatus
792limValidateAccessPolicy(
793 tpAniSirGlobal pMac,
794 tANI_U8 accessPolicy,
795 tANI_U16 assocId,
796 tpPESession psessionEntry)
797{
798 tSirRetStatus retval = eSIR_FAILURE;
799 tpDphHashNode pSta = dphGetHashEntry(pMac, assocId, &psessionEntry->dph.dphHashTable);
800
801 if ((pSta == NULL) || (! pSta->valid))
802 {
803 PELOGE(limLog(pMac, LOGE, FL("invalid station address passed\n"));)
804 return eSIR_FAILURE;
805 }
806
807 switch (accessPolicy)
808 {
809 case SIR_MAC_ACCESSPOLICY_EDCA:
810 if (pSta->wmeEnabled || pSta->lleEnabled)
811 retval = eSIR_SUCCESS;
812 break;
813
814 case SIR_MAC_ACCESSPOLICY_HCCA:
815 case SIR_MAC_ACCESSPOLICY_BOTH:
816#if 0 //only EDCA supported for now.
817 // TBD: check wsm doesn't support the hybrid access policy
818 if (pSta->wsmEnabled || pSta->lleEnabled)
819 retval = eSIR_SUCCESS;
820 break;
821#endif //only EDCA supported for now.
822 default:
823 PELOGE(limLog(pMac, LOGE, FL("Invalid accessPolicy %d\n"), accessPolicy);)
824 break;
825 }
826
827 if (retval != eSIR_SUCCESS)
828 limLog(pMac, LOGW, FL("failed (accPol %d, staId %d, lle %d, wme %d, wsm %d)\n"),
829 accessPolicy, pSta->staIndex, pSta->lleEnabled, pSta->wmeEnabled, pSta->wsmEnabled);
830
831 return retval;
832}
833
834/** -------------------------------------------------------------
835\fn limAdmitControlAddTS
836\brief Determine if STA with the specified TSPEC can be admitted. If it can,
837 a schedule element is provided
838\param tpAniSirGlobal pMac
839\param tANI_U8 *pAddr,
840\param tSirAddtsReqInfo *pAddts,
841\param tSirMacQosCapabilityIE *pQos,
842\param tANI_U16 assocId, // assocId, valid only if alloc==true
843\param tANI_U8 alloc, // true=>allocate bw for this tspec,
844 // else determine only if space is available
845\param tSirMacScheduleIE *pSch,
846\param tANI_U8 *pTspecIdx //index to the lim tspec table.
847\return eSirRetStatus - status
848 -------------------------------------------------------------*/
849
850tSirRetStatus limAdmitControlAddTS(
851 tpAniSirGlobal pMac,
852 tANI_U8 *pAddr,
853 tSirAddtsReqInfo *pAddts,
854 tSirMacQosCapabilityStaIE *pQos,
855 tANI_U16 assocId, // assocId, valid only if alloc==true
856 tANI_U8 alloc, // true=>allocate bw for this tspec,
857 // else determine only if space is available
858 tSirMacScheduleIE *pSch,
859 tANI_U8 *pTspecIdx, //index to the lim tspec table.
860 tpPESession psessionEntry
861 )
862{
863 tpLimTspecInfo pTspecInfo;
864 tSirRetStatus retval;
865 tANI_U32 svcInterval;
866 (void) pQos;
867
868 // TBD: modify tspec as needed
869 // EDCA: need to fill in the medium time and the minimum phy rate
870 // to be consistent with the desired traffic parameters.
871
872 limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("tsid %d, directn %d, start %d, intvl %d, accPolicy %d, up %d\n"),
873 pAddts->tspec.tsinfo.traffic.tsid, pAddts->tspec.tsinfo.traffic.direction,
874 pAddts->tspec.svcStartTime, pAddts->tspec.minSvcInterval,
875 pAddts->tspec.tsinfo.traffic.accessPolicy, pAddts->tspec.tsinfo.traffic.userPrio);
876
877 // check for duplicate tspec
878 retval = (alloc)
879 ? limTspecFindByAssocId(pMac, assocId, &pAddts->tspec, &pMac->lim.tspecInfo[0], &pTspecInfo)
880 : limTspecFindByStaAddr(pMac, pAddr, &pAddts->tspec, &pMac->lim.tspecInfo[0], &pTspecInfo);
881
882 if (retval == eSIR_SUCCESS)
883 {
884 limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("duplicate tspec (index %d)!\n"), pTspecInfo->idx);
885 return eSIR_FAILURE;
886 }
887
888 // check that the tspec's are well formed and acceptable
889 if (limValidateTspec(pMac, &pAddts->tspec, psessionEntry) != eSIR_SUCCESS)
890 {
891 PELOGW(limLog(pMac, LOGW, FL("tspec validation failed\n"));)
892 return eSIR_FAILURE;
893 }
894
895 // determine a service interval for the tspec
896 if (limCalculateSvcInt(pMac, &pAddts->tspec, &svcInterval) != eSIR_SUCCESS)
897 {
898 PELOGW(limLog(pMac, LOGW, FL("SvcInt calculate failed\n"));)
899 return eSIR_FAILURE;
900 }
901
902 // determine if the tspec can be admitted or not based on current policy
903 if (limAdmitPolicy(pMac, &pAddts->tspec, psessionEntry) != eSIR_SUCCESS)
904 {
905 PELOGW(limLog(pMac, LOGW, FL("tspec rejected by admit control policy\n"));)
906 return eSIR_FAILURE;
907 }
908
909 // fill in a schedule if requested
910 if (pSch != NULL)
911 {
912 palZeroMemory( pMac->hHdd, (tANI_U8 *) pSch, sizeof(*pSch));
913 pSch->svcStartTime = pAddts->tspec.svcStartTime;
914 pSch->svcInterval = svcInterval;
915 pSch->maxSvcDuration = (tANI_U16) pSch->svcInterval; // use SP = SI
916 pSch->specInterval = 0x1000; // fixed for now: TBD
917
918 pSch->info.direction = pAddts->tspec.tsinfo.traffic.direction;
919 pSch->info.tsid = pAddts->tspec.tsinfo.traffic.tsid;
920 pSch->info.aggregation = 0; // no support for aggregation for now: TBD
921 }
922
923 // if no allocation is requested, done
924 if (! alloc)
925 return eSIR_SUCCESS;
926
927 // check that we are in the proper mode to deal with the tspec type
928 if (limValidateAccessPolicy(pMac, (tANI_U8) pAddts->tspec.tsinfo.traffic.accessPolicy, assocId, psessionEntry) != eSIR_SUCCESS)
929 {
930 limLog(pMac, LOGW, FL("AccessPolicy %d is not valid in current mode\n"),
931 pAddts->tspec.tsinfo.traffic.accessPolicy);
932 return eSIR_FAILURE;
933 }
934
935 // add tspec to list
936 if (limTspecAdd(pMac, pAddr, assocId, &pAddts->tspec, svcInterval, &pTspecInfo)
937 != eSIR_SUCCESS)
938 {
939 PELOGE(limLog(pMac, LOGE, FL("no space in tspec list\n"));)
940 return eSIR_FAILURE;
941 }
942
943 //passing lim tspec table index to the caller
944 *pTspecIdx = pTspecInfo->idx;
945
946 return eSIR_SUCCESS;
947}
948
949/** -------------------------------------------------------------
950\fn limAdmitControlDeleteTS
951\brief Delete the specified Tspec for the specified STA
952\param tpAniSirGlobal pMac
953\param tANI_U16 assocId
954\param tSirMacTSInfo *pTsInfo
955\param tANI_U8 *pTsStatus
956\param tANI_U8 *ptspecIdx
957\return eSirRetStatus - status
958 -------------------------------------------------------------*/
959
960tSirRetStatus
961limAdmitControlDeleteTS(
962 tpAniSirGlobal pMac,
963 tANI_U16 assocId,
964 tSirMacTSInfo *pTsInfo,
965 tANI_U8 *pTsStatus,
966 tANI_U8 *ptspecIdx)
967{
968 tpLimTspecInfo pTspecInfo = NULL;
969
970 if (pTsStatus != NULL)
971 *pTsStatus = 0;
972
973 if (limFindTspec(pMac, assocId, pTsInfo, &pMac->lim.tspecInfo[0], &pTspecInfo) == eSIR_SUCCESS)
974 {
975 if(pTspecInfo != NULL)
976 {
977 limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("Tspec entry %d found\n"), pTspecInfo->idx);
978
979 *ptspecIdx = pTspecInfo->idx;
980 limTspecDelete(pMac, pTspecInfo);
981 return eSIR_SUCCESS;
982 }
983 }
984 return eSIR_FAILURE;
985}
986
987/** -------------------------------------------------------------
988\fn limAdmitControlDeleteSta
989\brief Delete all TSPEC for the specified STA
990\param tpAniSirGlobal pMac
991\param tANI_U16 assocId
992\return eSirRetStatus - status
993 -------------------------------------------------------------*/
994
995tSirRetStatus
996limAdmitControlDeleteSta(
997 tpAniSirGlobal pMac,
998 tANI_U16 assocId)
999{
1000 tpLimTspecInfo pTspecInfo = &pMac->lim.tspecInfo[0];
1001 int ctspec;
1002
1003 for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecInfo++)
1004 {
1005 if (assocId == pTspecInfo->assocId)
1006 {
1007 limTspecDelete(pMac, pTspecInfo);
1008 limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("Deleting TSPEC %d for assocId %d\n"),
1009 ctspec, assocId);
1010 }
1011 }
1012 limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("assocId %d done\n"), assocId);
1013
1014 return eSIR_SUCCESS;
1015}
1016
1017/** -------------------------------------------------------------
1018\fn limAdmitControlInit
1019\brief init tspec table
1020\param tpAniSirGlobal pMac
1021\return eSirRetStatus - status
1022 -------------------------------------------------------------*/
1023tSirRetStatus limAdmitControlInit(tpAniSirGlobal pMac)
1024{
1025 palZeroMemory(pMac->hHdd, pMac->lim.tspecInfo , LIM_NUM_TSPEC_MAX * sizeof(tLimTspecInfo));
1026 return eSIR_SUCCESS;
1027}
1028
1029/** -------------------------------------------------------------
1030\fn limUpdateAdmitPolicy
1031\brief Set the admit control policy based on CFG parameters
1032\param tpAniSirGlobal pMac
1033\return eSirRetStatus - status
1034 -------------------------------------------------------------*/
1035
1036tSirRetStatus limUpdateAdmitPolicy(tpAniSirGlobal pMac)
1037{
1038 tANI_U32 val;
1039 if (wlan_cfgGetInt(pMac, WNI_CFG_ADMIT_POLICY, &val) != eSIR_SUCCESS)
1040 {
1041 limLog(pMac, LOGP, FL("Unable to get CFG_ADMIT_POLICY\n"));
1042 return eSIR_FAILURE;
1043 }
1044 pMac->lim.admitPolicyInfo.type = (tANI_U8) val;
1045 if (wlan_cfgGetInt(pMac, WNI_CFG_ADMIT_BWFACTOR, &val) != eSIR_SUCCESS)
1046 {
1047 limLog(pMac, LOGP, FL("Unable to get CFG_ADMIT_BWFACTOR\n"));
1048 return eSIR_FAILURE;
1049 }
1050 pMac->lim.admitPolicyInfo.bw_factor = (tANI_U8) val;
1051
1052 PELOG1(limLog(pMac, LOG1, FL("LIM: AdmitPolicy %d, bw_factor %d\n"),
1053 pMac->lim.admitPolicyInfo.type, pMac->lim.admitPolicyInfo.bw_factor);)
1054
1055 return eSIR_SUCCESS;
1056}
1057
1058
1059/** -------------------------------------------------------------
1060\fn limSendHalMsgAddTs
1061\brief Send halMsg_AddTs to HAL
1062\param tpAniSirGlobal pMac
1063\param tANI_U16 staIdx
1064\param tANI_U8 tspecIdx
1065\param tSirMacTspecIE tspecIE
1066\param tSirTclasInfo *tclasInfo
1067\param tANI_U8 tclasProc
1068\return eSirRetStatus - status
1069 -------------------------------------------------------------*/
1070
1071tSirRetStatus
1072limSendHalMsgAddTs(
1073 tpAniSirGlobal pMac,
1074 tANI_U16 staIdx,
1075 tANI_U8 tspecIdx,
1076 tSirMacTspecIE tspecIE,
1077 tANI_U8 sessionId)
1078{
1079 tSirMsgQ msg;
1080 tpAddTsParams pAddTsParam;
1081
1082 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pAddTsParam, sizeof(tAddTsParams)))
1083 {
1084 PELOGW(limLog(pMac, LOGW, FL("palAllocateMemory() failed\n"));)
1085 return eSIR_MEM_ALLOC_FAILED;
1086 }
1087
1088 palZeroMemory( pMac->hHdd, (tANI_U8 *)pAddTsParam, sizeof(tAddTsParams));
1089 pAddTsParam->staIdx = staIdx;
1090 pAddTsParam->tspecIdx = tspecIdx;
1091 palCopyMemory(pMac->hHdd, &pAddTsParam->tspec, &tspecIE, sizeof(tSirMacTspecIE));
1092 pAddTsParam->sessionId = sessionId;
1093
1094 msg.type = WDA_ADD_TS_REQ;
1095 msg.bodyptr = pAddTsParam;
1096 msg.bodyval = 0;
1097
1098 /* We need to defer any incoming messages until we get a
1099 * WDA_ADD_TS_RSP from HAL.
1100 */
1101 SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
Jeff Johnsone7245742012-09-05 17:12:55 -07001102 MTRACE(macTraceMsgTx(pMac, sessionId, msg.type));
Jeff Johnson295189b2012-06-20 16:38:30 -07001103
1104 if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
1105 {
1106 PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg() failed\n"));)
1107 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
1108 palFreeMemory(pMac->hHdd, (tANI_U8*)pAddTsParam);
1109 return eSIR_FAILURE;
1110 }
1111 return eSIR_SUCCESS;
1112}
1113
1114/** -------------------------------------------------------------
1115\fn limSendHalMsgDelTs
1116\brief Send halMsg_AddTs to HAL
1117\param tpAniSirGlobal pMac
1118\param tANI_U16 staIdx
1119\param tANI_U8 tspecIdx
1120\param tSirAddtsReqInfo addts
1121\return eSirRetStatus - status
1122 -------------------------------------------------------------*/
1123
1124tSirRetStatus
1125limSendHalMsgDelTs(
1126 tpAniSirGlobal pMac,
1127 tANI_U16 staIdx,
1128 tANI_U8 tspecIdx,
Jeff Johnsone7245742012-09-05 17:12:55 -07001129 tSirDeltsReqInfo delts,
1130 tANI_U8 sessionId)
Jeff Johnson295189b2012-06-20 16:38:30 -07001131{
1132 tSirMsgQ msg;
1133 tpDelTsParams pDelTsParam;
1134
1135 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pDelTsParam, sizeof(tDelTsParams)))
1136 {
1137 limLog(pMac, LOGP, FL("palAllocateMemory() failed\n"));
1138 return eSIR_MEM_ALLOC_FAILED;
1139 }
1140
1141 msg.type = WDA_DEL_TS_REQ;
1142 msg.bodyptr = pDelTsParam;
1143 msg.bodyval = 0;
1144 palZeroMemory( pMac->hHdd, (tANI_U8 *)pDelTsParam, sizeof(tDelTsParams));
1145
1146 //filling message parameters.
1147 pDelTsParam->staIdx = staIdx;
1148 pDelTsParam->tspecIdx = tspecIdx;
1149
1150 PELOGW(limLog(pMac, LOGW, FL("calling wdaPostCtrlMsg()\n"));)
Jeff Johnsone7245742012-09-05 17:12:55 -07001151 MTRACE(macTraceMsgTx(pMac, sessionId, msg.type));
Jeff Johnson295189b2012-06-20 16:38:30 -07001152
1153 if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
1154 {
1155 PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg() failed\n"));)
1156 palFreeMemory(pMac->hHdd, (tANI_U8*)pDelTsParam);
1157 return eSIR_FAILURE;
1158 }
1159 return eSIR_SUCCESS;
1160}
1161
1162/** -------------------------------------------------------------
1163\fn limProcessHalAddTsRsp
1164\brief This function process the WDA_ADD_TS_RSP from HAL.
1165\ If response is successful, then send back SME_ADDTS_RSP.
1166\ Otherwise, send DELTS action frame to peer and then
1167\ then send back SME_ADDTS_RSP.
1168\
1169\param tpAniSirGlobal pMac
1170\param tpSirMsgQ limMsg
1171-------------------------------------------------------------*/
1172void limProcessHalAddTsRsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
1173{
1174 tpAddTsParams pAddTsRspMsg = NULL;
1175 tpDphHashNode pSta = NULL;
1176 tANI_U16 assocId =0;
1177 tSirMacAddr peerMacAddr;
1178 tANI_U8 rspReqd = 1;
1179 tpPESession psessionEntry = NULL;
1180
1181
1182 /* Need to process all the deferred messages enqueued
1183 * since sending the WDA_ADD_TS_REQ.
1184 */
1185 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
1186
1187 if (NULL == limMsg->bodyptr)
1188 {
1189 limLog(pMac, LOGP, FL("Received WDA_ADD_TS_RSP with NULL "));
1190 goto end;
1191 }
1192
1193 pAddTsRspMsg = (tpAddTsParams) (limMsg->bodyptr);
1194
1195 // 090803: Use peFindSessionBySessionId() to obtain the PE session context
1196 // from the sessionId in the Rsp Msg from HAL
1197 psessionEntry = peFindSessionBySessionId(pMac, pAddTsRspMsg->sessionId);
1198
1199 if(psessionEntry == NULL)
1200 {
1201 PELOGE(limLog(pMac, LOGE,FL("Session does Not exist with given sessionId :%d \n"), pAddTsRspMsg->sessionId);)
1202 limSendSmeAddtsRsp(pMac, rspReqd, eSIR_SME_ADDTS_RSP_FAILED, psessionEntry, pAddTsRspMsg->tspec,
1203 pMac->lim.gLimAddtsReq.sessionId, pMac->lim.gLimAddtsReq.transactionId);
1204 goto end;
1205 }
1206
1207 if(pAddTsRspMsg->status == eHAL_STATUS_SUCCESS)
1208 {
1209 PELOG1(limLog(pMac, LOG1, FL("Received successful ADDTS response from HAL \n"));)
1210 // Use the smesessionId and smetransactionId from the PE session context
1211 limSendSmeAddtsRsp(pMac, rspReqd, eSIR_SME_SUCCESS, psessionEntry, pAddTsRspMsg->tspec,
1212 psessionEntry->smeSessionId, psessionEntry->transactionId);
1213 goto end;
1214 }
1215 else
1216 {
1217 PELOG1(limLog(pMac, LOG1, FL("Received failure ADDTS response from HAL \n"));)
1218
1219 // Send DELTS action frame to AP
1220 // 090803: Get peer MAC addr from session
1221#if 0
1222 cfgLen = sizeof(tSirMacAddr);
1223 if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, peerMacAddr, &cfgLen) != eSIR_SUCCESS)
1224 {
1225 limLog(pMac, LOGP, FL("Fail to retrieve BSSID \n"));
1226 goto end;
1227 }
1228#endif //TO SUPPORT BT-AMP
1229 sirCopyMacAddr(peerMacAddr,psessionEntry->bssId);
1230
1231 // 090803: Add the SME Session ID
1232 limSendDeltsReqActionFrame(pMac, peerMacAddr, rspReqd, &pAddTsRspMsg->tspec.tsinfo, &pAddTsRspMsg->tspec,
1233 //psessionEntry->smeSessionId);
1234 psessionEntry);
1235
1236 // Delete TSPEC
1237 // 090803: Pull the hash table from the session
1238 pSta = dphLookupAssocId(pMac, pAddTsRspMsg->staIdx, &assocId,
1239 &psessionEntry->dph.dphHashTable);
1240 if (pSta != NULL)
1241 limAdmitControlDeleteTS(pMac, assocId, &pAddTsRspMsg->tspec.tsinfo, NULL, (tANI_U8 *)&pAddTsRspMsg->tspecIdx);
1242
1243 // Send SME_ADDTS_RSP
1244 // 090803: Use the smesessionId and smetransactionId from the PE session context
1245 limSendSmeAddtsRsp(pMac, rspReqd, eSIR_SME_ADDTS_RSP_FAILED, psessionEntry, pAddTsRspMsg->tspec,
1246 psessionEntry->smeSessionId, psessionEntry->transactionId);
1247 goto end;
1248 }
1249
1250end:
1251 if( pAddTsRspMsg != NULL )
1252 palFreeMemory( pMac->hHdd, (void *)pAddTsRspMsg );
1253 return;
1254}
1255