mirror of
https://github.com/proski/madwifi
synced 2024-11-22 06:21:47 +03:00
Formatting
git-svn-id: http://madwifi-project.org/svn/madwifi/trunk@3274 0192ed92-7a03-0410-a25b-9323aeb14dbd
This commit is contained in:
parent
60e9b06ffa
commit
cf6e609462
107
ath/if_ath.c
107
ath/if_ath.c
@ -328,9 +328,7 @@ static struct ath_buf* cleanup_ath_buf(struct ath_softc *sc, struct ath_buf *buf
|
||||
int direction);
|
||||
#endif /* #ifdef IEEE80211_DEBUG_REFCNT */
|
||||
|
||||
/*
|
||||
Regulatory agency testing - continuous transmit support
|
||||
*/
|
||||
/* Regulatory agency testing - continuous transmit support */
|
||||
static void txcont_on(struct ieee80211com *ic);
|
||||
static void txcont_off(struct ieee80211com *ic);
|
||||
|
||||
@ -343,9 +341,7 @@ static void ath_set_txcont_power(struct ieee80211com *, unsigned int);
|
||||
static unsigned int ath_get_txcont_rate(struct ieee80211com *);
|
||||
static void ath_set_txcont_rate(struct ieee80211com *ic, unsigned int new_rate);
|
||||
|
||||
/*
|
||||
802.11h DFS support functions
|
||||
*/
|
||||
/* 802.11h DFS support functions */
|
||||
static void ath_dfs_channel_check_completed(unsigned long);
|
||||
static void ath_interrupt_dfs_channel_check(struct ath_softc *sc, const char* reason);
|
||||
|
||||
@ -354,9 +350,7 @@ static int ath_check_total_radio_silence_not_required(struct ath_softc *sc, cons
|
||||
static int ath_radio_silence_required_for_dfs(struct ath_softc* sc);
|
||||
static int ath_check_radio_silence_not_required(struct ath_softc *sc, const char* func);
|
||||
|
||||
/*
|
||||
802.11h DFS testing functions
|
||||
*/
|
||||
/* 802.11h DFS testing functions */
|
||||
static int ath_get_dfs_testmode(struct ieee80211com *);
|
||||
static void ath_set_dfs_testmode(struct ieee80211com *, int);
|
||||
|
||||
@ -1347,23 +1341,18 @@ ath_vap_create(struct ieee80211com *ic, const char *name,
|
||||
ATH_TXQ_LOCK_INIT(&avp->av_mcastq);
|
||||
if (IEEE80211_IS_MODE_BEACON(opmode)) {
|
||||
unsigned int slot;
|
||||
/*
|
||||
* Allocate beacon state for hostap/ibss. We know
|
||||
* a buffer is available because of the check above.
|
||||
*/
|
||||
/* Allocate beacon state for hostap/ibss. We know
|
||||
* a buffer is available because of the check above. */
|
||||
avp->av_bcbuf = STAILQ_FIRST(&sc->sc_bbuf);
|
||||
STAILQ_REMOVE_HEAD(&sc->sc_bbuf, bf_list);
|
||||
/*
|
||||
* Assign the VAP to a beacon xmit slot. As
|
||||
* above, this cannot fail to find one.
|
||||
*/
|
||||
|
||||
/* Assign the VAP to a beacon xmit slot. As
|
||||
* above, this cannot fail to find one. */
|
||||
avp->av_bslot = 0;
|
||||
for (slot = 0; slot < ath_maxvaps; slot++)
|
||||
if (sc->sc_bslot[slot] == NULL) {
|
||||
/*
|
||||
* XXX hack, space out slots to better
|
||||
* deal with misses
|
||||
*/
|
||||
/* XXX: Hack, space out slots to better
|
||||
* deal with misses. */
|
||||
if (slot + 1 < ath_maxvaps &&
|
||||
sc->sc_bslot[slot+1] == NULL) {
|
||||
avp->av_bslot = slot + 1;
|
||||
@ -2145,7 +2134,8 @@ ath_intr(int irq, void *dev_id, struct pt_regs *regs)
|
||||
HAL_INT status;
|
||||
int needmark;
|
||||
|
||||
DPRINTF(sc, ATH_DEBUG_INTR, "dev->flags=0x%x%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s]\n",
|
||||
DPRINTF(sc, ATH_DEBUG_INTR,
|
||||
"dev->flags=0x%x%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s]\n",
|
||||
dev->flags,
|
||||
(dev->flags & IFF_UP) ? " IFF_UP" : "",
|
||||
(dev->flags & IFF_BROADCAST) ? " IFF_BROADCAST" : "",
|
||||
@ -2165,10 +2155,8 @@ ath_intr(int irq, void *dev_id, struct pt_regs *regs)
|
||||
(dev->flags & IFF_DYNAMIC) ? " IFF_DYNAMIC" : "");
|
||||
|
||||
if (sc->sc_invalid) {
|
||||
/*
|
||||
* The hardware is not ready/present, don't touch anything.
|
||||
* Note this can happen early on if the IRQ is shared.
|
||||
*/
|
||||
/* The hardware is not ready/present, don't touch anything.
|
||||
* Note this can happen early on if the IRQ is shared. */
|
||||
return IRQ_NONE;
|
||||
}
|
||||
if (!ath_hal_intrpend(ah)) /* shared irq, not for us */
|
||||
@ -2180,12 +2168,11 @@ ath_intr(int irq, void *dev_id, struct pt_regs *regs)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
needmark = 0;
|
||||
/*
|
||||
* Figure out the reason(s) for the interrupt. Note
|
||||
|
||||
/* Figure out the reason(s) for the interrupt. Note
|
||||
* that the HAL returns a pseudo-ISR that may include
|
||||
* bits we haven't explicitly enabled so we mask the
|
||||
* value to ensure we only process bits we requested.
|
||||
*/
|
||||
* value to ensure we only process bits we requested. */
|
||||
ath_hal_getisr(ah, &status); /* NB: clears ISR too */
|
||||
DPRINTF(sc, ATH_DEBUG_INTR,
|
||||
"ISR=0x%x%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
|
||||
@ -2220,8 +2207,7 @@ ath_intr(int irq, void *dev_id, struct pt_regs *regs)
|
||||
* we will check to see if we need an initial hardware TSF reading.
|
||||
* Normally we would just populate this all the time to keep things
|
||||
* clean, but this function (ath_hal_gettsf64) has been observed to be
|
||||
* VERY slow and hurting performance. There's nothing we can do for it.
|
||||
*/
|
||||
* VERY slow and hurting performance. There's nothing we can do for it. */
|
||||
if (status & (HAL_INT_RX | HAL_INT_RXPHY | HAL_INT_SWBA))
|
||||
hw_tsf = ath_hal_gettsf64(ah);
|
||||
|
||||
@ -2244,14 +2230,12 @@ ath_intr(int irq, void *dev_id, struct pt_regs *regs)
|
||||
DPRINTF(sc, ATH_DEBUG_BEACON,
|
||||
"ath_intr HAL_INT_SWBA at "
|
||||
"tsf %10llx nexttbtt %10llx\n",
|
||||
hw_tsf, (u_int64_t)sc->sc_nexttbtt<<10);
|
||||
hw_tsf, (u_int64_t)sc->sc_nexttbtt << 10);
|
||||
|
||||
/*
|
||||
* Software beacon alert--time to send a beacon.
|
||||
/* Software beacon alert--time to send a beacon.
|
||||
* Handle beacon transmission directly; deferring
|
||||
* this is too slow to meet timing constraints
|
||||
* under load.
|
||||
*/
|
||||
* under load. */
|
||||
if (!ath_total_radio_silence_required_for_dfs(sc))
|
||||
ath_beacon_send(sc, &needmark, hw_tsf);
|
||||
else {
|
||||
@ -6267,7 +6251,6 @@ ath_recv_mgmt(struct ieee80211vap * vap, struct ieee80211_node *ni_or_null,
|
||||
* A & B, A can merge to B and at the same time, B will
|
||||
* merge to A, still having a split */
|
||||
if (intval != 0) {
|
||||
|
||||
if ((sc->sc_nexttbtt % intval) !=
|
||||
(beacon_tu % intval)) {
|
||||
DPRINTF(sc, ATH_DEBUG_BEACON,
|
||||
@ -8574,7 +8557,7 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan)
|
||||
"Channel change interrupted DFS wait.");
|
||||
|
||||
/* Need a doth channel availability check? We do if ... */
|
||||
doth_channel_availability_check_needed = 1 &&
|
||||
doth_channel_availability_check_needed =
|
||||
IEEE80211_IS_MODE_DFS_MASTER(ic->ic_opmode) &&
|
||||
(hchan.channel != sc->sc_curchan.channel ||
|
||||
/* the scan wasn't already done */
|
||||
@ -8728,17 +8711,21 @@ ath_calibrate(unsigned long arg)
|
||||
* to load new gain values.
|
||||
*/
|
||||
int txcont_was_active = sc->sc_txcont;
|
||||
DPRINTF(sc, ATH_DEBUG_RESET | ATH_DEBUG_CALIBRATE | ATH_DEBUG_DOTH,
|
||||
DPRINTF(sc, ATH_DEBUG_RESET | ATH_DEBUG_CALIBRATE |
|
||||
ATH_DEBUG_DOTH,
|
||||
"Forcing reset() for (ath_hal_getrfgain(ah) == "
|
||||
"HAL_RFGAIN_NEED_CHANGE)\n");
|
||||
sc->sc_stats.ast_per_rfgain++;
|
||||
/* XXX: Ugly workaround */
|
||||
if (!sc->sc_beacons &&
|
||||
TAILQ_FIRST(&ic->ic_vaps)->iv_opmode != IEEE80211_M_WDS &&
|
||||
!txcont_was_active &&
|
||||
!ath_total_radio_silence_required_for_dfs(sc)) {
|
||||
sc->sc_beacons = 1;
|
||||
}
|
||||
|
||||
/* XXX: Ugly workaround */
|
||||
if (!sc->sc_beacons &&
|
||||
(TAILQ_FIRST(&ic->ic_vaps)->iv_opmode !=
|
||||
IEEE80211_M_WDS) &&
|
||||
!txcont_was_active &&
|
||||
!ath_total_radio_silence_required_for_dfs(sc)) {
|
||||
sc->sc_beacons = 1;
|
||||
}
|
||||
|
||||
ath_reset(dev);
|
||||
/* Turn txcont back on as necessary */
|
||||
if (txcont_was_active)
|
||||
@ -9098,7 +9085,8 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
|
||||
IEEE80211_IS_MODE_DFS_MASTER(vap->iv_opmode)) {
|
||||
DPRINTF(sc, ATH_DEBUG_STATE | ATH_DEBUG_DOTH,
|
||||
"VAP -> DFSWAIT_PENDING \n");
|
||||
/* start calibration timer with a really small value 1/10 sec */
|
||||
/* start calibration timer with a really small value
|
||||
* 1/10 sec */
|
||||
mod_timer(&sc->sc_cal_ch, jiffies + (HZ/10));
|
||||
/* wake the receiver */
|
||||
netif_wake_queue(dev);
|
||||
@ -9109,7 +9097,8 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
|
||||
|
||||
/* Configure the beacon and sleep timers. */
|
||||
if (!sc->sc_beacons && (vap->iv_opmode != IEEE80211_M_WDS)) {
|
||||
DPRINTF(sc, ATH_DEBUG_STATE | ATH_DEBUG_BEACON | ATH_DEBUG_BEACON_PROC,
|
||||
DPRINTF(sc, ATH_DEBUG_STATE | ATH_DEBUG_BEACON |
|
||||
ATH_DEBUG_BEACON_PROC,
|
||||
"Beacons reconfigured by %p[%s]!\n",
|
||||
vap, vap->iv_nickname);
|
||||
ath_beacon_config(sc, vap);
|
||||
@ -9122,14 +9111,16 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
|
||||
{
|
||||
del_timer_sync(&sc->sc_dfs_cac_timer);
|
||||
sc->sc_dfs_cac = 0;
|
||||
DPRINTF(sc, ATH_DEBUG_STATE, "VAP DFSWAIT_PENDING -> run\n");
|
||||
DPRINTF(sc, ATH_DEBUG_STATE,
|
||||
"VAP DFSWAIT_PENDING -> run\n");
|
||||
}
|
||||
|
||||
/* XXX: if it is SCAN state, disable beacons. */
|
||||
if (nstate == IEEE80211_S_SCAN) {
|
||||
sc->sc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS);
|
||||
ath_hal_intrset(ah, sc->sc_imask);
|
||||
/* need to reconfigure the beacons when it moves to RUN */
|
||||
/* need to reconfigure the beacons when it moves to
|
||||
* RUN */
|
||||
sc->sc_beacons = 0;
|
||||
}
|
||||
}
|
||||
@ -9259,7 +9250,7 @@ ath_dfs_channel_check_completed(unsigned long data )
|
||||
"%ld.%06ld\n",
|
||||
tv.tv_sec, tv.tv_usec);
|
||||
mod_timer(&sc->sc_dfs_cac_timer,
|
||||
jiffies +(sc->sc_dfs_cac_period * HZ));
|
||||
jiffies + (sc->sc_dfs_cac_period * HZ));
|
||||
} else {
|
||||
DPRINTF(sc, ATH_DEBUG_STATE | ATH_DEBUG_DOTH,
|
||||
"VAP DFSWAIT_PENDING still. "
|
||||
@ -10404,8 +10395,8 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl, write, filp, buffer, lenp, ppos)
|
||||
* sysctl API is only unsigned 32 bits. As a result, tsf might get
|
||||
* truncated */
|
||||
if (ctl->extra2 == (void *)ATH_RP) {
|
||||
ctl->data = &tab_3_val;
|
||||
ctl->maxlen = sizeof(tab_3_val);
|
||||
ctl->data = &tab_3_val;
|
||||
ctl->maxlen = sizeof(tab_3_val);
|
||||
}
|
||||
|
||||
ATH_LOCK(sc);
|
||||
@ -10906,7 +10897,7 @@ ath_announce(struct net_device *dev)
|
||||
u_int modes, cc;
|
||||
static const int MLEN = 1024;
|
||||
static const int BLEN = 64;
|
||||
char m[MLEN+1], b[BLEN+1];
|
||||
char m[MLEN + 1], b[BLEN + 1];
|
||||
m[MLEN] = '\0';
|
||||
b[BLEN] = '\0';
|
||||
|
||||
@ -10944,7 +10935,7 @@ ath_announce(struct net_device *dev)
|
||||
strncat(m, b, MLEN);
|
||||
}
|
||||
strncat(m, "\n", MLEN);
|
||||
if (1/*bootverbose*/) {
|
||||
if (1 /* bootverbose */) {
|
||||
unsigned int i;
|
||||
for (i = 0; i <= WME_AC_VO; i++) {
|
||||
struct ath_txq *txq = sc->sc_ac2q[i];
|
||||
@ -10958,7 +10949,7 @@ ath_announce(struct net_device *dev)
|
||||
}
|
||||
#undef HAL_MODE_DUALBAND
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Static (i.e. global) sysctls. Note that the HAL sysctls
|
||||
* are located under ours by sharing the setting for DEV_ATH.
|
||||
@ -11570,7 +11561,7 @@ ath_set_dfs_testmode(struct ieee80211com *ic, int value)
|
||||
{
|
||||
struct net_device *dev = ic->ic_dev;
|
||||
struct ath_softc *sc = dev->priv;
|
||||
sc->sc_dfs_testmode = ((0 != value) ? 1 : 0);
|
||||
sc->sc_dfs_testmode = !!value;
|
||||
}
|
||||
|
||||
/* Is continuous transmission mode enabled? It may not actually be
|
||||
|
@ -334,7 +334,8 @@ ieee80211_ifattach(struct ieee80211com *ic)
|
||||
ic->ic_newtxpowlimit = IEEE80211_TXPOWER_MAX;
|
||||
|
||||
init_timer(&ic->ic_dfs_non_occupancy_timer);
|
||||
ic->ic_dfs_non_occupancy_timer.function = ieee80211_expire_dfs_channel_non_occupancy_timer;
|
||||
ic->ic_dfs_non_occupancy_timer.function =
|
||||
ieee80211_expire_dfs_channel_non_occupancy_timer;
|
||||
ic->ic_dfs_non_occupancy_timer.data = (unsigned long) ic;
|
||||
|
||||
ieee80211_crypto_attach(ic);
|
||||
@ -813,23 +814,25 @@ ieee80211_dfs_action(struct ieee80211com *ic) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* No running/scanning VAP was found, so they're all in
|
||||
* INIT state, no channel change needed
|
||||
*/
|
||||
if (vap==NULL)
|
||||
/* No running/scanning VAP was found, so they're all in
|
||||
* INIT state, no channel change needed. */
|
||||
if (vap == NULL)
|
||||
return;
|
||||
/* Is it really Scanning */
|
||||
/* XXX: Race condition? */
|
||||
if (ic->ic_flags & IEEE80211_F_SCAN)
|
||||
return;
|
||||
/* It is not scanning, but waiting for ath driver to move the vap to RUN */
|
||||
/* It is not scanning, but waiting for ath driver to move the
|
||||
* vap to RUN. */
|
||||
}
|
||||
/* Check the scan results using only cached results */
|
||||
if (!(ieee80211_check_scan(vap, IEEE80211_SCAN_NOSSID | IEEE80211_SCAN_KEEPMODE | IEEE80211_SCAN_USECACHE, 0,
|
||||
if (!(ieee80211_check_scan(vap, IEEE80211_SCAN_NOSSID |
|
||||
IEEE80211_SCAN_KEEPMODE |
|
||||
IEEE80211_SCAN_USECACHE, 0,
|
||||
vap->iv_des_nssid, vap->iv_des_ssid,
|
||||
ieee80211_scan_dfs_action))) {
|
||||
/* No channel was found, so call the scan action with no result */
|
||||
/* No channel was found, so call the scan action with no
|
||||
* result. */
|
||||
ieee80211_scan_dfs_action(vap, NULL);
|
||||
}
|
||||
}
|
||||
@ -849,15 +852,22 @@ ieee80211_expire_channel_non_occupancy_restrictions(struct ieee80211com *ic)
|
||||
if (timeval_compare(&ic->ic_chan_non_occupy[i],
|
||||
&tv_now) < 0) {
|
||||
if_printf(dev,
|
||||
"Returning channel %3d (%4d MHz) radar avoidance marker expired. Channel now available again. -- Time: %10ld.%06ld\n",
|
||||
"Returning channel %3d (%4d MHz) "
|
||||
"radar avoidance marker expired. "
|
||||
"Channel now available again. -- "
|
||||
"Time: %10ld.%06ld\n",
|
||||
c->ic_ieee, c->ic_freq, tv_now.tv_sec,
|
||||
tv_now.tv_usec);
|
||||
c->ic_flags &= ~IEEE80211_CHAN_RADAR;
|
||||
} else {
|
||||
if_printf(dev,
|
||||
"Channel %3d (%4d MHz) is still marked for radar. Channel will become usable in %u seconds at Time: %10ld.%06ld\n",
|
||||
"Channel %3d (%4d MHz) is still "
|
||||
"marked for radar. Channel will "
|
||||
"become usable in %u seconds at "
|
||||
"Time: %10ld.%06ld\n",
|
||||
c->ic_ieee, c->ic_freq,
|
||||
ic->ic_chan_non_occupy[i].tv_sec - tv_now.tv_sec,
|
||||
ic->ic_chan_non_occupy[i].tv_sec -
|
||||
tv_now.tv_sec,
|
||||
ic->ic_chan_non_occupy[i].tv_sec,
|
||||
ic->ic_chan_non_occupy[i].tv_usec);
|
||||
}
|
||||
@ -881,7 +891,7 @@ ieee80211_update_dfs_channel_non_occupancy_timer(struct ieee80211com *ic)
|
||||
|
||||
tv_next.tv_sec = 0;
|
||||
tv_next.tv_usec = 0;
|
||||
for (i=0; i<ic->ic_nchans; i++) {
|
||||
for (i = 0; i < ic->ic_nchans; i++) {
|
||||
chan = &ic->ic_channels[i];
|
||||
if (chan->ic_flags & IEEE80211_CHAN_RADAR) {
|
||||
if ((tv_next.tv_sec == 0) &&
|
||||
@ -900,7 +910,8 @@ ieee80211_update_dfs_channel_non_occupancy_timer(struct ieee80211com *ic)
|
||||
del_timer(&ic->ic_dfs_non_occupancy_timer);
|
||||
} else {
|
||||
mod_timer(&ic->ic_dfs_non_occupancy_timer,
|
||||
jiffies_tmp + (tv_next.tv_sec - tv_now.tv_sec + 1) * HZ);
|
||||
jiffies_tmp +
|
||||
(tv_next.tv_sec - tv_now.tv_sec + 1) * HZ);
|
||||
}
|
||||
}
|
||||
|
||||
@ -911,10 +922,12 @@ ieee80211_expire_dfs_channel_non_occupancy_timer(unsigned long data)
|
||||
struct ieee80211com *ic = (struct ieee80211com *) data;
|
||||
struct ieee80211vap *vap;
|
||||
|
||||
printk(KERN_INFO "%s: %s: expiring Non-Occupancy Period\n", DEV_NAME(ic->ic_dev), __func__);
|
||||
printk(KERN_INFO "%s: %s: expiring Non-Occupancy Period\n",
|
||||
DEV_NAME(ic->ic_dev), __func__);
|
||||
|
||||
if (ic->ic_flags_ext & IEEE80211_FEXT_MARKDFS) {
|
||||
/* Make sure there are no channels that have just become available */
|
||||
/* Make sure there are no channels that have just become
|
||||
* available. */
|
||||
ieee80211_expire_channel_non_occupancy_restrictions(ic);
|
||||
/* Go through and clear any interference flag we have, if we
|
||||
* just got it cleared up for us */
|
||||
@ -928,44 +941,69 @@ ieee80211_expire_dfs_channel_non_occupancy_timer(unsigned long data)
|
||||
/* Operating on channel other than desired. */
|
||||
(vap->iv_des_chan != IEEE80211_CHAN_ANYC) &&
|
||||
(vap->iv_des_chan->ic_freq > 0) &&
|
||||
(vap->iv_des_chan->ic_freq != ic->ic_bsschan->ic_freq)) {
|
||||
(vap->iv_des_chan->ic_freq !=
|
||||
ic->ic_bsschan->ic_freq)) {
|
||||
struct ieee80211_channel *des_chan =
|
||||
ieee80211_find_channel(ic, vap->iv_des_chan->ic_freq,
|
||||
vap->iv_des_chan->ic_flags);
|
||||
ieee80211_find_channel(ic,
|
||||
vap->iv_des_chan->
|
||||
ic_freq,
|
||||
vap->iv_des_chan->
|
||||
ic_flags);
|
||||
/* Can we switch to it? */
|
||||
if (NULL == des_chan) {
|
||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
|
||||
"%s: Desired channel not found: %u/%x\n",
|
||||
__func__,
|
||||
vap->iv_des_chan->ic_freq,
|
||||
vap->iv_des_chan->ic_flags);
|
||||
} else if (0 == (des_chan->ic_flags & IEEE80211_CHAN_RADAR)) {
|
||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
|
||||
"%s: Desired channel found and available. Switching to %u/%x\n",
|
||||
__func__,
|
||||
vap->iv_des_chan->ic_freq,
|
||||
vap->iv_des_chan->ic_flags);
|
||||
ic->ic_chanchange_chan = des_chan->ic_ieee;
|
||||
ic->ic_chanchange_tbtt = IEEE80211_RADAR_CHANCHANGE_TBTT_COUNT;
|
||||
IEEE80211_DPRINTF(vap,
|
||||
IEEE80211_MSG_DOTH,
|
||||
"%s: Desired channel "
|
||||
"not found: %u/%x\n",
|
||||
__func__,
|
||||
vap->iv_des_chan->
|
||||
ic_freq,
|
||||
vap->iv_des_chan->
|
||||
ic_flags);
|
||||
} else if (!(des_chan->ic_flags &
|
||||
IEEE80211_CHAN_RADAR)) {
|
||||
IEEE80211_DPRINTF(vap,
|
||||
IEEE80211_MSG_DOTH,
|
||||
"%s: Desired channel "
|
||||
"found and available. "
|
||||
"Switching to %u/%x\n",
|
||||
__func__,
|
||||
vap->iv_des_chan->
|
||||
ic_freq,
|
||||
vap->iv_des_chan->
|
||||
ic_flags);
|
||||
ic->ic_chanchange_chan =
|
||||
des_chan->ic_ieee;
|
||||
ic->ic_chanchange_tbtt =
|
||||
IEEE80211_RADAR_CHANCHANGE_TBTT_COUNT;
|
||||
ic->ic_flags |= IEEE80211_F_CHANSWITCH;
|
||||
} else {
|
||||
if (ieee80211_msg_is_reported(vap, IEEE80211_MSG_DOTH)) {
|
||||
/* Find the desired channel in ic_channels, so
|
||||
* we can find the index into ic_chan_non_occupy */
|
||||
int i_des_chan = -1, i = 0;
|
||||
for (i=0; i<ic->ic_nchans; i++) {
|
||||
if (des_chan == &ic->ic_channels[i]) {
|
||||
i_des_chan = i;
|
||||
break;
|
||||
}
|
||||
} else if (ieee80211_msg_is_reported(vap,
|
||||
IEEE80211_MSG_DOTH)) {
|
||||
/* Find the desired channel in
|
||||
* ic_channels, so we can find the
|
||||
* index into ic_chan_non_occupy. */
|
||||
int i_des_chan = -1, i = 0;
|
||||
for (i = 0; i < ic->ic_nchans; i++) {
|
||||
if (&ic->ic_channels[i] ==
|
||||
des_chan) {
|
||||
i_des_chan = i;
|
||||
break;
|
||||
}
|
||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
|
||||
"%s: Desired channel found"
|
||||
" and not available until Time: %10ld.%06ld\n",
|
||||
__func__,
|
||||
ic->ic_chan_non_occupy[i_des_chan].tv_sec,
|
||||
ic->ic_chan_non_occupy[i_des_chan].tv_usec);
|
||||
}
|
||||
IEEE80211_DPRINTF(vap,
|
||||
IEEE80211_MSG_DOTH,
|
||||
"%s: Desired channel "
|
||||
"found and not "
|
||||
"available until Time: "
|
||||
"%10ld.%06ld\n",
|
||||
__func__,
|
||||
ic->ic_chan_non_occupy
|
||||
[i_des_chan].
|
||||
tv_sec,
|
||||
ic->ic_chan_non_occupy
|
||||
[i_des_chan].
|
||||
tv_usec
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -987,61 +1025,92 @@ ieee80211_mark_dfs(struct ieee80211com *ic, struct ieee80211_channel *ichan)
|
||||
int i;
|
||||
|
||||
do_gettimeofday(&tv_now);
|
||||
if_printf(dev, "Radar found on channel %3d (%4d MHz) -- Time: %ld.%06ld\n",
|
||||
ichan->ic_ieee, ichan->ic_freq, tv_now.tv_sec, tv_now.tv_usec);
|
||||
if_printf(dev, "Radar found on channel %3d (%4d MHz) -- "
|
||||
"Time: %ld.%06ld\n",
|
||||
ichan->ic_ieee, ichan->ic_freq,
|
||||
tv_now.tv_sec, tv_now.tv_usec);
|
||||
if (IEEE80211_IS_MODE_DFS_MASTER(ic->ic_opmode)) {
|
||||
/* Mark the channel in the ic_chan list */
|
||||
if (ic->ic_flags_ext & IEEE80211_FEXT_MARKDFS) {
|
||||
if_printf(dev, "Marking channel %3d (%4d MHz) in ic_chan list -- Time: %ld.%06ld\n",
|
||||
ichan->ic_ieee, ichan->ic_freq,
|
||||
tv_now.tv_sec, tv_now.tv_usec);
|
||||
if_printf(dev, "Marking channel %3d (%4d MHz) in "
|
||||
"ic_chan list -- Time: %ld.%06ld\n",
|
||||
ichan->ic_ieee, ichan->ic_freq,
|
||||
tv_now.tv_sec, tv_now.tv_usec);
|
||||
for (i = 0; i < ic->ic_nchans; i++) {
|
||||
c = &ic->ic_channels[i];
|
||||
if (c->ic_freq == ichan->ic_freq) {
|
||||
c->ic_flags |= IEEE80211_CHAN_RADAR;
|
||||
ic->ic_chan_non_occupy[i].tv_sec = tv_now.tv_sec + avoidance_time;
|
||||
ic->ic_chan_non_occupy[i].tv_usec = tv_now.tv_usec;
|
||||
ic->ic_chan_non_occupy[i].tv_sec =
|
||||
tv_now.tv_sec + avoidance_time;
|
||||
ic->ic_chan_non_occupy[i].tv_usec =
|
||||
tv_now.tv_usec;
|
||||
|
||||
if_printf(dev, "Channel %3d (%4d MHz) will become usable in %u seconds. Suspending use of the channel until: %ld.%06ld\n",
|
||||
ichan->ic_ieee, ichan->ic_freq,
|
||||
avoidance_time,
|
||||
ic->ic_chan_non_occupy[i].tv_sec,
|
||||
ic->ic_chan_non_occupy[i].tv_usec);
|
||||
if_printf(dev, "Channel %3d (%4d MHz) "
|
||||
"will become usable in %u "
|
||||
"seconds. Suspending use of "
|
||||
"the channel until: "
|
||||
"%ld.%06ld\n",
|
||||
ichan->ic_ieee, ichan->ic_freq,
|
||||
avoidance_time,
|
||||
ic->ic_chan_non_occupy[i].tv_sec,
|
||||
ic->ic_chan_non_occupy[i].tv_usec);
|
||||
}
|
||||
}
|
||||
|
||||
/* recompute the next time a Non-Occupancy Period
|
||||
* expires */
|
||||
/* Recompute the next time a Non-Occupancy Period
|
||||
* expires/ */
|
||||
ieee80211_update_dfs_channel_non_occupancy_timer(ic);
|
||||
|
||||
c = ieee80211_find_channel(ic, ichan->ic_freq, ichan->ic_flags);
|
||||
c = ieee80211_find_channel(ic, ichan->ic_freq,
|
||||
ichan->ic_flags);
|
||||
if (c == NULL) {
|
||||
if_printf(dev, "%s: Couldn't find matching channel for dfs chanchange (%d, 0x%x)\n",
|
||||
__func__, ichan->ic_freq, ichan->ic_flags);
|
||||
if_printf(dev, "%s: Couldn't find matching "
|
||||
"channel for dfs chanchange "
|
||||
"(%d, 0x%x)\n",
|
||||
__func__, ichan->ic_freq,
|
||||
ichan->ic_flags);
|
||||
return;
|
||||
}
|
||||
if (ic->ic_curchan->ic_freq == c->ic_freq) {
|
||||
if_printf(dev, "%s: Invoking ieee80211_dfs_action (%d, 0x%x)\n", __func__, ichan->ic_freq, ichan->ic_flags);
|
||||
/* The current channel has been marked. We need to move away from it. */
|
||||
if_printf(dev, "%s: Invoking "
|
||||
"ieee80211_dfs_action "
|
||||
"(%d, 0x%x)\n",
|
||||
__func__, ichan->ic_freq,
|
||||
ichan->ic_flags);
|
||||
/* The current channel has been marked. We
|
||||
* need to move away from it. */
|
||||
ieee80211_dfs_action(ic);
|
||||
}
|
||||
else
|
||||
} else
|
||||
if_printf(dev,
|
||||
"Channel frequency doesn't match expectation! ichan=%3d (%4d MHz) ic_curchan=%3d (%4d MHz). Not invoking ieee80211_dfs_action.\n",
|
||||
ichan->ic_ieee, ichan->ic_freq,
|
||||
ic->ic_curchan->ic_ieee, ic->ic_curchan->ic_freq);
|
||||
"Unexpected channel frequency! "
|
||||
"ichan=%3d (%4d MHz) "
|
||||
"ic_curchan=%3d (%4d MHz). "
|
||||
"Not invoking "
|
||||
"ieee80211_dfs_action.\n",
|
||||
ichan->ic_ieee,
|
||||
ichan->ic_freq,
|
||||
ic->ic_curchan->ic_ieee,
|
||||
ic->ic_curchan->ic_freq);
|
||||
} else {
|
||||
/* Change to a radar free 11a channel for dfstesttime seconds */
|
||||
/* Change to a radar free 11a channel for dfstesttime
|
||||
* seconds. */
|
||||
ic->ic_chanchange_chan = IEEE80211_RADAR_TEST_MUTE_CHAN;
|
||||
ic->ic_chanchange_tbtt = IEEE80211_RADAR_CHANCHANGE_TBTT_COUNT;
|
||||
ic->ic_chanchange_tbtt =
|
||||
IEEE80211_RADAR_CHANCHANGE_TBTT_COUNT;
|
||||
ic->ic_flags |= IEEE80211_F_CHANSWITCH;
|
||||
if_printf(dev,
|
||||
"Mute test - markdfs is off, we are in hostap mode, found radar on channel %3d (%4d MHz) ic->ic_curchan=%3d (%4d MHz). Not invoking ieee80211_dfs_action.\n",
|
||||
ichan->ic_ieee, ichan->ic_freq,
|
||||
ic->ic_curchan->ic_ieee, ic->ic_curchan->ic_freq);
|
||||
"Mute test - markdfs is off, we are "
|
||||
"in hostap mode, found radar on "
|
||||
"channel %3d (%4d MHz) "
|
||||
"ic->ic_curchan=%3d (%4d MHz). "
|
||||
"Not invoking ieee80211_dfs_action.\n",
|
||||
ichan->ic_ieee, ichan->ic_freq,
|
||||
ic->ic_curchan->ic_ieee,
|
||||
ic->ic_curchan->ic_freq);
|
||||
}
|
||||
} else {
|
||||
/* Are we in STA mode? If so, send an action msg to AP saying we found a radar? */
|
||||
/* XXX: Are we in STA mode? If so, send an action msg. to AP
|
||||
* saying we found a radar? */
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_mark_dfs);
|
||||
@ -1787,9 +1856,7 @@ ieee80211_build_sc_ie(struct ieee80211com *ic)
|
||||
struct ieee80211_channel *c;
|
||||
u_int8_t prevchan;
|
||||
|
||||
/*
|
||||
* Fill in Supported Channels IE.
|
||||
*/
|
||||
/* Fill in Supported Channels IE. */
|
||||
memset(ie, 0, sizeof(*ie));
|
||||
ie->sc_id = IEEE80211_ELEMID_SUPPCHAN;
|
||||
|
||||
|
@ -484,8 +484,7 @@ ieee80211_beacon_update(struct ieee80211_node *ni,
|
||||
* - iv_chanchange_count= number of beacon intervals elapsed (0)
|
||||
* - ic_chanchange_tbtt = number of beacon intervals before switching
|
||||
* - ic_chanchange_chan = IEEE channel number after switching
|
||||
* - ic_flags |= IEEE80211_F_CHANSWITCH
|
||||
*/
|
||||
* - ic_flags |= IEEE80211_F_CHANSWITCH */
|
||||
|
||||
if (IEEE80211_IS_MODE_BEACON(vap->iv_opmode)) {
|
||||
|
||||
@ -494,18 +493,25 @@ ieee80211_beacon_update(struct ieee80211_node *ni,
|
||||
struct ieee80211_ie_csa *csa_ie =
|
||||
(struct ieee80211_ie_csa *)bo->bo_chanswitch;
|
||||
|
||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH, "%s: Sending 802.11h chanswitch IE: %d/%d\n", __func__, ic->ic_chanchange_chan, ic->ic_chanchange_tbtt);
|
||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
|
||||
"%s: Sending 802.11h chanswitch IE: "
|
||||
"%d/%d\n", __func__,
|
||||
ic->ic_chanchange_chan,
|
||||
ic->ic_chanchange_tbtt);
|
||||
if (!vap->iv_chanchange_count) {
|
||||
vap->iv_flags |= IEEE80211_F_CHANSWITCH;
|
||||
|
||||
/* copy out trailer to open up a slot */
|
||||
memmove(bo->bo_chanswitch + sizeof(*csa_ie),
|
||||
bo->bo_chanswitch, bo->bo_chanswitch_trailerlen);
|
||||
bo->bo_chanswitch,
|
||||
bo->bo_chanswitch_trailerlen);
|
||||
|
||||
/* add ie in opened slot */
|
||||
csa_ie->csa_id = IEEE80211_ELEMID_CHANSWITCHANN;
|
||||
csa_ie->csa_len = sizeof(*csa_ie) - 2; /* fixed length */
|
||||
csa_ie->csa_mode = 1; /* STA shall transmit no further frames */
|
||||
/* fixed length */
|
||||
csa_ie->csa_len = sizeof(*csa_ie) - 2;
|
||||
/* STA shall transmit no further frames */
|
||||
csa_ie->csa_mode = 1;
|
||||
csa_ie->csa_chan = ic->ic_chanchange_chan;
|
||||
csa_ie->csa_count = ic->ic_chanchange_tbtt;
|
||||
|
||||
@ -517,7 +523,8 @@ ieee80211_beacon_update(struct ieee80211_node *ni,
|
||||
bo->bo_ath_caps += sizeof(*csa_ie);
|
||||
bo->bo_xr += sizeof(*csa_ie);
|
||||
|
||||
/* indicate new beacon length so other layers may manage memory */
|
||||
/* indicate new beacon length so other layers
|
||||
* may manage memory */
|
||||
skb_put(skb, sizeof(*csa_ie));
|
||||
len_changed = 1;
|
||||
} else if(csa_ie->csa_count)
|
||||
@ -531,40 +538,49 @@ ieee80211_beacon_update(struct ieee80211_node *ni,
|
||||
#ifdef ATH_SUPERG_XR
|
||||
if (vap->iv_flags & IEEE80211_F_XRUPDATE) {
|
||||
if (vap->iv_xrvap)
|
||||
(void) ieee80211_add_xr_param(bo->bo_xr, vap);
|
||||
(void)ieee80211_add_xr_param(bo->bo_xr, vap);
|
||||
vap->iv_flags &= ~IEEE80211_F_XRUPDATE;
|
||||
}
|
||||
#endif
|
||||
if ((ic->ic_flags_ext & IEEE80211_FEXT_ERPUPDATE) && (bo->bo_erp != NULL)) {
|
||||
(void) ieee80211_add_erp(bo->bo_erp, ic);
|
||||
if ((ic->ic_flags_ext & IEEE80211_FEXT_ERPUPDATE) &&
|
||||
(bo->bo_erp != NULL)) {
|
||||
(void)ieee80211_add_erp(bo->bo_erp, ic);
|
||||
ic->ic_flags_ext &= ~IEEE80211_FEXT_ERPUPDATE;
|
||||
}
|
||||
}
|
||||
/* if it is a mode change beacon for dynamic turbo case */
|
||||
if (((ic->ic_ath_cap & IEEE80211_ATHC_BOOST) != 0) ^
|
||||
IEEE80211_IS_CHAN_TURBO(ic->ic_curchan))
|
||||
ieee80211_add_athAdvCap(bo->bo_ath_caps, vap->iv_bss->ni_ath_flags,
|
||||
vap->iv_bss->ni_ath_defkeyindex);
|
||||
ieee80211_add_athAdvCap(bo->bo_ath_caps,
|
||||
vap->iv_bss->ni_ath_flags,
|
||||
vap->iv_bss->ni_ath_defkeyindex);
|
||||
/* add APP_IE buffer if app updated it */
|
||||
if (vap->iv_flags_ext & IEEE80211_FEXT_APPIE_UPDATE) {
|
||||
/* adjust the buffer size if the size is changed */
|
||||
if (vap->app_ie[IEEE80211_APPIE_FRAME_BEACON].length != bo->bo_appie_buf_len) {
|
||||
if (vap->app_ie[IEEE80211_APPIE_FRAME_BEACON].length !=
|
||||
bo->bo_appie_buf_len) {
|
||||
int diff_len;
|
||||
diff_len = vap->app_ie[IEEE80211_APPIE_FRAME_BEACON].length - bo->bo_appie_buf_len;
|
||||
diff_len =
|
||||
vap->app_ie[IEEE80211_APPIE_FRAME_BEACON].
|
||||
length -
|
||||
bo->bo_appie_buf_len;
|
||||
|
||||
if (diff_len > 0)
|
||||
skb_put(skb, diff_len);
|
||||
else
|
||||
skb_trim(skb, skb->len + diff_len);
|
||||
|
||||
bo->bo_appie_buf_len = vap->app_ie[IEEE80211_APPIE_FRAME_BEACON].length;
|
||||
bo->bo_appie_buf_len =
|
||||
vap->app_ie[IEEE80211_APPIE_FRAME_BEACON].
|
||||
length;
|
||||
/* update the trailer lens */
|
||||
bo->bo_chanswitch_trailerlen += diff_len;
|
||||
bo->bo_tim_trailerlen += diff_len;
|
||||
|
||||
len_changed = 1;
|
||||
}
|
||||
memcpy(bo->bo_appie_buf, vap->app_ie[IEEE80211_APPIE_FRAME_BEACON].ie,
|
||||
memcpy(bo->bo_appie_buf,
|
||||
vap->app_ie[IEEE80211_APPIE_FRAME_BEACON].ie,
|
||||
vap->app_ie[IEEE80211_APPIE_FRAME_BEACON].length);
|
||||
|
||||
vap->iv_flags_ext &= ~IEEE80211_FEXT_APPIE_UPDATE;
|
||||
|
@ -2378,9 +2378,7 @@ count_nodes(void *_arg, struct ieee80211_node *ni)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Structure to be passed through combinations() to channel_combination()
|
||||
*/
|
||||
/* Structure to be passed through combinations() to channel_combination() */
|
||||
struct channel_combination_arg {
|
||||
struct ieee80211com *ic;
|
||||
struct ieee80211_node *new;
|
||||
@ -2389,9 +2387,7 @@ struct channel_combination_arg {
|
||||
};
|
||||
|
||||
#ifdef IEEE80211_DEBUG
|
||||
/*
|
||||
* sprintf() set[] array consisting of k integers
|
||||
*/
|
||||
/* sprintf() set[] array consisting of k integers */
|
||||
static const char*
|
||||
ints_sprintf(const int k, const int set[])
|
||||
{
|
||||
@ -2403,32 +2399,37 @@ ints_sprintf(const int k, const int set[])
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Action done for each combination of channels that are not supported by currently joining station.
|
||||
* Context: combinations()
|
||||
*/
|
||||
|
||||
/* Action done for each combination of channels that are not supported by
|
||||
* currently joining station.
|
||||
* Context: combinations() */
|
||||
static void
|
||||
channel_combination(const int k, const int subset[], void *_arg)
|
||||
{
|
||||
struct channel_combination_arg *arg = (struct channel_combination_arg *)_arg;
|
||||
struct channel_combination_arg *arg =
|
||||
(struct channel_combination_arg *)_arg;
|
||||
struct ieee80211com *ic = arg->ic;
|
||||
struct count_nodes_arg cn_arg = { k, subset, 0, arg->new };
|
||||
int permil, allowed;
|
||||
int sta_assoc = ic->ic_sta_assoc; /* make > 0 check consistent with / operation */
|
||||
int sta_assoc = ic->ic_sta_assoc; /* make > 0 check consistent
|
||||
* with / operation */
|
||||
|
||||
ieee80211_iterate_nodes(&arg->ic->ic_sta, &count_nodes, (void*)&cn_arg);
|
||||
ieee80211_iterate_nodes(&arg->ic->ic_sta,
|
||||
&count_nodes, (void*)&cn_arg);
|
||||
|
||||
/* The following two sanity checks can theoretically fail due to lack
|
||||
* of locking, but since it is not fatal, we will just print a debug
|
||||
* msg and neglect it */
|
||||
if (cn_arg.count == 0) {
|
||||
IEEE80211_NOTE(arg->new->ni_vap, IEEE80211_MSG_ANY, arg->new, "%s",
|
||||
"ic_chan_nodes incosistency (incorrect uncommon channel count)");
|
||||
IEEE80211_NOTE(arg->new->ni_vap, IEEE80211_MSG_ANY, arg->new,
|
||||
"%s", "ic_chan_nodes incosistency (incorrect "
|
||||
"uncommon channel count)");
|
||||
return;
|
||||
}
|
||||
if (sta_assoc == 0) {
|
||||
IEEE80211_NOTE(arg->new->ni_vap, IEEE80211_MSG_ANY, arg->new, "%s",
|
||||
"no STAs associated, so there should be no \"uncommon\" channels");
|
||||
IEEE80211_NOTE(arg->new->ni_vap, IEEE80211_MSG_ANY, arg->new,
|
||||
"%s", "no STAs associated, so there should be "
|
||||
"no \"uncommon\" channels");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2438,11 +2439,13 @@ channel_combination(const int k, const int subset[], void *_arg)
|
||||
if (allowed > 1000)
|
||||
allowed = 1000;
|
||||
|
||||
IEEE80211_NOTE(arg->new->ni_vap, IEEE80211_MSG_ASSOC|IEEE80211_MSG_DOTH, arg->new,
|
||||
"Making channels %savailable would require kicking out %d stations,",
|
||||
ints_sprintf(k, subset), cn_arg.count);
|
||||
IEEE80211_NOTE(arg->new->ni_vap, IEEE80211_MSG_ASSOC|IEEE80211_MSG_DOTH, arg->new,
|
||||
"what is %d permils of all associated STAs (slcg permits < %d).", permil, allowed);
|
||||
IEEE80211_NOTE(arg->new->ni_vap, IEEE80211_MSG_ASSOC|IEEE80211_MSG_DOTH,
|
||||
arg->new, "Making channels %savailable would require "
|
||||
"kicking out %d stations,", ints_sprintf(k, subset),
|
||||
cn_arg.count);
|
||||
IEEE80211_NOTE(arg->new->ni_vap, IEEE80211_MSG_ASSOC|IEEE80211_MSG_DOTH,
|
||||
arg->new, "what is %d permils of all associated STAs "
|
||||
"(slcg permits < %d).", permil, allowed);
|
||||
|
||||
if (permil > allowed)
|
||||
return;
|
||||
@ -2452,11 +2455,11 @@ channel_combination(const int k, const int subset[], void *_arg)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Enumerate all combinations of k-element subset of n-element set via a callback function
|
||||
*/
|
||||
/* Enumerate all combinations of k-element subset of n-element set via a
|
||||
* callback function. */
|
||||
static void
|
||||
combinations(int n, int set[], int k, void (*callback)(const int, const int [], void *), void *arg)
|
||||
combinations(int n, int set[], int k,
|
||||
void (*callback)(const int, const int [], void *), void *arg)
|
||||
{
|
||||
int subset[k], pos[k], i;
|
||||
for (i = 0; i < k; i++)
|
||||
@ -2518,14 +2521,18 @@ find_worse_nodes(struct ieee80211com *ic, struct ieee80211_node *new)
|
||||
}
|
||||
|
||||
to_gain = ic->ic_sc_mincom - n_common + 1;
|
||||
IEEE80211_NOTE(new->ni_vap, IEEE80211_MSG_ASSOC|IEEE80211_MSG_DOTH, new,
|
||||
"By accepting STA we would need to gain at least %d common channels.", to_gain);
|
||||
IEEE80211_NOTE(new->ni_vap, IEEE80211_MSG_ASSOC|IEEE80211_MSG_DOTH, new,
|
||||
"%d channels supported by the joining STA are not commonly supported by others.", n_uncommon);
|
||||
IEEE80211_NOTE(new->ni_vap, IEEE80211_MSG_ASSOC | IEEE80211_MSG_DOTH,
|
||||
new, "By accepting STA we would need to gain at least "
|
||||
"%d common channels.", to_gain);
|
||||
IEEE80211_NOTE(new->ni_vap, IEEE80211_MSG_ASSOC | IEEE80211_MSG_DOTH,
|
||||
new, "%d channels supported by the joining STA are "
|
||||
"not commonly supported by others.", n_uncommon);
|
||||
|
||||
if (to_gain > n_uncommon) {
|
||||
IEEE80211_NOTE(new->ni_vap, IEEE80211_MSG_ASSOC|IEEE80211_MSG_DOTH, new,
|
||||
"%s", "Even disassociating all the nodes will not be enough.");
|
||||
IEEE80211_NOTE(new->ni_vap, IEEE80211_MSG_ASSOC |
|
||||
IEEE80211_MSG_DOTH, new, "%s",
|
||||
"Even disassociating all the nodes will not "
|
||||
"be enough.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2536,34 +2543,45 @@ find_worse_nodes(struct ieee80211com *ic, struct ieee80211_node *new)
|
||||
int j = 0;
|
||||
|
||||
CHANNEL_FOREACH(i, ic, tmp1, tmp2)
|
||||
if (isset(new->ni_suppchans_new, i) && ic->ic_chan_nodes[i] != ic->ic_cn_total) {
|
||||
if (isset(new->ni_suppchans_new, i) &&
|
||||
(ic->ic_chan_nodes[i] !=
|
||||
ic->ic_cn_total)) {
|
||||
if (j == n_uncommon)
|
||||
/* silent assert */
|
||||
break;
|
||||
uncommon[j++] = i;
|
||||
}
|
||||
|
||||
combinations(n_uncommon, uncommon, to_gain, &channel_combination, &arg);
|
||||
combinations(n_uncommon, uncommon, to_gain,
|
||||
&channel_combination, &arg);
|
||||
if (arg.benefit < 0) {
|
||||
IEEE80211_NOTE(new->ni_vap, IEEE80211_MSG_ASSOC|IEEE80211_MSG_DOTH, new,
|
||||
"%s", "No combination of channels allows a beneficial trade-off.");
|
||||
IEEE80211_NOTE(new->ni_vap, IEEE80211_MSG_ASSOC |
|
||||
IEEE80211_MSG_DOTH, new, "%s",
|
||||
"No combination of channels allows a "
|
||||
"beneficial trade-off.");
|
||||
return 0;
|
||||
}
|
||||
IEEE80211_NOTE(new->ni_vap, IEEE80211_MSG_ASSOC|IEEE80211_MSG_DOTH, new,
|
||||
"Nodes which don't support channels %swill be forced to leave.",
|
||||
IEEE80211_NOTE(new->ni_vap, IEEE80211_MSG_ASSOC |
|
||||
IEEE80211_MSG_DOTH, new,
|
||||
"Nodes which don't support channels %swill be "
|
||||
"forced to leave.",
|
||||
ints_sprintf(to_gain, best));
|
||||
|
||||
if (new->ni_needed_chans != NULL)
|
||||
FREE(new->ni_needed_chans, M_DEVBUF);
|
||||
MALLOC(new->ni_needed_chans, void*, to_gain * sizeof(*new->ni_needed_chans), M_DEVBUF, M_NOWAIT);
|
||||
MALLOC(new->ni_needed_chans, void*,
|
||||
to_gain * sizeof(*new->ni_needed_chans),
|
||||
M_DEVBUF, M_NOWAIT);
|
||||
|
||||
if (new->ni_needed_chans == NULL) {
|
||||
IEEE80211_NOTE(new->ni_vap,
|
||||
IEEE80211_MSG_DEBUG | IEEE80211_MSG_DOTH, new,
|
||||
"%s", "needed_chans allocation failed");
|
||||
IEEE80211_NOTE(new->ni_vap, IEEE80211_MSG_DEBUG |
|
||||
IEEE80211_MSG_DOTH, new, "%s",
|
||||
"needed_chans allocation failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* store the list of channels to remove nodes which don't support them */
|
||||
/* Store the list of channels to remove nodes which don't
|
||||
* support them. */
|
||||
for (i = 0; i < to_gain; i++)
|
||||
new->ni_needed_chans[i] = best[i];
|
||||
new->ni_n_needed_chans = to_gain;
|
||||
@ -2587,19 +2605,24 @@ ieee80211_parse_sc_ie(struct ieee80211_node *ni, u_int8_t *frm,
|
||||
|
||||
if (sc_ie == NULL) {
|
||||
if (ni->ni_ic->ic_sc_algorithm == IEEE80211_SC_STRICT) {
|
||||
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC|IEEE80211_MSG_DOTH, wh->i_addr2,
|
||||
"deny %s request, no supported channels ie",
|
||||
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC |
|
||||
IEEE80211_MSG_DOTH, wh->i_addr2,
|
||||
"deny %s request, no supported "
|
||||
"channels IE",
|
||||
reassoc ? "reassoc" : "assoc");
|
||||
return IEEE80211_STATUS_SUPPCHAN_UNACCEPTABLE;
|
||||
}
|
||||
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC|IEEE80211_MSG_DOTH, wh->i_addr2,
|
||||
"%s request: no supported channels ie",
|
||||
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC |
|
||||
IEEE80211_MSG_DOTH, wh->i_addr2,
|
||||
"%s request: no supported channels IE",
|
||||
reassoc ? "reassoc" : "assoc");
|
||||
return IEEE80211_STATUS_SUCCESS;
|
||||
}
|
||||
if (sc_ie->sc_len % 2 != 0) {
|
||||
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC|IEEE80211_MSG_DOTH, wh->i_addr2,
|
||||
"deny %s request, malformed supported channels ie (len)",
|
||||
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC |
|
||||
IEEE80211_MSG_DOTH, wh->i_addr2,
|
||||
"deny %s request, malformed supported "
|
||||
"channels IE (len)",
|
||||
reassoc ? "reassoc" : "assoc");
|
||||
/* XXX: deauth with IEEE80211_REASON_IE_INVALID? */
|
||||
return IEEE80211_STATUS_SUPPCHAN_UNACCEPTABLE;
|
||||
@ -2608,8 +2631,10 @@ ieee80211_parse_sc_ie(struct ieee80211_node *ni, u_int8_t *frm,
|
||||
MALLOC(ni->ni_suppchans_new, void*, IEEE80211_CHAN_BYTES,
|
||||
M_DEVBUF, M_NOWAIT);
|
||||
if (ni->ni_suppchans_new == NULL) {
|
||||
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC|IEEE80211_MSG_DOTH, wh->i_addr2,
|
||||
"deny %s request, couldn't allocate memory for sc ie!",
|
||||
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC |
|
||||
IEEE80211_MSG_DOTH, wh->i_addr2,
|
||||
"deny %s request, couldn't allocate "
|
||||
"memory for SC IE!",
|
||||
reassoc ? "reassoc" : "assoc");
|
||||
return IEEE80211_STATUS_SUPPCHAN_UNACCEPTABLE;
|
||||
}
|
||||
@ -2620,14 +2645,19 @@ ieee80211_parse_sc_ie(struct ieee80211_node *ni, u_int8_t *frm,
|
||||
/* XXX: see 802.11d-2001-4-05-03-interp,
|
||||
* but what about .11j, turbo, etc.? */
|
||||
u_int8_t step = (chan <= 14 ? 1 : 4);
|
||||
u_int16_t last = chan + step * (sc_ie->sc_subband[i].sc_number - 1);
|
||||
u_int16_t last = chan + step *
|
||||
(sc_ie->sc_subband[i].sc_number - 1);
|
||||
|
||||
/* check for subband under- (sc_number == 0) or overflow */
|
||||
if ((last < chan) || (chan <= 14 && last > 14) || (chan > 14 && last > 200)) {
|
||||
if ((last < chan) || ((chan <= 14) && (last > 14)) ||
|
||||
(chan > 14 && last > 200)) {
|
||||
/* XXX: deauth with IEEE80211_REASON_IE_INVALID? */
|
||||
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC|IEEE80211_MSG_DOTH, wh->i_addr2,
|
||||
"deny %s request, malformed supported channels ie "
|
||||
"(subbands, %d, %d)", reassoc ? "reassoc" : "assoc", chan, last);
|
||||
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC |
|
||||
IEEE80211_MSG_DOTH, wh->i_addr2,
|
||||
"deny %s request, malformed supported "
|
||||
"channels ie (subbands, %d, %d)",
|
||||
reassoc ? "reassoc" : "assoc",
|
||||
chan, last);
|
||||
return IEEE80211_STATUS_SUPPCHAN_UNACCEPTABLE;
|
||||
}
|
||||
|
||||
@ -2637,42 +2667,50 @@ ieee80211_parse_sc_ie(struct ieee80211_node *ni, u_int8_t *frm,
|
||||
/* forbid STAs that claim they don't support the channel they are
|
||||
* currently operating at */
|
||||
if (isclr(ni->ni_suppchans_new, ic->ic_bsschan->ic_ieee)) {
|
||||
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC|IEEE80211_MSG_DOTH, wh->i_addr2,
|
||||
"deny %s request, sc ie does not contain bss channel"
|
||||
"(subbands)", reassoc ? "reassoc" : "assoc");
|
||||
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC |
|
||||
IEEE80211_MSG_DOTH, wh->i_addr2,
|
||||
"deny %s request, sc ie does not contain bss "
|
||||
"channel(subbands)",
|
||||
reassoc ? "reassoc" : "assoc");
|
||||
return IEEE80211_STATUS_SUPPCHAN_UNACCEPTABLE;
|
||||
}
|
||||
|
||||
if (ic->ic_sc_algorithm != IEEE80211_SC_TIGHT &&
|
||||
ic->ic_sc_algorithm != IEEE80211_SC_STRICT)
|
||||
if ((ic->ic_sc_algorithm != IEEE80211_SC_TIGHT) &&
|
||||
(ic->ic_sc_algorithm != IEEE80211_SC_STRICT))
|
||||
goto success;
|
||||
|
||||
/* count number of channels that will be common to all STAs after the
|
||||
* new one joins */
|
||||
count = 0;
|
||||
CHANNEL_FOREACH(i, ic, tmp1, tmp2)
|
||||
if (isset(ni->ni_suppchans_new, i) && ic->ic_chan_nodes[i] == ic->ic_cn_total)
|
||||
if (isset(ni->ni_suppchans_new, i) && (
|
||||
ic->ic_chan_nodes[i] == ic->ic_cn_total))
|
||||
count++;
|
||||
|
||||
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC|IEEE80211_MSG_DOTH, wh->i_addr2,
|
||||
"%s request: %d common channels, %d required",
|
||||
reassoc ? "reassoc" : "assoc", count, ic->ic_sc_mincom);
|
||||
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC | IEEE80211_MSG_DOTH,
|
||||
wh->i_addr2, "%s request: %d common channels, %d "
|
||||
"required", reassoc ? "reassoc" : "assoc",
|
||||
count, ic->ic_sc_mincom);
|
||||
if (count < ic->ic_sc_mincom) {
|
||||
/* common channel count decreases below the required minimum */
|
||||
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC|IEEE80211_MSG_DOTH, wh->i_addr2,
|
||||
"%s request: not enough common channels available, tight/strict algorithm engaged",
|
||||
reassoc ? "reassoc" : "assoc");
|
||||
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC | IEEE80211_MSG_DOTH,
|
||||
wh->i_addr2, "%s request: not enough common "
|
||||
"channels available, tight/strict algorithm "
|
||||
"engaged", reassoc ? "reassoc" : "assoc");
|
||||
|
||||
if (!find_worse_nodes(ic, ni)) {
|
||||
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC|IEEE80211_MSG_DOTH, wh->i_addr2,
|
||||
"deny %s request, tight/strict criterium not met",
|
||||
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC |
|
||||
IEEE80211_MSG_DOTH, wh->i_addr2,
|
||||
"deny %s request, tight/strict "
|
||||
"criterion not met",
|
||||
reassoc ? "reassoc" : "assoc");
|
||||
return IEEE80211_STATUS_SUPPCHAN_UNACCEPTABLE;
|
||||
}
|
||||
}
|
||||
|
||||
success:
|
||||
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_DOTH|IEEE80211_MSG_ASSOC|IEEE80211_MSG_ELEMID, wh->i_addr2,
|
||||
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_DOTH | IEEE80211_MSG_ASSOC |
|
||||
IEEE80211_MSG_ELEMID, wh->i_addr2,
|
||||
"%s", "supported channels ie parsing successful");
|
||||
return IEEE80211_STATUS_SUCCESS;
|
||||
}
|
||||
@ -2700,8 +2738,8 @@ ieee80211_doth_cancel_cs(struct ieee80211vap *vap)
|
||||
del_timer(&vap->iv_csa_timer);
|
||||
if (vap->iv_csa_jiffies)
|
||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
|
||||
"channel switch canceled (was: to %3d (%4d MHz) in %u "
|
||||
"TBTT, mode %u)\n",
|
||||
"channel switch canceled (was: ""to %3d "
|
||||
"(%4d MHz) in %u TBTT, mode %u)\n",
|
||||
vap->iv_csa_chan->ic_ieee,
|
||||
vap->iv_csa_chan->ic_freq,
|
||||
vap->iv_csa_count, vap->iv_csa_mode);
|
||||
@ -3110,7 +3148,8 @@ ieee80211_recv_mgmt(struct ieee80211vap *vap,
|
||||
case IEEE80211_ELEMID_FHPARMS:
|
||||
if (ic->ic_phytype == IEEE80211_T_FH) {
|
||||
scan.fhdwell = LE_READ_2(&frm[2]);
|
||||
scan.chan = IEEE80211_FH_CHAN(frm[4], frm[5]);
|
||||
scan.chan = IEEE80211_FH_CHAN(frm[4],
|
||||
frm[5]);
|
||||
scan.fhindex = frm[6];
|
||||
}
|
||||
break;
|
||||
@ -3233,42 +3272,57 @@ ieee80211_recv_mgmt(struct ieee80211vap *vap,
|
||||
sizeof(ni->ni_tstamp));
|
||||
if (ni->ni_intval != scan.bintval) {
|
||||
IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,
|
||||
"beacon interval divergence: was %u, now %u",
|
||||
ni->ni_intval, scan.bintval);
|
||||
"beacon interval divergence: "
|
||||
"was %u, now %u",
|
||||
ni->ni_intval, scan.bintval);
|
||||
if (!ni->ni_intval_end) {
|
||||
int msecs = 0; /* silence compiler */
|
||||
ni->ni_intval_cnt = 0;
|
||||
ni->ni_intval_old = ni->ni_intval;
|
||||
msecs = (ni->ni_intval_old * 1024 * 10) / 1000;
|
||||
msecs = (ni->ni_intval_old * 1024 * 10) /
|
||||
1000;
|
||||
ni->ni_intval_end = jiffies +
|
||||
msecs_to_jiffies(msecs);
|
||||
IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,
|
||||
"scheduling beacon interval measurement for %u msecs",
|
||||
msecs);
|
||||
IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC,
|
||||
ni, "scheduling beacon "
|
||||
"interval measurement "
|
||||
"for %u msecs",
|
||||
msecs);
|
||||
}
|
||||
if (scan.bintval > ni->ni_intval) {
|
||||
ni->ni_intval = scan.bintval;
|
||||
vap->iv_flags_ext |= IEEE80211_FEXT_APPIE_UPDATE;
|
||||
vap->iv_flags_ext |=
|
||||
IEEE80211_FEXT_APPIE_UPDATE;
|
||||
}
|
||||
/* XXX statistic */
|
||||
/* XXX: statistic */
|
||||
}
|
||||
if (ni->ni_intval_end) {
|
||||
if (scan.bintval == ni->ni_intval_old)
|
||||
ni->ni_intval_cnt++;
|
||||
if (!time_before(jiffies, ni->ni_intval_end)) {
|
||||
IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,
|
||||
"beacon interval measurement finished, old value repeated: %u times",
|
||||
ni->ni_intval_cnt);
|
||||
IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC,
|
||||
ni, "beacon interval "
|
||||
"measurement finished, "
|
||||
"old value repeated: "
|
||||
"%u times",
|
||||
ni->ni_intval_cnt);
|
||||
ni->ni_intval_end = 0;
|
||||
if (ni->ni_intval_cnt == 0) {
|
||||
IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,
|
||||
"reprogramming bmiss timer from %u to %u",
|
||||
ni->ni_intval_old, scan.bintval);
|
||||
ni->ni_intval = scan.bintval;
|
||||
vap->iv_flags_ext |= IEEE80211_FEXT_APPIE_UPDATE;
|
||||
IEEE80211_NOTE(vap,
|
||||
IEEE80211_MSG_ASSOC, ni,
|
||||
"reprogramming bmiss "
|
||||
"timer from %u to %u",
|
||||
ni->ni_intval_old,
|
||||
scan.bintval);
|
||||
ni->ni_intval = scan.bintval;
|
||||
vap->iv_flags_ext |=
|
||||
IEEE80211_FEXT_APPIE_UPDATE;
|
||||
} else {
|
||||
IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,
|
||||
"ignoring the divergence (maybe someone tried to spoof the AP?)", 0);
|
||||
IEEE80211_NOTE(vap,
|
||||
IEEE80211_MSG_ASSOC, ni,
|
||||
"ignoring the divergence "
|
||||
"(maybe someone tried to "
|
||||
"spoof the AP?)", 0);
|
||||
}
|
||||
}
|
||||
/* XXX statistic */
|
||||
@ -3284,7 +3338,8 @@ ieee80211_recv_mgmt(struct ieee80211vap *vap,
|
||||
ni->ni_erp = scan.erp;
|
||||
/* XXX statistic */
|
||||
}
|
||||
if ((ni->ni_capinfo ^ scan.capinfo) & IEEE80211_CAPINFO_SHORT_SLOTTIME) {
|
||||
if ((ni->ni_capinfo ^ scan.capinfo) &
|
||||
IEEE80211_CAPINFO_SHORT_SLOTTIME) {
|
||||
IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,
|
||||
"capabilities change: was 0x%x, now 0x%x",
|
||||
ni->ni_capinfo, scan.capinfo);
|
||||
@ -3294,16 +3349,20 @@ ieee80211_recv_mgmt(struct ieee80211vap *vap,
|
||||
*/
|
||||
ieee80211_set_shortslottime(ic,
|
||||
IEEE80211_IS_CHAN_A(ic->ic_bsschan) ||
|
||||
(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
|
||||
(ni->ni_capinfo &
|
||||
IEEE80211_CAPINFO_SHORT_SLOTTIME));
|
||||
ni->ni_capinfo = scan.capinfo;
|
||||
/* XXX statistic */
|
||||
}
|
||||
if (scan.wme != NULL &&
|
||||
(ni->ni_flags & IEEE80211_NODE_QOS)) {
|
||||
int _retval;
|
||||
if ((_retval = ieee80211_parse_wmeparams(vap, scan.wme, wh, &qosinfo)) >= 0) {
|
||||
if ((_retval = ieee80211_parse_wmeparams(
|
||||
vap, scan.wme,
|
||||
wh, &qosinfo)) >= 0) {
|
||||
if (qosinfo & WME_CAPINFO_UAPSD_EN)
|
||||
ni->ni_flags |= IEEE80211_NODE_UAPSD;
|
||||
ni->ni_flags |=
|
||||
IEEE80211_NODE_UAPSD;
|
||||
if (_retval > 0)
|
||||
ieee80211_wme_updateparams(vap);
|
||||
}
|
||||
@ -3331,14 +3390,15 @@ ieee80211_recv_mgmt(struct ieee80211vap *vap,
|
||||
vap->iv_dtim_count = tim->tim_count;
|
||||
}
|
||||
|
||||
/* WDS/Repeater: re-schedule software beacon timer for STA */
|
||||
if (vap->iv_state == IEEE80211_S_RUN &&
|
||||
vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) {
|
||||
mod_timer(&vap->iv_swbmiss, jiffies + vap->iv_swbmiss_period);
|
||||
/* WDS/Repeater: re-schedule software beacon timer for
|
||||
* STA. */
|
||||
if ((vap->iv_state == IEEE80211_S_RUN) &&
|
||||
(vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)) {
|
||||
mod_timer(&vap->iv_swbmiss,
|
||||
jiffies + vap->iv_swbmiss_period);
|
||||
}
|
||||
|
||||
/*
|
||||
* If scanning, pass the info to the scan module.
|
||||
/* If scanning, pass the info to the scan module.
|
||||
* Otherwise, check if it's the right time to do
|
||||
* a background scan. Background scanning must
|
||||
* be enabled and we must not be operating in the
|
||||
@ -3349,8 +3409,7 @@ ieee80211_recv_mgmt(struct ieee80211vap *vap,
|
||||
* is the mechanism by which a background scan
|
||||
* is started _and_ continued each time we
|
||||
* return on-channel to receive a beacon from
|
||||
* our ap.
|
||||
*/
|
||||
* our ap. */
|
||||
if (ic->ic_flags & IEEE80211_F_SCAN)
|
||||
ieee80211_add_scan(vap, &scan, wh,
|
||||
subtype, rssi, rtsf);
|
||||
@ -3382,7 +3441,8 @@ ieee80211_recv_mgmt(struct ieee80211vap *vap,
|
||||
IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
|
||||
memcpy(ni->ni_tstamp.data, scan.tstamp,
|
||||
sizeof(ni->ni_tstamp));
|
||||
ni->ni_intval = IEEE80211_BINTVAL_SANITISE(scan.bintval);
|
||||
ni->ni_intval =
|
||||
IEEE80211_BINTVAL_SANITISE(scan.bintval);
|
||||
ni->ni_capinfo = scan.capinfo;
|
||||
ni->ni_chan = ic->ic_curchan;
|
||||
ni->ni_fhdwell = scan.fhdwell;
|
||||
@ -3420,7 +3480,7 @@ ieee80211_recv_mgmt(struct ieee80211vap *vap,
|
||||
}
|
||||
if (IEEE80211_IS_MULTICAST(wh->i_addr2)) {
|
||||
/* frame must be directed */
|
||||
vap->iv_stats.is_rx_mgtdiscard++; /* XXX stat */
|
||||
vap->iv_stats.is_rx_mgtdiscard++; /* XXX: stat */
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3542,9 +3602,9 @@ ieee80211_recv_mgmt(struct ieee80211vap *vap,
|
||||
ni = vap->iv_xrvap->iv_bss;
|
||||
else {
|
||||
ieee80211_node_leave(ni);
|
||||
/* This would be a stupid place to add a node to the table
|
||||
* XR stuff needs work anyway
|
||||
*/
|
||||
/* This would be a stupid place to add
|
||||
* a node to the table; XR stuff needs
|
||||
* work anyway. */
|
||||
ieee80211_node_reset(ni, vap->iv_xrvap);
|
||||
}
|
||||
vap = vap->iv_xrvap;
|
||||
@ -3590,7 +3650,8 @@ ieee80211_recv_mgmt(struct ieee80211vap *vap,
|
||||
/* XXX not right */
|
||||
ieee80211_send_error(ni, wh->i_addr2,
|
||||
IEEE80211_FC0_SUBTYPE_AUTH,
|
||||
(seq + 1) | (IEEE80211_STATUS_ALG << 16));
|
||||
(seq + 1) |
|
||||
(IEEE80211_STATUS_ALG << 16));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -3664,8 +3725,10 @@ ieee80211_recv_mgmt(struct ieee80211vap *vap,
|
||||
rsn = frm;
|
||||
else
|
||||
IEEE80211_DPRINTF(vap,
|
||||
IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA,
|
||||
"[" MAC_FMT "] ignoring RSN IE in association request\n",
|
||||
IEEE80211_MSG_ASSOC |
|
||||
IEEE80211_MSG_WPA,
|
||||
"[" MAC_FMT "] ignoring RSN IE "
|
||||
"in association request\n",
|
||||
MAC_ADDR(wh->i_addr2));
|
||||
break;
|
||||
case IEEE80211_ELEMID_VENDOR:
|
||||
@ -3676,8 +3739,11 @@ ieee80211_recv_mgmt(struct ieee80211vap *vap,
|
||||
wpa = frm;
|
||||
else
|
||||
IEEE80211_DPRINTF(vap,
|
||||
IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA,
|
||||
"[" MAC_FMT "] ignoring WPA IE in association request\n",
|
||||
IEEE80211_MSG_ASSOC |
|
||||
IEEE80211_MSG_WPA,
|
||||
"[" MAC_FMT "] "
|
||||
"ignoring WPA IE in "
|
||||
"association request\n",
|
||||
MAC_ADDR(wh->i_addr2));
|
||||
} else if (iswmeinfo(frm))
|
||||
wme = frm;
|
||||
@ -3839,7 +3905,8 @@ ieee80211_recv_mgmt(struct ieee80211vap *vap,
|
||||
|
||||
ieee80211_saveath(ni, ath);
|
||||
|
||||
/* Send Receiver Not Ready (RNR) followed by XID for newly associated stations */
|
||||
/* Send Receiver Not Ready (RNR) followed by XID for newly
|
||||
* associated stations. */
|
||||
ieee80211_deliver_l2_rnr(ni);
|
||||
ieee80211_deliver_l2_xid(ni);
|
||||
ieee80211_node_join(ni, resp);
|
||||
|
@ -1005,64 +1005,69 @@ ieee80211_scan_dfs_action(struct ieee80211vap *vap,
|
||||
* the probability of selecting a given channel shall be the
|
||||
* same for all channels (reference: ETSI 301 893 v1.3.1
|
||||
* $4.6.2.5.1 */
|
||||
|
||||
/* First, we count the usable channels */
|
||||
|
||||
count = 0;
|
||||
curChanFlags = (ic->ic_bsschan->ic_flags) & ~(IEEE80211_CHAN_RADAR);
|
||||
for (i=0; i<ic->ic_nchans; i++) {
|
||||
if ((ic->ic_channels[i].ic_ieee != ic->ic_bsschan->ic_ieee) &&
|
||||
curChanFlags = (ic->ic_bsschan->ic_flags) &
|
||||
~(IEEE80211_CHAN_RADAR);
|
||||
for (i = 0; i < ic->ic_nchans; i++) {
|
||||
if ((ic->ic_channels[i].ic_ieee !=
|
||||
ic->ic_bsschan->ic_ieee) &&
|
||||
(ic->ic_channels[i].ic_flags == curChanFlags)) {
|
||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
|
||||
"%s: usable channel %3d (%4d MHz)\n",
|
||||
__func__, ic->ic_channels[i].ic_ieee,
|
||||
ic->ic_channels[i].ic_freq);
|
||||
"%s: usable channel %3d "
|
||||
"(%4d MHz)\n",
|
||||
__func__,
|
||||
ic->ic_channels[i].ic_ieee,
|
||||
ic->ic_channels[i].ic_freq);
|
||||
count ++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count != 0) {
|
||||
|
||||
/* Next, we pickup a random usable channel */
|
||||
chanStart = jiffies % count;
|
||||
|
||||
count = 0;
|
||||
for (i=0; i<ic->ic_nchans; i++) {
|
||||
if ((ic->ic_channels[i].ic_ieee != ic->ic_bsschan->ic_ieee) &&
|
||||
(ic->ic_channels[i].ic_flags == curChanFlags)) {
|
||||
for (i = 0; i < ic->ic_nchans; i++) {
|
||||
if ((ic->ic_channels[i].ic_ieee !=
|
||||
ic->ic_bsschan->ic_ieee) &&
|
||||
(ic->ic_channels[i].ic_flags ==
|
||||
curChanFlags)) {
|
||||
if (count++ == chanStart) {
|
||||
new_channel = &ic->ic_channels[i];
|
||||
new_channel =
|
||||
&ic->ic_channels[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (new_channel != NULL) {
|
||||
if (new_channel != NULL)
|
||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
|
||||
"%s: new random channel found %3d (%4d MHz)\n",
|
||||
__func__, new_channel->ic_ieee, new_channel->ic_freq);
|
||||
}
|
||||
"%s: new random channel found %3d "
|
||||
"(%4d MHz)\n", __func__,
|
||||
new_channel->ic_ieee,
|
||||
new_channel->ic_freq);
|
||||
}
|
||||
if(!new_channel) {
|
||||
|
||||
if (!new_channel) {
|
||||
/* Search for the first channel with no radar detected */
|
||||
int n = 0;
|
||||
for(n = 0; n < ic->ic_nchans; n++) {
|
||||
if(0 == (ic->ic_channels[n].ic_flags & IEEE80211_CHAN_RADAR)) {
|
||||
if (0 == (ic->ic_channels[n].ic_flags &
|
||||
IEEE80211_CHAN_RADAR)) {
|
||||
new_channel = &ic->ic_channels[n];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (new_channel != NULL) {
|
||||
if (new_channel != NULL)
|
||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
|
||||
"%s: new non-radar channel found\n",
|
||||
__func__);
|
||||
}
|
||||
"%s: new non-radar channel found\n",
|
||||
__func__);
|
||||
}
|
||||
if (new_channel != NULL) {
|
||||
/* A suitable scan entry was found, so change channels */
|
||||
if (vap->iv_state == IEEE80211_S_RUN) {
|
||||
|
||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
|
||||
"%s: CSA switching to channel %3d (%4d MHz)\n",
|
||||
__func__,
|
||||
@ -1070,20 +1075,19 @@ ieee80211_scan_dfs_action(struct ieee80211vap *vap,
|
||||
new_channel->ic_freq);
|
||||
|
||||
ic->ic_chanchange_chan = new_channel->ic_ieee;
|
||||
ic->ic_chanchange_tbtt = IEEE80211_RADAR_CHANCHANGE_TBTT_COUNT;
|
||||
ic->ic_chanchange_tbtt =
|
||||
IEEE80211_RADAR_CHANCHANGE_TBTT_COUNT;
|
||||
ic->ic_flags |= IEEE80211_F_CHANSWITCH;
|
||||
} else {
|
||||
|
||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
|
||||
"%s: directly switching to channel %3d (%4d MHz)\n",
|
||||
__func__,
|
||||
new_channel->ic_ieee,
|
||||
new_channel->ic_freq);
|
||||
"%s: directly switching to channel "
|
||||
"%3d (%4d MHz)\n", __func__,
|
||||
new_channel->ic_ieee,
|
||||
new_channel->ic_freq);
|
||||
|
||||
/*
|
||||
* vap is not in run state yet. so
|
||||
* change the channel here.
|
||||
*/
|
||||
/* VAP is not in run state yet. so
|
||||
* change the channel here. */
|
||||
change_channel(ic, new_channel);
|
||||
ic->ic_bsschan = new_channel;
|
||||
if (vap->iv_bss)
|
||||
@ -1092,8 +1096,7 @@ ieee80211_scan_dfs_action(struct ieee80211vap *vap,
|
||||
} else {
|
||||
/* A suitable scan entry was not found */
|
||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
|
||||
"%s: new channel not found\n",
|
||||
__func__);
|
||||
"%s: new channel not found\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -48,10 +48,12 @@
|
||||
#include <net80211/ieee80211_proto.h>
|
||||
#include <net80211/ieee80211_scan.h>
|
||||
|
||||
/*
|
||||
Note: Atheros chips use 6 bits when power is specified in whole dBm units, with a value range from 0 to 63.
|
||||
Note: Atheros chips use 7 bits when power is specified in half dBm units, with a value range from 0 to 127.
|
||||
*/
|
||||
/* NB:
|
||||
* - Atheros chips use 6 bits when power is specified in whole dBm units, with
|
||||
* a value range from 0 to 63.
|
||||
* - Atheros chips use 7 bits when power is specified in half dBm units, with
|
||||
* a value range from 0 to 127.
|
||||
*/
|
||||
#define IEEE80211_TXPOWER_MAX 127 /* .5 dBm units */
|
||||
#define IEEE80211_TXPOWER_MIN 0 /* kill radio */
|
||||
|
||||
@ -700,11 +702,12 @@ void ieee80211_expire_channel_non_occupancy_restrictions(struct ieee80211com *);
|
||||
*
|
||||
* _i and prevchan are temporary variables
|
||||
*/
|
||||
#define CHANNEL_FOREACH(i, ic, _i, prevchan) \
|
||||
for (_i = 0, prevchan = 0; \
|
||||
_i<ic->ic_nchans && (i = ic->ic_channels[_i].ic_ieee); \
|
||||
prevchan = i, _i++ \
|
||||
) if (i != prevchan)
|
||||
#define CHANNEL_FOREACH(i, _ic, _i, _prevchan) \
|
||||
for ((_i) = 0, (_prevchan) = 0; \
|
||||
(_i) < (_ic)->ic_nchans && ((i) = \
|
||||
(_ic)->ic_channels[(_i)].ic_ieee); \
|
||||
(_prevchan) = (i), (_i)++ \
|
||||
) if ((i) != (_prevchan))
|
||||
|
||||
/* Key update synchronization methods. XXX should not be visible. */
|
||||
static __inline void
|
||||
|
@ -1419,7 +1419,8 @@ done:
|
||||
}
|
||||
|
||||
static int
|
||||
ieee80211_get_txcont(struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
|
||||
ieee80211_get_txcont(struct net_device *dev,
|
||||
struct iw_request_info *info, void *w, char *extra)
|
||||
{
|
||||
int *params = (int*) extra;
|
||||
struct ieee80211vap *vap = dev->priv;
|
||||
@ -1429,7 +1430,8 @@ ieee80211_get_txcont(struct net_device *dev, struct iw_request_info *info, void
|
||||
}
|
||||
|
||||
static int
|
||||
ieee80211_get_dfs_channel_availability_check_time (struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
|
||||
ieee80211_get_dfs_channel_availability_check_time(struct net_device *dev,
|
||||
struct iw_request_info *info, void *w, char *extra)
|
||||
{
|
||||
int *params = (int*) extra;
|
||||
struct ieee80211vap *vap = dev->priv;
|
||||
@ -1439,7 +1441,8 @@ ieee80211_get_dfs_channel_availability_check_time (struct net_device *dev, stru
|
||||
}
|
||||
|
||||
static int
|
||||
ieee80211_get_dfs_non_occupancy_period (struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
|
||||
ieee80211_get_dfs_non_occupancy_period(struct net_device *dev,
|
||||
struct iw_request_info *info, void *w, char *extra)
|
||||
{
|
||||
int *params = (int*) extra;
|
||||
struct ieee80211vap *vap = dev->priv;
|
||||
@ -1448,7 +1451,8 @@ ieee80211_get_dfs_non_occupancy_period (struct net_device *dev, struct iw_reque
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
ieee80211_set_dfs_channel_availability_check_time (struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
|
||||
ieee80211_set_dfs_channel_availability_check_time(struct net_device *dev,
|
||||
struct iw_request_info *info, void *w, char *extra)
|
||||
{
|
||||
int *params = (int*) extra;
|
||||
struct ieee80211vap *vap = dev->priv;
|
||||
@ -1457,7 +1461,8 @@ ieee80211_set_dfs_channel_availability_check_time (struct net_device *dev, stru
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
ieee80211_set_dfs_non_occupancy_period (struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
|
||||
ieee80211_set_dfs_non_occupancy_period (struct net_device *dev,
|
||||
struct iw_request_info *info, void *w, char *extra)
|
||||
{
|
||||
int *params = (int*) extra;
|
||||
struct ieee80211vap *vap = dev->priv;
|
||||
@ -1467,7 +1472,8 @@ ieee80211_set_dfs_non_occupancy_period (struct net_device *dev, struct iw_reque
|
||||
}
|
||||
|
||||
static int
|
||||
ieee80211_get_dfs_testmode(struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
|
||||
ieee80211_get_dfs_testmode(struct net_device *dev,
|
||||
struct iw_request_info *info, void *w, char *extra)
|
||||
{
|
||||
int *params = (int*) extra;
|
||||
struct ieee80211vap *vap = dev->priv;
|
||||
@ -1477,7 +1483,8 @@ ieee80211_get_dfs_testmode(struct net_device *dev, struct iw_request_info *info,
|
||||
}
|
||||
|
||||
static int
|
||||
ieee80211_get_txcont_rate(struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
|
||||
ieee80211_get_txcont_rate(struct net_device *dev,
|
||||
struct iw_request_info *info, void *w, char *extra)
|
||||
{
|
||||
int *params = (int*) extra;
|
||||
struct ieee80211vap *vap = dev->priv;
|
||||
@ -1487,7 +1494,8 @@ ieee80211_get_txcont_rate(struct net_device *dev, struct iw_request_info *info,
|
||||
}
|
||||
|
||||
static int
|
||||
ieee80211_set_txcont(struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
|
||||
ieee80211_set_txcont(struct net_device *dev, struct iw_request_info *info,
|
||||
void *w, char *extra)
|
||||
{
|
||||
int *params = (int*) extra;
|
||||
struct ieee80211vap *vap = dev->priv;
|
||||
@ -1497,7 +1505,8 @@ ieee80211_set_txcont(struct net_device *dev, struct iw_request_info *info, void
|
||||
}
|
||||
|
||||
static int
|
||||
ieee80211_set_dfs_testmode(struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
|
||||
ieee80211_set_dfs_testmode(struct net_device *dev,
|
||||
struct iw_request_info *info, void *w, char *extra)
|
||||
{
|
||||
int *params = (int*) extra;
|
||||
struct ieee80211vap *vap = dev->priv;
|
||||
@ -1507,7 +1516,8 @@ ieee80211_set_dfs_testmode(struct net_device *dev, struct iw_request_info *info,
|
||||
}
|
||||
|
||||
static int
|
||||
ieee80211_set_txcont_rate(struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
|
||||
ieee80211_set_txcont_rate(struct net_device *dev,
|
||||
struct iw_request_info *info, void *w, char *extra)
|
||||
{
|
||||
int *params = (int*) extra;
|
||||
struct ieee80211vap *vap = dev->priv;
|
||||
@ -1517,7 +1527,8 @@ ieee80211_set_txcont_rate(struct net_device *dev, struct iw_request_info *info,
|
||||
}
|
||||
|
||||
static int
|
||||
ieee80211_set_txcont_power(struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
|
||||
ieee80211_set_txcont_power(struct net_device *dev,
|
||||
struct iw_request_info *info, void *w, char *extra)
|
||||
{
|
||||
int *params = (int*) extra;
|
||||
struct ieee80211vap *vap = dev->priv;
|
||||
@ -1527,7 +1538,8 @@ ieee80211_set_txcont_power(struct net_device *dev, struct iw_request_info *info,
|
||||
}
|
||||
|
||||
static int
|
||||
ieee80211_get_txcont_power(struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
|
||||
ieee80211_get_txcont_power(struct net_device *dev,
|
||||
struct iw_request_info *info, void *w, char *extra)
|
||||
{
|
||||
int *params = (int*) extra;
|
||||
struct ieee80211vap *vap = dev->priv;
|
||||
|
Loading…
Reference in New Issue
Block a user