PERFORCE change 135761 for review
Sam Leffler
sam at FreeBSD.org
Wed Feb 20 00:25:10 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=135761
Change 135761 by sam at sam_ebb on 2008/02/20 00:25:08
hookup regdomain support
Affected files ...
.. //depot/projects/vap/sys/dev/ath/if_ath.c#29 edit
.. //depot/projects/vap/sys/dev/ath/if_athvar.h#15 edit
Differences ...
==== //depot/projects/vap/sys/dev/ath/if_ath.c#29 (text+ko) ====
@@ -178,8 +178,12 @@
static int ath_newstate(struct ieee80211vap *, 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 *,
- HAL_REG_DOMAIN, HAL_CTRY_CODE, HAL_BOOL, HAL_BOOL);
+static int ath_setregdomain(struct ieee80211com *,
+ struct ieee80211_regdomain *, int,
+ struct ieee80211_channel []);
+static void ath_getradiocaps(struct ieee80211com *, int *,
+ struct ieee80211_channel []);
+static int ath_getchannels(struct ath_softc *);
static void ath_led_event(struct ath_softc *, int);
static int ath_rate_setup(struct ath_softc *, u_int mode);
@@ -197,21 +201,6 @@
static int ath_calinterval = 30; /* calibrate every 30 secs */
SYSCTL_INT(_hw_ath, OID_AUTO, calibrate, CTLFLAG_RW, &ath_calinterval,
0, "chip calibration interval (secs)");
-static int ath_outdoor = AH_TRUE; /* outdoor operation */
-SYSCTL_INT(_hw_ath, OID_AUTO, outdoor, CTLFLAG_RW, &ath_outdoor,
- 0, "outdoor operation");
-TUNABLE_INT("hw.ath.outdoor", &ath_outdoor);
-static int ath_xchanmode = AH_TRUE; /* extended channel use */
-SYSCTL_INT(_hw_ath, OID_AUTO, xchanmode, CTLFLAG_RW, &ath_xchanmode,
- 0, "extended channel mode");
-TUNABLE_INT("hw.ath.xchanmode", &ath_xchanmode);
-static int ath_countrycode = CTRY_DEFAULT; /* country code */
-SYSCTL_INT(_hw_ath, OID_AUTO, countrycode, CTLFLAG_RW, &ath_countrycode,
- 0, "country code");
-TUNABLE_INT("hw.ath.countrycode", &ath_countrycode);
-static int ath_regdomain = 0; /* regulatory domain */
-SYSCTL_INT(_hw_ath, OID_AUTO, regdomain, CTLFLAG_RD, &ath_regdomain,
- 0, "regulatory domain");
static int ath_rxbuf = ATH_RXBUF; /* # rx buffers to allocate */
SYSCTL_INT(_hw_ath, OID_AUTO, rxbuf, CTLFLAG_RW, &ath_rxbuf,
@@ -350,13 +339,9 @@
ath_hal_keyreset(ah, i);
/*
- * 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.
+ * Collect the default channel list.
*/
- error = ath_getchannels(sc, ath_regdomain, ath_countrycode,
- ath_outdoor != 0, ath_xchanmode != 0);
+ error = ath_getchannels(sc);
if (error != 0)
goto bad;
@@ -583,7 +568,7 @@
sc->sc_hastsfadd = ath_hal_hastsfadjust(ah);
if (ath_hal_hasfastframes(ah))
ic->ic_caps |= IEEE80211_C_FF;
- if (ath_hal_getwirelessmodes(ah, ath_countrycode) & (HAL_MODE_108G|HAL_MODE_TURBO))
+ if (ath_hal_getwirelessmodes(ah, ic->ic_regdomain.country) & (HAL_MODE_108G|HAL_MODE_TURBO))
ic->ic_caps |= IEEE80211_C_TURBOP;
/*
@@ -610,6 +595,8 @@
ic->ic_max_keyix = sc->sc_keymax;
/* call MI attach routine. */
ieee80211_ifattach(ic);
+ ic->ic_setregdomain = ath_setregdomain;
+ ic->ic_getradiocaps = ath_getradiocaps;
sc->sc_opmode = HAL_M_STA;
/* override default methods */
@@ -5694,43 +5681,40 @@
}
static int
-ath_getchannels(struct ath_softc *sc,
- HAL_REG_DOMAIN rd, HAL_CTRY_CODE cc, HAL_BOOL outdoor, HAL_BOOL xchanmode)
+getchannels(struct ath_softc *sc, int *nchans, struct ieee80211_channel chans[],
+ int cc, int ecm, int outdoor)
{
- struct ieee80211com *ic = &sc->sc_ic;
- struct ifnet *ifp = sc->sc_ifp;
struct ath_hal *ah = sc->sc_ah;
- HAL_CHANNEL *chans;
- int i, nchan;
- u_int32_t regdomain;
+ HAL_CHANNEL *halchans;
+ int i, nhalchans, error;
- chans = malloc(IEEE80211_CHAN_MAX * sizeof(HAL_CHANNEL),
+ halchans = malloc(IEEE80211_CHAN_MAX * sizeof(HAL_CHANNEL),
M_TEMP, M_NOWAIT);
- if (chans == NULL) {
- if_printf(ifp, "unable to allocate channel table\n");
+ if (halchans == NULL) {
+ device_printf(sc->sc_dev,
+ "%s: unable to allocate channel table\n", __func__);
return ENOMEM;
}
- if (!ath_hal_init_channels(ah, chans, IEEE80211_CHAN_MAX, &nchan,
- NULL, 0, NULL, cc, HAL_MODE_ALL, outdoor, xchanmode)) {
- (void) ath_hal_getregdomain(ah, ®domain);
- if_printf(ifp, "unable to collect channel list from hal; "
- "regdomain likely %u country code %u\n", regdomain, cc);
- free(chans, M_TEMP);
- return EINVAL;
+ error = 0;
+ if (!ath_hal_init_channels(ah, halchans, IEEE80211_CHAN_MAX, &nhalchans,
+ NULL, 0, NULL, CTRY_DEFAULT, HAL_MODE_ALL, AH_FALSE, AH_TRUE)) {
+ error = EINVAL;
+ goto done;
}
+ if (nchans == NULL) /* no table requested */
+ goto done;
/*
* Convert HAL channels to ieee80211 ones.
*/
- memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
- for (i = 0; i < nchan; i++) {
- HAL_CHANNEL *c = &chans[i];
- struct ieee80211_channel *ichan = &ic->ic_channels[i];
+ for (i = 0; i < nhalchans; i++) {
+ HAL_CHANNEL *c = &halchans[i];
+ struct ieee80211_channel *ichan = &chans[i];
ichan->ic_ieee = ath_hal_mhz2ieee(ah, c->channel,
c->channelFlags);
if (bootverbose)
- if_printf(ifp, "hal channel %u/%x -> %u\n",
+ device_printf(sc->sc_dev, "hal channel %u/%x -> %u\n",
c->channel, c->channelFlags, ichan->ic_ieee);
ichan->ic_freq = c->channel;
@@ -5756,12 +5740,94 @@
ichan->ic_maxpower = c->maxTxPower; /* 1/2 dBm */
ichan->ic_minpower = c->minTxPower; /* 1/2 dBm */
}
- ic->ic_nchans = nchan;
- free(chans, M_TEMP);
- (void) ath_hal_getregdomain(ah, &sc->sc_regdomain);
- ath_hal_getcountrycode(ah, &sc->sc_countrycode);
- sc->sc_xchanmode = xchanmode;
- sc->sc_outdoor = outdoor;
+ *nchans = nhalchans;
+done:
+ free(halchans, M_TEMP);
+ return error;
+}
+
+static int
+ath_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd,
+ int nchans, struct ieee80211_channel chans[])
+{
+ struct ath_softc *sc = ic->ic_ifp->if_softc;
+ struct ath_hal *ah = sc->sc_ah;
+ u_int32_t ord;
+ int error;
+
+ (void) ath_hal_getregdomain(ah, &ord);
+ /* XXX map sku->rd */
+ ath_hal_setregdomain(ah, rd->regdomain);
+ error = getchannels(sc, &nchans, chans, rd->country,
+ rd->ecm ? AH_TRUE : AH_FALSE,
+ rd->location == 'O' ? AH_TRUE : AH_FALSE);
+ if (error != 0) {
+ /*
+ * Restore previous state.
+ */
+ ath_hal_setregdomain(ah, ord);
+ (void) getchannels(sc, NULL, NULL, ic->ic_regdomain.country,
+ ic->ic_regdomain.ecm ? AH_TRUE : AH_FALSE,
+ ic->ic_regdomain.location == 'O' ? AH_TRUE : AH_FALSE);
+ return error;
+ }
+ return 0;
+}
+
+static void
+ath_getradiocaps(struct ieee80211com *ic,
+ int *nchans, struct ieee80211_channel chans[])
+{
+ struct ath_softc *sc = ic->ic_ifp->if_softc;
+ struct ath_hal *ah = sc->sc_ah;
+ u_int32_t ord;
+
+ (void) ath_hal_getregdomain(ah, &ord);
+ ath_hal_setregdomain(ah, 0);
+ /* XXX not quite right but close enough for now */
+ getchannels(sc, nchans, chans, CTRY_DEBUG, AH_TRUE, AH_FALSE);
+ ath_hal_setregdomain(ah, ord);
+}
+
+static int
+ath_mapregdomain(struct ath_softc *sc, u_int32_t rd)
+{
+ /* map Atheros rd's to SKU's */
+ return rd;
+}
+
+static int
+ath_getchannels(struct ath_softc *sc)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ath_hal *ah = sc->sc_ah;
+ u_int32_t rd, cc;
+ int error;
+
+ /*
+ * Convert HAL channels to ieee80211 ones.
+ */
+ error = getchannels(sc, &ic->ic_nchans, ic->ic_channels,
+ CTRY_DEFAULT, AH_TRUE, AH_FALSE);
+ (void) ath_hal_getregdomain(ah, &rd);
+ ath_hal_getcountrycode(ah, &cc); /* NB: cannot fail */
+ if (error) {
+ device_printf(sc->sc_dev,
+ "%s: unable to collect channel list from hal, error %d\n",
+ __func__, error);
+ if (error == EINVAL) {
+ device_printf(sc->sc_dev,
+ "%s: regdomain likely %u country code %u\n",
+ __func__, rd, cc);
+ }
+ return error;
+ }
+ ic->ic_regdomain.regdomain = ath_mapregdomain(sc, rd);
+ ic->ic_regdomain.country = cc;
+ ic->ic_regdomain.ecm = 1;
+ ic->ic_regdomain.location = 'I';
+ ic->ic_regdomain.isocc[0] = ' '; /* XXX don't know */
+ ic->ic_regdomain.isocc[1] = ' ';
return 0;
}
==== //depot/projects/vap/sys/dev/ath/if_athvar.h#15 (text+ko) ====
@@ -209,8 +209,6 @@
u_int8_t sc_nbssid0; /* # vap's using base mac */
uint32_t sc_bssidmask; /* bssid mask */
- u_int32_t sc_countrycode;
- u_int32_t sc_regdomain;
void (*sc_node_free)(struct ieee80211_node *);
device_t sc_dev;
HAL_BUS_TAG sc_st; /* bus space tag */
@@ -497,7 +495,7 @@
#define ath_hal_getregdomain(_ah, _prd) \
(ath_hal_getcapability(_ah, HAL_CAP_REG_DMN, 0, (_prd)) == HAL_OK)
#define ath_hal_setregdomain(_ah, _rd) \
- ((*(_ah)->ah_setRegulatoryDomain)((_ah), (_rd), NULL))
+ (*(uint16_t *)(((uint8_t *)(_ah)) + 520) = (_rd))
#define ath_hal_getcountrycode(_ah, _pcc) \
(*(_pcc) = (_ah)->ah_countryCode)
#define ath_hal_hastkipsplit(_ah) \
More information about the p4-projects
mailing list