xref: /freebsd/sys/dev/bxe/bxe_debug.c (revision fcb560670601b2a4d87bb31d7531c8dcc37ee71b)
1 /*-
2  * Copyright (c) 2007-2014 QLogic Corporation. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24  * THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 #include "bxe.h"
31 
32 #include "ddb/ddb.h"
33 #include "ddb/db_sym.h"
34 #include "ddb/db_lex.h"
35 
36 #ifdef BXE_REG_NO_INLINE
37 
38 /*
39  * Debug versions of the 8/16/32 bit OS register read/write functions to
40  * capture/display values read/written from/to the controller.
41  */
42 
43 void
44 bxe_reg_write8(struct bxe_softc *sc, bus_size_t offset, uint8_t val)
45 {
46     BLOGD(sc, DBG_REGS, "offset=0x%08lx val=0x%02x\n", offset, val);
47     bus_space_write_1(sc->bar[BAR0].tag,
48                       sc->bar[BAR0].handle,
49                       offset,
50                       val);
51 }
52 
53 void
54 bxe_reg_write16(struct bxe_softc *sc, bus_size_t offset, uint16_t val)
55 {
56     if ((offset % 2) != 0) {
57         BLOGD(sc, DBG_REGS, "Unaligned 16-bit write to 0x%08lx\n", offset);
58     }
59 
60     BLOGD(sc, DBG_REGS, "offset=0x%08lx val=0x%04x\n", offset, val);
61     bus_space_write_2(sc->bar[BAR0].tag,
62                       sc->bar[BAR0].handle,
63                       offset,
64                       val);
65 }
66 
67 void
68 bxe_reg_write32(struct bxe_softc *sc, bus_size_t offset, uint32_t val)
69 {
70     if ((offset % 4) != 0) {
71         BLOGD(sc, DBG_REGS, "Unaligned 32-bit write to 0x%08lx\n", offset);
72     }
73 
74     BLOGD(sc, DBG_REGS, "offset=0x%08lx val=0x%08x\n", offset, val);
75     bus_space_write_4(sc->bar[BAR0].tag,
76                       sc->bar[BAR0].handle,
77                       offset,
78                       val);
79 }
80 
81 uint8_t
82 bxe_reg_read8(struct bxe_softc *sc, bus_size_t offset)
83 {
84     uint8_t val;
85 
86     val = bus_space_read_1(sc->bar[BAR0].tag,
87                            sc->bar[BAR0].handle,
88                            offset);
89     BLOGD(sc, DBG_REGS, "offset=0x%08lx val=0x%02x\n", offset, val);
90 
91     return (val);
92 }
93 
94 uint16_t
95 bxe_reg_read16(struct bxe_softc *sc, bus_size_t offset)
96 {
97     uint16_t val;
98 
99     if ((offset % 2) != 0) {
100         BLOGD(sc, DBG_REGS, "Unaligned 16-bit read from 0x%08lx\n", offset);
101     }
102 
103     val = bus_space_read_2(sc->bar[BAR0].tag,
104                            sc->bar[BAR0].handle,
105                            offset);
106     BLOGD(sc, DBG_REGS, "offset=0x%08lx val=0x%08x\n", offset, val);
107 
108     return (val);
109 }
110 
111 uint32_t
112 bxe_reg_read32(struct bxe_softc *sc, bus_size_t offset)
113 {
114     uint32_t val;
115 
116     if ((offset % 4) != 0) {
117         BLOGD(sc, DBG_REGS, "Unaligned 32-bit read from 0x%08lx\n", offset);
118     }
119 
120     val = bus_space_read_4(sc->bar[BAR0].tag,
121                            sc->bar[BAR0].handle,
122                            offset);
123     BLOGD(sc, DBG_REGS, "offset=0x%08lx val=0x%08x\n", offset, val);
124 
125     return (val);
126 }
127 
128 #endif /* BXE_REG_NO_INLINE */
129 
130 #ifdef ELINK_DEBUG
131 
132 void
133 elink_cb_dbg(struct bxe_softc *sc,
134              char             *fmt)
135 {
136     char buf[128];
137     if (__predict_false(sc->debug & DBG_PHY)) {
138         snprintf(buf, sizeof(buf), "ELINK: %s", fmt);
139         device_printf(sc->dev, "%s", buf);
140     }
141 }
142 
143 void
144 elink_cb_dbg1(struct bxe_softc *sc,
145               char             *fmt,
146               uint32_t         arg1)
147 {
148     char tmp[128], buf[128];
149     if (__predict_false(sc->debug & DBG_PHY)) {
150         snprintf(tmp, sizeof(tmp), "ELINK: %s", fmt);
151         snprintf(buf, sizeof(buf), tmp, arg1);
152         device_printf(sc->dev, "%s", buf);
153     }
154 }
155 
156 void
157 elink_cb_dbg2(struct bxe_softc *sc,
158               char             *fmt,
159               uint32_t         arg1,
160               uint32_t         arg2)
161 {
162     char tmp[128], buf[128];
163     if (__predict_false(sc->debug & DBG_PHY)) {
164         snprintf(tmp, sizeof(tmp), "ELINK: %s", fmt);
165         snprintf(buf, sizeof(buf), tmp, arg1, arg2);
166         device_printf(sc->dev, "%s", buf);
167     }
168 }
169 
170 void
171 elink_cb_dbg3(struct bxe_softc *sc,
172               char             *fmt,
173               uint32_t         arg1,
174               uint32_t         arg2,
175               uint32_t         arg3)
176 {
177     char tmp[128], buf[128];
178     if (__predict_false(sc->debug & DBG_PHY)) {
179         snprintf(tmp, sizeof(tmp), "ELINK: %s", fmt);
180         snprintf(buf, sizeof(buf), tmp, arg1, arg2, arg3);
181         device_printf(sc->dev, "%s", buf);
182     }
183 }
184 
185 #endif /* ELINK_DEBUG */
186 
187 extern struct mtx bxe_prev_mtx;
188 
189 void
190 bxe_dump_mem(struct bxe_softc *sc,
191              char             *tag,
192              uint8_t          *mem,
193              uint32_t         len)
194 {
195     char buf[256];
196     char c[32];
197     int  xx;
198 
199     mtx_lock(&bxe_prev_mtx);
200 
201     BLOGI(sc, "++++++++++++ %s\n", tag);
202     strcpy(buf, "** 000: ");
203 
204     for (xx = 0; xx < len; xx++)
205     {
206         if ((xx != 0) && (xx % 16 == 0))
207         {
208             BLOGI(sc, "%s\n", buf);
209             strcpy(buf, "** ");
210             snprintf(c, sizeof(c), "%03x", xx);
211             strcat(buf, c);
212             strcat(buf, ": ");
213         }
214 
215         snprintf(c, sizeof(c), "%02x ", *mem);
216         strcat(buf, c);
217 
218         mem++;
219     }
220 
221     BLOGI(sc, "%s\n", buf);
222     BLOGI(sc, "------------ %s\n", tag);
223 
224     mtx_unlock(&bxe_prev_mtx);
225 }
226 
227 void
228 bxe_dump_mbuf_data(struct bxe_softc *sc,
229                    char             *tag,
230                    struct mbuf      *m,
231                    uint8_t          contents)
232 {
233     char buf[256];
234     char c[32];
235     uint8_t *memp;
236     int i, xx = 0;
237 
238     mtx_lock(&bxe_prev_mtx);
239 
240     BLOGI(sc, "++++++++++++ %s\n", tag);
241 
242     while (m)
243     {
244         memp = m->m_data;
245         strcpy(buf, "** > ");
246         snprintf(c, sizeof(c), "%03x", xx);
247         strcat(buf, c);
248         strcat(buf, ": ");
249 
250         if (contents)
251         {
252             for (i = 0; i < m->m_len; i++)
253             {
254                 if ((xx != 0) && (xx % 16 == 0))
255                 {
256                     BLOGI(sc, "%s\n", buf);
257                     strcpy(buf, "**   ");
258                     snprintf(c, sizeof(c), "%03x", xx);
259                     strcat(buf, c);
260                     strcat(buf, ": ");
261                 }
262 
263                 snprintf(c, sizeof(c), "%02x ", *memp);
264                 strcat(buf, c);
265 
266                 memp++;
267                 xx++;
268             }
269         }
270         else
271         {
272             snprintf(c, sizeof(c), "%d", m->m_len);
273             strcat(buf, c);
274             xx += m->m_len;
275         }
276 
277         BLOGI(sc, "%s\n", buf);
278         m = m->m_next;
279     }
280 
281     BLOGI(sc, "------------ %s\n", tag);
282 
283     mtx_unlock(&bxe_prev_mtx);
284 }
285 
286 #ifdef DDB
287 
288 static void bxe_ddb_usage()
289 {
290     db_printf("Usage: bxe[/hpv] <instance> [<address>]\n");
291 }
292 
293 static db_cmdfcn_t bxe_ddb;
294 _DB_SET(_cmd, bxe, bxe_ddb, db_cmd_table, CS_OWN, NULL);
295 
296 static void bxe_ddb(db_expr_t blah1,
297                     boolean_t blah2,
298                     db_expr_t blah3,
299                     char      *blah4)
300 {
301     char if_xname[IFNAMSIZ];
302     if_t ifp = NULL;
303     struct bxe_softc *sc;
304     db_expr_t next_arg;
305     int index;
306     int tok;
307     int mod_phys_addr = FALSE;
308     int mod_virt_addr = FALSE;
309     db_addr_t addr;
310 
311     tok = db_read_token();
312     if (tok == tSLASH) {
313         tok = db_read_token();
314         if (tok != tIDENT) {
315             db_printf("ERROR: bad modifier\n");
316             bxe_ddb_usage();
317             goto bxe_ddb_done;
318         }
319         if (strcmp(db_tok_string, "h") == 0) {
320             bxe_ddb_usage();
321             goto bxe_ddb_done;
322         } else if (strcmp(db_tok_string, "p") == 0) {
323             mod_phys_addr = TRUE;
324         } else if (strcmp(db_tok_string, "v") == 0) {
325             mod_virt_addr = TRUE;
326         }
327     } else {
328         db_unread_token(tok);
329     }
330 
331     if (!db_expression((db_expr_t *)&index)) {
332         db_printf("ERROR: bxe index missing\n");
333         bxe_ddb_usage();
334         goto bxe_ddb_done;
335     }
336 
337     snprintf(if_xname, sizeof(if_xname), "bxe%d", index);
338     if ((ifp = ifunit_ref(if_xname)) == NULL) /* XXX */
339     {
340         db_printf("ERROR: Invalid interface %s\n", if_xname);
341         goto bxe_ddb_done;
342     }
343 
344     sc = (struct bxe_softc *)if_getsoftc(ifp);
345     db_printf("ifnet=%p (%s)\n", ifp, if_xname);
346     db_printf("softc=%p\n", sc);
347     db_printf("  dev=%p\n", sc->dev);
348     db_printf("  BDF=%d:%d:%d\n",
349               sc->pcie_bus, sc->pcie_device, sc->pcie_func);
350 
351     if (mod_phys_addr || mod_virt_addr) {
352         if (!db_expression((db_addr_t *)&addr)) {
353             db_printf("ERROR: Invalid address\n");
354             bxe_ddb_usage();
355             goto bxe_ddb_done;
356         }
357 
358         db_printf("addr=%p", addr);
359     }
360 
361 bxe_ddb_done:
362 
363     db_flush_lex();
364     if (ifp) if_rele(ifp);
365 }
366 
367 #endif /* DDB */
368 
369