Commit | Line | Data |
---|---|---|
4bd43f50 LR |
1 | /* |
2 | * Copyright (c) 2007-2008 Atheros Communications Inc. | |
3 | * | |
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. | |
7 | * | |
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. | |
15 | */ | |
16 | /* */ | |
17 | /* Module Name : performance.c */ | |
18 | /* */ | |
19 | /* Abstract */ | |
20 | /* This module performance evaluation functions. */ | |
21 | /* */ | |
22 | /* NOTES */ | |
23 | /* None */ | |
24 | /* */ | |
25 | /************************************************************************/ | |
26 | #include "cprecomp.h" | |
27 | #ifdef ZM_ENABLE_PERFORMANCE_EVALUATION | |
28 | ||
29 | #define ZM_TP_SIZE 50 | |
a5ca2dfc JL |
30 | static struct zsSummary zm_summary; |
31 | static struct zsVariation zm_var; | |
32 | static struct zsThroughput zm_tp; | |
4bd43f50 LR |
33 | |
34 | void zfiPerformanceInit(zdev_t* dev) | |
35 | { | |
36 | u16_t i; | |
37 | ||
38 | zmw_get_wlan_dev(dev); | |
39 | ||
40 | zm_summary.tick_base = wd->tick; | |
41 | zm_summary.tx_msdu_count = 0; | |
42 | zm_summary.tx_mpdu_count = 0; | |
43 | zm_summary.rx_msdu_count = 0; | |
44 | zm_summary.rx_mpdu_count = 0; | |
45 | zm_summary.rx_broken_seq = 0; | |
46 | zm_summary.rx_broken_sum = 0; | |
47 | zm_summary.rx_seq_base = 0; | |
48 | zm_summary.rx_broken_seq_dis = 0; | |
49 | zm_summary.rx_duplicate_seq = 0; | |
50 | zm_summary.rx_old_seq = 0; | |
51 | zm_summary.reset_count = 0; | |
52 | zm_summary.reset_sum = 0; | |
53 | zm_summary.rx_lost_sum = 0; | |
54 | zm_summary.rx_duplicate_error = 0; | |
55 | zm_summary.rx_free = 0; | |
56 | zm_summary.rx_amsdu_len = 0; | |
57 | zm_summary.rx_flush = 0; | |
58 | zm_summary.rx_clear = 0; | |
59 | zm_summary.rx_reorder = 0; | |
60 | ||
61 | for (i=0; i<100; i++) | |
62 | { | |
63 | zm_var.tx_msdu_tick[i] = zm_var.tx_mpdu_tick[i] = 0; | |
64 | zm_var.rx_msdu_tick[i] = zm_var.rx_mpdu_tick[i] = 0; | |
65 | } | |
66 | ||
67 | zfTimerSchedule(dev, ZM_EVENT_TIMEOUT_PERFORMANCE, 100); | |
68 | ||
69 | zm_tp.size = ZM_TP_SIZE; | |
70 | zm_tp.head = zm_tp.size - 1; | |
71 | zm_tp.tail = 0; | |
72 | for (i=0; i<zm_tp.size; i++) | |
73 | { | |
74 | zm_tp.tx[i]=0; | |
75 | zm_tp.rx[i]=0; | |
76 | } | |
77 | } | |
78 | ||
79 | void zfiPerformanceGraph(zdev_t* dev) | |
80 | { | |
81 | s16_t i,j; | |
82 | u8_t s[ZM_TP_SIZE+5]; | |
83 | zmw_get_wlan_dev(dev); | |
84 | ||
85 | for (i=0; i<(zm_tp.size-1); i++) | |
86 | { | |
87 | zm_tp.tx[i] = zm_tp.tx[i+1]; | |
88 | zm_tp.rx[i] = zm_tp.rx[i+1]; | |
89 | } | |
90 | zm_tp.tx[zm_tp.size-1] = zm_summary.tx_mpdu_count*1500*8/1000000; | |
91 | zm_tp.rx[zm_tp.size-1] = zm_summary.rx_msdu_count*1500*8/1000000; | |
92 | ||
93 | for (i=15; i>0; i--) | |
94 | { | |
95 | s[0] = (i/10) + '0'; | |
96 | s[1] = (i%10) + '0'; | |
97 | s[2] = '0'; | |
98 | s[3] = '|'; | |
99 | for (j=0; j<zm_tp.size; j++) | |
100 | { | |
101 | if ((zm_tp.tx[j]/10 == i) && (zm_tp.rx[j]/10 == i)) | |
102 | { | |
103 | s[4+j] = 'X'; | |
104 | } | |
105 | else if (zm_tp.tx[j]/10 == i) | |
106 | { | |
107 | s[4+j] = 'T'; | |
108 | } | |
109 | else if (zm_tp.rx[j]/10 == i) | |
110 | { | |
111 | s[4+j] = 'R'; | |
112 | } | |
113 | else | |
114 | { | |
115 | s[4+j] = ' '; | |
116 | } | |
117 | } | |
118 | s[zm_tp.size+4] = '\0'; | |
119 | DbgPrint("%s",s); | |
120 | } | |
121 | DbgPrint("000|__________________________________________________"); | |
122 | ||
123 | } | |
124 | ||
125 | ||
126 | void zfiPerformanceRefresh(zdev_t* dev) | |
127 | { | |
128 | u16_t i; | |
129 | ||
130 | zmw_get_wlan_dev(dev); | |
131 | ||
132 | zfiDbgReadReg(dev, 0x11772c); | |
133 | ||
134 | zm_var.tx_msdu_mean = zm_summary.tx_msdu_count / 100; | |
135 | zm_var.tx_mpdu_mean = zm_summary.tx_mpdu_count / 100; | |
136 | zm_var.rx_msdu_mean = zm_summary.rx_msdu_count / 100; | |
137 | zm_var.rx_mpdu_mean = zm_summary.rx_mpdu_count / 100; | |
138 | ||
139 | zm_var.tx_msdu_sum = zm_var.tx_mpdu_sum = 0; | |
140 | zm_var.rx_msdu_sum = zm_var.rx_mpdu_sum = 0; | |
141 | zm_summary.tx_idle_count = zm_summary.rx_idle_count = 0; | |
142 | for (i=0; i<100; i++) | |
143 | { | |
144 | zm_var.tx_msdu_sum += (zm_var.tx_msdu_tick[i] * zm_var.tx_msdu_tick[i]); | |
145 | zm_var.tx_mpdu_sum += (zm_var.tx_mpdu_tick[i] * zm_var.tx_mpdu_tick[i]); | |
146 | zm_var.rx_msdu_sum += (zm_var.rx_msdu_tick[i] * zm_var.rx_msdu_tick[i]); | |
147 | zm_var.rx_mpdu_sum += (zm_var.rx_mpdu_tick[i] * zm_var.rx_mpdu_tick[i]); | |
148 | ||
149 | if (!zm_var.tx_mpdu_tick[i]) zm_summary.tx_idle_count++; | |
150 | if (!zm_var.rx_mpdu_tick[i]) zm_summary.rx_idle_count++; | |
151 | } | |
152 | zm_var.tx_msdu_var = (zm_var.tx_msdu_sum / 100) - (zm_var.tx_msdu_mean * zm_var.tx_msdu_mean); | |
153 | zm_var.tx_mpdu_var = (zm_var.tx_mpdu_sum / 100) - (zm_var.tx_mpdu_mean * zm_var.tx_mpdu_mean); | |
154 | zm_var.rx_msdu_var = (zm_var.rx_msdu_sum / 100) - (zm_var.rx_msdu_mean * zm_var.rx_msdu_mean); | |
155 | zm_var.rx_mpdu_var = (zm_var.rx_mpdu_sum / 100) - (zm_var.rx_mpdu_mean * zm_var.rx_mpdu_mean); | |
156 | ||
157 | zm_summary.tick_base = wd->tick; | |
158 | zm_summary.rx_broken_sum += zm_summary.rx_broken_seq; | |
159 | zm_summary.rx_lost_sum += (zm_summary.rx_broken_seq - zm_summary.rx_duplicate_seq - zm_summary.rx_old_seq); | |
160 | ||
161 | zfiPerformanceGraph(dev); | |
162 | ||
163 | DbgPrint("******************************************************\n"); | |
164 | DbgPrint("* TX: MSDU=%5d, VAR=%5d; MPDU=%5d, VAR=%5d\n", zm_summary.tx_msdu_count, | |
165 | zm_var.tx_msdu_var, zm_summary.tx_mpdu_count, zm_var.tx_mpdu_var); | |
166 | DbgPrint("* TX: idle=%5d,TxRate=%3d, PER=%5d\n", zm_summary.tx_idle_count, | |
167 | wd->CurrentTxRateKbps/1000, | |
168 | (u16_t)wd->PER[wd->sta.oppositeInfo[0].rcCell.currentRate]); | |
169 | DbgPrint("* RX: MSDU=%5d, VAR=%5d; MPDU=%5d, VAR=%5d\n", zm_summary.rx_msdu_count, | |
170 | zm_var.rx_msdu_var, zm_summary.rx_mpdu_count, zm_var.rx_mpdu_var); | |
171 | DbgPrint("* RX: idle=%5d,RxRate=%3d,AMSDU=%5d\n", zm_summary.rx_idle_count, | |
172 | wd->CurrentRxRateKbps/1000, zm_summary.rx_amsdu_len); | |
173 | DbgPrint("* RX broken seq=%4d, distances=%4d, duplicates=%4d\n", zm_summary.rx_broken_seq, | |
174 | zm_summary.rx_broken_seq_dis, zm_summary.rx_duplicate_seq); | |
175 | DbgPrint("* RX old seq=%4d, lost=%4d, broken sum=%4d\n", zm_summary.rx_old_seq, | |
176 | (zm_summary.rx_broken_seq - zm_summary.rx_duplicate_seq - zm_summary.rx_old_seq), | |
177 | zm_summary.rx_broken_sum); | |
178 | DbgPrint("* Rx lost sum=%4d,dup. error=%4d, free count=%4d\n", zm_summary.rx_lost_sum, | |
179 | zm_summary.rx_duplicate_error, zm_summary.rx_free); | |
180 | DbgPrint("* Rx flush sum=%4d, clear sum=%4d, reorder=%7d\n", zm_summary.rx_flush, | |
181 | zm_summary.rx_clear, zm_summary.rx_reorder); | |
182 | DbgPrint("* Firmware reset=%3d, reset sum=%4d\n", zm_summary.reset_count, | |
183 | zm_summary.reset_sum); | |
184 | DbgPrint("******************************************************\n\n"); | |
185 | //reset count 11772c | |
186 | zm_summary.tx_msdu_count = 0; | |
187 | zm_summary.tx_mpdu_count = 0; | |
188 | zm_summary.rx_msdu_count = 0; | |
189 | zm_summary.rx_mpdu_count = 0; | |
190 | zm_summary.rx_broken_seq = 0; | |
191 | zm_summary.rx_broken_seq_dis = 0; | |
192 | zm_summary.rx_duplicate_seq = 0; | |
193 | zm_summary.rx_old_seq = 0; | |
194 | zm_summary.reset_count = 0; | |
195 | zm_summary.rx_amsdu_len = 0; | |
196 | ||
197 | for (i=0; i<100; i++) | |
198 | { | |
199 | zm_var.tx_msdu_tick[i] = zm_var.tx_mpdu_tick[i] = 0; | |
200 | zm_var.rx_msdu_tick[i] = zm_var.rx_mpdu_tick[i] = 0; | |
201 | } | |
202 | ||
203 | zfTimerSchedule(dev, ZM_EVENT_TIMEOUT_PERFORMANCE, 100); | |
204 | } | |
205 | ||
206 | void zfiTxPerformanceMSDU(zdev_t* dev, u32_t tick) | |
207 | { | |
208 | u32_t index; | |
209 | zm_summary.tx_msdu_count++; | |
210 | ||
211 | index = tick - zm_summary.tick_base; | |
212 | ||
213 | if (index < 100) | |
214 | { | |
215 | zm_var.tx_msdu_tick[index]++; | |
216 | } | |
217 | else | |
218 | { | |
219 | //DbgPrint("wd->tick exceeded tick_base+100!\n"); | |
220 | } | |
221 | } | |
222 | ||
223 | void zfiRxPerformanceMSDU(zdev_t* dev, u32_t tick) | |
224 | { | |
225 | u32_t index; | |
226 | zm_summary.rx_msdu_count++; | |
227 | ||
228 | index = tick - zm_summary.tick_base; | |
229 | ||
230 | if (index < 100) | |
231 | { | |
232 | zm_var.rx_msdu_tick[index]++; | |
233 | } | |
234 | else | |
235 | { | |
236 | //DbgPrint("wd->tick exceeded tick_base+100!\n"); | |
237 | } | |
238 | } | |
239 | ||
240 | void zfiTxPerformanceMPDU(zdev_t* dev, u32_t tick) | |
241 | { | |
242 | u32_t index; | |
243 | zm_summary.tx_mpdu_count++; | |
244 | ||
245 | index = tick - zm_summary.tick_base; | |
246 | ||
247 | if (index < 100) | |
248 | { | |
249 | zm_var.tx_mpdu_tick[index]++; | |
250 | } | |
251 | else | |
252 | { | |
253 | //DbgPrint("wd->tick exceeded tick_base+100!\n"); | |
254 | } | |
255 | } | |
256 | ||
257 | #ifndef ZM_INT_USE_EP2_HEADER_SIZE | |
258 | #define ZM_INT_USE_EP2_HEADER_SIZE 12 | |
259 | #endif | |
260 | void zfiRxPerformanceMPDU(zdev_t* dev, zbuf_t* buf) | |
261 | { | |
262 | u32_t index; | |
263 | u16_t frameType; | |
264 | u16_t frameCtrl; | |
265 | u8_t mpduInd; | |
266 | u16_t plcpHdrLen; | |
267 | u16_t len; | |
268 | ||
269 | zmw_get_wlan_dev(dev); | |
270 | ||
271 | len = zfwBufGetSize(dev, buf); | |
272 | mpduInd = zmw_rx_buf_readb(dev, buf, len-1); | |
273 | /* First MPDU or Single MPDU */ | |
274 | if(((mpduInd & 0x30) == 0x00) || ((mpduInd & 0x30) == 0x20)) | |
275 | //if ((mpduInd & 0x10) == 0x00) | |
276 | { | |
277 | plcpHdrLen = 12; // PLCP header length | |
278 | } | |
279 | else | |
280 | { | |
281 | if (zmw_rx_buf_readh(dev, buf, 4) == wd->macAddr[0] && | |
282 | zmw_rx_buf_readh(dev, buf, 6) == wd->macAddr[1] && | |
283 | zmw_rx_buf_readh(dev, buf, 8) == wd->macAddr[2]) { | |
284 | plcpHdrLen = 0; | |
285 | } | |
286 | else if (zmw_rx_buf_readh(dev, buf, 16) == wd->macAddr[0] && | |
287 | zmw_rx_buf_readh(dev, buf, 18) == wd->macAddr[1] && | |
288 | zmw_rx_buf_readh(dev, buf, 20) == wd->macAddr[2]){ | |
289 | plcpHdrLen = 12; | |
290 | } | |
291 | else { | |
292 | plcpHdrLen = 0; | |
293 | } | |
294 | } | |
295 | ||
296 | frameCtrl = zmw_rx_buf_readb(dev, buf, plcpHdrLen + 0); | |
297 | frameType = frameCtrl & 0xf; | |
298 | ||
299 | if (frameType != ZM_WLAN_DATA_FRAME) | |
300 | { | |
301 | return; | |
302 | } | |
303 | ||
304 | zm_summary.rx_mpdu_count++; | |
305 | ||
306 | index = wd->tick - zm_summary.tick_base; | |
307 | ||
308 | if (index < 100) | |
309 | { | |
310 | zm_var.rx_mpdu_tick[index]++; | |
311 | } | |
312 | else | |
313 | { | |
314 | //DbgPrint("wd->tick exceeded tick_base+100!\n"); | |
315 | } | |
316 | } | |
317 | ||
318 | void zfiRxPerformanceSeq(zdev_t* dev, zbuf_t* buf) | |
319 | { | |
320 | u16_t seq_no; | |
321 | u16_t offset = 0; | |
322 | u16_t old_dis = zm_summary.rx_broken_seq_dis; | |
323 | //sys_time = KeQueryPerformanceCounter(&freq); | |
324 | ||
325 | seq_no = zmw_rx_buf_readh(dev, buf, offset+22) >> 4; | |
326 | ||
327 | ZM_SEQ_DEBUG("Out %5d\n", seq_no); | |
328 | ||
329 | if (seq_no < zm_summary.rx_seq_base) | |
330 | { | |
331 | if (seq_no == 0) | |
332 | { | |
333 | if (zm_summary.rx_seq_base != 4095) | |
334 | { | |
335 | zm_summary.rx_broken_seq++; | |
336 | ZM_SEQ_DEBUG("Broken seq"); | |
337 | zm_summary.rx_broken_seq_dis+=(4096 - zm_summary.rx_seq_base); | |
338 | } | |
339 | } | |
340 | else if ((seq_no < 300) && (zm_summary.rx_seq_base > 3800)) | |
341 | { | |
342 | zm_summary.rx_broken_seq++; | |
343 | ZM_SEQ_DEBUG("Broken seq"); | |
344 | zm_summary.rx_broken_seq_dis+=(4096 - zm_summary.rx_seq_base + seq_no); | |
345 | } | |
346 | else | |
347 | { | |
348 | zm_summary.rx_broken_seq++; | |
349 | ZM_SEQ_DEBUG("Broken seq"); | |
350 | zm_summary.rx_broken_seq_dis+=(zm_summary.rx_seq_base - seq_no); | |
351 | zm_summary.rx_old_seq++; | |
352 | } | |
353 | } | |
354 | else | |
355 | { | |
356 | if (seq_no != (zm_summary.rx_seq_base + 1)) | |
357 | { | |
358 | if ((seq_no > 3800) && (zm_summary.rx_seq_base < 300)) | |
359 | { | |
360 | zm_summary.rx_broken_seq++; | |
361 | ZM_SEQ_DEBUG("Broken seq"); | |
362 | zm_summary.rx_broken_seq_dis+=(4096 - seq_no + zm_summary.rx_seq_base); | |
363 | zm_summary.rx_old_seq++; | |
364 | } | |
365 | else | |
366 | { | |
367 | zm_summary.rx_broken_seq++; | |
368 | ZM_SEQ_DEBUG("Broken seq"); | |
369 | zm_summary.rx_broken_seq_dis+=(seq_no - zm_summary.rx_seq_base); | |
370 | } | |
371 | } | |
372 | } | |
373 | if (seq_no == zm_summary.rx_seq_base) | |
374 | { | |
375 | zm_summary.rx_duplicate_seq++; | |
376 | } | |
377 | ||
378 | if ((zm_summary.rx_broken_seq_dis - old_dis) > 100) | |
379 | { | |
380 | DbgPrint("* seq_no=%4d, base_seq=%4d, dis_diff=%4d", seq_no, | |
381 | zm_summary.rx_seq_base, zm_summary.rx_broken_seq_dis - old_dis); | |
382 | } | |
383 | zm_summary.rx_seq_base = seq_no; | |
384 | } | |
385 | ||
386 | void zfiRxPerformanceReg(zdev_t* dev, u32_t reg, u32_t rsp) | |
387 | { | |
388 | zm_summary.reset_count = (u16_t)rsp - zm_summary.reset_sum; | |
389 | zm_summary.reset_sum = (u16_t)rsp; | |
390 | } | |
391 | ||
392 | void zfiRxPerformanceDup(zdev_t* dev, zbuf_t* buf1, zbuf_t* buf2) | |
393 | { | |
394 | u16_t seq_no1, seq_no2; | |
395 | ||
396 | seq_no1 = zmw_rx_buf_readh(dev, buf1, 22) >> 4; | |
397 | seq_no2 = zmw_rx_buf_readh(dev, buf2, 22) >> 4; | |
398 | if (seq_no1 != seq_no2) | |
399 | { | |
400 | zm_summary.rx_duplicate_error++; | |
401 | } | |
402 | } | |
403 | ||
404 | void zfiRxPerformanceFree(zdev_t* dev, zbuf_t* buf) | |
405 | { | |
406 | zm_summary.rx_free++; | |
407 | } | |
408 | ||
409 | void zfiRxPerformanceAMSDU(zdev_t* dev, zbuf_t* buf, u16_t len) | |
410 | { | |
411 | if (zm_summary.rx_amsdu_len < len) | |
412 | { | |
413 | zm_summary.rx_amsdu_len = len; | |
414 | } | |
415 | } | |
416 | void zfiRxPerformanceFlush(zdev_t* dev) | |
417 | { | |
418 | zm_summary.rx_flush++; | |
419 | } | |
420 | ||
421 | void zfiRxPerformanceClear(zdev_t* dev) | |
422 | { | |
423 | zm_summary.rx_clear++; | |
424 | ZM_SEQ_DEBUG("RxClear"); | |
425 | } | |
426 | ||
427 | void zfiRxPerformanceReorder(zdev_t* dev) | |
428 | { | |
429 | zm_summary.rx_reorder++; | |
430 | } | |
431 | #endif /* end of ZM_ENABLE_PERFORMANCE_EVALUATION */ |