summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/ic/ar5xxx.c81
-rw-r--r--sys/dev/ic/ar5xxx.h9
-rw-r--r--sys/dev/ic/ath.c45
-rw-r--r--sys/dev/ic/athvar.h4
4 files changed, 60 insertions, 79 deletions
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 <reyk@vantronix.net>
@@ -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 <reyk@vantronix.net>
@@ -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) \