diff options
author | adrian <adrian@FreeBSD.org> | 2013-08-01 21:45:30 +0000 |
---|---|---|
committer | adrian <adrian@FreeBSD.org> | 2013-08-01 21:45:30 +0000 |
commit | a149e02ce556e45359a9527ec0829b562839f201 (patch) | |
tree | 3e6a66922351ed07ea2307bd91d16aabc01f1169 | |
parent | d86268b3973287aa55ddce6d9c163990a9259aa8 (diff) | |
download | FreeBSD-src-a149e02ce556e45359a9527ec0829b562839f201.zip FreeBSD-src-a149e02ce556e45359a9527ec0829b562839f201.tar.gz |
iwn(4) debugging improvements.
* Add in some new register debugging under IWN_DEBUG_REGISTER
* Make IWN_DEBUG an option now for building. I'll chase this up
with a commit to 'options' soon.
Submitted by: Cedric GROSS <cg@cgross.info>
-rw-r--r-- | sys/dev/iwn/if_iwn.c | 118 | ||||
-rw-r--r-- | sys/dev/iwn/if_iwnreg.h | 6 |
2 files changed, 113 insertions, 11 deletions
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c index 644a7eb..6cda77f 100644 --- a/sys/dev/iwn/if_iwn.c +++ b/sys/dev/iwn/if_iwn.c @@ -160,7 +160,9 @@ static void iwn5000_ict_reset(struct iwn_softc *); static int iwn_read_eeprom(struct iwn_softc *, uint8_t macaddr[IEEE80211_ADDR_LEN]); static void iwn4965_read_eeprom(struct iwn_softc *); +#ifdef IWN_DEBUG static void iwn4965_print_power_group(struct iwn_softc *, int); +#endif static void iwn5000_read_eeprom(struct iwn_softc *); static uint32_t iwn_eeprom_channel_flags(struct iwn_eeprom_chan *); static void iwn_read_eeprom_band(struct iwn_softc *, int); @@ -320,9 +322,12 @@ static void iwn_set_channel(struct ieee80211com *); static void iwn_scan_curchan(struct ieee80211_scan_state *, unsigned long); static void iwn_scan_mindwell(struct ieee80211_scan_state *); static void iwn_hw_reset(void *, int); +#ifdef IWN_DEBUG +static char *iwn_get_csr_string(int); +static void iwn_debug_register(struct iwn_softc *); +#endif -#define IWN_DEBUG -#ifdef IWN_DEBUG +#ifdef IWN_DEBUG enum { IWN_DEBUG_XMIT = 0x00000001, /* basic xmit operation */ IWN_DEBUG_RECV = 0x00000002, /* basic recv operation */ @@ -339,6 +344,7 @@ enum { IWN_DEBUG_CMD = 0x00001000, /* cmd submission */ IWN_DEBUG_TXRATE = 0x00002000, /* TX rate debugging */ IWN_DEBUG_PWRSAVE = 0x00004000, /* Power save operations */ + IWN_DEBUG_REGISTER = 0x20000000, /* print chipset register */ IWN_DEBUG_TRACE = 0x40000000, /* Print begin and start driver function */ IWN_DEBUG_FATAL = 0x80000000, /* fatal errors */ IWN_DEBUG_ANY = 0xffffffff @@ -924,6 +930,8 @@ iwn_detach(device_t dev) struct ieee80211com *ic; int qid; + DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__); + if (ifp != NULL) { ic = ifp->if_l2com; @@ -961,7 +969,7 @@ iwn_detach(device_t dev) if (ifp != NULL) if_free(ifp); - DPRINTF(sc, IWN_DEBUG_TRACE, "->%s done\n", __func__); + DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n", __func__); IWN_LOCK_DESTROY(sc); return 0; } @@ -3202,8 +3210,6 @@ iwn_notif_intr(struct iwn_softc *sc) } case IWN_STATE_CHANGED: { - uint32_t *status = (uint32_t *)(desc + 1); - /* * State change allows hardware switch change to be * noted. However, we handle this in iwn_intr as we @@ -3211,32 +3217,37 @@ iwn_notif_intr(struct iwn_softc *sc) */ bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD); +#ifdef IWN_DEBUG + uint32_t *status = (uint32_t *)(desc + 1); DPRINTF(sc, IWN_DEBUG_INTR, "state changed to %x\n", le32toh(*status)); +#endif break; } case IWN_START_SCAN: { - struct iwn_start_scan *scan = - (struct iwn_start_scan *)(desc + 1); - bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD); +#ifdef IWN_DEBUG + struct iwn_start_scan *scan = + (struct iwn_start_scan *)(desc + 1); DPRINTF(sc, IWN_DEBUG_ANY, "%s: scanning channel %d status %x\n", __func__, scan->chan, le32toh(scan->status)); +#endif break; } case IWN_STOP_SCAN: { - struct iwn_stop_scan *scan = - (struct iwn_stop_scan *)(desc + 1); - bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD); +#ifdef IWN_DEBUG + struct iwn_stop_scan *scan = + (struct iwn_stop_scan *)(desc + 1); DPRINTF(sc, IWN_DEBUG_STATE, "scan finished nchan=%d status=%d chan=%d\n", scan->nchan, scan->status, scan->chan); +#endif IWN_UNLOCK(sc); ieee80211_scan_next(vap); @@ -3416,6 +3427,9 @@ iwn_intr(void *arg) if (r1 & (IWN_INT_SW_ERR | IWN_INT_HW_ERR)) { device_printf(sc->sc_dev, "%s: fatal firmware error\n", __func__); +#ifdef IWN_DEBUG + iwn_debug_register(sc); +#endif /* Dump firmware error log and stop. */ iwn_fatal_intr(sc); ifp->if_flags &= ~IFF_UP; @@ -7467,3 +7481,85 @@ iwn_hw_reset(void *arg0, int pending) iwn_init(sc); ieee80211_notify_radio(ic, 1); } +#ifdef IWN_DEBUG +#define IWN_DESC(x) case x: return #x +#define COUNTOF(array) (sizeof(array) / sizeof(array[0])) + +/* + * Transate CSR code to string + */ +static char *iwn_get_csr_string(int csr) +{ + switch (csr) { + IWN_DESC(IWN_HW_IF_CONFIG); + IWN_DESC(IWN_INT_COALESCING); + IWN_DESC(IWN_INT); + IWN_DESC(IWN_INT_MASK); + IWN_DESC(IWN_FH_INT); + IWN_DESC(IWN_GPIO_IN); + IWN_DESC(IWN_RESET); + IWN_DESC(IWN_GP_CNTRL); + IWN_DESC(IWN_HW_REV); + IWN_DESC(IWN_EEPROM); + IWN_DESC(IWN_EEPROM_GP); + IWN_DESC(IWN_OTP_GP); + IWN_DESC(IWN_GIO); + IWN_DESC(IWN_GP_UCODE); + IWN_DESC(IWN_GP_DRIVER); + IWN_DESC(IWN_UCODE_GP1); + IWN_DESC(IWN_UCODE_GP2); + IWN_DESC(IWN_LED); + IWN_DESC(IWN_DRAM_INT_TBL); + IWN_DESC(IWN_GIO_CHICKEN); + IWN_DESC(IWN_ANA_PLL); + IWN_DESC(IWN_HW_REV_WA); + IWN_DESC(IWN_DBG_HPET_MEM); + default: + return "UNKNOWN CSR"; + } +} + +/* + * This function print firmware register + */ +static void +iwn_debug_register(struct iwn_softc *sc) +{ + int i; + static const uint32_t csr_tbl[] = { + IWN_HW_IF_CONFIG, + IWN_INT_COALESCING, + IWN_INT, + IWN_INT_MASK, + IWN_FH_INT, + IWN_GPIO_IN, + IWN_RESET, + IWN_GP_CNTRL, + IWN_HW_REV, + IWN_EEPROM, + IWN_EEPROM_GP, + IWN_OTP_GP, + IWN_GIO, + IWN_GP_UCODE, + IWN_GP_DRIVER, + IWN_UCODE_GP1, + IWN_UCODE_GP2, + IWN_LED, + IWN_DRAM_INT_TBL, + IWN_GIO_CHICKEN, + IWN_ANA_PLL, + IWN_HW_REV_WA, + IWN_DBG_HPET_MEM, + }; + DPRINTF(sc, IWN_DEBUG_REGISTER, + "CSR values: (2nd byte of IWN_INT_COALESCING is IWN_INT_PERIODIC)%s", + "\n"); + for (i = 0; i < COUNTOF(csr_tbl); i++){ + DPRINTF(sc, IWN_DEBUG_REGISTER," %10s: 0x%08x ", + iwn_get_csr_string(csr_tbl[i]), IWN_READ(sc, csr_tbl[i])); + if ((i+1) % 3 == 0) + DPRINTF(sc, IWN_DEBUG_REGISTER,"%s","\n"); + } + DPRINTF(sc, IWN_DEBUG_REGISTER,"%s","\n"); +} +#endif diff --git a/sys/dev/iwn/if_iwnreg.h b/sys/dev/iwn/if_iwnreg.h index 062125f..74b4ece 100644 --- a/sys/dev/iwn/if_iwnreg.h +++ b/sys/dev/iwn/if_iwnreg.h @@ -62,6 +62,7 @@ #define IWN_INT 0x008 #define IWN_INT_MASK 0x00c #define IWN_FH_INT 0x010 +#define IWN_GPIO_IN 0x018 /* read external chip pins */ #define IWN_RESET 0x020 #define IWN_GP_CNTRL 0x024 #define IWN_HW_REV 0x028 @@ -69,8 +70,12 @@ #define IWN_EEPROM_GP 0x030 #define IWN_OTP_GP 0x034 #define IWN_GIO 0x03c +#define IWN_GP_UCODE 0x048 #define IWN_GP_DRIVER 0x050 +#define IWN_UCODE_GP1 0x054 +#define IWN_UCODE_GP1_SET 0x058 #define IWN_UCODE_GP1_CLR 0x05c +#define IWN_UCODE_GP2 0x060 #define IWN_LED 0x094 #define IWN_DRAM_INT_TBL 0x0a0 #define IWN_SHADOW_REG_CTRL 0x0a8 @@ -79,6 +84,7 @@ #define IWN_HW_REV_WA 0x22c #define IWN_DBG_HPET_MEM 0x240 #define IWN_DBG_LINK_PWR_MGMT 0x250 +/* Need nic_lock for use above */ #define IWN_MEM_RADDR 0x40c #define IWN_MEM_WADDR 0x410 #define IWN_MEM_WDATA 0x418 |