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