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