From 047258c7becbba49f513b8c20bf3e062bc4d7b3a Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Thu, 27 May 2010 01:25:42 -0400 Subject: [PATCH 6/6] ath(4) upgrade --- sys/dev/ic/ath.c | 208 +++++++++++++------------------------------ sys/dev/ic/ath_netbsd.c | 7 +- sys/dev/ic/athrate-sample.c | 5 +- sys/dev/ic/athvar.h | 9 +-- 4 files changed, 72 insertions(+), 157 deletions(-) diff --git a/sys/dev/ic/ath.c b/sys/dev/ic/ath.c index ab1e537..39bd18d 100644 --- a/sys/dev/ic/ath.c +++ b/sys/dev/ic/ath.c @@ -78,6 +78,7 @@ __KERNEL_RCSID(0, "$NetBSD: ath.c,v 1.108 2010/01/19 22:06:24 pooka Exp $"); #include #include +#include #include @@ -183,8 +184,7 @@ static void ath_calibrate(void *); static int ath_newstate(struct ieee80211com *, enum ieee80211_state, int); static void ath_setup_stationkey(struct ieee80211_node *); static void ath_newassoc(struct ieee80211_node *, int); -static int ath_getchannels(struct ath_softc *, u_int cc, - HAL_BOOL outdoor, HAL_BOOL xchanmode); +static int ath_getchannels(struct ath_softc *, u_int cc); static void ath_led_event(struct ath_softc *, int); static void ath_update_txpow(struct ath_softc *); static void ath_freetx(struct mbuf *); @@ -198,8 +198,6 @@ static void ath_announce(struct ath_softc *); int ath_dwelltime = 200; /* 5 channels/second */ int ath_calinterval = 30; /* calibrate every 30 secs */ -int ath_outdoor = AH_TRUE; /* outdoor operation */ -int ath_xchanmode = AH_TRUE; /* enable extended channels */ int ath_countrycode = CTRY_DEFAULT; /* country code */ int ath_regdomain = 0; /* regulatory domain */ int ath_debug = 0; @@ -275,13 +273,6 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) error = ENXIO; goto bad; } - if (ah->ah_abi != HAL_ABI_VERSION) { - if_printf(ifp, "HAL ABI mismatch detected " - "(HAL:0x%x != driver:0x%x)\n", - ah->ah_abi, HAL_ABI_VERSION); - error = ENXIO; - goto bad; - } sc->sc_ah = ah; if (!prop_dictionary_set_bool(device_properties(sc->sc_dev), @@ -339,8 +330,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) * is resposible for filtering this list based on settings * like the phy mode. */ - error = ath_getchannels(sc, ath_countrycode, - ath_outdoor, ath_xchanmode); + error = ath_getchannels(sc, ath_countrycode); if (error != 0) goto bad; @@ -466,7 +456,8 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) */ sc->sc_softled = (devid == AR5212_DEVID_IBM || devid == AR5211_DEVID); if (sc->sc_softled) { - ath_hal_gpioCfgOutput(ah, sc->sc_ledpin); + ath_hal_gpioCfgOutput(ah, sc->sc_ledpin, + HAL_GPIO_MUX_MAC_NETWORK_LED); ath_hal_gpioset(ah, sc->sc_ledpin, !sc->sc_ledon); } @@ -721,7 +712,8 @@ ath_resume(struct ath_softc *sc) ath_hal_resettxqueue(ah, i); if (sc->sc_softled) { - ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_ledpin); + ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_ledpin, + HAL_GPIO_MUX_MAC_NETWORK_LED); ath_hal_gpioset(sc->sc_ah, sc->sc_ledpin, !sc->sc_ledon); } return true; @@ -927,12 +919,12 @@ ath_chan2flags(struct ieee80211com *ic, struct ieee80211_channel *chan) #define N(a) (sizeof(a) / sizeof(a[0])) static const u_int modeflags[] = { 0, /* IEEE80211_MODE_AUTO */ - CHANNEL_A, /* IEEE80211_MODE_11A */ - CHANNEL_B, /* IEEE80211_MODE_11B */ - CHANNEL_PUREG, /* IEEE80211_MODE_11G */ + IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ + IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ + IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */ 0, /* IEEE80211_MODE_FH */ - CHANNEL_ST, /* IEEE80211_MODE_TURBO_A */ - CHANNEL_108G /* IEEE80211_MODE_TURBO_G */ + IEEE80211_CHAN_ST, /* IEEE80211_MODE_TURBO_A */ + IEEE80211_CHAN_108G /* IEEE80211_MODE_TURBO_G */ }; enum ieee80211_phymode mode = ieee80211_chan2mode(ic, chan); @@ -1002,8 +994,8 @@ ath_init(struct ath_softc *sc) * and then setup of the interrupt mask. */ ath_settkipmic(sc); - sc->sc_curchan.channel = ic->ic_curchan->ic_freq; - sc->sc_curchan.channelFlags = ath_chan2flags(ic, ic->ic_curchan); + sc->sc_curchan.ic_freq = ic->ic_curchan->ic_freq; + sc->sc_curchan.ic_flags = ath_chan2flags(ic, ic->ic_curchan); if (!ath_hal_reset(ah, ic->ic_opmode, &sc->sc_curchan, AH_FALSE, &status)) { if_printf(ifp, "unable to reset hardware; hal status %u\n", status); @@ -1175,8 +1167,8 @@ ath_reset(struct ifnet *ifp) * constrained to reflect the current operating mode. */ c = ic->ic_curchan; - sc->sc_curchan.channel = c->ic_freq; - sc->sc_curchan.channelFlags = ath_chan2flags(ic, c); + sc->sc_curchan.ic_freq = c->ic_freq; + sc->sc_curchan.ic_flags = ath_chan2flags(ic, c); ath_hal_intrset(ah, 0); /* disable interrupts */ ath_draintxq(sc); /* stop xmit side */ @@ -4105,8 +4097,6 @@ ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) u_int8_t txant = ds->ds_txstat.ts_antenna; sc->sc_stats.ast_ant_tx[txant]++; sc->sc_ant_tx[txant]++; - if (ds->ds_txstat.ts_rate & HAL_TXSTAT_ALTRATE) - sc->sc_stats.ast_tx_altrate++; sc->sc_stats.ast_tx_rssi = ds->ds_txstat.ts_rssi; ATH_RSSI_LPF(sc->sc_halstats.ns_avgtxrssi, @@ -4430,7 +4420,7 @@ ath_chan_change(struct ath_softc *sc, struct ieee80211_channel *chan) flags = IEEE80211_CHAN_G; else flags = IEEE80211_CHAN_B; - if (IEEE80211_IS_CHAN_T(chan)) + if (IEEE80211_IS_CHAN_TURBO(chan)) flags |= IEEE80211_CHAN_TURBO; sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = htole16(chan->ic_freq); @@ -4482,30 +4472,16 @@ ath_dfswait(void *arg) static int ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan) { - struct ath_hal *ah = sc->sc_ah; struct ieee80211com *ic = &sc->sc_ic; - HAL_CHANNEL hchan; + struct ath_hal *ah = sc->sc_ah; + struct ifnet *ifp = &sc->sc_if; - /* - * Convert to a HAL channel description with - * the flags constrained to reflect the current - * operating mode. - */ - hchan.channel = chan->ic_freq; - hchan.channelFlags = ath_chan2flags(ic, chan); + DPRINTF(sc, ATH_DEBUG_RESET, "%s: %u (%u MHz, flags 0x%x)\n", + __func__, ieee80211_chan2ieee(ic, chan), + chan->ic_freq, chan->ic_flags); - DPRINTF(sc, ATH_DEBUG_RESET, - "%s: %u (%u MHz, hal flags 0x%x) -> %u (%u MHz, hal flags 0x%x)\n", - __func__, - ath_hal_mhz2ieee(ah, sc->sc_curchan.channel, - sc->sc_curchan.channelFlags), - sc->sc_curchan.channel, sc->sc_curchan.channelFlags, - ath_hal_mhz2ieee(ah, hchan.channel, hchan.channelFlags), - hchan.channel, hchan.channelFlags); - if (hchan.channel != sc->sc_curchan.channel || - hchan.channelFlags != sc->sc_curchan.channelFlags) { + if (chan != &sc->sc_curchan) { HAL_STATUS status; - /* * To switch channels clear any pending DMA operations; * wait long enough for the RX fifo to drain, reset the @@ -4515,25 +4491,21 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan) ath_hal_intrset(ah, 0); /* disable interrupts */ ath_draintxq(sc); /* clear pending tx frames */ ath_stoprecv(sc); /* turn off frame recv */ - if (!ath_hal_reset(ah, ic->ic_opmode, &hchan, AH_TRUE, &status)) { - if_printf(ic->ic_ifp, "%s: unable to reset " - "channel %u (%u MHz, flags 0x%x hal flags 0x%x)\n", + if (!ath_hal_reset(ah, ic->ic_opmode, chan, AH_TRUE, &status)) { + if_printf(ifp, "%s: unable to reset " + "channel %u (%u MHz, flags 0x%x), hal status %u\n", __func__, ieee80211_chan2ieee(ic, chan), - chan->ic_freq, chan->ic_flags, hchan.channelFlags); + chan->ic_freq, chan->ic_flags, status); return EIO; } - sc->sc_curchan = hchan; - ath_update_txpow(sc); /* update tx power state */ - ath_restore_diversity(sc); - sc->sc_calinterval = 1; - sc->sc_caltries = 0; + sc->sc_diversity = ath_hal_getdiversity(ah); /* * Re-enable rx framework. */ if (ath_startrecv(sc) != 0) { - if_printf(&sc->sc_if, - "%s: unable to restart recv logic\n", __func__); + if_printf(ifp, "%s: unable to restart recv logic\n", + __func__); return EIO; } @@ -4541,30 +4513,8 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan) * Change channels and update the h/w rate map * if we're switching; e.g. 11a to 11b/g. */ - ic->ic_ibss_chan = chan; ath_chan_change(sc, chan); -#if 0 - /* - * Handle DFS required waiting period to determine - * if channel is clear of radar traffic. - */ - if (ic->ic_opmode == IEEE80211_M_HOSTAP) { -#define DFS_AND_NOT_CLEAR(_c) \ - (((_c)->privFlags & (CHANNEL_DFS | CHANNEL_DFS_CLEAR)) == CHANNEL_DFS) - if (DFS_AND_NOT_CLEAR(&sc->sc_curchan)) { - if_printf(&sc->sc_if, - "wait for DFS clear channel signal\n"); - /* XXX stop sndq */ - sc->sc_if.if_flags |= IFF_OACTIVE; - callout_reset(&sc->sc_dfs_ch, - 2 * hz, ath_dfswait, sc); - } else - callout_stop(&sc->sc_dfs_ch); -#undef DFS_NOT_CLEAR - } -#endif - /* * Re-enable interrupts. */ @@ -4616,7 +4566,7 @@ ath_calibrate(void *arg) if (!ath_hal_calibrate(ah, &sc->sc_curchan, &iqCalDone)) { DPRINTF(sc, ATH_DEBUG_ANY, "%s: calibration of channel %u failed\n", - __func__, sc->sc_curchan.channel); + __func__, sc->sc_curchan.ic_freq); sc->sc_stats.ast_per_calfail++; } /* @@ -4870,76 +4820,45 @@ ath_newassoc(struct ieee80211_node *ni, int isnew) } static int -ath_getchannels(struct ath_softc *sc, u_int cc, - HAL_BOOL outdoor, HAL_BOOL xchanmode) +ath_getchannels(struct ath_softc *sc, u_int cc) { -#define COMPAT (CHANNEL_ALL_NOTURBO|CHANNEL_PASSIVE) struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = &sc->sc_if; struct ath_hal *ah = sc->sc_ah; - HAL_CHANNEL *chans; - int i, ix, nchan; - - chans = malloc(IEEE80211_CHAN_MAX * sizeof(HAL_CHANNEL), - M_TEMP, M_NOWAIT); - if (chans == NULL) { - if_printf(ifp, "unable to allocate channel table\n"); - return ENOMEM; - } - if (!ath_hal_init_channels(ah, chans, IEEE80211_CHAN_MAX, &nchan, - NULL, 0, NULL, - cc, HAL_MODE_ALL, outdoor, xchanmode)) { - u_int32_t rd; - - (void)ath_hal_getregdomain(ah, &rd); - if_printf(ifp, "unable to collect channel list from hal; " - "regdomain likely %u country code %u\n", rd, cc); - free(chans, M_TEMP); - return EINVAL; - } + int nchans; + HAL_STATUS status; /* - * Convert HAL channels to ieee80211 ones and insert - * them in the table according to their channel number. + * Collect channel set based on EEPROM contents. */ - for (i = 0; i < nchan; i++) { - HAL_CHANNEL *c = &chans[i]; - u_int16_t flags; - - 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); - continue; - } - if (ix < 0) { - /* XXX can't handle stuff <2400 right now */ - if (bootverbose) - if_printf(ifp, "hal channel %d (%u/%x) " - "cannot be handled; ignored\n", - ix, c->channel, c->channelFlags); - continue; - } - /* - * Calculate net80211 flags; most are compatible - * but some need massaging. Note the static turbo - * conversion can be removed once net80211 is updated - * to understand static vs. dynamic turbo. - */ - flags = c->channelFlags & COMPAT; - if (c->channelFlags & CHANNEL_STURBO) - flags |= IEEE80211_CHAN_TURBO; - if (ic->ic_channels[ix].ic_freq == 0) { - ic->ic_channels[ix].ic_freq = c->channel; - ic->ic_channels[ix].ic_flags = flags; - } else { - /* channels overlap; e.g. 11g and 11b */ - ic->ic_channels[ix].ic_flags |= flags; - } + status = ath_hal_init_channels(ah, ic->ic_channels, IEEE80211_CHAN_MAX, + &nchans, HAL_MODE_ALL, CTRY_DEFAULT, SKU_NONE, AH_TRUE); + if (status != HAL_OK) { + if_printf(ifp, "%s: unable to collect channel list from hal, " + "status %d\n", __func__, status); + return EINVAL; } - free(chans, M_TEMP); +#ifdef notyet + (void) ath_hal_getregdomain(ah, &sc->sc_eerd); + ath_hal_getcountrycode(ah, &sc->sc_eecc); /* NB: cannot fail */ + /* XXX map Atheros sku's to net80211 SKU's */ + /* XXX net80211 types too small */ + ic->ic_regdomain.regdomain = (uint16_t) sc->sc_eerd; + ic->ic_regdomain.country = (uint16_t) sc->sc_eecc; + ic->ic_regdomain.isocc[0] = ' '; /* XXX don't know */ + ic->ic_regdomain.isocc[1] = ' '; + + ic->ic_regdomain.ecm = 1; + ic->ic_regdomain.location = 'I'; + + DPRINTF(sc, ATH_DEBUG_REGDOMAIN, + "%s: eeprom rd %u cc %u (mapped rd %u cc %u) location %c%s\n", + __func__, sc->sc_eerd, sc->sc_eecc, + ic->ic_regdomain.regdomain, ic->ic_regdomain.country, + ic->ic_regdomain.location, ic->ic_regdomain.ecm ? " ecm" : ""); +#endif + return 0; -#undef COMPAT } static void @@ -5411,7 +5330,7 @@ ath_announce(struct ath_softc *sc) #define HAL_MODE_DUALBAND (HAL_MODE_11A|HAL_MODE_11B) struct ifnet *ifp = &sc->sc_if; struct ath_hal *ah = sc->sc_ah; - u_int modes, cc; + u_int modes; if_printf(ifp, "mac %d.%d phy %d.%d", ah->ah_macVersion, ah->ah_macRev, @@ -5421,8 +5340,7 @@ ath_announce(struct ath_softc *sc) * to avoid falsely printing revs for inoperable parts. * Dual-band radio revs are returned in the 5 GHz rev number. */ - ath_hal_getcountrycode(ah, &cc); - modes = ath_hal_getwirelessmodes(ah, cc); + modes = ath_hal_getwirelessmodes(ah); if ((modes & HAL_MODE_DUALBAND) == HAL_MODE_DUALBAND) { if (ah->ah_analog5GhzRev && ah->ah_analog2GhzRev) printf(" 5 GHz radio %d.%d 2 GHz radio %d.%d", diff --git a/sys/dev/ic/ath_netbsd.c b/sys/dev/ic/ath_netbsd.c index dbdc1cd..0f8c202 100644 --- a/sys/dev/ic/ath_netbsd.c +++ b/sys/dev/ic/ath_netbsd.c @@ -91,10 +91,6 @@ SYSCTL_SETUP(sysctl_ath, "sysctl ath subtree setup") "chip calibration interval (secs)", calinterval)) != 0) goto err; - if ((rc = SYSCTL_GLOBAL_INT(CTLFLAG_READWRITE, "outdoor", - "outdoor operation", outdoor)) != 0) - goto err; - /* country code */ if ((rc = SYSCTL_GLOBAL_INT(CTLFLAG_READWRITE, "countrycode", "country code", countrycode)) != 0) @@ -194,7 +190,8 @@ ath_sysctl_softled(SYSCTLFN_ARGS) if (softled != sc->sc_softled) { if (softled) { /* NB: handle any sc_ledpin change */ - ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_ledpin); + ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_ledpin, + HAL_GPIO_MUX_MAC_NETWORK_LED); ath_hal_gpioset(sc->sc_ah, sc->sc_ledpin, !sc->sc_ledon); } diff --git a/sys/dev/ic/athrate-sample.c b/sys/dev/ic/athrate-sample.c index 55e463c..e167e35 100644 --- a/sys/dev/ic/athrate-sample.c +++ b/sys/dev/ic/athrate-sample.c @@ -494,7 +494,10 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an, int ndx = -1; int mrr; + final_rate = 0; +#ifdef FIXME final_rate = sc->sc_hwmap[ds->ds_txstat.ts_rate &~ HAL_TXSTAT_ALTRATE].ieeerate; +#endif short_tries = ds->ds_txstat.ts_shortretry + 1; long_tries = ds->ds_txstat.ts_longretry + 1; frame_size = ds0->ds_ctl0 & 0x0fff; /* low-order 12 bits of ds_ctl0 */ @@ -532,7 +535,7 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an, long_tries); } - if (!mrr || !(ds->ds_txstat.ts_rate & HAL_TXSTAT_ALTRATE)) { + if (!mrr || !(ds->ds_txstat.ts_rate /*& HAL_TXSTAT_ALTRATE*/)) { /* only one rate was used */ ndx = rate_to_ndx(sn, final_rate); DPRINTF(sc, "%s: %s size %d status %d rate/try %d/%d/%d\n", diff --git a/sys/dev/ic/athvar.h b/sys/dev/ic/athvar.h index 83eb8b5..92bc372 100644 --- a/sys/dev/ic/athvar.h +++ b/sys/dev/ic/athvar.h @@ -222,7 +222,7 @@ struct ath_softc { const HAL_RATE_TABLE *sc_currates; /* current rate table */ enum ieee80211_phymode sc_curmode; /* current phy mode */ u_int16_t sc_curtxpow; /* current tx power limit */ - HAL_CHANNEL sc_curchan; /* current h/w channel */ + struct ieee80211_channel sc_curchan; /* current h/w channel */ u_int8_t sc_rixmap[256]; /* IEEE to h/w rate table ix */ struct { u_int8_t ieeerate; /* IEEE rate */ @@ -324,8 +324,6 @@ void ath_sysctlattach(struct ath_softc *); extern int ath_dwelltime; extern int ath_calinterval; -extern int ath_outdoor; -extern int ath_xchanmode; extern int ath_countrycode; extern int ath_regdomain; extern int ath_debug; @@ -570,9 +568,8 @@ extern int ath_txbuf; ((*(_ah)->ah_procTxDesc)((_ah), (_ds), (_ts))) #define ath_hal_gettxintrtxqs(_ah, _txqs) \ ((*(_ah)->ah_getTxIntrQueue)((_ah), (_txqs))) - -#define ath_hal_gpioCfgOutput(_ah, _gpio) \ - ((*(_ah)->ah_gpioCfgOutput)((_ah), (_gpio))) +#define ath_hal_gpioCfgOutput(_ah, _gpio, _type) \ + ((*(_ah)->ah_gpioCfgOutput)((_ah), (_gpio), (_type))) #define ath_hal_gpioset(_ah, _gpio, _b) \ ((*(_ah)->ah_gpioSet)((_ah), (_gpio), (_b))) -- 1.7.1.rc0.7.g02125bc