1255736Sdavidch/*- 2255736Sdavidch * Copyright (c) 2007-2013 Broadcom Corporation. All rights reserved. 3255736Sdavidch * 4255736Sdavidch * Eric Davis <edavis@broadcom.com> 5255736Sdavidch * David Christensen <davidch@broadcom.com> 6255736Sdavidch * Gary Zambrano <zambrano@broadcom.com> 7255736Sdavidch * 8255736Sdavidch * Redistribution and use in source and binary forms, with or without 9255736Sdavidch * modification, are permitted provided that the following conditions 10255736Sdavidch * are met: 11255736Sdavidch * 12255736Sdavidch * 1. Redistributions of source code must retain the above copyright 13255736Sdavidch * notice, this list of conditions and the following disclaimer. 14255736Sdavidch * 2. Redistributions in binary form must reproduce the above copyright 15255736Sdavidch * notice, this list of conditions and the following disclaimer in the 16255736Sdavidch * documentation and/or other materials provided with the distribution. 17255736Sdavidch * 3. Neither the name of Broadcom Corporation nor the name of its contributors 18255736Sdavidch * may be used to endorse or promote products derived from this software 19255736Sdavidch * without specific prior written consent. 20255736Sdavidch * 21255736Sdavidch * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS' 22255736Sdavidch * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23255736Sdavidch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24255736Sdavidch * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 25255736Sdavidch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26255736Sdavidch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27255736Sdavidch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28255736Sdavidch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29255736Sdavidch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30255736Sdavidch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 31255736Sdavidch * THE POSSIBILITY OF SUCH DAMAGE. 32255736Sdavidch */ 33255736Sdavidch 34255736Sdavidch#include <sys/cdefs.h> 35255736Sdavidch__FBSDID("$FreeBSD$"); 36255736Sdavidch 37255736Sdavidch#include "bxe.h" 38255736Sdavidch 39255736Sdavidch#include "ddb/ddb.h" 40255736Sdavidch#include "ddb/db_sym.h" 41255736Sdavidch#include "ddb/db_lex.h" 42255736Sdavidch 43255736Sdavidch#ifdef BXE_REG_NO_INLINE 44255736Sdavidch 45255736Sdavidch/* 46255736Sdavidch * Debug versions of the 8/16/32 bit OS register read/write functions to 47255736Sdavidch * capture/display values read/written from/to the controller. 48255736Sdavidch */ 49255736Sdavidch 50255736Sdavidchvoid 51255736Sdavidchbxe_reg_write8(struct bxe_softc *sc, bus_size_t offset, uint8_t val) 52255736Sdavidch{ 53255736Sdavidch BLOGD(sc, DBG_REGS, "offset=0x%08lx val=0x%02x\n", offset, val); 54255736Sdavidch bus_space_write_1(sc->bar[BAR0].tag, 55255736Sdavidch sc->bar[BAR0].handle, 56255736Sdavidch offset, 57255736Sdavidch val); 58255736Sdavidch} 59255736Sdavidch 60255736Sdavidchvoid 61255736Sdavidchbxe_reg_write16(struct bxe_softc *sc, bus_size_t offset, uint16_t val) 62255736Sdavidch{ 63255736Sdavidch if ((offset % 2) != 0) { 64255736Sdavidch BLOGD(sc, DBG_REGS, "Unaligned 16-bit write to 0x%08lx\n", offset); 65255736Sdavidch } 66255736Sdavidch 67255736Sdavidch BLOGD(sc, DBG_REGS, "offset=0x%08lx val=0x%04x\n", offset, val); 68255736Sdavidch bus_space_write_2(sc->bar[BAR0].tag, 69255736Sdavidch sc->bar[BAR0].handle, 70255736Sdavidch offset, 71255736Sdavidch val); 72255736Sdavidch} 73255736Sdavidch 74255736Sdavidchvoid 75255736Sdavidchbxe_reg_write32(struct bxe_softc *sc, bus_size_t offset, uint32_t val) 76255736Sdavidch{ 77255736Sdavidch if ((offset % 4) != 0) { 78255736Sdavidch BLOGD(sc, DBG_REGS, "Unaligned 32-bit write to 0x%08lx\n", offset); 79255736Sdavidch } 80255736Sdavidch 81255736Sdavidch BLOGD(sc, DBG_REGS, "offset=0x%08lx val=0x%08x\n", offset, val); 82255736Sdavidch bus_space_write_4(sc->bar[BAR0].tag, 83255736Sdavidch sc->bar[BAR0].handle, 84255736Sdavidch offset, 85255736Sdavidch val); 86255736Sdavidch} 87255736Sdavidch 88255736Sdavidchuint8_t 89255736Sdavidchbxe_reg_read8(struct bxe_softc *sc, bus_size_t offset) 90255736Sdavidch{ 91255736Sdavidch uint8_t val; 92255736Sdavidch 93255736Sdavidch val = bus_space_read_1(sc->bar[BAR0].tag, 94255736Sdavidch sc->bar[BAR0].handle, 95255736Sdavidch offset); 96255736Sdavidch BLOGD(sc, DBG_REGS, "offset=0x%08lx val=0x%02x\n", offset, val); 97255736Sdavidch 98255736Sdavidch return (val); 99255736Sdavidch} 100255736Sdavidch 101255736Sdavidchuint16_t 102255736Sdavidchbxe_reg_read16(struct bxe_softc *sc, bus_size_t offset) 103255736Sdavidch{ 104255736Sdavidch uint16_t val; 105255736Sdavidch 106255736Sdavidch if ((offset % 2) != 0) { 107255736Sdavidch BLOGD(sc, DBG_REGS, "Unaligned 16-bit read from 0x%08lx\n", offset); 108255736Sdavidch } 109255736Sdavidch 110255736Sdavidch val = bus_space_read_2(sc->bar[BAR0].tag, 111255736Sdavidch sc->bar[BAR0].handle, 112255736Sdavidch offset); 113255736Sdavidch BLOGD(sc, DBG_REGS, "offset=0x%08lx val=0x%08x\n", offset, val); 114255736Sdavidch 115255736Sdavidch return (val); 116255736Sdavidch} 117255736Sdavidch 118255736Sdavidchuint32_t 119255736Sdavidchbxe_reg_read32(struct bxe_softc *sc, bus_size_t offset) 120255736Sdavidch{ 121255736Sdavidch uint32_t val; 122255736Sdavidch 123255736Sdavidch if ((offset % 4) != 0) { 124255736Sdavidch BLOGD(sc, DBG_REGS, "Unaligned 32-bit read from 0x%08lx\n", offset); 125255736Sdavidch } 126255736Sdavidch 127255736Sdavidch val = bus_space_read_4(sc->bar[BAR0].tag, 128255736Sdavidch sc->bar[BAR0].handle, 129255736Sdavidch offset); 130255736Sdavidch BLOGD(sc, DBG_REGS, "offset=0x%08lx val=0x%08x\n", offset, val); 131255736Sdavidch 132255736Sdavidch return (val); 133255736Sdavidch} 134255736Sdavidch 135255736Sdavidch#endif /* BXE_REG_NO_INLINE */ 136255736Sdavidch 137255736Sdavidch#ifdef ELINK_DEBUG 138255736Sdavidch 139255736Sdavidchvoid 140255736Sdavidchelink_cb_dbg(struct bxe_softc *sc, 141255736Sdavidch char *fmt) 142255736Sdavidch{ 143255736Sdavidch char buf[128]; 144255736Sdavidch if (__predict_false(sc->debug & DBG_PHY)) { 145255736Sdavidch snprintf(buf, sizeof(buf), "ELINK: %s", fmt); 146255736Sdavidch device_printf(sc->dev, "%s", buf); 147255736Sdavidch } 148255736Sdavidch} 149255736Sdavidch 150255736Sdavidchvoid 151255736Sdavidchelink_cb_dbg1(struct bxe_softc *sc, 152255736Sdavidch char *fmt, 153255736Sdavidch uint32_t arg1) 154255736Sdavidch{ 155255736Sdavidch char tmp[128], buf[128]; 156255736Sdavidch if (__predict_false(sc->debug & DBG_PHY)) { 157255736Sdavidch snprintf(tmp, sizeof(tmp), "ELINK: %s", fmt); 158255736Sdavidch snprintf(buf, sizeof(buf), tmp, arg1); 159255736Sdavidch device_printf(sc->dev, "%s", buf); 160255736Sdavidch } 161255736Sdavidch} 162255736Sdavidch 163255736Sdavidchvoid 164255736Sdavidchelink_cb_dbg2(struct bxe_softc *sc, 165255736Sdavidch char *fmt, 166255736Sdavidch uint32_t arg1, 167255736Sdavidch uint32_t arg2) 168255736Sdavidch{ 169255736Sdavidch char tmp[128], buf[128]; 170255736Sdavidch if (__predict_false(sc->debug & DBG_PHY)) { 171255736Sdavidch snprintf(tmp, sizeof(tmp), "ELINK: %s", fmt); 172255736Sdavidch snprintf(buf, sizeof(buf), tmp, arg1, arg2); 173255736Sdavidch device_printf(sc->dev, "%s", buf); 174255736Sdavidch } 175255736Sdavidch} 176255736Sdavidch 177255736Sdavidchvoid 178255736Sdavidchelink_cb_dbg3(struct bxe_softc *sc, 179255736Sdavidch char *fmt, 180255736Sdavidch uint32_t arg1, 181255736Sdavidch uint32_t arg2, 182255736Sdavidch uint32_t arg3) 183255736Sdavidch{ 184255736Sdavidch char tmp[128], buf[128]; 185255736Sdavidch if (__predict_false(sc->debug & DBG_PHY)) { 186255736Sdavidch snprintf(tmp, sizeof(tmp), "ELINK: %s", fmt); 187255736Sdavidch snprintf(buf, sizeof(buf), tmp, arg1, arg2, arg3); 188255736Sdavidch device_printf(sc->dev, "%s", buf); 189255736Sdavidch } 190255736Sdavidch} 191255736Sdavidch 192255736Sdavidch#endif /* ELINK_DEBUG */ 193255736Sdavidch 194255736Sdavidchextern struct mtx bxe_prev_mtx; 195255736Sdavidch 196255736Sdavidchvoid 197255736Sdavidchbxe_dump_mem(struct bxe_softc *sc, 198255736Sdavidch char *tag, 199255736Sdavidch uint8_t *mem, 200255736Sdavidch uint32_t len) 201255736Sdavidch{ 202255736Sdavidch char buf[256]; 203255736Sdavidch char c[32]; 204255736Sdavidch int xx; 205255736Sdavidch 206255736Sdavidch mtx_lock(&bxe_prev_mtx); 207255736Sdavidch 208255736Sdavidch BLOGI(sc, "++++++++++++ %s\n", tag); 209255736Sdavidch strcpy(buf, "** 000: "); 210255736Sdavidch 211255736Sdavidch for (xx = 0; xx < len; xx++) 212255736Sdavidch { 213255736Sdavidch if ((xx != 0) && (xx % 16 == 0)) 214255736Sdavidch { 215255736Sdavidch BLOGI(sc, "%s\n", buf); 216255736Sdavidch strcpy(buf, "** "); 217255736Sdavidch snprintf(c, sizeof(c), "%03x", xx); 218255736Sdavidch strcat(buf, c); 219255736Sdavidch strcat(buf, ": "); 220255736Sdavidch } 221255736Sdavidch 222255736Sdavidch snprintf(c, sizeof(c), "%02x ", *mem); 223255736Sdavidch strcat(buf, c); 224255736Sdavidch 225255736Sdavidch mem++; 226255736Sdavidch } 227255736Sdavidch 228255736Sdavidch BLOGI(sc, "%s\n", buf); 229255736Sdavidch BLOGI(sc, "------------ %s\n", tag); 230255736Sdavidch 231255736Sdavidch mtx_unlock(&bxe_prev_mtx); 232255736Sdavidch} 233255736Sdavidch 234255736Sdavidchvoid 235255736Sdavidchbxe_dump_mbuf_data(struct bxe_softc *sc, 236255736Sdavidch char *tag, 237255736Sdavidch struct mbuf *m, 238255736Sdavidch uint8_t contents) 239255736Sdavidch{ 240255736Sdavidch char buf[256]; 241255736Sdavidch char c[32]; 242255736Sdavidch uint8_t *memp; 243255736Sdavidch int i, xx = 0; 244255736Sdavidch 245255736Sdavidch mtx_lock(&bxe_prev_mtx); 246255736Sdavidch 247255736Sdavidch BLOGI(sc, "++++++++++++ %s\n", tag); 248255736Sdavidch 249255736Sdavidch while (m) 250255736Sdavidch { 251255736Sdavidch memp = m->m_data; 252255736Sdavidch strcpy(buf, "** > "); 253255736Sdavidch snprintf(c, sizeof(c), "%03x", xx); 254255736Sdavidch strcat(buf, c); 255255736Sdavidch strcat(buf, ": "); 256255736Sdavidch 257255736Sdavidch if (contents) 258255736Sdavidch { 259255736Sdavidch for (i = 0; i < m->m_len; i++) 260255736Sdavidch { 261255736Sdavidch if ((xx != 0) && (xx % 16 == 0)) 262255736Sdavidch { 263255736Sdavidch BLOGI(sc, "%s\n", buf); 264255736Sdavidch strcpy(buf, "** "); 265255736Sdavidch snprintf(c, sizeof(c), "%03x", xx); 266255736Sdavidch strcat(buf, c); 267255736Sdavidch strcat(buf, ": "); 268255736Sdavidch } 269255736Sdavidch 270255736Sdavidch snprintf(c, sizeof(c), "%02x ", *memp); 271255736Sdavidch strcat(buf, c); 272255736Sdavidch 273255736Sdavidch memp++; 274255736Sdavidch xx++; 275255736Sdavidch } 276255736Sdavidch } 277255736Sdavidch else 278255736Sdavidch { 279255736Sdavidch snprintf(c, sizeof(c), "%d", m->m_len); 280255736Sdavidch strcat(buf, c); 281255736Sdavidch xx += m->m_len; 282255736Sdavidch } 283255736Sdavidch 284255736Sdavidch BLOGI(sc, "%s\n", buf); 285255736Sdavidch m = m->m_next; 286255736Sdavidch } 287255736Sdavidch 288255736Sdavidch BLOGI(sc, "------------ %s\n", tag); 289255736Sdavidch 290255736Sdavidch mtx_unlock(&bxe_prev_mtx); 291255736Sdavidch} 292255736Sdavidch 293255736Sdavidch#ifdef DDB 294255736Sdavidch 295255736Sdavidchstatic void bxe_ddb_usage() 296255736Sdavidch{ 297255736Sdavidch db_printf("Usage: bxe[/hpv] <instance> [<address>]\n"); 298255736Sdavidch} 299255736Sdavidch 300255736Sdavidchstatic db_cmdfcn_t bxe_ddb; 301255736Sdavidch_DB_SET(_cmd, bxe, bxe_ddb, db_cmd_table, CS_OWN, NULL); 302255736Sdavidch 303255736Sdavidchstatic void bxe_ddb(db_expr_t blah1, 304255736Sdavidch boolean_t blah2, 305255736Sdavidch db_expr_t blah3, 306255736Sdavidch char *blah4) 307255736Sdavidch{ 308255736Sdavidch char if_xname[IFNAMSIZ]; 309255736Sdavidch struct ifnet *ifp = NULL; 310255736Sdavidch struct bxe_softc *sc; 311255736Sdavidch db_expr_t next_arg; 312255736Sdavidch int index; 313255736Sdavidch int tok; 314255736Sdavidch int mod_phys_addr = FALSE; 315255736Sdavidch int mod_virt_addr = FALSE; 316255736Sdavidch db_addr_t addr; 317255736Sdavidch 318255736Sdavidch tok = db_read_token(); 319255736Sdavidch if (tok == tSLASH) { 320255736Sdavidch tok = db_read_token(); 321255736Sdavidch if (tok != tIDENT) { 322255736Sdavidch db_printf("ERROR: bad modifier\n"); 323255736Sdavidch bxe_ddb_usage(); 324255736Sdavidch goto bxe_ddb_done; 325255736Sdavidch } 326255736Sdavidch if (strcmp(db_tok_string, "h") == 0) { 327255736Sdavidch bxe_ddb_usage(); 328255736Sdavidch goto bxe_ddb_done; 329255736Sdavidch } else if (strcmp(db_tok_string, "p") == 0) { 330255736Sdavidch mod_phys_addr = TRUE; 331255736Sdavidch } else if (strcmp(db_tok_string, "v") == 0) { 332255736Sdavidch mod_virt_addr = TRUE; 333255736Sdavidch } 334255736Sdavidch } else { 335255736Sdavidch db_unread_token(tok); 336255736Sdavidch } 337255736Sdavidch 338255736Sdavidch if (!db_expression((db_expr_t *)&index)) { 339255736Sdavidch db_printf("ERROR: bxe index missing\n"); 340255736Sdavidch bxe_ddb_usage(); 341255736Sdavidch goto bxe_ddb_done; 342255736Sdavidch } 343255736Sdavidch 344255736Sdavidch snprintf(if_xname, sizeof(if_xname), "bxe%d", index); 345255736Sdavidch if ((ifp = ifunit_ref(if_xname)) == NULL) 346255736Sdavidch { 347255736Sdavidch db_printf("ERROR: Invalid interface %s\n", if_xname); 348255736Sdavidch goto bxe_ddb_done; 349255736Sdavidch } 350255736Sdavidch 351255736Sdavidch sc = (struct bxe_softc *)ifp->if_softc; 352255736Sdavidch db_printf("ifnet=%p (%s)\n", ifp, if_xname); 353255736Sdavidch db_printf("softc=%p\n", sc); 354255736Sdavidch db_printf(" dev=%p\n", sc->dev); 355255736Sdavidch db_printf(" BDF=%d:%d:%d\n", 356255736Sdavidch sc->pcie_bus, sc->pcie_device, sc->pcie_func); 357255736Sdavidch 358255736Sdavidch if (mod_phys_addr || mod_virt_addr) { 359255736Sdavidch if (!db_expression((db_addr_t *)&addr)) { 360255736Sdavidch db_printf("ERROR: Invalid address\n"); 361255736Sdavidch bxe_ddb_usage(); 362255736Sdavidch goto bxe_ddb_done; 363255736Sdavidch } 364255736Sdavidch 365255736Sdavidch db_printf("addr=%p", addr); 366255736Sdavidch } 367255736Sdavidch 368255736Sdavidchbxe_ddb_done: 369255736Sdavidch 370255736Sdavidch db_flush_lex(); 371255736Sdavidch if (ifp) if_rele(ifp); 372255736Sdavidch} 373255736Sdavidch 374255736Sdavidch#endif /* DDB */ 375255736Sdavidch 376