26#include <net80211/_ieee80211.h>
27#include <net80211/ieee80211_regdomain.h>
42#define HAL_MODE_11A_TURBO HAL_MODE_108A
43#define HAL_MODE_11G_TURBO HAL_MODE_108G
48#define MULTI_DOMAIN_MASK 0xFF00
58#define WORLD_SKU_MASK 0x00F0
59#define WORLD_SKU_PREFIX 0x0060
73#define COUNTRY_ERD_FLAG 0x8000
74#define WORLDWIDE_ROAMING_FLAG 0x4000
137 return AH_PRIVATE(ah)->ah_currentRD &~ WORLDWIDE_ROAMING_FLAG;
147#error "add more cases"
153 return (bitmask[0] == 0);
167 uint16_t cc = rd &~ COUNTRY_ERD_FLAG;
182 "%s: invalid regulatory domain/country code 0x%x\n", __func__, rd);
240 uint16_t cc = rd & ~COUNTRY_ERD_FLAG;
255 int byteOffset, bitnum;
259 bitnum = bit - byteOffset*64;
260 val = ((uint64_t) 1) << bitnum;
261 return (bitmask[byteOffset] & val) != 0;
272 if (cc == CTRY_DEFAULT && regDmn == SKU_NONE) {
282 "%s: invalid EEPROM contents\n",__func__);
290 "NULL Country!, cc %d\n", cc);
295 __func__, cc, regDmn);
308 "%s: EEPROM rd 0x%x\n", __func__, rdnum);
315 "unknown country, cc %d\n", cc);
318 if (regDmn == SKU_NONE)
321 __func__, cc, regDmn);
331 "%s: no reg domain pair %u for country %u\n",
338 "%s: no 5GHz reg domain %u for country %u\n",
345 "%s: no 2GHz reg domain %u for country %u\n",
353 "%s: no unitary reg domain %u for country %u\n",
405 c->ic_flags |= IEEE80211_CHAN_PASSIVE;
407 c->ic_flags |= IEEE80211_CHAN_DFS;
409 c->ic_flags |= IEEE80211_CHAN_NOADHOC;
410 if (IEEE80211_IS_CHAN_TURBO(c) &&
412 c->ic_flags |= IEEE80211_CHAN_NOADHOC;
414 c->ic_flags |= IEEE80211_CHAN_NOHOSTAP;
416 c->ic_flags |= IEEE80211_CHAN_4MSXMIT;
423 u_int maxchans,
int *nchans, uint16_t freq, uint32_t
flags,
426 struct ieee80211_channel *c;
428 if (*nchans >= maxchans)
432 "%s: %d: freq=%d, flags=0x%08x\n",
433 __func__, *nchans, (
int) freq, flags);
435 c = &chans[(*nchans)++];
439 c->ic_maxregpower = fband->
powerDfs;
448 u_int maxchans,
int *nchans, uint16_t freq, uint32_t flags)
450 struct ieee80211_channel *c;
455 if (*nchans >= maxchans)
459 "%s: %d: freq=%d, flags=0x%08x\n",
460 __func__, *nchans, (
int) freq, flags);
462 c = &chans[(*nchans)++];
473 int maxchans,
int *nchans, uint16_t freq_lo, uint16_t freq_hi,
int step,
476 uint16_t freq = freq_lo;
479 if (freq_hi < freq_lo)
483 "%s: freq=%d..%d, flags=0x%08x, step=%d\n", __func__,
484 (
int) freq_lo, (
int) freq_hi, flags, step);
486 error =
addchan(ah, chans, maxchans, nchans, freq, flags, fband, rd);
487 for (freq += step; freq <= freq_hi && error == 0; freq += step)
488 error =
copychan_prev(ah, chans, maxchans, nchans, freq, flags);
497 *low_adj = *hi_adj = *channelSep = 0;
520 uint16_t freq_lo, freq_hi;
521 int b, error, low_adj, hi_adj, channelSep;
526 "%s: channels 0x%x not supported by hardware\n",
527 __func__, cm->
flags);
541 for (b = 0; b < 64*
BMLEN; b++) {
543 uint16_t bfreq_lo, bfreq_hi;
548 fband = &cm->
freqs[b];
551 !enableExtendedChannels) {
553 "skip ecm channels\n");
558 (cm->
flags & IEEE80211_CHAN_HT40)) {
561 "skip HT40 chan, DFS required\n");
583 if ((cm->
flags & IEEE80211_CHAN_5GHZ) &&
584 (cm->
flags & IEEE80211_CHAN_HT40U)) {
593 if ((cm->
flags & IEEE80211_CHAN_5GHZ) &&
594 (cm->
flags & IEEE80211_CHAN_HT40D)) {
605 "%s: freq_lo=%d, freq_hi=%d, low_adj=%d, hi_adj=%d, "
606 "bandlo=%d, bandhi=%d, bfreqlo=%d, bfreqhi=%d, step=%d, "
621 bfreq_lo, bfreq_hi, step, cm->
flags, fband, rd);
624 "%s: too many channels for channel table\n",
634#define HAL_MODE_11A_ALL \
635 (HAL_MODE_11A | HAL_MODE_11A_TURBO | HAL_MODE_TURBO | \
636 HAL_MODE_11A_QUARTER_RATE | HAL_MODE_11A_HALF_RATE)
641 modesMask &= modeSelect;
646 "%s: disallow all 11a\n", __func__);
647 modesMask &= ~HAL_MODE_11A_ALL;
651#undef HAL_MODE_11A_ALL
659 struct ieee80211_channel chans[], u_int maxchans,
int *nchans,
667 const struct cmode *cm;
671 __func__, cc, regDmn, modeSelect,
672 enableExtendedChannels ?
" ecm" :
"");
674 status =
getregstate(ah, cc, regDmn, pcountry, &rd2GHz, &rd5GHz);
686 if ((cm->
mode & modesMask) == 0) {
688 "%s: skip mode 0x%x flags 0x%x\n",
693 if (cm->
flags & IEEE80211_CHAN_5GHZ)
695 else if (cm->
flags & IEEE80211_CHAN_2GHZ)
699 __func__, cm->
flags);
704 rd, enableExtendedChannels);
705 if (*nchans >= maxchans)
722 struct ieee80211_channel chans[], u_int maxchans,
int *nchans,
726 return getchannels(ah, chans, maxchans, nchans, modeSelect,
740 if (sku == SKU_GZ901)
744 if (sku == SKU_XC900M)
747 "%s: cannot map freq %u unknown gsm sku %u\n",
748 __func__, freq, sku);
760 struct ieee80211_channel chans[],
int nchans,
int sku)
763 int i, j, next, freq;
766 for (i = 0; i < nchans; i++) {
767 struct ieee80211_channel *c = &chans[i];
768 for (j = i-1; j >= 0; j--)
769 if (chans[j].ic_freq == c->ic_freq) {
770 c->ic_devdata = chans[j].ic_devdata;
777 "%s: too many channels, max %zu\n",
787 freq = IEEE80211_IS_CHAN_GSM(c) ?
791 "%s: private[%3u] %u/0x%x -> channel %u\n",
792 __func__, next, c->ic_freq, c->ic_flags, freq);
802 c->ic_devdata = next;
808 __func__, nchans, next);
817 struct ieee80211_channel chans[], u_int maxchans,
int *nchans,
825 status =
getchannels(ah, chans, maxchans, nchans, modeSelect,
826 cc, regDmn, enableExtendedChannels, &country, &rd2GHz, &rd5GHz);
849 struct ieee80211_channel chans[],
int nchans,
869 &country, &rd2GHz, &rd5GHz);
873 &country, &rd2GHz, &rd5GHz);
904 if (c->ic_devdata <
AH_PRIVATE(ah)->ah_nchan &&
905 (c->ic_freq == cc->
channel || IEEE80211_IS_CHAN_GSM(c)))
907 if (c->ic_devdata >=
AH_PRIVATE(ah)->ah_nchan) {
909 "%s: bad mapping, devdata %u nchans %u\n",
910 __func__, c->ic_devdata,
AH_PRIVATE(ah)->ah_nchan);
914 "%s: no match for %u/0x%x devdata %u channel %u\n",
915 __func__, c->ic_freq, c->ic_flags, c->ic_devdata,
923#define isWwrSKU(_ah) \
924 ((getEepromRD((_ah)) & WORLD_SKU_MASK) == WORLD_SKU_PREFIX || \
925 getEepromRD(_ah) == WORLD)
939 else if (IEEE80211_IS_CHAN_2GHZ(c))
940 ctl =
AH_PRIVATE(ah)->ah_rd2GHz->conformanceTestLimit;
942 ctl =
AH_PRIVATE(ah)->ah_rd5GHz->conformanceTestLimit;
943 if (IEEE80211_IS_CHAN_B(c))
945 if (IEEE80211_IS_CHAN_G(c))
947 if (IEEE80211_IS_CHAN_108G(c))
949 if (IEEE80211_IS_CHAN_TURBO(c))
951 if (IEEE80211_IS_CHAN_A(c))
992 const struct ieee80211_channel *chan, u_int twiceGain)
994 int8_t antennaMax = twiceGain - chan->ic_maxantgain*2;
995 return (antennaMax < 0) ? 0 : antennaMax;
@ HAL_MODE_11G_QUARTER_RATE
@ HAL_MODE_11A_QUARTER_RATE
@ HAL_MODE_11NG_HT40MINUS
@ HAL_MODE_11NA_HT40MINUS
#define ath_hal_getWirelessModes(_ah)
static OS_INLINE HAL_CHANNEL_INTERNAL * ath_hal_checkchannel(struct ath_hal *ah, const struct ieee80211_channel *c)
#define ath_hal_getChannelEdges(_ah, _cf, _lc, _hc)
#define HALDEBUG(_ah, __m,...)
#define ath_hal_getpowerlimits(_ah, _chan)
#define CHANNEL_NFCREQUIRED
void ath_hal_printf(struct ath_hal *, const char *,...)
#define OS_MEMZERO(_a, _n)
static COUNTRY_CODE_TO_ENUM_RD allCountries[]
static REG_DOMAIN regDomains[]
static REG_DMN_FREQ_BAND regDmn2Ghz11gTurboFreq[]
static REG_DMN_FREQ_BAND regDmn5GhzFreq[]
static REG_DMN_FREQ_BAND regDmn5GhzTurboFreq[]
static REG_DMN_FREQ_BAND regDmn2GhzFreq[]
static REG_DMN_FREQ_BAND regDmn2Ghz11gFreq[]
static REG_DMN_PAIR_MAPPING regDomainPairs[]
static REG_DOMAIN * findRegDmn(int regDmn)
static void ath_hal_update_dfsdomain(struct ath_hal *ah)
u_int ath_hal_getantennareduction(struct ath_hal *ah, const struct ieee80211_channel *chan, u_int twiceGain)
static HAL_BOOL assignPrivateChannels(struct ath_hal *ah, struct ieee80211_channel chans[], int nchans, int sku)
#define HAL_MODE_11G_TURBO
static int add_chanlist_band(struct ath_hal *ah, struct ieee80211_channel chans[], int maxchans, int *nchans, uint16_t freq_lo, uint16_t freq_hi, int step, uint32_t flags, REG_DMN_FREQ_BAND *fband, REG_DOMAIN *rd)
static void adj_freq_ht40(u_int mode, int *low_adj, int *hi_adj, int *channelSep)
static HAL_BOOL isChanBitMaskZero(const uint64_t *bitmask)
#define HAL_MODE_11A_TURBO
HAL_STATUS ath_hal_getchannels(struct ath_hal *ah, struct ieee80211_channel chans[], u_int maxchans, int *nchans, u_int modeSelect, HAL_CTRY_CODE cc, HAL_REG_DOMAIN regDmn, HAL_BOOL enableExtendedChannels)
static const struct cmode modes[]
static void setchannelflags(struct ieee80211_channel *c, REG_DMN_FREQ_BAND *fband, REG_DOMAIN *rd)
static HAL_STATUS getregstate(struct ath_hal *ah, HAL_CTRY_CODE cc, HAL_REG_DOMAIN regDmn, COUNTRY_CODE_TO_ENUM_RD **pcountry, REG_DOMAIN **prd2GHz, REG_DOMAIN **prd5GHz)
static OS_INLINE uint16_t getEepromRD(struct ath_hal *ah)
static int ath_hal_mapgsm(int sku, int freq)
static void add_chanlist_mode(struct ath_hal *ah, struct ieee80211_channel chans[], u_int maxchans, int *nchans, const struct cmode *cm, REG_DOMAIN *rd, HAL_BOOL enableExtendedChannels)
#define MULTI_DOMAIN_MASK
static REG_DMN_PAIR_MAPPING * findRegDmnPair(int regDmnPair)
static int addchan(struct ath_hal *ah, struct ieee80211_channel chans[], u_int maxchans, int *nchans, uint16_t freq, uint32_t flags, REG_DMN_FREQ_BAND *fband, REG_DOMAIN *rd)
static uint64_t * getchannelBM(u_int mode, REG_DOMAIN *rd)
static HAL_CTRY_CODE getDefaultCountry(struct ath_hal *ah)
static HAL_STATUS getchannels(struct ath_hal *ah, struct ieee80211_channel chans[], u_int maxchans, int *nchans, u_int modeSelect, HAL_CTRY_CODE cc, HAL_REG_DOMAIN regDmn, HAL_BOOL enableExtendedChannels, COUNTRY_CODE_TO_ENUM_RD **pcountry, REG_DOMAIN **prd2GHz, REG_DOMAIN **prd5GHz)
HAL_STATUS ath_hal_set_channels(struct ath_hal *ah, struct ieee80211_channel chans[], int nchans, HAL_CTRY_CODE cc, HAL_REG_DOMAIN rd)
static HAL_BOOL IS_BIT_SET(int bit, const uint64_t bitmask[])
HAL_STATUS ath_hal_init_channels(struct ath_hal *ah, struct ieee80211_channel chans[], u_int maxchans, int *nchans, u_int modeSelect, HAL_CTRY_CODE cc, HAL_REG_DOMAIN regDmn, HAL_BOOL enableExtendedChannels)
static HAL_BOOL isEepromValid(struct ath_hal *ah)
static u_int getmodesmask(struct ath_hal *ah, REG_DOMAIN *rd5GHz, u_int modeSelect)
u_int ath_hal_getctl(struct ath_hal *ah, const struct ieee80211_channel *c)
static COUNTRY_CODE_TO_ENUM_RD * findCountry(HAL_CTRY_CODE countryCode)
static int copychan_prev(struct ath_hal *ah, struct ieee80211_channel chans[], u_int maxchans, int *nchans, uint16_t freq, uint32_t flags)
@ DISALLOW_ADHOC_11A_TURB
HAL_REG_DOMAIN regDmnEnum
HAL_CTRY_CODE countryCode
HAL_CTRY_CODE ah_countryCode
REG_DMN_FREQ_BAND * freqs
HAL_REG_DOMAIN regDmn5GHz
HAL_REG_DOMAIN regDmn2GHz
chanbmask_t chan11a_dyn_turbo
chanbmask_t chan11a_turbo
chanbmask_t chan11g_quarter
chanbmask_t chan11a_quarter
chanbmask_t chan11g_turbo