##############################################################################
#                                                                            #
# IAR ARM ANSI C/C++ Compiler V4.11A/W32               20/Jul/2004  18:58:51 #
# Copyright 1999-2004 IAR Systems. All rights reserved.                      #
#                                                                            #
#    Cpu mode        =  arm                                                  #
#    Endian          =  little                                               #
#    Stack alignment =  4                                                    #
#    Source file     =  C:\medusa\zl_rmon.c                                  #
#    Command line    =  -I "C:\Program Files\IAR Systems\Embedded Workbench  #
#                       4.0\ARM\INC\" -lc C:\medusa\Debug\List\ -la          #
#                       C:\medusa\Debug\List\ -o C:\medusa\Debug\Obj\ -s2    #
#                       --no_cse --no_unroll --no_inline --no_code_motion    #
#                       --no_tbaa --no_clustering --no_scheduling --debug    #
#                       --cpu_mode arm --endian little --cpu ARM7TDMI-S      #
#                       --stack_align 4 -e --fpu None                        #
#                       "-D_DLIB_CONFIG_FILE=C:\Program Files\IAR            #
#                       Systems\Embedded Workbench                           #
#                       4.0\ARM\LIB\dl4tpannl8n.h" C:\medusa\zl_rmon.c       #
#    List file       =  C:\medusa\Debug\List\zl_rmon.lst                     #
#    Object file     =  C:\medusa\Debug\Obj\zl_rmon.r79                      #
#                                                                            #
#                                                                            #
##############################################################################

