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