Date: Wed, 20 Feb 2008 00:25:09 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 135761 for review Message-ID: <200802200025.m1K0P93x041839@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=135761 Change 135761 by sam@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) \
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200802200025.m1K0P93x041839>