C:\medusa\zl_rmon.c
      1          #include "archinc.h"
      2          #include "cli.h"
      3          #include "strutil.h"
      4          #include "zarlink.h"
      5          
      6          #ifdef CONFIG_INCLUDE_ZARLINK
      7          
      8          #include <stdio.h>
      9          #include <stdlib.h>
     10          
     11          /*
     12           * when sending a request, use the current value of cmdFrameIndex. The reply received from 
     13           * the switch should match this index. If so, increment the index circularly. 
     14           */
     15          
     16          static zarlinkPortStats_t portStats[10];
     17          
     18          static union {
     19            unsigned char requestFrameData8[8];
     20            unsigned short requestFrameData16[4];
     21            } request;
     22          
     23          static unsigned short replyData16[20];
     24          
     25          static int ctrlRequestStats(int port, int octet)
     26          {
     27            int i;
     28            unsigned char tmpStatus;
     29            unsigned int baseAddr;
     30          
     31            // initialize command frame data
     32            for(i=0;i<8;i++)
     33              request.requestFrameData8[i] = 0x00;
     34          
     35            request.requestFrameData8[0] = 0x18; // read request
     36            request.requestFrameData8[1] = 0x00; // statistic counter memory
     37          
     38            /*
     39             * calculate base address in internal memory
     40             *
     41             * NOTE: internal memory is addressed in 8-byte chunks called octets, 
     42             * NOT bytes! Each port has eight octets of RMON data so, for example, 
     43             * port 1 base address is 0x8, port 7 base address is 0x38 (56).
     44             */
     45          
     46            baseAddr = (unsigned int)(((port * 0x8) + octet) & 0x0FFF);
     47          
     48            request.requestFrameData8[2] = (unsigned char) (baseAddr        & 0xff);
     49            request.requestFrameData8[3] = (unsigned char)((baseAddr >>  8) & 0xff);
     50            request.requestFrameData8[4] = (unsigned char)((baseAddr >> 16) & 0xff);
     51          
     52            request.requestFrameData8[5] = 0x01; // number of 8-byte octets
     53            request.requestFrameData8[6] = (unsigned char)((port*8) + octet);
     54          
     55            // poll status reg bit 0
     56            for(i=0;i<10000;i++) {
     57              tmpStatus = zarlinkStatusRead();
     58              if ((tmpStatus & 0x01) != 0)
     59                break;
     60              }
     61          
     62            if ((tmpStatus & 0x01) == 0)
     63              return -1;
     64          
     65            for(i=0;i<8/2;i++)
     66              zarlinkCtrlBuffer1Write(request.requestFrameData16[i]);
     67          
     68            zarlinkCommandWrite(0x01);
     69          
     70            return 0;
     71          }
     72          
     73          static int ctrlClearStats(int port, int octet)
     74          {
     75            int i;
     76            unsigned char tmpStatus;
     77            unsigned int baseAddr;
     78          
     79            // initialize command frame data
     80            for(i=0;i<8;i++)
     81              request.requestFrameData8[i] = 0x00;
     82          
     83            request.requestFrameData8[0] = 0x28; // write request
     84            request.requestFrameData8[1] = 0x00; // statistic counter memory
     85          
     86            /*
     87             * calculate base address in internal memory
     88             *
     89             * NOTE: internal memory is addressed in 8-byte chunks called octets, 
     90             * NOT bytes! Each port has eight octets of RMON data so, for example, 
     91             * port 1 base address is 0x8, port 7 base address is 0x38 (56).
     92             */
     93          
     94            baseAddr = (unsigned int)(((port * 0x8) + octet) & 0x0FFF);
     95          
     96            request.requestFrameData8[2] = (unsigned char) (baseAddr        & 0xff);
     97            request.requestFrameData8[3] = (unsigned char)((baseAddr >>  8) & 0xff);
     98            request.requestFrameData8[4] = (unsigned char)((baseAddr >> 16) & 0xff);
     99          
    100            request.requestFrameData8[5] = 0x01; // number of 8-byte octets
    101            request.requestFrameData8[6] = (unsigned char)((port*8) + octet);
    102          
    103            // poll status reg bit 0
    104            for(i=0;i<10000;i++) {
    105              tmpStatus = zarlinkStatusRead();
    106              if ((tmpStatus & 0x01) != 0)
    107                break;
    108              }
    109          
    110            if ((tmpStatus & 0x01) == 0)
    111              return -1;
    112          
    113            for(i=0;i<8/2;i++)
    114              zarlinkCtrlBuffer1Write(request.requestFrameData16[i]);
    115          
    116            for(i=0;i<8/2;i++)
    117              zarlinkCtrlBuffer1Write((unsigned short)0);
    118          
    119            zarlinkCommandWrite(0x01);
    120          
    121            return 0;
    122          }
    123          
    124          static int ctrlRetrieveStats(unsigned short * pReplyData16)
    125          {
    126            int i;
    127            unsigned char tmpStatus;
    128          
    129            if (pReplyData16 == NULL)
    130              return -1;
    131          
    132          #if 0
    133            // poll status reg bit 2
    134            for(i=0;i<10000;i++) {
    135              tmpStatus = zarlinkStatusRead();
    136              if ((tmpStatus & 0x04) != 0)
    137                break;
    138              }
    139          #else
    140          
    141            //
    142            // NOTE: reading this register clears _all_
    143            // interrupt causes, so a frame rx interrupt
    144            // could be lost here!
    145            //
    146          
    147            // poll interrupt reg bit 2
    148            for(i=0; i<1000; i++) {
    149              tmpStatus = zarlinkInterruptRead();
    150              if ((tmpStatus & 0x04) != 0)
    151                break;
    152              }
    153          
    154          #endif
    155          
    156            if ((tmpStatus & 0x04) != 0){
    157              // retrieve buffer 2
    158              for(i=0;i<40/2;i++) {
    159                pReplyData16[i] = zarlinkCtrlBuffer2Read();
    160                }
    161              zarlinkCommandWrite(0x04);
    162              // zarlinkInterruptWrite(0x04);
    163              // TODO: do checking on this
    164              }
    165            else {
    166              // no reply data buffers to retrieve
    167              return -1;
    168              }
    169          
    170            return 0;
    171          }
    172          
    173          static int ctrlClearPort(int port)
    174          {
    175            int octet;
    176            int retStat = 0;
    177          
    178            for(octet=0;((octet<8) && (retStat == 0)); octet++) {
    179              retStat = ctrlClearStats(port, octet);
    180              }
    181          
    182            return retStat;
    183          }
    184          
    185          static int ctrlClearAll(void)
    186          {
    187            int port;
    188            int retStat = 0;
    189          
    190            for(port=0;((port<10) && (retStat == 0)); port++) {
    191              retStat = ctrlClearPort(port);
    192              }
    193          
    194            return retStat;
    195          }
    196          
    197          static int decodeStats(char *pRawOctetData, int port, int octet)
    198          {
    199            int retVal = -1;
    200          
    201            if (pRawOctetData == NULL)
    202              return retVal;
    203          
    204            if ((port < 0) || (port > 10))
    205              return retVal;
    206          
    207            if ((octet < 0) || (octet > 8))
    208              return retVal;
    209          
    210            /*
    211             * for completed read, the first byte (byte 0) of data, bits[7:4] should be 0b0101 for
    212             * completed read. The frame # (byte 7) should also be examined, and also the 
    213             * address a bytes 3 and 4. The actual data begins at byte 8.
    214             */
    215          
    216            switch(octet) {
    217              case 0:
    218                portStats[port].bytesSent = (*(unsigned int *)pRawOctetData);
    219                pRawOctetData += 4;
    220                portStats[port].unicastFrameSent = ((*(unsigned int *)pRawOctetData) & 0x0fff);
    221                pRawOctetData += 3;
    222                portStats[port].frameSentFail = (unsigned int)*pRawOctetData;
    223                retVal = 0;
    224                break;
    225              case 1:
    226                portStats[port].flowCtrlSent = (*(unsigned short *)pRawOctetData);
    227                pRawOctetData += 2;
    228                portStats[port].nonUnicastFrameSent = (*(unsigned short *)pRawOctetData);
    229                pRawOctetData += 2;
    230                portStats[port].bytesReceived = (*(unsigned int *)pRawOctetData);
    231                retVal = 0;
    232                break;
    233              case 2:
    234                portStats[port].frameReceived = (*(unsigned int *)pRawOctetData);
    235                pRawOctetData += 4;
    236                portStats[port].totalBytesReceived = (*(unsigned int *)pRawOctetData);
    237                retVal = 0;
    238                break;
    239              case 3:
    240                portStats[port].totalFramesReceived = ((*(unsigned int *)pRawOctetData) & 0x0fff);
    241                pRawOctetData += 3;
    242                portStats[port].flowCtrlFramesReceived = (unsigned int)*pRawOctetData;
    243                pRawOctetData += 1;
    244                portStats[port].mcastFramesReceived = (*(unsigned short *)pRawOctetData);
    245                pRawOctetData += 2;
    246                portStats[port].bcastFramesReceived = (*(unsigned short *)pRawOctetData);
    247                retVal = 0;
    248                break;
    249              case 4:
    250                portStats[port].len64Frames = ((*(unsigned int *)pRawOctetData) & 0x0fff);
    251                pRawOctetData += 3;
    252                portStats[port].jabberFrames = (unsigned int)*pRawOctetData;
    253                pRawOctetData += 1;
    254                portStats[port].len65To127Frames = ((*(unsigned int *)pRawOctetData) & 0x0fff);
    255                pRawOctetData += 3;
    256                portStats[port].oversizeFrames = (unsigned int)*pRawOctetData;
    257                retVal = 0;
    258                break;
    259              case 5:
    260                portStats[port].len128To255Frames = (*(unsigned short *)pRawOctetData);
    261                pRawOctetData += 2;
    262                portStats[port].len256To511Frames = (*(unsigned short *)pRawOctetData);
    263                pRawOctetData += 2;
    264                portStats[port].len512To1023Frames = (*(unsigned short *)pRawOctetData);
    265                pRawOctetData += 2;
    266                portStats[port].len1024To1522Frames = (*(unsigned short *)pRawOctetData);
    267                retVal = 0;
    268                break;
    269              case 6:
    270                portStats[port].fragment = (*(unsigned short *)pRawOctetData);
    271                pRawOctetData += 2;
    272                portStats[port].alignError = (unsigned int)*pRawOctetData;
    273                pRawOctetData++;
    274                portStats[port].runtFrames = (unsigned int)*pRawOctetData;
    275                pRawOctetData++;
    276                portStats[port].crcErrors = (*(unsigned short *)pRawOctetData);
    277                pRawOctetData += 2;
    278                portStats[port].shortEvent = (*(unsigned short *)pRawOctetData);
    279                retVal = 0;
    280                break;
    281              case 7:
    282                portStats[port].collision = (*(unsigned short *)pRawOctetData);
    283                pRawOctetData += 2;
    284                portStats[port].droppedFrames = (*(unsigned short *)pRawOctetData);
    285                pRawOctetData += 2;
    286                portStats[port].filteringCounter = (*(unsigned short *)pRawOctetData);
    287                pRawOctetData += 2;
    288                portStats[port].delayExceedDiscardCounter = (unsigned int)*pRawOctetData;
    289                pRawOctetData++;
    290                portStats[port].lateCollision = (unsigned int)*pRawOctetData;
    291                retVal = 0;
    292                break;
    293              default:
    294                break;
    295              }
    296          
    297            return retVal;
    298          }
    299          
    300          int zarlinkRmonGet(int port)
    301          {
    302            int i;
    303            int retVal = 0;
    304          
    305            for(i=0; ((i<8) && (retVal == 0)); i++) {
    306          
    307              retVal = ctrlRequestStats(port, i);
    308              if (retVal != 0) {
    309                 return -1;
    310                }
    311          
    312              retVal = ctrlRetrieveStats(replyData16);
    313              if (retVal != 0) {
    314                return -2;
    315                }
    316          
    317              // TODO: check frame sequence number from returned data
    318          
    319              retVal = decodeStats((unsigned char *)(&(replyData16[4])), port, i);
                                          ^
Warning[Pe167]: argument of type "unsigned char *" is incompatible with
          parameter of type "char *"
    320              if (retVal != 0) {
    321                return -3;
    322                }
    323              }
    324          
    325            return 0;
    326          }
    327          
    328          static int statsHandler(int argc, char *argv[], int flags)
    329          {
    330            int retVal = -1;
    331            int bufLen;
    332            char * pOutBuf;
    333            int port;
    334          
    335            if (argc < 2)
    336              return retVal;
    337          
    338            pOutBuf = clicharGetOutputBuffer(&bufLen);
    339            port = (int)strtol(argv[1], (char **)NULL, 10);
    340            retVal = zarlinkRmonGet(port);
    341          
    342            if (retVal == 0) {
    343              sprintf(pOutBuf, "--- Zarlink port stats for port [%d] ---\r\n", port);
    344              clicharSendOutputBuffer(pOutBuf, bufLen);    
    345              
    346              sprintf(pOutBuf, "  TX: bytes[%u]  unicastFrame[%u]  frameTxFail[%u]\r\n",
    347                portStats[port].bytesSent, 
    348                portStats[port].unicastFrameSent, 
    349                portStats[port].frameSentFail);
    350              clicharSendOutputBuffer(pOutBuf, bufLen);    
    351          
    352              sprintf(pOutBuf, "  RX: bytes[%u]  frames[%u]  totalBytes[%u]  totalFrames[%u]\r\n",
    353                portStats[port].bytesReceived, 
    354                portStats[port].frameReceived, 
    355                portStats[port].totalBytesReceived, 
    356                portStats[port].totalFramesReceived);
    357              clicharSendOutputBuffer(pOutBuf, bufLen);    
    358          
    359              sprintf(pOutBuf, " ERR: align[%u]  runt[%u]  crc[%u]  shortEvent[%u]\r\n",
    360                portStats[port].alignError, 
    361                portStats[port].runtFrames, 
    362                portStats[port].crcErrors, 
    363                portStats[port].shortEvent);
    364              clicharSendOutputBuffer(pOutBuf, bufLen);    
    365          
    366              sprintf(pOutBuf, "FLOW: flowCtrlFramesRecv[%u]  flowCtrlSent[%u]\r\n",
    367                portStats[port].flowCtrlFramesReceived,
    368                portStats[port].flowCtrlSent);
    369              clicharSendOutputBuffer(pOutBuf, bufLen);    
    370          
    371              sprintf(pOutBuf, " PKT: len64[%u]  len65-127[%u]  jabber[%u]  oversize[%u]\r\n",
    372                portStats[port].len64Frames,
    373                portStats[port].len65To127Frames,
    374                portStats[port].jabberFrames,
    375                portStats[port].oversizeFrames);
    376              clicharSendOutputBuffer(pOutBuf, bufLen);    
    377                
    378              sprintf(pOutBuf, " LEN: 128-255[%u]  256-511[%u]  512-1023[%u]  1024-1522[%u]\r\n",
    379                portStats[port].len128To255Frames,
    380                portStats[port].len256To511Frames,
    381                portStats[port].len512To1023Frames,
    382                portStats[port].len1024To1522Frames);
    383              clicharSendOutputBuffer(pOutBuf, bufLen);    
    384          
    385              sprintf(pOutBuf, "OOPS: fragment[%u]  dropped[%u]  filterCount[%u]  delayExceedDiscard[%u]\r\n",
    386                portStats[port].fragment,
    387                portStats[port].droppedFrames,
    388                portStats[port].filteringCounter,
    389                portStats[port].delayExceedDiscardCounter);
    390              clicharSendOutputBuffer(pOutBuf, bufLen);    
    391              }
    392          
    393            return retVal;
    394          }
    395          
    396          static void clearLocalStatsPort(int port)
    397          {
    398          
    399            if ((port < 0) || (port > 9))
    400              return;
    401          
    402            portStats[port].bytesSent = 0;
    403            portStats[port].unicastFrameSent = 0;
    404            portStats[port].frameSentFail = 0;
    405            portStats[port].flowCtrlSent = 0;
    406            portStats[port].nonUnicastFrameSent = 0;
    407            portStats[port].bytesReceived = 0;
    408            portStats[port].frameReceived = 0;
    409            portStats[port].totalBytesReceived = 0;
    410            portStats[port].totalFramesReceived = 0;
    411            portStats[port].flowCtrlFramesReceived = 0;
    412            portStats[port].mcastFramesReceived = 0;
    413            portStats[port].bcastFramesReceived = 0;
    414            portStats[port].len64Frames = 0;
    415            portStats[port].jabberFrames = 0;
    416            portStats[port].len65To127Frames = 0;
    417            portStats[port].oversizeFrames = 0;
    418            portStats[port].len128To255Frames = 0;
    419            portStats[port].len256To511Frames = 0;
    420            portStats[port].len512To1023Frames = 0;
    421            portStats[port].len1024To1522Frames = 0;
    422            portStats[port].fragment = 0;
    423            portStats[port].alignError = 0;
    424            portStats[port].runtFrames = 0;
    425            portStats[port].crcErrors = 0;
    426            portStats[port].shortEvent = 0;
    427            portStats[port].collision = 0;
    428            portStats[port].droppedFrames = 0;
    429            portStats[port].filteringCounter = 0;
    430            portStats[port].delayExceedDiscardCounter = 0;
    431            portStats[port].lateCollision = 0;
    432          
    433          }
    434          
    435          static void clearLocalStatsAll(void)
    436          {
    437            int i;
    438          
    439            for (i=0;i<10;i++) {
    440              clearLocalStatsPort(i);
    441              }
    442          }
    443          
    444          static int clearHandler(int argc, char *argv[], int flags)
    445          {
    446            int retVal = -1;
    447            int bufLen;
                       ^
Warning[Pe177]: variable "bufLen" was declared but never referenced
    448            char * pOutBuf;
                          ^
Warning[Pe177]: variable "pOutBuf" was declared but never referenced
    449            int port;
    450          
    451            if (argc == 2) {
    452              port = (int)strtol(argv[1], (char **)NULL, 10);
    453              clearLocalStatsPort(port);
    454              retVal = ctrlClearPort(port);
    455              }
    456            else if (argc == 1) {
    457              clearLocalStatsAll();
    458              retVal = ctrlClearAll();
    459              }
    460          
    461            return retVal;
    462          }
    463          
    464          
    465          int zarlinkRmonInit(void)
    466          {
    467            cliRegisterCommand("stats", statsHandler, "stats [port] - retrieve port statistics from switch");
    468            cliRegisterCommand("clear", clearHandler, "clear [port] - clear port statistics");
    469            
    470            clearLocalStatsAll();
    471            return ctrlClearAll();
    472          }
    473          
    474          #endif
    475          

   Maximum stack usage in bytes:

     Function            CSTACK
     --------            ------
     clearHandler           32
     clearLocalStatsAll      8
     clearLocalStatsPort     0
     ctrlClearAll           12
     ctrlClearPort          16
     ctrlClearStats         24
     ctrlRequestStats       24
     ctrlRetrieveStats      16
     decodeStats             4
     statsHandler           40
     zarlinkRmonGet         16
     zarlinkRmonInit         4


   Segment part sizes:

     Function/Label                 Bytes
     --------------                 -----
     portStats                      1200
     request                           8
     replyData16                      40
     ctrlRequestStats                316
     ctrlClearStats                  348
     ctrlRetrieveStats               152
     ctrlClearPort                    72
     ctrlClearAll                     64
     decodeStats                    1060
     zarlinkRmonGet                  160
     statsHandler                    784
     clearLocalStatsPort             620
     clearLocalStatsAll               40
     clearHandler                    112
     zarlinkRmonInit                  72
     ??DataTable17                     4
     ??DataTable102                    4
     ?<Constant "--- Zarlink port stat...">
                                      44
     ?<Constant "  TX: bytes[%u]  unic...">
                                      56
     ?<Constant "  RX: bytes[%u]  fram...">
                                      64
     ?<Constant " ERR: align[%u]  runt...">
                                      56
     ?<Constant "FLOW: flowCtrlFramesR...">
                                      52
     ?<Constant " PKT: len64[%u]  len6...">
                                      60
     ?<Constant " LEN: 128-255[%u]  25...">
                                      64
     ?<Constant "OOPS: fragment[%u]  d...">
                                      76
     ?<Constant "stats">               8
     ?<Constant "stats [port] - retrie...">
                                      52
     ?<Constant "clear">               8
     ?<Constant "clear [port] - clear ...">
                                      40
      Others                         132

 
 3 928 bytes in segment CODE
   580 bytes in segment DATA_C
 1 248 bytes in segment DATA_Z
    12 bytes in segment INITTAB
 
 3 808 bytes of CODE  memory (+ 132 bytes shared)
   580 bytes of CONST memory
 1 248 bytes of DATA  memory

Errors: none
Warnings: 3
