From 4bc4ec7abed7631d736d6a4a1423bdcd84321da5 Mon Sep 17 00:00:00 2001 From: Reyk Floeter Date: Fri, 23 Sep 2005 20:06:51 +0000 Subject: cleanup and simplify the regulation domain handling. some devices are known to have a broken/unsupported regulation domain stored in their EEPROM, we use the default instead (Canada). there's no need to manually define COUNTRYCODE in ar5xxx.c anymore for invalid EEPROMs but it's still possible to force a specific country - your choice. ok aanriot@ --- sys/dev/ic/ar5xxx.c | 81 ++++++++++++++++++++++------------------------------- sys/dev/ic/ar5xxx.h | 9 ++---- sys/dev/ic/ath.c | 45 ++++++++++++++--------------- sys/dev/ic/athvar.h | 4 +-- 4 files changed, 60 insertions(+), 79 deletions(-) (limited to 'sys/dev/ic') diff --git a/sys/dev/ic/ar5xxx.c b/sys/dev/ic/ar5xxx.c index ad003805818..5407e2597d3 100644 --- a/sys/dev/ic/ar5xxx.c +++ b/sys/dev/ic/ar5xxx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar5xxx.c,v 1.30 2005/09/19 10:27:08 reyk Exp $ */ +/* $OpenBSD: ar5xxx.c,v 1.31 2005/09/23 20:06:50 reyk Exp $ */ /* * Copyright (c) 2004, 2005 Reyk Floeter @@ -144,8 +144,6 @@ struct ath_hal * ath_hal_attach(u_int16_t device, void *sc, bus_space_tag_t st, bus_space_handle_t sh, int *status) { - ieee80211_regdomain_t ieee_regdomain; - u_int16_t regdomain; struct ath_hal *hal = NULL; ar5k_attach_t *attach = NULL; u_int8_t mac[IEEE80211_ADDR_LEN]; @@ -187,8 +185,6 @@ ath_hal_attach(u_int16_t device, void *sc, bus_space_tag_t st, * HAL information */ hal->ah_abi = HAL_ABI_VERSION; - hal->ah_country_code = CTRY_DEFAULT; - hal->ah_capabilities.cap_regdomain.reg_current = AR5K_TUNE_REGDOMAIN; hal->ah_op_mode = HAL_M_STA; hal->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; hal->ah_turbo = AH_FALSE; @@ -217,21 +213,6 @@ ath_hal_attach(u_int16_t device, void *sc, bus_space_tag_t st, goto failed; } - /* Set regulation domain */ - if ((regdomain = - hal->ah_capabilities.cap_eeprom.ee_regdomain) != 0) { - hal->ah_capabilities.cap_regdomain.reg_current = - ieee_regdomain = ar5k_regdomain_to_ieee(regdomain); - } else { - ieee_regdomain = - hal->ah_capabilities.cap_regdomain.reg_current; - - /* Try to write default regulation domain to EEPROM */ - ar5k_eeprom_regulation_domain(hal, AH_TRUE, &ieee_regdomain); - } - - hal->ah_capabilities.cap_regdomain.reg_hw = ieee_regdomain; - /* Get misc capabilities */ if (hal->ah_get_capabilities(hal) != AH_TRUE) { AR5K_PRINTF("unable to get device capabilities: 0x%04x\n", @@ -379,8 +360,8 @@ ar5k_check_channel(struct ath_hal *hal, u_int16_t freq, u_int flags) HAL_BOOL ath_hal_init_channels(struct ath_hal *hal, HAL_CHANNEL *channels, - u_int max_channels, u_int *channels_size, HAL_CTRY_CODE country, - u_int16_t mode, HAL_BOOL outdoor, HAL_BOOL extended) + u_int max_channels, u_int *channels_size, u_int16_t mode, + HAL_BOOL outdoor, HAL_BOOL extended) { u_int i, c; u_int32_t domain_current; @@ -392,7 +373,7 @@ ath_hal_init_channels(struct ath_hal *hal, HAL_CHANNEL *channels, return (AH_FALSE); i = c = 0; - domain_current = hal->ah_get_regdomain(hal); + domain_current = hal->ah_regdomain; /* * In debugging mode, enable all channels supported by the chipset @@ -557,16 +538,22 @@ ar5k_regdomain_from_ieee(ieee80211_regdomain_t ieee) { u_int32_t regdomain = (u_int32_t)ieee; - if (regdomain & 0xf0000000) + /* + * Use the default regulation domain if the value is empty + * or not supported by the net80211 regulation code. + */ + if (ieee80211_regdomain2flag(regdomain, + IEEE80211_CHANNELS_5GHZ_MIN) == DMN_DEBUG) return ((u_int16_t)AR5K_TUNE_REGDOMAIN); - return (regdomain & 0xff); + /* It is supported, just return the value */ + return (regdomain); } ieee80211_regdomain_t ar5k_regdomain_to_ieee(u_int16_t regdomain) { - ieee80211_regdomain_t ieee = (ieee80211_regdomain_t)regdomain & 0xff; + ieee80211_regdomain_t ieee = (ieee80211_regdomain_t)regdomain; return (ieee); } @@ -574,31 +561,28 @@ ar5k_regdomain_to_ieee(u_int16_t regdomain) u_int16_t ar5k_get_regdomain(struct ath_hal *hal) { -#ifndef COUNTRYCODE - /* - * Use the regulation domain found in the EEPROM, if not - * forced by a static country code. - */ u_int16_t regdomain; ieee80211_regdomain_t ieee_regdomain; +#ifdef COUNTRYCODE + u_int16_t code; +#endif - if (ar5k_eeprom_regulation_domain(hal, - AH_FALSE, &ieee_regdomain) == AH_TRUE) { - if ((regdomain = ar5k_regdomain_from_ieee(ieee_regdomain))) - return (regdomain); - } + ar5k_eeprom_regulation_domain(hal, AH_FALSE, &ieee_regdomain); + hal->ah_capabilities.cap_regdomain.reg_hw = ieee_regdomain; - return (hal->ah_regdomain); -#else +#ifdef COUNTRYCODE /* * Get the regulation domain by country code. This will ignore * the settings found in the EEPROM. */ - u_int16_t code; - code = ieee80211_name2countrycode(COUNTRYCODE); - return (ieee80211_countrycode2regdomain(code)); + ieee_regdomain = ieee80211_countrycode2regdomain(code); #endif + + regdomain = ar5k_regdomain_from_ieee(ieee_regdomain); + hal->ah_capabilities.cap_regdomain.reg_current = regdomain; + + return (regdomain); } u_int32_t @@ -1037,25 +1021,26 @@ HAL_BOOL ar5k_eeprom_regulation_domain(struct ath_hal *hal, HAL_BOOL write, ieee80211_regdomain_t *regdomain) { + u_int16_t ee_regdomain; + /* Read current value */ if (write != AH_TRUE) { - *regdomain = hal->ah_capabilities.cap_regdomain.reg_current; + ee_regdomain = hal->ah_capabilities.cap_eeprom.ee_regdomain; + *regdomain = ar5k_regdomain_to_ieee(ee_regdomain); return (AH_TRUE); } - /* Try to write a new value */ - hal->ah_capabilities.cap_regdomain.reg_current = *regdomain; + ee_regdomain = ar5k_regdomain_from_ieee(*regdomain); + /* Try to write a new value */ if (hal->ah_capabilities.cap_eeprom.ee_protect & AR5K_EEPROM_PROTECT_WR_128_191) return (AH_FALSE); - if (hal->ah_eeprom_write(hal, AR5K_EEPROM_REG_DOMAIN, - hal->ah_capabilities.cap_eeprom.ee_regdomain) != 0) + ee_regdomain) != 0) return (AH_FALSE); - hal->ah_capabilities.cap_eeprom.ee_regdomain = - ar5k_regdomain_from_ieee(*regdomain); + hal->ah_capabilities.cap_eeprom.ee_regdomain = ee_regdomain; return (AH_TRUE); } diff --git a/sys/dev/ic/ar5xxx.h b/sys/dev/ic/ar5xxx.h index a5edb952788..035ef722850 100644 --- a/sys/dev/ic/ar5xxx.h +++ b/sys/dev/ic/ar5xxx.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ar5xxx.h,v 1.28 2005/09/23 19:11:40 reyk Exp $ */ +/* $OpenBSD: ar5xxx.h,v 1.29 2005/09/23 20:06:50 reyk Exp $ */ /* * Copyright (c) 2004, 2005 Reyk Floeter @@ -1090,7 +1090,6 @@ struct ath_hal { HAL_INT ah_imr; - HAL_CTRY_CODE ah_country_code; HAL_OPMODE ah_op_mode; HAL_POWER_MODE ah_power_mode; HAL_CHANNEL ah_current_channel; @@ -1099,8 +1098,6 @@ struct ath_hal { HAL_BOOL ah_running; HAL_RFGAIN ah_rf_gain; -#define ah_getcountrycode ah_country_code - HAL_RATE_TABLE ah_rt_11a; HAL_RATE_TABLE ah_rt_11b; HAL_RATE_TABLE ah_rt_11g; @@ -1122,6 +1119,7 @@ struct ath_hal { HAL_BOOL ah_2ghz; #define ah_regdomain ah_capabilities.cap_regdomain.reg_current +#define ah_regdomain_hw ah_capabilities.cap_regdomain.reg_hw #define ah_modes ah_capabilities.cap_mode #define ah_ee_version ah_capabilities.cap_eeprom.ee_version @@ -1278,7 +1276,6 @@ typedef HAL_BOOL (ar5k_rfgain_t) /* Default regulation domain if stored value EEPROM value is invalid */ #define AR5K_TUNE_REGDOMAIN DMN_FCC2_FCCA /* Canada */ -#define AR5K_TUNE_CTRY CTRY_DEFAULT /* * Common initial register values @@ -1811,7 +1808,7 @@ u_int ath_hal_mhz2ieee(u_int, u_int); u_int ath_hal_ieee2mhz(u_int, u_int); HAL_BOOL ath_hal_init_channels(struct ath_hal *, HAL_CHANNEL *, - u_int, u_int *, HAL_CTRY_CODE, u_int16_t, HAL_BOOL, HAL_BOOL); + u_int, u_int *, u_int16_t, HAL_BOOL, HAL_BOOL); const char *ar5k_printver(enum ar5k_srev_type, u_int); void ar5k_radar_alert(struct ath_hal *); diff --git a/sys/dev/ic/ath.c b/sys/dev/ic/ath.c index d953cd3f036..2ef9b736699 100644 --- a/sys/dev/ic/ath.c +++ b/sys/dev/ic/ath.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ath.c,v 1.41 2005/09/22 10:17:04 reyk Exp $ */ +/* $OpenBSD: ath.c,v 1.42 2005/09/23 20:06:50 reyk Exp $ */ /* $NetBSD: ath.c,v 1.37 2004/08/18 21:59:39 dyoung Exp $ */ /*- @@ -131,7 +131,7 @@ void ath_ledstate(struct ath_softc *, enum ieee80211_state); int ath_newstate(struct ieee80211com *, enum ieee80211_state, int); void ath_newassoc(struct ieee80211com *, struct ieee80211_node *, int); -int ath_getchannels(struct ath_softc *, u_int cc, HAL_BOOL outdoor, +int ath_getchannels(struct ath_softc *, HAL_BOOL outdoor, HAL_BOOL xchanmode); int ath_rate_setup(struct ath_softc *sc, u_int mode); void ath_setcurmode(struct ath_softc *, enum ieee80211_phymode); @@ -157,8 +157,6 @@ 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 = DMN_DEFAULT; /* regulatory domain */ struct cfdriver ath_cd = { NULL, "ath", DV_IFNET @@ -222,6 +220,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) DPRINTF(ATH_DEBUG_ANY, ("%s: devid 0x%x\n", __func__, devid)); bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); + sc->sc_flags &= ~ATH_ATTACHED; /* make sure that it's not attached */ ah = ath_hal_attach(devid, sc, sc->sc_st, sc->sc_sh, &status); if (ah == NULL) { @@ -263,21 +262,18 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) sc->sc_invalid = 0; /* ready to go, enable interrupt handling */ /* - * Collect the channel list using the default country - * code and including outdoor channels. The 802.11 layer - * is resposible for filtering this list based on settings - * like the phy mode. + * Get regulation domain either stored in the EEPROM or defined + * as the default value. Some devices are known to have broken + * regulation domain values in their EEPROM. */ - error = ath_getchannels(sc, ath_countrycode, ath_outdoor, - ath_xchanmode); - if (error != 0) - goto bad; + ath_hal_get_regdomain(ah, &ah->ah_regdomain); + /* - * Copy these back; they are set as a side effect - * of constructing the channel list. + * Construct channel list based on the current regulation domain. */ - ath_hal_get_regdomain(ah, &ath_regdomain); - ath_hal_getcountrycode(ah, &ath_countrycode); + error = ath_getchannels(sc, ath_outdoor, ath_xchanmode); + if (error != 0) + goto bad; /* * Setup rate tables for all potential media types. @@ -414,7 +410,13 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) if (sc->sc_powerhook == NULL) printf(": WARNING: unable to establish power hook\n"); - printf(", %s, address %s\n", ieee80211_regdomain2name(ath_regdomain), + /* + * Print regulation domain and the mac address. The regulation domain + * will be marked with a * if the EEPROM value has been overwritten. + */ + printf(", %s%s, address %s\n", + ieee80211_regdomain2name(ah->ah_regdomain), + ah->ah_regdomain != ah->ah_regdomain_hw ? "*" : "", ether_sprintf(ic->ic_myaddr)); if (ath_gpio_attach(sc, devid) == 0) @@ -3008,8 +3010,7 @@ ath_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew) } int -ath_getchannels(struct ath_softc *sc, u_int cc, HAL_BOOL outdoor, - HAL_BOOL xchanmode) +ath_getchannels(struct ath_softc *sc, HAL_BOOL outdoor, HAL_BOOL xchanmode) { struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = &ic->ic_if; @@ -3025,7 +3026,7 @@ ath_getchannels(struct ath_softc *sc, u_int cc, HAL_BOOL outdoor, return ENOMEM; } if (!ath_hal_init_channels(ah, chans, IEEE80211_CHAN_MAX, &nchan, - cc, HAL_MODE_ALL, outdoor, xchanmode)) { + HAL_MODE_ALL, outdoor, xchanmode)) { printf("%s: unable to collect channel list from hal\n", ifp->if_xname); free(chans, M_TEMP); @@ -3063,8 +3064,8 @@ ath_getchannels(struct ath_softc *sc, u_int cc, HAL_BOOL outdoor, if (sc->sc_nchan < 1) { printf("%s: no valid channels for regdomain %s(%u)\n", - ifp->if_xname, ieee80211_regdomain2name(ath_regdomain), - sc->sc_ah->ah_capabilities.cap_eeprom.ee_regdomain); + ifp->if_xname, ieee80211_regdomain2name(ah->ah_regdomain), + ah->ah_regdomain); return ENOENT; } diff --git a/sys/dev/ic/athvar.h b/sys/dev/ic/athvar.h index 6596ddc29fa..f9340714ef9 100644 --- a/sys/dev/ic/athvar.h +++ b/sys/dev/ic/athvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: athvar.h,v 1.15 2005/09/22 10:17:04 reyk Exp $ */ +/* $OpenBSD: athvar.h,v 1.16 2005/09/23 20:06:50 reyk Exp $ */ /* $NetBSD: athvar.h,v 1.10 2004/08/10 01:03:53 dyoung Exp $ */ /*- @@ -491,8 +491,6 @@ int ath_enable(struct ath_softc *); ((*(_ah)->ah_set_associd)((_ah), (_bss), (_associd), 0)) #define ath_hal_get_regdomain(_ah, _prd) \ (*(_prd) = (_ah)->ah_get_regdomain(_ah)) -#define ath_hal_getcountrycode(_ah, _pcc) \ - (*(_pcc) = (_ah)->ah_getcountrycode) #define ath_hal_detach(_ah) \ ((*(_ah)->ah_detach)(_ah)) #define ath_hal_set_slot_time(_ah, _t) \ -- cgit v1.2.3