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