Formatting

git-svn-id: http://madwifi-project.org/svn/madwifi/trunk@3274 0192ed92-7a03-0410-a25b-9323aeb14dbd
This commit is contained in:
mentor 2008-01-27 05:48:23 +00:00
parent 60e9b06ffa
commit cf6e609462
7 changed files with 485 additions and 326 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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;