1/****************************************************************************
2**+-----------------------------------------------------------------------+**
3**|                                                                       |**
4**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved.      |**
5**| All rights reserved.                                                  |**
6**|                                                                       |**
7**| Redistribution and use in source and binary forms, with or without    |**
8**| modification, are permitted provided that the following conditions    |**
9**| are met:                                                              |**
10**|                                                                       |**
11**|  * Redistributions of source code must retain the above copyright     |**
12**|    notice, this list of conditions and the following disclaimer.      |**
13**|  * Redistributions in binary form must reproduce the above copyright  |**
14**|    notice, this list of conditions and the following disclaimer in    |**
15**|    the documentation and/or other materials provided with the         |**
16**|    distribution.                                                      |**
17**|  * Neither the name Texas Instruments nor the names of its            |**
18**|    contributors may be used to endorse or promote products derived    |**
19**|    from this software without specific prior written permission.      |**
20**|                                                                       |**
21**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |**
22**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |**
23**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
24**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |**
25**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
26**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |**
27**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
28**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
29**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |**
30**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
31**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |**
32**|                                                                       |**
33**+-----------------------------------------------------------------------+**
34****************************************************************************/
35/**************************************************************************/
36/*                                                                        */
37/*   MODULE:  Rate Adaptation.c                                           */
38/*                                                                        */
39/**************************************************************************/
40#include "RateAdaptation.h"
41#include "DataCtrl_Api.h"
42#include "802_11Defs.h"
43#include "osApi.h"
44#include "report.h"
45#include "utils.h"
46#include "EvHandler.h"
47#include "apConn.h"
48
49
50static TI_STATUS rateAdaptationa_rateToIndexInRateMapTable(rateAdaptation_t* pRateAdaptation,
51														   rate_e rate, UINT8* Index);
52
53static modulationType_e setModulationForRate(rateAdaptation_t	*pRateAdaptation,
54   											 rate_e				rate,
55  											 modulationType_e	modulation,
56											 bssType_e			bssType);
57
58BOOL rateAdaptation_isRateInTable(ctrlData_rateAdapt_t *currTable,
59								rate_e			rate);
60
61void rateAdaptation_getFallBackStepUp(ctrlData_rateAdapt_t *currTable,
62										rate_e			rate,UINT8* FB,UINT8* SU);
63
64static void rateAdaptation_rxTimeOut(TI_HANDLE hRateAdaptation);
65
66static BOOL set4xEnableForRate(rateAdaptation_t*	pRateAdaptation,
67							   rate_e				rate,
68							   BOOL					enable4x,
69							   bssType_e			bssType);
70
71/*************************************************************************
72*                        ctrlData_create
73**************************************************************************
74* DESCRIPTION:	This function create the rateAdaptation module.
75*
76* INPUT:		hOs - handle to Os Abstraction Layer
77*
78* OUTPUT:
79*
80* RETURN:		Handle to the allocated rateAdaptation block
81************************************************************************/
82
83rateAdaptation_t* rateAdaptation_create(TI_HANDLE hOs)
84{
85	rateAdaptation_t* pRateAdaptation;
86	void			*pTimer;
87
88	if( hOs == NULL )
89	{
90	    WLAN_OS_REPORT(("FATAL ERROR: rateAdaptation_create(): OS handle Error - Aborting\n"));
91		return NULL;
92	}
93
94	/* alocate RateAdaptation block */
95	pRateAdaptation = os_memoryAlloc(hOs, (sizeof(rateAdaptation_t)));
96	if(!pRateAdaptation)
97		return NULL;
98
99	/* alocate Timer to use in PowerSave algorithm */
100	pTimer = os_timerCreate(hOs, rateAdaptation_rxTimeOut, pRateAdaptation);
101
102	if (!pTimer)
103	{
104		utils_nullMemoryFree(hOs, pRateAdaptation, sizeof(rateAdaptation_t));
105	    WLAN_OS_REPORT(("FATAL ERROR: rateAdaptation_create(): Error Creating rateAdaptation Module - Aborting\n"));
106		return NULL;
107	}
108
109
110	/* reset RateAdaptation module block */
111	os_memoryZero(hOs, pRateAdaptation, (sizeof(rateAdaptation_t)));
112
113	pRateAdaptation->pTimer = pTimer;
114
115	pRateAdaptation->hOs = hOs;
116
117	return(pRateAdaptation);
118
119}
120
121/***************************************************************************
122*						rateAdaptation_config
123****************************************************************************
124* DESCRIPTION:	This function initialize the Rate Adaptation algorithm
125*
126* INPUTS:		pRateAdaptation - the object
127*				hOs - Handle to the Os Abstraction Layer
128*				hReport - Handle to the Report object
129*				rateAdaptationInitParam - pointer to Rate Adaptation
130*										  module init parameters
131*
132* OUTPUT:
133*
134* RETURNS:		void
135***************************************************************************/
136TI_STATUS rateAdaptation_config(rateAdaptation_t*			pRateAdaptation,
137	   							TI_HANDLE					hOs,
138								TI_HANDLE					hReport,
139								TI_HANDLE					hCtrlData,
140                                TI_HANDLE					hEvHandler,
141								TI_HANDLE					hAPConnection,
142								rateAdaptationInitParam_t*	rateAdaptationInitParam)
143{
144
145	UINT32 i;
146
147	if( (pRateAdaptation == NULL)  || (hOs == NULL) ||
148		(hReport == NULL) ||  (rateAdaptationInitParam == NULL) )
149	{
150	    WLAN_OS_REPORT(("FATAL ERROR: rateAdaptation_config(): Parameters Error - Aborting\n"));
151		return NOK;
152	}
153
154	pRateAdaptation->hOs = hOs;
155	pRateAdaptation->hReport = hReport;
156	pRateAdaptation->hCtrlData = hCtrlData;
157    pRateAdaptation->hEvHandler = hEvHandler;
158	pRateAdaptation->hAPConnection = hAPConnection;
159
160	pRateAdaptation->contTxPacketsThreshold = rateAdaptationInitParam->contTxPacketsThreshold;
161	pRateAdaptation->stepUpTxPacketsThreshold = rateAdaptationInitParam->stepUpTxPacketsThreshold;
162	pRateAdaptation->ctrlDataFBShortInterval = rateAdaptationInitParam->ctrlDataFBShortInterval;
163	pRateAdaptation->ctrlDataFBLongInterval = rateAdaptationInitParam->ctrlDataFBLongInterval;
164	pRateAdaptation->lowRateThreshold = DEF_LOW_RATE_THRESHOLD;
165
166	pRateAdaptation->rateAdapt_timeout = 1000*rateAdaptationInitParam->rateAdapt_timeout;
167
168	pRateAdaptation->txCount = 0;
169	pRateAdaptation->txSkipCount = 0;
170	pRateAdaptation->txFailCount = 0;
171    pRateAdaptation->txRateFallBackCount = 0;
172
173	pRateAdaptation->stepUpFlag = FALSE;
174
175	/* resset Tspecs Rate Parameters */
176	for(i = 0 ; i < MAX_NUM_OF_AC ; i++)
177	{
178		pRateAdaptation->tspecsRateParameters[i].enableEvent = FALSE;
179		if(rateAdaptationInitParam->tspecsRateParameters[i].highRateThreshold < rateAdaptationInitParam->tspecsRateParameters[i].lowRateThreshold)
180		{
181			WLAN_REPORT_ERROR(pRateAdaptation->hReport, RATE_ADAPTATION_MODULE_LOG,
182					(" rateAdaptation_config() ERROR: highRateThreshold < lowRateThreshold,  ac = %d\n",i));
183
184			pRateAdaptation->tspecsRateParameters[i].highRateThreshold = 0;
185			pRateAdaptation->tspecsRateParameters[i].lowRateThreshold = 0;
186
187		}
188		/* if either one of the threshold is zero all threshold should be with zero default value */
189		else if( (rateAdaptationInitParam->tspecsRateParameters[i].highRateThreshold == 0) ||
190				 (rateAdaptationInitParam->tspecsRateParameters[i].lowRateThreshold == 0))
191		{
192			pRateAdaptation->tspecsRateParameters[i].highRateThreshold = 0;
193			pRateAdaptation->tspecsRateParameters[i].lowRateThreshold = 0;
194		}
195		else
196		{
197			pRateAdaptation->tspecsRateParameters[i].highRateThreshold = rateAdaptationInitParam->tspecsRateParameters[i].highRateThreshold;
198			pRateAdaptation->tspecsRateParameters[i].lowRateThreshold = rateAdaptationInitParam->tspecsRateParameters[i].lowRateThreshold;
199		}
200	}
201
202	WLAN_REPORT_INFORMATION(pRateAdaptation->hReport, RATE_ADAPTATION_MODULE_LOG,
203			(" Rate Adaptation initialize success\n"));
204
205	return OK;
206
207}
208
209/***************************************************************************
210*							rateAdaptation_destroy
211****************************************************************************
212* DESCRIPTION:	This function destroy the rateAdaptation object.
213*
214* INPUTS:		rateAdaptation - the object
215*
216* RETURNS:		OK - Unload succesfull
217*				NOK - Unload unsuccesfull
218***************************************************************************/
219
220TI_STATUS rateAdaptation_destroy(rateAdaptation_t* pRateAdaptation)
221{
222
223	/* check parameters validity */
224	if( pRateAdaptation == NULL )
225	{
226		WLAN_REPORT_ERROR(pRateAdaptation->hReport, RATE_ADAPTATION_MODULE_LOG,
227			(" rateAdaptation_destroy() : parametrs value error \n"));
228		return NOK;
229	}
230
231	/* free timer */
232	os_timerStop(pRateAdaptation->hOs, pRateAdaptation->pTimer);
233	utils_nullTimerDestroy(pRateAdaptation->hOs, pRateAdaptation->pTimer);
234
235
236	/* free rateAdaptation block */
237	os_memoryFree(pRateAdaptation->hOs, pRateAdaptation, sizeof(rateAdaptation_t));
238
239	return OK;
240}
241
242/***************************************************************************
243*							rateAdaptation_rxTimeOut
244****************************************************************************
245* DESCRIPTION:
246****************************************************************************/
247
248static void rateAdaptation_rxTimeOut(TI_HANDLE hRateAdaptation)
249{
250   rateAdaptation_t* pRateAdaptation = (rateAdaptation_t *) hRateAdaptation;
251   	UINT8		prevIndex = pRateAdaptation->currRateIndex,i;
252	OS_802_11_THRESHOLD_CROSS_INDICATION_PARAMS	tspecRateCross;
253
254	os_timerStop(pRateAdaptation->hOs, pRateAdaptation->pTimer);
255	os_timerStart(pRateAdaptation->hOs, pRateAdaptation->pTimer,pRateAdaptation->rateAdapt_timeout,FALSE);
256
257	pRateAdaptation->txCount = 0;
258	pRateAdaptation->txSkipCount = 0;
259	pRateAdaptation->txFailCount = 0;
260    pRateAdaptation->txRateFallBackCount = 0;
261	pRateAdaptation->currRateIndex = pRateAdaptation->maxRateIndex;
262
263
264   	/* update OS with the current rate */
265	if(prevIndex != pRateAdaptation->currRateIndex)
266	{
267		UINT32					statusData;
268		paramInfo_t				param;
269
270	    pRateAdaptation->expirTimeTick = os_timeStampMs(pRateAdaptation->hOs) + pRateAdaptation->ctrlDataFBShortInterval;
271	    pRateAdaptation->stepUpFlag = TRUE;
272
273        WLAN_REPORT_WARNING(pRateAdaptation->hReport, RATE_ADAPTATION_MODULE_LOG,
274			(" RateAdapt() : Time: %d, (60sec) OldRate(Index,Rate): %d,%d, NewRate(Index,Rate): %d,%d\n",
275            os_timeStampMs(pRateAdaptation->hOs),
276			prevIndex,pRateAdaptation->RatesMap[prevIndex].rateNumber,
277			pRateAdaptation->currRateIndex, pRateAdaptation->RatesMap[pRateAdaptation->currRateIndex].rateNumber ));
278
279        /* update OS with the current rate */
280		param.paramType = CTRL_DATA_FOUR_X_CURRRENT_STATUS_PARAM;
281		param.content.ctrlDataCerruentFourXstate = pRateAdaptation->RatesMap[pRateAdaptation->currRateIndex].fourXEnable;
282		ctrlData_setParam(pRateAdaptation->hCtrlData, &param);
283
284    	/* update OS with the current rate */
285
286		statusData = hostToUtilityRate(pRateAdaptation->RatesMap[pRateAdaptation->currRateIndex].rate);
287
288        EvHandlerSendEvent(pRateAdaptation->hEvHandler, IPC_EVENT_LINK_SPEED, (UINT8 *)&statusData,sizeof(UINT32));
289
290		/* send Tspecs Rate Event */
291		for(i = 0 ; i < MAX_NUM_OF_AC ; i++)
292		{
293			if(pRateAdaptation->tspecsRateParameters[i].enableEvent == FALSE)
294			{
295				continue;
296			}
297			else
298			{
299				if( ((pRateAdaptation->RatesMap[prevIndex].rateNumber) < (pRateAdaptation->tspecsRateParameters[i].highRateThreshold)) &&
300					(pRateAdaptation->RatesMap[pRateAdaptation->currRateIndex].rateNumber >= (pRateAdaptation->tspecsRateParameters[i].highRateThreshold)) )
301				{
302					tspecRateCross.uAC = i;
303					tspecRateCross.uHighOrLowThresholdFlag = HIGH_THRESHOLD_CROSS;
304                    tspecRateCross.uAboveOrBelowFlag = CROSS_ABOVE;
305					EvHandlerSendEvent(pRateAdaptation->hEvHandler, IPC_EVENT_TSPEC_RATE_STATUS, (UINT8 *)&tspecRateCross,sizeof(tspecRateCross));
306				}
307                else
308                if( ((pRateAdaptation->RatesMap[prevIndex].rateNumber) < (pRateAdaptation->tspecsRateParameters[i].lowRateThreshold)) &&
309						(hostRateToNumber((rate_e)pRateAdaptation->RatesMap[pRateAdaptation->currRateIndex].rateNumber) >= (pRateAdaptation->tspecsRateParameters[i].lowRateThreshold)) )
310					{
311						tspecRateCross.uAC = i;
312						tspecRateCross.uHighOrLowThresholdFlag = LOW_THRESHOLD_CROSS;
313                        tspecRateCross.uAboveOrBelowFlag = CROSS_ABOVE;
314						EvHandlerSendEvent(pRateAdaptation->hEvHandler, IPC_EVENT_TSPEC_RATE_STATUS, (UINT8 *)&tspecRateCross,sizeof(OS_802_11_THRESHOLD_CROSS_INDICATION_PARAMS));
315					}
316
317			}
318		}
319	}
320    else {
321        /* no change */
322        pRateAdaptation->expirTimeTick = os_timeStampMs(pRateAdaptation->hOs) + pRateAdaptation->ctrlDataFBLongInterval;
323	    pRateAdaptation->stepUpFlag = FALSE;
324    }
325
326}
327/***************************************************************************
328*							rateAdaptation_getCurrent
329****************************************************************************
330* DESCRIPTION:	get current state - Rate and Modulation
331*               Note: since a pointer to the rates map is returned,
332*               Its content should be treated as READ ONLY!!!
333****************************************************************************/
334rateModulation4x_table_t* rateAdaptation_getCurrent(rateAdaptation_t* pRateAdaptation)
335{
336    return &(pRateAdaptation->RatesMap[pRateAdaptation->currRateIndex]);
337}
338
339/***************************************************************************
340*						rateAdaptation_getCurrentRate
341****************************************************************************
342* DESCRIPTION:	get current Rate
343****************************************************************************/
344rate_e rateAdaptation_getCurrentRate(rateAdaptation_t* pRateAdaptation)
345{
346	return pRateAdaptation->RatesMap[pRateAdaptation->currRateIndex].rate;
347}
348
349/***************************************************************************
350*					rateAdaptation_getCurrentModulation		               *
351****************************************************************************
352* DESCRIPTION:	get current Modulation
353****************************************************************************/
354modulationType_e rateAdaptation_getCurrentModulation(rateAdaptation_t* pRateAdaptation)
355{
356	return pRateAdaptation->RatesMap[pRateAdaptation->currRateIndex].modulation;
357}
358
359/***************************************************************************
360*					rateAdaptation_getCurrentFourXEnable	               *
361****************************************************************************
362* DESCRIPTION:	get current fourx status
363****************************************************************************/
364BOOL rateAdaptation_getCurrentFourXEnable(rateAdaptation_t* pRateAdaptation)
365{
366	return pRateAdaptation->RatesMap[pRateAdaptation->currRateIndex].fourXEnable;
367}
368
369/***************************************************************************
370*					rateAdaptation_buildRateMapTable		               *
371****************************************************************************
372* DESCRIPTION:	build the rate map table
373****************************************************************************/
374TI_STATUS rateAdaptation_buildRateMapTable(rateAdaptation_t		*pRateAdaptation,
375												   ctrlData_rateAdapt_t *currTable,
376												   UINT32				supportedBitMap,
377												   UINT32				clientBitMap,
378												   modulationType_e		modulation,
379												   BOOL					enable4x,
380												   bssType_e			bssType)
381{
382	UINT8 i = 0;
383	UINT8 index = 0;
384	UINT32					statusData;
385	UINT8 fallBack,stepUp;
386
387	/*
388	Note : allRates[] is changed due to the fact that rate_e was set in the
389	wrong order : 6,9 were in higher numeric value then 5.5 and 11 !!!
390	 */
391	rate_e	allRates[] =   {DRV_RATE_1M,
392							DRV_RATE_2M,
393							DRV_RATE_5_5M,
394							DRV_RATE_6M,
395							DRV_RATE_9M,
396							DRV_RATE_11M,
397							DRV_RATE_12M,
398							DRV_RATE_18M,
399							DRV_RATE_22M,
400							DRV_RATE_24M,
401							DRV_RATE_36M,
402							DRV_RATE_48M,
403							DRV_RATE_54M
404	};
405
406	while(i < DRV_RATE_MAX)
407	{
408		if(rateAdaptation_Utils_IsRateInBitmap(pRateAdaptation,
409											  supportedBitMap,
410											  allRates[i]) == OK)
411		{
412			/* update rates parameters */
413			pRateAdaptation->RatesMap[index].rate = allRates[i];
414			pRateAdaptation->RatesMap[index].rateNumber = hostRateToNumber(allRates[i]);
415
416			if((rateAdaptation_isRateInTable(currTable,pRateAdaptation->RatesMap[index].rate)) &&
417				(rateAdaptation_Utils_IsRateInBitmap(pRateAdaptation,
418													clientBitMap,
419													allRates[i]) == OK))
420			{
421				pRateAdaptation->RatesMap[index].valid = TRUE;
422				rateAdaptation_getFallBackStepUp(currTable,pRateAdaptation->RatesMap[index].rate,&fallBack,&stepUp);
423				pRateAdaptation->RatesMap[index].rateAdaptFallBack = fallBack;
424				pRateAdaptation->RatesMap[index].rateAdaptStepUp = stepUp;
425
426				/* update modulation parameter */
427				pRateAdaptation->RatesMap[index].modulation = setModulationForRate(pRateAdaptation,
428																				   pRateAdaptation->RatesMap[index].rate,
429																				   modulation,bssType);
430
431				/* update 4x enable parameter */
432				pRateAdaptation->RatesMap[index].fourXEnable = set4xEnableForRate(pRateAdaptation,
433					 															  pRateAdaptation->RatesMap[index].rate,
434																				  enable4x, bssType);
435
436				pRateAdaptation->maxRateIndex = index;
437				pRateAdaptation->currRateIndex = index;
438			}
439			else
440			{
441				pRateAdaptation->RatesMap[index].valid = FALSE;
442				pRateAdaptation->RatesMap[index].modulation = setModulationForRate(pRateAdaptation,
443																				   pRateAdaptation->RatesMap[index].rate,
444																				   modulation,bssType);
445			}
446
447			index++;
448		}
449
450		i++;
451	}
452
453	/* report the current rate to OS */
454	statusData = hostToUtilityRate(pRateAdaptation->RatesMap[pRateAdaptation->currRateIndex].rate);
455
456    EvHandlerSendEvent(pRateAdaptation->hEvHandler, IPC_EVENT_LINK_SPEED, (UINT8 *)&statusData,sizeof(UINT32));
457
458	return OK;
459}
460
461/***************************************************************************
462*							buildRateBitMap					               *
463****************************************************************************
464* DESCRIPTION:
465****************************************************************************/
466
467UINT32 rateAdaptation_Utils_buildRateBitMap(rateAdaptation_t	*pRateAdaptation,
468											ctrlData_rateAdapt_t *currTable,
469											rate_e			rate,
470											UINT32			supportedBitMap,
471											UINT32			clientBitMap)
472{
473	UINT32 buildRateBitMap = 0;
474	UINT8 rateNumber = hostRateToNumber(rate);
475
476	if( (rateNumber >= hostRateToNumber(DRV_RATE_1M)) && (rateAdaptation_isRateInTable(currTable, DRV_RATE_1M) ) ) buildRateBitMap |= (clientBitMap & supportedBitMap & DRV_RATE_MASK_1_BARKER);
477	if( (rateNumber >= hostRateToNumber(DRV_RATE_2M)) && (rateAdaptation_isRateInTable(currTable, DRV_RATE_2M) ) )  buildRateBitMap |= (clientBitMap & supportedBitMap & DRV_RATE_MASK_2_BARKER);
478	if( (rateNumber >= hostRateToNumber(DRV_RATE_5_5M)) && (rateAdaptation_isRateInTable(currTable, DRV_RATE_5_5M) ) ) buildRateBitMap |= (clientBitMap & supportedBitMap & DRV_RATE_MASK_5_5_CCK);
479	if( (rateNumber >= hostRateToNumber(DRV_RATE_11M)) && (rateAdaptation_isRateInTable(currTable, DRV_RATE_11M) ) ) buildRateBitMap |= (clientBitMap & supportedBitMap & DRV_RATE_MASK_11_CCK);
480	if( (rateNumber >= hostRateToNumber(DRV_RATE_22M)) && (rateAdaptation_isRateInTable(currTable, DRV_RATE_22M) ) ) buildRateBitMap |= (clientBitMap & supportedBitMap & DRV_RATE_MASK_22_PBCC);
481	if( (rateNumber >= hostRateToNumber(DRV_RATE_6M)) && (rateAdaptation_isRateInTable(currTable, DRV_RATE_6M) ) )  buildRateBitMap |= (clientBitMap & supportedBitMap & DRV_RATE_MASK_6_OFDM);
482	if( (rateNumber >= hostRateToNumber(DRV_RATE_9M)) && (rateAdaptation_isRateInTable(currTable, DRV_RATE_9M) ) )  buildRateBitMap |= (clientBitMap & supportedBitMap & DRV_RATE_MASK_9_OFDM);
483	if( (rateNumber >= hostRateToNumber(DRV_RATE_12M)) && (rateAdaptation_isRateInTable(currTable, DRV_RATE_12M) ) ) buildRateBitMap |= (clientBitMap & supportedBitMap & DRV_RATE_MASK_12_OFDM);
484	if( (rateNumber >= hostRateToNumber(DRV_RATE_18M)) && (rateAdaptation_isRateInTable(currTable, DRV_RATE_18M) ) ) buildRateBitMap |= (clientBitMap & supportedBitMap & DRV_RATE_MASK_18_OFDM);
485	if( (rateNumber >= hostRateToNumber(DRV_RATE_24M)) && (rateAdaptation_isRateInTable(currTable, DRV_RATE_24M) ) ) buildRateBitMap |= (clientBitMap & supportedBitMap & DRV_RATE_MASK_24_OFDM);
486	if( (rateNumber >= hostRateToNumber(DRV_RATE_36M)) && (rateAdaptation_isRateInTable(currTable, DRV_RATE_36M) ) ) buildRateBitMap |= (clientBitMap & supportedBitMap & DRV_RATE_MASK_36_OFDM);
487	if( (rateNumber >= hostRateToNumber(DRV_RATE_48M)) && (rateAdaptation_isRateInTable(currTable, DRV_RATE_48M) ) ) buildRateBitMap |= (clientBitMap & supportedBitMap & DRV_RATE_MASK_48_OFDM);
488	if( (rateNumber >= hostRateToNumber(DRV_RATE_54M)) && (rateAdaptation_isRateInTable(currTable, DRV_RATE_54M) ) ) buildRateBitMap |= (clientBitMap & supportedBitMap & DRV_RATE_MASK_54_OFDM);
489
490	return buildRateBitMap;
491}
492
493/***************************************************************************
494*							rateAdaptation_isRateInTable					               *
495****************************************************************************
496* DESCRIPTION:	check if a specific rate is in a rates table
497****************************************************************************/
498
499BOOL rateAdaptation_isRateInTable(ctrlData_rateAdapt_t *currTable,
500										rate_e			rate)
501{
502	UINT8 i = 0;
503
504	while(i <= currTable->len)
505	{
506		if(currTable->rateAdaptRatesTable[i++] == rate)
507			return TRUE;
508	}
509	return FALSE;
510}
511
512/***************************************************************************
513*							rateAdaptation_getFallBackStepUp					               *
514****************************************************************************
515* DESCRIPTION:	return Fall Back & Step UP values of a certain rate
516****************************************************************************/
517
518void rateAdaptation_getFallBackStepUp(ctrlData_rateAdapt_t *currTable,
519										rate_e			rate,UINT8* FB,UINT8* SU)
520{
521	UINT8 i = 0;
522
523	while(i <= currTable->len)
524	{
525		if(currTable->rateAdaptRatesTable[i++] == rate)
526		{
527			*FB = currTable->rateAdaptFBTable[--i];
528			*SU = currTable->rateAdaptSUTable[i];
529			return;
530		}
531	}
532
533	*FB = 0;
534	*SU = 0;
535}
536
537
538/***************************************************************************
539*							IsRateInBitmap					               *
540****************************************************************************
541* DESCRIPTION:	check if a specific rate is in a rates bitmap
542****************************************************************************/
543TI_STATUS rateAdaptation_Utils_IsRateInBitmap(rateAdaptation_t	*pRateAdaptation,
544											UINT32				ratesBitMap,
545											rate_e				rate)
546{
547	if( ( (rate == DRV_RATE_1M) && (ratesBitMap & DRV_RATE_MASK_1_BARKER) )||
548		( (rate == DRV_RATE_2M) && (ratesBitMap & DRV_RATE_MASK_2_BARKER) ) ||
549		( (rate == DRV_RATE_5_5M) && (ratesBitMap & DRV_RATE_MASK_5_5_CCK) ) ||
550		( (rate == DRV_RATE_11M) && (ratesBitMap & DRV_RATE_MASK_11_CCK) ) ||
551		( (rate == DRV_RATE_22M) && (ratesBitMap & DRV_RATE_MASK_22_PBCC) ) ||
552		( (rate == DRV_RATE_6M) && (ratesBitMap & DRV_RATE_MASK_6_OFDM) ) ||
553		( (rate == DRV_RATE_9M) && (ratesBitMap & DRV_RATE_MASK_9_OFDM) ) ||
554		( (rate == DRV_RATE_12M) && (ratesBitMap & DRV_RATE_MASK_12_OFDM) ) ||
555		( (rate == DRV_RATE_18M) && (ratesBitMap & DRV_RATE_MASK_18_OFDM) ) ||
556		( (rate == DRV_RATE_24M) && (ratesBitMap & DRV_RATE_MASK_24_OFDM) ) ||
557		( (rate == DRV_RATE_36M) && (ratesBitMap & DRV_RATE_MASK_36_OFDM) ) ||
558		( (rate == DRV_RATE_48M) && (ratesBitMap & DRV_RATE_MASK_48_OFDM) ) ||
559		( (rate == DRV_RATE_54M) && (ratesBitMap & DRV_RATE_MASK_54_OFDM) ) )
560	{
561		return OK;
562	}
563
564	return NOK;
565}
566/***************************************************************************
567*							setModulationForRate			               *
568****************************************************************************
569* DESCRIPTION:	set modulation for the rate map table
570****************************************************************************/
571
572static modulationType_e setModulationForRate(rateAdaptation_t	*pRateAdaptation,
573   											 rate_e				rate,
574  											 modulationType_e	modulation,
575											 bssType_e			bssType)
576{
577	switch(rate)
578	{
579		case DRV_RATE_1M:
580			return DRV_MODULATION_QPSK;
581
582		case DRV_RATE_2M:
583			return DRV_MODULATION_QPSK;
584
585		case DRV_RATE_5_5M:
586			if( (modulation == DRV_MODULATION_PBCC) &&
587				(bssType == BSS_INFRASTRUCTURE) )
588				return DRV_MODULATION_PBCC;
589			else
590				return DRV_MODULATION_CCK;
591
592		case DRV_RATE_11M:
593			if( (modulation == DRV_MODULATION_PBCC) &&
594				(bssType == BSS_INFRASTRUCTURE) )
595				return DRV_MODULATION_PBCC;
596			else
597				return DRV_MODULATION_CCK;
598
599		case DRV_RATE_22M:
600			return DRV_MODULATION_PBCC;
601
602		case DRV_RATE_6M:
603			return DRV_MODULATION_OFDM;
604
605		case DRV_RATE_9M:
606			return DRV_MODULATION_OFDM;
607
608		case DRV_RATE_18M:
609			return DRV_MODULATION_OFDM;
610
611		case DRV_RATE_12M:
612			return DRV_MODULATION_OFDM;
613
614		case DRV_RATE_24M:
615			return DRV_MODULATION_OFDM;
616
617		case DRV_RATE_36M:
618			return DRV_MODULATION_OFDM;
619
620		case DRV_RATE_48M:
621			return DRV_MODULATION_OFDM;
622
623		case DRV_RATE_54M:
624			return DRV_MODULATION_OFDM;
625
626		default:
627			WLAN_REPORT_ERROR(pRateAdaptation->hReport, RATE_ADAPTATION_MODULE_LOG,
628						(" setModulationForRate(): unKnown rate !!! \n"));
629			return DRV_MODULATION_NONE;
630
631	}
632}
633
634static BOOL set4xEnableForRate(rateAdaptation_t*	pRateAdaptation,
635							   rate_e				rate,
636   							   BOOL					enable4x,
637							   bssType_e			bssType)
638{
639	if(bssType == BSS_INDEPENDENT)
640		return FALSE;
641
642	switch(rate)
643	{
644		case DRV_RATE_1M:
645			return FALSE;
646
647		case DRV_RATE_2M:
648			return FALSE;
649
650		case DRV_RATE_5_5M:
651			return FALSE;
652
653		case DRV_RATE_11M:
654			return enable4x;
655
656		case DRV_RATE_22M:
657			return enable4x;
658
659		case DRV_RATE_6M:
660			return FALSE;
661
662		case DRV_RATE_9M:
663			return FALSE;
664
665		case DRV_RATE_18M:
666			return enable4x;
667
668		case DRV_RATE_12M:
669			return enable4x;
670
671		case DRV_RATE_24M:
672			return enable4x;
673
674		case DRV_RATE_36M:
675			return enable4x;
676
677		case DRV_RATE_48M:
678			return enable4x;
679
680		case DRV_RATE_54M:
681			return enable4x;
682
683		default:
684			WLAN_REPORT_ERROR(pRateAdaptation->hReport, RATE_ADAPTATION_MODULE_LOG,
685						(" set4xEnableForRate(): unKnown rate !!! \n"));
686			return DRV_MODULATION_NONE;
687
688	}
689
690
691}
692/***************************************************************************
693*					rateAdaptation_setMaxActivRate
694****************************************************************************
695* DESCRIPTION:	set current rate
696****************************************************************************/
697TI_STATUS rateAdaptation_setMaxActivRate(rateAdaptation_t* pRateAdaptation, rate_e rate)
698{
699	UINT8  index;
700	UINT32 status;
701
702	status = rateAdaptationa_rateToIndexInRateMapTable(pRateAdaptation, rate, &index);
703
704	if(status != OK)
705		return NOK;
706
707	pRateAdaptation->maxRateIndex = index;
708
709	return OK;
710}
711
712/***************************************************************************
713*					rateAdaptation_configLowRateThrsh
714****************************************************************************
715* DESCRIPTION:	set low rate threshold
716****************************************************************************/
717TI_STATUS rateAdaptation_configLowRateThrsh(rateAdaptation_t *pRateAdaptation, UINT8 rate)
718{
719	pRateAdaptation->lowRateThreshold = rate;
720
721	WLAN_REPORT_INFORMATION(pRateAdaptation->hReport, RATE_ADAPTATION_MODULE_LOG,
722			(" \nrateAdaptation_configLowRateThrsh:rate  %d, translated to %d \n", rate, pRateAdaptation->lowRateThreshold));
723
724	return OK;
725}
726
727/***************************************************************************
728*					rateAdaptation_updateModulation
729****************************************************************************
730* DESCRIPTION:	set current rate
731****************************************************************************/
732void rateAdaptation_updateModulation(rateAdaptation_t* pRateAdaptation,
733									 modulationType_e modulation,
734									 bssType_e bssType)
735{
736	UINT8 index = 0;
737
738	for(index = 0 ; index < pRateAdaptation->maxRateIndex ; index++)
739	{
740		pRateAdaptation->RatesMap[index].modulation = setModulationForRate(pRateAdaptation,
741   																			pRateAdaptation->RatesMap[index].rate,
742  																			modulation,
743																			bssType);
744	}
745}
746/***************************************************************************
747*					rateAdaptation_updateModulation
748****************************************************************************
749* DESCRIPTION:	set current rate
750****************************************************************************/
751void rateAdaptation_update4xEnable(rateAdaptation_t* pRateAdaptation,
752								   BOOL				 enable4x,
753								   bssType_e		 bssType)
754{
755	UINT8 index = 0;
756
757	for(index = 0 ; index < pRateAdaptation->maxRateIndex ; index++)
758	{
759		pRateAdaptation->RatesMap[index].fourXEnable = set4xEnableForRate(pRateAdaptation,
760																		  pRateAdaptation->RatesMap[index].rate,
761																		  enable4x, bssType);
762
763	}
764}
765/***************************************************************************
766*						ctrlData_rateAdaptationStart
767****************************************************************************
768* DESCRIPTION:	This function start the Rate Adaptation algorithm
769***************************************************************************/
770TI_STATUS rateAdaptation_start(rateAdaptation_t* pRateAdaptation)
771{
772	UINT32					statusData;
773
774	pRateAdaptation->txCount = 0;
775	pRateAdaptation->txSkipCount = 0;
776	pRateAdaptation->txFailCount = 0;
777    pRateAdaptation->txRateFallBackCount = 0;
778
779	pRateAdaptation->stepUpFlag = FALSE;
780
781	os_timerStart(pRateAdaptation->hOs, pRateAdaptation->pTimer,pRateAdaptation->rateAdapt_timeout,FALSE);
782
783	pRateAdaptation->expirTimeTick = os_timeStampMs(pRateAdaptation->hOs) + pRateAdaptation->ctrlDataFBLongInterval;
784
785   	/* update OS with the current rate */
786	statusData = hostToUtilityRate(pRateAdaptation->RatesMap[pRateAdaptation->currRateIndex].rate);
787
788    EvHandlerSendEvent(pRateAdaptation->hEvHandler, IPC_EVENT_LINK_SPEED, (UINT8 *)&statusData,sizeof(UINT32));
789
790	return OK;
791}
792
793/***************************************************************************
794*						ctrlData_rateAdaptationStop
795****************************************************************************
796* DESCRIPTION:	This function stop the rate adaptation algorithm
797***************************************************************************/
798TI_STATUS rateAdaptation_stop(rateAdaptation_t* pRateAdaptation)
799{
800	os_timerStop(pRateAdaptation->hOs, pRateAdaptation->pTimer);
801
802	pRateAdaptation->txCount = 0;
803	pRateAdaptation->txSkipCount = 0;
804	pRateAdaptation->txFailCount = 0;
805    pRateAdaptation->txRateFallBackCount = 0;
806	pRateAdaptation->stepUpFlag = FALSE;
807	pRateAdaptation->expirTimeTick = 0;
808
809	pRateAdaptation->currRateIndex = pRateAdaptation->maxRateIndex;
810
811
812	return OK;
813}
814
815/***************************************************************************
816*						rateAdaptation_stopTimer
817****************************************************************************
818* DESCRIPTION:	This function stop the rate adaptation timer
819***************************************************************************/
820TI_STATUS rateAdaptation_stopTimer(rateAdaptation_t* pRateAdaptation)
821{
822	os_timerStop(pRateAdaptation->hOs, pRateAdaptation->pTimer);
823
824	return OK;
825}
826
827
828/***************************************************************************
829*					rateAdaptation_setCurrentRate
830****************************************************************************
831* DESCRIPTION:	set current rate
832****************************************************************************/
833TI_STATUS rateAdaptation_setCurrentRate(rateAdaptation_t* pRateAdaptation,rate_e rate)
834{
835	UINT8					index;
836	UINT32					statusData;
837
838	if(rateAdaptationa_rateToIndexInRateMapTable(pRateAdaptation, rate, &index) == OK)
839		pRateAdaptation->currRateIndex = index;
840	else
841		pRateAdaptation->currRateIndex = pRateAdaptation->maxRateIndex;
842
843	/* report the current rate to OS */
844
845	statusData = hostToUtilityRate(pRateAdaptation->RatesMap[pRateAdaptation->currRateIndex].rate);
846
847    EvHandlerSendEvent(pRateAdaptation->hEvHandler, IPC_EVENT_LINK_SPEED, (UINT8 *)&statusData,sizeof(UINT32));
848
849	return OK;
850}
851
852/***************************************************************************
853*					ctrlData_rateToIndexInRateMapTable
854****************************************************************************
855* DESCRIPTION:	This function convert a specific rate to index in the
856*				Rate Adaptation algorithm ratemap table
857*
858* INPUTS:		pRateAdaptation - the object
859*				rate - the rate to convert
860*
861* OUTPUT:		Index - the index of the rate in the table.
862*
863* RETURNS:		If the rate is not in the table - return NOK otherwise OK
864***************************************************************************/
865static TI_STATUS rateAdaptationa_rateToIndexInRateMapTable(rateAdaptation_t* pRateAdaptation,
866														   rate_e rate, UINT8* Index)
867{
868	UINT8 i;
869
870	for(i = 0 ; i <= pRateAdaptation->maxRateIndex ; i++)
871	{
872		if(pRateAdaptation->RatesMap[i].rate == rate)
873		{
874			*Index = i;
875			return OK;
876		}
877	}
878
879	return NOK;
880}
881
882/***************************************************************************
883*					getPrevRate
884****************************************************************************
885* DESCRIPTION:
886*
887* INPUTS:		pRateAdaptation - the object
888*
889* RETURNS:		new rate
890****************************************************************************/
891UINT8 getPrevRate(rateAdaptation_t *pRateAdaptation)
892{
893    INT16 i;
894    if(pRateAdaptation->currRateIndex != 0)
895    {
896        for(i = pRateAdaptation->currRateIndex - 1; i > 0; i--)
897        {
898            if(pRateAdaptation->RatesMap[i].valid)
899                return (UINT8)i;
900        }
901    }
902    return pRateAdaptation->currRateIndex;
903}
904
905
906
907/***************************************************************************
908*					getNextRate
909****************************************************************************
910* DESCRIPTION:
911*
912* INPUTS:		pRateAdaptation - the object
913*
914* RETURNS:		new rate
915****************************************************************************/
916UINT8 getNextRate(rateAdaptation_t *pRateAdaptation)
917{
918	UINT32 i;
919
920	for(i = pRateAdaptation->currRateIndex + 1; i <= pRateAdaptation->maxRateIndex; i++)
921	{
922		if(pRateAdaptation->RatesMap[i].valid)
923			return i;
924	}
925
926	return pRateAdaptation->currRateIndex;
927}
928
929/***************************************************************************
930*					rateAdaptation_updateRateAdaptation
931****************************************************************************
932* DESCRIPTION:	This function perform the Rate Adaptation algorithm. It
933*				called for every tx complete.
934*
935* INPUTS:		pRateAdaptation - the object
936*				actualTxRate - the actual tx rate
937*				requestTxRate - the request tx rate
938*				TxStatus - the tx status
939*               txNumWaiting - the number of descriptors in the HW with previous rate
940*
941* RETURNS:		OK/NOK
942****************************************************************************/
943TI_STATUS rateAdaptation_updateRateAdaptation(rateAdaptation_t* pRateAdaptation,
944											  rate_e			actualTxRate,
945											  rate_e			requestTxRate,
946											  UINT32			TxStatus,
947                                              int               txNumWaiting)
948{
949
950	UINT32		txFailPercent;
951	UINT32		timeStamp;
952	UINT8		actualTxRateNumber = hostRateToNumber(actualTxRate);
953	UINT8		requestTxRateNumber = hostRateToNumber(requestTxRate);
954	OS_802_11_THRESHOLD_CROSS_INDICATION_PARAMS	tspecRateCross;
955	UINT8		i,prevIndex = pRateAdaptation->currRateIndex;
956
957    /* Check if need to skip some packets due to rate update */
958    if (pRateAdaptation->txSkipCount > 0) {
959        pRateAdaptation->txSkipCount--;
960        return OK;
961    }
962
963    timeStamp = os_timeStampMs(pRateAdaptation->hOs);
964
965	pRateAdaptation->txCount++;
966
967    /* if the TxStatus wasn't SUCCESS or the rate was falling back - we will update the mechanism, unless */
968	/* the TxStatus is LIFETIME_EXCEEDED and there were no retries - we won't update the mechanism        */
969	if(((TxStatus != SEND_COMPLETE_SUCCESS) && (TxStatus != SEND_COMPLETE_LIFETIME_EXCEEDED))
970        || (actualTxRateNumber < requestTxRateNumber))
971	{
972		pRateAdaptation->txFailCount++;
973        if (actualTxRateNumber < requestTxRateNumber)
974           pRateAdaptation->txRateFallBackCount++;
975	}
976
977	/* Verify if the checking time has come. */
978	if( TS_EXCEEDS(timeStamp, pRateAdaptation->expirTimeTick) )
979	{
980		/* If step up has just done wait for 10 packets only. */
981		if((pRateAdaptation->stepUpFlag == TRUE) &&
982			(pRateAdaptation->txCount > pRateAdaptation->stepUpTxPacketsThreshold ))
983		{
984			/* Calculate the packet fail percent. */
985			txFailPercent = (pRateAdaptation->txFailCount * 100) / pRateAdaptation->txCount;
986
987			pRateAdaptation->stepUpFlag = FALSE; /* Flag is off for next time. */
988
989			if( (txFailPercent > pRateAdaptation->RatesMap[pRateAdaptation->currRateIndex].rateAdaptFallBack) &&
990				(pRateAdaptation->currRateIndex > 0) )
991			{
992				pRateAdaptation->currRateIndex = getPrevRate(pRateAdaptation);
993			}
994		}
995		else if (pRateAdaptation->txCount > pRateAdaptation->contTxPacketsThreshold )
996		{
997			/* Calculate the packet fail percents. */
998			txFailPercent = (pRateAdaptation->txFailCount * 100) / pRateAdaptation->txCount;
999
1000			if ( (txFailPercent > pRateAdaptation->RatesMap[pRateAdaptation->currRateIndex].rateAdaptFallBack) &&
1001				(pRateAdaptation->currRateIndex > 0) )
1002			{
1003                pRateAdaptation->currRateIndex = getPrevRate(pRateAdaptation);
1004			}
1005			else if ((txFailPercent < pRateAdaptation->RatesMap[pRateAdaptation->currRateIndex].rateAdaptStepUp) &&
1006				(pRateAdaptation->currRateIndex < pRateAdaptation->maxRateIndex))
1007			{
1008				pRateAdaptation->currRateIndex = getNextRate(pRateAdaptation);
1009				pRateAdaptation->stepUpFlag = TRUE; /* Flag is on for next time. */
1010			}
1011		}
1012		else
1013		{
1014			return OK;
1015		}
1016
1017		/* update OS with the current rate */
1018		if(prevIndex != pRateAdaptation->currRateIndex)
1019		{
1020			UINT32			statusData;
1021			paramInfo_t		param;
1022			rate_e			currentRate = pRateAdaptation->RatesMap[pRateAdaptation->currRateIndex].rate;
1023			UINT8			currentRateNumber = pRateAdaptation->RatesMap[pRateAdaptation->currRateIndex].rateNumber;
1024
1025		    WLAN_REPORT_WARNING(pRateAdaptation->hReport, RATE_ADAPTATION_MODULE_LOG,
1026			    (" RateAdapt() : Time: %d, Fail: %d, Count: %d,Skip: %d\n",
1027                timeStamp,pRateAdaptation->txFailCount,pRateAdaptation->txCount,txNumWaiting));
1028
1029			WLAN_REPORT_WARNING(pRateAdaptation->hReport, RATE_ADAPTATION_MODULE_LOG,
1030			    (" OldRate(Index,Rate): %d,%d\n ",prevIndex,pRateAdaptation->RatesMap[prevIndex].rateNumber));
1031			WLAN_REPORT_WARNING(pRateAdaptation->hReport, RATE_ADAPTATION_MODULE_LOG,
1032				(" NewRate(Index,Rate): %d,%d\n ",pRateAdaptation->currRateIndex,currentRateNumber));
1033
1034			/* If the current rate is lower or equal to the roaming threshold, issue roaming trigger. */
1035			if (currentRateNumber <= pRateAdaptation->lowRateThreshold)
1036			{
1037				roamingEventData_u RoamingEventData;
1038
1039				RoamingEventData.rate = currentRate;
1040				apConn_reportRoamingEvent(pRateAdaptation->hAPConnection, ROAMING_TRIGGER_LOW_TX_RATE, &RoamingEventData);
1041			}
1042
1043			/* Rate update - initialize the skip counter for packets that are already in the queue with old rates */
1044            if ((txNumWaiting >= 0) && (txNumWaiting <= 100)) {
1045                /* In reasonable range */
1046                pRateAdaptation->txSkipCount = (UINT32)txNumWaiting;
1047            } else {
1048                pRateAdaptation->txSkipCount = 30; /* something happened, at least skip 30 packets */
1049            }
1050
1051    		/* update OS with the current rate */
1052			param.paramType = CTRL_DATA_FOUR_X_CURRRENT_STATUS_PARAM;
1053			param.content.ctrlDataCerruentFourXstate = pRateAdaptation->RatesMap[pRateAdaptation->currRateIndex].fourXEnable;
1054			ctrlData_setParam(pRateAdaptation->hCtrlData, &param);
1055
1056    		/* update OS with the current rate */
1057
1058			statusData = hostToUtilityRate(currentRate);
1059
1060            EvHandlerSendEvent(pRateAdaptation->hEvHandler, IPC_EVENT_LINK_SPEED, (UINT8 *)&statusData,sizeof(UINT32));
1061
1062			/* send Tspecs Rate Event */
1063			for(i = 0 ; i < MAX_NUM_OF_AC ; i++)
1064			{
1065				if(pRateAdaptation->tspecsRateParameters[i].enableEvent == FALSE)
1066				{
1067					continue;
1068				}
1069				else
1070				{
1071					if ( (pRateAdaptation->RatesMap[prevIndex].rateNumber < pRateAdaptation->tspecsRateParameters[i].highRateThreshold) &&
1072						(currentRateNumber >= pRateAdaptation->tspecsRateParameters[i].highRateThreshold) )
1073					{
1074						tspecRateCross.uAC = i;
1075						tspecRateCross.uHighOrLowThresholdFlag = HIGH_THRESHOLD_CROSS;
1076                        tspecRateCross.uAboveOrBelowFlag = CROSS_ABOVE;
1077						EvHandlerSendEvent(pRateAdaptation->hEvHandler, IPC_EVENT_TSPEC_RATE_STATUS, (UINT8 *)&tspecRateCross,sizeof(OS_802_11_THRESHOLD_CROSS_INDICATION_PARAMS));
1078					}
1079					else
1080					if( (pRateAdaptation->RatesMap[prevIndex].rateNumber >= pRateAdaptation->tspecsRateParameters[i].highRateThreshold) &&
1081						(currentRateNumber < pRateAdaptation->tspecsRateParameters[i].highRateThreshold) )
1082					{
1083						tspecRateCross.uAC = i;
1084						tspecRateCross.uHighOrLowThresholdFlag = HIGH_THRESHOLD_CROSS;
1085                        tspecRateCross.uAboveOrBelowFlag = CROSS_BELOW;
1086						EvHandlerSendEvent(pRateAdaptation->hEvHandler, IPC_EVENT_TSPEC_RATE_STATUS, (UINT8 *)&tspecRateCross,sizeof(OS_802_11_THRESHOLD_CROSS_INDICATION_PARAMS));
1087					}
1088                    else
1089					if( (pRateAdaptation->RatesMap[prevIndex].rateNumber >= pRateAdaptation->tspecsRateParameters[i].lowRateThreshold) &&
1090						(currentRateNumber < pRateAdaptation->tspecsRateParameters[i].lowRateThreshold) )
1091					{
1092						tspecRateCross.uAC = i;
1093						tspecRateCross.uHighOrLowThresholdFlag = LOW_THRESHOLD_CROSS;
1094                        tspecRateCross.uAboveOrBelowFlag = CROSS_BELOW;
1095						EvHandlerSendEvent(pRateAdaptation->hEvHandler, IPC_EVENT_TSPEC_RATE_STATUS, (UINT8 *)&tspecRateCross,sizeof(OS_802_11_THRESHOLD_CROSS_INDICATION_PARAMS));
1096					}
1097                    else
1098					if( (pRateAdaptation->RatesMap[prevIndex].rateNumber < pRateAdaptation->tspecsRateParameters[i].lowRateThreshold) &&
1099						(currentRateNumber >= pRateAdaptation->tspecsRateParameters[i].lowRateThreshold) )
1100					{
1101						tspecRateCross.uAC = i;
1102						tspecRateCross.uHighOrLowThresholdFlag = LOW_THRESHOLD_CROSS;
1103                        tspecRateCross.uAboveOrBelowFlag = CROSS_ABOVE;
1104						EvHandlerSendEvent(pRateAdaptation->hEvHandler, IPC_EVENT_TSPEC_RATE_STATUS, (UINT8 *)&tspecRateCross,sizeof(OS_802_11_THRESHOLD_CROSS_INDICATION_PARAMS));
1105					}
1106
1107				}
1108			}
1109
1110		}
1111
1112		pRateAdaptation->txCount = 0;
1113		pRateAdaptation->txFailCount = 0;
1114        pRateAdaptation->txRateFallBackCount = 0;
1115		TS_ADVANCE( timeStamp, pRateAdaptation->expirTimeTick,
1116			(pRateAdaptation->stepUpFlag ? pRateAdaptation->ctrlDataFBShortInterval : pRateAdaptation->ctrlDataFBLongInterval));
1117
1118	}
1119
1120	return OK;
1121}
1122
1123/***************************************************************************
1124*					rateAdaptation_setTspecsRateParams
1125****************************************************************************
1126* DESCRIPTION:
1127*
1128* INPUTS:		pRateAdaptation - the object
1129**
1130* RETURNS:		OK/NOK
1131****************************************************************************/
1132
1133void rateAdaptation_setTspecsRateEvent(rateAdaptation_t* pRateAdaptation,
1134											 UINT8			acID,
1135											BOOL			enableEvent)
1136{
1137
1138   /* Prevent ENABLE_EVENTS if one of the threshold of that AC is ZERO */
1139  if (((pRateAdaptation->tspecsRateParameters[acID].highRateThreshold == 0) ||
1140	 (pRateAdaptation->tspecsRateParameters[acID].lowRateThreshold == 0)) && (enableEvent == TRUE))
1141   return;
1142
1143	pRateAdaptation->tspecsRateParameters[acID].enableEvent = enableEvent;
1144}
1145
1146/***************************************************************************
1147*					rateAdaptation_setTspecsRateThresholds
1148****************************************************************************
1149* DESCRIPTION:
1150*
1151* INPUTS:		pRateAdaptation - the object
1152**
1153* RETURNS:		OK/NOK
1154****************************************************************************/
1155
1156void rateAdaptation_setTspecsRateThresholds(rateAdaptation_t* pRateAdaptation,
1157											 UINT8			acID,
1158											 UINT8			highRateThreshold,
1159											 UINT8			lowRateThreshold)
1160{
1161		if(highRateThreshold < lowRateThreshold)
1162		{
1163			WLAN_REPORT_ERROR(pRateAdaptation->hReport, RATE_ADAPTATION_MODULE_LOG,
1164					(" rateAdaptation_setTspecsRateThresholds() ERROR: highRateThreshold < lowRateThreshold,  ac = %d\n",acID));
1165
1166			pRateAdaptation->tspecsRateParameters[acID].highRateThreshold = 0;
1167			pRateAdaptation->tspecsRateParameters[acID].lowRateThreshold = 0;
1168
1169		}
1170		else
1171		{
1172			pRateAdaptation->tspecsRateParameters[acID].highRateThreshold = highRateThreshold;
1173			pRateAdaptation->tspecsRateParameters[acID].lowRateThreshold = lowRateThreshold;
1174		}
1175}
1176
1177
1178/*************************************************************************
1179 *																		 *
1180 *							DEBUG FUNCTIONS								 *
1181 *																		 *
1182 *************************************************************************/
1183void rateAdaptation_print(rateAdaptation_t *pRateAdaptation)
1184{
1185	UINT32 count;
1186
1187	WLAN_OS_REPORT(("     Rate Adaptation Parameters    \n"));
1188	WLAN_OS_REPORT(("-----------------------------------\n"));
1189	WLAN_OS_REPORT(("txCount                   = %d\n",pRateAdaptation->txCount));
1190	WLAN_OS_REPORT(("txFailCount               = %d\n",pRateAdaptation->txFailCount));
1191    WLAN_OS_REPORT(("txRateFallBackCount       = %d\n",pRateAdaptation->txRateFallBackCount));
1192	WLAN_OS_REPORT(("txSkipCount               = %d\n",pRateAdaptation->txSkipCount));
1193	WLAN_OS_REPORT(("currRateIndex             = %d\n",pRateAdaptation->currRateIndex));
1194	WLAN_OS_REPORT(("currRate Number           = %d\n",pRateAdaptation->RatesMap[pRateAdaptation->currRateIndex].rateNumber));
1195	WLAN_OS_REPORT(("maxRateIndex              = %d\n",pRateAdaptation->maxRateIndex));
1196	WLAN_OS_REPORT(("maxRate Number            = %d\n",pRateAdaptation->RatesMap[pRateAdaptation->maxRateIndex].rateNumber));
1197	WLAN_OS_REPORT(("stepUpFlag                = %d\n",pRateAdaptation->stepUpFlag));
1198	WLAN_OS_REPORT(("expirTimeTick             = %d\n",pRateAdaptation->expirTimeTick));
1199	WLAN_OS_REPORT(("stepUpTxPacketsThreshold  = %d\n",pRateAdaptation->stepUpTxPacketsThreshold));
1200	WLAN_OS_REPORT(("contTxPacketsThreshold    = %d\n",pRateAdaptation->contTxPacketsThreshold));
1201	WLAN_OS_REPORT(("ctrlDataFBShortInterval   = %d\n",pRateAdaptation->ctrlDataFBShortInterval));
1202	WLAN_OS_REPORT(("ctrlDataFBLongInterval    = %d\n",pRateAdaptation->ctrlDataFBLongInterval));
1203
1204	WLAN_OS_REPORT(("    Rate Adaptation Table    \n"));
1205	WLAN_OS_REPORT(("-----------------------------\n"));
1206	for(count = 0 ; count <  MAX_SUPPORTED_RATES ; count++)
1207	{
1208		WLAN_OS_REPORT(("Index = %d ,RateNumber = %d,StepUp = %d ,FallBack = %d , Modulation = %d 4X = %d valid = %d,\n",
1209									count,
1210										  pRateAdaptation->RatesMap[count].rateNumber,
1211										  pRateAdaptation->RatesMap[count].rateAdaptStepUp,
1212										  pRateAdaptation->RatesMap[count].rateAdaptFallBack,
1213										  pRateAdaptation->RatesMap[count].modulation,
1214										  pRateAdaptation->RatesMap[count].fourXEnable,
1215										  pRateAdaptation->RatesMap[count].valid));
1216	}
1217
1218	WLAN_OS_REPORT(("Tspecs Rate Parameters AC = %d  \n",count));
1219	WLAN_OS_REPORT(("-----------------------------\n"));
1220	for(count = 0 ; count < MAX_NUM_OF_AC ; count++)
1221	{
1222		WLAN_OS_REPORT(("AC = %d  \n",count));
1223		WLAN_OS_REPORT(("---------\n"));
1224		WLAN_OS_REPORT(("enableEvent = %d  \n",pRateAdaptation->tspecsRateParameters[count].enableEvent));
1225		WLAN_OS_REPORT(("highRateThreshold = %d  \n",pRateAdaptation->tspecsRateParameters[count].highRateThreshold));
1226		WLAN_OS_REPORT(("lowRateThreshold = %d  \n",pRateAdaptation->tspecsRateParameters[count].lowRateThreshold));
1227	}
1228
1229
1230}
1231
1232