xref: /freebsd/sys/dev/bxe/bxe_debug.c (revision 4d846d26)
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 __FBSDID("$FreeBSD$");
31 
32 #include "bxe.h"
33 
34 #include "ddb/ddb.h"
35 #include "ddb/db_sym.h"
36 #include "ddb/db_lex.h"
37 
38 #ifdef BXE_REG_NO_INLINE
39 
40 /*
41  * Debug versions of the 8/16/32 bit OS register read/write functions to
42  * capture/display values read/written from/to the controller.
43  */
44 
45 void
46 bxe_reg_write8(struct bxe_softc *sc, bus_size_t offset, uint8_t val)
47 {
48     BLOGD(sc, DBG_REGS, "offset=0x%08lx val=0x%02x\n", offset, val);
49     bus_space_write_1(sc->bar[BAR0].tag,
50                       sc->bar[BAR0].handle,
51                       offset,
52                       val);
53 }
54 
55 void
56 bxe_reg_write16(struct bxe_softc *sc, bus_size_t offset, uint16_t val)
57 {
58     if ((offset % 2) != 0) {
59         BLOGD(sc, DBG_REGS, "Unaligned 16-bit write to 0x%08lx\n", offset);
60     }
61 
62     BLOGD(sc, DBG_REGS, "offset=0x%08lx val=0x%04x\n", offset, val);
63     bus_space_write_2(sc->bar[BAR0].tag,
64                       sc->bar[BAR0].handle,
65                       offset,
66                       val);
67 }
68 
69 void
70 bxe_reg_write32(struct bxe_softc *sc, bus_size_t offset, uint32_t val)
71 {
72     if ((offset % 4) != 0) {
73         BLOGD(sc, DBG_REGS, "Unaligned 32-bit write to 0x%08lx\n", offset);
74     }
75 
76     BLOGD(sc, DBG_REGS, "offset=0x%08lx val=0x%08x\n", offset, val);
77     bus_space_write_4(sc->bar[BAR0].tag,
78                       sc->bar[BAR0].handle,
79                       offset,
80                       val);
81 }
82 
83 uint8_t
84 bxe_reg_read8(struct bxe_softc *sc, bus_size_t offset)
85 {
86     uint8_t val;
87 
88     val = bus_space_read_1(sc->bar[BAR0].tag,
89                            sc->bar[BAR0].handle,
90                            offset);
91     BLOGD(sc, DBG_REGS, "offset=0x%08lx val=0x%02x\n", offset, val);
92 
93     return (val);
94 }
95 
96 uint16_t
97 bxe_reg_read16(struct bxe_softc *sc, bus_size_t offset)
98 {
99     uint16_t val;
100 
101     if ((offset % 2) != 0) {
102         BLOGD(sc, DBG_REGS, "Unaligned 16-bit read from 0x%08lx\n", offset);
103     }
104 
105     val = bus_space_read_2(sc->bar[BAR0].tag,
106                            sc->bar[BAR0].handle,
107                            offset);
108     BLOGD(sc, DBG_REGS, "offset=0x%08lx val=0x%08x\n", offset, val);
109 
110     return (val);
111 }
112 
113 uint32_t
114 bxe_reg_read32(struct bxe_softc *sc, bus_size_t offset)
115 {
116     uint32_t val;
117 
118     if ((offset % 4) != 0) {
119         BLOGD(sc, DBG_REGS, "Unaligned 32-bit read from 0x%08lx\n", offset);
120     }
121 
122     val = bus_space_read_4(sc->bar[BAR0].tag,
123                            sc->bar[BAR0].handle,
124                            offset);
125     BLOGD(sc, DBG_REGS, "offset=0x%08lx val=0x%08x\n", offset, val);
126 
127     return (val);
128 }
129 
130 #endif /* BXE_REG_NO_INLINE */
131 
132 #ifdef ELINK_DEBUG
133 
134 void
135 elink_cb_dbg(struct bxe_softc *sc,
136              char             *fmt)
137 {
138     char buf[128];
139     if (__predict_false(sc->debug & DBG_PHY)) {
140         snprintf(buf, sizeof(buf), "ELINK: %s", fmt);
141         device_printf(sc->dev, "%s", buf);
142     }
143 }
144 
145 void
146 elink_cb_dbg1(struct bxe_softc *sc,
147               char             *fmt,
148               uint32_t         arg1)
149 {
150     char tmp[128], buf[128];
151     if (__predict_false(sc->debug & DBG_PHY)) {
152         snprintf(tmp, sizeof(tmp), "ELINK: %s", fmt);
153         snprintf(buf, sizeof(buf), tmp, arg1);
154         device_printf(sc->dev, "%s", buf);
155     }
156 }
157 
158 void
159 elink_cb_dbg2(struct bxe_softc *sc,
160               char             *fmt,
161               uint32_t         arg1,
162               uint32_t         arg2)
163 {
164     char tmp[128], buf[128];
165     if (__predict_false(sc->debug & DBG_PHY)) {
166         snprintf(tmp, sizeof(tmp), "ELINK: %s", fmt);
167         snprintf(buf, sizeof(buf), tmp, arg1, arg2);
168         device_printf(sc->dev, "%s", buf);
169     }
170 }
171 
172 void
173 elink_cb_dbg3(struct bxe_softc *sc,
174               char             *fmt,
175               uint32_t         arg1,
176               uint32_t         arg2,
177               uint32_t         arg3)
178 {
179     char tmp[128], buf[128];
180     if (__predict_false(sc->debug & DBG_PHY)) {
181         snprintf(tmp, sizeof(tmp), "ELINK: %s", fmt);
182         snprintf(buf, sizeof(buf), tmp, arg1, arg2, arg3);
183         device_printf(sc->dev, "%s", buf);
184     }
185 }
186 
187 #endif /* ELINK_DEBUG */
188 
189 extern struct mtx bxe_prev_mtx;
190 
191 void
192 bxe_dump_mem(struct bxe_softc *sc,
193              char             *tag,
194              uint8_t          *mem,
195              uint32_t         len)
196 {
197     char buf[256];
198     char c[32];
199     int  xx;
200 
201     mtx_lock(&bxe_prev_mtx);
202 
203     BLOGI(sc, "++++++++++++ %s\n", tag);
204     strcpy(buf, "** 000: ");
205 
206     for (xx = 0; xx < len; xx++)
207     {
208         if ((xx != 0) && (xx % 16 == 0))
209         {
210             BLOGI(sc, "%s\n", buf);
211             strcpy(buf, "** ");
212             snprintf(c, sizeof(c), "%03x", xx);
213             strcat(buf, c);
214             strcat(buf, ": ");
215         }
216 
217         snprintf(c, sizeof(c), "%02x ", *mem);
218         strcat(buf, c);
219 
220         mem++;
221     }
222 
223     BLOGI(sc, "%s\n", buf);
224     BLOGI(sc, "------------ %s\n", tag);
225 
226     mtx_unlock(&bxe_prev_mtx);
227 }
228 
229 void
230 bxe_dump_mbuf_data(struct bxe_softc *sc,
231                    char             *tag,
232                    struct mbuf      *m,
233                    uint8_t          contents)
234 {
235     char buf[256];
236     char c[32];
237     uint8_t *memp;
238     int i, xx = 0;
239 
240     mtx_lock(&bxe_prev_mtx);
241 
242     BLOGI(sc, "++++++++++++ %s\n", tag);
243 
244     while (m)
245     {
246         memp = m->m_data;
247         strcpy(buf, "** > ");
248         snprintf(c, sizeof(c), "%03x", xx);
249         strcat(buf, c);
250         strcat(buf, ": ");
251 
252         if (contents)
253         {
254             for (i = 0; i < m->m_len; i++)
255             {
256                 if ((xx != 0) && (xx % 16 == 0))
257                 {
258                     BLOGI(sc, "%s\n", buf);
259                     strcpy(buf, "**   ");
260                     snprintf(c, sizeof(c), "%03x", xx);
261                     strcat(buf, c);
262                     strcat(buf, ": ");
263                 }
264 
265                 snprintf(c, sizeof(c), "%02x ", *memp);
266                 strcat(buf, c);
267 
268                 memp++;
269                 xx++;
270             }
271         }
272         else
273         {
274             snprintf(c, sizeof(c), "%d", m->m_len);
275             strcat(buf, c);
276             xx += m->m_len;
277         }
278 
279         BLOGI(sc, "%s\n", buf);
280         m = m->m_next;
281     }
282 
283     BLOGI(sc, "------------ %s\n", tag);
284 
285     mtx_unlock(&bxe_prev_mtx);
286 }
287 
288 #ifdef DDB
289 
290 static void bxe_ddb_usage()
291 {
292     db_printf("Usage: bxe[/hpv] <instance> [<address>]\n");
293 }
294 
295 DB_COMMAND_FLAGS(bxe, bxe_ddb, CS_OWN)
296 {
297     char if_xname[IFNAMSIZ];
298     if_t ifp = NULL;
299     struct bxe_softc *sc;
300     db_expr_t next_arg;
301     int index;
302     int tok;
303     int mod_phys_addr = FALSE;
304     int mod_virt_addr = FALSE;
305     db_addr_t addr;
306 
307     tok = db_read_token();
308     if (tok == tSLASH) {
309         tok = db_read_token();
310         if (tok != tIDENT) {
311             db_printf("ERROR: bad modifier\n");
312             bxe_ddb_usage();
313             goto bxe_ddb_done;
314         }
315         if (strcmp(db_tok_string, "h") == 0) {
316             bxe_ddb_usage();
317             goto bxe_ddb_done;
318         } else if (strcmp(db_tok_string, "p") == 0) {
319             mod_phys_addr = TRUE;
320         } else if (strcmp(db_tok_string, "v") == 0) {
321             mod_virt_addr = TRUE;
322         }
323     } else {
324         db_unread_token(tok);
325     }
326 
327     if (!db_expression((db_expr_t *)&index)) {
328         db_printf("ERROR: bxe index missing\n");
329         bxe_ddb_usage();
330         goto bxe_ddb_done;
331     }
332 
333     snprintf(if_xname, sizeof(if_xname), "bxe%d", index);
334     if ((ifp = ifunit_ref(if_xname)) == NULL) /* XXX */
335     {
336         db_printf("ERROR: Invalid interface %s\n", if_xname);
337         goto bxe_ddb_done;
338     }
339 
340     sc = (struct bxe_softc *)if_getsoftc(ifp);
341     db_printf("ifnet=%p (%s)\n", ifp, if_xname);
342     db_printf("softc=%p\n", sc);
343     db_printf("  dev=%p\n", sc->dev);
344     db_printf("  BDF=%d:%d:%d\n",
345               sc->pcie_bus, sc->pcie_device, sc->pcie_func);
346 
347     if (mod_phys_addr || mod_virt_addr) {
348         if (!db_expression((db_addr_t *)&addr)) {
349             db_printf("ERROR: Invalid address\n");
350             bxe_ddb_usage();
351             goto bxe_ddb_done;
352         }
353 
354         db_printf("addr=%p", addr);
355     }
356 
357 bxe_ddb_done:
358 
359     db_flush_lex();
360     if (ifp) if_rele(ifp);
361 }
362 
363 #endif /* DDB */
364 
365