--- if_ath.c.ori Sun May 7 20:38:42 2006 +++ if_ath.c Sun May 7 07:18:07 2006 @@ -293,7 +293,8 @@ if_initname(ifp, device_get_name(sc->sc_dev), device_get_unit(sc->sc_dev)); - ah = ath_hal_attach(devid, sc, sc->sc_st, sc->sc_sh, &status); + ah = ath_hal_attach(devid, sc, (HAL_BUS_TAG) sc->sc_st, + (HAL_BUS_HANDLE) sc->sc_sh, &status); if (ah == NULL) { if_printf(ifp, "unable to attach hardware; HAL status %u\n", status); @@ -817,8 +810,21 @@ { struct ath_softc *sc = arg; struct ifnet *ifp = sc->sc_ifp; + u_int32_t *state; + u_int32_t len; if_printf(ifp, "hardware error; resetting\n"); + /* + * Fatal errors are unrecoverable. Typically these + * are caused by DMA errors. Collect h/w state from + * the hal so we can diagnose what's going on. + */ + if (ath_hal_getfatalstate(sc->sc_ah, &state, &len)) { + KASSERT(len >= 6*sizeof(u_int32_t), ("len %u bytes", len)); + if_printf(ifp, "0x%08x 0x%08x 0x%08x, 0x%08x 0x%08x 0x%08x\n", + state[0], state[1] , state[2], state[3], + state[4], state[5]); + } ath_reset(ifp); } @@ -1924,7 +1930,7 @@ const HAL_RATE_TABLE *rt; u_int8_t rix, rate; - DPRINTF(sc, ATH_DEBUG_BEACON, "%s: m %p len %u\n", + DPRINTF(sc, ATH_DEBUG_BEACON_PROC, "%s: m %p len %u\n", __func__, m, m->m_len); /* setup descriptors */ @@ -2010,14 +2016,14 @@ } /* * Check if the previous beacon has gone out. If - * not don't don't try to post another, skip this - * period and wait for the next. Missed beacons - * indicate a problem and should not occur. If we - * miss too many consecutive beacons reset the device. + * not don't try to post another, skip this period + * and wait for the next. Missed beacons indicate + * a problem and should not occur. If we miss too + * many consecutive beacons reset the device. */ if (ath_hal_numtxpending(ah, sc->sc_bhalq) != 0) { sc->sc_bmisscount++; - DPRINTF(sc, ATH_DEBUG_BEACON_PROC, + DPRINTF(sc, ATH_DEBUG_BEACON, "%s: missed %u consecutive beacons\n", __func__, sc->sc_bmisscount); if (sc->sc_bmisscount > 3) /* NB: 3 is a guess */ @@ -2568,7 +2574,6 @@ rssi = HAL_EP_RND(avgrssi, HAL_RSSI_EP_MULTIPLIER); else rssi = ni->ni_rssi; - /* NB: theoretically we shouldn't need this, but be paranoid */ return rssi < 0 ? 0 : rssi > 127 ? 127 : rssi; #undef HAL_EP_RND } @@ -2916,7 +2921,7 @@ /* * Sync and unmap the frame. At this point we're * committed to passing the mbuf somewhere so clear - * bf_m; this means a new sk_buff must be allocated + * bf_m; this means a new mbuf must be allocated * when the rx descriptor is setup again to receive * another frame. */ @@ -3978,9 +3983,12 @@ ATH_TXQ_REMOVE_HEAD(txq, bf_list); ATH_TXQ_UNLOCK(txq); #ifdef ATH_DEBUG - if (sc->sc_debug & ATH_DEBUG_RESET) + if (sc->sc_debug & ATH_DEBUG_RESET) { ath_printtxbuf(bf, txq->axq_qnum, ix, ath_hal_txprocdesc(ah, bf->bf_desc) == HAL_OK); + ieee80211_dump_pkt(mtod(bf->bf_m, caddr_t), + bf->bf_m->m_len, 0, -1); + } #endif /* ATH_DEBUG */ bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap); m_freem(bf->bf_m); @@ -4004,11 +4012,11 @@ { struct ath_hal *ah = sc->sc_ah; - (void) ath_hal_stoptxdma(ah, txq->axq_qnum); DPRINTF(sc, ATH_DEBUG_RESET, "%s: tx queue [%u] %p, link %p\n", __func__, txq->axq_qnum, (caddr_t)(uintptr_t) ath_hal_gettxbuf(ah, txq->axq_qnum), txq->axq_link); + (void) ath_hal_stoptxdma(ah, txq->axq_qnum); } /* @@ -4024,10 +4032,11 @@ /* XXX return value */ if (!sc->sc_invalid) { /* don't touch the hardware if marked invalid */ + DPRINTF(sc, ATH_DEBUG_RESET, "%s: tx queue [%u] %p, link %p\n", + __func__, sc->sc_bhalq, + (caddr_t)(uintptr_t) ath_hal_gettxbuf(ah, sc->sc_bhalq), + NULL); (void) ath_hal_stoptxdma(ah, sc->sc_bhalq); - DPRINTF(sc, ATH_DEBUG_RESET, - "%s: beacon queue %p\n", __func__, - (caddr_t)(uintptr_t) ath_hal_gettxbuf(ah, sc->sc_bhalq)); for (i = 0; i < HAL_NUM_TX_QUEUES; i++) if (ATH_TXQ_SETUP(sc, i)) ath_tx_stopdma(sc, &sc->sc_txq[i]); @@ -4035,6 +4044,17 @@ for (i = 0; i < HAL_NUM_TX_QUEUES; i++) if (ATH_TXQ_SETUP(sc, i)) ath_tx_draintxq(sc, &sc->sc_txq[i]); +#ifdef ATH_DEBUG + if (sc->sc_debug & ATH_DEBUG_RESET) { + struct ath_buf *bf = STAILQ_FIRST(&sc->sc_bbuf); + if (bf != NULL && bf->bf_m != NULL) { + ath_printtxbuf(bf, sc->sc_bhalq, 0, + ath_hal_txprocdesc(ah, bf->bf_desc) == HAL_OK); + ieee80211_dump_pkt(mtod(bf->bf_m, caddr_t), + bf->bf_m->m_len, 0, -1); + } + } +#endif /* ATH_DEBUG */ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; sc->sc_tx_timer = 0; } @@ -4567,6 +4587,9 @@ HAL_BOOL outdoor, HAL_BOOL xchanmode) { #define COMPAT (CHANNEL_ALL_NOTURBO|CHANNEL_PASSIVE) +#define IS_CHAN_PUBLIC_SAFETY(_c) \ + (((_c)->channelFlags & CHANNEL_5GHZ) && \ + ((_c)->channel > 4940 && (_c)->channel < 4990)) struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = sc->sc_ifp; struct ath_hal *ah = sc->sc_ah; @@ -4599,7 +4622,16 @@ HAL_CHANNEL *c = &chans[i]; u_int16_t flags; - ix = ath_hal_mhz2ieee(ah, c->channel, c->channelFlags); + /* + * XXX we're not ready to handle the ieee number mapping + * for public safety channels as they overlap with any + * 2GHz channels; for now use the non-public safety + * numbering which is non-overlapping. + */ + if (IS_CHAN_PUBLIC_SAFETY(c)) + ix = (c->channel - 4000) / 5; + else + ix = ath_hal_mhz2ieee(ah, c->channel, c->channelFlags); if (ix > IEEE80211_CHAN_MAX) { if_printf(ifp, "bad hal channel %d (%u/%x) ignored\n", ix, c->channel, c->channelFlags); @@ -4632,6 +4664,7 @@ } free(chans, M_TEMP); return 0; +#undef IS_CHAN_PUBLIC_SAFETY #undef COMPAT }