• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
bm_control_size(void)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 
bm_res_read_proc(char * page,char ** start,off_t off,int count,int * eof,void * data)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 */
bm_init(struct tiwlan_net_dev * drv)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 */
bm_destroy(void)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 */
bm_trace(int loc,unsigned long p1,unsigned long p2)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