Home | History | Annotate | Download | only in src
      1 /****************************************************************************
      2 **+-----------------------------------------------------------------------+**
      3 **|                                                                       |**
      4 **| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved.      |**
      5 **| All rights reserved.                                                  |**
      6 **|                                                                       |**
      7 **| Redistribution and use in source and binary forms, with or without    |**
      8 **| modification, are permitted provided that the following conditions    |**
      9 **| are met:                                                              |**
     10 **|                                                                       |**
     11 **|  * Redistributions of source code must retain the above copyright     |**
     12 **|    notice, this list of conditions and the following disclaimer.      |**
     13 **|  * Redistributions in binary form must reproduce the above copyright  |**
     14 **|    notice, this list of conditions and the following disclaimer in    |**
     15 **|    the documentation and/or other materials provided with the         |**
     16 **|    distribution.                                                      |**
     17 **|  * Neither the name Texas Instruments nor the names of its            |**
     18 **|    contributors may be used to endorse or promote products derived    |**
     19 **|    from this software without specific prior written permission.      |**
     20 **|                                                                       |**
     21 **| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |**
     22 **| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |**
     23 **| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
     24 **| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |**
     25 **| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
     26 **| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |**
     27 **| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
     28 **| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
     29 **| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |**
     30 **| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
     31 **| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |**
     32 **|                                                                       |**
     33 **+-----------------------------------------------------------------------+**
     34 ****************************************************************************/
     35 
     36 
     37 #include <linux/config.h>
     38 #include <linux/module.h>
     39 #include <linux/errno.h>
     40 #include <linux/string.h>
     41 #include <linux/proc_fs.h>
     42 
     43 #include "osApi.h"
     44 #include "esta_drv.h"
     45 #include "bmtrace.h"
     46 
     47 #define OS_READ_REG(drv,reg,p_val)    \
     48    os_hwReadMemRegisterUINT32(drv, (UINT32 *)((unsigned long)drv->acx_reg.va + reg), p_val)
     49 
     50 typedef struct {
     51       unsigned long loc;/* trace entry identification */
     52       unsigned long ts;/* Timestamp */
     53       unsigned long p1; /* Parameter 1 */
     54       unsigned long p2; /* Parameter 2 */
     55 } bm_entry_t;
     56 
     57 typedef struct {
     58       int pos;
     59       int count;
     60       int print_pos;
     61       int nusers;
     62       unsigned long self_delay;
     63       tiwlan_net_dev_t *drv;
     64       bm_entry_t entry[1]; /* Array of entries */
     65 } bm_control_t;
     66 
     67 static bm_control_t *bm_control;
     68 
     69 static inline int bm_control_size(void)
     70 {
     71    return offsetof(bm_control_t, entry) + sizeof(bm_entry_t)*BM_NUM_ENTRIES;
     72 }
     73 
     74 static int bm_res_read_proc(char *page, char **start, off_t off,
     75 			    int count, int *eof, void *data)
     76 {
     77    int i;
     78    int len=0;
     79    int limit=count-80;
     80    int entry_count;
     81    unsigned long prev=0;
     82    int print_pos;
     83 
     84    print_pos = bm_control->print_pos++; /* It will disable tracing as well */
     85 
     86    entry_count = (bm_control->count > BM_NUM_ENTRIES) ? BM_NUM_ENTRIES : bm_control->count;
     87 
     88    /* Skip off entries */
     89    if ( print_pos >= entry_count) /* paranoid */
     90    {
     91       bm_control->pos = bm_control->count = bm_control->print_pos = 0;
     92       *eof = 1;
     93       return 0;
     94    }
     95 
     96    if (!off)
     97    {
     98       len = sprintf(page, "Events stored: %u   discarded: %u\n",
     99 		    entry_count, bm_control->count-entry_count);
    100       len += sprintf(page+len, "loc delta      ts         p1         p2\n");
    101    }
    102 
    103    /* Initial index */
    104    if (bm_control->count > BM_NUM_ENTRIES)
    105       i = (bm_control->pos+print_pos-1)%BM_NUM_ENTRIES;
    106    else
    107       i = bm_control->print_pos-1;
    108 
    109    for(; (print_pos<entry_count) && (len<=limit); print_pos++)
    110    {
    111       bm_entry_t *bme= &bm_control->entry[i];
    112       len += sprintf(page+len,
    113 		     "%-3lu %-10lu %-10lu %-10lu %-10lu\n",
    114 		     bme->loc,
    115 		     ((bme->ts-prev)>bm_control->self_delay)?bme->ts-prev-bm_control->self_delay:0,
    116 		     bme->ts,
    117 		     bme->p1, bme->p2);
    118       prev = bme->ts;
    119       ++i;
    120       i %= BM_NUM_ENTRIES;
    121    }
    122    if (print_pos >= entry_count)
    123    {
    124       *eof = 1;
    125       bm_control->pos = bm_control->count = bm_control->print_pos = 0;
    126    }
    127    else
    128       bm_control->print_pos = print_pos;
    129    return len;
    130 }
    131 
    132 
    133 /* Initialization */
    134 int bm_init(struct tiwlan_net_dev *drv)
    135 {
    136    if (bm_control)
    137    {
    138       ++bm_control->nusers;
    139       return 0;
    140    }
    141    bm_control = (bm_control_t *)kmalloc(bm_control_size(), GFP_KERNEL);
    142    if (!bm_control)
    143       return -ENOMEM;
    144    memset(bm_control, 0, offsetof(bm_control_t, entry) + sizeof(bm_entry_t)*BM_NUM_ENTRIES);
    145    bm_control->nusers = 1;
    146    bm_control->drv = drv;
    147 
    148    create_proc_read_entry("bmtrace", 0, NULL, bm_res_read_proc, NULL);
    149    /* Measure self-delay */
    150    bm_trace(0, 0, 0);
    151    bm_trace(0, 0, 0);
    152    bm_control->self_delay = bm_control->entry[1].ts - bm_control->entry[0].ts;
    153    bm_control->pos = bm_control->count = 0;
    154    print_info("%s: self_delay=%lu\n", __FUNCTION__, bm_control->self_delay);
    155    return 0;
    156 }
    157 
    158 /* De-initialization */
    159 void bm_destroy(void)
    160 {
    161    if (--bm_control->nusers)
    162       return;
    163    remove_proc_entry("bmtrace", NULL);
    164    kfree( bm_control );
    165 }
    166 
    167 
    168 /* Add trace entry. not safe, but will do */
    169 void bm_trace(int loc, unsigned long p1, unsigned long p2)
    170 {
    171    int pos;
    172    if (!bm_control || bm_control->print_pos)
    173       return;
    174    pos = bm_control->pos;
    175    bm_control->pos = (pos+1) % BM_NUM_ENTRIES;
    176    ++bm_control->count;
    177 
    178    bm_control->entry[pos].ts = os_timeStampUs(NULL);
    179    bm_control->entry[pos].loc= loc;
    180    bm_control->entry[pos].p1 = p1;
    181    bm_control->entry[pos].p2 = p2;
    182 }
    183 
    184