linux/drivers/staging/otus/80211core/performance.c
<<
>>
Prefs
   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
  30static struct zsSummary zm_summary;
  31static struct zsVariation zm_var;
  32static struct zsThroughput zm_tp;
  33
  34void 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
  79void 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
 126void 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
 206void 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
 223void 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
 240void 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
 260void 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
 318void 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
 386void 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
 392void 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
 404void zfiRxPerformanceFree(zdev_t* dev, zbuf_t* buf)
 405{
 406    zm_summary.rx_free++;
 407}
 408
 409void 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}
 416void zfiRxPerformanceFlush(zdev_t* dev)
 417{
 418    zm_summary.rx_flush++;
 419}
 420
 421void zfiRxPerformanceClear(zdev_t* dev)
 422{
 423    zm_summary.rx_clear++;
 424    ZM_SEQ_DEBUG("RxClear");
 425}
 426
 427void zfiRxPerformanceReorder(zdev_t* dev)
 428{
 429    zm_summary.rx_reorder++;
 430}
 431#endif /* end of ZM_ENABLE_PERFORMANCE_EVALUATION */
 432