xref: /freebsd/sys/dev/bxe/bxe_debug.c (revision 685dc743)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2007-2014 QLogic Corporation. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26  * THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
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
bxe_reg_write8(struct bxe_softc * sc,bus_size_t offset,uint8_t val)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
bxe_reg_write16(struct bxe_softc * sc,bus_size_t offset,uint16_t val)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
bxe_reg_write32(struct bxe_softc * sc,bus_size_t offset,uint32_t val)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
bxe_reg_read8(struct bxe_softc * sc,bus_size_t offset)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
bxe_reg_read16(struct bxe_softc * sc,bus_size_t offset)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
bxe_reg_read32(struct bxe_softc * sc,bus_size_t offset)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
elink_cb_dbg(struct bxe_softc * sc,char * fmt)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
elink_cb_dbg1(struct bxe_softc * sc,char * fmt,uint32_t arg1)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
elink_cb_dbg2(struct bxe_softc * sc,char * fmt,uint32_t arg1,uint32_t arg2)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
elink_cb_dbg3(struct bxe_softc * sc,char * fmt,uint32_t arg1,uint32_t arg2,uint32_t arg3)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
bxe_dump_mem(struct bxe_softc * sc,char * tag,uint8_t * mem,uint32_t len)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
bxe_dump_mbuf_data(struct bxe_softc * sc,char * tag,struct mbuf * m,uint8_t contents)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 
bxe_ddb_usage()288 static void bxe_ddb_usage()
289 {
290     db_printf("Usage: bxe[/hpv] <instance> [<address>]\n");
291 }
292 
DB_COMMAND_FLAGS(bxe,bxe_ddb,CS_OWN)293 DB_COMMAND_FLAGS(bxe, bxe_ddb, CS_OWN)
294 {
295     char if_xname[IFNAMSIZ];
296     if_t ifp = NULL;
297     struct bxe_softc *sc;
298     db_expr_t next_arg;
299     int index;
300     int tok;
301     int mod_phys_addr = FALSE;
302     int mod_virt_addr = FALSE;
303     db_addr_t addr;
304 
305     tok = db_read_token();
306     if (tok == tSLASH) {
307         tok = db_read_token();
308         if (tok != tIDENT) {
309             db_printf("ERROR: bad modifier\n");
310             bxe_ddb_usage();
311             goto bxe_ddb_done;
312         }
313         if (strcmp(db_tok_string, "h") == 0) {
314             bxe_ddb_usage();
315             goto bxe_ddb_done;
316         } else if (strcmp(db_tok_string, "p") == 0) {
317             mod_phys_addr = TRUE;
318         } else if (strcmp(db_tok_string, "v") == 0) {
319             mod_virt_addr = TRUE;
320         }
321     } else {
322         db_unread_token(tok);
323     }
324 
325     if (!db_expression((db_expr_t *)&index)) {
326         db_printf("ERROR: bxe index missing\n");
327         bxe_ddb_usage();
328         goto bxe_ddb_done;
329     }
330 
331     snprintf(if_xname, sizeof(if_xname), "bxe%d", index);
332     if ((ifp = ifunit_ref(if_xname)) == NULL) /* XXX */
333     {
334         db_printf("ERROR: Invalid interface %s\n", if_xname);
335         goto bxe_ddb_done;
336     }
337 
338     sc = (struct bxe_softc *)if_getsoftc(ifp);
339     db_printf("ifnet=%p (%s)\n", ifp, if_xname);
340     db_printf("softc=%p\n", sc);
341     db_printf("  dev=%p\n", sc->dev);
342     db_printf("  BDF=%d:%d:%d\n",
343               sc->pcie_bus, sc->pcie_device, sc->pcie_func);
344 
345     if (mod_phys_addr || mod_virt_addr) {
346         if (!db_expression((db_addr_t *)&addr)) {
347             db_printf("ERROR: Invalid address\n");
348             bxe_ddb_usage();
349             goto bxe_ddb_done;
350         }
351 
352         db_printf("addr=%p", addr);
353     }
354 
355 bxe_ddb_done:
356 
357     db_flush_lex();
358     if (ifp) if_rele(ifp);
359 }
360 
361 #endif /* DDB */
362 
363