Staging: add w35und wifi driver
[linux-2.6/mini2440.git] / drivers / staging / winbond / mto.c
blob2ef60e5120cc224b9b81adcc48b204effa2c4955
1 //============================================================================
2 // MTO.C -
3 //
4 // Description:
5 // MAC Throughput Optimization for W89C33 802.11g WLAN STA.
6 //
7 // The following MIB attributes or internal variables will be affected
8 // while the MTO is being executed:
9 // dot11FragmentationThreshold,
10 // dot11RTSThreshold,
11 // transmission rate and PLCP preamble type,
12 // CCA mode,
13 // antenna diversity.
15 // Revision history:
16 // --------------------------------------------------------------------------
17 // 20031227 UN20 Pete Chao
18 // First draft
19 // 20031229 Turbo copy from PD43
20 // 20040210 Kevin revised
21 // Copyright (c) 2003 Winbond Electronics Corp. All rights reserved.
22 //============================================================================
24 // LA20040210_DTO kevin
25 #include "os_common.h"
27 // Declare SQ3 to rate and fragmentation threshold table
28 // Declare fragmentation thresholds table
29 #define MTO_MAX_SQ3_LEVELS 14
30 #define MTO_MAX_FRAG_TH_LEVELS 5
31 #define MTO_MAX_DATA_RATE_LEVELS 12
33 u16 MTO_Frag_Th_Tbl[MTO_MAX_FRAG_TH_LEVELS] =
35 256, 384, 512, 768, 1536
38 u8 MTO_SQ3_Level[MTO_MAX_SQ3_LEVELS] =
40 0, 26, 30, 32, 34, 35, 37, 42, 44, 46, 54, 62, 78, 81
42 u8 MTO_SQ3toRate[MTO_MAX_SQ3_LEVELS] =
44 0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
46 u8 MTO_SQ3toFrag[MTO_MAX_SQ3_LEVELS] =
48 0, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4
51 // One Exchange Time table
53 u16 MTO_One_Exchange_Time_Tbl_l[MTO_MAX_FRAG_TH_LEVELS][MTO_MAX_DATA_RATE_LEVELS] =
55 { 2554, 1474, 822, 0, 0, 636, 0, 0, 0, 0, 0, 0},
56 { 3578, 1986, 1009, 0, 0, 729, 0, 0, 0, 0, 0, 0},
57 { 4602, 2498, 1195, 0, 0, 822, 0, 0, 0, 0, 0, 0},
58 { 6650, 3522, 1567, 0, 0, 1009, 0, 0, 0, 0, 0, 0},
59 {12794, 6594, 2684, 0, 0, 1567, 0, 0, 0, 0, 0, 0}
62 u16 MTO_One_Exchange_Time_Tbl_s[MTO_MAX_FRAG_TH_LEVELS][MTO_MAX_DATA_RATE_LEVELS] =
64 { 0, 1282, 630, 404, 288, 444, 232, 172, 144, 116, 100, 96},
65 { 0, 1794, 817, 572, 400, 537, 316, 228, 188, 144, 124, 116},
66 { 0, 2306, 1003, 744, 516, 630, 400, 288, 228, 172, 144, 136},
67 { 0, 3330, 1375, 1084, 744, 817, 572, 400, 316, 228, 188, 172},
68 { 0, 6402, 2492, 2108, 1424, 1375, 1084, 740, 572, 400, 316, 284}
71 #define MTO_ONE_EXCHANGE_TIME(preamble_type, frag_th_lvl, data_rate_lvl) \
72 (preamble_type) ? MTO_One_Exchange_Time_Tbl_s[frag_th_lvl][data_rate_lvl] : \
73 MTO_One_Exchange_Time_Tbl_l[frag_th_lvl][data_rate_lvl]
75 // Declare data rate table
76 //The following table will be changed at anytime if the opration rate supported by AP don't
77 //match the table
78 u8 MTO_Data_Rate_Tbl[MTO_MAX_DATA_RATE_LEVELS] =
80 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108
83 //The Stardard_Data_Rate_Tbl and Level2PerTbl table is used to indirectly retreive PER
84 //information from Rate_PER_TBL
85 //The default settings is AP can support full rate set.
86 static u8 Stardard_Data_Rate_Tbl[MTO_MAX_DATA_RATE_LEVELS] =
88 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108
90 static u8 Level2PerTbl[MTO_MAX_DATA_RATE_LEVELS] =
92 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
94 //How many kind of tx rate can be supported by AP
95 //DTO will change Rate between MTO_Data_Rate_Tbl[0] and MTO_Data_Rate_Tbl[MTO_DataRateAvailableLevel-1]
96 static u8 MTO_DataRateAvailableLevel = MTO_MAX_DATA_RATE_LEVELS;
97 //Smoothed PER table for each different RATE based on packet length of 1514
98 static int Rate_PER_TBL[91][MTO_MAX_DATA_RATE_LEVELS] = {
99 // 1M 2M 5.5M 11M 6M 9M 12M 18M 24M 36M 48M 54M
100 /* 0% */{ 93, 177, 420, 538, 690, 774, 1001, 1401, 1768, 2358, 2838, 3039},
101 /* 1% */{ 92, 176, 416, 533, 683, 767, 992, 1389, 1752, 2336, 2811, 3010},
102 /* 2% */{ 91, 174, 412, 528, 675, 760, 983, 1376, 1735, 2313, 2783, 2979},
103 /* 3% */{ 90, 172, 407, 523, 667, 753, 973, 1363, 1719, 2290, 2755, 2948},
104 /* 4% */{ 90, 170, 403, 518, 659, 746, 964, 1350, 1701, 2266, 2726, 2916},
105 /* 5% */{ 89, 169, 398, 512, 651, 738, 954, 1336, 1684, 2242, 2696, 2884},
106 /* 6% */{ 88, 167, 394, 507, 643, 731, 944, 1322, 1666, 2217, 2665, 2851},
107 /* 7% */{ 87, 165, 389, 502, 635, 723, 935, 1308, 1648, 2192, 2634, 2817},
108 /* 8% */{ 86, 163, 384, 497, 626, 716, 924, 1294, 1629, 2166, 2602, 2782},
109 /* 9% */{ 85, 161, 380, 491, 618, 708, 914, 1279, 1611, 2140, 2570, 2747},
110 /* 10% */{ 84, 160, 375, 486, 609, 700, 904, 1265, 1591, 2113, 2537, 2711},
111 /* 11% */{ 83, 158, 370, 480, 600, 692, 894, 1250, 1572, 2086, 2503, 2675},
112 /* 12% */{ 82, 156, 365, 475, 592, 684, 883, 1234, 1552, 2059, 2469, 2638},
113 /* 13% */{ 81, 154, 360, 469, 583, 676, 872, 1219, 1532, 2031, 2435, 2600},
114 /* 14% */{ 80, 152, 355, 464, 574, 668, 862, 1204, 1512, 2003, 2400, 2562},
115 /* 15% */{ 79, 150, 350, 458, 565, 660, 851, 1188, 1492, 1974, 2365, 2524},
116 /* 16% */{ 78, 148, 345, 453, 556, 652, 840, 1172, 1471, 1945, 2329, 2485},
117 /* 17% */{ 77, 146, 340, 447, 547, 643, 829, 1156, 1450, 1916, 2293, 2446},
118 /* 18% */{ 76, 144, 335, 441, 538, 635, 818, 1140, 1429, 1887, 2256, 2406},
119 /* 19% */{ 75, 143, 330, 436, 529, 627, 807, 1124, 1408, 1857, 2219, 2366},
120 /* 20% */{ 74, 141, 325, 430, 520, 618, 795, 1107, 1386, 1827, 2182, 2326},
121 /* 21% */{ 73, 139, 320, 424, 510, 610, 784, 1091, 1365, 1797, 2145, 2285},
122 /* 22% */{ 72, 137, 314, 418, 501, 601, 772, 1074, 1343, 1766, 2107, 2244},
123 /* 23% */{ 71, 135, 309, 412, 492, 592, 761, 1057, 1321, 1736, 2069, 2203},
124 /* 24% */{ 70, 133, 304, 407, 482, 584, 749, 1040, 1299, 1705, 2031, 2161},
125 /* 25% */{ 69, 131, 299, 401, 473, 575, 738, 1023, 1277, 1674, 1992, 2120},
126 /* 26% */{ 68, 129, 293, 395, 464, 566, 726, 1006, 1254, 1642, 1953, 2078},
127 /* 27% */{ 67, 127, 288, 389, 454, 557, 714, 989, 1232, 1611, 1915, 2035},
128 /* 28% */{ 66, 125, 283, 383, 445, 549, 703, 972, 1209, 1579, 1876, 1993},
129 /* 29% */{ 65, 123, 278, 377, 436, 540, 691, 955, 1187, 1548, 1836, 1951},
130 /* 30% */{ 64, 121, 272, 371, 426, 531, 679, 937, 1164, 1516, 1797, 1908},
131 /* 31% */{ 63, 119, 267, 365, 417, 522, 667, 920, 1141, 1484, 1758, 1866},
132 /* 32% */{ 62, 117, 262, 359, 407, 513, 655, 902, 1118, 1453, 1719, 1823},
133 /* 33% */{ 61, 115, 256, 353, 398, 504, 643, 885, 1095, 1421, 1679, 1781},
134 /* 34% */{ 60, 113, 251, 347, 389, 495, 631, 867, 1072, 1389, 1640, 1738},
135 /* 35% */{ 59, 111, 246, 341, 379, 486, 619, 850, 1049, 1357, 1600, 1695},
136 /* 36% */{ 58, 108, 240, 335, 370, 477, 607, 832, 1027, 1325, 1561, 1653},
137 /* 37% */{ 57, 106, 235, 329, 361, 468, 595, 815, 1004, 1293, 1522, 1610},
138 /* 38% */{ 56, 104, 230, 323, 351, 459, 584, 797, 981, 1261, 1483, 1568},
139 /* 39% */{ 55, 102, 224, 317, 342, 450, 572, 780, 958, 1230, 1443, 1526},
140 /* 40% */{ 54, 100, 219, 311, 333, 441, 560, 762, 935, 1198, 1404, 1484},
141 /* 41% */{ 53, 98, 214, 305, 324, 432, 548, 744, 912, 1166, 1366, 1442},
142 /* 42% */{ 52, 96, 209, 299, 315, 423, 536, 727, 889, 1135, 1327, 1400},
143 /* 43% */{ 51, 94, 203, 293, 306, 414, 524, 709, 866, 1104, 1289, 1358},
144 /* 44% */{ 50, 92, 198, 287, 297, 405, 512, 692, 844, 1072, 1250, 1317},
145 /* 45% */{ 49, 90, 193, 281, 288, 396, 500, 675, 821, 1041, 1212, 1276},
146 /* 46% */{ 48, 88, 188, 275, 279, 387, 488, 657, 799, 1011, 1174, 1236},
147 /* 47% */{ 47, 86, 183, 269, 271, 378, 476, 640, 777, 980, 1137, 1195},
148 /* 48% */{ 46, 84, 178, 262, 262, 369, 464, 623, 754, 949, 1100, 1155},
149 /* 49% */{ 45, 82, 173, 256, 254, 360, 452, 606, 732, 919, 1063, 1116},
150 /* 50% */{ 44, 80, 168, 251, 245, 351, 441, 589, 710, 889, 1026, 1076},
151 /* 51% */{ 43, 78, 163, 245, 237, 342, 429, 572, 689, 860, 990, 1038},
152 /* 52% */{ 42, 76, 158, 239, 228, 333, 417, 555, 667, 830, 955, 999},
153 /* 53% */{ 41, 74, 153, 233, 220, 324, 406, 538, 645, 801, 919, 961},
154 /* 54% */{ 40, 72, 148, 227, 212, 315, 394, 522, 624, 773, 884, 924},
155 /* 55% */{ 39, 70, 143, 221, 204, 307, 383, 505, 603, 744, 850, 887},
156 /* 56% */{ 38, 68, 138, 215, 196, 298, 371, 489, 582, 716, 816, 851},
157 /* 57% */{ 37, 67, 134, 209, 189, 289, 360, 473, 562, 688, 783, 815},
158 /* 58% */{ 36, 65, 129, 203, 181, 281, 349, 457, 541, 661, 750, 780},
159 /* 59% */{ 35, 63, 124, 197, 174, 272, 338, 441, 521, 634, 717, 745},
160 /* 60% */{ 34, 61, 120, 192, 166, 264, 327, 425, 501, 608, 686, 712},
161 /* 61% */{ 33, 59, 115, 186, 159, 255, 316, 409, 482, 582, 655, 678},
162 /* 62% */{ 32, 57, 111, 180, 152, 247, 305, 394, 462, 556, 624, 646},
163 /* 63% */{ 31, 55, 107, 174, 145, 238, 294, 379, 443, 531, 594, 614},
164 /* 64% */{ 30, 53, 102, 169, 138, 230, 283, 364, 425, 506, 565, 583},
165 /* 65% */{ 29, 52, 98, 163, 132, 222, 273, 349, 406, 482, 536, 553},
166 /* 66% */{ 28, 50, 94, 158, 125, 214, 262, 334, 388, 459, 508, 523},
167 /* 67% */{ 27, 48, 90, 152, 119, 206, 252, 320, 370, 436, 481, 495},
168 /* 68% */{ 26, 46, 86, 147, 113, 198, 242, 306, 353, 413, 455, 467},
169 /* 69% */{ 26, 44, 82, 141, 107, 190, 231, 292, 336, 391, 429, 440},
170 /* 70% */{ 25, 43, 78, 136, 101, 182, 221, 278, 319, 370, 405, 414},
171 /* 71% */{ 24, 41, 74, 130, 95, 174, 212, 265, 303, 350, 381, 389},
172 /* 72% */{ 23, 39, 71, 125, 90, 167, 202, 252, 287, 329, 358, 365},
173 /* 73% */{ 22, 37, 67, 119, 85, 159, 192, 239, 271, 310, 335, 342},
174 /* 74% */{ 21, 36, 63, 114, 80, 151, 183, 226, 256, 291, 314, 320},
175 /* 75% */{ 20, 34, 60, 109, 75, 144, 174, 214, 241, 273, 294, 298},
176 /* 76% */{ 19, 32, 57, 104, 70, 137, 164, 202, 227, 256, 274, 278},
177 /* 77% */{ 18, 31, 53, 99, 66, 130, 155, 190, 213, 239, 256, 259},
178 /* 78% */{ 17, 29, 50, 94, 62, 122, 146, 178, 200, 223, 238, 241},
179 /* 79% */{ 16, 28, 47, 89, 58, 115, 138, 167, 187, 208, 222, 225},
180 /* 80% */{ 16, 26, 44, 84, 54, 109, 129, 156, 175, 194, 206, 209},
181 /* 81% */{ 15, 24, 41, 79, 50, 102, 121, 146, 163, 180, 192, 194},
182 /* 82% */{ 14, 23, 39, 74, 47, 95, 113, 136, 151, 167, 178, 181},
183 /* 83% */{ 13, 21, 36, 69, 44, 89, 105, 126, 140, 155, 166, 169},
184 /* 84% */{ 12, 20, 33, 64, 41, 82, 97, 116, 130, 144, 155, 158},
185 /* 85% */{ 11, 19, 31, 60, 39, 76, 89, 107, 120, 134, 145, 149},
186 /* 86% */{ 11, 17, 29, 55, 36, 70, 82, 98, 110, 125, 136, 140},
187 /* 87% */{ 10, 16, 26, 51, 34, 64, 75, 90, 102, 116, 128, 133},
188 /* 88% */{ 9, 14, 24, 46, 32, 58, 68, 81, 93, 108, 121, 128},
189 /* 89% */{ 8, 13, 22, 42, 31, 52, 61, 74, 86, 102, 116, 124},
190 /* 90% */{ 7, 12, 21, 37, 29, 46, 54, 66, 79, 96, 112, 121}
193 #define RSSIBUF_NUM 10
194 #define RSSI2RATE_SIZE 9
196 static TXRETRY_REC TxRateRec={MTO_MAX_DATA_RATE_LEVELS - 1, 0}; //new record=>TxRateRec
197 static int TxRetryRate;
198 //static int SQ3, BSS_PK_CNT, NIDLESLOT, SLOT_CNT, INTERF_CNT, GAP_CNT, DS_EVM;
199 static s32 RSSIBuf[RSSIBUF_NUM]={-70, -70, -70, -70, -70, -70, -70, -70, -70, -70};
200 static s32 RSSISmoothed=-700;
201 static int RSSIBufIndex=0;
202 static u8 max_rssi_rate;
203 static int rate_tbl[13] = {0,1,2,5,11,6,9,12,18,24,36,48,54};
204 //[WKCHEN]static core_data_t *pMTOcore_data=NULL;
206 static int TotalTxPkt = 0;
207 static int TotalTxPktRetry = 0;
208 static int TxPktPerAnt[3] = {0,0,0};
209 static int RXRSSIANT[3] ={-70,-70,-70};
210 static int TxPktRetryPerAnt[3] = {0,0,0};
211 //static int TxDominateFlag=FALSE;
212 static u8 old_antenna[4]={1 ,0 ,1 ,0};
213 static int retryrate_rec[MTO_MAX_DATA_RATE_LEVELS];//this record the retry rate at different data rate
215 static int PeriodTotalTxPkt = 0;
216 static int PeriodTotalTxPktRetry = 0;
218 typedef struct
220 s32 RSSI;
221 u8 TxRate;
222 }RSSI2RATE;
224 static RSSI2RATE RSSI2RateTbl[RSSI2RATE_SIZE] =
226 {-740, 108}, // 54M
227 {-760, 96}, // 48M
228 {-820, 72}, // 36M
229 {-850, 48}, // 24M
230 {-870, 36}, // 18M
231 {-890, 24}, // 12M
232 {-900, 12}, // 6M
233 {-920, 11}, // 5.5M
234 {-950, 4}, // 2M
236 static u8 untogglecount;
237 static u8 last_rate_ant; //this is used for antenna backoff-hh
239 u8 boSparseTxTraffic = FALSE;
241 void MTO_Init(MTO_FUNC_INPUT);
242 void AntennaToggleInitiator(MTO_FUNC_INPUT);
243 void AntennaToggleState(MTO_FUNC_INPUT);
244 void TxPwrControl(MTO_FUNC_INPUT);
245 void GetFreshAntennaData(MTO_FUNC_INPUT);
246 void TxRateReductionCtrl(MTO_FUNC_INPUT);
247 /** 1.1.31.1000 Turbo modify */
248 //void MTO_SetDTORateRange(int type);
249 void MTO_SetDTORateRange(MTO_FUNC_INPUT, u8 *pRateArray, u8 ArraySize);
250 void MTO_SetTxCount(MTO_FUNC_INPUT, u8 t0, u8 index);
251 void MTO_TxFailed(MTO_FUNC_INPUT);
252 void SmoothRSSI(s32 new_rssi);
253 void hal_get_dto_para(MTO_FUNC_INPUT, char *buffer);
254 u8 CalcNewRate(MTO_FUNC_INPUT, u8 old_rate, u32 retry_cnt, u32 tx_frag_cnt);
255 u8 GetMaxRateLevelFromRSSI(void);
256 u8 MTO_GetTxFallbackRate(MTO_FUNC_INPUT);
257 int Divide(int a, int b);
258 void multiagc(MTO_FUNC_INPUT, u8 high_gain_mode);
260 //===========================================================================
261 // MTO_Init --
263 // Description:
264 // Set DTO Tx Rate Scope because different AP could have different Rate set.
265 // After our staion join with AP, LM core will call this function to initialize
266 // Tx Rate table.
268 // Arguments:
269 // pRateArray - The pointer to the Tx Rate Array by the following order
270 // - 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108
271 // - DTO won't check whether rate order is invalid or not
272 // ArraySize - The array size to indicate how many tx rate we can choose
274 // sample code:
275 // {
276 // u8 RateArray[4] = {2, 4, 11, 22};
277 // MTO_SetDTORateRange(RateArray, 4);
278 // }
280 // Return Value:
281 // None
282 //============================================================================
283 void MTO_SetDTORateRange(MTO_FUNC_INPUT,u8 *pRateArray, u8 ArraySize)
285 u8 i, j=0;
287 for(i=0;i<ArraySize;i++)
289 if(pRateArray[i] == 22)
290 break;
292 if(i < ArraySize) //we need adjust the order of rate list because 11Mbps rate exists
294 for(;i>0;i--)
296 if(pRateArray[i-1] <= 11)
297 break;
298 pRateArray[i] = pRateArray[i-1];
300 pRateArray[i] = 22;
301 MTO_OFDM_RATE_LEVEL() = i;
303 else
305 for(i=0; i<ArraySize; i++)
307 if (pRateArray[i] >= 12)
308 break;
310 MTO_OFDM_RATE_LEVEL() = i;
313 for(i=0;i<ArraySize;i++)
315 MTO_Data_Rate_Tbl[i] = pRateArray[i];
316 for(;j<MTO_MAX_DATA_RATE_LEVELS;j++)
318 if(Stardard_Data_Rate_Tbl[j] == pRateArray[i])
319 break;
321 Level2PerTbl[i] = j;
322 #ifdef _PE_DTO_DUMP_
323 WBDEBUG(("[MTO]:Op Rate[%d]: %d\n",i, MTO_Data_Rate_Tbl[i]));
324 #endif
326 MTO_DataRateAvailableLevel = ArraySize;
327 if( MTO_DATA().RatePolicy ) // 0 means that no registry setting
329 if( MTO_DATA().RatePolicy == 1 )
330 TxRateRec.tx_rate = 0; //ascent
331 else
332 TxRateRec.tx_rate = MTO_DataRateAvailableLevel -1 ; //descent
334 else
336 if( MTO_INITTXRATE_MODE )
337 TxRateRec.tx_rate = 0; //ascent
338 else
339 TxRateRec.tx_rate = MTO_DataRateAvailableLevel -1 ; //descent
341 TxRateRec.tx_retry_rate = 0;
342 //set default rate for initial use
343 MTO_RATE_LEVEL() = TxRateRec.tx_rate;
344 MTO_FALLBACK_RATE_LEVEL() = MTO_RATE_LEVEL();
347 //===========================================================================
348 // MTO_Init --
350 // Description:
351 // Initialize MTO parameters.
353 // This function should be invoked during system initialization.
355 // Arguments:
356 // Adapter - The pointer to the Miniport Adapter Context
358 // Return Value:
359 // None
360 //============================================================================
361 void MTO_Init(MTO_FUNC_INPUT)
363 int i;
364 //WBDEBUG(("[MTO] -> MTO_Init()\n"));
365 //[WKCHEN]pMTOcore_data = pcore_data;
366 // 20040510 Turbo add for global variable
367 MTO_TMR_CNT() = 0;
368 MTO_TOGGLE_STATE() = TOGGLE_STATE_IDLE;
369 MTO_TX_RATE_REDUCTION_STATE() = RATE_CHGSTATE_IDLE;
370 MTO_BACKOFF_TMR() = 0;
371 MTO_LAST_RATE() = 11;
372 MTO_CO_EFFICENT() = 0;
374 //MTO_TH_FIXANT() = MTO_DEFAULT_TH_FIXANT;
375 MTO_TH_CNT() = MTO_DEFAULT_TH_CNT;
376 MTO_TH_SQ3() = MTO_DEFAULT_TH_SQ3;
377 MTO_TH_IDLE_SLOT() = MTO_DEFAULT_TH_IDLE_SLOT;
378 MTO_TH_PR_INTERF() = MTO_DEFAULT_TH_PR_INTERF;
380 MTO_TMR_AGING() = MTO_DEFAULT_TMR_AGING;
381 MTO_TMR_PERIODIC() = MTO_DEFAULT_TMR_PERIODIC;
383 //[WKCHEN]MTO_CCA_MODE_SETUP()= (u8) hal_get_cca_mode(MTO_HAL());
384 //[WKCHEN]MTO_CCA_MODE() = MTO_CCA_MODE_SETUP();
386 //MTO_PREAMBLE_TYPE() = MTO_PREAMBLE_LONG;
387 MTO_PREAMBLE_TYPE() = MTO_PREAMBLE_SHORT; // for test
389 MTO_ANT_SEL() = hal_get_antenna_number(MTO_HAL());
390 MTO_ANT_MAC() = MTO_ANT_SEL();
391 MTO_CNT_ANT(0) = 0;
392 MTO_CNT_ANT(1) = 0;
393 MTO_SQ_ANT(0) = 0;
394 MTO_SQ_ANT(1) = 0;
395 MTO_ANT_DIVERSITY() = MTO_ANTENNA_DIVERSITY_ON;
396 //CardSet_AntennaDiversity(Adapter, MTO_ANT_DIVERSITY());
397 //PLMESetAntennaDiversity( Adapter, MTO_ANT_DIVERSITY());
399 MTO_AGING_TIMEOUT() = 0;//MTO_TMR_AGING() / MTO_TMR_PERIODIC();
401 // The following parameters should be initialized to the values set by user
403 //MTO_RATE_LEVEL() = 10;
404 MTO_RATE_LEVEL() = 0;
405 MTO_FALLBACK_RATE_LEVEL() = MTO_RATE_LEVEL();
406 MTO_FRAG_TH_LEVEL() = 4;
407 /** 1.1.23.1000 Turbo modify from -1 to +1
408 MTO_RTS_THRESHOLD() = MTO_FRAG_TH() - 1;
409 MTO_RTS_THRESHOLD_SETUP() = MTO_FRAG_TH() - 1;
411 MTO_RTS_THRESHOLD() = MTO_FRAG_TH() + 1;
412 MTO_RTS_THRESHOLD_SETUP() = MTO_FRAG_TH() + 1;
413 // 1.1.23.1000 Turbo add for mto change preamble from 0 to 1
414 MTO_RATE_CHANGE_ENABLE() = 1;
415 MTO_FRAG_CHANGE_ENABLE() = 0; // 1.1.29.1000 Turbo add don't support frag
416 //The default valud of ANTDIV_DEFAULT_ON will be decided by EEPROM
417 //#ifdef ANTDIV_DEFAULT_ON
418 //MTO_ANT_DIVERSITY_ENABLE() = 1;
419 //#else
420 //MTO_ANT_DIVERSITY_ENABLE() = 0;
421 //#endif
422 MTO_POWER_CHANGE_ENABLE() = 1;
423 MTO_PREAMBLE_CHANGE_ENABLE()= 1;
424 MTO_RTS_CHANGE_ENABLE() = 0; // 1.1.29.1000 Turbo add don't support frag
425 // 20040512 Turbo add
426 //old_antenna[0] = 1;
427 //old_antenna[1] = 0;
428 //old_antenna[2] = 1;
429 //old_antenna[3] = 0;
430 for (i=0;i<MTO_MAX_DATA_RATE_LEVELS;i++)
431 retryrate_rec[i]=5;
433 MTO_TXFLOWCOUNT() = 0;
434 //--------- DTO threshold parameters -------------
435 //MTOPARA_PERIODIC_CHECK_CYCLE() = 50;
436 MTOPARA_PERIODIC_CHECK_CYCLE() = 10;
437 MTOPARA_RSSI_TH_FOR_ANTDIV() = 10;
438 MTOPARA_TXCOUNT_TH_FOR_CALC_RATE() = 50;
439 MTOPARA_TXRATE_INC_TH() = 10;
440 MTOPARA_TXRATE_DEC_TH() = 30;
441 MTOPARA_TXRATE_EQ_TH() = 40;
442 MTOPARA_TXRATE_BACKOFF() = 12;
443 MTOPARA_TXRETRYRATE_REDUCE() = 6;
444 if ( MTO_TXPOWER_FROM_EEPROM == 0xff)
446 switch( MTO_HAL()->phy_type)
448 case RF_AIROHA_2230:
449 case RF_AIROHA_2230S: // 20060420 Add this
450 MTOPARA_TXPOWER_INDEX() = 46; // MAX-8 // @@ Only for AL 2230
451 break;
452 case RF_AIROHA_7230:
453 MTOPARA_TXPOWER_INDEX() = 49;
454 break;
455 case RF_WB_242:
456 MTOPARA_TXPOWER_INDEX() = 10;
457 break;
458 case RF_WB_242_1:
459 MTOPARA_TXPOWER_INDEX() = 24; // ->10 20060316.1 modify
460 break;
463 else //follow the setting from EEPROM
464 MTOPARA_TXPOWER_INDEX() = MTO_TXPOWER_FROM_EEPROM;
465 hal_set_rf_power(MTO_HAL(), (u8)MTOPARA_TXPOWER_INDEX());
466 //------------------------------------------------
468 // For RSSI turning 20060808.4 Cancel load from EEPROM
469 MTO_DATA().RSSI_high = -41;
470 MTO_DATA().RSSI_low = -60;
473 //---------------------------------------------------------------------------//
474 static u32 DTO_Rx_Info[13][3];
475 static u32 DTO_RxCRCFail_Info[13][3];
476 static u32 AntennaToggleBkoffTimer=5;
477 typedef struct{
478 int RxRate;
479 int RxRatePkts;
480 int index;
481 }RXRATE_ANT;
482 RXRATE_ANT RxRatePeakAnt[3];
484 #define ANT0 0
485 #define ANT1 1
486 #define OLD_ANT 2
488 void SearchPeakRxRate(int index)
490 int i;
491 RxRatePeakAnt[index].RxRatePkts=0;
492 //Find out the best rx rate which is used on different antenna
493 for(i=1;i<13;i++)
495 if(DTO_Rx_Info[i][index] > (u32) RxRatePeakAnt[index].RxRatePkts)
497 RxRatePeakAnt[index].RxRatePkts = DTO_Rx_Info[i][index];
498 RxRatePeakAnt[index].RxRate = rate_tbl[i];
499 RxRatePeakAnt[index].index = i;
504 void ResetDTO_RxInfo(int index, MTO_FUNC_INPUT)
506 int i;
508 #ifdef _PE_DTO_DUMP_
509 WBDEBUG(("ResetDTOrx\n"));
510 #endif
512 for(i=0;i<13;i++)
513 DTO_Rx_Info[i][index] = MTO_HAL()->rx_ok_count[i];
515 for(i=0;i<13;i++)
516 DTO_RxCRCFail_Info[i][index] = MTO_HAL()->rx_err_count[i];
518 TotalTxPkt = 0;
519 TotalTxPktRetry = 0;
522 void GetDTO_RxInfo(int index, MTO_FUNC_INPUT)
524 int i;
526 #ifdef _PE_DTO_DUMP_
527 WBDEBUG(("GetDTOrx\n"));
528 #endif
530 //PDEBUG(("[MTO]:DTO_Rx_Info[%d]=%d, rx_ok_count=%d\n", index, DTO_Rx_Info[0][index], phw_data->rx_ok_count[0]));
531 for(i=0;i<13;i++)
532 DTO_Rx_Info[i][index] = abs(MTO_HAL()->rx_ok_count[i] - DTO_Rx_Info[i][index]);
533 if(DTO_Rx_Info[0][index]==0) DTO_Rx_Info[0][index] = 1;
535 for(i=0;i<13;i++)
536 DTO_RxCRCFail_Info[i][index] = MTO_HAL()->rx_err_count[i] - DTO_RxCRCFail_Info[i][index];
538 TxPktPerAnt[index] = TotalTxPkt;
539 TxPktRetryPerAnt[index] = TotalTxPktRetry;
540 TotalTxPkt = 0;
541 TotalTxPktRetry = 0;
544 void OutputDebugInfo(int index1, int index2)
546 #ifdef _PE_DTO_DUMP_
547 WBDEBUG(("[HHDTO]:Total Rx (%d)\t\t(%d) \n ", DTO_Rx_Info[0][index1], DTO_Rx_Info[0][index2]));
548 WBDEBUG(("[HHDTO]:RECEIVE RSSI: (%d)\t\t(%d) \n ", RXRSSIANT[index1], RXRSSIANT[index2]));
549 WBDEBUG(("[HHDTO]:TX packet correct rate: (%d)%%\t\t(%d)%% \n ",Divide(TxPktPerAnt[index1]*100,TxPktRetryPerAnt[index1]), Divide(TxPktPerAnt[index2]*100,TxPktRetryPerAnt[index2])));
550 #endif
552 int tmp1, tmp2;
553 #ifdef _PE_DTO_DUMP_
554 WBDEBUG(("[HHDTO]:Total Tx (%d)\t\t(%d) \n ", TxPktPerAnt[index1], TxPktPerAnt[index2]));
555 WBDEBUG(("[HHDTO]:Total Tx retry (%d)\t\t(%d) \n ", TxPktRetryPerAnt[index1], TxPktRetryPerAnt[index2]));
556 #endif
557 tmp1 = TxPktPerAnt[index1] + DTO_Rx_Info[0][index1];
558 tmp2 = TxPktPerAnt[index2] + DTO_Rx_Info[0][index2];
559 #ifdef _PE_DTO_DUMP_
560 WBDEBUG(("[HHDTO]:Total Tx+RX (%d)\t\t(%d) \n ", tmp1, tmp2));
561 #endif
565 unsigned char TxDominate(int index)
567 int tmp;
569 tmp = TxPktPerAnt[index] + DTO_Rx_Info[0][index];
571 if(Divide(TxPktPerAnt[index]*100, tmp) > 40)
572 return TRUE;
573 else
574 return FALSE;
577 unsigned char CmpTxRetryRate(int index1, int index2)
579 int tx_retry_rate1, tx_retry_rate2;
580 tx_retry_rate1 = Divide((TxPktRetryPerAnt[index1] - TxPktPerAnt[index1])*100, TxPktRetryPerAnt[index1]);
581 tx_retry_rate2 = Divide((TxPktRetryPerAnt[index2] - TxPktPerAnt[index2])*100, TxPktRetryPerAnt[index2]);
582 #ifdef _PE_DTO_DUMP_
583 WBDEBUG(("[MTO]:TxRetry Ant0: (%d%%) Ant1: (%d%%) \n ", tx_retry_rate1, tx_retry_rate2));
584 #endif
586 if(tx_retry_rate1 > tx_retry_rate2)
587 return TRUE;
588 else
589 return FALSE;
592 void GetFreshAntennaData(MTO_FUNC_INPUT)
594 u8 x;
596 x = hal_get_antenna_number(MTO_HAL());
597 //hal_get_bss_pk_cnt(MTO_HAL());
598 //hal_get_est_sq3(MTO_HAL(), 1);
599 old_antenna[0] = x;
600 //if this is the function for timer
601 ResetDTO_RxInfo(x, MTO_FUNC_INPUT_DATA);
602 if(AntennaToggleBkoffTimer)
603 AntennaToggleBkoffTimer--;
604 if (abs(last_rate_ant-MTO_RATE_LEVEL())>1) //backoff timer reset
605 AntennaToggleBkoffTimer=0;
607 if (MTO_ANT_DIVERSITY() != MTO_ANTENNA_DIVERSITY_ON ||
608 MTO_ANT_DIVERSITY_ENABLE() != 1)
609 AntennaToggleBkoffTimer=1;
610 #ifdef _PE_DTO_DUMP_
611 WBDEBUG(("[HHDTO]:**last data rate=%d,now data rate=%d**antenna toggle timer=%d",last_rate_ant,MTO_RATE_LEVEL(),AntennaToggleBkoffTimer));
612 #endif
613 last_rate_ant=MTO_RATE_LEVEL();
614 if(AntennaToggleBkoffTimer==0)
616 MTO_TOGGLE_STATE() = TOGGLE_STATE_WAIT0;
617 #ifdef _PE_DTO_DUMP_
618 WBDEBUG(("[HHDTO]:===state is starting==for antenna toggle==="));
619 #endif
621 else
622 MTO_TOGGLE_STATE() = TOGGLE_STATE_IDLE;
624 if ((MTO_BACKOFF_TMR()!=0)&&(MTO_RATE_LEVEL()>MTO_DataRateAvailableLevel - 3))
626 MTO_TOGGLE_STATE() = TOGGLE_STATE_IDLE;
627 #ifdef _PE_DTO_DUMP_
628 WBDEBUG(("[HHDTO]:===the data rate is %d (good)and will not toogle ===",MTO_DATA_RATE()>>1));
629 #endif
635 int WB_PCR[2]; //packet correct rate
637 void AntennaToggleState(MTO_FUNC_INPUT)
639 int decideantflag = 0;
640 u8 x;
641 s32 rssi;
643 if(MTO_ANT_DIVERSITY_ENABLE() != 1)
644 return;
645 x = hal_get_antenna_number(MTO_HAL());
646 switch(MTO_TOGGLE_STATE())
649 //Missing.....
650 case TOGGLE_STATE_IDLE:
651 case TOGGLE_STATE_BKOFF:
652 break;;
654 case TOGGLE_STATE_WAIT0://========
655 GetDTO_RxInfo(x, MTO_FUNC_INPUT_DATA);
656 sme_get_rssi(MTO_FUNC_INPUT_DATA, &rssi);
657 RXRSSIANT[x] = rssi;
658 #ifdef _PE_DTO_DUMP_
659 WBDEBUG(("[HHDTO] **wait0==== Collecting Ant%d--rssi=%d\n", x,RXRSSIANT[x]));
660 #endif
662 //change antenna and reset the data at changed antenna
663 x = (~x) & 0x01;
664 MTO_ANT_SEL() = x;
665 hal_set_antenna_number(MTO_HAL(), MTO_ANT_SEL());
666 LOCAL_ANTENNA_NO() = x;
668 MTO_TOGGLE_STATE() = TOGGLE_STATE_WAIT1;//go to wait1
669 ResetDTO_RxInfo(x, MTO_FUNC_INPUT_DATA);
670 break;
671 case TOGGLE_STATE_WAIT1://=====wait1
672 //MTO_CNT_ANT(x) = hal_get_bss_pk_cnt(MTO_HAL());
673 //RXRSSIANT[x] = hal_get_rssi(MTO_HAL());
674 sme_get_rssi(MTO_FUNC_INPUT_DATA, &rssi);
675 RXRSSIANT[x] = rssi;
676 GetDTO_RxInfo(x, MTO_FUNC_INPUT_DATA);
677 #ifdef _PE_DTO_DUMP_
678 WBDEBUG(("[HHDTO] **wait1==== Collecting Ant%d--rssi=%d\n", x,RXRSSIANT[x]));
679 #endif
680 MTO_TOGGLE_STATE() = TOGGLE_STATE_MAKEDESISION;
681 break;
682 case TOGGLE_STATE_MAKEDESISION:
683 #ifdef _PE_DTO_DUMP_
684 WBDEBUG(("[HHDTO]:Ant--0-----------------1---\n"));
685 OutputDebugInfo(ANT0,ANT1);
686 #endif
687 //PDEBUG(("[HHDTO] **decision====\n "));
689 //=====following is the decision produrce
691 // first: compare the rssi if difference >10
692 // select the larger one
693 // ,others go to second
694 // second: comapre the tx+rx packet count if difference >100
695 // use larger total packets antenna
696 // third::compare the tx PER if packets>20
697 // if difference >5% using the bigger one
699 // fourth:compare the RX PER if packets>20
700 // if PER difference <5%
701 // using old antenna
704 if (abs(RXRSSIANT[ANT0]-RXRSSIANT[ANT1]) > MTOPARA_RSSI_TH_FOR_ANTDIV())//====rssi_th
706 if (RXRSSIANT[ANT0]>RXRSSIANT[ANT1])
708 decideantflag=1;
709 MTO_ANT_MAC() = ANT0;
711 else
713 decideantflag=1;
714 MTO_ANT_MAC() = ANT1;
716 #ifdef _PE_DTO_DUMP_
717 WBDEBUG(("Select antenna by RSSI\n"));
718 #endif
720 else if (abs(TxPktPerAnt[ANT0] + DTO_Rx_Info[0][ANT0]-TxPktPerAnt[ANT1]-DTO_Rx_Info[0][ANT1])<50)//=====total packet_th
722 #ifdef _PE_DTO_DUMP_
723 WBDEBUG(("Total tx/rx is close\n"));
724 #endif
725 if (TxDominate(ANT0) && TxDominate(ANT1))
727 if ((TxPktPerAnt[ANT0]>10) && (TxPktPerAnt[ANT1]>10))//====tx packet_th
729 WB_PCR[ANT0]=Divide(TxPktPerAnt[ANT0]*100,TxPktRetryPerAnt[ANT0]);
730 WB_PCR[ANT1]=Divide(TxPktPerAnt[ANT1]*100,TxPktRetryPerAnt[ANT1]);
731 if (abs(WB_PCR[ANT0]-WB_PCR[ANT1])>5)// tx PER_th
733 #ifdef _PE_DTO_DUMP_
734 WBDEBUG(("Decide by Tx correct rate\n"));
735 #endif
736 if (WB_PCR[ANT0]>WB_PCR[ANT1])
738 decideantflag=1;
739 MTO_ANT_MAC() = ANT0;
741 else
743 decideantflag=1;
744 MTO_ANT_MAC() = ANT1;
747 else
749 decideantflag=0;
750 untogglecount++;
751 MTO_ANT_MAC() = old_antenna[0];
754 else
756 decideantflag=0;
757 MTO_ANT_MAC() = old_antenna[0];
760 else if ((DTO_Rx_Info[0][ANT0]>10)&&(DTO_Rx_Info[0][ANT1]>10))//rx packet th
762 #ifdef _PE_DTO_DUMP_
763 WBDEBUG(("Decide by Rx\n"));
764 #endif
765 if (abs(DTO_Rx_Info[0][ANT0] - DTO_Rx_Info[0][ANT1])>50)
767 if (DTO_Rx_Info[0][ANT0] > DTO_Rx_Info[0][ANT1])
769 decideantflag=1;
770 MTO_ANT_MAC() = ANT0;
772 else
774 decideantflag=1;
775 MTO_ANT_MAC() = ANT1;
778 else
780 decideantflag=0;
781 untogglecount++;
782 MTO_ANT_MAC() = old_antenna[0];
785 else
787 decideantflag=0;
788 MTO_ANT_MAC() = old_antenna[0];
791 else if ((TxPktPerAnt[ANT0]+DTO_Rx_Info[0][ANT0])>(TxPktPerAnt[ANT1]+DTO_Rx_Info[0][ANT1]))//use more packekts
793 #ifdef _PE_DTO_DUMP_
794 WBDEBUG(("decide by total tx/rx : ANT 0\n"));
795 #endif
797 decideantflag=1;
798 MTO_ANT_MAC() = ANT0;
800 else
802 #ifdef _PE_DTO_DUMP_
803 WBDEBUG(("decide by total tx/rx : ANT 1\n"));
804 #endif
805 decideantflag=1;
806 MTO_ANT_MAC() = ANT1;
809 //this is force ant toggle
810 if (decideantflag==1)
811 untogglecount=0;
813 untogglecount=untogglecount%4;
814 if (untogglecount==3) //change antenna
815 MTO_ANT_MAC() = ((~old_antenna[0]) & 0x1);
816 #ifdef _PE_DTO_DUMP_
817 WBDEBUG(("[HHDTO]:==================untoggle-count=%d",untogglecount));
818 #endif
823 //PDEBUG(("[HHDTO] **********************************DTO ENABLE=%d",MTO_ANT_DIVERSITY_ENABLE()));
824 if(MTO_ANT_DIVERSITY_ENABLE() == 1)
826 MTO_ANT_SEL() = MTO_ANT_MAC();
827 hal_set_antenna_number(MTO_HAL(), MTO_ANT_SEL());
828 LOCAL_ANTENNA_NO() = MTO_ANT_SEL();
829 #ifdef _PE_DTO_DUMP_
830 WBDEBUG(("[HHDTO] ==decision==*******antflag=%d******************selected antenna=%d\n",decideantflag,MTO_ANT_SEL()));
831 #endif
833 if (decideantflag)
835 old_antenna[3]=old_antenna[2];//store antenna info
836 old_antenna[2]=old_antenna[1];
837 old_antenna[1]=old_antenna[0];
838 old_antenna[0]= MTO_ANT_MAC();
840 #ifdef _PE_DTO_DUMP_
841 WBDEBUG(("[HHDTO]:**old antenna=[%d][%d][%d][%d]\n",old_antenna[0],old_antenna[1],old_antenna[2],old_antenna[3]));
842 #endif
843 if (old_antenna[0]!=old_antenna[1])
844 AntennaToggleBkoffTimer=0;
845 else if (old_antenna[1]!=old_antenna[2])
846 AntennaToggleBkoffTimer=1;
847 else if (old_antenna[2]!=old_antenna[3])
848 AntennaToggleBkoffTimer=2;
849 else
850 AntennaToggleBkoffTimer=4;
852 #ifdef _PE_DTO_DUMP_
853 WBDEBUG(("[HHDTO]:**back off timer=%d",AntennaToggleBkoffTimer));
854 #endif
856 ResetDTO_RxInfo(MTO_ANT_MAC(), MTO_FUNC_INPUT_DATA);
857 if (AntennaToggleBkoffTimer==0 && decideantflag)
858 MTO_TOGGLE_STATE() = TOGGLE_STATE_WAIT0;
859 else
860 MTO_TOGGLE_STATE() = TOGGLE_STATE_IDLE;
861 break;
866 void multiagc(MTO_FUNC_INPUT, u8 high_gain_mode )
868 s32 rssi;
869 hw_data_t *pHwData = MTO_HAL();
871 sme_get_rssi(MTO_FUNC_INPUT_DATA, &rssi);
873 if( (RF_WB_242 == pHwData->phy_type) ||
874 (RF_WB_242_1 == pHwData->phy_type) ) // 20060619.5 Add
876 if (high_gain_mode==1)
878 //hw_set_dxx_reg(phw_data, 0x0C, 0xf8f52230);
879 //hw_set_dxx_reg(phw_data, 0x20, 0x06C43440);
880 Wb35Reg_Write( pHwData, 0x100C, 0xF2F32232 ); // 940916 0xf8f52230 );
881 Wb35Reg_Write( pHwData, 0x1020, 0x04cb3440 ); // 940915 0x06C43440
883 else if (high_gain_mode==0)
885 //hw_set_dxx_reg(phw_data, 0x0C, 0xEEEE000D);
886 //hw_set_dxx_reg(phw_data, 0x20, 0x06c41440);
887 Wb35Reg_Write( pHwData, 0x100C, 0xEEEE000D );
888 Wb35Reg_Write( pHwData, 0x1020, 0x04cb1440 ); // 940915 0x06c41440
890 #ifdef _PE_DTO_DUMP_
891 WBDEBUG(("[HHDTOAGC] **rssi=%d, high gain mode=%d", rssi, high_gain_mode));
892 #endif
896 void TxPwrControl(MTO_FUNC_INPUT)
898 s32 rssi;
899 hw_data_t *pHwData = MTO_HAL();
901 sme_get_rssi(MTO_FUNC_INPUT_DATA, &rssi);
902 if( (RF_WB_242 == pHwData->phy_type) ||
903 (RF_WB_242_1 == pHwData->phy_type) ) // 20060619.5 Add
905 static u8 high_gain_mode; //this is for winbond RF switch LNA
906 //using different register setting
908 if (high_gain_mode==1)
910 if( rssi > MTO_DATA().RSSI_high )
912 //hw_set_dxx_reg(phw_data, 0x0C, 0xf8f52230);
913 //hw_set_dxx_reg(phw_data, 0x20, 0x05541640);
914 high_gain_mode=0;
916 else
918 //hw_set_dxx_reg(phw_data, 0x0C, 0xf8f51830);
919 //hw_set_dxx_reg(phw_data, 0x20, 0x05543E40);
920 high_gain_mode=1;
923 else //if (high_gain_mode==0)
925 if( rssi < MTO_DATA().RSSI_low )
927 //hw_set_dxx_reg(phw_data, 0x0C, 0xf8f51830);
928 //hw_set_dxx_reg(phw_data, 0x20, 0x05543E40);
929 high_gain_mode=1;
931 else
933 //hw_set_dxx_reg(phw_data, 0x0C, 0xf8f52230);
934 //hw_set_dxx_reg(phw_data, 0x20, 0x05541640);
935 high_gain_mode=0;
939 // Always high gain 20051014. Using the initial value only.
940 multiagc(MTO_FUNC_INPUT_DATA, high_gain_mode);
945 u8 CalcNewRate(MTO_FUNC_INPUT, u8 old_rate, u32 retry_cnt, u32 tx_frag_cnt)
947 int i;
948 u8 new_rate;
949 u32 retry_rate;
950 int TxThrouput1, TxThrouput2, TxThrouput3, BestThroupht;
952 if(tx_frag_cnt < MTOPARA_TXCOUNT_TH_FOR_CALC_RATE()) //too few packets transmit
954 return 0xff;
956 retry_rate = Divide(retry_cnt * 100, tx_frag_cnt);
958 if(retry_rate > 90) retry_rate = 90; //always truncate to 90% due to lookup table size
959 #ifdef _PE_DTO_DUMP_
960 WBDEBUG(("##### Current level =%d, Retry count =%d, Frag count =%d\n",
961 old_rate, retry_cnt, tx_frag_cnt));
962 WBDEBUG(("*##* Retry rate =%d, throughput =%d\n",
963 retry_rate, Rate_PER_TBL[retry_rate][old_rate]));
964 WBDEBUG(("TxRateRec.tx_rate =%d, Retry rate = %d, throughput = %d\n",
965 TxRateRec.tx_rate, TxRateRec.tx_retry_rate,
966 Rate_PER_TBL[TxRateRec.tx_retry_rate][Level2PerTbl[TxRateRec.tx_rate]]));
967 WBDEBUG(("old_rate-1 =%d, Retry rate = %d, throughput = %d\n",
968 old_rate-1, retryrate_rec[old_rate-1],
969 Rate_PER_TBL[retryrate_rec[old_rate-1]][old_rate-1]));
970 WBDEBUG(("old_rate+1 =%d, Retry rate = %d, throughput = %d\n",
971 old_rate+1, retryrate_rec[old_rate+1],
972 Rate_PER_TBL[retryrate_rec[old_rate+1]][old_rate+1]));
973 #endif
975 //following is for record the retry rate at the different data rate
976 if (abs(retry_rate-retryrate_rec[old_rate])<50)//---the per TH
977 retryrate_rec[old_rate] = retry_rate; //update retry rate
978 else
980 for (i=0;i<MTO_DataRateAvailableLevel;i++) //reset all retry rate
981 retryrate_rec[i]=0;
982 retryrate_rec[old_rate] = retry_rate;
983 #ifdef _PE_DTO_DUMP_
984 WBDEBUG(("Reset retry rate table\n"));
985 #endif
988 if(TxRateRec.tx_rate > old_rate) //Decrease Tx Rate
990 TxThrouput1 = Rate_PER_TBL[TxRateRec.tx_retry_rate][Level2PerTbl[TxRateRec.tx_rate]];
991 TxThrouput2 = Rate_PER_TBL[retry_rate][Level2PerTbl[old_rate]];
992 if(TxThrouput1 > TxThrouput2)
994 new_rate = TxRateRec.tx_rate;
995 BestThroupht = TxThrouput1;
997 else
999 new_rate = old_rate;
1000 BestThroupht = TxThrouput2;
1002 if((old_rate > 0) &&(retry_rate>MTOPARA_TXRATE_DEC_TH())) //Min Rate
1004 TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate-1]][Level2PerTbl[old_rate-1]];
1005 if(BestThroupht < TxThrouput3)
1007 new_rate = old_rate - 1;
1008 #ifdef _PE_DTO_DUMP_
1009 WBDEBUG(("--------\n"));
1010 #endif
1011 BestThroupht = TxThrouput3;
1015 else if(TxRateRec.tx_rate < old_rate) //Increase Tx Rate
1017 TxThrouput1 = Rate_PER_TBL[TxRateRec.tx_retry_rate][Level2PerTbl[TxRateRec.tx_rate]];
1018 TxThrouput2 = Rate_PER_TBL[retry_rate][Level2PerTbl[old_rate]];
1019 if(TxThrouput1 > TxThrouput2)
1021 new_rate = TxRateRec.tx_rate;
1022 BestThroupht = TxThrouput1;
1024 else
1026 new_rate = old_rate;
1027 BestThroupht = TxThrouput2;
1029 if ((old_rate < MTO_DataRateAvailableLevel - 1)&&(retry_rate<MTOPARA_TXRATE_INC_TH()))
1031 //TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]][Level2PerTbl[old_rate+1]];
1032 if (retryrate_rec[old_rate+1] > MTOPARA_TXRETRYRATE_REDUCE())
1033 TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]-MTOPARA_TXRETRYRATE_REDUCE()][Level2PerTbl[old_rate+1]];
1034 else
1035 TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]][Level2PerTbl[old_rate+1]];
1036 if(BestThroupht < TxThrouput3)
1038 new_rate = old_rate + 1;
1039 #ifdef _PE_DTO_DUMP_
1040 WBDEBUG(("++++++++++\n"));
1041 #endif
1042 BestThroupht = TxThrouput3;
1046 else //Tx Rate no change
1048 TxThrouput2 = Rate_PER_TBL[retry_rate][Level2PerTbl[old_rate]];
1049 new_rate = old_rate;
1050 BestThroupht = TxThrouput2;
1052 if (retry_rate <MTOPARA_TXRATE_EQ_TH()) //th for change higher rate
1054 if(old_rate < MTO_DataRateAvailableLevel - 1)
1056 //TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]][Level2PerTbl[old_rate+1]];
1057 if (retryrate_rec[old_rate+1] > MTOPARA_TXRETRYRATE_REDUCE())
1058 TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]-MTOPARA_TXRETRYRATE_REDUCE()][Level2PerTbl[old_rate+1]];
1059 else
1060 TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]][Level2PerTbl[old_rate+1]];
1061 if(BestThroupht < TxThrouput3)
1063 new_rate = old_rate + 1;
1064 BestThroupht = TxThrouput3;
1065 #ifdef _PE_DTO_DUMP_
1066 WBDEBUG(("=++++++++++\n"));
1067 #endif
1071 else
1072 if(old_rate > 0) //Min Rate
1074 TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate-1]][Level2PerTbl[old_rate-1]];
1075 if(BestThroupht < TxThrouput3)
1077 new_rate = old_rate - 1;
1078 #ifdef _PE_DTO_DUMP_
1079 WBDEBUG(("=--------\n"));
1080 #endif
1081 BestThroupht = TxThrouput3;
1086 if (!LOCAL_IS_IBSS_MODE())
1088 max_rssi_rate = GetMaxRateLevelFromRSSI();
1089 #ifdef _PE_DTO_DUMP_
1090 WBDEBUG(("[MTO]:RSSI2Rate=%d\n", MTO_Data_Rate_Tbl[max_rssi_rate]));
1091 #endif
1092 if(new_rate > max_rssi_rate)
1093 new_rate = max_rssi_rate;
1096 //save new rate;
1097 TxRateRec.tx_rate = old_rate;
1098 TxRateRec.tx_retry_rate = (u8) retry_rate;
1099 TxRetryRate = retry_rate;
1100 return new_rate;
1103 void SmoothRSSI(s32 new_rssi)
1105 RSSISmoothed = RSSISmoothed + new_rssi - RSSIBuf[RSSIBufIndex];
1106 RSSIBuf[RSSIBufIndex] = new_rssi;
1107 RSSIBufIndex = (RSSIBufIndex + 1) % 10;
1110 u8 GetMaxRateLevelFromRSSI(void)
1112 u8 i;
1113 u8 TxRate;
1115 for(i=0;i<RSSI2RATE_SIZE;i++)
1117 if(RSSISmoothed > RSSI2RateTbl[i].RSSI)
1118 break;
1120 #ifdef _PE_DTO_DUMP_
1121 WBDEBUG(("[MTO]:RSSI=%d\n", Divide(RSSISmoothed, 10)));
1122 #endif
1123 if(i < RSSI2RATE_SIZE)
1124 TxRate = RSSI2RateTbl[i].TxRate;
1125 else
1126 TxRate = 2; //divided by 2 = 1Mbps
1128 for(i=MTO_DataRateAvailableLevel-1;i>0;i--)
1130 if(TxRate >=MTO_Data_Rate_Tbl[i])
1131 break;
1133 return i;
1136 //===========================================================================
1137 // Description:
1138 // If we enable DTO, we will ignore the tx count with different tx rate from
1139 // DTO rate. This is because when we adjust DTO tx rate, there could be some
1140 // packets in the tx queue with previous tx rate
1141 void MTO_SetTxCount(MTO_FUNC_INPUT, u8 tx_rate, u8 index)
1143 MTO_TXFLOWCOUNT()++;
1144 if ((MTO_ENABLE==1) && (MTO_RATE_CHANGE_ENABLE()==1))
1146 if(tx_rate == MTO_DATA_RATE())
1148 if (index == 0)
1150 if (boSparseTxTraffic)
1151 MTO_HAL()->dto_tx_frag_count += MTOPARA_PERIODIC_CHECK_CYCLE();
1152 else
1153 MTO_HAL()->dto_tx_frag_count += 1;
1155 else
1157 if (index<8)
1159 MTO_HAL()->dto_tx_retry_count += index;
1160 MTO_HAL()->dto_tx_frag_count += (index+1);
1162 else
1164 MTO_HAL()->dto_tx_retry_count += 7;
1165 MTO_HAL()->dto_tx_frag_count += 7;
1169 else if(MTO_DATA_RATE()>48 && tx_rate ==48)
1170 {//ALFRED
1171 if (index<3) //for reduciing data rate scheme ,
1172 //do not calcu different data rate
1173 //3 is the reducing data rate at retry
1175 MTO_HAL()->dto_tx_retry_count += index;
1176 MTO_HAL()->dto_tx_frag_count += (index+1);
1178 else
1180 MTO_HAL()->dto_tx_retry_count += 3;
1181 MTO_HAL()->dto_tx_frag_count += 3;
1186 else
1188 MTO_HAL()->dto_tx_retry_count += index;
1189 MTO_HAL()->dto_tx_frag_count += (index+1);
1191 TotalTxPkt ++;
1192 TotalTxPktRetry += (index+1);
1194 PeriodTotalTxPkt ++;
1195 PeriodTotalTxPktRetry += (index+1);
1198 u8 MTO_GetTxFallbackRate(MTO_FUNC_INPUT)
1200 return MTO_DATA_FALLBACK_RATE();
1204 //===========================================================================
1205 // MTO_TxFailed --
1207 // Description:
1208 // Failure of transmitting a packet indicates that certain MTO parmeters
1209 // may need to be adjusted. This function is called when NIC just failed
1210 // to transmit a packet or when MSDULifeTime expired.
1212 // Arguments:
1213 // Adapter - The pointer to the Miniport Adapter Context
1215 // Return Value:
1216 // None
1217 //============================================================================
1218 void MTO_TxFailed(MTO_FUNC_INPUT)
1220 return;
1223 int Divide(int a, int b)
1225 if (b==0) b=1;
1226 return a/b;