2 * Copyright (c) 2007-2008 Atheros Communications Inc.
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 const u32_t zcRateToPhyCtrl[] =
22 /* 1M, 2M, 5M, 11M , 0 1 2 3*/
23 0x00000, 0x10000, 0x20000, 0x30000,
24 /* 6M 9M 12M 18M , 4 5 6 7*/
25 0xb0001, 0xf0001, 0xa0001, 0xe0001,
26 /* 24M 36M 48M 54M , 8 9 10 11*/
27 0x90001, 0xd0001, 0x80001, 0xc0001,
28 /* MCS0 MCS1 MCS2 MCS3, 12 13 14 15*/
29 0x00002, 0x10002, 0x20002, 0x30002,
30 /* MCS4 MCS5 MCS6 MCS7, 16 17 18 19*/
31 0x40002, 0x50002, 0x60002, 0x70002,
32 /* MCS8 MCS9 MCS10 MCS11, 20 21 22 23*/
33 0x80002, 0x90002, 0xa0002, 0xb0002,
34 /* MCS12 MCS13 MCS14 MCS15, 24 25 26 27*/
35 0xc0002, 0xd0002, 0xe0002, 0xf0002,
36 /* MCS14SG, MCS15SG MCS7SG , 28 29, 30*/
37 0x800e0002, 0x800f0002, 0x80070002
41 const u8_t zcHtRateTable[15][4] =
42 { /*[5G 20MHz] [5G 40MHz] [2.4G 20MHz] [2.4G 40MHz]*/
43 { 4, 4, 0, 0}, /*OFDM6M OFDM6M CCK1M CCK1M */
44 { 5, 5, 1, 1}, /*OFDM9M OFDM9M CCK2M CCK2M */
45 { 13, 12, 2, 2}, /*MCS1 MCS0 CCK5M CCK5M */
46 { 14, 13, 3, 3}, /*MCS2 MCS1 CCK11M CCK11M */
47 { 15, 14, 13, 12}, /*MCS3 MCS2 MCS1 MCS0 */
48 { 16, 15, 14, 13}, /*MCS4 MCS3 MCS2 MCS1 */
49 { 23, 16, 15, 14}, /*MCS11 MCS4 MCS3 MCS2 */
50 { 24, 23, 16, 15}, /*MCS12 MCS11 MCS4 MCS3 */
51 { 25, 24, 23, 16}, /*MCS13 MCS12 MCS11 MCS4 */
52 { 26, 25, 24, 23}, /*MCS14 MCS13 MCS12 MCS11 */
53 { 27, 26, 25, 24}, /*MCS15 MCS14 MCS13 MCS12 */
54 { 0, 27, 26, 25}, /*0 MCS15 MCS14 MCS13 */
55 { 0, 29, 27, 26}, /*0 MCS15SG MCS15 MCS14 */
56 { 0, 0, 0, 28}, /*0 0 0 MCS14SG*/
57 { 0, 0, 0, 29} /*0 0 0 MCS15SG*/
60 const u8_t zcHtOneTxStreamRateTable[15][4] =
61 { /*[5G 20MHz] [5G 40MHz] [2.4G 20MHz] [2.4G 40MHz]*/
62 { 4, 4, 0, 0}, /*OFDM6M OFDM6M CCK1M CCK1M */
63 { 5, 5, 1, 1}, /*OFDM9M OFDM9M CCK2M CCK2M */
64 { 13, 12, 2, 2}, /*MCS1 MCS0 CCK5M CCK5M */
65 { 14, 13, 3, 3}, /*MCS2 MCS1 CCK11M CCK11M */
66 { 15, 14, 13, 12}, /*MCS3 MCS2 MCS1 MCS0 */
67 { 16, 15, 14, 13}, /*MCS4 MCS3 MCS2 MCS1 */
68 { 17, 16, 15, 14}, /*MCS5 MCS4 MCS3 MCS2 */
69 { 18, 17, 16, 15}, /*MCS6 MCS5 MCS4 MCS3 */
70 { 19, 18, 17, 16}, /*MCS7 MCS6 MCS5 MCS4 */
71 { 0, 19, 18, 17}, /*0 MCS7 MCS6 MCS5 */
72 { 0, 30, 19, 18}, /*0 MCS7SG MCS7 MCS6 */
73 { 0, 0, 0, 19}, /*0 0 0 MCS7 */
74 { 0, 0, 0, 30}, /*0 0 0 MCS7SG */
75 { 0, 0, 0, 0 }, /*0 0 0 0 */
76 { 0, 0, 0, 0 } /*0 0 0 0 */
79 const u16_t zcRate[] =
81 1, 2, 5, 11, /* 1M, 2M, 5M, 11M , 0 1 2 3*/
82 6, 9, 12, 18, /* 6M 9M 12M 18M , 4 5 6 7*/
83 24, 36, 48, 54, /* 24M 36M 48M 54M , 8 9 10 11*/
84 13, 27, 40, 54, /* MCS0 MCS1 MCS2 MCS3 , 12 13 14 15*/
85 81, 108, 121, 135, /* MCS4 MCS5 MCS6 MCS7 , 16 17 18 19*/
86 27, 54, 81, 108, /* MCS8 MCS9 MCS10 MCS11 , 20 21 22 23*/
87 162, 216, 243, 270, /* MCS12 MCS13 MCS14 MCS15 , 24 25 26 27*/
88 270, 300, 150 /* MCS14SG, MCS15SG, MCS7SG , 28 29 30*/
91 const u16_t PERThreshold[] =
93 100, 50, 50, 50, /* 1M, 2M, 5M, 11M , 0 1 2 3*/
94 50, 50, 30, 30, /* 6M 9M 12M 18M , 4 5 6 7*/
95 25, 25, 25, 20, /* 24M 36M 48M 54M , 8 9 10 11*/
96 50, 50, 50, 40, /* MCS0 MCS1 MCS2 MCS3 , 12 13 14 15*/
97 30, 30, 30, 30, /* MCS4 MCS5 MCS6 MCS7 , 16 17 18 19*/
98 30, 30, 25, 25, /* MCS8 MCS9 MCS10 MCS11 , 20 21 22 23*/
99 25, 25, 15, 15, /* MCS12 MCS13 MCS14 MCS15 , 24 25 26 27*/
100 15, 15, 10 /* MCS14SG, MCS15SG , 28 29*/
103 const u16_t FailDiff[] =
105 40, 46, 40, 0, /* 1M, 2M, 5M, 11M , 0 1 2 3*/
106 24, 17, 22, 16, /* 6M 9M 12M 18M , 4 5 6 7*/
107 19, 13, 5, 0, /* 24M 36M 48M 54M , 8 9 10 11*/
108 36, 22, 15, 19, /* MCS0 MCS1 MCS2 MCS3 , 12 13 14 15*/
109 12, 5, 4, 7, /* MCS4 MCS5 MCS6 MCS7 , 16 17 18 19*/
110 0, 0, 0, 0, /* MCS8 MCS9 MCS10 MCS11 , 20 21 22 23*/
111 9, 4, 3, 3, /* MCS12 MCS13 MCS14 MCS15 , 24 25 26 27*/
112 3, 0, 0 /* MCS14SG, MCS15SG , 28 29*/
116 #ifdef ZM_ENABLE_BA_RATECTRL
120 const u16_t BADiff[] =
133 /************************************************************************/
135 /* FUNCTION DESCRIPTION zfRateCtrlInitCell */
136 /* Initialize rate control cell. */
139 /* dev : device pointer */
140 /* type : 0=>11b, 1=>11a/g, 2=>11n, 3=>11n one Tx stream */
141 /* gBand : 1=>2.4G, 0=>5G */
147 /* Stephen Chen Atheros Communications, INC. 2007.2 */
149 /************************************************************************/
150 void zfRateCtrlInitCell(zdev_t* dev, struct zsRcCell* rcCell, u8_t type,
151 u8_t gBand, u8_t SG40)
155 zmw_get_wlan_dev(dev);
163 for (i=0; i<4; i++) //1M 2M 5M 11M
165 rcCell->operationRateSet[i] = (u8_t)i;
167 for (i=4; i<10; i++) //12M 18M 24M 36M 48M 54M
169 rcCell->operationRateSet[i] = 2+i;
171 rcCell->operationRateCount = 10;
172 rcCell->currentRateIndex = 5; //18M
174 else if (type == 2) //11ng
176 if (wd->wlanMode == ZM_MODE_AP) //AP 11ng 40M
180 rcCell->operationRateSet[i] = zcHtRateTable[i][3];
182 if(!SG40) rcCell->operationRateSet[13] = 27;
183 rcCell->operationRateCount = 14+SG40;
184 rcCell->currentRateIndex = 10;
188 if (wd->sta.htCtrlBandwidth == ZM_BANDWIDTH_40MHZ) //11ng 40M
192 rcCell->operationRateSet[i] = zcHtRateTable[i][3];
194 if(!SG40) rcCell->operationRateSet[13] = 27;
195 rcCell->operationRateCount = 14+SG40;
196 rcCell->currentRateIndex = 10;
202 rcCell->operationRateSet[i] = zcHtRateTable[i][2];
204 rcCell->operationRateCount = 13;
205 rcCell->currentRateIndex = 9;
209 else if (type == 3) //11ng one Tx stream
211 if (wd->sta.htCtrlBandwidth == ZM_BANDWIDTH_40MHZ) //11ng 40M one Tx stream
221 for (i=0; i<maxrate; i++)
223 rcCell->operationRateSet[i] = zcHtOneTxStreamRateTable[i][3];
225 rcCell->operationRateCount = i;
226 rcCell->currentRateIndex = ((i+1)*3)/4;
232 rcCell->operationRateSet[i] = zcHtOneTxStreamRateTable[i][2];
234 rcCell->operationRateCount = i;
235 rcCell->currentRateIndex = ((i+1)*3)/4;
238 else //if (type == 0) //11b
242 rcCell->operationRateSet[i] = (u8_t)i;
244 rcCell->operationRateCount = 4;
245 rcCell->currentRateIndex = rcCell->operationRateCount-1;
250 if (type == 2) //11na
252 if (wd->wlanMode == ZM_MODE_AP) //AP 11na 40M
254 for (i=0; i<(12+SG40); i++)
256 rcCell->operationRateSet[i] = zcHtRateTable[i][1];
258 rcCell->operationRateCount = 12+SG40;
259 rcCell->currentRateIndex = 8;
263 if (wd->sta.htCtrlBandwidth == ZM_BANDWIDTH_40MHZ) //11na 40M
265 for (i=0; i<(12+SG40); i++)
267 rcCell->operationRateSet[i] = zcHtRateTable[i][1];
269 rcCell->operationRateCount = 12+SG40;
270 rcCell->currentRateIndex = 8;
276 rcCell->operationRateSet[i] = zcHtRateTable[i][0];
278 rcCell->operationRateCount = 11;
279 rcCell->currentRateIndex = 7;
283 else if (type == 3) //11na one Tx stream
285 if (wd->sta.htCtrlBandwidth == ZM_BANDWIDTH_40MHZ) //11na 40M one Tx stream
295 for (i=0; i<maxrate; i++)
297 rcCell->operationRateSet[i] = zcHtOneTxStreamRateTable[i][1];
299 rcCell->operationRateCount = i;
300 rcCell->currentRateIndex = ((i+1)*3)/4;
306 rcCell->operationRateSet[i] = zcHtOneTxStreamRateTable[i][0];
308 rcCell->operationRateCount = i;
309 rcCell->currentRateIndex = ((i+1)*3)/4;
312 else //if (type == 1) //11a
314 for (i=0; i<8; i++) //6M 9M 12M 18M 24M 36M 48M 54M
316 rcCell->operationRateSet[i] = i+4;
318 rcCell->operationRateCount = 8;
319 rcCell->currentRateIndex = 4; //24M
325 rcCell->failCount = 0;
326 rcCell->currentRate = rcCell->operationRateSet[rcCell->currentRateIndex];
327 rcCell->lasttxCount = 0;
328 rcCell->lastTime = wd->tick;
329 rcCell->probingTime = wd->tick;
330 for (i=0; i<ZM_RATE_TABLE_SIZE; i++) {
332 wd->txMPDU[i] = wd->txFail[i] = 0;
335 wd->probeInterval = 0;
336 #ifdef ZM_ENABLE_BA_RATECTRL
337 for (i=0; i<29; i++) {
347 /************************************************************************/
349 /* FUNCTION DESCRIPTION zfRateCtrlGetHigherRate */
350 /* Get a higher rate. */
353 /* rcCell : rate control cell */
359 /* Stephen Chen Atheros Communications, INC. 2007.2 */
361 /************************************************************************/
362 u8_t zfRateCtrlGetHigherRate(struct zsRcCell* rcCell)
366 rateIndex = rcCell->currentRateIndex
367 + (((rcCell->currentRateIndex+1) < rcCell->operationRateCount)?1:0);
368 return rcCell->operationRateSet[rateIndex];
372 /************************************************************************/
374 /* FUNCTION DESCRIPTION zfRateCtrlNextLowerRate */
375 /* Get a lower rate. */
378 /* rcCell : rate control cell */
384 /* Stephen Chen Atheros Communications, INC. 2007.2 */
386 /************************************************************************/
387 u8_t zfRateCtrlNextLowerRate(zdev_t* dev, struct zsRcCell* rcCell)
389 zmw_get_wlan_dev(dev);
390 if (rcCell->currentRateIndex > 0)
392 rcCell->currentRateIndex--;
393 rcCell->currentRate = rcCell->operationRateSet[rcCell->currentRateIndex];
395 zm_msg1_tx(ZM_LV_0, "Lower Tx Rate=", rcCell->currentRate);
396 //DbgPrint("Lower Tx Rate=%d", rcCell->currentRate);
397 rcCell->failCount = rcCell->txCount = 0;
398 rcCell->lasttxCount = 0;
399 rcCell->lastTime = wd->tick;
400 return rcCell->currentRate;
404 /************************************************************************/
406 /* FUNCTION DESCRIPTION zfRateCtrlRateDiff */
407 /* Rate difference. */
410 /* rcCell : rate control cell */
411 /* retryRate : retry rate */
414 /* rate difference */
417 /* Stephen Chen Atheros Communications, INC. 2007.2 */
419 /************************************************************************/
420 u8_t zfRateCtrlRateDiff(struct zsRcCell* rcCell, u8_t retryRate)
424 /* Find retryRate in operationRateSet[] */
425 for (i=0; i<rcCell->operationRateCount; i++)
427 if (retryRate == rcCell->operationRateSet[i])
429 if (i < rcCell->currentRateIndex)
431 return ((rcCell->currentRateIndex - i)+1)>>1;
433 else if (i == rcCell->currentRateIndex == 0)
443 /* TODO : retry rate not in operation rate set */
444 zm_msg1_tx(ZM_LV_0, "Not in operation rate set:", retryRate);
449 u32_t zfRateCtrlUDPTP(zdev_t* dev, u16_t Rate, u32_t PER) {
450 if ((PER < 100) && (Rate > 0) && PER)
451 return 1168000/(((12304/Rate)+197)*(100+100*PER/(100-PER)));
456 u8_t zfRateCtrlFindMaxUDPTP(zdev_t* dev, struct zsRcCell* rcCell) {
457 u8_t i, maxIndex=0, rateIndex;
458 u32_t max=0, UDPThroughput;
460 zmw_get_wlan_dev(dev);
462 rateIndex = zm_agg_min(rcCell->currentRateIndex+3, rcCell->operationRateCount-1);
463 for (i=rcCell->currentRateIndex; i < rateIndex; i++) {
464 UDPThroughput = zfRateCtrlUDPTP(dev, zcRate[rcCell->operationRateSet[i]],
465 wd->PER[rcCell->operationRateSet[i]]);
466 if (max < UDPThroughput) {
472 return rcCell->operationRateSet[maxIndex];
474 /************************************************************************/
476 /* FUNCTION DESCRIPTION zfRateCtrlGetTxRate */
477 /* Get transmission rate. */
480 /* dev : device pointer */
481 /* rcCell : rate control cell */
482 /* probing : rate probing flag */
488 /* Stephen Chen Atheros Communications, INC. 2007.2 */
490 /************************************************************************/
491 u16_t zfRateCtrlGetTxRate(zdev_t* dev, struct zsRcCell* rcCell, u16_t* probing)
493 u8_t newRate, highRate;
494 zmw_get_wlan_dev(dev);
496 zm_msg1_tx(ZM_LV_3, "txCount=", rcCell->txCount);
497 zm_msg1_tx(ZM_LV_3, "probingTime=", rcCell->probingTime);
498 zm_msg1_tx(ZM_LV_3, "tick=", wd->tick);
500 newRate = rcCell->currentRate;
502 if (wd->probeCount && (wd->probeCount < wd->success_probing))
504 if (wd->probeInterval < 50)
511 if (wd->probeInterval > 52) //probe 51, 52, 53 three packets every 50 packets
513 wd->probeInterval = 0;
515 newRate=zfRateCtrlGetHigherRate(rcCell);
518 rcCell->probingTime = wd->tick;
521 /* Accumulate at least 1000ms and 8 packets or Accumulate over 1K packets */
522 else if ((((wd->tick - rcCell->probingTime) > (ZM_RATE_CTRL_PROBING_INTERVAL_MS/ZM_MS_PER_TICK))
523 && (rcCell->txCount >= ZM_RATE_CTRL_MIN_PROBING_PACKET))
524 || (rcCell->txCount >= 1000))
526 #ifndef ZM_DISABLE_RATE_CTRL
527 /* PER = fail/total */
529 wd->probeSuccessCount = 0;
530 if (wd->txMPDU[rcCell->currentRate] != 0) {
531 wd->PER[rcCell->currentRate] = zm_agg_min(100,
532 (wd->txFail[rcCell->currentRate]*100)/wd->txMPDU[rcCell->currentRate]);
533 if (!wd->PER[rcCell->currentRate]) wd->PER[rcCell->currentRate] ++;
536 /* if PER < threshold, do rate probing, return probing rate */
537 if ((wd->PER[rcCell->currentRate] <= (ZM_RATE_PROBING_THRESHOLD+15)) ||
538 ((rcCell->currentRate <= 16) &&
539 ((wd->PER[rcCell->currentRate]/2) <= ZM_RATE_PROBING_THRESHOLD)))
541 newRate = zfRateCtrlGetHigherRate(rcCell);
542 if (newRate != rcCell->currentRate)
546 wd->probeInterval = 0;
547 wd->success_probing =
548 (rcCell->currentRate <= 16)? (ZM_RATE_SUCCESS_PROBING/2) : ZM_RATE_SUCCESS_PROBING;
549 //DbgPrint("Start Probing");
550 zm_msg1_tx(ZM_LV_0, "Probing Rate=", newRate);
555 zm_msg0_tx(ZM_LV_1, "Diminish counter");
556 rcCell->failCount = rcCell->failCount>>1;
557 rcCell->txCount = rcCell->txCount>>1;
558 wd->txFail[rcCell->currentRate] = wd->txFail[rcCell->currentRate] >> 1;
559 wd->txMPDU[rcCell->currentRate] = wd->txMPDU[rcCell->currentRate] >> 1;
562 if (rcCell->currentRate > 15) {
563 highRate = zfRateCtrlGetHigherRate(rcCell);
564 if ((highRate != rcCell->currentRate) && wd->PER[highRate] &&
565 ((wd->PER[rcCell->currentRate] + FailDiff[rcCell->currentRate]) >
566 wd->PER[highRate])) {
567 //DbgPrint("PER compare force raise rate to %d", highRate);
568 wd->probeSuccessCount = wd->probeCount = ZM_RATE_SUCCESS_PROBING;
569 zfRateCtrlTxSuccessEvent(dev, rcCell, highRate);
573 highRate = zfRateCtrlFindMaxUDPTP(dev, rcCell);
574 if (rcCell->currentRate < highRate) {
575 //DbgPrint("UDP Throughput compare force raise rate to %d", highRate);
576 wd->probeSuccessCount = wd->probeCount = ZM_RATE_SUCCESS_PROBING;
577 zfRateCtrlTxSuccessEvent(dev, rcCell, highRate);
580 rcCell->probingTime = wd->tick;
583 if( (wd->tick > 1000)
584 && ((wd->tick - rcCell->lastTime) > 3840) )
586 if (rcCell->lasttxCount < 70)
588 rcCell->failCount = rcCell->failCount>>1;
589 rcCell->txCount = rcCell->txCount>>1;
590 wd->txFail[rcCell->currentRate] = wd->txFail[rcCell->currentRate] >> 1;
591 wd->txMPDU[rcCell->currentRate] = wd->txMPDU[rcCell->currentRate] >> 1;
593 rcCell->failCount = (rcCell->failCount < rcCell->txCount)?
594 rcCell->failCount : rcCell->txCount;
595 wd->txFail[rcCell->currentRate] = (wd->txFail[rcCell->currentRate] < wd->txMPDU[rcCell->currentRate])?
596 wd->txFail[rcCell->currentRate] : wd->txMPDU[rcCell->currentRate];
599 rcCell->lastTime = wd->tick;
600 rcCell->lasttxCount = 0;
604 rcCell->lasttxCount++;
605 wd->txMPDU[rcCell->currentRate]++;
606 zm_msg1_tx(ZM_LV_1, "Get Tx Rate=", newRate);
611 /************************************************************************/
613 /* FUNCTION DESCRIPTION zfRateCtrlTxFailEvent */
614 /* Tx fail event. Calculate PER and lower Tx rate if under */
615 /* PER under threshold. */
618 /* rcCell : rate control cell */
619 /* retryRate : retry rate */
625 /* Stephen Chen Atheros Communications, INC. 2007.2 */
627 /************************************************************************/
628 void zfRateCtrlTxFailEvent(zdev_t* dev, struct zsRcCell* rcCell, u8_t aggRate, u32_t retryRate)
630 zmw_get_wlan_dev(dev);
632 zmw_declare_for_critical_section();
634 #ifndef ZM_DISABLE_RATE_CTRL
635 //DbgPrint("aggRate=%d, retryRate=%d", aggRate, retryRate);
636 if (aggRate && (aggRate != rcCell->currentRate)) {
637 wd->txFail[aggRate] += retryRate;
642 retryRate = (zfRateCtrlRateDiff(rcCell, (u8_t)retryRate)+1)>>1;
643 if (rcCell->currentRate <12) //legacy rate
648 rcCell->failCount += retryRate;
649 wd->txFail[rcCell->currentRate] += retryRate;
651 //DbgPrint("failCount=%d", rcCell->failCount);
652 if (rcCell->failCount > ZM_MIN_RATE_FAIL_COUNT)
654 if (wd->txMPDU[rcCell->currentRate] != 0) {
655 wd->PER[rcCell->currentRate] = zm_agg_min(100,
656 (wd->txFail[rcCell->currentRate]*100)/wd->txMPDU[rcCell->currentRate]);
657 if (!wd->PER[rcCell->currentRate]) wd->PER[rcCell->currentRate] ++;
659 //zm_msg1_tx(ZM_LV_1, "PER=", per);
660 //DbgPrint("PER=%d, txFail=%d, txMPDU=%d", wd->PER[rcCell->currentRate], wd->txFail[rcCell->currentRate], wd->txMPDU[rcCell->currentRate]);
661 if (wd->PER[rcCell->currentRate] > PERThreshold[rcCell->currentRate])
663 /* Lower Tx Rate if PER < THRESHOLD */
664 zfRateCtrlNextLowerRate(dev, rcCell);
665 rcCell->flag |= ZM_RC_TRAINED_BIT;
667 // Resolve compatibility problem with Marvell
668 if(rcCell->currentRate == 15)
670 zmw_leave_critical_section(dev);
671 zfHpSetAggPktNum(dev, 8);
672 zmw_enter_critical_section(dev);
675 wd->txFail[rcCell->currentRate] = wd->txFail[rcCell->currentRate] >> 1;
676 wd->txMPDU[rcCell->currentRate] = wd->txMPDU[rcCell->currentRate] >> 1;
678 wd->probeCount = wd->probeSuccessCount = 0;
687 /************************************************************************/
689 /* FUNCTION DESCRIPTION zfRateCtrlTxSuccessEvent */
690 /* Tx success event. Raise Tx rate because rate probing success. */
693 /* rcCell : rate control cell */
694 /* successRate : success rate */
700 /* Stephen Chen Atheros Communications, INC. 2007.2 */
702 /************************************************************************/
703 void zfRateCtrlTxSuccessEvent(zdev_t* dev, struct zsRcCell* rcCell, u8_t successRate)
708 zmw_get_wlan_dev(dev);
710 zmw_declare_for_critical_section();
712 //DbgPrint("Probing successRate=%d", successRate);
713 /* Find successRate in operationRateSet[] */
714 wd->probeSuccessCount++;
715 if (wd->probeCount < wd->success_probing)
720 pcount = wd->probeCount;
723 PERProbe = wd->probeSuccessCount * 100 / pcount;
730 if (PERProbe < ((rcCell->currentRate < 16)? 80:100))
734 //DbgPrint("wd->probeCount=%d, wd->probeSuccessCount=%d", wd->probeCount, wd->probeSuccessCount);
735 wd->probeCount = wd->probeSuccessCount = 0;
736 for (i=0; i<rcCell->operationRateCount; i++)
738 if (successRate == rcCell->operationRateSet[i])
740 if (i > rcCell->currentRateIndex)
742 /* Raise current Tx rate */
743 zm_msg1_tx(ZM_LV_0, "Raise Tx Rate=", successRate);
744 //DbgPrint("Raise Tx Rate=%d", successRate);
746 // Resolve compatibility problem with Marvell
747 if((rcCell->currentRate <= 15) && (successRate > 15))
749 zmw_leave_critical_section(dev);
750 zfHpSetAggPktNum(dev, 16);
751 zmw_enter_critical_section(dev);
754 rcCell->currentRate = successRate;
755 rcCell->currentRateIndex = (u8_t)i;
756 rcCell->failCount = rcCell->txCount = 0;
757 rcCell->lasttxCount = 0;
758 rcCell->lastTime = wd->tick;
759 wd->txFail[rcCell->currentRate] = wd->txFail[rcCell->currentRate] >> 1;
760 wd->txMPDU[rcCell->currentRate] = wd->txMPDU[rcCell->currentRate] >> 1;
769 /************************************************************************/
771 /* FUNCTION DESCRIPTION zfRateCtrlRxRssiEvent */
772 /* Rx RSSI event. Calculate RSSI moving average, accelarate */
773 /* rate probing if RSSI variation over threshold. */
776 /* rcCell : rate control cell */
777 /* successRate : success rate */
783 /* Stephen Chen Atheros Communications, INC. 2007.2 */
785 /************************************************************************/
786 void zfRateCtrlRxRssiEvent(struct zsRcCell* rcCell, u16_t rxRssi)
788 /* if delta(rcCell->rxRssi, rxRssi) > ZM_RATE_CTRL_RSSI_VARIATION */
789 if ((rcCell->rxRssi - rxRssi) > ZM_RATE_CTRL_RSSI_VARIATION)
791 /* Accelerate rate probing via decreaing rcCell->probingTime */
792 rcCell->probingTime -= ZM_RATE_CTRL_PROBING_INTERVAL_MS/ZM_MS_PER_TICK;
795 /* Update RSSI moving average */
796 rcCell->rxRssi = (((rcCell->rxRssi*7) + rxRssi)+4) >> 3;
801 #ifdef ZM_ENABLE_BA_RATECTRL
802 u8_t HigherRate(u8_t Rate) {
803 if (Rate < 28) Rate++; //28=MCS15SG, 27=MCS15, 26=MCS14, 25=MCS13
804 if (Rate > 28) Rate = 28;
805 while ((Rate >= 20) && (Rate <= 23)) {
811 u8_t LowerRate(u8_t Rate) {
812 if (Rate > 1) Rate--;
813 while ((Rate >= 20) && (Rate <= 23)) {
819 u8_t RateMapToRateIndex(u8_t Rate, struct zsRcCell* rcCell) {
821 for (i=0; i<rcCell->operationRateCount; i++) {
822 if (Rate == rcCell->operationRateSet[i]) {
829 void zfRateCtrlAggrSta(zdev_t* dev) {
830 u8_t RateIndex, Rate;
833 u32_t RateCtrlTxMPDU, RateCtrlBAFail;
834 zmw_get_wlan_dev(dev);
836 RateIndex = wd->sta.oppositeInfo[0].rcCell.currentRateIndex;
837 Rate = wd->sta.oppositeInfo[0].rcCell.operationRateSet[RateIndex];
839 TxMPDU[Rate] = (TxMPDU[Rate] / 5) + (wd->commTally.RateCtrlTxMPDU * 4 / 5);
840 BAFail[Rate] = (BAFail[Rate] / 5) + (wd->commTally.RateCtrlBAFail * 4 / 5);
841 RateCtrlTxMPDU = wd->commTally.RateCtrlTxMPDU;
842 RateCtrlBAFail = wd->commTally.RateCtrlBAFail;
843 wd->commTally.RateCtrlTxMPDU = 0;
844 wd->commTally.RateCtrlBAFail = 0;
845 if (TxMPDU[Rate] > 0) {
846 BAPER[Rate] = BAFail[Rate] * 1000 / TxMPDU[Rate]; //PER*1000
847 BAPER[Rate] = (BAPER[Rate]>0)? BAPER[Rate]:1;
853 HRate = HigherRate(Rate);
854 LRate = LowerRate(Rate);
855 if (BAPER[Rate]>200) {
856 if ((RateCtrlTxMPDU > 100) && (BAPER[Rate]<300) && (HRate != Rate) && BAPER[HRate] &&
857 (BAPER[HRate] < BAPER[Rate] + BADiff[Rate])) {
859 //DbgPrint("Rate improved to %d", Rate);
863 //DbgPrint("Rate decreased to %d", Rate);
866 else if (BAPER[Rate] && BAPER[Rate]<100) {
867 if (RateCtrlTxMPDU > 100) {
869 //DbgPrint("Rate improved to %d", Rate);
872 wd->sta.oppositeInfo[0].rcCell.currentRate = Rate;
873 wd->sta.oppositeInfo[0].rcCell.currentRateIndex = RateMapToRateIndex(Rate, &wd->sta.oppositeInfo[0].rcCell);