static void print_chaninfo(const struct ieee80211_channel *c) { #define IEEE80211_IS_CHAN_PASSIVE(_c) \ (((_c)->ic_flags & IEEE80211_CHAN_PASSIVE)) char buf[14]; buf[0] = '\0'; if (IEEE80211_IS_CHAN_FHSS(c)) strlcat(buf, " FHSS", sizeof(buf)); if (IEEE80211_IS_CHAN_A(c)) strlcat(buf, " 11a", sizeof(buf)); /* XXX 11g schizophrenia */ if (IEEE80211_IS_CHAN_G(c) || IEEE80211_IS_CHAN_PUREG(c)) strlcat(buf, " 11g", sizeof(buf)); else if (IEEE80211_IS_CHAN_B(c)) strlcat(buf, " 11b", sizeof(buf)); if (IEEE80211_IS_CHAN_STURBO(c)) strlcat(buf, " Static", sizeof(buf)); if (IEEE80211_IS_CHAN_DTURBO(c)) strlcat(buf, " Dynamic", sizeof(buf)); printf("Channel %3u : %u%c Mhz%-14.14s", c->ic_ieee, c->ic_freq, IEEE80211_IS_CHAN_PASSIVE(c) ? '*' : ' ', buf); #undef IEEE80211_IS_CHAN_PASSIVE }
static void print_chaninfo(const struct ieee80211_channel *c) { char buf[14]; buf[0] = '\0'; if (IEEE80211_IS_CHAN_FHSS(c)) strlcat(buf, " FHSS", sizeof(buf)); if (IEEE80211_IS_CHAN_A(c)) strlcat(buf, " 11a", sizeof(buf)); /* XXX 11g schizophrenia */ if (IEEE80211_IS_CHAN_G(c) || IEEE80211_IS_CHAN_PUREG(c)) strlcat(buf, " 11g", sizeof(buf)); else if (IEEE80211_IS_CHAN_B(c)) strlcat(buf, " 11b", sizeof(buf)); if (IEEE80211_IS_CHAN_STURBO(c)) strlcat(buf, " Static", sizeof(buf)); if (IEEE80211_IS_CHAN_DTURBO(c)) strlcat(buf, " Dynamic", sizeof(buf)); if (IEEE80211_IS_CHAN_HALF(c)) strlcat(buf, " Half", sizeof(buf)); if (IEEE80211_IS_CHAN_QUARTER(c)) strlcat(buf, " Quarter", sizeof(buf)); printf("Channel %3u : %u%c%c Mhz%-14.14s", c->ic_ieee, c->ic_freq, IEEE80211_IS_CHAN_PASSIVE(c) ? '*' : ' ', IEEE80211_IS_CHAN_RADAR(c) ? '!' : ' ', buf); }
static int iwm_mvm_scan_skip_channel(struct ieee80211_channel *c) { if (IEEE80211_IS_CHAN_2GHZ(c) && IEEE80211_IS_CHAN_B(c)) return 0; else if (IEEE80211_IS_CHAN_5GHZ(c) && IEEE80211_IS_CHAN_A(c)) return 0; else return 1; }
static void dumpchannels(struct ath_hal *ah, int nc, const struct ieee80211_channel *chans, int16_t *txpow) { int i; for (i = 0; i < nc; i++) { const struct ieee80211_channel *c = &chans[i]; int type; if (showchannels) printf("%s%3d", sep, ath_hal_mhz2ieee(ah, c->ic_freq, c->ic_flags)); else printf("%s%u", sep, c->ic_freq); if (IEEE80211_IS_CHAN_HALF(c)) type = 'H'; else if (IEEE80211_IS_CHAN_QUARTER(c)) type = 'Q'; else if (IEEE80211_IS_CHAN_TURBO(c)) type = 'T'; else if (IEEE80211_IS_CHAN_HT(c)) type = 'N'; else if (IEEE80211_IS_CHAN_A(c)) type = 'A'; else if (IEEE80211_IS_CHAN_108G(c)) type = 'T'; else if (IEEE80211_IS_CHAN_G(c)) type = 'G'; else type = 'B'; if (dopassive && IEEE80211_IS_CHAN_PASSIVE(c)) type = tolower(type); if (isdfs && is4ms) printf("%c%c%c %d.%d", type, IEEE80211_IS_CHAN_DFS(c) ? '*' : ' ', IEEE80211_IS_CHAN_4MS(c) ? '4' : ' ', txpow[i]/2, (txpow[i]%2)*5); else if (isdfs) printf("%c%c %d.%d", type, IEEE80211_IS_CHAN_DFS(c) ? '*' : ' ', txpow[i]/2, (txpow[i]%2)*5); else if (is4ms) printf("%c%c %d.%d", type, IEEE80211_IS_CHAN_4MS(c) ? '4' : ' ', txpow[i]/2, (txpow[i]%2)*5); else printf("%c %d.%d", type, txpow[i]/2, (txpow[i]%2)*5); if ((n++ % (showchannels ? 7 : 6)) == 0) sep = "\n"; else sep = " "; } }
static int iwm_mvm_scan_fill_channels(struct iwm_softc *sc, struct iwm_scan_cmd *cmd, int flags, int n_ssids, int basic_ssid) { struct ieee80211com *ic = sc->sc_ic; uint16_t passive_dwell = iwm_mvm_get_passive_dwell(sc, flags); uint16_t active_dwell = iwm_mvm_get_active_dwell(sc, flags, n_ssids); struct iwm_scan_channel *chan = (struct iwm_scan_channel *) (cmd->data + le16toh(cmd->tx_cmd.len)); int type = (1 << n_ssids) - 1; struct ieee80211_channel *c; int nchan, j; if (!basic_ssid) type |= (1 << n_ssids); for (nchan = j = 0; j < ic->ic_nchans; j++) { c = &ic->ic_channels[j]; /* For 2GHz, only populate 11b channels */ /* For 5GHz, only populate 11a channels */ /* * Catch other channels, in case we have 900MHz channels or * something in the chanlist. */ if ((flags & IEEE80211_CHAN_2GHZ) && (! IEEE80211_IS_CHAN_B(c))) { continue; } else if ((flags & IEEE80211_CHAN_5GHZ) && (! IEEE80211_IS_CHAN_A(c))) { continue; } else { IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_EEPROM, "%s: skipping channel (freq=%d, ieee=%d, flags=0x%08x)\n", __func__, c->ic_freq, c->ic_ieee, c->ic_flags); } IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_EEPROM, "Adding channel %d (%d Mhz) to the list\n", nchan, c->ic_freq); chan->channel = htole16(ieee80211_mhz2ieee(c->ic_freq, flags)); chan->type = htole32(type); if (c->ic_flags & IEEE80211_CHAN_PASSIVE) chan->type &= htole32(~IWM_SCAN_CHANNEL_TYPE_ACTIVE); chan->active_dwell = htole16(active_dwell); chan->passive_dwell = htole16(passive_dwell); chan->iteration_count = htole16(1); chan++; nchan++; } if (nchan == 0) device_printf(sc->sc_dev, "%s: NO CHANNEL!\n", __func__); return nchan; }
void icm_display_channel_flags(ICM_CHANNEL_T* pch) { ICM_DEV_INFO_T* pdev = get_pdev(); if (IEEE80211_IS_CHAN_FHSS(pch)) { ICM_DPRINTF(pdev, ICM_PRCTRL_FLAG_NONE, ICM_DEBUG_LEVEL_DEFAULT, ICM_MODULE_ID_UTIL, "\tFHSS\n"); } if (IEEE80211_IS_CHAN_11NA(pch)) { ICM_DPRINTF(pdev, ICM_PRCTRL_FLAG_NONE, ICM_DEBUG_LEVEL_DEFAULT, ICM_MODULE_ID_UTIL, "\t11na\n"); } else if (IEEE80211_IS_CHAN_A(pch)) { ICM_DPRINTF(pdev, ICM_PRCTRL_FLAG_NONE, ICM_DEBUG_LEVEL_DEFAULT, ICM_MODULE_ID_UTIL, "\t11a\n"); } else if (IEEE80211_IS_CHAN_11NG(pch)) { ICM_DPRINTF(pdev, ICM_PRCTRL_FLAG_NONE, ICM_DEBUG_LEVEL_DEFAULT, ICM_MODULE_ID_UTIL, "\t11ng\n"); } else if (IEEE80211_IS_CHAN_G(pch) || IEEE80211_IS_CHAN_PUREG(pch)) { ICM_DPRINTF(pdev, ICM_PRCTRL_FLAG_NONE, ICM_DEBUG_LEVEL_DEFAULT, ICM_MODULE_ID_UTIL, "\t11g\n"); } else if (IEEE80211_IS_CHAN_B(pch)) { ICM_DPRINTF(pdev, ICM_PRCTRL_FLAG_NONE, ICM_DEBUG_LEVEL_DEFAULT, ICM_MODULE_ID_UTIL, "\t11b\n"); } if (IEEE80211_IS_CHAN_TURBO(pch)) { ICM_DPRINTF(pdev, ICM_PRCTRL_FLAG_NONE, ICM_DEBUG_LEVEL_DEFAULT, ICM_MODULE_ID_UTIL, "\tTurbo\n"); } if(IEEE80211_IS_CHAN_11N_CTL_CAPABLE(pch)) { ICM_DPRINTF(pdev, ICM_PRCTRL_FLAG_NONE, ICM_DEBUG_LEVEL_DEFAULT, ICM_MODULE_ID_UTIL, "\tControl capable\n"); } if(IEEE80211_IS_CHAN_11N_CTL_U_CAPABLE(pch)) { ICM_DPRINTF(pdev, ICM_PRCTRL_FLAG_NONE, ICM_DEBUG_LEVEL_DEFAULT, ICM_MODULE_ID_UTIL, "\tControl capable upper\n"); } if(IEEE80211_IS_CHAN_11N_CTL_L_CAPABLE(pch)) { ICM_DPRINTF(pdev, ICM_PRCTRL_FLAG_NONE, ICM_DEBUG_LEVEL_DEFAULT, ICM_MODULE_ID_UTIL, "\tControl capable lower\n"); } if (IEEE80211_IS_CHAN_DFSFLAG(pch)) { ICM_DPRINTF(pdev, ICM_PRCTRL_FLAG_NONE, ICM_DEBUG_LEVEL_DEFAULT, ICM_MODULE_ID_UTIL, "\tDFS\n"); } if (IEEE80211_IS_CHAN_HALF(pch)) { ICM_DPRINTF(pdev, ICM_PRCTRL_FLAG_NONE, ICM_DEBUG_LEVEL_DEFAULT, ICM_MODULE_ID_UTIL, "\tHalf\n"); } if (IEEE80211_IS_CHAN_PASSIVE(pch)) { ICM_DPRINTF(pdev, ICM_PRCTRL_FLAG_NONE, ICM_DEBUG_LEVEL_DEFAULT, ICM_MODULE_ID_UTIL, "\tPassive\n"); } if (IEEE80211_IS_CHAN_QUARTER(pch)) { ICM_DPRINTF(pdev, ICM_PRCTRL_FLAG_NONE, ICM_DEBUG_LEVEL_DEFAULT, ICM_MODULE_ID_UTIL, "\tQuarter\n"); } }
void ieee80211_channel_init(struct ifnet *ifp) { struct ieee80211com *ic = (void *)ifp; struct ieee80211_channel *c; int i; /* * Fill in 802.11 available channel set, mark * all available channels as active, and pick * a default channel if not already specified. */ memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail)); ic->ic_modecaps |= 1<<IEEE80211_MODE_AUTO; for (i = 0; i <= IEEE80211_CHAN_MAX; i++) { c = &ic->ic_channels[i]; if (c->ic_flags) { /* * Verify driver passed us valid data. */ if (i != ieee80211_chan2ieee(ic, c)) { printf("%s: bad channel ignored; " "freq %u flags %x number %u\n", ifp->if_xname, c->ic_freq, c->ic_flags, i); c->ic_flags = 0; /* NB: remove */ continue; } setbit(ic->ic_chan_avail, i); /* * Identify mode capabilities. */ if (IEEE80211_IS_CHAN_A(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_11A; if (IEEE80211_IS_CHAN_B(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_11B; if (IEEE80211_IS_CHAN_PUREG(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_11G; if (IEEE80211_IS_CHAN_T(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_TURBO; } } /* validate ic->ic_curmode */ if ((ic->ic_modecaps & (1<<ic->ic_curmode)) == 0) ic->ic_curmode = IEEE80211_MODE_AUTO; ic->ic_des_chan = IEEE80211_CHAN_ANYC; /* any channel is ok */ ic->ic_scan_lock = IEEE80211_SCAN_UNLOCKED; }
static char channel_type(const struct ieee80211_channel *c) { if (IEEE80211_IS_CHAN_ST(c)) return 'S'; if (IEEE80211_IS_CHAN_108A(c)) return 'T'; if (IEEE80211_IS_CHAN_108G(c)) return 'G'; if (IEEE80211_IS_CHAN_HT(c)) return 'n'; if (IEEE80211_IS_CHAN_A(c)) return 'a'; if (IEEE80211_IS_CHAN_ANYG(c)) return 'g'; if (IEEE80211_IS_CHAN_B(c)) return 'b'; return 'f'; }
/* * Return the test group for the specific channel based on * the current regulatory setup. */ u_int ath_hal_getctl(struct ath_hal *ah, const struct ieee80211_channel *c) { u_int ctl; if (AH_PRIVATE(ah)->ah_rd2GHz == AH_PRIVATE(ah)->ah_rd5GHz || (ah->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah))) ctl = SD_NO_CTL; else if (IEEE80211_IS_CHAN_2GHZ(c)) ctl = AH_PRIVATE(ah)->ah_rd2GHz->conformanceTestLimit; else ctl = AH_PRIVATE(ah)->ah_rd5GHz->conformanceTestLimit; if (IEEE80211_IS_CHAN_B(c)) return ctl | CTL_11B; if (IEEE80211_IS_CHAN_G(c)) return ctl | CTL_11G; if (IEEE80211_IS_CHAN_108G(c)) return ctl | CTL_108G; if (IEEE80211_IS_CHAN_TURBO(c)) return ctl | CTL_TURBO; if (IEEE80211_IS_CHAN_A(c)) return ctl | CTL_11A; return ctl; }
/* * Fill in 802.11 available channel set, mark * all available channels as active, and pick * a default channel if not already specified. */ static void ieee80211_chan_init(struct ieee80211com *ic) { #define DEFAULTRATES(m, def) do { \ if (ic->ic_sup_rates[m].rs_nrates == 0) \ ic->ic_sup_rates[m] = def; \ } while (0) struct ieee80211_channel *c; int i; KASSERT(0 < ic->ic_nchans && ic->ic_nchans <= IEEE80211_CHAN_MAX, ("invalid number of channels specified: %u", ic->ic_nchans)); memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail)); memset(ic->ic_modecaps, 0, sizeof(ic->ic_modecaps)); setbit(ic->ic_modecaps, IEEE80211_MODE_AUTO); for (i = 0; i < ic->ic_nchans; i++) { c = &ic->ic_channels[i]; KASSERT(c->ic_flags != 0, ("channel with no flags")); /* * Help drivers that work only with frequencies by filling * in IEEE channel #'s if not already calculated. Note this * mimics similar work done in ieee80211_setregdomain when * changing regulatory state. */ if (c->ic_ieee == 0) c->ic_ieee = ieee80211_mhz2ieee(c->ic_freq,c->ic_flags); if (IEEE80211_IS_CHAN_HT40(c) && c->ic_extieee == 0) c->ic_extieee = ieee80211_mhz2ieee(c->ic_freq + (IEEE80211_IS_CHAN_HT40U(c) ? 20 : -20), c->ic_flags); /* default max tx power to max regulatory */ if (c->ic_maxpower == 0) c->ic_maxpower = 2*c->ic_maxregpower; setbit(ic->ic_chan_avail, c->ic_ieee); /* * Identify mode capabilities. */ if (IEEE80211_IS_CHAN_A(c)) setbit(ic->ic_modecaps, IEEE80211_MODE_11A); if (IEEE80211_IS_CHAN_B(c)) setbit(ic->ic_modecaps, IEEE80211_MODE_11B); if (IEEE80211_IS_CHAN_ANYG(c)) setbit(ic->ic_modecaps, IEEE80211_MODE_11G); if (IEEE80211_IS_CHAN_FHSS(c)) setbit(ic->ic_modecaps, IEEE80211_MODE_FH); if (IEEE80211_IS_CHAN_108A(c)) setbit(ic->ic_modecaps, IEEE80211_MODE_TURBO_A); if (IEEE80211_IS_CHAN_108G(c)) setbit(ic->ic_modecaps, IEEE80211_MODE_TURBO_G); if (IEEE80211_IS_CHAN_ST(c)) setbit(ic->ic_modecaps, IEEE80211_MODE_STURBO_A); if (IEEE80211_IS_CHAN_HALF(c)) setbit(ic->ic_modecaps, IEEE80211_MODE_HALF); if (IEEE80211_IS_CHAN_QUARTER(c)) setbit(ic->ic_modecaps, IEEE80211_MODE_QUARTER); if (IEEE80211_IS_CHAN_HTA(c)) setbit(ic->ic_modecaps, IEEE80211_MODE_11NA); if (IEEE80211_IS_CHAN_HTG(c)) setbit(ic->ic_modecaps, IEEE80211_MODE_11NG); } /* initialize candidate channels to all available */ memcpy(ic->ic_chan_active, ic->ic_chan_avail, sizeof(ic->ic_chan_avail)); /* sort channel table to allow lookup optimizations */ ieee80211_sort_channels(ic->ic_channels, ic->ic_nchans); /* invalidate any previous state */ ic->ic_bsschan = IEEE80211_CHAN_ANYC; ic->ic_prevchan = NULL; ic->ic_csa_newchan = NULL; /* arbitrarily pick the first channel */ ic->ic_curchan = &ic->ic_channels[0]; ic->ic_rt = ieee80211_get_ratetable(ic->ic_curchan); /* fillin well-known rate sets if driver has not specified */ DEFAULTRATES(IEEE80211_MODE_11B, ieee80211_rateset_11b); DEFAULTRATES(IEEE80211_MODE_11G, ieee80211_rateset_11g); DEFAULTRATES(IEEE80211_MODE_11A, ieee80211_rateset_11a); DEFAULTRATES(IEEE80211_MODE_TURBO_A, ieee80211_rateset_11a); DEFAULTRATES(IEEE80211_MODE_TURBO_G, ieee80211_rateset_11g); DEFAULTRATES(IEEE80211_MODE_STURBO_A, ieee80211_rateset_11a); DEFAULTRATES(IEEE80211_MODE_HALF, ieee80211_rateset_half); DEFAULTRATES(IEEE80211_MODE_QUARTER, ieee80211_rateset_quarter); DEFAULTRATES(IEEE80211_MODE_11NA, ieee80211_rateset_11a); DEFAULTRATES(IEEE80211_MODE_11NG, ieee80211_rateset_11g); /* * Set auto mode to reset active channel state and any desired channel. */ (void) ieee80211_setmode(ic, IEEE80211_MODE_AUTO); #undef DEFAULTRATES }
void ieee80211_ifattach(struct ieee80211com *ic) { struct ifnet *ifp = ic->ic_ifp; struct ieee80211_channel *c; int i; #ifdef __NetBSD__ ieee80211_init(); #endif /* __NetBSD__ */ ether_ifattach(ifp, ic->ic_myaddr); bpf_attach2(ifp, DLT_IEEE802_11, sizeof(struct ieee80211_frame_addr4), &ic->ic_rawbpf); ieee80211_crypto_attach(ic); /* * Fill in 802.11 available channel set, mark * all available channels as active, and pick * a default channel if not already specified. */ memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail)); ic->ic_modecaps |= 1<<IEEE80211_MODE_AUTO; for (i = 0; i <= IEEE80211_CHAN_MAX; i++) { c = &ic->ic_channels[i]; if (c->ic_flags) { /* * Verify driver passed us valid data. */ if (i != ieee80211_chan2ieee(ic, c)) { if_printf(ifp, "bad channel ignored; " "freq %u flags %x number %u\n", c->ic_freq, c->ic_flags, i); c->ic_flags = 0; /* NB: remove */ continue; } setbit(ic->ic_chan_avail, i); /* * Identify mode capabilities. */ if (IEEE80211_IS_CHAN_A(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_11A; if (IEEE80211_IS_CHAN_B(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_11B; if (IEEE80211_IS_CHAN_PUREG(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_11G; if (IEEE80211_IS_CHAN_FHSS(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_FH; if (IEEE80211_IS_CHAN_T(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_TURBO_A; if (IEEE80211_IS_CHAN_108G(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_TURBO_G; if (ic->ic_curchan == NULL) { /* arbitrarily pick the first channel */ ic->ic_curchan = &ic->ic_channels[i]; } } } /* validate ic->ic_curmode */ if ((ic->ic_modecaps & (1<<ic->ic_curmode)) == 0) ic->ic_curmode = IEEE80211_MODE_AUTO; ic->ic_des_chan = IEEE80211_CHAN_ANYC; /* any channel is ok */ #if 0 /* * Enable WME by default if we're capable. */ if (ic->ic_caps & IEEE80211_C_WME) ic->ic_flags |= IEEE80211_F_WME; #endif (void) ieee80211_setmode(ic, ic->ic_curmode); if (ic->ic_bintval == 0) ic->ic_bintval = IEEE80211_BINTVAL_DEFAULT; ic->ic_bmisstimeout = 7*ic->ic_bintval; /* default 7 beacons */ ic->ic_dtim_period = IEEE80211_DTIM_DEFAULT; IEEE80211_BEACON_LOCK_INIT(ic, "beacon"); if (ic->ic_lintval == 0) ic->ic_lintval = ic->ic_bintval; ic->ic_txpowlimit = IEEE80211_TXPOWER_MAX; LIST_INSERT_HEAD(&ieee80211com_head, ic, ic_list); ieee80211_node_attach(ic); ieee80211_proto_attach(ic); ieee80211_add_vap(ic); ieee80211_sysctl_attach(ic); /* NB: requires ic_vap */ /* * Install a default reset method for the ioctl support. * The driver is expected to fill this in before calling us. */ if (ic->ic_reset == NULL) ic->ic_reset = ieee80211_default_reset; }
/* * Places the device in and out of reset and then places sane * values in the registers based on EEPROM config, initialization * vectors (as determined by the mode), and station configuration * * bChannelChange is used to preserve DMA/PCU registers across * a HW Reset during channel change. */ HAL_BOOL ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode, struct ieee80211_channel *chan, HAL_BOOL bChannelChange, HAL_RESET_TYPE resetType, HAL_STATUS *status) { #define N(a) (sizeof (a) / sizeof (a[0])) #define FAIL(_code) do { ecode = _code; goto bad; } while (0) struct ath_hal_5212 *ahp = AH5212(ah); HAL_CHANNEL_INTERNAL *ichan; const HAL_EEPROM *ee; uint32_t saveFrameSeqCount, saveDefAntenna; uint32_t macStaId1, synthDelay, txFrm2TxDStart; uint16_t rfXpdGain[MAX_NUM_PDGAINS_PER_CHANNEL]; int16_t cckOfdmPwrDelta = 0; u_int modesIndex, freqIndex; HAL_STATUS ecode; int i, regWrites = 0; uint32_t testReg; uint32_t saveLedState = 0; HALASSERT(ah->ah_magic == AR5212_MAGIC); ee = AH_PRIVATE(ah)->ah_eeprom; OS_MARK(ah, AH_MARK_RESET, bChannelChange); /* * Map public channel to private. */ ichan = ath_hal_checkchannel(ah, chan); if (ichan == AH_NULL) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u/0x%x; no mapping\n", __func__, chan->ic_freq, chan->ic_flags); FAIL(HAL_EINVAL); } switch (opmode) { case HAL_M_STA: case HAL_M_IBSS: case HAL_M_HOSTAP: case HAL_M_MONITOR: break; default: HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid operating mode %u\n", __func__, opmode); FAIL(HAL_EINVAL); break; } HALASSERT(ahp->ah_eeversion >= AR_EEPROM_VER3); /* Preserve certain DMA hardware registers on a channel change */ if (bChannelChange) { /* * On Venice, the TSF is almost preserved across a reset; * it requires the doubling writes to the RESET_TSF * bit in the AR_BEACON register; it also has the quirk * of the TSF going back in time on the station (station * latches onto the last beacon's tsf during a reset 50% * of the times); the latter is not a problem for adhoc * stations since as long as the TSF is behind, it will * get resynchronized on receiving the next beacon; the * TSF going backwards in time could be a problem for the * sleep operation (supported on infrastructure stations * only) - the best and most general fix for this situation * is to resynchronize the various sleep/beacon timers on * the receipt of the next beacon i.e. when the TSF itself * gets resynchronized to the AP's TSF - power save is * needed to be temporarily disabled until that time * * Need to save the sequence number to restore it after * the reset! */ saveFrameSeqCount = OS_REG_READ(ah, AR_D_SEQNUM); } else saveFrameSeqCount = 0; /* NB: silence compiler */ /* If the channel change is across the same mode - perform a fast channel change */ if ((IS_2413(ah) || IS_5413(ah))) { /* * Channel change can only be used when: * -channel change requested - so it's not the initial reset. * -it's not a change to the current channel - often called when switching modes * on a channel * -the modes of the previous and requested channel are the same - some ugly code for XR */ if (bChannelChange && AH_PRIVATE(ah)->ah_curchan != AH_NULL && (chan->ic_freq != AH_PRIVATE(ah)->ah_curchan->ic_freq) && ((chan->ic_flags & IEEE80211_CHAN_ALLTURBO) == (AH_PRIVATE(ah)->ah_curchan->ic_flags & IEEE80211_CHAN_ALLTURBO))) { if (ar5212ChannelChange(ah, chan)) /* If ChannelChange completed - skip the rest of reset */ return AH_TRUE; } } /* * Preserve the antenna on a channel change */ saveDefAntenna = OS_REG_READ(ah, AR_DEF_ANTENNA); if (saveDefAntenna == 0) /* XXX magic constants */ saveDefAntenna = 1; /* Save hardware flag before chip reset clears the register */ macStaId1 = OS_REG_READ(ah, AR_STA_ID1) & (AR_STA_ID1_BASE_RATE_11B | AR_STA_ID1_USE_DEFANT); /* Save led state from pci config register */ if (!IS_5315(ah)) saveLedState = OS_REG_READ(ah, AR5312_PCICFG) & (AR_PCICFG_LEDCTL | AR_PCICFG_LEDMODE | AR_PCICFG_LEDBLINK | AR_PCICFG_LEDSLOW); ar5312RestoreClock(ah, opmode); /* move to refclk operation */ /* * Adjust gain parameters before reset if * there's an outstanding gain updated. */ (void) ar5212GetRfgain(ah); if (!ar5312ChipReset(ah, chan)) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__); FAIL(HAL_EIO); } /* Setup the indices for the next set of register array writes */ if (IEEE80211_IS_CHAN_2GHZ(chan)) { freqIndex = 2; modesIndex = IEEE80211_IS_CHAN_108G(chan) ? 5 : IEEE80211_IS_CHAN_G(chan) ? 4 : 3; } else { freqIndex = 1; modesIndex = IEEE80211_IS_CHAN_ST(chan) ? 2 : 1; } OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); /* Set correct Baseband to analog shift setting to access analog chips. */ OS_REG_WRITE(ah, AR_PHY(0), 0x00000007); regWrites = ath_hal_ini_write(ah, &ahp->ah_ini_modes, modesIndex, 0); regWrites = write_common(ah, &ahp->ah_ini_common, bChannelChange, regWrites); ahp->ah_rfHal->writeRegs(ah, modesIndex, freqIndex, regWrites); OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); if (IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan)) ar5212SetIFSTiming(ah, chan); /* Overwrite INI values for revised chipsets */ if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2) { /* ADC_CTL */ OS_REG_WRITE(ah, AR_PHY_ADC_CTL, SM(2, AR_PHY_ADC_CTL_OFF_INBUFGAIN) | SM(2, AR_PHY_ADC_CTL_ON_INBUFGAIN) | AR_PHY_ADC_CTL_OFF_PWDDAC | AR_PHY_ADC_CTL_OFF_PWDADC); /* TX_PWR_ADJ */ if (chan->channel == 2484) { cckOfdmPwrDelta = SCALE_OC_DELTA(ee->ee_cckOfdmPwrDelta - ee->ee_scaledCh14FilterCckDelta); } else { cckOfdmPwrDelta = SCALE_OC_DELTA(ee->ee_cckOfdmPwrDelta); } if (IEEE80211_IS_CHAN_G(chan)) { OS_REG_WRITE(ah, AR_PHY_TXPWRADJ, SM((ee->ee_cckOfdmPwrDelta*-1), AR_PHY_TXPWRADJ_CCK_GAIN_DELTA) | SM((cckOfdmPwrDelta*-1), AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX)); } else { OS_REG_WRITE(ah, AR_PHY_TXPWRADJ, 0); } /* Add barker RSSI thresh enable as disabled */ OS_REG_CLR_BIT(ah, AR_PHY_DAG_CTRLCCK, AR_PHY_DAG_CTRLCCK_EN_RSSI_THR); OS_REG_RMW_FIELD(ah, AR_PHY_DAG_CTRLCCK, AR_PHY_DAG_CTRLCCK_RSSI_THR, 2); /* Set the mute mask to the correct default */ OS_REG_WRITE(ah, AR_SEQ_MASK, 0x0000000F); } if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_3) { /* Clear reg to alllow RX_CLEAR line debug */ OS_REG_WRITE(ah, AR_PHY_BLUETOOTH, 0); } if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_4) { #ifdef notyet /* Enable burst prefetch for the data queues */ OS_REG_RMW_FIELD(ah, AR_D_FPCTL, ... ); /* Enable double-buffering */ OS_REG_CLR_BIT(ah, AR_TXCFG, AR_TXCFG_DBL_BUF_DIS); #endif } if (IS_5312_2_X(ah)) { /* ADC_CTRL */ OS_REG_WRITE(ah, AR_PHY_SIGMA_DELTA, SM(2, AR_PHY_SIGMA_DELTA_ADC_SEL) | SM(4, AR_PHY_SIGMA_DELTA_FILT2) | SM(0x16, AR_PHY_SIGMA_DELTA_FILT1) | SM(0, AR_PHY_SIGMA_DELTA_ADC_CLIP)); if (IEEE80211_IS_CHAN_2GHZ(chan)) OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN, AR_PHY_RXGAIN_TXRX_RF_MAX, 0x0F); /* CCK Short parameter adjustment in 11B mode */ if (IEEE80211_IS_CHAN_B(chan)) OS_REG_RMW_FIELD(ah, AR_PHY_CCK_RXCTRL4, AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT, 12); /* Set ADC/DAC select values */ OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x04); /* Increase 11A AGC Settling */ if (IEEE80211_IS_CHAN_A(chan)) OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_AGC, 32); } else { /* Set ADC/DAC select values */ OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e); } /* Setup the transmit power values. */ if (!ar5212SetTransmitPower(ah, chan, rfXpdGain)) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: error init'ing transmit power\n", __func__); FAIL(HAL_EIO); } /* Write the analog registers */ if (!ahp->ah_rfHal->setRfRegs(ah, chan, modesIndex, rfXpdGain)) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5212SetRfRegs failed\n", __func__); FAIL(HAL_EIO); } /* Write delta slope for OFDM enabled modes (A, G, Turbo) */ if (IEEE80211_IS_CHAN_OFDM(chan)) { if (IS_5413(ah) || AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3) ar5212SetSpurMitigation(ah, chan); ar5212SetDeltaSlope(ah, chan); } /* Setup board specific options for EEPROM version 3 */ if (!ar5212SetBoardValues(ah, chan)) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: error setting board options\n", __func__); FAIL(HAL_EIO); } /* Restore certain DMA hardware registers on a channel change */ if (bChannelChange) OS_REG_WRITE(ah, AR_D_SEQNUM, saveFrameSeqCount); OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr)); OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4) | macStaId1 | AR_STA_ID1_RTS_USE_DEF | ahp->ah_staId1Defaults ); ar5212SetOperatingMode(ah, opmode); /* Set Venice BSSID mask according to current state */ OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask)); OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4)); /* Restore previous led state */ if (!IS_5315(ah)) OS_REG_WRITE(ah, AR5312_PCICFG, OS_REG_READ(ah, AR_PCICFG) | saveLedState); /* Restore previous antenna */ OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); /* then our BSSID */ OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid)); OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4)); /* Restore bmiss rssi & count thresholds */ OS_REG_WRITE(ah, AR_RSSI_THR, ahp->ah_rssiThr); OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */ if (!ar5212SetChannel(ah, chan)) FAIL(HAL_EIO); OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); ar5212SetCoverageClass(ah, AH_PRIVATE(ah)->ah_coverageClass, 1); ar5212SetRateDurationTable(ah, chan); /* Set Tx frame start to tx data start delay */ if (IS_RAD5112_ANY(ah) && (IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan))) { txFrm2TxDStart = IEEE80211_IS_CHAN_HALF(chan) ? TX_FRAME_D_START_HALF_RATE: TX_FRAME_D_START_QUARTER_RATE; OS_REG_RMW_FIELD(ah, AR_PHY_TX_CTL, AR_PHY_TX_FRAME_TO_TX_DATA_START, txFrm2TxDStart); } /* * Setup fast diversity. * Fast diversity can be enabled or disabled via regadd.txt. * Default is enabled. * For reference, * Disable: reg val * 0x00009860 0x00009d18 (if 11a / 11g, else no change) * 0x00009970 0x192bb514 * 0x0000a208 0xd03e4648 * * Enable: 0x00009860 0x00009d10 (if 11a / 11g, else no change) * 0x00009970 0x192fb514 * 0x0000a208 0xd03e6788 */ /* XXX Setup pre PHY ENABLE EAR additions */ /* flush SCAL reg */ if (IS_5312_2_X(ah)) { (void) OS_REG_READ(ah, AR_PHY_SLEEP_SCAL); } /* * Wait for the frequency synth to settle (synth goes on * via AR_PHY_ACTIVE_EN). Read the phy active delay register. * Value is in 100ns increments. */ synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; if (IEEE80211_IS_CHAN_B(chan)) { synthDelay = (4 * synthDelay) / 22; } else { synthDelay /= 10; } /* Activate the PHY (includes baseband activate and synthesizer on) */ OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); /* * There is an issue if the AP starts the calibration before * the base band timeout completes. This could result in the * rx_clear false triggering. As a workaround we add delay an * extra BASE_ACTIVATE_DELAY usecs to ensure this condition * does not happen. */ if (IEEE80211_IS_CHAN_HALF(chan)) { OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY); } else if (IEEE80211_IS_CHAN_QUARTER(chan)) { OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY); } else { OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY); } /* * The udelay method is not reliable with notebooks. * Need to check to see if the baseband is ready */ testReg = OS_REG_READ(ah, AR_PHY_TESTCTRL); /* Selects the Tx hold */ OS_REG_WRITE(ah, AR_PHY_TESTCTRL, AR_PHY_TESTCTRL_TXHOLD); i = 0; while ((i++ < 20) && (OS_REG_READ(ah, 0x9c24) & 0x10)) /* test if baseband not ready */ OS_DELAY(200); OS_REG_WRITE(ah, AR_PHY_TESTCTRL, testReg); /* Calibrate the AGC and start a NF calculation */ OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL, OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL | AR_PHY_AGC_CONTROL_NF); if (!IEEE80211_IS_CHAN_B(chan) && ahp->ah_bIQCalibration != IQ_CAL_DONE) { /* Start IQ calibration w/ 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples */ OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4, AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX, INIT_IQCAL_LOG_COUNT_MAX); OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4, AR_PHY_TIMING_CTRL4_DO_IQCAL); ahp->ah_bIQCalibration = IQ_CAL_RUNNING; } else ahp->ah_bIQCalibration = IQ_CAL_INACTIVE; /* Setup compression registers */ ar5212SetCompRegs(ah); /* Set 1:1 QCU to DCU mapping for all queues */ for (i = 0; i < AR_NUM_DCU; i++) OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); ahp->ah_intrTxqs = 0; for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++) ar5212ResetTxQueue(ah, i); /* * Setup interrupt handling. Note that ar5212ResetTxQueue * manipulates the secondary IMR's as queues are enabled * and disabled. This is done with RMW ops to insure the * settings we make here are preserved. */ ahp->ah_maskReg = AR_IMR_TXOK | AR_IMR_TXERR | AR_IMR_TXURN | AR_IMR_RXOK | AR_IMR_RXERR | AR_IMR_RXORN | AR_IMR_HIUERR ; if (opmode == HAL_M_HOSTAP) ahp->ah_maskReg |= AR_IMR_MIB; OS_REG_WRITE(ah, AR_IMR, ahp->ah_maskReg); /* Enable bus errors that are OR'd to set the HIUERR bit */ OS_REG_WRITE(ah, AR_IMR_S2, OS_REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_MCABT | AR_IMR_S2_SSERR | AR_IMR_S2_DPERR); if (AH_PRIVATE(ah)->ah_rfkillEnabled) ar5212EnableRfKill(ah); if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: offset calibration failed to complete in 1ms;" " noisy environment?\n", __func__); } /* * Set clocks back to 32kHz if they had been using refClk, then * use an external 32kHz crystal when sleeping, if one exists. */ ar5312SetupClock(ah, opmode); /* * Writing to AR_BEACON will start timers. Hence it should * be the last register to be written. Do not reset tsf, do * not enable beacons at this point, but preserve other values * like beaconInterval. */ OS_REG_WRITE(ah, AR_BEACON, (OS_REG_READ(ah, AR_BEACON) &~ (AR_BEACON_EN | AR_BEACON_RESET_TSF))); /* XXX Setup post reset EAR additions */ /* QoS support */ if (AH_PRIVATE(ah)->ah_macVersion > AR_SREV_VERSION_VENICE || (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_VENICE && AH_PRIVATE(ah)->ah_macRev >= AR_SREV_GRIFFIN_LITE)) { OS_REG_WRITE(ah, AR_QOS_CONTROL, 0x100aa); /* XXX magic */ OS_REG_WRITE(ah, AR_QOS_SELECT, 0x3210); /* XXX magic */ } /* Turn on NOACK Support for QoS packets */ OS_REG_WRITE(ah, AR_NOACK, SM(2, AR_NOACK_2BIT_VALUE) | SM(5, AR_NOACK_BIT_OFFSET) | SM(0, AR_NOACK_BYTE_OFFSET)); /* Restore user-specified settings */ if (ahp->ah_miscMode != 0) OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode); if (ahp->ah_slottime != (u_int) -1) ar5212SetSlotTime(ah, ahp->ah_slottime); if (ahp->ah_acktimeout != (u_int) -1) ar5212SetAckTimeout(ah, ahp->ah_acktimeout); if (ahp->ah_ctstimeout != (u_int) -1) ar5212SetCTSTimeout(ah, ahp->ah_ctstimeout); if (ahp->ah_sifstime != (u_int) -1) ar5212SetSifsTime(ah, ahp->ah_sifstime); if (AH_PRIVATE(ah)->ah_diagreg != 0) OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg); AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */ if (bChannelChange && !IEEE80211_IS_CHAN_DFS(chan)) chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT; HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__); OS_MARK(ah, AH_MARK_RESET_DONE, 0); return AH_TRUE; bad: OS_MARK(ah, AH_MARK_RESET_DONE, ecode); if (status != AH_NULL) *status = ecode; return AH_FALSE; #undef FAIL #undef N }
void ieee80211_mlme_join_infra_continue(struct ieee80211vap *vap, int32_t status) { struct ieee80211com *ic = vap->iv_ic; struct ieee80211_node *ni; struct ieee80211_mlme_priv *mlme_priv = vap->iv_mlme_priv; u_int32_t join_timeout_ms; if (mlme_priv->im_request_type != MLME_REQ_JOIN_INFRA) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s : im_request_type != JOIN_INFRA\n", __func__); return; } if (status != EOK) { mlme_priv->im_request_type = MLME_REQ_NONE; IEEE80211_DELIVER_EVENT_MLME_JOIN_COMPLETE_INFRA(vap, IEEE80211_STATUS_UNSPECIFIED); return; } /* iv_bss is valid only after ieee80211_sta_join */ ni = vap->iv_bss; IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s ni=%02X:%02X:%02X:%02X:%02X:%02X\n", __func__, ni->ni_macaddr[0], ni->ni_macaddr[1], ni->ni_macaddr[2], ni->ni_macaddr[3], ni->ni_macaddr[4], ni->ni_macaddr[5]); /* Update erp info */ if (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION) ic->ic_flags |= IEEE80211_F_USEPROT; else ic->ic_flags &= ~IEEE80211_F_USEPROT; ic->ic_update_protmode(ic); if(ni->ni_erp & IEEE80211_ERP_LONG_PREAMBLE) ic->ic_flags |= IEEE80211_F_USEBARKER; else ic->ic_flags &= (~IEEE80211_F_USEBARKER); /* Update slot time info */ ieee80211_set_shortslottime(ic, IEEE80211_IS_CHAN_A(vap->iv_bsschan) || IEEE80211_IS_CHAN_11NA(vap->iv_bsschan) || (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)); /* Put underlying H/W to JOIN state */ ieee80211_vap_join(vap); #ifdef ATH_SUPPORT_TxBF ieee80211_init_txbf(ic, ni); #endif /* Send a direct probe to increase the odds of receiving a probe response */ ieee80211_send_probereq(ni, ic->ic_myaddr, ni->ni_bssid, ni->ni_bssid, ni->ni_essid, ni->ni_esslen, vap->iv_opt_ie.ie, vap->iv_opt_ie.length); /* Set the timeout timer for Join Failure case. */ join_timeout_ms = IEEE80211_TU_TO_MS(mlme_priv->im_timeout * ni->ni_intval); IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s: Setting Join Timeout timer for %d ms\n", __func__, join_timeout_ms); OS_SET_TIMER(&mlme_priv->im_timeout_timer, join_timeout_ms); /* Set the appropriate filtering function and wait for Join Beacon */ MLME_WAIT_FOR_BSS_JOIN(mlme_priv); }
/* * Reads EEPROM header info from device structure and programs * all rf registers * * REQUIRES: Access to the analog rf device */ static HAL_BOOL ar5111SetRfRegs(struct ath_hal *ah, const struct ieee80211_channel *chan, uint16_t modesIndex, uint16_t *rfXpdGain) { uint16_t freq = ath_hal_gethwchannel(ah, chan); struct ath_hal_5212 *ahp = AH5212(ah); const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom; uint16_t rfXpdGainFixed, rfPloSel, rfPwdXpd, gainI; uint16_t tempOB, tempDB; uint32_t ob2GHz, db2GHz, rfReg[NELEM(ar5212Bank6_5111)]; int i, regWrites = 0; HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan %u/0x%x modesIndex %u\n", __func__, chan->ic_freq, chan->ic_flags, modesIndex); /* Setup rf parameters */ switch (chan->ic_flags & IEEE80211_CHAN_ALLFULL) { case IEEE80211_CHAN_A: if (4000 < freq && freq < 5260) { tempOB = ee->ee_ob1; tempDB = ee->ee_db1; } else if (5260 <= freq && freq < 5500) { tempOB = ee->ee_ob2; tempDB = ee->ee_db2; } else if (5500 <= freq && freq < 5725) { tempOB = ee->ee_ob3; tempDB = ee->ee_db3; } else if (freq >= 5725) { tempOB = ee->ee_ob4; tempDB = ee->ee_db4; } else { /* XXX when does this happen??? */ tempOB = tempDB = 0; } ob2GHz = db2GHz = 0; rfXpdGainFixed = ee->ee_xgain[headerInfo11A]; rfPloSel = ee->ee_xpd[headerInfo11A]; rfPwdXpd = !ee->ee_xpd[headerInfo11A]; gainI = ee->ee_gainI[headerInfo11A]; break; case IEEE80211_CHAN_B: tempOB = ee->ee_obFor24; tempDB = ee->ee_dbFor24; ob2GHz = ee->ee_ob2GHz[0]; db2GHz = ee->ee_db2GHz[0]; rfXpdGainFixed = ee->ee_xgain[headerInfo11B]; rfPloSel = ee->ee_xpd[headerInfo11B]; rfPwdXpd = !ee->ee_xpd[headerInfo11B]; gainI = ee->ee_gainI[headerInfo11B]; break; case IEEE80211_CHAN_G: case IEEE80211_CHAN_PUREG: /* NB: really 108G */ tempOB = ee->ee_obFor24g; tempDB = ee->ee_dbFor24g; ob2GHz = ee->ee_ob2GHz[1]; db2GHz = ee->ee_db2GHz[1]; rfXpdGainFixed = ee->ee_xgain[headerInfo11G]; rfPloSel = ee->ee_xpd[headerInfo11G]; rfPwdXpd = !ee->ee_xpd[headerInfo11G]; gainI = ee->ee_gainI[headerInfo11G]; break; default: HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n", __func__, chan->ic_flags); return AH_FALSE; } HALASSERT(1 <= tempOB && tempOB <= 5); HALASSERT(1 <= tempDB && tempDB <= 5); /* Bank 0 Write */ for (i = 0; i < NELEM(ar5212Bank0_5111); i++) rfReg[i] = ar5212Bank0_5111[i][modesIndex]; if (IEEE80211_IS_CHAN_2GHZ(chan)) { ar5212ModifyRfBuffer(rfReg, ob2GHz, 3, 119, 0); ar5212ModifyRfBuffer(rfReg, db2GHz, 3, 122, 0); } HAL_INI_WRITE_BANK(ah, ar5212Bank0_5111, rfReg, regWrites); /* Bank 1 Write */ HAL_INI_WRITE_ARRAY(ah, ar5212Bank1_5111, 1, regWrites); /* Bank 2 Write */ HAL_INI_WRITE_ARRAY(ah, ar5212Bank2_5111, modesIndex, regWrites); /* Bank 3 Write */ HAL_INI_WRITE_ARRAY(ah, ar5212Bank3_5111, modesIndex, regWrites); /* Bank 6 Write */ for (i = 0; i < NELEM(ar5212Bank6_5111); i++) rfReg[i] = ar5212Bank6_5111[i][modesIndex]; if (IEEE80211_IS_CHAN_A(chan)) { /* NB: CHANNEL_A | CHANNEL_T */ ar5212ModifyRfBuffer(rfReg, ee->ee_cornerCal.pd84, 1, 51, 3); ar5212ModifyRfBuffer(rfReg, ee->ee_cornerCal.pd90, 1, 45, 3); } ar5212ModifyRfBuffer(rfReg, rfPwdXpd, 1, 95, 0); ar5212ModifyRfBuffer(rfReg, rfXpdGainFixed, 4, 96, 0); /* Set 5212 OB & DB */ ar5212ModifyRfBuffer(rfReg, tempOB, 3, 104, 0); ar5212ModifyRfBuffer(rfReg, tempDB, 3, 107, 0); HAL_INI_WRITE_BANK(ah, ar5212Bank6_5111, rfReg, regWrites); /* Bank 7 Write */ for (i = 0; i < NELEM(ar5212Bank7_5111); i++) rfReg[i] = ar5212Bank7_5111[i][modesIndex]; ar5212ModifyRfBuffer(rfReg, gainI, 6, 29, 0); ar5212ModifyRfBuffer(rfReg, rfPloSel, 1, 4, 0); if (IEEE80211_IS_CHAN_QUARTER(chan) || IEEE80211_IS_CHAN_HALF(chan)) { uint32_t rfWaitI, rfWaitS, rfMaxTime; rfWaitS = 0x1f; rfWaitI = (IEEE80211_IS_CHAN_HALF(chan)) ? 0x10 : 0x1f; rfMaxTime = 3; ar5212ModifyRfBuffer(rfReg, rfWaitS, 5, 19, 0); ar5212ModifyRfBuffer(rfReg, rfWaitI, 5, 24, 0); ar5212ModifyRfBuffer(rfReg, rfMaxTime, 2, 49, 0); } HAL_INI_WRITE_BANK(ah, ar5212Bank7_5111, rfReg, regWrites); /* Now that we have reprogrammed rfgain value, clear the flag. */ ahp->ah_rfgainState = HAL_RFGAIN_INACTIVE; return AH_TRUE; }
void ieee80211_ifattach(struct ifnet *ifp) { struct ieee80211com *ic = (void *)ifp; struct ieee80211_channel *c; int i; memcpy(((struct arpcom *)ifp)->ac_enaddr, ic->ic_myaddr, ETHER_ADDR_LEN); ether_ifattach(ifp); ifp->if_output = ieee80211_output; #if NBPFILTER > 0 bpfattach(&ic->ic_rawbpf, ifp, DLT_IEEE802_11, sizeof(struct ieee80211_frame_addr4)); #endif ieee80211_crypto_attach(ifp); /* * Fill in 802.11 available channel set, mark * all available channels as active, and pick * a default channel if not already specified. */ memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail)); ic->ic_modecaps |= 1<<IEEE80211_MODE_AUTO; for (i = 0; i <= IEEE80211_CHAN_MAX; i++) { c = &ic->ic_channels[i]; if (c->ic_flags) { /* * Verify driver passed us valid data. */ if (i != ieee80211_chan2ieee(ic, c)) { printf("%s: bad channel ignored; " "freq %u flags %x number %u\n", ifp->if_xname, c->ic_freq, c->ic_flags, i); c->ic_flags = 0; /* NB: remove */ continue; } setbit(ic->ic_chan_avail, i); /* * Identify mode capabilities. */ if (IEEE80211_IS_CHAN_A(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_11A; if (IEEE80211_IS_CHAN_B(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_11B; if (IEEE80211_IS_CHAN_PUREG(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_11G; if (IEEE80211_IS_CHAN_T(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_TURBO; } } /* validate ic->ic_curmode */ if ((ic->ic_modecaps & (1<<ic->ic_curmode)) == 0) ic->ic_curmode = IEEE80211_MODE_AUTO; ic->ic_des_chan = IEEE80211_CHAN_ANYC; /* any channel is ok */ ic->ic_scan_lock = IEEE80211_SCAN_UNLOCKED; /* IEEE 802.11 defines a MTU >= 2290 */ ifp->if_capabilities |= IFCAP_VLAN_MTU; ieee80211_setbasicrates(ic); (void)ieee80211_setmode(ic, ic->ic_curmode); if (ic->ic_lintval == 0) ic->ic_lintval = 100; /* default sleep */ ic->ic_bmisstimeout = 7*ic->ic_lintval; /* default 7 beacons */ ic->ic_dtim_period = 1; /* all TIMs are DTIMs */ LIST_INSERT_HEAD(&ieee80211com_head, ic, ic_list); ieee80211_node_attach(ifp); ieee80211_proto_attach(ifp); if_addgroup(ifp, "wlan"); ifp->if_priority = IF_WIRELESS_DEFAULT_PRIORITY; }
void ieee80211_ifattach(struct ifnet *ifp) { struct ieee80211com *ic = (void *)ifp; struct ieee80211_channel *c; int i; ether_ifattach(ifp, ic->ic_myaddr); #if NBPFILTER > 0 bpfattach2(ifp, DLT_IEEE802_11, sizeof(struct ieee80211_frame_addr4), &ic->ic_rawbpf); #endif ieee80211_crypto_attach(ifp); /* * Fill in 802.11 available channel set, mark * all available channels as active, and pick * a default channel if not already specified. */ memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail)); ic->ic_modecaps |= 1<<IEEE80211_MODE_AUTO; for (i = 0; i <= IEEE80211_CHAN_MAX; i++) { c = &ic->ic_channels[i]; if (c->ic_flags) { /* * Verify driver passed us valid data. */ if (i != ieee80211_chan2ieee(ic, c)) { if_printf(ifp, "bad channel ignored; " "freq %u flags %x number %u\n", c->ic_freq, c->ic_flags, i); c->ic_flags = 0; /* NB: remove */ continue; } setbit(ic->ic_chan_avail, i); /* * Identify mode capabilities. */ if (IEEE80211_IS_CHAN_A(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_11A; if (IEEE80211_IS_CHAN_B(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_11B; if (IEEE80211_IS_CHAN_PUREG(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_11G; if (IEEE80211_IS_CHAN_FHSS(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_FH; if (IEEE80211_IS_CHAN_T(c)) ic->ic_modecaps |= 1<<IEEE80211_MODE_TURBO; } } /* validate ic->ic_curmode */ if ((ic->ic_modecaps & (1<<ic->ic_curmode)) == 0) ic->ic_curmode = IEEE80211_MODE_AUTO; ieee80211_setbasicrates(ic); (void) ieee80211_setmode(ic, ic->ic_curmode); ic->ic_des_chan = IEEE80211_CHAN_ANYC; /* any channel is ok */ if (ic->ic_lintval == 0) ic->ic_lintval = 100; /* default sleep */ ic->ic_bmisstimeout = 7*ic->ic_lintval; /* default 7 beacons */ ieee80211_node_attach(ifp); ieee80211_proto_attach(ifp); }